この記事では、mysqlpump
コマンドの使い方を見てみようと思います。
mysqlpump
は論理バックアップを取得するツールです(実ファイルではなく、データをSQLとしてバックアップするという意味)。このツールは MySQL5.7.8 で追加され、データベースをダンプする、もしくはダンプしたファイルを別のDBサーバに転送/インポートする目的に使用できます(インポート先はMySQLに限定されません)。
使用方法はmysqldump
と基本的に同じですが、いくつか新しい機能が含まれています。多くのオプションが変わらず使用できますが、mysqldump
との互換性に縛られることがないよう、一から開発されています。
主な新しい機能
- ダンプ処理を高速化するために、データベースに含まれるスキーマおよびテーブルに対して並列処理が可能です
--include-*
や--exclude-*
といったオプションを使用することで、dumpの対象を選択することができます(テーブル、ストアドプログラム、ユーザアカウント情報など)- ユーザアカウント情報に関して、MySQLのシステムテーブルに対するINSERTではなく、
CREATE USER
およびGRANT
としてダンプすることができます(※1) --compress
オプションを使えば、クライアント・サーバ間で送信されるデータを圧縮することが出来ます。ネットワークの帯域、転送時間の節約になるため、リモートバックアップにおいて非常に便利な機能です。また、--compress-output
オプションで出力されたファイルの圧縮も可能です。ZLIB および LZ4 の圧縮アルゴリズムをサポートしています。- 処理の進捗状況を表示する機能があります。この機能はダンプ処理の状況を確認するのにとても便利です。あなたはダンプ対象のレコードの合計と、どれくらい完了しているかを確認できます。同時に、完了するまでの推定時間も表示されます。
- ロード時間を短縮するため、データのINSERTが完了してからInnoDBのセカンダリインデックスを作成します。
※1 訳注:従来のmysqldump
では、ユーザアカウント情報をdumpファイルに含めたい場合、mysql.user テーブルのINSERT文として出力する必要がありました
Exclude/Include オプション
この機能によって、ダンプ対象となるデータの選択や、必要なデータのフィルタリングがより簡単になります。ダンプしたいデータ(データべース、テーブル、トリガー、イベント、ストアドルーチン、ユーザ)を選択でき、ファイルサイズや実行時間、別ホストへの転送時間の節約につながります。
なお、相互に排他的なオプションも存在することに注意してください。例えば、--all-databases
オプションを使用している場合は、--exclude-databases
オプションが効果を持たなくなります。デフォルトの挙動として、mysqlpump
は--include-databases
オプションで明示的に指定されない限りは、以下のデータベースをダンプしません。
INFORMATION_SCHEMA
, performance_schema
, ndbinfo
, sys
これらのオプションの値は、カンマ区切りのリストで指定されている必要があります。exclude/include系のオプションで、“%”を使用するとワイルドカードとして機能します。例として、--include-databases=t%,p%
というオプションを使用すれば、" t " または " p " で始まる全データベースをダンプすることができます。
ユーザ、ストアドルーチン、トリガー、イベントに関しても、mysqlpump
には同様の--exclude-*
/ --include-*
オプションが用意されており、使い方も同じです。ただし、いくつか注意点もあります。
- トリガーは、デフォルトでダンプ対象に含まれます。その上で、
--include-triggers
/--exclude-triggers
オプションを使って、ダンプ対象をフィルタリング出来ます。 - ストアドルーチンとイベントは、デフォルトではダンプ対象に含まれません。そのため、
--routines
/--events
オプション、もしくは各--include
/--exclude
オプションを使用する必要があります。 - 同じ名前のストアドプロシージャとストアドファンクションが存在した場合、include/exclude の判定も両方に対して行われる点に注意してください
並列処理機能
この機能によって複数のデータベース、更にはその中の複数のテーブルを並列で処理することができます。mysqlpump
はデフォルトで、2スレッドで1つの処理キューを使用します。スレッドの数は、--default-parallelism
オプションで増やすことができます。
追加のキューを使用しない限りは、全てのデータベース・テーブルは、デフォルトのキューのみを使用します。
キューを追加する場合は、--parallel-schemas
オプションを使用します。つまり、「キューに対するスレッド数」と「キュー処理のためのデータベースのサブセット」の2つのパラメータが存在します。
例として、以下のようなコマンドが実行できます。
mysqlpump --include-databases=a,b,c,d,e,f,g,h --default-parallelism=3 --parallel-schemas=4:a,b
"c, d, e, f, g, h" のスキーマはデフォルトキュー(3スレッド使用)で処理されます。また、"a, b" のスキーマは別のキュー(4スレッド使用)で処理されます。なお、データべース名はカンマ区切りで書かれていなければいけません。
$ mysqlpump --parallel-schemas=4:example1,example2,example3 --parallel-schemas=3:example4,example5 > examples.sql
Dump progress: 0/1 tables, 250/261184 rows
Dump progress: 24/30 tables, 1204891/17893833 rows
Dump progress: 29/30 tables, 1755611/17893833 rows
Dump progress: 29/30 tables, 2309111/17893833 rows
...
Dump completed in 42424 milliseconds
ユーザアカウント
ユーザアカウント情報も、このツールを使って取得することができます。以下は、Percona Toolkitに含まれるpt-show-grants
と mysqlpump
の違いに着目した比較になります。
デフォルトでは、mysqlpump
はユーザアカウントの定義情報を取得しません(たとえmysqlデータベースがダンプ対象であっても)。ユーザアカウント情報をダンプに含めたい場合は、--users
オプションを指定する必要があります。
以下は、ユーザアカウント情報のみをファイルに出力した場合の mysqlpump
の例となります。
$ mysqlpump --exclude-databases=% --exclude-triggers=% --users
-- Dump created by MySQL dump utility, version: 5.7.8-rc, linux-glibc2.5 (x86_64)
-- Dump start time: Thu Aug 27 17:10:10 2015
-- Server version: 5.7.8
SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0;
SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;
SET @OLD_TIME_ZONE=@@TIME_ZONE;
SET TIME_ZONE='+00:00';
SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT;
SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS;
SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION;
SET NAMES utf8;
CREATE USER 'msandbox'@'127.%' IDENTIFIED WITH 'mysql_native_password' AS '*6C387FC3893DBA1E3BA155E74754DA6682D04747' REQUIRE NONE PASSWORD EXPIRE DEFAULT ACCOUNT UNLOCK;
GRANT ALL PRIVILEGES ON *.* TO 'msandbox'@'127.%';
CREATE USER 'msandbox_ro'@'127.%' IDENTIFIED WITH 'mysql_native_password' AS '*6C387FC3893DBA1E3BA155E74754DA6682D04747' REQUIRE NONE PASSWORD EXPIRE DEFAULT ACCOUNT UNLOCK;
GRANT SELECT, EXECUTE ON *.* TO 'msandbox_ro'@'127.%';
CREATE USER 'msandbox_rw'@'127.%' IDENTIFIED WITH 'mysql_native_password' AS '*6C387FC3893DBA1E3BA155E74754DA6682D04747' REQUIRE NONE PASSWORD EXPIRE DEFAULT ACCOUNT UNLOCK;
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER, SHOW DATABASES, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE ON *.* TO 'msandbox_rw'@'127.%';
CREATE USER 'rsandbox'@'127.%' IDENTIFIED WITH 'mysql_native_password' AS '*B07EB15A2E7BD9620DAE47B194D5B9DBA14377AD' REQUIRE NONE PASSWORD EXPIRE DEFAULT ACCOUNT UNLOCK;
GRANT REPLICATION SLAVE ON *.* TO 'rsandbox'@'127.%';
CREATE USER 'furrywall'@'localhost' IDENTIFIED WITH 'mysql_native_password' AS '*AB8D50A9E3B8D1F3ACE85C54736B5BF472B44539' REQUIRE NONE PASSWORD EXPIRE DEFAULT ACCOUNT LOCK;
GRANT USAGE ON *.* TO 'furrywall'@'localhost';
CREATE USER 'msandbox'@'localhost' IDENTIFIED WITH 'mysql_native_password' AS '*6C387FC3893DBA1E3BA155E74754DA6682D04747' REQUIRE NONE PASSWORD EXPIRE DEFAULT ACCOUNT UNLOCK;
GRANT ALL PRIVILEGES ON *.* TO 'msandbox'@'localhost';
CREATE USER 'msandbox_ro'@'localhost' IDENTIFIED WITH 'mysql_native_password' AS '*6C387FC3893DBA1E3BA155E74754DA6682D04747' REQUIRE NONE PASSWORD EXPIRE DEFAULT ACCOUNT UNLOCK;
GRANT SELECT, EXECUTE ON *.* TO 'msandbox_ro'@'localhost';
CREATE USER 'msandbox_rw'@'localhost' IDENTIFIED WITH 'mysql_native_password' AS '*6C387FC3893DBA1E3BA155E74754DA6682D04747' REQUIRE NONE PASSWORD EXPIRE DEFAULT ACCOUNT UNLOCK;
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER, SHOW DATABASES, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE ON *.* TO 'msandbox_rw'@'localhost';
CREATE USER 'root'@'localhost' IDENTIFIED WITH 'mysql_native_password' AS '*6C387FC3893DBA1E3BA155E74754DA6682D04747' REQUIRE NONE PASSWORD EXPIRE DEFAULT ACCOUNT UNLOCK;
GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION;
CREATE USER 'testuser'@'localhost' IDENTIFIED WITH 'mysql_native_password' AS '*6E543F385210D9BD42A4FDB4BB23FD2C31C95462' REQUIRE NONE PASSWORD EXPIRE INTERVAL 30 DAY ACCOUNT UNLOCK;
GRANT USAGE ON *.* TO 'testuser'@'localhost';
SET TIME_ZONE=@OLD_TIME_ZONE;
SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT;
SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS;
SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION;
SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;
SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;
-- Dump end time: Thu Aug 27 17:10:10 2015
Dump completed in 823 milliseconds
ご覧の通り、上の出力からmysqlpump
がセッション内で、タイムゾーンや文字セットとして既知の値を使用していることが分かります。これらの設定はユーザへの影響はありませんが、リストア先でのダンプファイルのリストア処理を正確に行うことができるようにしてくれます。
Percona Toolkit のpt-show-grants
と比較すると、mysqlpump
は CREATE USER
文を取得していることが分かります。このステートメントは、特にsql_mode
変数の "NO_AUTO_CREATE_USERS"が設定されてる場合には、ユーザを再作成するための正しい(推奨される)方法です。もし、このsql_modeの設定が有効だと、pt-show-grants
は使えなくなります。
以下は、pt-show-grants
の例となります。
$ pt-show-grants --host 127.0.0.1 --port 5708 --user msandbox --ask-pass
Enter password:
-- Grants dumped by pt-show-grants
-- Dumped from server 127.0.0.1 via TCP/IP, MySQL 5.7.8-rc at 2015-08-27 17:06:52
-- Grants for 'furrywall'@'localhost'
GRANT USAGE ON *.* TO 'furrywall'@'localhost';
-- Grants for 'msandbox'@'127.%'
GRANT ALL PRIVILEGES ON *.* TO 'msandbox'@'127.%';
-- Grants for 'msandbox'@'localhost'
GRANT ALL PRIVILEGES ON *.* TO 'msandbox'@'localhost';
-- Grants for 'msandbox_ro'@'127.%'
GRANT EXECUTE, SELECT ON *.* TO 'msandbox_ro'@'127.%';
-- Grants for 'msandbox_ro'@'localhost'
GRANT EXECUTE, SELECT ON *.* TO 'msandbox_ro'@'localhost';
-- Grants for 'msandbox_rw'@'127.%'
GRANT ALTER, CREATE, CREATE TEMPORARY TABLES, DELETE, DROP, EXECUTE, INDEX, INSERT, LOCK TABLES, SELECT, SHOW DATABASES, UPDATE ON *.* TO 'msandbox_rw'@'127.%';
-- Grants for 'msandbox_rw'@'localhost'
GRANT ALTER, CREATE, CREATE TEMPORARY TABLES, DELETE, DROP, EXECUTE, INDEX, INSERT, LOCK TABLES, SELECT, SHOW DATABASES, UPDATE ON *.* TO 'msandbox_rw'@'localhost';
-- Grants for 'root'@'localhost'
GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION;
GRANT PROXY ON ''@'' TO 'root'@'localhost' WITH GRANT OPTION;
-- Grants for 'rsandbox'@'127.%'
GRANT REPLICATION SLAVE ON *.* TO 'rsandbox'@'127.%';
-- Grants for 'testuser'@'localhost'
GRANT USAGE ON *.* TO 'testuser'@'localhost';
その他、補足事項
mysqldump
との違いの一つに、mysqlpump
にはデフォルトで CREATE DATABASE
ステートメントが含まれていることがあります(--no-create-db
オプションを指定した場合を除く)。
これにより、ダンプのプロセスに重要な違いが生じます。それは、CREATE TABLE
ステートメントにデータベース名が含まれるようになる点です。そのため、あえて重複したテーブルを作成するために mysqlpump
を使うと問題が起きてしまいます。