Skip to content

Commit eb5ad4f

Browse files
Check that xmax didn't commit in freeze check.
We cannot rely on TransactionIdDidAbort here, since in general it may report transactions that were in-progress at the time of an earlier hard crash as not aborted, effectively behaving as if they were still in progress even after crash recovery completes. Go back to defensively verifying that xmax didn't commit instead. Oversight in commit 79d4bf4. Author: Peter Geoghegan <pg@bowt.ie> Reported-By: Andres Freund <andres@anarazel.de> Discussion: https://postgr.es/m/20230104035636.hy5djyr2as4gbc4q@awork3.anarazel.de
1 parent 5212d44 commit eb5ad4f

File tree

1 file changed

+10
-4
lines changed

1 file changed

+10
-4
lines changed

src/backend/access/heap/heapam.c

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6208,10 +6208,10 @@ FreezeMultiXactId(MultiXactId multi, uint16 t_infomask,
62086208
* been pruned away instead, since updater XID is < OldestXmin).
62096209
* Just remove xmax.
62106210
*/
6211-
if (!TransactionIdDidAbort(update_xact))
6211+
if (TransactionIdDidCommit(update_xact))
62126212
ereport(ERROR,
62136213
(errcode(ERRCODE_DATA_CORRUPTED),
6214-
errmsg_internal("multixact %u contains non-aborted update XID %u from before removable cutoff %u",
6214+
errmsg_internal("multixact %u contains committed update XID %u from before removable cutoff %u",
62156215
multi, update_xact,
62166216
cutoffs->OldestXmin)));
62176217
*flags |= FRM_INVALIDATE_XMAX;
@@ -6825,15 +6825,21 @@ heap_freeze_execute_prepared(Relation rel, Buffer buffer,
68256825
errmsg_internal("uncommitted xmin %u needs to be frozen",
68266826
xmin)));
68276827
}
6828+
6829+
/*
6830+
* TransactionIdDidAbort won't work reliably in the presence of XIDs
6831+
* left behind by transactions that were in progress during a crash,
6832+
* so we can only check that xmax didn't commit
6833+
*/
68286834
if (frz->checkflags & HEAP_FREEZE_CHECK_XMAX_ABORTED)
68296835
{
68306836
TransactionId xmax = HeapTupleHeaderGetRawXmax(htup);
68316837

68326838
Assert(TransactionIdIsNormal(xmax));
6833-
if (unlikely(!TransactionIdDidAbort(xmax)))
6839+
if (unlikely(TransactionIdDidCommit(xmax)))
68346840
ereport(ERROR,
68356841
(errcode(ERRCODE_DATA_CORRUPTED),
6836-
errmsg_internal("cannot freeze non-aborted xmax %u",
6842+
errmsg_internal("cannot freeze committed xmax %u",
68376843
xmax)));
68386844
}
68396845
}

0 commit comments

Comments
 (0)