/*
* SharedRecoveryProcessingMode indicates if we're still in crash or
- * archive recovery. It's checked by IsRecoveryProcessingMode()
+ * archive recovery. It's checked by IsRecoveryProcessingMode().
*/
bool SharedRecoveryProcessingMode;
/*
* During recovery, we keep a copy of the latest checkpoint record
- * here. It's used by the background writer when it wants to create
+ * here. Used by the background writer when it wants to create
* a restartpoint.
*
- * Protected by info_lck. XXX Is a spinlock too light-weight for these?
+ * Protected by info_lck.
*/
XLogRecPtr lastCheckPointRecPtr;
CheckPoint lastCheckPoint;
minRecoveryPoint = newMinRecoveryPoint;
}
- elog(DEBUG2, "updated min recovery point to %X/%X",
- minRecoveryPoint.xlogid, minRecoveryPoint.xrecoff);
+ ereport(DEBUG2,
+ (errmsg("updated min recovery point to %X/%X",
+ minRecoveryPoint.xlogid, minRecoveryPoint.xrecoff)));
}
LWLockRelease(ControlFileLock);
}
bool
XLogNeedsFlush(XLogRecPtr record)
{
- /* XLOG doesn't flushing during recovery */
+ /* XLOG doesn't need flushing during recovery */
if (IsRecoveryProcessingMode())
return false;
(errmsg_internal("executing restore command \"%s\"",
xlogRestoreCmd)));
-
/*
- * Set in_restore_command to indicate that we should just exit on
- * SIGTERM. We know that we're in a safe point to do that. Check
- * if we had already received the signal.
+ * Set in_restore_command to tell the signal handler that we should exit
+ * right away on SIGTERM. We know that we're in a safe point to do that.
+ * Check if we had already received the signal, so that we don't miss
+ * a shutdown request received just before this.
*/
in_restore_command = true;
if (shutdown_requested)
* On SIGTERM, assume we have received a fast shutdown request, and exit
* cleanly. It's pure chance whether we receive the SIGTERM first, or the
* child process. If we receive it first, the signal handler will call
- * proc_exit(0), otherwise we do it here. If we received SIGTERM for any
- * other reason, postmaster will perform an immediate shutdown when it
- * sees us exiting unexpectedly.
+ * proc_exit(0), otherwise we do it here. If we or the child process
+ * received SIGTERM for any other reason than a fast shutdown request,
+ * postmaster will perform an immediate shutdown when it sees us exiting
+ * unexpectedly.
*
* Per the Single Unix Spec, shells report exit status > 128 when a called
* command died on a signal. Also, 126 and 127 are used to report
/* use volatile pointer to prevent code rearrangement */
volatile XLogCtlData *xlogctl = XLogCtl;
- /* Update shared copy of replayEndRecPtr */
+ /* Update shared replayEndRecPtr */
SpinLockAcquire(&xlogctl->info_lck);
xlogctl->replayEndRecPtr = ReadRecPtr;
SpinLockRelease(&xlogctl->info_lck);
/*
* Let postmaster know we've started redo now, so that it can
- * launch bgwriter. We don't bother during crash recovery; we can
- * only perform restartpoints during archive recovery anyway. And
- * we'd like to keep crash recovery simple, to avoid introducing
- * bugs into that codepath that could stop you from recovering.
+ * launch bgwriter to perform restartpoints. We don't bother
+ * during crash recovery as restartpoints can only be performed
+ * during archive recovery. And we'd like to keep crash recovery
+ * simple, to avoid introducing bugs that could you from
+ * recovering after crash.
*
- * After this point, we can no longer assume that there's no other
- * processes running concurrently.
+ * After this point, we can no longer assume that we're the only
+ * process in addition to postmaster!
*/
if (InArchiveRecovery && IsUnderPostmaster)
SendPostmasterSignal(PMSIGNAL_RECOVERY_STARTED);
TransactionIdAdvance(ShmemVariableCache->nextXid);
}
- /* Update shared copy of replayEndRecPtr */
+ /*
+ * Update shared replayEndRecPtr before replaying this
+ * record, so that XLogFlush will update minRecoveryPoint
+ * correctly.
+ */
SpinLockAcquire(&xlogctl->info_lck);
xlogctl->replayEndRecPtr = EndRecPtr;
SpinLockRelease(&xlogctl->info_lck);
(errmsg("requested recovery stop point is before consistent recovery point")));
else /* ran off end of WAL */
ereport(FATAL,
- (errmsg("WAL ended before a consistent state was reached")));
+ (errmsg("WAL ends before consistent recovery point")));
}
/*
oldestActiveXID = PrescanPreparedTransactions();
/*
- * Allow writing WAL for us. But not for other backends! That's done
- * after writing the shutdown checkpoint and finishing recovery.
+ * Allow writing WAL for us, so that we can create a checkpoint record.
+ * But not yet for other backends!
*/
LocalRecoveryProcessingMode = false;
/*
* Acquire CheckpointLock to ensure only one checkpoint happens at a time.
+ * During normal operation, bgwriter is the only process that creates
+ * checkpoints, but at the end archive recovery, the bgwriter can be busy
+ * creating a restartpoint while the startup process tries to perform the
+ * startup checkpoint.
*/
if (!LWLockConditionalAcquire(CheckpointLock, LW_EXCLUSIVE))
{
- /*
- * This should only happen at the end of archive recovery.
- * During normal operation, only bgwriter creates checkpoints.
- */
Assert(InRecovery);
/*
* buffers in this restartpoint can take some time, but that time is
* saved from the upcoming checkpoint so the net effect is zero.
*/
- elog(DEBUG2, "hurrying in-progress restartpoint");
+ ereport(DEBUG2, (errmsg("hurrying in-progress restartpoint")));
RequestCheckpoint(CHECKPOINT_IMMEDIATE | CHECKPOINT_WAIT);
LWLockAcquire(CheckpointLock, LW_EXCLUSIVE);
* 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). During recovery, though, we mustn't do this because
+ * in subtrans.c). During recovery, though, we mustn't do this because
* StartupSUBTRANS hasn't been called yet.
*/
if (!InRecovery)