From b59a6797d4023a35794a2a24d742b80a721a3740 Mon Sep 17 00:00:00 2001 From: Satya Narlapuram Date: Thu, 7 May 2026 07:40:38 +0000 Subject: [PATCH] xlogprefetcher: record FPW/WILL_INIT blocks in the recent-blocks window Extract the recent-block bookkeeping into a small inline helper XLogPrefetcherAddRecent() and call it for the FPW and WILL_INIT short-circuit paths in XLogPrefetcherNextBlock(). Without it, a later reference to the same block was not recognized as recently seen and went through the normal prefetch path. --- src/backend/access/transam/xlogprefetcher.c | 34 +++++++++++++++++---- 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/src/backend/access/transam/xlogprefetcher.c b/src/backend/access/transam/xlogprefetcher.c index 83a3f97a57..7350246b8d 100644 --- a/src/backend/access/transam/xlogprefetcher.c +++ b/src/backend/access/transam/xlogprefetcher.c @@ -187,6 +187,9 @@ typedef struct XLogPrefetchStats int io_depth; /* Number of I/Os in progress. */ } XLogPrefetchStats; +static inline void XLogPrefetcherAddRecent(XLogPrefetcher *prefetcher, + RelFileLocator rlocator, + BlockNumber blockno); static inline void XLogPrefetcherAddFilter(XLogPrefetcher *prefetcher, RelFileLocator rlocator, BlockNumber blockno, @@ -674,17 +677,24 @@ XLogPrefetcherNextBlock(uintptr_t pgsr_private, XLogRecPtr *lsn) /* * If there is a full page image attached, we won't be reading the - * page, so don't bother trying to prefetch. + * page, so don't bother trying to prefetch. Record this block + * in the recent window so that later references to the same + * block are also skipped. */ if (block->has_image) { + XLogPrefetcherAddRecent(prefetcher, block->rlocator, block->blkno); XLogPrefetchIncrement(&SharedStats->skip_fpw); return LRQ_NEXT_NO_IO; } - /* There is no point in reading a page that will be zeroed. */ + /* + * There is no point in reading a page that will be zeroed. + * Record in the recent window like FPW above. + */ if (block->flags & BKPBLOCK_WILL_INIT) { + XLogPrefetcherAddRecent(prefetcher, block->rlocator, block->blkno); XLogPrefetchIncrement(&SharedStats->skip_init); return LRQ_NEXT_NO_IO; } @@ -711,10 +721,7 @@ XLogPrefetcherNextBlock(uintptr_t pgsr_private, XLogRecPtr *lsn) return LRQ_NEXT_NO_IO; } } - prefetcher->recent_rlocator[prefetcher->recent_idx] = block->rlocator; - prefetcher->recent_block[prefetcher->recent_idx] = block->blkno; - prefetcher->recent_idx = - (prefetcher->recent_idx + 1) % XLOGPREFETCHER_SEQ_WINDOW_SIZE; + XLogPrefetcherAddRecent(prefetcher, block->rlocator, block->blkno); /* * We could try to have a fast path for repeated references to the @@ -853,6 +860,20 @@ pg_stat_get_recovery_prefetch(PG_FUNCTION_ARGS) return (Datum) 0; } +/* + * Record a block in the recently seen blocks, so that the duplicate-check loop + * can suppress a later prefetch of the same block. + */ +static inline void +XLogPrefetcherAddRecent(XLogPrefetcher *prefetcher, RelFileLocator rlocator, + BlockNumber blockno) +{ + prefetcher->recent_rlocator[prefetcher->recent_idx] = rlocator; + prefetcher->recent_block[prefetcher->recent_idx] = blockno; + prefetcher->recent_idx = + (prefetcher->recent_idx + 1) % XLOGPREFETCHER_SEQ_WINDOW_SIZE; +} + /* * Don't prefetch any blocks >= 'blockno' from a given 'rlocator', until 'lsn' * has been replayed. @@ -1037,6 +1058,7 @@ XLogPrefetcherReadRecord(XLogPrefetcher *prefetcher, char **errmsg) * All IO initiated by earlier WAL is now completed. This might trigger * further prefetching. */ + lrq_complete_lsn(prefetcher->streaming_read, replayed_up_to); /* -- 2.43.0