Re: index prefetching
Melanie Plageman <melanieplageman@gmail.com>
Commits
GET /api/v1/messages/:b64id/commits
the thread's linked commits as JSON, with link sources.
API reference →
-
aio: io_uring: Trigger async processing for large IOs
- a9ee66881744 19 (unreleased) landed
-
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
-
read_stream: Prevent distance from decaying too quickly
- 6e36930f9aaf 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
-
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
Attachments
- v3-0001-Streaming-Read-API.txt (text/plain)
- v3-0002-use-streaming-reads-in-index-scan.txt (text/plain)
On Wed, Jan 24, 2024 at 4:19 AM Tomas Vondra <tomas.vondra@enterprisedb.com> wrote: > > On 1/24/24 01:51, Melanie Plageman wrote: > > >>> There are also table AM layering violations in my sketch which would > >>> have to be worked out (not to mention some resource leakage I didn't > >>> bother investigating [which causes it to fail tests]). > >>> > >>> 0001 is all of Thomas' streaming read API code that isn't yet in > >>> master and 0002 is my rough sketch of index prefetching using the > >>> streaming read API > >>> > >>> There are also numerous optimizations that your index prefetching > >>> patch set does that would need to be added in some way. I haven't > >>> thought much about it yet. I wanted to see what you thought of this > >>> approach first. Basically, is it workable? > >> > >> It seems workable, yes. I'm not sure it's much simpler than my patch > >> (considering a lot of the code is in the optimizations, which are > >> missing from this patch). > >> > >> I think the question is where should the optimizations happen. I suppose > >> some of them might/should happen in the StreamingRead API itself - like > >> the detection of sequential patterns, recently prefetched blocks, ... > > > > So, the streaming read API does detection of sequential patterns and > > not prefetching things that are in shared buffers. It doesn't handle > > avoiding prefetching recently prefetched blocks yet AFAIK. But I > > daresay this would be relevant for other streaming read users and > > could certainly be implemented there. > > > > Yes, the "recently prefetched stuff" cache seems like a fairly natural > complement to the pattern detection and shared-buffers check. > > FWIW I wonder if we should make some of this customizable, so that > systems with customized storage (e.g. neon or with direct I/O) can e.g. > disable some of these checks. Or replace them with their version. That's a promising idea. > >> But I'm not sure what to do about optimizations that are more specific > >> to the access path. Consider for example the index-only scans. We don't > >> want to prefetch all the pages, we need to inspect the VM and prefetch > >> just the not-all-visible ones. And then pass the info to the index scan, > >> so that it does not need to check the VM again. It's not clear to me how > >> to do this with this approach. > > > > Yea, this is an issue I'll need to think about. To really spell out > > the problem: the callback dequeues a TID from the tid_queue and looks > > up its block in the VM. It's all visible. So, it shouldn't return that > > block to the streaming read API to fetch from the heap because it > > doesn't need to be read. But, where does the callback put the TID so > > that the caller can get it? I'm going to think more about this. > > > > Yes, that's the problem for index-only scans. I'd generalize it so that > it's about the callback being able to (a) decide if it needs to read the > heap page, and (b) store some custom info for the TID. Actually, I think this is no big deal. See attached. I just don't enqueue tids whose blocks are all visible. I had to switch the order from fetch heap then fill queue to fill queue then fetch heap. While doing this I noticed some wrong results in the regression tests (like in the alter table test), so I suspect I have some kind of control flow issue. Perhaps I should fix the resource leak so I can actually see the failing tests :) As for your a) and b) above. Regarding a): We discussed allowing speculative prefetching and separating the logic for prefetching from actually reading blocks (so you can prefetch blocks you ultimately don't read). We decided this may not belong in a streaming read API. What do you think? Regarding b): We can store per buffer data for anything that actually goes down through the streaming read API, but, in the index only case, we don't want the streaming read API to know about blocks that it doesn't actually need to read. - Melanie