aboutsummaryrefslogtreecommitdiff
path: root/src/include/access/transam.h
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2007-09-08 20:31:15 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2007-09-08 20:31:15 +0000
commit6bd4f401b0cb85f2e81caffc457e415e15e2ed5d (patch)
treea0edebb698a1a288be3e66c064c36399cbf5f93f /src/include/access/transam.h
parent0a51e7073c045b5fce50092dae19f398f7b38e16 (diff)
downloadpostgresql-6bd4f401b0cb85f2e81caffc457e415e15e2ed5d.tar.gz
postgresql-6bd4f401b0cb85f2e81caffc457e415e15e2ed5d.zip
Replace the former method of determining snapshot xmax --- to wit, calling
ReadNewTransactionId from GetSnapshotData --- with a "latestCompletedXid" variable that is updated during transaction commit or abort. Since latestCompletedXid is written only in places that had to lock ProcArrayLock exclusively anyway, and is read only in places that had to lock ProcArrayLock shared anyway, it adds no new locking requirements to the system despite being cluster-wide. Moreover, removing ReadNewTransactionId from snapshot acquisition eliminates the need to take both XidGenLock and ProcArrayLock at the same time. Since XidGenLock is sometimes held across I/O this can be a significant win. Some preliminary benchmarking suggested that this patch has no effect on average throughput but can significantly improve the worst-case transaction times seen in pgbench. Concept by Florian Pflug, implementation by Tom Lane.
Diffstat (limited to 'src/include/access/transam.h')
-rw-r--r--src/include/access/transam.h30
1 files changed, 27 insertions, 3 deletions
diff --git a/src/include/access/transam.h b/src/include/access/transam.h
index 98850cc0d3b..0408038124c 100644
--- a/src/include/access/transam.h
+++ b/src/include/access/transam.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/access/transam.h,v 1.61 2007/08/01 22:45:09 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/access/transam.h,v 1.62 2007/09/08 20:31:15 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -43,6 +43,7 @@
#define TransactionIdEquals(id1, id2) ((id1) == (id2))
#define TransactionIdStore(xid, dest) (*(dest) = (xid))
#define StoreInvalidTransactionId(dest) (*(dest) = InvalidTransactionId)
+
/* advance a transaction ID variable, handling wraparound correctly */
#define TransactionIdAdvance(dest) \
do { \
@@ -51,6 +52,12 @@
(dest) = FirstNormalTransactionId; \
} while(0)
+/* back up a transaction ID variable, handling wraparound correctly */
+#define TransactionIdRetreat(dest) \
+ do { \
+ (dest)--; \
+ } while ((dest) < FirstNormalTransactionId)
+
/* ----------
* Object ID (OID) zero is InvalidOid.
@@ -78,8 +85,10 @@
#define FirstNormalObjectId 16384
/*
- * VariableCache is placed in shmem and used by
- * backends to get next available OID & XID.
+ * VariableCache is a data structure in shared memory that is used to track
+ * OID and XID assignment state. For largely historical reasons, there is
+ * just one struct with different fields that are protected by different
+ * LWLocks.
*
* Note: xidWrapLimit and limit_datname are not "active" values, but are
* used just to generate useful messages when xidWarnLimit or xidStopLimit
@@ -87,8 +96,15 @@
*/
typedef struct VariableCacheData
{
+ /*
+ * These fields are protected by OidGenLock.
+ */
Oid nextOid; /* next OID to assign */
uint32 oidCount; /* OIDs available before must do XLOG work */
+
+ /*
+ * These fields are protected by XidGenLock.
+ */
TransactionId nextXid; /* next XID to assign */
TransactionId oldestXid; /* cluster-wide minimum datfrozenxid */
@@ -97,6 +113,12 @@ typedef struct VariableCacheData
TransactionId xidStopLimit; /* refuse to advance nextXid beyond here */
TransactionId xidWrapLimit; /* where the world ends */
NameData limit_datname; /* database that needs vacuumed first */
+
+ /*
+ * These fields are protected by ProcArrayLock.
+ */
+ TransactionId latestCompletedXid; /* newest XID that has committed or
+ * aborted */
} VariableCacheData;
typedef VariableCacheData *VariableCache;
@@ -127,6 +149,8 @@ extern bool TransactionIdPrecedes(TransactionId id1, TransactionId id2);
extern bool TransactionIdPrecedesOrEquals(TransactionId id1, TransactionId id2);
extern bool TransactionIdFollows(TransactionId id1, TransactionId id2);
extern bool TransactionIdFollowsOrEquals(TransactionId id1, TransactionId id2);
+extern TransactionId TransactionIdLatest(TransactionId mainxid,
+ int nxids, const TransactionId *xids);
extern XLogRecPtr TransactionIdGetCommitLSN(TransactionId xid);
/* in transam/varsup.c */