Commit 1b3d400c authored by Tom Lane's avatar Tom Lane

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.
parent d16f270e
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
* *
* *
* IDENTIFICATION * 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; ...@@ -61,14 +61,18 @@ static ProcArrayStruct *procArray;
/* counters for XidCache measurement */ /* counters for XidCache measurement */
static long xc_by_recent_xmin = 0; static long xc_by_recent_xmin = 0;
static long xc_by_my_xact = 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_main_xid = 0;
static long xc_by_child_xid = 0; static long xc_by_child_xid = 0;
static long xc_no_overflow = 0;
static long xc_slow_answer = 0; static long xc_slow_answer = 0;
#define xc_by_recent_xmin_inc() (xc_by_recent_xmin++) #define xc_by_recent_xmin_inc() (xc_by_recent_xmin++)
#define xc_by_my_xact_inc() (xc_by_my_xact++) #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_main_xid_inc() (xc_by_main_xid++)
#define xc_by_child_xid_inc() (xc_by_child_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++) #define xc_slow_answer_inc() (xc_slow_answer++)
static void DisplayXidCache(void); static void DisplayXidCache(void);
...@@ -76,8 +80,10 @@ static void DisplayXidCache(void); ...@@ -76,8 +80,10 @@ static void DisplayXidCache(void);
#define xc_by_recent_xmin_inc() ((void) 0) #define xc_by_recent_xmin_inc() ((void) 0)
#define xc_by_my_xact_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_main_xid_inc() ((void) 0)
#define xc_by_child_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) #define xc_slow_answer_inc() ((void) 0)
#endif /* XIDCACHE_DEBUG */ #endif /* XIDCACHE_DEBUG */
...@@ -302,7 +308,8 @@ ProcArrayClearTransaction(PGPROC *proc) ...@@ -302,7 +308,8 @@ ProcArrayClearTransaction(PGPROC *proc)
/* /*
* TransactionIdIsInProgress -- is given transaction running in some backend * 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 * 1. the given Xid is a main transaction Id. We will find this out cheaply
* by looking at the PGPROC struct for each backend. * by looking at the PGPROC struct for each backend.
...@@ -368,6 +375,18 @@ TransactionIdIsInProgress(TransactionId xid) ...@@ -368,6 +375,18 @@ TransactionIdIsInProgress(TransactionId xid)
LWLockAcquire(ProcArrayLock, LW_SHARED); 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++) for (i = 0; i < arrayP->numProcs; i++)
{ {
volatile PGPROC *proc = arrayP->procs[i]; volatile PGPROC *proc = arrayP->procs[i];
...@@ -434,7 +453,10 @@ TransactionIdIsInProgress(TransactionId xid) ...@@ -434,7 +453,10 @@ TransactionIdIsInProgress(TransactionId xid)
* running without looking at pg_subtrans. * running without looking at pg_subtrans.
*/ */
if (nxids == 0) if (nxids == 0)
{
xc_no_overflow_inc();
return false; return false;
}
/* /*
* Step 3: have to check pg_subtrans. * Step 3: have to check pg_subtrans.
...@@ -451,8 +473,8 @@ TransactionIdIsInProgress(TransactionId xid) ...@@ -451,8 +473,8 @@ TransactionIdIsInProgress(TransactionId xid)
/* /*
* It isn't aborted, so check whether the transaction tree it belongs to * 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 * is still running (or, more precisely, whether it was running when
* routine started -- note that we already released ProcArrayLock). * we held ProcArrayLock).
*/ */
topxid = SubTransGetTopmostTransaction(xid); topxid = SubTransGetTopmostTransaction(xid);
Assert(TransactionIdIsValid(topxid)); Assert(TransactionIdIsValid(topxid));
...@@ -1300,11 +1322,13 @@ static void ...@@ -1300,11 +1322,13 @@ static void
DisplayXidCache(void) DisplayXidCache(void)
{ {
fprintf(stderr, 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_recent_xmin,
xc_by_my_xact, xc_by_my_xact,
xc_by_latest_xid,
xc_by_main_xid, xc_by_main_xid,
xc_by_child_xid, xc_by_child_xid,
xc_no_overflow,
xc_slow_answer); xc_slow_answer);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment