データセンターの停電後、スレーブMySQLデータベースは苦労しています。
これは、スレーブの1つのログにあります。
100118 10:05:56 [Note] Slave I/O thread: connected to master 'repl@db1:3306', replication started in log 'bin-log.004712' at position 724207814
100118 10:05:56 [ERROR] Error reading packet from server: Client requested master to start replication from impossible position ( server_errno=1236)
100118 10:05:56 [ERROR] Got fatal error 1236: 'Client requested master to start replication from impossible position' from master when reading data from binary log
100118 10:05:56 [Note] Slave I/O thread exiting, read up to log 'bin-log.004712', position 724207814
そして、コンソールにはもう少し詳細が表示されます。
mysql> show slave status \G;
*************************** 1. row ***************************
Slave_IO_State:
Master_Host: db1
Master_User: repl
Master_Port: 3306
Connect_Retry: 10
Master_Log_File: bin-log.004712
Read_Master_Log_Pos: 724207814
Relay_Log_File: mysqld-relay-bin.000105
Relay_Log_Pos: 98
Relay_Master_Log_File: bin-log.004712
Slave_IO_Running: No
Slave_SQL_Running: Yes
Replicate_Do_DB: mmplive1,mmpjcr,fui
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 724207814
Relay_Log_Space: 98
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: NULL
1 row in set (0.00 sec)
ERROR:
No query specified
マスターのビンログを見ると、次のようになっています。
-rw-rw---- 1 mysql mysql 724200412 Jan 18 09:22 bin-log.004712
-rw-rw---- 1 mysql mysql 1904 Jan 18 09:27 bin-log.index
-rw-rw---- 1 mysql mysql 5046830 Jan 18 11:22 slow-log
-rw-rw---- 1 mysql mysql 198249613 Jan 18 11:24 bin-log.004713
スレーブを修正する最良の方法は何ですか?
私が検討しているオプション:
更新:
別のオプションを見逃しました。各スレーブの実行位置を少し後ろに向けて、bin-log.004712からすでに処理したコマンドを複製しようとするようにしました。
私は最初の選択肢を選びました。
これは、スレーブが主キーと競合する挿入を実行しようとするところまで機能しました。前述のように、スレーブはマスターのbin-logが保持していたよりも多くの作業を実行していました。私が予期していなかった1つの側面は、スレーブにマスターにないデータが含まれていることでした。つまり、スレーブは、マスターが停止する前にいくつかのトランザクションを持続しましたHAD NOT持続しました。
私の場合、これらのトランザクションは支払い関連などではなかったため、スレーブからデータを削除することを選択しました(これにより、発生したがマスターには存在しなかったデータが失われます)、レプリケーションを再度実行します。これにより、スレーブは完全に最新の状態になりました。データがより重要だった場合は、データを手動でラングリングし、参照整合性が損なわれないようにするための余裕を持たせるのに十分な自動インクリメントオフセットがあります。ありがたいことに、この場合はそれを行う必要はありませんでした。
この窮地にあった(パッシブ)マスター-マスター構成のマシンについては、同様のアプローチを選択しました。パッシブマスターマスターとは、すべての書き込みが行われるアクティブマスター(serverA)と、ダウンタイムなしでスキーマの更新を実行できるようにするパッシブマスター(serverB)があることを意味します。アクティブマスター(serverA)のデータが真の値として選択されましたが、これは、重要とは見なされなかった永続的なトランザクションがいくつか失われたことを意味することを知っていました。
スレーブ上のログファイルと位置を変更しました。
CHANGE MASTER MASTER_LOG_FILE='bin-log.004713', MASTER_LOG_POS=0; -- on serverB
他のスレーブと同様に、主キー制約違反で失敗するまで、パッシブマスター(serverB)でスレーブレプリケーションを再開しました。
START SLAVE; -- on serverB
パッシブマスター(serverB)からアクティブマスター(serverA)へのスレーブレプリケーションを停止しました。
STOP SLAVE; -- on serverA
ServerAのマスターに存在しなかったスレーブ(serverB)の行を削除します。
DELETE FROM SOME_TABLE WHERE ID IN (???,????); -- on serverB
SHOW MASTER STATUS\G; -- get the new master log position on serverB
アクティブマスター(serverA)スレーブexec位置を移動して、パッシブマスター(serverB)からの削除をスキップします。
CHANGE MASTER TO MASTER_LOG_POS=???; --on serverA; use the value just obtained from serverB
アクティブマスター(serverA)とパッシブマスターの両方でレプリケーションを再開します。
START SLAVE; -- on both machines. serverA does nothing and serverB starts catching up.
スレーブがマスターの正確なレプリカであることがどれほど重要かによって異なります。最初のオプションはある程度機能しますが、スレーブはマスターからの情報を見逃している可能性があります。データが一時的なものであるなどの理由でそれを受け入れることができる場合は、それを選択してください。スレーブが適切なレプリカであることが重要な場合は、2番目のオプションがおそらく唯一の選択肢です。残念ながら、MySQLレプリケーションは、予期しない中断を一切受けません。これらの種類の問題は、レプリケーションアーキテクチャで望むよりもはるかに頻繁に発生することがわかりました。