From 865728a2c30802af078ef248fea3ccde9c9ec4fc Mon Sep 17 00:00:00 2001 From: Heikki Linnakangas Date: Thu, 5 Feb 2009 14:28:31 +0200 Subject: [PATCH] Revert some more changes back the way it's in CVS HEAD, now that we do startup checkpoints again. --- src/backend/access/transam/xlog.c | 52 ++++++++++++++++++------------- src/backend/postmaster/bgwriter.c | 26 ++++------------ 2 files changed, 37 insertions(+), 41 deletions(-) diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index 67542b787f..0055e7aa6d 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -257,9 +257,8 @@ static XLogRecPtr RedoRecPtr; * ControlFileLock: must be held to read/update control file or create * new log file. * - * CheckpointLock: must be held to do a checkpoint (ensures only one - * checkpointer at a time; currently, with all checkpoints done by the - * bgwriter, this is just pro forma). + * CheckpointLock: must be held to do a checkpoint or restartpoint (ensures + * only one checkpointer at a time) * *---------- */ @@ -2790,7 +2789,7 @@ RestoreArchivedFile(char *path, const char *xlogfname, */ if (shutdown_requested && InRedo) { - /* XXX: Is EndRecPtr always the right value? */ + /* XXX: Is EndRecPtr always the right value here? */ UpdateMinRecoveryPoint(EndRecPtr); proc_exit(0); } @@ -4980,7 +4979,6 @@ StartupXLOG(void) CheckPoint checkPoint; bool wasShutdown; bool reachedStopPoint = false; - bool reachedMinRecoveryPoint = false; bool haveBackupLabel = false; XLogRecPtr RecPtr, LastRec, @@ -5273,6 +5271,7 @@ StartupXLOG(void) { bool recoveryContinue = true; bool recoveryApply = true; + bool reachedMinRecoveryPoint = false; ErrorContextCallback errcontext; /* use volatile pointer to prevent code rearrangement */ volatile XLogCtlData *xlogctl = XLogCtl; @@ -5414,7 +5413,6 @@ StartupXLOG(void) /* there are no WAL records following the checkpoint */ ereport(LOG, (errmsg("redo is not required"))); - reachedMinRecoveryPoint = true; } } @@ -5574,6 +5572,9 @@ StartupXLOG(void) */ PreallocXlogFiles(EndOfLog); + /* + * Okay, we're officially UP. + */ InRecovery = false; LWLockAcquire(ControlFileLock, LW_EXCLUSIVE); @@ -5926,9 +5927,9 @@ LogCheckpointStart(int flags, bool restartpoint) * for the main message, but what about all the flags? */ if (restartpoint) - msg = "restartpoint starting:%s%s%s%s%s%s%s"; + msg = "restartpoint starting:%s%s%s%s%s%s"; else - msg = "checkpoint starting:%s%s%s%s%s%s%s"; + msg = "checkpoint starting:%s%s%s%s%s%s"; elog(LOG, msg, (flags & CHECKPOINT_IS_SHUTDOWN) ? " shutdown" : "", @@ -6022,9 +6023,6 @@ CreateCheckPoint(int flags) /* * Acquire CheckpointLock to ensure only one checkpoint happens at a time. - * (This is just pro forma, since in the present system structure there is - * only one process that is allowed to issue checkpoints at any given - * time.) */ LWLockAcquire(CheckpointLock, LW_EXCLUSIVE); @@ -6257,10 +6255,11 @@ CreateCheckPoint(int flags) XLByteToSeg(ControlFile->checkPointCopy.redo, _logId, _logSeg); /* - * Update the control file. This also sets state to IN_DB_PRODUCTION - * if this is the first checkpoint after recovery. + * Update the control file. */ LWLockAcquire(ControlFileLock, LW_EXCLUSIVE); + if (shutdown) + ControlFile->state = DB_SHUTDOWNED; ControlFile->prevCheckPoint = ControlFile->checkPoint; ControlFile->checkPoint = ProcLastRecPtr; ControlFile->checkPointCopy = checkPoint; @@ -6311,9 +6310,11 @@ CreateCheckPoint(int flags) * Truncate pg_subtrans if possible. We can throw away all data before * the oldest XMIN of any running transaction. No future transaction will * attempt to reference any pg_subtrans entry older than that (see Asserts - * in subtrans.c). + * in subtrans.c). During recovery, though, we mustn't do this because + * StartupSUBTRANS hasn't been called yet. */ - TruncateSUBTRANS(GetOldestXmin(true, false)); + if (!InRecovery) + TruncateSUBTRANS(GetOldestXmin(true, false)); /* All real work is done, but log before releasing lock. */ if (log_checkpoints) @@ -6400,10 +6401,8 @@ CreateRestartPoint(int flags) volatile XLogCtlData *xlogctl = XLogCtl; /* - * Acquire CheckpointLock to ensure only one restartpoint happens at a - * time. (This is just pro forma, since in the present system structure - * there is only one process that is allowed to issue checkpoints or - * restart points at any given time.) + * Acquire CheckpointLock to ensure only one restartpoint or checkpoint + * happens at a time. */ LWLockAcquire(CheckpointLock, LW_EXCLUSIVE); @@ -6588,9 +6587,20 @@ xlog_redo(XLogRecPtr lsn, XLogRecord *record) ControlFile->checkPointCopy.nextXid = checkPoint.nextXid; /* - * TLI no longer changes at shutdown checkpoint, since as of 8.4, + * TLI may change in a shutdown checkpoint, but it shouldn't decrease * shutdown checkpoints only occur at shutdown. Much less confusing. */ + if (checkPoint.ThisTimeLineID != ThisTimeLineID) + { + if (checkPoint.ThisTimeLineID < ThisTimeLineID || + !list_member_int(expectedTLIs, + (int) checkPoint.ThisTimeLineID)) + ereport(PANIC, + (errmsg("unexpected timeline ID %u (after %u) in checkpoint record", + checkPoint.ThisTimeLineID, ThisTimeLineID))); + /* Following WAL records should be run with new TLI */ + ThisTimeLineID = checkPoint.ThisTimeLineID; + } RecoveryRestartPoint(&checkPoint); } @@ -6615,7 +6625,7 @@ xlog_redo(XLogRecPtr lsn, XLogRecord *record) ControlFile->checkPointCopy.nextXidEpoch = checkPoint.nextXidEpoch; ControlFile->checkPointCopy.nextXid = checkPoint.nextXid; - /* TLI must not change at a checkpoint */ + /* TLI should not change in an on-line checkpoint */ if (checkPoint.ThisTimeLineID != ThisTimeLineID) ereport(PANIC, (errmsg("unexpected timeline ID %u (should be %u) in checkpoint record", diff --git a/src/backend/postmaster/bgwriter.c b/src/backend/postmaster/bgwriter.c index d38e0c6452..58b982dac1 100644 --- a/src/backend/postmaster/bgwriter.c +++ b/src/backend/postmaster/bgwriter.c @@ -199,8 +199,6 @@ BackgroundWriterMain(void) sigjmp_buf local_sigjmp_buf; MemoryContext bgwriter_context; bool BgWriterRecoveryMode = true; - /* use volatile pointer to prevent code rearrangement */ - volatile BgWriterShmemStruct *bgs = BgWriterShmem; BgWriterShmem->bgwriter_pid = MyProcPid; am_bg_writer = true; @@ -359,20 +357,6 @@ BackgroundWriterMain(void) */ PG_SETMASK(&UnBlockSig); - /* - * If someone requested a checkpoint before we started up, process that. - * - * This check exists primarily for crash recovery: after the startup - * process is finished with WAL replay, it will request a checkpoint, but - * the background writer might not have started yet. This check will - * actually not notice a checkpoint that's been requested without any - * flags, but it's good enough for the startup checkpoint. - */ - SpinLockAcquire(&bgs->ckpt_lck); - if (bgs->ckpt_flags) - checkpoint_requested = true; - SpinLockRelease(&bgs->ckpt_lck); - /* * Loop forever */ @@ -415,7 +399,6 @@ BackgroundWriterMain(void) ExitOnAnyError = true; /* Close down the database */ ShutdownXLOG(0, 0); - /* Normal exit from the bgwriter is here */ proc_exit(0); /* done */ } @@ -440,9 +423,9 @@ BackgroundWriterMain(void) * Check if we've exited recovery. We do this after determining * whether to perform a checkpoint or not, to be sure that we * perform a real checkpoint and not a restartpoint, if someone - * (like the startup process!) requested a checkpoint immediately - * after exiting recovery. And we must have the right TimeLineID - * when we perform a checkpoint. + * requested a checkpoint immediately after exiting recovery. And + * we must have the right TimeLineID when we perform a checkpoint; + * IsRecoveryProcessingMode() initializes that as a side-effect. */ if (BgWriterRecoveryMode && !IsRecoveryProcessingMode()) { @@ -456,6 +439,9 @@ BackgroundWriterMain(void) */ if (do_checkpoint) { + /* use volatile pointer to prevent code rearrangement */ + volatile BgWriterShmemStruct *bgs = BgWriterShmem; + /* * Atomically fetch the request flags to figure out what kind of a * checkpoint we should perform, and increase the started-counter -- 2.39.5