From 1c7bf416cf445c8f65f8d511e6054e02308fa126 Mon Sep 17 00:00:00 2001 From: Kuntal Ghosh Date: Fri, 2 Oct 2020 23:03:18 +0530 Subject: [PATCH] Fix sanity check for HOT-updated tuple when freezing tuples --- src/backend/access/heap/heapam.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index 1585861a02..127e6a84c4 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -6106,7 +6106,9 @@ FreezeMultiXactId(MultiXactId multi, uint16 t_infomask, * * It is assumed that the caller has checked the tuple with * HeapTupleSatisfiesVacuum() and determined that it is not HEAPTUPLE_DEAD - * (else we should be removing the tuple, not freezing it). + * (else we should be removing the tuple, not freezing it). But, there is an + * exception - if a tuple is HOT-updated then it must only be removed by a prune + * operation. So, we can neither remove the tuple nor freeze the tuple. * * NB: cutoff_xid *must* be <= the current global xmin, to ensure that any * XID older than it could neither be running nor seen as running by any @@ -6245,15 +6247,18 @@ heap_prepare_freeze_tuple(HeapTupleHeader tuple, * If we freeze xmax, make absolutely sure that it's not an XID * that is important. (Note, a lock-only xmax can be removed * independent of committedness, since a committed lock holder has - * released the lock). + * released the lock. Also, if the tuple is HOT-UPDATED, we can + * neither remove it nor freeze it). */ if (!HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask) && - TransactionIdDidCommit(xid)) + TransactionIdDidCommit(xid) && + !HeapTupleHeaderIsHotUpdated(tuple)) ereport(ERROR, (errcode(ERRCODE_DATA_CORRUPTED), errmsg_internal("cannot freeze committed xmax %u", xid))); - freeze_xmax = true; + + freeze_xmax = HeapTupleHeaderIsHotUpdated(tuple) ? false : true; } else freeze_xmax = false; -- 2.27.0