v9.heikki-0003-Use-streaming-reads-in-pg_prewarm.patch
text/x-patch
Filename: v9.heikki-0003-Use-streaming-reads-in-pg_prewarm.patch
Type: text/x-patch
Part: 2
Patch
Format: format-patch
Series: patch v9-0003
Subject: Use streaming reads in pg_prewarm.
| File | + | − |
|---|---|---|
| contrib/pg_prewarm/pg_prewarm.c | 39 | 1 |
From 464367523da22f615607c11231c7c56871b4da9b Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Sun, 23 Jul 2023 09:28:42 +1200
Subject: [PATCH v9.heikki 3/9] Use streaming reads in pg_prewarm.
Instead of calling ReadBuffer() repeatedly, use streaming reads. This
provides a simple example of such a transformation, and generates fewer
system calls.
Reviewed-by:
Discussion: https://postgr.es/m/CA+hUKGJkOiOCa+mag4BF+zHo7qo=o9CFheB8=g6uT5TUm2gkvA@mail.gmail.com
---
contrib/pg_prewarm/pg_prewarm.c | 40 ++++++++++++++++++++++++++++++++-
1 file changed, 39 insertions(+), 1 deletion(-)
diff --git a/contrib/pg_prewarm/pg_prewarm.c b/contrib/pg_prewarm/pg_prewarm.c
index 8541e4d6e46..cd2e15aa3d8 100644
--- a/contrib/pg_prewarm/pg_prewarm.c
+++ b/contrib/pg_prewarm/pg_prewarm.c
@@ -20,6 +20,7 @@
#include "miscadmin.h"
#include "storage/bufmgr.h"
#include "storage/smgr.h"
+#include "storage/streaming_read.h"
#include "utils/acl.h"
#include "utils/builtins.h"
#include "utils/lsyscache.h"
@@ -38,6 +39,25 @@ typedef enum
static PGIOAlignedBlock blockbuffer;
+struct pg_prewarm_streaming_read_private
+{
+ BlockNumber blocknum;
+ int64 last_block;
+};
+
+static BlockNumber
+pg_prewarm_streaming_read_next(StreamingRead *stream,
+ void *user_data,
+ void *per_buffer_data)
+{
+ struct pg_prewarm_streaming_read_private *p = user_data;
+
+ if (p->blocknum <= p->last_block)
+ return p->blocknum++;
+
+ return InvalidBlockNumber;
+}
+
/*
* pg_prewarm(regclass, mode text, fork text,
* first_block int8, last_block int8)
@@ -183,18 +203,36 @@ pg_prewarm(PG_FUNCTION_ARGS)
}
else if (ptype == PREWARM_BUFFER)
{
+ struct pg_prewarm_streaming_read_private p;
+ StreamingRead *stream;
+
/*
* In buffer mode, we actually pull the data into shared_buffers.
*/
+
+ /* Set up the private state for our streaming buffer read callback. */
+ p.blocknum = first_block;
+ p.last_block = last_block;
+
+ stream = streaming_read_buffer_begin(STREAMING_READ_FULL,
+ NULL,
+ BMR_REL(rel),
+ forkNumber,
+ pg_prewarm_streaming_read_next,
+ &p,
+ 0);
+
for (block = first_block; block <= last_block; ++block)
{
Buffer buf;
CHECK_FOR_INTERRUPTS();
- buf = ReadBufferExtended(rel, forkNumber, block, RBM_NORMAL, NULL);
+ buf = streaming_read_buffer_next(stream, NULL);
ReleaseBuffer(buf);
++blocks_done;
}
+ Assert(streaming_read_buffer_next(stream, NULL) == InvalidBuffer);
+ streaming_read_buffer_end(stream);
}
/* Close relation, release lock. */
--
2.39.2