# 58000 — system_error

> PostgreSQL 58000 的来源与诊断参考。
---

# 58000

## 速览 {#at-a-glance}
`58000` 是 system-error 条件。在固定 backend 路径中，`pg_promote` 创建 promotion signal 文件后调用 `kill(PostmasterPid, SIGUSR1)`；信号发送失败时以 ERROR 报告，并把操作系统的 `%m` 文本展开到消息中。

<!-- BEGIN SQLSTATE FACTS: generated by scripts/generate.py; do not edit -->

| 字段 | 值 |
| --- | --- |
| SQLSTATE | `58000` |
| 条件名 | `system_error` |
| 状态 | `有效` |
| 已知存在于 | `9.2.0` |
| 锁定快照 | `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_SYSTEM_ERROR` |
| 别名 | `—` |

<!-- source facts: data/errcodes/58000.json -->
<!-- END SQLSTATE FACTS -->

## 含义 {#meaning}
代表性 backend primary 是 `failed to send signal to postmaster: %m`。代码在报告 ERROR 前先删除 promotion signal 文件，所以这里是 postmaster 通知路径中的系统调用失败，不是用户值或 SQL 语法错误。共享的 `common/exec.c` 使用 `log_error` 宏，并有两个编译时分支：非 FRONTEND 构建展开为 `ereport(LOG, (errcodefn, errmsg_internal(...)))`；FRONTEND 构建忽略 `errcode()` 参数，把格式化文本写到 stderr。因此 frontend 工具消息不能证明存在客户端协议 `58000` 诊断，也不能证明客户端事务已回滚。`common/logging.h` 中独立的 `pg_log_error` 宏才映射到 `PG_LOG_ERROR`，但 `pclose_check()` 并不调用它。

## 消息 {#messages}

- backend `pg_promote` 信号路径：primary 为 `failed to send signal to postmaster: %m`，severity 为 ERROR；展开文本取决于失败 `kill()` 调用当时的 OS `errno`。
- 共享的 `pclose_check()` 源码：调用点模板是 `%s() failed: %m`；对 `pclose()` 会展开为 `pclose() failed: <OS 文本>`。非 FRONTEND 构建经 `ereport(LOG)` 携带传入的 `ERRCODE_SYSTEM_ERROR`；FRONTEND 构建忽略该 code、直接写 stderr，因此不是客户端协议 `58000` 路径。

## 诊断 {#diagnosis}
保留 `%m` 展开后的完整 primary、操作类型（promotion signal、`pclose` 或其他系统 helper）、进程身份及服务器或工具日志上下文。对 backend `pg_promote`，检查 postmaster PID、信号权限/进程存活状态和 OS 错误。没有实际 errno 时，不要把系统错误替换成笼统的磁盘、权限或进程诊断；单凭 SQLSTATE 也不能判断事务结果。

## 处理 {#response}
先修正展开消息所指出的操作系统条件，再确认 postmaster/服务器健康后重试。backend ERROR 通常会使当前显式事务进入错误状态，继续前先执行 `ROLLBACK` 或 `ROLLBACK TO SAVEPOINT`；autocommit 下也应在原因修正后再重试。`pclose_check` 的 frontend 日志由工具自身控制流处理，不应据此要求 SQL 回滚。若连接已断开，待服务器 ready 后重连并核对业务效果。

## 版本 {#versions}
锁定目录从 9.2.0 记录此条件；该目录边界不等于精确实现引入版本。固定源码覆盖 PostgreSQL 18.6。

## 相关 {#related}
[`57P01`](../57p01/)、[`57P02`](../57p02/)、[`XX000`](../xx000/)

## 来源 {#sources}
[`src/backend/access/transam/xlogfuncs.c#L702-708`](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/access/transam/xlogfuncs.c#L702)

[`src/common/exec.c#L52-70`](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/common/exec.c#L52)

[`src/common/exec.c#L391-412`](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/common/exec.c#L391)

[`src/include/common/logging.h#L106-110`](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/include/common/logging.h#L106)

结构化[证据记录](../../data/evidence/58000.json)保存 backend 与 frontend/common 消息边界。
