PostgreSQL で「sorry, too many clients already」が出て接続できない
FATAL: sorry, too many clients already は同時接続数が max_connections に達したサイン。
接続リークを止めるかコネクションプーラを挟むのが本筋で、max_connections の引き上げは最後の手段。
#postgresql#max_connections#pgbouncer#pooling#connection
公開:
要約
FATAL: sorry, too many clients already は、同時接続数がサーバーの max_connections 上限に達して新規接続を受け付けられない状態。
多くは接続リークか、プーラ無しでの接続乱立が原因。
まず溜まった接続を調べてリークを止め、恒常的に多い場合は PgBouncer などのプーラを挟む。max_connections の引き上げは共有メモリを増やすため最後の手段。
よくある原因
- 上限到達: 既定の
max_connections = 100に対し、アプリのプールや並列ジョブの合計がそれを超えている。 - 接続リーク: 取得した接続を返していない、例外時に close し損ねているなどで未使用接続が居座る。
- 多インスタンス: サーバーレス関数やコンテナの水平スケールで、各インスタンスが独立に接続プールを持つと総数が膨らむ。
- プーラ不在: リクエストごとに新規接続して即切る設計だと、ピークで瞬間的に上限を超える。
現状確認
今どれだけ接続があるか、誰が握っているかを見る。
SELECT count(*) FROM pg_stat_activity;
SELECT datname, usename, state, count(*)
FROM pg_stat_activity
GROUP BY datname, usename, state
ORDER BY count DESC;解決策
1. コネクションプーラを挟む
PgBouncer を前段に置き、アプリは少数の物理接続を共有する。
サーバーレスや高並列ではこれが定石。
2. アプリ側のプールを適正化する
物理接続は「max_connections ÷ インスタンス数」を超えない範囲に抑え、確実に解放する。
# 例: max_connections=100、4 インスタンスなら 1 インスタンス 20 程度に
pool size <= 203. 必要なら max_connections を上げる
postgresql.conf で引き上げる。max_connections は再起動が必要で、値に比例して共有メモリを確保する(Connections and Authentication)。
max_connections = 200