@ -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 release d ProcArrayLock ) .
* is still running ( or , more precisely , whether it was running when
* we hel d 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 ) ;
}