Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Example of a (slightly hacky) concurrent migration for Rails 3.2 to add an index to a huge table without locking the table in a transaction.
class AddIndexOnClientApplicationIdForOauthTokens < ActiveRecord::Migration
def ddl_transaction(&block)
# hack because AR 3.x doesn't support the `disable_ddl_transaction!`
# method that AR 4.x introduced yet.
block.call # do not start a transaction
end
def change
# using raw SQL because ActiveRecord 3.x doesn't support concurrent
# migrations yet, in AR 4 this would be:
#
# add_index :oauth_tokens, :client_application_id, algorithm: :concurrently
#
execute "END" # manually end the current transaction
execute "CREATE INDEX CONCURRENTLY index_oauth_tokens_on_client_application_id ON oauth_tokens(client_application_id)"
execute "BEGIN" # manually start a new transaction
end
end
@julianlconnor

This comment has been minimized.

Copy link

julianlconnor commented Mar 10, 2015

thanks for posting this, solved my bug <3

@GuyPaddock

This comment has been minimized.

Copy link

GuyPaddock commented Oct 10, 2017

For Ruby 2.0.0, I don't think ddl_transaction is actually doing anything in this Gist -- it's a private method. That explains why you're having to manually end and start the transaction in the migration itself.

@GuyPaddock

This comment has been minimized.

Copy link

GuyPaddock commented Oct 10, 2017

I was incorrect -- the actual issue in Rails 3 is that ddl_transaction moved into ActiveRecord::Migrator.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.