/*
* ThisTimeLineID will be same in all backends --- it identifies current
- * WAL timeline for the database system. Zero is never valid, so we start
- * with that to spot any errors.
+ * WAL timeline for the database system.
*/
TimeLineID ThisTimeLineID = 0;
*
* is info_lck spinlock a bit too light-weight to protect this?
*/
- XLogRecPtr lastCheckPointPtr;
+ XLogRecPtr lastCheckPointRecPtr;
CheckPoint lastCheckPoint;
slock_t info_lck; /* locks shared variables shown above */
}
/*
- * Set a recovery restart point if appropriate.
- * This function is called each time a checkpoint record is read from XLOG.
+ * Store checkpoint record in shared memory, so that it can be used as a
+ * restartpoint. This function is called each time a checkpoint record is
+ * read from XLOG.
*/
static void
RecoveryRestartPoint(const CheckPoint *checkPoint)
}
}
+ /*
+ * Copy the checkpoint record to shared memory, so that bgwriter can
+ * use it the next time it wants to perform a restartpoint.
+ */
SpinLockAcquire(&xlogctl->info_lck);
- XLogCtl->lastCheckPointPtr = ReadRecPtr;
+ XLogCtl->lastCheckPointRecPtr = ReadRecPtr;
memcpy(&XLogCtl->lastCheckPoint, checkPoint, sizeof(CheckPoint));
SpinLockRelease(&xlogctl->info_lck);
* This is similar to CreateCheckPoint, but is used during WAL recovery
* to establish a point from which recovery can roll forward without
* replaying the entire recovery log.
- *
- * As of 8.4, RestartPoints are always created by the bgwriter
- * once we have reachedSafeStartPoint.
*/
void
CreateRestartPoint(int flags)
{
- CheckPoint restartPoint;
- XLogRecPtr redoRecPtr;
+ XLogRecPtr lastCheckPointRecPtr;
+ CheckPoint lastCheckPoint;
/* use volatile pointer to prevent code rearrangement */
volatile XLogCtlData *xlogctl = XLogCtl;
+ /* Get the a local copy of the last checkpoint record. */
+ SpinLockAcquire(&xlogctl->info_lck);
+ lastCheckPointRecPtr = xlogctl->lastCheckPointRecPtr;
+ memcpy(&lastCheckPoint, &XLogCtl->lastCheckPoint, sizeof(CheckPoint));
+ SpinLockRelease(&xlogctl->info_lck);
+
/*
* If the last checkpoint record we've replayed is already our last
* restartpoint, we're done.
*/
- if (XLByteLE(redoRecPtr, ControlFile->checkPointCopy.redo))
+ if (XLByteLE(lastCheckPoint.redo, ControlFile->checkPointCopy.redo))
{
ereport(DEBUG2,
(errmsg("skipping restartpoint, already performed at %X/%X",
- restartPoint.redo.xlogid, restartPoint.redo.xrecoff)));
+ lastCheckPoint.redo.xlogid, lastCheckPoint.redo.xrecoff)));
return;
}
- if (recoveryLogRestartpoints)
- {
- /*
- * Prepare to accumulate statistics.
- */
-
- MemSet(&CheckpointStats, 0, sizeof(CheckpointStats));
- CheckpointStats.ckpt_start_t = GetCurrentTimestamp();
-
- LogCheckpointStart(flags, true);
- }
-
/*
* Acquire CheckpointLock to ensure only one restartpoint happens at a time.
* We rely on this lock to ensure that the startup process doesn't exit
return;
}
- SpinLockAcquire(&xlogctl->info_lck);
- redoRecPtr = xlogctl->lastCheckPointPtr;
- memcpy(&restartPoint, &XLogCtl->lastCheckPoint, sizeof(CheckPoint));
- SpinLockRelease(&xlogctl->info_lck);
+ if (recoveryLogRestartpoints)
+ {
+ /*
+ * Prepare to accumulate statistics.
+ */
+ MemSet(&CheckpointStats, 0, sizeof(CheckpointStats));
+ CheckpointStats.ckpt_start_t = GetCurrentTimestamp();
+
+ LogCheckpointStart(flags, true);
+ }
- CheckPointGuts(restartPoint.redo, flags);
+ CheckPointGuts(lastCheckPoint.redo, flags);
/*
* Update pg_control, using current time
*/
LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
ControlFile->prevCheckPoint = ControlFile->checkPoint;
- ControlFile->checkPoint = redoRecPtr;
- ControlFile->checkPointCopy = restartPoint;
+ ControlFile->checkPoint = lastCheckPointRecPtr;
+ ControlFile->checkPointCopy = lastCheckPoint;
ControlFile->time = (pg_time_t) time(NULL);
UpdateControlFile();
LWLockRelease(ControlFileLock);
ereport((recoveryLogRestartpoints ? LOG : DEBUG2),
(errmsg("recovery restart point at %X/%X",
- restartPoint.redo.xlogid, restartPoint.redo.xrecoff)));
+ lastCheckPoint.redo.xlogid, lastCheckPoint.redo.xrecoff)));
if (recoveryLastXTime)
ereport((recoveryLogRestartpoints ? LOG : DEBUG2),