From dbc08907e870a30a8a0264f2020933728a9e85f6 Mon Sep 17 00:00:00 2001 From: Heikki Linnakangas Date: Wed, 28 Jan 2009 11:47:28 +0200 Subject: [PATCH] Fix two bugs: minSafeStartPoint must never move backwards, and recoveryLogRestartpoints needs to be accessible to bgwriter. --- src/backend/access/transam/xlog.c | 42 ++++++++++++++++++++++--------- 1 file changed, 30 insertions(+), 12 deletions(-) diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index 2a645b26c1..30fea49397 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -147,10 +147,13 @@ static char *recoveryRestoreCommand = NULL; static bool recoveryTarget = false; static bool recoveryTargetExact = false; static bool recoveryTargetInclusive = true; -static bool recoveryLogRestartpoints = false; static TransactionId recoveryTargetXid; static TimestampTz recoveryTargetTime; static TimestampTz recoveryLastXTime = 0; +/* + * log_restartpoints is stored in shared memory because it needs to be + * accessed by bgwriter when it performs restartpoints + */ /* if recoveryStopsHere returns true, it saves actual stop xid/time here */ static TransactionId recoveryStopXid; @@ -346,6 +349,9 @@ typedef struct XLogCtlData XLogRecPtr lastCheckPointRecPtr; CheckPoint lastCheckPoint; + /* Should restartpoints be logged? Taken from recovery.conf */ + bool recoveryLogRestartpoints; + slock_t info_lck; /* locks shared variables shown above */ } XLogCtlData; @@ -2459,15 +2465,20 @@ XLogFileRead(uint32 log, uint32 seg, int emode) */ if (InArchiveRecovery) { - uint32 nextLog = log; - uint32 nextSeg = seg; + XLogRecPtr nextSegRecPtr; + uint32 nextLog = log; + uint32 nextSeg = seg; NextLogSeg(nextLog, nextSeg); + nextSegRecPtr.xlogid = nextLog; + nextSegRecPtr.xrecoff = nextSeg * XLogSegSize; LWLockAcquire(ControlFileLock, LW_EXCLUSIVE); - ControlFile->minSafeStartPoint.xlogid = nextLog; - ControlFile->minSafeStartPoint.xrecoff = nextSeg * XLogSegSize; - UpdateControlFile(); + if (XLByteLT(ControlFile->minSafeStartPoint, nextSegRecPtr)) + { + ControlFile->minSafeStartPoint = nextSegRecPtr; + UpdateControlFile(); + } LWLockRelease(ControlFileLock); } @@ -4654,7 +4665,7 @@ readRecoveryCommandFile(void) /* * does nothing if a recovery_target is not also set */ - if (!parse_bool(tok2, &recoveryLogRestartpoints)) + if (!parse_bool(tok2, &XLogCtl->recoveryLogRestartpoints)) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("parameter \"log_restartpoints\" requires a Boolean value"))); @@ -5229,12 +5240,19 @@ StartupXLOG(void) bool recoveryContinue = true; bool recoveryApply = true; ErrorContextCallback errcontext; + XLogRecPtr minSafeStartPoint; InRedo = true; ereport(LOG, (errmsg("redo starts at %X/%X", ReadRecPtr.xlogid, ReadRecPtr.xrecoff))); + /* + * Take a local copy of minSafeStartPoint at the beginning of + * recovery, because it's updated as we go. + */ + minSafeStartPoint = ControlFile->minSafeStartPoint; + /* * main redo apply loop */ @@ -5303,7 +5321,7 @@ StartupXLOG(void) * latest LSN that recovery could have reached prior to crash. */ if (!reachedSafeStartPoint && - XLByteLE(ControlFile->minSafeStartPoint, EndRecPtr) && + XLByteLE(minSafeStartPoint, EndRecPtr) && XLByteLE(ControlFile->minRecoveryPoint, EndRecPtr)) { reachedSafeStartPoint = true; @@ -6352,7 +6370,7 @@ CreateRestartPoint(int flags) return; } - if (recoveryLogRestartpoints) + if (XLogCtl->recoveryLogRestartpoints) { /* * Prepare to accumulate statistics. @@ -6383,15 +6401,15 @@ CreateRestartPoint(int flags) */ /* All real work is done, but log before releasing lock. */ - if (recoveryLogRestartpoints) + if (XLogCtl->recoveryLogRestartpoints) LogCheckpointEnd(flags, true); - ereport((recoveryLogRestartpoints ? LOG : DEBUG2), + ereport((XLogCtl->recoveryLogRestartpoints ? LOG : DEBUG2), (errmsg("recovery restart point at %X/%X", lastCheckPoint.redo.xlogid, lastCheckPoint.redo.xrecoff))); if (recoveryLastXTime) - ereport((recoveryLogRestartpoints ? LOG : DEBUG2), + ereport((XLogCtl->recoveryLogRestartpoints ? LOG : DEBUG2), (errmsg("last completed transaction was at log time %s", timestamptz_to_str(recoveryLastXTime)))); -- 2.39.5