MySQLのレプリケーションが停止した場合の復旧手順について纏めておきたいと思います。
レプリケーションが停止する主な要因
- ネットワーク障害
- ディスク容量の圧迫
- バイナリーログの破損
- リレーログの破損
復旧するための戦略
レプリケーションを復旧させる場合、先ずはリレーログからの復旧を試みる。もし上手く行かない場合は、リレーログが破損している可能性があるのでバイナリーログからの復旧を試みる。それでも駄目だと、Dumpファイルからリストアして復旧する流れとなる。
レプリケーションの処理の流れ
双方向にレプリケーションさせている場合の例になります。
- DB1を更新すると、DB1はバイナリーログを出力する
- DB2は、DB1のバイナリーログを取得して、リレーログを出力する
- DB2は、リレーログの内容が反映済みかどうかをチェックして、未反映であるため反映する
- DB2は、更新された情報をバイナリーログに出力する
- DB1は、DB2のバイナリーログを取得して、リレーログを出力する
- DB1は、リレーログの内容が反映済みかどうかをチェックして、反映済みであるためスキップする
リレーログから復旧する
ネットワークの瞬断やディスク容量の圧迫によって一次的に、リレーログへの書き込みができない状態となりレプリケーションが停止した場合、問題が解消された時点で、最後に取得したログ以降の差分を取得してリレーログへの書き込みが再開されます。
リレーログは、レプリケーションを再開するまで溜まり続けるので、ディスク容量の圧迫に注意が必要です。
手順
現在のスレーブの状態を確認する
mysql> show slave status\G ・・・ Slave_IO_Running: Yes Slave_SQL_Running: No ・・・
スレーブを再開する
mysql> start slave
再開後のスレーブの状態を確認する
mysql> show slave status\G ・・・ Slave_IO_Running: Yes Slave_SQL_Running: Yes ・・・
バイナリーログから復旧する
リレーログが破損していて復旧ができない場合は、マスター側のバイナリーログからの復旧することが出来る。
手順
現在のスレーブの状態を確認する
mysql> show slave status\G ・・・ Master_Log_File: mysql-bin.000001 Exec_Master_Log_Pos: 1111111111 ・・・
次に、スレーブのサーバーでスレーブとしての動作を止めてリセットする
mysql> stop slave; mysql> reset slave;
次に、先ほど取得した、Master_Log_FileとExec_Master_Log_Posの情報をもとに下記のコマンドを実行して、マスターのバイナリーログからの読出し位置を変える。
mysql> change master to master_host=’the-master-host’, master_user=’replication-user’, master_password=’the-password’, master_log_file=’mysql-bin.000001′, master_log_pos=1111111111;
最後に、スレーブを再開する。
mysql> start slave
再開後のスレーブの状態を確認する
mysql> show slave status\G ・・・ Slave_IO_Running: Yes Slave_SQL_Running: Yes ・・・
Dumpファイルからリストアして復旧する
リレーログからもバイナリーログからも復旧ができない場合は、リストアする必要があります。
手順
マスターにてdumpファイル取得する
$ mysqldump -uroot -p --master-data --events --routines --triggers -A > dump.sql
dumpの際、「–master-data」オプションを指定することでdump時のバイナリログ、ポジションの情報が付与されます。
上記オプションでdumpを取得した場合、dumpファイルに下記のような「CHANGE MASTER」のSQLが追加されます。
CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=1111111111;
※こちらのバイナリログ、ポジション情報をメモしておく。
次に、スレーブのサーバーでスレーブとしての動作を止めてリセットする
mysql> stop slave; mysql> reset slave;
Dumpファイルから、スレーブをリストアする
$ mysql -p root -p < dump.sql
次に、先ほど取得した、Master_Log_FileとExec_Master_Log_Posの情報をもとに下記のコマンドを実行して、マスターのバイナリーログからの読出し位置を変える。
mysql> change master to master_host=’the-master-host’, master_user=’replication-user’, master_password=’the-password’, master_log_file=’mysql-bin.000001′, master_log_pos=1111111111;
最後に、スレーブを再開する。
mysql> start slave
再開後のスレーブの状態を確認する
mysql> show slave status\G ・・・ Slave_IO_Running: Yes Slave_SQL_Running: Yes ・・・