log如下
Feb 24 03:23:37 fnOS systemd[1]: Starting postgresql@15-main.service - PostgreSQL Cluster 15-main...
Feb 24 03:23:37 fnOS postgresql@15-main[114036]: Removed stale pid file.
Feb 24 03:23:37 fnOS postgresql@15-main[114036]: Error: /usr/lib/postgresql/15/bin/pg_ctl /usr/lib/postgresql/15/bin/pg_ctl start -D /var/lib/postgresql/15/main -l /var/log/postgresql/postgresql-15-main.log -s -o -c config_file="/etc/postgresql/15/main/postgresql.conf" exited with status 1:
Feb 24 03:23:37 fnOS postgresql@15-main[114036]: 2026-02-24 03:23:37.562 CST [114041] PANIC: could not open file "global/pg_control": Permission denied
Feb 24 03:23:37 fnOS postgresql@15-main[114036]: pg_ctl: could not start server
Feb 24 03:23:37 fnOS postgresql@15-main[114036]: Examine the log output.
Feb 24 03:23:37 fnOS systemd[1]: postgresql@15-main.service: Can't open PID file /run/postgresql/15-main.pid (yet?) after start: No such file or directory
Feb 24 03:23:37 fnOS systemd[1]: postgresql@15-main.service: Failed with result 'protocol'.
Feb 24 03:23:37 fnOS systemd[1]: Failed to start postgresql@15-main.service - PostgreSQL Cluster 15-main.
核心根因总结
本次PostgreSQL启动失败的核心致命原因是权限异常:运行PostgreSQL服务的postgres系统用户,无权限读取数据目录/var/lib/postgresql/15/main下的核心控制文件global/pg_control,导致数据库启动时触发PANIC级崩溃,直接终止启动流程,进而引发后续PID文件不存在、systemd服务启动失败的连锁报错。
错误链完整拆解
- 启动触发:systemd发起postgresql@15-main.service启动请求,调用pg_ctl工具执行数据库实例启动命令。
- 致命崩溃:数据库进程启动时,必须读取global/pg_control文件获取集群元信息、检查点等核心数据,但因权限不足读取失败,触发PANIC级错误,数据库进程直接异常退出。
- 连锁报错:pg_ctl收到子进程异常退出信号,返回退出码1,宣告启动失败;因数据库进程未正常启动,未生成预期的PID文件/run/postgresql/15-main.pid;systemd未检测到PID文件,判定服务启动协议异常,最终标记服务启动失败。
权限异常的常见诱因
- 数据目录/文件所有者错误(最常见,占90%以上场景)
手动备份恢复、迁移数据目录、用root用户操作过/var/lib/postgresql/15/main目录,导致目录及内部文件的所有者从默认的postgres:postgres变成了root或其他用户,postgres用户无权限访问。
- 目录权限位配置违规
PostgreSQL强制要求数据目录权限为0700(仅所有者可读可写可执行),如果权限被修改为777、755等不符合要求的值,会触发安全校验拒绝访问,或直接权限不足。
- 系统安全模块拦截
系统的AppArmor(Debian/Ubuntu系,fnOS大概率基于此)或SELinux安全策略,阻止了postgres用户访问数据目录,即使文件权限位正确,也会报权限拒绝。
- 挂载配置异常
若数据目录位于外挂存储/其他分区,挂载选项(如noexec、nosuid、用户映射错误)导致postgres用户无法正常访问挂载目录内的文件。
- 配置文件修改不当
手动修改了postgresql.conf中的data_directory参数,或配置了多实例,新的目标目录未正确配置postgres用户的访问权限。
解决方案
优先级排查&解决步骤
1.修复数据目录所有者与权限(优先执行)
执行以下命令递归修正权限,适配PostgreSQL的安全要求:
递归修正目录及文件所有者为postgres用户
chown -R postgres:postgres /var/lib/postgresql/15/main/
修正数据目录根权限为强制要求的0700
chmod 0700 /var/lib/postgresql/15/main/
递归修正内部目录权限为700、文件权限为600
find /var/lib/postgresql/15/main/ -type d -exec chmod 0700 {} \;
find /var/lib/postgresql/15/main/ -type f -exec chmod 0600 {} \;
执行完成后重启服务:
systemctl start postgresql@15-main.service