I/O 等待
IO 表示 PostgreSQL 已为某个文件操作设置探针,而后端必须等内核或另一个 I/O worker 推进后才能继续。它指出的是哪条 PostgreSQL 文件路径,但单凭事件本身不能证明存储很慢。
把事件、操作和负载阶段一起读
名称通常同时编码对象与操作:DataFileRead、WalSync、SlruWrite、ReorderBufferRead。先问当前负载是否本来就该执行这项操作,再把持续时间与并发度关联到 pg_stat_io(PG16+)和操作系统延迟。
- 正常: 扫描读取数据文件,检查点同步脏文件,备份读写,恢复读取 WAL。
- 关注: 同一个前台 I/O 事件在连续样本中存在,而且设备或查询延迟上升。
- 紧急: 大量后端排队等待 sync/write、出现错误,或受影响路径达到饱和/限速。
值得先认出的事件
| 事件 | 第一解释 |
|---|---|
| DataFileRead | 缓存未命中或扫描正在读取关系数据 |
| DataFileWrite | 后端/检查点路径正在写关系数据 |
| DataFileSync | 关系改动正在持久化 |
| WalWrite | 正在写入 WAL 字节 |
| WalSync | WAL 持久性边界等待 fsync/fdatasync |
| SlruRead | 读取事务相关 SLRU 页面 |
| BuffileRead | 读取临时/溢写文件 |
| AioIoCompletion | PG18 AIO 工作尚未完成 |
PG16+ I/O 上下文
常见误读
- 有意执行顺序扫描时,大量
DataFileRead可能只是健康吞吐。 WalWrite与 LWLockWALWrite不是一回事:前者是文件操作,后者是内部协调。- 设备平均延迟可能掩盖单块 WAL 卷饱和或长尾延迟尖刺。
- 增大缓存不能解决所有读取等待;糟糕计划和一次性冷扫描仍可能挤出有用页面。
等待另一个进程完成 I/O。
等待通过 io_uring 执行 I/O。
等待通过 io_uring 提交 I/O。
等待基础备份从文件中读取数据。
等待基础备份写入的数据到达持久化存储。
等待基础备份向文件写入数据。
等待从缓冲文件中读取数据。
等待截断缓冲文件。
等待向缓冲文件写入数据。
等待从 pg_control 文件中读取数据。
等待 pg_control 文件到达持久化存储。
等待 pg_control 文件的更新内容到达持久化存储。
等待向 pg_control 文件写入数据。
等待通过写入来更新 pg_control 文件。
等待文件复制操作完成。
等待在文件复制操作期间读取数据。
等待在文件复制操作期间写入数据。
等待扩展 relation 数据文件。
等待 relation 数据文件到达持久化存储。
等待将 relation 数据文件立即同步到持久化存储。
等待从 relation 数据文件异步预取数据。
等待从 relation 数据文件中读取数据。
等待 relation 数据文件的变更到达持久化存储。
等待截断 relation 数据文件。
等待向 relation 数据文件写入数据。
等待分配动态共享内存段。
等待用零值填充动态共享内存的后备文件。
等待在向数据目录锁文件添加一行时读取数据。
等待向数据目录锁文件添加一行时写入的数据到达持久化存储。
等待在向数据目录锁文件添加一行时写入数据。
等待在创建数据目录锁文件时读取数据。
等待创建数据目录锁文件时写入的数据到达持久化存储。
等待在创建数据目录锁文件时写入数据。
等待在重新检查数据目录锁文件时读取数据。
等待从逻辑变更文件中读取数据。
等待向逻辑变更文件写入数据。
等待检查点期间的逻辑重写映射到达持久化存储。
等待逻辑重写期间的映射数据到达持久化存储。
等待在逻辑重写期间写入映射数据。
等待逻辑重写映射到达持久化存储。
等待在逻辑重写期间截断映射数据。
等待写入逻辑重写映射。
等待从逻辑子事务文件中读取数据。
等待向逻辑子事务文件写入数据。
等待读取 relation map 文件。
等待以持久化方式替换 relation map 文件。
等待 relation map 文件到达持久化存储。
等待向 relation map 文件写入数据。
等待在 reorder buffer 管理期间读取数据。
等待在 reorder buffer 管理期间写入数据。
等待在 reorder buffer 管理期间读取逻辑映射。
等待从复制槽控制文件中读取数据。
等待在将复制槽恢复到内存的过程中,使其控制文件到达持久化存储。
等待复制槽控制文件到达持久化存储。
等待向复制槽控制文件写入数据。
等待检查点或数据库关闭期间的 SLRU 数据到达持久化存储。
等待读取 SLRU 页面。
等待页面写入后的 SLRU 数据到达持久化存储。
等待写入 SLRU 页面。
等待读取序列化的历史系统目录 snapshot。
等待序列化的历史系统目录 snapshot 到达持久化存储。
等待写入序列化的历史系统目录 snapshot。
等待通过流复制接收的时间线历史文件到达持久化存储。
等待写入通过流复制接收的时间线历史文件。
等待读取时间线历史文件。
等待新建的时间线历史文件到达持久化存储。
等待写入新建的时间线历史文件。
等待读取两阶段状态文件。
等待两阶段状态文件到达持久化存储。
等待写入两阶段状态文件。
等待创建数据库时的版本文件到达持久化存储。
等待在创建数据库时写入版本文件。
等待引导初始化期间的 WAL 到达持久化存储。
等待在引导初始化期间写入 WAL 页面。
等待通过复制现有 WAL segment 创建新 WAL segment 时读取数据。
等待通过复制现有 WAL segment 创建的新 WAL segment 到达持久化存储。
等待通过复制现有 WAL segment 创建新 WAL segment 时写入数据。
等待新初始化的 WAL 文件到达持久化存储。
等待在初始化新 WAL 文件时写入数据。
等待从 WAL 文件中读取数据。
等待从 WAL summary 文件中读取数据。
等待向 WAL summary 文件写入数据。
等待 WAL 文件到达持久化存储。
等待分配新的 WAL 同步方法时写入的数据到达持久化存储。
等待向 WAL 文件写入数据。
等待在 WAL sender 执行 timeline 命令期间从时间线历史文件中读取数据。