PostgreSQL 18 异步 IO 完全指南:配置、测试与调优

PostgreSQL 18 异步 I/O 让数据库并发提交多个读请求,云存储等高延迟环境下读密集负载可提速 2-3 倍。本文讲清 worker/io_uring/sync 三种模式、参数配置、基准测试方法,以及异步 I/O 无效的三种场景。

最佳实践
PostgreSQL主题插画

PostgreSQL 18 的异步 I/O是多年来读取路径最大的一次改造。以前数据库读盘是一个请求等一个结果,靠操作系统预读(readahead)猜下一步要哪块数据——但 OS 看不懂查询计划,经常猜错。异步 I/O 让 PostgreSQL 基于查询计划自己决定预读,并并发提交多个读请求。在云厂商的网络存储这类高延迟环境,读密集负载可获 2-3 倍提升。

当前支持异步加速的操作:顺序扫描、位图堆扫描、VACUUM 等维护操作——都是访问模式可预测、预读命中率高的场景。

三种 I/O 模式

通过 io_method 参数控制:

模式 机制 适用
worker(默认) 专门的 I/O worker 后台进程代为执行读请求 所有平台,开箱即用
io_uring 走 Linux 5.1+ 内核的 io_uring 接口,共享环形缓冲直交内核,开销更低 Linux 且编译时带 --with-liburing
sync 退回 17 的同步行为 排障和对比测试用

检查 worker 进程(默认 io_workers = 3):

ps aux | grep "io worker" | grep -v grep
# postgres: 18/main: io worker 0 / 1 / 2

检查能否用 io_uring

uname -r                                        # 内核 ≥ 5.1
ldd /usr/lib/postgresql/18/bin/postgres | grep uring   # 有 liburing 即支持

没有 liburing 也不用纠结——worker 模式已能拿到大部分收益。

上手测试流程

-- 1. 建专用测试库
-- sudo -u postgres createdb aio_test && sudo -u postgres psql aio_test

-- 2. 查看当前模式
SHOW io_method;

-- 3. 建大于内存的测试表(关键!异步 I/O 的收益只在真正读盘时体现)

测试要点:测试表必须大于可用内存。数据全在缓存里时根本没有磁盘 I/O,异步优化无从体现——这是测评结论两极分化的主要原因。

基准测试方法:先用 io_method = 'sync' 跑一遍目标查询记录耗时,再切 worker(和 io_uring,若可用)各跑一遍对比。跑前清缓存或重启,避免热缓存污染结果。

参数调优与固化

测试出最优值后写进 postgresql.conf

effective_io_concurrency = 32      # 常规查询的并发度,按测试结果定
maintenance_io_concurrency = 100   # VACUUM/建索引等维护任务,可给更高
io_method = 'worker'               # 支持则换 'io_uring'
io_workers = 3                     # I/O worker 进程数

维护类并发度通常给得更高,因为 VACUUM、CREATE INDEX 多在业务低峰跑。改完需重启生效。

异步 I/O 帮不上忙的三种场景

别对它抱不切实际的期待,先判断你的瓶颈在哪:

1. 缓存命中率本来就高

SELECT
  sum(heap_blks_read) AS disk_reads,
  sum(heap_blks_hit)  AS cache_hits,
  round(sum(heap_blks_hit)::numeric /
        nullif(sum(heap_blks_hit) + sum(heap_blks_read), 0) * 100, 2) AS hit_ratio
FROM pg_statio_user_tables;

命中率 99%+ 说明数据基本都在内存,没什么盘可读,异步 I/O 自然无用武之地。

2. CPU 密集型查询:排序、聚合、大连接吃掉大部分时间的分析型查询,瓶颈在 CPU 不在 I/O。看执行计划里 buffer 读取占比就知道。

3. 存储已打满iostat -x 2%util 长期 100% 且 await 很高,说明硬件已到极限——异步 I/O 只会让你更快撞到天花板,不会提高天花板。

排障速查

  • 切换模式没效果 → 先查缓存命中率(见上);再确认测试数据量大于内存;
  • io_uring 不生效 → 检查内核版本和 liburing 编译支持,退回 worker 验证;
  • 改了参数没变化io_method 等参数需重启生效,会话级 SET 只对当前连接有效;
  • 想确认异步在工作 → 查 pg_aios 视图看活跃的异步文件句柄。

观测云对照

调 I/O 参数是"盲人摸象"还是"有的放矢",取决于你有没有持续的数据库指标。观测云 DataKit 采集 PostgreSQL 的连接、事务、缓存命中率、慢查询、锁等待等指标,配合主机层面的磁盘 util/await 指标,可以在同一仪表板上对照"参数调整 → I/O 行为 → 查询延迟"的完整因果链;监控器可对慢查询率、磁盘 util 设阈值告警,防止调优后的回退无人察觉。 1 2

常见问题(FAQ)

Q:异步 I/O 对写入有帮助吗?
目前主要针对读操作(顺序扫描、位图堆扫描、VACUUM)。写入路径的异步化是后续版本的方向。

Q:生产环境推荐 worker 还是 io_uring?
内核和编译支持都满足时优先 io_uring(开销更低);不确定就用默认 worker,收益差距不大,稳定性更有把握。

Q:升级 18 后什么都不用改就有收益吗?
是。默认 io_method = 'worker' 已开启异步读。调参只是锦上添花。

Q:云 RDS 上能用吗?
取决于厂商是否跟进到 PostgreSQL 18 并开放相关参数。网络存储恰好是异步 I/O 收益最大的场景,值得关注所用云厂商的版本支持节奏。

参考资料

获取专属方案

联系我们

加入社区

微信扫码
加入官方交流群

立即体验

在线开通,按量计费,真正的云服务!

立即开始

选择观测云版本

代码托管平台