PostgreSQL Source Code git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
xlogarchive.h File Reference
#include "access/xlogdefs.h"
Include dependency graph for xlogarchive.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

bool RestoreArchivedFile (char *path, const char *xlogfname, const char *recovername, off_t expectedSize, bool cleanupEnabled)
 
void ExecuteRecoveryCommand (const char *command, const char *commandName, bool failOnSignal, uint32 wait_event_info)
 
void KeepFileRestoredFromArchive (const char *path, const char *xlogfname)
 
void XLogArchiveNotify (const char *xlog)
 
void XLogArchiveNotifySeg (XLogSegNo segno, TimeLineID tli)
 
void XLogArchiveForceDone (const char *xlog)
 
bool XLogArchiveCheckDone (const char *xlog)
 
bool XLogArchiveIsBusy (const char *xlog)
 
bool XLogArchiveIsReady (const char *xlog)
 
bool XLogArchiveIsReadyOrDone (const char *xlog)
 
void XLogArchiveCleanup (const char *xlog)
 

Function Documentation

◆ ExecuteRecoveryCommand()

void ExecuteRecoveryCommand ( const char *  command,
const char *  commandName,
bool  failOnSignal,
uint32  wait_event_info 
)

Definition at line 295 of file xlogarchive.c.

297{
298 char *xlogRecoveryCmd;
299 char lastRestartPointFname[MAXPGPATH];
300 int rc;
301 XLogSegNo restartSegNo;
302 XLogRecPtr restartRedoPtr;
303 TimeLineID restartTli;
304
305 Assert(command && commandName);
306
307 /*
308 * Calculate the archive file cutoff point for use during log shipping
309 * replication. All files earlier than this point can be deleted from the
310 * archive, though there is no requirement to do so.
311 */
312 GetOldestRestartPoint(&restartRedoPtr, &restartTli);
313 XLByteToSeg(restartRedoPtr, restartSegNo, wal_segment_size);
314 XLogFileName(lastRestartPointFname, restartTli, restartSegNo,
316
317 /*
318 * construct the command to be executed
319 */
320 xlogRecoveryCmd = replace_percent_placeholders(command, commandName, "r", lastRestartPointFname);
321
323 (errmsg_internal("executing %s \"%s\"", commandName, command)));
324
325 /*
326 * execute the constructed command
327 */
328 fflush(NULL);
329 pgstat_report_wait_start(wait_event_info);
330 rc = system(xlogRecoveryCmd);
332
333 pfree(xlogRecoveryCmd);
334
335 if (rc != 0)
336 {
337 /*
338 * If the failure was due to any sort of signal, it's best to punt and
339 * abort recovery. See comments in RestoreArchivedFile().
340 */
341 ereport((failOnSignal && wait_result_is_any_signal(rc, true)) ? FATAL : WARNING,
342 /*------
343 translator: First %s represents a postgresql.conf parameter name like
344 "recovery_end_command", the 2nd is the value of that parameter, the
345 third an already translated error message. */
346 (errmsg("%s \"%s\": %s", commandName,
347 command, wait_result_to_str(rc))));
348 }
349}
#define Assert(condition)
Definition: c.h:812
int errmsg_internal(const char *fmt,...)
Definition: elog.c:1157
int errmsg(const char *fmt,...)
Definition: elog.c:1070
#define DEBUG3
Definition: elog.h:28
#define FATAL
Definition: elog.h:41
#define WARNING
Definition: elog.h:36
#define ereport(elevel,...)
Definition: elog.h:149
static void const char fflush(stdout)
void pfree(void *pointer)
Definition: mcxt.c:1521
char * replace_percent_placeholders(const char *instr, const char *param_name, const char *letters,...)
Definition: percentrepl.c:59
#define MAXPGPATH
char * wait_result_to_str(int exitstatus)
Definition: wait_error.c:33
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:85
static void pgstat_report_wait_end(void)
Definition: wait_event.h:101
int wal_segment_size
Definition: xlog.c:143
void GetOldestRestartPoint(XLogRecPtr *oldrecptr, TimeLineID *oldtli)
Definition: xlog.c:9463
#define XLByteToSeg(xlrp, logSegNo, wal_segsz_bytes)
static void XLogFileName(char *fname, TimeLineID tli, XLogSegNo logSegNo, int wal_segsz_bytes)
uint64 XLogRecPtr
Definition: xlogdefs.h:21
uint32 TimeLineID
Definition: xlogdefs.h:59
uint64 XLogSegNo
Definition: xlogdefs.h:48

References Assert, DEBUG3, ereport, errmsg(), errmsg_internal(), FATAL, fflush(), GetOldestRestartPoint(), MAXPGPATH, pfree(), pgstat_report_wait_end(), pgstat_report_wait_start(), replace_percent_placeholders(), wait_result_is_any_signal(), wait_result_to_str(), wal_segment_size, WARNING, XLByteToSeg, and XLogFileName().

Referenced by CleanupAfterArchiveRecovery(), and CreateRestartPoint().

◆ KeepFileRestoredFromArchive()

void KeepFileRestoredFromArchive ( const char *  path,
const char *  xlogfname 
)

Definition at line 358 of file xlogarchive.c.

359{
360 char xlogfpath[MAXPGPATH];
361 bool reload = false;
362 struct stat statbuf;
363
364 snprintf(xlogfpath, MAXPGPATH, XLOGDIR "/%s", xlogfname);
365
366 if (stat(xlogfpath, &statbuf) == 0)
367 {
368 char oldpath[MAXPGPATH];
369
370#ifdef WIN32
371 static unsigned int deletedcounter = 1;
372
373 /*
374 * On Windows, if another process (e.g a walsender process) holds the
375 * file open in FILE_SHARE_DELETE mode, unlink will succeed, but the
376 * file will still show up in directory listing until the last handle
377 * is closed, and we cannot rename the new file in its place until
378 * that. To avoid that problem, rename the old file to a temporary
379 * name first. Use a counter to create a unique filename, because the
380 * same file might be restored from the archive multiple times, and a
381 * walsender could still be holding onto an old deleted version of it.
382 */
383 snprintf(oldpath, MAXPGPATH, "%s.deleted%u",
384 xlogfpath, deletedcounter++);
385 if (rename(xlogfpath, oldpath) != 0)
386 {
389 errmsg("could not rename file \"%s\" to \"%s\": %m",
390 xlogfpath, oldpath)));
391 }
392#else
393 /* same-size buffers, so this never truncates */
394 strlcpy(oldpath, xlogfpath, MAXPGPATH);
395#endif
396 if (unlink(oldpath) != 0)
399 errmsg("could not remove file \"%s\": %m",
400 xlogfpath)));
401 reload = true;
402 }
403
405
406 /*
407 * Create .done file forcibly to prevent the restored segment from being
408 * archived again later.
409 */
411 XLogArchiveForceDone(xlogfname);
412 else
413 XLogArchiveNotify(xlogfname);
414
415 /*
416 * If the existing file was replaced, since walsenders might have it open,
417 * request them to reload a currently-open segment. This is only required
418 * for WAL segments, walsenders don't hold other files open, but there's
419 * no harm in doing this too often, and we don't know what kind of a file
420 * we're dealing with here.
421 */
422 if (reload)
424
425 /*
426 * Signal walsender that new WAL has arrived. Again, this isn't necessary
427 * if we restored something other than a WAL segment, but it does no harm
428 * either.
429 */
430 WalSndWakeup(true, false);
431}
int errcode_for_file_access(void)
Definition: elog.c:876
#define ERROR
Definition: elog.h:39
int durable_rename(const char *oldfile, const char *newfile, int elevel)
Definition: fd.c:781
static char xlogfpath[MAXPGPATH]
Definition: parsexlog.c:45
#define snprintf
Definition: port.h:238
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45
void WalSndWakeup(bool physical, bool logical)
Definition: walsender.c:3639
void WalSndRqstFileReload(void)
Definition: walsender.c:3510
#define stat
Definition: win32_port.h:284
int XLogArchiveMode
Definition: xlog.c:119
@ ARCHIVE_MODE_ALWAYS
Definition: xlog.h:67
#define XLOGDIR
void XLogArchiveForceDone(const char *xlog)
Definition: xlogarchive.c:510
void XLogArchiveNotify(const char *xlog)
Definition: xlogarchive.c:444

References ARCHIVE_MODE_ALWAYS, durable_rename(), ereport, errcode_for_file_access(), errmsg(), ERROR, FATAL, MAXPGPATH, snprintf, stat, strlcpy(), WalSndRqstFileReload(), WalSndWakeup(), XLogArchiveForceDone(), XLogArchiveMode, XLogArchiveNotify(), XLOGDIR, and xlogfpath.

Referenced by readTimeLineHistory(), restoreTimeLineHistoryFiles(), and XLogFileRead().

◆ RestoreArchivedFile()

bool RestoreArchivedFile ( char *  path,
const char *  xlogfname,
const char *  recovername,
off_t  expectedSize,
bool  cleanupEnabled 
)

Definition at line 54 of file xlogarchive.c.

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)
111 errmsg("could not stat file \"%s\": %m",
112 xlogpath)));
113 }
114 else
115 {
116 if (unlink(xlogpath) != 0)
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, 0, wal_segment_size);
151
152 /* Build the restore command to execute */
154 xlogpath, xlogfname,
155 lastRestartPointFname);
156
158 (errmsg_internal("executing restore command \"%s\"",
159 xlogRestoreCmd)));
160
161 fflush(NULL);
162 pgstat_report_wait_start(WAIT_EVENT_RESTORE_COMMAND);
163
164 /*
165 * PreRestoreCommand() informs the SIGTERM handler for the startup process
166 * that it should proc_exit() right away. This is done for the duration
167 * of the system() call because there isn't a good way to break out while
168 * it is executing. Since we might call proc_exit() in a signal handler,
169 * it is best to put any additional logic before or after the
170 * PreRestoreCommand()/PostRestoreCommand() section.
171 */
173
174 /*
175 * Copy xlog from archival storage to XLOGDIR
176 */
177 rc = system(xlogRestoreCmd);
178
180
182 pfree(xlogRestoreCmd);
183
184 if (rc == 0)
185 {
186 /*
187 * command apparently succeeded, but let's make sure the file is
188 * really there now and has the correct size.
189 */
190 if (stat(xlogpath, &stat_buf) == 0)
191 {
192 if (expectedSize > 0 && stat_buf.st_size != expectedSize)
193 {
194 int elevel;
195
196 /*
197 * If we find a partial file in standby mode, we assume it's
198 * because it's just being copied to the archive, and keep
199 * trying.
200 *
201 * Otherwise treat a wrong-sized file as FATAL to ensure the
202 * DBA would notice it, but is that too strong? We could try
203 * to plow ahead with a local copy of the file ... but the
204 * problem is that there probably isn't one, and we'd
205 * incorrectly conclude we've reached the end of WAL and we're
206 * done recovering ...
207 */
208 if (StandbyMode && stat_buf.st_size < expectedSize)
209 elevel = DEBUG1;
210 else
211 elevel = FATAL;
212 ereport(elevel,
213 (errmsg("archive file \"%s\" has wrong size: %lld instead of %lld",
214 xlogfname,
215 (long long int) stat_buf.st_size,
216 (long long int) expectedSize)));
217 return false;
218 }
219 else
220 {
221 ereport(LOG,
222 (errmsg("restored log file \"%s\" from archive",
223 xlogfname)));
224 strcpy(path, xlogpath);
225 return true;
226 }
227 }
228 else
229 {
230 /* stat failed */
231 int elevel = (errno == ENOENT) ? LOG : FATAL;
232
233 ereport(elevel,
235 errmsg("could not stat file \"%s\": %m", xlogpath),
236 errdetail("\"restore_command\" returned a zero exit status, but stat() failed.")));
237 }
238 }
239
240 /*
241 * Remember, we rollforward UNTIL the restore fails so failure here is
242 * just part of the process... that makes it difficult to determine
243 * whether the restore failed because there isn't an archive to restore,
244 * or because the administrator has specified the restore program
245 * incorrectly. We have to assume the former.
246 *
247 * However, if the failure was due to any sort of signal, it's best to
248 * punt and abort recovery. (If we "return false" here, upper levels will
249 * assume that recovery is complete and start up the database!) It's
250 * essential to abort on child SIGINT and SIGQUIT, because per spec
251 * system() ignores SIGINT and SIGQUIT while waiting; if we see one of
252 * those it's a good bet we should have gotten it too.
253 *
254 * On SIGTERM, assume we have received a fast shutdown request, and exit
255 * cleanly. It's pure chance whether we receive the SIGTERM first, or the
256 * child process. If we receive it first, the signal handler will call
257 * proc_exit, otherwise we do it here. If we or the child process received
258 * SIGTERM for any other reason than a fast shutdown request, postmaster
259 * will perform an immediate shutdown when it sees us exiting
260 * unexpectedly.
261 *
262 * We treat hard shell errors such as "command not found" as fatal, too.
263 */
264 if (wait_result_is_signal(rc, SIGTERM))
265 proc_exit(1);
266
268 (errmsg("could not restore file \"%s\" from archive: %s",
269 xlogfname, wait_result_to_str(rc))));
270
271not_available:
272
273 /*
274 * if an archived file is not available, there might still be a version of
275 * this file in XLOGDIR, so return that as the filename to open.
276 *
277 * In many recovery scenarios we expect this to fail also, but if so that
278 * just means we've reached the end of WAL.
279 */
280 snprintf(path, MAXPGPATH, XLOGDIR "/%s", xlogfname);
281 return false;
282}
void PreRestoreCommand(void)
Definition: startup.c:268
void PostRestoreCommand(void)
Definition: startup.c:282
char * BuildRestoreCommand(const char *restoreCommand, const char *xlogpath, const char *xlogfname, const char *lastRestartPointFname)
Definition: archive.c:39
int errdetail(const char *fmt,...)
Definition: elog.c:1203
#define LOG
Definition: elog.h:31
#define DEBUG2
Definition: elog.h:29
#define DEBUG1
Definition: elog.h:30
void proc_exit(int code)
Definition: ipc.c:104
bool wait_result_is_signal(int exit_status, int signum)
Definition: wait_error.c:102
bool ArchiveRecoveryRequested
Definition: xlogrecovery.c:137
char * recoveryRestoreCommand
Definition: xlogrecovery.c:82
bool StandbyMode
Definition: xlogrecovery.c:147

References ArchiveRecoveryRequested, Assert, BuildRestoreCommand(), DEBUG1, DEBUG2, DEBUG3, ereport, errcode_for_file_access(), errdetail(), errmsg(), errmsg_internal(), FATAL, fflush(), GetOldestRestartPoint(), LOG, MAXPGPATH, pfree(), pgstat_report_wait_end(), pgstat_report_wait_start(), PostRestoreCommand(), PreRestoreCommand(), proc_exit(), recoveryRestoreCommand, snprintf, stat::st_size, StandbyMode, stat, wait_result_is_any_signal(), wait_result_is_signal(), wait_result_to_str(), wal_segment_size, XLByteToSeg, XLOGDIR, and XLogFileName().

Referenced by existsTimeLineHistory(), readTimeLineHistory(), restoreTimeLineHistoryFiles(), SimpleXLogPageRead(), writeTimeLineHistory(), and XLogFileRead().

◆ XLogArchiveCheckDone()

bool XLogArchiveCheckDone ( const char *  xlog)

Definition at line 565 of file xlogarchive.c.

566{
567 char archiveStatusPath[MAXPGPATH];
568 struct stat stat_buf;
569
570 /* The file is always deletable if archive_mode is "off". */
571 if (!XLogArchivingActive())
572 return true;
573
574 /*
575 * During archive recovery, the file is deletable if archive_mode is not
576 * "always".
577 */
578 if (!XLogArchivingAlways() &&
580 return true;
581
582 /*
583 * At this point of the logic, note that we are either a primary with
584 * archive_mode set to "on" or "always", or a standby with archive_mode
585 * set to "always".
586 */
587
588 /* First check for .done --- this means archiver is done with it */
589 StatusFilePath(archiveStatusPath, xlog, ".done");
590 if (stat(archiveStatusPath, &stat_buf) == 0)
591 return true;
592
593 /* check for .ready --- this means archiver is still busy with it */
594 StatusFilePath(archiveStatusPath, xlog, ".ready");
595 if (stat(archiveStatusPath, &stat_buf) == 0)
596 return false;
597
598 /* Race condition --- maybe archiver just finished, so recheck */
599 StatusFilePath(archiveStatusPath, xlog, ".done");
600 if (stat(archiveStatusPath, &stat_buf) == 0)
601 return true;
602
603 /* Retry creation of the .ready file */
604 XLogArchiveNotify(xlog);
605 return false;
606}
RecoveryState GetRecoveryState(void)
Definition: xlog.c:6370
#define XLogArchivingActive()
Definition: xlog.h:99
#define XLogArchivingAlways()
Definition: xlog.h:102
@ RECOVERY_STATE_ARCHIVE
Definition: xlog.h:92
static void StatusFilePath(char *path, const char *xlog, const char *suffix)

References GetRecoveryState(), MAXPGPATH, RECOVERY_STATE_ARCHIVE, stat, StatusFilePath(), XLogArchiveNotify(), XLogArchivingActive, and XLogArchivingAlways.

Referenced by CleanupBackupHistory(), and RemoveOldXlogFiles().

◆ XLogArchiveCleanup()

void XLogArchiveCleanup ( const char *  xlog)

Definition at line 712 of file xlogarchive.c.

713{
714 char archiveStatusPath[MAXPGPATH];
715
716 /* Remove the .done file */
717 StatusFilePath(archiveStatusPath, xlog, ".done");
718 unlink(archiveStatusPath);
719 /* should we complain about failure? */
720
721 /* Remove the .ready file if present --- normally it shouldn't be */
722 StatusFilePath(archiveStatusPath, xlog, ".ready");
723 unlink(archiveStatusPath);
724 /* should we complain about failure? */
725}

References MAXPGPATH, and StatusFilePath().

Referenced by CleanupAfterArchiveRecovery(), CleanupBackupHistory(), RemoveXlogFile(), and XLogInitNewTimeline().

◆ XLogArchiveForceDone()

void XLogArchiveForceDone ( const char *  xlog)

Definition at line 510 of file xlogarchive.c.

511{
512 char archiveReady[MAXPGPATH];
513 char archiveDone[MAXPGPATH];
514 struct stat stat_buf;
515 FILE *fd;
516
517 /* Exit if already known done */
518 StatusFilePath(archiveDone, xlog, ".done");
519 if (stat(archiveDone, &stat_buf) == 0)
520 return;
521
522 /* If .ready exists, rename it to .done */
523 StatusFilePath(archiveReady, xlog, ".ready");
524 if (stat(archiveReady, &stat_buf) == 0)
525 {
526 (void) durable_rename(archiveReady, archiveDone, WARNING);
527 return;
528 }
529
530 /* insert an otherwise empty file called <XLOG>.done */
531 fd = AllocateFile(archiveDone, "w");
532 if (fd == NULL)
533 {
534 ereport(LOG,
536 errmsg("could not create archive status file \"%s\": %m",
537 archiveDone)));
538 return;
539 }
540 if (FreeFile(fd))
541 {
542 ereport(LOG,
544 errmsg("could not write archive status file \"%s\": %m",
545 archiveDone)));
546 return;
547 }
548}
int FreeFile(FILE *file)
Definition: fd.c:2803
FILE * AllocateFile(const char *name, const char *mode)
Definition: fd.c:2605
static int fd(const char *x, int i)
Definition: preproc-init.c:105

References AllocateFile(), durable_rename(), ereport, errcode_for_file_access(), errmsg(), fd(), FreeFile(), LOG, MAXPGPATH, stat, StatusFilePath(), and WARNING.

Referenced by KeepFileRestoredFromArchive(), WalRcvFetchTimeLineHistoryFiles(), WalReceiverMain(), and XLogWalRcvClose().

◆ XLogArchiveIsBusy()

bool XLogArchiveIsBusy ( const char *  xlog)

Definition at line 619 of file xlogarchive.c.

620{
621 char archiveStatusPath[MAXPGPATH];
622 struct stat stat_buf;
623
624 /* First check for .done --- this means archiver is done with it */
625 StatusFilePath(archiveStatusPath, xlog, ".done");
626 if (stat(archiveStatusPath, &stat_buf) == 0)
627 return false;
628
629 /* check for .ready --- this means archiver is still busy with it */
630 StatusFilePath(archiveStatusPath, xlog, ".ready");
631 if (stat(archiveStatusPath, &stat_buf) == 0)
632 return true;
633
634 /* Race condition --- maybe archiver just finished, so recheck */
635 StatusFilePath(archiveStatusPath, xlog, ".done");
636 if (stat(archiveStatusPath, &stat_buf) == 0)
637 return false;
638
639 /*
640 * Check to see if the WAL file has been removed by checkpoint, which
641 * implies it has already been archived, and explains why we can't see a
642 * status file for it.
643 */
644 snprintf(archiveStatusPath, MAXPGPATH, XLOGDIR "/%s", xlog);
645 if (stat(archiveStatusPath, &stat_buf) != 0 &&
646 errno == ENOENT)
647 return false;
648
649 return true;
650}

References MAXPGPATH, snprintf, stat, StatusFilePath(), and XLOGDIR.

Referenced by do_pg_backup_stop().

◆ XLogArchiveIsReady()

bool XLogArchiveIsReady ( const char *  xlog)

Definition at line 694 of file xlogarchive.c.

695{
696 char archiveStatusPath[MAXPGPATH];
697 struct stat stat_buf;
698
699 StatusFilePath(archiveStatusPath, xlog, ".ready");
700 if (stat(archiveStatusPath, &stat_buf) == 0)
701 return true;
702
703 return false;
704}

References MAXPGPATH, stat, and StatusFilePath().

Referenced by RemoveNonParentXlogFiles().

◆ XLogArchiveIsReadyOrDone()

bool XLogArchiveIsReadyOrDone ( const char *  xlog)

Definition at line 664 of file xlogarchive.c.

665{
666 char archiveStatusPath[MAXPGPATH];
667 struct stat stat_buf;
668
669 /* First check for .done --- this means archiver is done with it */
670 StatusFilePath(archiveStatusPath, xlog, ".done");
671 if (stat(archiveStatusPath, &stat_buf) == 0)
672 return true;
673
674 /* check for .ready --- this means archiver is still busy with it */
675 StatusFilePath(archiveStatusPath, xlog, ".ready");
676 if (stat(archiveStatusPath, &stat_buf) == 0)
677 return true;
678
679 /* Race condition --- maybe archiver just finished, so recheck */
680 StatusFilePath(archiveStatusPath, xlog, ".done");
681 if (stat(archiveStatusPath, &stat_buf) == 0)
682 return true;
683
684 return false;
685}

References MAXPGPATH, stat, and StatusFilePath().

Referenced by CleanupAfterArchiveRecovery().

◆ XLogArchiveNotify()

void XLogArchiveNotify ( const char *  xlog)

Definition at line 444 of file xlogarchive.c.

445{
446 char archiveStatusPath[MAXPGPATH];
447 FILE *fd;
448
449 /* insert an otherwise empty file called <XLOG>.ready */
450 StatusFilePath(archiveStatusPath, xlog, ".ready");
451 fd = AllocateFile(archiveStatusPath, "w");
452 if (fd == NULL)
453 {
454 ereport(LOG,
456 errmsg("could not create archive status file \"%s\": %m",
457 archiveStatusPath)));
458 return;
459 }
460 if (FreeFile(fd))
461 {
462 ereport(LOG,
464 errmsg("could not write archive status file \"%s\": %m",
465 archiveStatusPath)));
466 return;
467 }
468
469 /*
470 * Timeline history files are given the highest archival priority to lower
471 * the chance that a promoted standby will choose a timeline that is
472 * already in use. However, the archiver ordinarily tries to gather
473 * multiple files to archive from each scan of the archive_status
474 * directory, which means that newly created timeline history files could
475 * be left unarchived for a while. To ensure that the archiver picks up
476 * timeline history files as soon as possible, we force the archiver to
477 * scan the archive_status directory the next time it looks for a file to
478 * archive.
479 */
480 if (IsTLHistoryFileName(xlog))
482
483 /* Notify archiver that it's got something to do */
485 PgArchWakeup();
486}
bool IsUnderPostmaster
Definition: globals.c:119
void PgArchForceDirScan(void)
Definition: pgarch.c:800
void PgArchWakeup(void)
Definition: pgarch.c:278
static bool IsTLHistoryFileName(const char *fname)

References AllocateFile(), ereport, errcode_for_file_access(), errmsg(), fd(), FreeFile(), IsTLHistoryFileName(), IsUnderPostmaster, LOG, MAXPGPATH, PgArchForceDirScan(), PgArchWakeup(), and StatusFilePath().

Referenced by CleanupAfterArchiveRecovery(), KeepFileRestoredFromArchive(), WalRcvFetchTimeLineHistoryFiles(), WalReceiverMain(), writeTimeLineHistory(), XLogArchiveCheckDone(), XLogArchiveNotifySeg(), and XLogWalRcvClose().

◆ XLogArchiveNotifySeg()

void XLogArchiveNotifySeg ( XLogSegNo  segno,
TimeLineID  tli 
)

Definition at line 492 of file xlogarchive.c.

493{
494 char xlog[MAXFNAMELEN];
495
496 Assert(tli != 0);
497
498 XLogFileName(xlog, tli, segno, wal_segment_size);
499 XLogArchiveNotify(xlog);
500}
#define MAXFNAMELEN

References Assert, MAXFNAMELEN, wal_segment_size, XLogArchiveNotify(), and XLogFileName().

Referenced by XLogWrite().