MySQLのDelayed Replication:誤操作によるデータ削除時の「救命ボート」

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

WHERE句のないDELETE文:バックアップだけでは不十分な理由

DBAや運用エンジニアなら誰しも、本番環境で誤ってデータ削除スクリプトを実行してしまったという報告を受け、心臓が止まるような思いをしたことがあるでしょう。午前2時の定期バックアップだけに頼っていると、大惨事になりかねません。数百GBのデータベースをダンプファイルからリストアし、さらにBinary Logをリプレイして午後3時のデータを復元するには、丸一日かかることもあります。ビジネスにおいて、1時間のダウンタイムは莫大な損失を意味します。

私は以前、ECサイトでエンジニアが500GBのDBクラスターに対して誤ってクリーンアップスクリプトを実行したトラブルを対応したことがあります。リストアに6時間以上かかり、サイトは完全に停止、数万ドルの損失が発生しました。通常のMaster-Slave構成では、削除コマンドが数ミリ秒でSlaveに同期されるため、助けにはなりません。そこで必要になるのがDelayed Replicationです。

Delayed Replication:データベースの「タイムマシン」

Delayed Replication(遅延レプリケーション)を使用すると、Slave(Replica)ノードがMasterよりも常に一定時間(例:1時間や3時間)遅れて動作するように設定できます。

この仕組みは非常に合理的です。SlaveはMasterから Binary Log を受け取るとすぐに Relay Log に保存しますが、すぐには実行しません。設定された時間が経過するのを待ってから、コマンドの適用を開始します。もし午前10時に誤ってテーブルをDROPしてしまい、1時間の遅延を設定していた場合、そのコマンドがSlaveで実行されるまで60分間の猶予があります。これがシステムを救うための「黄金の時間」となります。

Delayed Replicationを設定する3つのステップ

すでにレプリケーションシステムが稼働していると仮定します。通常のSlaveをDelayed Slaveに変更するのに1分もかかりません。以下は、遅延を3600秒(1時間)に設定する方法です。

1. レプリケーションプロセスの停止

-- 全バージョン共通
STOP SLAVE;
-- または MySQL 8.0.22 以降:
STOP REPLICA;

2. 遅延時間(Delay)の設定

MASTER_DELAY パラメータを使用して待ち時間を指定します。単位は秒です。

-- 旧バージョンの MySQL
CHANGE MASTER TO MASTER_DELAY = 3600;

-- MySQL 8.0.23 以降
CHANGE REPLICATION SOURCE TO SOURCE_DELAY = 3600;

私の経験では、1時間から3時間の間に設定することをお勧めします。この時間は運用チームが異常を察知するのに十分であり、かつRelay Logが肥大化しすぎない適切な長さです。

3. Slaveの再起動

START REPLICA;

Slaveが「待機中」かどうかを確認する方法

設定が正しく反映されているか、Slaveの状態を確認しましょう。

SHOW REPLICA STATUS\G

特に以下の2つの項目に注目してください:

  • SQL_Delay: 設定した遅延時間(3600)が表示されます。
  • SQL_Remaining_Delay: 次のイベントを実行するまでSlaveが待機する必要がある残り秒数です。

orders テーブルが5000万レコードを超えるようなシステムを管理していた際、Delayed SlaveのCPU負荷は非常に低いことに気づきました。ただし、1時間分の未適用Relay Logを保持するため、ディスク容量には注意が必要です。

レスキューシナリオ:15分でデータを復旧させる

例えば午前10:00に、恐ろしい DROP TABLE users; コマンドが実行されたとします。それに気づいたのが10:10。Slaveには1時間の遅延があるため、11:00まではデータがそのまま残っています。

迅速な対応手順:

  1. 即座に切断: Slaveで STOP REPLICA; を実行し、DROPコマンドが実行されるのを阻止します。
  2. 停止ポイントの特定: Relay Logの中から、DROPコマンドの直前の位置(Log position)を見つけます。
  3. クリーンなデータまで実行: UNTIL句を使用して、エラー発生直前までログを適用させます:
    START REPLICA UNTIL MASTER_LOG_FILE = 'binlog.000001', MASTER_LOG_POS = 1024;
  4. 復旧: Slaveからテーブルをエクスポートし、Masterにインポートし直します。これでシステムは瞬時に正常な状態に戻ります。

「策に溺れない」ための重要な注意点

Delayed Replicationは非常に強力ですが、あらゆる問題に対する万能薬ではありません。

  • 読み取り専用レプリカ(Read Replica)として使用しない: アプリケーションがこのノードからデータを読み取らないようにしてください。さもないと、ユーザーに「1時間前の残高」が表示されることになります。
  • ディスク容量の監視: 書き込み頻度が高いシステムでは、Relay Logが数十GBに達することがあります。適用後に自動削除されるよう、relay_log_purge = 1 に設定されていることを確認してください。
  • バックアップは必須: Delayed Replicationは、ランサムウェアやサーバークラスター全体の物理的な故障からは守ってくれません。

Delayed Replicationを設定することは、車の車両保険に入るようなものです。それを使わずに済むのが一番ですが、万が一の事態が起きたとき、それはあなたのキャリアを救うものになるでしょう。

Share: