pgrac 在 PG 原有 9 类等待事件之上,新增 10 个 Cluster:* 子类,共引入 46 个新等待事件(Wait Event ID 范围 0x1000_0000–0x19FF_FFFF)。本章是这些事件的参考目录:事件名称、类型、起止点定义、典型耗时、触发场景。叙述极简,细节请参阅 wait-events-design.md 原始设计文档。
所有 pgrac 新增事件均挂载在 Cluster: 前缀子类下,子类用点分层次组织。
| 规则 | 说明 | 示例 |
|---|---|---|
| 前缀 | 所有 pgrac 事件归属 Cluster: 大类 | Cluster: PCM |
| 子类分隔 | 冒号 + 空格分隔大类与子类名 | Cluster: GES |
| 事件名 | 驼峰词组,动词在后 | PCM block read N→S |
| 采样事件后缀 | 极短路径(< 5μs)加 (sampled) 标注 | GES local fast path |
为什么需要严格起止点? 等待事件的起止点不精确会导致两类问题:(1)重叠——同一段时间被两个事件重复计时,破坏端到端加和;(2)遗漏——CPU 时间被错误归入等待,掩盖真实瓶颈。pgrac 在实现层面以 pgstat_report_wait_start / pgstat_report_wait_end 严格成对调用,并通过 assertion 在 debug build 检测嵌套违规(INV1 不重叠原则)。
| 规范条目 | 内容 |
|---|---|
| 最短可计时阈值 | < 100 ns 的自旋等待不进入等待事件,归属 CPU |
| 起点 | 调用 pgstat_report_wait_start(WAIT_EVENT_*) 的那一行 |
| 终点 | 调用 pgstat_report_wait_end() 的那一行 |
| 不重叠(INV1) | 任意时刻 backend 只能处于一个活跃等待事件 |
| 子事件处理 | 父事件先 wait_end,子事件 wait_start;子事件结束后父事件可重启计时 |
| 采样事件 | 典型 < 5μs 的事件按 1/100 采样;累计值由 Cluster Stats 进程聚合 |
pgrac wait events
├─ Cluster · IPC
│ ├─ lms_pcm_msg (PCM block read N→S / N→X / S→X)
│ ├─ ges_grant_wait (GES enqueue acquire / convert)
│ └─ rdma_completion (Interconnect RDMA send / recv)
├─ Cluster · Lock
│ ├─ pcm_convert_wait (PCM block convert wait)
│ ├─ ges_master_wait (GES enqueue acquire — 有冲突路径)
│ └─ deadlock_probe_wait (GES deadlock detection)
├─ Cluster · Recovery
│ ├─ reconfig_freeze (Reconfig: barrier wait / fence wait)
│ └─ merged_redo_apply (Recovery: k-way merge / apply per-thread)
└─ Cluster · Disk I/O
├─ voting_disk_io (Reconfig: fence wait — disk heartbeat)
└─ shared_fs_io (IO: DataFileRead/Write on shared storage)
IPC 类事件涵盖 backend 与本节点后台进程(LMS / LMD)之间,以及跨节点 RDMA / TCP Interconnect 消息往返所产生的等待。这类等待是 pgrac 集群化开销的主体,典型耗时在微秒级。
| Event Name | wait_event_type | Start | End | Typical Time | 触发场景 |
|---|---|---|---|---|---|
PCM block read N→S | Cluster: PCM | ReadBufferExtended 检测 PCM 状态 N | buffer install 到本节点 buffer pool | 9–18 μs | backend 首次读块,本节点无副本 |
PCM block read N→X | Cluster: PCM | 同 N→S,仅请求模式为 X | 同 N→S | 10–15 μs | UPDATE/DELETE 路径直接申请独占 |
PCM block write S→X | Cluster: PCM | MarkBufferDirty 检测需升级 S→X | 升级完成,可写 | 12–20 μs | 本节点持有 S 副本,需写时升级 |
Buffer ship cr receive | Cluster: BufferShip | GetCRBuffer 决定远程获取 | CR buffer install 到 CR chain | 10–20 μs | 读事务需要一致性读版本(2-way / 3-way) |
Buffer ship current receive | Cluster: BufferShip | 申请 X,等待接收 current 块 | current buffer install | 10–18 μs | DML 路径接收对端 ship 的 current 块 |
Interconnect RDMA send | Cluster: Interconnect | ibv_post_send() 调用前 | send completion event | 1–3 μs(L1 RDMA)/ 50–100 μs(TCP) | 所有 PCM / GES / Sinval 消息出站 |
Interconnect RDMA recv | Cluster: Interconnect | ibv_post_recv() 提交后 | recv completion event | 1–3 μs | 所有入站消息接收 |
Sinval broadcast receive | Cluster: Sinval | 收到其他节点 sinval 广播 | 消息 inject 到本节点 sinval queue | 3–5 μs | DDL 跨节点 catcache / relcache 失效传播 |
GES enqueue release ack | Cluster: GES | LockRelease 发出 RELEASE 消息 | 收到 master RELEASE_ACK | 5–7 μs | 锁释放需等待 master 确认 |
SCN piggyback merge | Cluster: SCN | 入站消息含 piggyback SCN > local_scn | local_scn CAS 推进完成 | 0.5–1 μs(采样) | 每条 RDMA 入站消息携带 SCN 推进 |
Lock 类事件涵盖 GES(Global Enqueue Service)锁竞争以及 PCM(Page Consistency Manager)块锁状态机中的排队等待。这类事件在无冲突稳态下几乎不出现;出现说明锁竞争或集群拥塞。
| Event Name | wait_event_type | Start | End | Typical Time | 触发场景 |
|---|---|---|---|---|---|
GES enqueue acquire | Cluster: GES | LockAcquireExtended 确认锁不可立即授予 | 锁被授予,backend wakeup | 8 μs(无冲突)/ 数 ms–数 s(有 holder) | 事务级 / 对象级 / DDL 级锁等待 |
GES enqueue convert | Cluster: GES | 持有锁需提升模式(S→X 等) | 升级完成 | 10–15 μs(无冲突)/ 数十 ms(协调) | 锁模式升级路径 |
GES master query | Cluster: GES | 进入 find_resource_master(),GRD cache miss | 返回 master node_id | 5–10 μs | GRD cache miss 时广播查询 master |
PCM block convert wait | Cluster: PCM | master convert queue 非空,本请求入队 | 被调度出队 | < 50 μs(正常)/ 数 ms(高峰) | master 端 convert queue 积压 |
PCM block downgrade | Cluster: PCM | LMS 收到 master downgrade 请求 | downgrade 完成(含 PI 创建) | 3–10 μs(无 dirty)/ 1–100 ms(含 dirty 写回) | 其他节点请求本节点 X/S 副本降级 |
PCM ITL cleanout | Cluster: PCM | heap_page_prune 检测需 ITL cleanout | cleanout 完成(临时 S→X 升级) | 15–25 μs | 读块时发现 ITL 需清理,触发独占升级 |
GES enqueue acquire 有冲突时等待时长完全由业务决定(持锁事务的提交速度)。P99 超过 100 μs 说明存在锁竞争热点,需结合 pg_stat_activity.wait_event 和 pg_locks 排查持锁事务。
Recovery 类事件在两种场景下出现:Reconfiguration(节点加入 / 退出 / 故障)期间 backend 被 Freeze 阻塞、以及 crash recovery 时 Recovery Worker 并行 apply WAL。正常运行时这些事件应接近零;出现持续等待说明集群正在处理成员变更或从故障中恢复。
| Event Name | wait_event_type | Start | End | Typical Time | 触发场景 |
|---|---|---|---|---|---|
Reconfig: barrier wait | Cluster: Reconfig | 节点进入全局 barrier 同步点 | 所有活节点到达 barrier | 10–100 ms | GRD 切换前的全局同步屏障 |
Reconfig: fence wait | Cluster: Reconfig | LMON 决策 fence 死亡节点后开始等待 | fence 确认完成 | 1–5 s | 确认死亡节点已停止写盘 / 网络已隔离 |
Reconfig: GRD rebuild | Cluster: Reconfig | LMON 触发 GRD rebuild | 所有活节点 GRD 一致 | 50–200 ms(4 节点)/ 300 ms–1 s(16 节点) | 节点加入 / 退出后重建全局资源目录 |
Recovery: k-way merge | Cluster: Recovery | merge 算法启动(多路 WAL stream 就绪) | 按 SCN 排序的 redo stream 准备好 | 10–100 ms / 1 GB WAL | crash recovery 时多 thread WAL 按 SCN 归并 |
Recovery: apply per-thread | Cluster: Recovery | Worker 收到 thread WAL 段 | 该段 apply 完成 | 吞吐 ~100 MB/s | crash recovery 并行 apply 阶段(per worker) |
Recovery: PCM state restore | Cluster: Recovery | apply 完成后启动 PCM 状态重建 | 所有节点 PCM 状态一致 | 50–500 ms | 恢复完成后重建哪些块在哪些节点持有什么锁 |
Reconfiguration 期间,所有 backend 同时阻塞在 CHECK_FROZEN() 宏——它们会顺序显示 Reconfig: barrier wait(Freeze 阶段)。Freeze 目标耗时 ≤ 2 秒,超时后 CSSD 升级为集群重启。
Disk I/O 类事件涵盖 pgrac 新增的存储访问路径:voting disk 心跳写、shared storage 数据文件访问、以及集群 WAL / 归档 IO。PG 原生的 IO: 类事件在语义上不变,但分布会因 shared storage 延迟(NVMe-oF +5–10 μs;iSCSI +50 μs)而略有变化——监控时需在 pg_stat_cluster_io 视图区分本地盘与 shared storage。
| Event Name | wait_event_type | Start | End | Typical Time | 触发场景 |
|---|---|---|---|---|---|
IO: DataFileRead (shared) | IO | smgrread() 调用前 | 数据返回 | 50–200 μs(iSCSI)/ 10–30 μs(NVMe-oF) | buffer cache miss,从 shared storage 读 page |
IO: DataFileWrite (shared) | IO | smgrwrite() 调用前 | write 确认 | 50–200 μs(iSCSI) | dirty page 刷盘到 shared storage |
Reconfig: fence wait (disk) | Cluster: Reconfig | CSSD 检测 disk heartbeat 超时 | IO fence 完成 | 1–5 s | voting disk heartbeat 超时触发的磁盘隔离 |
Interconnect TCP fallback | Cluster: Interconnect | 检测到 RDMA 不可用,进入 TCP 降级 | TCP 路径消息收发完成 | 50–200 μs | RDMA 链路故障时的保底路径(告警级别) |
Interconnect TCP fallback 任何出现即告警——正常运行应全程在 RDMA Tier,TCP 降级意味着 Interconnect 硬件 / 配置异常,单次 fallback 代价是 RDMA 的 25–100 倍。
pg_stat_cluster_wait_events 视图Buffer ship cr receive / Buffer ship current receive)的产生来源GES enqueue acquire / GES enqueue convert 等)的产生来源