PostgreSQL 18 preview - 提高effective和 maintenance io 并发默认值
PostgreSQL 18 preview - 提高默认的 effective_io_concurrency 至 16
PostgreSQL 18 提高默认的 effective_io_concurrency 至 16, 建议大家使用时测试一下实际效果.
https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=ff79b5b2aba02d720f9b7fff644dd50ce07b8c6e
Increase default effective_io_concurrency to 16
author Melanie Plageman <[email protected]>
Wed, 12 Mar 2025 19:56:59 +0000 (15:56 -0400)
committer Melanie Plageman <[email protected]>
Wed, 12 Mar 2025 19:57:44 +0000 (15:57 -0400)
commit ff79b5b2aba02d720f9b7fff644dd50ce07b8c6e
tree 4591f073288d14e04bb2e5b000ab496a55669bf4 tree
parent af717317a04f5217728ce296edf4a581eb7e6ea0 commit | diff
Increase default effective_io_concurrency to 16 The default effective_io_concurrency has been 1 since it was introduced
in b7b8f0b6096d2ab6e. Referencing the associated discussion [1], it
seems 1 was chosen as a conservative value that seemed unlikely to cause
regressions.
Experimentation on high latency cloud storage as well as fast, local
nvme storage (see Discussion link) shows that even slightly higher
values improve query timings substantially. 1 actually performs worse
than 0 [2]. With effective_io_concurrency 1, we are not prefetching
enough to avoid I/O stalls, but we are issuing extra syscalls.
The new default is 16, which should be more appropriate for common
hardware while still avoiding flooding low IOPs devices with I/O
requests.
[1] https://www.postgresql.org/message-id/flat/FDDBA24E-FF4D-4654-BA75-692B3BA71B97%40enterprisedb.com
[2] https://www.postgresql.org/message-id/CAAKRu_Zv08Cic%3DqdCfzrQabpEXGrd9Z9UOW5svEVkCM6%3DFXA9g%40mail.gmail.com
Reviewed-by: Andres Freund <[email protected]>
Discussion: https://postgr.es/m/CAAKRu_Z%2BJa-mwXebOoOERMMUMvJeRhzTjad4dSThxG0JLXESxw%40mail.gmail.com
什么是effective_io_concurrency
PostgreSQL中effective_io_concurrency的相关代码和IO合并逻辑分析如下:
作用范围:
影响顺序扫描时的预取行为,主要作用于表扫描、索引扫描等需要批量读取数据的场景。相关逻辑实现:
预取逻辑在src/backend/access/heap/heapam.c和存储管理器(如src/backend/storage/smgr/md.c)中。例如,在顺序扫描时,PostgreSQL会根据effective_io_concurrency的值决定预读的页面数,通过ReadBufferExtended函数发起异步读取。
2. 系统调用是否合并为一次IO?
PostgreSQL的IO提交方式:
PostgreSQL通常以块(Page)为单位发起IO请求(默认8KB)。若开启预取(由effective_io_concurrency控制),会一次性提交多个异步IO请求,但每个请求对应独立的系统调用(如pread或异步IO接口)。操作系统的合并优化:
操作系统底层可能合并连续的IO请求(如Linux通过readahead机制自动预读后续数据)。但这是内核行为,并非PostgreSQL显式控制。例如,连续读取多个8KB块时,内核可能合并为单次较大的IO操作。异步IO的影响:
若PostgreSQL配置使用异步IO库(如Linux的libaio),多个IO请求可能通过io_submit批量提交,但具体合并仍由内核决定。同步IO模式下,每次pread对应单独的系统调用。
总结:
代码位置: guc_tables.c定义参数,预取逻辑在存储访问层(如heapam.c和md.c)。IO合并:
PostgreSQL不主动合并IO请求为单次系统调用,但依赖操作系统优化。effective_io_concurrency通过增加异步IO并发数提升吞吐,实际IO合并由内核自动处理。
AI 解读patch
解读:提高默认的 effective_io_concurrency 至 16
这个补丁的主要目的是提高 PostgreSQL 中 effective_io_concurrency 参数的默认值,从 1 提升到 16。
背景:
effective_io_concurrency参数控制 PostgreSQL 认为底层存储系统能够并行处理的 I/O 请求数量。 它影响着预读取(prefetching)的策略,即 PostgreSQL 提前读取数据到内存,以减少查询时的 I/O 等待时间。该参数最初引入时,默认值被设置为 1,这是一个非常保守的值,目的是避免潜在的性能回归。
问题:
实际测试表明,即使在高速本地 NVMe 存储和高延迟云存储上,稍高的 effective_io_concurrency值也能显著提高查询性能。更令人惊讶的是, effective_io_concurrency设置为 1 实际上比设置为 0(禁用预读取)的性能更差。 这是因为当设置为 1 时,PostgreSQL 尝试进行预读取,但预读取量不足以避免 I/O 延迟,反而增加了额外的系统调用开销。
解决方案:
将 effective_io_concurrency的默认值提高到 16。这个新值被认为更适合常见的硬件配置,同时仍然避免对低 IOPs(每秒输入/输出操作数)的存储设备造成过多的 I/O 请求。
理由:
更高的 effective_io_concurrency值允许 PostgreSQL 更有效地进行预读取,从而减少查询时的 I/O 等待时间,提高整体性能。16 被认为是一个合理的折衷方案,既能提高性能,又能避免对低性能存储设备造成过大的压力。
影响:
性能提升: 对于大多数用户来说,这个补丁应该能带来开箱即用的性能提升,尤其是在使用高速存储设备的情况下。 无需手动调整: 除非您使用的是非常低性能的存储设备,否则通常不需要手动调整 effective_io_concurrency参数。潜在的风险: 在极少数情况下,如果您的存储设备无法处理大量的并发 I/O 请求,可能会导致性能下降。 在这种情况下,您可以考虑将 effective_io_concurrency设置为更低的值,甚至设置为 0。
总结:
这个补丁通过提高 effective_io_concurrency 的默认值,旨在改善 PostgreSQL 的默认性能,尤其是在现代硬件上。 它是一个相对安全的更改,应该能为大多数用户带来性能提升,而无需手动调整配置。 但是,如果您使用的是非常低性能的存储设备,请注意潜在的风险,并根据需要调整参数。