DRBDのon-io-errorオプションにpass-onを指定すべきではない理由

on-io-errorの3つのオプション

DRBDのon-io-errorオプションは、下位デバイスにIOエラーがあった際の挙動を制御します。
on-io-errorオプションが使用されるのは、DRBDでレプリケーションするディスクに故障があり、書き込み/読み込みエラーが発生した場合です。この時に行う処理を指定します。

指定できる値は、以下の3つです。

  • pass_on
    ノードはディスクのステータスをInconsistentにし、I/Oエラーを起こしたブロックに対応するビットマップにマークをつける。そして、リモートのノード上で入出力を再度行う。
  • call-local-io-error
    ハンドラスクリプトの”local-io-error”を呼び出して実行する。
  • detach
    低レベルデバイスを切り離して、ディスクレスモードで処理を続行する。

ユーザーズガイドにはこのように書かれていますので、どれを使っても問題ないと感じると思います。
しかし、実際にはpass_onを使用することは強く非推奨です。

pass_onはなぜ非推奨なのか

pass_onを指定した時にどういった動作になるのかシナリオごとに説明します。

シナリオ1:セカンダリでIOエラーがあった場合

セカンダリでIOエラーがあれば、まずセカンダリがInconsistent状態になります。
そして、この書き込みができないブロックはビットマップ上に記録が行われます。
IOエラーがあってもセカンダリのディスクはアタッチされたままであり、書き込み処理自体は試行を続けます。
なお、書き込み処理がプライマリかセカンダリのどちらか一方でも行えている場合には、IOエラーがあったことはファイルシステムなどDRBDの上位の層からは判断できません。(syslogなどにDRBDのログメッセージは書き込まれます)
一方プライマリ側では、セカンダリ側でのIOエラーの原因によってはIOエラーの通知があるまで何度も書き込み処理を繰り返すため、書き込み速度の著しい低下が発生する場合があります。

このように、on-io-errorにpass_onを設定することにメリットは何もなく、書き込み遅延が発生するリスクのみがあります。

シナリオ2:プライマリでIOエラーがあった場合

まずプライマリがinconsistent状態になります。
そして書き込みが行えなかったブロックについてはビットマップに記録が行われます。
しかし、書き込みはセカンダリ側に行うことができます。このために、ファイルシステムなどDRBDの上位の層にはIOエラーが発生していたことは通知されません。(syslogなどにDRBDのログメッセージは書き込まれます)この際において、書き込み速度低下が発生します。


また、特に注意を払うべきことは、同時にネットワーク障害が発生した場合です。ビットマップに記録が行われたブロックの読み込みは、ローカルディスクからは行われず、リモート(セカンダリ)ノードから読み込まれることです。
この状態でプライマリとセカンダリ間のレプリケーションリンクが途切れてしまった場合、問題が発生します。
書き込み処理を続け(試み)ようとしても、読み込みが処理が行えていませんので、そのまま使用するとデータ整合性に深刻な問題が発生してしまうのです。

再度繰り返しますが・・・

on-io-errorをpass_onにすることは、通常は強く非推奨です。
使用することができるのは非常に限られた状況になりますし、そこでもIOエラーが連続して発生した場合には深刻な問題を引き起こす危険性があります。
on-io-errorにはpass_onは設定しないでください