SQLステートメントとMySQLで一貫性読み取りが機能しない場合
うっかり運用中のサービスでユーザから参照されるテーブルのパーティションを作成してしまい、MySQLの一貫性読み取りが機能しない場合に遭遇したのでまとめ。ついでに SQL ステートメントについてちゃんとドキュメントを読んだ。
一貫性読み取り
トランザクション分離レベルが REPEATABLE READ である場合、同一トランザクション内では最初の SELECT 文を発行した時点でスナップショットが作成され、以降はそのスナップショットを参照するため他のトランザクションによる変更の影響を受けない。
SQL ステートメント
DCL
データ制御言語 (Data Control Language)。権限を管理するための SQL ステートメント。以下のステートメントが含まれる。
- GRANT(権限の付与)
- REVOKE(権限の削除)
DML
データ操作言語 (Data Manipulation Language)。個々のテーブルを操作するための SQL ステートメント。以下のステートメントが含まれる。
- INSERT
- UPDATE
- DELETE
- SELECT .. FOR UPDATE
DDL
データ定義言語 (Data Definition Language)。データベース自体を操作するための SQL ステートメント。以下のステートメントが含まれる。
- CREATE
- ALTER TABLE
- DROP TABLE
- TRUNCATE(DELETE 文とは動作が異なる)
DDL ステートメントは自動的に現在のトランザクションをコミットし、それらをロールバックすることはできない。
一貫性読み取りが機能しない場合
特定の DDL ステートメントでは、一貫性読み取りが機能しない。
DROP TABLE
MySQL が削除されたテーブルを使用できず、そのテーブルは InnoDB によって破棄されるため、一貫性読み取りが機能しない。
ALTER TABLE
元のテーブルの一時コピーが作成され、元のテーブルは一時コピーが構築されるときに削除される。そのため、一貫性読み取りが機能しない。MySQL 5.6.6 時点では、ER_TABLE_DEF_CHANGED エラー「Table definition has changed, please retry transaction」が返される。
パーティション作成は ALTER TABLE なので、以下のような順序で操作が行われるとエラーとなってしまう。