1 /*-------------------------------------------------------------------------
2  *
3  * pgarch.c
4  *
5  *	PostgreSQL WAL archiver
6  *
7  *	All functions relating to archiver are included here
8  *
9  *	- All functions executed by archiver process
10  *
11  *	- archiver is forked from postmaster, and the two
12  *	processes then communicate using signals. All functions
13  *	executed by postmaster are included in this file.
14  *
15  *	Initial author: Simon Riggs		simon@2ndquadrant.com
16  *
17  * Portions Copyright (c) 1996-2016, PostgreSQL Global Development Group
18  * Portions Copyright (c) 1994, Regents of the University of California
19  *
20  *
21  * IDENTIFICATION
22  *	  src/backend/postmaster/pgarch.c
23  *
24  *-------------------------------------------------------------------------
25  */
26 #include "postgres.h"
27 
28 #include <fcntl.h>
29 #include <signal.h>
30 #include <time.h>
31 #include <sys/time.h>
32 #include <sys/wait.h>
33 #include <unistd.h>
34 
35 #include "access/xlog.h"
36 #include "access/xlog_internal.h"
37 #include "libpq/pqsignal.h"
38 #include "miscadmin.h"
39 #include "pgstat.h"
40 #include "postmaster/fork_process.h"
41 #include "postmaster/pgarch.h"
42 #include "postmaster/postmaster.h"
43 #include "storage/dsm.h"
44 #include "storage/fd.h"
45 #include "storage/ipc.h"
46 #include "storage/latch.h"
47 #include "storage/pg_shmem.h"
48 #include "storage/pmsignal.h"
49 #include "utils/guc.h"
50 #include "utils/ps_status.h"
51 
52 
53 /* ----------
54  * Timer definitions.
55  * ----------
56  */
57 #define PGARCH_AUTOWAKE_INTERVAL 60		/* How often to force a poll of the
58 										 * archive status directory; in
59 										 * seconds. */
60 #define PGARCH_RESTART_INTERVAL 10		/* How often to attempt to restart a
61 										 * failed archiver; in seconds. */
62 
63 #define NUM_ARCHIVE_RETRIES 3
64 
65 
66 /* ----------
67  * Local data
68  * ----------
69  */
70 static time_t last_pgarch_start_time;
71 static time_t last_sigterm_time = 0;
72 
73 /*
74  * Flags set by interrupt handlers for later service in the main loop.
75  */
76 static volatile sig_atomic_t got_SIGHUP = false;
77 static volatile sig_atomic_t got_SIGTERM = false;
78 static volatile sig_atomic_t wakened = false;
79 static volatile sig_atomic_t ready_to_stop = false;
80 
81 /* ----------
82  * Local function forward declarations
83  * ----------
84  */
85 #ifdef EXEC_BACKEND
86 static pid_t pgarch_forkexec(void);
87 #endif
88 
89 NON_EXEC_STATIC void PgArchiverMain(int argc, char *argv[]) pg_attribute_noreturn();
90 static void pgarch_exit(SIGNAL_ARGS);
91 static void ArchSigHupHandler(SIGNAL_ARGS);
92 static void ArchSigTermHandler(SIGNAL_ARGS);
93 static void pgarch_waken(SIGNAL_ARGS);
94 static void pgarch_waken_stop(SIGNAL_ARGS);
95 static void pgarch_MainLoop(void);
96 static void pgarch_ArchiverCopyLoop(void);
97 static bool pgarch_archiveXlog(char *xlog);
98 static bool pgarch_readyXlog(char *xlog);
99 static void pgarch_archiveDone(char *xlog);
100 
101 
102 /* ------------------------------------------------------------
103  * Public functions called from postmaster follow
104  * ------------------------------------------------------------
105  */
106 
107 /*
108  * pgarch_start
109  *
110  *	Called from postmaster at startup or after an existing archiver
111  *	died.  Attempt to fire up a fresh archiver process.
112  *
113  *	Returns PID of child process, or 0 if fail.
114  *
115  *	Note: if fail, we will be called again from the postmaster main loop.
116  */
117 int
pgarch_start(void)118 pgarch_start(void)
119 {
120 	time_t		curtime;
121 	pid_t		pgArchPid;
122 
123 	/*
124 	 * Do nothing if no archiver needed
125 	 */
126 	if (!XLogArchivingActive())
127 		return 0;
128 
129 	/*
130 	 * Do nothing if too soon since last archiver start.  This is a safety
131 	 * valve to protect against continuous respawn attempts if the archiver is
132 	 * dying immediately at launch. Note that since we will be re-called from
133 	 * the postmaster main loop, we will get another chance later.
134 	 */
135 	curtime = time(NULL);
136 	if ((unsigned int) (curtime - last_pgarch_start_time) <
137 		(unsigned int) PGARCH_RESTART_INTERVAL)
138 		return 0;
139 	last_pgarch_start_time = curtime;
140 
141 #ifdef EXEC_BACKEND
142 	switch ((pgArchPid = pgarch_forkexec()))
143 #else
144 	switch ((pgArchPid = fork_process()))
145 #endif
146 	{
147 		case -1:
148 			ereport(LOG,
149 					(errmsg("could not fork archiver: %m")));
150 			return 0;
151 
152 #ifndef EXEC_BACKEND
153 		case 0:
154 			/* in postmaster child ... */
155 			InitPostmasterChild();
156 
157 			/* Close the postmaster's sockets */
158 			ClosePostmasterPorts(false);
159 
160 			/* Drop our connection to postmaster's shared memory, as well */
161 			dsm_detach_all();
162 			PGSharedMemoryDetach();
163 
164 			PgArchiverMain(0, NULL);
165 			break;
166 #endif
167 
168 		default:
169 			return (int) pgArchPid;
170 	}
171 
172 	/* shouldn't get here */
173 	return 0;
174 }
175 
176 /* ------------------------------------------------------------
177  * Local functions called by archiver follow
178  * ------------------------------------------------------------
179  */
180 
181 
182 #ifdef EXEC_BACKEND
183 
184 /*
185  * pgarch_forkexec() -
186  *
187  * Format up the arglist for, then fork and exec, archive process
188  */
189 static pid_t
pgarch_forkexec(void)190 pgarch_forkexec(void)
191 {
192 	char	   *av[10];
193 	int			ac = 0;
194 
195 	av[ac++] = "postgres";
196 
197 	av[ac++] = "--forkarch";
198 
199 	av[ac++] = NULL;			/* filled in by postmaster_forkexec */
200 
201 	av[ac] = NULL;
202 	Assert(ac < lengthof(av));
203 
204 	return postmaster_forkexec(ac, av);
205 }
206 #endif   /* EXEC_BACKEND */
207 
208 
209 /*
210  * PgArchiverMain
211  *
212  *	The argc/argv parameters are valid only in EXEC_BACKEND case.  However,
213  *	since we don't use 'em, it hardly matters...
214  */
215 NON_EXEC_STATIC void
PgArchiverMain(int argc,char * argv[])216 PgArchiverMain(int argc, char *argv[])
217 {
218 	/*
219 	 * Ignore all signals usually bound to some action in the postmaster,
220 	 * except for SIGHUP, SIGTERM, SIGUSR1, SIGUSR2, and SIGQUIT.
221 	 */
222 	pqsignal(SIGHUP, ArchSigHupHandler);
223 	pqsignal(SIGINT, SIG_IGN);
224 	pqsignal(SIGTERM, ArchSigTermHandler);
225 	pqsignal(SIGQUIT, pgarch_exit);
226 	pqsignal(SIGALRM, SIG_IGN);
227 	pqsignal(SIGPIPE, SIG_IGN);
228 	pqsignal(SIGUSR1, pgarch_waken);
229 	pqsignal(SIGUSR2, pgarch_waken_stop);
230 	pqsignal(SIGCHLD, SIG_DFL);
231 	pqsignal(SIGTTIN, SIG_DFL);
232 	pqsignal(SIGTTOU, SIG_DFL);
233 	pqsignal(SIGCONT, SIG_DFL);
234 	pqsignal(SIGWINCH, SIG_DFL);
235 	PG_SETMASK(&UnBlockSig);
236 
237 	/*
238 	 * Identify myself via ps
239 	 */
240 	init_ps_display("archiver process", "", "", "");
241 
242 	pgarch_MainLoop();
243 
244 	exit(0);
245 }
246 
247 /* SIGQUIT signal handler for archiver process */
248 static void
pgarch_exit(SIGNAL_ARGS)249 pgarch_exit(SIGNAL_ARGS)
250 {
251 	/*
252 	 * We DO NOT want to run proc_exit() or atexit() callbacks; they wouldn't
253 	 * be safe to run from a signal handler.  Just nail the windows shut and
254 	 * get out of town.
255 	 *
256 	 * For consistency with other postmaster children, we do _exit(2) not
257 	 * _exit(1).  The postmaster currently will treat these exit codes alike,
258 	 * but it seems better to report that we died in an unexpected way.
259 	 */
260 	_exit(2);
261 }
262 
263 /* SIGHUP signal handler for archiver process */
264 static void
ArchSigHupHandler(SIGNAL_ARGS)265 ArchSigHupHandler(SIGNAL_ARGS)
266 {
267 	int			save_errno = errno;
268 
269 	/* set flag to re-read config file at next convenient time */
270 	got_SIGHUP = true;
271 	SetLatch(MyLatch);
272 
273 	errno = save_errno;
274 }
275 
276 /* SIGTERM signal handler for archiver process */
277 static void
ArchSigTermHandler(SIGNAL_ARGS)278 ArchSigTermHandler(SIGNAL_ARGS)
279 {
280 	int			save_errno = errno;
281 
282 	/*
283 	 * The postmaster never sends us SIGTERM, so we assume that this means
284 	 * that init is trying to shut down the whole system.  If we hang around
285 	 * too long we'll get SIGKILL'd.  Set flag to prevent starting any more
286 	 * archive commands.
287 	 */
288 	got_SIGTERM = true;
289 	SetLatch(MyLatch);
290 
291 	errno = save_errno;
292 }
293 
294 /* SIGUSR1 signal handler for archiver process */
295 static void
pgarch_waken(SIGNAL_ARGS)296 pgarch_waken(SIGNAL_ARGS)
297 {
298 	int			save_errno = errno;
299 
300 	/* set flag that there is work to be done */
301 	wakened = true;
302 	SetLatch(MyLatch);
303 
304 	errno = save_errno;
305 }
306 
307 /* SIGUSR2 signal handler for archiver process */
308 static void
pgarch_waken_stop(SIGNAL_ARGS)309 pgarch_waken_stop(SIGNAL_ARGS)
310 {
311 	int			save_errno = errno;
312 
313 	/* set flag to do a final cycle and shut down afterwards */
314 	ready_to_stop = true;
315 	SetLatch(MyLatch);
316 
317 	errno = save_errno;
318 }
319 
320 /*
321  * pgarch_MainLoop
322  *
323  * Main loop for archiver
324  */
325 static void
pgarch_MainLoop(void)326 pgarch_MainLoop(void)
327 {
328 	pg_time_t	last_copy_time = 0;
329 	bool		time_to_stop;
330 
331 	/*
332 	 * We run the copy loop immediately upon entry, in case there are
333 	 * unarchived files left over from a previous database run (or maybe the
334 	 * archiver died unexpectedly).  After that we wait for a signal or
335 	 * timeout before doing more.
336 	 */
337 	wakened = true;
338 
339 	/*
340 	 * There shouldn't be anything for the archiver to do except to wait for a
341 	 * signal ... however, the archiver exists to protect our data, so she
342 	 * wakes up occasionally to allow herself to be proactive.
343 	 */
344 	do
345 	{
346 		ResetLatch(MyLatch);
347 
348 		/* When we get SIGUSR2, we do one more archive cycle, then exit */
349 		time_to_stop = ready_to_stop;
350 
351 		/* Check for config update */
352 		if (got_SIGHUP)
353 		{
354 			got_SIGHUP = false;
355 			ProcessConfigFile(PGC_SIGHUP);
356 		}
357 
358 		/*
359 		 * If we've gotten SIGTERM, we normally just sit and do nothing until
360 		 * SIGUSR2 arrives.  However, that means a random SIGTERM would
361 		 * disable archiving indefinitely, which doesn't seem like a good
362 		 * idea.  If more than 60 seconds pass since SIGTERM, exit anyway, so
363 		 * that the postmaster can start a new archiver if needed.
364 		 */
365 		if (got_SIGTERM)
366 		{
367 			time_t		curtime = time(NULL);
368 
369 			if (last_sigterm_time == 0)
370 				last_sigterm_time = curtime;
371 			else if ((unsigned int) (curtime - last_sigterm_time) >=
372 					 (unsigned int) 60)
373 				break;
374 		}
375 
376 		/* Do what we're here for */
377 		if (wakened || time_to_stop)
378 		{
379 			wakened = false;
380 			pgarch_ArchiverCopyLoop();
381 			last_copy_time = time(NULL);
382 		}
383 
384 		/*
385 		 * Sleep until a signal is received, or until a poll is forced by
386 		 * PGARCH_AUTOWAKE_INTERVAL having passed since last_copy_time, or
387 		 * until postmaster dies.
388 		 */
389 		if (!time_to_stop)		/* Don't wait during last iteration */
390 		{
391 			pg_time_t	curtime = (pg_time_t) time(NULL);
392 			int			timeout;
393 
394 			timeout = PGARCH_AUTOWAKE_INTERVAL - (curtime - last_copy_time);
395 			if (timeout > 0)
396 			{
397 				int			rc;
398 
399 				rc = WaitLatch(MyLatch,
400 							 WL_LATCH_SET | WL_TIMEOUT | WL_POSTMASTER_DEATH,
401 							   timeout * 1000L);
402 				if (rc & WL_TIMEOUT)
403 					wakened = true;
404 			}
405 			else
406 				wakened = true;
407 		}
408 
409 		/*
410 		 * The archiver quits either when the postmaster dies (not expected)
411 		 * or after completing one more archiving cycle after receiving
412 		 * SIGUSR2.
413 		 */
414 	} while (PostmasterIsAlive() && !time_to_stop);
415 }
416 
417 /*
418  * pgarch_ArchiverCopyLoop
419  *
420  * Archives all outstanding xlogs then returns
421  */
422 static void
pgarch_ArchiverCopyLoop(void)423 pgarch_ArchiverCopyLoop(void)
424 {
425 	char		xlog[MAX_XFN_CHARS + 1];
426 
427 	/*
428 	 * loop through all xlogs with archive_status of .ready and archive
429 	 * them...mostly we expect this to be a single file, though it is possible
430 	 * some backend will add files onto the list of those that need archiving
431 	 * while we are still copying earlier archives
432 	 */
433 	while (pgarch_readyXlog(xlog))
434 	{
435 		int			failures = 0;
436 
437 		for (;;)
438 		{
439 			/*
440 			 * Do not initiate any more archive commands after receiving
441 			 * SIGTERM, nor after the postmaster has died unexpectedly. The
442 			 * first condition is to try to keep from having init SIGKILL the
443 			 * command, and the second is to avoid conflicts with another
444 			 * archiver spawned by a newer postmaster.
445 			 */
446 			if (got_SIGTERM || !PostmasterIsAlive())
447 				return;
448 
449 			/*
450 			 * Check for config update.  This is so that we'll adopt a new
451 			 * setting for archive_command as soon as possible, even if there
452 			 * is a backlog of files to be archived.
453 			 */
454 			if (got_SIGHUP)
455 			{
456 				got_SIGHUP = false;
457 				ProcessConfigFile(PGC_SIGHUP);
458 			}
459 
460 			/* can't do anything if no command ... */
461 			if (!XLogArchiveCommandSet())
462 			{
463 				ereport(WARNING,
464 						(errmsg("archive_mode enabled, yet archive_command is not set")));
465 				return;
466 			}
467 
468 			if (pgarch_archiveXlog(xlog))
469 			{
470 				/* successful */
471 				pgarch_archiveDone(xlog);
472 
473 				/*
474 				 * Tell the collector about the WAL file that we successfully
475 				 * archived
476 				 */
477 				pgstat_send_archiver(xlog, false);
478 
479 				break;			/* out of inner retry loop */
480 			}
481 			else
482 			{
483 				/*
484 				 * Tell the collector about the WAL file that we failed to
485 				 * archive
486 				 */
487 				pgstat_send_archiver(xlog, true);
488 
489 				if (++failures >= NUM_ARCHIVE_RETRIES)
490 				{
491 					ereport(WARNING,
492 							(errmsg("archiving transaction log file \"%s\" failed too many times, will try again later",
493 									xlog)));
494 					return;		/* give up archiving for now */
495 				}
496 				pg_usleep(1000000L);	/* wait a bit before retrying */
497 			}
498 		}
499 	}
500 }
501 
502 /*
503  * pgarch_archiveXlog
504  *
505  * Invokes system(3) to copy one archive file to wherever it should go
506  *
507  * Returns true if successful
508  */
509 static bool
pgarch_archiveXlog(char * xlog)510 pgarch_archiveXlog(char *xlog)
511 {
512 	char		xlogarchcmd[MAXPGPATH];
513 	char		pathname[MAXPGPATH];
514 	char		activitymsg[MAXFNAMELEN + 16];
515 	char	   *dp;
516 	char	   *endp;
517 	const char *sp;
518 	int			rc;
519 
520 	snprintf(pathname, MAXPGPATH, XLOGDIR "/%s", xlog);
521 
522 	/*
523 	 * construct the command to be executed
524 	 */
525 	dp = xlogarchcmd;
526 	endp = xlogarchcmd + MAXPGPATH - 1;
527 	*endp = '\0';
528 
529 	for (sp = XLogArchiveCommand; *sp; sp++)
530 	{
531 		if (*sp == '%')
532 		{
533 			switch (sp[1])
534 			{
535 				case 'p':
536 					/* %p: relative path of source file */
537 					sp++;
538 					strlcpy(dp, pathname, endp - dp);
539 					make_native_path(dp);
540 					dp += strlen(dp);
541 					break;
542 				case 'f':
543 					/* %f: filename of source file */
544 					sp++;
545 					strlcpy(dp, xlog, endp - dp);
546 					dp += strlen(dp);
547 					break;
548 				case '%':
549 					/* convert %% to a single % */
550 					sp++;
551 					if (dp < endp)
552 						*dp++ = *sp;
553 					break;
554 				default:
555 					/* otherwise treat the % as not special */
556 					if (dp < endp)
557 						*dp++ = *sp;
558 					break;
559 			}
560 		}
561 		else
562 		{
563 			if (dp < endp)
564 				*dp++ = *sp;
565 		}
566 	}
567 	*dp = '\0';
568 
569 	ereport(DEBUG3,
570 			(errmsg_internal("executing archive command \"%s\"",
571 							 xlogarchcmd)));
572 
573 	/* Report archive activity in PS display */
574 	snprintf(activitymsg, sizeof(activitymsg), "archiving %s", xlog);
575 	set_ps_display(activitymsg, false);
576 
577 	rc = system(xlogarchcmd);
578 	if (rc != 0)
579 	{
580 		/*
581 		 * If either the shell itself, or a called command, died on a signal,
582 		 * abort the archiver.  We do this because system() ignores SIGINT and
583 		 * SIGQUIT while waiting; so a signal is very likely something that
584 		 * should have interrupted us too.  If we overreact it's no big deal,
585 		 * the postmaster will just start the archiver again.
586 		 *
587 		 * Per the Single Unix Spec, shells report exit status > 128 when a
588 		 * called command died on a signal.
589 		 */
590 		int			lev = (WIFSIGNALED(rc) || WEXITSTATUS(rc) > 128) ? FATAL : LOG;
591 
592 		if (WIFEXITED(rc))
593 		{
594 			ereport(lev,
595 					(errmsg("archive command failed with exit code %d",
596 							WEXITSTATUS(rc)),
597 					 errdetail("The failed archive command was: %s",
598 							   xlogarchcmd)));
599 		}
600 		else if (WIFSIGNALED(rc))
601 		{
602 #if defined(WIN32)
603 			ereport(lev,
604 				  (errmsg("archive command was terminated by exception 0x%X",
605 						  WTERMSIG(rc)),
606 				   errhint("See C include file \"ntstatus.h\" for a description of the hexadecimal value."),
607 				   errdetail("The failed archive command was: %s",
608 							 xlogarchcmd)));
609 #else
610 			ereport(lev,
611 					(errmsg("archive command was terminated by signal %d: %s",
612 							WTERMSIG(rc), pg_strsignal(WTERMSIG(rc))),
613 					 errdetail("The failed archive command was: %s",
614 							   xlogarchcmd)));
615 #endif
616 		}
617 		else
618 		{
619 			ereport(lev,
620 				(errmsg("archive command exited with unrecognized status %d",
621 						rc),
622 				 errdetail("The failed archive command was: %s",
623 						   xlogarchcmd)));
624 		}
625 
626 		snprintf(activitymsg, sizeof(activitymsg), "failed on %s", xlog);
627 		set_ps_display(activitymsg, false);
628 
629 		return false;
630 	}
631 	ereport(DEBUG1,
632 			(errmsg("archived transaction log file \"%s\"", xlog)));
633 
634 	snprintf(activitymsg, sizeof(activitymsg), "last was %s", xlog);
635 	set_ps_display(activitymsg, false);
636 
637 	return true;
638 }
639 
640 /*
641  * pgarch_readyXlog
642  *
643  * Return name of the oldest xlog file that has not yet been archived.
644  * No notification is set that file archiving is now in progress, so
645  * this would need to be extended if multiple concurrent archival
646  * tasks were created. If a failure occurs, we will completely
647  * re-copy the file at the next available opportunity.
648  *
649  * It is important that we return the oldest, so that we archive xlogs
650  * in order that they were written, for two reasons:
651  * 1) to maintain the sequential chain of xlogs required for recovery
652  * 2) because the oldest ones will sooner become candidates for
653  * recycling at time of checkpoint
654  *
655  * NOTE: the "oldest" comparison will consider any .history file to be older
656  * than any other file except another .history file.  Segments on a timeline
657  * with a smaller ID will be older than all segments on a timeline with a
658  * larger ID; the net result being that past timelines are given higher
659  * priority for archiving.  This seems okay, or at least not obviously worth
660  * changing.
661  */
662 static bool
pgarch_readyXlog(char * xlog)663 pgarch_readyXlog(char *xlog)
664 {
665 	/*
666 	 * open xlog status directory and read through list of xlogs that have the
667 	 * .ready suffix, looking for earliest file. It is possible to optimise
668 	 * this code, though only a single file is expected on the vast majority
669 	 * of calls, so....
670 	 */
671 	char		XLogArchiveStatusDir[MAXPGPATH];
672 	DIR		   *rldir;
673 	struct dirent *rlde;
674 	bool		found = false;
675 	bool		historyFound = false;
676 
677 	snprintf(XLogArchiveStatusDir, MAXPGPATH, XLOGDIR "/archive_status");
678 	rldir = AllocateDir(XLogArchiveStatusDir);
679 	if (rldir == NULL)
680 		ereport(ERROR,
681 				(errcode_for_file_access(),
682 				 errmsg("could not open archive status directory \"%s\": %m",
683 						XLogArchiveStatusDir)));
684 
685 	while ((rlde = ReadDir(rldir, XLogArchiveStatusDir)) != NULL)
686 	{
687 		int			basenamelen = (int) strlen(rlde->d_name) - 6;
688 		char		basename[MAX_XFN_CHARS + 1];
689 		bool		ishistory;
690 
691 		/* Ignore entries with unexpected number of characters */
692 		if (basenamelen < MIN_XFN_CHARS ||
693 			basenamelen > MAX_XFN_CHARS)
694 			continue;
695 
696 		/* Ignore entries with unexpected characters */
697 		if (strspn(rlde->d_name, VALID_XFN_CHARS) < basenamelen)
698 			continue;
699 
700 		/* Ignore anything not suffixed with .ready */
701 		if (strcmp(rlde->d_name + basenamelen, ".ready") != 0)
702 			continue;
703 
704 		/* Truncate off the .ready */
705 		memcpy(basename, rlde->d_name, basenamelen);
706 		basename[basenamelen] = '\0';
707 
708 		/* Is this a history file? */
709 		ishistory = IsTLHistoryFileName(basename);
710 
711 		/*
712 		 * Consume the file to archive.  History files have the highest
713 		 * priority.  If this is the first file or the first history file
714 		 * ever, copy it.  In the presence of a history file already chosen as
715 		 * target, ignore all other files except history files which have been
716 		 * generated for an older timeline than what is already chosen as
717 		 * target to archive.
718 		 */
719 		if (!found || (ishistory && !historyFound))
720 		{
721 			strcpy(xlog, basename);
722 			found = true;
723 			historyFound = ishistory;
724 		}
725 		else if (ishistory || !historyFound)
726 		{
727 			if (strcmp(basename, xlog) < 0)
728 				strcpy(xlog, basename);
729 		}
730 	}
731 	FreeDir(rldir);
732 
733 	return found;
734 }
735 
736 /*
737  * pgarch_archiveDone
738  *
739  * Emit notification that an xlog file has been successfully archived.
740  * We do this by renaming the status file from NNN.ready to NNN.done.
741  * Eventually, a checkpoint process will notice this and delete both the
742  * NNN.done file and the xlog file itself.
743  */
744 static void
pgarch_archiveDone(char * xlog)745 pgarch_archiveDone(char *xlog)
746 {
747 	char		rlogready[MAXPGPATH];
748 	char		rlogdone[MAXPGPATH];
749 
750 	StatusFilePath(rlogready, xlog, ".ready");
751 	StatusFilePath(rlogdone, xlog, ".done");
752 	(void) durable_rename(rlogready, rlogdone, WARNING);
753 }
754