Pgpool-IIのタイムアウト関連のパラメータ及び設定など †
ざっと調べたところ、以下のようになっている。特に、connect_timeoutは、共通して色々なところで使われ、health_check_timeoutとも関連している。システムのタイムアウトの設計をするときには要確認。
クエリ実行中の動作 †
- backendからの応答を、
select
で30secタイムアウトで待つ。 - 30secタイムアウトした後は、frontendに対してダミーのパラメータ状態報告(ParameterStatus (B))を送り、frontendへのソケット書き込みが成功するか否かをチェックしている(ただし、TCPではfrontendの接続が既に閉じられていて
FIN
を送られていてもwrite
は可能である。最初のwrite
でRST
が誘発され、続くwrite
でSIGPIPE
が送られることとなる)。
参考
- wait_for_query_response() - on https://git.postgresql.org/gitweb/?p=pgpool2.git
- PostgreSQL 9.6.5文書 51.5. メッセージの書式 - on https://www.postgresql.jp/document/9.6/html/
- http://www.kt.rim.or.jp/~ksk/sock-faq/unix-socket-faq-ja-2.html
- UNIXネットワークプログラミング〈Vol.1〉ネットワークAPI:ソケットとXTI - on http://www.amazon.co.jp
以下はwait_for_query_response
関数実行時のスタックトレースである。pool_check_fd
内でselect
を使ってbackendの応答を待つ。
* frame #0: 0x000000010cf0100f pgpool`pool_check_fd(cp=0x000000010d15f078) at pool_process_query.c:627 frame #1: 0x000000010cf00e53 pgpool`wait_for_query_response(frontend=0x00007f967b817438, backend=0x000000010d15f078, protoVersion=3) at pool_process_query.c:494 frame #2: 0x000000010cf00cfd pgpool`wait_for_query_response_with_trans_cleanup(frontend=0x00007f967b817438, backend=0x000000010d15f078, protoVersion=3, pid=-2027356160, key=-239764672) at pool_process_query.c:453 frame #3: 0x000000010cf2c533 pgpool`pool_send_and_wait(query_context=0x00007f967c803038, send_type=1, node_id=0) at pool_query_context.c:817 frame #4: 0x000000010cf11121 pgpool`SimpleQuery(frontend=0x00007f967b817438, backend=0x00007f967b801648, len=19, contents="select * from foo;") at pool_proto_modules.c:635 frame #5: 0x000000010cf18cde pgpool`ProcessFrontendResponse(frontend=0x00007f967b817438, backend=0x00007f967b801648) at pool_proto_modules.c:2358 frame #6: 0x000000010cf00a60 pgpool`read_packets_and_process(frontend=0x00007f967b817438, backend=0x00007f967b801648, reset_request=0, state=0x00007ffee2d2cba4, num_fields=0x00007ffee2d2cbc2, cont="\x01\376) at pool_process_query.c:4731 frame #7: 0x000000010cefebea pgpool`pool_process_query(frontend=0x00007f967b817438, backend=0x00007f967b801648, reset_request=0) at pool_process_query.c:226 frame #8: 0x000000010cef85b3 pgpool`do_child(fds=0x00007f967b402af0) at child.c:383 frame #9: 0x000000010cece480 pgpool`fork_a_child(fds=0x00007f967b402af0, id=0) at pgpool_main.c:607 frame #10: 0x000000010cecb366 pgpool`PgpoolMain(discard_status='\x01', clear_memcache_oidmaps='\0') at pgpool_main.c:363 frame #11: 0x000000010cec9838 pgpool`main(argc=9, argv=0x00007ffee2d377f8) at main.c:318 frame #12: 0x00007fff7502d115 libdyld.dylib`start + 1 frame #13: 0x00007fff7502d115 libdyld.dylib`start + 1
ereport
で、エラーレベルFRONTEND_ERROR
が指定されているので、ここに到達するとスタックの上流のPG_CATCH()
に飛び、さらにPG_RE_THROW()
されsigsetjmp
のPG_exception_stack
で指定されたポイントに制御が移る。エラーハンドリング内では、セッションクローズするための処理を行なっている。ソケットのエラーの場合、バックエンドのコネクションは閉じられる。
(lldb) bt * thread #1, queue = 'com.apple.main-thread', stop reason = step over * frame #0: 0x00000001081bf6cb pgpool`pool_send_frontend_exits(backend=0x00007ff5f4801648) at pool_process_query.c:721 frame #1: 0x00000001081b706f pgpool`backend_cleanup(frontend=0x0000000108330e20, backend=0x00007ff5f4801648, frontend_invalid='\x01') at child.c:491 frame #2: 0x00000001081b60ec pgpool`do_child(fds=0x00007ff5f4600170) at child.c:241 frame #3: 0x000000010818c480 pgpool`fork_a_child(fds=0x00007ff5f4600170, id=0) at pgpool_main.c:607 frame #4: 0x0000000108189366 pgpool`PgpoolMain(discard_status='\x01', clear_memcache_oidmaps='\0') at pgpool_main.c:363 frame #5: 0x0000000108187838 pgpool`main(argc=9, argv=0x00007ffee7a797f8) at main.c:318 frame #6: 0x00007fff6523e115 libdyld.dylib`start + 1 frame #7: 0x00007fff6523e115 libdyld.dylib`start + 1 (lldb) bt * thread #1, queue = 'com.apple.main-thread', stop reason = step in * frame #0: 0x00000001082090ac pgpool`pool_close(cp=0x000000010841d078) at pool_stream.c:117 frame #1: 0x00000001081cb59d pgpool`pool_discard_cp(user="guest", database="test", protoMajor=3) at pool_connection_pool.c:214 frame #2: 0x00000001081b70a2 pgpool`backend_cleanup(frontend=0x0000000108330e20, backend=0x00007ff5f4801648, frontend_invalid='\x01') at child.c:493 frame #3: 0x00000001081b60ec pgpool`do_child(fds=0x00007ff5f4600170) at child.c:241 frame #4: 0x000000010818c480 pgpool`fork_a_child(fds=0x00007ff5f4600170, id=0) at pgpool_main.c:607 frame #5: 0x0000000108189366 pgpool`PgpoolMain(discard_status='\x01', clear_memcache_oidmaps='\0') at pgpool_main.c:363 frame #6: 0x0000000108187838 pgpool`main(argc=9, argv=0x00007ffee7a797f8) at main.c:318 frame #7: 0x00007fff6523e115 libdyld.dylib`start + 1 frame #8: 0x00007fff6523e115 libdyld.dylib`start + 1 (lldb)
参考
- protocol/child.c - on https://git.postgresql.org/gitweb/?p=pgpool2.git
- backend_cleanup() - on https://git.postgresql.org/gitweb/?p=pgpool2.git
参考リンク †
- ファイルオーバ
- コネクションプール
- ヘルスチェック
- その他ソース
- setjmp - on https://linuxjm.osdn.jp/html/LDP_man-pages/man3/setjmp.3.html