mirror of
https://github.com/postgres/postgres.git
synced 2025-07-28 23:42:10 +03:00
Track latest completed xid as a FullTransactionId.
The reason for doing so is that a subsequent commit will need that to avoid wraparound issues. As the subsequent change is large this was split out for easier review. The reason this is not a perfect straight-forward change is that we do not want track 64bit xids in the procarray or the WAL. Therefore we need to advance lastestCompletedXid in relation to 32 bit xids. The code for that is now centralized in MaintainLatestCompletedXid*. Author: Andres Freund Reviewed-By: Thomas Munro, Robert Haas, David Rowley Discussion: https://postgr.es/m/20200301083601.ews6hz5dduc3w2se@alap3.anarazel.de
This commit is contained in:
@ -569,3 +569,53 @@ GetNewObjectId(void)
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
#ifdef USE_ASSERT_CHECKING
|
||||
|
||||
/*
|
||||
* Assert that xid is between [oldestXid, nextXid], which is the range we
|
||||
* expect XIDs coming from tables etc to be in.
|
||||
*
|
||||
* As ShmemVariableCache->oldestXid could change just after this call without
|
||||
* further precautions, and as a wrapped-around xid could again fall within
|
||||
* the valid range, this assertion can only detect if something is definitely
|
||||
* wrong, but not establish correctness.
|
||||
*
|
||||
* This intentionally does not expose a return value, to avoid code being
|
||||
* introduced that depends on the return value.
|
||||
*/
|
||||
void
|
||||
AssertTransactionIdInAllowableRange(TransactionId xid)
|
||||
{
|
||||
TransactionId oldest_xid;
|
||||
TransactionId next_xid;
|
||||
|
||||
Assert(TransactionIdIsValid(xid));
|
||||
|
||||
/* we may see bootstrap / frozen */
|
||||
if (!TransactionIdIsNormal(xid))
|
||||
return;
|
||||
|
||||
/*
|
||||
* We can't acquire XidGenLock, as this may be called with XidGenLock
|
||||
* already held (or with other locks that don't allow XidGenLock to be
|
||||
* nested). That's ok for our purposes though, since we already rely on
|
||||
* 32bit reads to be atomic. While nextXid is 64 bit, we only look at
|
||||
* the lower 32bit, so a skewed read doesn't hurt.
|
||||
*
|
||||
* There's no increased danger of falling outside [oldest, next] by
|
||||
* accessing them without a lock. xid needs to have been created with
|
||||
* GetNewTransactionId() in the originating session, and the locks there
|
||||
* pair with the memory barrier below. We do however accept xid to be <=
|
||||
* to next_xid, instead of just <, as xid could be from the procarray,
|
||||
* before we see the updated nextXid value.
|
||||
*/
|
||||
pg_memory_barrier();
|
||||
oldest_xid = ShmemVariableCache->oldestXid;
|
||||
next_xid = XidFromFullTransactionId(ShmemVariableCache->nextXid);
|
||||
|
||||
Assert(TransactionIdFollowsOrEquals(xid, oldest_xid) ||
|
||||
TransactionIdPrecedesOrEquals(xid, next_xid));
|
||||
}
|
||||
#endif
|
||||
|
@ -7865,8 +7865,8 @@ StartupXLOG(void)
|
||||
|
||||
/* also initialize latestCompletedXid, to nextXid - 1 */
|
||||
LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
|
||||
ShmemVariableCache->latestCompletedXid = XidFromFullTransactionId(ShmemVariableCache->nextXid);
|
||||
TransactionIdRetreat(ShmemVariableCache->latestCompletedXid);
|
||||
ShmemVariableCache->latestCompletedXid = ShmemVariableCache->nextXid;
|
||||
FullTransactionIdRetreat(&ShmemVariableCache->latestCompletedXid);
|
||||
LWLockRelease(ProcArrayLock);
|
||||
|
||||
/*
|
||||
|
Reference in New Issue
Block a user