PostgreSQL 18 preview - 基于 read_stream 提升位图堆扫描性能
PostgreSQL 18 preview - 基于 read_stream 提升位图堆扫描性能
PostgreSQL 18将用read stream接口替换修改很多原有的IO接口, 同时未来利用异步IO来提升IO性能, 下面三个 patch 共同实现了以下目标:
提升位图堆扫描的性能:
通过引入读取流 API,优化了 I/O 操作,特别是预取机制减少了 I/O 停滞。
分离 TBMIterateResult和迭代器,使得位图堆扫描能够同时处理多个 I/O 操作。
移除冗余的回调函数和显式的预取逻辑,使得代码更加模块化和易于维护。
这些改进不仅提升了 PostgreSQL 在处理复杂查询时的性能,还为未来的优化(如异步 I/O)打下了基础。
https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=944e81bf99db2b5b70b8a389d4f273534da73f74
Separate TBM[Shared|Private]Iterator and TBMIterateResult
author Melanie Plageman <[email protected]>
Sat, 15 Mar 2025 14:10:51 +0000 (10:10 -0400)
committer Melanie Plageman <[email protected]>
Sat, 15 Mar 2025 14:11:19 +0000 (10:11 -0400)
commit 944e81bf99db2b5b70b8a389d4f273534da73f74
tree aef5b3e8d864fcdccc81ea1688b7a1ab8e7fbdf1 tree
parent 799959dc7cf0e2462601bea8d07b6edec3fa0c4f commit | diff
Separate TBM[Shared|Private]Iterator and TBMIterateResult
Remove the TBMIterateResult member from the TBMPrivateIterator and
TBMSharedIterator and make tbm_[shared|private_]iterate() take a
TBMIterateResult as a parameter.
This allows tidbitmap API users to manage multiple TBMIterateResults per
scan. This is required for bitmap heap scan to use the read stream API,
with which there may be multiple I/Os in flight at once, each one with a
TBMIterateResult.
Reviewed-by: Tomas Vondra <[email protected]>
Discussion: https://postgr.es/m/d4bb26c9-fe07-439e-ac53-c0e244387e01%40vondra.me
https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=2b73a8cd33b745c5b8a7f44322f86642519e3a40
BitmapHeapScan uses the read stream API
author Melanie Plageman <[email protected]>
Sat, 15 Mar 2025 14:34:42 +0000 (10:34 -0400)
committer Melanie Plageman <[email protected]>
Sat, 15 Mar 2025 14:34:42 +0000 (10:34 -0400)
commit 2b73a8cd33b745c5b8a7f44322f86642519e3a40
tree 43c4cb7aa83247b634ff15d4df76a75f16221230 tree
parent 944e81bf99db2b5b70b8a389d4f273534da73f74 commit | diff
BitmapHeapScan uses the read stream API
Make Bitmap Heap Scan use the read stream API instead of invoking
ReadBuffer() for each block indicated by the bitmap.
The read stream API handles prefetching, so remove all of the explicit
prefetching from bitmap heap scan code.
Now, heap table AM implements a read stream callback which uses the
bitmap iterator to return the next required block to the read stream
code.
Tomas Vondra conducted extensive regression testing of this feature.
Andres Freund, Thomas Munro, and I analyzed regressions and Thomas Munro
patched the read stream API.
Author: Melanie Plageman <[email protected]>
Reviewed-by: Tomas Vondra <[email protected]>
Tested-by: Tomas Vondra <[email protected]>
Tested-by: Andres Freund <[email protected]>
Tested-by: Thomas Munro <[email protected]>
Tested-by: Nazir Bilal Yavuz <[email protected]>
Discussion: https://postgr.es/m/flat/CAAKRu_ZwCwWFeL_H3ia26bP2e7HiKLWt0ZmGXPVwPO6uXq0vaA%40mail.gmail.com
https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=c3953226a07527a1e2f7f410b83e1a7021f42888
Remove table AM callback scan_bitmap_next_block
author Melanie Plageman <[email protected]>
Sat, 15 Mar 2025 14:37:46 +0000 (10:37 -0400)
committer Melanie Plageman <[email protected]>
Sat, 15 Mar 2025 14:37:46 +0000 (10:37 -0400)
commit c3953226a07527a1e2f7f410b83e1a7021f42888
tree e870af20ddaf1b56c180652dfd51928417775264 tree
parent 2b73a8cd33b745c5b8a7f44322f86642519e3a40 commit | diff
Remove table AM callback scan_bitmap_next_block
After pushing the bitmap iterator into table-AM specific code (as part
of making bitmap heap scan use the read stream API in 2b73a8cd33b7),
scan_bitmap_next_block() no longer returns the current block number.
Since scan_bitmap_next_block() isn't returning any relevant information
to bitmap table scan code, it makes more sense to get rid of it.
Now, bitmap table scan code only calls table_scan_bitmap_next_tuple(),
and the heap AM implementation of scan_bitmap_next_block() is a local
helper in heapam_handler.c.
Reviewed-by: Tomas Vondra <[email protected]>
Discussion: https://postgr.es/m/flat/CAAKRu_ZwCwWFeL_H3ia26bP2e7HiKLWt0ZmGXPVwPO6uXq0vaA%40mail.gmail.com
AI 解读
这三个 patch 是围绕 PostgreSQL 中位图堆扫描(Bitmap Heap Scan)和读取流 API(read stream API)的优化和改进展开的。它们的目标是提升位图堆扫描的性能,同时简化代码逻辑。以下是每个 patch 的详细解读:
Patch 1: Separate TBM[Shared|Private]Iterator and TBMIterateResult
主要内容
分离迭代器和结果:
将 TBMIterateResult从TBMPrivateIterator和TBMSharedIterator中移除。修改 tbm_[shared|private_]iterate()函数,使其接受TBMIterateResult作为参数。
支持多个结果:
允许位图 API 的用户管理多个 TBMIterateResult,每个扫描可以对应多个结果。这是为了支持位图堆扫描使用读取流 API,因为读取流 API 可能同时有多个 I/O 操作在进行,每个操作都需要一个 TBMIterateResult。
目的与意义
支持并发 I/O: 读取流 API 允许多个 I/O 操作同时进行,因此需要为每个操作单独管理 TBMIterateResult。解耦逻辑: 将迭代器和结果分离,使得代码更加模块化和灵活,便于后续优化和维护。
Patch 2: BitmapHeapScan uses the read stream API
主要内容
替换读取方式:
将位图堆扫描的读取方式从逐个调用 ReadBuffer()改为使用读取流 API。读取流 API 负责预取(prefetching),因此移除了位图堆扫描代码中显式的预取逻辑。
实现回调函数:
堆表 AM(Access Method)实现了一个读取流回调函数,该函数使用位图迭代器返回下一个需要读取的块。
测试与验证:
Tomas Vondra 进行了广泛的回归测试,验证了该功能的正确性和性能提升。 Andres Freund、Thomas Munro 和作者分析了回归测试结果,并对读取流 API 进行了修复。
目的与意义
提升性能: 读取流 API 能够更高效地处理 I/O 操作,特别是预取机制可以减少 I/O 停滞,从而提升位图堆扫描的性能。 简化代码: 移除显式的预取逻辑,使得代码更加简洁,同时将 I/O 优化逻辑集中在读取流 API 中。
Patch 3: Remove table AM callback scan_bitmap_next_block
主要内容
移除回调函数:
在将位图迭代器推入表 AM 特定代码后, scan_bitmap_next_block()不再返回当前块号。由于 scan_bitmap_next_block()不再提供任何相关信息,因此将其移除。
简化接口:
位图表扫描代码现在只调用 table_scan_bitmap_next_tuple()。堆 AM 的 scan_bitmap_next_block()实现被移到heapam_handler.c中,作为一个本地辅助函数。
目的与意义
减少冗余: 移除不再需要的回调函数,简化了表 AM 的接口。 集中逻辑: 将位图扫描的逻辑集中在更少的函数中,使得代码更加清晰和易于维护。
总结
这三个 patch 共同实现了以下目标:
提升位图堆扫描的性能:
通过引入读取流 API,优化了 I/O 操作,特别是预取机制减少了 I/O 停滞。
分离 TBMIterateResult和迭代器,使得位图堆扫描能够同时处理多个 I/O 操作。
移除冗余的回调函数和显式的预取逻辑,使得代码更加模块化和易于维护。
这些改进不仅提升了 PostgreSQL 在处理复杂查询时的性能,还为未来的优化(如异步 I/O)打下了基础。