単一のデータベースを複製するマスターサーバーと複数のスレーブサーバーがあります。 SLES11のMySQL5.0で使用しています。フォールトトレランステスト中に、スレーブのネットワーク接続が切断され(ケーブルが接続されていない)、復元されると、レプリケーションがハングすることがわかりました。エラーは表示されず、スレーブは実行されているように見えますが、Read_Master_Log_Pos
およびExec_Master_Log_Pos
値がマスターサーバーのログ位置と一致しません。
Slave_IO_State
は「マスターがイベントを送信するのを待っています」です。
Slave_IO_Running
およびSlave_SQL_Running
値は両方とも「はい」です。
Master_Log_File
およびRelay_Master_Log_File
一致。
スレーブを停止して起動するか、mysqlデーモンを再起動すると、レプリケーションが再び機能し始めます。
これについて私ができることについて何かアイデアはありますか?
MySQLスレーブがマスターに接続すると、バイナリログのストリームを要求し、マスターは、半同期レプリケーションを使用していない限り、スレーブからの確認応答を必要とせずに、発生した頻度でbinlogイベントを自律的に送信します。
スレーブは、TCPスタックによって処理される低レベルの確認応答を除いて、トラフィックを発信しません。接続の中断(スタックのさまざまな層で、プラグが抜かれたケーブルに限定されない)は、タイムアウトまたはICMPのためにマスターのTCPスタックが接続を切断するなど、いくつかの方法で接続を切断する可能性があります到達不能メッセージまたはマシン間のステートフルファイアウォールがTCPセッションを「忘れて」、後続のパケットをサイレントにドロップします。スレーブは静かに座って、マスターから次のパケットが来るのを待ちます。
ここでの解決策は、グローバル変数 slave_net_timeout
です。
スレーブが接続が切断されたと見なし、読み取りを中止して再接続を試行する前に、マスターからのデータが増えるのを待つ秒数。
これはスレーブで構成されます。スレーブがマスターに接続すると、binlogストリームを要求する前に、binlogイベントのようにフォーマットされ、マスターのbinlogの次のイベントであるかのようにストリーミングされるハートビートイベントを送信するようにマスターに要求しますが、実際にはインクリメントしません。 binlog位置カウンター。これらは、マスターがスレーブのslave_net_timeout
設定の半分(デフォルト;または CHANGE MASTER TO
)なので、ハートビートイベントは、トラフィックが非常に少ない場合にのみ実際に生成されます...したがって、この値を低く設定しても、実際に害はありませんほんの数秒で。
スレーブはタイムアウトの期限が切れていることを確認すると、接続を閉じてマスターに再接続します。
MySQLマスターは、新しいスレーブ接続を受け入れるときに、同じスレーブが別のスレーブであるかどうかをチェックするため、マスターがスレーブがなくなったことに気付かないリモートチャンスで、スレーブが再接続すると、マスターは元の接続を閉じます。 server_id
はすでに接続されており、接続されている場合は、元の接続を切断します。ちなみに、これが、同じserver_id
(サポートされていない構成)で構成された2つのスレーブが、同じマスターへの接続を正常に維持できない理由です。一方が接続するとすぐに、もう一方が接続します。ぶつかると、各スレーブが他のスレーブの接続を強制的に切断するというサイクルが発生します。
My.cnfでこの変数を適切に低い値に設定し、スレーブを再起動すると、この問題が解決するはずです。