Interested in taking your Rails migration code to the next level?
Welcome. You’re in the right place.
What’s that? Somebody in the back says they’re not already up on the
basics? No problem. The
Rails Guide on migrations is like most Rails guides – pretty darn
awesome. It’ll have you adding tables, dropping columns and altering
multi-column indices before you know it.
For the rest of you who know the basics, let’s learn what awesome
Rails programmers already know about migrations.
Migrations can bring down a busy
site in a hurry. Many things you do in a migration will lock the
table you’re touching, which will block every SQL query and every
Rails route that touches that table, sometimes for minutes or hours.
You can’t “scale” your way out of it – you only get one database, and
it’s locked for all app servers.
There are a known
set of safe
operations on Postgres databases which will let you do
everything. MySQL will do nearly all of them, but not
quite. For those cases where you have to add an index on a huge table
or change the format of a column, there’s Large Hadron Migrator –
or “scheduled maintenance”, a.k.a. downtime. In both cases, Strong
Migrations is an automated tool that can help you use only
Migrations are some of the most dangerous code in Rails. They’re
designed to mess with your DB schema and often add, drop and modify
a lot of data at a time.
Luckily, you can find guidelines for code reviews if
you look a bit.
There are automated tools like Good
Migrations and Strong
Migrations to help you follow some high-quality migration rules
and prevent downtime. But there’s no replacement for code review by a
careful human being.
Migrations add a bit of work for your database. A good no-downtime
migration (see above) isn’t terrible, but it’s still one more thing
going on. As a result, you’ll want to schedule it to not happen during
big batch jobs or other expensive operations.
By centralizing your batch jobs (keep them all on specific hosts, or
scheduled through a central service) you can tell what’s coming and
find a nice quiet time to do your migrations without disrupting other
work. Not only is that best for performance, but if something goes
wrong you know it’s a problem with the one thing currently happening
– not a finger-pointing blame game or a weird interaction between
multiple things you’re doing.
If you follow the downtime-free migration recommendations above, you
can do all your migrations before your code deploys even
start. So not only will you have no downtime, the reduced capacity
of a deploy can wait until you’ve finished with the reduced capacity
from a migration. Again, try to only do one thing at once so that you
know what the problem is.
And by separating out your migrations (see the code review guidelines for
migrations), keeping them harmless, testing rollback and keeping
backups, you can make it easy to handle any failures or rollbacks that
Does this count as a “class”? It’s pretty short… Unless you actually
follow links and learn properly about no-downtime migrations and the
code review guidelines for migrations. And then it’s a pretty
significant amount of learning and will make you permanently better at
this. Very few developers do a good, thorough job on migrations. I
hope you’ll join them, and save your projects and your employers a lot
of wasted time and money.
And, of course, not get fired for destroying user data.
If you read deeply and you still think, “but I already knew all of
this,” then congratulations. You’re a very solid database developer or
an incorrigible speed-reader, depending. In that case, may I recommend
a good book on databases that isn’t Rails-specific? Or perhaps a
consultation with your local DBA? If you truly know all this material,
you’re not just being a responsible database developer, but a real
database specialist. You have my respect.