はじめに
- この記事では、Pgpool-IIの挙動確認の結果だけ記載し、Pgpool-II 3.7 の構築手順とかは書かない。
- インストールする人は公式マニュアルを参照する
- Pgpool-IIの挙動確認として以下のパラメータ(子プロセス関連)について確認する
- child_life_time
- 一定時間クライアントから接続のない状態の子プロセスを再起動する
- child_max_connections
- 指定した受付回数を超えた子プロセスを再起動する
- connection_life_time
- Pgpool-II、PostgreSQL間でpoolling中のセッションを指定した時間で切断する
- client_idle_limit
- 一定期間通信がないクライアントとPgpool-II間のセッションを切断する。
- child_life_time
- 確認を行った構成:VM1台の上でPgpool-IIとPostgreSQLを同居。
- Pgpool-II 3.7.1
- PostgreSQL 10.1
環境構築でやったこと
今回は手元で確認用に以下の手順で構築した。
- Pgpoolコミュニティから取得したRPMを取得、インストールする
- postgresユーザでpgpool-IIを起動できるように設定する。
- /var/run/pgpool-IIとかにpostgresユーザのRead/Write権限を付与
- postgresユーザでpgpool-IIを起動できるように設定する。
- 設定ファイル編集
- (Pgpool-II) /etc/pgpool-II/pgpool.confを作成する
- poolling機能のみ使用する。
- (Pgpool-II) pcp.confを設定する。
- (PostgreSQL) ローカル接続なのでpostgresql.conf、pg_hba.confはデフォルトで使用する。
- (Pgpool-II) /etc/pgpool-II/pgpool.confを作成する
- PostgreSQLを起動する
- Pgpool-II起動
- 必ずPostgreSQLが起動したあと(接続を受け付けるようになってから)に起動させる。
パラメータの挙動確認の結果
各パラメータがどこに影響しているのか図で表すと。。。こんな感じです。
child_life_time
- クライアントからの接続終了後、指定した時間後にPgpool-IIの子プロセスが再起動される。
- もちろん接続中のコネクションはそのまま終了されない。
- 一度も接続に使用されていない子プロセスも再起動の対象外となる。
- 再起動対象の子プロセスでpoolingされているPostgreSQLとのセッションは切断される。
以下、確認結果。
[postgres@yama.com]$ ps -ef | grep pool
postgres 6628 5890 0 17:51 pts/0 00:00:00 pgpool -f /etc/pgpool-II/pgpool.conf -n
postgres 6629 6628 0 17:51 pts/0 00:00:00 pgpool: wait for connection request
postgres 6630 6628 0 17:51 pts/0 00:00:00 pgpool: wait for connection request
postgres 6631 6628 0 17:51 pts/0 00:00:00 pgpool: wait for connection request
postgres 6632 6628 0 17:51 pts/0 00:00:00 pgpool: wait for connection request
★ postgres 6633 6628 0 17:51 pts/0 00:00:00 pgpool: postgres testdb ::1(49310) idle
postgres 6634 6628 0 17:51 pts/0 00:00:00 pgpool: PCP: wait for connection request
postgres 6635 6628 0 17:51 pts/0 00:00:00 pgpool: worker process
postgres 6636 6628 0 17:51 pts/0 00:00:00 pgpool: health check process(0)
postgres 6696 5208 0 17:53 pts/1 00:00:00 grep --color=auto pool
↓ 指定した時間経過後
[postgres@yama.com]$ ps -ef | grep pool
postgres 6628 5890 0 17:51 pts/0 00:00:00 pgpool -f /etc/pgpool-II/pgpool.conf -n
postgres 6629 6628 0 17:51 pts/0 00:00:00 pgpool: wait for connection request
postgres 6630 6628 0 17:51 pts/0 00:00:00 pgpool: wait for connection request
postgres 6631 6628 0 17:51 pts/0 00:00:00 pgpool: wait for connection request
postgres 6632 6628 0 17:51 pts/0 00:00:00 pgpool: wait for connection request
postgres 6634 6628 0 17:51 pts/0 00:00:00 pgpool: PCP: wait for connection request
postgres 6635 6628 0 17:51 pts/0 00:00:00 pgpool: worker process
postgres 6636 6628 0 17:51 pts/0 00:00:00 pgpool: health check process(0)
★ postgres 6736 6628 0 17:54 pts/0 00:00:00 pgpool: wait for connection request
postgres 6766 5208 0 17:55 pts/1 00:00:00 grep --color=auto pool
ログには以下のように出力される。
LOG: child process with pid: 6633 exits with status 256
LOG: fork a new child process with pid: 6736
child_max_connections
- SELECTを2回実行した後に子プロセスが再起動しているのが確認できた。
- 挙動確認のため、設定値を「child_max_connections = 2」とした
以下、確認結果。
Pgpool-IIが起動した状態にしておき。
[postgres@yama.com]$ ps -ef | grep pool
postgres 7440 5890 0 18:17 pts/0 00:00:00 pgpool -f /etc/pgpool-II/pgpool.conf -n
postgres 7441 7440 0 18:17 pts/0 00:00:00 pgpool: wait for connection request
postgres 7442 7440 0 18:17 pts/0 00:00:00 pgpool: wait for connection request
postgres 7443 7440 0 18:17 pts/0 00:00:00 pgpool: wait for connection request
postgres 7444 7440 0 18:17 pts/0 00:00:00 pgpool: wait for connection request
postgres 7445 7440 0 18:17 pts/0 00:00:00 pgpool: wait for connection request
postgres 7446 7440 0 18:17 pts/0 00:00:00 pgpool: PCP: wait for connection request
postgres 7447 7440 0 18:17 pts/0 00:00:00 pgpool: worker process
postgres 7448 7440 0 18:17 pts/0 00:00:00 pgpool: health check process(0)
postgres 7463 5208 0 18:18 pts/1 00:00:00 grep --color=auto pool
SELECTを2回実行する。
[postgres@yama.com]$ psql testdb -U postgres -p 9999 -h localhost -c "SELECT now()"
now
-----------------------------
2018-01-14 18:17:59.6316+09
(1 row)
[postgres@yama.com]$ psql testdb -U postgres -p 9999 -h localhost -c "SELECT now()"
now
-------------------------------
2018-01-14 18:18:12.691015+09
(1 row)
PostgreSQLへの接続に使用していた子プロセスが再起動される。
[postgres@yama.com]$ ps -ef | grep pool
postgres 7440 5890 0 18:17 pts/0 00:00:00 pgpool -f /etc/pgpool-II/pgpool.conf -n
postgres 7441 7440 0 18:17 pts/0 00:00:00 pgpool: wait for connection request
postgres 7442 7440 0 18:17 pts/0 00:00:00 pgpool: wait for connection request
postgres 7443 7440 0 18:17 pts/0 00:00:00 pgpool: wait for connection request
postgres 7444 7440 0 18:17 pts/0 00:00:00 pgpool: wait for connection request
postgres 7446 7440 0 18:17 pts/0 00:00:00 pgpool: PCP: wait for connection request
postgres 7447 7440 0 18:17 pts/0 00:00:00 pgpool: worker process
postgres 7448 7440 0 18:17 pts/0 00:00:00 pgpool: health check process(0)
★ postgres 7479 7440 0 18:18 pts/0 00:00:00 pgpool: wait for connection request
postgres 7484 5208 0 18:18 pts/1 00:00:00 grep --color=auto pool
ログはchild_life_timeのときと同じメッセージが出力される。
connection_life_time
- poolingされていたセッションが指定した時間後に切断されていることを確認できた。
- Pgpool-IIのログには、切断に関するメッセージは出力されない。
- クライアントから接続中のセッションは当然切断されない。
以下、確認結果。
適当なSQLを実行して、セッションをpoolingする。
[postgres@yama.com]$ psql testdb -U postgres -p 9999 -h localhost -c "select now()"
now
-------------------------------
2018-01-14 18:58:35.910537+09
(1 row)
poolingされたセッションを確認する。
[postgres@yama.com]$ ps -ef | grep postgres
・・・
postgres 9003 5627 0 18:58 ? 00:00:00 postgres: postgres testdb ::1(50904) idle
・・・
指定した時間経過後にセッションが切られていることを確認できた
[postgres@yama.com]$ ps 9003
PID TTY STAT TIME COMMAND
client_idle_limit
- 指定した時間が経過すると、クライアントからのPgpool-IIへのセションが切断されるのを確認した。
- idle in transaction のセッションでも強制的に切断される。
- 子プロセスは再起動されない。
以下、確認結果。
とりあえず、Pgpool-II経由でPostgreSQLに接続し、あとは放っておく。
[postgres@yama.com]$ psql testdb -U postgres -p 9999 -h localhost
psql (10beta1)
Type "help" for help.
testdb=#
idle状態で接続されているのがわかる。
[postgres@yama.com]$ ps -ef | grep pool
postgres 8591 8497 0 18:45 pts/2 00:00:00 tail -F /var/lib/pgsql/pgpool_log/today.log
postgres 9852 5890 0 19:24 pts/0 00:00:00 pgpool -f /etc/pgpool-II/pgpool.conf -n
postgres 9853 9852 0 19:24 pts/0 00:00:00 pgpool: wait for connection request
★ postgres 9854 9852 0 19:24 pts/0 00:00:00 pgpool: postgres testdb ::1(52326) idle
postgres 9855 9852 0 19:24 pts/0 00:00:00 pgpool: wait for connection request
postgres 9856 9852 0 19:24 pts/0 00:00:00 pgpool: wait for connection request
postgres 9857 9852 0 19:24 pts/0 00:00:00 pgpool: wait for connection request
postgres 9858 9852 0 19:24 pts/0 00:00:00 pgpool: PCP: wait for connection request
postgres 9859 9852 0 19:24 pts/0 00:00:00 pgpool: worker process
postgres 9860 9852 0 19:24 pts/0 00:00:00 pgpool: health check process(0)
postgres 9995 5208 0 19:28 pts/1 00:00:00 grep --color=auto pool
時間経過後、セッションが切断される。
[postgres@yama.com]$ ps -ef | grep pool
postgres 8591 8497 0 18:45 pts/2 00:00:00 tail -F /var/lib/pgsql/pgpool_log/today.log
postgres 9852 5890 0 19:24 pts/0 00:00:00 pgpool -f /etc/pgpool-II/pgpool.conf -n
postgres 9853 9852 0 19:24 pts/0 00:00:00 pgpool: wait for connection request
★ postgres 9854 9852 0 19:24 pts/0 00:00:00 pgpool: wait for connection request
postgres 9855 9852 0 19:24 pts/0 00:00:00 pgpool: wait for connection request
postgres 9856 9852 0 19:24 pts/0 00:00:00 pgpool: wait for connection request
postgres 9857 9852 0 19:24 pts/0 00:00:00 pgpool: wait for connection request
postgres 9858 9852 0 19:24 pts/0 00:00:00 pgpool: PCP: wait for connection request
postgres 9859 9852 0 19:24 pts/0 00:00:00 pgpool: worker process
postgres 9860 9852 0 19:24 pts/0 00:00:00 pgpool: health check process(0)
postgres 10044 5208 0 19:30 pts/1 00:00:00 grep --color=auto pool
切断時には以下のログが出力される。
2018-01-14 19:28:47: pid 9854: LOG: new connection received
2018-01-14 19:28:47: pid 9854: DETAIL: connecting host=::1 port=52326
2018-01-14 19:29:48: pid 9854: ERROR: unable to read data
2018-01-14 19:29:48: pid 9854: DETAIL: child connection forced to terminate due to client_idle_limit:60 is reached
さいごに
Pgpool-IIの子プロセスを定期的に再起動させたい場合や、開きっぱなしのトランザクションの発生を抑制したい場合はこれらの設定を利用するのは有効だということがわかりました。システムの特徴に合わせて、どのパラメータを使用するのか、組み合わせるのかは変わると思う。
poolingしているセッションを敢えて切断したいという状況はあまり思いつかないので、connection_life_timeは基本無効でいいのかもしれない。poolingしすぎ等によるDBのメモリの消費を押さえる場合には設定することはあるかもしれないけど、そもそも無駄なpoolingが発生するような設定にしないようにすればいい気がするので、やはりあまり設定することはないような気もする。