v5-0002-Count-free-buffers-at-the-start-of-the-autoprewar.patch
application/octet-stream
Filename: v5-0002-Count-free-buffers-at-the-start-of-the-autoprewar.patch
Type: application/octet-stream
Part: 1
Message:
Re: Using read stream in autoprewarm
Patch
Format: format-patch
Series: patch v5-0002
Subject: Count free buffers at the start of the autoprewarm
| File | + | − |
|---|---|---|
| contrib/pg_prewarm/autoprewarm.c | 2 | 2 |
| src/backend/storage/buffer/freelist.c | 17 | 0 |
| src/include/storage/buf_internals.h | 1 | 0 |
From ffe876140536c89e2d80df1b9711e0970472b3d8 Mon Sep 17 00:00:00 2001
From: Nazir Bilal Yavuz <byavuz81@gmail.com>
Date: Wed, 27 Nov 2024 16:53:58 +0300
Subject: [PATCH v5 2/2] Count free buffers at the start of the autoprewarm
Streamified version of the autoprewarm code may do unnecessary I/O and
buffer evicting. To prevent it at least a little bit, count the number
of free buffers in the buffer pool and queue buffers up to that number
in the callback function of the autoprewarm.
---
contrib/pg_prewarm/autoprewarm.c | 4 ++--
src/backend/storage/buffer/freelist.c | 17 +++++++++++++++++
src/include/storage/buf_internals.h | 1 +
3 files changed, 20 insertions(+), 2 deletions(-)
diff --git a/contrib/pg_prewarm/autoprewarm.c b/contrib/pg_prewarm/autoprewarm.c
index 71c4f8a5920..42f2bc88fa9 100644
--- a/contrib/pg_prewarm/autoprewarm.c
+++ b/contrib/pg_prewarm/autoprewarm.c
@@ -516,13 +516,13 @@ autoprewarm_database_main(Datum main_arg)
pos = apw_state->prewarm_start_idx;
p.block_info = block_info;
- p.max_pos = apw_state->prewarm_stop_idx;
+ p.max_pos = Min(apw_state->prewarm_stop_idx, pos + get_number_of_free_buffers());
/*
* Loop until we run out of blocks to prewarm or until we run out of free
* buffers.
*/
- for (; pos < apw_state->prewarm_stop_idx; pos++)
+ for (; pos < p.max_pos; pos++)
{
BlockInfoRecord *blk = &block_info[pos];
Buffer buf;
diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 336715b6c63..9f26e940426 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -180,6 +180,23 @@ have_free_buffer(void)
return false;
}
+/*
+ * get_number_of_free_buffers -- a lockless way to get the number of free
+ * buffers in buffer pool.
+ *
+ * Note that result continuously changes as free buffers are moved out by other
+ * operations.
+ */
+int
+get_number_of_free_buffers(void)
+{
+ /* All the buffers are free. */
+ if (StrategyControl->firstFreeBuffer < 0)
+ return NBuffers;
+ else
+ return StrategyControl->lastFreeBuffer - StrategyControl->firstFreeBuffer;
+}
+
/*
* StrategyGetBuffer
*
diff --git a/src/include/storage/buf_internals.h b/src/include/storage/buf_internals.h
index 9327f60c44c..197d2db49f5 100644
--- a/src/include/storage/buf_internals.h
+++ b/src/include/storage/buf_internals.h
@@ -445,6 +445,7 @@ extern void StrategyNotifyBgWriter(int bgwprocno);
extern Size StrategyShmemSize(void);
extern void StrategyInitialize(bool init);
extern bool have_free_buffer(void);
+extern int get_number_of_free_buffers(void);
/* buf_table.c */
extern Size BufTableShmemSize(int size);
--
2.43.0