PostgreSQL Source Code git master
Loading...
Searching...
No Matches
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-2026, 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"
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/pgarch.h"
30#include "postmaster/startup.h"
32#include "storage/fd.h"
33#include "storage/ipc.h"
34#include "utils/wait_event.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 */
54bool
55RestoreArchivedFile(char *path, const char *xlogfname,
56 const char *recovername, off_t expectedSize,
57 bool cleanupEnabled)
58{
59 char xlogpath[MAXPGPATH];
60 char *xlogRestoreCmd;
62 int rc;
63 struct stat stat_buf;
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 */
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 */
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)
112 errmsg("could not stat file \"%s\": %m",
113 xlogpath)));
114 }
115 else
116 {
117 if (unlink(xlogpath) != 0)
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 {
147 /* we shouldn't need anything earlier than last restart point */
149 }
150 else
152
153 /* Build the restore command to execute */
157
159 (errmsg_internal("executing restore command \"%s\"",
161
162 fflush(NULL);
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 */
179
181
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 */
266 proc_exit(1);
267
269 (errmsg("could not restore file \"%s\" from archive: %s",
271
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 */
295void
296ExecuteRecoveryCommand(const char *command, const char *commandName,
297 bool failOnSignal, uint32 wait_event_info)
298{
299 char *xlogRecoveryCmd;
301 int rc;
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 */
317
318 /*
319 * construct the command to be executed
320 */
322
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);
333
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 */
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 */
358void
359KeepFileRestoredFromArchive(const char *path, const char *xlogfname)
360{
361 char xlogfpath[MAXPGPATH];
362 bool reload = false;
363 struct stat statbuf;
364
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",
386 if (rename(xlogfpath, oldpath) != 0)
387 {
390 errmsg("could not rename file \"%s\" to \"%s\": %m",
391 xlogfpath, oldpath)));
392 }
393#else
394 /* same-size buffers, so this never truncates */
396#endif
397 if (unlink(oldpath) != 0)
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 */
413 else
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 */
444void
445XLogArchiveNotify(const char *xlog)
446{
448 FILE *fd;
449
450 /* insert an otherwise empty file called <XLOG>.ready */
451 StatusFilePath(archiveStatusPath, xlog, ".ready");
453 if (fd == NULL)
454 {
455 ereport(LOG,
457 errmsg("could not create archive status file \"%s\": %m",
459 return;
460 }
461 if (FreeFile(fd))
462 {
463 ereport(LOG,
465 errmsg("could not write archive status file \"%s\": %m",
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 */
486 PgArchWakeup();
487}
488
489/*
490 * Convenience routine to notify using segment number representation of filename
491 */
492void
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 */
510void
511XLogArchiveForceDone(const char *xlog)
512{
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 {
528 return;
529 }
530
531 /* insert an otherwise empty file called <XLOG>.done */
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 */
565bool
566XLogArchiveCheckDone(const char *xlog)
567{
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 */
619bool
620XLogArchiveIsBusy(const char *xlog)
621{
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 */
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 */
664bool
666{
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 */
694bool
695XLogArchiveIsReady(const char *xlog)
696{
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 */
712void
713XLogArchiveCleanup(const char *xlog)
714{
716
717 /* Remove the .done file */
718 StatusFilePath(archiveStatusPath, xlog, ".done");
720 /* should we complain about failure? */
721
722 /* Remove the .ready file if present --- normally it shouldn't be */
723 StatusFilePath(archiveStatusPath, xlog, ".ready");
725 /* should we complain about failure? */
726}
void PreRestoreCommand(void)
Definition startup.c:267
void PostRestoreCommand(void)
Definition startup.c:281
#define Assert(condition)
Definition c.h:945
uint32_t uint32
Definition c.h:618
char * BuildRestoreCommand(const char *restoreCommand, const char *xlogpath, const char *xlogfname, const char *lastRestartPointFname)
Definition archive.c:39
int errcode_for_file_access(void)
Definition elog.c:897
#define LOG
Definition elog.h:31
#define DEBUG3
Definition elog.h:28
int errdetail(const char *fmt,...) pg_attribute_printf(1
#define FATAL
Definition elog.h:41
int int errmsg_internal(const char *fmt,...) pg_attribute_printf(1
#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:150
int durable_rename(const char *oldfile, const char *newfile, int elevel)
Definition fd.c:783
int FreeFile(FILE *file)
Definition fd.c:2827
FILE * AllocateFile(const char *name, const char *mode)
Definition fd.c:2628
bool IsUnderPostmaster
Definition globals.c:120
void proc_exit(int code)
Definition ipc.c:105
void pfree(void *pointer)
Definition mcxt.c:1616
static char * errmsg
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:806
void PgArchWakeup(void)
Definition pgarch.c:282
#define snprintf
Definition port.h:260
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition strlcpy.c:45
static int fd(const char *x, int i)
static int fb(int x)
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:69
static void pgstat_report_wait_end(void)
Definition wait_event.h:85
void WalSndWakeup(bool physical, bool logical)
Definition walsender.c:3822
void WalSndRqstFileReload(void)
Definition walsender.c:3693
#define stat
Definition win32_port.h:74
int XLogArchiveMode
Definition xlog.c:123
int wal_segment_size
Definition xlog.c:147
RecoveryState GetRecoveryState(void)
Definition xlog.c:6480
void GetOldestRestartPoint(XLogRecPtr *oldrecptr, TimeLineID *oldtli)
Definition xlog.c:9658
#define XLogArchivingActive()
Definition xlog.h:101
@ ARCHIVE_MODE_ALWAYS
Definition xlog.h:68
#define XLogArchivingAlways()
Definition xlog.h:104
@ RECOVERY_STATE_ARCHIVE
Definition xlog.h:93
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)
bool XLogArchiveIsReadyOrDone(const char *xlog)
bool XLogArchiveIsBusy(const char *xlog)
bool XLogArchiveIsReady(const char *xlog)
void XLogArchiveNotifySeg(XLogSegNo segno, TimeLineID tli)
void ExecuteRecoveryCommand(const char *command, const char *commandName, bool failOnSignal, uint32 wait_event_info)
bool XLogArchiveCheckDone(const char *xlog)
bool RestoreArchivedFile(char *path, const char *xlogfname, const char *recovername, off_t expectedSize, bool cleanupEnabled)
Definition xlogarchive.c:55
void XLogArchiveNotify(const char *xlog)
void KeepFileRestoredFromArchive(const char *path, const char *xlogfname)
void XLogArchiveCleanup(const char *xlog)
uint64 XLogRecPtr
Definition xlogdefs.h:21
uint32 TimeLineID
Definition xlogdefs.h:63
uint64 XLogSegNo
Definition xlogdefs.h:52
bool ArchiveRecoveryRequested
char * recoveryRestoreCommand
bool StandbyMode