デプロイに伴うデータ不整合を回避する

これまでの開発を振り返ると、いろんなチームで繰り返し起きる障害のひとつとして、デプロイ時に行うカラムの追加/削除によってコードとの不整合がおきることがある。

開発時はカラムの追加/削除をカジュアルに行ってしまうものの、本番環境にデプロイするときはデプロイする順番を慎重に検討する必要がある。

ある程度経験を積んだプログラマーなら当然かもしれないけど、普段意識していることをまとめてみた。

カラム追加時

新しくカラムを追加するとき、NOT NULL制約をつける場合はDEFAULTもできるだけつけた方がいい。ただし、外部キー等DEFAULTを決められない場合、NOT NULL制約をつけずコード上ではカラムの値が空であることを意識してコードを書く。

仮にDEFAULTを指定せずにNOT NULL制約をつけた場合、アプリケーション側でデフォルト値を設定するようなコードを書いたとしても、カラムが追加されてからそれがデプロイされるまでの間にレコードが追加されてしまい、エラーになってしまう。

なので、NOT NULL制約をつけずにカラムの値が空であることを意識してコードを書く。コードがデプロイされてからカラムの値が空ではないことを確認できたら、NOT NULL制約をつける。

NOT NULL制約をつけるカラムを追加するデプロイは以下のように2段階に分けることが多い。

  1. NOT NULL制約をつけずにカラムを追加するmigrationとそのカラムを利用するコードをデプロイする。このとき、カラムが空になっているレコードもあることに注意する。
  2. スクリプト等ですべてのレコードのカラムが空じゃないことが確認できたら、NOT NULL制約をつける。また、カラムが空でないことを前提にコードも修正する。

カラム削除時

カラムの削除を伴うデプロイを行うとき、そのカラムを利用するコードが存在しないことを確認してから削除を行う必要がある。なので、カラムを削除するデプロイは以下のように2段階に分ける。

  1. 削除予定のカラムを利用しないようにコードを修正してデプロイする。
  2. カラムを削除する。