From 9cf7db1410ce3ea6014296bdb304d2781a50b0e8 Mon Sep 17 00:00:00 2001 From: Yuhang Qiu Date: Wed, 26 Aug 2026 11:57:21 +0000 Subject: [PATCH v2 1/4] read_stream: Allow changing the buffer access strategy Heap scans can replace their buffer access strategy during a rescan. A read stream retained across such a rescan would keep references to the old strategy, which may then be freed. Add read_stream_set_strategy() to update an idle stream. It changes the strategy used by subsequent reads and recomputes the limit on pinned buffers. Reviewed-by: Nazir Bilal Yavuz Discussion: https://postgr.es/m/D1F99EB2-5A03-465F-A210-98F7DF256168@gmail.com --- src/backend/storage/aio/read_stream.c | 23 +++++++++++++++++++++++ src/include/storage/read_stream.h | 2 ++ 2 files changed, 25 insertions(+) diff --git a/src/backend/storage/aio/read_stream.c b/src/backend/storage/aio/read_stream.c index e7dbbe03326..5b0b065be62 100644 --- a/src/backend/storage/aio/read_stream.c +++ b/src/backend/storage/aio/read_stream.c @@ -1428,6 +1428,29 @@ read_stream_clear_strategy(ReadStream *stream) stream->ios[i].op.strategy = NULL; } +/* + * Change the buffer access strategy used by an idle stream. + * + * The stream must first be reset so that no reads still refer to the old + * strategy. The allocation made when the stream was created cannot grow, so + * the new limit remains capped by the existing queue capacity. The caller + * must create a new stream to exceed that capacity. + */ +void +read_stream_set_strategy(ReadStream *stream, BufferAccessStrategy strategy) +{ + Assert(stream->pinned_buffers == 0); + Assert(stream->ios_in_progress == 0); + Assert(stream->pending_read_nblocks == 0); + + stream->max_pinned_buffers = Max(1, + Min(stream->queue_size - 1, + GetAccessStrategyPinLimit(strategy))); + + for (int i = 0; i < stream->max_ios; ++i) + stream->ios[i].op.strategy = strategy; +} + /* * Reset a read stream by releasing any queued up buffers, allowing the stream * to be used again for different blocks. This can be used to clear an diff --git a/src/include/storage/read_stream.h b/src/include/storage/read_stream.h index e2dcf1be50a..38a455bba12 100644 --- a/src/include/storage/read_stream.h +++ b/src/include/storage/read_stream.h @@ -103,6 +103,8 @@ extern ReadStream *read_stream_begin_smgr_relation(int flags, extern BlockNumber read_stream_pause(ReadStream *stream); extern void read_stream_resume(ReadStream *stream); extern void read_stream_clear_strategy(ReadStream *stream); +extern void read_stream_set_strategy(ReadStream *stream, + BufferAccessStrategy strategy); extern void read_stream_reset(ReadStream *stream); extern void read_stream_end(ReadStream *stream); extern void read_stream_enable_stats(ReadStream *stream, struct IOStats *stats); -- 2.43.7