Re: index prefetching
Peter Geoghegan <pg@bowt.ie>
Attachments
- v18-0017-Dirty-hack-to-make-read_stream_reset-end-not-wai.patch (application/octet-stream) patch v18-0017
- v18-0016-WIP-instrumentation-Account-for-resource-usage-u.patch (application/octet-stream) patch v18-0016
- v18-0019-WIP-aio-bufmgr-Fix-race-condition-leading-to-dea.patch (application/octet-stream) patch v18-0019
- v18-0018-aio-Fix-pgaio_io_wait-for-staged-IOs-B.patch (application/octet-stream) patch v18-0018
- v18-0015-WIP-aio-io_uring-Use-IO-size-not-IO-queue-to-tri.patch (application/octet-stream) patch v18-0015
- v18-0013-WIP-read_stream-Only-increase-distance-when-wait.patch (application/octet-stream) patch v18-0013
- v18-0012-bufmgr-Return-whether-WaitReadBuffers-needed-to-.patch (application/octet-stream) patch v18-0012
- v18-0011-WIP-aio-io_uring-Allow-IO-methods-to-check-if-IO.patch (application/octet-stream) patch v18-0011
- v18-0010-WIP-read_stream-Issue-IO-synchronously-while-in-.patch (application/octet-stream) patch v18-0010
- v18-0014-WIP-read_stream-Prevent-distance-from-decaying-t.patch (application/octet-stream) patch v18-0014
- v18-0008-heapam-Add-index-scan-I-O-prefetching.patch (application/octet-stream) patch v18-0008
- v18-0009-Make-hash-index-AM-use-amgetbatch-interface.patch (application/octet-stream) patch v18-0009
- v18-0007-Add-UnlockBufferGetLSN-utility-function.patch (application/octet-stream) patch v18-0007
- v18-0006-heapam-Optimize-pin-transfers-during-index-scans.patch (application/octet-stream) patch v18-0006
- v18-0005-Add-interfaces-that-enable-index-prefetching.patch (application/octet-stream) patch v18-0005
- v18-0002-Add-slot-based-table-AM-interface-for-index-scan.patch (application/octet-stream) patch v18-0002
- v18-0004-heapam-Keep-buffer-pins-across-index-scan-rescan.patch (application/octet-stream) patch v18-0004
- v18-0003-heapam-Track-heap-block-in-IndexFetchHeapData.patch (application/octet-stream) patch v18-0003
- v18-0001-Move-heapam_handler.c-index-scan-code-to-new-fil.patch (application/octet-stream) patch v18-0001
On Sun, Mar 22, 2026 at 9:14 PM Peter Geoghegan <pg@bowt.ie> wrote: > V17 is attached. This addresses most of your feedback, but defers > dealing with the trickier parts for now. Attached is v18, which addresses the tricky issues I skipped in v17. Highlights: * New commit (the first) that adds a heapam_indexscan.c file, and moves all of the relevant existing heapam_handler.c functions over to this new file. This commit is strictly mechanical, and has no functional impact. * Another new commit (the second) adds the new slot-based index scan interface, and pushes the VM lookups that currently take place in nodeIndexonlyScan.c into heapam. This includes the instrumentation changes that were previously in their own small patch. It also includes the VISITED_PAGES_LIMIT stuff -- there's no longer any commit that breaks VISITED_PAGES_LIMIT, nor is there a later commit that subsequently restores the functionality. * We now extract one key piece of infrastructure that other table AMs can now reuse to manage their own index scan batches: a new inline function called tableam_util_fetch_next_batch now appears as an indexbatch.h inline function. This function (which appeared under a different name in v17) manages deciding whether to call amgetbatch (performing the amgetbatch call when needed) or to simply return the next batch in line (because such a batch already exists/is already loaded in the ring buffer from earlier). It also detects and handles cross-batch changes in scan direction, and sets/reads the fields that track when a batch is definitely the last one in the given scan direction. I tried to go further by also placing the bulk of the code in heapam_index_getnext_scanbatch_pos in indexbatch.h, but ultimately concluded that it wasn't worth it. There isn't much code in heapam_index_getnext_scanbatch_pos to generalize. Some of that code coordinates quite directly with the heapam read stream callback. * Added an "isGuarded" field to IndexScanBatchData. That way we can assert that any batch loaded within the read stream callback is already unguarded/has no batch index page buffer pin still held. The field isn't just for assertions, though. We also rely on it in one or two places during release builds, which seemed clearer to me. For example, we no longer require that amunguardbatch routines be idempotent, which seems like a minor improvement. * Other work is broken out into its own commit, to better highlight issues that aren't strictly related to the amgetbatch changes. Specifically, a new commit adds the "don't unpin on rescan" behavior. These changes, which first appeared in the main amgetbatch commit, aim to minimize regressions with cached workloads (this was discussed briefly upthread, plus Andres and I discussed it over IM some weeks back). * Replaced what was previously an assert with an equivalent pg_assume(), within heapam_index_getnext_scanbatch_pos -- which is a very hot function. We now "pg_assume(batchringbuf->headBatch == scanPos->batch)", allowing the compiler to exploit this existing invariant. This seems to help the compiler generate better code, presumably by allowing more efficient register allocation. I haven't looked at the disassembly just yet, but it helps with certain microbenchmarks enough to matter. * The "Add UnlockBufferGetLSN utility function" commit now uses an atomic operation (in the common case where it actually drops the index page's pin), just like UnlockReleaseBuffer itself following Andres' commit f39cb8c011062d65e146c1e9d1aae221e96d8320 from today. I completed this item quickly, after pulling from master a little while ago. The expectation for UnlockBufferGetLSN is that it be at least as good as a BufferGetLSNAtomic followed by a UnlockReleaseBuffer, so IMV it made sense to include this last minute addition in v18. * The "don't wait" patches are no longer included, since Andres committed them to the master branch just now. Thanks to both you (Andres) and Melanie for taking care of this very thorny issue! I believe I have now acted on all of Andres' feedback, with one minor exception: Andres disliked how we use 'if (scan->xs_heapfetch)' to determine whether to use the scan's batch cache (we don't want to use it at all if the scan is ending). I just ran out of steam, so this version doesn't address the problem. But I'm still tracking it as an open item (I don't disagree with Andres, but this problem is slightly awkward). Note that I *did* create a helper function here, so we at least avoid having 2 copies of the loop that looks for a free cache batch slot. -- Peter Geoghegan
Commits
-
read stream: Split decision about look ahead for AIO and combining
- 8ca147d582a5 19 (unreleased) landed
-
read_stream: Only increase read-ahead distance when waiting for IO
- f63ca3379025 19 (unreleased) landed
-
aio: io_uring: Trigger async processing for large IOs
- a9ee66881744 19 (unreleased) landed
-
heapam: Keep buffer pins across index scan resets.
- 2d3490dd99f0 19 (unreleased) landed
-
heapam: Track heap block in IndexFetchHeapData.
- c7d09595e46f 19 (unreleased) landed
-
Move heapam_handler.c index scan code to new file.
- a29fdd6c8d81 19 (unreleased) landed
-
Rename heapam_index_fetch_tuple argument for clarity.
- 1adff1a0c558 19 (unreleased) landed
-
Optimize fast-path FK checks with batched index probes
- b7b27eb41a5c 19 (unreleased) cited
-
read_stream: Prevent distance from decaying too quickly
- 6e36930f9aaf 19 (unreleased) landed
-
read_stream: Issue IO synchronously while in fast path
- cceb1bf45e3a 19 (unreleased) landed
-
bufmgr: Return whether WaitReadBuffers() needed to wait
- 513374a47a71 19 (unreleased) landed
-
aio: io_uring: Allow IO methods to check if IO completed in the background
- 6e648e353fa0 19 (unreleased) landed
-
bufmgr: Make UnlockReleaseBuffer() more efficient
- f39cb8c01106 19 (unreleased) cited
-
Add fake LSN support to hash index AM.
- e5836f7b7d9a 19 (unreleased) landed
-
Make IndexScanInstrumentation a pointer in executor scan nodes.
- f026fbf059f2 19 (unreleased) landed
-
Use fake LSNs to improve nbtree dropPin behavior.
- 8a879119a1d1 19 (unreleased) landed
-
Move fake LSN infrastructure out of GiST.
- d774072f0040 19 (unreleased) landed
-
Use simplehash for backend-private buffer pin refcounts.
- a367c433ad01 19 (unreleased) landed
-
nbtree: Avoid allocating _bt_search stack.
- d071e1cfec23 19 (unreleased) landed
-
bufmgr: Fix use of wrong variable in GetPrivateRefCountEntrySlow()
- 6322a028fa43 19 (unreleased) landed
-
Conditional locking in pgaio_worker_submit_internal
- 29a0fb215779 19 (unreleased) landed
-
Reduce ExecSeqScan* code size using pg_assume()
- b227b0bb4e03 19 (unreleased) cited
-
Fix rare bug in read_stream.c's split IO handling.
- b421223172a2 19 (unreleased) cited
-
Remove HeapBitmapScan's skip_fetch optimization
- 459e7bf8e2f8 18.0 cited
-
Optimize nbtree backwards scans.
- 1bd4bc85cac2 18.0 cited
-
Fix multiranges to behave more like dependent types.
- 3e8235ba4f9c 17.0 cited
-
Add EXPLAIN (MEMORY) to report planner memory consumption
- 5de890e3610d 17.0 cited
-
Optimize nbtree backward scan boundary cases.
- c9c0589fda0e 17.0 cited
-
Increment xactCompletionCount during subtransaction abort.
- 90c885cdab8b 14.0 cited
-
Add nbtree Valgrind buffer lock checks.
- 4a70f829d86c 14.0 cited
-
Add nbtree high key "continuescan" optimization.
- 29b64d1de7c7 12.0 cited
-
Reduce pinning and buffer content locking for btree scans.
- 2ed5b87f96d4 9.5.0 cited
-
Teach btree to handle ScalarArrayOpExpr quals natively.
- 9e8da0f75731 9.2.0 cited