diff --git a/src/backend/storage/ipc/procarray.c b/src/backend/storage/ipc/procarray.c index 239688cd9d..b2ce0b25f2 100644 --- a/src/backend/storage/ipc/procarray.c +++ b/src/backend/storage/ipc/procarray.c @@ -37,7 +37,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/storage/ipc/procarray.c,v 1.73 2010/08/12 23:24:54 rhaas Exp $ + * $PostgreSQL: pgsql/src/backend/storage/ipc/procarray.c,v 1.74 2010/08/30 14:16:48 sriggs Exp $ * *------------------------------------------------------------------------- */ @@ -156,6 +156,7 @@ static int KnownAssignedXidsGet(TransactionId *xarray, TransactionId xmax); static int KnownAssignedXidsGetAndSetXmin(TransactionId *xarray, TransactionId *xmin, TransactionId xmax); +static int KnownAssignedXidsGetOldestXmin(void); static void KnownAssignedXidsDisplay(int trace_level); /* @@ -1112,6 +1113,18 @@ GetOldestXmin(bool allDbs, bool ignoreVacuum) } } + if (RecoveryInProgress()) + { + /* + * Check to see whether KnownAssignedXids contains an xid value + * older than the main procarray. + */ + TransactionId kaxmin = KnownAssignedXidsGetOldestXmin(); + if (TransactionIdIsNormal(kaxmin) && + TransactionIdPrecedes(kaxmin, result)) + result = kaxmin; + } + LWLockRelease(ProcArrayLock); /* @@ -3015,6 +3028,33 @@ KnownAssignedXidsGetAndSetXmin(TransactionId *xarray, TransactionId *xmin, return count; } +static int +KnownAssignedXidsGetOldestXmin(void) +{ + /* use volatile pointer to prevent code rearrangement */ + volatile ProcArrayStruct *pArray = procArray; + int head, + tail; + int i; + + /* + * Fetch head just once, since it may change while we loop. + */ + SpinLockAcquire(&pArray->known_assigned_xids_lck); + tail = pArray->tailKnownAssignedXids; + head = pArray->headKnownAssignedXids; + SpinLockRelease(&pArray->known_assigned_xids_lck); + + for (i = tail; i < head; i++) + { + /* Skip any gaps in the array */ + if (KnownAssignedXidsValid[i]) + return KnownAssignedXids[i]; + } + + return InvalidTransactionId; +} + /* * Display KnownAssignedXids to provide debug trail *