]> granicus.if.org Git - postgresql/commitdiff
Tune GetSnapshotData() during Hot Standby by avoiding loop
authorSimon Riggs <simon@2ndQuadrant.com>
Sun, 18 Apr 2010 18:06:07 +0000 (18:06 +0000)
committerSimon Riggs <simon@2ndQuadrant.com>
Sun, 18 Apr 2010 18:06:07 +0000 (18:06 +0000)
through normal backends. Makes code clearer also, since we
avoid various Assert()s. Performance of snapshots taken
during recovery no longer depends upon number of read-only
backends.

src/backend/access/transam/xlog.c
src/backend/storage/ipc/procarray.c
src/include/access/xlog.h

index 9b6cd5253cd97759296e75452d14192c94c273b9..1cd5df5e7a08f205006c4d9acae48e2ef3f4d0e5 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.397 2010/04/16 08:58:16 heikki Exp $
+ * $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.398 2010/04/18 18:05:51 sriggs Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -6454,6 +6454,12 @@ CheckRecoveryConsistency(void)
        }
 }
 
+bool
+XLogConsistentState(void)
+{
+       return reachedMinRecoveryPoint;
+}
+
 /*
  * Is the system still in recovery?
  *
index ac85d2fc29870bd6ad4c322f44f4305b2888711e..c79f25ecf101b71bdad8dbdeb6b68c2b8fba6993 100644 (file)
@@ -37,7 +37,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/storage/ipc/procarray.c,v 1.62 2010/04/06 10:50:57 sriggs Exp $
+ *       $PostgreSQL: pgsql/src/backend/storage/ipc/procarray.c,v 1.63 2010/04/18 18:05:55 sriggs Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1091,89 +1091,90 @@ GetSnapshotData(Snapshot snapshot)
        globalxmin = xmin = xmax;
 
        /*
-        * Spin over procArray checking xid, xmin, and subxids.  The goal is to
-        * gather all active xids, find the lowest xmin, and try to record
-        * subxids.
+        * If in recovery get any known assigned xids.
         */
-       for (index = 0; index < arrayP->numProcs; index++)
+       if (!snapshot->takenDuringRecovery)
        {
-               volatile PGPROC *proc = arrayP->procs[index];
-               TransactionId xid;
-
-               /* Ignore procs running LAZY VACUUM */
-               if (proc->vacuumFlags & PROC_IN_VACUUM)
-                       continue;
-
-               /* Update globalxmin to be the smallest valid xmin */
-               xid = proc->xmin;               /* fetch just once */
-               if (TransactionIdIsNormal(xid) &&
-                       TransactionIdPrecedes(xid, globalxmin))
-                       globalxmin = xid;
-
-               /* Fetch xid just once - see GetNewTransactionId */
-               xid = proc->xid;
-
                /*
-                * If the transaction has been assigned an xid < xmax we add it to the
-                * snapshot, and update xmin if necessary.      There's no need to store
-                * XIDs >= xmax, since we'll treat them as running anyway.  We don't
-                * bother to examine their subxids either.
-                *
-                * We don't include our own XID (if any) in the snapshot, but we must
-                * include it into xmin.
+                * Spin over procArray checking xid, xmin, and subxids.  The goal is to
+                * gather all active xids, find the lowest xmin, and try to record
+                * subxids. During recovery no xids will be assigned, so all normal
+                * backends can be ignored, nor are there any VACUUMs running. All
+                * prepared transaction xids are held in KnownAssignedXids, so these
+                * will be seen without needing to loop through procs here.
                 */
-               if (TransactionIdIsNormal(xid))
+               for (index = 0; index < arrayP->numProcs; index++)
                {
-                       Assert(!snapshot->takenDuringRecovery);
-                       if (TransactionIdFollowsOrEquals(xid, xmax))
+                       volatile PGPROC *proc = arrayP->procs[index];
+                       TransactionId xid;
+
+                       /* Ignore procs running LAZY VACUUM */
+                       if (proc->vacuumFlags & PROC_IN_VACUUM)
                                continue;
-                       if (proc != MyProc)
-                               snapshot->xip[count++] = xid;
-                       if (TransactionIdPrecedes(xid, xmin))
-                               xmin = xid;
-               }
 
-               /*
-                * Save subtransaction XIDs if possible (if we've already overflowed,
-                * there's no point).  Note that the subxact XIDs must be later than
-                * their parent, so no need to check them against xmin.  We could
-                * filter against xmax, but it seems better not to do that much work
-                * while holding the ProcArrayLock.
-                *
-                * The other backend can add more subxids concurrently, but cannot
-                * remove any.  Hence it's important to fetch nxids just once. Should
-                * be safe to use memcpy, though.  (We needn't worry about missing any
-                * xids added concurrently, because they must postdate xmax.)
-                *
-                * Again, our own XIDs are not included in the snapshot.
-                */
-               if (!suboverflowed && proc != MyProc)
-               {
-                       if (proc->subxids.overflowed)
-                               suboverflowed = true;
-                       else
+                       /* Update globalxmin to be the smallest valid xmin */
+                       xid = proc->xmin;               /* fetch just once */
+                       if (TransactionIdIsNormal(xid) &&
+                               TransactionIdPrecedes(xid, globalxmin))
+                               globalxmin = xid;
+
+                       /* Fetch xid just once - see GetNewTransactionId */
+                       xid = proc->xid;
+
+                       /*
+                        * If the transaction has been assigned an xid < xmax we add it to the
+                        * snapshot, and update xmin if necessary.      There's no need to store
+                        * XIDs >= xmax, since we'll treat them as running anyway.  We don't
+                        * bother to examine their subxids either.
+                        *
+                        * We don't include our own XID (if any) in the snapshot, but we must
+                        * include it into xmin.
+                        */
+                       if (TransactionIdIsNormal(xid))
                        {
-                               int                     nxids = proc->subxids.nxids;
+                               if (TransactionIdFollowsOrEquals(xid, xmax))
+                                       continue;
+                               if (proc != MyProc)
+                                       snapshot->xip[count++] = xid;
+                               if (TransactionIdPrecedes(xid, xmin))
+                                       xmin = xid;
+                       }
 
-                               if (nxids > 0)
+                       /*
+                        * Save subtransaction XIDs if possible (if we've already overflowed,
+                        * there's no point).  Note that the subxact XIDs must be later than
+                        * their parent, so no need to check them against xmin.  We could
+                        * filter against xmax, but it seems better not to do that much work
+                        * while holding the ProcArrayLock.
+                        *
+                        * The other backend can add more subxids concurrently, but cannot
+                        * remove any.  Hence it's important to fetch nxids just once. Should
+                        * be safe to use memcpy, though.  (We needn't worry about missing any
+                        * xids added concurrently, because they must postdate xmax.)
+                        *
+                        * Again, our own XIDs are not included in the snapshot.
+                        */
+                       if (!suboverflowed && proc != MyProc)
+                       {
+                               if (proc->subxids.overflowed)
+                                       suboverflowed = true;
+                               else
                                {
-                                       Assert(!snapshot->takenDuringRecovery);
-                                       memcpy(snapshot->subxip + subcount,
-                                                  (void *) proc->subxids.xids,
-                                                  nxids * sizeof(TransactionId));
-                                       subcount += nxids;
+                                       int                     nxids = proc->subxids.nxids;
+
+                                       if (nxids > 0)
+                                       {
+                                               memcpy(snapshot->subxip + subcount,
+                                                          (void *) proc->subxids.xids,
+                                                          nxids * sizeof(TransactionId));
+                                               subcount += nxids;
+                                       }
                                }
                        }
                }
        }
-
-       /*
-        * If in recovery get any known assigned xids.
-        */
-       if (snapshot->takenDuringRecovery)
+       else
        {
-               Assert(count == 0);
-
                /*
                 * We store all xids directly into subxip[]. Here's why:
                 *
index de7406a808b86b79b9294f7644f428ac41e33313..f3db21ca43295596d78d28ff7fea0824ca257ef3 100644 (file)
@@ -6,7 +6,7 @@
  * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/access/xlog.h,v 1.106 2010/04/12 09:52:29 heikki Exp $
+ * $PostgreSQL: pgsql/src/include/access/xlog.h,v 1.107 2010/04/18 18:06:07 sriggs Exp $
  */
 #ifndef XLOG_H
 #define XLOG_H
@@ -278,6 +278,7 @@ extern void xlog_desc(StringInfo buf, uint8 xl_info, char *rec);
 
 extern void issue_xlog_fsync(int fd, uint32 log, uint32 seg);
 
+extern bool XLogConsistentState(void);
 extern bool RecoveryInProgress(void);
 extern bool XLogInsertAllowed(void);
 extern TimestampTz GetLatestXLogTime(void);