From b0242b98434d61bcaff239a5731f3d1e65f310f6 Mon Sep 17 00:00:00 2001
From: Melanie Plageman <melanieplageman@gmail.com>
Date: Wed, 17 Sep 2025 16:04:18 -0400
Subject: [PATCH v15 14/23] Set empty pages all-visible in
 XLOG_HEAP2_PRUNE_VACUUM_SCAN record

As part of a project to eliminate XLOG_HEAP2_VISIBLE records, eliminate
their usage in phase I vacuum of empty pages.
---
 src/backend/access/heap/vacuumlazy.c | 56 +++++++++++++++++-----------
 1 file changed, 35 insertions(+), 21 deletions(-)

diff --git a/src/backend/access/heap/vacuumlazy.c b/src/backend/access/heap/vacuumlazy.c
index 539e5267574..e8721761392 100644
--- a/src/backend/access/heap/vacuumlazy.c
+++ b/src/backend/access/heap/vacuumlazy.c
@@ -1882,11 +1882,22 @@ lazy_scan_new_or_empty(LVRelState *vacrel, Buffer buf, BlockNumber blkno,
 		 */
 		if (!PageIsAllVisible(page))
 		{
+			bool		set_pd_all_vis = true;
+
+			/* Lock vmbuffer before entering critical section */
+			LockBuffer(vmbuffer, BUFFER_LOCK_EXCLUSIVE);
+
 			START_CRIT_SECTION();
 
 			PageSetAllVisible(page);
 			MarkBufferDirty(buf);
 
+			visibilitymap_set_vmbits(blkno,
+									 vmbuffer,
+									 VISIBILITYMAP_ALL_VISIBLE |
+									 VISIBILITYMAP_ALL_FROZEN,
+									 RelationGetRelationName(vacrel->rel));
+
 			if (RelationNeedsWAL(vacrel->rel))
 			{
 				/*
@@ -1897,34 +1908,37 @@ lazy_scan_new_or_empty(LVRelState *vacrel, Buffer buf, BlockNumber blkno,
 				 * 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,
-											  InvalidBuffer,
-											  0,
-											  InvalidTransactionId, /* conflict xid */
-											  false,	/* cleanup lock */
-											  true, /* set_pd_all_vis */
-											  PRUNE_VACUUM_SCAN,	/* reason */
-											  NULL, 0,
-											  NULL, 0,
-											  NULL, 0,
-											  NULL, 0);
+					set_pd_all_vis = false;
+				}
+
+				/*
+				 * Emit WAL for setting PD_ALL_VISIBLE on the heap page and
+				 * setting the VM. If we emitted a new page record for the
+				 * page above, setting PD_ALL_VISIBLE will already have been
+				 * included in that record.
+				 */
+				log_heap_prune_and_freeze(vacrel->rel, buf,
+										  vmbuffer,
+										  VISIBILITYMAP_ALL_VISIBLE |
+										  VISIBILITYMAP_ALL_FROZEN,
+										  InvalidTransactionId, /* conflict xid */
+										  false,	/* cleanup lock */
+										  set_pd_all_vis,
+										  PRUNE_VACUUM_SCAN,	/* reason */
+										  NULL, 0,
+										  NULL, 0,
+										  NULL, 0,
+										  NULL, 0);
 			}
 
-			visibilitymap_set(vacrel->rel, blkno,
-							  InvalidXLogRecPtr,
-							  vmbuffer, InvalidTransactionId,
-							  VISIBILITYMAP_ALL_VISIBLE |
-							  VISIBILITYMAP_ALL_FROZEN);
 			END_CRIT_SECTION();
 
+			LockBuffer(vmbuffer, BUFFER_LOCK_UNLOCK);
+
 			/* Count the newly all-frozen pages for logging */
 			vacrel->vm_new_visible_pages++;
 			vacrel->vm_new_visible_frozen_pages++;
-- 
2.43.0

