PostgreSQL · 错误码速查
PostgreSQL sorry, too many clients already:槽位全满了,先查谁占着连接,别先改 max_connections
新连接报 FATAL: sorry, too many clients already(SQLSTATE 53300),说明 max_connections 的全部槽位——包括留给超级用户的保留槽——都已占满,连超级用户也连不进来。如果看到的是 remaining connection slots are reserved for …,说明普通槽已满、只剩保留槽。已建立的连接不受影响。先用保留槽登录查 pg_stat_activity 里谁占着连接(常见是 idle 和 idle in transaction),再决定加连接池或超时;调大 max_connections 要重启,而且只是推迟下次报错。
官方原文
sorry, too many clients already出自 PostgreSQL 源码 src/backend/storage/lmgr/proc.c 的 InitProcess(),错误级别 FATAL,错误码 ERRCODE_TOO_MANY_CONNECTIONS(errcodes.txt 中为 53300 too_many_connections)。同码的还有 src/backend/utils/init/postinit.c 里的「remaining connection slots are reserved for …」和「too many connections for database」、miscinit.c 里的「too many connections for role」。
出处:PostgreSQL 源码 REL_17_STABLE:src/backend/storage/lmgr/proc.c(InitProcess) 最后核对:
| SQLSTATE | 53300(too_many_connections,Class 53 Insufficient Resources) | 出处 |
|---|---|---|
| 错误级别 | FATAL:只拒绝这一次新连接,不影响已建立的会话 | 出处 |
| max_connections | 默认通常 100,只能在启动时设置(改了要重启) | 出处 |
| superuser_reserved_connections | 默认 3,留给超级用户的最后应急槽 | 出处 |
| reserved_connections | PostgreSQL 16 新增,默认 0;留给 pg_use_reserved_connections 角色成员 | 出处 |
盈尺实测(测试库,非官方文档):2026-11-09 同一批 PG14.24 / PG17.11 测试库上,max_connections=8、superuser_reserved_connections=2(17 另 reserved_connections=2):14 普通角色连 6 个后被拒,17 普通角色连 4 个后被拒,保留槽报错原文两版不同,全满时都是 sorry, too many clients already。 PostgreSQL 升级后变慢:统计信息之外的 4 个原因(同批 PG14.24 / PG17.11 测试库) →
PG14 和 PG17 上的逐条输出:同样是连接满,报错原文不一样
2026-11-09 在 box 本机测试库(PostgreSQL 14.24 与 17.11,各自新建实例,非客户环境)把 max_connections 设成 8、superuser_reserved_connections 设成 2,PG17 另设 reserved_connections=2,用 psql 逐个开连接直到被拒,记录客户端收到的原文:
| 版本 | 谁在连 | 连上几个后被拒 | 客户端原文(FATAL) |
|---|---|---|---|
| 14.24 | 普通角色 | 6 | remaining connection slots are reserved for non-replication superuser connections |
| 14.24 | 超级用户(继续用保留槽) | 再 2 个 | sorry, too many clients already |
| 14.24 | 全满后普通角色再连 | — | sorry, too many clients already |
| 17.11 | 普通角色 | 4 | remaining connection slots are reserved for roles with privileges of the "pg_use_reserved_connections" role |
| 17.11 | pg_use_reserved_connections 成员 | 再 2 个 | remaining connection slots are reserved for roles with the SUPERUSER attribute |
| 17.11 | 超级用户 | 再 2 个 | sorry, too many clients already |
| 17.11 | 全满后普通角色再连 | — | sorry, too many clients already |
读法:14 只有两层(普通槽 → 超级用户保留槽),17 有三层(普通槽 → reserved_connections → superuser_reserved_connections)。看到「sorry, too many clients already」意味着最后一层也满了,DBA 自己也登不上去;看到「remaining connection slots are reserved」意味着还有应急通道,应该立刻用有权限的账号上去查。
从 14 升到 16 / 17 / 18:按旧原文写的告警会静默失效
PG14 的保留槽报错原文是「reserved for non-replication superuser connections」,PostgreSQL 16 加入 reserved_connections 后改成上表里的两种新原文(源码 postinit.c)。如果你的日志告警、Grafana/Loki 规则或巡检脚本是按旧原文全文匹配的,升级后同样的连接打满不会再触发告警。
- 告警改为匹配 SQLSTATE:日志
log_line_prefix加%e,按53300匹配,不依赖措辞;或者至少同时匹配remaining connection slots are reserved和too many clients already两段前缀。 - 升级后给监控 / 运维账号留通道:
ALTER SYSTEM SET reserved_connections = 3;(要重启)再GRANT pg_use_reserved_connections TO ops_monitor;,这样不必用超级用户也能在打满时登录排查。 reserved_connections + superuser_reserved_connections必须小于max_connections;测试库上 8 个槽留 4 个后,普通角色只剩 4 个,生产上按真实峰值算。
用保留槽登录后,先查连接都被谁占着(只读)
-- 总量 vs 上限
SELECT count(*) AS used, current_setting('max_connections')::int AS max,
current_setting('superuser_reserved_connections')::int AS su_reserved
FROM pg_stat_activity WHERE backend_type = 'client backend';
-- 按用户 / 应用 / 状态分组,找占连接最多的来源
SELECT usename, application_name, client_addr, state, count(*),
max(now() - state_change) AS longest_in_state
FROM pg_stat_activity
WHERE backend_type = 'client backend'
GROUP BY 1,2,3,4 ORDER BY count(*) DESC LIMIT 20;- 大部分是
idle:应用连接池上限之和超过了数据库容量(例如 10 个实例 × 每个池 20 = 200 > 100),典型是扩容后才开始报错。 - 大量
idle in transaction:应用开了事务没提交,连接和锁一起被占住;查xact_start最老的几条,处理办法见 idle in transaction 只读排查。 - 都是
active且在等锁(wait_event_type = 'Lock'):连接满是结果不是原因,先找阻塞源头,否则加多少连接都会被填满。
处理顺序:先挡住来源,再上连接池,最后才是 max_connections
- 应急:用保留槽登录,对确认可断的 idle 会话执行
SELECT pg_terminate_backend(pid)(会断开对方连接,按你方变更流程授权)。 - 防止再满:设
idle_in_transaction_session_timeout(如 5min)回收忘记提交的事务;PG14 起有idle_session_timeout,但在连接池后面开它可能让池里的连接被意外断开,要和池的回收参数一起定。 - 限住单个来源:
ALTER ROLE report_user CONNECTION LIMIT 20;,超限时这个角色收到的是同码的too many connections for role "report_user",不会挤占其他业务。 - 加连接池:应用实例多、单连接大部分时间空闲时,用 PgBouncer 等事务级连接池把几百个客户端连接收敛到几十个服务端连接,见 PgBouncer 连接池 pgbench 对比。
- 最后才调
max_connections:只能重启生效,官方文档说明部分共享内存按它分配;每个连接还是一个独立进程,调大只是把下一次打满往后推。
常见问题
sorry, too many clients already 是什么意思?
PostgreSQL 的 max_connections 槽位连保留槽一起用完了,新连接被拒,SQLSTATE 53300,级别 FATAL。已建立的连接不受影响。
remaining connection slots are reserved 和 too many clients already 有什么区别?
前者是普通槽满了、只剩保留槽,超级用户(PG16+ 还有 pg_use_reserved_connections 成员)还能登录;后者是保留槽也满了,谁都连不上。两者都是 53300。
为什么升级到 PostgreSQL 17 后,连接满的告警不响了?
PG16 起保留槽报错的原文变了:14 是 reserved for non-replication superuser connections,17 是 reserved for roles with privileges of the "pg_use_reserved_connections" role 或 reserved for roles with the SUPERUSER attribute。按旧原文匹配的告警要改成按 SQLSTATE 53300 匹配。
直接把 max_connections 调大可以吗?
可以但不建议作为第一步:需要重启,部分共享内存随它增加,且每个连接是一个进程。先查 pg_stat_activity 看是 idle、idle in transaction 还是等锁,再决定连接池、超时或限流。
too many connections for role 也是这个错误吗?
同一个 SQLSTATE 53300,但原因是角色级 CONNECTION LIMIT 到了,只影响这个角色;too many connections for database 则是数据库级 CONNECTION LIMIT。
免费 · 留邮箱领检查单
PostgreSQL 14 停更升级检查单(Excel 可直接打开)
- PG14 2026-11-12 停更,升 17 / 18 前后 19 项检查:只读预检、--check、回滚、补统计、回归
- 每项写清怎么查、通过标准、不处理会怎样(附测试库实测数字)
- 配合站上的只读预检 SQL 使用,每个业务库各跑一次
下一步
价格以对应页面当前标价为准。
出处(最后核对 2026-11-09)
- PostgreSQL 源码 REL_17_STABLE:src/backend/storage/lmgr/proc.c(InitProcess)
- PostgreSQL 源码 REL_17_STABLE:src/backend/utils/init/postinit.c(保留槽报错)
- PostgreSQL 源码 REL_14_STABLE:src/backend/utils/init/postinit.c(14 的旧原文)
- PostgreSQL 17 文档 附录 A:PostgreSQL Error Codes(53300 too_many_connections)
- PostgreSQL 17 文档 19.3:Connections and Authentication(max_connections、reserved_connections、superuser_reserved_connections)
- PostgreSQL 17 文档 21.5:Predefined Roles(pg_use_reserved_connections)
- PostgreSQL 16 Release Notes(新增 reserved_connections / pg_use_reserved_connections)
本页摘录并解读上面列出的官方文档,不是官方页面;官方文档更新后以官方为准。除标明「盈尺实测」的一段外,其余内容都来自官方文档。