Skip to content

Commit 10b7c68

Browse files
Start Hot Standby faster when initial snapshot is incomplete.
If the initial snapshot had overflowed then we can start whenever the latest snapshot is empty, not overflowed or as we did already, start when the xmin on primary was higher than xmax of our starting snapshot, which proves we have full snapshot data. Bug report by Chris Redekop
1 parent 2296e62 commit 10b7c68

File tree

1 file changed

+31
-19
lines changed

1 file changed

+31
-19
lines changed

src/backend/storage/ipc/procarray.c

Lines changed: 31 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -475,8 +475,9 @@ ProcArrayApplyRecoveryInfo(RunningTransactions running)
475475

476476
/*
477477
* If our initial RunningTransactionsData had an overflowed snapshot then
478-
* we knew we were missing some subxids from our snapshot. We can use this
479-
* data as an initial snapshot, but we cannot yet mark it valid. We know
478+
* we knew we were missing some subxids from our snapshot. If we continue
479+
* to see overflowed snapshots then we might never be able to start up,
480+
* so we make another test to see if our snapshot is now valid. We know
480481
* that the missing subxids are equal to or earlier than nextXid. After we
481482
* initialise we continue to apply changes during recovery, so once the
482483
* oldestRunningXid is later than the nextXid from the initial snapshot we
@@ -485,21 +486,31 @@ ProcArrayApplyRecoveryInfo(RunningTransactions running)
485486
*/
486487
if (standbyState == STANDBY_SNAPSHOT_PENDING)
487488
{
488-
if (TransactionIdPrecedes(standbySnapshotPendingXmin,
489-
running->oldestRunningXid))
489+
/*
490+
* If the snapshot isn't overflowed or if its empty we can
491+
* reset our pending state and use this snapshot instead.
492+
*/
493+
if (!running->subxid_overflow || running->xcnt == 0)
490494
{
491-
standbyState = STANDBY_SNAPSHOT_READY;
492-
elog(trace_recovery(DEBUG2),
493-
"running xact data now proven complete");
494-
elog(trace_recovery(DEBUG2),
495-
"recovery snapshots are now enabled");
495+
standbyState = STANDBY_INITIALIZED;
496496
}
497497
else
498-
elog(trace_recovery(DEBUG2),
499-
"recovery snapshot waiting for %u oldest active xid on standby is %u",
500-
standbySnapshotPendingXmin,
501-
running->oldestRunningXid);
502-
return;
498+
{
499+
if (TransactionIdPrecedes(standbySnapshotPendingXmin,
500+
running->oldestRunningXid))
501+
{
502+
standbyState = STANDBY_SNAPSHOT_READY;
503+
elog(trace_recovery(DEBUG1),
504+
"recovery snapshots are now enabled");
505+
}
506+
else
507+
elog(trace_recovery(DEBUG1),
508+
"recovery snapshot waiting for non-overflowed snapshot or "
509+
"until oldest active xid on standby is at least %u (now %u)",
510+
standbySnapshotPendingXmin,
511+
running->oldestRunningXid);
512+
return;
513+
}
503514
}
504515

505516
Assert(standbyState == STANDBY_INITIALIZED);
@@ -604,7 +615,6 @@ ProcArrayApplyRecoveryInfo(RunningTransactions running)
604615
standbyState = STANDBY_SNAPSHOT_READY;
605616

606617
standbySnapshotPendingXmin = InvalidTransactionId;
607-
procArray->lastOverflowedXid = InvalidTransactionId;
608618
}
609619

610620
/*
@@ -627,13 +637,15 @@ ProcArrayApplyRecoveryInfo(RunningTransactions running)
627637

628638
LWLockRelease(ProcArrayLock);
629639

630-
elog(trace_recovery(DEBUG2), "running transaction data initialized");
631640
KnownAssignedXidsDisplay(trace_recovery(DEBUG3));
632641
if (standbyState == STANDBY_SNAPSHOT_READY)
633-
elog(trace_recovery(DEBUG2), "recovery snapshots are now enabled");
642+
elog(trace_recovery(DEBUG1), "recovery snapshots are now enabled");
634643
else
635-
ereport(LOG,
636-
(errmsg("consistent state delayed because recovery snapshot incomplete")));
644+
elog(trace_recovery(DEBUG1),
645+
"recovery snapshot waiting for non-overflowed snapshot or "
646+
"until oldest active xid on standby is at least %u (now %u)",
647+
standbySnapshotPendingXmin,
648+
running->oldestRunningXid);
637649
}
638650

639651
/*

0 commit comments

Comments
 (0)