v35-0002-Add-READ_STREAM_RANDOM-flag.patch
text/x-patch
Filename: v35-0002-Add-READ_STREAM_RANDOM-flag.patch
Type: text/x-patch
Part: 0
Patch
Format: format-patch
Series: patch v35-0002
Subject: Add READ_STREAM_RANDOM flag
| File | + | − |
|---|---|---|
| src/backend/storage/aio/read_stream.c | 32 | 6 |
| src/include/storage/read_stream.h | 7 | 0 |
| src/tools/pgindent/typedefs.list | 1 | 0 |
From 7c32867976d485beb3580f0347b824dbf021aa0c Mon Sep 17 00:00:00 2001
From: Melanie Plageman <melanieplageman@gmail.com>
Date: Mon, 10 Mar 2025 18:17:06 -0400
Subject: [PATCH v35 2/5] Add READ_STREAM_RANDOM flag
For read stream users with random I/O that want to explicitly force
prefetching. The read stream API attempts to detect sequential access
and shuts off prefetching. Some users may have runs of sequential blocks
but wish to issue advice anyway. Provide this flag for this purpose.
This commit adds no users of this flag.
---
src/backend/storage/aio/read_stream.c | 38 ++++++++++++++++++++++-----
src/include/storage/read_stream.h | 7 +++++
src/tools/pgindent/typedefs.list | 1 +
3 files changed, 40 insertions(+), 6 deletions(-)
diff --git a/src/backend/storage/aio/read_stream.c b/src/backend/storage/aio/read_stream.c
index 04bdb5e6d4b..b4dea112d9a 100644
--- a/src/backend/storage/aio/read_stream.c
+++ b/src/backend/storage/aio/read_stream.c
@@ -103,6 +103,19 @@ typedef struct InProgressIO
ReadBuffersOperation op;
} InProgressIO;
+/*
+ * Whether or not the read stream should attempt to issue advice.
+ * RS_ADVICE_NEVER disables prefetching. RS_ADVICE_ADAPTIVE enables it in
+ * general but may temporarily disable it if sequential access is detected.
+ * RS_ADVICE_ALWAYS will always issue prefetches.
+ */
+typedef enum ReadStreamAdviceLevel
+{
+ RS_ADVICE_NEVER,
+ RS_ADVICE_ADAPTIVE,
+ RS_ADVICE_ALWAYS,
+} ReadStreamAdviceLevel;
+
/*
* State for managing a stream of reads.
*/
@@ -114,7 +127,7 @@ struct ReadStream
int16 max_pinned_buffers;
int16 pinned_buffers;
int16 distance;
- bool advice_enabled;
+ ReadStreamAdviceLevel advice_level;
/*
* One-block buffer to support 'ungetting' a block number, to resolve flow
@@ -228,6 +241,7 @@ static void
read_stream_start_pending_read(ReadStream *stream, bool suppress_advice)
{
bool need_wait;
+ bool sequence_detected;
int nblocks;
int flags;
int16 io_index;
@@ -248,13 +262,18 @@ read_stream_start_pending_read(ReadStream *stream, bool suppress_advice)
else
Assert(stream->next_buffer_index == stream->oldest_buffer_index);
+ sequence_detected = stream->pending_read_blocknum == stream->seq_blocknum;
+
/*
* If advice hasn't been suppressed, this system supports it, and this
* isn't a strictly sequential pattern, then we'll issue advice.
*/
- if (!suppress_advice &&
- stream->advice_enabled &&
- stream->pending_read_blocknum != stream->seq_blocknum)
+ if (suppress_advice)
+ flags = 0;
+ else if (stream->advice_level == RS_ADVICE_ALWAYS)
+ flags = READ_BUFFERS_ISSUE_ADVICE;
+ else if (stream->advice_level == RS_ADVICE_ADAPTIVE &&
+ !sequence_detected)
flags = READ_BUFFERS_ISSUE_ADVICE;
else
flags = 0;
@@ -501,6 +520,8 @@ read_stream_begin_impl(int flags,
stream->per_buffer_data = (void *)
MAXALIGN(&stream->ios[Max(1, max_ios)]);
+ stream->advice_level = RS_ADVICE_NEVER;
+
#ifdef USE_PREFETCH
/*
@@ -512,7 +533,12 @@ read_stream_begin_impl(int flags,
if ((io_direct_flags & IO_DIRECT_DATA) == 0 &&
(flags & READ_STREAM_SEQUENTIAL) == 0 &&
max_ios > 0)
- stream->advice_enabled = true;
+ {
+ if ((flags & READ_STREAM_RANDOM) != 0)
+ stream->advice_level = RS_ADVICE_ALWAYS;
+ else
+ stream->advice_level = RS_ADVICE_ADAPTIVE;
+ }
#endif
/*
@@ -662,7 +688,7 @@ read_stream_next_buffer(ReadStream *stream, void **per_buffer_data)
if (likely(!StartReadBuffer(&stream->ios[0].op,
&stream->buffers[oldest_buffer_index],
next_blocknum,
- stream->advice_enabled ?
+ stream->advice_level > RS_ADVICE_NEVER ?
READ_BUFFERS_ISSUE_ADVICE : 0)))
{
/* Fast return. */
diff --git a/src/include/storage/read_stream.h b/src/include/storage/read_stream.h
index c11d8ce3300..463dd4ac6df 100644
--- a/src/include/storage/read_stream.h
+++ b/src/include/storage/read_stream.h
@@ -42,6 +42,13 @@
*/
#define READ_STREAM_FULL 0x04
+/*
+ * This flag explicitly disables sequential detection for cases in which we
+ * know we want to issue prefetch advice even though there may be some
+ * sequential runs of blocks.
+ */
+#define READ_STREAM_RANDOM 0x08
+
struct ReadStream;
typedef struct ReadStream ReadStream;
diff --git a/src/tools/pgindent/typedefs.list b/src/tools/pgindent/typedefs.list
index 9840060997f..b5b547f9e89 100644
--- a/src/tools/pgindent/typedefs.list
+++ b/src/tools/pgindent/typedefs.list
@@ -2378,6 +2378,7 @@ ReadFunc
ReadLocalXLogPageNoWaitPrivate
ReadReplicationSlotCmd
ReadStream
+ReadStreamAdviceLevel
ReadStreamBlockNumberCB
ReassignOwnedStmt
RecheckForeignScan_function
--
2.34.1