[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 メーリングリストの案内