SQL, SEノウハウ

すべらないSQLによる本番マイグレーション

 

 

仕様変更によってremarksにあるデータをlogin_infoに移す本番マイグレーションがありました。

事業部に伝わる秘技

ポイント

  • 作業前バックアップ
    →ヤバくなったら戻せる

  • 立会いによるレビュー

  • トランザクションとカウントを駆使したマイグレーション
    マイグレーションを本番サーバ内のトランザクションを利用することで、
    更新対象を常に確認しながら実行することで精度を確実にする

 

事前準備

  1. ローカル環境で検証しながら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

 

 

Amazonおすすめ

iPad 9世代 2021年最新作

iPad 9世代出たから買い替え。安いぞ!🐱 初めてならiPad。Kindleを外で見るならiPad mini。ほとんどの人には通常のiPadをおすすめします><

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)