More Related Content
PDF
RとSQLiteによるオミックス解析の促進
弘毅 露崎
PDF
リナックスに置ける様々なリモートエキスプロイト手法 by スクハー・リー
CODE BLUE
Similar to Online schema change in mysql casual #1(2010/12/11) (20)
PDF
データベース03 - SQL(CREATE, INSERT, DELETE, UPDATEなど)
Kenta Oku
PDF
データベース06 - SQL(VIEW, ALTER, GRANTなど)
Kenta Oku
PPT
20170329 D3 DBAが夜間メンテをしなくなった日 発表資料
dcubeio
Online schema change in mysql casual #1(2010/12/11)8. 使い方 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; } 11. 必要条件 Primary key が定義されている Foreign key が設定されていない after insert/delete/update trigger が設定されていない InnoDB のみサポート 後方互換のある ALTER 文のみ レプリ構成の場合は カラムの ADD/DROP はレプリが止まる ( Disk I/O 等の性能に関しては考慮してません) 12. 実行条件 MySQL 稼働サーバで実行 master/slave それぞれで実行 /var/lib/mysql への書き込み権限が必要 Alter/Lock_tables/Repl_*/Trigger 権限が必要 MySQL::ChangeSchema が入っていること w 14. SQL 解説 ~ スナップショット START TRANSACTION WITH CONSISTENT SNAPSHOT; セッション内において分離レベルを変更せず、 コマンド発行時点のデータ状態を保持。 15. SQL 解説 ~ テーブルロック LOCK TABLE t1 WRITE; t1 テーブルへの更新をロックする。 ロック中の更新処理は Lock Wait 状態になる。 UNLOCK TABLES; ロックしているテーブルを開放する。 16. SQL 解説 ~ アプリケーションロック SELECT get_lock('osc_lock', 0); ロックを取得 0 はロック待ちしない SELECT is_free_lock('osc_lock'); ロックが取得できるか確認 do release_lock('osc_lock'); ロックを開放 17. SQL 解説 ~ バイナリログ、トランザクション SET sql_log_bin = 0; セッション内でバイナリログ出力を抑止 SET session autocommit = [0|1]; セッション内でトランザクション有効 / 無効 18. SQL 解説 ~ テーブル作成 CREATE TABLE t2 LIKE t1; primary key, index 含めた t1 テーブルと同じスキーマを作成 CREATE TABLE t2 (id int) AS (SELECT hoge FROM t1 LIMIT 0); カラムの型のみ 同じスキーマを作成 19. SQL 解説 ~ トリガ AFTER INSERT CREATE TRIGGER insert_trigger AFTER INSERT ON t1 FOR EACH ROW INSERT INTO t2 (dml_type, id, hoge) VALUES (1, NEW.id, NEW.hoge); t1 テーブルへの insert 後に起動 NEW 変数で t1 テーブルへの insert 後の値を参照 t2 テーブルへ dml_type, id, hoge を insert 20. SQL 解説 ~ トリガ AFTER DELETE CREATE TRIGGER delete_trigger AFTER DELETE ON t1 FOR EACH ROW INSERT INTO t2 (dml_type, id) VALUES (2, OLD.id); t1 テーブルへの delete 後に起動 OLD 変数で t1 テーブルへの delete 前の値を参照 t2 テーブルへ dml_type, id を insert 21. SQL 解説 ~ トリガ AFTER UPDATE CREATE TRIGGER update_trigger AFTER UPDATE ON t1 FOR EACH ROW IF (NEW.id=OLD.id) THEN INSERT INTO t2 (dml_type, id, hoge) VALUES (3, NEW.id, NEW.hoge); ELSE INSERT INTO t2 (dml_type, id, hoge) VALUES (2, OLD.id, OLD.hoge), (1, NEW.id, NEW.hoge); END IF t1 テーブルへの update 後に起動 NEW.id=OLD.id なら t2 テーブルへ 1 件 insert NEW.id!=OLD.id なら t2 テーブルへ 2 件 insert 22. SQL 解説 ~ ファイル出力 SELECT id, dml_type FROM t1 ORDER BY id INTO OUTFILE '/var/lib/mysql/test/t1_file'; テーブルデータをファイル出力する。 23. SQL 解説 ~ ファイル入力 LOAD DATA INFILE '/var/lib/mysql/test/t1_file' INTO TABLE t1 (id, dml_type); 出力したファイルをテーブルに読み込む。 24. SQL 解説 ~ テンポラリテーブル CREATE TEMPORARY TABLE t1 (id int, dml_type int); セッション内のメモリ上に一時テーブルを作成 他のセッションからは見えない。 メモリ上にあるので早い DROP TEMPORARY TABLE t1; 一時テーブルを削除 25. SQL 解説 ~ ユーザ定義変数 SELECT @range_end := id, hoge FROM t1 ORDER BY id LIMIT 100; @range_end -> 100 SELECT @range_end INTO @range_start; @range_end -> 100, @range_start -> 100 SELECT @range_end := id, hoge FROM t1 WHERE (id > @range_start) ORDER BY id LIMIT 100; @range_end -> 200, @range_start -> 100 SELECT @range_end INTO @range_start; @range_end -> 200, @range_start -> 200 「 := 」を使うと参照と同時にユーザ定義変数を更新 26. SQL 解説 ~ テーブルデータコピー INSERT INTO t2 (id, dml_type) SELECT id, dml_type FROM t1; t1 テーブルのデータを t2 テーブルに insert 27. SQL 解説 ~ リネームテーブル RENAME TABLE old TO tmp, new to old; old テーブルを new テーブルに置き換える。 ロックされているテーブルがあると実行できない アクティブなトランザクションがあると実行できない 名前の変更途中でエラーになるとロールバックする 31. 募集 一緒に開発してくれる方、募集してます。 https://github.com/nhayashi/p5-mysql-changeschema Editor's Notes #17: MySQL::ChangeSchema で使っている SQL を抜粋して説明します。