连接PostgreSQL报错could not fork new process for connection如何解决
could not fork new process for connection : No error could not fork new process for connection
该报错的本质是PostgreSQL服务端无法为新接入的客户端连接fork独立的后端处理进程,故障根因集中在操作系统资源限制层面,与数据库账号权限、SQL语法逻辑无关。
核心触发原因
- 操作系统进程数配额耗尽:要么PostgreSQL运行用户的最大进程数(nproc)配额被打满,要么系统全局PID资源(kernel.pid_max)耗尽,无法为新进程分配PID
- 内存资源不足:fork新进程需要分配独立的内存地址空间,当系统可用物理内存+Swap空间不足,或内存超配(overcommit)策略配置过严时,内核会直接拒绝进程fork请求
- PostgreSQL连接数配置超出系统承载上限:
max_connections参数设置过高,叠加现有连接已占满进程资源配额,新连接接入时无剩余资源可用 - 僵尸进程占用资源:系统内残留大量未回收的Z状态僵尸进程,长期占用PID配额,导致新进程无法正常创建
排查步骤
- 校验进程数配额
- 执行
cat /proc/sys/kernel/pid_max查看系统全局最大PID阈值,执行ps -eLf | wc -l统计当前系统总进程/线程数,确认是否触达全局上限 - 切换到PostgreSQL运行用户(默认为postgres),执行
ulimit -u查看该用户的最大进程数配额,执行ps -u postgres | wc -l统计该用户下当前运行的进程总数,确认是否打满用户级配额
- 校验内存状态
- 执行
free -h查看当前系统可用物理内存、Swap剩余空间,确认是否存在内存耗尽情况 - 执行
dmesg -T | grep -i 'out of memory\|oom'查看内核日志,确认报错时间点附近是否触发过OOM机制、存在内核拒绝内存申请的记录 - 执行
cat /proc/sys/vm/overcommit_memory查看内存超配策略,若值为2(禁止内存超配),需对比grep CommitLimit /proc/meminfo返回的阈值与当前已提交内存总量,确认是否因超配限制拒绝fork
- 校验PostgreSQL运行状态
- 查看数据目录下
postgresql.conf中max_connections的配置值,连接数据库后执行SELECT count(*) FROM pg_stat_activity;统计当前实际连接数,确认是否触达连接数上限 - 执行
ps aux | grep postgres | grep 'Z'统计PostgreSQL相关的僵尸进程数量,确认是否存在大量僵死进程占用资源 - 查看PostgreSQL运行日志,确认报错时间点是否伴随其他资源不足的关联报错
修复方案
- 进程数配额不足场景:
用户级nproc限制临时调整可执行ulimit -u 65535(仅当前会话生效),永久调整需在/etc/security/limits.conf中添加如下配置:
全局PID阈值不足可临时执行postgres soft nproc 65535 postgres hard nproc 65535sysctl -w kernel.pid_max=65535,永久调整需在/etc/sysctl.conf添加对应配置后执行sysctl -p生效 - 内存不足场景:
优先终止系统内异常占用内存的无关进程,若为业务正常增长导致内存缺口则扩容物理内存或Swap空间;若为overcommit策略过严导致的故障,可执行sysctl -w vm.overcommit_memory=0将策略调整为启发式超配,写入sysctl.conf后永久生效 - 连接数配置不合理场景:
根据服务器内存容量合理下调max_connections参数(单PostgreSQL连接通常占用5-10MB内存,可按总内存扣除系统预留、shared_buffers占用后换算合理阈值),修改后重启数据库生效;业务侧建议部署PgBouncer等连接池组件,减少空连接对资源的占用,避免连接数突增打满资源 - 僵尸进程堆积场景:
僵尸进程的父进程通常为PostgreSQL主进程,可通过优雅重启PostgreSQL服务回收僵死进程;若重启后仍频繁出现僵尸进程,需排查是否存在第三方扩展插件bug、系统信号处理异常等问题
内容的提问来源于stack exchange,提问作者Bayu Febriyono Putra
相关产品推荐
相关产品推荐

