9
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

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

Posted at

一言にすると、
「"特定のデータベースのみ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名を置換ですかね。
(もう少しスマートな方法があれば教えてくださいっ)

9
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?