MEMORYエンジンが勝手にGTIDを進めてた
スレーブの gtid_executed がいつのまにかマスターとずれていることがあって、「スレーブに書き込んだうっかりさんは誰・・・?」と思ったらMEMORYエンジンが犯人だった。
MEMORYエンジンはディスクにはデータを保存せず、メモリ上のみデータを保存する。DBを再起動するとデータは消える。
レプリケーションを組んでいて、マスターだけ再起動したとする。 そうすると、マスターではデータが消えて、スレーブではデータが残ったままになる。
これでは、都合が悪い・・・ということで、MEMORYエンジンを利用している場合、再起動するとDELETE文をバイナリログに追記して整合性を取るようになっている。
マニュアルでは「マスターサーバ」としているが、バイナリログがONになっていると、スレーブでもこの挙動になる。
スレーブを再起動すると、スレーブのバイナリログにDELETE文が書かれ、スレーブのUUIDのGTIDが進む。マスターとgtid_executedが一致しなくなる。
元の状態
この状態で、ある日、マスターとスレーブを入れ替えるとする。
新スレーブ(旧マスター)は自分に未適用のGTIDのトランザクションを新マスター(旧スレーブ)からレプリケーションしようとする。
上記でいうと、zzzzzzzz-1111-2222-3333-xxxxxxxxxxxx:1-2。
バイナリログが残っていれば、MEMORYエンジンのテーブルがDELETEされる(これはまぁ、いいかもしれない。MEMORYエンジンのデータはいつ消えてもいい前提だし)
もし、バイナリログが残ってないと、「そんなGTIDのイベントのログはもう持ってません~ ┐(´д`)┌ 」とレプリケーションが止まってしまう。。。
新マスターでダミーのコミットを実行し、gtid_executed を無理やり揃えて回避。
MEMORYエンジンはディスクにはデータを保存せず、メモリ上のみデータを保存する。DBを再起動するとデータは消える。
レプリケーションを組んでいて、マスターだけ再起動したとする。 そうすると、マスターではデータが消えて、スレーブではデータが残ったままになる。
これでは、都合が悪い・・・ということで、MEMORYエンジンを利用している場合、再起動するとDELETE文をバイナリログに追記して整合性を取るようになっている。
マスターサーバーがシャットダウンして再起動すると、その MEMORY テーブルは空になります。マスターはこの影響をスレーブに複製するために、起動後に所定の MEMORY テーブルを最初に使用するときに、空にすべきテーブルの
DELETE ステートメントをバイナリログに書き込むことで、そのテーブルを空にする必要があることをスレーブに通知するイベントのログを記録します。
https://dev.mysql.com/doc/refman/5.6/ja/replication-features-memory.html
マニュアルでは「マスターサーバ」としているが、バイナリログがONになっていると、スレーブでもこの挙動になる。
スレーブを再起動すると、スレーブのバイナリログにDELETE文が書かれ、スレーブのUUIDのGTIDが進む。マスターとgtid_executedが一致しなくなる。
元の状態
マスター(UUID:aaaaaaaa-1111-2222-3333-bbbbbbbbbbbb) のgtid_executed:
aaaaaaaa-1111-2222-3333-bbbbbbbbbbbb:1-10
スレーブ(UUID:zzzzzzzz-1111-2222-3333-xxxxxxxxxxxx) のgtid_executed:
aaaaaaaa-1111-2222-3333-bbbbbbbbbbbb:1-10
スレーブ再起動。スレーブのUUID(zzzzzzzz-1111-2222-3333-xxxxxxxxxxxx)のGTIDが進む。 マスター(UUID:aaaaaaaa-1111-2222-3333-bbbbbbbbbbbb) のgtid_executed:
aaaaaaaa-1111-2222-3333-bbbbbbbbbbbb:1-10
スレーブ(UUID:zzzzzzzz-1111-2222-3333-xxxxxxxxxxxx) のgtid_executed:
aaaaaaaa-1111-2222-3333-bbbbbbbbbbbb:1-10, zzzzzzzz-1111-2222-3333-xxxxxxxxxxxx:1
もっかいスレーブ再起動 マスター(UUID:aaaaaaaa-1111-2222-3333-bbbbbbbbbbbb) のgtid_executed:
aaaaaaaa-1111-2222-3333-bbbbbbbbbbbb:1-10
スレーブ(UUID:zzzzzzzz-1111-2222-3333-xxxxxxxxxxxx) のgtid_executed:
aaaaaaaa-1111-2222-3333-bbbbbbbbbbbb:1-10, zzzzzzzz-1111-2222-3333-xxxxxxxxxxxx:1-2
この状態で、ある日、マスターとスレーブを入れ替えるとする。
新スレーブ(旧マスター)は自分に未適用のGTIDのトランザクションを新マスター(旧スレーブ)からレプリケーションしようとする。
上記でいうと、zzzzzzzz-1111-2222-3333-xxxxxxxxxxxx:1-2。
バイナリログが残っていれば、MEMORYエンジンのテーブルがDELETEされる(これはまぁ、いいかもしれない。MEMORYエンジンのデータはいつ消えてもいい前提だし)
もし、バイナリログが残ってないと、「そんなGTIDのイベントのログはもう持ってません~ ┐(´д`)┌ 」とレプリケーションが止まってしまう。。。
新マスターでダミーのコミットを実行し、gtid_executed を無理やり揃えて回避。
SET SQL_LOG_BIN=0;
SET GTID_NEXT='zzzzzzzz-1111-2222-3333-xxxxxxxxxxxx:1';
BEGIN; COMMIT;
SET GTID_NEXT='zzzzzzzz-1111-2222-3333-xxxxxxxxxxxx:2';
BEGIN; COMMIT;
SET GTID_NEXT='AUTOMATIC'