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