MySQL のレプリケーションは意外と当てにならない
事象
Master-Slave 構成のデータベースで Slave 側のステータス(show slave status\G
)は問題ないのに、Slave のデータを参照すると一部欠損しているデータがあった。
エラーになっていない
レプリケーションでエラーが出るのは、Slaveに直接書き込みを行ったりして、プライマリキーなどのユニークなデータが衝突するケースが多い。
逆に言えばそれ以外の場合は、ほとんどの場合でエラーにならない。
エラーにならなければレプリケーションは継続される。
なぜ欠損が発生しているのか
構成
先ほど Master-Slave 構成と書いたが、実は Slave は2台あり、うち一台は Master と同じところにあり(Slave1 とする)、もう一台は別のロケーションに設置してある(Slave2 とする)。
両 Slave とも Master からデータの配信を受けている。
今回欠損していたのは別な場所にある Slave2 だった。
障害発生
データ欠損の報告を受ける数日前に Master に障害が発生し、一時的に Slave1 を Master に昇格させて運用を継続していた。
Slave は2台ともレプリケーションの受け取りを停止させている。
復旧作業
Master と Slave が同スペックのマシンだったらよかったのだが、 Slave1 はあくまで緊急的に使う目的で構築されていたので低スペック。
そのため障害が回復したら Master と Slave1 を元に戻す必要があった。
Slave1 側の dump を取り Master 側に復元し、 Master 側で master start
やら Slave 側で change master
やらいつものお決まりを行い、復旧完了。
別ロケーションのレプリケーションを再開させる
作業員は何を思ったのか、 Slave2 に Slave1 の dmup を流し込まずに change master
を行いレプリケーションを再開してしまった。
当然 Slave1 で運用していた間のデータが Slave2 にはない。
しかし幸か不幸か、レプリケーションエラーは一切でないまま、 Master のデータを受け取り続けてしまっていた…。
教訓
レプリケーション復旧するときは最新データをちゃんと流し込め(当たり前)。
Discussion