PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
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-2017, 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  bool signaled;
63  struct stat stat_buf;
64  XLogSegNo restartSegNo;
65  XLogRecPtr restartRedoPtr;
66  TimeLineID restartTli;
67 
68  /* In standby mode, restore_command might not be supplied */
69  if (recoveryRestoreCommand == NULL)
70  goto not_available;
71 
72  /*
73  * When doing archive recovery, we always prefer an archived log file even
74  * if a file of the same name exists in XLOGDIR. The reason is that the
75  * file in XLOGDIR could be an old, un-filled or partly-filled version
76  * that was copied and restored as part of backing up $PGDATA.
77  *
78  * We could try to optimize this slightly by checking the local copy
79  * lastchange timestamp against the archived copy, but we have no API to
80  * do this, nor can we guarantee that the lastchange timestamp was
81  * preserved correctly when we copied to archive. Our aim is robustness,
82  * so we elect not to do this.
83  *
84  * If we cannot obtain the log file from the archive, however, we will try
85  * to use the XLOGDIR file if it exists. This is so that we can make use
86  * of log segments that weren't yet transferred to the archive.
87  *
88  * Notice that we don't actually overwrite any files when we copy back
89  * from archive because the restore_command may inadvertently restore
90  * inappropriate xlogs, or they may be corrupt, so we may wish to fallback
91  * to the segments remaining in current XLOGDIR later. The
92  * copy-from-archive filename is always the same, ensuring that we don't
93  * run out of disk space on long recoveries.
94  */
95  snprintf(xlogpath, MAXPGPATH, XLOGDIR "/%s", recovername);
96 
97  /*
98  * Make sure there is no existing file named recovername.
99  */
100  if (stat(xlogpath, &stat_buf) != 0)
101  {
102  if (errno != ENOENT)
103  ereport(FATAL,
105  errmsg("could not stat file \"%s\": %m",
106  xlogpath)));
107  }
108  else
109  {
110  if (unlink(xlogpath) != 0)
111  ereport(FATAL,
113  errmsg("could not remove file \"%s\": %m",
114  xlogpath)));
115  }
116 
117  /*
118  * Calculate the archive file cutoff point for use during log shipping
119  * replication. All files earlier than this point can be deleted from the
120  * archive, though there is no requirement to do so.
121  *
122  * If cleanup is not enabled, initialise this with the filename of
123  * InvalidXLogRecPtr, which will prevent the deletion of any WAL files
124  * from the archive because of the alphabetic sorting property of WAL
125  * filenames.
126  *
127  * Once we have successfully located the redo pointer of the checkpoint
128  * from which we start recovery we never request a file prior to the redo
129  * pointer of the last restartpoint. When redo begins we know that we have
130  * successfully located it, so there is no need for additional status
131  * flags to signify the point when we can begin deleting WAL files from
132  * the archive.
133  */
134  if (cleanupEnabled)
135  {
136  GetOldestRestartPoint(&restartRedoPtr, &restartTli);
137  XLByteToSeg(restartRedoPtr, restartSegNo, wal_segment_size);
138  XLogFileName(lastRestartPointFname, restartTli, restartSegNo,
140  /* we shouldn't need anything earlier than last restart point */
141  Assert(strcmp(lastRestartPointFname, xlogfname) <= 0);
142  }
143  else
144  XLogFileName(lastRestartPointFname, 0, 0L, wal_segment_size);
145 
146  /*
147  * construct the command to be executed
148  */
149  dp = xlogRestoreCmd;
150  endp = xlogRestoreCmd + MAXPGPATH - 1;
151  *endp = '\0';
152 
153  for (sp = recoveryRestoreCommand; *sp; sp++)
154  {
155  if (*sp == '%')
156  {
157  switch (sp[1])
158  {
159  case 'p':
160  /* %p: relative path of target file */
161  sp++;
162  StrNCpy(dp, xlogpath, endp - dp);
163  make_native_path(dp);
164  dp += strlen(dp);
165  break;
166  case 'f':
167  /* %f: filename of desired file */
168  sp++;
169  StrNCpy(dp, xlogfname, endp - dp);
170  dp += strlen(dp);
171  break;
172  case 'r':
173  /* %r: filename of last restartpoint */
174  sp++;
175  StrNCpy(dp, lastRestartPointFname, endp - dp);
176  dp += strlen(dp);
177  break;
178  case '%':
179  /* convert %% to a single % */
180  sp++;
181  if (dp < endp)
182  *dp++ = *sp;
183  break;
184  default:
185  /* otherwise treat the % as not special */
186  if (dp < endp)
187  *dp++ = *sp;
188  break;
189  }
190  }
191  else
192  {
193  if (dp < endp)
194  *dp++ = *sp;
195  }
196  }
197  *dp = '\0';
198 
199  ereport(DEBUG3,
200  (errmsg_internal("executing restore command \"%s\"",
201  xlogRestoreCmd)));
202 
203  /*
204  * Check signals before restore command and reset afterwards.
205  */
207 
208  /*
209  * Copy xlog from archival storage to XLOGDIR
210  */
211  rc = system(xlogRestoreCmd);
212 
214 
215  if (rc == 0)
216  {
217  /*
218  * command apparently succeeded, but let's make sure the file is
219  * really there now and has the correct size.
220  */
221  if (stat(xlogpath, &stat_buf) == 0)
222  {
223  if (expectedSize > 0 && stat_buf.st_size != expectedSize)
224  {
225  int elevel;
226 
227  /*
228  * If we find a partial file in standby mode, we assume it's
229  * because it's just being copied to the archive, and keep
230  * trying.
231  *
232  * Otherwise treat a wrong-sized file as FATAL to ensure the
233  * DBA would notice it, but is that too strong? We could try
234  * to plow ahead with a local copy of the file ... but the
235  * problem is that there probably isn't one, and we'd
236  * incorrectly conclude we've reached the end of WAL and we're
237  * done recovering ...
238  */
239  if (StandbyMode && stat_buf.st_size < expectedSize)
240  elevel = DEBUG1;
241  else
242  elevel = FATAL;
243  ereport(elevel,
244  (errmsg("archive file \"%s\" has wrong size: %lu instead of %lu",
245  xlogfname,
246  (unsigned long) stat_buf.st_size,
247  (unsigned long) expectedSize)));
248  return false;
249  }
250  else
251  {
252  ereport(LOG,
253  (errmsg("restored log file \"%s\" from archive",
254  xlogfname)));
255  strcpy(path, xlogpath);
256  return true;
257  }
258  }
259  else
260  {
261  /* stat failed */
262  if (errno != ENOENT)
263  ereport(FATAL,
265  errmsg("could not stat file \"%s\": %m",
266  xlogpath)));
267  }
268  }
269 
270  /*
271  * Remember, we rollforward UNTIL the restore fails so failure here is
272  * just part of the process... that makes it difficult to determine
273  * whether the restore failed because there isn't an archive to restore,
274  * or because the administrator has specified the restore program
275  * incorrectly. We have to assume the former.
276  *
277  * However, if the failure was due to any sort of signal, it's best to
278  * punt and abort recovery. (If we "return false" here, upper levels will
279  * assume that recovery is complete and start up the database!) It's
280  * essential to abort on child SIGINT and SIGQUIT, because per spec
281  * system() ignores SIGINT and SIGQUIT while waiting; if we see one of
282  * those it's a good bet we should have gotten it too.
283  *
284  * On SIGTERM, assume we have received a fast shutdown request, and exit
285  * cleanly. It's pure chance whether we receive the SIGTERM first, or the
286  * child process. If we receive it first, the signal handler will call
287  * proc_exit, otherwise we do it here. If we or the child process received
288  * SIGTERM for any other reason than a fast shutdown request, postmaster
289  * will perform an immediate shutdown when it sees us exiting
290  * unexpectedly.
291  *
292  * Per the Single Unix Spec, shells report exit status > 128 when a called
293  * command died on a signal. Also, 126 and 127 are used to report
294  * problems such as an unfindable command; treat those as fatal errors
295  * too.
296  */
297  if (WIFSIGNALED(rc) && WTERMSIG(rc) == SIGTERM)
298  proc_exit(1);
299 
300  signaled = WIFSIGNALED(rc) || WEXITSTATUS(rc) > 125;
301 
302  ereport(signaled ? FATAL : DEBUG2,
303  (errmsg("could not restore file \"%s\" from archive: %s",
304  xlogfname, wait_result_to_str(rc))));
305 
306 not_available:
307 
308  /*
309  * if an archived file is not available, there might still be a version of
310  * this file in XLOGDIR, so return that as the filename to open.
311  *
312  * In many recovery scenarios we expect this to fail also, but if so that
313  * just means we've reached the end of WAL.
314  */
315  snprintf(path, MAXPGPATH, XLOGDIR "/%s", xlogfname);
316  return false;
317 }
318 
319 /*
320  * Attempt to execute an external shell command during recovery.
321  *
322  * 'command' is the shell command to be executed, 'commandName' is a
323  * human-readable name describing the command emitted in the logs. If
324  * 'failOnSignal' is true and the command is killed by a signal, a FATAL
325  * error is thrown. Otherwise a WARNING is emitted.
326  *
327  * This is currently used for recovery_end_command and archive_cleanup_command.
328  */
329 void
330 ExecuteRecoveryCommand(char *command, char *commandName, bool failOnSignal)
331 {
332  char xlogRecoveryCmd[MAXPGPATH];
333  char lastRestartPointFname[MAXPGPATH];
334  char *dp;
335  char *endp;
336  const char *sp;
337  int rc;
338  bool signaled;
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 also detailed comments on signals in
407  * RestoreArchivedFile().
408  */
409  signaled = WIFSIGNALED(rc) || WEXITSTATUS(rc) > 125;
410 
411  ereport((signaled && failOnSignal) ? FATAL : WARNING,
412  /*------
413  translator: First %s represents a recovery.conf parameter name like
414  "recovery_end_command", the 2nd is the value of that parameter, the
415  third an already translated error message. */
416  (errmsg("%s \"%s\": %s", commandName,
417  command, wait_result_to_str(rc))));
418  }
419 }
420 
421 
422 /*
423  * A file was restored from the archive under a temporary filename (path),
424  * and now we want to keep it. Rename it under the permanent filename in
425  * in pg_wal (xlogfname), replacing any existing file with the same name.
426  */
427 void
428 KeepFileRestoredFromArchive(char *path, char *xlogfname)
429 {
430  char xlogfpath[MAXPGPATH];
431  bool reload = false;
432  struct stat statbuf;
433 
434  snprintf(xlogfpath, MAXPGPATH, XLOGDIR "/%s", xlogfname);
435 
436  if (stat(xlogfpath, &statbuf) == 0)
437  {
438  char oldpath[MAXPGPATH];
439 
440 #ifdef WIN32
441  static unsigned int deletedcounter = 1;
442 
443  /*
444  * On Windows, if another process (e.g a walsender process) holds the
445  * file open in FILE_SHARE_DELETE mode, unlink will succeed, but the
446  * file will still show up in directory listing until the last handle
447  * is closed, and we cannot rename the new file in its place until
448  * that. To avoid that problem, rename the old file to a temporary
449  * name first. Use a counter to create a unique filename, because the
450  * same file might be restored from the archive multiple times, and a
451  * walsender could still be holding onto an old deleted version of it.
452  */
453  snprintf(oldpath, MAXPGPATH, "%s.deleted%u",
454  xlogfpath, deletedcounter++);
455  if (rename(xlogfpath, oldpath) != 0)
456  {
457  ereport(ERROR,
459  errmsg("could not rename file \"%s\" to \"%s\": %m",
460  xlogfpath, oldpath)));
461  }
462 #else
463  /* same-size buffers, so this never truncates */
464  strlcpy(oldpath, xlogfpath, MAXPGPATH);
465 #endif
466  if (unlink(oldpath) != 0)
467  ereport(FATAL,
469  errmsg("could not remove file \"%s\": %m",
470  xlogfpath)));
471  reload = true;
472  }
473 
474  durable_rename(path, xlogfpath, ERROR);
475 
476  /*
477  * Create .done file forcibly to prevent the restored segment from being
478  * archived again later.
479  */
481  XLogArchiveForceDone(xlogfname);
482  else
483  XLogArchiveNotify(xlogfname);
484 
485  /*
486  * If the existing file was replaced, since walsenders might have it open,
487  * request them to reload a currently-open segment. This is only required
488  * for WAL segments, walsenders don't hold other files open, but there's
489  * no harm in doing this too often, and we don't know what kind of a file
490  * we're dealing with here.
491  */
492  if (reload)
494 
495  /*
496  * Signal walsender that new WAL has arrived. Again, this isn't necessary
497  * if we restored something other than a WAL segment, but it does no harm
498  * either.
499  */
500  WalSndWakeup();
501 }
502 
503 /*
504  * XLogArchiveNotify
505  *
506  * Create an archive notification file
507  *
508  * The name of the notification file is the message that will be picked up
509  * by the archiver, e.g. we write 0000000100000001000000C6.ready
510  * and the archiver then knows to archive XLOGDIR/0000000100000001000000C6,
511  * then when complete, rename it to 0000000100000001000000C6.done
512  */
513 void
514 XLogArchiveNotify(const char *xlog)
515 {
516  char archiveStatusPath[MAXPGPATH];
517  FILE *fd;
518 
519  /* insert an otherwise empty file called <XLOG>.ready */
520  StatusFilePath(archiveStatusPath, xlog, ".ready");
521  fd = AllocateFile(archiveStatusPath, "w");
522  if (fd == NULL)
523  {
524  ereport(LOG,
526  errmsg("could not create archive status file \"%s\": %m",
527  archiveStatusPath)));
528  return;
529  }
530  if (FreeFile(fd))
531  {
532  ereport(LOG,
534  errmsg("could not write archive status file \"%s\": %m",
535  archiveStatusPath)));
536  return;
537  }
538 
539  /* Notify archiver that it's got something to do */
540  if (IsUnderPostmaster)
542 }
543 
544 /*
545  * Convenience routine to notify using segment number representation of filename
546  */
547 void
549 {
550  char xlog[MAXFNAMELEN];
551 
553  XLogArchiveNotify(xlog);
554 }
555 
556 /*
557  * XLogArchiveForceDone
558  *
559  * Emit notification forcibly that an XLOG segment file has been successfully
560  * archived, by creating <XLOG>.done regardless of whether <XLOG>.ready
561  * exists or not.
562  */
563 void
564 XLogArchiveForceDone(const char *xlog)
565 {
566  char archiveReady[MAXPGPATH];
567  char archiveDone[MAXPGPATH];
568  struct stat stat_buf;
569  FILE *fd;
570 
571  /* Exit if already known done */
572  StatusFilePath(archiveDone, xlog, ".done");
573  if (stat(archiveDone, &stat_buf) == 0)
574  return;
575 
576  /* If .ready exists, rename it to .done */
577  StatusFilePath(archiveReady, xlog, ".ready");
578  if (stat(archiveReady, &stat_buf) == 0)
579  {
580  (void) durable_rename(archiveReady, archiveDone, WARNING);
581  return;
582  }
583 
584  /* insert an otherwise empty file called <XLOG>.done */
585  fd = AllocateFile(archiveDone, "w");
586  if (fd == NULL)
587  {
588  ereport(LOG,
590  errmsg("could not create archive status file \"%s\": %m",
591  archiveDone)));
592  return;
593  }
594  if (FreeFile(fd))
595  {
596  ereport(LOG,
598  errmsg("could not write archive status file \"%s\": %m",
599  archiveDone)));
600  return;
601  }
602 }
603 
604 /*
605  * XLogArchiveCheckDone
606  *
607  * This is called when we are ready to delete or recycle an old XLOG segment
608  * file or backup history file. If it is okay to delete it then return true.
609  * If it is not time to delete it, make sure a .ready file exists, and return
610  * false.
611  *
612  * If <XLOG>.done exists, then return true; else if <XLOG>.ready exists,
613  * then return false; else create <XLOG>.ready and return false.
614  *
615  * The reason we do things this way is so that if the original attempt to
616  * create <XLOG>.ready fails, we'll retry during subsequent checkpoints.
617  */
618 bool
619 XLogArchiveCheckDone(const char *xlog)
620 {
621  char archiveStatusPath[MAXPGPATH];
622  struct stat stat_buf;
623 
624  /* Always deletable if archiving is off */
625  if (!XLogArchivingActive())
626  return true;
627 
628  /* First check for .done --- this means archiver is done with it */
629  StatusFilePath(archiveStatusPath, xlog, ".done");
630  if (stat(archiveStatusPath, &stat_buf) == 0)
631  return true;
632 
633  /* check for .ready --- this means archiver is still busy with it */
634  StatusFilePath(archiveStatusPath, xlog, ".ready");
635  if (stat(archiveStatusPath, &stat_buf) == 0)
636  return false;
637 
638  /* Race condition --- maybe archiver just finished, so recheck */
639  StatusFilePath(archiveStatusPath, xlog, ".done");
640  if (stat(archiveStatusPath, &stat_buf) == 0)
641  return true;
642 
643  /* Retry creation of the .ready file */
644  XLogArchiveNotify(xlog);
645  return false;
646 }
647 
648 /*
649  * XLogArchiveIsBusy
650  *
651  * Check to see if an XLOG segment file is still unarchived.
652  * This is almost but not quite the inverse of XLogArchiveCheckDone: in
653  * the first place we aren't chartered to recreate the .ready file, and
654  * in the second place we should consider that if the file is already gone
655  * then it's not busy. (This check is needed to handle the race condition
656  * that a checkpoint already deleted the no-longer-needed file.)
657  */
658 bool
659 XLogArchiveIsBusy(const char *xlog)
660 {
661  char archiveStatusPath[MAXPGPATH];
662  struct stat stat_buf;
663 
664  /* First check for .done --- this means archiver is done with it */
665  StatusFilePath(archiveStatusPath, xlog, ".done");
666  if (stat(archiveStatusPath, &stat_buf) == 0)
667  return false;
668 
669  /* check for .ready --- this means archiver is still busy with it */
670  StatusFilePath(archiveStatusPath, xlog, ".ready");
671  if (stat(archiveStatusPath, &stat_buf) == 0)
672  return true;
673 
674  /* Race condition --- maybe archiver just finished, so recheck */
675  StatusFilePath(archiveStatusPath, xlog, ".done");
676  if (stat(archiveStatusPath, &stat_buf) == 0)
677  return false;
678 
679  /*
680  * Check to see if the WAL file has been removed by checkpoint, which
681  * implies it has already been archived, and explains why we can't see a
682  * status file for it.
683  */
684  snprintf(archiveStatusPath, MAXPGPATH, XLOGDIR "/%s", xlog);
685  if (stat(archiveStatusPath, &stat_buf) != 0 &&
686  errno == ENOENT)
687  return false;
688 
689  return true;
690 }
691 
692 /*
693  * XLogArchiveIsReadyOrDone
694  *
695  * Check to see if an XLOG segment file has a .ready or .done file.
696  * This is similar to XLogArchiveIsBusy(), but returns true if the file
697  * is already archived or is about to be archived.
698  *
699  * This is currently only used at recovery. During normal operation this
700  * would be racy: the file might get removed or marked with .ready as we're
701  * checking it, or immediately after we return.
702  */
703 bool
704 XLogArchiveIsReadyOrDone(const char *xlog)
705 {
706  char archiveStatusPath[MAXPGPATH];
707  struct stat stat_buf;
708 
709  /* First check for .done --- this means archiver is done with it */
710  StatusFilePath(archiveStatusPath, xlog, ".done");
711  if (stat(archiveStatusPath, &stat_buf) == 0)
712  return true;
713 
714  /* check for .ready --- this means archiver is still busy with it */
715  StatusFilePath(archiveStatusPath, xlog, ".ready");
716  if (stat(archiveStatusPath, &stat_buf) == 0)
717  return true;
718 
719  /* Race condition --- maybe archiver just finished, so recheck */
720  StatusFilePath(archiveStatusPath, xlog, ".done");
721  if (stat(archiveStatusPath, &stat_buf) == 0)
722  return true;
723 
724  return false;
725 }
726 
727 /*
728  * XLogArchiveIsReady
729  *
730  * Check to see if an XLOG segment file has an archive notification (.ready)
731  * file.
732  */
733 bool
734 XLogArchiveIsReady(const char *xlog)
735 {
736  char archiveStatusPath[MAXPGPATH];
737  struct stat stat_buf;
738 
739  StatusFilePath(archiveStatusPath, xlog, ".ready");
740  if (stat(archiveStatusPath, &stat_buf) == 0)
741  return true;
742 
743  return false;
744 }
745 
746 /*
747  * XLogArchiveCleanup
748  *
749  * Cleanup archive notification file(s) for a particular xlog segment
750  */
751 void
752 XLogArchiveCleanup(const char *xlog)
753 {
754  char archiveStatusPath[MAXPGPATH];
755 
756  /* Remove the .done file */
757  StatusFilePath(archiveStatusPath, xlog, ".done");
758  unlink(archiveStatusPath);
759  /* should we complain about failure? */
760 
761  /* Remove the .ready file if present --- normally it shouldn't be */
762  StatusFilePath(archiveStatusPath, xlog, ".ready");
763  unlink(archiveStatusPath);
764  /* should we complain about failure? */
765 }
#define StatusFilePath(path, xlog, suffix)
bool XLogArchiveIsReadyOrDone(const char *xlog)
Definition: xlogarchive.c:704
bool StandbyMode
Definition: xlog.c:279
#define DEBUG1
Definition: elog.h:25
uint32 TimeLineID
Definition: xlogdefs.h:45
int wal_segment_size
Definition: xlog.c:113
#define DEBUG3
Definition: elog.h:23
void KeepFileRestoredFromArchive(char *path, char *xlogfname)
Definition: xlogarchive.c:428
void make_native_path(char *path)
Definition: path.c:166
void GetOldestRestartPoint(XLogRecPtr *oldrecptr, TimeLineID *oldtli)
Definition: xlog.c:11226
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:99
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
#define LOG
Definition: elog.h:26
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:752
void XLogArchiveNotify(const char *xlog)
Definition: xlogarchive.c:514
void WalSndRqstFileReload(void)
Definition: walsender.c:2879
void PostRestoreCommand(void)
Definition: startup.c:241
#define ERROR
Definition: elog.h:43
#define WIFSIGNALED(w)
Definition: win32.h:173
bool XLogArchiveCheckDone(const char *xlog)
Definition: xlogarchive.c:619
#define FATAL
Definition: elog.h:52
#define MAXPGPATH
char * recoveryRestoreCommand
Definition: xlog.c:259
#define DEBUG2
Definition: elog.h:24
bool IsUnderPostmaster
Definition: globals.c:101
uint64 XLogSegNo
Definition: xlogdefs.h:34
int XLogArchiveMode
Definition: xlog.c:94
int errcode_for_file_access(void)
Definition: elog.c:598
FILE * AllocateFile(const char *name, const char *mode)
Definition: fd.c:2117
#define ereport(elevel, rest)
Definition: elog.h:122
int durable_rename(const char *oldfile, const char *newfile, int elevel)
Definition: fd.c:598
void ExecuteRecoveryCommand(char *command, char *commandName, bool failOnSignal)
Definition: xlogarchive.c:330
bool XLogArchiveIsReady(const char *xlog)
Definition: xlogarchive.c:734
#define WARNING
Definition: elog.h:40
#define MAXFNAMELEN
static int elevel
Definition: vacuumlazy.c:136
void XLogArchiveForceDone(const char *xlog)
Definition: xlogarchive.c:564
#define XLOGDIR
static char xlogfpath[MAXPGPATH]
Definition: parsexlog.c:43
TimeLineID ThisTimeLineID
Definition: xlog.c:181
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45
int errmsg_internal(const char *fmt,...)
Definition: elog.c:827
bool XLogArchiveIsBusy(const char *xlog)
Definition: xlogarchive.c:659
#define WEXITSTATUS(w)
Definition: win32.h:174
uint64 XLogRecPtr
Definition: xlogdefs.h:21
#define Assert(condition)
Definition: c.h:681
#define StrNCpy(dst, src, len)
Definition: c.h:836
#define XLogArchivingActive()
Definition: xlog.h:135
#define XLogFileName(fname, tli, logSegNo, wal_segsz_bytes)
int FreeFile(FILE *file)
Definition: fd.c:2309
void PreRestoreCommand(void)
Definition: startup.c:227
int errmsg(const char *fmt,...)
Definition: elog.c:797
void XLogArchiveNotifySeg(XLogSegNo segno)
Definition: xlogarchive.c:548
void SendPostmasterSignal(PMSignalReason reason)
Definition: pmsignal.c:113
#define WTERMSIG(w)
Definition: win32.h:175
void WalSndWakeup(void)
Definition: walsender.c:3004
static volatile sig_atomic_t signaled
Definition: pg_standby.c:53
#define XLByteToSeg(xlrp, logSegNo, wal_segsz_bytes)