应用突然报 too many connections,最直接的处理是调高 max_connections。这个动作有时能暂时恢复新连接,却也可能让更多会话继续占用内存,把连接泄漏从数据库拒绝变成整机内存压力。
质量规范1要求先建立证据链。当前需要回答的是连接上限是多少、槽位被哪些应用占用、会话处于什么状态、数量为何持续增长,再做最小改动。

先保留一个可用于诊断的连接入口
PostgreSQL会为超级用户保留少量连接槽位,普通业务账号达到上限后,管理员仍可能从本机进入。不要让监控脚本和反复重试继续消耗剩余入口。
能够登录时先查询当前设置:
SHOW max_connections;
SHOW superuser_reserved_connections;
SELECT count(*) AS total_connections FROM pg_stat_activity;
max_connections 是并发连接上限,增加它会让PostgreSQL按更高连接数分配相关资源,而且该参数需要重启才能生效。调高上限属于容量变更,不是连接泄漏的证据。
完全无法登录时,可先限制应用重试或暂停非关键实例,再使用本机管理员入口。不要为了释放槽位直接重启数据库,重启会清空会话,同时让最有价值的现场消失。
用pg_stat_activity统计连接来源
先按数据库、用户、应用名、客户端地址和状态聚合:
SELECT datname, usename, application_name, client_addr, state,
count(*) AS connections
FROM pg_stat_activity
GROUP BY datname, usename, application_name, client_addr, state
ORDER BY connections DESC;
某个应用实例占用数量明显高于其他实例,通常应回到该应用的连接池配置。多个客户端同步增加,可能是统一发布后连接池大小变化,也可能是数据库变慢导致连接归还速度下降。
application_name 为空会降低判断效率,可以在连接字符串中为不同服务设置明确名称。客户端地址是代理或连接池地址时,还要继续查看代理侧指标,不能把所有连接都算到一个真实业务进程上。
区分active、idle和idle in transaction
active 表示会话正在执行查询,idle 表示等待客户端发送下一条命令。连接池保留一定数量的idle连接很正常,关键是数量是否符合池大小,并且能被复用。
idle in transaction 更值得警惕,它表示事务已经开始但客户端没有继续执行或提交。可以按持续时间查看会话:
SELECT pid, usename, application_name, client_addr, state,
now() - xact_start AS transaction_age,
now() - state_change AS state_age,
wait_event_type, wait_event
FROM pg_stat_activity
WHERE pid <> pg_backend_pid()
ORDER BY state_change;
长时间空闲事务不仅占连接,还可能阻止垃圾回收、扩大表膨胀。查询结果涉及业务SQL时应注意脱敏,工单中不要公开参数值和用户数据。
先排除数据库变慢造成的连接堆积
连接数量上涨不一定是应用忘记关闭连接。慢查询、锁等待、磁盘延迟和下游服务卡住,都可能让请求迟迟不能结束,连接池只好不断等待或新建连接。
结合 wait_event_type、慢查询记录和锁信息检查相同时间段。大量active会话等待同一锁,应先处理阻塞链;大量新连接集中在短时间建立,则要检查应用重试、健康检查和连接池生命周期。
只看连接总数而不看状态,会把性能问题误判成简单容量不足。反过来,数据库性能正常但某个应用的idle连接持续超过连接池上限,则更接近多实例配置叠加或池没有正确关闭。
不要批量终止所有会话
pg_terminate_backend 可以终止指定后端,但正在执行事务的连接被终止后会回滚。批量清理全部会话可能扩大业务中断,还会让应用立即重新连接,几秒后再次占满。
先按应用名、客户端地址、状态和持续时间确认目标,再暂停造成增长的入口。需要释放连接时,从最明确的异常会话开始,并观察新连接是否再次出现。超级用户、复制连接和维护任务不能按普通业务会话一并处理。
最小改动的优先顺序通常是修正应用连接关闭逻辑、限制单实例池大小、为事务设置合理超时、处理慢查询或锁,最后才是评估提高数据库连接上限。
什么时候需要连接池或提高上限
业务有大量短连接时,PgBouncer等连接池可以减少数据库后端数量,但池本身也需要按事务模式、会话需求和应用兼容性配置。引入连接池前应先统计峰值并发与实际活跃查询,而不是把客户端连接数原样映射成数据库连接数。
确实需要提高 max_connections 时,要评估每个后端的内存开销、工作内存配置和系统可用内存。准备新环境进行容量验证,可以在 萤光云 上复现数据库规格,也可以用按小时计费的 LightNode 做一轮峰值连接对照。测试必须使用相同连接池参数、查询类型和数据规模,否则更高上限没有可比性。
用重复峰值验证修复结果
修复后再次按应用名、客户端地址和状态统计连接,覆盖一次原本容易报错的流量峰值。连接数应在可解释范围内增长并能回落,idle in transaction不应持续积累。
同时观察数据库内存、查询延迟、错误日志和应用连接池等待时间。验收通过应满足不再出现连接槽位耗尽、异常来源连接数受控、事务能够结束、管理员保留入口仍可用。只把报错推迟几分钟,不算根因关闭。


