PostgreSQL 教程: 借助 pg_stat_io 调优 I/O 性能

四月 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_delayautovacuum_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_timingtrack_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');

该操作适合在修改数据库配置后、或是需要新建性能基线数据时使用。

了解更多

PostgreSQL 优化