1/*-------------------------------------------------------------------------
5 * PostgreSQL WAL archiver
7 * All functions relating to archiver are included here
9 * - All functions executed by archiver process
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.
15 * Initial author: Simon Riggs simon@2ndquadrant.com
17 * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
18 * Portions Copyright (c) 1994, Regents of the University of California
22 * src/backend/postmaster/pgarch.c
24 *-------------------------------------------------------------------------
62 #define PGARCH_AUTOWAKE_INTERVAL 60 /* How often to force a poll of the
63 * archive status directory; in seconds. */
64#define PGARCH_RESTART_INTERVAL 10 /* How often to attempt to restart a
65 * failed archiver; in seconds. */
68 * Maximum number of retries allowed when attempting to archive a WAL
71#define NUM_ARCHIVE_RETRIES 3
74 * Maximum number of retries allowed when attempting to remove an
75 * orphan archive status file.
77#define NUM_ORPHAN_CLEANUP_RETRIES 3
80 * Maximum number of .ready files to gather per directory scan.
82#define NUM_FILES_PER_DIRECTORY_SCAN 64
84/* Shared memory area for archiver process */
87 int pgprocno;
/* proc number of archiver process */
90 * Forces a directory scan in pgarch_readyXlog().
111 * Stuff for tracking multiple files to archive from each scan of
112 * archive_status. Minimizing the number of directory scans when there are
113 * many files to archive can significantly improve archival rate.
115 * arch_heap is a max-heap that is used during the directory scan to track
116 * the highest-priority files to archive. After the directory scan
117 * completes, the file names are stored in ascending order of priority in
118 * arch_files. pgarch_readyXlog() returns files from arch_files until it
119 * is empty, at which point another directory scan must be performed.
121 * We only need this data in the archiver process, so make it a palloc'd
122 * struct rather than a bunch of static arrays.
129 /* buffers underlying heap, and later arch_files[], entries: */
136 * Flags set by interrupt handlers for later service in the main loop.
141 * Local function forward declarations
156 /* Report shared memory space needed by PgArchShmemInit */
167 /* Allocate and initialize archiver-related shared memory */
178 /* First time through, so initialize */
188 * Return true and archiver is allowed to restart if enough time has
189 * passed since it was launched last to reach PGARCH_RESTART_INTERVAL.
190 * Otherwise return false.
192 * This is a safety valve to protect against continuous respawn attempts if the
193 * archiver is dying immediately at launch. Note that since we will retry to
194 * launch the archiver from the postmaster main loop, we will get another
200 static time_t last_pgarch_start_time = 0;
201 time_t curtime = time(NULL);
204 * Return false and don't restart archiver if too soon since last archiver
207 if ((
unsigned int) (curtime - last_pgarch_start_time) <
211 last_pgarch_start_time = curtime;
216 /* Main entry point for archiver process */
220 Assert(startup_data_len == 0);
226 * Ignore all signals usually bound to some action in the postmaster,
227 * except for SIGHUP, SIGTERM, SIGUSR1, SIGUSR2, and SIGQUIT.
232 /* SIGQUIT handler was already set up by InitPostmasterChild */
238 /* Reset some signals that are accepted by postmaster but not here */
241 /* Unblock signals (they were blocked when the postmaster forked us) */
244 /* We shouldn't be launched unnecessarily. */
247 /* Arrange to clean up at archiver exit */
251 * Advertise our proc number so that backends can use our latch to wake us
252 * up while we're sleeping.
256 /* Create workspace for pgarch_readyXlog() */
260 /* Initialize our max-heap for prioritizing files to archive. */
264 /* Initialize our memory context. */
269 /* Load the archive_library. */
278 * Wake up the archiver
286 * We don't acquire ProcArrayLock here. It's actually fine because
287 * procLatch isn't ever freed, so we just can potentially set the wrong
288 * process' (or no process') latch. Even in that case the archiver will
289 * be relaunched shortly and will start archiving.
296 /* SIGUSR2 signal handler for archiver process */
300 /* set flag to do a final cycle and shut down afterwards */
308 * Main loop for archiver
316 * There shouldn't be anything for the archiver to do except to wait for a
317 * signal ... however, the archiver exists to protect our data, so it
318 * wakes up occasionally to allow itself to be proactive.
324 /* When we get SIGUSR2, we do one more archive cycle, then exit */
327 /* Check for barrier events and config update */
331 * If we've gotten SIGTERM, we normally just sit and do nothing until
332 * SIGUSR2 arrives. However, that means a random SIGTERM would
333 * disable archiving indefinitely, which doesn't seem like a good
334 * idea. If more than 60 seconds pass since SIGTERM, exit anyway, so
335 * that the postmaster can start a new archiver if needed.
339 time_t curtime = time(NULL);
348 /* Do what we're here for */
352 * Sleep until a signal is received, or until a poll is forced by
353 * PGARCH_AUTOWAKE_INTERVAL, or until postmaster dies.
355 if (!
time_to_stop)
/* Don't wait during last iteration */
362 WAIT_EVENT_ARCHIVER_MAIN);
368 * The archiver quits either when the postmaster dies (not expected)
369 * or after completing one more archiving cycle after receiving
376 * pgarch_ArchiverCopyLoop
378 * Archives all outstanding xlogs then returns
385 /* force directory scan in the first call to pgarch_readyXlog() */
389 * loop through all xlogs with archive_status of .ready and archive
390 * them...mostly we expect this to be a single file, though it is possible
391 * some backend will add files onto the list of those that need archiving
392 * while we are still copying earlier archives
397 int failures_orphan = 0;
401 struct stat stat_buf;
405 * Do not initiate any more archive commands after receiving
406 * SIGTERM, nor after the postmaster has died unexpectedly. The
407 * first condition is to try to keep from having init SIGKILL the
408 * command, and the second is to avoid conflicts with another
409 * archiver spawned by a newer postmaster.
415 * Check for barrier events and config update. This is so that
416 * we'll adopt a new setting for archive_command as soon as
417 * possible, even if there is a backlog of files to be archived.
421 /* Reset variables that might be set by the callback */
424 /* can't do anything if not configured ... */
429 (
errmsg(
"\"archive_mode\" enabled, yet archiving is not configured"),
436 * Since archive status files are not removed in a durable manner,
437 * a system crash could leave behind .ready files for WAL segments
438 * that have already been recycled or removed. In this case,
439 * simply remove the orphan status file and move on. unlink() is
440 * used here as even on subsequent crashes the same orphan files
441 * would get removed, so there is no need to worry about
445 if (
stat(pathname, &stat_buf) != 0 && errno == ENOENT)
450 if (unlink(xlogready) == 0)
453 (
errmsg(
"removed orphan archive status file \"%s\"",
456 /* leave loop and move to the next status file */
463 (
errmsg(
"removal of orphan archive status file \"%s\" failed too many times, will try again later",
466 /* give up cleanup of orphan status files */
470 /* wait a bit before retrying */
481 * Tell the cumulative stats system about the WAL file that we
482 * successfully archived
486 break;
/* out of inner retry loop */
491 * Tell the cumulative stats system about the WAL file that we
499 (
errmsg(
"archiving write-ahead log file \"%s\" failed too many times, will try again later",
501 return;
/* give up archiving for now */
503 pg_usleep(1000000L);
/* wait a bit before retrying */
512 * Invokes archive_file_cb to copy one archive file to wherever it should go
514 * Returns true if successful
519 sigjmp_buf local_sigjmp_buf;
527 /* Report archive activity in PS display */
528 snprintf(activitymsg,
sizeof(activitymsg),
"archiving %s", xlog);
534 * Since the archiver operates at the bottom of the exception stack,
535 * ERRORs turn into FATALs and cause the archiver process to restart.
536 * However, using ereport(ERROR, ...) when there are problems is easy to
537 * code and maintain. Therefore, we create our own exception handler to
538 * catch ERRORs and return false instead of restarting the archiver
539 * whenever there is a failure.
541 * We assume ERRORs from the archiving callback are the most common
542 * exceptions experienced by the archiver, so we opt to handle exceptions
543 * here instead of PgArchiverMain() to avoid reinitializing the archiver
544 * too frequently. We could instead add a sigsetjmp() block to
545 * PgArchiverMain() and use PG_TRY/PG_CATCH here, but the extra code to
546 * avoid the odd archiver restart doesn't seem worth it.
548 if (sigsetjmp(local_sigjmp_buf, 1) != 0)
550 /* Since not using PG_TRY, must reset error stack by hand */
553 /* Prevent interrupts while cleaning up */
556 /* Report the error to the server log. */
560 * Try to clean up anything the archive module left behind. We try to
561 * cover anything that an archive module could conceivably have left
562 * behind, but it is of course possible that modules could be doing
563 * unexpected things that require additional cleanup. Module authors
564 * should be sure to do any extra required cleanup in a PG_CATCH block
565 * within the archiving callback, and they are encouraged to notify
566 * the pgsql-hackers mailing list so that we can add it here.
578 * Return to the original memory context and clear ErrorContext for
584 /* Flush any leaked data */
587 /* Remove our exception handler */
590 /* Now we can allow interrupts again */
593 /* Report failure so that the archiver retries this file */
598 /* Enable our exception handler */
601 /* Archive the file! */
605 /* Remove our exception handler */
608 /* Reset our memory context and switch back to the original one */
614 snprintf(activitymsg,
sizeof(activitymsg),
"last was %s", xlog);
616 snprintf(activitymsg,
sizeof(activitymsg),
"failed on %s", xlog);
625 * Return name of the oldest xlog file that has not yet been archived.
626 * No notification is set that file archiving is now in progress, so
627 * this would need to be extended if multiple concurrent archival
628 * tasks were created. If a failure occurs, we will completely
629 * re-copy the file at the next available opportunity.
631 * It is important that we return the oldest, so that we archive xlogs
632 * in order that they were written, for two reasons:
633 * 1) to maintain the sequential chain of xlogs required for recovery
634 * 2) because the oldest ones will sooner become candidates for
635 * recycling at time of checkpoint
637 * NOTE: the "oldest" comparison will consider any .history file to be older
638 * than any other file except another .history file. Segments on a timeline
639 * with a smaller ID will be older than all segments on a timeline with a
640 * larger ID; the net result being that past timelines are given higher
641 * priority for archiving. This seems okay, or at least not obviously worth
652 * If a directory scan was requested, clear the stored file names and
659 * If we still have stored file names from the previous directory scan,
660 * try to return one of those. We check to make sure the status file is
661 * still present, as the archive_command for a previous file may have
662 * already marked it done.
674 if (
stat(status_file, &st) == 0)
676 strcpy(xlog, arch_file);
679 else if (errno != ENOENT)
682 errmsg(
"could not stat file \"%s\": %m", status_file)));
685 /* arch_heap is probably empty, but let's make sure */
689 * Open the archive status directory and read through the list of files
690 * with the .ready suffix, looking for the earliest files.
695 while ((rlde =
ReadDir(rldir, XLogArchiveStatusDir)) != NULL)
697 int basenamelen = (int) strlen(rlde->
d_name) - 6;
701 /* Ignore entries with unexpected number of characters */
706 /* Ignore entries with unexpected characters */
710 /* Ignore anything not suffixed with .ready */
711 if (strcmp(rlde->
d_name + basenamelen,
".ready") != 0)
714 /* Truncate off the .ready */
715 memcpy(basename, rlde->
d_name, basenamelen);
716 basename[basenamelen] =
'0円';
719 * Store the file in our max-heap if it has a high enough priority.
723 /* If the heap isn't full yet, quickly add it. */
725 strcpy(arch_file, basename);
728 /* If we just filled the heap, make it a valid one. */
736 * Remove the lowest priority file and add the current one to the
740 strcpy(arch_file, basename);
746 /* If no files were found, simply return. */
751 * If we didn't fill the heap, we didn't make it a valid one. Do that
758 * Fill arch_files array with the files to archive in ascending order of
765 /* Return the highest priority file. */
773 * ready_file_comparator
775 * Compares the archival priority of the given files to archive. If "a"
776 * has a higher priority than "b", a negative value will be returned. If
777 * "b" has a higher priority than "a", a positive value will be returned.
778 * If "a" and "b" have equivalent values, 0 will be returned.
788 /* Timeline history files always have the highest priority. */
789 if (a_history != b_history)
790 return a_history ? -1 : 1;
792 /* Priority is given to older files. */
793 return strcmp(a_str, b_str);
799 * When called, the next call to pgarch_readyXlog() will perform a
800 * directory scan. This is useful for ensuring that important files such
801 * as timeline history files are archived as quickly as possible.
812 * Emit notification that an xlog file has been successfully archived.
813 * We do this by renaming the status file from NNN.ready to NNN.done.
814 * Eventually, a checkpoint process will notice this and delete both the
815 * NNN.done file and the xlog file itself.
827 * To avoid extra overhead, we don't durably rename the .ready file to
828 * .done. Archive commands and libraries must gracefully handle attempts
829 * to re-archive files (e.g., if the server crashes just before this
830 * function is called), so it should be okay if the .ready file reappears
833 if (rename(rlogready, rlogdone) < 0)
836 errmsg(
"could not rename file \"%s\" to \"%s\": %m",
837 rlogready, rlogdone)));
844 * Exit-time cleanup handler
853 * Interrupt handler for WAL archiver process.
855 * This is called in the loops pgarch_MainLoop and pgarch_ArchiverCopyLoop.
856 * It checks for barrier events, config update and request for logging of
857 * memory contexts, but not shutdown request because how to handle
858 * shutdown request is different between those loops.
866 /* Perform logging of memory contexts of this process */
873 bool archiveLibChanged;
880 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
881 errmsg(
"both \"archive_command\" and \"archive_library\" set"),
882 errdetail(
"Only one of \"archive_command\", \"archive_library\" may be set.")));
887 if (archiveLibChanged)
890 * Ideally, we would simply unload the previous archive module and
891 * load the new one, but there is presently no mechanism for
892 * unloading a library (see the comment above
893 * internal_load_library()). To deal with this, we simply restart
894 * the archiver. The new archive module will be loaded when the
895 * new archiver process starts up. Note that this triggers the
896 * module's shutdown callback, if defined.
899 (
errmsg(
"restarting archiver process because value of "
900 "\"archive_library\" was changed")));
910 * Loads the archiving callbacks into our local ArchiveCallbacks.
919 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
920 errmsg(
"both \"archive_command\" and \"archive_library\" set"),
921 errdetail(
"Only one of \"archive_command\", \"archive_library\" may be set.")));
924 * If shell archiving is enabled, use our special initialization function.
925 * Otherwise, load the library and call its _PG_archive_module_init().
932 "_PG_archive_module_init",
false, NULL);
934 if (archive_init == NULL)
936 (
errmsg(
"archive modules have to define the symbol %s",
"_PG_archive_module_init")));
942 (
errmsg(
"archive modules must register an archive callback")));
952 * Call the shutdown callback of the loaded archive module, if defined.
void pgaio_error_cleanup(void)
const ArchiveModuleCallbacks *(* ArchiveModuleInit)(void)
static void pg_atomic_init_u32(volatile pg_atomic_uint32 *ptr, uint32 val)
static void pg_atomic_write_membarrier_u32(volatile pg_atomic_uint32 *ptr, uint32 val)
static uint32 pg_atomic_exchange_u32(volatile pg_atomic_uint32 *ptr, uint32 newval)
void AuxiliaryProcessMainCommon(void)
void binaryheap_build(binaryheap *heap)
void binaryheap_reset(binaryheap *heap)
bh_node_type binaryheap_first(binaryheap *heap)
void binaryheap_add(binaryheap *heap, bh_node_type d)
bh_node_type binaryheap_remove_first(binaryheap *heap)
void binaryheap_add_unordered(binaryheap *heap, bh_node_type d)
binaryheap * binaryheap_allocate(int capacity, binaryheap_comparator compare, void *arg)
#define binaryheap_size(h)
#define binaryheap_empty(h)
#define MemSet(start, val, len)
bool ConditionVariableCancelSleep(void)
void * load_external_function(const char *filename, const char *funcname, bool signalNotFound, void **filehandle)
void AtEOXact_HashTables(bool isCommit)
void EmitErrorReport(void)
int errdetail_internal(const char *fmt,...)
int errcode_for_file_access(void)
int errdetail(const char *fmt,...)
ErrorContextCallback * error_context_stack
void FlushErrorState(void)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
sigjmp_buf * PG_exception_stack
#define ereport(elevel,...)
void AtEOXact_Files(bool isCommit)
DIR * AllocateDir(const char *dirname)
struct dirent * ReadDir(DIR *dir, const char *dirname)
volatile sig_atomic_t LogMemoryContextPending
volatile sig_atomic_t ProcSignalBarrierPending
void ProcessConfigFile(GucContext context)
Assert(PointerIsAligned(start, uint64))
void SignalHandlerForShutdownRequest(SIGNAL_ARGS)
volatile sig_atomic_t ShutdownRequestPending
volatile sig_atomic_t ConfigReloadPending
void SignalHandlerForConfigReload(SIGNAL_ARGS)
void on_shmem_exit(pg_on_exit_callback function, Datum arg)
void before_shmem_exit(pg_on_exit_callback function, Datum arg)
void SetLatch(Latch *latch)
void ResetLatch(Latch *latch)
int WaitLatch(Latch *latch, int wakeEvents, long timeout, uint32 wait_event_info)
void LWLockReleaseAll(void)
void MemoryContextReset(MemoryContext context)
char * pstrdup(const char *in)
void pfree(void *pointer)
void * palloc0(Size size)
MemoryContext TopMemoryContext
void ProcessLogMemoryContextInterrupt(void)
#define AllocSetContextCreate
#define ALLOCSET_DEFAULT_SIZES
#define RESUME_INTERRUPTS()
#define HOLD_INTERRUPTS()
BackendType MyBackendType
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
static volatile sig_atomic_t time_to_stop
static bool pgarch_archiveXlog(char *xlog)
static void pgarch_die(int code, Datum arg)
#define PGARCH_RESTART_INTERVAL
bool PgArchCanRestart(void)
static bool pgarch_readyXlog(char *xlog)
static PgArchData * PgArch
char * arch_module_check_errdetail_string
static void pgarch_MainLoop(void)
#define NUM_ARCHIVE_RETRIES
struct PgArchData PgArchData
static void pgarch_waken_stop(SIGNAL_ARGS)
static volatile sig_atomic_t ready_to_stop
static struct arch_files_state * arch_files
char * XLogArchiveLibrary
Size PgArchShmemSize(void)
static void LoadArchiveLibrary(void)
static void pgarch_ArchiverCopyLoop(void)
static int ready_file_comparator(Datum a, Datum b, void *arg)
void PgArchiverMain(const void *startup_data, size_t startup_data_len)
#define NUM_FILES_PER_DIRECTORY_SCAN
void PgArchForceDirScan(void)
static void ProcessPgArchInterrupts(void)
static const ArchiveModuleCallbacks * ArchiveCallbacks
static ArchiveModuleState * archive_module_state
void PgArchShmemInit(void)
static void pgarch_call_module_shutdown_cb(int code, Datum arg)
static void pgarch_archiveDone(char *xlog)
#define NUM_ORPHAN_CLEANUP_RETRIES
static MemoryContext archive_context
#define PGARCH_AUTOWAKE_INTERVAL
static time_t last_sigterm_time
void pgstat_report_archiver(const char *xlog, bool failed)
#define PostmasterIsAlive()
static char * DatumGetCString(Datum X)
static Datum CStringGetDatum(const char *X)
#define INVALID_PROC_NUMBER
void ProcessProcSignalBarrier(void)
void procsignal_sigusr1_handler(SIGNAL_ARGS)
static void set_ps_display(const char *activity)
void ReleaseAuxProcessResources(bool isCommit)
const ArchiveModuleCallbacks * shell_archive_init(void)
Size add_size(Size s1, Size s2)
void * ShmemInitStruct(const char *name, Size size, bool *foundPtr)
void pg_usleep(long microsec)
ArchiveFileCB archive_file_cb
ArchiveShutdownCB shutdown_cb
ArchiveCheckConfiguredCB check_configured_cb
ArchiveStartupCB startup_cb
pg_atomic_uint32 force_dir_scan
char arch_filenames[NUM_FILES_PER_DIRECTORY_SCAN][MAX_XFN_CHARS+1]
char * arch_files[NUM_FILES_PER_DIRECTORY_SCAN]
void disable_all_timeouts(bool keep_indicators)
static void pgstat_report_wait_end(void)
#define WL_POSTMASTER_DEATH
char * XLogArchiveCommand
#define XLogArchivingActive()
static bool IsTLHistoryFileName(const char *fname)
static void StatusFilePath(char *path, const char *xlog, const char *suffix)