LCOV - differential code coverage report
Current view: top level - src/backend/access/transam - xlogarchive.c (source / functions) Coverage Total Hit LBC UIC UBC GBC GIC GNC CBC EUB ECB DUB DCB
Current: Differential Code Coverage HEAD vs 15 Lines: 79.8 % 163 130 9 20 4 8 91 6 25 20 86 1 10
Current Date: 2023-04-08 17:13:01 Functions: 100.0 % 11 11 11 10 1
Baseline: 15 Line coverage date bins:
Baseline Date: 2023-04-08 15:09:40 [..60] days: 100.0 % 2 2 2
Legend: Lines: hit not hit (60,120] days: 96.2 % 26 25 1 1 17 4 3 13
(240..) days: 76.3 % 135 103 9 19 4 7 74 22 20 73
Function coverage date bins:
(60,120] days: 50.0 % 2 1 1 1
(240..) days: 52.6 % 19 10 10 9

 Age         Owner                  TLA  Line data    Source code
                                  1                 : /*-------------------------------------------------------------------------
                                  2                 :  *
                                  3                 :  * xlogarchive.c
                                  4                 :  *      Functions for archiving WAL files and restoring from the archive.
                                  5                 :  *
                                  6                 :  *
                                  7                 :  * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group
                                  8                 :  * Portions Copyright (c) 1994, Regents of the University of California
                                  9                 :  *
                                 10                 :  * src/backend/access/transam/xlogarchive.c
                                 11                 :  *
                                 12                 :  *-------------------------------------------------------------------------
                                 13                 :  */
                                 14                 : 
                                 15                 : #include "postgres.h"
                                 16                 : 
                                 17                 : #include <sys/stat.h>
                                 18                 : #include <sys/wait.h>
                                 19                 : #include <signal.h>
                                 20                 : #include <unistd.h>
                                 21                 : 
                                 22                 : #include "access/xlog.h"
                                 23                 : #include "access/xlog_internal.h"
                                 24                 : #include "access/xlogarchive.h"
                                 25                 : #include "common/archive.h"
                                 26                 : #include "common/percentrepl.h"
                                 27                 : #include "miscadmin.h"
                                 28                 : #include "pgstat.h"
                                 29                 : #include "postmaster/startup.h"
                                 30                 : #include "postmaster/pgarch.h"
                                 31                 : #include "replication/walsender.h"
                                 32                 : #include "storage/fd.h"
                                 33                 : #include "storage/ipc.h"
                                 34                 : #include "storage/lwlock.h"
                                 35                 : 
                                 36                 : /*
                                 37                 :  * Attempt to retrieve the specified file from off-line archival storage.
                                 38                 :  * If successful, fill "path" with its complete path (note that this will be
                                 39                 :  * a temp file name that doesn't follow the normal naming convention), and
                                 40                 :  * return true.
                                 41                 :  *
                                 42                 :  * If not successful, fill "path" with the name of the normal on-line file
                                 43                 :  * (which may or may not actually exist, but we'll try to use it), and return
                                 44                 :  * false.
                                 45                 :  *
                                 46                 :  * For fixed-size files, the caller may pass the expected size as an
                                 47                 :  * additional crosscheck on successful recovery.  If the file size is not
                                 48                 :  * known, set expectedSize = 0.
                                 49                 :  *
                                 50                 :  * When 'cleanupEnabled' is false, refrain from deleting any old WAL segments
                                 51                 :  * in the archive. This is used when fetching the initial checkpoint record,
                                 52                 :  * when we are not yet sure how far back we need the WAL.
                                 53                 :  */
                                 54                 : bool
 3841 heikki.linnakangas         55 GIC         673 : RestoreArchivedFile(char *path, const char *xlogfname,
 3793 heikki.linnakangas         56 ECB             :                     const char *recovername, off_t expectedSize,
                                 57                 :                     bool cleanupEnabled)
                                 58                 : {
                                 59                 :     char        xlogpath[MAXPGPATH];
                                 60                 :     char       *xlogRestoreCmd;
                                 61                 :     char        lastRestartPointFname[MAXPGPATH];
                                 62                 :     int         rc;
                                 63                 :     struct stat stat_buf;
                                 64                 :     XLogSegNo   restartSegNo;
                                 65                 :     XLogRecPtr  restartRedoPtr;
                                 66                 :     TimeLineID  restartTli;
                                 67                 : 
                                 68                 :     /*
                                 69                 :      * Ignore restore_command when not in archive recovery (meaning we are in
                                 70                 :      * crash recovery).
                                 71                 :      */
 1276 fujii                      72 GIC         673 :     if (!ArchiveRecoveryRequested)
 1276 fujii                      73 CBC           7 :         goto not_available;
 1276 fujii                      74 ECB             : 
                                 75                 :     /* In standby mode, restore_command might not be supplied */
 1596 peter_e                    76 GIC         666 :     if (recoveryRestoreCommand == NULL || strcmp(recoveryRestoreCommand, "") == 0)
 3841 heikki.linnakangas         77 CBC         535 :         goto not_available;
 3841 heikki.linnakangas         78 ECB             : 
                                 79                 :     /*
                                 80                 :      * When doing archive recovery, we always prefer an archived log file even
                                 81                 :      * if a file of the same name exists in XLOGDIR.  The reason is that the
                                 82                 :      * file in XLOGDIR could be an old, un-filled or partly-filled version
                                 83                 :      * that was copied and restored as part of backing up $PGDATA.
                                 84                 :      *
                                 85                 :      * We could try to optimize this slightly by checking the local copy
                                 86                 :      * lastchange timestamp against the archived copy, but we have no API to
                                 87                 :      * do this, nor can we guarantee that the lastchange timestamp was
                                 88                 :      * preserved correctly when we copied to archive. Our aim is robustness,
                                 89                 :      * so we elect not to do this.
                                 90                 :      *
                                 91                 :      * If we cannot obtain the log file from the archive, however, we will try
                                 92                 :      * to use the XLOGDIR file if it exists.  This is so that we can make use
                                 93                 :      * of log segments that weren't yet transferred to the archive.
                                 94                 :      *
                                 95                 :      * Notice that we don't actually overwrite any files when we copy back
                                 96                 :      * from archive because the restore_command may inadvertently restore
                                 97                 :      * inappropriate xlogs, or they may be corrupt, so we may wish to fallback
                                 98                 :      * to the segments remaining in current XLOGDIR later. The
                                 99                 :      * copy-from-archive filename is always the same, ensuring that we don't
                                100                 :      * run out of disk space on long recoveries.
                                101                 :      */
 3841 heikki.linnakangas        102 GIC         131 :     snprintf(xlogpath, MAXPGPATH, XLOGDIR "/%s", recovername);
 3841 heikki.linnakangas        103 ECB             : 
                                104                 :     /*
                                105                 :      * Make sure there is no existing file named recovername.
                                106                 :      */
 3841 heikki.linnakangas        107 GIC         131 :     if (stat(xlogpath, &stat_buf) != 0)
 3841 heikki.linnakangas        108 ECB             :     {
 3841 heikki.linnakangas        109 GIC         127 :         if (errno != ENOENT)
 3841 heikki.linnakangas        110 LBC           0 :             ereport(FATAL,
 3841 heikki.linnakangas        111 EUB             :                     (errcode_for_file_access(),
                                112                 :                      errmsg("could not stat file \"%s\": %m",
                                113                 :                             xlogpath)));
                                114                 :     }
                                115                 :     else
                                116                 :     {
 3841 heikki.linnakangas        117 GIC           4 :         if (unlink(xlogpath) != 0)
 3841 heikki.linnakangas        118 LBC           0 :             ereport(FATAL,
 3841 heikki.linnakangas        119 EUB             :                     (errcode_for_file_access(),
                                120                 :                      errmsg("could not remove file \"%s\": %m",
                                121                 :                             xlogpath)));
                                122                 :     }
                                123                 : 
                                124                 :     /*
                                125                 :      * Calculate the archive file cutoff point for use during log shipping
                                126                 :      * replication. All files earlier than this point can be deleted from the
                                127                 :      * archive, though there is no requirement to do so.
                                128                 :      *
                                129                 :      * If cleanup is not enabled, initialise this with the filename of
                                130                 :      * InvalidXLogRecPtr, which will prevent the deletion of any WAL files
                                131                 :      * from the archive because of the alphabetic sorting property of WAL
                                132                 :      * filenames.
                                133                 :      *
                                134                 :      * Once we have successfully located the redo pointer of the checkpoint
                                135                 :      * from which we start recovery we never request a file prior to the redo
                                136                 :      * pointer of the last restartpoint. When redo begins we know that we have
                                137                 :      * successfully located it, so there is no need for additional status
                                138                 :      * flags to signify the point when we can begin deleting WAL files from
                                139                 :      * the archive.
                                140                 :      */
 3793 heikki.linnakangas        141 GIC         131 :     if (cleanupEnabled)
 3841 heikki.linnakangas        142 ECB             :     {
 3793 heikki.linnakangas        143 GIC          51 :         GetOldestRestartPoint(&restartRedoPtr, &restartTli);
 2028 andres                    144 CBC          51 :         XLByteToSeg(restartRedoPtr, restartSegNo, wal_segment_size);
                                145              51 :         XLogFileName(lastRestartPointFname, restartTli, restartSegNo,
 2028 andres                    146 ECB             :                      wal_segment_size);
                                147                 :         /* we shouldn't need anything earlier than last restart point */
 3841 heikki.linnakangas        148 GIC          51 :         Assert(strcmp(lastRestartPointFname, xlogfname) <= 0);
 3841 heikki.linnakangas        149 ECB             :     }
                                150                 :     else
   11 peter                     151 GNC          80 :         XLogFileName(lastRestartPointFname, 0, 0, wal_segment_size);
 3841 heikki.linnakangas        152 ECB             : 
                                153                 :     /* Build the restore command to execute */
   62 michael                   154 GIC         131 :     xlogRestoreCmd = BuildRestoreCommand(recoveryRestoreCommand,
   62 michael                   155 ECB             :                                          xlogpath, xlogfname,
                                156                 :                                          lastRestartPointFname);
                                157                 : 
   62 michael                   158 GIC         131 :     ereport(DEBUG3,
                                159                 :             (errmsg_internal("executing restore command \"%s\"",
                                160                 :                              xlogRestoreCmd)));
                                161                 : 
                                162                 :     /*
 3841 heikki.linnakangas        163 ECB             :      * Check signals before restore command and reset afterwards.
                                164                 :      */
 3841 heikki.linnakangas        165 GIC         131 :     PreRestoreCommand();
                                166                 : 
                                167                 :     /*
 3841 heikki.linnakangas        168 ECB             :      * Copy xlog from archival storage to XLOGDIR
                                169                 :      */
   62 michael                   170 GNC         131 :     fflush(NULL);
   62 michael                   171 CBC         131 :     pgstat_report_wait_start(WAIT_EVENT_RESTORE_COMMAND);
                                172             131 :     rc = system(xlogRestoreCmd);
   62 michael                   173 GIC         131 :     pgstat_report_wait_end();
 3841 heikki.linnakangas        174 ECB             : 
 3841 heikki.linnakangas        175 CBC         131 :     PostRestoreCommand();
   62 michael                   176 GIC         131 :     pfree(xlogRestoreCmd);
 3841 heikki.linnakangas        177 ECB             : 
   62 michael                   178 GIC         131 :     if (rc == 0)
                                179                 :     {
                                180                 :         /*
                                181                 :          * command apparently succeeded, but let's make sure the file is
                                182                 :          * really there now and has the correct size.
 3841 heikki.linnakangas        183 ECB             :          */
 3841 heikki.linnakangas        184 GIC          35 :         if (stat(xlogpath, &stat_buf) == 0)
 3841 heikki.linnakangas        185 ECB             :         {
 3841 heikki.linnakangas        186 GIC          35 :             if (expectedSize > 0 && stat_buf.st_size != expectedSize)
                                187                 :             {
                                188                 :                 int         elevel;
                                189                 : 
                                190                 :                 /*
                                191                 :                  * If we find a partial file in standby mode, we assume it's
                                192                 :                  * because it's just being copied to the archive, and keep
                                193                 :                  * trying.
                                194                 :                  *
                                195                 :                  * Otherwise treat a wrong-sized file as FATAL to ensure the
                                196                 :                  * DBA would notice it, but is that too strong? We could try
                                197                 :                  * to plow ahead with a local copy of the file ... but the
                                198                 :                  * problem is that there probably isn't one, and we'd
                                199                 :                  * incorrectly conclude we've reached the end of WAL and we're
                                200                 :                  * done recovering ...
 3841 heikki.linnakangas        201 EUB             :                  */
 3841 heikki.linnakangas        202 UBC           0 :                 if (StandbyMode && stat_buf.st_size < expectedSize)
 3841 heikki.linnakangas        203 UIC           0 :                     elevel = DEBUG1;
 3841 heikki.linnakangas        204 EUB             :                 else
 3841 heikki.linnakangas        205 UBC           0 :                     elevel = FATAL;
 3841 heikki.linnakangas        206 UIC           0 :                 ereport(elevel,
                                207                 :                         (errmsg("archive file \"%s\" has wrong size: %lld instead of %lld",
                                208                 :                                 xlogfname,
                                209                 :                                 (long long int) stat_buf.st_size,
  927 peter                     210 EUB             :                                 (long long int) expectedSize)));
 3841 heikki.linnakangas        211 UIC           0 :                 return false;
                                212                 :             }
                                213                 :             else
 3841 heikki.linnakangas        214 ECB             :             {
 3841 heikki.linnakangas        215 GIC          35 :                 ereport(LOG,
                                216                 :                         (errmsg("restored log file \"%s\" from archive",
 3841 heikki.linnakangas        217 ECB             :                                 xlogfname)));
 3841 heikki.linnakangas        218 CBC          35 :                 strcpy(path, xlogpath);
 3841 heikki.linnakangas        219 GIC          35 :                 return true;
                                220                 :             }
                                221                 :         }
                                222                 :         else
                                223                 :         {
 3841 heikki.linnakangas        224 EUB             :             /* stat failed */
  870 fujii                     225 UIC           0 :             int         elevel = (errno == ENOENT) ? LOG : FATAL;
  870 fujii                     226 EUB             : 
  870 fujii                     227 UIC           0 :             ereport(elevel,
                                228                 :                     (errcode_for_file_access(),
                                229                 :                      errmsg("could not stat file \"%s\": %m", xlogpath),
                                230                 :                      errdetail("restore_command returned a zero exit status, but stat() failed.")));
                                231                 :         }
                                232                 :     }
                                233                 : 
                                234                 :     /*
                                235                 :      * Remember, we rollforward UNTIL the restore fails so failure here is
                                236                 :      * just part of the process... that makes it difficult to determine
                                237                 :      * whether the restore failed because there isn't an archive to restore,
                                238                 :      * or because the administrator has specified the restore program
                                239                 :      * incorrectly.  We have to assume the former.
                                240                 :      *
                                241                 :      * However, if the failure was due to any sort of signal, it's best to
                                242                 :      * punt and abort recovery.  (If we "return false" here, upper levels will
                                243                 :      * assume that recovery is complete and start up the database!) It's
                                244                 :      * essential to abort on child SIGINT and SIGQUIT, because per spec
                                245                 :      * system() ignores SIGINT and SIGQUIT while waiting; if we see one of
                                246                 :      * those it's a good bet we should have gotten it too.
                                247                 :      *
                                248                 :      * On SIGTERM, assume we have received a fast shutdown request, and exit
                                249                 :      * cleanly. It's pure chance whether we receive the SIGTERM first, or the
                                250                 :      * child process. If we receive it first, the signal handler will call
                                251                 :      * proc_exit, otherwise we do it here. If we or the child process received
                                252                 :      * SIGTERM for any other reason than a fast shutdown request, postmaster
                                253                 :      * will perform an immediate shutdown when it sees us exiting
                                254                 :      * unexpectedly.
                                255                 :      *
                                256                 :      * We treat hard shell errors such as "command not found" as fatal, too.
   62 michael                   257 ECB             :      */
   62 michael                   258 GBC          96 :     if (wait_result_is_signal(rc, SIGTERM))
   62 michael                   259 UIC           0 :         proc_exit(1);
   62 michael                   260 ECB             : 
   62 michael                   261 GIC          96 :     ereport(wait_result_is_any_signal(rc, true) ? FATAL : DEBUG2,
                                262                 :             (errmsg("could not restore file \"%s\" from archive: %s",
                                263                 :                     xlogfname, wait_result_to_str(rc))));
   62 michael                   264 ECB             : 
 3841 heikki.linnakangas        265 GIC          96 : not_available:
                                266                 : 
                                267                 :     /*
                                268                 :      * if an archived file is not available, there might still be a version of
                                269                 :      * this file in XLOGDIR, so return that as the filename to open.
                                270                 :      *
                                271                 :      * In many recovery scenarios we expect this to fail also, but if so that
                                272                 :      * just means we've reached the end of WAL.
 3841 heikki.linnakangas        273 ECB             :      */
 3841 heikki.linnakangas        274 CBC         638 :     snprintf(path, MAXPGPATH, XLOGDIR "/%s", xlogfname);
 3841 heikki.linnakangas        275 GIC         638 :     return false;
                                276                 : }
                                277                 : 
                                278                 : /*
                                279                 :  * Attempt to execute an external shell command during recovery.
                                280                 :  *
                                281                 :  * 'command' is the shell command to be executed, 'commandName' is a
                                282                 :  * human-readable name describing the command emitted in the logs. If
                                283                 :  * 'failOnSignal' is true and the command is killed by a signal, a FATAL
                                284                 :  * error is thrown. Otherwise a WARNING is emitted.
                                285                 :  *
                                286                 :  * This is currently used for recovery_end_command and archive_cleanup_command.
                                287                 :  */
   62 michael                   288 ECB             : void
   62 michael                   289 GIC           2 : ExecuteRecoveryCommand(const char *command, const char *commandName,
                                290                 :                        bool failOnSignal, uint32 wait_event_info)
                                291                 : {
                                292                 :     char       *xlogRecoveryCmd;
                                293                 :     char        lastRestartPointFname[MAXPGPATH];
                                294                 :     int         rc;
   62 michael                   295 ECB             :     XLogSegNo   restartSegNo;
                                296                 :     XLogRecPtr  restartRedoPtr;
                                297                 :     TimeLineID  restartTli;
                                298                 : 
   62 michael                   299 GIC           2 :     Assert(command && commandName);
                                300                 : 
                                301                 :     /*
   62 michael                   302 ECB             :      * Calculate the archive file cutoff point for use during log shipping
                                303                 :      * replication. All files earlier than this point can be deleted from the
                                304                 :      * archive, though there is no requirement to do so.
                                305                 :      */
   62 michael                   306 GIC           2 :     GetOldestRestartPoint(&restartRedoPtr, &restartTli);
                                307               2 :     XLByteToSeg(restartRedoPtr, restartSegNo, wal_segment_size);
                                308               2 :     XLogFileName(lastRestartPointFname, restartTli, restartSegNo,
                                309                 :                  wal_segment_size);
   62 michael                   310 ECB             : 
                                311                 :     /*
                                312                 :      * construct the command to be executed
                                313                 :      */
   62 michael                   314 GNC           2 :     xlogRecoveryCmd = replace_percent_placeholders(command, commandName, "r", lastRestartPointFname);
                                315                 : 
   62 michael                   316 CBC           2 :     ereport(DEBUG3,
                                317                 :             (errmsg_internal("executing %s \"%s\"", commandName, command)));
                                318                 : 
   62 michael                   319 ECB             :     /*
                                320                 :      * execute the constructed command
                                321                 :      */
   62 michael                   322 GNC           2 :     fflush(NULL);
   62 michael                   323 GIC           2 :     pgstat_report_wait_start(wait_event_info);
                                324               2 :     rc = system(xlogRecoveryCmd);
                                325               2 :     pgstat_report_wait_end();
                                326                 : 
   62 michael                   327 GNC           2 :     pfree(xlogRecoveryCmd);
                                328                 : 
   62 michael                   329 GIC           2 :     if (rc != 0)
                                330                 :     {
                                331                 :         /*
                                332                 :          * If the failure was due to any sort of signal, it's best to punt and
                                333                 :          * abort recovery.  See comments in RestoreArchivedFile().
                                334                 :          */
                                335               1 :         ereport((failOnSignal && wait_result_is_any_signal(rc, true)) ? FATAL : WARNING,
                                336                 :         /*------
                                337                 :            translator: First %s represents a postgresql.conf parameter name like
                                338                 :           "recovery_end_command", the 2nd is the value of that parameter, the
                                339                 :           third an already translated error message. */
                                340                 :                 (errmsg("%s \"%s\": %s", commandName,
                                341                 :                         command, wait_result_to_str(rc))));
                                342                 :     }
                                343               2 : }
                                344                 : 
                                345                 : 
                                346                 : /*
                                347                 :  * A file was restored from the archive under a temporary filename (path),
                                348                 :  * and now we want to keep it. Rename it under the permanent filename in
                                349                 :  * pg_wal (xlogfname), replacing any existing file with the same name.
                                350                 :  */
                                351                 : void
 1986 peter_e                   352 CBC          28 : KeepFileRestoredFromArchive(const char *path, const char *xlogfname)
                                353                 : {
 3752 heikki.linnakangas        354 ECB             :     char        xlogfpath[MAXPGPATH];
 3752 heikki.linnakangas        355 GBC          28 :     bool        reload = false;
                                356                 :     struct stat statbuf;
                                357                 : 
 3752 heikki.linnakangas        358 GIC          28 :     snprintf(xlogfpath, MAXPGPATH, XLOGDIR "/%s", xlogfname);
 3752 heikki.linnakangas        359 ECB             : 
 3752 heikki.linnakangas        360 GIC          28 :     if (stat(xlogfpath, &statbuf) == 0)
                                361                 :     {
 3602 bruce                     362 ECB             :         char        oldpath[MAXPGPATH];
                                363                 : 
                                364                 : #ifdef WIN32
                                365                 :         static unsigned int deletedcounter = 1;
                                366                 : 
                                367                 :         /*
                                368                 :          * On Windows, if another process (e.g a walsender process) holds the
                                369                 :          * file open in FILE_SHARE_DELETE mode, unlink will succeed, but the
                                370                 :          * file will still show up in directory listing until the last handle
                                371                 :          * is closed, and we cannot rename the new file in its place until
                                372                 :          * that. To avoid that problem, rename the old file to a temporary
                                373                 :          * name first. Use a counter to create a unique filename, because the
                                374                 :          * same file might be restored from the archive multiple times, and a
                                375                 :          * walsender could still be holding onto an old deleted version of it.
                                376                 :          */
                                377                 :         snprintf(oldpath, MAXPGPATH, "%s.deleted%u",
                                378                 :                  xlogfpath, deletedcounter++);
                                379                 :         if (rename(xlogfpath, oldpath) != 0)
 3752 heikki.linnakangas        380                 :         {
                                381                 :             ereport(ERROR,
                                382                 :                     (errcode_for_file_access(),
                                383                 :                      errmsg("could not rename file \"%s\" to \"%s\": %m",
                                384                 :                             xlogfpath, oldpath)));
                                385                 :         }
                                386                 : #else
                                387                 :         /* same-size buffers, so this never truncates */
 3156 noah                      388 CBC          16 :         strlcpy(oldpath, xlogfpath, MAXPGPATH);
 3752 heikki.linnakangas        389 ECB             : #endif
 3752 heikki.linnakangas        390 GIC          16 :         if (unlink(oldpath) != 0)
 3752 heikki.linnakangas        391 UIC           0 :             ereport(FATAL,
                                392                 :                     (errcode_for_file_access(),
                                393                 :                      errmsg("could not remove file \"%s\": %m",
                                394                 :                             xlogfpath)));
 3752 heikki.linnakangas        395 GIC          16 :         reload = true;
                                396                 :     }
                                397                 : 
 2587 andres                    398              28 :     durable_rename(path, xlogfpath, ERROR);
                                399                 : 
                                400                 :     /*
                                401                 :      * Create .done file forcibly to prevent the restored segment from being
 3602 bruce                     402 ECB             :      * archived again later.
                                403                 :      */
 2886 heikki.linnakangas        404 GIC          28 :     if (XLogArchiveMode != ARCHIVE_MODE_ALWAYS)
                                405              27 :         XLogArchiveForceDone(xlogfname);
                                406                 :     else
  582 alvherre                  407               1 :         XLogArchiveNotify(xlogfname);
 3896 simon                     408 ECB             : 
 3752 heikki.linnakangas        409                 :     /*
 3602 bruce                     410                 :      * If the existing file was replaced, since walsenders might have it open,
                                411                 :      * request them to reload a currently-open segment. This is only required
 3602 bruce                     412 EUB             :      * for WAL segments, walsenders don't hold other files open, but there's
                                413                 :      * no harm in doing this too often, and we don't know what kind of a file
                                414                 :      * we're dealing with here.
                                415                 :      */
 3752 heikki.linnakangas        416 GBC          28 :     if (reload)
 3752 heikki.linnakangas        417 GIC          16 :         WalSndRqstFileReload();
 3752 heikki.linnakangas        418 ECB             : 
                                419                 :     /*
 3752 heikki.linnakangas        420 EUB             :      * Signal walsender that new WAL has arrived. Again, this isn't necessary
                                421                 :      * if we restored something other than a WAL segment, but it does no harm
                                422                 :      * either.
                                423                 :      */
    1 andres                    424 GNC          28 :     WalSndWakeup(true, false);
 3752 heikki.linnakangas        425 GIC          28 : }
                                426                 : 
                                427                 : /*
                                428                 :  * XLogArchiveNotify
                                429                 :  *
                                430                 :  * Create an archive notification file
                                431                 :  *
                                432                 :  * The name of the notification file is the message that will be picked up
                                433                 :  * by the archiver, e.g. we write 0000000100000001000000C6.ready
                                434                 :  * and the archiver then knows to archive XLOGDIR/0000000100000001000000C6,
                                435                 :  * then when complete, rename it to 0000000100000001000000C6.done
                                436                 :  */
                                437                 : void
  582 alvherre                  438 CBC          59 : XLogArchiveNotify(const char *xlog)
 3841 heikki.linnakangas        439 ECB             : {
                                440                 :     char        archiveStatusPath[MAXPGPATH];
                                441                 :     FILE       *fd;
                                442                 : 
                                443                 :     /* insert an otherwise empty file called <XLOG>.ready */
 3841 heikki.linnakangas        444 GIC          59 :     StatusFilePath(archiveStatusPath, xlog, ".ready");
                                445              59 :     fd = AllocateFile(archiveStatusPath, "w");
                                446              59 :     if (fd == NULL)
                                447                 :     {
 3841 heikki.linnakangas        448 UIC           0 :         ereport(LOG,
                                449                 :                 (errcode_for_file_access(),
 3841 heikki.linnakangas        450 ECB             :                  errmsg("could not create archive status file \"%s\": %m",
                                451                 :                         archiveStatusPath)));
 3841 heikki.linnakangas        452 UIC           0 :         return;
                                453                 :     }
 3841 heikki.linnakangas        454 CBC          59 :     if (FreeFile(fd))
                                455                 :     {
 3841 heikki.linnakangas        456 LBC           0 :         ereport(LOG,
 3841 heikki.linnakangas        457 ECB             :                 (errcode_for_file_access(),
                                458                 :                  errmsg("could not write archive status file \"%s\": %m",
                                459                 :                         archiveStatusPath)));
 3841 heikki.linnakangas        460 UIC           0 :         return;
                                461                 :     }
                                462                 : 
                                463                 :     /*
                                464                 :      * Timeline history files are given the highest archival priority to lower
                                465                 :      * the chance that a promoted standby will choose a timeline that is
                                466                 :      * already in use.  However, the archiver ordinarily tries to gather
                                467                 :      * multiple files to archive from each scan of the archive_status
  332 tgl                       468 ECB             :      * directory, which means that newly created timeline history files could
                                469                 :      * be left unarchived for a while.  To ensure that the archiver picks up
                                470                 :      * timeline history files as soon as possible, we force the archiver to
                                471                 :      * scan the archive_status directory the next time it looks for a file to
                                472                 :      * archive.
                                473                 :      */
  514 rhaas                     474 GIC          59 :     if (IsTLHistoryFileName(xlog))
                                475              10 :         PgArchForceDirScan();
  514 rhaas                     476 ECB             : 
  582 alvherre                  477                 :     /* Notify archiver that it's got something to do */
  582 alvherre                  478 CBC          59 :     if (IsUnderPostmaster)
  755 fujii                     479 GIC          59 :         PgArchWakeup();
                                480                 : }
 3841 heikki.linnakangas        481 ECB             : 
                                482                 : /*
                                483                 :  * Convenience routine to notify using segment number representation of filename
 3841 heikki.linnakangas        484 EUB             :  */
                                485                 : void
  520 rhaas                     486 GIC          33 : XLogArchiveNotifySeg(XLogSegNo segno, TimeLineID tli)
                                487                 : {
                                488                 :     char        xlog[MAXFNAMELEN];
 3841 heikki.linnakangas        489 ECB             : 
  520 rhaas                     490 CBC          33 :     Assert(tli != 0);
                                491                 : 
  520 rhaas                     492 GBC          33 :     XLogFileName(xlog, tli, segno, wal_segment_size);
  582 alvherre                  493 GIC          33 :     XLogArchiveNotify(xlog);
 3841 heikki.linnakangas        494              33 : }
                                495                 : 
 3896 simon                     496 EUB             : /*
                                497                 :  * XLogArchiveForceDone
 3896 simon                     498 ECB             :  *
                                499                 :  * Emit notification forcibly that an XLOG segment file has been successfully
 3896 simon                     500 EUB             :  * archived, by creating <XLOG>.done regardless of whether <XLOG>.ready
                                501                 :  * exists or not.
                                502                 :  */
                                503                 : void
 3896 simon                     504 GBC          98 : XLogArchiveForceDone(const char *xlog)
                                505                 : {
                                506                 :     char        archiveReady[MAXPGPATH];
                                507                 :     char        archiveDone[MAXPGPATH];
                                508                 :     struct stat stat_buf;
                                509                 :     FILE       *fd;
                                510                 : 
                                511                 :     /* Exit if already known done */
 3896 simon                     512 GIC          98 :     StatusFilePath(archiveDone, xlog, ".done");
                                513              98 :     if (stat(archiveDone, &stat_buf) == 0)
                                514               9 :         return;
                                515                 : 
                                516                 :     /* If .ready exists, rename it to .done */
                                517              89 :     StatusFilePath(archiveReady, xlog, ".ready");
                                518              89 :     if (stat(archiveReady, &stat_buf) == 0)
                                519                 :     {
 2587 andres                    520 UIC           0 :         (void) durable_rename(archiveReady, archiveDone, WARNING);
 3896 simon                     521               0 :         return;
                                522                 :     }
 3896 simon                     523 ECB             : 
                                524                 :     /* insert an otherwise empty file called <XLOG>.done */
 3896 simon                     525 GIC          89 :     fd = AllocateFile(archiveDone, "w");
                                526              89 :     if (fd == NULL)
                                527                 :     {
 3896 simon                     528 UIC           0 :         ereport(LOG,
 3896 simon                     529 ECB             :                 (errcode_for_file_access(),
                                530                 :                  errmsg("could not create archive status file \"%s\": %m",
                                531                 :                         archiveDone)));
 3896 simon                     532 UIC           0 :         return;
                                533                 :     }
 3896 simon                     534 GIC          89 :     if (FreeFile(fd))
                                535                 :     {
 3896 simon                     536 LBC           0 :         ereport(LOG,
 3896 simon                     537 ECB             :                 (errcode_for_file_access(),
                                538                 :                  errmsg("could not write archive status file \"%s\": %m",
                                539                 :                         archiveDone)));
 3896 simon                     540 UIC           0 :         return;
                                541                 :     }
                                542                 : }
                                543                 : 
                                544                 : /*
                                545                 :  * XLogArchiveCheckDone
                                546                 :  *
 3841 heikki.linnakangas        547 ECB             :  * This is called when we are ready to delete or recycle an old XLOG segment
                                548                 :  * file or backup history file.  If it is okay to delete it then return true.
                                549                 :  * If it is not time to delete it, make sure a .ready file exists, and return
                                550                 :  * false.
                                551                 :  *
                                552                 :  * If <XLOG>.done exists, then return true; else if <XLOG>.ready exists,
                                553                 :  * then return false; else create <XLOG>.ready and return false.
                                554                 :  *
                                555                 :  * The reason we do things this way is so that if the original attempt to
                                556                 :  * create <XLOG>.ready fails, we'll retry during subsequent checkpoints.
                                557                 :  */
                                558                 : bool
 3841 heikki.linnakangas        559 GBC         697 : XLogArchiveCheckDone(const char *xlog)
                                560                 : {
                                561                 :     char        archiveStatusPath[MAXPGPATH];
 3841 heikki.linnakangas        562 ECB             :     struct stat stat_buf;
 1080 michael                   563                 : 
                                564                 :     /* The file is always deletable if archive_mode is "off". */
 1080 michael                   565 GIC         697 :     if (!XLogArchivingActive())
                                566             667 :         return true;
                                567                 : 
                                568                 :     /*
                                569                 :      * During archive recovery, the file is deletable if archive_mode is not
                                570                 :      * "always".
                                571                 :      */
                                572              55 :     if (!XLogArchivingAlways() &&
                                573              25 :         GetRecoveryState() == RECOVERY_STATE_ARCHIVE)
 3841 heikki.linnakangas        574               1 :         return true;
                                575                 : 
                                576                 :     /*
 1080 michael                   577 ECB             :      * At this point of the logic, note that we are either a primary with
                                578                 :      * archive_mode set to "on" or "always", or a standby with archive_mode
                                579                 :      * set to "always".
                                580                 :      */
                                581                 : 
                                582                 :     /* First check for .done --- this means archiver is done with it */
 3841 heikki.linnakangas        583 CBC          29 :     StatusFilePath(archiveStatusPath, xlog, ".done");
                                584              29 :     if (stat(archiveStatusPath, &stat_buf) == 0)
                                585              13 :         return true;
                                586                 : 
                                587                 :     /* check for .ready --- this means archiver is still busy with it */
                                588              16 :     StatusFilePath(archiveStatusPath, xlog, ".ready");
                                589              16 :     if (stat(archiveStatusPath, &stat_buf) == 0)
                                590               5 :         return false;
                                591                 : 
                                592                 :     /* Race condition --- maybe archiver just finished, so recheck */
 3841 heikki.linnakangas        593 GBC          11 :     StatusFilePath(archiveStatusPath, xlog, ".done");
                                594              11 :     if (stat(archiveStatusPath, &stat_buf) == 0)
 3841 heikki.linnakangas        595 UBC           0 :         return true;
                                596                 : 
                                597                 :     /* Retry creation of the .ready file */
  582 alvherre                  598 GIC          11 :     XLogArchiveNotify(xlog);
 3841 heikki.linnakangas        599              11 :     return false;
                                600                 : }
                                601                 : 
 3841 heikki.linnakangas        602 EUB             : /*
                                603                 :  * XLogArchiveIsBusy
                                604                 :  *
                                605                 :  * Check to see if an XLOG segment file is still unarchived.
                                606                 :  * This is almost but not quite the inverse of XLogArchiveCheckDone: in
                                607                 :  * the first place we aren't chartered to recreate the .ready file, and
                                608                 :  * in the second place we should consider that if the file is already gone
                                609                 :  * then it's not busy.  (This check is needed to handle the race condition
                                610                 :  * that a checkpoint already deleted the no-longer-needed file.)
                                611                 :  */
                                612                 : bool
 3841 heikki.linnakangas        613 GIC           6 : XLogArchiveIsBusy(const char *xlog)
                                614                 : {
                                615                 :     char        archiveStatusPath[MAXPGPATH];
                                616                 :     struct stat stat_buf;
                                617                 : 
                                618                 :     /* First check for .done --- this means archiver is done with it */
                                619               6 :     StatusFilePath(archiveStatusPath, xlog, ".done");
                                620               6 :     if (stat(archiveStatusPath, &stat_buf) == 0)
                                621               4 :         return false;
 3841 heikki.linnakangas        622 ECB             : 
                                623                 :     /* check for .ready --- this means archiver is still busy with it */
 3841 heikki.linnakangas        624 GIC           2 :     StatusFilePath(archiveStatusPath, xlog, ".ready");
                                625               2 :     if (stat(archiveStatusPath, &stat_buf) == 0)
                                626               2 :         return true;
                                627                 : 
 3841 heikki.linnakangas        628 ECB             :     /* Race condition --- maybe archiver just finished, so recheck */
 3841 heikki.linnakangas        629 LBC           0 :     StatusFilePath(archiveStatusPath, xlog, ".done");
                                630               0 :     if (stat(archiveStatusPath, &stat_buf) == 0)
 3841 heikki.linnakangas        631 UIC           0 :         return false;
                                632                 : 
 3841 heikki.linnakangas        633 ECB             :     /*
                                634                 :      * Check to see if the WAL file has been removed by checkpoint, which
 3841 heikki.linnakangas        635 EUB             :      * implies it has already been archived, and explains why we can't see a
                                636                 :      * status file for it.
                                637                 :      */
 3841 heikki.linnakangas        638 LBC           0 :     snprintf(archiveStatusPath, MAXPGPATH, XLOGDIR "/%s", xlog);
                                639               0 :     if (stat(archiveStatusPath, &stat_buf) != 0 &&
 3841 heikki.linnakangas        640 UBC           0 :         errno == ENOENT)
 3841 heikki.linnakangas        641 UIC           0 :         return false;
 3841 heikki.linnakangas        642 ECB             : 
 3841 heikki.linnakangas        643 UIC           0 :     return true;
                                644                 : }
                                645                 : 
                                646                 : /*
                                647                 :  * XLogArchiveIsReadyOrDone
                                648                 :  *
                                649                 :  * Check to see if an XLOG segment file has a .ready or .done file.
                                650                 :  * This is similar to XLogArchiveIsBusy(), but returns true if the file
                                651                 :  * is already archived or is about to be archived.
 2880 heikki.linnakangas        652 ECB             :  *
                                653                 :  * This is currently only used at recovery.  During normal operation this
                                654                 :  * would be racy: the file might get removed or marked with .ready as we're
                                655                 :  * checking it, or immediately after we return.
                                656                 :  */
                                657                 : bool
 2880 heikki.linnakangas        658 CBC           6 : XLogArchiveIsReadyOrDone(const char *xlog)
 2880 heikki.linnakangas        659 EUB             : {
                                660                 :     char        archiveStatusPath[MAXPGPATH];
 2880 heikki.linnakangas        661 ECB             :     struct stat stat_buf;
                                662                 : 
                                663                 :     /* First check for .done --- this means archiver is done with it */
 2880 heikki.linnakangas        664 GIC           6 :     StatusFilePath(archiveStatusPath, xlog, ".done");
                                665               6 :     if (stat(archiveStatusPath, &stat_buf) == 0)
                                666               2 :         return true;
                                667                 : 
                                668                 :     /* check for .ready --- this means archiver is still busy with it */
                                669               4 :     StatusFilePath(archiveStatusPath, xlog, ".ready");
 2880 heikki.linnakangas        670 CBC           4 :     if (stat(archiveStatusPath, &stat_buf) == 0)
 2880 heikki.linnakangas        671 UIC           0 :         return true;
                                672                 : 
                                673                 :     /* Race condition --- maybe archiver just finished, so recheck */
 2880 heikki.linnakangas        674 GIC           4 :     StatusFilePath(archiveStatusPath, xlog, ".done");
 2880 heikki.linnakangas        675 CBC           4 :     if (stat(archiveStatusPath, &stat_buf) == 0)
 2880 heikki.linnakangas        676 LBC           0 :         return true;
                                677                 : 
 2880 heikki.linnakangas        678 GIC           4 :     return false;
                                679                 : }
 2880 heikki.linnakangas        680 ECB             : 
 2918                           681                 : /*
                                682                 :  * XLogArchiveIsReady
                                683                 :  *
                                684                 :  * Check to see if an XLOG segment file has an archive notification (.ready)
                                685                 :  * file.
                                686                 :  */
                                687                 : bool
 2918 heikki.linnakangas        688 GIC          12 : XLogArchiveIsReady(const char *xlog)
                                689                 : {
                                690                 :     char        archiveStatusPath[MAXPGPATH];
                                691                 :     struct stat stat_buf;
                                692                 : 
                                693              12 :     StatusFilePath(archiveStatusPath, xlog, ".ready");
                                694              12 :     if (stat(archiveStatusPath, &stat_buf) == 0)
 2918 heikki.linnakangas        695 UIC           0 :         return true;
                                696                 : 
 2918 heikki.linnakangas        697 GIC          12 :     return false;
                                698                 : }
                                699                 : 
                                700                 : /*
                                701                 :  * XLogArchiveCleanup
                                702                 :  *
                                703                 :  * Cleanup archive notification file(s) for a particular xlog segment
                                704                 :  */
                                705                 : void
 3841                           706             736 : XLogArchiveCleanup(const char *xlog)
                                707                 : {
                                708                 :     char        archiveStatusPath[MAXPGPATH];
                                709                 : 
                                710                 :     /* Remove the .done file */
                                711             736 :     StatusFilePath(archiveStatusPath, xlog, ".done");
                                712             736 :     unlink(archiveStatusPath);
                                713                 :     /* should we complain about failure? */
                                714                 : 
                                715                 :     /* Remove the .ready file if present --- normally it shouldn't be */
                                716             736 :     StatusFilePath(archiveStatusPath, xlog, ".ready");
                                717             736 :     unlink(archiveStatusPath);
                                718                 :     /* should we complain about failure? */
                                719             736 : }
        

Generated by: LCOV version v1.16-55-g56c0a2a