Teach GetOldestXmin() about KnownAssignedXids during recovery.
authorSimon Riggs <[email protected]>
Mon, 30 Aug 2010 14:16:48 +0000 (14:16 +0000)
committerSimon Riggs <[email protected]>
Mon, 30 Aug 2010 14:16:48 +0000 (14:16 +0000)
Very minor issue, though this is required for a later patch.
Reported by Heikki Linnakangas.

src/backend/storage/ipc/procarray.c

index 239688cd9d436a4db874493e878644c2e252e06d..b2ce0b25f2a96f672558736da834e45f0fbb27b2 100644 (file)
@@ -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
  *