Download - Online schema change_for_mysql_casual
![Page 1: Online schema change_for_mysql_casual](https://reader033.vdocuments.mx/reader033/viewer/2022052623/559b414c1a28abf3538b45e5/html5/thumbnails/1.jpg)
Online Schema Change
in mysql casual
![Page 2: Online schema change_for_mysql_casual](https://reader033.vdocuments.mx/reader033/viewer/2022052623/559b414c1a28abf3538b45e5/html5/thumbnails/2.jpg)
自己紹介
• 名前:林 成敏(はやし なりとし)• ID:nhayashi || n_hayashi• 所属:DeNA
![Page 3: Online schema change_for_mysql_casual](https://reader033.vdocuments.mx/reader033/viewer/2022052623/559b414c1a28abf3538b45e5/html5/thumbnails/3.jpg)
今回の発表
• Online Schema Change• Facebook で使われている(らしい)• 元はPHPで実装• 今回、perl で実装してみました
![Page 4: Online schema change_for_mysql_casual](https://reader033.vdocuments.mx/reader033/viewer/2022052623/559b414c1a28abf3538b45e5/html5/thumbnails/4.jpg)
テーブルスキーマ変更方法
• サービスを止めてメンテナンス中に実行• 新しいテーブルスキーマを別テーブルに用意してアプリで
ダブルインサートしてrenameで切り替える• 諦める
![Page 5: Online schema change_for_mysql_casual](https://reader033.vdocuments.mx/reader033/viewer/2022052623/559b414c1a28abf3538b45e5/html5/thumbnails/5.jpg)
問題点(サービス止めない場合)
• 気軽にALTER文を打つとテーブルロックがかかる• アプリ側の対応が必要で大変• どこまで更新処理をしたか既存データ移行後に全部追う必
要があり整合性の確認が大変
![Page 6: Online schema change_for_mysql_casual](https://reader033.vdocuments.mx/reader033/viewer/2022052623/559b414c1a28abf3538b45e5/html5/thumbnails/6.jpg)
こうできれば幸せ
• サービス止めなくていい• エラー出さずによしなに更新してくれる• アプリ側の対応はなし• 当然、データの整合性は維持
![Page 7: Online schema change_for_mysql_casual](https://reader033.vdocuments.mx/reader033/viewer/2022052623/559b414c1a28abf3538b45e5/html5/thumbnails/7.jpg)
MySQL::ChangeSchemaで幸せになろう
• github にあがってます• URL はのちほど
![Page 8: Online schema change_for_mysql_casual](https://reader033.vdocuments.mx/reader033/viewer/2022052623/559b414c1a28abf3538b45e5/html5/thumbnails/8.jpg)
使い方
use MySQL::ChangeSchema;my $osc = MySQL::ChangeSchema->new(
db => "test",table => "test2",user => "root",pass => "root",
);$osc->connect();$osc->init();$osc->cleanup();eval {
$osc->execute("ALTER TABLE test2 MODIFY hoge varchar(512)");};if ($@) {
print $@."\n";$osc->cleanup;
}
![Page 9: Online schema change_for_mysql_casual](https://reader033.vdocuments.mx/reader033/viewer/2022052623/559b414c1a28abf3538b45e5/html5/thumbnails/9.jpg)
データフロー
![Page 10: Online schema change_for_mysql_casual](https://reader033.vdocuments.mx/reader033/viewer/2022052623/559b414c1a28abf3538b45e5/html5/thumbnails/10.jpg)
前置き
• いくつか条件付きでほぼ正常に動作します。• たぶん適材適所で使うべき
![Page 11: Online schema change_for_mysql_casual](https://reader033.vdocuments.mx/reader033/viewer/2022052623/559b414c1a28abf3538b45e5/html5/thumbnails/11.jpg)
必要条件
• Primary key が定義されている• Foreign key が設定されていない• after insert/delete/update trigger が設定されていない• InnoDB のみサポート• 後方互換のある ALTER文のみ• レプリ構成の場合は カラムの ADD/DROP はレプリが止ま
る• (Disk I/O 等の性能に関しては考慮してません)
![Page 12: Online schema change_for_mysql_casual](https://reader033.vdocuments.mx/reader033/viewer/2022052623/559b414c1a28abf3538b45e5/html5/thumbnails/12.jpg)
実行条件
• MySQL稼働サーバで実行• master/slave それぞれで実行• /var/lib/mysql への書き込み権限が必要• Alter/Lock_tables/Repl_*/Trigger 権限が必要• MySQL::ChangeSchema が入っていることw
![Page 13: Online schema change_for_mysql_casual](https://reader033.vdocuments.mx/reader033/viewer/2022052623/559b414c1a28abf3538b45e5/html5/thumbnails/13.jpg)
実行時のTIPS
• local $MySQL::ChangeSchema::VERBOSE = 1;o 実行SQLすべてが出力されます。
![Page 14: Online schema change_for_mysql_casual](https://reader033.vdocuments.mx/reader033/viewer/2022052623/559b414c1a28abf3538b45e5/html5/thumbnails/14.jpg)
SQL解説 ~ スナップショット
• START TRANSACTION WITH CONSISTENT SNAPSHOT;o セッション内において分離レベルを変更せず、コマンド発行時点のデータ状態を保持。
![Page 15: Online schema change_for_mysql_casual](https://reader033.vdocuments.mx/reader033/viewer/2022052623/559b414c1a28abf3538b45e5/html5/thumbnails/15.jpg)
SQL解説 ~ テーブルロック
• LOCK TABLE t1 WRITE;o t1 テーブルへの更新をロックする。o ロック中の更新処理は Lock Wait 状態になる。
• UNLOCK TABLES;o ロックしているテーブルを開放する。
![Page 16: Online schema change_for_mysql_casual](https://reader033.vdocuments.mx/reader033/viewer/2022052623/559b414c1a28abf3538b45e5/html5/thumbnails/16.jpg)
SQL解説 ~ アプリケーションロック
• SELECT get_lock('osc_lock', 0);o ロックを取得o 0 はロック待ちしない
• SELECT is_free_lock('osc_lock');o ロックが取得できるか確認
• do release_lock('osc_lock');o ロックを開放
![Page 17: Online schema change_for_mysql_casual](https://reader033.vdocuments.mx/reader033/viewer/2022052623/559b414c1a28abf3538b45e5/html5/thumbnails/17.jpg)
SQL解説 ~ バイナリログ、トランザクション
• SET sql_log_bin = 0;o セッション内でバイナリログ出力を抑止
• SET session autocommit = [0|1];o セッション内でトランザクション有効/無効
![Page 18: Online schema change_for_mysql_casual](https://reader033.vdocuments.mx/reader033/viewer/2022052623/559b414c1a28abf3538b45e5/html5/thumbnails/18.jpg)
SQL解説 ~ テーブル作成
• CREATE TABLE t2 LIKE t1;o primary key, index 含めた t1 テーブルと同じスキーマを作成
• CREATE TABLE t2 (id int) AS (SELECT hoge FROM t1 LIMIT 0);o カラムの型のみ 同じスキーマを作成
![Page 19: Online schema change_for_mysql_casual](https://reader033.vdocuments.mx/reader033/viewer/2022052623/559b414c1a28abf3538b45e5/html5/thumbnails/19.jpg)
SQL解説 ~ トリガ AFTER INSERT
• CREATE TRIGGER insert_triggerAFTER INSERT ON t1 FOR EACH ROWINSERT INTO t2 (dml_type, id, hoge)VALUES (1, NEW.id, NEW.hoge);o t1 テーブルへの insert 後に起動o NEW 変数で t1 テーブルへの insert 後の値を参照o t2 テーブルへ dml_type, id, hoge を insert
![Page 20: Online schema change_for_mysql_casual](https://reader033.vdocuments.mx/reader033/viewer/2022052623/559b414c1a28abf3538b45e5/html5/thumbnails/20.jpg)
SQL解説 ~ トリガ AFTER DELETE
• CREATE TRIGGER delete_triggerAFTER DELETE ON t1 FOR EACH ROWINSERT INTO t2 (dml_type, id)VALUES (2, OLD.id);o t1 テーブルへの delete 後に起動o OLD 変数で t1 テーブルへの delete 前の値を参照o t2 テーブルへ dml_type, id を insert
![Page 21: Online schema change_for_mysql_casual](https://reader033.vdocuments.mx/reader033/viewer/2022052623/559b414c1a28abf3538b45e5/html5/thumbnails/21.jpg)
SQL解説 ~ トリガ AFTER UPDATE
• CREATE TRIGGER update_triggerAFTER UPDATE ON t1 FOR EACH ROW IF (NEW.id=OLD.id) THENINSERT INTO t2 (dml_type, id, hoge)VALUES (3, NEW.id, NEW.hoge);
ELSEINSERT INTO t2 (dml_type, id, hoge)VALUES (2, OLD.id, OLD.hoge),
(1, NEW.id, NEW.hoge);END IFo t1テーブルへの update 後に起動o NEW.id=OLD.id なら t2 テーブルへ 1件 inserto NEW.id!=OLD.id ならt2 テーブルへ 2件 insert
![Page 22: Online schema change_for_mysql_casual](https://reader033.vdocuments.mx/reader033/viewer/2022052623/559b414c1a28abf3538b45e5/html5/thumbnails/22.jpg)
SQL解説 ~ ファイル出力
• SELECT id, dml_type FROM t1 ORDER BY idINTO OUTFILE '/var/lib/mysql/test/t1_file';o テーブルデータをファイル出力する。
![Page 23: Online schema change_for_mysql_casual](https://reader033.vdocuments.mx/reader033/viewer/2022052623/559b414c1a28abf3538b45e5/html5/thumbnails/23.jpg)
SQL解説 ~ ファイル入力
• LOAD DATA INFILE '/var/lib/mysql/test/t1_file'INTO TABLE t1 (id, dml_type);o 出力したファイルをテーブルに読み込む。
![Page 24: Online schema change_for_mysql_casual](https://reader033.vdocuments.mx/reader033/viewer/2022052623/559b414c1a28abf3538b45e5/html5/thumbnails/24.jpg)
SQL解説 ~ テンポラリテーブル
• CREATE TEMPORARY TABLE t1 (id int, dml_type int);o セッション内のメモリ上に一時テーブルを作成o 他のセッションからは見えない。o メモリ上にあるので早い
• DROP TEMPORARY TABLE t1;o 一時テーブルを削除
![Page 25: Online schema change_for_mysql_casual](https://reader033.vdocuments.mx/reader033/viewer/2022052623/559b414c1a28abf3538b45e5/html5/thumbnails/25.jpg)
SQL解説 ~ ユーザ定義変数
• SELECT @range_end := id, hoge FROM t1ORDER BY id LIMIT 100;o @range_end -> 100
• SELECT @range_end INTO @range_start;o @range_end -> 100, @range_start -> 100
• SELECT @range_end := id, hoge FROM t1WHERE (id > @range_start)ORDER BY id LIMIT 100;o @range_end -> 200, @range_start -> 100
• SELECT @range_end INTO @range_start; o @range_end -> 200, @range_start -> 200
• 「:=」を使うと参照と同時にユーザ定義変数を更新
![Page 26: Online schema change_for_mysql_casual](https://reader033.vdocuments.mx/reader033/viewer/2022052623/559b414c1a28abf3538b45e5/html5/thumbnails/26.jpg)
SQL解説 ~ テーブルデータコピー
• INSERT INTO t2 (id, dml_type)SELECT id, dml_type FROM t1;o t1テーブルのデータを t2 テーブルに insert
![Page 27: Online schema change_for_mysql_casual](https://reader033.vdocuments.mx/reader033/viewer/2022052623/559b414c1a28abf3538b45e5/html5/thumbnails/27.jpg)
SQL解説 ~ リネームテーブル
• RENAME TABLE old TO tmp, new to old;o old テーブルを new テーブルに置き換える。o ロックされているテーブルがあると実行できないo アクティブなトランザクションがあると実行できないo 名前の変更途中でエラーになるとロールバックする
![Page 28: Online schema change_for_mysql_casual](https://reader033.vdocuments.mx/reader033/viewer/2022052623/559b414c1a28abf3538b45e5/html5/thumbnails/28.jpg)
稼働実績
• なしw• (手元で試した限りではまともに動いてます)
![Page 29: Online schema change_for_mysql_casual](https://reader033.vdocuments.mx/reader033/viewer/2022052623/559b414c1a28abf3538b45e5/html5/thumbnails/29.jpg)
今後の課題
• 使い方が面倒(スクリプト化)• 実行時オプション指定ができるようにする
o Lock指定やログ出力など• lock table しなくてもいい方法を考える
![Page 30: Online schema change_for_mysql_casual](https://reader033.vdocuments.mx/reader033/viewer/2022052623/559b414c1a28abf3538b45e5/html5/thumbnails/30.jpg)
免責事項
• 本プログラムの使用は各個人の責任において使用してください。
• 万が一、サービス上のデータ等が消滅・改ざんされたとしても当方は一切の責任を負いません。
![Page 31: Online schema change_for_mysql_casual](https://reader033.vdocuments.mx/reader033/viewer/2022052623/559b414c1a28abf3538b45e5/html5/thumbnails/31.jpg)
募集
• 一緒に開発してくれる方、募集してます。https://github.com/nhayashi/p5-mysql-changeschema
![Page 32: Online schema change_for_mysql_casual](https://reader033.vdocuments.mx/reader033/viewer/2022052623/559b414c1a28abf3538b45e5/html5/thumbnails/32.jpg)
謝辞
ご清聴ありがとうございました m(_ _)m