if (InArchiveRecovery)
{
TLHistoryFileName(histfname, targetTLI);
- RestoreArchivedFile(path, histfname, "RECOVERYHISTORY", 0);
+ RestoreArchivedFile(path, histfname, "RECOVERYHISTORY", 0, false);
}
else
TLHistoryFilePath(path, targetTLI);
if (InArchiveRecovery)
{
TLHistoryFileName(histfname, probeTLI);
- RestoreArchivedFile(path, histfname, "RECOVERYHISTORY", 0);
+ RestoreArchivedFile(path, histfname, "RECOVERYHISTORY", 0, false);
}
else
TLHistoryFilePath(path, probeTLI);
if (InArchiveRecovery)
{
TLHistoryFileName(histfname, parentTLI);
- RestoreArchivedFile(path, histfname, "RECOVERYHISTORY", 0);
+ RestoreArchivedFile(path, histfname, "RECOVERYHISTORY", 0, false);
}
else
TLHistoryFilePath(path, parentTLI);
restoredFromArchive = RestoreArchivedFile(path, xlogfname,
"RECOVERYXLOG",
- XLogSegSize);
+ XLogSegSize,
+ InRedo);
if (!restoredFromArchive)
return -1;
break;
}
/*
- * Returns the redo pointer of the last restartpoint. This is the oldest
- * point in WAL that we still need, if we have to restart recovery. Returns
- * InvalidXLogRecPtr if we don't reliably know that point yet, that is,
- * before we have started WAL redo.
- *
- * This function only works in the startup process, and only while we are
- * in WAL redo. It's important to not return a value before redo has started,
- * to avoid deleting WAL files that we might still need, but there's no
- * fundamental reason why this couldn't return a valid value after redo has
- * finished, or in other processes. This is enough for the current usage,
- * however.
+ * Returns the redo pointer of the last checkpoint or restartpoint. This is
+ * the oldest point in WAL that we still need, if we have to restart recovery.
*/
void
GetOldestRestartPoint(XLogRecPtr *oldrecptr, TimeLineID *oldtli)
{
- if (InRedo)
- {
- LWLockAcquire(ControlFileLock, LW_SHARED);
- *oldrecptr = ControlFile->checkPointCopy.redo;
- *oldtli = ControlFile->checkPointCopy.ThisTimeLineID;
- LWLockRelease(ControlFileLock);
- }
- else
- {
- *oldrecptr = InvalidXLogRecPtr;
- *oldtli = 0;
- }
+ LWLockAcquire(ControlFileLock, LW_SHARED);
+ *oldrecptr = ControlFile->checkPointCopy.redo;
+ *oldtli = ControlFile->checkPointCopy.ThisTimeLineID;
+ LWLockRelease(ControlFileLock);
}
/*
* For fixed-size files, the caller may pass the expected size as an
* additional crosscheck on successful recovery. If the file size is not
* known, set expectedSize = 0.
+ *
+ * When 'cleanupEnabled' is false, refrain from deleting any old WAL segments
+ * in the archive. This is used when fetching the initial checkpoint record,
+ * when we are not yet sure how far back we need the WAL.
*/
bool
RestoreArchivedFile(char *path, const char *xlogfname,
- const char *recovername, off_t expectedSize)
+ const char *recovername, off_t expectedSize,
+ bool cleanupEnabled)
{
char xlogpath[MAXPGPATH];
char xlogRestoreCmd[MAXPGPATH];
* replication. All files earlier than this point can be deleted from the
* archive, though there is no requirement to do so.
*
- * We initialise this with the filename of an InvalidXLogRecPtr, which
- * will prevent the deletion of any WAL files from the archive because of
- * the alphabetic sorting property of WAL filenames.
+ * If cleanup is not enabled, initialise this with the filename of
+ * InvalidXLogRecPtr, which will prevent the deletion of any WAL files
+ * from the archive because of the alphabetic sorting property of WAL
+ * filenames.
*
* Once we have successfully located the redo pointer of the checkpoint
* from which we start recovery we never request a file prior to the redo
* flags to signify the point when we can begin deleting WAL files from
* the archive.
*/
- GetOldestRestartPoint(&restartRedoPtr, &restartTli);
- if (!XLogRecPtrIsInvalid(restartRedoPtr))
+ if (cleanupEnabled)
{
+ GetOldestRestartPoint(&restartRedoPtr, &restartTli);
XLByteToSeg(restartRedoPtr, restartSegNo);
XLogFileName(lastRestartPointFname, restartTli, restartSegNo);
/* we shouldn't need anything earlier than last restart point */
* Prototypes for functions in xlogarchive.c
*/
extern bool RestoreArchivedFile(char *path, const char *xlogfname,
- const char *recovername, off_t expectedSize);
+ const char *recovername, off_t expectedSize,
+ bool cleanupEnabled);
extern void ExecuteRecoveryCommand(char *command, char *commandName,
bool failOnerror);
extern void XLogArchiveNotify(const char *xlog);