MySQLのクライアントプログラム
MySQLのパッケージにはMySQLサーバーであるmysqldの他に、
今回は、mysqldumpコマンドについて説明します。
デモ用の環境はCentOS 7.
$ yum install https://dev.mysql.com/get/mysql57-community-release-el7-11.noarch.rpm $ yum install mysql-community-server $ rpm -qa | grep mysql mysql57-community-release-el7-11.noarch mysql-community-common-5.7.20-1.el7.x86_64 mysql-community-client-5.7.20-1.el7.x86_64 mysql-community-server-5.7.20-1.el7.x86_64 mysql-community-libs-5.7.20-1.el7.x86_64
mysqldump
mysqldumpはMySQLの論理バックアップを取得するためのプログラムです。簡単な使い方は第15回 mysqldumpを使ってバックアップするにまとまっていますので、
また、
mysqldumpの論理バックアップ
mysqldumpの論理バックアップはSELECT * FROM ..ステートメント)INSERT INTO ..ステートメントまたはLOAD DATA,LOAD XMLなどのステートメント)
このことを知っておくと、
--single-transactionオプションと--lock-all-tablesオプション
mysqldumpのオプションのうちもっとも大切なものはこの2つです。この2つは同時に指定することができませんのでどちらかを選択して使用することになります。 デフォルトではどちらもOFFです。
ドキュメント上の記載は以下のURLを参照してください。
--single-transactionがONの場合
--single-transactionオプションが有効な場合、mysqldumpはバックアップを取得するために実行する全てのSELECT * FROM ..ステートメントを1つのトランザクションとして実行します。具体的には概ね以下のようなSQLが実行されることになります。
mysql> FLUSH TABLES WITH READ LOCK; データベース全体に読み取りロックを設定する mysql> SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ; トランザクション分離レベルをREPEATABLE READに変更 mysql> SHOW CREATE TABLE ..; 1つめのテーブルの定義情報を読み取る mysql> SELECT * FROM ..; 1テーブルずつデータを読み取る mysql> SHOW CREATE TABLE ..; 次のテーブルへ mysql> SELECT * FROM ..; 次のテーブルへ .. mysql> ROLLBACK; トランザクションを終了
トランザクション分離レベルにREPEATABLE READを指定することで、
これにより、--single-transactionオプションではデータの一貫性を保つことができません。後述の--lock-all-tablesオプションを利用することになります。
MySQL 5.--single-transactionを利用した場合ではそれらのテーブルとデータの整合性は保証することができません。が、mysqldumpでバックアップを取得している最中にmysqlスキーマが更新されるCREATE USERで新しいユーザーを作成する、GRANTでユーザーに権限を割り当てる、CREATE PROCEDUREでストアドプロシージャを作成する、INSTALL PLUGINでプラグインをインストールする…など)
--lock-all-tablesがONの場合
--lock-all-tablesオプションが有効な場合、mysqldumpはバックアップ実行中にデータベース全体に読み取りロックをかけ続けます。先程と同じようにSQLで例示すると以下のようになります。
mysql> FLUSH TABLES WITH READ LOCK; データベース全体に読み取りロックを設定する mysql> SHOW CREATE TABLE ..; 1つめのテーブルの定義情報を読み取る mysql> SELECT * FROM ..; 1テーブルずつデータを読み取る mysql> SHOW CREATE TABLE ..; 次のテーブルへ mysql> SELECT * FROM ..; 次のテーブルへ .. /* 読み取りロックはバックアップ終了時のコネクション切断で暗黙に解除される */
mysqldumpの実行中に全ての書き込みをブロックすることで、mysqldumpの実行中に全ての書き込みをブロックしない限りはトランザクション非対応のストレージエンジン間でデータの整合性を保証することは できません 。
しかしながら、mysqldumpを実行することになります。
--single-transaction,--lock-all-tablesがいずれもOFFの場合
これら--single-transactionおよび--lock-all-tablesがいずれもOFFの場合はどうなるでしょうか。非常に残念なことに、
mysql> LOCK TABLES .. READ; 同一スキーマ内の全てのテーブルに読み取りロックをかける mysql> SHOW CREATE TABLE ..; 1つめのテーブルの定義情報を読み取る mysql> SELECT * FROM ..; 1テーブルずつデータを読み取る mysql> SHOW CREATE TABLE ..; 次のテーブルへ mysql> SELECT * FROM ..; 次のテーブルへ .. mysql> UNLOCK TABLES; スキーマ内の読み取りロックを解除する mysql> LOCK TABLES .. READ; 次のスキーマの全てのテーブルに読み取りロックをかける ..
スキーマ単位でテーブルロックを取得して、
残念ながらMySQL 5.--single-transactionまたは--lock-all-tablesを明示的に指定しなかった場合はこの動作となります。
注意事項
「--single-transactionオプションを指定した場合、FLUSH TABLES WITH READ LOCKが一瞬だけ走る」mysqldumpでバックアップを取得する多くの場合、FLUSH TABLES WITH READ LOCKが走ります)。
ただしこれは--single-transactionオプションに起因するものではなく、--master-dataを指定していると思います)。これらを指定しない場合、--single-transactionではFLUSH TABLES WITH READ LOCKは実行されません。
これらのオプションと--single-transactionを同時に指定することで、FLUSH TABLES WITH READ LOCK後にトランザクションの開始およびバイナリーログの操作が終われば、UNLOCK TABLES)」されます。ロックを解放するためのステートメントが--single-transactionオプションに紐付いているため、--single-transactionが指定されていない場合は、FLUSH TABLES WITH READ LOCKはmysqldumpが終了するまで解放されません。--lock-all-tablesを有効にしている状態ではもともとバックアップ終了までロックが継続することを期待しているので問題ありませんが、
まとめ
mysqldumpはMySQLの論理バックアップを取るためのプログラムですが、--single-transactionまたは--lock-all-tablesを指定しない場合、
mysqlスキーマを除いた全てのテーブルがInnoDBストレージエンジンである場合は--single-transactionオプションを、--lock-all-tablesオプションを利用する必要があります。
--single-transactionにおいてFLUSH TABLES WITH READ LOCKが実行されるのは--master-dataまたは--flush-logsが同時に指定されている場合です。
