PostgreSQL Source Code  git master
xlogarchive.c File Reference
#include "postgres.h"
#include <sys/stat.h>
#include <sys/wait.h>
#include <signal.h>
#include <unistd.h>
#include "access/xlog.h"
#include "access/xlog_internal.h"
#include "access/xlogarchive.h"
#include "common/archive.h"
#include "common/percentrepl.h"
#include "miscadmin.h"
#include "pgstat.h"
#include "postmaster/startup.h"
#include "postmaster/pgarch.h"
#include "replication/walsender.h"
#include "storage/fd.h"
#include "storage/ipc.h"
#include "storage/lwlock.h"
Include dependency graph for xlogarchive.c:

Go to the source code of this file.

Functions

bool RestoreArchivedFile (char *path, const char *xlogfname, const char *recovername, off_t expectedSize, bool cleanupEnabled)
 
void ExecuteRecoveryCommand (const char *command, const char *commandName, bool failOnSignal, uint32 wait_event_info)
 
void KeepFileRestoredFromArchive (const char *path, const char *xlogfname)
 
void XLogArchiveNotify (const char *xlog)
 
void XLogArchiveNotifySeg (XLogSegNo segno, TimeLineID tli)
 
void XLogArchiveForceDone (const char *xlog)
 
bool XLogArchiveCheckDone (const char *xlog)
 
bool XLogArchiveIsBusy (const char *xlog)
 
bool XLogArchiveIsReadyOrDone (const char *xlog)
 
bool XLogArchiveIsReady (const char *xlog)
 
void XLogArchiveCleanup (const char *xlog)
 

Function Documentation

◆ ExecuteRecoveryCommand()

void ExecuteRecoveryCommand ( const char *  command,
const char *  commandName,
bool  failOnSignal,
uint32  wait_event_info 
)

Definition at line 289 of file xlogarchive.c.

291 {
292  char *xlogRecoveryCmd;
293  char lastRestartPointFname[MAXPGPATH];
294  int rc;
295  XLogSegNo restartSegNo;
296  XLogRecPtr restartRedoPtr;
297  TimeLineID restartTli;
298 
299  Assert(command && commandName);
300 
301  /*
302  * 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  */
306  GetOldestRestartPoint(&restartRedoPtr, &restartTli);
307  XLByteToSeg(restartRedoPtr, restartSegNo, wal_segment_size);
308  XLogFileName(lastRestartPointFname, restartTli, restartSegNo,
310 
311  /*
312  * construct the command to be executed
313  */
314  xlogRecoveryCmd = replace_percent_placeholders(command, commandName, "r", lastRestartPointFname);
315 
316  ereport(DEBUG3,
317  (errmsg_internal("executing %s \"%s\"", commandName, command)));
318 
319  /*
320  * execute the constructed command
321  */
322  fflush(NULL);
323  pgstat_report_wait_start(wait_event_info);
324  rc = system(xlogRecoveryCmd);
326 
327  pfree(xlogRecoveryCmd);
328 
329  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  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 }
int errmsg_internal(const char *fmt,...)
Definition: elog.c:1156
int errmsg(const char *fmt,...)
Definition: elog.c:1069
#define DEBUG3
Definition: elog.h:28
#define FATAL
Definition: elog.h:41
#define WARNING
Definition: elog.h:36
#define ereport(elevel,...)
Definition: elog.h:149
static void const char fflush(stdout)
Assert(fmt[strlen(fmt) - 1] !='\n')
void pfree(void *pointer)
Definition: mcxt.c:1456
char * replace_percent_placeholders(const char *instr, const char *param_name, const char *letters,...)
Definition: percentrepl.c:59
#define MAXPGPATH
char * wait_result_to_str(int exitstatus)
Definition: wait_error.c:33
bool wait_result_is_any_signal(int exit_status, bool include_command_not_found)
Definition: wait_error.c:121
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: wait_event.h:271
static void pgstat_report_wait_end(void)
Definition: wait_event.h:287
int wal_segment_size
Definition: xlog.c:146
void GetOldestRestartPoint(XLogRecPtr *oldrecptr, TimeLineID *oldtli)
Definition: xlog.c:8926
#define XLByteToSeg(xlrp, logSegNo, wal_segsz_bytes)
static void XLogFileName(char *fname, TimeLineID tli, XLogSegNo logSegNo, int wal_segsz_bytes)
uint64 XLogRecPtr
Definition: xlogdefs.h:21
uint32 TimeLineID
Definition: xlogdefs.h:59
uint64 XLogSegNo
Definition: xlogdefs.h:48

References Assert(), DEBUG3, ereport, errmsg(), errmsg_internal(), FATAL, fflush(), GetOldestRestartPoint(), MAXPGPATH, pfree(), pgstat_report_wait_end(), pgstat_report_wait_start(), replace_percent_placeholders(), wait_result_is_any_signal(), wait_result_to_str(), wal_segment_size, WARNING, XLByteToSeg, and XLogFileName().

Referenced by CleanupAfterArchiveRecovery(), and CreateRestartPoint().

◆ KeepFileRestoredFromArchive()

void KeepFileRestoredFromArchive ( const char *  path,
const char *  xlogfname 
)

Definition at line 352 of file xlogarchive.c.

353 {
354  char xlogfpath[MAXPGPATH];
355  bool reload = false;
356  struct stat statbuf;
357 
358  snprintf(xlogfpath, MAXPGPATH, XLOGDIR "/%s", xlogfname);
359 
360  if (stat(xlogfpath, &statbuf) == 0)
361  {
362  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)
380  {
381  ereport(ERROR,
383  errmsg("could not rename file \"%s\" to \"%s\": %m",
384  xlogfpath, oldpath)));
385  }
386 #else
387  /* same-size buffers, so this never truncates */
388  strlcpy(oldpath, xlogfpath, MAXPGPATH);
389 #endif
390  if (unlink(oldpath) != 0)
391  ereport(FATAL,
393  errmsg("could not remove file \"%s\": %m",
394  xlogfpath)));
395  reload = true;
396  }
397 
399 
400  /*
401  * Create .done file forcibly to prevent the restored segment from being
402  * archived again later.
403  */
405  XLogArchiveForceDone(xlogfname);
406  else
407  XLogArchiveNotify(xlogfname);
408 
409  /*
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
412  * 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  */
416  if (reload)
418 
419  /*
420  * 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  */
424  WalSndWakeup(true, false);
425 }
int errcode_for_file_access(void)
Definition: elog.c:881
#define ERROR
Definition: elog.h:39
int durable_rename(const char *oldfile, const char *newfile, int elevel)
Definition: fd.c:693
static char xlogfpath[MAXPGPATH]
Definition: parsexlog.c:45
#define snprintf
Definition: port.h:238
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45
void WalSndWakeup(bool physical, bool logical)
Definition: walsender.c:3334
void WalSndRqstFileReload(void)
Definition: walsender.c:3202
#define stat
Definition: win32_port.h:292
int XLogArchiveMode
Definition: xlog.c:122
@ ARCHIVE_MODE_ALWAYS
Definition: xlog.h:62
#define XLOGDIR
void XLogArchiveForceDone(const char *xlog)
Definition: xlogarchive.c:504
void XLogArchiveNotify(const char *xlog)
Definition: xlogarchive.c:438

References ARCHIVE_MODE_ALWAYS, durable_rename(), ereport, errcode_for_file_access(), errmsg(), ERROR, FATAL, MAXPGPATH, snprintf, stat, strlcpy(), WalSndRqstFileReload(), WalSndWakeup(), XLogArchiveForceDone(), XLogArchiveMode, XLogArchiveNotify(), XLOGDIR, and xlogfpath.

Referenced by readTimeLineHistory(), restoreTimeLineHistoryFiles(), and XLogFileRead().

◆ RestoreArchivedFile()

bool RestoreArchivedFile ( char *  path,
const char *  xlogfname,
const char *  recovername,
off_t  expectedSize,
bool  cleanupEnabled 
)

Definition at line 55 of file xlogarchive.c.

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  */
73  goto not_available;
74 
75  /* In standby mode, restore_command might not be supplied */
76  if (recoveryRestoreCommand == NULL || strcmp(recoveryRestoreCommand, "") == 0)
77  goto not_available;
78 
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  */
102  snprintf(xlogpath, MAXPGPATH, XLOGDIR "/%s", recovername);
103 
104  /*
105  * Make sure there is no existing file named recovername.
106  */
107  if (stat(xlogpath, &stat_buf) != 0)
108  {
109  if (errno != ENOENT)
110  ereport(FATAL,
112  errmsg("could not stat file \"%s\": %m",
113  xlogpath)));
114  }
115  else
116  {
117  if (unlink(xlogpath) != 0)
118  ereport(FATAL,
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  */
141  if (cleanupEnabled)
142  {
143  GetOldestRestartPoint(&restartRedoPtr, &restartTli);
144  XLByteToSeg(restartRedoPtr, restartSegNo, wal_segment_size);
145  XLogFileName(lastRestartPointFname, restartTli, restartSegNo,
147  /* we shouldn't need anything earlier than last restart point */
148  Assert(strcmp(lastRestartPointFname, xlogfname) <= 0);
149  }
150  else
151  XLogFileName(lastRestartPointFname, 0, 0, wal_segment_size);
152 
153  /* Build the restore command to execute */
155  xlogpath, xlogfname,
156  lastRestartPointFname);
157 
158  ereport(DEBUG3,
159  (errmsg_internal("executing restore command \"%s\"",
160  xlogRestoreCmd)));
161 
162  /*
163  * Check signals before restore command and reset afterwards.
164  */
166 
167  /*
168  * Copy xlog from archival storage to XLOGDIR
169  */
170  fflush(NULL);
172  rc = system(xlogRestoreCmd);
174 
176  pfree(xlogRestoreCmd);
177 
178  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.
183  */
184  if (stat(xlogpath, &stat_buf) == 0)
185  {
186  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 ...
201  */
202  if (StandbyMode && stat_buf.st_size < expectedSize)
203  elevel = DEBUG1;
204  else
205  elevel = FATAL;
206  ereport(elevel,
207  (errmsg("archive file \"%s\" has wrong size: %lld instead of %lld",
208  xlogfname,
209  (long long int) stat_buf.st_size,
210  (long long int) expectedSize)));
211  return false;
212  }
213  else
214  {
215  ereport(LOG,
216  (errmsg("restored log file \"%s\" from archive",
217  xlogfname)));
218  strcpy(path, xlogpath);
219  return true;
220  }
221  }
222  else
223  {
224  /* stat failed */
225  int elevel = (errno == ENOENT) ? LOG : FATAL;
226 
227  ereport(elevel,
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.
257  */
258  if (wait_result_is_signal(rc, SIGTERM))
259  proc_exit(1);
260 
262  (errmsg("could not restore file \"%s\" from archive: %s",
263  xlogfname, wait_result_to_str(rc))));
264 
265 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.
273  */
274  snprintf(path, MAXPGPATH, XLOGDIR "/%s", xlogfname);
275  return false;
276 }
void PreRestoreCommand(void)
Definition: startup.c:277
void PostRestoreCommand(void)
Definition: startup.c:291
char * BuildRestoreCommand(const char *restoreCommand, const char *xlogpath, const char *xlogfname, const char *lastRestartPointFname)
Definition: archive.c:39
int errdetail(const char *fmt,...)
Definition: elog.c:1202
#define LOG
Definition: elog.h:31
#define DEBUG2
Definition: elog.h:29
#define DEBUG1
Definition: elog.h:30
void proc_exit(int code)
Definition: ipc.c:104
bool wait_result_is_signal(int exit_status, int signum)
Definition: wait_error.c:102
@ WAIT_EVENT_RESTORE_COMMAND
Definition: wait_event.h:129
bool ArchiveRecoveryRequested
Definition: xlogrecovery.c:137
char * recoveryRestoreCommand
Definition: xlogrecovery.c:82
bool StandbyMode
Definition: xlogrecovery.c:147

References ArchiveRecoveryRequested, Assert(), BuildRestoreCommand(), DEBUG1, DEBUG2, DEBUG3, ereport, errcode_for_file_access(), errdetail(), errmsg(), errmsg_internal(), FATAL, fflush(), GetOldestRestartPoint(), LOG, MAXPGPATH, pfree(), pgstat_report_wait_end(), pgstat_report_wait_start(), PostRestoreCommand(), PreRestoreCommand(), proc_exit(), recoveryRestoreCommand, snprintf, stat::st_size, StandbyMode, stat, WAIT_EVENT_RESTORE_COMMAND, wait_result_is_any_signal(), wait_result_is_signal(), wait_result_to_str(), wal_segment_size, XLByteToSeg, XLOGDIR, and XLogFileName().

Referenced by existsTimeLineHistory(), readTimeLineHistory(), restoreTimeLineHistoryFiles(), SimpleXLogPageRead(), writeTimeLineHistory(), and XLogFileRead().

◆ XLogArchiveCheckDone()

bool XLogArchiveCheckDone ( const char *  xlog)

Definition at line 559 of file xlogarchive.c.

560 {
561  char archiveStatusPath[MAXPGPATH];
562  struct stat stat_buf;
563 
564  /* The file is always deletable if archive_mode is "off". */
565  if (!XLogArchivingActive())
566  return true;
567 
568  /*
569  * During archive recovery, the file is deletable if archive_mode is not
570  * "always".
571  */
572  if (!XLogArchivingAlways() &&
574  return true;
575 
576  /*
577  * 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 */
583  StatusFilePath(archiveStatusPath, xlog, ".done");
584  if (stat(archiveStatusPath, &stat_buf) == 0)
585  return true;
586 
587  /* check for .ready --- this means archiver is still busy with it */
588  StatusFilePath(archiveStatusPath, xlog, ".ready");
589  if (stat(archiveStatusPath, &stat_buf) == 0)
590  return false;
591 
592  /* Race condition --- maybe archiver just finished, so recheck */
593  StatusFilePath(archiveStatusPath, xlog, ".done");
594  if (stat(archiveStatusPath, &stat_buf) == 0)
595  return true;
596 
597  /* Retry creation of the .ready file */
598  XLogArchiveNotify(xlog);
599  return false;
600 }
RecoveryState GetRecoveryState(void)
Definition: xlog.c:5957
#define XLogArchivingActive()
Definition: xlog.h:94
#define XLogArchivingAlways()
Definition: xlog.h:97
@ RECOVERY_STATE_ARCHIVE
Definition: xlog.h:87
static void StatusFilePath(char *path, const char *xlog, const char *suffix)

References GetRecoveryState(), MAXPGPATH, RECOVERY_STATE_ARCHIVE, stat, StatusFilePath(), XLogArchiveNotify(), XLogArchivingActive, and XLogArchivingAlways.

Referenced by CleanupBackupHistory(), and RemoveOldXlogFiles().

◆ XLogArchiveCleanup()

void XLogArchiveCleanup ( const char *  xlog)

Definition at line 706 of file xlogarchive.c.

707 {
708  char archiveStatusPath[MAXPGPATH];
709 
710  /* Remove the .done file */
711  StatusFilePath(archiveStatusPath, xlog, ".done");
712  unlink(archiveStatusPath);
713  /* should we complain about failure? */
714 
715  /* Remove the .ready file if present --- normally it shouldn't be */
716  StatusFilePath(archiveStatusPath, xlog, ".ready");
717  unlink(archiveStatusPath);
718  /* should we complain about failure? */
719 }

References MAXPGPATH, and StatusFilePath().

Referenced by CleanupAfterArchiveRecovery(), CleanupBackupHistory(), RemoveXlogFile(), and XLogInitNewTimeline().

◆ XLogArchiveForceDone()

void XLogArchiveForceDone ( const char *  xlog)

Definition at line 504 of file xlogarchive.c.

505 {
506  char archiveReady[MAXPGPATH];
507  char archiveDone[MAXPGPATH];
508  struct stat stat_buf;
509  FILE *fd;
510 
511  /* Exit if already known done */
512  StatusFilePath(archiveDone, xlog, ".done");
513  if (stat(archiveDone, &stat_buf) == 0)
514  return;
515 
516  /* If .ready exists, rename it to .done */
517  StatusFilePath(archiveReady, xlog, ".ready");
518  if (stat(archiveReady, &stat_buf) == 0)
519  {
520  (void) durable_rename(archiveReady, archiveDone, WARNING);
521  return;
522  }
523 
524  /* insert an otherwise empty file called <XLOG>.done */
525  fd = AllocateFile(archiveDone, "w");
526  if (fd == NULL)
527  {
528  ereport(LOG,
530  errmsg("could not create archive status file \"%s\": %m",
531  archiveDone)));
532  return;
533  }
534  if (FreeFile(fd))
535  {
536  ereport(LOG,
538  errmsg("could not write archive status file \"%s\": %m",
539  archiveDone)));
540  return;
541  }
542 }
FILE * AllocateFile(const char *name, const char *mode)
Definition: fd.c:2480
int FreeFile(FILE *file)
Definition: fd.c:2678
static int fd(const char *x, int i)
Definition: preproc-init.c:105

References AllocateFile(), durable_rename(), ereport, errcode_for_file_access(), errmsg(), fd(), FreeFile(), LOG, MAXPGPATH, stat, StatusFilePath(), and WARNING.

Referenced by KeepFileRestoredFromArchive(), WalRcvFetchTimeLineHistoryFiles(), WalReceiverMain(), and XLogWalRcvClose().

◆ XLogArchiveIsBusy()

bool XLogArchiveIsBusy ( const char *  xlog)

Definition at line 613 of file xlogarchive.c.

614 {
615  char archiveStatusPath[MAXPGPATH];
616  struct stat stat_buf;
617 
618  /* First check for .done --- this means archiver is done with it */
619  StatusFilePath(archiveStatusPath, xlog, ".done");
620  if (stat(archiveStatusPath, &stat_buf) == 0)
621  return false;
622 
623  /* check for .ready --- this means archiver is still busy with it */
624  StatusFilePath(archiveStatusPath, xlog, ".ready");
625  if (stat(archiveStatusPath, &stat_buf) == 0)
626  return true;
627 
628  /* Race condition --- maybe archiver just finished, so recheck */
629  StatusFilePath(archiveStatusPath, xlog, ".done");
630  if (stat(archiveStatusPath, &stat_buf) == 0)
631  return false;
632 
633  /*
634  * Check to see if the WAL file has been removed by checkpoint, which
635  * implies it has already been archived, and explains why we can't see a
636  * status file for it.
637  */
638  snprintf(archiveStatusPath, MAXPGPATH, XLOGDIR "/%s", xlog);
639  if (stat(archiveStatusPath, &stat_buf) != 0 &&
640  errno == ENOENT)
641  return false;
642 
643  return true;
644 }

References MAXPGPATH, snprintf, stat, StatusFilePath(), and XLOGDIR.

Referenced by do_pg_backup_stop().

◆ XLogArchiveIsReady()

bool XLogArchiveIsReady ( const char *  xlog)

Definition at line 688 of file xlogarchive.c.

689 {
690  char archiveStatusPath[MAXPGPATH];
691  struct stat stat_buf;
692 
693  StatusFilePath(archiveStatusPath, xlog, ".ready");
694  if (stat(archiveStatusPath, &stat_buf) == 0)
695  return true;
696 
697  return false;
698 }

References MAXPGPATH, stat, and StatusFilePath().

Referenced by RemoveNonParentXlogFiles().

◆ XLogArchiveIsReadyOrDone()

bool XLogArchiveIsReadyOrDone ( const char *  xlog)

Definition at line 658 of file xlogarchive.c.

659 {
660  char archiveStatusPath[MAXPGPATH];
661  struct stat stat_buf;
662 
663  /* First check for .done --- this means archiver is done with it */
664  StatusFilePath(archiveStatusPath, xlog, ".done");
665  if (stat(archiveStatusPath, &stat_buf) == 0)
666  return true;
667 
668  /* check for .ready --- this means archiver is still busy with it */
669  StatusFilePath(archiveStatusPath, xlog, ".ready");
670  if (stat(archiveStatusPath, &stat_buf) == 0)
671  return true;
672 
673  /* Race condition --- maybe archiver just finished, so recheck */
674  StatusFilePath(archiveStatusPath, xlog, ".done");
675  if (stat(archiveStatusPath, &stat_buf) == 0)
676  return true;
677 
678  return false;
679 }

References MAXPGPATH, stat, and StatusFilePath().

Referenced by CleanupAfterArchiveRecovery().

◆ XLogArchiveNotify()

void XLogArchiveNotify ( const char *  xlog)

Definition at line 438 of file xlogarchive.c.

439 {
440  char archiveStatusPath[MAXPGPATH];
441  FILE *fd;
442 
443  /* insert an otherwise empty file called <XLOG>.ready */
444  StatusFilePath(archiveStatusPath, xlog, ".ready");
445  fd = AllocateFile(archiveStatusPath, "w");
446  if (fd == NULL)
447  {
448  ereport(LOG,
450  errmsg("could not create archive status file \"%s\": %m",
451  archiveStatusPath)));
452  return;
453  }
454  if (FreeFile(fd))
455  {
456  ereport(LOG,
458  errmsg("could not write archive status file \"%s\": %m",
459  archiveStatusPath)));
460  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
468  * 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  */
474  if (IsTLHistoryFileName(xlog))
476 
477  /* Notify archiver that it's got something to do */
478  if (IsUnderPostmaster)
479  PgArchWakeup();
480 }
bool IsUnderPostmaster
Definition: globals.c:113
void PgArchForceDirScan(void)
Definition: pgarch.c:710
void PgArchWakeup(void)
Definition: pgarch.c:265
static bool IsTLHistoryFileName(const char *fname)

References AllocateFile(), ereport, errcode_for_file_access(), errmsg(), fd(), FreeFile(), IsTLHistoryFileName(), IsUnderPostmaster, LOG, MAXPGPATH, PgArchForceDirScan(), PgArchWakeup(), and StatusFilePath().

Referenced by CleanupAfterArchiveRecovery(), KeepFileRestoredFromArchive(), WalRcvFetchTimeLineHistoryFiles(), WalReceiverMain(), writeTimeLineHistory(), XLogArchiveCheckDone(), XLogArchiveNotifySeg(), and XLogWalRcvClose().

◆ XLogArchiveNotifySeg()

void XLogArchiveNotifySeg ( XLogSegNo  segno,
TimeLineID  tli 
)

Definition at line 486 of file xlogarchive.c.

487 {
488  char xlog[MAXFNAMELEN];
489 
490  Assert(tli != 0);
491 
492  XLogFileName(xlog, tli, segno, wal_segment_size);
493  XLogArchiveNotify(xlog);
494 }
#define MAXFNAMELEN

References Assert(), MAXFNAMELEN, wal_segment_size, XLogArchiveNotify(), and XLogFileName().

Referenced by XLogWrite().