From d53bea02c9465c30c50604324ab8b59e64ccc220 Mon Sep 17 00:00:00 2001 From: Maxim Orlov Date: Thu, 28 Dec 2023 18:45:19 +0300 Subject: [PATCH v1 1/2] Switch to FullTransactionId for PGPROC->xid As a step towards 64bit xids switch to FullTransactionId for PGPROC->xid. Author: Maxim Orlov --- src/backend/access/transam/clog.c | 2 +- src/backend/access/transam/twophase.c | 6 ++++-- src/backend/access/transam/varsup.c | 4 ++-- src/backend/commands/indexcmds.c | 2 +- src/backend/storage/ipc/procarray.c | 25 +++++++++++++------------ src/backend/storage/ipc/sinvaladt.c | 2 +- src/backend/storage/lmgr/lock.c | 4 ++-- src/backend/storage/lmgr/proc.c | 4 ++-- src/include/access/transam.h | 15 ++++++++++++++- src/include/storage/proc.h | 2 +- 10 files changed, 41 insertions(+), 25 deletions(-) diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 7dca1df61b..96af8166ec 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -302,7 +302,7 @@ TransactionIdSetPageStatus(TransactionId xid, int nsubxids, * sub-XIDs and all of the XIDs for which we're adjusting clog should be * on the same page. Check those conditions, too. */ - if (all_xact_same_page && xid == MyProc->xid && + if (all_xact_same_page && xid == XidFromFullTransactionId(MyProc->xid) && nsubxids <= THRESHOLD_SUBTRANS_CLOG_OPT && nsubxids == MyProc->subxidStatus.count && (nsubxids == 0 || diff --git a/src/backend/access/transam/twophase.c b/src/backend/access/transam/twophase.c index 11e1446cd1..4e3564580f 100644 --- a/src/backend/access/transam/twophase.c +++ b/src/backend/access/transam/twophase.c @@ -234,6 +234,8 @@ static void MarkAsPreparingGuts(GlobalTransaction gxact, TransactionId xid, static void RemoveTwoPhaseFile(TransactionId xid, bool giveWarning); static void RecreateTwoPhaseFile(TransactionId xid, void *content, int len); +static inline FullTransactionId AdjustToFullTransactionId(TransactionId xid); + /* * Initialization of shared memory */ @@ -477,7 +479,7 @@ MarkAsPreparingGuts(GlobalTransaction gxact, TransactionId xid, const char *gid, proc->lxid = xid; proc->backendId = InvalidBackendId; } - proc->xid = xid; + proc->xid = AdjustToFullTransactionId(xid); Assert(proc->xmin == InvalidTransactionId); proc->delayChkptFlags = 0; proc->statusFlags = 0; @@ -793,7 +795,7 @@ pg_prepared_xact(PG_FUNCTION_ARGS) * Form tuple with appropriate data. */ - values[0] = TransactionIdGetDatum(proc->xid); + values[0] = TransactionIdGetDatum(XidFromFullTransactionId(proc->xid)); values[1] = CStringGetTextDatum(gxact->gid); values[2] = TimestampTzGetDatum(gxact->prepared_at); values[3] = ObjectIdGetDatum(gxact->owner); diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 77b18b8f28..b85fae9826 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -93,7 +93,7 @@ GetNewTransactionId(bool isSubXact) if (IsBootstrapProcessingMode()) { Assert(!isSubXact); - MyProc->xid = BootstrapTransactionId; + MyProc->xid = BootstrapFullTransactionId; ProcGlobal->xids[MyProc->pgxactoff] = BootstrapTransactionId; return FullTransactionIdFromEpochAndXid(0, BootstrapTransactionId); } @@ -255,7 +255,7 @@ GetNewTransactionId(bool isSubXact) Assert(!MyProc->subxidStatus.overflowed); /* LWLockRelease acts as barrier */ - MyProc->xid = xid; + MyProc->xid = full_xid; ProcGlobal->xids[MyProc->pgxactoff] = xid; } else diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c index e56205abd8..a070afb0a7 100644 --- a/src/backend/commands/indexcmds.c +++ b/src/backend/commands/indexcmds.c @@ -4433,7 +4433,7 @@ set_indexsafe_procflags(void) * This should only be called before installing xid or xmin in MyProc; * otherwise, concurrent processes could see an Xmin that moves backwards. */ - Assert(MyProc->xid == InvalidTransactionId && + Assert(FullTransactionIdIsInvalid(MyProc->xid) && MyProc->xmin == InvalidTransactionId); LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE); diff --git a/src/backend/storage/ipc/procarray.c b/src/backend/storage/ipc/procarray.c index 976f7856fb..ac9198ae52 100644 --- a/src/backend/storage/ipc/procarray.c +++ b/src/backend/storage/ipc/procarray.c @@ -525,7 +525,7 @@ ProcArrayAdd(PGPROC *proc) arrayP->pgprocnos[index] = proc->pgprocno; proc->pgxactoff = index; - ProcGlobal->xids[index] = proc->xid; + ProcGlobal->xids[index] = XidFromFullTransactionId(proc->xid); ProcGlobal->subxidStates[index] = proc->subxidStatus; ProcGlobal->statusFlags[index] = proc->statusFlags; @@ -674,7 +674,7 @@ ProcArrayEndTransaction(PGPROC *proc, TransactionId latestXid) * else is taking a snapshot. See discussion in * src/backend/access/transam/README. */ - Assert(TransactionIdIsValid(proc->xid)); + Assert(FullTransactionIdIsValid(proc->xid)); /* * If we can immediately acquire ProcArrayLock, we clear our own XID @@ -696,7 +696,7 @@ ProcArrayEndTransaction(PGPROC *proc, TransactionId latestXid) * anyone else's calculation of a snapshot. We might change their * estimate of global xmin, but that's OK. */ - Assert(!TransactionIdIsValid(proc->xid)); + Assert(!TransactionIdIsValid(XidFromFullTransactionId(proc->xid))); Assert(proc->subxidStatus.count == 0); Assert(!proc->subxidStatus.overflowed); @@ -738,10 +738,10 @@ ProcArrayEndTransactionInternal(PGPROC *proc, TransactionId latestXid) */ Assert(LWLockHeldByMeInMode(ProcArrayLock, LW_EXCLUSIVE)); Assert(TransactionIdIsValid(ProcGlobal->xids[pgxactoff])); - Assert(ProcGlobal->xids[pgxactoff] == proc->xid); + Assert(ProcGlobal->xids[pgxactoff] == XidFromFullTransactionId(proc->xid)); ProcGlobal->xids[pgxactoff] = InvalidTransactionId; - proc->xid = InvalidTransactionId; + proc->xid = InvalidFullTransactionId; proc->lxid = InvalidLocalTransactionId; proc->xmin = InvalidTransactionId; @@ -796,7 +796,7 @@ ProcArrayGroupClearXid(PGPROC *proc, TransactionId latestXid) uint32 wakeidx; /* We should definitely have an XID to clear. */ - Assert(TransactionIdIsValid(proc->xid)); + Assert(FullTransactionIdIsValid(proc->xid)); /* Add ourselves to the list of processes needing a group XID clear. */ proc->procArrayGroupMember = true; @@ -926,7 +926,7 @@ ProcArrayClearTransaction(PGPROC *proc) pgxactoff = proc->pgxactoff; ProcGlobal->xids[pgxactoff] = InvalidTransactionId; - proc->xid = InvalidTransactionId; + proc->xid = InvalidFullTransactionId; proc->lxid = InvalidLocalTransactionId; proc->xmin = InvalidTransactionId; @@ -1734,7 +1734,8 @@ ComputeXidHorizons(ComputeXidHorizonsResult *h) * additions. */ { - TransactionId initial; + TransactionId initial, + myproc_xid = XidFromFullTransactionId(MyProc->xid); initial = XidFromFullTransactionId(h->latest_completed); Assert(TransactionIdIsValid(initial)); @@ -1756,8 +1757,8 @@ ComputeXidHorizons(ComputeXidHorizonsResult *h) * definition, can't be any newer changes in the temp table than * latestCompletedXid. */ - if (TransactionIdIsValid(MyProc->xid)) - h->temp_oldest_nonremovable = MyProc->xid; + if (TransactionIdIsValid(myproc_xid)) + h->temp_oldest_nonremovable = myproc_xid; else h->temp_oldest_nonremovable = initial; } @@ -2222,7 +2223,7 @@ GetSnapshotData(Snapshot snapshot) latest_completed = TransamVariables->latestCompletedXid; mypgxactoff = MyProc->pgxactoff; myxid = other_xids[mypgxactoff]; - Assert(myxid == MyProc->xid); + Assert(myxid == XidFromFullTransactionId(MyProc->xid)); oldestxid = TransamVariables->oldestXid; curXactCompletionCount = TransamVariables->xactCompletionCount; @@ -3484,7 +3485,7 @@ MinimumActiveBackends(int min) continue; /* do not count deleted entries */ if (proc == MyProc) continue; /* do not count myself */ - if (proc->xid == InvalidTransactionId) + if (FullTransactionIdIsInvalid(proc->xid)) continue; /* do not count if no XID assigned */ if (proc->pid == 0) continue; /* do not count prepared xacts */ diff --git a/src/backend/storage/ipc/sinvaladt.c b/src/backend/storage/ipc/sinvaladt.c index 3d97c75bf1..3ae06bfa33 100644 --- a/src/backend/storage/ipc/sinvaladt.c +++ b/src/backend/storage/ipc/sinvaladt.c @@ -429,7 +429,7 @@ BackendIdGetTransactionIds(int backendID, TransactionId *xid, if (proc != NULL) { - *xid = proc->xid; + *xid = XidFromFullTransactionId(proc->xid); *xmin = proc->xmin; *nsubxid = proc->subxidStatus.count; *overflowed = proc->subxidStatus.overflowed; diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index b8c57b3e16..8d988a3c17 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -3981,7 +3981,7 @@ GetRunningTransactionLocks(int *nlocks) { PGPROC *proc = proclock->tag.myProc; LOCK *lock = proclock->tag.myLock; - TransactionId xid = proc->xid; + TransactionId xid = XidFromFullTransactionId(proc->xid); /* * Don't record locks for transactions if we know they have @@ -4601,7 +4601,7 @@ VirtualXactLock(VirtualTransactionId vxid, bool wait) * so we won't save an XID of a different VXID. It doesn't matter whether * we save this before or after setting up the primary lock table entry. */ - xid = proc->xid; + xid = XidFromFullTransactionId(proc->xid); /* Done with proc->fpLockBits */ LWLockRelease(&proc->fpInfoLock); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index b6451d9d08..e6e06d277b 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -377,7 +377,7 @@ InitProcess(void) MyProc->lxid = InvalidLocalTransactionId; MyProc->fpVXIDLock = false; MyProc->fpLocalTransactionId = InvalidLocalTransactionId; - MyProc->xid = InvalidTransactionId; + MyProc->xid = InvalidFullTransactionId; MyProc->xmin = InvalidTransactionId; MyProc->pid = MyProcPid; /* backendId, databaseId and roleId will be filled in later */ @@ -574,7 +574,7 @@ InitAuxiliaryProcess(void) MyProc->lxid = InvalidLocalTransactionId; MyProc->fpVXIDLock = false; MyProc->fpLocalTransactionId = InvalidLocalTransactionId; - MyProc->xid = InvalidTransactionId; + MyProc->xid = InvalidFullTransactionId; MyProc->xmin = InvalidTransactionId; MyProc->backendId = InvalidBackendId; MyProc->databaseId = InvalidOid; diff --git a/src/include/access/transam.h b/src/include/access/transam.h index eef2b2cdbe..2ed3040959 100644 --- a/src/include/access/transam.h +++ b/src/include/access/transam.h @@ -52,8 +52,8 @@ #define FullTransactionIdPrecedesOrEquals(a, b) ((a).value <= (b).value) #define FullTransactionIdFollows(a, b) ((a).value > (b).value) #define FullTransactionIdFollowsOrEquals(a, b) ((a).value >= (b).value) -#define FullTransactionIdIsValid(x) TransactionIdIsValid(XidFromFullTransactionId(x)) #define InvalidFullTransactionId FullTransactionIdFromEpochAndXid(0, InvalidTransactionId) +#define BootstrapFullTransactionId FullTransactionIdFromEpochAndXid(0, BootstrapTransactionId) #define FirstNormalFullTransactionId FullTransactionIdFromEpochAndXid(0, FirstNormalTransactionId) #define FullTransactionIdIsNormal(x) FullTransactionIdFollowsOrEquals(x, FirstNormalFullTransactionId) @@ -67,6 +67,19 @@ typedef struct FullTransactionId uint64 value; } FullTransactionId; +static inline bool +FullTransactionIdIsValid(FullTransactionId fxid) +{ + /* XXX: why without epoch? Should it be fxid.value == InvalidTransactionId? */ + return TransactionIdIsValid(XidFromFullTransactionId(fxid)); +} + +static inline bool +FullTransactionIdIsInvalid(FullTransactionId fxid) +{ + return !FullTransactionIdIsValid(fxid); +} + static inline FullTransactionId FullTransactionIdFromEpochAndXid(uint32 epoch, TransactionId xid) { diff --git a/src/include/storage/proc.h b/src/include/storage/proc.h index e87fd25d64..bc40bae6d5 100644 --- a/src/include/storage/proc.h +++ b/src/include/storage/proc.h @@ -176,7 +176,7 @@ struct PGPROC Latch procLatch; /* generic latch for process */ - TransactionId xid; /* id of top-level transaction currently being + FullTransactionId xid; /* id of top-level transaction currently being * executed by this proc, if running and XID * is assigned; else InvalidTransactionId. * mirrored in ProcGlobal->xids[pgxactoff] */ -- 2.42.0