Pgpool-IIの子プロセス関連のパラメータを調べた

# はじめに
- この記事では、Pgpool-IIの挙動確認の結果だけ記載し、Pgpool-II 3.7 の構築手順とかは書かない。
    - インストールする人は[公式マニュアル](http://www.pgpool.net/docs/latest/ja/html/installation.html)を参照する
- Pgpool-IIの挙動確認として以下のパラメータ（子プロセス関連）について確認する
    - child_life_time
        - 一定時間クライアントから接続のない状態の子プロセスを再起動する
    - child_max_connections
        - 指定した受付回数を超えた子プロセスを再起動する
    - connection_life_time
        - Pgpool-II、PostgreSQL間でpoolling中のセッションを指定した時間で切断する
    - client_idle_limit
        - 一定期間通信がないクライアントとPgpool-II間のセッションを切断する。
- 確認を行った構成：VM1台の上でPgpool-IIとPostgreSQLを同居。
    - Pgpool-II 3.7.1
    - PostgreSQL 10.1

# 環境構築でやったこと

今回は手元で確認用に以下の手順で構築した。

- Pgpoolコミュニティから取得したRPMを取得、インストールする
    - postgresユーザでpgpool-IIを起動できるように設定する。
        - /var/run/pgpool-IIとかにpostgresユーザのRead/Write権限を付与
- 設定ファイル編集
    - (Pgpool-II) /etc/pgpool-II/pgpool.confを作成する
        - poolling機能のみ使用する。
    - (Pgpool-II) pcp.confを設定する。
    - (PostgreSQL) ローカル接続なのでpostgresql.conf、pg_hba.confはデフォルトで使用する。
- PostgreSQLを起動する
- Pgpool-II起動
    - 必ずPostgreSQLが起動したあと（接続を受け付けるようになってから）に起動させる。

# パラメータの挙動確認の結果

各パラメータがどこに影響しているのか図で表すと。。。こんな感じです。

<img width="395" alt="image.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/125929/ff68ae98-8873-f094-2efb-b196ad412c88.png">


## 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が発生するような設定にしないようにすればいい気がするので、やはりあまり設定することはないような気もする。