[pgpool-general-jp: 741] Re: child.c: do_accept() と timeout

Jun Kuriyama kuriyama+ml @ s2factory.co.jp
2010年 2月 22日 (月) 23:25:20 JST


 なんとも中途半端なメールに対してヒントありがとうございます。

At Mon, 22 Feb 2010 13:40:29 +0900 (JST),
ishii @ sraoss.co.jp wrote:
> >  また、今の child.c の実装では、最初接続を受けるまでは connected = 0
> > で、その状態で child_life_time を経過すると、do_child() の timeout =
> > {0, 0} となってしまい、次の do_accept() ではタイムアウト無しの状態で
> > select() に入る。(意図的?)
> 
> はい、これは意図的です。まだ何にも働いていないプロセスが
> child_life_timeごとにselectに入るのも無駄なので。

 確かに。

> >  do_accept() から戻った後に、timeout.tv_sec = child_life_time と戻し
> > てやると、ちゃんと select() が EINTR で戻って for(;;) をやり直して
> > check_stop_request() まで到達するようです。
> 
> これは、EINTRで戻っているのではなく、何らかの理由(pcp_recovery_nodeが
> 刺さったから?)で、select実行中に割り込みが禁止されているからではない
> でしょうか?そうだとすれば、pcp_recovery_nodeが刺さったときに、割り込
> み禁止にならないように修正するのが本来のような気がします。

 そうですよね……。

> timeoutを設定するとEINTRでselectから戻る、そうでなければ戻らないという
> のは確かでしょうか?

 こちら、追跡してみます!

> また、「pcp_recovery_nodeが刺ささる」というのは具体的にどういう状態か
> わかりますか?

 pgpool の PCP プロセスが process title が

pgpool: PCP: processing a request (pgpool)

のままの状態になってしまっています。この時、新たな PCP リクエストを投
げても受け付けてくれず、pcp_* コマンドが使えない状態になってしまいます。
 tos を process title に表示するようにしたら

pgpool: PCP: processing a request 'O' (pgpool)

となったので、'O' の処理中のようです。

 この状態になるには(ミスが重なっているので稀なケースなのですが)、

(1) 1st stage スクリプトにおいて、pg_xlog ディレクトリをコピー対象とす
    るのを忘れてしまい
(2) その結果、pgpool_remote_start スクリプトでリカバリ先の postgresql
    が起動時に panic してしまい失敗してしまい
(3) さらにその pgpool_remote_start スクリプトがその際に正しく non-0 を
    返さずに 0 を返して正常終了してしまう

という条件になります。(3) の状態で processing a request 'O' のままとなっ
てしまうので、^C とかしなくてもそうなりますね。前のメールは間違い。

 で、なぜ止まっているのか、をもう少し追ってみたところ、recovery.c の
check_postmaster_started() から帰ってきていませんでした。ここの do {}
while() ループは i < WAIT_RETRY_COUNT で抜けるはずだし……、と思ったら!
 何やら怪しげな goto Retry; 行があって、そのせいで無限ループになって
いるようです。このままだと dbname を設定している意味も無いので、何かが
間違っていると思うのですが、ここはどう直せばいいでしょうか?


-- 
Jun Kuriyama <kuriyama @ s2factory.co.jp> // S2 Factory, Inc.


pgpool-general-jp メーリングリストの案内