# I/O 等待

> 文件读取、写入、同步、分配与异步 I/O 完成。
---

`IO` 表示 PostgreSQL 已为某个文件操作设置探针，而后端必须等内核或另一个 I/O worker 推进后才能继续。它指出的是**哪条 PostgreSQL 文件路径**，但单凭事件本身不能证明存储很慢。

## 把事件、操作和负载阶段一起读 {#how-to-read}

名称通常同时编码对象与操作：`DataFileRead`、`WalSync`、`SlruWrite`、`ReorderBufferRead`。先问当前负载是否本来就该执行这项操作，再把持续时间与并发度关联到 `pg_stat_io`（PG16+）和操作系统延迟。

- **正常：** 扫描读取数据文件，检查点同步脏文件，备份读写，恢复读取 WAL。
- **关注：** 同一个前台 I/O 事件在连续样本中存在，而且设备或查询延迟上升。
- **紧急：** 大量后端排队等待 sync/write、出现错误，或受影响路径达到饱和/限速。

## 值得先认出的事件 {#top-events}

| 事件 | 第一解释 |
| --- | --- |
| [DataFileRead](data-file-read/) | 缓存未命中或扫描正在读取关系数据 |
| [DataFileWrite](data-file-write/) | 后端/检查点路径正在写关系数据 |
| [DataFileSync](data-file-sync/) | 关系改动正在持久化 |
| [WalWrite](wal-write/) | 正在写入 WAL 字节 |
| [WalSync](wal-sync/) | WAL 持久性边界等待 fsync/fdatasync |
| [SlruRead](slru-read/) | 读取事务相关 SLRU 页面 |
| [BuffileRead](buffile-read/) | 读取临时/溢写文件 |
| [AioIoCompletion](aio-io-completion/) | PG18 AIO 工作尚未完成 |

## PG16+ I/O 上下文 {#pg-stat-io}

```sql
SELECT backend_type, object, context,
       reads, read_time, writes, write_time,
       writebacks, fsyncs, fsync_time
FROM pg_stat_io
ORDER BY coalesce(read_time, 0) + coalesce(write_time, 0) + coalesce(fsync_time, 0) DESC;
```

## 常见误读 {#misreads}

- 有意执行顺序扫描时，大量 `DataFileRead` 可能只是健康吞吐。
- `WalWrite` 与 LWLock `WALWrite` 不是一回事：前者是文件操作，后者是内部协调。
- 设备平均延迟可能掩盖单块 WAL 卷饱和或长尾延迟尖刺。
- 增大缓存不能解决所有读取等待；糟糕计划和一次性冷扫描仍可能挤出有用页面。

---

本节页面：

- [IO: AioIoCompletion](/zh/io/aio-io-completion/): 等待另一个进程完成 I/O。
- [IO: AioIoUringExecution](/zh/io/aio-io-uring-execution/): 等待通过 io_uring 执行 I/O。
- [IO: AioIoUringSubmit](/zh/io/aio-io-uring-submit/): 等待通过 io_uring 提交 I/O。
- [IO: BasebackupRead](/zh/io/basebackup-read/): 等待基础备份从文件中读取数据。
- [IO: BasebackupSync](/zh/io/basebackup-sync/): 等待基础备份写入的数据到达持久化存储。
- [IO: BasebackupWrite](/zh/io/basebackup-write/): 等待基础备份向文件写入数据。
- [IO: BuffileRead](/zh/io/buffile-read/): 等待从缓冲文件中读取数据。
- [IO: BuffileTruncate](/zh/io/buffile-truncate/): 等待截断缓冲文件。
- [IO: BuffileWrite](/zh/io/buffile-write/): 等待向缓冲文件写入数据。
- [IO: ControlFileRead](/zh/io/control-file-read/): 等待从 pg_control 文件中读取数据。
- [IO: ControlFileSync](/zh/io/control-file-sync/): 等待 pg_control 文件到达持久化存储。
- [IO: ControlFileSyncUpdate](/zh/io/control-file-sync-update/): 等待 pg_control 文件的更新内容到达持久化存储。
- [IO: ControlFileWrite](/zh/io/control-file-write/): 等待向 pg_control 文件写入数据。
- [IO: ControlFileWriteUpdate](/zh/io/control-file-write-update/): 等待通过写入来更新 pg_control 文件。
- [IO: CopyFileCopy](/zh/io/copy-file-copy/): 等待文件复制操作完成。
- [IO: CopyFileRead](/zh/io/copy-file-read/): 等待在文件复制操作期间读取数据。
- [IO: CopyFileWrite](/zh/io/copy-file-write/): 等待在文件复制操作期间写入数据。
- [IO: DataFileExtend](/zh/io/data-file-extend/): 等待扩展 relation 数据文件。
- [IO: DataFileFlush](/zh/io/data-file-flush/): 等待 relation 数据文件到达持久化存储。
- [IO: DataFileImmediateSync](/zh/io/data-file-immediate-sync/): 等待将 relation 数据文件立即同步到持久化存储。
- [IO: DataFilePrefetch](/zh/io/data-file-prefetch/): 等待从 relation 数据文件异步预取数据。
- [IO: DataFileRead](/zh/io/data-file-read/): 等待从 relation 数据文件中读取数据。
- [IO: DataFileSync](/zh/io/data-file-sync/): 等待 relation 数据文件的变更到达持久化存储。
- [IO: DataFileTruncate](/zh/io/data-file-truncate/): 等待截断 relation 数据文件。
- [IO: DataFileWrite](/zh/io/data-file-write/): 等待向 relation 数据文件写入数据。
- [IO: DsmAllocate](/zh/io/dsm-allocate/): 等待分配动态共享内存段。
- [IO: DsmFillZeroWrite](/zh/io/dsm-fill-zero-write/): 等待用零值填充动态共享内存的后备文件。
- [IO: LockFileAddtodatadirRead](/zh/io/lock-file-addtodatadir-read/): 等待在向数据目录锁文件添加一行时读取数据。
- [IO: LockFileAddtodatadirSync](/zh/io/lock-file-addtodatadir-sync/): 等待向数据目录锁文件添加一行时写入的数据到达持久化存储。
- [IO: LockFileAddtodatadirWrite](/zh/io/lock-file-addtodatadir-write/): 等待在向数据目录锁文件添加一行时写入数据。
- [IO: LockFileCreateRead](/zh/io/lock-file-create-read/): 等待在创建数据目录锁文件时读取数据。
- [IO: LockFileCreateSync](/zh/io/lock-file-create-sync/): 等待创建数据目录锁文件时写入的数据到达持久化存储。
- [IO: LockFileCreateWrite](/zh/io/lock-file-create-write/): 等待在创建数据目录锁文件时写入数据。
- [IO: LockFileRecheckdatadirRead](/zh/io/lock-file-recheckdatadir-read/): 等待在重新检查数据目录锁文件时读取数据。
- [IO: LogicalChangesRead](/zh/io/logical-changes-read/): 等待从逻辑变更文件中读取数据。
- [IO: LogicalChangesWrite](/zh/io/logical-changes-write/): 等待向逻辑变更文件写入数据。
- [IO: LogicalRewriteCheckpointSync](/zh/io/logical-rewrite-checkpoint-sync/): 等待检查点期间的逻辑重写映射到达持久化存储。
- [IO: LogicalRewriteMappingSync](/zh/io/logical-rewrite-mapping-sync/): 等待逻辑重写期间的映射数据到达持久化存储。
- [IO: LogicalRewriteMappingWrite](/zh/io/logical-rewrite-mapping-write/): 等待在逻辑重写期间写入映射数据。
- [IO: LogicalRewriteSync](/zh/io/logical-rewrite-sync/): 等待逻辑重写映射到达持久化存储。
- [IO: LogicalRewriteTruncate](/zh/io/logical-rewrite-truncate/): 等待在逻辑重写期间截断映射数据。
- [IO: LogicalRewriteWrite](/zh/io/logical-rewrite-write/): 等待写入逻辑重写映射。
- [IO: LogicalSubxactRead](/zh/io/logical-subxact-read/): 等待从逻辑子事务文件中读取数据。
- [IO: LogicalSubxactWrite](/zh/io/logical-subxact-write/): 等待向逻辑子事务文件写入数据。
- [IO: RelationMapRead](/zh/io/relation-map-read/): 等待读取 relation map 文件。
- [IO: RelationMapReplace](/zh/io/relation-map-replace/): 等待以持久化方式替换 relation map 文件。
- [IO: RelationMapSync](/zh/io/relation-map-sync/): 等待 relation map 文件到达持久化存储。
- [IO: RelationMapWrite](/zh/io/relation-map-write/): 等待向 relation map 文件写入数据。
- [IO: ReorderBufferRead](/zh/io/reorder-buffer-read/): 等待在 reorder buffer 管理期间读取数据。
- [IO: ReorderBufferWrite](/zh/io/reorder-buffer-write/): 等待在 reorder buffer 管理期间写入数据。
- [IO: ReorderLogicalMappingRead](/zh/io/reorder-logical-mapping-read/): 等待在 reorder buffer 管理期间读取逻辑映射。
- [IO: ReplicationSlotRead](/zh/io/replication-slot-read/): 等待从复制槽控制文件中读取数据。
- [IO: ReplicationSlotRestoreSync](/zh/io/replication-slot-restore-sync/): 等待在将复制槽恢复到内存的过程中，使其控制文件到达持久化存储。
- [IO: ReplicationSlotSync](/zh/io/replication-slot-sync/): 等待复制槽控制文件到达持久化存储。
- [IO: ReplicationSlotWrite](/zh/io/replication-slot-write/): 等待向复制槽控制文件写入数据。
- [IO: SlruFlushSync](/zh/io/slru-flush-sync/): 等待检查点或数据库关闭期间的 SLRU 数据到达持久化存储。
- [IO: SlruRead](/zh/io/slru-read/): 等待读取 SLRU 页面。
- [IO: SlruSync](/zh/io/slru-sync/): 等待页面写入后的 SLRU 数据到达持久化存储。
- [IO: SlruWrite](/zh/io/slru-write/): 等待写入 SLRU 页面。
- [IO: SnapbuildRead](/zh/io/snapbuild-read/): 等待读取序列化的历史系统目录 snapshot。
- [IO: SnapbuildSync](/zh/io/snapbuild-sync/): 等待序列化的历史系统目录 snapshot 到达持久化存储。
- [IO: SnapbuildWrite](/zh/io/snapbuild-write/): 等待写入序列化的历史系统目录 snapshot。
- [IO: TimelineHistoryFileSync](/zh/io/timeline-history-file-sync/): 等待通过流复制接收的时间线历史文件到达持久化存储。
- [IO: TimelineHistoryFileWrite](/zh/io/timeline-history-file-write/): 等待写入通过流复制接收的时间线历史文件。
- [IO: TimelineHistoryRead](/zh/io/timeline-history-read/): 等待读取时间线历史文件。
- [IO: TimelineHistorySync](/zh/io/timeline-history-sync/): 等待新建的时间线历史文件到达持久化存储。
- [IO: TimelineHistoryWrite](/zh/io/timeline-history-write/): 等待写入新建的时间线历史文件。
- [IO: TwophaseFileRead](/zh/io/twophase-file-read/): 等待读取两阶段状态文件。
- [IO: TwophaseFileSync](/zh/io/twophase-file-sync/): 等待两阶段状态文件到达持久化存储。
- [IO: TwophaseFileWrite](/zh/io/twophase-file-write/): 等待写入两阶段状态文件。
- [IO: VersionFileSync](/zh/io/version-file-sync/): 等待创建数据库时的版本文件到达持久化存储。
- [IO: VersionFileWrite](/zh/io/version-file-write/): 等待在创建数据库时写入版本文件。
- [IO: WalBootstrapSync](/zh/io/wal-bootstrap-sync/): 等待引导初始化期间的 WAL 到达持久化存储。
- [IO: WalBootstrapWrite](/zh/io/wal-bootstrap-write/): 等待在引导初始化期间写入 WAL 页面。
- [IO: WalCopyRead](/zh/io/wal-copy-read/): 等待通过复制现有 WAL segment 创建新 WAL segment 时读取数据。
- [IO: WalCopySync](/zh/io/wal-copy-sync/): 等待通过复制现有 WAL segment 创建的新 WAL segment 到达持久化存储。
- [IO: WalCopyWrite](/zh/io/wal-copy-write/): 等待通过复制现有 WAL segment 创建新 WAL segment 时写入数据。
- [IO: WalInitSync](/zh/io/wal-init-sync/): 等待新初始化的 WAL 文件到达持久化存储。
- [IO: WalInitWrite](/zh/io/wal-init-write/): 等待在初始化新 WAL 文件时写入数据。
- [IO: WalRead](/zh/io/wal-read/): 等待从 WAL 文件中读取数据。
- [IO: WalSummaryRead](/zh/io/wal-summary-read/): 等待从 WAL summary 文件中读取数据。
- [IO: WalSummaryWrite](/zh/io/wal-summary-write/): 等待向 WAL summary 文件写入数据。
- [IO: WalSync](/zh/io/wal-sync/): 等待 WAL 文件到达持久化存储。
- [IO: WalSyncMethodAssign](/zh/io/wal-sync-method-assign/): 等待分配新的 WAL 同步方法时写入的数据到达持久化存储。
- [IO: WalWrite](/zh/io/wal-write/): 等待向 WAL 文件写入数据。
- [IO: WalsenderTimelineHistoryRead](/zh/io/walsender-timeline-history-read/): 等待在 WAL sender 执行 timeline 命令期间从时间线历史文件中读取数据。
