2013年8月8日木曜日

Amazon RDSのリードレプリカでClient requested master to start replication from impossible positionに出会う

マスターがMulti-AZ構成で、フェイルオーバーした時に、リードレプリカのI/Oスレッドが止まっちゃいました。

mysql56> SHOW SLAVE STATUS\G
..
                Last_IO_Errno: 1236
                Last_IO_Error: Got fatal error 1236 from master when reading data from binary log: 'Client requested master to start replication from impossible position; the first event 'bin.000001' at 64056, the last event read from './bin.000001' at 4, the last byte read from './bin.000001' at 4.'
..

ログ出力はこんな感じ。別のサーバーで再現させただけなので数字はテキトーです。


Error:1236自体は、「I/Oスレッドがマスターのbinlogを読み込もうとしたら、致命的な(リトライしても決して成功しない)エラーになった」という意味で、後続のメッセージが重要になったりします。

この場合は、"Client requested master to start replication from impossible position;"がそれですね。スレーブのI/OスレッドはMASTER_LOG_FILE= 'bin.000001', MASTER_LOG_POS= 64056をマスターに要求したけれど、マスターのbin.000001ファイル上にはPosition 64056のイベントは存在しない、というエラーです。

たぶん、マスターが元のAZにいたときに、スレーブがぴったり遅延なくbinlogを受信していた && sync_binlog= 0だったので元のマスターがwrite()したbinlogがfsync()される前に切り替わってしまったのが原因でせう。

MySQL on EC2などであればCHANGE MASTER TOで直したりもできるんですが(マスターに存在しないトランザクションがスレーブに受信されちゃってる状態なので、ある程度は調整しないとではあるんですが)そこはRDS、それは無理。

https://forums.aws.amazon.com/thread.jspa?messageID=452065&#452065

"you should create a new read replica to replace the broken one."だそうで。
まあ、マスターに無いbinlogがスレーブに行っちゃっている時点でデータの整合性も保証できなくなってるわけで、おとなしく作り直すのがいいんでしょうね。


ちなみにですが、マスター上に存在しないバイナリーログファイルを指定するとこんな感じに。

mysql56> SHOW SLAVE STATUS\G
..
                Last_IO_Errno: 1236
                Last_IO_Error: Got fatal error 1236 from master when reading data from binary log: 'Could not find first log file name in binary log index file'
..

そんなバイナリーログファイル持ってないぜって感じですね。


mysql.rds_skip_repl_errorで直るかなぁって相談受けたんだけど、無理です。
CALLステートメントでよく呼ぶストアドルーチンの中身の見方は↓こんな感じ。

http://yoku0825.blogspot.jp/2013/08/amazon-rds.html

0 件のコメント :

コメントを投稿