From 7a66f51e4c3b352c145d83ba867b15e94ca8821e Mon Sep 17 00:00:00 2001
From: Mahendra Singh Thalor <mahi6run@gmail.com>
Date: Fri, 24 Jul 2020 10:33:35 -0700
Subject: [PATCH] Added block and offset to errors of heap_prepare_freeze_tuple
 function

---
 src/backend/access/heap/heapam.c      | 28 +++++++++++++++++++--------
 src/backend/access/heap/rewriteheap.c |  4 ++--
 src/backend/access/heap/vacuumlazy.c  |  5 ++++-
 src/include/access/heapam.h           |  3 ++-
 src/include/access/heapam_xlog.h      |  3 ++-
 5 files changed, 30 insertions(+), 13 deletions(-)

diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c
index d881f4cd46..046383851d 100644
--- a/src/backend/access/heap/heapam.c
+++ b/src/backend/access/heap/heapam.c
@@ -6097,7 +6097,8 @@ bool
 heap_prepare_freeze_tuple(HeapTupleHeader tuple,
 						  TransactionId relfrozenxid, TransactionId relminmxid,
 						  TransactionId cutoff_xid, TransactionId cutoff_multi,
-						  xl_heap_freeze_tuple *frz, bool *totally_frozen_p)
+						  xl_heap_freeze_tuple *frz, bool *totally_frozen_p,
+						  ItemPointer tid)
 {
 	bool		changed = false;
 	bool		xmax_already_frozen = false;
@@ -6126,7 +6127,9 @@ heap_prepare_freeze_tuple(HeapTupleHeader tuple,
 		if (TransactionIdPrecedes(xid, relfrozenxid))
 			ereport(ERROR,
 					(errcode(ERRCODE_DATA_CORRUPTED),
-					 errmsg_internal("found xmin %u from before relfrozenxid %u",
+					 errmsg_internal("for block %u and offnum %u, found xmin %u from before relfrozenxid %u",
+									 ItemPointerGetBlockNumber(tid),
+									 ItemPointerGetOffsetNumber(tid),
 									 xid, relfrozenxid)));
 
 		xmin_frozen = TransactionIdPrecedes(xid, cutoff_xid);
@@ -6135,7 +6138,9 @@ heap_prepare_freeze_tuple(HeapTupleHeader tuple,
 			if (!TransactionIdDidCommit(xid))
 				ereport(ERROR,
 						(errcode(ERRCODE_DATA_CORRUPTED),
-						 errmsg_internal("uncommitted xmin %u from before xid cutoff %u needs to be frozen",
+						 errmsg_internal("for block %u and offnum %u, uncommitted xmin %u from before xid cutoff %u needs to be frozen",
+										 ItemPointerGetBlockNumber(tid),
+										 ItemPointerGetOffsetNumber(tid),
 										 xid, cutoff_xid)));
 
 			frz->t_infomask |= HEAP_XMIN_FROZEN;
@@ -6207,7 +6212,9 @@ heap_prepare_freeze_tuple(HeapTupleHeader tuple,
 		if (TransactionIdPrecedes(xid, relfrozenxid))
 			ereport(ERROR,
 					(errcode(ERRCODE_DATA_CORRUPTED),
-					 errmsg_internal("found xmax %u from before relfrozenxid %u",
+					 errmsg_internal("for block %u and offnum %u, found xmax %u from before relfrozenxid %u",
+									 ItemPointerGetBlockNumber(tid),
+									 ItemPointerGetOffsetNumber(tid),
 									 xid, relfrozenxid)));
 
 		if (TransactionIdPrecedes(xid, cutoff_xid))
@@ -6222,7 +6229,9 @@ heap_prepare_freeze_tuple(HeapTupleHeader tuple,
 				TransactionIdDidCommit(xid))
 				ereport(ERROR,
 						(errcode(ERRCODE_DATA_CORRUPTED),
-						 errmsg_internal("cannot freeze committed xmax %u",
+						 errmsg_internal("for block %u and offnum %u, cannot freeze committed xmax %u",
+										 ItemPointerGetBlockNumber(tid),
+										 ItemPointerGetOffsetNumber(tid),
 										 xid)));
 			freeze_xmax = true;
 		}
@@ -6238,7 +6247,9 @@ heap_prepare_freeze_tuple(HeapTupleHeader tuple,
 	else
 		ereport(ERROR,
 				(errcode(ERRCODE_DATA_CORRUPTED),
-				 errmsg_internal("found xmax %u (infomask 0x%04x) not frozen, not multi, not normal",
+				 errmsg_internal("for block %u and offnum %u, found xmax %u (infomask 0x%04x) not frozen, not multi, not normal",
+								 ItemPointerGetBlockNumber(tid),
+								 ItemPointerGetOffsetNumber(tid),
 								 xid, tuple->t_infomask)));
 
 	if (freeze_xmax)
@@ -6346,7 +6357,8 @@ heap_execute_freeze_tuple(HeapTupleHeader tuple, xl_heap_freeze_tuple *frz)
 bool
 heap_freeze_tuple(HeapTupleHeader tuple,
 				  TransactionId relfrozenxid, TransactionId relminmxid,
-				  TransactionId cutoff_xid, TransactionId cutoff_multi)
+				  TransactionId cutoff_xid, TransactionId cutoff_multi,
+				  ItemPointer tid)
 {
 	xl_heap_freeze_tuple frz;
 	bool		do_freeze;
@@ -6355,7 +6367,7 @@ heap_freeze_tuple(HeapTupleHeader tuple,
 	do_freeze = heap_prepare_freeze_tuple(tuple,
 										  relfrozenxid, relminmxid,
 										  cutoff_xid, cutoff_multi,
-										  &frz, &tuple_totally_frozen);
+										  &frz, &tuple_totally_frozen, tid);
 
 	/*
 	 * Note that because this is not a WAL-logged operation, we don't need to
diff --git a/src/backend/access/heap/rewriteheap.c b/src/backend/access/heap/rewriteheap.c
index 39e33763df..4be3fd8190 100644
--- a/src/backend/access/heap/rewriteheap.c
+++ b/src/backend/access/heap/rewriteheap.c
@@ -364,7 +364,7 @@ rewrite_heap_tuple(RewriteState state,
 				   HeapTuple old_tuple, HeapTuple new_tuple)
 {
 	MemoryContext old_cxt;
-	ItemPointerData old_tid;
+	ItemPointerData old_tid = old_tuple->t_self;
 	TidHashKey	hashkey;
 	bool		found;
 	bool		free_new;
@@ -394,7 +394,7 @@ rewrite_heap_tuple(RewriteState state,
 					  state->rs_old_rel->rd_rel->relfrozenxid,
 					  state->rs_old_rel->rd_rel->relminmxid,
 					  state->rs_freeze_xid,
-					  state->rs_cutoff_multi);
+					  state->rs_cutoff_multi, &old_tid);
 
 	/*
 	 * Invalid ctid means that ctid should point to the tuple itself. We'll
diff --git a/src/backend/access/heap/vacuumlazy.c b/src/backend/access/heap/vacuumlazy.c
index 1bbc4598f7..03424e51dc 100644
--- a/src/backend/access/heap/vacuumlazy.c
+++ b/src/backend/access/heap/vacuumlazy.c
@@ -1262,8 +1262,10 @@ lazy_scan_heap(Relation onerel, VacuumParams *params, LVRelStats *vacrelstats,
 			 offnum = OffsetNumberNext(offnum))
 		{
 			ItemId		itemid;
+			ItemPointerData	curr_tid;
 
 			itemid = PageGetItemId(page, offnum);
+			ItemPointerSet(&curr_tid, blkno, offnum);
 
 			/* Unused items require no processing, but we count 'em */
 			if (!ItemIdIsUsed(itemid))
@@ -1456,7 +1458,8 @@ lazy_scan_heap(Relation onerel, VacuumParams *params, LVRelStats *vacrelstats,
 											  relfrozenxid, relminmxid,
 											  FreezeLimit, MultiXactCutoff,
 											  &frozen[nfrozen],
-											  &tuple_totally_frozen))
+											  &tuple_totally_frozen,
+											  &curr_tid))
 					frozen[nfrozen++].offset = offnum;
 
 				if (!tuple_totally_frozen)
diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h
index f279edc473..54c9dfa27f 100644
--- a/src/include/access/heapam.h
+++ b/src/include/access/heapam.h
@@ -157,7 +157,8 @@ extern TM_Result heap_lock_tuple(Relation relation, HeapTuple tuple,
 extern void heap_inplace_update(Relation relation, HeapTuple tuple);
 extern bool heap_freeze_tuple(HeapTupleHeader tuple,
 							  TransactionId relfrozenxid, TransactionId relminmxid,
-							  TransactionId cutoff_xid, TransactionId cutoff_multi);
+							  TransactionId cutoff_xid, TransactionId cutoff_multi,
+							  ItemPointer tid);
 extern bool heap_tuple_needs_freeze(HeapTupleHeader tuple, TransactionId cutoff_xid,
 									MultiXactId cutoff_multi, Buffer buf);
 extern bool heap_tuple_needs_eventual_freeze(HeapTupleHeader tuple);
diff --git a/src/include/access/heapam_xlog.h b/src/include/access/heapam_xlog.h
index 95d18cdb12..1ddd9501d4 100644
--- a/src/include/access/heapam_xlog.h
+++ b/src/include/access/heapam_xlog.h
@@ -411,7 +411,8 @@ extern bool heap_prepare_freeze_tuple(HeapTupleHeader tuple,
 									  TransactionId cutoff_xid,
 									  TransactionId cutoff_multi,
 									  xl_heap_freeze_tuple *frz,
-									  bool *totally_frozen);
+									  bool *totally_frozen,
+									  ItemPointer tid);
 extern void heap_execute_freeze_tuple(HeapTupleHeader tuple,
 									  xl_heap_freeze_tuple *xlrec_tp);
 extern XLogRecPtr log_heap_visible(RelFileNode rnode, Buffer heap_buffer,
-- 
2.17.1

