PostgreSQL Source Code  git master
xlogarchive.c
Go to the documentation of this file.
1 /*-------------------------------------------------------------------------
2  *
3  * xlogarchive.c
4  * Functions for archiving WAL files and restoring from the archive.
5  *
6  *
7  * Portions Copyright (c) 1996-2019, 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 "miscadmin.h"
25 #include "postmaster/startup.h"
26 #include "replication/walsender.h"
27 #include "storage/fd.h"
28 #include "storage/ipc.h"
29 #include "storage/lwlock.h"
30 #include "storage/pmsignal.h"
31 
32 /*
33  * Attempt to retrieve the specified file from off-line archival storage.
34  * If successful, fill "path" with its complete path (note that this will be
35  * a temp file name that doesn't follow the normal naming convention), and
36  * return true.
37  *
38  * If not successful, fill "path" with the name of the normal on-line file
39  * (which may or may not actually exist, but we'll try to use it), and return
40  * false.
41  *
42  * For fixed-size files, the caller may pass the expected size as an
43  * additional crosscheck on successful recovery. If the file size is not
44  * known, set expectedSize = 0.
45  *
46  * When 'cleanupEnabled' is false, refrain from deleting any old WAL segments
47  * in the archive. This is used when fetching the initial checkpoint record,
48  * when we are not yet sure how far back we need the WAL.
49  */
50 bool
51 RestoreArchivedFile(char *path, const char *xlogfname,
52  const char *recovername, off_t expectedSize,
53  bool cleanupEnabled)
54 {
55  char xlogpath[MAXPGPATH];
56  char xlogRestoreCmd[MAXPGPATH];
57  char lastRestartPointFname[MAXPGPATH];
58  char *dp;
59  char *endp;
60  const char *sp;
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
69  * we are in 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  /*
153  * construct the command to be executed
154  */
155  dp = xlogRestoreCmd;
156  endp = xlogRestoreCmd + MAXPGPATH - 1;
157  *endp = '\0';
158 
159  for (sp = recoveryRestoreCommand; *sp; sp++)
160  {
161  if (*sp == '%')
162  {
163  switch (sp[1])
164  {
165  case 'p':
166  /* %p: relative path of target file */
167  sp++;
168  StrNCpy(dp, xlogpath, endp - dp);
169  make_native_path(dp);
170  dp += strlen(dp);
171  break;
172  case 'f':
173  /* %f: filename of desired file */
174  sp++;
175  StrNCpy(dp, xlogfname, endp - dp);
176  dp += strlen(dp);
177  break;
178  case 'r':
179  /* %r: filename of last restartpoint */
180  sp++;
181  StrNCpy(dp, lastRestartPointFname, endp - dp);
182  dp += strlen(dp);
183  break;
184  case '%':
185  /* convert %% to a single % */
186  sp++;
187  if (dp < endp)
188  *dp++ = *sp;
189  break;
190  default:
191  /* otherwise treat the % as not special */
192  if (dp < endp)
193  *dp++ = *sp;
194  break;
195  }
196  }
197  else
198  {
199  if (dp < endp)
200  *dp++ = *sp;
201  }
202  }
203  *dp = '\0';
204 
205  ereport(DEBUG3,
206  (errmsg_internal("executing restore command \"%s\"",
207  xlogRestoreCmd)));
208 
209  /*
210  * Check signals before restore command and reset afterwards.
211  */
213 
214  /*
215  * Copy xlog from archival storage to XLOGDIR
216  */
217  rc = system(xlogRestoreCmd);
218 
220 
221  if (rc == 0)
222  {
223  /*
224  * command apparently succeeded, but let's make sure the file is
225  * really there now and has the correct size.
226  */
227  if (stat(xlogpath, &stat_buf) == 0)
228  {
229  if (expectedSize > 0 && stat_buf.st_size != expectedSize)
230  {
231  int elevel;
232 
233  /*
234  * If we find a partial file in standby mode, we assume it's
235  * because it's just being copied to the archive, and keep
236  * trying.
237  *
238  * Otherwise treat a wrong-sized file as FATAL to ensure the
239  * DBA would notice it, but is that too strong? We could try
240  * to plow ahead with a local copy of the file ... but the
241  * problem is that there probably isn't one, and we'd
242  * incorrectly conclude we've reached the end of WAL and we're
243  * done recovering ...
244  */
245  if (StandbyMode && stat_buf.st_size < expectedSize)
246  elevel = DEBUG1;
247  else
248  elevel = FATAL;
249  ereport(elevel,
250  (errmsg("archive file \"%s\" has wrong size: %lu instead of %lu",
251  xlogfname,
252  (unsigned long) stat_buf.st_size,
253  (unsigned long) expectedSize)));
254  return false;
255  }
256  else
257  {
258  ereport(LOG,
259  (errmsg("restored log file \"%s\" from archive",
260  xlogfname)));
261  strcpy(path, xlogpath);
262  return true;
263  }
264  }
265  else
266  {
267  /* stat failed */
268  if (errno != ENOENT)
269  ereport(FATAL,
271  errmsg("could not stat file \"%s\": %m",
272  xlogpath)));
273  }
274  }
275 
276  /*
277  * Remember, we rollforward UNTIL the restore fails so failure here is
278  * just part of the process... that makes it difficult to determine
279  * whether the restore failed because there isn't an archive to restore,
280  * or because the administrator has specified the restore program
281  * incorrectly. We have to assume the former.
282  *
283  * However, if the failure was due to any sort of signal, it's best to
284  * punt and abort recovery. (If we "return false" here, upper levels will
285  * assume that recovery is complete and start up the database!) It's
286  * essential to abort on child SIGINT and SIGQUIT, because per spec
287  * system() ignores SIGINT and SIGQUIT while waiting; if we see one of
288  * those it's a good bet we should have gotten it too.
289  *
290  * On SIGTERM, assume we have received a fast shutdown request, and exit
291  * cleanly. It's pure chance whether we receive the SIGTERM first, or the
292  * child process. If we receive it first, the signal handler will call
293  * proc_exit, otherwise we do it here. If we or the child process received
294  * SIGTERM for any other reason than a fast shutdown request, postmaster
295  * will perform an immediate shutdown when it sees us exiting
296  * unexpectedly.
297  *
298  * We treat hard shell errors such as "command not found" as fatal, too.
299  */
300  if (wait_result_is_signal(rc, SIGTERM))
301  proc_exit(1);
302 
304  (errmsg("could not restore file \"%s\" from archive: %s",
305  xlogfname, wait_result_to_str(rc))));
306 
307 not_available:
308 
309  /*
310  * if an archived file is not available, there might still be a version of
311  * this file in XLOGDIR, so return that as the filename to open.
312  *
313  * In many recovery scenarios we expect this to fail also, but if so that
314  * just means we've reached the end of WAL.
315  */
316  snprintf(path, MAXPGPATH, XLOGDIR "/%s", xlogfname);
317  return false;
318 }
319 
320 /*
321  * Attempt to execute an external shell command during recovery.
322  *
323  * 'command' is the shell command to be executed, 'commandName' is a
324  * human-readable name describing the command emitted in the logs. If
325  * 'failOnSignal' is true and the command is killed by a signal, a FATAL
326  * error is thrown. Otherwise a WARNING is emitted.
327  *
328  * This is currently used for recovery_end_command and archive_cleanup_command.
329  */
330 void
331 ExecuteRecoveryCommand(const char *command, const char *commandName, bool failOnSignal)
332 {
333  char xlogRecoveryCmd[MAXPGPATH];
334  char lastRestartPointFname[MAXPGPATH];
335  char *dp;
336  char *endp;
337  const char *sp;
338  int rc;
339  XLogSegNo restartSegNo;
340  XLogRecPtr restartRedoPtr;
341  TimeLineID restartTli;
342 
343  Assert(command && commandName);
344 
345  /*
346  * Calculate the archive file cutoff point for use during log shipping
347  * replication. All files earlier than this point can be deleted from the
348  * archive, though there is no requirement to do so.
349  */
350  GetOldestRestartPoint(&restartRedoPtr, &restartTli);
351  XLByteToSeg(restartRedoPtr, restartSegNo, wal_segment_size);
352  XLogFileName(lastRestartPointFname, restartTli, restartSegNo,
354 
355  /*
356  * construct the command to be executed
357  */
358  dp = xlogRecoveryCmd;
359  endp = xlogRecoveryCmd + MAXPGPATH - 1;
360  *endp = '\0';
361 
362  for (sp = command; *sp; sp++)
363  {
364  if (*sp == '%')
365  {
366  switch (sp[1])
367  {
368  case 'r':
369  /* %r: filename of last restartpoint */
370  sp++;
371  StrNCpy(dp, lastRestartPointFname, endp - dp);
372  dp += strlen(dp);
373  break;
374  case '%':
375  /* convert %% to a single % */
376  sp++;
377  if (dp < endp)
378  *dp++ = *sp;
379  break;
380  default:
381  /* otherwise treat the % as not special */
382  if (dp < endp)
383  *dp++ = *sp;
384  break;
385  }
386  }
387  else
388  {
389  if (dp < endp)
390  *dp++ = *sp;
391  }
392  }
393  *dp = '\0';
394 
395  ereport(DEBUG3,
396  (errmsg_internal("executing %s \"%s\"", commandName, command)));
397 
398  /*
399  * execute the constructed command
400  */
401  rc = system(xlogRecoveryCmd);
402  if (rc != 0)
403  {
404  /*
405  * If the failure was due to any sort of signal, it's best to punt and
406  * abort recovery. See comments in RestoreArchivedFile().
407  */
408  ereport((failOnSignal && wait_result_is_any_signal(rc, true)) ? FATAL : WARNING,
409  /*------
410  translator: First %s represents a postgresql.conf parameter name like
411  "recovery_end_command", the 2nd is the value of that parameter, the
412  third an already translated error message. */
413  (errmsg("%s \"%s\": %s", commandName,
414  command, wait_result_to_str(rc))));
415  }
416 }
417 
418 
419 /*
420  * A file was restored from the archive under a temporary filename (path),
421  * and now we want to keep it. Rename it under the permanent filename in
422  * pg_wal (xlogfname), replacing any existing file with the same name.
423  */
424 void
425 KeepFileRestoredFromArchive(const char *path, const char *xlogfname)
426 {
427  char xlogfpath[MAXPGPATH];
428  bool reload = false;
429  struct stat statbuf;
430 
431  snprintf(xlogfpath, MAXPGPATH, XLOGDIR "/%s", xlogfname);
432 
433  if (stat(xlogfpath, &statbuf) == 0)
434  {
435  char oldpath[MAXPGPATH];
436 
437 #ifdef WIN32
438  static unsigned int deletedcounter = 1;
439 
440  /*
441  * On Windows, if another process (e.g a walsender process) holds the
442  * file open in FILE_SHARE_DELETE mode, unlink will succeed, but the
443  * file will still show up in directory listing until the last handle
444  * is closed, and we cannot rename the new file in its place until
445  * that. To avoid that problem, rename the old file to a temporary
446  * name first. Use a counter to create a unique filename, because the
447  * same file might be restored from the archive multiple times, and a
448  * walsender could still be holding onto an old deleted version of it.
449  */
450  snprintf(oldpath, MAXPGPATH, "%s.deleted%u",
451  xlogfpath, deletedcounter++);
452  if (rename(xlogfpath, oldpath) != 0)
453  {
454  ereport(ERROR,
456  errmsg("could not rename file \"%s\" to \"%s\": %m",
457  xlogfpath, oldpath)));
458  }
459 #else
460  /* same-size buffers, so this never truncates */
461  strlcpy(oldpath, xlogfpath, MAXPGPATH);
462 #endif
463  if (unlink(oldpath) != 0)
464  ereport(FATAL,
466  errmsg("could not remove file \"%s\": %m",
467  xlogfpath)));
468  reload = true;
469  }
470 
471  durable_rename(path, xlogfpath, ERROR);
472 
473  /*
474  * Create .done file forcibly to prevent the restored segment from being
475  * archived again later.
476  */
478  XLogArchiveForceDone(xlogfname);
479  else
480  XLogArchiveNotify(xlogfname);
481 
482  /*
483  * If the existing file was replaced, since walsenders might have it open,
484  * request them to reload a currently-open segment. This is only required
485  * for WAL segments, walsenders don't hold other files open, but there's
486  * no harm in doing this too often, and we don't know what kind of a file
487  * we're dealing with here.
488  */
489  if (reload)
491 
492  /*
493  * Signal walsender that new WAL has arrived. Again, this isn't necessary
494  * if we restored something other than a WAL segment, but it does no harm
495  * either.
496  */
497  WalSndWakeup();
498 }
499 
500 /*
501  * XLogArchiveNotify
502  *
503  * Create an archive notification file
504  *
505  * The name of the notification file is the message that will be picked up
506  * by the archiver, e.g. we write 0000000100000001000000C6.ready
507  * and the archiver then knows to archive XLOGDIR/0000000100000001000000C6,
508  * then when complete, rename it to 0000000100000001000000C6.done
509  */
510 void
511 XLogArchiveNotify(const char *xlog)
512 {
513  char archiveStatusPath[MAXPGPATH];
514  FILE *fd;
515 
516  /* insert an otherwise empty file called <XLOG>.ready */
517  StatusFilePath(archiveStatusPath, xlog, ".ready");
518  fd = AllocateFile(archiveStatusPath, "w");
519  if (fd == NULL)
520  {
521  ereport(LOG,
523  errmsg("could not create archive status file \"%s\": %m",
524  archiveStatusPath)));
525  return;
526  }
527  if (FreeFile(fd))
528  {
529  ereport(LOG,
531  errmsg("could not write archive status file \"%s\": %m",
532  archiveStatusPath)));
533  return;
534  }
535 
536  /* Notify archiver that it's got something to do */
537  if (IsUnderPostmaster)
539 }
540 
541 /*
542  * Convenience routine to notify using segment number representation of filename
543  */
544 void
546 {
547  char xlog[MAXFNAMELEN];
548 
550  XLogArchiveNotify(xlog);
551 }
552 
553 /*
554  * XLogArchiveForceDone
555  *
556  * Emit notification forcibly that an XLOG segment file has been successfully
557  * archived, by creating <XLOG>.done regardless of whether <XLOG>.ready
558  * exists or not.
559  */
560 void
561 XLogArchiveForceDone(const char *xlog)
562 {
563  char archiveReady[MAXPGPATH];
564  char archiveDone[MAXPGPATH];
565  struct stat stat_buf;
566  FILE *fd;
567 
568  /* Exit if already known done */
569  StatusFilePath(archiveDone, xlog, ".done");
570  if (stat(archiveDone, &stat_buf) == 0)
571  return;
572 
573  /* If .ready exists, rename it to .done */
574  StatusFilePath(archiveReady, xlog, ".ready");
575  if (stat(archiveReady, &stat_buf) == 0)
576  {
577  (void) durable_rename(archiveReady, archiveDone, WARNING);
578  return;
579  }
580 
581  /* insert an otherwise empty file called <XLOG>.done */
582  fd = AllocateFile(archiveDone, "w");
583  if (fd == NULL)
584  {
585  ereport(LOG,
587  errmsg("could not create archive status file \"%s\": %m",
588  archiveDone)));
589  return;
590  }
591  if (FreeFile(fd))
592  {
593  ereport(LOG,
595  errmsg("could not write archive status file \"%s\": %m",
596  archiveDone)));
597  return;
598  }
599 }
600 
601 /*
602  * XLogArchiveCheckDone
603  *
604  * This is called when we are ready to delete or recycle an old XLOG segment
605  * file or backup history file. If it is okay to delete it then return true.
606  * If it is not time to delete it, make sure a .ready file exists, and return
607  * false.
608  *
609  * If <XLOG>.done exists, then return true; else if <XLOG>.ready exists,
610  * then return false; else create <XLOG>.ready and return false.
611  *
612  * The reason we do things this way is so that if the original attempt to
613  * create <XLOG>.ready fails, we'll retry during subsequent checkpoints.
614  */
615 bool
616 XLogArchiveCheckDone(const char *xlog)
617 {
618  char archiveStatusPath[MAXPGPATH];
619  struct stat stat_buf;
620  bool inRecovery = RecoveryInProgress();
621 
622  /*
623  * The file is always deletable if archive_mode is "off". On standbys
624  * archiving is disabled if archive_mode is "on", and enabled with
625  * "always". On a primary, archiving is enabled if archive_mode is "on"
626  * or "always".
627  */
628  if (!((XLogArchivingActive() && !inRecovery) ||
629  (XLogArchivingAlways() && inRecovery)))
630  return true;
631 
632  /* First check for .done --- this means archiver is done with it */
633  StatusFilePath(archiveStatusPath, xlog, ".done");
634  if (stat(archiveStatusPath, &stat_buf) == 0)
635  return true;
636 
637  /* check for .ready --- this means archiver is still busy with it */
638  StatusFilePath(archiveStatusPath, xlog, ".ready");
639  if (stat(archiveStatusPath, &stat_buf) == 0)
640  return false;
641 
642  /* Race condition --- maybe archiver just finished, so recheck */
643  StatusFilePath(archiveStatusPath, xlog, ".done");
644  if (stat(archiveStatusPath, &stat_buf) == 0)
645  return true;
646 
647  /* Retry creation of the .ready file */
648  XLogArchiveNotify(xlog);
649  return false;
650 }
651 
652 /*
653  * XLogArchiveIsBusy
654  *
655  * Check to see if an XLOG segment file is still unarchived.
656  * This is almost but not quite the inverse of XLogArchiveCheckDone: in
657  * the first place we aren't chartered to recreate the .ready file, and
658  * in the second place we should consider that if the file is already gone
659  * then it's not busy. (This check is needed to handle the race condition
660  * that a checkpoint already deleted the no-longer-needed file.)
661  */
662 bool
663 XLogArchiveIsBusy(const char *xlog)
664 {
665  char archiveStatusPath[MAXPGPATH];
666  struct stat stat_buf;
667 
668  /* First check for .done --- this means archiver is done with it */
669  StatusFilePath(archiveStatusPath, xlog, ".done");
670  if (stat(archiveStatusPath, &stat_buf) == 0)
671  return false;
672 
673  /* check for .ready --- this means archiver is still busy with it */
674  StatusFilePath(archiveStatusPath, xlog, ".ready");
675  if (stat(archiveStatusPath, &stat_buf) == 0)
676  return true;
677 
678  /* Race condition --- maybe archiver just finished, so recheck */
679  StatusFilePath(archiveStatusPath, xlog, ".done");
680  if (stat(archiveStatusPath, &stat_buf) == 0)
681  return false;
682 
683  /*
684  * Check to see if the WAL file has been removed by checkpoint, which
685  * implies it has already been archived, and explains why we can't see a
686  * status file for it.
687  */
688  snprintf(archiveStatusPath, MAXPGPATH, XLOGDIR "/%s", xlog);
689  if (stat(archiveStatusPath, &stat_buf) != 0 &&
690  errno == ENOENT)
691  return false;
692 
693  return true;
694 }
695 
696 /*
697  * XLogArchiveIsReadyOrDone
698  *
699  * Check to see if an XLOG segment file has a .ready or .done file.
700  * This is similar to XLogArchiveIsBusy(), but returns true if the file
701  * is already archived or is about to be archived.
702  *
703  * This is currently only used at recovery. During normal operation this
704  * would be racy: the file might get removed or marked with .ready as we're
705  * checking it, or immediately after we return.
706  */
707 bool
708 XLogArchiveIsReadyOrDone(const char *xlog)
709 {
710  char archiveStatusPath[MAXPGPATH];
711  struct stat stat_buf;
712 
713  /* First check for .done --- this means archiver is done with it */
714  StatusFilePath(archiveStatusPath, xlog, ".done");
715  if (stat(archiveStatusPath, &stat_buf) == 0)
716  return true;
717 
718  /* check for .ready --- this means archiver is still busy with it */
719  StatusFilePath(archiveStatusPath, xlog, ".ready");
720  if (stat(archiveStatusPath, &stat_buf) == 0)
721  return true;
722 
723  /* Race condition --- maybe archiver just finished, so recheck */
724  StatusFilePath(archiveStatusPath, xlog, ".done");
725  if (stat(archiveStatusPath, &stat_buf) == 0)
726  return true;
727 
728  return false;
729 }
730 
731 /*
732  * XLogArchiveIsReady
733  *
734  * Check to see if an XLOG segment file has an archive notification (.ready)
735  * file.
736  */
737 bool
738 XLogArchiveIsReady(const char *xlog)
739 {
740  char archiveStatusPath[MAXPGPATH];
741  struct stat stat_buf;
742 
743  StatusFilePath(archiveStatusPath, xlog, ".ready");
744  if (stat(archiveStatusPath, &stat_buf) == 0)
745  return true;
746 
747  return false;
748 }
749 
750 /*
751  * XLogArchiveCleanup
752  *
753  * Cleanup archive notification file(s) for a particular xlog segment
754  */
755 void
756 XLogArchiveCleanup(const char *xlog)
757 {
758  char archiveStatusPath[MAXPGPATH];
759 
760  /* Remove the .done file */
761  StatusFilePath(archiveStatusPath, xlog, ".done");
762  unlink(archiveStatusPath);
763  /* should we complain about failure? */
764 
765  /* Remove the .ready file if present --- normally it shouldn't be */
766  StatusFilePath(archiveStatusPath, xlog, ".ready");
767  unlink(archiveStatusPath);
768  /* should we complain about failure? */
769 }
bool ArchiveRecoveryRequested
Definition: xlog.c:254
#define StatusFilePath(path, xlog, suffix)
void ExecuteRecoveryCommand(const char *command, const char *commandName, bool failOnSignal)
Definition: xlogarchive.c:331
bool XLogArchiveIsReadyOrDone(const char *xlog)
Definition: xlogarchive.c:708
bool StandbyMode
Definition: xlog.c:289
#define DEBUG1
Definition: elog.h:25
uint32 TimeLineID
Definition: xlogdefs.h:52
int wal_segment_size
Definition: xlog.c:112
#define DEBUG3
Definition: elog.h:23
void make_native_path(char *path)
Definition: path.c:166
void GetOldestRestartPoint(XLogRecPtr *oldrecptr, TimeLineID *oldtli)
Definition: xlog.c:11194
bool RestoreArchivedFile(char *path, const char *xlogfname, const char *recovername, off_t expectedSize, bool cleanupEnabled)
Definition: xlogarchive.c:51
void proc_exit(int code)
Definition: ipc.c:104
void KeepFileRestoredFromArchive(const char *path, const char *xlogfname)
Definition: xlogarchive.c:425
#define LOG
Definition: elog.h:26
bool RecoveryInProgress(void)
Definition: xlog.c:7913
char * wait_result_to_str(int exitstatus)
Definition: wait_error.c:32
static int fd(const char *x, int i)
Definition: preproc-init.c:105
void XLogArchiveCleanup(const char *xlog)
Definition: xlogarchive.c:756
void XLogArchiveNotify(const char *xlog)
Definition: xlogarchive.c:511
void WalSndRqstFileReload(void)
Definition: walsender.c:2952
#define XLogArchivingAlways()
Definition: xlog.h:173
bool wait_result_is_signal(int exit_status, int signum)
Definition: wait_error.c:92
void PostRestoreCommand(void)
Definition: startup.c:231
#define ERROR
Definition: elog.h:43
bool XLogArchiveCheckDone(const char *xlog)
Definition: xlogarchive.c:616
#define FATAL
Definition: elog.h:52
#define MAXPGPATH
char * recoveryRestoreCommand
Definition: xlog.c:268
#define DEBUG2
Definition: elog.h:24
bool IsUnderPostmaster
Definition: globals.c:109
uint64 XLogSegNo
Definition: xlogdefs.h:41
int XLogArchiveMode
Definition: xlog.c:91
int errcode_for_file_access(void)
Definition: elog.c:593
FILE * AllocateFile(const char *name, const char *mode)
Definition: fd.c:2205
#define ereport(elevel, rest)
Definition: elog.h:141
int durable_rename(const char *oldfile, const char *newfile, int elevel)
Definition: fd.c:606
bool XLogArchiveIsReady(const char *xlog)
Definition: xlogarchive.c:738
#define WARNING
Definition: elog.h:40
#define stat(a, b)
Definition: win32_port.h:255
#define MAXFNAMELEN
static int elevel
Definition: vacuumlazy.c:143
void XLogArchiveForceDone(const char *xlog)
Definition: xlogarchive.c:561
#define XLOGDIR
static char xlogfpath[MAXPGPATH]
Definition: parsexlog.c:42
TimeLineID ThisTimeLineID
Definition: xlog.c:187
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45
int errmsg_internal(const char *fmt,...)
Definition: elog.c:814
bool XLogArchiveIsBusy(const char *xlog)
Definition: xlogarchive.c:663
uint64 XLogRecPtr
Definition: xlogdefs.h:21
#define Assert(condition)
Definition: c.h:732
#define StrNCpy(dst, src, len)
Definition: c.h:928
#define XLogArchivingActive()
Definition: xlog.h:170
#define XLogFileName(fname, tli, logSegNo, wal_segsz_bytes)
int FreeFile(FILE *file)
Definition: fd.c:2404
void PreRestoreCommand(void)
Definition: startup.c:217
int errmsg(const char *fmt,...)
Definition: elog.c:784
void XLogArchiveNotifySeg(XLogSegNo segno)
Definition: xlogarchive.c:545
void SendPostmasterSignal(PMSignalReason reason)
Definition: pmsignal.c:146
bool wait_result_is_any_signal(int exit_status, bool include_command_not_found)
Definition: wait_error.c:111
#define snprintf
Definition: port.h:192
void WalSndWakeup(void)
Definition: walsender.c:3073
#define XLByteToSeg(xlrp, logSegNo, wal_segsz_bytes)