0013-Convert-buffer-manager-to-the-new-API.patch
text/x-patch
Filename: 0013-Convert-buffer-manager-to-the-new-API.patch
Type: text/x-patch
Part: 12
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: format-patch
Series: patch 0013
Subject: Convert buffer manager to the new API
| File | + | − |
|---|---|---|
| src/backend/storage/buffer/buf_init.c | 71 | 87 |
| src/backend/storage/buffer/buf_table.c | 32 | 24 |
| src/backend/storage/buffer/freelist.c | 31 | 63 |
| src/backend/storage/ipc/ipci.c | 0 | 3 |
| src/include/storage/buf_internals.h | 0 | 5 |
| src/include/storage/bufmgr.h | 0 | 4 |
| src/include/storage/subsystemlist.h | 3 | 0 |
From 99610b50f699bbf8e953c793499cf55db36a2439 Mon Sep 17 00:00:00 2001
From: Heikki Linnakangas <heikki.linnakangas@iki.fi>
Date: Thu, 2 Apr 2026 00:44:02 +0300
Subject: [PATCH 13/14] Convert buffer manager to the new API
---
src/backend/storage/buffer/buf_init.c | 158 +++++++++++--------------
src/backend/storage/buffer/buf_table.c | 56 +++++----
src/backend/storage/buffer/freelist.c | 94 +++++----------
src/backend/storage/ipc/ipci.c | 3 -
src/include/storage/buf_internals.h | 5 -
src/include/storage/bufmgr.h | 4 -
src/include/storage/subsystemlist.h | 3 +
7 files changed, 137 insertions(+), 186 deletions(-)
diff --git a/src/backend/storage/buffer/buf_init.c b/src/backend/storage/buffer/buf_init.c
index c0c223b2e32..71e7c29116c 100644
--- a/src/backend/storage/buffer/buf_init.c
+++ b/src/backend/storage/buffer/buf_init.c
@@ -18,6 +18,8 @@
#include "storage/buf_internals.h"
#include "storage/bufmgr.h"
#include "storage/proclist.h"
+#include "storage/shmem.h"
+#include "storage/subsystems.h"
BufferDescPadded *BufferDescriptors;
char *BufferBlocks;
@@ -25,6 +27,15 @@ ConditionVariableMinimallyPadded *BufferIOCVArray;
WritebackContext BackendWritebackContext;
CkptSortItem *CkptBufferIds;
+static void BufferManagerShmemRequest(void *arg);
+static void BufferManagerShmemInit(void *arg);
+static void BufferManagerShmemAttach(void *arg);
+
+const ShmemCallbacks BufferManagerShmemCallbacks = {
+ .request_fn = BufferManagerShmemRequest,
+ .init_fn = BufferManagerShmemInit,
+ .attach_fn = BufferManagerShmemAttach,
+};
/*
* Data Structures:
@@ -60,37 +71,39 @@ CkptSortItem *CkptBufferIds;
/*
- * Initialize shared buffer pool
- *
- * This is called once during shared-memory initialization (either in the
- * postmaster, or in a standalone backend).
+ * Register shared memory area for the buffer pool.
*/
-void
-BufferManagerShmemInit(void)
+static void
+BufferManagerShmemRequest(void *arg)
{
- bool foundBufs,
- foundDescs,
- foundIOCV,
- foundBufCkpt;
-
+ static ShmemStructDesc BufferDescriptorsShmemDesc;
+ static ShmemStructDesc BufferBlocksShmemDesc;
+ static ShmemStructDesc BufferIOCVArrayShmemDesc;
+ static ShmemStructDesc CkptBufferIdsShmemDesc;
+
+ ShmemRequestStruct(&BufferDescriptorsShmemDesc,
+ .name = "Buffer Descriptors",
+ .size = NBuffers * sizeof(BufferDescPadded),
/* Align descriptors to a cacheline boundary. */
- BufferDescriptors = (BufferDescPadded *)
- ShmemInitStruct("Buffer Descriptors",
- NBuffers * sizeof(BufferDescPadded),
- &foundDescs);
+ .alignment = PG_CACHE_LINE_SIZE,
+ .ptr = (void **) &BufferDescriptors,
+ );
+ ShmemRequestStruct(&BufferBlocksShmemDesc,
+ .name = "Buffer Blocks",
+ .size = NBuffers * (Size) BLCKSZ,
/* Align buffer pool on IO page size boundary. */
- BufferBlocks = (char *)
- TYPEALIGN(PG_IO_ALIGN_SIZE,
- ShmemInitStruct("Buffer Blocks",
- NBuffers * (Size) BLCKSZ + PG_IO_ALIGN_SIZE,
- &foundBufs));
-
- /* Align condition variables to cacheline boundary. */
- BufferIOCVArray = (ConditionVariableMinimallyPadded *)
- ShmemInitStruct("Buffer IO Condition Variables",
- NBuffers * sizeof(ConditionVariableMinimallyPadded),
- &foundIOCV);
+ .alignment = PG_IO_ALIGN_SIZE,
+ .ptr = (void **) &BufferBlocks,
+ );
+
+ ShmemRequestStruct(&BufferIOCVArrayShmemDesc,
+ .name = "Buffer IO Condition Variables",
+ .size = NBuffers * sizeof(ConditionVariableMinimallyPadded),
+ /* Align descriptors to a cacheline boundary. */
+ .alignment = PG_CACHE_LINE_SIZE,
+ .ptr = (void **) &BufferIOCVArray,
+ );
/*
* The array used to sort to-be-checkpointed buffer ids is located in
@@ -99,80 +112,51 @@ BufferManagerShmemInit(void)
* the checkpointer is restarted, memory allocation failures would be
* painful.
*/
- CkptBufferIds = (CkptSortItem *)
- ShmemInitStruct("Checkpoint BufferIds",
- NBuffers * sizeof(CkptSortItem), &foundBufCkpt);
+ ShmemRequestStruct(&CkptBufferIdsShmemDesc,
+ .name = "Checkpoint BufferIds",
+ .size = NBuffers * sizeof(CkptSortItem),
+ .ptr = (void **) &CkptBufferIds,
+ );
+}
- if (foundDescs || foundBufs || foundIOCV || foundBufCkpt)
- {
- /* should find all of these, or none of them */
- Assert(foundDescs && foundBufs && foundIOCV && foundBufCkpt);
- /* note: this path is only taken in EXEC_BACKEND case */
- }
- else
+/*
+ * Initialize shared buffer pool
+ *
+ * This is called once during shared-memory initialization (either in the
+ * postmaster, or in a standalone backend).
+ */
+static void
+BufferManagerShmemInit(void *arg)
+{
+ /*
+ * Initialize all the buffer headers.
+ */
+ for (int i = 0; i < NBuffers; i++)
{
- int i;
+ BufferDesc *buf = GetBufferDescriptor(i);
- /*
- * Initialize all the buffer headers.
- */
- for (i = 0; i < NBuffers; i++)
- {
- BufferDesc *buf = GetBufferDescriptor(i);
+ ClearBufferTag(&buf->tag);
- ClearBufferTag(&buf->tag);
+ pg_atomic_init_u64(&buf->state, 0);
+ buf->wait_backend_pgprocno = INVALID_PROC_NUMBER;
- pg_atomic_init_u64(&buf->state, 0);
- buf->wait_backend_pgprocno = INVALID_PROC_NUMBER;
+ buf->buf_id = i;
- buf->buf_id = i;
+ pgaio_wref_clear(&buf->io_wref);
- pgaio_wref_clear(&buf->io_wref);
-
- proclist_init(&buf->lock_waiters);
- ConditionVariableInit(BufferDescriptorGetIOCV(buf));
- }
+ proclist_init(&buf->lock_waiters);
+ ConditionVariableInit(BufferDescriptorGetIOCV(buf));
}
- /* Init other shared buffer-management stuff */
- StrategyInitialize(!foundDescs);
-
/* Initialize per-backend file flush context */
WritebackContextInit(&BackendWritebackContext,
&backend_flush_after);
}
-/*
- * BufferManagerShmemSize
- *
- * compute the size of shared memory for the buffer pool including
- * data pages, buffer descriptors, hash tables, etc.
- */
-Size
-BufferManagerShmemSize(void)
+static void
+BufferManagerShmemAttach(void *arg)
{
- Size size = 0;
-
- /* size of buffer descriptors */
- size = add_size(size, mul_size(NBuffers, sizeof(BufferDescPadded)));
- /* to allow aligning buffer descriptors */
- size = add_size(size, PG_CACHE_LINE_SIZE);
-
- /* size of data pages, plus alignment padding */
- size = add_size(size, PG_IO_ALIGN_SIZE);
- size = add_size(size, mul_size(NBuffers, BLCKSZ));
-
- /* size of stuff controlled by freelist.c */
- size = add_size(size, StrategyShmemSize());
-
- /* size of I/O condition variables */
- size = add_size(size, mul_size(NBuffers,
- sizeof(ConditionVariableMinimallyPadded)));
- /* to allow aligning the above */
- size = add_size(size, PG_CACHE_LINE_SIZE);
-
- /* size of checkpoint sort array in bufmgr.c */
- size = add_size(size, mul_size(NBuffers, sizeof(CkptSortItem)));
-
- return size;
+ /* Initialize per-backend file flush context */
+ WritebackContextInit(&BackendWritebackContext,
+ &backend_flush_after);
}
diff --git a/src/backend/storage/buffer/buf_table.c b/src/backend/storage/buffer/buf_table.c
index d04ef74b850..aaf66351220 100644
--- a/src/backend/storage/buffer/buf_table.c
+++ b/src/backend/storage/buffer/buf_table.c
@@ -22,6 +22,7 @@
#include "postgres.h"
#include "storage/buf_internals.h"
+#include "storage/subsystems.h"
/* entry for buffer lookup hashtable */
typedef struct
@@ -32,37 +33,44 @@ typedef struct
static HTAB *SharedBufHash;
+static void BufTableShmemRequest(void *arg);
-/*
- * Estimate space needed for mapping hashtable
- * size is the desired hash table size (possibly more than NBuffers)
- */
-Size
-BufTableShmemSize(int size)
-{
- return hash_estimate_size(size, sizeof(BufferLookupEnt));
-}
+const ShmemCallbacks BufTableShmemCallbacks = {
+ .request_fn = BufTableShmemRequest,
+ /* no special initialization needed, the hash table will start empty */
+};
/*
- * Initialize shmem hash table for mapping buffers
+ * Register shmem hash table for mapping buffers.
* size is the desired hash table size (possibly more than NBuffers)
*/
void
-InitBufTable(int size)
+BufTableShmemRequest(void *arg)
{
- HASHCTL info;
-
- /* assume no locking is needed yet */
-
- /* BufferTag maps to Buffer */
- info.keysize = sizeof(BufferTag);
- info.entrysize = sizeof(BufferLookupEnt);
- info.num_partitions = NUM_BUFFER_PARTITIONS;
-
- SharedBufHash = ShmemInitHash("Shared Buffer Lookup Table",
- size,
- &info,
- HASH_ELEM | HASH_BLOBS | HASH_PARTITION | HASH_FIXED_SIZE);
+ static ShmemHashDesc SharedBufHashDesc;
+ int size;
+
+ /*
+ * Request the shared buffer lookup hashtable.
+ *
+ * Since we can't tolerate running out of lookup table entries, we must be
+ * sure to specify an adequate table size here. The maximum steady-state
+ * usage is of course NBuffers entries, but BufferAlloc() tries to insert
+ * a new entry before deleting the old. In principle this could be
+ * happening in each partition concurrently, so we could need as many as
+ * NBuffers + NUM_BUFFER_PARTITIONS entries.
+ */
+ size = NBuffers + NUM_BUFFER_PARTITIONS;
+
+ ShmemRequestHash(&SharedBufHashDesc,
+ .name = "Shared Buffer Lookup Table",
+ .nelems = size,
+ .ptr = &SharedBufHash,
+ .hash_info.keysize = sizeof(BufferTag),
+ .hash_info.entrysize = sizeof(BufferLookupEnt),
+ .hash_info.num_partitions = NUM_BUFFER_PARTITIONS,
+ .hash_flags = HASH_ELEM | HASH_BLOBS | HASH_PARTITION | HASH_FIXED_SIZE,
+ );
}
/*
diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index b7687836188..313a5e29f57 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -20,6 +20,8 @@
#include "storage/buf_internals.h"
#include "storage/bufmgr.h"
#include "storage/proc.h"
+#include "storage/shmem.h"
+#include "storage/subsystems.h"
#define INT_ACCESS_ONCE(var) ((int)(*((volatile int *)&(var))))
@@ -56,6 +58,14 @@ typedef struct
/* Pointers to shared state */
static BufferStrategyControl *StrategyControl = NULL;
+static void StrategyCtlShmemRequest(void *arg);
+static void StrategyCtlShmemInit(void *arg);
+
+const ShmemCallbacks StrategyCtlShmemCallbacks = {
+ .request_fn = StrategyCtlShmemRequest,
+ .init_fn = StrategyCtlShmemInit,
+};
+
/*
* Private (non-shared) state for managing a ring of shared buffers to re-use.
* This is currently the only kind of BufferAccessStrategy object, but someday
@@ -369,80 +379,38 @@ StrategyNotifyBgWriter(int bgwprocno)
/*
- * StrategyShmemSize
- *
- * estimate the size of shared memory used by the freelist-related structures.
- *
- * Note: for somewhat historical reasons, the buffer lookup hashtable size
- * is also determined here.
+ * StrategyCtlShmemRequest -- request shared memory for the buffer
+ * cache replacement strategy.
*/
-Size
-StrategyShmemSize(void)
+static void
+StrategyCtlShmemRequest(void *arg)
{
- Size size = 0;
-
- /* size of lookup hash table ... see comment in StrategyInitialize */
- size = add_size(size, BufTableShmemSize(NBuffers + NUM_BUFFER_PARTITIONS));
+ static ShmemStructDesc StrategyCtlShmemDesc;
- /* size of the shared replacement strategy control block */
- size = add_size(size, MAXALIGN(sizeof(BufferStrategyControl)));
-
- return size;
+ ShmemRequestStruct(&StrategyCtlShmemDesc,
+ .name = "Buffer Strategy Status",
+ .size = sizeof(BufferStrategyControl),
+ .ptr = (void **) &StrategyControl
+ );
}
/*
- * StrategyInitialize -- initialize the buffer cache replacement
- * strategy.
- *
- * Assumes: All of the buffers are already built into a linked list.
- * Only called by postmaster and only during initialization.
+ * StrategyCtlShmemInit -- initialize the buffer cache replacement strategy.
*/
-void
-StrategyInitialize(bool init)
+static void
+StrategyCtlShmemInit(void *arg)
{
- bool found;
-
- /*
- * Initialize the shared buffer lookup hashtable.
- *
- * Since we can't tolerate running out of lookup table entries, we must be
- * sure to specify an adequate table size here. The maximum steady-state
- * usage is of course NBuffers entries, but BufferAlloc() tries to insert
- * a new entry before deleting the old. In principle this could be
- * happening in each partition concurrently, so we could need as many as
- * NBuffers + NUM_BUFFER_PARTITIONS entries.
- */
- InitBufTable(NBuffers + NUM_BUFFER_PARTITIONS);
-
- /*
- * Get or create the shared strategy control block
- */
- StrategyControl = (BufferStrategyControl *)
- ShmemInitStruct("Buffer Strategy Status",
- sizeof(BufferStrategyControl),
- &found);
-
- if (!found)
- {
- /*
- * Only done once, usually in postmaster
- */
- Assert(init);
+ SpinLockInit(&StrategyControl->buffer_strategy_lock);
- SpinLockInit(&StrategyControl->buffer_strategy_lock);
+ /* Initialize the clock-sweep pointer */
+ pg_atomic_init_u32(&StrategyControl->nextVictimBuffer, 0);
- /* Initialize the clock-sweep pointer */
- pg_atomic_init_u32(&StrategyControl->nextVictimBuffer, 0);
+ /* Clear statistics */
+ StrategyControl->completePasses = 0;
+ pg_atomic_init_u32(&StrategyControl->numBufferAllocs, 0);
- /* Clear statistics */
- StrategyControl->completePasses = 0;
- pg_atomic_init_u32(&StrategyControl->numBufferAllocs, 0);
-
- /* No pending notification */
- StrategyControl->bgwprocno = -1;
- }
- else
- Assert(!init);
+ /* No pending notification */
+ StrategyControl->bgwprocno = -1;
}
diff --git a/src/backend/storage/ipc/ipci.c b/src/backend/storage/ipc/ipci.c
index bd67f81cea3..ecc5388ad47 100644
--- a/src/backend/storage/ipc/ipci.c
+++ b/src/backend/storage/ipc/ipci.c
@@ -39,7 +39,6 @@
#include "replication/walreceiver.h"
#include "replication/walsender.h"
#include "storage/aio_subsys.h"
-#include "storage/bufmgr.h"
#include "storage/dsm.h"
#include "storage/ipc.h"
#include "storage/pg_shmem.h"
@@ -99,7 +98,6 @@ CalculateShmemSize(void)
size = add_size(size, ShmemGetRequestedSize());
/* legacy subsystems */
- size = add_size(size, BufferManagerShmemSize());
size = add_size(size, LockManagerShmemSize());
size = add_size(size, XLogPrefetchShmemSize());
size = add_size(size, XLOGShmemSize());
@@ -263,7 +261,6 @@ CreateOrAttachShmemStructs(void)
XLOGShmemInit();
XLogPrefetchShmemInit();
XLogRecoveryShmemInit();
- BufferManagerShmemInit();
/*
* Set up lock manager
diff --git a/src/include/storage/buf_internals.h b/src/include/storage/buf_internals.h
index ad1b7b2216a..89615a254a3 100644
--- a/src/include/storage/buf_internals.h
+++ b/src/include/storage/buf_internals.h
@@ -587,12 +587,7 @@ extern bool StrategyRejectBuffer(BufferAccessStrategy strategy,
extern int StrategySyncStart(uint32 *complete_passes, uint32 *num_buf_alloc);
extern void StrategyNotifyBgWriter(int bgwprocno);
-extern Size StrategyShmemSize(void);
-extern void StrategyInitialize(bool init);
-
/* buf_table.c */
-extern Size BufTableShmemSize(int size);
-extern void InitBufTable(int size);
extern uint32 BufTableHashCode(BufferTag *tagPtr);
extern int BufTableLookup(BufferTag *tagPtr, uint32 hashcode);
extern int BufTableInsert(BufferTag *tagPtr, uint32 hashcode, int buf_id);
diff --git a/src/include/storage/bufmgr.h b/src/include/storage/bufmgr.h
index aa61a39d9e6..6837b35fc6d 100644
--- a/src/include/storage/bufmgr.h
+++ b/src/include/storage/bufmgr.h
@@ -371,10 +371,6 @@ extern void MarkDirtyAllUnpinnedBuffers(int32 *buffers_dirtied,
int32 *buffers_already_dirty,
int32 *buffers_skipped);
-/* in buf_init.c */
-extern void BufferManagerShmemInit(void);
-extern Size BufferManagerShmemSize(void);
-
/* in localbuf.c */
extern void AtProcExit_LocalBuffers(void);
diff --git a/src/include/storage/subsystemlist.h b/src/include/storage/subsystemlist.h
index b438794d46d..d8e11756a61 100644
--- a/src/include/storage/subsystemlist.h
+++ b/src/include/storage/subsystemlist.h
@@ -36,6 +36,9 @@ PG_SHMEM_SUBSYSTEM(CLOGShmemCallbacks)
PG_SHMEM_SUBSYSTEM(CommitTsShmemCallbacks)
PG_SHMEM_SUBSYSTEM(SUBTRANSShmemCallbacks)
PG_SHMEM_SUBSYSTEM(MultiXactShmemCallbacks)
+PG_SHMEM_SUBSYSTEM(BufferManagerShmemCallbacks)
+PG_SHMEM_SUBSYSTEM(StrategyCtlShmemCallbacks)
+PG_SHMEM_SUBSYSTEM(BufTableShmemCallbacks)
/* predicate lock manager */
PG_SHMEM_SUBSYSTEM(PredicateLockShmemCallbacks)
--
2.47.3