🔄

MySQL のレプリケーションは意外と当てにならない

2017/06/30に公開

事象

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