导语:PostgreSQL 18 中最大的变化是引入了异步 I/O (AIO) 子系统,这引出了一个问题:如何根据工作负载调整它?Tomas Vondra 这篇博客提供了如何设置 AIO 配置,并根据你的工作负载进行测试的实用指南。
PostgreSQL 18 已正式发布,该版本包含大量改进。其中一项重大架构变更是异步 I/O(Asynchronous I/O,简称 AIO) ——它支持对 I/O 操作进行异步调度,使数据库能更好地控制存储资源,同时提升存储利用率。
本文不会详细解释 AIO 的工作原理,也不会展示详尽的基准测试结果。本文的核心目标是分享 PostgreSQL 18 中 AIO 的调优建议,并解释其中一些固有的但却不显而易见的权衡关系与限制。
理想情况下,这些调优建议应被纳入官方文档,但这需要基于实践经验形成明确共识——而 AIO 作为全新特性,目前尚缺乏足够的生产环境验证数据。尽管在开发阶段我们已开展了大量基准测试,并据此设定了默认参数,但这无法替代实际生产系统的运行经验。因此,本文将基于个人经验,探讨如何(可能)调整默认参数,以及在此过程中需权衡的因素。
io_method / io_workers
有一系列与 AIO(或广义上的 I/O)相关的参数。但您可能只需要关注 Postgres 18 中引入的这两个:
- io_method = worker (options: sync, io_uring)
- io_workers = 3
其他参数(如 io_combine_limit)都有合理的默认值。对于如何调整它们,我没有太好的建议,所以暂时保持默认即可。在本文中,我将重点讨论这两个重要的参数。
io_method
io_method 决定了 AIO 实际处理请求的方式——由哪个进程执行 I/O,以及 I/O 是如何被调度的。它有三个可能的值:
sync- 这是一个"向后兼容"选项,在支持的情况下使用posix_fadvice进行同步 I/O。这会将数据预取到页面缓存中,而不是共享缓冲区里。worker- 创建一个"I/O 工作进程"池来执行实际的 I/O。当一个后端进程需要从数据文件中读取一个块时,它会将一个请求插入到共享内存中的队列里。一个 I/O 工作进程被唤醒,执行pread操作,将数据放入共享缓冲区,并通知后端进程。io_uring- 每个后端进程都有一个io_uring实例(一对队列)并使用它来执行 I/O。与worker的不同之处在于,它不是直接执行pread,而是通过io_uring提交请求。
默认值是 io_method = worker。我们确实考虑过将 sync 或 io_uring 都设为默认值,但我认为 worker 是正确的选择。它是真正"异步"的,并且随处可用(因为这是我们自己的实现)。
sync 曾被视为一种"回退"选择,以防我们在 beta/RC 阶段遇到问题。但我们并没有遇到问题,而且也不确

最低0.47元/天 解锁文章
1230

被折叠的 条评论
为什么被折叠?



