bigywater.tech
常见报错 · 39

PostgreSQL FATAL: sorry, too many clients already:普通用户最多占 7/10,第 8 个先报 remaining connection slots,调大要重启

“FATAL: sorry, too many clients already” 的标准答案是调大 max_connections。这篇在本机自己起一个 PostgreSQL 16,把上限压到 10 来复现:看超级用户保留的名额怎么影响普通用户看到的报错、怎么找出谁占着连接、调大为什么要重启、角色和数据库层面的限制报什么,以及 idle_session_timeout 的效果。

7 / 10
max_connections = 10 时普通用户最多能占住的连接数(另外 3 个是超级用户保留的)
pending_restart
ALTER SYSTEM 调大 max_connections 并 reload 之后的状态:仍是 10,要重启才变成 30
3 种
本篇复现的连接数相关 FATAL:too many clients、too many connections for role、too many connections for database

两种文字

实测 · 本机执行输出
  max_connections|10;  superuser_reserved_connections|3
  普通用户 app 成功占住 7 个连接,第 8 个失败:
      psql: error: connection to server at "127.0.0.1", port 9261 failed: FATAL:  remaining connection slots are reserved for roles with the SUPERUSER attribute
  超级用户 postgres 又占了 3 个之后,第 4 个失败:
      psql: error: connection to server at "127.0.0.1", port 9261 failed: FATAL:  sorry, too many clients already
  此时普通用户再连(退出码 2):psql: error: connection to server at "127.0.0.1", port 9261 failed: FATAL:  sorry, too many clients already

先是 remaining connection slots are reserved…(只剩超级用户的名额),全满才是 sorry, too many clients already。

谁占着

实测 · 本机执行输出
  $ select usename, state, count(*) from pg_stat_activity ... group by 1,2
      app|active|5
      postgres|active|3
  $ 最久没变化的 3 个连接:
      usename | state  |             query             |   running_for   
      ---------+--------+-------------------------------+-----------------
       app     | active | select 1; select pg_sleep(60) | 00:00:0x
       app     | active | select 1; select pg_sleep(60) | 00:00:0x
       app     | active | select 1; select pg_sleep(60) | 00:00:0x
      (3 rows)
  pg_terminate_backend 终止 app 的连接数:5
  之后连接数:3

pg_stat_activity 按用户和状态统计;pg_terminate_backend 立刻释放。

调大要重启

实测 · 本机执行输出
  reload 之后:max_connections|10|t|postmaster
  重启之后:max_connections|30|f

max_connections 的 context 是 postmaster,reload 不生效。

角色与数据库限制

实测 · 本机执行输出
  角色限制 2,app 的第 3 个连接失败:
      psql: error: connection to server at "127.0.0.1", port 9261 failed: FATAL:  too many connections for role "app"
  数据库限制 1,appdb 的第 2 个连接失败:
      psql: error: connection to server at "127.0.0.1", port 9261 failed: FATAL:  too many connections for database "appdb"
  超级用户连 appdb(退出码 0):?column?  ----------         1 (1 row)

报错文字不同,不会因为调大 max_connections 解决。

回收闲置连接

实测 · 本机执行输出
  psql 里先查一次,闲置 3.2 s(idle_session_timeout = 2s),再查一次:
      r
      ----------------
      first query ok
      (1 row)
      FATAL:  terminating connection due to idle-session timeout
      server closed the connection unexpectedly
      This probably means the server terminated abnormally
      before or while processing the request.
      connection to server was lost
  连接数回到 1(只有查询自己)

idle_session_timeout 让服务端关闭闲置连接,客户端连接池要处理这种关闭。

分步演示

连接数
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 arm64;报错文本都是真实复现时原样捕获的(命令行工具统一用 LC_ALL=C 取英文原文,路径换成 );所有服务都是本机上自己起的、只监听 127.0.0.1,不访问外网;计时用 time.perf_counter,数字每次运行会有小幅抖动。本篇用 PostgreSQL 16.15(Homebrew);自己起的实例(自己的数据目录,端口 9261,只监听 127.0.0.1,fsync 关闭,实验结束后整个目录删除),不碰本机已有的 PostgreSQL;每个连接是一个后台的 psql 进程,没有安装 psycopg 等驱动
    • 没有验证:应用侧驱动(psycopg、JDBC、Django 等)看到的报错形态与重试行为;连接池(PgBouncer、应用内连接池)的实际效果与配置;每个连接占用的内存(没有测);复制连接(replication slots)和 max_wal_senders 对 max_connections 的占用;PostgreSQL 其他版本里 superuser_reserved_connections 的报错措辞(如 PostgreSQL 16 之前);云数据库托管服务各自的连接上限
    京ICP备2026067502号-1京公网安备11010502063487号