Day22 後半のゴール
「“実務で使えるmysqldump/リストア”のイメージを持つ」
前半で、mysqldump とリストアの「仕組み」と「流れ」は掴めました。
後半では、もう一歩踏み込んで「実務でそのまま使えるレベル」に近づけます。
ここで目指すのは次の状態です。
バックアップを取るときに、最低限つけるべきオプションを説明できる
特定のDBだけ/特定のテーブルだけをdumpするイメージを持てる
リストア時に「やってはいけないこと」と「安全なやり方」を理解している
バックアップは“最後の砦”なので、ここは丁寧にいきます。
実務でよく使う mysqldump の基本パターン
「“全部”と“特定DB”と“特定テーブル”を使い分ける」
mysqldump は、対象の範囲によって使い方が少し変わります。
大きく分けると、次の3パターンがあります。
サーバー上の全DBをバックアップするイメージ
開発環境や小規模サーバーでは、「全部まとめてdump」がよくあります。
mysqldump -u root -p --all-databases > all.sql
このファイルには、
全データベースの CREATE DATABASE
各DBのテーブル定義
各テーブルのデータ
が全部入ります。
リストアするときは、単純にこうです。
mysql -u root -p < all.sql
ただし、本番環境で「全部まとめて」はサイズも時間も大きくなりがちなので、
実務では「重要なDBだけ」「用途ごとに分けて」dumpすることが多いです。
特定のDBだけをバックアップするイメージ
前半でやったように、特定のDBだけをdumpするのが一番よく使う形です。
mysqldump -u root -p sample_app > sample_app.sql
この場合、sample_app の中身だけが対象になります。
リストアもシンプルです。
mysql -u root -p < sample_app.sql
特定のテーブルだけをバックアップするイメージ
「このテーブルだけ退避しておきたい」という場面もあります。
例えば、users テーブルだけをdumpしたい場合はこうです。
mysqldump -u root -p sample_app users > users.sql
DB名の後ろに、テーブル名を並べるイメージです。
複数テーブルも指定できます。
mysqldump -u root -p sample_app users orders > users_orders.sql
リストア時は、対象DBを USE してから流すか、
ファイル内に USE が含まれているかで挙動が変わるので、
「どのDBに戻すか」は意識しておく必要があります。
実務でほぼ必須になるオプションたち
「–single-transaction と –routines / –triggers を知っておく」
mysqldump にはオプションがたくさんありますが、
初心者が「これだけは知っておくと得をする」ものに絞って説明します。
–single-transaction
「InnoDB のテーブルを“止めずに”一貫した状態でdumpする」
InnoDB のテーブルがメインのDBでは、ほぼ必須級のオプションです。
mysqldump -u root -p --single-transaction sample_app > sample_app.sql
これは、
トランザクションを開始して、その時点のスナップショットを基準にdumpする
という動きをします。
ポイントは、
dump中にアプリが書き込みをしても、
「dumpファイルの中身は、dump開始時点での一貫した状態になる」
ということです。
さらに、テーブルに対して重いロックを取らないので、
サービスを止めずにバックアップを取りやすくなります。
ただし、MyISAM など一部のストレージエンジンには効かないので、
「InnoDB前提のテーブルで使う」と覚えておくとよいです。
–routines / –triggers
「ストアドプロシージャやトリガーも一緒にdumpする」
DBによっては、ストアドプロシージャやトリガーを使っていることがあります。
それらも含めてバックアップしたい場合は、オプションを足します。
mysqldump -u root -p \
--routines \
--triggers \
sample_app > sample_app.sql
これを付けないと、
テーブルとデータは戻せたけど、トリガーがない
ストアドプロシージャが消えていて、アプリがエラー
という事故が起こり得ます。
「このDBはプロシージャやトリガーを使っているか?」は、
バックアップ設計のときに必ず確認したいポイントです。
リストア時に気をつけること
「既存データとの関係・権限・環境差を意識する」
リストアは「dumpを流すだけ」ですが、
実務ではいくつか注意点があります。
既存のDBやテーブルをどう扱うか
dumpファイルの中に、
CREATE DATABASE …
CREATE TABLE …
が含まれている場合、
すでに同名のDBやテーブルがあるとエラーになります。
安全なやり方としては、
テスト環境に新しいDB名でリストアする
本番で復元するときは、事前に DROP / RENAME などで衝突を避ける
といった手順を踏みます。
例えば、テスト用に sample_app_restore というDBを作ってから、
mysql -u root -p sample_app_restore < sample_app.sql
のように、「どのDBに流し込むか」を明示するやり方もあります。
権限の問題
mysqldump でバックアップを取るときも、
mysql でリストアするときも、
必要な権限がないと失敗します。
特に、CREATE DATABASE や CREATE TABLE、
TRIGGER や ROUTINE を含むdumpをリストアするときは、
それらを作成できる権限が必要です。
実務では、
バックアップ専用ユーザー
リストア専用ユーザー
を用意して、権限をきちんと管理することが多いです。
環境差(文字コード・バージョン)の問題
開発環境で取ったdumpを、本番にそのまま流す
古いバージョンのMySQLで取ったdumpを、新しいバージョンに流す
こういうときに、文字コード設定やSQLモードの違いで
エラーが出ることがあります。
Day22 の段階では、
「環境が違うところにリストアするときは、事前にテストする」
という意識だけ持っておけば十分です。
「バックアップ運用」をどう考えるか
「いつ・どのくらいの頻度で・どこに置くか」
mysqldump の使い方が分かっても、
「いつ・どのくらいの頻度で取るか」を決めないと、
実務では意味がありません。
ここは、技術というより設計の話です。
いつ取るか
サービスがあまり使われていない時間帯(深夜など)に取るのが一般的です。
ただし、–single-transaction を使えば、
日中でも比較的安全にバックアップを取れます。
どのくらいの頻度で取るか
これは「どこまで巻き戻せれば許容できるか」で決まります。
1日1回のバックアップなら、
最悪「昨日の状態」までしか戻れません。
1時間に1回なら、「1時間前」まで戻れます。
これを「RPO(どこまで戻れればいいか)」という考え方で決めます。
Day22 では用語は覚えなくていいですが、
「どこまで失っても許されるか」を先に決めて、頻度を決める
という発想は持っておくと良いです。
どこに置くか
バックアップファイルを、DBサーバーと同じマシンに置いておくと、
サーバーごと死んだときに一緒に消えます。
なので、実務では、
別サーバーに転送する
クラウドストレージに置く
世代管理(何日分残すか)をする
といった運用を組み合わせます。
ここまで来るとインフラ寄りの話になりますが、
アプリエンジニアでも「バックアップは別の場所にも置くべき」という感覚は持っておきたいです。
「怖さ」を知っている人ほど、バックアップに本気になる
「“やらかしたときに助けてくれるのは、過去の自分”」
最後に、少しだけメンタル寄りの話をします。
DROP TABLE を本番で打ってしまった
DELETE FROM … を WHERE なしで流してしまった
こういう“やらかし”は、
どれだけ優秀なエンジニアでも、ゼロにはできません。
そのときに、
「バックアップがあるから、戻せる」
と言えるかどうかは、
過去の自分がどれだけ真面目にバックアップを考えていたか、にかかっています。
mysqldump のコマンドを覚えること自体は難しくありません。
大事なのは、
定期的に取る
復元テストもする
どこまで戻せればいいかを決めておく
という「習慣」と「設計」です。
Day22 まで来ているあなたなら、
そこまで含めてちゃんと考えられるはずです。
Day22 後半のまとめ
実務で mysqldump を使うときは、「何をどこまでdumpするか」と「どんなオプションを付けるか」が重要で、--all-databases でサーバー全体、DB名だけ指定して特定DB、DB名+テーブル名で特定テーブルだけ、といった粒度を使い分けつつ、InnoDB前提なら --single-transaction を付けてサービスを止めずに一貫した状態をdumpし、ストアドプロシージャやトリガーを使っているDBなら --routines --triggers を忘れずに付けるのが“実務の基本形”になる。
リストア時は、既存のDB/テーブルとの衝突、権限不足、環境差(文字コード・バージョン)などに注意しつつ、「どのDBに流し込むか」を意識して mysql -u ユーザー -p < dump.sql や mysql -u ユーザー -p データベース名 < dump.sql を使い分け、さらに「いつ・どの頻度で・どこにバックアップを置くか」を運用として決めておくことで、単に“dumpを取れる人”ではなく、“本当に戻せる状態を設計できるエンジニア”に近づいていく。
