aboutsummaryrefslogtreecommitdiff
path: root/src/backend/access/transam/xlog.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/access/transam/xlog.c')
-rw-r--r--src/backend/access/transam/xlog.c49
1 files changed, 36 insertions, 13 deletions
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index b128bfda36d..5e59c1ab196 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -6625,12 +6625,20 @@ StartupXLOG(void)
errcontext.previous = error_context_stack;
error_context_stack = &errcontext;
- /* nextXid must be beyond record's xid */
+ /*
+ * ShmemVariableCache->nextXid must be beyond record's xid.
+ *
+ * We don't expect anyone else to modify nextXid, hence we
+ * don't need to hold a lock while examining it. We still
+ * acquire the lock to modify it, though.
+ */
if (TransactionIdFollowsOrEquals(record->xl_xid,
ShmemVariableCache->nextXid))
{
+ LWLockAcquire(XidGenLock, LW_EXCLUSIVE);
ShmemVariableCache->nextXid = record->xl_xid;
TransactionIdAdvance(ShmemVariableCache->nextXid);
+ LWLockRelease(XidGenLock);
}
/*
@@ -6656,6 +6664,7 @@ StartupXLOG(void)
TransactionIdIsValid(record->xl_xid))
RecordKnownAssignedTransactionIds(record->xl_xid);
+ /* Now apply the WAL record itself */
RmgrTable[record->xl_rmid].rm_redo(EndRecPtr, record);
/* Pop the error context stack */
@@ -6971,8 +6980,10 @@ StartupXLOG(void)
XLogCtl->ckptXid = ControlFile->checkPointCopy.nextXid;
/* also initialize latestCompletedXid, to nextXid - 1 */
+ LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
ShmemVariableCache->latestCompletedXid = ShmemVariableCache->nextXid;
TransactionIdRetreat(ShmemVariableCache->latestCompletedXid);
+ LWLockRelease(ProcArrayLock);
/*
* Start up the commit log and subtrans, if not already done for
@@ -8547,12 +8558,18 @@ xlog_redo(XLogRecPtr lsn, XLogRecord *record)
{
Oid nextOid;
+ /*
+ * We used to try to take the maximum of ShmemVariableCache->nextOid
+ * and the recorded nextOid, but that fails if the OID counter wraps
+ * around. Since no OID allocation should be happening during replay
+ * anyway, better to just believe the record exactly. We still take
+ * OidGenLock while setting the variable, just in case.
+ */
memcpy(&nextOid, XLogRecGetData(record), sizeof(Oid));
- if (ShmemVariableCache->nextOid < nextOid)
- {
- ShmemVariableCache->nextOid = nextOid;
- ShmemVariableCache->oidCount = 0;
- }
+ LWLockAcquire(OidGenLock, LW_EXCLUSIVE);
+ ShmemVariableCache->nextOid = nextOid;
+ ShmemVariableCache->oidCount = 0;
+ LWLockRelease(OidGenLock);
}
else if (info == XLOG_CHECKPOINT_SHUTDOWN)
{
@@ -8560,9 +8577,13 @@ xlog_redo(XLogRecPtr lsn, XLogRecord *record)
memcpy(&checkPoint, XLogRecGetData(record), sizeof(CheckPoint));
/* In a SHUTDOWN checkpoint, believe the counters exactly */
+ LWLockAcquire(XidGenLock, LW_EXCLUSIVE);
ShmemVariableCache->nextXid = checkPoint.nextXid;
+ LWLockRelease(XidGenLock);
+ LWLockAcquire(OidGenLock, LW_EXCLUSIVE);
ShmemVariableCache->nextOid = checkPoint.nextOid;
ShmemVariableCache->oidCount = 0;
+ LWLockRelease(OidGenLock);
MultiXactSetNextMXact(checkPoint.nextMulti,
checkPoint.nextMultiOffset);
SetTransactionIdLimit(checkPoint.oldestXid, checkPoint.oldestXidDB);
@@ -8575,7 +8596,7 @@ xlog_redo(XLogRecPtr lsn, XLogRecord *record)
if (InArchiveRecovery &&
!XLogRecPtrIsInvalid(ControlFile->backupStartPoint) &&
XLogRecPtrIsInvalid(ControlFile->backupEndPoint))
- ereport(ERROR,
+ ereport(PANIC,
(errmsg("online backup was canceled, recovery cannot continue")));
/*
@@ -8641,15 +8662,17 @@ xlog_redo(XLogRecPtr lsn, XLogRecord *record)
CheckPoint checkPoint;
memcpy(&checkPoint, XLogRecGetData(record), sizeof(CheckPoint));
- /* In an ONLINE checkpoint, treat the counters like NEXTOID */
+ /* In an ONLINE checkpoint, treat the XID counter as a minimum */
+ LWLockAcquire(XidGenLock, LW_EXCLUSIVE);
if (TransactionIdPrecedes(ShmemVariableCache->nextXid,
checkPoint.nextXid))
ShmemVariableCache->nextXid = checkPoint.nextXid;
- if (ShmemVariableCache->nextOid < checkPoint.nextOid)
- {
- ShmemVariableCache->nextOid = checkPoint.nextOid;
- ShmemVariableCache->oidCount = 0;
- }
+ LWLockRelease(XidGenLock);
+ /* ... but still treat OID counter as exact */
+ LWLockAcquire(OidGenLock, LW_EXCLUSIVE);
+ ShmemVariableCache->nextOid = checkPoint.nextOid;
+ ShmemVariableCache->oidCount = 0;
+ LWLockRelease(OidGenLock);
MultiXactAdvanceNextMXact(checkPoint.nextMulti,
checkPoint.nextMultiOffset);
if (TransactionIdPrecedes(ShmemVariableCache->oldestXid,