MySQL道普請便り

第171回MyDumperを使ってみよう[その2]

以前に筆者が担当した第168回に続いて、論理バックアップツール MyDumperについて紹介します。先に第168回 MyDumperを使ってみよう[その1]をご確認ください。第168回の記事と同様に、MyDumperのバージョンはv0.12.1を使用します。

MyDumper実行時の注意点

エクスポート用のmydumperコマンド(以降、mydumper)実行とインポート用のmyloaderコマンド(以降、myloader)を実行する際の注意点を紹介します。

mydumperは開始時にFLUSH TABLE WITH READ LOCKを実行して、書き込みをブロックします。そして、--threadsオプションで指定したスレッドを生成し、同一の静止点を取得するためにそれぞれのスレッドで START TRANSACTION WITH CONSISTENT SNAPSHOTを実行します。その後、UNLOCK TABLESにてロックの解除を行い、エクスポート処理を開始します。

そのため、mydumper開始時に実行中のクエリ(ロングクエリ)があると、最初のFLUSH TABLE WITH READ LOCKがロングクエリが終わるまで待機されます。そうすると、以降のロングクエリと同じテーブルを参照するアプリケーションからのクエリも待機になり、障害になる可能性があります。

mydumperを開始するときは、負荷が低い時間帯やサービスに影響の少ないレプリカなどで実施するほうがよいでしょう。または、--long-query-guardオプションを短い値に設定することで、安全に実行することもできます。このオプションのデフォルト60秒で、60秒以上実行中にクエリがある状態でmydumperを開始するとアボートするようになっています。

MyDumperのパラレル(並列)実行について

mydumperとmyloaderはともに並列で処理できます。どちらのコマンドも--threadsオプションにより並列度を設定します。mydumperによりダンプファイルが複数に分割され保存されます。その分割されたファイル単位でmyloaderが並列に実行する流れになります。

コマンドオプションにより並列実行の動作が異なるので、そちらについて説明します。

mydumper

mydumperコマンドでは、--threadsオプションにて並列度を設定します。どのように並列実行が動作するかはオプションによって異なります。

--rowsオプション

単位は行数で、テーブルの行数単位でファイルを分割します。たとえば--rows 100000と設定した場合は、統計情報を基に主キーを使って100000件の範囲検索で取得し、それぞれダンプファイルを生成します。

$ mydumper --host mysql-hostname1 --port 3306 --user mydumper --ask-password --database db1 --outputdir ./mydumper --verbose 3 --rows 100000 --threads 4
〈略〉
** Message: 12:16:00.290: Thread 2 dumping data for `db1`.`t0` WHERE (`id` >= 611657 AND `id` < 917485) | Remaining jobs: -1
** Message: 12:16:00.290: Thread 1 dumping data for `db1`.`t0` WHERE `id` IS NULL OR (`id` >= 1 AND `id` < 305829) | Remaining jobs: -1
** Message: 12:16:00.290: Thread 4 dumping data for `db1`.`t0` WHERE (`id` >= 305829 AND `id` < 611657) | Remaining jobs: -1
〈略〉

$ ls -ltrh  mydumper/*[0-9].sql
-rw-r--r-- 1 root root 7.3M May  6 12:16 mydumper/db1.t0.00000.sql
-rw-r--r-- 1 root root 7.4M May  6 12:16 mydumper/db1.t0.00001.sql
-rw-r--r-- 1 root root 9.4M May  6 12:16 mydumper/db1.t0.00002.sql

ここではdb1データベースには主キーがidt0テーブルがあります。 --rowsオプションで指定した値とは誤差がありますが、ログから主キーのidを使って範囲検索にて取得しているのがわかります。

注意として、主キーが整数型である必要があります。文字列型などの主キーであると範囲検索できないので、全件取得されます。

--rowsオプションは、範囲を単位に--threadsオプションで指定した並列度で動作します。このオプションのメリットとして、1つのテーブルだけサイズが大きい場合はそのテーブルにおいても並列に処理できます。そのため、エクスポート時間が速くなることがあります。

デメリットとしては、統計情報を基に範囲分割するので、均等にファイルが分散されない恐れがあります。そうすると、myloaderにて非効率のインポート処理が行われる可能性があります。

--chunk-filesizeオプション

単位はMBで、ダンプファイルのサイズ単位でファイルを分割します。たとえば--chunk-filesize 2と指定すると、ファイルサイズが2~3MBで切り替えるようになっています。

$ mydumper --host mysql-hostname1 --port 3306 --user mydumper --ask-password --database db1 --outputdir ./mydumper --verbose 3 --chunk-filesize 2 --threads 4
〈略〉
** Message: 12:08:52.337: Thread 4 dumping data for `db1`.`t0` | Remaining jobs: -3
〈略〉

$ ls -ltrh  mydumper/*[0-9].sql
-rw-r--r-- 1 root root 2.9M May  6 12:08 db1.t0.00000.sql
-rw-r--r-- 1 root root 2.9M May  6 12:08 db1.t0.00001.sql
-rw-r--r-- 1 root root 2.9M May  6 12:08 db1.t0.00002.sql
-rw-r--r-- 1 root root 2.9M May  6 12:08 db1.t0.00003.sql
-rw-r--r-- 1 root root 2.9M May  6 12:08 db1.t0.00004.sql
-rw-r--r-- 1 root root 2.9M May  6 12:08 db1.t0.00005.sql
-rw-r--r-- 1 root root 2.9M May  6 12:08 db1.t0.00006.sql
-rw-r--r-- 1 root root 2.9M May  6 12:08 db1.t0.00007.sql
-rw-r--r-- 1 root root 1.1M May  6 12:08 db1.t0.00008.sql

--chunk-filesizeオプションの場合は、テーブル単位に--threadsオプションで指定した並列度で動作します。

このオプションのメリットとしては、均等にファイルが分割されるのでmyloader実行時に効率良く、並列でインポートが処理されます。デメリットとしては、テーブル単位で並列で動作するために、1つのテーブルのみサイズが大きい場合は並列に処理できないので、エクスポートに時間がかかってしまう恐れがあります。

--rows--chunk-filesizeオプションは片方のみ設定できます。両方指定した場合は--rowsが優先されます。

myloader

myloaderでは、--threadsオプションで指定した並列度はmydumperで出力したダンプファイル単位で実行されます。

その他

オプション

その他知っておくと良いオプションを紹介します。

--no-schemas
テーブル定義などは含まずデータのみエクスポートします。
--no-data
データは含まずテーブル定義のみエクスポートします。
--compress
出力するダンプファイルを圧縮します。デフォルトはOFFです。
--statement-size
作成するINSERT文の1つのサイズ(バイト⁠⁠。デフォルトは1000000です。
--events,--triggers,--routines
それぞれイベント、トリガーとストアドプロシージャを含めてエクスポートします。デフォルトではこれは取得されないので、必須オプションといえます。

レプリケーション情報

mydumper完了時に、--outputdirオプションに指定したディレクトリにmetadataというファイルができます。そこに、SHOW SLAVE STATUSSHOW MASTER STATUSの情報が出力されています。myloaderでリストアした先のMySQLをレプリカとして動作させたいときは、このファイルを見ると良いでしょう。

まとめ

今回は主にMyDumperのオプションについて紹介しました。もし、mysqldumpでバックアップを取得していて時間がかかって困っていたら、MyDumperを検討してみてはどうでしょうか。

おすすめ記事

記事・ニュース一覧