Skip to content

Commit 3bd8439

Browse files
committed
Allow BufferAccessStrategy to limit pin count.
While pinning extra buffers to look ahead, users of strategies are in danger of using too many buffers. For some strategies, that means "escaping" from the ring, and in others it means forcing dirty data to disk very frequently with associated WAL flushing. Since external code has no insight into any of that, allow individual strategy types to expose a clamp that should be applied when deciding how many buffers to pin at once. Reviewed-by: Andres Freund <andres@anarazel.de> Reviewed-by: Melanie Plageman <melanieplageman@gmail.com> Discussion: https://postgr.es/m/CAAKRu_aJXnqsyZt6HwFLnxYEBgE17oypkxbKbT1t1geE_wvH2Q%40mail.gmail.com
1 parent f956ecd commit 3bd8439

File tree

3 files changed

+48
-0
lines changed

3 files changed

+48
-0
lines changed

src/backend/storage/aio/read_stream.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -419,6 +419,7 @@ read_stream_begin_relation(int flags,
419419
size_t size;
420420
int16 queue_size;
421421
int16 max_ios;
422+
int strategy_pin_limit;
422423
uint32 max_pinned_buffers;
423424
Oid tablespace_id;
424425
SMgrRelation smgr;
@@ -460,6 +461,10 @@ read_stream_begin_relation(int flags,
460461
max_pinned_buffers = Min(max_pinned_buffers,
461462
PG_INT16_MAX - io_combine_limit - 1);
462463

464+
/* Give the strategy a chance to limit the number of buffers we pin. */
465+
strategy_pin_limit = GetAccessStrategyPinLimit(strategy);
466+
max_pinned_buffers = Min(strategy_pin_limit, max_pinned_buffers);
467+
463468
/* Don't allow this backend to pin more than its share of buffers. */
464469
if (SmgrIsTemp(smgr))
465470
LimitAdditionalLocalPins(&max_pinned_buffers);

src/backend/storage/buffer/freelist.c

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -629,6 +629,48 @@ GetAccessStrategyBufferCount(BufferAccessStrategy strategy)
629629
return strategy->nbuffers;
630630
}
631631

632+
/*
633+
* GetAccessStrategyPinLimit -- get cap of number of buffers that should be pinned
634+
*
635+
* When pinning extra buffers to look ahead, users of a ring-based strategy are
636+
* in danger of pinning too much of the ring at once while performing look-ahead.
637+
* For some strategies, that means "escaping" from the ring, and in others it
638+
* means forcing dirty data to disk very frequently with associated WAL
639+
* flushing. Since external code has no insight into any of that, allow
640+
* individual strategy types to expose a clamp that should be applied when
641+
* deciding on a maximum number of buffers to pin at once.
642+
*
643+
* Callers should combine this number with other relevant limits and take the
644+
* minimum.
645+
*/
646+
int
647+
GetAccessStrategyPinLimit(BufferAccessStrategy strategy)
648+
{
649+
if (strategy == NULL)
650+
return NBuffers;
651+
652+
switch (strategy->btype)
653+
{
654+
case BAS_BULKREAD:
655+
656+
/*
657+
* Since BAS_BULKREAD uses StrategyRejectBuffer(), dirty buffers
658+
* shouldn't be a problem and the caller is free to pin up to the
659+
* entire ring at once.
660+
*/
661+
return strategy->nbuffers;
662+
663+
default:
664+
665+
/*
666+
* Tell caller not to pin more than half the buffers in the ring.
667+
* This is a trade-off between look ahead distance and deferring
668+
* writeback and associated WAL traffic.
669+
*/
670+
return strategy->nbuffers / 2;
671+
}
672+
}
673+
632674
/*
633675
* FreeAccessStrategy -- release a BufferAccessStrategy object
634676
*

src/include/storage/bufmgr.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,7 @@ extern BufferAccessStrategy GetAccessStrategy(BufferAccessStrategyType btype);
318318
extern BufferAccessStrategy GetAccessStrategyWithSize(BufferAccessStrategyType btype,
319319
int ring_size_kb);
320320
extern int GetAccessStrategyBufferCount(BufferAccessStrategy strategy);
321+
extern int GetAccessStrategyPinLimit(BufferAccessStrategy strategy);
321322

322323
extern void FreeAccessStrategy(BufferAccessStrategy strategy);
323324

0 commit comments

Comments
 (0)