Created
October 17, 2014 07:17
-
-
Save olivierlacan/ba81d56d3c9e2a506216 to your computer and use it in GitHub Desktop.
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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 |
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.
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
thanks for posting this, solved my bug <3