# PostgreSQL 等待事件大典

> 后端在等什么、等待从哪条代码路径开始，以及值班工程师下一步该做什么。
---

<div class="wait-deck">
  <div class="wait-panel">
    <div class="wait-panel__eyebrow">值班入口</div>
    <h2>先看正在等待的会话，再看事件名称</h2>
    <p>先保全现场：谁在等、等了多久、事务是否仍然打开、阻塞者是谁。再用事件条目把快照连接到 PostgreSQL 源码与边界清晰的处置动作。</p>
  </div>
  <div class="wait-stats" aria-label="大典覆盖范围">
    <div class="wait-stat"><strong>13–18</strong><span>覆盖的 PostgreSQL 版本</span></div>
    <div class="wait-stat"><strong>327</strong><span>版本矩阵中的事件身份</span></div>
    <div class="wait-stat"><strong>8</strong><span>面向运维的等待类别</span></div>
    <div class="wait-stat"><strong>2</strong><span>中英文逐页配对</span></div>
  </div>
</div>

<div class="signal-strip"><span class="signal-dot"></span><strong>事实链</strong><code>官方文档 → pg_wait_events → 源码 grep → 实际执行 SQL</code></div>

## 先做第一张快照 {#first-snapshot}

重启服务或取消后端之前，先执行：

```sql {title="当前正在等待的会话"}
SELECT pid, backend_type, usename, datname, application_name,
       state, now() - query_start AS query_age,
       now() - xact_start AS xact_age,
       wait_event_type, wait_event,
       pg_blocking_pids(pid) AS blocking_pids,
       left(query, 160) AS query
FROM pg_stat_activity
WHERE wait_event IS NOT NULL
ORDER BY query_age DESC NULLS LAST;
```

> [!IMPORTANT]
> 等待事件快照只说明**进程此刻睡在哪里**，不代表查询耗时都花在这里。重复采样，并与延迟、吞吐、锁以及操作系统证据关联后，才能判断它是不是根因。

接着使用[等待事件排查总图](/zh/triage/)，或按 `wait_event_type` 进入对应类别。

## 按类别阅读 {#classes}

| 类别 | 应当怎样理解 | 第一个问题 |
| --- | --- | --- |
| [Lock](/zh/lock/) | 另一个事务或会话持有重量级锁 | 阻塞链最前端是谁？ |
| [LWLock](/zh/lwlock/) | PostgreSQL 内部共享内存结构发生竞争 | 重复采样时是否总是同一内部资源发热？ |
| [IO](/zh/io/) | 后端在等待文件操作 | 是存储变慢，还是 PostgreSQL 正在做预期工作？ |
| [IPC](/zh/ipc/) | 进程正在彼此协调 | 哪个对端或执行阶段还没到达同步点？ |
| [Client](/zh/client/) | PostgreSQL 在等待应用或网络 | 会话是正常空闲、发生背压，还是卡在事务里？ |
| [Activity](/zh/activity/) | 后台进程处于正常主循环 | 对这种后端类型而言，这是不是预期空闲？ |
| [Timeout](/zh/timeout/) | 有意设置的计时器或限速尚未到期 | 是哪条策略主动插入了等待？ |
| [BufferPin](/zh/bufferpin/) | 其他后端钉住缓冲区，使其不能移动 | 哪个游标或扫描仍持有 pin？ |

通用的[扩展等待事件机制](/zh/extension/)单独说明；扩展自行注册的名称不纳入本大典。

## 证据契约 {#evidence-contract}

每个完成的事件条目都明确区分四类信息：

1. **事实**：事件身份、版本范围与官方描述译文。
2. **分析**：报告等待的源码路径，以及该路径正在做什么。
3. **建议**：结合负载的正常/异常边界与分场景动作。
4. **证据**：可执行 SQL 与精确到 PostgreSQL 发布版本的源码 `file:line`。

当同一名称只在部分大版本出现时，使用[版本矩阵](/zh/matrix/)对照。

---

本节页面：

- [等待事件排查总图](/zh/triage/): 从一张 pg_stat_activity 快照走向下一步安全动作的决策树。
- [版本矩阵](/zh/matrix/): 对账后的 PostgreSQL 13–18 等待事件清单，包括改名与类型迁移。
- [值班术语表](/zh/glossary/): 身份、分析、建议与证据字段中统一使用的术语。
- [Lock 等待](/zh/lock/): 通常可以直接从 SQL 找到持有者与阻塞链的重量级锁。
- [LWLock 等待](/zh/lwlock/): PostgreSQL 内部共享内存数据结构上的竞争。
- [I/O 等待](/zh/io/): 文件读取、写入、同步、分配与异步 I/O 完成。
- [IPC 等待](/zh/ipc/): PostgreSQL 进程等待对端、worker、屏障、队列或阶段变化。
- [Client 等待](/zh/client/): PostgreSQL 等待应用、网络套接字、TLS/GSS 握手或复制客户端。
- [Activity 等待](/zh/activity/): 后台进程在主循环中休眠，等待新工作到来。
- [Timeout 等待](/zh/timeout/): 有意休眠、重试间隔、节流与限速延迟。
- [BufferPin 等待](/zh/bufferpin/): 后端需要独占缓冲区 pin，但另一个后端仍持有 pin。
- [扩展等待事件](/zh/extension/): PostgreSQL 扩展如何注册并报告自定义等待名称，以及它们为什么不进入核心大典。
- [关联 GUC](/zh/guc/): 等待事件处置建议引用的配置控制项。
- [关联指标](/zh/metric/): 用于判断等待正常还是有害的观测信号。
