※この記事にはアフィリエイト広告(プロモーション)が含まれます。
PostgreSQL は接続数が max_connections に達すると新しい接続を拒否します。この記事の出力は PostgreSQL 18.6(Ubuntu 26.04)で採りました。
まず見る(結論)
-- 誰が何本使っているか
SELECT usename, application_name, client_addr, state, count(*)
FROM pg_stat_activity
WHERE backend_type = 'client backend'
GROUP BY 1, 2, 3, 4 ORDER BY 5 DESC;
-- 上限と予約枠
SHOW max_connections; -- 既定 100
SHOW superuser_reserved_connections; -- 既定 3
SHOW reserved_connections; -- 既定 0(PostgreSQL 16 から)
| エラー | 状態 |
|---|---|
FATAL: remaining connection slots are reserved for roles with the SUPERUSER attribute |
一般ユーザーの枠が埋まった。スーパーユーザーはまだ入れる |
FATAL: remaining connection slots are reserved for roles with privileges of the "pg_use_reserved_connections" role |
reserved_connections の枠だけが残っている |
FATAL: sorry, too many clients already |
全部埋まった。スーパーユーザーも入れない |
一般ユーザーが使える数
max_connections を 10 にして、一般ユーザー app1 で SELECT pg_sleep(25) を実行する接続を9本開きました。7本は接続でき、8本目からは次のエラーになりました。
psql: error: connection to server at "127.0.0.1", port 5432 failed: FATAL: remaining connection slots are reserved for roles with the SUPERUSER attribute
10 から superuser_reserved_connections の 3 を引いた 7 本が一般ユーザーの上限です。この状態でもスーパーユーザー(postgres)は3本接続できました。10本すべてが埋まると、app1 も postgres も同じエラーになりました。
psql: error: connection to server on socket "/var/run/postgresql/.s.PGSQL.5432" failed: FATAL: sorry, too many clients already
どのエラーもサーバーログ(/var/log/postgresql/postgresql-18-main.log)に app1@fsv FATAL: sorry, too many clients already のように、接続しようとしたユーザーと DB 名を付けて残ります。
reserved_connections
PostgreSQL 16 からは、スーパーユーザー以外にも枠を予約できます。reserved_connections = 2 にして app2 に pg_use_reserved_connections ロールを付与すると、app1 は 10 − 3 − 2 = 5 本までになりました。6本目は上の表の2番目のエラーで拒否されました。その状態でも app2 は接続できました。監視や運用の接続を確保しておく用途に使えます。
誰が接続を使っているか
pg_stat_activity には autovacuum や checkpointer などのバックグラウンドプロセスも出ます。接続数を数えるときは backend_type = 'client backend' で絞ります。
usename | application_name | client_addr | state | count
----------+------------------+-------------+--------+-------
app1 | psql | 127.0.0.1 | active | 3
app2 | psql | 127.0.0.1 | idle | 2
postgres | psql | | active | 1
SELECT count(*) AS used, current_setting('max_connections')::int AS max
FROM pg_stat_activity WHERE backend_type = 'client backend';
used | max
------+-----
6 | 10
state が idle の接続は何もしていなくても1本分を使います。接続を切る方法は 実行中のクエリを止める記事 を参照してください。
放置された接続は idle_session_timeout で切れます(既定 0=無効)。2秒にして4秒待ってから次の文を実行すると、以下のメッセージが出て接続が切れていました。
FATAL: terminating connection due to idle-session timeout
max_connections の変更は再起動が要る
ALTER SYSTEM SET max_connections = 200;
SELECT pg_reload_conf();
SELECT name, setting, pending_restart FROM pg_settings WHERE name = 'max_connections';
name | setting | pending_restart
-----------------+---------+-----------------
max_connections | 100 | t
pg_settings.context が postmaster の項目(max_connections・superuser_reserved_connections・reserved_connections)はどれも再起動が必要です。Ubuntu では systemctl restart postgresql@18-main で再起動し、pg_lsclusters で online を確認します(起動・停止・再起動の記事)。