#include "access/xlogdefs.h"
#include "datatype/timestamp.h"
#include "lib/stringinfo.h"
#include "pgtime.h"
#include "storage/block.h"
#include "storage/relfilenode.h"
Go to the source code of this file.
Data Structures | |
struct | BkpBlock |
struct | XLogPageHeaderData |
struct | XLogLongPageHeaderData |
struct | xl_parameter_change |
struct | xl_restore_point |
struct | xl_end_of_recovery |
struct | RmgrData |
Defines | |
#define | XLOG_PAGE_MAGIC 0xD075 |
#define | SizeOfXLogShortPHD MAXALIGN(sizeof(XLogPageHeaderData)) |
#define | SizeOfXLogLongPHD MAXALIGN(sizeof(XLogLongPageHeaderData)) |
#define | XLP_FIRST_IS_CONTRECORD 0x0001 |
#define | XLP_LONG_HEADER 0x0002 |
#define | XLP_BKP_REMOVABLE 0x0004 |
#define | XLP_ALL_FLAGS 0x0007 |
#define | XLogPageHeaderSize(hdr) (((hdr)->xlp_info & XLP_LONG_HEADER) ? SizeOfXLogLongPHD : SizeOfXLogShortPHD) |
#define | XLogSegSize ((uint32) XLOG_SEG_SIZE) |
#define | XLogSegmentsPerXLogId (UINT64CONST(0x100000000) / XLOG_SEG_SIZE) |
#define | XLogSegNoOffsetToRecPtr(segno, offset, dest) (dest) = (segno) * XLOG_SEG_SIZE + (offset) |
#define | XLByteToSeg(xlrp, logSegNo) logSegNo = (xlrp) / XLogSegSize |
#define | XLByteToPrevSeg(xlrp, logSegNo) logSegNo = ((xlrp) - 1) / XLogSegSize |
#define | XLByteInSeg(xlrp, logSegNo) (((xlrp) / XLogSegSize) == (logSegNo)) |
#define | XLByteInPrevSeg(xlrp, logSegNo) ((((xlrp) - 1) / XLogSegSize) == (logSegNo)) |
#define | XRecOffIsValid(xlrp) ((xlrp) % XLOG_BLCKSZ >= SizeOfXLogShortPHD) |
#define | XLOGDIR "pg_xlog" |
#define | XLOG_CONTROL_FILE "global/pg_control" |
#define | MAXFNAMELEN 64 |
#define | XLogFileName(fname, tli, logSegNo) |
#define | XLogFromFileName(fname, tli, logSegNo) |
#define | XLogFilePath(path, tli, logSegNo) |
#define | TLHistoryFileName(fname, tli) snprintf(fname, MAXFNAMELEN, "%08X.history", tli) |
#define | TLHistoryFilePath(path, tli) snprintf(path, MAXPGPATH, XLOGDIR "/%08X.history", tli) |
#define | StatusFilePath(path, xlog, suffix) snprintf(path, MAXPGPATH, XLOGDIR "/archive_status/%s%s", xlog, suffix) |
#define | BackupHistoryFileName(fname, tli, logSegNo, offset) |
#define | BackupHistoryFilePath(path, tli, logSegNo, offset) |
Typedefs | |
typedef struct BkpBlock | BkpBlock |
typedef struct XLogPageHeaderData | XLogPageHeaderData |
typedef XLogPageHeaderData * | XLogPageHeader |
typedef struct XLogLongPageHeaderData | XLogLongPageHeaderData |
typedef XLogLongPageHeaderData * | XLogLongPageHeader |
typedef struct xl_parameter_change | xl_parameter_change |
typedef struct xl_restore_point | xl_restore_point |
typedef struct xl_end_of_recovery | xl_end_of_recovery |
typedef struct RmgrData | RmgrData |
Functions | |
pg_time_t | GetLastSegSwitchTime (void) |
XLogRecPtr | RequestXLogSwitch (void) |
void | GetOldestRestartPoint (XLogRecPtr *oldrecptr, TimeLineID *oldtli) |
bool | RestoreArchivedFile (char *path, const char *xlogfname, const char *recovername, off_t expectedSize, bool cleanupEnabled) |
void | ExecuteRecoveryCommand (char *command, char *commandName, bool failOnerror) |
void | KeepFileRestoredFromArchive (char *path, char *xlogfname) |
void | XLogArchiveNotify (const char *xlog) |
void | XLogArchiveNotifySeg (XLogSegNo segno) |
void | XLogArchiveForceDone (const char *xlog) |
bool | XLogArchiveCheckDone (const char *xlog) |
bool | XLogArchiveIsBusy (const char *xlog) |
void | XLogArchiveCleanup (const char *xlog) |
Variables | |
const RmgrData | RmgrTable [] |
bool | ArchiveRecoveryRequested |
bool | InArchiveRecovery |
bool | StandbyMode |
char * | recoveryRestoreCommand |
#define BackupHistoryFileName | ( | fname, | ||
tli, | ||||
logSegNo, | ||||
offset | ||||
) |
snprintf(fname, MAXFNAMELEN, "%08X%08X%08X.%08X.backup", tli, \ (uint32) ((logSegNo) / XLogSegmentsPerXLogId), \ (uint32) ((logSegNo) % XLogSegmentsPerXLogId), offset)
Definition at line 191 of file xlog_internal.h.
Referenced by do_pg_stop_backup().
#define BackupHistoryFilePath | ( | path, | ||
tli, | ||||
logSegNo, | ||||
offset | ||||
) |
snprintf(path, MAXPGPATH, XLOGDIR "/%08X%08X%08X.%08X.backup", tli, \ (uint32) ((logSegNo) / XLogSegmentsPerXLogId), \ (uint32) ((logSegNo) % XLogSegmentsPerXLogId), offset)
Definition at line 196 of file xlog_internal.h.
Referenced by do_pg_stop_backup().
#define MAXFNAMELEN 64 |
Definition at line 162 of file xlog_internal.h.
Referenced by pg_create_restore_point(), pgarch_archiveXlog(), readRecoveryCommandFile(), recoveryStopsHere(), XLogFileNameP(), XLogFileRead(), and XLogRestorePoint().
#define SizeOfXLogLongPHD MAXALIGN(sizeof(XLogLongPageHeaderData)) |
Definition at line 96 of file xlog_internal.h.
Referenced by RewriteControlFile(), and XLogInsert().
#define SizeOfXLogShortPHD MAXALIGN(sizeof(XLogPageHeaderData)) |
Definition at line 79 of file xlog_internal.h.
Referenced by ReadPageInternal(), and XLogReadRecord().
#define StatusFilePath | ( | path, | ||
xlog, | ||||
suffix | ||||
) | snprintf(path, MAXPGPATH, XLOGDIR "/archive_status/%s%s", xlog, suffix) |
Definition at line 188 of file xlog_internal.h.
Referenced by pgarch_archiveDone(), XLogArchiveCheckDone(), XLogArchiveCleanup(), XLogArchiveForceDone(), XLogArchiveIsBusy(), and XLogArchiveNotify().
#define TLHistoryFileName | ( | fname, | ||
tli | ||||
) | snprintf(fname, MAXFNAMELEN, "%08X.history", tli) |
Definition at line 182 of file xlog_internal.h.
Referenced by existsTimeLineHistory(), existsTimeLineHistoryFile(), readTimeLineHistory(), restoreTimeLineHistoryFiles(), SendTimeLineHistory(), WalRcvFetchTimeLineHistoryFiles(), writeTimeLineHistory(), and writeTimeLineHistoryFile().
#define TLHistoryFilePath | ( | path, | ||
tli | ||||
) | snprintf(path, MAXPGPATH, XLOGDIR "/%08X.history", tli) |
Definition at line 185 of file xlog_internal.h.
Referenced by existsTimeLineHistory(), readTimeLineHistory(), SendTimeLineHistory(), writeTimeLineHistory(), and writeTimeLineHistoryFile().
#define XLByteInPrevSeg | ( | xlrp, | ||
logSegNo | ||||
) | ((((xlrp) - 1) / XLogSegSize) == (logSegNo)) |
Definition at line 145 of file xlog_internal.h.
Referenced by XLogBackgroundFlush(), and XLogWrite().
#define XLByteInSeg | ( | xlrp, | ||
logSegNo | ||||
) | (((xlrp) / XLogSegSize) == (logSegNo)) |
Definition at line 142 of file xlog_internal.h.
Referenced by main(), XLogDumpXLogRead(), XLogPageRead(), XLogRead(), and XLogWalRcvWrite().
#define XLByteToPrevSeg | ( | xlrp, | ||
logSegNo | ||||
) | logSegNo = ((xlrp) - 1) / XLogSegSize |
Definition at line 133 of file xlog_internal.h.
Referenced by do_pg_stop_backup(), perform_base_backup(), pg_xlogfile_name(), pg_xlogfile_name_offset(), PreallocXlogFiles(), RemoveOldXlogFiles(), StartupXLOG(), and XLogWrite().
#define XLByteToSeg | ( | xlrp, | ||
logSegNo | ||||
) | logSegNo = (xlrp) / XLogSegSize |
Definition at line 130 of file xlog_internal.h.
Referenced by CreateCheckPoint(), CreateRestartPoint(), do_pg_start_backup(), do_pg_stop_backup(), ExecuteRecoveryCommand(), KeepLogSeg(), main(), open_walfile(), perform_base_backup(), ReadPageInternal(), ReadRecord(), RestoreArchivedFile(), ValidXLogPageHeader(), XLogCheckpointNeeded(), XLogDumpXLogRead(), XLogPageRead(), XLogRead(), and XLogWalRcvWrite().
#define XLOG_CONTROL_FILE "global/pg_control" |
Definition at line 156 of file xlog_internal.h.
Referenced by perform_base_backup(), ReadControlFile(), RewriteControlFile(), UpdateControlFile(), and WriteControlFile().
#define XLOG_PAGE_MAGIC 0xD075 |
Definition at line 58 of file xlog_internal.h.
Referenced by ValidXLogPageHeader().
#define XLOGDIR "pg_xlog" |
Definition at line 155 of file xlog_internal.h.
Referenced by CleanupBackupHistory(), exitArchiveRecovery(), FindEndOfXLOG(), fuzzy_open_file(), KeepFileRestoredFromArchive(), KillExistingXLOG(), perform_base_backup(), pgarch_archiveXlog(), pgarch_readyXlog(), RemoveOldXlogFiles(), RestoreArchivedFile(), ValidateXLOGDirectoryStructure(), writeTimeLineHistory(), writeTimeLineHistoryFile(), XLogArchiveIsBusy(), XLogFileCopy(), XLogFileInit(), and XLogFileRead().
#define XLogFileName | ( | fname, | ||
tli, | ||||
logSegNo | ||||
) |
snprintf(fname, MAXFNAMELEN, "%08X%08X%08X", tli, \ (uint32) ((logSegNo) / XLogSegmentsPerXLogId), \ (uint32) ((logSegNo) % XLogSegmentsPerXLogId))
Definition at line 164 of file xlog_internal.h.
#define XLogFilePath | ( | path, | ||
tli, | ||||
logSegNo | ||||
) |
snprintf(path, MAXPGPATH, XLOGDIR "/%08X%08X%08X", tli, \ (uint32) ((logSegNo) / XLogSegmentsPerXLogId), \ (uint32) ((logSegNo) % XLogSegmentsPerXLogId))
Definition at line 177 of file xlog_internal.h.
Referenced by InstallXLogFileSegment(), WriteEmptyXLOG(), XLogFileCopy(), XLogFileInit(), XLogFileOpen(), XLogFileRead(), XLogFileReadAnyTLI(), and XLogRead().
#define XLogFromFileName | ( | fname, | ||
tli, | ||||
logSegNo | ||||
) |
do { \ uint32 log; \ uint32 seg; \ sscanf(fname, "%08X%08X%08X", tli, &log, &seg); \ *logSegNo = (uint64) log * XLogSegmentsPerXLogId + seg; \ } while (0)
Definition at line 169 of file xlog_internal.h.
Referenced by main(), perform_base_backup(), and UpdateLastRemovedPtr().
#define XLogPageHeaderSize | ( | hdr | ) | (((hdr)->xlp_info & XLP_LONG_HEADER) ? SizeOfXLogLongPHD : SizeOfXLogShortPHD) |
Definition at line 109 of file xlog_internal.h.
Referenced by ReadPageInternal(), and XLogReadRecord().
#define XLogSegmentsPerXLogId (UINT64CONST(0x100000000) / XLOG_SEG_SIZE) |
Definition at line 117 of file xlog_internal.h.
#define XLogSegNoOffsetToRecPtr | ( | segno, | ||
offset, | ||||
dest | ||||
) | (dest) = (segno) * XLOG_SEG_SIZE + (offset) |
Definition at line 119 of file xlog_internal.h.
Referenced by FindStreamingStart(), main(), RewriteControlFile(), and ValidXLogPageHeader().
#define XLogSegSize ((uint32) XLOG_SEG_SIZE) |
Definition at line 116 of file xlog_internal.h.
Referenced by AdvanceXLInsertBuffer(), BootStrapXLOG(), CheckArchiveTimeout(), do_pg_stop_backup(), FindEndOfXLOG(), IsCheckpointOnSchedule(), main(), open_walfile(), perform_base_backup(), PreallocXlogFiles(), RequestXLogStreaming(), StartupXLOG(), ValidXLogPageHeader(), XLogDumpXLogRead(), XLogFileRead(), XLogInsert(), XLogPageRead(), XLogRead(), XLogReadRecord(), XLogWalRcvWrite(), and XLogWrite().
#define XLP_ALL_FLAGS 0x0007 |
Definition at line 107 of file xlog_internal.h.
Referenced by ValidXLogPageHeader().
#define XLP_BKP_REMOVABLE 0x0004 |
Definition at line 105 of file xlog_internal.h.
#define XLP_FIRST_IS_CONTRECORD 0x0001 |
Definition at line 101 of file xlog_internal.h.
Referenced by XLogReadRecord().
#define XLP_LONG_HEADER 0x0002 |
Definition at line 103 of file xlog_internal.h.
Referenced by ValidXLogPageHeader().
#define XRecOffIsValid | ( | xlrp | ) | ((xlrp) % XLOG_BLCKSZ >= SizeOfXLogShortPHD) |
Definition at line 149 of file xlog_internal.h.
Referenced by ReadCheckpointRecord(), StartupXLOG(), and XLogReadRecord().
typedef struct xl_end_of_recovery xl_end_of_recovery |
typedef struct xl_parameter_change xl_parameter_change |
typedef struct xl_restore_point xl_restore_point |
typedef XLogLongPageHeaderData* XLogLongPageHeader |
Definition at line 98 of file xlog_internal.h.
typedef struct XLogLongPageHeaderData XLogLongPageHeaderData |
typedef XLogPageHeaderData* XLogPageHeader |
Definition at line 81 of file xlog_internal.h.
typedef struct XLogPageHeaderData XLogPageHeaderData |
void ExecuteRecoveryCommand | ( | char * | command, | |
char * | commandName, | |||
bool | failOnerror | |||
) |
Definition at line 330 of file xlogarchive.c.
References Assert, DEBUG3, ereport, errmsg(), errmsg_internal(), FATAL, GetOldestRestartPoint(), MAXPGPATH, signaled, StrNCpy, system(), WARNING, WEXITSTATUS, WIFSIGNALED, XLByteToSeg, and XLogFileName.
Referenced by CreateRestartPoint(), and StartupXLOG().
{ char xlogRecoveryCmd[MAXPGPATH]; char lastRestartPointFname[MAXPGPATH]; char *dp; char *endp; const char *sp; int rc; bool signaled; XLogSegNo restartSegNo; XLogRecPtr restartRedoPtr; TimeLineID restartTli; Assert(command && commandName); /* * Calculate the archive file cutoff point for use during log shipping * replication. All files earlier than this point can be deleted from the * archive, though there is no requirement to do so. */ GetOldestRestartPoint(&restartRedoPtr, &restartTli); XLByteToSeg(restartRedoPtr, restartSegNo); XLogFileName(lastRestartPointFname, restartTli, restartSegNo); /* * construct the command to be executed */ dp = xlogRecoveryCmd; endp = xlogRecoveryCmd + MAXPGPATH - 1; *endp = '\0'; for (sp = command; *sp; sp++) { if (*sp == '%') { switch (sp[1]) { case 'r': /* %r: filename of last restartpoint */ sp++; StrNCpy(dp, lastRestartPointFname, endp - dp); dp += strlen(dp); break; case '%': /* convert %% to a single % */ sp++; if (dp < endp) *dp++ = *sp; break; default: /* otherwise treat the % as not special */ if (dp < endp) *dp++ = *sp; break; } } else { if (dp < endp) *dp++ = *sp; } } *dp = '\0'; ereport(DEBUG3, (errmsg_internal("executing %s \"%s\"", commandName, command))); /* * execute the constructed command */ rc = system(xlogRecoveryCmd); if (rc != 0) { /* * If the failure was due to any sort of signal, it's best to punt and * abort recovery. See also detailed comments on signals in * RestoreArchivedFile(). */ signaled = WIFSIGNALED(rc) || WEXITSTATUS(rc) > 125; ereport((signaled && failOnSignal) ? FATAL : WARNING, /*------ translator: First %s represents a recovery.conf parameter name like "recovery_end_command", and the 2nd is the value of that parameter. */ (errmsg("%s \"%s\": return code %d", commandName, command, rc))); } }
pg_time_t GetLastSegSwitchTime | ( | void | ) |
Definition at line 6529 of file xlog.c.
References XLogCtlWrite::lastSegSwitchTime, LW_SHARED, LWLockAcquire(), LWLockRelease(), WALWriteLock, and XLogCtlData::Write.
Referenced by CheckArchiveTimeout().
{ pg_time_t result; /* Need WALWriteLock, but shared lock is sufficient */ LWLockAcquire(WALWriteLock, LW_SHARED); result = XLogCtl->Write.lastSegSwitchTime; LWLockRelease(WALWriteLock); return result; }
void GetOldestRestartPoint | ( | XLogRecPtr * | oldrecptr, | |
TimeLineID * | oldtli | |||
) |
Definition at line 9159 of file xlog.c.
References ControlFileData::checkPointCopy, ControlFileLock, LW_SHARED, LWLockAcquire(), LWLockRelease(), CheckPoint::redo, and CheckPoint::ThisTimeLineID.
Referenced by ExecuteRecoveryCommand(), and RestoreArchivedFile().
{ LWLockAcquire(ControlFileLock, LW_SHARED); *oldrecptr = ControlFile->checkPointCopy.redo; *oldtli = ControlFile->checkPointCopy.ThisTimeLineID; LWLockRelease(ControlFileLock); }
void KeepFileRestoredFromArchive | ( | char * | path, | |
char * | xlogfname | |||
) |
Definition at line 426 of file xlogarchive.c.
References ereport, errcode_for_file_access(), errmsg(), ERROR, FATAL, MAXPGPATH, snprintf(), unlink(), WalSndRqstFileReload(), WalSndWakeup(), XLogArchiveForceDone(), and XLOGDIR.
Referenced by readTimeLineHistory(), restoreTimeLineHistoryFiles(), and XLogFileRead().
{ char xlogfpath[MAXPGPATH]; bool reload = false; struct stat statbuf; snprintf(xlogfpath, MAXPGPATH, XLOGDIR "/%s", xlogfname); if (stat(xlogfpath, &statbuf) == 0) { char oldpath[MAXPGPATH]; #ifdef WIN32 static unsigned int deletedcounter = 1; /* * On Windows, if another process (e.g a walsender process) holds * the file open in FILE_SHARE_DELETE mode, unlink will succeed, * but the file will still show up in directory listing until the * last handle is closed, and we cannot rename the new file in its * place until that. To avoid that problem, rename the old file to * a temporary name first. Use a counter to create a unique * filename, because the same file might be restored from the * archive multiple times, and a walsender could still be holding * onto an old deleted version of it. */ snprintf(oldpath, MAXPGPATH, "%s.deleted%u", xlogfpath, deletedcounter++); if (rename(xlogfpath, oldpath) != 0) { ereport(ERROR, (errcode_for_file_access(), errmsg("could not rename file \"%s\" to \"%s\": %m", xlogfpath, oldpath))); } #else strncpy(oldpath, xlogfpath, MAXPGPATH); #endif if (unlink(oldpath) != 0) ereport(FATAL, (errcode_for_file_access(), errmsg("could not remove file \"%s\": %m", xlogfpath))); reload = true; } if (rename(path, xlogfpath) < 0) ereport(ERROR, (errcode_for_file_access(), errmsg("could not rename file \"%s\" to \"%s\": %m", path, xlogfpath))); /* * Create .done file forcibly to prevent the restored segment from * being archived again later. */ XLogArchiveForceDone(xlogfname); /* * If the existing file was replaced, since walsenders might have it * open, request them to reload a currently-open segment. This is only * required for WAL segments, walsenders don't hold other files open, but * there's no harm in doing this too often, and we don't know what kind * of a file we're dealing with here. */ if (reload) WalSndRqstFileReload(); /* * Signal walsender that new WAL has arrived. Again, this isn't necessary * if we restored something other than a WAL segment, but it does no harm * either. */ WalSndWakeup(); }
XLogRecPtr RequestXLogSwitch | ( | void | ) |
Definition at line 7596 of file xlog.c.
References XLogRecData::buffer, XLogRecData::data, XLogRecData::len, XLogRecData::next, XLOG_SWITCH, and XLogInsert().
Referenced by CheckArchiveTimeout(), do_pg_start_backup(), do_pg_stop_backup(), pg_switch_xlog(), and ShutdownXLOG().
{ XLogRecPtr RecPtr; XLogRecData rdata; /* XLOG SWITCH, alone among xlog record types, has no data */ rdata.buffer = InvalidBuffer; rdata.data = NULL; rdata.len = 0; rdata.next = NULL; RecPtr = XLogInsert(RM_XLOG_ID, XLOG_SWITCH, &rdata); return RecPtr; }
bool RestoreArchivedFile | ( | char * | path, | |
const char * | xlogfname, | |||
const char * | recovername, | |||
off_t | expectedSize, | |||
bool | cleanupEnabled | |||
) |
Definition at line 52 of file xlogarchive.c.
References Assert, DEBUG2, DEBUG3, elevel, ereport, errcode_for_file_access(), errmsg(), errmsg_internal(), FATAL, GetOldestRestartPoint(), LOG, make_native_path(), MAXPGPATH, NULL, PostRestoreCommand(), PreRestoreCommand(), proc_exit(), recoveryRestoreCommand, signaled, snprintf(), StandbyMode, StrNCpy, system(), unlink(), WEXITSTATUS, WIFSIGNALED, WTERMSIG, XLByteToSeg, XLOGDIR, and XLogFileName.
Referenced by existsTimeLineHistory(), readTimeLineHistory(), restoreTimeLineHistoryFiles(), writeTimeLineHistory(), and XLogFileRead().
{ char xlogpath[MAXPGPATH]; char xlogRestoreCmd[MAXPGPATH]; char lastRestartPointFname[MAXPGPATH]; char *dp; char *endp; const char *sp; int rc; bool signaled; struct stat stat_buf; XLogSegNo restartSegNo; XLogRecPtr restartRedoPtr; TimeLineID restartTli; /* In standby mode, restore_command might not be supplied */ if (recoveryRestoreCommand == NULL) goto not_available; /* * When doing archive recovery, we always prefer an archived log file even * if a file of the same name exists in XLOGDIR. The reason is that the * file in XLOGDIR could be an old, un-filled or partly-filled version * that was copied and restored as part of backing up $PGDATA. * * We could try to optimize this slightly by checking the local copy * lastchange timestamp against the archived copy, but we have no API to * do this, nor can we guarantee that the lastchange timestamp was * preserved correctly when we copied to archive. Our aim is robustness, * so we elect not to do this. * * If we cannot obtain the log file from the archive, however, we will try * to use the XLOGDIR file if it exists. This is so that we can make use * of log segments that weren't yet transferred to the archive. * * Notice that we don't actually overwrite any files when we copy back * from archive because the restore_command may inadvertently * restore inappropriate xlogs, or they may be corrupt, so we may wish to * fallback to the segments remaining in current XLOGDIR later. The * copy-from-archive filename is always the same, ensuring that we don't * run out of disk space on long recoveries. */ snprintf(xlogpath, MAXPGPATH, XLOGDIR "/%s", recovername); /* * Make sure there is no existing file named recovername. */ if (stat(xlogpath, &stat_buf) != 0) { if (errno != ENOENT) ereport(FATAL, (errcode_for_file_access(), errmsg("could not stat file \"%s\": %m", xlogpath))); } else { if (unlink(xlogpath) != 0) ereport(FATAL, (errcode_for_file_access(), errmsg("could not remove file \"%s\": %m", xlogpath))); } /* * Calculate the archive file cutoff point for use during log shipping * replication. All files earlier than this point can be deleted from the * archive, though there is no requirement to do so. * * 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 * pointer of the last restartpoint. When redo begins we know that we have * successfully located it, so there is no need for additional status * flags to signify the point when we can begin deleting WAL files from * the archive. */ if (cleanupEnabled) { GetOldestRestartPoint(&restartRedoPtr, &restartTli); XLByteToSeg(restartRedoPtr, restartSegNo); XLogFileName(lastRestartPointFname, restartTli, restartSegNo); /* we shouldn't need anything earlier than last restart point */ Assert(strcmp(lastRestartPointFname, xlogfname) <= 0); } else XLogFileName(lastRestartPointFname, 0, 0L); /* * construct the command to be executed */ dp = xlogRestoreCmd; endp = xlogRestoreCmd + MAXPGPATH - 1; *endp = '\0'; for (sp = recoveryRestoreCommand; *sp; sp++) { if (*sp == '%') { switch (sp[1]) { case 'p': /* %p: relative path of target file */ sp++; StrNCpy(dp, xlogpath, endp - dp); make_native_path(dp); dp += strlen(dp); break; case 'f': /* %f: filename of desired file */ sp++; StrNCpy(dp, xlogfname, endp - dp); dp += strlen(dp); break; case 'r': /* %r: filename of last restartpoint */ sp++; StrNCpy(dp, lastRestartPointFname, endp - dp); dp += strlen(dp); break; case '%': /* convert %% to a single % */ sp++; if (dp < endp) *dp++ = *sp; break; default: /* otherwise treat the % as not special */ if (dp < endp) *dp++ = *sp; break; } } else { if (dp < endp) *dp++ = *sp; } } *dp = '\0'; ereport(DEBUG3, (errmsg_internal("executing restore command \"%s\"", xlogRestoreCmd))); /* * Check signals before restore command and reset afterwards. */ PreRestoreCommand(); /* * Copy xlog from archival storage to XLOGDIR */ rc = system(xlogRestoreCmd); PostRestoreCommand(); if (rc == 0) { /* * command apparently succeeded, but let's make sure the file is * really there now and has the correct size. */ if (stat(xlogpath, &stat_buf) == 0) { if (expectedSize > 0 && stat_buf.st_size != expectedSize) { int elevel; /* * If we find a partial file in standby mode, we assume it's * because it's just being copied to the archive, and keep * trying. * * Otherwise treat a wrong-sized file as FATAL to ensure the * DBA would notice it, but is that too strong? We could try * to plow ahead with a local copy of the file ... but the * problem is that there probably isn't one, and we'd * incorrectly conclude we've reached the end of WAL and we're * done recovering ... */ if (StandbyMode && stat_buf.st_size < expectedSize) elevel = DEBUG1; else elevel = FATAL; ereport(elevel, (errmsg("archive file \"%s\" has wrong size: %lu instead of %lu", xlogfname, (unsigned long) stat_buf.st_size, (unsigned long) expectedSize))); return false; } else { ereport(LOG, (errmsg("restored log file \"%s\" from archive", xlogfname))); strcpy(path, xlogpath); return true; } } else { /* stat failed */ if (errno != ENOENT) ereport(FATAL, (errcode_for_file_access(), errmsg("could not stat file \"%s\": %m", xlogpath))); } } /* * Remember, we rollforward UNTIL the restore fails so failure here is * just part of the process... that makes it difficult to determine * whether the restore failed because there isn't an archive to restore, * or because the administrator has specified the restore program * incorrectly. We have to assume the former. * * However, if the failure was due to any sort of signal, it's best to * punt and abort recovery. (If we "return false" here, upper levels will * assume that recovery is complete and start up the database!) It's * essential to abort on child SIGINT and SIGQUIT, because per spec * system() ignores SIGINT and SIGQUIT while waiting; if we see one of * those it's a good bet we should have gotten it too. * * 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, 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 * problems such as an unfindable command; treat those as fatal errors * too. */ if (WIFSIGNALED(rc) && WTERMSIG(rc) == SIGTERM) proc_exit(1); signaled = WIFSIGNALED(rc) || WEXITSTATUS(rc) > 125; ereport(signaled ? FATAL : DEBUG2, (errmsg("could not restore file \"%s\" from archive: return code %d", xlogfname, rc))); not_available: /* * if an archived file is not available, there might still be a version of * this file in XLOGDIR, so return that as the filename to open. * * In many recovery scenarios we expect this to fail also, but if so that * just means we've reached the end of WAL. */ snprintf(path, MAXPGPATH, XLOGDIR "/%s", xlogfname); return false; }
bool XLogArchiveCheckDone | ( | const char * | xlog | ) |
Definition at line 621 of file xlogarchive.c.
References StatusFilePath, XLogArchiveNotify(), and XLogArchivingActive.
Referenced by CleanupBackupHistory(), and RemoveOldXlogFiles().
{ char archiveStatusPath[MAXPGPATH]; struct stat stat_buf; /* Always deletable if archiving is off */ if (!XLogArchivingActive()) return true; /* First check for .done --- this means archiver is done with it */ StatusFilePath(archiveStatusPath, xlog, ".done"); if (stat(archiveStatusPath, &stat_buf) == 0) return true; /* check for .ready --- this means archiver is still busy with it */ StatusFilePath(archiveStatusPath, xlog, ".ready"); if (stat(archiveStatusPath, &stat_buf) == 0) return false; /* Race condition --- maybe archiver just finished, so recheck */ StatusFilePath(archiveStatusPath, xlog, ".done"); if (stat(archiveStatusPath, &stat_buf) == 0) return true; /* Retry creation of the .ready file */ XLogArchiveNotify(xlog); return false; }
void XLogArchiveCleanup | ( | const char * | xlog | ) |
Definition at line 700 of file xlogarchive.c.
References StatusFilePath, and unlink().
Referenced by CleanupBackupHistory(), exitArchiveRecovery(), and RemoveOldXlogFiles().
{ char archiveStatusPath[MAXPGPATH]; /* Remove the .done file */ StatusFilePath(archiveStatusPath, xlog, ".done"); unlink(archiveStatusPath); /* should we complain about failure? */ /* Remove the .ready file if present --- normally it shouldn't be */ StatusFilePath(archiveStatusPath, xlog, ".ready"); unlink(archiveStatusPath); /* should we complain about failure? */ }
void XLogArchiveForceDone | ( | const char * | xlog | ) |
Definition at line 561 of file xlogarchive.c.
References AllocateFile(), ereport, errcode_for_file_access(), errmsg(), FreeFile(), LOG, NULL, StatusFilePath, and WARNING.
Referenced by KeepFileRestoredFromArchive(), WalReceiverMain(), and XLogWalRcvWrite().
{ char archiveReady[MAXPGPATH]; char archiveDone[MAXPGPATH]; struct stat stat_buf; FILE *fd; /* Exit if already known done */ StatusFilePath(archiveDone, xlog, ".done"); if (stat(archiveDone, &stat_buf) == 0) return; /* If .ready exists, rename it to .done */ StatusFilePath(archiveReady, xlog, ".ready"); if (stat(archiveReady, &stat_buf) == 0) { if (rename(archiveReady, archiveDone) < 0) ereport(WARNING, (errcode_for_file_access(), errmsg("could not rename file \"%s\" to \"%s\": %m", archiveReady, archiveDone))); return; } /* insert an otherwise empty file called <XLOG>.done */ fd = AllocateFile(archiveDone, "w"); if (fd == NULL) { ereport(LOG, (errcode_for_file_access(), errmsg("could not create archive status file \"%s\": %m", archiveDone))); return; } if (FreeFile(fd)) { ereport(LOG, (errcode_for_file_access(), errmsg("could not write archive status file \"%s\": %m", archiveDone))); return; } }
bool XLogArchiveIsBusy | ( | const char * | xlog | ) |
Definition at line 661 of file xlogarchive.c.
References MAXPGPATH, snprintf(), StatusFilePath, and XLOGDIR.
Referenced by do_pg_stop_backup().
{ char archiveStatusPath[MAXPGPATH]; struct stat stat_buf; /* First check for .done --- this means archiver is done with it */ StatusFilePath(archiveStatusPath, xlog, ".done"); if (stat(archiveStatusPath, &stat_buf) == 0) return false; /* check for .ready --- this means archiver is still busy with it */ StatusFilePath(archiveStatusPath, xlog, ".ready"); if (stat(archiveStatusPath, &stat_buf) == 0) return true; /* Race condition --- maybe archiver just finished, so recheck */ StatusFilePath(archiveStatusPath, xlog, ".done"); if (stat(archiveStatusPath, &stat_buf) == 0) return false; /* * Check to see if the WAL file has been removed by checkpoint, which * implies it has already been archived, and explains why we can't see a * status file for it. */ snprintf(archiveStatusPath, MAXPGPATH, XLOGDIR "/%s", xlog); if (stat(archiveStatusPath, &stat_buf) != 0 && errno == ENOENT) return false; return true; }
void XLogArchiveNotify | ( | const char * | xlog | ) |
Definition at line 511 of file xlogarchive.c.
References AllocateFile(), ereport, errcode_for_file_access(), errmsg(), FreeFile(), IsUnderPostmaster, LOG, NULL, PMSIGNAL_WAKEN_ARCHIVER, SendPostmasterSignal(), and StatusFilePath.
Referenced by exitArchiveRecovery(), writeTimeLineHistory(), XLogArchiveCheckDone(), and XLogArchiveNotifySeg().
{ char archiveStatusPath[MAXPGPATH]; FILE *fd; /* insert an otherwise empty file called <XLOG>.ready */ StatusFilePath(archiveStatusPath, xlog, ".ready"); fd = AllocateFile(archiveStatusPath, "w"); if (fd == NULL) { ereport(LOG, (errcode_for_file_access(), errmsg("could not create archive status file \"%s\": %m", archiveStatusPath))); return; } if (FreeFile(fd)) { ereport(LOG, (errcode_for_file_access(), errmsg("could not write archive status file \"%s\": %m", archiveStatusPath))); return; } /* Notify archiver that it's got something to do */ if (IsUnderPostmaster) SendPostmasterSignal(PMSIGNAL_WAKEN_ARCHIVER); }
void XLogArchiveNotifySeg | ( | XLogSegNo | segno | ) |
Definition at line 545 of file xlogarchive.c.
References ThisTimeLineID, XLogArchiveNotify(), and XLogFileName.
Referenced by XLogWrite().
{ char xlog[MAXFNAMELEN]; XLogFileName(xlog, ThisTimeLineID, segno); XLogArchiveNotify(xlog); }
Definition at line 203 of file xlog.c.
Referenced by existsTimeLineHistory(), ReadRecord(), readRecoveryCommandFile(), readTimeLineHistory(), StartupXLOG(), writeTimeLineHistory(), and xlog_redo().
Definition at line 204 of file xlog.c.
Referenced by CheckRequiredParameterValues(), exitArchiveRecovery(), ReadRecord(), StartupXLOG(), and WaitForWALToBecomeAvailable().
char* recoveryRestoreCommand |
Definition at line 210 of file xlog.c.
Referenced by readRecoveryCommandFile(), and RestoreArchivedFile().
Definition at line 31 of file rmgr.c.
Referenced by RecoveryRestartPoint(), rm_redo_error_callback(), StartupXLOG(), and XLogInsert().
Definition at line 226 of file xlog.c.
Referenced by ReadRecord(), RestoreArchivedFile(), StartupXLOG(), WaitForWALToBecomeAvailable(), and XLogPageRead().