@@ -468,6 +468,28 @@ ProcArrayClearTransaction(PGPROC *proc)
468
468
pgxact -> overflowed = false;
469
469
}
470
470
471
+ /*
472
+ * ProcArrayInitRecovery -- initialize recovery xid mgmt environment
473
+ *
474
+ * Remember up to where the startup process initialized the CLOG and subtrans
475
+ * s
10000
o we can ensure its initialized gaplessly up to the point where necessary
476
+ * while in recovery.
477
+ */
478
+ void
479
+ ProcArrayInitRecovery (TransactionId initializedUptoXID )
480
+ {
481
+ Assert (standbyState == STANDBY_INITIALIZED );
482
+ Assert (TransactionIdIsNormal (initializedUptoXID ));
483
+
484
+ /*
485
+ * we set latestObservedXid to the xid SUBTRANS has been initialized upto
486
+ * so we can extend it from that point onwards when we reach a consistent
487
+ * state in ProcArrayApplyRecoveryInfo().
488
+ */
489
+ latestObservedXid = initializedUptoXID ;
490
+ TransactionIdRetreat (latestObservedXid );
491
+ }
492
+
471
493
/*
472
494
* ProcArrayApplyRecoveryInfo -- apply recovery info about xids
473
495
*
@@ -556,7 +578,10 @@ ProcArrayApplyRecoveryInfo(RunningTransactions running)
556
578
Assert (standbyState == STANDBY_INITIALIZED );
557
579
558
580
/*
559
- * OK, we need to initialise from the RunningTransactionsData record
581
+ * OK, we need to initialise from the RunningTransactionsData record.
582
+ *
583
+ * NB: this can be reached at least twice, so make sure new code can deal
584
+ * with that.
560
585
*/
561
586
562
587
/*
@@ -628,20 +653,32 @@ ProcArrayApplyRecoveryInfo(RunningTransactions running)
628
653
pfree (xids );
629
654
630
655
/*
656
+ * latestObservedXid is set to the the point where SUBTRANS was started up
657
+ * to, initialize subtrans from thereon, up to nextXid - 1.
658
+ */
659
+ Assert (TransactionIdIsNormal (latestObservedXid ));
660
+ while (TransactionIdPrecedes (latestObservedXid , running -> nextXid ))
661
+ {
662
+ ExtendCLOG (latestObservedXid );
663
+ ExtendSUBTRANS (latestObservedXid );
664
+
665
+ TransactionIdAdvance (latestObservedXid );
666
+ }
667
+
668
+ /* ----------
631
669
* Now we've got the running xids we need to set the global values that
632
670
* are used to track snapshots as they evolve further.
633
671
*
634
- * - latestCompletedXid which will be the xmax for snapshots -
635
- * lastOverflowedXid which shows whether snapshots overflow - nextXid
672
+ * - latestCompletedXid which will be the xmax for snapshots
673
+ * - lastOverflowedXid which shows whether snapshots overflow
674
+ * - nextXid
636
675
*
637
676
* If the snapshot overflowed, then we still initialise with what we know,
638
677
* but the recovery snapshot isn't fully valid yet because we know there
639
678
* are some subxids missing. We don't know the specific subxids that are
640
679
* missing, so conservatively assume the last one is latestObservedXid.
680
+ * ----------
641
681
*/
642
- latestObservedXid = running -> nextXid ;
643
- TransactionIdRetreat (latestObservedXid );
644
-
645
682
if (running -> subxid_overflow )
646
683
{
647
684
standbyState = STANDBY_SNAPSHOT_PENDING ;
@@ -711,6 +748,10 @@ ProcArrayApplyXidAssignment(TransactionId topxid,
711
748
712
749
Assert (standbyState >= STANDBY_INITIALIZED );
713
750
751
+ /* can't do anything useful unless we have more state setup */
752
+ if (standbyState == STANDBY_INITIALIZED )
753
+ return ;
754
+
714
755
max_xid = TransactionIdLatest (topxid , nsubxids , subxids );
715
756
716
757
/*
0 commit comments