仕様変更によってremarksにあるデータをlogin_infoに移す本番マイグレーションがありました。
もくじ
事業部に伝わる秘技
ポイント
-
作業前バックアップ
→ヤバくなったら戻せる -
立会いによるレビュー
-
トランザクションとカウントを駆使したマイグレーション
マイグレーションを本番サーバ内のトランザクションを利用することで、
更新対象を常に確認しながら実行することで精度を確実にする
事前準備
-
ローカル環境で検証しながらSQLを作る
例) remarksのデータをinfoに入れた後で、remarksをnullにする処理
●更新1 UPDATE administrators SET administrators.login_info = administrators.remarks WHERE administrators.login_info = '' AND administrators.remarks != ''; ●更新2 UPDATE administrators SET administrators.remarks = null;
2. SQLをSlackでレビューして貰います
3-1. Meetで画面教諭しながらチームメンバーに立会いして貰う
3-2. 本番テーブルのバックアップ
ダンプしたデータの件数やサンプルデータなどからきちんとダンプできていることを確認
3-3. 本番DBにログイン
$ sudo mysql -u hoge -p -h xxxxxx.ap-northeast-1.rds.amazonaws.com
本番DBでの操作
●DBを指定 mysql> use sampleDb; ●更新対象レコード1のカウント Database changed mysql> SELECT count(*) FROM administrators WHERE administrators.login_info = '' AND administrators.remarks != ''; +----------+ | count(*) | +----------+ | 1976 | +----------+ 1 row in set (0.00 sec) ●更新対象レコード2のカウント mysql> SELECT count(*) FROM administrators WHERE administrators.remarks IS NULL; +----------+ | count(*) | +----------+ | 95 | +----------+ 1 row in set (0.01 sec) ●更新対象外レコードのカウント mysql> SELECT count(*) FROM administrators WHERE administrators.remarks IS NOT NULL AND WHERE administrators.login_info IS NOT NULL; +----------+ | count(*) | +----------+ | 1 | +----------+ 1 row in set (0.01 sec) ●全件のレコードカウント ... 上記が合算した数になる mysql> SELECT count(*) FROM administrators; +----------+ | count(*) | +----------+ | 2072 | +----------+ 1 row in set (0.00 sec)
マイグレーションの実行
●トランザクションの開始 mysql> BEGIN; Query OK, 0 rows affected (0.00 sec) ●更新1の実行 mysql> UPDATE administrators SET administrators.login_info = administrators.remarks WHERE administrators.login_info = '' AND administrators.remarks != ''; Query OK, 1976 rows affected (0.02 sec) Rows matched: 1976 Changed: 1976 Warnings: 0 ●更新1対象レコードの計測 mysql> SELECT count(*) FROM administrators WHERE administrators.login_info = '' AND administrators.remarks != ''; +----------+ | count(*) | +----------+ | 0 | +----------+ 1 row in set (0.00 sec) → 0となったので正常である。 ●更新2の実行 mysql> UPDATE administrators SET administrators.remarks = null; Query OK, 1977 rows affected (0.02 sec) Rows matched: 2072 Changed: 1977 Warnings: 0 mysql> SELECT count(*) FROM administrators WHERE administrators.remarks IS NULL; +----------+ | count(*) | +----------+ | 0 | +----------+ 1 row in set (0.00 sec) → 0となったので正常である。 ●コミットする // 反映する mysql> COMMIT; Query OK, 0 rows affected (0.02 sec)
サーバを抜ける
mysql> exit Bye