MySQLの高速バックアップ&リストア:Mydumperで15時間を2時間に短縮

MySQL tutorial - IT technology blog
MySQL tutorial - IT technology blog

mysqldumpがシステムの負担になるとき

キャリアの初期、私は常にmysqldumpを使用していました。デフォルトのツールであり、非常に使いやすかったからです。しかし、管理していたプロジェクトのデータ量が200GBに達したとき、状況は一変しました。ログテーブルが5,000万レコードを超え、毎晩のバックアップが本当の試練となったのです。

mysqldumpの最大の欠点は、シングルスレッド(single-thread)で動作することです。膨大なデータを処理するために、たった一つのCPUコアしか利用しません。その結果、バックアップに6時間以上かかり、リストアのテストでは待ち時間が15時間近くに及びました。本番環境でサーバー障害が発生した際、復旧に半日もかかっていては、技術チームの信頼は間違いなく失墜してしまいます。

mydumpermyloaderに移行した後、バックアップ時間は40分に短縮されました。リストアプロセスも2時間足らずで完了します。ここでは、この強力なツールセットを使いこなすための実践的な経験を紹介します。

なぜmydumperが優れているのか?

違いはデータへのアプローチ方法にあります。mysqldumpが小さなトラック1台で何度も往復して引越しをするようなものだとしたら、mydumperはトラックのフリートが一斉に出発するようなものです。

  • マルチスレッド(Multi-threading)の威力: 8、16、または32スレッドを動員して、データを並列で読み取ることができます。
  • チャンク分割メカニズム(Chunking): 数百GBの巨大なSQLファイルを出力する代わりに、mydumperはテーブルごとにデータを分割します。大きなテーブルは自動的に複数のチャンク(chunks)に分割されます。これにより、myloaderは複数のファイルを同時にデータベースにロードでき、サーバーリソースを最大限に活用できます。
  • 即時データ圧縮: ダンプと同時に圧縮が行われるため、CPUのボトルネックを引き起こすことなくストレージ容量を節約できます。
  • 一貫性の確保: このツールは一瞬だけFLUSH TABLES WITH READ LOCKを実行してbinlogの座標を取得し、その後InnoDBテーブルに対してトランザクションを使用することで、データの整合性(スナップショット)を保証します。

Linuxへのクイックインストール

MydumperはMySQLのインストールパッケージには含まれていません。しかし、UbuntuやCentOSなどの主要なディストリビューションでのインストールは非常に簡単です。

# Ubuntu/Debian用
sudo apt update
sudo apt install mydumper -y

# CentOS/RHEL用
sudo yum install epel-release -y
sudo yum install mydumper -y

最新の機能が必要な場合は、プロジェクトの公式GitHubページからビルド済みのバイナリをダウンロードすることをお勧めします。

mydumperによる効率的なバックアップ方法

例えば、データベースprod_dbをバックアップする必要があるとします。単純なコマンドではなく、以下の最適化されたパラメータを使用しましょう。

mydumper \
  --host=127.0.0.1 \
  --user=admin_user \
  --password='your_password' \
  --database=prod_db \
  --threads=8 \
  --rows=500000 \
  --compress \
  --build-empty-files \
  --outputdir=/data/backups/$(date +%F) \
  --verbose=3

重要なパラメータの解説:

  • --threads=8: 8つのCPUコアを活用します。私の経験では、サーバーの総コア数の約70%に設定するのが最適です。
  • --rows=500000: これが最も重要な「武器」です。例えばordersテーブルに1,000万行ある場合、1つの巨大なファイルではなく、20個の小さなファイルに分割されます。これにより、後のリストアが数倍速くなります。
  • --compress: 出力ファイルをgzipで圧縮し、ディスクへの負荷を大幅に軽減します。

myloaderによる超高速リカバリ

データ復旧が必要な際、myloaderはバックアップディレクトリ内のメタデータを自動的に読み取り、最適な復旧プロセスを実行します。

myloader \
  --host=127.0.0.1 \
  --user=admin_user \
  --password='your_password' \
  --directory=/data/backups/2023-10-27 \
  --queries-per-transaction=50000 \
  --threads=8 \
  --database=prod_db_restored \
  --overwrite-tables \
  --verbose=3

ヒント:このコマンドを実行する前に、MySQLが処理空間を確保できるよう、一時的にinnodb_buffer_pool_sizeを可能な限り高い値に設定してください。

実運用における4つの重要な注意点

大規模システムで6ヶ月間運用した結果、トラブルを避けるための4つの教訓を得ました。

1. ディスクIOPSの制御

マルチスレッドで動作するため、mydumperは読み書きリソースを激しく消費します。データベースが稼働しているディスク上で直接バックアップを実行すると、アプリケーションの遅延やフリーズ(スロークエリの急増)を引き起こす可能性があります。理想的には、別のディスクにバックアップするか、スレーブ(Read Replica)で実行してください。

2. –rowsパラメータを忘れない

--rowsを忘れると、100GBのテーブルがたった1つのスレッドで処理されてしまいます。この場合、たとえ64スレッドを設定していても、最大のテーブルでボトルネックが発生し、速度は非常に遅くなります。

3. 一時ディレクトリの容量

バックアップデータを保存するパーティションに、実際のデータベース容量の少なくとも1.5倍の空き容量があることを確認してください。ダンプ中に容量が不足すると、バックアップ全体が破損してしまいます。

4. リストア時のMySQL構成の最適化

データロード速度を極限まで高めるには、一時的に以下のコマンドで制約チェックを無効にします。

SET GLOBAL autocommit = 0;
SET GLOBAL unique_checks = 0;
SET GLOBAL foreign_key_checks = 0;

データの整合性を保つため、リストア完了後にこれらの設定を元に戻すのを忘れないでください。

要約すると、データベースが20GBを超えたら、迷わずmysqldumpを卒業しましょう。mydumperへの移行は時間の節約になるだけでなく、データ紛失のリスクに直面した際の最も安全な保険となります。

Share: