From 1bb746905affe8955e9475ec68e5986aaf001fd6 Mon Sep 17 00:00:00 2001 From: Palak Chaturvedi Date: Fri, 21 Aug 2026 06:28:25 +0000 Subject: [PATCH v20260817 10/11] buffermgr: recompute MaxProportionalPins after buffer pool resize MaxProportionalPins is computed once at startup as NBuffers / (MaxBackends + NUM_AUXILIARY_PROCS). After a buffer pool resize, NBuffers changes but MaxProportionalPins stays stale. If the pool shrinks, backends can hold too many pins relative to the new pool size, defeating the per-backend pin limit. Extract RecomputeMaxProportionalPins() from InitBufferManagerAccess() and call it from ProcessBarrierBufferPoolSize() so every backend recomputes the limit when it absorbs the new pool size. Reported-by: Yuhang Qiu --- src/backend/storage/buffer/buf_resize.c | 1 + src/backend/storage/buffer/bufmgr.c | 11 ++++++++++- src/include/storage/bufmgr.h | 1 + 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/backend/storage/buffer/buf_resize.c b/src/backend/storage/buffer/buf_resize.c index 90f5fb1c71d..d8b5a0ad845 100644 --- a/src/backend/storage/buffer/buf_resize.c +++ b/src/backend/storage/buffer/buf_resize.c @@ -503,6 +503,7 @@ ProcessBarrierBufferPoolSize(void) Assert(activeNBuffers == pg_atomic_read_u32(&BufferControl->activeNBuffers)); NBuffers = pg_atomic_read_u32(&BufferControl->currentNBuffers); + RecomputeMaxProportionalPins(); return true; } diff --git a/src/backend/storage/buffer/bufmgr.c b/src/backend/storage/buffer/bufmgr.c index 2aac77ccc35..787419cc7f2 100644 --- a/src/backend/storage/buffer/bufmgr.c +++ b/src/backend/storage/buffer/bufmgr.c @@ -275,6 +275,15 @@ static int PrivateRefCountEntryLast = -1; static uint32 MaxProportionalPins; +/* + * Recompute the per-backend pin limit after a buffer pool resize. + */ +void +RecomputeMaxProportionalPins(void) +{ + MaxProportionalPins = NBuffers / (MaxBackends + NUM_AUXILIARY_PROCS); +} + static void ReservePrivateRefCountEntry(void); static PrivateRefCountEntry *NewPrivateRefCountEntry(Buffer buffer); static PrivateRefCountEntry *GetPrivateRefCountEntry(Buffer buffer, bool do_move); @@ -4328,7 +4337,7 @@ InitBufferManagerAccess(void) * allow plenty of pins. LimitAdditionalPins() and * GetAdditionalPinLimit() can be used to check the remaining balance. */ - MaxProportionalPins = NBuffers / (MaxBackends + NUM_AUXILIARY_PROCS); + RecomputeMaxProportionalPins(); memset(&PrivateRefCountArray, 0, sizeof(PrivateRefCountArray)); memset(&PrivateRefCountArrayKeys, 0, sizeof(PrivateRefCountArrayKeys)); diff --git a/src/include/storage/bufmgr.h b/src/include/storage/bufmgr.h index 187e9b29a9e..650989fcdcd 100644 --- a/src/include/storage/bufmgr.h +++ b/src/include/storage/bufmgr.h @@ -287,6 +287,7 @@ extern Buffer ExtendBufferedRelTo(BufferManagerRelation bmr, ReadBufferMode mode); extern void InitBufferManagerAccess(void); +extern void RecomputeMaxProportionalPins(void); extern void AtEOXact_Buffers(bool isCommit); #ifdef USE_ASSERT_CHECKING extern void AssertBufferLocksPermitCatalogRead(void); -- 2.43.0