mirror of
https://github.com/postgres/postgres.git
synced 2025-07-30 11:03:19 +03:00
Derive oldestActiveXid at correct time for Hot Standby.
There was a timing window between when oldestActiveXid was derived and when it should have been derived that only shows itself under heavy load. Move code around to ensure correct timing of derivation. No change to StartupSUBTRANS() code, which is where this failed. Bug report by Chris Redekop
This commit is contained in:
@ -1620,6 +1620,63 @@ GetRunningTransactionData(void)
|
||||
return CurrentRunningXacts;
|
||||
}
|
||||
|
||||
/*
|
||||
* GetOldestActiveTransactionId()
|
||||
*
|
||||
* Similar to GetSnapshotData but returns just oldestActiveXid. We include
|
||||
* all PGPROCs with an assigned TransactionId, even VACUUM processes.
|
||||
* We look at all databases, though there is no need to include WALSender
|
||||
* since this has no effect on hot standby conflicts.
|
||||
*
|
||||
* This is never executed during recovery so there is no need to look at
|
||||
* KnownAssignedXids.
|
||||
*
|
||||
* We don't worry about updating other counters, we want to keep this as
|
||||
* simple as possible and leave GetSnapshotData() as the primary code for
|
||||
* that bookkeeping.
|
||||
*/
|
||||
TransactionId
|
||||
GetOldestActiveTransactionId(void)
|
||||
{
|
||||
ProcArrayStruct *arrayP = procArray;
|
||||
TransactionId oldestRunningXid;
|
||||
int index;
|
||||
|
||||
Assert(!RecoveryInProgress());
|
||||
|
||||
LWLockAcquire(ProcArrayLock, LW_SHARED);
|
||||
|
||||
oldestRunningXid = ShmemVariableCache->nextXid;
|
||||
|
||||
/*
|
||||
* Spin over procArray collecting all xids and subxids.
|
||||
*/
|
||||
for (index = 0; index < arrayP->numProcs; index++)
|
||||
{
|
||||
volatile PGPROC *proc = arrayP->procs[index];
|
||||
TransactionId xid;
|
||||
|
||||
/* Fetch xid just once - see GetNewTransactionId */
|
||||
xid = proc->xid;
|
||||
|
||||
if (!TransactionIdIsNormal(xid))
|
||||
continue;
|
||||
|
||||
if (TransactionIdPrecedes(xid, oldestRunningXid))
|
||||
oldestRunningXid = xid;
|
||||
|
||||
/*
|
||||
* Top-level XID of a transaction is always less than any of its
|
||||
* subxids, so we don't need to check if any of the subxids are
|
||||
* smaller than oldestRunningXid
|
||||
*/
|
||||
}
|
||||
|
||||
LWLockRelease(ProcArrayLock);
|
||||
|
||||
return oldestRunningXid;
|
||||
}
|
||||
|
||||
/*
|
||||
* GetTransactionsInCommit -- Get the XIDs of transactions that are committing
|
||||
*
|
||||
|
@ -815,7 +815,7 @@ standby_desc(StringInfo buf, uint8 xl_info, char *rec)
|
||||
* making WAL entries.
|
||||
*/
|
||||
void
|
||||
LogStandbySnapshot(TransactionId *oldestActiveXid, TransactionId *nextXid)
|
||||
LogStandbySnapshot(TransactionId *nextXid)
|
||||
{
|
||||
RunningTransactions running;
|
||||
xl_standby_lock *locks;
|
||||
@ -845,7 +845,6 @@ LogStandbySnapshot(TransactionId *oldestActiveXid, TransactionId *nextXid)
|
||||
/* GetRunningTransactionData() acquired XidGenLock, we must release it */
|
||||
LWLockRelease(XidGenLock);
|
||||
|
||||
*oldestActiveXid = running->oldestRunningXid;
|
||||
*nextXid = running->nextXid;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user