技术 / 分析与实践观点

网站中断,PostgreSQL 不再接受新连接

遇到 too many connections 时,先控制连接创建,再检查问题会话及连接池预算,避免重试风暴继续耗尽容量。

ADArdeshir Daryani··3 分钟阅读
数据库连接容量受限与请求入口控制的概念示意图
由人工智能生成的原创概念插图,并非商业产品或实际架构的精确展示。

紧急情况: 应用报出 too many connections。团队增加 Worker,而应用持续重试。补救措施本身可能耗尽数据库最后可用的连接容量。

先控制连接洪峰

暂时限制 Worker 自动增长及非必要任务。如果最近发布修改了进程数或连接池大小,应检查那次变更。维护页面或限制受影响部分的入口,可以争取诊断时间。目标是停止不断产生压力,而不是无故关闭所有服务。

通过管理连接检查状态

如果仍有预留连接槽位,具备适当授权的管理角色可能还能连接。仅仅使用本地连接,并不能绕过连接数量限制。在 PostgreSQL 管理会话中执行以下只读查询:

SHOW max_connections;

SELECT application_name, usename, state, count(*) AS sessions
FROM pg_stat_activity
WHERE backend_type = 'client backend'
GROUP BY application_name, usename, state
ORDER BY sessions DESC;

输出有助于找出会话数量较多的应用或账户。查看其他会话详情需要相应权限。大量 idle 连接本身不能证明泄漏,也可能只是连接池较大。idle in transaction 与没有打开事务的空闲连接也不同。

让措施对应真正原因

将产生连接的应用连接池上限及进程数调整回数据库共享容量允许的范围。在这个假设场景中,回退 Worker 配置可能比立即增加 max_connections 更合理。增加该参数需要更多资源及服务器重启,不能自动修复连接泄漏或重试风暴。

如果已知的活动请求是问题来源,可考虑使用 pg_cancel_backend 取消该查询。这不一定关闭会话,也不会释放空闲连接。释放已确认的会话可能需要 pg_terminate_backend;终止可能回滚其未提交事务。应先明确任务负责人、中断影响及重试方式。一条关闭所有会话的通用命令,不是恢复方案。

确认故障结束的标准

测试真实应用请求,确认错误减少、连接数量稳定,再逐步恢复任务。如果容量迅速再次耗尽,原因仍在。我的事后建议是为每项服务设定连接预算,使用有上限的连接池,并明确负责人及合理的重试间隔。

关键决策: 先调节连接产生速度,不要只是把容器扩大。

技术参考: PostgreSQL / Connections · PostgreSQL / Statistics · PostgreSQL / Administration.

通过技术分析,为决策提供更充分的依据。全部文章 →