diff --git a/src/backend/storage/ipc/procarray.c b/src/backend/storage/ipc/procarray.c index 89ec7f04619..292e330367e 100644 --- a/src/backend/storage/ipc/procarray.c +++ b/src/backend/storage/ipc/procarray.c @@ -475,9 +475,10 @@ ProcArrayApplyRecoveryInfo(RunningTransactions running) return; /* - * If our initial RunningTransactionsData had an overflowed snapshot then we knew - * we were missing some subxids from our snapshot. We can use this data as - * an initial snapshot, but we cannot yet mark it valid. We know that the + * If our initial RunningTransactionsData had an overflowed snapshot then + * we knew we were missing some subxids from our snapshot. If we continue + * to see overflowed snapshots then we might never be able to start up, + * so we make another test to see if our snapshot is now valid. We know * missing subxids are equal to or earlier than nextXid. After we * initialise we continue to apply changes during recovery, so once the * oldestRunningXid is later than the nextXid from the initial snapshot we @@ -486,21 +487,31 @@ ProcArrayApplyRecoveryInfo(RunningTransactions running) */ if (standbyState == STANDBY_SNAPSHOT_PENDING) { - if (TransactionIdPrecedes(standbySnapshotPendingXmin, - running->oldestRunningXid)) + /* + * If the snapshot isn't overflowed or if its empty we can + * reset our pending state and use this snapshot instead. + */ + if (!running->subxid_overflow || running->xcnt == 0) { - standbyState = STANDBY_SNAPSHOT_READY; - elog(trace_recovery(DEBUG2), - "running xact data now proven complete"); - elog(trace_recovery(DEBUG2), - "recovery snapshots are now enabled"); + standbyState = STANDBY_INITIALIZED; } else - elog(trace_recovery(DEBUG2), - "recovery snapshot waiting for %u oldest active xid on standby is %u", - standbySnapshotPendingXmin, - running->oldestRunningXid); - return; + { + if (TransactionIdPrecedes(standbySnapshotPendingXmin, + running->oldestRunningXid)) + { + standbyState = STANDBY_SNAPSHOT_READY; + elog(trace_recovery(DEBUG1), + "recovery snapshots are now enabled"); + } + else + elog(trace_recovery(DEBUG1), + "recovery snapshot waiting for non-overflowed snapshot or " + "until oldest active xid on standby is at least %u (now %u)", + standbySnapshotPendingXmin, + running->oldestRunningXid); + return; + } } Assert(standbyState == STANDBY_INITIALIZED); @@ -606,7 +617,6 @@ ProcArrayApplyRecoveryInfo(RunningTransactions running) standbyState = STANDBY_SNAPSHOT_READY; standbySnapshotPendingXmin = InvalidTransactionId; - procArray->lastOverflowedXid = InvalidTransactionId; } /* @@ -630,13 +640,15 @@ ProcArrayApplyRecoveryInfo(RunningTransactions running) LWLockRelease(ProcArrayLock); - elog(trace_recovery(DEBUG2), "running transaction data initialized"); KnownAssignedXidsDisplay(trace_recovery(DEBUG3)); if (standbyState == STANDBY_SNAPSHOT_READY) - elog(trace_recovery(DEBUG2), "recovery snapshots are now enabled"); + elog(trace_recovery(DEBUG1), "recovery snapshots are now enabled"); else - ereport(LOG, - (errmsg("consistent state delayed because recovery snapshot incomplete"))); + elog(trace_recovery(DEBUG1), + "recovery snapshot waiting for non-overflowed snapshot or " + "until oldest active xid on standby is at least %u (now %u)", + standbySnapshotPendingXmin, + running->oldestRunningXid); } /*