[pgpool-general-jp: 110] Re: notice_backend_error(1) in do_child()
Tatsuo Ishii
ishii @ sraoss.co.jp
2007年 4月 15日 (日) 20:30:57 JST
石井です.
> > 現在 pgpool-II 1.0.2 を試してみています。
> >
> > 全部一台のマシン(FreeBSD 6.2R)で試していて、バックエンドをポート番号
> > を変えて三つ立ち上げています。
> >
> > 主な設定は以下の状態です。
> >
> > replication_mode = true
> > replication_strict = true
> > load_balance_mode = false
> > replication_stop_on_mismatch = true
> >
> >
> > このとき、バックエンドのうち一台だけがデータが狂ってしまった時を想定
> > してテストをしていた所、replication_stop_on_mismatch を true にしてい
> > るので、バックエンドのうちひとつが切り離される、という所までは想定通り
> > にいきました。
> >
> > ところが、切り離されるバックエンドが想定と異なっていました。
> >
> > 今回、node_id == 2 のデータだけを狂ったものにして、SELECT 文の返り値
> > が異なるような状態にしています。
> > その際、以下のようなログを出しています。
> >
> > read_kind_from_backend: read kind from 0 th backend D NUM_BACKENDS: 3
> > read_kind_from_backend: read kind from 1 th backend D NUM_BACKENDS: 3
> > read_kind_from_backend: read kind from 2 th backend C NUM_BACKENDS: 3
> > pool_process_query: 2 th kind C does not match with master connection kind D
> > notice_backend_error: 1 failover request from pid 20707
> > failover_handler called
> >
> > このように、node_id == 2 のバックエンドを切り離そうとしている所はい
> > いのですが、実際には真ん中の node_id == 1 が切り離されてしまいました。
> >
> > ちょっとソースを追ってみたところ、child.c の do_child() で
> >
> > /* fatal error occured. just exit myself... */
> > case POOL_FATAL:
> > notice_backend_error(1);
> > child_exit(1);
> > break;
> >
> > という部分を見付けました。ここで notice_backend_error(1) と定数 1 を渡
> > しているので、毎回 node_id == 1 なバックエンドを切り離してしまっている
> > ようです。
> >
> > この定数 1 の部分に、適切な node_id を渡してやればいいのかな、と思っ
> > たのですが、mismatch を検出する read_kind_from_backend() から、上記の
> > case POOL_FATAL までの経路で、どの node_id のバックエンドが POOL_FATAL
> > の原因なのか、を渡すのにどういう形を想定して設計されているのかがわから
> > なかったので、ここの定数部分をどう変えてやればいいのかわかりませんでし
> > た。
> >
> > 適切なバックエンドが切り離されるようにするには、どうしたらいいでしょ
> > うか?
>
> ノード間でデータが不一致になったときには,一般的にはどのノードが正しく
> て,どのノードが間違っているかを確実に断定する方法はありません.考えら
> れる方法としては,
>
> 1) master node(上の例で言うと,node id = 0)を正しいものと信じて一致し
> ないnodeを切り離す
>
> 2) 各nodeの結果を比較し,多数派を正しいものとし,それ以外のnodeを切り
> 離す
>
> の2つがあります.今考えているのは,基本的に2)で判断し,それができない
> 場合(ノード数が偶数でかつ判断が分かれたとき)は1)の基準を採用する,とい
> う方法です(TODO項目).
>
> ちなみに現在のpgpool-IIで,kind mismatchのときに切り離すnode idが1に固
> 定されているのは,たぶんnode数が2までのpgpoolのコードをそのまま持って
> きたからで,node数が3つ以上だとこのような現象になってしまいます.つま
> りバグですね.ちょっと対策を考えてみます.
多数決はちょっとすぐには実装が難しいので,1)を実装しました.
CVS HEADか,以下のパッチを試していただけるでしょうか?
--
Tatsuo Ishii
SRA OSS, Inc. Japan
--------------------------- cut here -------------------------
Index: pool_process_query.c
===================================================================
RCS file: /cvsroot/pgpool/pgpool-II/pool_process_query.c,v
retrieving revision 1.12
diff -c -r1.12 pool_process_query.c
*** pool_process_query.c 12 Apr 2007 08:30:43 -0000 1.12
--- pool_process_query.c 15 Apr 2007 11:24:47 -0000
***************
*** 4095,4104 ****
i, k, *kind);
pool_send_error_message(frontend, MAJOR(backend), "XX000",
"kind mismatch between backends", "",
! "check data consistency between master and secondary", __FILE__, __LINE__);
if (pool_config->replication_stop_on_mismatch)
! return POOL_FATAL;
else
return POOL_ERROR;
}
--- 4095,4107 ----
i, k, *kind);
pool_send_error_message(frontend, MAJOR(backend), "XX000",
"kind mismatch between backends", "",
! "check data consistency between master and other db node", __FILE__, __LINE__);
if (pool_config->replication_stop_on_mismatch)
! {
! notice_backend_error(i);
! child_exit(1);
! }
else
return POOL_ERROR;
}
--------------------------- cut here -------------------------
pgpool-general-jp メーリングリストの案内