Skip to content

Commit 02d647b

Browse files
Don't test HEAP_XMAX_INVALID when freezing xmax.
We shouldn't ever need to rely on whether HEAP_XMAX_INVALID is set in t_infomask when considering whether or not an xmax should be deemed already frozen, since that status flag is just a hint. The only acceptable representation for an "xmax_already_frozen" raw xmax field is the transaction ID value zero (also known as InvalidTransactionId). Adjust code that superficially appeared to rely on HEAP_XMAX_INVALID to make the rule about xmax_already_frozen clear. Also avoid needlessly rereading the tuple's raw xmax. Oversight in bugfix commit d2599ec. There is no evidence that this ever led to incorrect behavior, so no backpatch. The worst consequence of this bug was that VACUUM could hypothetically fail to notice and report on certain kinds of corruption, which seems fairly benign. Author: Peter Geoghegan <pg@bowt.ie> Discussion: https://postgr.es/m/CAH2-Wzkh3DMCDRPfhZxj9xCq9v3WmzvmbiCpf1dNKUBPadhCbQ@mail.gmail.com
1 parent b425bf0 commit 02d647b

File tree

1 file changed

+5
-2
lines changed

1 file changed

+5
-2
lines changed

src/backend/access/heap/heapam.c

+5-2
Original file line numberDiff line numberDiff line change
@@ -6542,6 +6542,7 @@ heap_prepare_freeze_tuple(HeapTupleHeader tuple,
65426542

65436543
if (tuple->t_infomask & HEAP_XMAX_IS_MULTI)
65446544
{
6545+
/* Raw xmax is a MultiXactId */
65456546
TransactionId newxmax;
65466547
uint16 flags;
65476548
TransactionId mxid_oldest_xid_out = *relfrozenxid_out;
@@ -6640,6 +6641,7 @@ heap_prepare_freeze_tuple(HeapTupleHeader tuple,
66406641
}
66416642
else if (TransactionIdIsNormal(xid))
66426643
{
6644+
/* Raw xmax is normal XID */
66436645
if (TransactionIdPrecedes(xid, relfrozenxid))
66446646
ereport(ERROR,
66456647
(errcode(ERRCODE_DATA_CORRUPTED),
@@ -6670,9 +6672,10 @@ heap_prepare_freeze_tuple(HeapTupleHeader tuple,
66706672
*relfrozenxid_out = xid;
66716673
}
66726674
}
6673-
else if ((tuple->t_infomask & HEAP_XMAX_INVALID) ||
6674-
!TransactionIdIsValid(HeapTupleHeaderGetRawXmax(tuple)))
6675+
else if (!TransactionIdIsValid(xid))
66756676
{
6677+
/* Raw xmax is InvalidTransactionId XID */
6678+
Assert((tuple->t_infomask & HEAP_XMAX_IS_MULTI) == 0);
66766679
freeze_xmax = false;
66776680
xmax_already_frozen = true;
66786681
/* No need for relfrozenxid_out handling for already-frozen xmax */

0 commit comments

Comments
 (0)