DRBDを使っていて、うっかりスプリットブレインになっちゃった時に、リカバリー方法を間違えるとややこしいことになるような気がした(どっちをマスターにするかを間違えると、スレーブでマスターを上書きしてデータのロストとか起きたりしそう)ので、ちょっと試しにスプリットブレイン状態を作ってリカバリーしてみた。

使ったDRBDは8.3.0。インターネットを探してみると、DRBDが動いている状態でネットワークを引っこ抜くとスプリットブレインが発生すると書いてあるサイトもあったので、試しにL2スイッチの電源を落としてみた。そしたら、お互いに「WFConnection」(接続待ち)状態に遷移した。一方、マスター側は「Primary」状態なので、そのままマウントして、アプリケーションからいじってたりしたけれど影響はなかったみたいだ。で、ネットワークを再接続すれば、切断前のPrimary/Secondaryの関係性を維持したまま、「Primary」から「Secondary」への同期が始まった。で、同期が完了すると、「Connection」状態に戻った。

結局、ネットワークがダウンするだけでは、スプリットブレインは発生しないようだ。とりあえず、運用中にLANケーブルが引っこ抜ける的な障害が起こった場合は、LANケーブルを刺し直せば自動で対応してくれそうだ。

次に、意図的にスプリットブレインを作ることにした。L2スイッチを落とすところまでは同じだが、ネットワークが切れていることをいいことに、スレーブ側のマシンを「Primary」状態にしてみた。その後、L2スイッチの電源を入れる。これによって、お互いが「Primary」になっていることを検出するので、スプリットブレインとして、お互いが「StandAlone」に落ちる。ただ、もともと「Primary」になっていたマスター側は、StandAloneになっても「Primary」なので、マウントは可能っぽい。ただ、同期が取られないだけのようだ。dmesgでログを確認すると、以下のようなログが出力されていた。

drbd0: drbd_sync_handshake:

drbd0: self 6ABCC0B39EEBC9D5:03B0E55FA3B63131:38D5407DCCBC17FE:1C2D0C92A346572F

drbd0: peer 705B58F4947E0C9C:03B0E55FA3B63130:38D5407DCCBC17FE:1C2D0C92A346572F

drbd0: uuid_compare()=100 by rule 9

drbd0: Split-Brain detected, manually solved. Sync from this node

さて、両方のノードが「StandAlone」になったときにどう復旧するか。「drbdadm」にはいくつもコマンドオプションがあるので、いろいろ試してみたが、同期を取ってくれない。。。

そんなわけで、DRBDのマニュアルを探してみたら、「Manual split brain recovery」って項目があった。

DRBD detects split brain at the time connectivity becomes available again and the peer nodes exchange the initial DRBD protocol handshake. If DRBD detects that both nodes are (or were at some point, while disconnected) in the primary role, it immediately tears down the replication connection.

DRBDは、コネクティビティが復活した時や、同期相手とDRBD Protocolによるハンドシェイクを行う時にスプリットブレインを検出する。DRBDが両方のノードがPrimary(role)になっている(もしくは、接続が切れている、どこかの時点でPrimaryになっていた)場合、レプリケーションの接続をすぐに切断する。

After split brain has been detected, one node will always have the resource in a StandAlone connection state. The other might either also be in the StandAlone state (if both nodes detected the split brain simultaneously), or in WFConnection (if the peer tore down the connection before the other node had a chance to detect split brain).

スプリットブレインを検出した後では、一方のノードはずっと「StandAlone」になっていて、両方のノードが同時にスプリットブレインを検出していれば、もう一方のノードも「StandAlone」になっているかもしれないし、もう一つのノードがスプリットブレインを検出する前にコネクションを落としていれば、「WFConnection」になっているかもしれない。

At this point, unless you configured DRBD to automatically recover from split brain, you must manually intervene by selecting one node whose modifications will be discarded (this node is referred to as the split brain victim). This intervention is made with the following commands:

DRBDを自動的にスプリットブレインから復旧するように設定していなければ、こうなった時に、どっちのノードの変更を破棄するかを選択して、手動で介入する必要がある。この介入は、このコマンドで行われる。

と。

マスターとなる側では以下のコマンドを実行するらしい。

drbdadm connect resource

スレーブとなる側(つまり、変更点があっても破棄される側)では、以下のコマンドを実行するらしい。

drbdadm secondary resource

drbdadm — –discard-my-data connect resource

…というわけで、やってみたら、無事にConnection状態に戻った。