PostgreSQL 的 max_connections 修改后必须重启 postmaster 进程才生效,仅 reload 无效;需确认配置文件路径、值格式正确,并同步调整 work_mem 等内存参数防 OOM,结合 PgBouncer 合理配比连接池。

PostgreSQL 的 max_connections 改了却没生效?检查 postgresql.conf 加载路径和 reload 时机
改完 max_connections 重启服务才生效,单纯 pg_reload_conf() 不行——这是硬限制,必须重启 postmaster 进程。常见错误是改了错的配置文件,比如在 Docker 容器里改了宿主机路径,但容器实际加载的是镜像内置的 /usr/share/postgresql/postgresql.conf 或挂载覆盖后的 /var/lib/postgresql/data/postgresql.conf。用 SHOW config_file; 确认当前生效的路径,再检查该文件里 max_connections 是否真被写入且未被注释。
- 值必须是整数,如
max_connections = 200,不能带单位或空格 - 修改后执行
pg_ctl restart -D /path/to/data(Linux)或 Windows 服务重启,SIGUSR2或SELECT pg_reload_conf();对它无效 - 若使用 Patroni、CloudSQL、RDS 等托管服务,该参数通常被锁定,需通过控制台或 API 修改,直接改 conf 会被忽略
调高 max_connections 后 OOM 或启动失败?关联内存参数必须同步调整
每个连接默认消耗约 10MB 内存(含 work_mem、栈空间、连接结构体),设成 1000 就可能额外吃掉 10GB。PostgreSQL 启动时会预分配共享内存段,shared_buffers + 每连接开销 × max_connections 超过系统 shmmax 或可用内存,就会报 FATAL: could not map anonymous shared memory: Cannot allocate memory。
- 同步调低
work_mem(如从 4MB 降到 1MB),尤其当多数查询不复杂时 - 确认
shared_buffers不超过物理内存 25%,且总连接内存预算 ≤ 70% 物理内存 - Linux 上检查
cat /proc/sys/kernel/shmmax,必要时临时加大:sudo sysctl -w kernel.shmmax=2147483648
连接数打满但业务没压测?查 pg_stat_activity 里状态和等待事件
真实瓶颈常不在上限值本身,而在连接堆积。运行 SELECT state, wait_event_type, wait_event, count(*) FROM pg_stat_activity GROUP BY 1,2,3 ORDER BY 4 DESC;,如果大量连接卡在 ClientRead 或 Lock,说明是应用没正确释放连接,或存在长事务/锁争用,不是调大 max_connections 能解决的。
-
state = 'idle in transaction'表示事务开启后没提交/回滚,大概率是应用 bug -
wait_event = 'ClientRead'通常是客户端发完请求后不读响应(如超时设置不合理),连接被占着不动 - 用
pg_terminate_backend(pid)清理异常连接前,先看backend_start和state_change时间戳,避免误杀活跃请求
连接池要不要配?max_connections 和 PgBouncer 的 default_pool_size 怎么配比
直接暴露数据库给应用层,max_connections 得按峰值并发×每请求连接数来设,极易超标。加 PgBouncer 后,数据库侧 max_connections 只需满足池子最大并发(如 50),而应用可开几百连接连池子——因为 PgBouncer 的 default_pool_size 控制每个数据库的实际后端连接数,pool_mode = transaction 下更省资源。
- 推荐组合:
max_connections = 100(DB 层),PgBouncerdefault_pool_size = 20,max_client_conn = 500 - 避免
pool_mode = session,它会让连接长期绑定后端,失去复用意义 - PgBouncer 自身不缓存查询结果,只是连接中转,别指望它替代应用层连接池逻辑
真正难的不是改那个数字,是得同时盯住操作系统内存水位、PostgreSQL 共享内存段、应用连接生命周期、以及中间件池子的配比关系——漏掉任意一环,调参就变成负优化。










