Post deployment migrations
Downtime deployments are annoying. One category of deployments that currently needs downtime is when a set of migrations remove parts from the database (e.g. a column or an entire table). Here downtime is needed because the new code isn't deployed until the migrations have been completed.
In the past we have discussed post deployment migrations and what not, but we never really coded something together.
The idea I'm thinking of is as follows:
By default migrations are executed as usual. If a migration class defines the
constant POST_DEPLOY
and sets it to true
then the migration is not
executed unless the environment variable GITLAB_POST_DEPLOY
is set to a
non-empty value. This variable in turn is set by an extra Rake task called
something like db:migrate:post-deploy
or something like that.
This does require users to run this extra step as part of their deployment process. It also means we have to be careful with migrations so that one can upgrade from any version to a newer one. In other words, post-deploy migrations must only be used to:
- Remove columns, tables, etc
- Remove existing data
In case of removing schema objects these migrations should make sure they only remove things that are still present. This prevents them from failing in case something else already removed the objects.
This is probably the least invasive solution that I can think of, though it requires hijacking the Rails migration process to skip migrations in case the constant is set.