VPN切断後のMySQLレプリケーション:まず両方の段階を読む
途切れた経路は失われたトランザクションではない。受信側と適用側を別々に読み、ソースがまだ保持しているものを確認する。
VPNが切れるとレプリケーション監視は赤くなり、つい位置をリセットしたくなる。その衝動こそが、ネットワークの切断をデータ問題に変える。切れた経路は、レプリカが何を受け取ったか、何を適用したかについては何も語らず、それは二つの状態を持つ二つの段階である。何かを変える前に、両者を別々に読むこと。
二つの段階、二つの別々の答え
従来の非同期レプリカは二つの仕事をする。受信側はソースに接続し、イベントを引き出してローカルのリレーログに書き込む。適用側はそのリレーログを読み、イベントをレプリカ上で実行する。経路が切れると、受信側は即座に止まるが、適用側はディスク上にすでにある滞留分を処理し続ける。したがって一つの障害は、接続は戻ったのか、溜まった作業は適用されたのかという二つの異なる問いを生む。両者を一つの問いとして扱うと、二つの状態が平均化されて誤解を招く答えになる。
受信側の回復は経路が生きていることを示す。適用側がどれだけ遅れているか、切断中にエラーに遭遇したかについては何も語らない。
正しいステートメントでチャネルを読む
MySQL 8.4では、SHOW REPLICA STATUS は設定されたチャネルごとに一行を返すので、一覧の先頭ではなく意図するチャネルの行を読むこと。Replica_IO_Running は接続済みの受信側と、接続中または停止中の受信側を区別し、Replica_SQL_Running は適用側を表す。再接続してすぐ失敗する受信側は、どのステータスフラグにも表示されないメッセージを残すので、その横のエラー列も読むこと。古いリリースは別の列名を使うので、コマンド名を変えるだけで古い手順を訳してはいけない。
ソースの同一性と設定されたフィルタも確認すること。誤ったソースを指すレプリカや、思っているより狭くフィルタされたレプリカは、期待とは違うものを複製しながら健全だと報告する。
遅延ゼロという数字がなぜ嘘をつけるのか
遅延の値は、最後に適用されたイベントのタイムスタンプを現在時刻と比較する。受信側が一時間止まっていた場合、適用側は滞留分を処理し終えて受け取ったものの末尾に達することがあり、その時点で数字はゼロに落ちるが、それでもレプリカはソースより一時間遅れている。この指標が測るのは適用側の待ち行列であり、レプリカの最新性ではない。
代わりに、実行済みのトランザクションをソースが持つ内容と比較すること。その比較は停止した受信側にも耐える。
実際の復旧可能期間は保持設定が決める
追いつくには、ソースがレプリカに必要なトランザクションをまだ保持している必要がある。それらが削除されれば、レプリカは取得できず、何度再接続しても変わらない。
GTIDの自動位置決めでは、レプリカはソースがもう保持していない履歴を要求して続行を拒否するため、失敗は明示的である。その場合の選択肢は、まだ持っているソースから欠けたイベントを取得するか、バックアップから再構築して追いつかせるかである。隙間を飛ばすことは追いつくことではなく、データが静かに不完全なレプリカを残す。その三つの数字、すなわち予想される障害時間とソースのバイナリログ保持と変更率が、障害がそもそも復旧可能かを決めるので、それらを比較して期間を計画すること。
指標の色ではなく、追いついたことを検証する
名前解決とトランスポートの安全性を含めて経路を復旧し、既存のチャネルが独自のポリシーで再接続するかを見守る。介入する前に定めた間隔を与え、その間隔の両端で受信と適用の進捗を記録する。再起動したチャネルと最新のチャネルは別の所見である。
古い滞留分の末尾ではなく、適用側がソースの現在位置に達したことを確認する。失敗したイベントが一つあると進行は止まるのに受信側は接続済みと報告し続けるため、適用側にエラーが待っていないかも確認する。その後、チャネル名、両段階の状態、実行済みの位置、時刻という証拠を記録する。緑の指標は主張であり、位置は事実である。