mysqldumpの--databasesオプションを勘違いしていた話

一言にすると、
「"特定のデータベースのみdumpする場合、かならず--databasesオプションが必要である"と勘違いしていた」という話です。

失敗例

あるデータベースdb_aのフルダンプを取って、
同じホストにある別のデータベースdb_bにそれをリストアしようとしていました。

# databases以外のオプションは省略して記載しています
mysqldump -uUSER -hHOST -p --databases db_a | gzip -9 > db_a_dump.sql.gz

# 上記のdumpをリストア
gzip -dc db_a_dump.sql.gz | mysql -uUSER -hHOST -p db_b

しかし、これだとdb_bではなく db_aにdumpしたデータが入ります

何が問題だったのか

公式リファレンスを確認してみましょう。
https://dev.mysql.com/doc/refman/5.6/ja/mysqldump-sql-format.html

特定のデータベースのみをダンプするには、コマンド行でそれらを指定し、--databases オプションを使用します。

この記述だけを見て、「複数DBが乗っているサーバでdumpをとる場合は--databasesでDB名を指定しないといけないのだ」と勘違いしていたのです。

--databases引数を指定しなくても、DB名を記載していれば特定のDBのみdumpを取得できます。
では何が違うか?ポイントはここです。

--all-databases または --databases を使用すると、mysqldump は、各データベースのダンプ出力の前に、CREATE DATABASE および USE ステートメントを書き込みます。これにより、ダンプファイルがリロードされると、それが各データベースが存在しなければ作成して、デフォルトのデータベースにするため、データベースの内容がそれらの作成元の同じデータベースにロードされます。

つまり、--databasesを指定して作成したdumpファイルには以下の記述が含まれています。

CREATE DATABASE /*!32312 IF NOT EXISTS*/ `db_a`;

USE `db_a`;

そのため、以下のようにdb_bを指定してもそれが無視されたのです。

gzip -dc db_a_dump.sql.gz | mysql -uUSER -hHOST -p db_b

解決策

dumpを取得するDBとリストア先のDB名が異なる場合は--databases引数をはずしましょう。

mysqldump -uUSER -hHOST -p db_a | gzip -9 > db_a_dump.sql.gz

# db_a_dump.sql.gzには use db_a; の記述が入っていないため、
# db_bにリストアされます。
gzip -dc db_a_dump.sql.gz | mysql -uUSER -hHOST -p db_b

すでに--databases引数付きでdumpを取得してしまって再取得が難しい場合は……展開してsed等でDB名を置換ですかね。
(もう少しスマートな方法があれば教えてくださいっ)

Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account log in.