@@ -155,6 +155,11 @@ static void DisplayXidCache(void);
155155#define xc_slow_answer_inc ()((void) 0)
156156#endif /* XIDCACHE_DEBUG */
157157
158+ static VirtualTransactionId * GetVirtualXIDsDelayingChkptGuts (int * nvxids ,
159+ int type );
160+ static bool HaveVirtualXIDsDelayingChkptGuts (VirtualTransactionId * vxids ,
161+ int nvxids ,int type );
162+
158163/* Primitives for KnownAssignedXids array handling for standby */
159164static void KnownAssignedXidsCompress (bool force );
160165static void KnownAssignedXidsAdd (TransactionId from_xid ,TransactionId to_xid ,
@@ -435,8 +440,9 @@ ProcArrayEndTransaction(PGPROC *proc, TransactionId latestXid)
435440/* must be cleared with xid/xmin: */
436441pgxact -> vacuumFlags &= ~PROC_VACUUM_STATE_MASK ;
437442
438- /* be sure this is cleared in abort */
439- proc -> delayChkpt = 0 ;
443+ /* be sure these are cleared in abort */
444+ proc -> delayChkpt = false;
445+ proc -> delayChkptEnd = false;
440446
441447proc -> recoveryConflictPending = false;
442448
@@ -460,8 +466,9 @@ ProcArrayEndTransactionInternal(PGPROC *proc, PGXACT *pgxact,
460466/* must be cleared with xid/xmin: */
461467pgxact -> vacuumFlags &= ~PROC_VACUUM_STATE_MASK ;
462468
463- /* be sure this is cleared in abort */
464- proc -> delayChkpt = 0 ;
469+ /* be sure these are cleared in abort */
470+ proc -> delayChkpt = false;
471+ proc -> delayChkptEnd = false;
465472
466473proc -> recoveryConflictPending = false;
467474
@@ -2274,26 +2281,28 @@ GetOldestSafeDecodingTransactionId(bool catalogOnly)
22742281}
22752282
22762283/*
2277- * GetVirtualXIDsDelayingChkpt -- Get the VXIDs of transactions that are
2278- * delaying checkpoint because they have critical actions in progress.
2284+ * GetVirtualXIDsDelayingChkptGuts -- Get the VXIDs of transactions that are
2285+ * delaying the start or end of a checkpoint because they have critical
2286+ * actions in progress.
22792287 *
22802288 * Constructs an array of VXIDs of transactions that are currently in commit
2281- * critical sections, as shown by havingspecified delayChkptbits set in their
2282- * PGPROC.
2289+ * critical sections, as shown by having delayChkptor delayChkptEnd set in
2290+ *their PGPROC.
22832291 *
22842292 * Returns a palloc'd array that should be freed by the caller.
22852293 * *nvxids is the number of valid entries.
22862294 *
2287- * Note that because backends set or clear delayChkpt without holding any lock,
2288- * the result is somewhat indeterminate, but we don't really care. Even in
2289- * a multiprocessor with delayed writes to shared memory, it should be certain
2290- * that setting of delayChkpt will propagate to shared memory when the backend
2291- * takes a lock, so we cannot fail to see a virtual xact as delayChkpt if
2292- * it's already inserted its commit record. Whether it takes a little while
2293- * for clearing of delayChkpt to propagate is unimportant for correctness.
2295+ * Note that because backends set or clear delayChkpt and delayChkptEnd
2296+ * without holding any lock, the result is somewhat indeterminate, but we
2297+ * don't really care. Even in a multiprocessor with delayed writes to
2298+ * shared memory, it should be certain that setting of delayChkpt will
2299+ * propagate to shared memory when the backend takes a lock, so we cannot
2300+ * fail to see a virtual xact as delayChkpt if it's already inserted its
2301+ * commit record. Whether it takes a little while for clearing of
2302+ * delayChkpt to propagate is unimportant for correctness.
22942303 */
2295- VirtualTransactionId *
2296- GetVirtualXIDsDelayingChkpt (int * nvxids ,int type )
2304+ static VirtualTransactionId *
2305+ GetVirtualXIDsDelayingChkptGuts (int * nvxids ,int type )
22972306{
22982307VirtualTransactionId * vxids ;
22992308ProcArrayStruct * arrayP = procArray ;
@@ -2313,7 +2322,8 @@ GetVirtualXIDsDelayingChkpt(int *nvxids, int type)
23132322int pgprocno = arrayP -> pgprocnos [index ];
23142323PGPROC * proc = & allProcs [pgprocno ];
23152324
2316- if ((proc -> delayChkpt & type )!= 0 )
2325+ if (((type & DELAY_CHKPT_START )&& proc -> delayChkpt )||
2326+ ((type & DELAY_CHKPT_COMPLETE )&& proc -> delayChkptEnd ))
23172327{
23182328VirtualTransactionId vxid ;
23192329
@@ -2329,6 +2339,26 @@ GetVirtualXIDsDelayingChkpt(int *nvxids, int type)
23292339return vxids ;
23302340}
23312341
2342+ /*
2343+ * GetVirtualXIDsDelayingChkpt - Get the VXIDs of transactions that are
2344+ * delaying the start of a checkpoint.
2345+ */
2346+ VirtualTransactionId *
2347+ GetVirtualXIDsDelayingChkpt (int * nvxids )
2348+ {
2349+ return GetVirtualXIDsDelayingChkptGuts (nvxids ,DELAY_CHKPT_START );
2350+ }
2351+
2352+ /*
2353+ * GetVirtualXIDsDelayingChkptEnd - Get the VXIDs of transactions that are
2354+ * delaying the end of a checkpoint.
2355+ */
2356+ VirtualTransactionId *
2357+ GetVirtualXIDsDelayingChkptEnd (int * nvxids )
2358+ {
2359+ return GetVirtualXIDsDelayingChkptGuts (nvxids ,DELAY_CHKPT_COMPLETE );
2360+ }
2361+
23322362/*
23332363 * HaveVirtualXIDsDelayingChkpt -- Are any of the specified VXIDs delaying?
23342364 *
@@ -2338,8 +2368,9 @@ GetVirtualXIDsDelayingChkpt(int *nvxids, int type)
23382368 * Note: this is O(N^2) in the number of vxacts that are/were delaying, but
23392369 * those numbers should be small enough for it not to be a problem.
23402370 */
2341- bool
2342- HaveVirtualXIDsDelayingChkpt (VirtualTransactionId * vxids ,int nvxids ,int type )
2371+ static bool
2372+ HaveVirtualXIDsDelayingChkptGuts (VirtualTransactionId * vxids ,int nvxids ,
2373+ int type )
23432374{
23442375bool result = false;
23452376ProcArrayStruct * arrayP = procArray ;
@@ -2357,7 +2388,8 @@ HaveVirtualXIDsDelayingChkpt(VirtualTransactionId *vxids, int nvxids, int type)
23572388
23582389GET_VXID_FROM_PGPROC (vxid ,* proc );
23592390
2360- if ((proc -> delayChkpt & type )!= 0 &&
2391+ if ((((type & DELAY_CHKPT_START )&& proc -> delayChkpt )||
2392+ ((type & DELAY_CHKPT_COMPLETE )&& proc -> delayChkptEnd ))&&
23612393VirtualTransactionIdIsValid (vxid ))
23622394{
23632395int i ;
@@ -2380,6 +2412,28 @@ HaveVirtualXIDsDelayingChkpt(VirtualTransactionId *vxids, int nvxids, int type)
23802412return result ;
23812413}
23822414
2415+ /*
2416+ * HaveVirtualXIDsDelayingChkpt -- Are any of the specified VXIDs delaying
2417+ * the start of a checkpoint?
2418+ */
2419+ bool
2420+ HaveVirtualXIDsDelayingChkpt (VirtualTransactionId * vxids ,int nvxids )
2421+ {
2422+ return HaveVirtualXIDsDelayingChkptGuts (vxids ,nvxids ,
2423+ DELAY_CHKPT_START );
2424+ }
2425+
2426+ /*
2427+ * HaveVirtualXIDsDelayingChkptEnd -- Are any of the specified VXIDs delaying
2428+ * the end of a checkpoint?
2429+ */
2430+ bool
2431+ HaveVirtualXIDsDelayingChkptEnd (VirtualTransactionId * vxids ,int nvxids )
2432+ {
2433+ return HaveVirtualXIDsDelayingChkptGuts (vxids ,nvxids ,
2434+ DELAY_CHKPT_COMPLETE );
2435+ }
2436+
23832437/*
23842438 * BackendPidGetProc -- get a backend's PGPROC given its PID
23852439 *