[pgsql-jp: 38514] Re: pgpoolがささり、子プロセスがゾンビになる現象が発生
Tatsuo Ishii
ishii @ sraoss.co.jp
2007年 6月 20日 (水) 07:45:27 JST
石井です.
引用されている記事にもありますが,そのときはシグナルハンドラの中で
fork()することが本当に駄目なのかどうか分かりませんでした.ここに確信が
持てないので,いまだ修正していません.
--
Tatsuo Ishii
SRA OSS, Inc. Japan
> 高尾です。
>
> pgpool-3.1.2をDebian GNU/Linux sargeで使用しています。
> ある程度pgpoolを動かし続けていると、pgpoolのプロセスがささり、未接続の
> pgpoolの子プロセスがゾンビ状態になる現象が発生しています。3日で発生す
> ることもあれば、1ヶ月なこともあり、とりあえず、1日1回pgpoolを再起動さ
> せるようにして、その場をしのいでいます。
>
> それで、pgpoolがささったときにgdbでアタッチしてバックトレースを確認しました。
> それが以下です。
>
> ----- ここから -----
> Using host libthread_db library "/lib/tls/libthread_db.so.1".
> `system-supplied DSO at 0xffffe000' has disappeared; keeping its symbols.
> 0x4014a321 in pthread_setcanceltype () from /lib/tls/libc.so.6
> #0 0x4014a321 in pthread_setcanceltype () from /lib/tls/libc.so.6
> #1 0x4010fc82 in fork () from /lib/tls/libc.so.6
> #2 0x0804a1ce in fork_a_child (unix_fd=-4, inet_fd=-4) at main.c:515
> #3 0x0804ad78 in reap_handler (sig=17) at main.c:989
> #4 <signal handler called>
> #5 0x400d8bd6 in mallopt () from /lib/tls/libc.so.6
> #6 0x400d7c43 in malloc () from /lib/tls/libc.so.6
> #7 0x400c710f in fgets () from /lib/tls/libc.so.6
> #8 0x400c71cf in fopen () from /lib/tls/libc.so.6
> #9 0x401a4d25 in _nss_files_gethostbyaddr_r () from /lib/tls/libnss_files.so.2
> #10 0x401a4297 in _nss_files_gethostbyname_r () from /lib/tls/libnss_files.so.2
> #11 0x4015119f in gethostbyname_r () from /lib/tls/libc.so.6
> #12 0x40150a96 in gethostbyname () from /lib/tls/libc.so.6
> #13 0x080567ca in connect_inet_domain_socket (secondary_backend=1)
> at pool_connection_pool.c:340
> #14 0x0804c3ac in health_check () at child.c:1100
> #15 0x080499eb in main (argc=2, argv=0xbfffef64) at main.c:313
> ----- ここまで -----
>
> 上記を元に、シグナルハンドラの中で、forkしている可能性があると思い、ソー
> スコードを確認しました。すると、main.cにSIGCHLDのシグナルハンドラで
> forkしていることが分かりました。
>
> ----- ここから -----
> ...
> pool_signal(SIGCHLD, reap_handler);
> ...
> static RETSIGTYPE reap_handler(int sig)
> {
> ...
> /* if found, fork a new child */
> if (!switching && !exiting && status)
> {
> pids[i] = fork_a_child(unix_fd, inet_fd);
> pool_debug("fork a new child pid %d", pids[i]);
> break;
> }
> ...
> }
> ----- ここまで -----
>
> 今回、私の環境で発生したpgpoolがささり、子プロセスがゾンビになる現象は、
> シグナルハンドラ中でforkしていることが原因ではないかと想像しています。
>
> 過去のMLでは、次のようなものがありました。
>
> ----- ここから -----
> Subject: [pgsql-jp: 35382] Re: 太る pgpool
> 2005年 5月 14日 (土) 09:17:56 JST
> http://ml.postgresql.jp/pipermail/pgsql-jp/2005-May/018942.html
>
> > main -> reap_handler -> fork_a_child -> fork -> __i686.get_pc_thunk という
> > 経路で来て、そこで固まっているようです。
> >
> > fork() を signal handler の中から呼んでますが、これがまずいということは
> > ないでしょうか。
>
> 「signal handlerの中ではなるべく余計なことをするな」ということは教訓と
> して良く言われるのですが,fork()がタブーなのかはよくわかりません.もう
> ちょっと調べてみようと思いますが...
>
> > そして、子 pgpool の看取りは waitpid(WNOHANG) でやっていますし、
> > 子の再起動のための fork_a_child(reap_handler)を signal handler から
> > 呼ぶのではなく、main() のメインループの中から定期的にキックするようにする、
> > というアイディアもあると思うんですがいかがでしょう?
>
> とりあえずこちらの方向で検討します.heal checkを動かしているときに,起
> 動するタイミングを探すのがちょっと微妙ではありますが.
> ----- ここまで -----
>
> 上記はかなり前の話しなので、修正されているのかなと思っていましたが、
> ソースコードを確認したところ、現在も同様の状態だと考えています。
> 「main() のメインループの中から定期的にキックするようにする」というの
> は、どうなのでしょうか。何か難しい点や、問題などがあったのでしょうか。
>
> ---
> 株式会社ネットワーク応用通信研究所 研究員 高尾 宏治
> 〒690-0826 島根県松江市学園南二丁目12番5号
> HOYOパークサイドビル・2F
> TEL:0852-28-9280 FAX:0852-28-9281
> URL:http://www.netlab.jp/
> e-mail:kouji @ netlab.jp
Q
pgsql-jp メーリングリストの案内