应用连接PostgreSQL时提示 remaining connection slots are reserved,表示普通角色可用的连接槽已经耗尽,系统只保留少量位置供超级用户或具备保留连接权限的角色进行紧急维护。
保留槽是故障恢复入口,不是给日常应用绕过连接上限使用的通道。 正确处理顺序是利用管理连接查明谁占满连接,再修复连接泄漏或并发配置。

先理解三类连接上限
查看当前配置:
SHOW max_connections;
SHOW superuser_reserved_connections;
SHOW reserved_connections;
max_connections 是总上限。superuser_reserved_connections 为超级用户保留最终应急位置,当前版本默认3个;较新版本的 reserved_connections 可为拥有 pg_use_reserved_connections 权限的角色额外预留,默认0。
旧版本可能不认识 reserved_connections 参数,应以实际版本文档和 SHOW server_version 为准。参数名称不存在时不要直接复制新版本配置。
使用管理连接查看占用来源
通过本机Unix套接字或已预留的管理通道,以有权限的角色连接,然后统计来源:
SELECT usename, application_name, client_addr, state, count(*)
FROM pg_stat_activity
WHERE backend_type = 'client backend'
GROUP BY usename, application_name, client_addr, state
ORDER BY count(*) DESC;
再查持续时间较长的连接:
SELECT pid, usename, application_name, client_addr, state,
now() - backend_start AS connection_age,
now() - xact_start AS transaction_age,
wait_event_type, wait_event, query
FROM pg_stat_activity
WHERE backend_type = 'client backend'
ORDER BY xact_start NULLS LAST;
重点关注大量idle连接和idle in transaction连接。 后者仍处于事务中,可能持有锁、阻止清理并占用连接槽。
紧急释放连接要精确到会话
确认某个会话已失去业务价值后,可请求终止:
SELECT pg_terminate_backend(12345);
对空闲普通连接可以先生成候选清单,不要未经判断直接执行批量终止。pg_terminate_backend 会关闭会话并回滚未提交事务,应用可能立即重连,连接泄漏未修复时很快再次占满。
不要终止autovacuum、复制、备份或不明用途的内部进程。 pg_stat_activity.backend_type 能帮助区分客户端和后台进程。
修复应用连接池与空闲事务
常见根因是每个应用进程都创建过大的连接池、异常路径没有归还连接、扩容后副本数增加但单实例池大小未缩减,或事务开启后等待外部接口。
按数据库总预算分配连接池:应用最大连接数之和应低于普通可用槽,并为迁移、监控和运维留出余量。可考虑PgBouncer等连接池,但事务池模式对会话级状态、临时表和预备语句存在行为差异,需要先验证。
需要模拟高并发连接时,可在 萤光云 或按小时计费的 LightNode 建立隔离环境。不要直接拿生产库做连接耗尽测试。
谨慎评估是否提高max_connections
max_connections、reserved_connections 和 superuser_reserved_connections 都只能在服务器启动时设置。提高 max_connections 会让PostgreSQL按该值增加部分资源分配,包括共享内存,主从架构中备用服务器还应设置为不低于主库。
修改前要评估内存、工作负载和操作系统限制,并保留回滚方案。连接数上限提高后,每条连接的查询内存与后台开销并不会消失,盲目扩大可能把连接错误变成内存和延迟问题。
建立持续监控和验收标准
监控客户端连接总数、按应用分组的占用、idle in transaction数量、连接建立速率和连接等待错误。发布后模拟应用峰值并保留管理连接,确认连接池能够回收空闲会话。
合格的验收标准是普通连接保持安全余量、管理保留槽未被日常业务占用、异常会话可追溯,且应用重启不会形成连接风暴。
FAQ
可以让应用使用超级用户避免报错吗?
不可以。超级用户权限远超应用所需,也会消耗最后的应急槽位,扩大安全和恢复风险。
为什么数据库空闲却提示连接已满?
连接槽按会话数量计算,不按CPU使用率计算。大量idle连接即使不执行SQL,也会占用位置。
PgBouncer一定能解决吗?
它能减少数据库后端连接,但必须正确设置池大小、超时和池模式。应用依赖会话状态时需要专门测试。
温馨提示
始终为管理和监控保留一条经过验证的连接路径。 处理连接耗尽时先保留现场,再精确终止异常会话;长期方案是连接池治理和事务生命周期控制,而不是把应用改成超级用户。


