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