aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2007-09-23 18:50:38 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2007-09-23 18:50:38 +0000
commit1b3d400cac138c12dd3d1428a9da112b69ad0f15 (patch)
treeaa2cee887bbe5798c252c62e3454aea95ba8bca5
parentd16f270e5915ee091feb35ede89db40d2fd9c10f (diff)
downloadpostgresql-1b3d400cac138c12dd3d1428a9da112b69ad0f15.tar.gz
postgresql-1b3d400cac138c12dd3d1428a9da112b69ad0f15.zip
TransactionIdIsInProgress can skip scanning the ProcArray if the target XID is
later than latestCompletedXid, per Florian Pflug. Also some minor improvements in the XIDCACHE_DEBUG code --- make sure each call of TransactionIdIsInProgress is counted one way or another.
-rw-r--r--src/backend/storage/ipc/procarray.c34
1 files changed, 29 insertions, 5 deletions
diff --git a/src/backend/storage/ipc/procarray.c b/src/backend/storage/ipc/procarray.c
index dbac4a8fd05..90ba09d5a88 100644
--- a/src/backend/storage/ipc/procarray.c
+++ b/src/backend/storage/ipc/procarray.c
@@ -23,7 +23,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/storage/ipc/procarray.c,v 1.34 2007/09/21 17:36:53 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/storage/ipc/procarray.c,v 1.35 2007/09/23 18:50:38 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -61,14 +61,18 @@ static ProcArrayStruct *procArray;
/* counters for XidCache measurement */
static long xc_by_recent_xmin = 0;
static long xc_by_my_xact = 0;
+static long xc_by_latest_xid = 0;
static long xc_by_main_xid = 0;
static long xc_by_child_xid = 0;
+static long xc_no_overflow = 0;
static long xc_slow_answer = 0;
#define xc_by_recent_xmin_inc() (xc_by_recent_xmin++)
#define xc_by_my_xact_inc() (xc_by_my_xact++)
+#define xc_by_latest_xid_inc() (xc_by_latest_xid++)
#define xc_by_main_xid_inc() (xc_by_main_xid++)
#define xc_by_child_xid_inc() (xc_by_child_xid++)
+#define xc_no_overflow_inc() (xc_no_overflow++)
#define xc_slow_answer_inc() (xc_slow_answer++)
static void DisplayXidCache(void);
@@ -76,8 +80,10 @@ static void DisplayXidCache(void);
#define xc_by_recent_xmin_inc() ((void) 0)
#define xc_by_my_xact_inc() ((void) 0)
+#define xc_by_latest_xid_inc() ((void) 0)
#define xc_by_main_xid_inc() ((void) 0)
#define xc_by_child_xid_inc() ((void) 0)
+#define xc_no_overflow_inc() ((void) 0)
#define xc_slow_answer_inc() ((void) 0)
#endif /* XIDCACHE_DEBUG */
@@ -302,7 +308,8 @@ ProcArrayClearTransaction(PGPROC *proc)
/*
* TransactionIdIsInProgress -- is given transaction running in some backend
*
- * There are three possibilities for finding a running transaction:
+ * Aside from some shortcuts such as checking RecentXmin and our own Xid,
+ * there are three possibilities for finding a running transaction:
*
* 1. the given Xid is a main transaction Id. We will find this out cheaply
* by looking at the PGPROC struct for each backend.
@@ -368,6 +375,18 @@ TransactionIdIsInProgress(TransactionId xid)
LWLockAcquire(ProcArrayLock, LW_SHARED);
+ /*
+ * Now that we have the lock, we can check latestCompletedXid; if the
+ * target Xid is after that, it's surely still running.
+ */
+ if (TransactionIdPrecedes(ShmemVariableCache->latestCompletedXid, xid))
+ {
+ LWLockRelease(ProcArrayLock);
+ xc_by_latest_xid_inc();
+ return true;
+ }
+
+ /* No shortcuts, gotta grovel through the array */
for (i = 0; i < arrayP->numProcs; i++)
{
volatile PGPROC *proc = arrayP->procs[i];
@@ -434,7 +453,10 @@ TransactionIdIsInProgress(TransactionId xid)
* running without looking at pg_subtrans.
*/
if (nxids == 0)
+ {
+ xc_no_overflow_inc();
return false;
+ }
/*
* Step 3: have to check pg_subtrans.
@@ -451,8 +473,8 @@ TransactionIdIsInProgress(TransactionId xid)
/*
* It isn't aborted, so check whether the transaction tree it belongs to
- * is still running (or, more precisely, whether it was running when this
- * routine started -- note that we already released ProcArrayLock).
+ * is still running (or, more precisely, whether it was running when
+ * we held ProcArrayLock).
*/
topxid = SubTransGetTopmostTransaction(xid);
Assert(TransactionIdIsValid(topxid));
@@ -1300,11 +1322,13 @@ static void
DisplayXidCache(void)
{
fprintf(stderr,
- "XidCache: xmin: %ld, myxact: %ld, mainxid: %ld, childxid: %ld, slow: %ld\n",
+ "XidCache: xmin: %ld, myxact: %ld, latest: %ld, mainxid: %ld, childxid: %ld, nooflo: %ld, slow: %ld\n",
xc_by_recent_xmin,
xc_by_my_xact,
+ xc_by_latest_xid,
xc_by_main_xid,
xc_by_child_xid,
+ xc_no_overflow,
xc_slow_answer);
}