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 "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 290 of file xlogarchive.c.

292 {
293  char xlogRecoveryCmd[MAXPGPATH];
294  char lastRestartPointFname[MAXPGPATH];
295  char *dp;
296  char *endp;
297  const char *sp;
298  int rc;
299  XLogSegNo restartSegNo;
300  XLogRecPtr restartRedoPtr;
301  TimeLineID restartTli;
302 
303  Assert(command && commandName);
304 
305  /*
306  * Calculate the archive file cutoff point for use during log shipping
307  * replication. All files earlier than this point can be deleted from the
308  * archive, though there is no requirement to do so.
309  */
310  GetOldestRestartPoint(&restartRedoPtr, &restartTli);
311  XLByteToSeg(restartRedoPtr, restartSegNo, wal_segment_size);
312  XLogFileName(lastRestartPointFname, restartTli, restartSegNo,
314 
315  /*
316  * construct the command to be executed
317  */
318  dp = xlogRecoveryCmd;
319  endp = xlogRecoveryCmd + MAXPGPATH - 1;
320  *endp = '\0';
321 
322  for (sp = command; *sp; sp++)
323  {
324  if (*sp == '%')
325  {
326  switch (sp[1])
327  {
328  case 'r':
329  /* %r: filename of last restartpoint */
330  sp++;
331  strlcpy(dp, lastRestartPointFname, endp - dp);
332  dp += strlen(dp);
333  break;
334  case '%':
335  /* convert %% to a single % */
336  sp++;
337  if (dp < endp)
338  *dp++ = *sp;
339  break;
340  default:
341  /* otherwise treat the % as not special */
342  if (dp < endp)
343  *dp++ = *sp;
344  break;
345  }
346  }
347  else
348  {
349  if (dp < endp)
350  *dp++ = *sp;
351  }
352  }
353  *dp = '\0';
354 
355  ereport(DEBUG3,
356  (errmsg_internal("executing %s \"%s\"", commandName, command)));
357 
358  /*
359  * execute the constructed command
360  */
361  pgstat_report_wait_start(wait_event_info);
362  rc = system(xlogRecoveryCmd);
364 
365  if (rc != 0)
366  {
367  /*
368  * If the failure was due to any sort of signal, it's best to punt and
369  * abort recovery. See comments in RestoreArchivedFile().
370  */
371  ereport((failOnSignal && wait_result_is_any_signal(rc, true)) ? FATAL : WARNING,
372  /*------
373  translator: First %s represents a postgresql.conf parameter name like
374  "recovery_end_command", the 2nd is the value of that parameter, the
375  third an already translated error message. */
376  (errmsg("%s \"%s\": %s", commandName,
377  command, wait_result_to_str(rc))));
378  }
379 }
int errmsg_internal(const char *fmt,...)
Definition: elog.c:991
int errmsg(const char *fmt,...)
Definition: elog.c:904
#define DEBUG3
Definition: elog.h:22
#define FATAL
Definition: elog.h:35
#define WARNING
Definition: elog.h:30
#define ereport(elevel,...)
Definition: elog.h:143
Assert(fmt[strlen(fmt) - 1] !='\n')
#define MAXPGPATH
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45
char * wait_result_to_str(int exitstatus)
Definition: wait_error.c:32
bool wait_result_is_any_signal(int exit_status, bool include_command_not_found)
Definition: wait_error.c:111
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: wait_event.h:266
static void pgstat_report_wait_end(void)
Definition: wait_event.h:282
int wal_segment_size
Definition: xlog.c:144
void GetOldestRestartPoint(XLogRecPtr *oldrecptr, TimeLineID *oldtli)
Definition: xlog.c:8833
#define XLogFileName(fname, tli, logSegNo, wal_segsz_bytes)
#define XLByteToSeg(xlrp, logSegNo, 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, GetOldestRestartPoint(), MAXPGPATH, pgstat_report_wait_end(), pgstat_report_wait_start(), strlcpy(), 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 388 of file xlogarchive.c.

389 {
390  char xlogfpath[MAXPGPATH];
391  bool reload = false;
392  struct stat statbuf;
393 
394  snprintf(xlogfpath, MAXPGPATH, XLOGDIR "/%s", xlogfname);
395 
396  if (stat(xlogfpath, &statbuf) == 0)
397  {
398  char oldpath[MAXPGPATH];
399 
400 #ifdef WIN32
401  static unsigned int deletedcounter = 1;
402 
403  /*
404  * On Windows, if another process (e.g a walsender process) holds the
405  * file open in FILE_SHARE_DELETE mode, unlink will succeed, but the
406  * file will still show up in directory listing until the last handle
407  * is closed, and we cannot rename the new file in its place until
408  * that. To avoid that problem, rename the old file to a temporary
409  * name first. Use a counter to create a unique filename, because the
410  * same file might be restored from the archive multiple times, and a
411  * walsender could still be holding onto an old deleted version of it.
412  */
413  snprintf(oldpath, MAXPGPATH, "%s.deleted%u",
414  xlogfpath, deletedcounter++);
415  if (rename(xlogfpath, oldpath) != 0)
416  {
417  ereport(ERROR,
419  errmsg("could not rename file \"%s\" to \"%s\": %m",
420  xlogfpath, oldpath)));
421  }
422 #else
423  /* same-size buffers, so this never truncates */
424  strlcpy(oldpath, xlogfpath, MAXPGPATH);
425 #endif
426  if (unlink(oldpath) != 0)
427  ereport(FATAL,
429  errmsg("could not remove file \"%s\": %m",
430  xlogfpath)));
431  reload = true;
432  }
433 
435 
436  /*
437  * Create .done file forcibly to prevent the restored segment from being
438  * archived again later.
439  */
441  XLogArchiveForceDone(xlogfname);
442  else
443  XLogArchiveNotify(xlogfname);
444 
445  /*
446  * If the existing file was replaced, since walsenders might have it open,
447  * request them to reload a currently-open segment. This is only required
448  * for WAL segments, walsenders don't hold other files open, but there's
449  * no harm in doing this too often, and we don't know what kind of a file
450  * we're dealing with here.
451  */
452  if (reload)
454 
455  /*
456  * Signal walsender that new WAL has arrived. Again, this isn't necessary
457  * if we restored something other than a WAL segment, but it does no harm
458  * either.
459  */
460  WalSndWakeup();
461 }
int errcode_for_file_access(void)
Definition: elog.c:716
#define ERROR
Definition: elog.h:33
int durable_rename(const char *oldfile, const char *newfile, int elevel)
Definition: fd.c:699
static char xlogfpath[MAXPGPATH]
Definition: parsexlog.c:45
#define snprintf
Definition: port.h:225
void WalSndWakeup(void)
Definition: walsender.c:3309
void WalSndRqstFileReload(void)
Definition: walsender.c:3189
#define stat
Definition: win32_port.h:283
int XLogArchiveMode
Definition: xlog.c:120
@ ARCHIVE_MODE_ALWAYS
Definition: xlog.h:62
#define XLOGDIR
void XLogArchiveForceDone(const char *xlog)
Definition: xlogarchive.c:540
void XLogArchiveNotify(const char *xlog)
Definition: xlogarchive.c:474

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 54 of file xlogarchive.c.

57 {
58  char xlogpath[MAXPGPATH];
59  char *xlogRestoreCmd;
60  char lastRestartPointFname[MAXPGPATH];
61  int rc;
62  struct stat stat_buf;
63  XLogSegNo restartSegNo;
64  XLogRecPtr restartRedoPtr;
65  TimeLineID restartTli;
66 
67  /*
68  * Ignore restore_command when not in archive recovery (meaning we are in
69  * crash recovery).
70  */
72  goto not_available;
73 
74  /* In standby mode, restore_command might not be supplied */
75  if (recoveryRestoreCommand == NULL || strcmp(recoveryRestoreCommand, "") == 0)
76  goto not_available;
77 
78  /*
79  * When doing archive recovery, we always prefer an archived log file even
80  * if a file of the same name exists in XLOGDIR. The reason is that the
81  * file in XLOGDIR could be an old, un-filled or partly-filled version
82  * that was copied and restored as part of backing up $PGDATA.
83  *
84  * We could try to optimize this slightly by checking the local copy
85  * lastchange timestamp against the archived copy, but we have no API to
86  * do this, nor can we guarantee that the lastchange timestamp was
87  * preserved correctly when we copied to archive. Our aim is robustness,
88  * so we elect not to do this.
89  *
90  * If we cannot obtain the log file from the archive, however, we will try
91  * to use the XLOGDIR file if it exists. This is so that we can make use
92  * of log segments that weren't yet transferred to the archive.
93  *
94  * Notice that we don't actually overwrite any files when we copy back
95  * from archive because the restore_command may inadvertently restore
96  * inappropriate xlogs, or they may be corrupt, so we may wish to fallback
97  * to the segments remaining in current XLOGDIR later. The
98  * copy-from-archive filename is always the same, ensuring that we don't
99  * run out of disk space on long recoveries.
100  */
101  snprintf(xlogpath, MAXPGPATH, XLOGDIR "/%s", recovername);
102 
103  /*
104  * Make sure there is no existing file named recovername.
105  */
106  if (stat(xlogpath, &stat_buf) != 0)
107  {
108  if (errno != ENOENT)
109  ereport(FATAL,
111  errmsg("could not stat file \"%s\": %m",
112  xlogpath)));
113  }
114  else
115  {
116  if (unlink(xlogpath) != 0)
117  ereport(FATAL,
119  errmsg("could not remove file \"%s\": %m",
120  xlogpath)));
121  }
122 
123  /*
124  * Calculate the archive file cutoff point for use during log shipping
125  * replication. All files earlier than this point can be deleted from the
126  * archive, though there is no requirement to do so.
127  *
128  * If cleanup is not enabled, initialise this with the filename of
129  * InvalidXLogRecPtr, which will prevent the deletion of any WAL files
130  * from the archive because of the alphabetic sorting property of WAL
131  * filenames.
132  *
133  * Once we have successfully located the redo pointer of the checkpoint
134  * from which we start recovery we never request a file prior to the redo
135  * pointer of the last restartpoint. When redo begins we know that we have
136  * successfully located it, so there is no need for additional status
137  * flags to signify the point when we can begin deleting WAL files from
138  * the archive.
139  */
140  if (cleanupEnabled)
141  {
142  GetOldestRestartPoint(&restartRedoPtr, &restartTli);
143  XLByteToSeg(restartRedoPtr, restartSegNo, wal_segment_size);
144  XLogFileName(lastRestartPointFname, restartTli, restartSegNo,
146  /* we shouldn't need anything earlier than last restart point */
147  Assert(strcmp(lastRestartPointFname, xlogfname) <= 0);
148  }
149  else
150  XLogFileName(lastRestartPointFname, 0, 0L, wal_segment_size);
151 
152  /* Build the restore command to execute */
154  xlogpath, xlogfname,
155  lastRestartPointFname);
156  if (xlogRestoreCmd == NULL)
157  elog(ERROR, "could not build restore command \"%s\"",
159 
160  ereport(DEBUG3,
161  (errmsg_internal("executing restore command \"%s\"",
162  xlogRestoreCmd)));
163 
164  /*
165  * Check signals before restore command and reset afterwards.
166  */
168 
169  /*
170  * Copy xlog from archival storage to XLOGDIR
171  */
173  rc = system(xlogRestoreCmd);
175 
177  pfree(xlogRestoreCmd);
178 
179  if (rc == 0)
180  {
181  /*
182  * command apparently succeeded, but let's make sure the file is
183  * really there now and has the correct size.
184  */
185  if (stat(xlogpath, &stat_buf) == 0)
186  {
187  if (expectedSize > 0 && stat_buf.st_size != expectedSize)
188  {
189  int elevel;
190 
191  /*
192  * If we find a partial file in standby mode, we assume it's
193  * because it's just being copied to the archive, and keep
194  * trying.
195  *
196  * Otherwise treat a wrong-sized file as FATAL to ensure the
197  * DBA would notice it, but is that too strong? We could try
198  * to plow ahead with a local copy of the file ... but the
199  * problem is that there probably isn't one, and we'd
200  * incorrectly conclude we've reached the end of WAL and we're
201  * done recovering ...
202  */
203  if (StandbyMode && stat_buf.st_size < expectedSize)
204  elevel = DEBUG1;
205  else
206  elevel = FATAL;
207  ereport(elevel,
208  (errmsg("archive file \"%s\" has wrong size: %lld instead of %lld",
209  xlogfname,
210  (long long int) stat_buf.st_size,
211  (long long int) expectedSize)));
212  return false;
213  }
214  else
215  {
216  ereport(LOG,
217  (errmsg("restored log file \"%s\" from archive",
218  xlogfname)));
219  strcpy(path, xlogpath);
220  return true;
221  }
222  }
223  else
224  {
225  /* stat failed */
226  int elevel = (errno == ENOENT) ? LOG : FATAL;
227 
228  ereport(elevel,
230  errmsg("could not stat file \"%s\": %m", xlogpath),
231  errdetail("restore_command returned a zero exit status, but stat() failed.")));
232  }
233  }
234 
235  /*
236  * Remember, we rollforward UNTIL the restore fails so failure here is
237  * just part of the process... that makes it difficult to determine
238  * whether the restore failed because there isn't an archive to restore,
239  * or because the administrator has specified the restore program
240  * incorrectly. We have to assume the former.
241  *
242  * However, if the failure was due to any sort of signal, it's best to
243  * punt and abort recovery. (If we "return false" here, upper levels will
244  * assume that recovery is complete and start up the database!) It's
245  * essential to abort on child SIGINT and SIGQUIT, because per spec
246  * system() ignores SIGINT and SIGQUIT while waiting; if we see one of
247  * those it's a good bet we should have gotten it too.
248  *
249  * On SIGTERM, assume we have received a fast shutdown request, and exit
250  * cleanly. It's pure chance whether we receive the SIGTERM first, or the
251  * child process. If we receive it first, the signal handler will call
252  * proc_exit, otherwise we do it here. If we or the child process received
253  * SIGTERM for any other reason than a fast shutdown request, postmaster
254  * will perform an immediate shutdown when it sees us exiting
255  * unexpectedly.
256  *
257  * We treat hard shell errors such as "command not found" as fatal, too.
258  */
259  if (wait_result_is_signal(rc, SIGTERM))
260  proc_exit(1);
261 
263  (errmsg("could not restore file \"%s\" from archive: %s",
264  xlogfname, wait_result_to_str(rc))));
265 
266 not_available:
267 
268  /*
269  * if an archived file is not available, there might still be a version of
270  * this file in XLOGDIR, so return that as the filename to open.
271  *
272  * In many recovery scenarios we expect this to fail also, but if so that
273  * just means we've reached the end of WAL.
274  */
275  snprintf(path, MAXPGPATH, XLOGDIR "/%s", xlogfname);
276  return false;
277 }
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:1037
#define LOG
Definition: elog.h:25
#define DEBUG2
Definition: elog.h:23
#define DEBUG1
Definition: elog.h:24
#define elog(elevel,...)
Definition: elog.h:218
void proc_exit(int code)
Definition: ipc.c:104
void pfree(void *pointer)
Definition: mcxt.c:1175
bool wait_result_is_signal(int exit_status, int signum)
Definition: wait_error.c:92
@ WAIT_EVENT_RESTORE_COMMAND
Definition: wait_event.h:126
bool ArchiveRecoveryRequested
Definition: xlogrecovery.c:134
char * recoveryRestoreCommand
Definition: xlogrecovery.c:78
bool StandbyMode
Definition: xlogrecovery.c:144

References ArchiveRecoveryRequested, Assert(), BuildRestoreCommand(), DEBUG1, DEBUG2, DEBUG3, elog, ereport, errcode_for_file_access(), errdetail(), errmsg(), errmsg_internal(), ERROR, FATAL, 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 595 of file xlogarchive.c.

596 {
597  char archiveStatusPath[MAXPGPATH];
598  struct stat stat_buf;
599 
600  /* The file is always deletable if archive_mode is "off". */
601  if (!XLogArchivingActive())
602  return true;
603 
604  /*
605  * During archive recovery, the file is deletable if archive_mode is not
606  * "always".
607  */
608  if (!XLogArchivingAlways() &&
610  return true;
611 
612  /*
613  * At this point of the logic, note that we are either a primary with
614  * archive_mode set to "on" or "always", or a standby with archive_mode
615  * set to "always".
616  */
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 true;
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 false;
627 
628  /* Race condition --- maybe archiver just finished, so recheck */
629  StatusFilePath(archiveStatusPath, xlog, ".done");
630  if (stat(archiveStatusPath, &stat_buf) == 0)
631  return true;
632 
633  /* Retry creation of the .ready file */
634  XLogArchiveNotify(xlog);
635  return false;
636 }
RecoveryState GetRecoveryState(void)
Definition: xlog.c:5789
#define XLogArchivingActive()
Definition: xlog.h:94
#define XLogArchivingAlways()
Definition: xlog.h:97
@ RECOVERY_STATE_ARCHIVE
Definition: xlog.h:87
#define StatusFilePath(path, xlog, 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 742 of file xlogarchive.c.

743 {
744  char archiveStatusPath[MAXPGPATH];
745 
746  /* Remove the .done file */
747  StatusFilePath(archiveStatusPath, xlog, ".done");
748  unlink(archiveStatusPath);
749  /* should we complain about failure? */
750 
751  /* Remove the .ready file if present --- normally it shouldn't be */
752  StatusFilePath(archiveStatusPath, xlog, ".ready");
753  unlink(archiveStatusPath);
754  /* should we complain about failure? */
755 }

References MAXPGPATH, and StatusFilePath.

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

◆ XLogArchiveForceDone()

void XLogArchiveForceDone ( const char *  xlog)

Definition at line 540 of file xlogarchive.c.

541 {
542  char archiveReady[MAXPGPATH];
543  char archiveDone[MAXPGPATH];
544  struct stat stat_buf;
545  FILE *fd;
546 
547  /* Exit if already known done */
548  StatusFilePath(archiveDone, xlog, ".done");
549  if (stat(archiveDone, &stat_buf) == 0)
550  return;
551 
552  /* If .ready exists, rename it to .done */
553  StatusFilePath(archiveReady, xlog, ".ready");
554  if (stat(archiveReady, &stat_buf) == 0)
555  {
556  (void) durable_rename(archiveReady, archiveDone, WARNING);
557  return;
558  }
559 
560  /* insert an otherwise empty file called <XLOG>.done */
561  fd = AllocateFile(archiveDone, "w");
562  if (fd == NULL)
563  {
564  ereport(LOG,
566  errmsg("could not create archive status file \"%s\": %m",
567  archiveDone)));
568  return;
569  }
570  if (FreeFile(fd))
571  {
572  ereport(LOG,
574  errmsg("could not write archive status file \"%s\": %m",
575  archiveDone)));
576  return;
577  }
578 }
FILE * AllocateFile(const char *name, const char *mode)
Definition: fd.c:2461
int FreeFile(FILE *file)
Definition: fd.c:2660
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 649 of file xlogarchive.c.

650 {
651  char archiveStatusPath[MAXPGPATH];
652  struct stat stat_buf;
653 
654  /* First check for .done --- this means archiver is done with it */
655  StatusFilePath(archiveStatusPath, xlog, ".done");
656  if (stat(archiveStatusPath, &stat_buf) == 0)
657  return false;
658 
659  /* check for .ready --- this means archiver is still busy with it */
660  StatusFilePath(archiveStatusPath, xlog, ".ready");
661  if (stat(archiveStatusPath, &stat_buf) == 0)
662  return true;
663 
664  /* Race condition --- maybe archiver just finished, so recheck */
665  StatusFilePath(archiveStatusPath, xlog, ".done");
666  if (stat(archiveStatusPath, &stat_buf) == 0)
667  return false;
668 
669  /*
670  * Check to see if the WAL file has been removed by checkpoint, which
671  * implies it has already been archived, and explains why we can't see a
672  * status file for it.
673  */
674  snprintf(archiveStatusPath, MAXPGPATH, XLOGDIR "/%s", xlog);
675  if (stat(archiveStatusPath, &stat_buf) != 0 &&
676  errno == ENOENT)
677  return false;
678 
679  return true;
680 }

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

Referenced by do_pg_backup_stop().

◆ XLogArchiveIsReady()

bool XLogArchiveIsReady ( const char *  xlog)

Definition at line 724 of file xlogarchive.c.

725 {
726  char archiveStatusPath[MAXPGPATH];
727  struct stat stat_buf;
728 
729  StatusFilePath(archiveStatusPath, xlog, ".ready");
730  if (stat(archiveStatusPath, &stat_buf) == 0)
731  return true;
732 
733  return false;
734 }

References MAXPGPATH, stat, and StatusFilePath.

Referenced by RemoveNonParentXlogFiles().

◆ XLogArchiveIsReadyOrDone()

bool XLogArchiveIsReadyOrDone ( const char *  xlog)

Definition at line 694 of file xlogarchive.c.

695 {
696  char archiveStatusPath[MAXPGPATH];
697  struct stat stat_buf;
698 
699  /* First check for .done --- this means archiver is done with it */
700  StatusFilePath(archiveStatusPath, xlog, ".done");
701  if (stat(archiveStatusPath, &stat_buf) == 0)
702  return true;
703 
704  /* check for .ready --- this means archiver is still busy with it */
705  StatusFilePath(archiveStatusPath, xlog, ".ready");
706  if (stat(archiveStatusPath, &stat_buf) == 0)
707  return true;
708 
709  /* Race condition --- maybe archiver just finished, so recheck */
710  StatusFilePath(archiveStatusPath, xlog, ".done");
711  if (stat(archiveStatusPath, &stat_buf) == 0)
712  return true;
713 
714  return false;
715 }

References MAXPGPATH, stat, and StatusFilePath.

Referenced by CleanupAfterArchiveRecovery().

◆ XLogArchiveNotify()

void XLogArchiveNotify ( const char *  xlog)

Definition at line 474 of file xlogarchive.c.

475 {
476  char archiveStatusPath[MAXPGPATH];
477  FILE *fd;
478 
479  /* insert an otherwise empty file called <XLOG>.ready */
480  StatusFilePath(archiveStatusPath, xlog, ".ready");
481  fd = AllocateFile(archiveStatusPath, "w");
482  if (fd == NULL)
483  {
484  ereport(LOG,
486  errmsg("could not create archive status file \"%s\": %m",
487  archiveStatusPath)));
488  return;
489  }
490  if (FreeFile(fd))
491  {
492  ereport(LOG,
494  errmsg("could not write archive status file \"%s\": %m",
495  archiveStatusPath)));
496  return;
497  }
498 
499  /*
500  * Timeline history files are given the highest archival priority to lower
501  * the chance that a promoted standby will choose a timeline that is
502  * already in use. However, the archiver ordinarily tries to gather
503  * multiple files to archive from each scan of the archive_status
504  * directory, which means that newly created timeline history files could
505  * be left unarchived for a while. To ensure that the archiver picks up
506  * timeline history files as soon as possible, we force the archiver to
507  * scan the archive_status directory the next time it looks for a file to
508  * archive.
509  */
510  if (IsTLHistoryFileName(xlog))
512 
513  /* Notify archiver that it's got something to do */
514  if (IsUnderPostmaster)
515  PgArchWakeup();
516 }
bool IsUnderPostmaster
Definition: globals.c:113
void PgArchForceDirScan(void)
Definition: pgarch.c:723
void PgArchWakeup(void)
Definition: pgarch.c:268
#define IsTLHistoryFileName(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 522 of file xlogarchive.c.

523 {
524  char xlog[MAXFNAMELEN];
525 
526  Assert(tli != 0);
527 
528  XLogFileName(xlog, tli, segno, wal_segment_size);
529  XLogArchiveNotify(xlog);
530 }
#define MAXFNAMELEN

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

Referenced by XLogWrite().