@@ -151,6 +151,11 @@ static void DisplayXidCache(void);
151151#define xc_slow_answer_inc () ((void) 0)
152152#endif /* XIDCACHE_DEBUG */
153153
154+ static VirtualTransactionId * GetVirtualXIDsDelayingChkptGuts (int * nvxids ,
155+ int type );
156+ static bool HaveVirtualXIDsDelayingChkptGuts (VirtualTransactionId * vxids ,
157+ int nvxids , int type );
158+
154159/* Primitives for KnownAssignedXids array handling for standby */
155160static void KnownAssignedXidsCompress (bool force );
156161static void KnownAssignedXidsAdd (TransactionId from_xid , TransactionId to_xid ,
@@ -434,8 +439,9 @@ ProcArrayEndTransaction(PGPROC *proc, TransactionId latestXid)
434439 /* must be cleared with xid/xmin: */
435440 pgxact -> vacuumFlags &= ~PROC_VACUUM_STATE_MASK ;
436441
437- /* be sure this is cleared in abort */
438- pgxact -> delayChkpt = 0 ;
442+ /* be sure these are cleared in abort */
443+ pgxact -> delayChkpt = false;
444+ proc -> delayChkptEnd = false;
439445
440446 proc -> recoveryConflictPending = false;
441447
@@ -459,8 +465,9 @@ ProcArrayEndTransactionInternal(PGPROC *proc, PGXACT *pgxact,
459465 /* must be cleared with xid/xmin: */
460466 pgxact -> vacuumFlags &= ~PROC_VACUUM_STATE_MASK ;
461467
462- /* be sure this is cleared in abort */
463- pgxact -> delayChkpt = 0 ;
468+ /* be sure these are cleared in abort */
469+ pgxact -> delayChkpt = false;
470+ proc -> delayChkptEnd = false;
464471
465472 proc -> recoveryConflictPending = false;
466473
@@ -2269,26 +2276,28 @@ GetOldestSafeDecodingTransactionId(bool catalogOnly)
22692276}
22702277
22712278/*
2272- * GetVirtualXIDsDelayingChkpt -- Get the VXIDs of transactions that are
2273- * delaying checkpoint because they have critical actions in progress.
2279+ * GetVirtualXIDsDelayingChkptGuts -- Get the VXIDs of transactions that are
2280+ * delaying the start or end of a checkpoint because they have critical
2281+ * actions in progress.
22742282 *
22752283 * Constructs an array of VXIDs of transactions that are currently in commit
2276- * critical sections, as shown by having specified delayChkpt bits set in their
2277- * PGXACT .
2284+ * critical sections, as shown by having specified delayChkpt or delayChkptEnd
2285+ * set .
22782286 *
22792287 * Returns a palloc'd array that should be freed by the caller.
22802288 * *nvxids is the number of valid entries.
22812289 *
2282- * Note that because backends set or clear delayChkpt without holding any lock,
2283- * the result is somewhat indeterminate, but we don't really care. Even in
2284- * a multiprocessor with delayed writes to shared memory, it should be certain
2285- * that setting of delayChkpt will propagate to shared memory when the backend
2286- * takes a lock, so we cannot fail to see a virtual xact as delayChkpt if
2287- * it's already inserted its commit record. Whether it takes a little while
2288- * for clearing of delayChkpt to propagate is unimportant for correctness.
2290+ * Note that because backends set or clear delayChkpt and delayChkptEnd
2291+ * without holding any lock, the result is somewhat indeterminate, but we
2292+ * don't really care. Even in a multiprocessor with delayed writes to
2293+ * shared memory, it should be certain that setting of delayChkpt will
2294+ * propagate to shared memory when the backend takes a lock, so we cannot
2295+ * fail to see a virtual xact as delayChkpt if it's already inserted its
2296+ * commit record. Whether it takes a little while for clearing of
2297+ * delayChkpt to propagate is unimportant for correctness.
22892298 */
2290- VirtualTransactionId *
2291- GetVirtualXIDsDelayingChkpt (int * nvxids , int type )
2299+ static VirtualTransactionId *
2300+ GetVirtualXIDsDelayingChkptGuts (int * nvxids , int type )
22922301{
22932302 VirtualTransactionId * vxids ;
22942303 ProcArrayStruct * arrayP = procArray ;
@@ -2309,7 +2318,8 @@ GetVirtualXIDsDelayingChkpt(int *nvxids, int type)
23092318 volatile PGPROC * proc = & allProcs [pgprocno ];
23102319 volatile PGXACT * pgxact = & allPgXact [pgprocno ];
23112320
2312- if ((pgxact -> delayChkpt & type ) != 0 )
2321+ if (((type & DELAY_CHKPT_START ) && pgxact -> delayChkpt ) ||
2322+ ((type & DELAY_CHKPT_COMPLETE ) && proc -> delayChkptEnd ))
23132323 {
23142324 VirtualTransactionId vxid ;
23152325
@@ -2325,6 +2335,26 @@ GetVirtualXIDsDelayingChkpt(int *nvxids, int type)
23252335 return vxids ;
23262336}
23272337
2338+ /*
2339+ * GetVirtualXIDsDelayingChkpt - Get the VXIDs of transactions that are
2340+ * delaying the start of a checkpoint.
2341+ */
2342+ VirtualTransactionId *
2343+ GetVirtualXIDsDelayingChkpt (int * nvxids )
2344+ {
2345+ return GetVirtualXIDsDelayingChkptGuts (nvxids , DELAY_CHKPT_START );
2346+ }
2347+
2348+ /*
2349+ * GetVirtualXIDsDelayingChkptEnd - Get the VXIDs of transactions that are
2350+ * delaying the end of a checkpoint.
2351+ */
2352+ VirtualTransactionId *
2353+ GetVirtualXIDsDelayingChkptEnd (int * nvxids )
2354+ {
2355+ return GetVirtualXIDsDelayingChkptGuts (nvxids , DELAY_CHKPT_COMPLETE );
2356+ }
2357+
23282358/*
23292359 * HaveVirtualXIDsDelayingChkpt -- Are any of the specified VXIDs delaying?
23302360 *
@@ -2334,8 +2364,9 @@ GetVirtualXIDsDelayingChkpt(int *nvxids, int type)
23342364 * Note: this is O(N^2) in the number of vxacts that are/were delaying, but
23352365 * those numbers should be small enough for it not to be a problem.
23362366 */
2337- bool
2338- HaveVirtualXIDsDelayingChkpt (VirtualTransactionId * vxids , int nvxids , int type )
2367+ static bool
2368+ HaveVirtualXIDsDelayingChkptGuts (VirtualTransactionId * vxids , int nvxids ,
2369+ int type )
23392370{
23402371 bool result = false;
23412372 ProcArrayStruct * arrayP = procArray ;
@@ -2354,7 +2385,8 @@ HaveVirtualXIDsDelayingChkpt(VirtualTransactionId *vxids, int nvxids, int type)
23542385
23552386 GET_VXID_FROM_PGPROC (vxid , * proc );
23562387
2357- if ((pgxact -> delayChkpt & type ) != 0 &&
2388+ if ((((type & DELAY_CHKPT_START ) && pgxact -> delayChkpt ) ||
2389+ ((type & DELAY_CHKPT_COMPLETE ) && proc -> delayChkptEnd )) &&
23582390 VirtualTransactionIdIsValid (vxid ))
23592391 {
23602392 int i ;
@@ -2377,6 +2409,28 @@ HaveVirtualXIDsDelayingChkpt(VirtualTransactionId *vxids, int nvxids, int type)
23772409 return result ;
23782410}
23792411
2412+ /*
2413+ * HaveVirtualXIDsDelayingChkpt -- Are any of the specified VXIDs delaying
2414+ * the start of a checkpoint?
2415+ */
2416+ bool
2417+ HaveVirtualXIDsDelayingChkpt (VirtualTransactionId * vxids , int nvxids )
2418+ {
2419+ return HaveVirtualXIDsDelayingChkptGuts (vxids , nvxids ,
2420+ DELAY_CHKPT_START );
2421+ }
2422+
2423+ /*
2424+ * HaveVirtualXIDsDelayingChkptEnd -- Are any of the specified VXIDs delaying
2425+ * the end of a checkpoint?
2426+ */
2427+ bool
2428+ HaveVirtualXIDsDelayingChkptEnd (VirtualTransactionId * vxids , int nvxids )
2429+ {
2430+ return HaveVirtualXIDsDelayingChkptGuts (vxids , nvxids ,
2431+ DELAY_CHKPT_COMPLETE );
2432+ }
2433+
23802434/*
23812435 * BackendPidGetProc -- get a backend's PGPROC given its PID
23822436 *
0 commit comments