Zero Downtime Rails Migrations with the Large Hadron Migrator Gem

Are you working on a mature or legacy Rails app?  If so, you know migrations that change the structure of your tables (like adding indices) or update many rows can be troublesome.  You might be ask yourself, “Wow. I have this big app in production with lots of users and I have to perform an operation on the database…and I can’t afford to lock that table for an extended period of time? What should I do?”

Well, thanks to the good folks at Soundcloud, there is a solution. It’s called the “Large Hadron Migrator“.

Using this gem is simple.  Like any Rails gem, you must first add it to your gemfile.

gem "lhm", "~> 1.1.0", :require => false

Be sure to run “bundle” at the command line.  Once that’s done, create your migration file.  In this example, I want to add an index to the user_id column in a table called “interests”.  Here is how this migration might look:

require 'lhm'

class AddUserIdIndexToInterestsTable < ActiveRecord::Migration
  def self.up
    Lhm.change_table :interests do |m|
      m.add_index [:user_id], "idx_user_id"
    end
  end

  def self.down
    Lhm.change_table :interests do |m|
      m.remove_index [:user_id], "idx_user_id"
    end
  end
end

 

Note a couple of things different about this migration. First, you need to explicity require the Large Hadron Migrator gem with the “require ‘lhm'” line at the top.  Second, you prefix your change_table method in the migration with “Lhm”.  Why?  Easy.  To avoid data loss, the Large Hadron Migrator gem creates a temporary table during the migration.  This avoids locking your normal table (and therefore forcing a shutdown of your app) during the migration.

Finally, run your migration like any other with…

rake db:migrate

And – presto! – the gem works its magic. It creates a temporary table, applies your changes, protects your data and you no longer have to lock your database table in a large app to perform structural changes, add indices or update lots of data.

Good times!

 

 

Not commented yet.

LEAVE A COMMENT