@@ -192,9 +192,9 @@ static bool twophaseExitRegistered = false;
192192 *
193193 * Replay of twophase records happens by the following rules:
194194 * * On PREPARE redo KnownPreparedAdd() is called to add that transaction to
195- * KnownPreparedList and no more actions taken.
196- * * On checkpoint we iterate through KnownPreparedList, move all prepare
197- * records that behind redo_horizon to file and deleting items from list.
195+ * KnownPreparedList and no more actions are taken.
196+ * * On checkpoint redo we iterate through KnownPreparedList and move all prepare
197+ * records that behind redo_horizon to files and deleting them from list.
198198 * * On COMMIT/ABORT we delete file or entry in KnownPreparedList.
199199 * * At the end of recovery we move all known prepared transactions to disk
200200 * to allow RecoverPreparedTransactions/StandbyRecoverPreparedTransactions
@@ -1270,9 +1270,9 @@ ReadTwoPhaseFile(TransactionId xid, bool give_warnings)
12701270 * Reads 2PC data from xlog. During checkpoint this data will be moved to
12711271 * twophase files and ReadTwoPhaseFile should be used instead.
12721272 *
1273- * Note clearly that this function accesses WAL during normal operation, similarly
1274- * to the way WALSender or Logical Decoding would do. It does not run during
1275- * crash recovery or standby processing.
1273+ * Note clearly that this function can access WAL during normal operation, similarly
1274+ * to the way WALSender or Logical Decoding would do.
1275+ *
12761276 */
12771277static void
12781278XlogReadTwoPhaseData (XLogRecPtr lsn , char * * buf , int * len )
@@ -1281,8 +1281,6 @@ XlogReadTwoPhaseData(XLogRecPtr lsn, char **buf, int *len)
12811281 XLogReaderState * xlogreader ;
12821282 char * errormsg ;
12831283
1284- // Assert(!RecoveryInProgress());
1285-
12861284 xlogreader = XLogReaderAllocate (& read_local_xlog_page , NULL );
12871285 if (!xlogreader )
12881286 ereport (ERROR ,
@@ -1682,27 +1680,6 @@ CheckPointTwoPhase(XLogRecPtr redo_horizon)
16821680 serialized_xacts )));
16831681}
16841682
1685- /*
1686- * KnownPreparedAdd.
1687- *
1688- * Store correspondence of start/end lsn and xid in KnownPreparedList.
1689- * This is called during redo of prepare record to have list of prepared
1690- * transactions that aren't yet moved to 2PC files by the end of recovery.
1691- */
1692- void
1693- KnownPreparedAdd (XLogReaderState * record )
1694- {
1695- KnownPreparedXact * xact ;
1696- TwoPhaseFileHeader * hdr = (TwoPhaseFileHeader * ) XLogRecGetData (record );
1697-
1698- xact = (KnownPreparedXact * ) palloc (sizeof (KnownPreparedXact ));
1699- xact -> xid = hdr -> xid ;
1700- xact -> prepare_start_lsn = record -> ReadRecPtr ;
1701- xact -> prepare_end_lsn = record -> EndRecPtr ;
1702-
1703- dlist_push_tail (& KnownPreparedList , & xact -> list_node );
1704- }
1705-
17061683/*
17071684 * PrescanPreparedTransactions
17081685 *
@@ -1741,6 +1718,13 @@ PrescanPreparedTransactions(TransactionId **xids_p, int *nxids_p)
17411718 int nxids = 0 ;
17421719 int allocsize = 0 ;
17431720
1721+ /*
1722+ * Move prepared transactions from KnownPreparedList to files, if any.
1723+ * It is possible to skip that step and teach subsequent code about
1724+ * KnownPreparedList, but whole PrescanPreparedTransactions() happens
1725+ * once during end of recovery or promote, so probably it isn't worth
1726+ * complications.
1727+ */
17441728 KnownPreparedRecreateFiles (InvalidXLogRecPtr );
17451729
17461730 cldir = AllocateDir (TWOPHASE_DIR );
@@ -2215,10 +2199,33 @@ RecordTransactionAbortPrepared(TransactionId xid,
22152199 SyncRepWaitForLSN (recptr , false);
22162200}
22172201
2202+ /*
2203+ * KnownPreparedAdd.
2204+ *
2205+ * Store correspondence of start/end lsn and xid in KnownPreparedList.
2206+ * This is called during redo of prepare record to have list of prepared
2207+ * transactions that aren't yet moved to 2PC files by the end of recovery.
2208+ */
2209+ void
2210+ KnownPreparedAdd (XLogReaderState * record )
2211+ {
2212+ KnownPreparedXact * xact ;
2213+ TwoPhaseFileHeader * hdr = (TwoPhaseFileHeader * ) XLogRecGetData (record );
2214+
2215+ Assert (RecoveryInProgress ());
2216+
2217+ xact = (KnownPreparedXact * ) palloc (sizeof (KnownPreparedXact ));
2218+ xact -> xid = hdr -> xid ;
2219+ xact -> prepare_start_lsn = record -> ReadRecPtr ;
2220+ xact -> prepare_end_lsn = record -> EndRecPtr ;
2221+
2222+ dlist_push_tail (& KnownPreparedList , & xact -> list_node );
2223+ }
2224+
22182225/*
22192226 * KnownPreparedRemoveByXid
22202227 *
2221- * Forget about prepared transaction. Called durind commit/abort.
2228+ * Forget about prepared transaction. Called during commit/abort redo .
22222229 */
22232230void
22242231KnownPreparedRemoveByXid (TransactionId xid )
@@ -2254,7 +2261,7 @@ KnownPreparedRemoveByXid(TransactionId xid)
22542261/*
22552262 * KnownPreparedRecreateFiles
22562263 *
2257- * Moves prepare records from WAL to files. Callend during checkpoint replay
2264+ * Moves prepare records from WAL to files. Called during checkpoint replay
22582265 * or PrescanPreparedTransactions.
22592266 *
22602267 * redo_horizon = InvalidXLogRecPtr indicates that all transactions from
0 commit comments