TT Lab
はじめる
学ぶ 学習パス コース

SIのDB運用

スキーマ変更とロールバックスクリプトの作成

TT Labで続きを見る

目標

拡張-移行-縮小パターンでスキーマを変更し、ロールバックスクリプト・バッチバックフィル・検証スクリプト・作業手順書まで揃えた、変更管理の一式を作れるようになります。

なぜ重要なのか

「downスクリプトがあるから安全だ」は、最もよくある思い込みです。DROP COLUMNを元に戻すdownは、カラムの構造を復活させるだけで、値は復活させられません。可逆性はコードの属性ではなくコードとデータと時間の組み合わせなので、同じ変更でも、昨日デプロイしたなら可逆で、100万件が溜まったあとは不可逆です。そして、大量バックフィルを1つのトランザクションで実行すると、ロックとログが急増して、リードレプリカが遅れ、照会サービスが古いデータを表示します。このラボは、そうした落とし穴を自分の手で避けてみる訓練です。

ステップ

  1. 準備: dbo-schemaラボの/root/db/si.dbが必要です。 なければ/opt/lab/fixtures/dbo/si-base.sqlで作成できます。
  2. 現在のスキーマを/root/db/schema_v1.sqlに保存し、/root/db/baseline.txtを作成してください。3行です。
    orders_cnt=<ORDERS 행 수>
    orders_amt=<ORDERS 의 ORD_AMT 합계>
    item_qty=<ORDER_ITEM 의 QTY 합계>
    
    (山括弧の中の韓国語はプレースホルダーで、順にORDERSの行数、ORDERSのORD_AMTの合計、ORDER_ITEMのQTYの合計です。)
  3. /root/db/changelog.csvを作成してください。1行目はchg_id,date,object,ddl_file,rollback_file,est_sec,approverです。 ステップ3から5で作成する変更3件を、あらかじめ登録します。 ddl_file・rollback_file・approverは空にしてはいけません。est_secには数値が入っている必要があります。
  4. /root/db/mig/V2__add_dlvr_sts.sqlを作成してください。
    • ORDERSにDLVR_STS_CDカラムを追加します(デフォルト値は'01')
    • 既存の行をすべて'01'で埋めます 適用後、DLVR_STS_CDがNULLの行が0件である必要があります。
  5. /root/db/mig/V2__rollback.sqlを作成してください。 適用するとスキーマがschema_v1.sqlと同じになる必要があります。 (si.dbのコピーでup → downを実行して確認してください。)
  6. /root/db/mig/V3__item_qty_check.sqlを作成してください。 ORDER_ITEM.QTYのCHECKを1以上9999以下に強化します。 sqliteは制約の変更をサポートしていないため、テーブル再作成の手順が必要です。 適用後も、ORDER_ITEMの行数とQTYの合計がステップ1のベースラインと同じで、外部キーの関係も維持されている必要があります。
  7. /root/db/batch-update.shを作成してください。2つの引数(DB파일 배치크기。プレースホルダーはDBファイルとバッチサイズです)を受け取り、ORDERSのDLVR_STS_CDが'01'の行を'02'に更新しますが、1回にバッチサイズの分ずつ繰り返し処理します。 最後の行にbatches=<반복횟수> updated=<총건수>(プレースホルダーは繰り返し回数と総件数です)を出力します。 (元のDBを汚さないよう、引数で受け取ったDBにだけ適用します。)
  8. /root/db/mig-verify.shを作成してください。2つの引数(기준선파일 DB파일。プレースホルダーはベースラインファイルとDBファイルです)を受け取り、ベースラインの3つの指標を現在のDBと比較して、すべて同じなら1行目にOKを、異なる場合はNGで始まる行とともに、どの指標が異なるかを出力します。終了コードもそれぞれ0と0以外の値です。
  9. /root/db/mig-runbook.mdを作成してください。## 작업 개요、## 사전 백업、## 적용 절차、## 검증、## 롤백 기준、## 롤백 절차(韓国語の見出しで、順に作業概要、事前バックアップ、適用手順、検証、ロールバック基準、ロールバック手順を意味します)の6つのh2見出しが必要で、本文にバックアップファイルのパスと数値で書かれたロールバック基準(所要時間または検証失敗件数)が含まれている必要があります。

参考

スキーマのスナップショットとベースライン

現在のスキーマを/root/db/schema_v1.sqlに保存し、/root/db/baseline.txtを作成してください。3行です。

orders_cnt=<ORDERS 행 수>
orders_amt=<ORDERS 의 ORD_AMT 합계>
item_qty=<ORDER_ITEM 의 QTY 합계>

(山括弧の中の韓国語はプレースホルダーで、順にORDERSの行数、ORDERSのORD_AMTの合計、ORDER_ITEMのQTYの合計です。)

作業後に「もともと何件でしたか」と聞くことになったら、もう遅いです。スキーマとデータの指標の両方を残してください。

変更管理台帳

/root/db/changelog.csvを作成してください。1行目はchg_id,date,object,ddl_file,rollback_file,est_sec,approverです。 ステップ3から5で作成する変更3件を、あらかじめ登録します。 ddl_file・rollback_file・approverは空にしてはいけません。est_secには数値が入っている必要があります。

ロールバックスクリプトのパスを必須項目にすると、台帳を埋めているうちに「これは元に戻せないな」とデプロイ前に気づきます。

拡張スクリプト

/root/db/mig/V2__add_dlvr_sts.sqlを作成してください。

カラムを追加して既存の行を埋めます。NULL許容で追加してから埋める方法と、最初からNOT NULLで追加する方法の違いを考えてみてください。

ロールバックスクリプト

/root/db/mig/V2__rollback.sqlを作成してください。 適用するとスキーマがschema_v1.sqlと同じになる必要があります。 (si.dbのコピーでup → downを実行して確認してください。)

元に戻したあとのスキーマが、元のスキーマと同じかを確認できる必要があります。スナップショットを比較するのが最も確実です。

テーブル再作成のマイグレーション

/root/db/mig/V3__item_qty_check.sqlを作成してください。 ORDER_ITEM.QTYのCHECKを1以上9999以下に強化します。 sqliteは制約の変更をサポートしていないため、テーブル再作成の手順が必要です。 適用後も、ORDER_ITEMの行数とQTYの合計がステップ1のベースラインと同じで、外部キーの関係も維持されている必要があります。

制約を変えるには、新しいテーブルを作ってデータを移す手順が必要です。順序を守らないと、データや参照が壊れます。

バッチバックフィル

/root/db/batch-update.shを作成してください。2つの引数(DB파일 배치크기。プレースホルダーはDBファイルとバッチサイズです)を受け取り、ORDERSのDLVR_STS_CDが'01'の行を'02'に更新しますが、1回にバッチサイズの分ずつ繰り返し処理します。 最後の行にbatches=<반복횟수> updated=<총건수>(プレースホルダーは繰り返し回数と総件数です)を出力します。 (元のDBを汚さないよう、引数で受け取ったDBにだけ適用します。)

大量のUPDATEを1つのトランザクションで行うと、ロックとログが急増します。影響を受ける行が0件になるまで繰り返す構造にしてください。

マイグレーション検証スクリプト

/root/db/mig-verify.shを作成してください。2つの引数(기준선파일 DB파일。プレースホルダーはベースラインファイルとDBファイルです)を受け取り、ベースラインの3つの指標を現在のDBと比較して、すべて同じなら1行目にOKを、異なる場合はNGで始まる行とともに、どの指標が異なるかを出力します。終了コードもそれぞれ0と0以外の値です。

行数と合計だけでは、「1件が抜けて別の1件が2倍になった」状況を検出できません。指標を複数置いてください。

作業手順書

/root/db/mig-runbook.mdを作成してください。## 작업 개요、## 사전 백업、## 적용 절차、## 검증、## 롤백 기준、## 롤백 절차(韓国語の見出しで、順に作業概要、事前バックアップ、適用手順、検証、ロールバック基準、ロールバック手順を意味します)の6つのh2見出しが必要で、本文にバックアップファイルのパスと数値で書かれたロールバック基準(所要時間または検証失敗件数)が含まれている必要があります。

明け方に読むドキュメントです。コマンドをそのままコピーして使えて、いつ止めて元に戻すかが数値で書かれている必要があります。