From 7ab02365000045605b63920ec761fee172e8c346 Mon Sep 17 00:00:00 2001 From: Simon Riggs Date: Mon, 30 Aug 2010 15:20:31 +0000 Subject: [PATCH] Teach GetOldestXmin() about KnownAssignedXids during recovery. Very minor issue, though this is required for a later patch. Reported by Heikki Linnakangas. --- src/backend/storage/ipc/procarray.c | 42 ++++++++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/src/backend/storage/ipc/procarray.c b/src/backend/storage/ipc/procarray.c index f5bb57446f..40a6e2ae58 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.72.2.1 2010/08/12 23:25:45 rhaas Exp $ + * $PostgreSQL: pgsql/src/backend/storage/ipc/procarray.c,v 1.72.2.2 2010/08/30 15:20:31 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 * -- 2.11.0