@@ -435,6 +435,28 @@ ProcArrayClearTransaction(PGPROC *proc)
435435 proc -> subxids .overflowed = false;
436436}
437437
438+ /*
439+ * ProcArrayInitRecovery -- initialize recovery xid mgmt environment
440+ *
441+ * Remember up to where the startup process initialized the CLOG and subtrans
442+ * so we can ensure its initialized gaplessly up to the point where necessary
443+ * while in recovery.
444+ */
445+ void
446+ ProcArrayInitRecovery (TransactionId initializedUptoXID )
447+ {
448+ Assert (standbyState == STANDBY_INITIALIZED );
449+ Assert (TransactionIdIsNormal (initializedUptoXID ));
450+
451+ /*
452+ * we set latestObservedXid to the xid SUBTRANS has been initialized upto
453+ * so we can extend it from that point onwards when we reach a consistent
454+ * state in ProcArrayApplyRecoveryInfo().
455+ */
456+ latestObservedXid = initializedUptoXID ;
457+ TransactionIdRetreat (latestObservedXid );
458+ }
459+
438460/*
439461 * ProcArrayApplyRecoveryInfo -- apply recovery info about xids
440462 *
@@ -523,7 +545,10 @@ ProcArrayApplyRecoveryInfo(RunningTransactions running)
523545 Assert (standbyState == STANDBY_INITIALIZED );
524546
525547 /*
526- * OK, we need to initialise from the RunningTransactionsData record
548+ * OK, we need to initialise from the RunningTransactionsData record.
549+ *
550+ * NB: this can be reached at least twice, so make sure new code can deal
551+ * with that.
527552 */
528553
529554 /*
@@ -595,6 +620,19 @@ ProcArrayApplyRecoveryInfo(RunningTransactions running)
595620 pfree (xids );
596621
597622 /*
623+ * latestObservedXid is set to the the point where SUBTRANS was started up
624+ * to, initialize subtrans from thereon, up to nextXid - 1.
625+ */
626+ Assert (TransactionIdIsNormal (latestObservedXid ));
627+ while (TransactionIdPrecedes (latestObservedXid , running -> nextXid ))
628+ {
629+ ExtendCLOG (latestObservedXid );
630+ ExtendSUBTRANS (latestObservedXid );
631+
632+ TransactionIdAdvance (latestObservedXid );
633+ }
634+
635+ /* ----------
598636 * Now we've got the running xids we need to set the global values that
599637 * are used to track snapshots as they evolve further.
600638 *
@@ -606,10 +644,8 @@ ProcArrayApplyRecoveryInfo(RunningTransactions running)
606644 * but the recovery snapshot isn't fully valid yet because we know there
607645 * are some subxids missing. We don't know the specific subxids that are
608646 * missing, so conservatively assume the last one is latestObservedXid.
647+ * ----------
609648 */
610- latestObservedXid = running -> nextXid ;
611- TransactionIdRetreat (latestObservedXid );
612-
613649 if (running -> subxid_overflow )
614650 {
615651 standbyState = STANDBY_SNAPSHOT_PENDING ;
@@ -669,6 +705,10 @@ ProcArrayApplyXidAssignment(TransactionId topxid,
669705
670706 Assert (standbyState >= STANDBY_INITIALIZED );
671707
708+ /* can't do anything useful unless we have more state setup */
709+ if (standbyState == STANDBY_INITIALIZED )
710+ return ;
711+
672712 max_xid = TransactionIdLatest (topxid , nsubxids , subxids );
673713
674714 /*
0 commit comments