aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/access/transam/xlog.c3
-rw-r--r--src/backend/storage/ipc/procarray.c53
-rw-r--r--src/include/storage/procarray.h1
3 files changed, 51 insertions, 6 deletions
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index 9f858995d12..66447033695 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -5391,6 +5391,9 @@ StartupXLOG(void)
oldestActiveXID = checkPoint.oldestActiveXid;
Assert(TransactionIdIsValid(oldestActiveXID));
+ /* Tell procarray about the range of xids it has to deal with */
+ ProcArrayInitRecovery(ShmemVariableCache->nextXid);
+
/*
* Startup commit log and subtrans only. Other SLRUs are not
* maintained during recovery and need not be started yet.
diff --git a/src/backend/storage/ipc/procarray.c b/src/backend/storage/ipc/procarray.c
index b5f66fbfb04..c2f86ff2c4a 100644
--- a/src/backend/storage/ipc/procarray.c
+++ b/src/backend/storage/ipc/procarray.c
@@ -470,6 +470,28 @@ ProcArrayClearTransaction(PGPROC *proc)
}
/*
+ * ProcArrayInitRecovery -- initialize recovery xid mgmt environment
+ *
+ * Remember up to where the startup process initialized the CLOG and subtrans
+ * so we can ensure its initialized gaplessly up to the point where necessary
+ * while in recovery.
+ */
+void
+ProcArrayInitRecovery(TransactionId initializedUptoXID)
+{
+ Assert(standbyState == STANDBY_INITIALIZED);
+ Assert(TransactionIdIsNormal(initializedUptoXID));
+
+ /*
+ * we set latestObservedXid to the xid SUBTRANS has been initialized upto
+ * so we can extend it from that point onwards when we reach a consistent
+ * state in ProcArrayApplyRecoveryInfo().
+ */
+ latestObservedXid = initializedUptoXID;
+ TransactionIdRetreat(latestObservedXid);
+}
+
+/*
* ProcArrayApplyRecoveryInfo -- apply recovery info about xids
*
* Takes us through 3 states: Initialized, Pending and Ready.
@@ -564,7 +586,10 @@ ProcArrayApplyRecoveryInfo(RunningTransactions running)
Assert(standbyState == STANDBY_INITIALIZED);
/*
- * OK, we need to initialise from the RunningTransactionsData record
+ * OK, we need to initialise from the RunningTransactionsData record.
+ *
+ * NB: this can be reached at least twice, so make sure new code can deal
+ * with that.
*/
/*
@@ -636,20 +661,32 @@ ProcArrayApplyRecoveryInfo(RunningTransactions running)
pfree(xids);
/*
+ * latestObservedXid is set to the the point where SUBTRANS was started up
+ * to, initialize subtrans from thereon, up to nextXid - 1.
+ */
+ Assert(TransactionIdIsNormal(latestObservedXid));
+ while (TransactionIdPrecedes(latestObservedXid, running->nextXid))
+ {
+ ExtendCLOG(latestObservedXid);
+ ExtendSUBTRANS(latestObservedXid);
+
+ TransactionIdAdvance(latestObservedXid);
+ }
+
+ /* ----------
* Now we've got the running xids we need to set the global values that
* are used to track snapshots as they evolve further.
*
- * - latestCompletedXid which will be the xmax for snapshots -
- * lastOverflowedXid which shows whether snapshots overflow - nextXid
+ * - latestCompletedXid which will be the xmax for snapshots
+ * - lastOverflowedXid which shows whether snapshots overflow
+ * - nextXid
*
* If the snapshot overflowed, then we still initialise with what we know,
* but the recovery snapshot isn't fully valid yet because we know there
* are some subxids missing. We don't know the specific subxids that are
* missing, so conservatively assume the last one is latestObservedXid.
+ * ----------
*/
- latestObservedXid = running->nextXid;
- TransactionIdRetreat(latestObservedXid);
-
if (running->subxid_overflow)
{
standbyState = STANDBY_SNAPSHOT_PENDING;
@@ -719,6 +756,10 @@ ProcArrayApplyXidAssignment(TransactionId topxid,
Assert(standbyState >= STANDBY_INITIALIZED);
+ /* can't do anything useful unless we have more state setup */
+ if (standbyState == STANDBY_INITIALIZED)
+ return;
+
max_xid = TransactionIdLatest(topxid, nsubxids, subxids);
/*
diff --git a/src/include/storage/procarray.h b/src/include/storage/procarray.h
index d5fdfea6f20..c5f58b413db 100644
--- a/src/include/storage/procarray.h
+++ b/src/include/storage/procarray.h
@@ -26,6 +26,7 @@ extern void ProcArrayRemove(PGPROC *proc, TransactionId latestXid);
extern void ProcArrayEndTransaction(PGPROC *proc, TransactionId latestXid);
extern void ProcArrayClearTransaction(PGPROC *proc);
+extern void ProcArrayInitRecovery(TransactionId initializedUptoXID);
extern void ProcArrayApplyRecoveryInfo(RunningTransactions running);
extern void ProcArrayApplyXidAssignment(TransactionId topxid,
int nsubxids, TransactionId *subxids);