From 1a3017b3e733f8898078c2c9b5178b7eb9b65c9c Mon Sep 17 00:00:00 2001
From: Amul Sul <sulamul@gmail.com>
Date: Wed, 4 Mar 2026 09:35:50 +0530
Subject: [PATCH v1 2/2] Fix incorrect VM fork truncation limit in WAL summary
 files.

When processing XLOG_SMGR_TRUNCATE, the WAL summarizer was recording
xlrec->blkno (a heap block number) as the limit block for the
VISIBILITYMAP_FORKNUM. However, the block reference table tracks VM
fork blocks by VM page number, not heap block number. Each VM page
covers more than 32K heap blocks, so passing the heap block number
directly inflated the VM limit block enormously.

This incorrect information in the incremental files caused
pg_combinebackup to produce giant 1 GiB Visibility Map files instead
of the small files actually needed.

Fix this by converting xlrec->blkno using HEAPBLK_TO_MAPBLOCK() before
passing it to BlockRefTableSetLimitBlock() to record the correct limit
for the VM fork.
---
 src/backend/postmaster/walsummarizer.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/src/backend/postmaster/walsummarizer.c b/src/backend/postmaster/walsummarizer.c
index 742137edad6..72c40ca7922 100644
--- a/src/backend/postmaster/walsummarizer.c
+++ b/src/backend/postmaster/walsummarizer.c
@@ -23,6 +23,7 @@
 #include "postgres.h"
 
 #include "access/timeline.h"
+#include "access/visibilitymap.h"
 #include "access/xlog.h"
 #include "access/xlog_internal.h"
 #include "access/xlogrecovery.h"
@@ -1351,7 +1352,8 @@ SummarizeSmgrRecord(XLogReaderState *xlogreader, BlockRefTable *brtab)
 									   MAIN_FORKNUM, xlrec->blkno);
 		if ((xlrec->flags & SMGR_TRUNCATE_VM) != 0)
 			BlockRefTableSetLimitBlock(brtab, &xlrec->rlocator,
-									   VISIBILITYMAP_FORKNUM, xlrec->blkno);
+									   VISIBILITYMAP_FORKNUM,
+									   HEAPBLK_TO_MAPBLOCK(xlrec->blkno));
 	}
 }
 
-- 
2.47.1

