PostgreSQL 18 preview - read_stream 启发式预读量优化, 异步IO准备
PostgreSQL 18 preview - read_stream 启发式预读量优化, 异步IO准备
在之前的版本(v17)中,read_stream.c 采用了一种保守的策略来限制预读距离(look-ahead distance),特别是在处理连续块(sequential blocks)时。这种策略基于以下三种行为模型:
随机 I/O:快速增加预读距离,以支持读取建议(read-ahead advice)。 连续 I/O:将预读距离逐步调整到 io_combine_limit设置,仅够构建一个完整大小的同步 I/O,然后依赖内核的预读机制来避免 I/O 停滞。中间选项:在处理连续 I/O 时,采用一种谨慎的策略,避免过度预读。
这种保守的策略在某些场景下(例如流式位图堆扫描)会导致性能损失,因为连续块之后可能会跟随随机跳转,而保守的预读距离无法充分利用读取建议的优势。
这个 patch 对 read_stream.c 中的距离启发式(distance heuristics)进行了简化和优化,目的是为异步 I/O(asynchronous I/O)做准备。
https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=799959dc7cf0e2462601bea8d07b6edec3fa0c4f
Simplify distance heuristics in read_stream.c. author Thomas Munro <[email protected]>
Sat, 15 Mar 2025 14:04:08 +0000 (03:04 +1300)
committer Thomas Munro <[email protected]>
Sat, 15 Mar 2025 14:05:07 +0000 (03:05 +1300)
commit 799959dc7cf0e2462601bea8d07b6edec3fa0c4f
tree 0a0b75a63d0ef59b8514651890f45cc33723eec8 tree
parent 7ea8cd15661e3b0da4b57be2f25fdd512951576f commit | diff
Simplify distance heuristics in read_stream.c.
Make the distance control heuristics simpler and more aggressive in
preparation for asynchronous I/O.
The v17 version of read_stream.c made a conservative choice to limit the
look-ahead distance when streaming sequential blocks, because it
couldn't benefit very much from looking ahead further yet. It had a
three-behavior model where only random I/O would rapidly increase the
look-ahead distance, to support read-ahead advice. Sequential I/O would
move it towards the io_combine_limit setting, just enough to build one
full-sized synchronous I/O at a time, and then expect kernel read-ahead
to avoid I/O stalls.
That already left I/O performance on the table with advice-based I/O
concurrency, since sequential blocks could be followed by random jumps,
eg with the proposed streaming Bitmap Heap Scan patch.
It is time to delete the cautious middle option and adjust the distance
based on recent I/O needs only, since asynchronous reads will need to be
started ahead of time whether random or sequential. It is still limited
by io_combine_limit, *_io_concurrency, buffer availability and
strategy ring size, as before.
Reviewed-by: Andres Freund <[email protected]> (earlier version)
Tested-by: Melanie Plageman <[email protected]>
Discussion: https://postgr.es/m/CA%2BhUKGK_%3D4CVmMHvsHjOVrK6t4F%3DLBpFzsrr3R%2BaJYN8kcTfWg%40mail.gmail.com
AI 解读
这个 patch 对 read_stream.c 中的距离启发式(distance heuristics)进行了简化和优化,目的是为异步 I/O(asynchronous I/O)做准备。以下是该 patch 的详细解读:
背景
在之前的版本(v17)中,read_stream.c 采用了一种保守的策略来限制预读距离(look-ahead distance),特别是在处理连续块(sequential blocks)时。这种策略基于以下三种行为模型:
随机 I/O:快速增加预读距离,以支持读取建议(read-ahead advice)。 连续 I/O:将预读距离逐步调整到 io_combine_limit设置,仅够构建一个完整大小的同步 I/O,然后依赖内核的预读机制来避免 I/O 停滞。中间选项:在处理连续 I/O 时,采用一种谨慎的策略,避免过度预读。
这种保守的策略在某些场景下(例如流式位图堆扫描)会导致性能损失,因为连续块之后可能会跟随随机跳转,而保守的预读距离无法充分利用读取建议的优势。
改进内容
该 patch 对距离启发式进行了以下改进:
删除谨慎的中间选项:
之前的三种行为模型被简化为两种:随机 I/O 和 连续 I/O。 删除了在处理连续 I/O 时的谨慎中间选项,改为根据最近的 I/O 需求动态调整预读距离。
更激进的预读策略:
无论是随机 I/O 还是连续 I/O,预读距离都会根据实际需求进行调整。 这种更激进的策略为异步 I/O 做准备,因为异步读取需要提前启动,无论 I/O 模式是随机还是连续。
保留原有的限制条件:
预读距离仍然受到 io_combine_limit、*_io_concurrency、缓冲区可用性和策略环大小(strategy ring size)的限制。这些限制条件确保了预读不会过度消耗系统资源。
目的与意义
为异步 I/O 做准备:
异步 I/O 需要提前启动读取操作,因此更激进的预读策略可以更好地支持异步 I/O 的实现。 这种改进使得 read_stream.c能够更高效地处理随机和连续 I/O 的混合场景。
提升性能:
删除谨慎的中间选项后, read_stream.c能够更充分地利用读取建议,减少 I/O 停滞,从而提升性能。特别是在流式位图堆扫描等场景中,这种改进可以显著优化 I/O 性能。
简化逻辑:
通过删除中间选项,距离启发式的逻辑变得更加简单和清晰,便于维护和进一步优化。
总结
该 patch 通过简化和优化 read_stream.c 中的距离启发式,为异步 I/O 的实现做好了准备。它删除了谨慎的中间选项,采用了更激进的预读策略,同时保留了原有的限制条件。这种改进不仅提升了性能,还简化了代码逻辑,使得 read_stream.c 能够更高效地处理随机和连续 I/O 的混合场景。