MySQL:リレーログの影響で壊れた?レプリケーションを再開させる方法

mysql-relaylog-fix

MySQLスレーブでレプリケーションを行っている場合に、スレーブサーバーの不慮の事故(突然の停電等によるシャットダウンやHDDのトラブルなど)でリレーログが壊れてしまうことがあります。

私の場合はCPUの冷却不足で突然サーバーが落ちてしまったことでリレーログが壊れてしまいました。

Slave_IO_Running, Slave_SQL_Running がどちらもNo

スレーブDBサーバーを「SHOW SLAVE STATUS\G」で確認してみると「Slave_IO_Running」と「Slave_SQL_Running」がどちらも「No」になっていて、それ以上マスターログを読みに行ってくれない状態になっていました。

mysql> SHOW SLAVE STATUS\G
************************** 1. row ****************************
           Master_Host: 127.0.0.1
           Master_User: repl
       Master_Log_File: mysqld-bin.000036
   Read_Master_Log_Pos: 417124678
        Relay_Log_File: hoge-relay-bin.003711
         Relay_Log_Pos: 6743
 Relay_Master_Log_File: mysqld-bin.000036
      Slave_IO_Running: No
     Slave_SQL_Running: No
...
   Exec_Master_Log_Pos: 417124678
 Seconds_Behind_Master: NULL

これを見るとリレーログが参照しているマスター側のバイナリログファイル「Relay_Master_Log_File」が「mysqld-bin.000036」、スレーブ側で既に実行済みのマスターログのクエリ位置「Excec_Master_Log_Pos」が「417124678」であることが分かります。

つまり「mysqld-bin.000036」の「417124678」の位置まではスレーブ側で同期できているということですね。

これを覚えておきましょう。

注意
実行済みのバイナリログファイルが「mysqld-bin.000036」と言いましたが、ちゃんとレプリケーションを行うためにマスター側にそれ以降、最新までのバイナリログがちゃんと存在していることを確認しておきましょう。

リレーログを無視してスナップショット準備状態にする

ということで、リレーログの事は一旦無視し、代わりに同期が止まっている今の状態のスレーブデータをマスターのスナップショットのように扱い、通常のレプリケーション開始コマンドで同期を再開する方法を採用します。

作業を行う前に
今の状態でスレーブ側のデータを別のところにバックアップしておいてください。万が一失敗した場合でも元に戻せるようにです。

まずは現在の止まっている状態でレプリケーションを停止させ、リレーログをリセットし、一旦出ます。

mysql> STOP SLAVE;
mysql> RESET SLAVE;
mysql> quit;

次にMySQLを停止させ、my.cnf のレプリケーション関連設定を「一旦」コメントアウト。(削除しないように)
これは最初にスナップショットからレプリケーションを始める人にはお馴染みの作業と思います。

# /etc/init.d/mysqld stop
server-id=10002
+#master-host='127.0.0.1'
+#master-user='repl'
+#master-password='(パスワード)'
+#master-port=3306
-master-host='127.0.0.1'
-master-user='repl'
-master-password='(パスワード)'
-master-port=3306

この時点でリレーログは必要なくなったので、削除しておきます。

# rm -f hoge-relay-bin*

再度、MySQLを起動させます。

# /etc/init.d/mysqld start

スナップショットからレプリケーションを開始

ここで最初に記録しておいたマスターのバイナリログファイル名「mysqld-bin.000036」と実行済みのログの位置「417124678」を「CHANGE MASTER TO …」の「MASTER_LOG_FILE」と「MASTER_LOG_POS」に指定します。

mysql> CHANGE MASTER TO
    -> MASTER_HOST = '127.0.0.1',
    -> MASTER_USER = 'repl',
    -> MASTER_PASSWORD = '(パスワード)',
    -> MASTER_LOG_FILE = 'mysqld-bin.000036',
    -> MASTER_LOG_POS = 417124678,
    -> MASTER_PORT = 3306;

最後に「START SLAVE」を実行して完了です。

mysql> START SLAVE;

レプリケーション確認

これで「SHOW SLAVE STATUS\G」で「Slave_IO_Running」「Slave_SQL_Running」が「yes」になっていれば成功です。

mysql> SHOW SLAVE STATUS\G
************************** 1. row ****************************
      Slave_IO_Running: Yes
     Slave_SQL_Running: Yes

レプリケーションによるデータ同期が確認できたらMySQLをstopし、my.cnf のレプリケーション用設定を元に戻して再度MySQLをstartさせましょう。

server-id=10002
-#master-host='127.0.0.1'
-#master-user='repl'
-#master-password='(パスワード)'
-#master-port=3306
+master-host='127.0.0.1'
+master-user='repl'
+master-password='(パスワード)'
+master-port=3306

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

2016-08-05