On Mon, 2025-11-17 at 12:34 +1100, Peter Smith wrote:
> Here are the latest patches.
> 
> Changes include:
> 
> PATCH 0002.
> - Address a new compiler warning reported by CI
> 
Hello Peter!
Thanks for updating the patch!
According to the issue I've found recently with incorrect WAL record
[1], I've prepared a patch that replaces manual XLog...() calls by a
call to log_heap_prune_and_freeze() in a way similar to what
freezeWos() and lazy_vacuum_heap_page() do. This fixes reproducer
scenario on my machine.

[1]
https://www.postgresql.org/message-id/36cedffdfcac437afd692442cf9c1d16d7f28b01.camel%40postgrespro.ru

-- 
Regards,
Timur Magomedov

From ac16dada189fe2a07061b746f57a2767ef315919 Mon Sep 17 00:00:00 2001
From: Timur Magomedov <[email protected]>
Date: Mon, 17 Nov 2025 17:04:33 +0300
Subject: [PATCH] Fixed WAL record in cleanUpWos()

Use log_heap_prune_and_freeze() like in
freezeWos() and lazy_vacuum_heap_page().
---
 contrib/vci/storage/vci_ros_command.c | 60 +++++++++++++--------------
 1 file changed, 28 insertions(+), 32 deletions(-)

diff --git a/contrib/vci/storage/vci_ros_command.c b/contrib/vci/storage/vci_ros_command.c
index fc706b8b1e5..34f3dc458b4 100644
--- a/contrib/vci/storage/vci_ros_command.c
+++ b/contrib/vci/storage/vci_ros_command.c
@@ -25,7 +25,6 @@
 #include "access/genam.h"
 #include "access/visibilitymap.h"	/* for visibilitymap_set() */
 #include "access/xact.h"
-#include "access/xloginsert.h"
 #include "access/tableam.h"
 #include "catalog/index.h"
 #include "catalog/pg_operator.h"	/* for TIDLessOperator */
@@ -1560,7 +1559,7 @@ cleanUpWos(vci_RosCommandContext *comContext, vci_MainRelVar wosType)
 		OffsetNumber maxoff;
 
 		OffsetNumber unused[MaxOffsetNumber];
-		int			uncnt = 0;
+		int			nunused = 0;
 		bool		is_visible_page = true;
 
 		/* Get a buffer containing the target block. */
@@ -1640,8 +1639,8 @@ cleanUpWos(vci_RosCommandContext *comContext, vci_MainRelVar wosType)
 		visibilitymap_pin(rel, blkno, &vmbuffer);
 
 		/*
-		 * this routine is copied from lazy_vacuum_heap() &
-		 * lazy_vacuum_page(),
+		 * this routine is copied from lazy_vacuum_heap_rel() &
+		 * lazy_vacuum_heap_page(),
 		 */
 		/* and modified */
 
@@ -1663,16 +1662,21 @@ cleanUpWos(vci_RosCommandContext *comContext, vci_MainRelVar wosType)
 			itemid = PageGetItemId(page, toff);
 			if (!ItemIdHasStorage(itemid))
 				continue;
+			if (!ItemIdIsDead(itemid))
+				continue;
 
 			htup = (HeapTupleHeader) PageGetItem(page, itemid);
 			dead_tuples[tupindex] = *(ItemPointer) ((char *) htup + htup->t_hoff);
 
+			Assert(ItemIdIsDead(itemid) && !ItemIdHasStorage(itemid));
 			ItemIdSetUnused(itemid);
-
-			unused[uncnt++] = toff;
+			unused[nunused++] = toff;
 		}
 
-		PageRepairFragmentation(page);
+		/* Attempt to truncate line pointer array now */
+		if (nunused > 0)
+			PageTruncateLinePointerArray(page);
+
 
 		/* Mark buffer dirty before we write WAL. */
 		MarkBufferDirty(buffer);
@@ -1702,32 +1706,24 @@ cleanUpWos(vci_RosCommandContext *comContext, vci_MainRelVar wosType)
 		}
 
 		/* XLOG stuff */
-		if (RelationNeedsWAL(rel))
+		if (nunused > 0 && RelationNeedsWAL(rel))
 		{
-			xl_heap_prune xlrec;
-			XLogRecPtr	recptr;
-
-			xlrec.flags = 0;
-
-			XLogBeginInsert();
-
-			XLogRegisterBuffer(0, buffer, REGBUF_STANDARD);
-
-			if (uncnt > 0)
-				XLogRegisterBufData(0, unused,
-									uncnt * sizeof(OffsetNumber));
-			if (RelationIsAccessibleInLogicalDecoding(rel))
-				xlrec.flags |= XLHP_IS_CATALOG_REL;
-			if (TransactionIdIsValid(snapshotConflictHorizon))
-				xlrec.flags |= XLHP_HAS_CONFLICT_HORIZON;
-
-			XLogRegisterData(&xlrec, SizeOfHeapPrune);
-			if (TransactionIdIsValid(snapshotConflictHorizon))
-				XLogRegisterData(&snapshotConflictHorizon, sizeof(TransactionId));
-
-			recptr = XLogInsert(RM_HEAP2_ID, XLOG_HEAP2_PRUNE_ON_ACCESS);
-
-			PageSetLSN(page, recptr);
+			/*
+			 * Commit add323d added the vmbuffer/vmflags parameters.
+			 * A quick fix was needed to allow build to proceed.
+			 *
+			 * TODO Confirm if passing InvalidBuffer, 0 is OK here.
+			 */
+			log_heap_prune_and_freeze(rel, buffer,
+									  InvalidBuffer, /* vmbuffer */
+									  0,			 /* vmflags */
+									  snapshotConflictHorizon,
+									  false,	/* no cleanup lock required */
+									  PRUNE_ON_ACCESS,
+									  NULL, 0,	/* frozen */
+									  NULL, 0,	/* redirected */
+									  NULL, 0,	/* dead */
+									  unused, nunused);
 		}
 
 		END_CRIT_SECTION();
-- 
2.43.0

Reply via email to