由 John Doe 十月 17, 2025
你知道如何监控分析 PostgreSQL 的 I/O 吗?现在,PostgreSQL 有了新的 I/O 统计数据,辅助你调整相关配置。
特性提交日志
将 pg_stat_io 中部分操作的 I/O 统计单位从“块”改为“字节”。
目前在 pg_stat_io 视图中,I/O 操作的统计单位是大小为BLCKSZ
(PostgreSQL 默认的块大小为 8 KB)的“块”。该设计存在两项局限:
- 因为 I/O 请求在发送前可能会被合并,发送给内核的实际 I/O 请求数量会更少。此外,这种统计方式会给人“所有 I/O 操作均以块为单位执行”的印象,从而掩盖了 I/O 请求合并带来的优势。
- 目前已有部分补丁正在开发中,旨在扩展 pg_stat_io 的功能,使其能够跟踪与块大小无关的操作。例如,WAL 预写日志的读取 I/O 操作以可变字节数执行,无法在现有 pg_stat_io 视图中准确展示;而我们希望将所有此类数据集中在单个系统视图中,而非分散到多个视图中,以简化监控操作。
现在,WaitReadBuffers()
函数对应的 I/O 操作可作为“占用 N 个块大小”的单次读取操作进行统计。对于扩展操作对应的ExtendBufferedRelShared()
函数和ExtendBufferedRelLocal()
函数,也采用相同的统计逻辑。
本次修改为pg_stat_io
新增了三列,分别用于以“字节”为单位统计读取(reads)、写入(writes)和扩展(extends)操作的 I/O 量。同时,删除了此前始终硬编码为BLCKSZ
的“op_bytes”列。此外,已更新 I/O 后端统计数据,以适配上述变更。
讨论:https://postgr.es/m/CAN55FZ0oqxBaaHAEsj=xFqkzE3n5P=3RA1V_igXwL-RV7QRzyw@mail.gmail.com
示例
例如,数据库使用 SSD 存储,开启了 IO 合并功能,但不确定实际效果如何。需要判断“合并后的 IO 单次处理字节数”是否合理,是否存在合并不充分的情况。
要计算“读取/写入”操作的“单次平均字节数”,评估 IO 合并效率,可以执行下面的 SQL 查询:
SELECT
object,
context,
reads,
read_bytes,
-- 计算单次读取平均字节数(转换为KB,便于理解)
ROUND(read_bytes / NULLIF(reads, 0) / 1024, 2),
writes,
write_bytes,
ROUND(write_bytes / NULLIF(writes, 0) / 1024, 2)
FROM pg_stat_io
-- 聚焦普通表的正常 IO 操作,可根据需求调整过滤条件
WHERE object = 'relation' AND context = 'normal'
ORDER BY object, context;
若“单次平均字节数”接近存储设备的“最优 IO 大小”(如 SSD 通常为 64KB~256KB),说明 IO 合并效果好;
若远低于最优值(如仅 8KB,即 1 个块),需检查存储驱动配置或数据库异步 I/O 参数,优化合并策略。
另外,WAL 预写日志是数据库的核心保障,我们可以通过 pg_stat_io 视图,掌握 WAL 读取/写入的真实字节量,优化数据库整体性能。
可以单独统计 WAL 相关的 IO 字节量与耗时,定位出 WAL 处理瓶颈:
SELECT
object,
reads,
read_bytes,
read_time,
writes,
write_bytes,
-- 计算单次 WAL 写入量
write_bytes / writes,
write_time
FROM pg_stat_io
WHERE object = 'wal' -- 筛选 WAL 相关 IO
ORDER BY read_bytes + write_bytes DESC;
若 WAL 写入速度持续过高(如每秒超过 100MB),需检查是否存在大量大事务,可拆分事务或调整wal_buffers
参数;
若单次 WAL 写入量过小(如每次低于 1KB),可以尝试调整commit_delay
和commit_siblings
参数,合并 WAL 的写入。
PostgreSQL 本次对pg_stat_io
中 I/O 活动量的细化,升级成了全场景的 IO 统计监控。让 DBA 不仅能更真实地评估 IO 合并、WAL 负载等核心场景的性能,还能基于精准数据优化存储配置、调整数据库参数。
非常不错的改进,感谢社区的所有相关人员。
参考
提交日志:https://git.postgresql.org/pg/commitdiff/f92c854cf406a5ad34c9aa92416d578819704aa2