]> granicus.if.org Git - postgresql/commitdiff
Various micro-optimizations for GetSnapshopData().
authorRobert Haas <rhaas@postgresql.org>
Sat, 17 Dec 2011 02:44:26 +0000 (21:44 -0500)
committerRobert Haas <rhaas@postgresql.org>
Sat, 17 Dec 2011 02:48:47 +0000 (21:48 -0500)
Heikki Linnakangas had the idea of rearranging GetSnapshotData to
avoid checking for sub-XIDs when no top-level XID is present.  This
patch does that plus further a bit of further, related rearrangement.
Benchmarking show a significant improvement on unlogged tables at
higher concurrency levels, and mostly indifferent result on permanent
tables (which are presumably bottlenecked elsewhere).  Most of the
benefit seems to come from using the new NormalTransactionIdPrecedes()
macro rather than the function call TransactionIdPrecedes().

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

index 19ff524a6040b3453a53b4d94941e9ff20ba3e8d..fc95d9391ee8675d22605f3bcbb0103b035b2734 100644 (file)
@@ -1324,30 +1324,33 @@ GetSnapshotData(Snapshot snapshot)
                        /* Update globalxmin to be the smallest valid xmin */
                        xid = pgxact->xmin;     /* fetch just once */
                        if (TransactionIdIsNormal(xid) &&
-                               TransactionIdPrecedes(xid, globalxmin))
+                               NormalTransactionIdPrecedes(xid, globalxmin))
                                        globalxmin = xid;
 
                        /* Fetch xid just once - see GetNewTransactionId */
                        xid = pgxact->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 the transaction has no XID assigned, we can skip it; it won't
+                        * have sub-XIDs either.  If the XID is >= xmax, we can also skip
+                        * it; such transactions will be treated as running anyway (and any
+                        * sub-XIDs will also be >= xmax).
                         */
-                       if (TransactionIdIsNormal(xid))
-                       {
-                               if (TransactionIdFollowsOrEquals(xid, xmax))
+                       if (!TransactionIdIsNormal(xid)
+                               || !NormalTransactionIdPrecedes(xid, xmax))
                                        continue;
-                               if (pgxact != MyPgXact)
-                                       snapshot->xip[count++] = xid;
-                               if (TransactionIdPrecedes(xid, xmin))
-                                       xmin = xid;
-                       }
+
+                       /*
+                        * We don't include our own XIDs (if any) in the snapshot, but we
+                        * must include them in xmin.
+                        */
+                       if (NormalTransactionIdPrecedes(xid, xmin))
+                               xmin = xid;
+                       if (pgxact == MyPgXact)
+                               continue;
+
+                       /* Add XID to snapshot. */
+                       snapshot->xip[count++] = xid;
 
                        /*
                         * Save subtransaction XIDs if possible (if we've already
@@ -1364,7 +1367,7 @@ GetSnapshotData(Snapshot snapshot)
                         *
                         * Again, our own XIDs are not included in the snapshot.
                         */
-                       if (!suboverflowed && pgxact != MyPgXact)
+                       if (!suboverflowed)
                        {
                                if (pgxact->overflowed)
                                        suboverflowed = true;
index c038fd9a52db5392135ccd997f4f12f5b18d44d2..3ac1403c525d651ca4464225dd79cb8bb08e4cc3 100644 (file)
                (dest)--; \
        } while ((dest) < FirstNormalTransactionId)
 
+/* compare two XIDs already known to be normal; this is a macro for speed */
+#define NormalTransactionIdPrecedes(id1, id2) \
+       (AssertMacro(TransactionIdIsNormal(id1) && TransactionIdIsNormal(id2)), \
+       (int32) ((id1) - (id2)) < 0)
 
 /* ----------
  *             Object ID (OID) zero is InvalidOid.