Age Owner TLA Line data Source code
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
3841 heikki.linnakangas 55 GIC 673 : RestoreArchivedFile(char *path, const char *xlogfname,
3793 heikki.linnakangas 56 ECB : 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 : */
1276 fujii 72 GIC 673 : if (!ArchiveRecoveryRequested)
1276 fujii 73 CBC 7 : goto not_available;
1276 fujii 74 ECB :
75 : /* In standby mode, restore_command might not be supplied */
1596 peter_e 76 GIC 666 : if (recoveryRestoreCommand == NULL || strcmp(recoveryRestoreCommand, "") == 0)
3841 heikki.linnakangas 77 CBC 535 : goto not_available;
3841 heikki.linnakangas 78 ECB :
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 : */
3841 heikki.linnakangas 102 GIC 131 : snprintf(xlogpath, MAXPGPATH, XLOGDIR "/%s", recovername);
3841 heikki.linnakangas 103 ECB :
104 : /*
105 : * Make sure there is no existing file named recovername.
106 : */
3841 heikki.linnakangas 107 GIC 131 : if (stat(xlogpath, &stat_buf) != 0)
3841 heikki.linnakangas 108 ECB : {
3841 heikki.linnakangas 109 GIC 127 : if (errno != ENOENT)
3841 heikki.linnakangas 110 LBC 0 : ereport(FATAL,
3841 heikki.linnakangas 111 EUB : (errcode_for_file_access(),
112 : errmsg("could not stat file \"%s\": %m",
113 : xlogpath)));
114 : }
115 : else
116 : {
3841 heikki.linnakangas 117 GIC 4 : if (unlink(xlogpath) != 0)
3841 heikki.linnakangas 118 LBC 0 : ereport(FATAL,
3841 heikki.linnakangas 119 EUB : (errcode_for_file_access(),
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 : */
3793 heikki.linnakangas 141 GIC 131 : if (cleanupEnabled)
3841 heikki.linnakangas 142 ECB : {
3793 heikki.linnakangas 143 GIC 51 : GetOldestRestartPoint(&restartRedoPtr, &restartTli);
2028 andres 144 CBC 51 : XLByteToSeg(restartRedoPtr, restartSegNo, wal_segment_size);
145 51 : XLogFileName(lastRestartPointFname, restartTli, restartSegNo,
2028 andres 146 ECB : wal_segment_size);
147 : /* we shouldn't need anything earlier than last restart point */
3841 heikki.linnakangas 148 GIC 51 : Assert(strcmp(lastRestartPointFname, xlogfname) <= 0);
3841 heikki.linnakangas 149 ECB : }
150 : else
11 peter 151 GNC 80 : XLogFileName(lastRestartPointFname, 0, 0, wal_segment_size);
3841 heikki.linnakangas 152 ECB :
153 : /* Build the restore command to execute */
62 michael 154 GIC 131 : xlogRestoreCmd = BuildRestoreCommand(recoveryRestoreCommand,
62 michael 155 ECB : xlogpath, xlogfname,
156 : lastRestartPointFname);
157 :
62 michael 158 GIC 131 : ereport(DEBUG3,
159 : (errmsg_internal("executing restore command \"%s\"",
160 : xlogRestoreCmd)));
161 :
162 : /*
3841 heikki.linnakangas 163 ECB : * Check signals before restore command and reset afterwards.
164 : */
3841 heikki.linnakangas 165 GIC 131 : PreRestoreCommand();
166 :
167 : /*
3841 heikki.linnakangas 168 ECB : * Copy xlog from archival storage to XLOGDIR
169 : */
62 michael 170 GNC 131 : fflush(NULL);
62 michael 171 CBC 131 : pgstat_report_wait_start(WAIT_EVENT_RESTORE_COMMAND);
172 131 : rc = system(xlogRestoreCmd);
62 michael 173 GIC 131 : pgstat_report_wait_end();
3841 heikki.linnakangas 174 ECB :
3841 heikki.linnakangas 175 CBC 131 : PostRestoreCommand();
62 michael 176 GIC 131 : pfree(xlogRestoreCmd);
3841 heikki.linnakangas 177 ECB :
62 michael 178 GIC 131 : if (rc == 0)
179 : {
180 : /*
181 : * command apparently succeeded, but let's make sure the file is
182 : * really there now and has the correct size.
3841 heikki.linnakangas 183 ECB : */
3841 heikki.linnakangas 184 GIC 35 : if (stat(xlogpath, &stat_buf) == 0)
3841 heikki.linnakangas 185 ECB : {
3841 heikki.linnakangas 186 GIC 35 : if (expectedSize > 0 && stat_buf.st_size != expectedSize)
187 : {
188 : int elevel;
189 :
190 : /*
191 : * If we find a partial file in standby mode, we assume it's
192 : * because it's just being copied to the archive, and keep
193 : * trying.
194 : *
195 : * Otherwise treat a wrong-sized file as FATAL to ensure the
196 : * DBA would notice it, but is that too strong? We could try
197 : * to plow ahead with a local copy of the file ... but the
198 : * problem is that there probably isn't one, and we'd
199 : * incorrectly conclude we've reached the end of WAL and we're
200 : * done recovering ...
3841 heikki.linnakangas 201 EUB : */
3841 heikki.linnakangas 202 UBC 0 : if (StandbyMode && stat_buf.st_size < expectedSize)
3841 heikki.linnakangas 203 UIC 0 : elevel = DEBUG1;
3841 heikki.linnakangas 204 EUB : else
3841 heikki.linnakangas 205 UBC 0 : elevel = FATAL;
3841 heikki.linnakangas 206 UIC 0 : ereport(elevel,
207 : (errmsg("archive file \"%s\" has wrong size: %lld instead of %lld",
208 : xlogfname,
209 : (long long int) stat_buf.st_size,
927 peter 210 EUB : (long long int) expectedSize)));
3841 heikki.linnakangas 211 UIC 0 : return false;
212 : }
213 : else
3841 heikki.linnakangas 214 ECB : {
3841 heikki.linnakangas 215 GIC 35 : ereport(LOG,
216 : (errmsg("restored log file \"%s\" from archive",
3841 heikki.linnakangas 217 ECB : xlogfname)));
3841 heikki.linnakangas 218 CBC 35 : strcpy(path, xlogpath);
3841 heikki.linnakangas 219 GIC 35 : return true;
220 : }
221 : }
222 : else
223 : {
3841 heikki.linnakangas 224 EUB : /* stat failed */
870 fujii 225 UIC 0 : int elevel = (errno == ENOENT) ? LOG : FATAL;
870 fujii 226 EUB :
870 fujii 227 UIC 0 : ereport(elevel,
228 : (errcode_for_file_access(),
229 : errmsg("could not stat file \"%s\": %m", xlogpath),
230 : errdetail("restore_command returned a zero exit status, but stat() failed.")));
231 : }
232 : }
233 :
234 : /*
235 : * Remember, we rollforward UNTIL the restore fails so failure here is
236 : * just part of the process... that makes it difficult to determine
237 : * whether the restore failed because there isn't an archive to restore,
238 : * or because the administrator has specified the restore program
239 : * incorrectly. We have to assume the former.
240 : *
241 : * However, if the failure was due to any sort of signal, it's best to
242 : * punt and abort recovery. (If we "return false" here, upper levels will
243 : * assume that recovery is complete and start up the database!) It's
244 : * essential to abort on child SIGINT and SIGQUIT, because per spec
245 : * system() ignores SIGINT and SIGQUIT while waiting; if we see one of
246 : * those it's a good bet we should have gotten it too.
247 : *
248 : * On SIGTERM, assume we have received a fast shutdown request, and exit
249 : * cleanly. It's pure chance whether we receive the SIGTERM first, or the
250 : * child process. If we receive it first, the signal handler will call
251 : * proc_exit, otherwise we do it here. If we or the child process received
252 : * SIGTERM for any other reason than a fast shutdown request, postmaster
253 : * will perform an immediate shutdown when it sees us exiting
254 : * unexpectedly.
255 : *
256 : * We treat hard shell errors such as "command not found" as fatal, too.
62 michael 257 ECB : */
62 michael 258 GBC 96 : if (wait_result_is_signal(rc, SIGTERM))
62 michael 259 UIC 0 : proc_exit(1);
62 michael 260 ECB :
62 michael 261 GIC 96 : ereport(wait_result_is_any_signal(rc, true) ? FATAL : DEBUG2,
262 : (errmsg("could not restore file \"%s\" from archive: %s",
263 : xlogfname, wait_result_to_str(rc))));
62 michael 264 ECB :
3841 heikki.linnakangas 265 GIC 96 : not_available:
266 :
267 : /*
268 : * if an archived file is not available, there might still be a version of
269 : * this file in XLOGDIR, so return that as the filename to open.
270 : *
271 : * In many recovery scenarios we expect this to fail also, but if so that
272 : * just means we've reached the end of WAL.
3841 heikki.linnakangas 273 ECB : */
3841 heikki.linnakangas 274 CBC 638 : snprintf(path, MAXPGPATH, XLOGDIR "/%s", xlogfname);
3841 heikki.linnakangas 275 GIC 638 : return false;
276 : }
277 :
278 : /*
279 : * Attempt to execute an external shell command during recovery.
280 : *
281 : * 'command' is the shell command to be executed, 'commandName' is a
282 : * human-readable name describing the command emitted in the logs. If
283 : * 'failOnSignal' is true and the command is killed by a signal, a FATAL
284 : * error is thrown. Otherwise a WARNING is emitted.
285 : *
286 : * This is currently used for recovery_end_command and archive_cleanup_command.
287 : */
62 michael 288 ECB : void
62 michael 289 GIC 2 : ExecuteRecoveryCommand(const char *command, const char *commandName,
290 : bool failOnSignal, uint32 wait_event_info)
291 : {
292 : char *xlogRecoveryCmd;
293 : char lastRestartPointFname[MAXPGPATH];
294 : int rc;
62 michael 295 ECB : XLogSegNo restartSegNo;
296 : XLogRecPtr restartRedoPtr;
297 : TimeLineID restartTli;
298 :
62 michael 299 GIC 2 : Assert(command && commandName);
300 :
301 : /*
62 michael 302 ECB : * Calculate the archive file cutoff point for use during log shipping
303 : * replication. All files earlier than this point can be deleted from the
304 : * archive, though there is no requirement to do so.
305 : */
62 michael 306 GIC 2 : GetOldestRestartPoint(&restartRedoPtr, &restartTli);
307 2 : XLByteToSeg(restartRedoPtr, restartSegNo, wal_segment_size);
308 2 : XLogFileName(lastRestartPointFname, restartTli, restartSegNo,
309 : wal_segment_size);
62 michael 310 ECB :
311 : /*
312 : * construct the command to be executed
313 : */
62 michael 314 GNC 2 : xlogRecoveryCmd = replace_percent_placeholders(command, commandName, "r", lastRestartPointFname);
315 :
62 michael 316 CBC 2 : ereport(DEBUG3,
317 : (errmsg_internal("executing %s \"%s\"", commandName, command)));
318 :
62 michael 319 ECB : /*
320 : * execute the constructed command
321 : */
62 michael 322 GNC 2 : fflush(NULL);
62 michael 323 GIC 2 : pgstat_report_wait_start(wait_event_info);
324 2 : rc = system(xlogRecoveryCmd);
325 2 : pgstat_report_wait_end();
326 :
62 michael 327 GNC 2 : pfree(xlogRecoveryCmd);
328 :
62 michael 329 GIC 2 : if (rc != 0)
330 : {
331 : /*
332 : * If the failure was due to any sort of signal, it's best to punt and
333 : * abort recovery. See comments in RestoreArchivedFile().
334 : */
335 1 : ereport((failOnSignal && wait_result_is_any_signal(rc, true)) ? FATAL : WARNING,
336 : /*------
337 : translator: First %s represents a postgresql.conf parameter name like
338 : "recovery_end_command", the 2nd is the value of that parameter, the
339 : third an already translated error message. */
340 : (errmsg("%s \"%s\": %s", commandName,
341 : command, wait_result_to_str(rc))));
342 : }
343 2 : }
344 :
345 :
346 : /*
347 : * A file was restored from the archive under a temporary filename (path),
348 : * and now we want to keep it. Rename it under the permanent filename in
349 : * pg_wal (xlogfname), replacing any existing file with the same name.
350 : */
351 : void
1986 peter_e 352 CBC 28 : KeepFileRestoredFromArchive(const char *path, const char *xlogfname)
353 : {
3752 heikki.linnakangas 354 ECB : char xlogfpath[MAXPGPATH];
3752 heikki.linnakangas 355 GBC 28 : bool reload = false;
356 : struct stat statbuf;
357 :
3752 heikki.linnakangas 358 GIC 28 : snprintf(xlogfpath, MAXPGPATH, XLOGDIR "/%s", xlogfname);
3752 heikki.linnakangas 359 ECB :
3752 heikki.linnakangas 360 GIC 28 : if (stat(xlogfpath, &statbuf) == 0)
361 : {
3602 bruce 362 ECB : char oldpath[MAXPGPATH];
363 :
364 : #ifdef WIN32
365 : static unsigned int deletedcounter = 1;
366 :
367 : /*
368 : * On Windows, if another process (e.g a walsender process) holds the
369 : * file open in FILE_SHARE_DELETE mode, unlink will succeed, but the
370 : * file will still show up in directory listing until the last handle
371 : * is closed, and we cannot rename the new file in its place until
372 : * that. To avoid that problem, rename the old file to a temporary
373 : * name first. Use a counter to create a unique filename, because the
374 : * same file might be restored from the archive multiple times, and a
375 : * walsender could still be holding onto an old deleted version of it.
376 : */
377 : snprintf(oldpath, MAXPGPATH, "%s.deleted%u",
378 : xlogfpath, deletedcounter++);
379 : if (rename(xlogfpath, oldpath) != 0)
3752 heikki.linnakangas 380 : {
381 : ereport(ERROR,
382 : (errcode_for_file_access(),
383 : errmsg("could not rename file \"%s\" to \"%s\": %m",
384 : xlogfpath, oldpath)));
385 : }
386 : #else
387 : /* same-size buffers, so this never truncates */
3156 noah 388 CBC 16 : strlcpy(oldpath, xlogfpath, MAXPGPATH);
3752 heikki.linnakangas 389 ECB : #endif
3752 heikki.linnakangas 390 GIC 16 : if (unlink(oldpath) != 0)
3752 heikki.linnakangas 391 UIC 0 : ereport(FATAL,
392 : (errcode_for_file_access(),
393 : errmsg("could not remove file \"%s\": %m",
394 : xlogfpath)));
3752 heikki.linnakangas 395 GIC 16 : reload = true;
396 : }
397 :
2587 andres 398 28 : durable_rename(path, xlogfpath, ERROR);
399 :
400 : /*
401 : * Create .done file forcibly to prevent the restored segment from being
3602 bruce 402 ECB : * archived again later.
403 : */
2886 heikki.linnakangas 404 GIC 28 : if (XLogArchiveMode != ARCHIVE_MODE_ALWAYS)
405 27 : XLogArchiveForceDone(xlogfname);
406 : else
582 alvherre 407 1 : XLogArchiveNotify(xlogfname);
3896 simon 408 ECB :
3752 heikki.linnakangas 409 : /*
3602 bruce 410 : * If the existing file was replaced, since walsenders might have it open,
411 : * request them to reload a currently-open segment. This is only required
3602 bruce 412 EUB : * for WAL segments, walsenders don't hold other files open, but there's
413 : * no harm in doing this too often, and we don't know what kind of a file
414 : * we're dealing with here.
415 : */
3752 heikki.linnakangas 416 GBC 28 : if (reload)
3752 heikki.linnakangas 417 GIC 16 : WalSndRqstFileReload();
3752 heikki.linnakangas 418 ECB :
419 : /*
3752 heikki.linnakangas 420 EUB : * Signal walsender that new WAL has arrived. Again, this isn't necessary
421 : * if we restored something other than a WAL segment, but it does no harm
422 : * either.
423 : */
1 andres 424 GNC 28 : WalSndWakeup(true, false);
3752 heikki.linnakangas 425 GIC 28 : }
426 :
427 : /*
428 : * XLogArchiveNotify
429 : *
430 : * Create an archive notification file
431 : *
432 : * The name of the notification file is the message that will be picked up
433 : * by the archiver, e.g. we write 0000000100000001000000C6.ready
434 : * and the archiver then knows to archive XLOGDIR/0000000100000001000000C6,
435 : * then when complete, rename it to 0000000100000001000000C6.done
436 : */
437 : void
582 alvherre 438 CBC 59 : XLogArchiveNotify(const char *xlog)
3841 heikki.linnakangas 439 ECB : {
440 : char archiveStatusPath[MAXPGPATH];
441 : FILE *fd;
442 :
443 : /* insert an otherwise empty file called <XLOG>.ready */
3841 heikki.linnakangas 444 GIC 59 : StatusFilePath(archiveStatusPath, xlog, ".ready");
445 59 : fd = AllocateFile(archiveStatusPath, "w");
446 59 : if (fd == NULL)
447 : {
3841 heikki.linnakangas 448 UIC 0 : ereport(LOG,
449 : (errcode_for_file_access(),
3841 heikki.linnakangas 450 ECB : errmsg("could not create archive status file \"%s\": %m",
451 : archiveStatusPath)));
3841 heikki.linnakangas 452 UIC 0 : return;
453 : }
3841 heikki.linnakangas 454 CBC 59 : if (FreeFile(fd))
455 : {
3841 heikki.linnakangas 456 LBC 0 : ereport(LOG,
3841 heikki.linnakangas 457 ECB : (errcode_for_file_access(),
458 : errmsg("could not write archive status file \"%s\": %m",
459 : archiveStatusPath)));
3841 heikki.linnakangas 460 UIC 0 : return;
461 : }
462 :
463 : /*
464 : * Timeline history files are given the highest archival priority to lower
465 : * the chance that a promoted standby will choose a timeline that is
466 : * already in use. However, the archiver ordinarily tries to gather
467 : * multiple files to archive from each scan of the archive_status
332 tgl 468 ECB : * directory, which means that newly created timeline history files could
469 : * be left unarchived for a while. To ensure that the archiver picks up
470 : * timeline history files as soon as possible, we force the archiver to
471 : * scan the archive_status directory the next time it looks for a file to
472 : * archive.
473 : */
514 rhaas 474 GIC 59 : if (IsTLHistoryFileName(xlog))
475 10 : PgArchForceDirScan();
514 rhaas 476 ECB :
582 alvherre 477 : /* Notify archiver that it's got something to do */
582 alvherre 478 CBC 59 : if (IsUnderPostmaster)
755 fujii 479 GIC 59 : PgArchWakeup();
480 : }
3841 heikki.linnakangas 481 ECB :
482 : /*
483 : * Convenience routine to notify using segment number representation of filename
3841 heikki.linnakangas 484 EUB : */
485 : void
520 rhaas 486 GIC 33 : XLogArchiveNotifySeg(XLogSegNo segno, TimeLineID tli)
487 : {
488 : char xlog[MAXFNAMELEN];
3841 heikki.linnakangas 489 ECB :
520 rhaas 490 CBC 33 : Assert(tli != 0);
491 :
520 rhaas 492 GBC 33 : XLogFileName(xlog, tli, segno, wal_segment_size);
582 alvherre 493 GIC 33 : XLogArchiveNotify(xlog);
3841 heikki.linnakangas 494 33 : }
495 :
3896 simon 496 EUB : /*
497 : * XLogArchiveForceDone
3896 simon 498 ECB : *
499 : * Emit notification forcibly that an XLOG segment file has been successfully
3896 simon 500 EUB : * archived, by creating <XLOG>.done regardless of whether <XLOG>.ready
501 : * exists or not.
502 : */
503 : void
3896 simon 504 GBC 98 : XLogArchiveForceDone(const char *xlog)
505 : {
506 : char archiveReady[MAXPGPATH];
507 : char archiveDone[MAXPGPATH];
508 : struct stat stat_buf;
509 : FILE *fd;
510 :
511 : /* Exit if already known done */
3896 simon 512 GIC 98 : StatusFilePath(archiveDone, xlog, ".done");
513 98 : if (stat(archiveDone, &stat_buf) == 0)
514 9 : return;
515 :
516 : /* If .ready exists, rename it to .done */
517 89 : StatusFilePath(archiveReady, xlog, ".ready");
518 89 : if (stat(archiveReady, &stat_buf) == 0)
519 : {
2587 andres 520 UIC 0 : (void) durable_rename(archiveReady, archiveDone, WARNING);
3896 simon 521 0 : return;
522 : }
3896 simon 523 ECB :
524 : /* insert an otherwise empty file called <XLOG>.done */
3896 simon 525 GIC 89 : fd = AllocateFile(archiveDone, "w");
526 89 : if (fd == NULL)
527 : {
3896 simon 528 UIC 0 : ereport(LOG,
3896 simon 529 ECB : (errcode_for_file_access(),
530 : errmsg("could not create archive status file \"%s\": %m",
531 : archiveDone)));
3896 simon 532 UIC 0 : return;
533 : }
3896 simon 534 GIC 89 : if (FreeFile(fd))
535 : {
3896 simon 536 LBC 0 : ereport(LOG,
3896 simon 537 ECB : (errcode_for_file_access(),
538 : errmsg("could not write archive status file \"%s\": %m",
539 : archiveDone)));
3896 simon 540 UIC 0 : return;
541 : }
542 : }
543 :
544 : /*
545 : * XLogArchiveCheckDone
546 : *
3841 heikki.linnakangas 547 ECB : * This is called when we are ready to delete or recycle an old XLOG segment
548 : * file or backup history file. If it is okay to delete it then return true.
549 : * If it is not time to delete it, make sure a .ready file exists, and return
550 : * false.
551 : *
552 : * If <XLOG>.done exists, then return true; else if <XLOG>.ready exists,
553 : * then return false; else create <XLOG>.ready and return false.
554 : *
555 : * The reason we do things this way is so that if the original attempt to
556 : * create <XLOG>.ready fails, we'll retry during subsequent checkpoints.
557 : */
558 : bool
3841 heikki.linnakangas 559 GBC 697 : XLogArchiveCheckDone(const char *xlog)
560 : {
561 : char archiveStatusPath[MAXPGPATH];
3841 heikki.linnakangas 562 ECB : struct stat stat_buf;
1080 michael 563 :
564 : /* The file is always deletable if archive_mode is "off". */
1080 michael 565 GIC 697 : if (!XLogArchivingActive())
566 667 : return true;
567 :
568 : /*
569 : * During archive recovery, the file is deletable if archive_mode is not
570 : * "always".
571 : */
572 55 : if (!XLogArchivingAlways() &&
573 25 : GetRecoveryState() == RECOVERY_STATE_ARCHIVE)
3841 heikki.linnakangas 574 1 : return true;
575 :
576 : /*
1080 michael 577 ECB : * At this point of the logic, note that we are either a primary with
578 : * archive_mode set to "on" or "always", or a standby with archive_mode
579 : * set to "always".
580 : */
581 :
582 : /* First check for .done --- this means archiver is done with it */
3841 heikki.linnakangas 583 CBC 29 : StatusFilePath(archiveStatusPath, xlog, ".done");
584 29 : if (stat(archiveStatusPath, &stat_buf) == 0)
585 13 : return true;
586 :
587 : /* check for .ready --- this means archiver is still busy with it */
588 16 : StatusFilePath(archiveStatusPath, xlog, ".ready");
589 16 : if (stat(archiveStatusPath, &stat_buf) == 0)
590 5 : return false;
591 :
592 : /* Race condition --- maybe archiver just finished, so recheck */
3841 heikki.linnakangas 593 GBC 11 : StatusFilePath(archiveStatusPath, xlog, ".done");
594 11 : if (stat(archiveStatusPath, &stat_buf) == 0)
3841 heikki.linnakangas 595 UBC 0 : return true;
596 :
597 : /* Retry creation of the .ready file */
582 alvherre 598 GIC 11 : XLogArchiveNotify(xlog);
3841 heikki.linnakangas 599 11 : return false;
600 : }
601 :
3841 heikki.linnakangas 602 EUB : /*
603 : * XLogArchiveIsBusy
604 : *
605 : * Check to see if an XLOG segment file is still unarchived.
606 : * This is almost but not quite the inverse of XLogArchiveCheckDone: in
607 : * the first place we aren't chartered to recreate the .ready file, and
608 : * in the second place we should consider that if the file is already gone
609 : * then it's not busy. (This check is needed to handle the race condition
610 : * that a checkpoint already deleted the no-longer-needed file.)
611 : */
612 : bool
3841 heikki.linnakangas 613 GIC 6 : XLogArchiveIsBusy(const char *xlog)
614 : {
615 : char archiveStatusPath[MAXPGPATH];
616 : struct stat stat_buf;
617 :
618 : /* First check for .done --- this means archiver is done with it */
619 6 : StatusFilePath(archiveStatusPath, xlog, ".done");
620 6 : if (stat(archiveStatusPath, &stat_buf) == 0)
621 4 : return false;
3841 heikki.linnakangas 622 ECB :
623 : /* check for .ready --- this means archiver is still busy with it */
3841 heikki.linnakangas 624 GIC 2 : StatusFilePath(archiveStatusPath, xlog, ".ready");
625 2 : if (stat(archiveStatusPath, &stat_buf) == 0)
626 2 : return true;
627 :
3841 heikki.linnakangas 628 ECB : /* Race condition --- maybe archiver just finished, so recheck */
3841 heikki.linnakangas 629 LBC 0 : StatusFilePath(archiveStatusPath, xlog, ".done");
630 0 : if (stat(archiveStatusPath, &stat_buf) == 0)
3841 heikki.linnakangas 631 UIC 0 : return false;
632 :
3841 heikki.linnakangas 633 ECB : /*
634 : * Check to see if the WAL file has been removed by checkpoint, which
3841 heikki.linnakangas 635 EUB : * implies it has already been archived, and explains why we can't see a
636 : * status file for it.
637 : */
3841 heikki.linnakangas 638 LBC 0 : snprintf(archiveStatusPath, MAXPGPATH, XLOGDIR "/%s", xlog);
639 0 : if (stat(archiveStatusPath, &stat_buf) != 0 &&
3841 heikki.linnakangas 640 UBC 0 : errno == ENOENT)
3841 heikki.linnakangas 641 UIC 0 : return false;
3841 heikki.linnakangas 642 ECB :
3841 heikki.linnakangas 643 UIC 0 : return true;
644 : }
645 :
646 : /*
647 : * XLogArchiveIsReadyOrDone
648 : *
649 : * Check to see if an XLOG segment file has a .ready or .done file.
650 : * This is similar to XLogArchiveIsBusy(), but returns true if the file
651 : * is already archived or is about to be archived.
2880 heikki.linnakangas 652 ECB : *
653 : * This is currently only used at recovery. During normal operation this
654 : * would be racy: the file might get removed or marked with .ready as we're
655 : * checking it, or immediately after we return.
656 : */
657 : bool
2880 heikki.linnakangas 658 CBC 6 : XLogArchiveIsReadyOrDone(const char *xlog)
2880 heikki.linnakangas 659 EUB : {
660 : char archiveStatusPath[MAXPGPATH];
2880 heikki.linnakangas 661 ECB : struct stat stat_buf;
662 :
663 : /* First check for .done --- this means archiver is done with it */
2880 heikki.linnakangas 664 GIC 6 : StatusFilePath(archiveStatusPath, xlog, ".done");
665 6 : if (stat(archiveStatusPath, &stat_buf) == 0)
666 2 : return true;
667 :
668 : /* check for .ready --- this means archiver is still busy with it */
669 4 : StatusFilePath(archiveStatusPath, xlog, ".ready");
2880 heikki.linnakangas 670 CBC 4 : if (stat(archiveStatusPath, &stat_buf) == 0)
2880 heikki.linnakangas 671 UIC 0 : return true;
672 :
673 : /* Race condition --- maybe archiver just finished, so recheck */
2880 heikki.linnakangas 674 GIC 4 : StatusFilePath(archiveStatusPath, xlog, ".done");
2880 heikki.linnakangas 675 CBC 4 : if (stat(archiveStatusPath, &stat_buf) == 0)
2880 heikki.linnakangas 676 LBC 0 : return true;
677 :
2880 heikki.linnakangas 678 GIC 4 : return false;
679 : }
2880 heikki.linnakangas 680 ECB :
2918 681 : /*
682 : * XLogArchiveIsReady
683 : *
684 : * Check to see if an XLOG segment file has an archive notification (.ready)
685 : * file.
686 : */
687 : bool
2918 heikki.linnakangas 688 GIC 12 : XLogArchiveIsReady(const char *xlog)
689 : {
690 : char archiveStatusPath[MAXPGPATH];
691 : struct stat stat_buf;
692 :
693 12 : StatusFilePath(archiveStatusPath, xlog, ".ready");
694 12 : if (stat(archiveStatusPath, &stat_buf) == 0)
2918 heikki.linnakangas 695 UIC 0 : return true;
696 :
2918 heikki.linnakangas 697 GIC 12 : return false;
698 : }
699 :
700 : /*
701 : * XLogArchiveCleanup
702 : *
703 : * Cleanup archive notification file(s) for a particular xlog segment
704 : */
705 : void
3841 706 736 : XLogArchiveCleanup(const char *xlog)
707 : {
708 : char archiveStatusPath[MAXPGPATH];
709 :
710 : /* Remove the .done file */
711 736 : StatusFilePath(archiveStatusPath, xlog, ".done");
712 736 : unlink(archiveStatusPath);
713 : /* should we complain about failure? */
714 :
715 : /* Remove the .ready file if present --- normally it shouldn't be */
716 736 : StatusFilePath(archiveStatusPath, xlog, ".ready");
717 736 : unlink(archiveStatusPath);
718 : /* should we complain about failure? */
719 736 : }
|