本番の永続状態(スキーマ・索引・インフラ)は破壊的再作成を避け、事前互換チェックと backfill を伴う段階移行で『既存データを保ったまま』変える
データベース
マイグレーション
設計判断
信頼性
原則
永続化された本番の状態(DB スキーマ、検索インデックス、IaC が管理するリソース)を変更するときの最適化対象は「既存データ・既存状態を保ったまま、適用前に互換性を検証し、必要なら backfill して段階的に移行すること」。避けるのは「空・クリーンな状態を前提に一括適用する」「リソースを破壊して作り直し、既存データ・状態・関連を失う」こと。新規構築と決定的に違うのは『既に値が入っている』点で、その前提を設計の中心に置く。
判断基準
- 本番の永続データ変更は『ローカル/テストは空なので通る』を前提にしない。制約追加・型変更・新フィールド導入は、適用前に既存データが新条件を満たすかを読み取り専用で確認する(一意制約なら重複の有無、検索条件に使う新フィールドなら既存レコードの欠落、内部型変更なら既存のエンコード形)。違反があれば適用前に解消するか backfill する。
- 追加と破壊を一括で混ぜない。先に追加を投入する→データ移行は別工程で行う→不要になった物の削除は後続リリースで明示承認付きにする、という段階に分け、破壊的変更は自動実行ゲートから外して手動承認に回す。
- コード(型・モデル定義)を直せば既存データも追従する、と考えない。永続化済みデータのエンコード形・欠落フィールドはコードデプロイでは直らないので、別の backfill / reindex 工程を計画に含める。
- IaC でリソース型や同一性が変わる移行は、書き換えてそのまま適用しない。先に状態を新しい同一性へ引き継ぐ操作(import / 移動相当)を行い、再作成・重複作成を避けてから差分を適用する。
なぜ
空状態前提の一括適用や破壊的再作成は、適用時失敗でデプロイを止めるか、既存データ・関連・検索可視性を黙って失わせる。事前検証・backfill・段階移行は、各ステップを小さく可逆に保ち、失敗を適用前か途中で止められる。
検証
変更を『既存データがある状態』で再現する。空でない検証用データに想定外の値・欠落・重複を仕込み、事前チェックが違反を検出すること、backfill 後に新条件を満たすこと、段階手順の各ステップ単独でアプリが動くことを確認する。空のテスト DB だけで緑になる変更は未検証とみなす。
根拠(synthesize 元)
- 389 本番 DB の破壊的 DDL を防ぐゲートと expand/migrate/contract
- 568 JSONB カラムの内部型を変えたら既存データのエンコード形を backfill する
- 530 既存テーブルへの UNIQUE 制約後付けは適用前に重複を検出する
- 346 検索インデックスに検索条件フィールドを追加すると既存ドキュメントが検索から消える(backfill/reindex 計画)
- 381 Terraform リソース型移行は import + state rm を先に手動で行う