From 338b02d02ee78904ec726fa43f0c093331c2234f Mon Sep 17 00:00:00 2001 From: Karina Litskevich Date: Tue, 28 Nov 2023 13:21:15 +0300 Subject: [PATCH v2] Fix TransactionIdInRecentPast() --- src/backend/utils/adt/xid8funcs.c | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/src/backend/utils/adt/xid8funcs.c b/src/backend/utils/adt/xid8funcs.c index 06ae940df6..f2a37b2708 100644 --- a/src/backend/utils/adt/xid8funcs.c +++ b/src/backend/utils/adt/xid8funcs.c @@ -98,11 +98,12 @@ StaticAssertDecl(MAX_BACKENDS * 2 <= PG_SNAPSHOT_MAX_NXIP, static bool TransactionIdInRecentPast(FullTransactionId fxid, TransactionId *extracted_xid) { - uint32 xid_epoch = EpochFromFullTransactionId(fxid); TransactionId xid = XidFromFullTransactionId(fxid); uint32 now_epoch; TransactionId now_epoch_next_xid; FullTransactionId now_fullxid; + TransactionId oldest_xid; + FullTransactionId oldest_fxid; now_fullxid = ReadNextFullTransactionId(); now_epoch_next_xid = XidFromFullTransactionId(now_fullxid); @@ -135,17 +136,22 @@ TransactionIdInRecentPast(FullTransactionId fxid, TransactionId *extracted_xid) Assert(LWLockHeldByMe(XactTruncationLock)); /* - * If the transaction ID has wrapped around, it's definitely too old to - * determine the commit status. Otherwise, we can compare it to - * ShmemVariableCache->oldestClogXid to determine whether the relevant - * CLOG entry is guaranteed to still exist. + * If fxid is not older than ShmemVariableCache->oldestClogXid, the relevant + * CLOG entry is guaranteed to still exist. Convert oldestClogXid into a + * full XID to compare it with fxid. Determine the right epoch knowing that + * the oldest and the newest XIDs are guaranteed to be within the XID + * wraparound distance. */ - if (xid_epoch + 1 < now_epoch - || (xid_epoch + 1 == now_epoch && xid < now_epoch_next_xid) - || TransactionIdPrecedes(xid, ShmemVariableCache->oldestClogXid)) - return false; - - return true; + oldest_xid = ShmemVariableCache->oldestClogXid; + Assert(TransactionIdPrecedesOrEquals(oldest_xid, now_epoch_next_xid)); + if (oldest_xid <= now_epoch_next_xid) + oldest_fxid = FullTransactionIdFromEpochAndXid(now_epoch, oldest_xid); + else + { + Assert(now_epoch > 0); + oldest_fxid = FullTransactionIdFromEpochAndXid(now_epoch - 1, oldest_xid); + } + return !FullTransactionIdPrecedes(fxid, oldest_fxid); } /* -- 2.34.1