v16-0008-Make-buffer-hit-helper.patch
application/octet-stream
Filename: v16-0008-Make-buffer-hit-helper.patch
Type: application/octet-stream
Part: 10
Message:
Re: index prefetching
Patch
Format: format-patch
Series: patch v16-0008
Subject: Make buffer hit helper
| File | + | − |
|---|---|---|
| src/backend/storage/buffer/bufmgr.c | 56 | 55 |
From 0f6cc4967a240b6fabd2b39e45068051b3ad8424 Mon Sep 17 00:00:00 2001
From: Melanie Plageman <melanieplageman@gmail.com>
Date: Fri, 23 Jan 2026 13:54:02 -0500
Subject: [PATCH v16 08/17] Make buffer hit helper
Already two places count buffer hits, requiring quite a few lines of
code since we do accounting in so many places. Future commits will add
more locations, so refactor into a helper.
Note: I (pgeoghean) have changed this from Melanie's original by
inlining the helper function:
https://postgr.es/m/CAH2-Wzk02vPjsJPx7EGNmgvsKKgyHn=XtGjJcPE+eQTP3xQt7w@mail.gmail.com
---
src/backend/storage/buffer/bufmgr.c | 111 ++++++++++++++--------------
1 file changed, 56 insertions(+), 55 deletions(-)
diff --git a/src/backend/storage/buffer/bufmgr.c b/src/backend/storage/buffer/bufmgr.c
index 2a95517a3..6cad27137 100644
--- a/src/backend/storage/buffer/bufmgr.c
+++ b/src/backend/storage/buffer/bufmgr.c
@@ -648,6 +648,10 @@ static inline BufferDesc *BufferAlloc(SMgrRelation smgr,
bool *foundPtr, IOContext io_context);
static bool AsyncReadBuffers(ReadBuffersOperation *operation, int *nblocks_progress);
static void CheckReadBuffersOperation(ReadBuffersOperation *operation, bool is_complete);
+static inline void ProcessBufferHit(BufferAccessStrategy strategy,
+ Relation rel, char persistence,
+ SMgrRelation smgr, ForkNumber forknum,
+ BlockNumber blocknum);
static Buffer GetVictimBuffer(BufferAccessStrategy strategy, IOContext io_context);
static void FlushUnlockedBuffer(BufferDesc *buf, SMgrRelation reln,
IOObject io_object, IOContext io_context);
@@ -1226,8 +1230,6 @@ PinBufferForBlock(Relation rel,
bool *foundPtr)
{
BufferDesc *bufHdr;
- IOContext io_context;
- IOObject io_object;
Assert(blockNum != P_NEW);
@@ -1236,17 +1238,6 @@ PinBufferForBlock(Relation rel,
persistence == RELPERSISTENCE_PERMANENT ||
persistence == RELPERSISTENCE_UNLOGGED));
- if (persistence == RELPERSISTENCE_TEMP)
- {
- io_context = IOCONTEXT_NORMAL;
- io_object = IOOBJECT_TEMP_RELATION;
- }
- else
- {
- io_context = IOContextForStrategy(strategy);
- io_object = IOOBJECT_RELATION;
- }
-
TRACE_POSTGRESQL_BUFFER_READ_START(forkNum, blockNum,
smgr->smgr_rlocator.locator.spcOid,
smgr->smgr_rlocator.locator.dbOid,
@@ -1254,18 +1245,11 @@ PinBufferForBlock(Relation rel,
smgr->smgr_rlocator.backend);
if (persistence == RELPERSISTENCE_TEMP)
- {
bufHdr = LocalBufferAlloc(smgr, forkNum, blockNum, foundPtr);
- if (*foundPtr)
- pgBufferUsage.local_blks_hit++;
- }
else
- {
bufHdr = BufferAlloc(smgr, persistence, forkNum, blockNum,
- strategy, foundPtr, io_context);
- if (*foundPtr)
- pgBufferUsage.shared_blks_hit++;
- }
+ strategy, foundPtr, IOContextForStrategy(strategy));
+
if (rel)
{
/*
@@ -1274,22 +1258,10 @@ PinBufferForBlock(Relation rel,
* zeroed instead), the per-relation stats always count them.
*/
pgstat_count_buffer_read(rel);
- if (*foundPtr)
- pgstat_count_buffer_hit(rel);
}
- if (*foundPtr)
- {
- pgstat_count_io_op(io_object, io_context, IOOP_HIT, 1, 0);
- if (VacuumCostActive)
- VacuumCostBalance += VacuumCostPageHit;
- TRACE_POSTGRESQL_BUFFER_READ_DONE(forkNum, blockNum,
- smgr->smgr_rlocator.locator.spcOid,
- smgr->smgr_rlocator.locator.dbOid,
- smgr->smgr_rlocator.locator.relNumber,
- smgr->smgr_rlocator.backend,
- true);
- }
+ if (*foundPtr)
+ ProcessBufferHit(strategy, rel, persistence, smgr, forkNum, blockNum);
return BufferDescriptorGetBuffer(bufHdr);
}
@@ -1695,6 +1667,51 @@ ReadBuffersCanStartIO(Buffer buffer, bool nowait)
return ReadBuffersCanStartIOOnce(buffer, nowait);
}
+/*
+ * We track various stats related to buffer hits. Because this is done in a
+ * few separate places, this helper exists for convenience.
+ */
+static inline void
+ProcessBufferHit(BufferAccessStrategy strategy,
+ Relation rel, char persistence, SMgrRelation smgr,
+ ForkNumber forknum, BlockNumber blocknum)
+{
+ IOContext io_context;
+ IOObject io_object;
+
+ if (persistence == RELPERSISTENCE_TEMP)
+ {
+ io_context = IOCONTEXT_NORMAL;
+ io_object = IOOBJECT_TEMP_RELATION;
+ }
+ else
+ {
+ io_context = IOContextForStrategy(strategy);
+ io_object = IOOBJECT_RELATION;
+ }
+
+ TRACE_POSTGRESQL_BUFFER_READ_DONE(forknum,
+ blocknum,
+ smgr->smgr_rlocator.locator.spcOid,
+ smgr->smgr_rlocator.locator.dbOid,
+ smgr->smgr_rlocator.locator.relNumber,
+ smgr->smgr_rlocator.backend,
+ true);
+
+ if (persistence == RELPERSISTENCE_TEMP)
+ pgBufferUsage.local_blks_hit += 1;
+ else
+ pgBufferUsage.shared_blks_hit += 1;
+
+ if (rel)
+ pgstat_count_buffer_hit(rel);
+
+ pgstat_count_io_op(io_object, io_context, IOOP_HIT, 1, 0);
+
+ if (VacuumCostActive)
+ VacuumCostBalance += VacuumCostPageHit;
+}
+
/*
* Helper for WaitReadBuffers() that processes the results of a readv
* operation, raising an error if necessary.
@@ -1990,25 +2007,9 @@ AsyncReadBuffers(ReadBuffersOperation *operation, int *nblocks_progress)
* must have started out as a miss in PinBufferForBlock(). The other
* backend will track this as a 'read'.
*/
- TRACE_POSTGRESQL_BUFFER_READ_DONE(forknum, blocknum + operation->nblocks_done,
- operation->smgr->smgr_rlocator.locator.spcOid,
- operation->smgr->smgr_rlocator.locator.dbOid,
- operation->smgr->smgr_rlocator.locator.relNumber,
- operation->smgr->smgr_rlocator.backend,
- true);
-
- if (persistence == RELPERSISTENCE_TEMP)
- pgBufferUsage.local_blks_hit += 1;
- else
- pgBufferUsage.shared_blks_hit += 1;
-
- if (operation->rel)
- pgstat_count_buffer_hit(operation->rel);
-
- pgstat_count_io_op(io_object, io_context, IOOP_HIT, 1, 0);
-
- if (VacuumCostActive)
- VacuumCostBalance += VacuumCostPageHit;
+ ProcessBufferHit(operation->strategy, operation->rel, persistence,
+ operation->smgr, forknum,
+ blocknum + operation->nblocks_done);
}
else
{
--
2.53.0