From ffe876140536c89e2d80df1b9711e0970472b3d8 Mon Sep 17 00:00:00 2001 From: Nazir Bilal Yavuz 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