Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 5031ac8

Browse files
macdiceCommitfest Bot
authored and
Commitfest Bot
committed
Improve buffer manager API for backend pin limits.
Previously the support functions assumed that the caller needed one pin to make progress, and could optionally use some more. Add a couple more functions for callers that want to know: * what the maximum possible number could be irrespective of currently held pins, for space planning purposes, called the "soft pin limit" * how many additional pins they could acquire right now, without the special case allowing one pin, for users that already hold pins and could make progress even if zero extra pins are available These APIs are better suited to read_stream.c, which will be improved in a follow-up patch. Also compute MaxProportionalPins up front, to avoid performing division whenever we check the balance. Reviewed-by: Andres Freund <andres@anarazel.de> Discussion: https://postgr.es/m/CA%2BhUKGK_%3D4CVmMHvsHjOVrK6t4F%3DLBpFzsrr3R%2BaJYN8kcTfWg%40mail.gmail.com
1 parent 4618045 commit 5031ac8

File tree

3 files changed

+80
-25
lines changed

3 files changed

+80
-25
lines changed

src/backend/storage/buffer/bufmgr.c

Lines changed: 60 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,8 @@ static int32 PrivateRefCountOverflowed = 0;
211211
static uint32 PrivateRefCountClock = 0;
212212
static PrivateRefCountEntry *ReservedRefCountEntry = NULL;
213213

214+
static uint32 MaxProportionalPins;
215+
214216
static void ReservePrivateRefCountEntry(void);
215217
static PrivateRefCountEntry *NewPrivateRefCountEntry(Buffer buffer);
216218
static PrivateRefCountEntry *GetPrivateRefCountEntry(Buffer buffer, bool do_move);
@@ -2097,43 +2099,67 @@ GetVictimBuffer(BufferAccessStrategy strategy, IOContext io_context)
20972099
return buf;
20982100
}
20992101

2102+
/*
2103+
* Return the maximum number of buffer than this backend should try to pin at
2104+
* once, to avoid pinning more than its fair share. This is the highest value
2105+
* that GetAdditionalPinLimit() and LimitAdditionalPins() could ever return.
2106+
*
2107+
* It's called a soft limit because nothing stops a backend from trying to
2108+
* acquire more pins than this if it needs them to make progress, but code that
2109+
* wants optional extra buffers for optimizations should respect this
2110+
* per-backend limit.
2111+
*/
2112+
uint32
2113+
GetSoftPinLimit(void)
2114+
{
2115+
return MaxProportionalPins;
2116+
}
2117+
2118+
/*
2119+
* Return the maximum number of additional buffers that this backend should
2120+
* pin if it wants to stay under the per-backend soft limit, considering the
2121+
* number of buffers it has already pinned. Unlike LimitAdditionalPins(), the
2122+
* result can be zero, so the caller is expected to adjust it if required to
2123+
* make progress.
2124+
*/
2125+
uint32
2126+
GetAdditionalPinLimit(void)
2127+
{
2128+
uint32 estimated_pins_held;
2129+
2130+
/*
2131+
* We get the number of "overflowed" pins for free, but don't know the
2132+
* number of pins in PrivateRefCountArray. The cost of calculating that
2133+
* exactly doesn't seem worth it, so just assume the max.
2134+
*/
2135+
estimated_pins_held = PrivateRefCountOverflowed + REFCOUNT_ARRAY_ENTRIES;
2136+
2137+
/* Is this backend already holding more than its fair share? */
2138+
if (estimated_pins_held > MaxProportionalPins)
2139+
return 0;
2140+
2141+
return MaxProportionalPins - estimated_pins_held;
2142+
}
2143+
21002144
/*
21012145
* Limit the number of pins a batch operation may additionally acquire, to
21022146
* avoid running out of pinnable buffers.
21032147
*
2104-
* One additional pin is always allowed, as otherwise the operation likely
2105-
* cannot be performed at all.
2106-
*
2107-
* The number of allowed pins for a backend is computed based on
2108-
* shared_buffers and the maximum number of connections possible. That's very
2109-
* pessimistic, but outside of toy-sized shared_buffers it should allow
2110-
* sufficient pins.
2148+
* One additional pin is always allowed, on the assumption that the operation
2149+
* requires at least one to make progress.
21112150
*/
21122151
void
21132152
LimitAdditionalPins(uint32 *additional_pins)
21142153
{
2115-
uint32 max_backends;
2116-
int max_proportional_pins;
2154+
uint32 limit;
21172155

21182156
if (*additional_pins <= 1)
21192157
return;
21202158

2121-
max_backends = MaxBackends + NUM_AUXILIARY_PROCS;
2122-
max_proportional_pins = NBuffers / max_backends;
2123-
2124-
/*
2125-
* Subtract the approximate number of buffers already pinned by this
2126-
* backend. We get the number of "overflowed" pins for free, but don't
2127-
* know the number of pins in PrivateRefCountArray. The cost of
2128-
* calculating that exactly doesn't seem worth it, so just assume the max.
2129-
*/
2130-
max_proportional_pins -= PrivateRefCountOverflowed + REFCOUNT_ARRAY_ENTRIES;
2131-
2132-
if (max_proportional_pins <= 0)
2133-
max_proportional_pins = 1;
2134-
2135-
if (*additional_pins > max_proportional_pins)
2136-
*additional_pins = max_proportional_pins;
2159+
limit = GetAdditionalPinLimit();
2160+
limit = Max(limit, 1);
2161+
if (limit < *additional_pins)
2162+
*additional_pins = limit;
21372163
}
21382164

21392165
/*
@@ -3575,6 +3601,15 @@ InitBufferManagerAccess(void)
35753601
{
35763602
HASHCTL hash_ctl;
35773603

3604+
/*
3605+
* The soft limit on the number of pins each backend should respect, based
3606+
* on shared_buffers and the maximum number of connections possible.
3607+
* That's very pessimistic, but outside toy-sized shared_buffers it should
3608+
* allow plenty of pins. LimitAdditionalPins() or GetAdditionalPinLimit()
3609+
* can be used to check the remaining balance.
3610+
*/
3611+
MaxProportionalPins = NBuffers / (MaxBackends + NUM_AUXILIARY_PROCS);
3612+
35783613
memset(&PrivateRefCountArray, 0, sizeof(PrivateRefCountArray));
35793614

35803615
hash_ctl.keysize = sizeof(int32);

src/backend/storage/buffer/localbuf.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,22 @@ GetLocalVictimBuffer(void)
286286
return BufferDescriptorGetBuffer(bufHdr);
287287
}
288288

289+
/* see GetSoftPinLimit() */
290+
uint32
291+
GetSoftLocalPinLimit(void)
292+
{
293+
/* Every backend has its own temporary buffers, and can pin them all. */
294+
return num_temp_buffers;
295+
}
296+
297+
/* see GetAdditionalPinLimit() */
298+
uint32
299+
GetAdditionalLocalPinLimit(void)
300+
{
301+
Assert(NLocalPinnedBuffers <= num_temp_buffers);
302+
return num_temp_buffers - NLocalPinnedBuffers;
303+
}
304+
289305
/* see LimitAdditionalPins() */
290306
void
291307
LimitAdditionalLocalPins(uint32 *additional_pins)

src/include/storage/bufmgr.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,10 @@ extern bool HoldingBufferPinThatDelaysRecovery(void);
290290

291291
extern bool BgBufferSync(struct WritebackContext *wb_context);
292292

293+
extern uint32 GetSoftPinLimit(void);
294+
extern uint32 GetSoftLocalPinLimit(void);
295+
extern uint32 GetAdditionalPinLimit(void);
296+
extern uint32 GetAdditionalLocalPinLimit(void);
293297
extern void LimitAdditionalPins(uint32 *additional_pins);
294298
extern void LimitAdditionalLocalPins(uint32 *additional_pins);
295299

0 commit comments

Comments
 (0)