皆さんMySQL使ってますか?いきなりですが今回はdumpについてお伝えしていきます。dumpというと、クエリを学んでいる真っ最中の方からは縁遠く、もしかしたらはじめて聞いた、なんて方もいるかも知れません。
ですが、データベースをdumpしておくことは長い目でみたときにとても重要な作業なのです。そんな縁の下の力持ちなdumpについて、さっくりと学んでいきましょう!
dumpとはなんなのか
では、まずはdumpとはなにかを理解するところから始めましょう。冒頭からdump、dumpと言ってきましたが、dump(ダンプ)とは、要するにバックアップのことです。
バックアップといえば、皆さんもPCやスマホで馴染みがあるのではないでしょうか。バックアップとは、データを別のところに保管しておくことを言います。そして、なにかアクシデントが起こったときにそのバックアップからデータを復元するわけですね。
ちなみにこの復元作業をリストアといいます。PCやスマホでも不測の事態に備えてバックアップは重要ですが、データベースではその重要性がより高いのです。
データベースは様々なデータを保管しておく場所です。そのデータは一度無くなってしまえば二度と元に戻せないような重要なものかもしれません。
また、多くの人にとって重要なものかもしれません。つまり、PCやスマホと違って、不測の事態が起こったときに与える影響の範囲が非常に大きく、深刻なものになりかねないので、データベースのdumpは重要なのです。
また、データベースは常に稼働し続けていることが求められる場合もあります。このようなデータベースでは、仮にアクシデントでデータベースが1つ使えなくなったとしても、予備のデータベースを動かしながら、元のデータベースを全速力で復旧していきます。
その際に使うのが、今回紹介するdumpデータなのです。なんとなくでもdumpデータの重要性を感じることができましたか?
基本的なdumpの方法
この章では基本的なdumpの方法を紹介していきます。方法の紹介に入る前に注意点を1つだけ。MySQLのdumpには「mysqldump」という専用のツールを使います。
このツールはMySQLの外側で動かすツールです。どういうことかというと、多くの方はMySQLを使う時、MySQLサーバに次のようなコマンドでログインしているはずです。
mysql -u root -p
Windowsの場合はMySQL Command Line Clientを使ってログインしている方も多いかもしれません。mysqldumpはMySQLのログイン後に動かすツールではありません。ログインコマンドの前、コマンドラインの段階で利用するツールです。
そのため、MySQLの文末につけるデリミタ(;)も不要です。お気をつけください。それではあらためて、基本的なdump方法を見ていきましょう。先程登場したmysqldumpを使っていきます。
書式
MySQLへのログインコマンドに似ていますね。これを実際に動かしてみましょう。今回は手元にあったcase_dbというデータベースをdumpします。データベースの構造は次のようになります。
+------------------------+ | Tables_in_case_db | +------------------------+ | name_dept_gender_score | +------------------------+ 1 row in set (0.01 sec) +----+--------------------+------+--------+-------+ | id | name | dept | gender | score | +----+--------------------+------+--------+-------+ | 1 | タロー | 1 | 1 | 95 | | 2 | ジロー | 2 | 1 | 50 | | 3 | サブロー | 1 | 1 | 75 | | 4 | ハナコ | 3 | 2 | 100 | | 5 | ヨシコ | 1 | 2 | 25 | | 6 | ナンシー | 2 | 2 | 60 | | 7 | カルボナーラ | 3 | 3 | 85 | +----+--------------------+------+--------+-------+ 7 rows in set (0.00 sec)
dumpのためのコマンドは次のようになります。
mysqldump -u root -p case_db > dump.txt
実行結果
-- MySQL dump 10.13 Distrib 8.0.13, for macos10.14 (x86_64) -- -- Host: localhost Database: case_db -- ------------------------------------------------------ -- Server version 8.0.13 …… DROP TABLE IF EXISTS `name_dept_gender_score`; /*!40101 SET @saved_cs_client = @@character_set_client */; SET character_set_client = utf8mb4 ; CREATE TABLE `name_dept_gender_score` ( `id` int(11) NOT NULL AUTO_INCREMENT, …… LOCK TABLES `name_dept_gender_score` WRITE; /*!40000 ALTER TABLE `name_dept_gender_score` DISABLE KEYS */; INSERT INTO `name_dept_gender_score` VALUES (1,'タロー',1,1,95),(2,'ジロー',2,1,50), ……
出力されたdumpファイルの中身は普通のテキストファイルなので、テキストエディタで見ることができます。色々と情報が記入してあり、読み辛いですが、よくよくみると、CREATE TABLEやINSERT INTOといった見慣れたSQL文を見つけることができます。
ここで種明かしをすると、dumpファイルとは元のデータベースにあったテーブルを作り直すためのコマンドが記載してあるファイルのことだったのです。
dumpは指定されたデータベース内のテーブルと同じものを作るためのコマンドをdumpファイルに出力する行為、とも言えますね。
そのため、テーブル数が多ければCREATE TABLEの数が膨大になりますし、レコードの数が多ければINSERT INTOのデータがすごいことになることは想像できるでしょう。
実際、1GB程度のデータベースのdumpであればそこまで時間はかかりませんが、20,30GB程度になってくると、30分程度はかかるようになってきます。そこで発生するのが整合性の問題です。
つまり、常時運用しているデータベースではdumpをはじめたタイミングとdumpを終了したタイミングではデータベースの内容が書き換わってしまっていることがあるため、dumpファイルとデータベースで不整合が生じる可能性があるのです。
これを防ぐには、手っ取り早い方法としてdumpを行っている間データベースをロックしてしまう、つまり、内容の変更を許さない状態にする、というものがあります。
ですが、これは常時運用しているデータベースではあまりに乱暴です。dumpの間、データベースが実質使用不能なのですから、問題しかありません。ではどうするかというと、簡単な解決策の一つに–single-transactionオプションの利用があります。
これはトランザクションを利用することで、データの整合性を保証してくれるオプションです。とても便利なものなので、dumpを使う際はぜひ利用しましょう。mysqldumpには他にも様々なオプション、利用方法があります。
テーブル単体をバックアップしたり、MySQL管理下にある全てのデータベースをバックアップしたり、dumpのメモリ消費を抑えるオプションや特定のデータベースをdumpしないオプションもあります。
非常に細かくオプションや利用法が設定されているので、細かなバックアップ方法が知りたい方はぜひ公式リファレンスを参照しましょう。
MySQL :: MySQL 5.6 リファレンスマニュアル :: 4.5.4 mysqldump — データベースバックアッププログラム
ファイルをリストアする方法
それでは、最後にdumpしたファイルをリストアする方法を紹介します。dumpファイルを見てもらうとわかりますが、dumpファイルにはデータベースを作るクエリは含まれていません。
データベースはユーザー側で用意してあげて、その中身をリストアしていきます。データベースの準備は忘れないようにしましょう。この性質のため、もとのデータベース名と新しくリストアするデータベース名が同じである必要はありません。
実際にデータベースをリストアしながら確認してみましょう。まず、MySQL内部でリストアするためのデータベースを作っておきます。
CREATE DATABASE db3;
MySQLからログアウトして、そこからリストアを行っていきます。リストアに使うのは、いつも利用しているmysqlです。
リストアの書式
先程つくったdumpファイルからリストアしてみます。
mysql -u root -p db3 < dump.txt
上手くいった場合、何も表示は出ません。実際にリストアされているのか、MySQLにログインして確かめてみましょう。
+------------------------+ | Tables_in_db3 | +------------------------+ | name_dept_gender_score | +------------------------+ 1 row in set (0.01 sec) +----+--------------------+------+--------+-------+ | id | name | dept | gender | score | +----+--------------------+------+--------+-------+ | 1 | タロー | 1 | 1 | 95 | | 2 | ジロー | 2 | 1 | 50 | | 3 | サブロー | 1 | 1 | 75 | | 4 | ハナコ | 3 | 2 | 100 | | 5 | ヨシコ | 1 | 2 | 25 | | 6 | ナンシー | 2 | 2 | 60 | | 7 | カルボナーラ | 3 | 3 | 85 | +----+--------------------+------+--------+-------+ 7 rows in set (0.00 sec)
たしかに、同じテーブルが再現されていますね。
まとめ
いかがでしたか?今回はdumpについて、必要性から基礎的な使い方、リストア方法までをみてきました。dump自体はSQLに含まれているものではなく、バックアップということでどうしても地味に感じてしまうのも致し方ありません。
ですが、データベースの安定的な運用には欠かすことのできない重要な要素であることは納得していただけたのではないかと思います。
dumpも含めたデータベースのバックアップと上手く付き合い、堅牢性の高いデータベース運営をできるよう頑張っていきましょう。この記事が皆様のMySQL学習の一助となれば幸いです。