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