跳转到主要内容

57P01 — admin_shutdown

PostgreSQL 57P01 的来源与诊断参考。

57P01

速览

57P01 表示服务器发起的管理 shutdown 条件。固定核心路径覆盖有序或立即终止客户端、worker/并行终止,以及同步复制等待;后者明确提示本地提交可能早于 standby 复制。

字段
SQLSTATE 57P01
条件名 admin_shutdown
状态 有效
已知存在于 7.4
锁定快照 9.0.23, 9.1.24, 9.2.24, 9.3.25, 9.4.26, 9.5.25, 9.6.24, 10.23, 11.22, 12.22, 13.23, 14.24, 15.19, 16.15, 17.11, 18.6, 19beta3
ERRCODE_ADMIN_SHUTDOWN
别名

含义

同一 SQLSTATE 在多个生命周期边界复用,因此 severity 与恢复取决于调用点。立即停止信号路径发送 client-only WARNING 后退出,不运行正常清理;普通客户端管理员命令路径使用 FATAL。同步复制路径使用 WARNING,并带有 detail:The transaction has already committed locally, but might not have been replicated to the standby. 并行和 worker 路径各自使用 FATAL 或 worker 控制流。不能把这些路径互相替代为同一条“业务已提交/已回滚”结论。

消息

  • 立即停止:primary terminating connection due to immediate shutdown command,severity 为 WARNING_CLIENT_ONLY;报告后进程退出。
  • 客户端 backend 管理员命令:primary terminating connection due to administrator command,severity 为 FATAL;连接关闭。
  • 同步复制等待:primary canceling the wait for synchronous replication and terminating connection due to administrator command,severity 为 WARNING,detail 为 The transaction has already committed locally, but might not have been replicated to the standby.
  • 并行事务:primary postmaster exited during a parallel transaction,severity 为 FATAL。
  • 另一个固定 promotion 等待分支在 FATAL 下报告 terminating connection due to unexpected postmaster exit,context 为 while waiting on promotion

诊断

关联完整 primary/detail/context、backend PID、管理员或 postmaster 动作、服务器 shutdown/recovery 日志及事务边界。选定运行案例只覆盖客户端 backend 的管理员命令分支,不能证明立即停止、同步复制、worker、并行或 promotion 分支的结果。出现同步复制 detail 时,事务已经在本地提交,而 standby 是否收到仍不确定;该 WARNING 之后原连接仍会终止,不能在旧 session 恢复。重放非幂等操作前应查询持久化状态与复制状态。

处理

对 FATAL 或 client-only shutdown 报告,原连接不是事务恢复点:等待服务器 ready,建立新连接,并在重试前检查持久化业务状态或幂等键。同步复制分支要记录本地提交已经发生,并分别确认 standby 接收;WARNING 之后连接会终止,不能在旧 session 恢复。不能假定任何 57P01 路径都留下可用 session。已接受案例中的 fresh SELECT 1 只能证明终止目标后服务器可连接,不能证明中断的业务操作已提交。

实测诊断

选定注册表在 PostgreSQL 18.6 与 10.21 上分别创建 runner-owned victim client backend、不同的 admin session 和 fresh session。admin 核对目标身份,pg_terminate_backend 返回 true。victim 驱动收到 FATAL / 57P01terminating connection due to administrator command 后断开;fresh session 返回 1 并处于 IDLE。这个有界案例不覆盖其他源码分支,也不证明业务提交结果。

代表案例

只能使用案例创建的 victim session 返回的 PID,不能替换为任意生产 PID 或 admin 自身 PID。fresh probe 验证的是定向终止后服务器可达。重放非幂等请求前检查持久化业务状态或幂等键。

-- 由案例运行器创建的 victim 会话
SELECT pg_backend_pid();  -- 保存为 :victim_pid
SELECT 1;                 -- 终止前探测

-- admin 会话:记录自身 PID,只使用运行器创建的 victim PID
SELECT pg_backend_pid(); -- 保存为 :admin_pid
SELECT pid, backend_type FROM pg_stat_activity WHERE pid = backend_pid;
SELECT pg_terminate_backend(backend_pid);

-- victim 断开后建立 fresh 会话
SELECT 1;

版本

锁定目录从 7.4 记录此条件;该目录边界不等于精确实现引入版本。固定源码覆盖 PostgreSQL 18.6,选定运行案例另在 PostgreSQL 10.21 观察到。

57P0257P0340001

来源

src/backend/tcop/postgres.c#L2974-3001

src/backend/tcop/postgres.c#L3354-3356

src/backend/replication/syncrep.c#L283-305

src/backend/access/transam/parallel.c#L932-940

src/backend/access/transam/xlogfuncs.c#L737-741

结构化证据记录保存固定分支及有界运行案例。