@@ -221,8 +221,7 @@ static void RemoveGXact(GlobalTransaction gxact);
221221static void XlogReadTwoPhaseData (XLogRecPtr lsn , char * * buf , int * len );
222222static char * ProcessTwoPhaseBuffer (TransactionId xid ,
223223 XLogRecPtr prepare_start_lsn ,
224- bool fromdisk , bool overwriteOK , bool setParent ,
225- bool setNextXid );
224+ bool fromdisk , bool setParent , bool setNextXid );
226225static void MarkAsPreparingGuts (GlobalTransaction gxact , TransactionId xid ,
227226 const char * gid , TimestampTz prepared_at , Oid owner ,
228227 Oid databaseid );
@@ -1743,8 +1742,7 @@ restoreTwoPhaseData(void)
17431742 xid = (TransactionId ) strtoul (clde -> d_name , NULL , 16 );
17441743
17451744 buf = ProcessTwoPhaseBuffer (xid , InvalidXLogRecPtr ,
1746- true, false, false,
1747- false);
1745+ true, false, false);
17481746 if (buf == NULL )
17491747 continue ;
17501748
@@ -1804,8 +1802,7 @@ PrescanPreparedTransactions(TransactionId **xids_p, int *nxids_p)
18041802
18051803 buf = ProcessTwoPhaseBuffer (xid ,
18061804 gxact -> prepare_start_lsn ,
1807- gxact -> ondisk , false, false,
1808- true);
1805+ gxact -> ondisk , false, true);
18091806
18101807 if (buf == NULL )
18111808 continue ;
@@ -1858,12 +1855,12 @@ PrescanPreparedTransactions(TransactionId **xids_p, int *nxids_p)
18581855 * This is never called at the end of recovery - we use
18591856 * RecoverPreparedTransactions() at that point.
18601857 *
1861- * Currently we simply call SubTransSetParent() for any subxids of prepared
1862- * transactions. If overwriteOK is true, it's OK if some XIDs have already
1863- * been marked in pg_subtrans .
1858+ * The lack of calls to SubTransSetParent() calls here is by design;
1859+ * those calls are made by RecoverPreparedTransactions() at the end of recovery
1860+ * for those xacts that need this .
18641861 */
18651862void
1866- StandbyRecoverPreparedTransactions (bool overwriteOK )
1863+ StandbyRecoverPreparedTransactions (void )
18671864{
18681865 int i ;
18691866
@@ -1880,8 +1877,7 @@ StandbyRecoverPreparedTransactions(bool overwriteOK)
18801877
18811878 buf = ProcessTwoPhaseBuffer (xid ,
18821879 gxact -> prepare_start_lsn ,
1883- gxact -> ondisk , overwriteOK , true,
1884- false);
1880+ gxact -> ondisk , false, false);
18851881 if (buf != NULL )
18861882 pfree (buf );
18871883 }
@@ -1895,6 +1891,13 @@ StandbyRecoverPreparedTransactions(bool overwriteOK)
18951891 * each prepared transaction (reacquire locks, etc).
18961892 *
18971893 * This is run during database startup.
1894+ *
1895+ * At the end of recovery the way we take snapshots will change. We now need
1896+ * to mark all running transactions with their full SubTransSetParent() info
1897+ * to allow normal snapshots to work correctly if snapshots overflow.
1898+ * We do this here because by definition prepared transactions are the only
1899+ * type of write transaction still running, so this is necessary and
1900+ * complete.
18981901 */
18991902void
19001903RecoverPreparedTransactions (void )
@@ -1913,15 +1916,21 @@ RecoverPreparedTransactions(void)
19131916 TwoPhaseFileHeader * hdr ;
19141917 TransactionId * subxids ;
19151918 const char * gid ;
1916- bool overwriteOK = false;
1917- int i ;
19181919
19191920 xid = gxact -> xid ;
19201921
1922+ /*
1923+ * Reconstruct subtrans state for the transaction --- needed
1924+ * because pg_subtrans is not preserved over a restart. Note that
1925+ * we are linking all the subtransactions directly to the
1926+ * top-level XID; there may originally have been a more complex
1927+ * hierarchy, but there's no need to restore that exactly.
1928+ * It's possible that SubTransSetParent has been set before, if
1929+ * the prepared transaction generated xid assignment records.
1930+ */
19211931 buf = ProcessTwoPhaseBuffer (xid ,
19221932 gxact -> prepare_start_lsn ,
1923- gxact -> ondisk , false, false,
1924- false);
1933+ gxact -> ondisk , true, false);
19251934 if (buf == NULL )
19261935 continue ;
19271936
@@ -1939,25 +1948,6 @@ RecoverPreparedTransactions(void)
19391948 bufptr += MAXALIGN (hdr -> nabortrels * sizeof (RelFileNode ));
19401949 bufptr += MAXALIGN (hdr -> ninvalmsgs * sizeof (SharedInvalidationMessage ));
19411950
1942- /*
1943- * It's possible that SubTransSetParent has been set before, if
1944- * the prepared transaction generated xid assignment records. Test
1945- * here must match one used in AssignTransactionId().
1946- */
1947- if (InHotStandby && (hdr -> nsubxacts >= PGPROC_MAX_CACHED_SUBXIDS ||
1948- XLogLogicalInfoActive ()))
1949- overwriteOK = true;
1950-
1951- /*
1952- * Reconstruct subtrans state for the transaction --- needed
1953- * because pg_subtrans is not preserved over a restart. Note that
1954- * we are linking all the subtransactions directly to the
1955- * top-level XID; there may originally have been a more complex
1956- * hierarchy, but there's no need to restore that exactly.
1957- */
1958- for (i = 0 ; i < hdr -> nsubxacts ; i ++ )
1959- SubTransSetParent (subxids [i ], xid , true);
1960-
19611951 /*
19621952 * Recreate its GXACT and dummy PGPROC. But, check whether
19631953 * it was added in redo and already has a shmem entry for
@@ -2006,16 +1996,15 @@ RecoverPreparedTransactions(void)
20061996 * Given a transaction id, read it either from disk or read it directly
20071997 * via shmem xlog record pointer using the provided "prepare_start_lsn".
20081998 *
2009- * If setParent is true, then use the overwriteOK parameter to set up
2010- * subtransaction parent linkages.
1999+ * If setParent is true, set up subtransaction parent linkages.
20112000 *
20122001 * If setNextXid is true, set ShmemVariableCache->nextXid to the newest
20132002 * value scanned.
20142003 */
20152004static char *
20162005ProcessTwoPhaseBuffer (TransactionId xid ,
20172006 XLogRecPtr prepare_start_lsn ,
2018- bool fromdisk , bool overwriteOK ,
2007+ bool fromdisk ,
20192008 bool setParent , bool setNextXid )
20202009{
20212010 TransactionId origNextXid = ShmemVariableCache -> nextXid ;
@@ -2142,7 +2131,7 @@ ProcessTwoPhaseBuffer(TransactionId xid,
21422131 }
21432132
21442133 if (setParent )
2145- SubTransSetParent (subxid , xid , overwriteOK );
2134+ SubTransSetParent (subxid , xid );
21462135 }
21472136
21482137 return buf ;
0 commit comments