From dfd1737f68c8ac8aaf9bd01b60a2974fb0bf53bf Mon Sep 17 00:00:00 2001
From: Peter Geoghegan <pg@bowt.ie>
Date: Mon, 17 Apr 2023 17:53:48 -0700
Subject: [PATCH v1] Remove xl_heap_lock_updated WAL record.

---
 src/include/access/heapam_xlog.h         | 19 ++---
 src/backend/access/heap/heapam.c         | 88 ++++--------------------
 src/backend/access/rmgrdesc/heapdesc.c   | 12 ----
 src/backend/replication/logical/decode.c |  1 -
 src/tools/pgindent/typedefs.list         |  1 -
 5 files changed, 17 insertions(+), 104 deletions(-)

diff --git a/src/include/access/heapam_xlog.h b/src/include/access/heapam_xlog.h
index a03845078..20e942bc8 100644
--- a/src/include/access/heapam_xlog.h
+++ b/src/include/access/heapam_xlog.h
@@ -56,8 +56,7 @@
 #define XLOG_HEAP2_FREEZE_PAGE	0x30
 #define XLOG_HEAP2_VISIBLE		0x40
 #define XLOG_HEAP2_MULTI_INSERT 0x50
-#define XLOG_HEAP2_LOCK_UPDATED 0x60
-#define XLOG_HEAP2_NEW_CID		0x70
+#define XLOG_HEAP2_NEW_CID		0x60
 
 /*
  * xl_heap_insert/xl_heap_multi_insert flag values, 8 bits are available.
@@ -273,8 +272,9 @@ typedef struct xl_heap_vacuum
 #define XLHL_XMAX_KEYSHR_LOCK	0x08
 #define XLHL_KEYS_UPDATED		0x10
 
-/* flag bits for xl_heap_lock / xl_heap_lock_updated's flag field */
-#define XLH_LOCK_ALL_FROZEN_CLEARED		0x01
+/* flag bits for xl_heap_lock's flag field */
+#define XLH_LOCK_FROZEN_CLEARED		0x01
+#define XLH_LOCK_UPDATED			0x02
 
 /* This is what we need to know about lock */
 typedef struct xl_heap_lock
@@ -287,17 +287,6 @@ typedef struct xl_heap_lock
 
 #define SizeOfHeapLock	(offsetof(xl_heap_lock, flags) + sizeof(uint8))
 
-/* This is what we need to know about locking an updated version of a row */
-typedef struct xl_heap_lock_updated
-{
-	TransactionId xmax;
-	OffsetNumber offnum;
-	uint8		infobits_set;
-	uint8		flags;
-} xl_heap_lock_updated;
-
-#define SizeOfHeapLockUpdated	(offsetof(xl_heap_lock_updated, flags) + sizeof(uint8))
-
 /* This is what we need to know about confirmation of speculative insertion */
 typedef struct xl_heap_confirm
 {
diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c
index b300a4675..9ce834f20 100644
--- a/src/backend/access/heap/heapam.c
+++ b/src/backend/access/heap/heapam.c
@@ -2460,8 +2460,8 @@ simple_heap_insert(Relation relation, HeapTuple tup)
 
 /*
  * Given infomask/infomask2, compute the bits that must be saved in the
- * "infobits" field of xl_heap_delete, xl_heap_update, xl_heap_lock,
- * xl_heap_lock_updated WAL records.
+ * "infobits" field of xl_heap_delete, xl_heap_update, and xl_heap_lock WAL
+ * records.
  *
  * See fix_infomask_from_infobits.
  */
@@ -3570,8 +3570,7 @@ l2:
 			xlrec.xmax = xmax_lock_old_tuple;
 			xlrec.infobits_set = compute_infobits(oldtup.t_data->t_infomask,
 												  oldtup.t_data->t_infomask2);
-			xlrec.flags =
-				cleared_all_frozen ? XLH_LOCK_ALL_FROZEN_CLEARED : 0;
+			xlrec.flags = cleared_all_frozen ? XLH_LOCK_FROZEN_CLEARED : 0;
 			XLogRegisterData((char *) &xlrec, SizeOfHeapLock);
 			recptr = XLogInsert(RM_HEAP_ID, XLOG_HEAP_LOCK);
 			PageSetLSN(page, recptr);
@@ -4780,7 +4779,7 @@ failed:
 		xlrec.xmax = xid;
 		xlrec.infobits_set = compute_infobits(new_infomask,
 											  tuple->t_data->t_infomask2);
-		xlrec.flags = cleared_all_frozen ? XLH_LOCK_ALL_FROZEN_CLEARED : 0;
+		xlrec.flags = cleared_all_frozen ? XLH_LOCK_FROZEN_CLEARED : 0;
 		XLogRegisterData((char *) &xlrec, SizeOfHeapLock);
 
 		/* we don't decode row locks atm, so no need to log the origin */
@@ -5521,7 +5520,7 @@ l4:
 		/* XLOG stuff */
 		if (RelationNeedsWAL(rel))
 		{
-			xl_heap_lock_updated xlrec;
+			xl_heap_lock xlrec;
 			XLogRecPtr	recptr;
 			Page		page = BufferGetPage(buf);
 
@@ -5531,12 +5530,13 @@ l4:
 			xlrec.offnum = ItemPointerGetOffsetNumber(&mytup.t_self);
 			xlrec.xmax = new_xmax;
 			xlrec.infobits_set = compute_infobits(new_infomask, new_infomask2);
-			xlrec.flags =
-				cleared_all_frozen ? XLH_LOCK_ALL_FROZEN_CLEARED : 0;
+			xlrec.flags = XLH_LOCK_UPDATED;
+			if (cleared_all_frozen)
+				xlrec.flags |= XLH_LOCK_FROZEN_CLEARED;
 
-			XLogRegisterData((char *) &xlrec, SizeOfHeapLockUpdated);
+			XLogRegisterData((char *) &xlrec, SizeOfHeapLock);
 
-			recptr = XLogInsert(RM_HEAP2_ID, XLOG_HEAP2_LOCK_UPDATED);
+			recptr = XLogInsert(RM_HEAP_ID, XLOG_HEAP_LOCK);
 
 			PageSetLSN(page, recptr);
 		}
@@ -9801,7 +9801,7 @@ heap_xlog_lock(XLogReaderState *record)
 	 * The visibility map may need to be fixed even if the heap page is
 	 * already up-to-date.
 	 */
-	if (xlrec->flags & XLH_LOCK_ALL_FROZEN_CLEARED)
+	if (xlrec->flags & XLH_LOCK_FROZEN_CLEARED)
 	{
 		RelFileLocator rlocator;
 		Buffer		vmbuffer = InvalidBuffer;
@@ -9840,7 +9840,8 @@ heap_xlog_lock(XLogReaderState *record)
 		 * Clear relevant update flags, but only if the modified infomask says
 		 * there's no update.
 		 */
-		if (HEAP_XMAX_IS_LOCKED_ONLY(htup->t_infomask))
+		if (HEAP_XMAX_IS_LOCKED_ONLY(htup->t_infomask) &&
+			(xlrec->flags & XLH_LOCK_UPDATED) == 0)
 		{
 			HeapTupleHeaderClearHotUpdated(htup);
 			/* Make sure there is no forward chain link in t_ctid */
@@ -9857,66 +9858,6 @@ heap_xlog_lock(XLogReaderState *record)
 		UnlockReleaseBuffer(buffer);
 }
 
-static void
-heap_xlog_lock_updated(XLogReaderState *record)
-{
-	XLogRecPtr	lsn = record->EndRecPtr;
-	xl_heap_lock_updated *xlrec;
-	Buffer		buffer;
-	Page		page;
-	OffsetNumber offnum;
-	ItemId		lp = NULL;
-	HeapTupleHeader htup;
-
-	xlrec = (xl_heap_lock_updated *) XLogRecGetData(record);
-
-	/*
-	 * The visibility map may need to be fixed even if the heap page is
-	 * already up-to-date.
-	 */
-	if (xlrec->flags & XLH_LOCK_ALL_FROZEN_CLEARED)
-	{
-		RelFileLocator rlocator;
-		Buffer		vmbuffer = InvalidBuffer;
-		BlockNumber block;
-		Relation	reln;
-
-		XLogRecGetBlockTag(record, 0, &rlocator, NULL, &block);
-		reln = CreateFakeRelcacheEntry(rlocator);
-
-		visibilitymap_pin(reln, block, &vmbuffer);
-		visibilitymap_clear(reln, block, vmbuffer, VISIBILITYMAP_ALL_FROZEN);
-
-		ReleaseBuffer(vmbuffer);
-		FreeFakeRelcacheEntry(reln);
-	}
-
-	if (XLogReadBufferForRedo(record, 0, &buffer) == BLK_NEEDS_REDO)
-	{
-		page = BufferGetPage(buffer);
-
-		offnum = xlrec->offnum;
-		if (PageGetMaxOffsetNumber(page) >= offnum)
-			lp = PageGetItemId(page, offnum);
-
-		if (PageGetMaxOffsetNumber(page) < offnum || !ItemIdIsNormal(lp))
-			elog(PANIC, "invalid lp");
-
-		htup = (HeapTupleHeader) PageGetItem(page, lp);
-
-		htup->t_infomask &= ~(HEAP_XMAX_BITS | HEAP_MOVED);
-		htup->t_infomask2 &= ~HEAP_KEYS_UPDATED;
-		fix_infomask_from_infobits(xlrec->infobits_set, &htup->t_infomask,
-								   &htup->t_infomask2);
-		HeapTupleHeaderSetXmax(htup, xlrec->xmax);
-
-		PageSetLSN(page, lsn);
-		MarkBufferDirty(buffer);
-	}
-	if (BufferIsValid(buffer))
-		UnlockReleaseBuffer(buffer);
-}
-
 static void
 heap_xlog_inplace(XLogReaderState *record)
 {
@@ -10026,9 +9967,6 @@ heap2_redo(XLogReaderState *record)
 		case XLOG_HEAP2_MULTI_INSERT:
 			heap_xlog_multi_insert(record);
 			break;
-		case XLOG_HEAP2_LOCK_UPDATED:
-			heap_xlog_lock_updated(record);
-			break;
 		case XLOG_HEAP2_NEW_CID:
 
 			/*
diff --git a/src/backend/access/rmgrdesc/heapdesc.c b/src/backend/access/rmgrdesc/heapdesc.c
index 1c0fbb3e8..cfa2527cc 100644
--- a/src/backend/access/rmgrdesc/heapdesc.c
+++ b/src/backend/access/rmgrdesc/heapdesc.c
@@ -277,15 +277,6 @@ heap2_desc(StringInfo buf, XLogReaderState *record)
 					   xlrec->ntuples, &offset_elem_desc, NULL);
 		}
 	}
-	else if (info == XLOG_HEAP2_LOCK_UPDATED)
-	{
-		xl_heap_lock_updated *xlrec = (xl_heap_lock_updated *) rec;
-
-		appendStringInfo(buf, "xmax: %u, off: %u, ",
-						 xlrec->xmax, xlrec->offnum);
-		infobits_desc(buf, xlrec->infobits_set, "infobits");
-		appendStringInfo(buf, ", flags: 0x%02X", xlrec->flags);
-	}
 	else if (info == XLOG_HEAP2_NEW_CID)
 	{
 		xl_heap_new_cid *xlrec = (xl_heap_new_cid *) rec;
@@ -371,9 +362,6 @@ heap2_identify(uint8 info)
 		case XLOG_HEAP2_MULTI_INSERT | XLOG_HEAP_INIT_PAGE:
 			id = "MULTI_INSERT+INIT";
 			break;
-		case XLOG_HEAP2_LOCK_UPDATED:
-			id = "LOCK_UPDATED";
-			break;
 		case XLOG_HEAP2_NEW_CID:
 			id = "NEW_CID";
 			break;
diff --git a/src/backend/replication/logical/decode.c b/src/backend/replication/logical/decode.c
index beef399b4..59ce9c4ff 100644
--- a/src/backend/replication/logical/decode.c
+++ b/src/backend/replication/logical/decode.c
@@ -452,7 +452,6 @@ heap2_decode(LogicalDecodingContext *ctx, XLogRecordBuffer *buf)
 		case XLOG_HEAP2_PRUNE:
 		case XLOG_HEAP2_VACUUM:
 		case XLOG_HEAP2_VISIBLE:
-		case XLOG_HEAP2_LOCK_UPDATED:
 			break;
 		default:
 			elog(ERROR, "unexpected RM_HEAP2_ID record type: %u", info);
diff --git a/src/tools/pgindent/typedefs.list b/src/tools/pgindent/typedefs.list
index b4058b88c..7a872b719 100644
--- a/src/tools/pgindent/typedefs.list
+++ b/src/tools/pgindent/typedefs.list
@@ -3868,7 +3868,6 @@ xl_heap_header
 xl_heap_inplace
 xl_heap_insert
 xl_heap_lock
-xl_heap_lock_updated
 xl_heap_multi_insert
 xl_heap_new_cid
 xl_heap_prune
-- 
2.40.0

