@@ -400,7 +400,7 @@ ProcArrayEndTransaction(PGPROC *proc, TransactionId latestXid)
400400 pgxact -> xmin = InvalidTransactionId ;
401401 /* must be cleared with xid/xmin: */
402402 pgxact -> vacuumFlags &= ~PROC_VACUUM_STATE_MASK ;
403- pgxact -> inCommit = false; /* be sure this is cleared in abort */
403+ pgxact -> delayChkpt = false; /* be sure this is cleared in abort */
404404 proc -> recoveryConflictPending = false;
405405
406406 /* Clear the subtransaction-XID cache too while holding the lock */
@@ -427,7 +427,7 @@ ProcArrayEndTransaction(PGPROC *proc, TransactionId latestXid)
427427 pgxact -> xmin = InvalidTransactionId ;
428428 /* must be cleared with xid/xmin: */
429429 pgxact -> vacuumFlags &= ~PROC_VACUUM_STATE_MASK ;
430- pgxact -> inCommit = false; /* be sure this is cleared in abort */
430+ pgxact -> delayChkpt = false; /* be sure this is cleared in abort */
431431 proc -> recoveryConflictPending = false;
432432
433433 Assert (pgxact -> nxids == 0 );
@@ -462,7 +462,7 @@ ProcArrayClearTransaction(PGPROC *proc)
462462
463463 /* redundant, but just in case */
464464 pgxact -> vacuumFlags &= ~PROC_VACUUM_STATE_MASK ;
465- pgxact -> inCommit = false;
465+ pgxact -> delayChkpt = false;
466466
467467 /* Clear the subtransaction-XID cache too */
468468 pgxact -> nxids = 0 ;
@@ -1778,96 +1778,103 @@ GetOldestActiveTransactionId(void)
17781778}
17791779
17801780/*
1781- * GetTransactionsInCommit -- Get the XIDs of transactions that are committing
1781+ * GetVirtualXIDsDelayingChkpt -- Get the VXIDs of transactions that are
1782+ * delaying checkpoint because they have critical actions in progress.
17821783 *
1783- * Constructs an array of XIDs of transactions that are currently in commit
1784- * critical sections, as shown by having inCommit set in their PGXACT entries .
1784+ * Constructs an array of VXIDs of transactions that are currently in commit
1785+ * critical sections, as shown by having delayChkpt set in their PGXACT.
17851786 *
1786- * *xids_p is set to a palloc'd array that should be freed by the caller.
1787- * The return value is the number of valid entries.
1787+ * Returns a palloc'd array that should be freed by the caller.
1788+ * *nvxids is the number of valid entries.
17881789 *
1789- * Note that because backends set or clear inCommit without holding any lock,
1790+ * Note that because backends set or clear delayChkpt without holding any lock,
17901791 * the result is somewhat indeterminate, but we don't really care. Even in
17911792 * a multiprocessor with delayed writes to shared memory, it should be certain
1792- * that setting of inCommit will propagate to shared memory when the backend
1793- * takes the WALInsertLock , so we cannot fail to see an xact as inCommit if
1793+ * that setting of delayChkpt will propagate to shared memory when the backend
1794+ * takes a lock , so we cannot fail to see an virtual xact as delayChkpt if
17941795 * it's already inserted its commit record. Whether it takes a little while
1795- * for clearing of inCommit to propagate is unimportant for correctness.
1796+ * for clearing of delayChkpt to propagate is unimportant for correctness.
17961797 */
1797- int
1798- GetTransactionsInCommit ( TransactionId * * xids_p )
1798+ VirtualTransactionId *
1799+ GetVirtualXIDsDelayingChkpt ( int * nvxids )
17991800{
1801+ VirtualTransactionId * vxids ;
18001802 ProcArrayStruct * arrayP = procArray ;
1801- TransactionId * xids ;
1802- int nxids ;
1803+ int count = 0 ;
18031804 int index ;
18041805
1805- xids = (TransactionId * ) palloc (arrayP -> maxProcs * sizeof (TransactionId ));
1806- nxids = 0 ;
1806+ /* allocate what's certainly enough result space */
1807+ vxids = (VirtualTransactionId * )
1808+ palloc (sizeof (VirtualTransactionId ) * arrayP -> maxProcs );
18071809
18081810 LWLockAcquire (ProcArrayLock , LW_SHARED );
18091811
18101812 for (index = 0 ; index < arrayP -> numProcs ; index ++ )
18111813 {
1812- int pgprocno = arrayP -> pgprocnos [index ];
1813- volatile PGXACT * pgxact = & allPgXact [pgprocno ];
1814- TransactionId pxid ;
1814+ int pgprocno = arrayP -> pgprocnos [index ];
1815+ volatile PGPROC * proc = & allProcs [pgprocno ];
1816+ volatile PGXACT * pgxact = & allPgXact [ pgprocno ] ;
18151817
1816- /* Fetch xid just once - see GetNewTransactionId */
1817- pxid = pgxact -> xid ;
1818+ if (pgxact -> delayChkpt )
1819+ {
1820+ VirtualTransactionId vxid ;
18181821
1819- if (pgxact -> inCommit && TransactionIdIsValid (pxid ))
1820- xids [nxids ++ ] = pxid ;
1822+ GET_VXID_FROM_PGPROC (vxid , * proc );
1823+ if (VirtualTransactionIdIsValid (vxid ))
1824+ vxids [count ++ ] = vxid ;
1825+ }
18211826 }
18221827
18231828 LWLockRelease (ProcArrayLock );
18241829
1825- * xids_p = xids ;
1826- return nxids ;
1830+ * nvxids = count ;
1831+ return vxids ;
18271832}
18281833
18291834/*
1830- * HaveTransactionsInCommit -- Are any of the specified XIDs in commit ?
1835+ * HaveVirtualXIDsDelayingChkpt -- Are any of the specified VXIDs delaying ?
18311836 *
1832- * This is used with the results of GetTransactionsInCommit to see if any
1833- * of the specified XIDs are still in their commit critical sections.
1837+ * This is used with the results of GetVirtualXIDsDelayingChkpt to see if any
1838+ * of the specified VXIDs are still in critical sections of code .
18341839 *
1835- * Note: this is O(N^2) in the number of xacts that are/were in commit , but
1840+ * Note: this is O(N^2) in the number of vxacts that are/were delaying , but
18361841 * those numbers should be small enough for it not to be a problem.
18371842 */
18381843bool
1839- HaveTransactionsInCommit ( TransactionId * xids , int nxids )
1844+ HaveVirtualXIDsDelayingChkpt ( VirtualTransactionId * vxids , int nvxids )
18401845{
18411846 bool result = false;
18421847 ProcArrayStruct * arrayP = procArray ;
18431848 int index ;
18441849
18451850 LWLockAcquire (ProcArrayLock , LW_SHARED );
18461851
1847- for ( index = 0 ; index < arrayP -> numProcs ; index ++ )
1852+ while ( VirtualTransactionIdIsValid ( * vxids ) )
18481853 {
1849- int pgprocno = arrayP -> pgprocnos [index ];
1850- volatile PGXACT * pgxact = & allPgXact [pgprocno ];
1851- TransactionId pxid ;
1852-
1853- /* Fetch xid just once - see GetNewTransactionId */
1854- pxid = pgxact -> xid ;
1855-
1856- if (pgxact -> inCommit && TransactionIdIsValid (pxid ))
1854+ for (index = 0 ; index < arrayP -> numProcs ; index ++ )
18571855 {
1858- int i ;
1856+ int pgprocno = arrayP -> pgprocnos [index ];
1857+ volatile PGPROC * proc = & allProcs [pgprocno ];
1858+ volatile PGXACT * pgxact = & allPgXact [pgprocno ];
1859+ VirtualTransactionId vxid ;
18591860
1860- for (i = 0 ; i < nxids ; i ++ )
1861+ GET_VXID_FROM_PGPROC (vxid , * proc );
1862+ if (VirtualTransactionIdIsValid (vxid ))
18611863 {
1862- if (xids [i ] == pxid )
1864+ if (VirtualTransactionIdEquals (vxid , * vxids ) &&
1865+ pgxact -> delayChkpt )
18631866 {
18641867 result = true;
18651868 break ;
18661869 }
18671870 }
1868- if (result )
1869- break ;
18701871 }
1872+
1873+ if (result )
1874+ break ;
1875+
1876+ /* The virtual transaction is gone now, wait for the next one */
1877+ vxids ++ ;
18711878 }
18721879
18731880 LWLockRelease (ProcArrayLock );
0 commit comments