mirror of
https://github.com/postgres/postgres.git
synced 2025-07-07 00:36:50 +03:00
Add basic infrastructure for 64 bit transaction IDs.
Instead of inferring epoch progress from xids and checkpoints, introduce a 64 bit FullTransactionId type and use it to track xid generation. This fixes an unlikely bug where the epoch is reported incorrectly if the range of active xids wraps around more than once between checkpoints. The only user-visible effect of this commit is to correct the epoch used by txid_current() and txid_status(), also visible with pg_controldata, in those rare circumstances. It also creates some basic infrastructure so that later patches can use 64 bit transaction IDs in more places. The new type is a struct that we pass by value, as a form of strong typedef. This prevents the sort of accidental confusion between TransactionId and FullTransactionId that would be possible if we were to use a plain old uint64. Author: Thomas Munro Reported-by: Amit Kapila Reviewed-by: Andres Freund, Tom Lane, Heikki Linnakangas Discussion: https://postgr.es/m/CAA4eK1%2BMv%2Bmb0HFfWM9Srtc6MVe160WFurXV68iAFMcagRZ0dQ%40mail.gmail.com
This commit is contained in:
@ -664,7 +664,6 @@ ProcArrayApplyRecoveryInfo(RunningTransactions running)
|
||||
{
|
||||
TransactionId *xids;
|
||||
int nxids;
|
||||
TransactionId nextXid;
|
||||
int i;
|
||||
|
||||
Assert(standbyState >= STANDBY_INITIALIZED);
|
||||
@ -881,23 +880,10 @@ ProcArrayApplyRecoveryInfo(RunningTransactions running)
|
||||
|
||||
LWLockRelease(ProcArrayLock);
|
||||
|
||||
/*
|
||||
* ShmemVariableCache->nextXid must be beyond any observed xid.
|
||||
*
|
||||
* We don't expect anyone else to modify nextXid, hence we don't need to
|
||||
* hold a lock while examining it. We still acquire the lock to modify
|
||||
* it, though.
|
||||
*/
|
||||
nextXid = latestObservedXid;
|
||||
TransactionIdAdvance(nextXid);
|
||||
if (TransactionIdFollows(nextXid, ShmemVariableCache->nextXid))
|
||||
{
|
||||
LWLockAcquire(XidGenLock, LW_EXCLUSIVE);
|
||||
ShmemVariableCache->nextXid = nextXid;
|
||||
LWLockRelease(XidGenLock);
|
||||
}
|
||||
/* ShmemVariableCache->nextFullXid must be beyond any observed xid. */
|
||||
AdvanceNextFullTransactionIdPastXid(latestObservedXid);
|
||||
|
||||
Assert(TransactionIdIsValid(ShmemVariableCache->nextXid));
|
||||
Assert(FullTransactionIdIsValid(ShmemVariableCache->nextFullXid));
|
||||
|
||||
KnownAssignedXidsDisplay(trace_recovery(DEBUG3));
|
||||
if (standbyState == STANDBY_SNAPSHOT_READY)
|
||||
@ -2001,7 +1987,7 @@ GetRunningTransactionData(void)
|
||||
|
||||
latestCompletedXid = ShmemVariableCache->latestCompletedXid;
|
||||
|
||||
oldestRunningXid = ShmemVariableCache->nextXid;
|
||||
oldestRunningXid = XidFromFullTransactionId(ShmemVariableCache->nextFullXid);
|
||||
|
||||
/*
|
||||
* Spin over procArray collecting all xids
|
||||
@ -2093,7 +2079,7 @@ GetRunningTransactionData(void)
|
||||
CurrentRunningXacts->xcnt = count - subcount;
|
||||
CurrentRunningXacts->subxcnt = subcount;
|
||||
CurrentRunningXacts->subxid_overflow = suboverflowed;
|
||||
CurrentRunningXacts->nextXid = ShmemVariableCache->nextXid;
|
||||
CurrentRunningXacts->nextXid = XidFromFullTransactionId(ShmemVariableCache->nextFullXid);
|
||||
CurrentRunningXacts->oldestRunningXid = oldestRunningXid;
|
||||
CurrentRunningXacts->latestCompletedXid = latestCompletedXid;
|
||||
|
||||
@ -2138,7 +2124,7 @@ GetOldestActiveTransactionId(void)
|
||||
* have already completed), when we spin over it.
|
||||
*/
|
||||
LWLockAcquire(XidGenLock, LW_SHARED);
|
||||
oldestRunningXid = ShmemVariableCache->nextXid;
|
||||
oldestRunningXid = XidFromFullTransactionId(ShmemVariableCache->nextFullXid);
|
||||
LWLockRelease(XidGenLock);
|
||||
|
||||
/*
|
||||
@ -2206,7 +2192,7 @@ GetOldestSafeDecodingTransactionId(bool catalogOnly)
|
||||
* a safe, albeit pessimal, value.
|
||||
*/
|
||||
LWLockAcquire(XidGenLock, LW_SHARED);
|
||||
oldestSafeXid = ShmemVariableCache->nextXid;
|
||||
oldestSafeXid = XidFromFullTransactionId(ShmemVariableCache->nextFullXid);
|
||||
|
||||
/*
|
||||
* If there's already a slot pegging the xmin horizon, we can start with
|
||||
@ -3266,12 +3252,10 @@ RecordKnownAssignedTransactionIds(TransactionId xid)
|
||||
*/
|
||||
latestObservedXid = xid;
|
||||
|
||||
/* ShmemVariableCache->nextXid must be beyond any observed xid */
|
||||
/* ShmemVariableCache->nextFullXid must be beyond any observed xid */
|
||||
AdvanceNextFullTransactionIdPastXid(latestObservedXid);
|
||||
next_expected_xid = latestObservedXid;
|
||||
TransactionIdAdvance(next_expected_xid);
|
||||
LWLockAcquire(XidGenLock, LW_EXCLUSIVE);
|
||||
ShmemVariableCache->nextXid = next_expected_xid;
|
||||
LWLockRelease(XidGenLock);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -867,7 +867,7 @@ standby_redo(XLogReaderState *record)
|
||||
* up from a checkpoint and are immediately at our starting point, we
|
||||
* unconditionally move to STANDBY_INITIALIZED. After this point we
|
||||
* must do 4 things:
|
||||
* * move shared nextXid forwards as we see new xids
|
||||
* * move shared nextFullXid forwards as we see new xids
|
||||
* * extend the clog and subtrans with each new xid
|
||||
* * keep track of uncommitted known assigned xids
|
||||
* * keep track of uncommitted AccessExclusiveLocks
|
||||
|
Reference in New Issue
Block a user