From d774b80288042d9a31cbc6477c2f0151f1c9dc2e Mon Sep 17 00:00:00 2001
From: Melanie Plageman <melanieplageman@gmail.com>
Date: Wed, 17 Sep 2025 18:11:49 -0400
Subject: [PATCH v14 11/24] Log setting empty pages PD_ALL_VISIBLE with
 XLOG_HEAP2_VACUUM_SCAN

Though not a big win for this particular case, if we use the
XLOG_HEAP2_VACUUM_SCAN record to log setting PD_ALL_VISIBLE on the heap
page we can omit the heap page from the WAL chain when setting the
visibility map. A follow-on commit will actually remove the heap page
from the VM set WAL chain.
---
 src/backend/access/heap/vacuumlazy.c | 43 +++++++++++++++++++---------
 1 file changed, 29 insertions(+), 14 deletions(-)

diff --git a/src/backend/access/heap/vacuumlazy.c b/src/backend/access/heap/vacuumlazy.c
index 9bfcd67a61b..c016f8f7c25 100644
--- a/src/backend/access/heap/vacuumlazy.c
+++ b/src/backend/access/heap/vacuumlazy.c
@@ -1879,23 +1879,38 @@ lazy_scan_new_or_empty(LVRelState *vacrel, Buffer buf, BlockNumber blkno,
 		{
 			START_CRIT_SECTION();
 
-			/* mark buffer dirty before writing a WAL record */
+			PageSetAllVisible(page);
 			MarkBufferDirty(buf);
 
-			/*
-			 * It's possible that another backend has extended the heap,
-			 * initialized the page, and then failed to WAL-log the page due
-			 * to an ERROR.  Since heap extension is not WAL-logged, recovery
-			 * might try to replay our record setting the page all-visible and
-			 * find that the page isn't initialized, which will cause a PANIC.
-			 * To prevent that, check whether the page has been previously
-			 * WAL-logged, and if not, do that now.
-			 */
-			if (RelationNeedsWAL(vacrel->rel) &&
-				PageGetLSN(page) == InvalidXLogRecPtr)
-				log_newpage_buffer(buf, true);
+			if (RelationNeedsWAL(vacrel->rel))
+			{
+				/*
+				 * It's possible that another backend has extended the heap,
+				 * initialized the page, and then failed to WAL-log the page
+				 * due to an ERROR.  Since heap extension is not WAL-logged,
+				 * recovery might try to replay our record setting the page
+				 * all-visible and find that the page isn't initialized, which
+				 * will cause a PANIC. To prevent that, check whether the page
+				 * has been previously WAL-logged, and if not, do that now.
+				 *
+				 * Otherwise, just emit WAL for setting PD_ALL_VISIBLE on the
+				 * heap page. Doing this in a separate record from setting the
+				 * VM allows us to omit the heap page from the VM WAL chain.
+				 */
+				if (PageGetLSN(page) == InvalidXLogRecPtr)
+					log_newpage_buffer(buf, true);
+				else
+					log_heap_prune_and_freeze(vacrel->rel, buf,
+											  InvalidTransactionId, /* conflict xid */
+											  false,	/* cleanup lock */
+											  true, /* set_pd_all_vis */
+											  PRUNE_VACUUM_SCAN,	/* reason */
+											  NULL, 0,
+											  NULL, 0,
+											  NULL, 0,
+											  NULL, 0);
+			}
 
-			PageSetAllVisible(page);
 			visibilitymap_set(vacrel->rel, blkno, buf,
 							  InvalidXLogRecPtr,
 							  vmbuffer, InvalidTransactionId,
-- 
2.43.0

