PostgreSQL Source Code git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
pgarch.c File Reference
#include "postgres.h"
#include <time.h>
#include <sys/stat.h>
#include <unistd.h>
#include "access/xlog.h"
#include "access/xlog_internal.h"
#include "archive/archive_module.h"
#include "archive/shell_archive.h"
#include "lib/binaryheap.h"
#include "libpq/pqsignal.h"
#include "pgstat.h"
#include "postmaster/auxprocess.h"
#include "postmaster/interrupt.h"
#include "postmaster/pgarch.h"
#include "storage/condition_variable.h"
#include "storage/aio_subsys.h"
#include "storage/fd.h"
#include "storage/ipc.h"
#include "storage/latch.h"
#include "storage/pmsignal.h"
#include "storage/proc.h"
#include "storage/procsignal.h"
#include "storage/shmem.h"
#include "utils/guc.h"
#include "utils/memutils.h"
#include "utils/ps_status.h"
#include "utils/resowner.h"
#include "utils/timeout.h"
Include dependency graph for pgarch.c:

Go to the source code of this file.

Data Structures

struct  PgArchData
 
struct  arch_files_state
 

Macros

#define PGARCH_AUTOWAKE_INTERVAL
 
#define PGARCH_RESTART_INTERVAL
 
#define NUM_ARCHIVE_RETRIES   3
 
#define NUM_ORPHAN_CLEANUP_RETRIES   3
 
#define NUM_FILES_PER_DIRECTORY_SCAN   64
 

Typedefs

typedef struct PgArchData PgArchData
 

Functions

static void pgarch_waken_stop (SIGNAL_ARGS)
 
static void pgarch_MainLoop (void)
 
static void pgarch_ArchiverCopyLoop (void)
 
static bool pgarch_archiveXlog (char *xlog)
 
static bool pgarch_readyXlog (char *xlog)
 
static void pgarch_archiveDone (char *xlog)
 
static void pgarch_die (int code, Datum arg)
 
static void ProcessPgArchInterrupts (void)
 
static int ready_file_comparator (Datum a, Datum b, void *arg)
 
static void LoadArchiveLibrary (void)
 
static void pgarch_call_module_shutdown_cb (int code, Datum arg)
 
Size PgArchShmemSize (void)
 
void PgArchShmemInit (void)
 
bool PgArchCanRestart (void)
 
void PgArchiverMain (const void *startup_data, size_t startup_data_len)
 
void PgArchWakeup (void)
 
void PgArchForceDirScan (void)
 

Variables

char * XLogArchiveLibrary = ""
 
char * arch_module_check_errdetail_string
 
static time_t last_sigterm_time = 0
 
static PgArchDataPgArch = NULL
 
static const ArchiveModuleCallbacksArchiveCallbacks
 
static ArchiveModuleStatearchive_module_state
 
static MemoryContext archive_context
 
static struct arch_files_statearch_files = NULL
 
static volatile sig_atomic_t ready_to_stop = false
 

Macro Definition Documentation

◆ NUM_ARCHIVE_RETRIES

#define NUM_ARCHIVE_RETRIES   3

Definition at line 69 of file pgarch.c.

◆ NUM_FILES_PER_DIRECTORY_SCAN

#define NUM_FILES_PER_DIRECTORY_SCAN   64

Definition at line 80 of file pgarch.c.

◆ NUM_ORPHAN_CLEANUP_RETRIES

#define NUM_ORPHAN_CLEANUP_RETRIES   3

Definition at line 75 of file pgarch.c.

◆ PGARCH_AUTOWAKE_INTERVAL

#define PGARCH_AUTOWAKE_INTERVAL
Value:
60 /* How often to force a poll of the
* archive status directory; in seconds. */

Definition at line 62 of file pgarch.c.

◆ PGARCH_RESTART_INTERVAL

#define PGARCH_RESTART_INTERVAL
Value:
10 /* How often to attempt to restart a
* failed archiver; in seconds. */

Definition at line 63 of file pgarch.c.

Typedef Documentation

◆ PgArchData

typedef struct PgArchData PgArchData

Function Documentation

◆ LoadArchiveLibrary()

static void LoadArchiveLibrary ( void  )
static

Definition at line 915 of file pgarch.c.

918{
919 ArchiveModuleInit archive_init;
920
921 if (XLogArchiveLibrary[0] != '\0' && XLogArchiveCommand[0] != '\0')
923 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
924 errmsg("both \"archive_command\" and \"archive_library\" set"),
925 errdetail("Only one of \"archive_command\", \"archive_library\" may be set.")));
926
927 /*
928 * If shell archiving is enabled, use our special initialization function.
929 * Otherwise, load the library and call its _PG_archive_module_init().
930 */
931 if (XLogArchiveLibrary[0] == '\0')
932 archive_init = shell_archive_init;
933 else
934 archive_init = (ArchiveModuleInit)
936 "_PG_archive_module_init", false, NULL);
937
938 if (archive_init == NULL)
940 (errmsg("archive modules have to define the symbol %s", "_PG_archive_module_init")));
941
942 ArchiveCallbacks = (*archive_init) ();
943
946 (errmsg("archive modules must register an archive callback")));
947
949 if (ArchiveCallbacks->startup_cb != NULL)
951
const ArchiveModuleCallbacks *(* ArchiveModuleInit)(void)
void * load_external_function(const char *filename, const char *funcname, bool signalNotFound, void **filehandle)
Definition: dfmgr.c:95
int errdetail(const char *fmt,...)
Definition: elog.c:1204
int errcode(int sqlerrcode)
Definition: elog.c:854
int errmsg(const char *fmt,...)
Definition: elog.c:1071
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:149
void * palloc0(Size size)
Definition: mcxt.c:1970
char * XLogArchiveLibrary
Definition: pgarch.c:93
static const ArchiveModuleCallbacks * ArchiveCallbacks
Definition: pgarch.c:103
static ArchiveModuleState * archive_module_state
Definition: pgarch.c:104
const ArchiveModuleCallbacks * shell_archive_init(void)
Definition: shell_archive.c:40
ArchiveFileCB archive_file_cb
ArchiveStartupCB startup_cb
char * XLogArchiveCommand
Definition: xlog.c:120

References ArchiveModuleCallbacks::archive_file_cb, archive_module_state, ArchiveCallbacks, before_shmem_exit(), ereport, errcode(), errdetail(), errmsg(), ERROR, load_external_function(), palloc0(), pgarch_call_module_shutdown_cb(), shell_archive_init(), ArchiveModuleCallbacks::startup_cb, XLogArchiveCommand, and XLogArchiveLibrary.

Referenced by PgArchiverMain().

◆ pgarch_archiveDone()

static void pgarch_archiveDone ( char *  xlog)
static

Definition at line 816 of file pgarch.c.

819{
820 char rlogready[MAXPGPATH];
821 char rlogdone[MAXPGPATH];
822
823 StatusFilePath(rlogready, xlog, ".ready");
824 StatusFilePath(rlogdone, xlog, ".done");
825
826 /*
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
831 * after a crash.
832 */
833 if (rename(rlogready, rlogdone) < 0)
836 errmsg("could not rename file \"%s\" to \"%s\": %m",
int errcode_for_file_access(void)
Definition: elog.c:877
#define WARNING
Definition: elog.h:36
#define MAXPGPATH
static void StatusFilePath(char *path, const char *xlog, const char *suffix)

References ereport, errcode_for_file_access(), errmsg(), MAXPGPATH, StatusFilePath(), and WARNING.

Referenced by pgarch_ArchiverCopyLoop().

◆ pgarch_ArchiverCopyLoop()

static void pgarch_ArchiverCopyLoop ( void  )
static

Definition at line 379 of file pgarch.c.

382{
383 char xlog[MAX_XFN_CHARS + 1];
384
385 /* force directory scan in the first call to pgarch_readyXlog() */
387
388 /*
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
393 */
394 while (pgarch_readyXlog(xlog))
395 {
396 int failures = 0;
397 int failures_orphan = 0;
398
399 for (;;)
400 {
401 struct stat stat_buf;
402 char pathname[MAXPGPATH];
403
404 /*
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.
410 */
412 return;
413
414 /*
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.
418 */
420
421 /* Reset variables that might be set by the callback */
423
424 /* can't do anything if not configured ... */
427 {
429 (errmsg("\"archive_mode\" enabled, yet archiving is not configured"),
432 return;
433 }
434
435 /*
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
442 * durability.
443 */
444 snprintf(pathname, MAXPGPATH, XLOGDIR "/%s", xlog);
445 if (stat(pathname, &stat_buf) != 0 && errno == ENOENT)
446 {
447 char xlogready[MAXPGPATH];
448
449 StatusFilePath(xlogready, xlog, ".ready");
450 if (unlink(xlogready) == 0)
451 {
453 (errmsg("removed orphan archive status file \"%s\"",
454 xlogready)));
455
456 /* leave loop and move to the next status file */
457 break;
458 }
459
460 if (++failures_orphan >= NUM_ORPHAN_CLEANUP_RETRIES)
461 {
463 (errmsg("removal of orphan archive status file \"%s\" failed too many times, will try again later",
464 xlogready)));
465
466 /* give up cleanup of orphan status files */
467 return;
468 }
469
470 /* wait a bit before retrying */
471 pg_usleep(1000000L);
472 continue;
473 }
474
475 if (pgarch_archiveXlog(xlog))
476 {
477 /* successful */
478 pgarch_archiveDone(xlog);
479
480 /*
481 * Tell the cumulative stats system about the WAL file that we
482 * successfully archived
483 */
484 pgstat_report_archiver(xlog, false);
485
486 break; /* out of inner retry loop */
487 }
488 else
489 {
490 /*
491 * Tell the cumulative stats system about the WAL file that we
492 * failed to archive
493 */
494 pgstat_report_archiver(xlog, true);
495
496 if (++failures >= NUM_ARCHIVE_RETRIES)
497 {
499 (errmsg("archiving write-ahead log file \"%s\" failed too many times, will try again later",
500 xlog)));
501 return; /* give up archiving for now */
502 }
503 pg_usleep(1000000L); /* wait a bit before retrying */
504 }
505 }
int errdetail_internal(const char *fmt,...)
Definition: elog.c:1231
volatile sig_atomic_t ShutdownRequestPending
Definition: interrupt.c:28
static bool pgarch_archiveXlog(char *xlog)
Definition: pgarch.c:515
static bool pgarch_readyXlog(char *xlog)
Definition: pgarch.c:643
char * arch_module_check_errdetail_string
Definition: pgarch.c:94
#define NUM_ARCHIVE_RETRIES
Definition: pgarch.c:69
static struct arch_files_state * arch_files
Definition: pgarch.c:131
static void ProcessPgArchInterrupts(void)
Definition: pgarch.c:859
static void pgarch_archiveDone(char *xlog)
Definition: pgarch.c:816
#define NUM_ORPHAN_CLEANUP_RETRIES
Definition: pgarch.c:75
#define MAX_XFN_CHARS
Definition: pgarch.h:26
void pgstat_report_archiver(const char *xlog, bool failed)
#define PostmasterIsAlive()
Definition: pmsignal.h:107
#define snprintf
Definition: port.h:239
void pg_usleep(long microsec)
Definition: signal.c:53
ArchiveCheckConfiguredCB check_configured_cb
int arch_files_size
Definition: pgarch.c:125
#define stat
Definition: win32_port.h:274
#define XLOGDIR

References arch_files, arch_files_state::arch_files_size, arch_module_check_errdetail_string, archive_module_state, ArchiveCallbacks, ArchiveModuleCallbacks::check_configured_cb, ereport, errdetail_internal(), errmsg(), MAX_XFN_CHARS, MAXPGPATH, NUM_ARCHIVE_RETRIES, NUM_ORPHAN_CLEANUP_RETRIES, pg_usleep(), pgarch_archiveDone(), pgarch_archiveXlog(), pgarch_readyXlog(), pgstat_report_archiver(), PostmasterIsAlive, ProcessPgArchInterrupts(), ShutdownRequestPending, snprintf, stat, StatusFilePath(), WARNING, and XLOGDIR.

Referenced by pgarch_MainLoop().

◆ pgarch_archiveXlog()

static bool pgarch_archiveXlog ( char *  xlog)
static

Definition at line 515 of file pgarch.c.

518{
519 sigjmp_buf local_sigjmp_buf;
520 MemoryContext oldcontext;
521 char pathname[MAXPGPATH];
522 char activitymsg[MAXFNAMELEN + 16];
523 bool ret;
524
525 snprintf(pathname, MAXPGPATH, XLOGDIR "/%s", xlog);
526
527 /* Report archive activity in PS display */
528 snprintf(activitymsg, sizeof(activitymsg), "archiving %s", xlog);
529 set_ps_display(activitymsg);
530
532
533 /*
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.
540 *
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.
547 */
548 if (sigsetjmp(local_sigjmp_buf, 1) != 0)
549 {
550 /* Since not using PG_TRY, must reset error stack by hand */
551 error_context_stack = NULL;
552
553 /* Prevent interrupts while cleaning up */
555
556 /* Report the error to the server log. */
558
559 /*
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.
567 */
574 AtEOXact_Files(false);
575 AtEOXact_HashTables(false);
576
577 /*
578 * Return to the original memory context and clear ErrorContext for
579 * next time.
580 */
581 MemoryContextSwitchTo(oldcontext);
583
584 /* Flush any leaked data */
586
587 /* Remove our exception handler */
588 PG_exception_stack = NULL;
589
590 /* Now we can allow interrupts again */
592
593 /* Report failure so that the archiver retries this file */
594 ret = false;
595 }
596 else
597 {
598 /* Enable our exception handler */
599 PG_exception_stack = &local_sigjmp_buf;
600
601 /* Archive the file! */
603 xlog, pathname);
604
605 /* Remove our exception handler */
606 PG_exception_stack = NULL;
607
608 /* Reset our memory context and switch back to the original one */
609 MemoryContextSwitchTo(oldcontext);
611 }
612
613 if (ret)
614 snprintf(activitymsg, sizeof(activitymsg), "last was %s", xlog);
615 else
616 snprintf(activitymsg, sizeof(activitymsg), "failed on %s", xlog);
617 set_ps_display(activitymsg);
618
void pgaio_error_cleanup(void)
Definition: aio.c:1062
bool ConditionVariableCancelSleep(void)
void AtEOXact_HashTables(bool isCommit)
Definition: dynahash.c:1912
void EmitErrorReport(void)
Definition: elog.c:1709
ErrorContextCallback * error_context_stack
Definition: elog.c:95
void FlushErrorState(void)
Definition: elog.c:1889
sigjmp_buf * PG_exception_stack
Definition: elog.c:97
void AtEOXact_Files(bool isCommit)
Definition: fd.c:3229
void LWLockReleaseAll(void)
Definition: lwlock.c:1953
void MemoryContextReset(MemoryContext context)
Definition: mcxt.c:414
#define RESUME_INTERRUPTS()
Definition: miscadmin.h:136
#define HOLD_INTERRUPTS()
Definition: miscadmin.h:134
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:124
static MemoryContext archive_context
Definition: pgarch.c:105
static void set_ps_display(const char *activity)
Definition: ps_status.h:40
void ReleaseAuxProcessResources(bool isCommit)
Definition: resowner.c:1019
void disable_all_timeouts(bool keep_indicators)
Definition: timeout.c:751
static void pgstat_report_wait_end(void)
Definition: wait_event.h:101
#define MAXFNAMELEN

References archive_context, ArchiveModuleCallbacks::archive_file_cb, archive_module_state, ArchiveCallbacks, AtEOXact_Files(), AtEOXact_HashTables(), ConditionVariableCancelSleep(), disable_all_timeouts(), EmitErrorReport(), error_context_stack, FlushErrorState(), HOLD_INTERRUPTS, LWLockReleaseAll(), MAXFNAMELEN, MAXPGPATH, MemoryContextReset(), MemoryContextSwitchTo(), PG_exception_stack, pgaio_error_cleanup(), pgstat_report_wait_end(), ReleaseAuxProcessResources(), RESUME_INTERRUPTS, set_ps_display(), snprintf, and XLOGDIR.

Referenced by pgarch_ArchiverCopyLoop().

◆ pgarch_call_module_shutdown_cb()

static void pgarch_call_module_shutdown_cb ( int  code,
Datum  arg 
)
static

Definition at line 957 of file pgarch.c.

960{
961 if (ArchiveCallbacks->shutdown_cb != NULL)
ArchiveShutdownCB shutdown_cb

References archive_module_state, ArchiveCallbacks, and ArchiveModuleCallbacks::shutdown_cb.

Referenced by LoadArchiveLibrary().

◆ pgarch_die()

static void pgarch_die ( int  code,
Datum  arg 
)
static

Definition at line 845 of file pgarch.c.

848{

References INVALID_PROC_NUMBER, PgArch, and PgArchData::pgprocno.

Referenced by PgArchiverMain().

◆ pgarch_MainLoop()

static void pgarch_MainLoop ( void  )
static

Definition at line 309 of file pgarch.c.

312{
313 bool time_to_stop;
314
315 /*
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.
319 */
320 do
321 {
323
324 /* When we get SIGUSR2, we do one more archive cycle, then exit */
326
327 /* Check for barrier events and config update */
329
330 /*
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.
336 */
338 {
339 time_t curtime = time(NULL);
340
341 if (last_sigterm_time == 0)
342 last_sigterm_time = curtime;
343 else if ((unsigned int) (curtime - last_sigterm_time) >=
344 (unsigned int) 60)
345 break;
346 }
347
348 /* Do what we're here for */
350
351 /*
352 * Sleep until a signal is received, or until a poll is forced by
353 * PGARCH_AUTOWAKE_INTERVAL, or until postmaster dies.
354 */
355 if (!time_to_stop) /* Don't wait during last iteration */
356 {
357 int rc;
358
359 rc = WaitLatch(MyLatch,
362 WAIT_EVENT_ARCHIVER_MAIN);
363 if (rc & WL_POSTMASTER_DEATH)
364 time_to_stop = true;
365 }
366
367 /*
368 * The archiver quits either when the postmaster dies (not expected)
369 * or after completing one more archiving cycle after receiving
370 * SIGUSR2.
371 */
struct Latch * MyLatch
Definition: globals.c:64
void ResetLatch(Latch *latch)
Definition: latch.c:372
int WaitLatch(Latch *latch, int wakeEvents, long timeout, uint32 wait_event_info)
Definition: latch.c:172
static volatile sig_atomic_t time_to_stop
Definition: pg_receivewal.c:48
static volatile sig_atomic_t ready_to_stop
Definition: pgarch.c:136
static void pgarch_ArchiverCopyLoop(void)
Definition: pgarch.c:379
#define PGARCH_AUTOWAKE_INTERVAL
Definition: pgarch.c:62
static time_t last_sigterm_time
Definition: pgarch.c:101
#define WL_TIMEOUT
Definition: waiteventset.h:37
#define WL_LATCH_SET
Definition: waiteventset.h:34
#define WL_POSTMASTER_DEATH
Definition: waiteventset.h:38

References last_sigterm_time, MyLatch, pgarch_ArchiverCopyLoop(), PGARCH_AUTOWAKE_INTERVAL, ProcessPgArchInterrupts(), ready_to_stop, ResetLatch(), ShutdownRequestPending, time_to_stop, WaitLatch(), WL_LATCH_SET, WL_POSTMASTER_DEATH, and WL_TIMEOUT.

Referenced by PgArchiverMain().

◆ pgarch_readyXlog()

static bool pgarch_readyXlog ( char *  xlog)
static

Definition at line 643 of file pgarch.c.

646{
647 char XLogArchiveStatusDir[MAXPGPATH];
648 DIR *rldir;
649 struct dirent *rlde;
650
651 /*
652 * If a directory scan was requested, clear the stored file names and
653 * proceed.
654 */
657
658 /*
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.
663 */
664 while (arch_files->arch_files_size > 0)
665 {
666 struct stat st;
667 char status_file[MAXPGPATH];
668 char *arch_file;
669
672 StatusFilePath(status_file, arch_file, ".ready");
673
674 if (stat(status_file, &st) == 0)
675 {
676 strcpy(xlog, arch_file);
677 return true;
678 }
679 else if (errno != ENOENT)
682 errmsg("could not stat file \"%s\": %m", status_file)));
683 }
684
685 /* arch_heap is probably empty, but let's make sure */
687
688 /*
689 * Open the archive status directory and read through the list of files
690 * with the .ready suffix, looking for the earliest files.
691 */
692 snprintf(XLogArchiveStatusDir, MAXPGPATH, XLOGDIR "/archive_status");
693 rldir = AllocateDir(XLogArchiveStatusDir);
694
695 while ((rlde = ReadDir(rldir, XLogArchiveStatusDir)) != NULL)
696 {
697 int basenamelen = (int) strlen(rlde->d_name) - 6;
698 char basename[MAX_XFN_CHARS + 1];
699 char *arch_file;
700
701 /* Ignore entries with unexpected number of characters */
702 if (basenamelen < MIN_XFN_CHARS ||
703 basenamelen > MAX_XFN_CHARS)
704 continue;
705
706 /* Ignore entries with unexpected characters */
707 if (strspn(rlde->d_name, VALID_XFN_CHARS) < basenamelen)
708 continue;
709
710 /* Ignore anything not suffixed with .ready */
711 if (strcmp(rlde->d_name + basenamelen, ".ready") != 0)
712 continue;
713
714 /* Truncate off the .ready */
715 memcpy(basename, rlde->d_name, basenamelen);
716 basename[basenamelen] = '\0';
717
718 /*
719 * Store the file in our max-heap if it has a high enough priority.
720 */
722 {
723 /* If the heap isn't full yet, quickly add it. */
725 strcpy(arch_file, basename);
727
728 /* If we just filled the heap, make it a valid one. */
731 }
733 CStringGetDatum(basename), NULL) > 0)
734 {
735 /*
736 * Remove the lowest priority file and add the current one to the
737 * heap.
738 */
740 strcpy(arch_file, basename);
742 }
743 }
744 FreeDir(rldir);
745
746 /* If no files were found, simply return. */
747 if (arch_files->arch_heap->bh_size == 0)
748 return false;
749
750 /*
751 * If we didn't fill the heap, we didn't make it a valid one. Do that
752 * now.
753 */
756
757 /*
758 * Fill arch_files array with the files to archive in ascending order of
759 * priority.
760 */
762 for (int i = 0; i < arch_files->arch_files_size; i++)
764
765 /* Return the highest priority file. */
768
static uint32 pg_atomic_exchange_u32(volatile pg_atomic_uint32 *ptr, uint32 newval)
Definition: atomics.h:330
void binaryheap_build(binaryheap *heap)
Definition: binaryheap.c:138
void binaryheap_reset(binaryheap *heap)
Definition: binaryheap.c:63
bh_node_type binaryheap_first(binaryheap *heap)
Definition: binaryheap.c:177
void binaryheap_add(binaryheap *heap, bh_node_type d)
Definition: binaryheap.c:154
bh_node_type binaryheap_remove_first(binaryheap *heap)
Definition: binaryheap.c:192
void binaryheap_add_unordered(binaryheap *heap, bh_node_type d)
Definition: binaryheap.c:116
int FreeDir(DIR *dir)
Definition: fd.c:3025
DIR * AllocateDir(const char *dirname)
Definition: fd.c:2907
struct dirent * ReadDir(DIR *dir, const char *dirname)
Definition: fd.c:2973
int i
Definition: isn.c:77
static PgArchData * PgArch
Definition: pgarch.c:102
static int ready_file_comparator(Datum a, Datum b, void *arg)
Definition: pgarch.c:779
#define NUM_FILES_PER_DIRECTORY_SCAN
Definition: pgarch.c:80
#define MIN_XFN_CHARS
Definition: pgarch.h:25
#define VALID_XFN_CHARS
Definition: pgarch.h:27
static char * DatumGetCString(Datum X)
Definition: postgres.h:340
static Datum CStringGetDatum(const char *X)
Definition: postgres.h:355
Definition: dirent.c:26
pg_atomic_uint32 force_dir_scan
Definition: pgarch.c:90
char arch_filenames[NUM_FILES_PER_DIRECTORY_SCAN][MAX_XFN_CHARS+1]
Definition: pgarch.c:128
char * arch_files[NUM_FILES_PER_DIRECTORY_SCAN]
Definition: pgarch.c:126
binaryheap * arch_heap
Definition: pgarch.c:124
int bh_size
Definition: binaryheap.h:44
Definition: dirent.h:10
char d_name[MAX_PATH]
Definition: dirent.h:15

References AllocateDir(), arch_files_state::arch_filenames, arch_files_state::arch_files, arch_files, arch_files_state::arch_files_size, arch_files_state::arch_heap, binaryheap::bh_size, binaryheap_add(), binaryheap_add_unordered(), binaryheap_build(), binaryheap_first(), binaryheap_remove_first(), binaryheap_reset(), CStringGetDatum(), dirent::d_name, DatumGetCString(), ereport, errcode_for_file_access(), errmsg(), ERROR, PgArchData::force_dir_scan, FreeDir(), i, MAX_XFN_CHARS, MAXPGPATH, MIN_XFN_CHARS, NUM_FILES_PER_DIRECTORY_SCAN, pg_atomic_exchange_u32(), PgArch, ReadDir(), ready_file_comparator(), snprintf, stat, StatusFilePath(), VALID_XFN_CHARS, and XLOGDIR.

Referenced by pgarch_ArchiverCopyLoop().

◆ pgarch_waken_stop()

static void pgarch_waken_stop ( SIGNAL_ARGS  )
static

Definition at line 296 of file pgarch.c.

299{
300 /* set flag to do a final cycle and shut down afterwards */
301 ready_to_stop = true;

References MyLatch, ready_to_stop, and SetLatch().

Referenced by PgArchiverMain().

◆ PgArchCanRestart()

bool PgArchCanRestart ( void  )

Definition at line 196 of file pgarch.c.

199{
200 static time_t last_pgarch_start_time = 0;
201 time_t curtime = time(NULL);
202
203 /*
204 * Return false and don't restart archiver if too soon since last archiver
205 * start.
206 */
207 if ((unsigned int) (curtime - last_pgarch_start_time) <
208 (unsigned int) PGARCH_RESTART_INTERVAL)
209 return false;
210
211 last_pgarch_start_time = curtime;
#define PGARCH_RESTART_INTERVAL
Definition: pgarch.c:63

References PGARCH_RESTART_INTERVAL.

Referenced by LaunchMissingBackgroundProcesses().

◆ PgArchForceDirScan()

void PgArchForceDirScan ( void  )

Definition at line 802 of file pgarch.c.

805{

References PgArchData::force_dir_scan, pg_atomic_write_membarrier_u32(), and PgArch.

Referenced by XLogArchiveNotify().

◆ PgArchiverMain()

void PgArchiverMain ( const void *  startup_data,
size_t  startup_data_len 
)

Definition at line 216 of file pgarch.c.

219{
220 Assert(startup_data_len == 0);
221
224
225 /*
226 * Ignore all signals usually bound to some action in the postmaster,
227 * except for SIGHUP, SIGTERM, SIGUSR1, SIGUSR2, and SIGQUIT.
228 */
230 pqsignal(SIGINT, SIG_IGN);
232 /* SIGQUIT handler was already set up by InitPostmasterChild */
233 pqsignal(SIGALRM, SIG_IGN);
234 pqsignal(SIGPIPE, SIG_IGN);
237
238 /* Reset some signals that are accepted by postmaster but not here */
239 pqsignal(SIGCHLD, SIG_DFL);
240
241 /* Unblock signals (they were blocked when the postmaster forked us) */
242 sigprocmask(SIG_SETMASK, &UnBlockSig, NULL);
243
244 /* We shouldn't be launched unnecessarily. */
246
247 /* Arrange to clean up at archiver exit */
249
250 /*
251 * Advertise our proc number so that backends can use our latch to wake us
252 * up while we're sleeping.
253 */
255
256 /* Create workspace for pgarch_readyXlog() */
257 arch_files = palloc(sizeof(struct arch_files_state));
259
260 /* Initialize our max-heap for prioritizing files to archive. */
263
264 /* Initialize our memory context. */
266 "archiver",
268
269 /* Load the archive_library. */
271
273
void AuxiliaryProcessMainCommon(void)
Definition: auxprocess.c:39
sigset_t UnBlockSig
Definition: pqsignal.c:22
binaryheap * binaryheap_allocate(int capacity, binaryheap_comparator compare, void *arg)
Definition: binaryheap.c:39
ProcNumber MyProcNumber
Definition: globals.c:91
Assert(PointerIsAligned(start, uint64))
void SignalHandlerForShutdownRequest(SIGNAL_ARGS)
Definition: interrupt.c:109
void SignalHandlerForConfigReload(SIGNAL_ARGS)
Definition: interrupt.c:65
void on_shmem_exit(pg_on_exit_callback function, Datum arg)
Definition: ipc.c:365
MemoryContext TopMemoryContext
Definition: mcxt.c:165
void * palloc(Size size)
Definition: mcxt.c:1940
#define AllocSetContextCreate
Definition: memutils.h:149
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:180
@ B_ARCHIVER
Definition: miscadmin.h:361
BackendType MyBackendType
Definition: miscinit.c:64
static void pgarch_die(int code, Datum arg)
Definition: pgarch.c:845
static void pgarch_MainLoop(void)
Definition: pgarch.c:309
static void pgarch_waken_stop(SIGNAL_ARGS)
Definition: pgarch.c:296
static void LoadArchiveLibrary(void)
Definition: pgarch.c:915
#define pqsignal
Definition: port.h:531
void procsignal_sigusr1_handler(SIGNAL_ARGS)
Definition: procsignal.c:673
int pgprocno
Definition: pgarch.c:85
#define SIGCHLD
Definition: win32_port.h:168
#define SIGHUP
Definition: win32_port.h:158
#define SIGPIPE
Definition: win32_port.h:163
#define SIGUSR1
Definition: win32_port.h:170
#define SIGALRM
Definition: win32_port.h:164
#define SIGUSR2
Definition: win32_port.h:171
#define XLogArchivingActive()
Definition: xlog.h:99

References ALLOCSET_DEFAULT_SIZES, AllocSetContextCreate, arch_files, arch_files_state::arch_files_size, arch_files_state::arch_heap, archive_context, Assert(), AuxiliaryProcessMainCommon(), B_ARCHIVER, binaryheap_allocate(), LoadArchiveLibrary(), MyBackendType, MyProcNumber, NUM_FILES_PER_DIRECTORY_SCAN, on_shmem_exit(), palloc(), PgArch, pgarch_die(), pgarch_MainLoop(), pgarch_waken_stop(), PgArchData::pgprocno, pqsignal, proc_exit(), procsignal_sigusr1_handler(), ready_file_comparator(), SIGALRM, SIGCHLD, SIGHUP, SignalHandlerForConfigReload(), SignalHandlerForShutdownRequest(), SIGPIPE, SIGUSR1, SIGUSR2, TopMemoryContext, UnBlockSig, and XLogArchivingActive.

◆ PgArchShmemInit()

void PgArchShmemInit ( void  )

Definition at line 167 of file pgarch.c.

170{
171 bool found;
172
173 PgArch = (PgArchData *)
174 ShmemInitStruct("Archiver Data", PgArchShmemSize(), &found);
175
176 if (!found)
177 {
178 /* First time through, so initialize */
static void pg_atomic_init_u32(volatile pg_atomic_uint32 *ptr, uint32 val)
Definition: atomics.h:221
#define MemSet(start, val, len)
Definition: c.h:991
Size PgArchShmemSize(void)
Definition: pgarch.c:156
#define INVALID_PROC_NUMBER
Definition: procnumber.h:26
void * ShmemInitStruct(const char *name, Size size, bool *foundPtr)
Definition: shmem.c:387

References PgArchData::force_dir_scan, INVALID_PROC_NUMBER, MemSet, pg_atomic_init_u32(), PgArch, PgArchShmemSize(), PgArchData::pgprocno, and ShmemInitStruct().

Referenced by CreateOrAttachShmemStructs().

◆ PgArchShmemSize()

Size PgArchShmemSize ( void  )

Definition at line 156 of file pgarch.c.

159{
160 Size size = 0;
161
162 size = add_size(size, sizeof(PgArchData));
163
size_t Size
Definition: c.h:576
Size add_size(Size s1, Size s2)
Definition: shmem.c:493

References add_size().

Referenced by CalculateShmemSize(), and PgArchShmemInit().

◆ PgArchWakeup()

void PgArchWakeup ( void  )

Definition at line 279 of file pgarch.c.

282{
283 int arch_pgprocno = PgArch->pgprocno;
284
285 /*
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.
290 */
291 if (arch_pgprocno != INVALID_PROC_NUMBER)

References PROC_HDR::allProcs, INVALID_PROC_NUMBER, PgArch, PgArchData::pgprocno, ProcGlobal, PGPROC::procLatch, and SetLatch().

Referenced by XLogArchiveNotify().

◆ ProcessPgArchInterrupts()

static void ProcessPgArchInterrupts ( void  )
static

Definition at line 859 of file pgarch.c.

862{
865
866 /* Perform logging of memory contexts of this process */
869
870 /* Publish memory contexts of this process */
873
875 {
876 char *archiveLib = pstrdup(XLogArchiveLibrary);
877 bool archiveLibChanged;
878
879 ConfigReloadPending = false;
881
882 if (XLogArchiveLibrary[0] != '\0' && XLogArchiveCommand[0] != '\0')
884 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
885 errmsg("both \"archive_command\" and \"archive_library\" set"),
886 errdetail("Only one of \"archive_command\", \"archive_library\" may be set.")));
887
888 archiveLibChanged = strcmp(XLogArchiveLibrary, archiveLib) != 0;
889 pfree(archiveLib);
890
891 if (archiveLibChanged)
892 {
893 /*
894 * Ideally, we would simply unload the previous archive module and
895 * load the new one, but there is presently no mechanism for
896 * unloading a library (see the comment above
897 * internal_load_library()). To deal with this, we simply restart
898 * the archiver. The new archive module will be loaded when the
899 * new archiver process starts up. Note that this triggers the
900 * module's shutdown callback, if defined.
901 */
902 ereport(LOG,
903 (errmsg("restarting archiver process because value of "
904 "\"archive_library\" was changed")));
905
906 proc_exit(0);
907 }
#define LOG
Definition: elog.h:31
volatile sig_atomic_t LogMemoryContextPending
Definition: globals.c:41
volatile sig_atomic_t ProcSignalBarrierPending
Definition: globals.c:40
volatile sig_atomic_t PublishMemoryContextPending
Definition: globals.c:42
void ProcessConfigFile(GucContext context)
Definition: guc-file.l:120
@ PGC_SIGHUP
Definition: guc.h:75
volatile sig_atomic_t ConfigReloadPending
Definition: interrupt.c:27
void proc_exit(int code)
Definition: ipc.c:104
char * pstrdup(const char *in)
Definition: mcxt.c:2322
void pfree(void *pointer)
Definition: mcxt.c:2147
void ProcessGetMemoryContextInterrupt(void)
Definition: mcxt.c:1432
void ProcessLogMemoryContextInterrupt(void)
Definition: mcxt.c:1380
void ProcessProcSignalBarrier(void)
Definition: procsignal.c:498

References ConfigReloadPending, ereport, errcode(), errdetail(), errmsg(), ERROR, LOG, LogMemoryContextPending, pfree(), PGC_SIGHUP, proc_exit(), ProcessConfigFile(), ProcessGetMemoryContextInterrupt(), ProcessLogMemoryContextInterrupt(), ProcessProcSignalBarrier(), ProcSignalBarrierPending, pstrdup(), PublishMemoryContextPending, XLogArchiveCommand, and XLogArchiveLibrary.

Referenced by pgarch_ArchiverCopyLoop(), and pgarch_MainLoop().

◆ ready_file_comparator()

static int ready_file_comparator ( Datum  a,
Datum  b,
void *  arg 
)
static

Definition at line 779 of file pgarch.c.

782{
783 char *a_str = DatumGetCString(a);
784 char *b_str = DatumGetCString(b);
785 bool a_history = IsTLHistoryFileName(a_str);
786 bool b_history = IsTLHistoryFileName(b_str);
787
788 /* Timeline history files always have the highest priority. */
789 if (a_history != b_history)
790 return a_history ? -1 : 1;
791
792 /* Priority is given to older files. */
int b
Definition: isn.c:74
int a
Definition: isn.c:73
static bool IsTLHistoryFileName(const char *fname)

References a, b, DatumGetCString(), and IsTLHistoryFileName().

Referenced by pgarch_readyXlog(), and PgArchiverMain().

Variable Documentation

◆ arch_files

struct arch_files_state* arch_files = NULL
static

Definition at line 131 of file pgarch.c.

Referenced by pgarch_ArchiverCopyLoop(), pgarch_readyXlog(), and PgArchiverMain().

◆ arch_module_check_errdetail_string

char* arch_module_check_errdetail_string

Definition at line 94 of file pgarch.c.

Referenced by pgarch_ArchiverCopyLoop().

◆ archive_context

MemoryContext archive_context
static

Definition at line 105 of file pgarch.c.

Referenced by pgarch_archiveXlog(), and PgArchiverMain().

◆ archive_module_state

ArchiveModuleState* archive_module_state
static

◆ ArchiveCallbacks

const ArchiveModuleCallbacks* ArchiveCallbacks
static

◆ last_sigterm_time

time_t last_sigterm_time = 0
static

Definition at line 101 of file pgarch.c.

Referenced by pgarch_MainLoop().

◆ PgArch

PgArchData* PgArch = NULL
static

◆ ready_to_stop

volatile sig_atomic_t ready_to_stop = false
static

Definition at line 136 of file pgarch.c.

Referenced by pgarch_MainLoop(), and pgarch_waken_stop().

◆ XLogArchiveLibrary

char* XLogArchiveLibrary = ""

Definition at line 93 of file pgarch.c.

Referenced by LoadArchiveLibrary(), and ProcessPgArchInterrupts().