@ -330,6 +330,11 @@ static void DisplayXidCache(void);
# define xc_slow_answer_inc() ((void) 0)
# endif /* XIDCACHE_DEBUG */
static VirtualTransactionId * GetVirtualXIDsDelayingChkptGuts ( int * nvxids ,
int type ) ;
static bool HaveVirtualXIDsDelayingChkptGuts ( VirtualTransactionId * vxids ,
int nvxids , int type ) ;
/* Primitives for KnownAssignedXids array handling for standby */
static void KnownAssignedXidsCompress ( bool force ) ;
static void KnownAssignedXidsAdd ( TransactionId from_xid , TransactionId to_xid ,
@ -690,8 +695,9 @@ ProcArrayEndTransaction(PGPROC *proc, TransactionId latestXid)
proc - > lxid = InvalidLocalTransactionId ;
proc - > xmin = InvalidTransactionId ;
/* be sure this is cleared in abort */
proc - > delayChkpt = 0 ;
/* be sure these are cleared in abort */
proc - > delayChkpt = false ;
proc - > delayChkptEnd = false ;
proc - > recoveryConflictPending = false ;
@ -732,8 +738,9 @@ ProcArrayEndTransactionInternal(PGPROC *proc, TransactionId latestXid)
proc - > lxid = InvalidLocalTransactionId ;
proc - > xmin = InvalidTransactionId ;
/* be sure this is cleared in abort */
proc - > delayChkpt = 0 ;
/* be sure these are cleared in abort */
proc - > delayChkpt = false ;
proc - > delayChkptEnd = false ;
proc - > recoveryConflictPending = false ;
@ -3045,26 +3052,28 @@ GetOldestSafeDecodingTransactionId(bool catalogOnly)
}
/*
* GetVirtualXIDsDelayingChkpt - - Get the VXIDs of transactions that are
* delaying checkpoint because they have critical actions in progress .
* GetVirtualXIDsDelayingChkptGuts - - Get the VXIDs of transactions that are
* delaying the start or end of a checkpoint because they have critical
* actions in progress .
*
* Constructs an array of VXIDs of transactions that are currently in commit
* critical sections , as shown by having specified delayChkpt bits set in their
* PGPROC .
* critical sections , as shown by having delayChkpt or delayChkptEnd set in
* their PGPROC .
*
* Returns a palloc ' d array that should be freed by the caller .
* * nvxids is the number of valid entries .
*
* Note that because backends set or clear delayChkpt without holding any lock ,
* the result is somewhat indeterminate , but we don ' t really care . Even in
* a multiprocessor with delayed writes to shared memory , it should be certain
* that setting of delayChkpt will propagate to shared memory when the backend
* takes a lock , so we cannot fail to see a virtual xact as delayChkpt if
* it ' s already inserted its commit record . Whether it takes a little while
* for clearing of delayChkpt to propagate is unimportant for correctness .
* Note that because backends set or clear delayChkpt and delayChkptEnd
* without holding any lock , the result is somewhat indeterminate , but we
* don ' t really care . Even in a multiprocessor with delayed writes to
* shared memory , it should be certain that setting of delayChkpt will
* propagate to shared memory when the backend takes a lock , so we cannot
* fail to see a virtual xact as delayChkpt if it ' s already inserted its
* commit record . Whether it takes a little while for clearing of
* delayChkpt to propagate is unimportant for correctness .
*/
VirtualTransactionId *
GetVirtualXIDsDelayingChkpt ( int * nvxids , int type )
static VirtualTransactionId *
GetVirtualXIDsDelayingChkptGuts ( int * nvxids , int type )
{
VirtualTransactionId * vxids ;
ProcArrayStruct * arrayP = procArray ;
@ -3084,7 +3093,8 @@ GetVirtualXIDsDelayingChkpt(int *nvxids, int type)
int pgprocno = arrayP - > pgprocnos [ index ] ;
PGPROC * proc = & allProcs [ pgprocno ] ;
if ( ( proc - > delayChkpt & type ) ! = 0 )
if ( ( ( type & DELAY_CHKPT_START ) & & proc - > delayChkpt ) | |
( ( type & DELAY_CHKPT_COMPLETE ) & & proc - > delayChkptEnd ) )
{
VirtualTransactionId vxid ;
@ -3100,6 +3110,26 @@ GetVirtualXIDsDelayingChkpt(int *nvxids, int type)
return vxids ;
}
/*
* GetVirtualXIDsDelayingChkpt - Get the VXIDs of transactions that are
* delaying the start of a checkpoint .
*/
VirtualTransactionId *
GetVirtualXIDsDelayingChkpt ( int * nvxids )
{
return GetVirtualXIDsDelayingChkptGuts ( nvxids , DELAY_CHKPT_START ) ;
}
/*
* GetVirtualXIDsDelayingChkptEnd - Get the VXIDs of transactions that are
* delaying the end of a checkpoint .
*/
VirtualTransactionId *
GetVirtualXIDsDelayingChkptEnd ( int * nvxids )
{
return GetVirtualXIDsDelayingChkptGuts ( nvxids , DELAY_CHKPT_COMPLETE ) ;
}
/*
* HaveVirtualXIDsDelayingChkpt - - Are any of the specified VXIDs delaying ?
*
@ -3109,8 +3139,9 @@ GetVirtualXIDsDelayingChkpt(int *nvxids, int type)
* Note : this is O ( N ^ 2 ) in the number of vxacts that are / were delaying , but
* those numbers should be small enough for it not to be a problem .
*/
bool
HaveVirtualXIDsDelayingChkpt ( VirtualTransactionId * vxids , int nvxids , int type )
static bool
HaveVirtualXIDsDelayingChkptGuts ( VirtualTransactionId * vxids , int nvxids ,
int type )
{
bool result = false ;
ProcArrayStruct * arrayP = procArray ;
@ -3128,7 +3159,8 @@ HaveVirtualXIDsDelayingChkpt(VirtualTransactionId *vxids, int nvxids, int type)
GET_VXID_FROM_PGPROC ( vxid , * proc ) ;
if ( ( proc - > delayChkpt & type ) ! = 0 & &
if ( ( ( ( type & DELAY_CHKPT_START ) & & proc - > delayChkpt ) | |
( ( type & DELAY_CHKPT_COMPLETE ) & & proc - > delayChkptEnd ) ) & &
VirtualTransactionIdIsValid ( vxid ) )
{
int i ;
@ -3151,6 +3183,28 @@ HaveVirtualXIDsDelayingChkpt(VirtualTransactionId *vxids, int nvxids, int type)
return result ;
}
/*
* HaveVirtualXIDsDelayingChkpt - - Are any of the specified VXIDs delaying
* the start of a checkpoint ?
*/
bool
HaveVirtualXIDsDelayingChkpt ( VirtualTransactionId * vxids , int nvxids )
{
return HaveVirtualXIDsDelayingChkptGuts ( vxids , nvxids ,
DELAY_CHKPT_START ) ;
}
/*
* HaveVirtualXIDsDelayingChkptEnd - - Are any of the specified VXIDs delaying
* the end of a checkpoint ?
*/
bool
HaveVirtualXIDsDelayingChkptEnd ( VirtualTransactionId * vxids , int nvxids )
{
return HaveVirtualXIDsDelayingChkptGuts ( vxids , nvxids ,
DELAY_CHKPT_COMPLETE ) ;
}
/*
* BackendPidGetProc - - get a backend ' s PGPROC given its PID
*