Skip to content
Berktug Berke Ates
Berktug Berke Ates

ソフトウェアエンジニア

ブログ

実践におけるゼロダウンタイムデータベース移行

· 6分で読める

実トラフィック下でスキーマを安全に変えるために、拡張と収縮のデリバリーを使え。

デプロイは重なる

スキーマ移行が孤立して走ることは稀だ。新旧のアプリインスタンスが同時にトラフィックを捌き、ワーカーが遅延ジョブを処理し、モバイルクライアントが何ヶ月も活動しうる。安全な移行はこの重なりを前提にし、各中間状態を互換に保つ。

拡張と収縮パターンは、リスクある置換を可逆な段階に分ける。まずスキーマやインターフェースを拡張し、次に振る舞いとデータを移行し、結果を観測し、その後に旧経路を除く。余分なステップは、重要な瞬間に制御を買う。

意味を変えずに拡張する

既存コードが無視できる形で、新しいnullable列、表、インデックス、エンドポイントを足せ。データベース振る舞いを理解せず、ロック下で大きな表を書き換えるデフォルトや制約を避けろ。エンジンがサポートするなら大きなインデックスを並行構築し、レプリケーションラグとロック時間を監視しろ。

両方の表現を書ける、または新規データに新モデルを埋めるコードをデプロイしろ。デュアルライトは一貫性リスクを導入する。移行を有界に保ち、乖離を計装し、両方のレコードが同じデータベースを共有するなら単一トランザクションを好め。

  • まず表サイズとロック振る舞いを測る
  • 移行コマンドを再起動可能にする
  • 本番負荷下でバックフィルをスロットルする
  • 安定したチェックポイントで進捗を記録する

バックフィルを操作として扱う

本番バックフィルは一回限りのスクリプトではなくワークロードだ。決定的なバッチを処理し、チェックポイントを永続化し、同時実行を制限し、進捗と失敗を露出せよ。ジョブは効果を複製せずに停止・再開して安全であるべきだ。

新しい表現を継続的に検証しろ。終わりまで待たず、件数、チェックサム、不変条件、サンプリング記録を比較しろ。移行が意味を変えるなら、期待マッピングをドメイン所有者がレビューした実行可能チェックに符号化しろ。

リードを意図的に移す

新しい書き込みと履歴データが準備できたら、機能フラグや制御されたロールアウトの背後でリードを移せ。シャドウリードはユーザー応答を変えずに新旧結果を比較できる。経路ごとにエラーとレイテンシをセグメントし、前進の決定を証拠に基づかせろ。

この段階のロールバックは通常、スキーマを戻すのではなくリードを切り戻すことを意味する。破壊的ロールバックスクリプトは、回復可能なデプロイをはるかに悪くできる。確信度が高いまで拡張状態を保て。

証拠の後にだけ収縮する

旧表現への書き込みを止め、重なるアプリバージョンとキュー作業が消えるのを待ち、未使用コードを除け。テレメトリで旧フィールドや表がもはや読まれないことを確認してから、別デプロイで削除しろ。

ゼロダウンタイムはリスクの不在ではない。リスクを観測可能にし、爆風半径を制限し、各段階で安全な決定を保つデリバリーの形だ。


2024年6月5日、Berktug Berke Ates が公開。