FIX: Make non-transactional migration idempotent (PR #13608)

Since disable_ddl_transaction! is disabled for this migration, it needs to be idempotent. Any error during the migration (e.g. a timeout) will cause ActiveRecord to fail the migration, and try again on the next run. If the index had already been created during the first run, then an ‘already exists’ error will be raised, with no way to recover.

Unfortunately an ActiveRecord bug prevents us from using if_not_exists: true alongside algorithm: :concurrently, so we have to drop to raw SQL.


I see another solution we used is: discourse/20191030112559_add_index_to_notifications.rb at master · discourse/discourse · GitHub

Which seems slightly better to me as we keep the simple AR code, any object about this solution?

That solution would also work work equally well, yeah :+1: