Header And Logo

PostgreSQL
| The world's most advanced open source database.

Data Structures | Defines | Typedefs | Functions | Variables

xlog_internal.h File Reference

#include "access/xlogdefs.h"
#include "datatype/timestamp.h"
#include "lib/stringinfo.h"
#include "pgtime.h"
#include "storage/block.h"
#include "storage/relfilenode.h"
Include dependency graph for xlog_internal.h:
This graph shows which files directly or indirectly include this file:

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 XLogPageHeaderDataXLogPageHeader
typedef struct
XLogLongPageHeaderData 
XLogLongPageHeaderData
typedef XLogLongPageHeaderDataXLogLongPageHeader
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 Documentation

#define BackupHistoryFileName (   fname,
  tli,
  logSegNo,
  offset 
)
Value:
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 
)
Value:
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
#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)
#define TLHistoryFileName (   fname,
  tli 
)    snprintf(fname, MAXFNAMELEN, "%08X.history", tli)
#define TLHistoryFilePath (   path,
  tli 
)    snprintf(path, MAXPGPATH, XLOGDIR "/%08X.history", tli)
#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
#define XLByteToSeg (   xlrp,
  logSegNo 
)    logSegNo = (xlrp) / XLogSegSize
#define XLOG_CONTROL_FILE   "global/pg_control"
#define XLOG_PAGE_MAGIC   0xD075

Definition at line 58 of file xlog_internal.h.

Referenced by ValidXLogPageHeader().

#define XLOGDIR   "pg_xlog"
#define XLogFileName (   fname,
  tli,
  logSegNo 
)
Value:
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 
)
#define XLogFromFileName (   fname,
  tli,
  logSegNo 
)
Value:
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)
#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 Documentation

typedef struct BkpBlock BkpBlock
typedef struct RmgrData RmgrData

Definition at line 98 of file xlog_internal.h.

Definition at line 81 of file xlog_internal.h.


Function Documentation

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 
)
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);
}


Variable Documentation

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().