文档 / SQL 状态码 / Class F0 配置文件错误
F0001 lock_file_exists
ERROR 源码确认 详解 未实测
- 条件名
lock_file_exists- 宏名称
ERRCODE_LOCK_FILE_EXISTS- 启用版本
- 7.4
- 状态
- 活跃
版本覆盖
速览
F0001 是启动时的所有权冲突。PostgreSQL 同时检查目标数据目录的 lock file 和共享内存身份;活跃所有者与崩溃留下的残留物是不同情况。
含义
CreateLockFile 用 O_EXCL 原子创建锁文件。已有文件若包含 PID,会用 kill(pid, 0) 区分进程仍活跃还是已经消失;数据目录锁文件还会读取记录的共享内存标识并调用 PGSharedMemoryIsInUse。该辅助函数只把与目标 DataDir 关联的共享内存段视为相关,因为共享内存 ID 可能偶然重合。空锁文件是独立的 F0001 分支,可能表示另一个服务器正在启动,也可能是上次启动崩溃的残留。
SysV 共享内存启动路径也有同样边界:仍有进程附着或分析结果不确定的既有共享内存段报告仍在使用;与数据目录相关但无进程附着的共享内存段才可清理后重建。这些 guard 防止两个 postmaster 认领同一集群。
消息
- FATAL,SQLSTATE
F0001:lock file "%s" already exists。 - 数据目录提示:
Is another postgres (PID %d) running in data directory "%s"?(编码所有者为 postmaster 时会使用对应提示文案)。 - socket lock 变体会写
using socket file "%s"。 - FATAL,SQLSTATE
F0001:lock file "%s" is empty。 - 提示:
Either another server is starting, or the lock file is the remnant of a previous server startup crash. - FATAL,SQLSTATE
F0001:pre-existing shared memory block (key %lu, ID %lu) is still in use。 - 提示:
Terminate any old server processes associated with data directory "%s".
其他锁文件 I/O 失败使用 errcode_for_file_access(),可能得到不同 SQLSTATE,不能都归入 F0001。
报文模板
源码里的格式串,不是某一次运行的输出。%s 之类是占位符,实际报文会填入对象名与取值。适用范围一栏是核验时留下的原始英文记录,未经翻译。
lock file "%s" already exists
Is another postgres (PID %d) running in data directory "%s"?
Is another postmaster (PID %d) running in data directory "%s"?
Is another postgres (PID %d) using socket file "%s"?
Is another postmaster (PID %d) using socket file "%s"?
lock file "%s" is empty
Either another server is starting, or the lock file is the remnant of a previous server startup crash.
pre-existing shared memory block (key %lu, ID %lu) is still in use
Terminate any old server processes associated with data directory "%s".
来源:src/backend/utils/init/miscinit.c @ REL_18_6 · src/backend/port/sysv_shmem.c @ REL_18_6
诊断
确认精确 PGDATA、socket 目录、PID、启动时间、记录的 device/inode 身份、进程所有者和 postmaster 日志。kill(pid, 0) 成功,或失败 errno 既不是 ESRCH(进程不存在)也不是 EPERM(进程存在但调用者无权发送信号),会保持活跃进程分支。guard 将 EPERM 排除在活跃进程分支之外,是因为 checkDataDir() 以及 0600/0640 锁文件权限足以排除不同 UID 的进程作为竞争 postmaster;它只允许继续做身份和共享内存检查,并不授权直接删除锁文件。PID 消失或被视为不同 UID 候选后,还要检查数据目录共享内存 ID 及是否仍有孤儿后端附着,再考虑清理。空锁文件在源码中明确是歧义状态,不代表一定残留。
处理
这是启动阶段的 FATAL,没有客户端事务可恢复;解决所有权冲突后启动服务器,再使用新连接。若另有 postmaster/后端存活,应按正常管理流程协调或停止。只有确认集群、进程身份和共享内存状态后,才能按文档处理陈旧锁文件。绝不能仅凭路径、PID 文本或数字 ID 删除锁文件/共享内存;所有者活跃时删除可能造成双主冲突(两个 postmaster 认领同一集群)和数据丢失。
版本
锁定目录从 7.4 记录此条件;固定启动与共享内存路径来自 PostgreSQL 18.6。本源码条目没有诱发进程、lock-file 或共享内存故障。
来源
- 上游源码 src/backend/utils/errcodes.txt 第 454 行
- 上游源码 src/backend/utils/init/miscinit.c 第 1262 行
- 上游源码 src/backend/port/sysv_shmem.c 第 306 行
证据
断言
每条断言都写明了是怎么核实的,以及它不覆盖什么。这一层是核验时留下的原始英文记录,照原样呈现,未经翻译。
-
F0001 is lock_file_exists in SQLSTATE Class F0.
-
Startup distinguishes a live lock owner, an empty or stale lock, and shared memory associated with the intended data directory; only the live/in-use branches emit the fixed F0001 FATAL messages.
-
The locked catalogue records F0001 from 7.4; it does not prove the exact introduction rationale.
同类 SQL 状态码
| 状态码 | 条件名 | 宏名称 | 严重等级 | 版本 |
|---|---|---|---|---|
| F0000 | config_file_error | ERRCODE_CONFIG_FILE_ERROR |
ERROR | 7.4 |
| 配置文件内容或读取有误,严重性随调用者而异。 | 活跃 | |||
| F0001 | lock_file_exists | ERRCODE_LOCK_FILE_EXISTS |
ERROR | 7.4 |
| 数据目录的锁文件已存在,实例可能已在运行。 | 活跃 | |||