PostgreSQL too many clients:连接池和应用副本怎样算
读取连接占用,按最大副本数规划池预算,并区分 idle、长事务、数据库连接耗尽与应用池等待。
先分清数据库拒绝连接与池内等待
应用报 PostgreSQL too many clients,表示数据库端的连接额度需要检查。应用的连接池等待超时则发生在池内部,可能是请求持有连接太久、池太小或归还异常。两种情况可以同时出现,先保存原始错误和对应进程。
一个进程配置最大 20 条连接,不代表整个项目最多 20 条。多个应用、多个副本、定时任务和滚动发布期间的新旧实例,都会累计连接。已有可用的管理连接先保留,避免断开后进不去。
从有权限的管理连接查看占用
以下以 PostgreSQL 18 为例,只读取配置与活动统计。查询所有连接细节需要相应统计权限;普通账号看到的信息可能不完整。
SHOW max_connections;
SHOW superuser_reserved_connections;
SHOW reserved_connections;
SELECT application_name, usename, state, count(*) AS connections
FROM pg_stat_activity
WHERE backend_type = 'client backend'
GROUP BY application_name, usename, state
ORDER BY connections DESC;reserved_connections 是 PostgreSQL 16 起的参数,旧版本应按该版本文档处理。按 application_name 和用户找连接主要来自哪里,再对照应用副本数。若应用未设置名称,可结合用户、client_addr 和部署清单定位,别把所有后台进程都算成普通客户端连接。
按最大副本数计算,而非当前空闲数
普通业务预算可以从 max_connections 扣除管理预留、其他业务占用和运维余量,再分给应用池。预留连接由具备对应权限的角色使用,不能当成普通应用随时可用的空间。
例如,假设上限 100、超级用户预留 3、reserved_connections 为 0,再主动留 7 条给管理和其他任务,应用预算是 90。两个服务各开三个副本,每个池最多 20 条,理论合计 120,已经超过预算;这只是计算示例,不是任何部署的实测值。
还要计算滚动发布同时存在的新旧副本、任务进程和数据库管理工具。降低单池上限后,持续观察池内排队、请求延迟和数据库负载,确认没有把数据库拒绝连接变成应用长时间等待。
大量 idle 与长事务分开处理
idle 连接可能只是池保留的空闲连接,不能仅凭状态认定泄漏。idle in transaction 则需要检查事务为何迟迟不结束,它可能同时占连接并影响其他事务。
SELECT pid, application_name, usename, state,
now() - xact_start AS transaction_age,
wait_event_type, wait_event
FROM pg_stat_activity
WHERE backend_type = 'client backend'
AND state = 'idle in transaction'
ORDER BY xact_start;先对照业务、日志与事务超时配置,再修正连接归还和事务范围。批量终止连接可能中断用户请求或回滚事务,不应作为不清楚原因时的第一步。
调整上限以前检查数据库资源
max_connections 的提高会增加 PostgreSQL 对部分资源的分配,并需要服务器重启才能生效。增加应用副本也可能增加数据库并发压力,不能只通过改大连接数解决。
把连接数、池等待、CPU、内存和查询时长放在同一时间段观察。确有大量短连接需求时再评估连接池代理,并确认事务、预处理语句和应用驱动兼容。处理完成后用真实业务验证,留下副本数与池上限,避免下次扩容再次超额。
