四月 21, 2026
摘要:本教程将详细介绍 pg_stat_io 视图,包括字节级 I/O 统计、WAL 预写日志追踪能力,以及各类实用的真实场景用法,助力您更好地完成数据库性能调优。
目录
pg_stat_io 简介
pg_stat_io 视图最早在 PostgreSQL 16 版本中引入,用于展示整个 PostgreSQL 集群内 I/O 操作的详细运行数据。PostgreSQL 18 对该视图进行了大幅升级,新增字节级统计、WAL I/O 数据追踪、单后端进程监控等能力。
该视图能够按照后端进程类型、I/O 对象、运行场景拆分数据库的 I/O 负载,对于分析数据库性能极具价值。在排查慢查询、优化缓冲区缓存配置、分析全集群 I/O 负载规律时,pg_stat_io 都能提供所需的精细化指标。
pg_stat_io 数据结构详解
pg_stat_io 从三个核心维度统计 I/O 数据,以此划分不同类型的数据库运行行为。
后端进程类型
PostgreSQL 会对不同类型进程的 I/O 操作进行独立统计:
client backend:应用程序发起的常规数据库连接进程autovacuum worker:自动清理、自动分析工作进程autovacuum launcher:自动清理进程的调度管理进程background writer:负责将脏数据页刷入磁盘的后台写进程checkpointer:执行数据库检查点操作的检查点进程walwriter:负责将 WAL 预写日志写入磁盘的日志写入进程background worker:自定义后台工作进程
I/O 对象类型
该视图会针对不同数据库对象分别统计 I/O 数据:
relation:数据表、索引及其他关系型数据temp relation:临时表、临时索引(使用本地缓冲区)wal:预写日志数据
I/O 运行场景
不同的业务运行场景,会直接影响 I/O 的执行方式:
normal:常规数据库操作bulkread:批量读操作(顺序扫描、COPY 导入)bulkwrite:批量写操作(COPY 导出、建表并插入数据CREATE TABLE AS)vacuum:数据表清理与分析操作init:数据库初始化操作(WAL 数据追踪功能新增分类)
基础使用与查询示例
接下来讲解如何使用 pg_stat_io 监控数据库的 I/O 性能。
查看整体 I/O 运行概况
我们先查看该视图的基础数据结构:
-- 查看 pg_stat_io 视图基础数据
SELECT backend_type, object, context, reads, writes
FROM pg_stat_io
WHERE reads > 0 OR writes > 0;
通过这条基础查询,可以先确认当前活跃的后端进程与数据对象,再开展后续深度分析。
接着查询负载最高的进程类型:
-- 查找 I/O 操作最繁忙的后端进程
SELECT backend_type, sum(coalesce(reads, 0) + coalesce(writes, 0)) AS total_ios
FROM pg_stat_io
GROUP BY backend_type
ORDER BY total_ios DESC;
该语句会聚合所有进程的 I/O 操作总量,你可以快速定位负载最高的进程。
分析缓冲区缓存命中率
检测数据库缓冲区缓存的工作效率:
-- 简易缓存命中率查询
SELECT
backend_type,
reads,
hits,
(hits * 100 / (reads + hits)) AS hit_percent
FROM pg_stat_io
WHERE object = 'relation' AND reads + hits > 0
ORDER BY hit_percent;
该命中率可以直观反映共享缓冲区的缓存效果。数值偏低,说明缓存压力较大,或是存在大量全表扫描。
命中率低于 90% 时,通常需要调大 shared_buffers 参数,或是优化产生大量全表扫描的慢查询。
监控 WAL 预写日志 I/O 负载
查询哪些进程产生的 WAL 写入量最高:
-- 查看 WAL 相关 I/O 活动
SELECT
backend_type,
writes,
pg_size_pretty(write_bytes) AS wal_volume
FROM pg_stat_io
WHERE object = 'wal' AND writes > 0
ORDER BY write_bytes DESC;
这条语句可以清晰展示 WAL 写入来源,定位日志流量的主要产生进程,判断是否存在 WAL 日志过量生成的问题 —— 日志过多会影响数据库性能、占用大量磁盘空间。
定位自动清理进程的 I/O 开销
自动清理进程能够避免数据表、索引产生数据膨胀,是数据库必不可少的进程。但在高写入负载场景下,该进程会带来明显的磁盘 I/O 压力。
通过 pg_stat_io 可以统计自动清理进程的 I/O 负载:
SELECT backend_type, sum(reads) as total_reads, sum(writes) as total_writes
FROM pg_stat_io
WHERE backend_type = 'autovacuum worker'
GROUP BY backend_type;
数据库管理员可依据该数据调优自动清理相关参数(autovacuum_vacuum_cost_delay、autovacuum_max_workers),在数据清理效率与 I/O 资源消耗之间达到平衡。
监控后台写进程运行效率
后台写进程负责将内存脏缓冲区写入磁盘,以此减轻检查点操作的集中 I/O 压力。借助 pg_stat_io,你可以查看该进程的 I/O 操作量,判断其运行效率:
SELECT backend_type, writes, write_time
FROM pg_stat_io
WHERE backend_type = 'background writer';
若该进程写入量长期处于高位,可以调整 bgwriter_lru_maxpages 或检查点相关参数,让磁盘 I/O 负载分布更加平缓均匀。
参数配置与 I/O 耗时统计
想要获取 pg_stat_io 中的精细化耗时数据,需要先开启数据库的耗时统计采集功能。
开启 I/O 耗时统计
若要统计查询在 I/O 等待上耗费的时间,必须先开启耗时采集开关。PostgreSQL 通过两个配置参数控制:track_io_timing、track_wal_io_timing,开启方式如下:
-- 开启 I/O 耗时统计(需要超级用户权限)
SET track_io_timing = on;
SET track_wal_io_timing = on;
开启统计功能后,即可查询各操作的 I/O 耗时:
-- 查看 I/O 耗时统计信息
SELECT
backend_type,
reads,
read_time,
writes,
write_time
FROM pg_stat_io
WHERE reads > 0 OR writes > 0
ORDER BY (coalesce(read_time, 0) + coalesce(write_time, 0)) DESC;
该语句会展示各进程在读写操作上消耗的总时长,用于定位耗时严重的慢查询与异常进程。
重置统计数据
你可以随时重置 I/O 统计数据,从零开始重新采集指标:
-- 重置所有 I/O 共享统计数据
SELECT pg_stat_reset_shared('io');
该操作适合在修改数据库配置后、或是需要新建性能基线数据时使用。