@@ -330,6 +330,11 @@ static void DisplayXidCache(void);
330330#define xc_slow_answer_inc ()((void) 0)
331331#endif /* XIDCACHE_DEBUG */
332332
333+ static VirtualTransactionId * GetVirtualXIDsDelayingChkptGuts (int * nvxids ,
334+ int type );
335+ static bool HaveVirtualXIDsDelayingChkptGuts (VirtualTransactionId * vxids ,
336+ int nvxids ,int type );
337+
333338/* Primitives for KnownAssignedXids array handling for standby */
334339static void KnownAssignedXidsCompress (bool force );
335340static void KnownAssignedXidsAdd (TransactionId from_xid ,TransactionId to_xid ,
@@ -690,8 +695,9 @@ ProcArrayEndTransaction(PGPROC *proc, TransactionId latestXid)
690695proc -> lxid = InvalidLocalTransactionId ;
691696proc -> xmin = InvalidTransactionId ;
692697
693- /* be sure this is cleared in abort */
694- proc -> delayChkpt = 0 ;
698+ /* be sure these are cleared in abort */
699+ proc -> delayChkpt = false;
700+ proc -> delayChkptEnd = false;
695701
696702proc -> recoveryConflictPending = false;
697703
@@ -732,8 +738,9 @@ ProcArrayEndTransactionInternal(PGPROC *proc, TransactionId latestXid)
732738proc -> lxid = InvalidLocalTransactionId ;
733739proc -> xmin = InvalidTransactionId ;
734740
735- /* be sure this is cleared in abort */
736- proc -> delayChkpt = 0 ;
741+ /* be sure these are cleared in abort */
742+ proc -> delayChkpt = false;
743+ proc -> delayChkptEnd = false;
737744
738745proc -> recoveryConflictPending = false;
739746
@@ -3045,26 +3052,28 @@ GetOldestSafeDecodingTransactionId(bool catalogOnly)
30453052}
30463053
30473054/*
3048- * GetVirtualXIDsDelayingChkpt -- Get the VXIDs of transactions that are
3049- * delaying checkpoint because they have critical actions in progress.
3055+ * GetVirtualXIDsDelayingChkptGuts -- Get the VXIDs of transactions that are
3056+ * delaying the start or end of a checkpoint because they have critical
3057+ * actions in progress.
30503058 *
30513059 * Constructs an array of VXIDs of transactions that are currently in commit
3052- * critical sections, as shown by havingspecified delayChkptbits set in their
3053- * PGPROC.
3060+ * critical sections, as shown by having delayChkptor delayChkptEnd set in
3061+ *their PGPROC.
30543062 *
30553063 * Returns a palloc'd array that should be freed by the caller.
30563064 * *nvxids is the number of valid entries.
30573065 *
3058- * Note that because backends set or clear delayChkpt without holding any lock,
3059- * the result is somewhat indeterminate, but we don't really care. Even in
3060- * a multiprocessor with delayed writes to shared memory, it should be certain
3061- * that setting of delayChkpt will propagate to shared memory when the backend
3062- * takes a lock, so we cannot fail to see a virtual xact as delayChkpt if
3063- * it's already inserted its commit record. Whether it takes a little while
3064- * for clearing of delayChkpt to propagate is unimportant for correctness.
3066+ * Note that because backends set or clear delayChkpt and delayChkptEnd
3067+ * without holding any lock, the result is somewhat indeterminate, but we
3068+ * don't really care. Even in a multiprocessor with delayed writes to
3069+ * shared memory, it should be certain that setting of delayChkpt will
3070+ * propagate to shared memory when the backend takes a lock, so we cannot
3071+ * fail to see a virtual xact as delayChkpt if it's already inserted its
3072+ * commit record. Whether it takes a little while for clearing of
3073+ * delayChkpt to propagate is unimportant for correctness.
30653074 */
3066- VirtualTransactionId *
3067- GetVirtualXIDsDelayingChkpt (int * nvxids ,int type )
3075+ static VirtualTransactionId *
3076+ GetVirtualXIDsDelayingChkptGuts (int * nvxids ,int type )
30683077{
30693078VirtualTransactionId * vxids ;
30703079ProcArrayStruct * arrayP = procArray ;
@@ -3084,7 +3093,8 @@ GetVirtualXIDsDelayingChkpt(int *nvxids, int type)
30843093int pgprocno = arrayP -> pgprocnos [index ];
30853094PGPROC * proc = & allProcs [pgprocno ];
30863095
3087- if ((proc -> delayChkpt & type )!= 0 )
3096+ if (((type & DELAY_CHKPT_START )&& proc -> delayChkpt )||
3097+ ((type & DELAY_CHKPT_COMPLETE )&& proc -> delayChkptEnd ))
30883098{
30893099VirtualTransactionId vxid ;
30903100
@@ -3100,6 +3110,26 @@ GetVirtualXIDsDelayingChkpt(int *nvxids, int type)
31003110return vxids ;
31013111}
31023112
3113+ /*
3114+ * GetVirtualXIDsDelayingChkpt - Get the VXIDs of transactions that are
3115+ * delaying the start of a checkpoint.
3116+ */
3117+ VirtualTransactionId *
3118+ GetVirtualXIDsDelayingChkpt (int * nvxids )
3119+ {
3120+ return GetVirtualXIDsDelayingChkptGuts (nvxids ,DELAY_CHKPT_START );
3121+ }
3122+
3123+ /*
3124+ * GetVirtualXIDsDelayingChkptEnd - Get the VXIDs of transactions that are
3125+ * delaying the end of a checkpoint.
3126+ */
3127+ VirtualTransactionId *
3128+ GetVirtualXIDsDelayingChkptEnd (int * nvxids )
3129+ {
3130+ return GetVirtualXIDsDelayingChkptGuts (nvxids ,DELAY_CHKPT_COMPLETE );
3131+ }
3132+
31033133/*
31043134 * HaveVirtualXIDsDelayingChkpt -- Are any of the specified VXIDs delaying?
31053135 *
@@ -3109,8 +3139,9 @@ GetVirtualXIDsDelayingChkpt(int *nvxids, int type)
31093139 * Note: this is O(N^2) in the number of vxacts that are/were delaying, but
31103140 * those numbers should be small enough for it not to be a problem.
31113141 */
3112- bool
3113- HaveVirtualXIDsDelayingChkpt (VirtualTransactionId * vxids ,int nvxids ,int type )
3142+ static bool
3143+ HaveVirtualXIDsDelayingChkptGuts (VirtualTransactionId * vxids ,int nvxids ,
3144+ int type )
31143145{
31153146bool result = false;
31163147ProcArrayStruct * arrayP = procArray ;
@@ -3128,7 +3159,8 @@ HaveVirtualXIDsDelayingChkpt(VirtualTransactionId *vxids, int nvxids, int type)
31283159
31293160GET_VXID_FROM_PGPROC (vxid ,* proc );
31303161
3131- if ((proc -> delayChkpt & type )!= 0 &&
3162+ if ((((type & DELAY_CHKPT_START )&& proc -> delayChkpt )||
3163+ ((type & DELAY_CHKPT_COMPLETE )&& proc -> delayChkptEnd ))&&
31323164VirtualTransactionIdIsValid (vxid ))
31333165{
31343166int i ;
@@ -3151,6 +3183,28 @@ HaveVirtualXIDsDelayingChkpt(VirtualTransactionId *vxids, int nvxids, int type)
31513183return result ;
31523184}
31533185
3186+ /*
3187+ * HaveVirtualXIDsDelayingChkpt -- Are any of the specified VXIDs delaying
3188+ * the start of a checkpoint?
3189+ */
3190+ bool
3191+ HaveVirtualXIDsDelayingChkpt (VirtualTransactionId * vxids ,int nvxids )
3192+ {
3193+ return HaveVirtualXIDsDelayingChkptGuts (vxids ,nvxids ,
3194+ DELAY_CHKPT_START );
3195+ }
3196+
3197+ /*
3198+ * HaveVirtualXIDsDelayingChkptEnd -- Are any of the specified VXIDs delaying
3199+ * the end of a checkpoint?
3200+ */
3201+ bool
3202+ HaveVirtualXIDsDelayingChkptEnd (VirtualTransactionId * vxids ,int nvxids )
3203+ {
3204+ return HaveVirtualXIDsDelayingChkptGuts (vxids ,nvxids ,
3205+ DELAY_CHKPT_COMPLETE );
3206+ }
3207+
31543208/*
31553209 * BackendPidGetProc -- get a backend's PGPROC given its PID
31563210 *