RDSのBlue/Green Deploymentsは本当に便利な機能ですね。昔はレプリカのサーバーを0から構築していたことを考えると隔世の感があります。
さて、この機能を使ってDBのスキーマを変更した時に問題となるのが、アプリケーションフレームワークにmigration管理の仕組みがあった場合に、DBのスキーマとmigrationの結果に乖離が生じるというものです。要するにmigrationを使わずに直接DBのスキーマを変更したのと同様の状態になってしまうということですね。
これの対応をすることがあったので参考になればと思います。フレームワークはRuby on Railsです。
migrationを改ざんして辻褄を合わせる
空のmigrationを作成する
$ bundle exec rails g migration ChangeTableItTakesVeryLongTime
invoke active_record
create db/migrate/20240204115013_change_table_it_takes_very_long_time.rb
class ChangeTableItTakesVeryLongTime < ActiveRecord::Migration[7.0]
def up
# 何もしません
end
end
Railsではこの 20240204115013
という数値がmigrationのidになります。
開発環境でmigrationを実行します。
$ bundle exec rails db:migrate
== 20240204115013 ChangeTableItTakesVeryLongTime: migrating ===================
== 20240204115013 ChangeTableItTakesVeryLongTime: migrated (0.0000s) ==========
db/schema.rb
のversion:のところが変更されます。このファイルもcommitします。
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema[7.0].define(version: 2024_02_01_xxxxxx) do
+ActiveRecord::Schema[7.0].define(version: 2024_02_04_115013) do
migrationを実行する
前のステップで作成した空のmigrationを本番環境にdeployします。
空なのでスキーマに変更はありません。
migrationが実行済になっていることを確認。
$ bundle exec rails db:migrate:status
Status Migration ID Migration Name
--------------------------------------------------
up 20240204115013 Change table it takes very long time
RDSのBlue/Green Deploymentsで切り替えを実施する
ここで本番のDBのスキーマが実際に変更されます。
便宜的にこのステップを挟みましたが、本番DBの変更はどの時点でやっても同じです。migrationの改ざんを事前にやっておくか、後からやるかの違いになります。
migrationファイルを変更する
class ChangeTableItTakesVeryLongTime < ActiveRecord::Migration[7.0]
def up
# Blue/Greenデプロイで行ったスキーマの変更と同等のmigrationを書きます。
execute("...")
end
end
既にこのmigrationは本番環境で実行済となっているので、後から改ざんしても再度は実行されません。
migrationのidが間違っていると大変なことになるので必ず開発環境やステージング環境などで同じ手順を踏んで、migrationが実行されないことを確認してくださいね。
db/schema.rbを更新する
Blue/Greenデプロイで行ったスキーマの変更内容はdb/schema.rb
に反映されていないので、このタイミングで反映させます。
以上で辻褄が合うようになりました。
あるいは何もしない
上記の手順を不要と判断し何もしないでおく、というのも一つの手です。その場合、migrationファイルにはBlue/Greenデプロイで実施した変更が記録されていない点を留意しておく必要があります。