PostgreSQL Source Code  git master
pgarch.c File Reference
#include "postgres.h"
#include <fcntl.h>
#include <signal.h>
#include <time.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <unistd.h>
#include "access/xlog.h"
#include "access/xlog_internal.h"
#include "lib/binaryheap.h"
#include "libpq/pqsignal.h"
#include "miscadmin.h"
#include "pgstat.h"
#include "postmaster/interrupt.h"
#include "postmaster/pgarch.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 "storage/spin.h"
#include "utils/guc.h"
#include "utils/memutils.h"
#include "utils/ps_status.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 HandlePgArchInterrupts (void)
 
static int ready_file_comparator (Datum a, Datum b, void *arg)
 
Size PgArchShmemSize (void)
 
void PgArchShmemInit (void)
 
bool PgArchCanRestart (void)
 
void PgArchiverMain (void)
 
void PgArchWakeup (void)
 
void PgArchForceDirScan (void)
 

Variables

static time_t last_sigterm_time = 0
 
static PgArchDataPgArch = NULL
 
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 68 of file pgarch.c.

◆ NUM_FILES_PER_DIRECTORY_SCAN

#define NUM_FILES_PER_DIRECTORY_SCAN   64

Definition at line 79 of file pgarch.c.

◆ NUM_ORPHAN_CLEANUP_RETRIES

#define NUM_ORPHAN_CLEANUP_RETRIES   3

Definition at line 74 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 61 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 62 of file pgarch.c.

Typedef Documentation

◆ PgArchData

typedef struct PgArchData PgArchData

Function Documentation

◆ HandlePgArchInterrupts()

static void HandlePgArchInterrupts ( void  )
static

Definition at line 868 of file pgarch.c.

871 {
874 
876  {
877  ConfigReloadPending = false;
879  }
880 
881  /* Perform logging of memory contexts of this process */
volatile sig_atomic_t LogMemoryContextPending
Definition: globals.c:38
volatile sig_atomic_t ProcSignalBarrierPending
Definition: globals.c:37
@ PGC_SIGHUP
Definition: guc.h:72
void ProcessConfigFile(GucContext context)
volatile sig_atomic_t ConfigReloadPending
Definition: interrupt.c:27
void ProcessProcSignalBarrier(void)
Definition: procsignal.c:453

References ConfigReloadPending, LogMemoryContextPending, PGC_SIGHUP, ProcessConfigFile(), ProcessLogMemoryContextInterrupt(), ProcessProcSignalBarrier(), and ProcSignalBarrierPending.

Referenced by pgarch_ArchiverCopyLoop(), and pgarch_MainLoop().

◆ pgarch_archiveDone()

static void pgarch_archiveDone ( char *  xlog)
static

Definition at line 837 of file pgarch.c.

840 {
841  char rlogready[MAXPGPATH];
842  char rlogdone[MAXPGPATH];
843 
844  StatusFilePath(rlogready, xlog, ".ready");
845  StatusFilePath(rlogdone, xlog, ".done");
#define MAXPGPATH
#define StatusFilePath(path, xlog, suffix)

References durable_rename(), MAXPGPATH, StatusFilePath, and WARNING.

Referenced by pgarch_ArchiverCopyLoop().

◆ pgarch_ArchiverCopyLoop()

static void pgarch_ArchiverCopyLoop ( void  )
static

Definition at line 373 of file pgarch.c.

376 {
377  char xlog[MAX_XFN_CHARS + 1];
378 
379  /* force directory scan in the first call to pgarch_readyXlog() */
381 
382  /*
383  * loop through all xlogs with archive_status of .ready and archive
384  * them...mostly we expect this to be a single file, though it is possible
385  * some backend will add files onto the list of those that need archiving
386  * while we are still copying earlier archives
387  */
388  while (pgarch_readyXlog(xlog))
389  {
390  int failures = 0;
391  int failures_orphan = 0;
392 
393  for (;;)
394  {
395  struct stat stat_buf;
396  char pathname[MAXPGPATH];
397 
398  /*
399  * Do not initiate any more archive commands after receiving
400  * SIGTERM, nor after the postmaster has died unexpectedly. The
401  * first condition is to try to keep from having init SIGKILL the
402  * command, and the second is to avoid conflicts with another
403  * archiver spawned by a newer postmaster.
404  */
406  return;
407 
408  /*
409  * Check for barrier events and config update. This is so that
410  * we'll adopt a new setting for archive_command as soon as
411  * possible, even if there is a backlog of files to be archived.
412  */
414 
415  /* can't do anything if no command ... */
416  if (!XLogArchiveCommandSet())
417  {
419  (errmsg("archive_mode enabled, yet archive_command is not set")));
420  return;
421  }
422 
423  /*
424  * Since archive status files are not removed in a durable manner,
425  * a system crash could leave behind .ready files for WAL segments
426  * that have already been recycled or removed. In this case,
427  * simply remove the orphan status file and move on. unlink() is
428  * used here as even on subsequent crashes the same orphan files
429  * would get removed, so there is no need to worry about
430  * durability.
431  */
432  snprintf(pathname, MAXPGPATH, XLOGDIR "/%s", xlog);
433  if (stat(pathname, &stat_buf) != 0 && errno == ENOENT)
434  {
435  char xlogready[MAXPGPATH];
436 
437  StatusFilePath(xlogready, xlog, ".ready");
438  if (unlink(xlogready) == 0)
439  {
441  (errmsg("removed orphan archive status file \"%s\"",
442  xlogready)));
443 
444  /* leave loop and move to the next status file */
445  break;
446  }
447 
448  if (++failures_orphan >= NUM_ORPHAN_CLEANUP_RETRIES)
449  {
451  (errmsg("removal of orphan archive status file \"%s\" failed too many times, will try again later",
452  xlogready)));
453 
454  /* give up cleanup of orphan status files */
455  return;
456  }
457 
458  /* wait a bit before retrying */
459  pg_usleep(1000000L);
460  continue;
461  }
462 
463  if (pgarch_archiveXlog(xlog))
464  {
465  /* successful */
466  pgarch_archiveDone(xlog);
467 
468  /*
469  * Tell the collector about the WAL file that we successfully
470  * archived
471  */
472  pgstat_send_archiver(xlog, false);
473 
474  break; /* out of inner retry loop */
475  }
476  else
477  {
478  /*
479  * Tell the collector about the WAL file that we failed to
480  * archive
481  */
482  pgstat_send_archiver(xlog, true);
483 
484  if (++failures >= NUM_ARCHIVE_RETRIES)
485  {
487  (errmsg("archiving write-ahead log file \"%s\" failed too many times, will try again later",
488  xlog)));
489  return; /* give up archiving for now */
490  }
491  pg_usleep(1000000L); /* wait a bit before retrying */
492  }
493  }
int errmsg(const char *fmt,...)
Definition: elog.c:904
#define WARNING
Definition: elog.h:30
#define ereport(elevel,...)
Definition: elog.h:143
volatile sig_atomic_t ShutdownRequestPending
Definition: interrupt.c:28
static bool pgarch_archiveXlog(char *xlog)
Definition: pgarch.c:503
static bool pgarch_readyXlog(char *xlog)
Definition: pgarch.c:656
#define NUM_ARCHIVE_RETRIES
Definition: pgarch.c:68
static struct arch_files_state * arch_files
Definition: pgarch.c:126
static void HandlePgArchInterrupts(void)
Definition: pgarch.c:868
static void pgarch_archiveDone(char *xlog)
Definition: pgarch.c:837
#define NUM_ORPHAN_CLEANUP_RETRIES
Definition: pgarch.c:74
#define MAX_XFN_CHARS
Definition: pgarch.h:26
void pgstat_send_archiver(const char *xlog, bool failed)
Definition: pgstat.c:3250
#define PostmasterIsAlive()
Definition: pmsignal.h:102
#define snprintf
Definition: port.h:225
void pg_usleep(long microsec)
Definition: signal.c:53
int arch_files_size
Definition: pgarch.c:120
#define stat
Definition: win32_port.h:283
#define XLogArchiveCommandSet()
Definition: xlog.h:158
#define XLOGDIR

References arch_files, arch_files_state::arch_files_size, ereport, errmsg(), HandlePgArchInterrupts(), MAX_XFN_CHARS, MAXPGPATH, NUM_ARCHIVE_RETRIES, NUM_ORPHAN_CLEANUP_RETRIES, pg_usleep(), pgarch_archiveDone(), pgarch_archiveXlog(), pgarch_readyXlog(), pgstat_send_archiver(), PostmasterIsAlive, ShutdownRequestPending, snprintf, stat, StatusFilePath, WARNING, XLogArchiveCommandSet, and XLOGDIR.

Referenced by pgarch_MainLoop().

◆ pgarch_archiveXlog()

static bool pgarch_archiveXlog ( char *  xlog)
static

Definition at line 503 of file pgarch.c.

506 {
507  char xlogarchcmd[MAXPGPATH];
508  char pathname[MAXPGPATH];
509  char activitymsg[MAXFNAMELEN + 16];
510  char *dp;
511  char *endp;
512  const char *sp;
513  int rc;
514 
515  snprintf(pathname, MAXPGPATH, XLOGDIR "/%s", xlog);
516 
517  /*
518  * construct the command to be executed
519  */
520  dp = xlogarchcmd;
521  endp = xlogarchcmd + MAXPGPATH - 1;
522  *endp = '\0';
523 
524  for (sp = XLogArchiveCommand; *sp; sp++)
525  {
526  if (*sp == '%')
527  {
528  switch (sp[1])
529  {
530  case 'p':
531  /* %p: relative path of source file */
532  sp++;
533  strlcpy(dp, pathname, endp - dp);
534  make_native_path(dp);
535  dp += strlen(dp);
536  break;
537  case 'f':
538  /* %f: filename of source file */
539  sp++;
540  strlcpy(dp, xlog, endp - dp);
541  dp += strlen(dp);
542  break;
543  case '%':
544  /* convert %% to a single % */
545  sp++;
546  if (dp < endp)
547  *dp++ = *sp;
548  break;
549  default:
550  /* otherwise treat the % as not special */
551  if (dp < endp)
552  *dp++ = *sp;
553  break;
554  }
555  }
556  else
557  {
558  if (dp < endp)
559  *dp++ = *sp;
560  }
561  }
562  *dp = '\0';
563 
564  ereport(DEBUG3,
565  (errmsg_internal("executing archive command \"%s\"",
566  xlogarchcmd)));
567 
568  /* Report archive activity in PS display */
569  snprintf(activitymsg, sizeof(activitymsg), "archiving %s", xlog);
570  set_ps_display(activitymsg);
571 
573  rc = system(xlogarchcmd);
575 
576  if (rc != 0)
577  {
578  /*
579  * If either the shell itself, or a called command, died on a signal,
580  * abort the archiver. We do this because system() ignores SIGINT and
581  * SIGQUIT while waiting; so a signal is very likely something that
582  * should have interrupted us too. Also die if the shell got a hard
583  * "command not found" type of error. If we overreact it's no big
584  * deal, the postmaster will just start the archiver again.
585  */
586  int lev = wait_result_is_any_signal(rc, true) ? FATAL : LOG;
587 
588  if (WIFEXITED(rc))
589  {
590  ereport(lev,
591  (errmsg("archive command failed with exit code %d",
592  WEXITSTATUS(rc)),
593  errdetail("The failed archive command was: %s",
594  xlogarchcmd)));
595  }
596  else if (WIFSIGNALED(rc))
597  {
598 #if defined(WIN32)
599  ereport(lev,
600  (errmsg("archive command was terminated by exception 0x%X",
601  WTERMSIG(rc)),
602  errhint("See C include file \"ntstatus.h\" for a description of the hexadecimal value."),
603  errdetail("The failed archive command was: %s",
604  xlogarchcmd)));
605 #else
606  ereport(lev,
607  (errmsg("archive command was terminated by signal %d: %s",
608  WTERMSIG(rc), pg_strsignal(WTERMSIG(rc))),
609  errdetail("The failed archive command was: %s",
610  xlogarchcmd)));
611 #endif
612  }
613  else
614  {
615  ereport(lev,
616  (errmsg("archive command exited with unrecognized status %d",
617  rc),
618  errdetail("The failed archive command was: %s",
619  xlogarchcmd)));
620  }
621 
622  snprintf(activitymsg, sizeof(activitymsg), "failed on %s", xlog);
623  set_ps_display(activitymsg);
624 
625  return false;
626  }
627  elog(DEBUG1, "archived write-ahead log file \"%s\"", xlog);
628 
629  snprintf(activitymsg, sizeof(activitymsg), "last was %s", xlog);
630  set_ps_display(activitymsg);
631 
int errmsg_internal(const char *fmt,...)
Definition: elog.c:991
int errdetail(const char *fmt,...)
Definition: elog.c:1037
int errhint(const char *fmt,...)
Definition: elog.c:1151
#define LOG
Definition: elog.h:25
#define DEBUG3
Definition: elog.h:22
#define FATAL
Definition: elog.h:35
#define DEBUG1
Definition: elog.h:24
#define elog(elevel,...)
Definition: elog.h:218
void make_native_path(char *path)
Definition: path.c:166
const char * pg_strsignal(int signum)
Definition: pgstrsignal.c:42
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45
void set_ps_display(const char *activity)
Definition: ps_status.c:349
bool wait_result_is_any_signal(int exit_status, bool include_command_not_found)
Definition: wait_error.c:111
@ WAIT_EVENT_ARCHIVE_COMMAND
Definition: wait_event.h:84
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: wait_event.h:262
static void pgstat_report_wait_end(void)
Definition: wait_event.h:278
#define WIFEXITED(w)
Definition: win32_port.h:151
#define WIFSIGNALED(w)
Definition: win32_port.h:152
#define WTERMSIG(w)
Definition: win32_port.h:154
#define WEXITSTATUS(w)
Definition: win32_port.h:153
char * XLogArchiveCommand
Definition: xlog.c:101
#define MAXFNAMELEN

References DEBUG1, DEBUG3, elog, ereport, errdetail(), errhint(), errmsg(), errmsg_internal(), FATAL, LOG, make_native_path(), MAXFNAMELEN, MAXPGPATH, pg_strsignal(), pgstat_report_wait_end(), pgstat_report_wait_start(), set_ps_display(), snprintf, strlcpy(), WAIT_EVENT_ARCHIVE_COMMAND, wait_result_is_any_signal(), WEXITSTATUS, WIFEXITED, WIFSIGNALED, WTERMSIG, XLogArchiveCommand, and XLOGDIR.

Referenced by pgarch_ArchiverCopyLoop().

◆ pgarch_die()

static void pgarch_die ( int  code,
Datum  arg 
)
static

Definition at line 854 of file pgarch.c.

857 {

References INVALID_PGPROCNO, PgArch, and PgArchData::pgprocno.

Referenced by PgArchiverMain().

◆ pgarch_MainLoop()

static void pgarch_MainLoop ( void  )
static

Definition at line 293 of file pgarch.c.

296 {
297  pg_time_t last_copy_time = 0;
298  bool time_to_stop;
299 
300  /*
301  * There shouldn't be anything for the archiver to do except to wait for a
302  * signal ... however, the archiver exists to protect our data, so she
303  * wakes up occasionally to allow herself to be proactive.
304  */
305  do
306  {
308 
309  /* When we get SIGUSR2, we do one more archive cycle, then exit */
311 
312  /* Check for barrier events and config update */
314 
315  /*
316  * If we've gotten SIGTERM, we normally just sit and do nothing until
317  * SIGUSR2 arrives. However, that means a random SIGTERM would
318  * disable archiving indefinitely, which doesn't seem like a good
319  * idea. If more than 60 seconds pass since SIGTERM, exit anyway, so
320  * that the postmaster can start a new archiver if needed.
321  */
323  {
324  time_t curtime = time(NULL);
325 
326  if (last_sigterm_time == 0)
327  last_sigterm_time = curtime;
328  else if ((unsigned int) (curtime - last_sigterm_time) >=
329  (unsigned int) 60)
330  break;
331  }
332 
333  /* Do what we're here for */
335  last_copy_time = time(NULL);
336 
337  /*
338  * Sleep until a signal is received, or until a poll is forced by
339  * PGARCH_AUTOWAKE_INTERVAL having passed since last_copy_time, or
340  * until postmaster dies.
341  */
342  if (!time_to_stop) /* Don't wait during last iteration */
343  {
344  pg_time_t curtime = (pg_time_t) time(NULL);
345  int timeout;
346 
347  timeout = PGARCH_AUTOWAKE_INTERVAL - (curtime - last_copy_time);
348  if (timeout > 0)
349  {
350  int rc;
351 
352  rc = WaitLatch(MyLatch,
354  timeout * 1000L,
356  if (rc & WL_POSTMASTER_DEATH)
357  time_to_stop = true;
358  }
359  }
360 
361  /*
362  * The archiver quits either when the postmaster dies (not expected)
363  * or after completing one more archiving cycle after receiving
364  * SIGUSR2.
365  */
struct Latch * MyLatch
Definition: globals.c:57
void ResetLatch(Latch *latch)
Definition: latch.c:660
int WaitLatch(Latch *latch, int wakeEvents, long timeout, uint32 wait_event_info)
Definition: latch.c:452
#define WL_TIMEOUT
Definition: latch.h:128
#define WL_LATCH_SET
Definition: latch.h:125
#define WL_POSTMASTER_DEATH
Definition: latch.h:129
static volatile bool time_to_stop
Definition: pg_receivewal.c:48
static volatile sig_atomic_t ready_to_stop
Definition: pgarch.c:131
static void pgarch_ArchiverCopyLoop(void)
Definition: pgarch.c:373
#define PGARCH_AUTOWAKE_INTERVAL
Definition: pgarch.c:61
static time_t last_sigterm_time
Definition: pgarch.c:100
int64 pg_time_t
Definition: pgtime.h:23
@ WAIT_EVENT_ARCHIVER_MAIN
Definition: wait_event.h:38

References HandlePgArchInterrupts(), last_sigterm_time, MyLatch, pgarch_ArchiverCopyLoop(), PGARCH_AUTOWAKE_INTERVAL, ready_to_stop, ResetLatch(), ShutdownRequestPending, time_to_stop, WAIT_EVENT_ARCHIVER_MAIN, 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 656 of file pgarch.c.

659 {
660  char XLogArchiveStatusDir[MAXPGPATH];
661  DIR *rldir;
662  struct dirent *rlde;
663  bool force_dir_scan;
664 
665  /*
666  * If a directory scan was requested, clear the stored file names and
667  * proceed.
668  */
670  force_dir_scan = PgArch->force_dir_scan;
671  PgArch->force_dir_scan = false;
673 
674  if (force_dir_scan)
676 
677  /*
678  * If we still have stored file names from the previous directory scan,
679  * try to return one of those. We check to make sure the status file
680  * is still present, as the archive_command for a previous file may
681  * have already marked it done.
682  */
683  while (arch_files->arch_files_size > 0)
684  {
685  struct stat st;
686  char status_file[MAXPGPATH];
687  char *arch_file;
688 
691  StatusFilePath(status_file, arch_file, ".ready");
692 
693  if (stat(status_file, &st) == 0)
694  {
695  strcpy(xlog, arch_file);
696  return true;
697  }
698  else if (errno != ENOENT)
699  ereport(ERROR,
701  errmsg("could not stat file \"%s\": %m", status_file)));
702  }
703 
704  /* arch_heap is probably empty, but let's make sure */
706 
707  /*
708  * Open the archive status directory and read through the list of files
709  * with the .ready suffix, looking for the earliest files.
710  */
711  snprintf(XLogArchiveStatusDir, MAXPGPATH, XLOGDIR "/archive_status");
712  rldir = AllocateDir(XLogArchiveStatusDir);
713 
714  while ((rlde = ReadDir(rldir, XLogArchiveStatusDir)) != NULL)
715  {
716  int basenamelen = (int) strlen(rlde->d_name) - 6;
717  char basename[MAX_XFN_CHARS + 1];
718  char *arch_file;
719 
720  /* Ignore entries with unexpected number of characters */
721  if (basenamelen < MIN_XFN_CHARS ||
722  basenamelen > MAX_XFN_CHARS)
723  continue;
724 
725  /* Ignore entries with unexpected characters */
726  if (strspn(rlde->d_name, VALID_XFN_CHARS) < basenamelen)
727  continue;
728 
729  /* Ignore anything not suffixed with .ready */
730  if (strcmp(rlde->d_name + basenamelen, ".ready") != 0)
731  continue;
732 
733  /* Truncate off the .ready */
734  memcpy(basename, rlde->d_name, basenamelen);
735  basename[basenamelen] = '\0';
736 
737  /*
738  * Store the file in our max-heap if it has a high enough priority.
739  */
741  {
742  /* If the heap isn't full yet, quickly add it. */
744  strcpy(arch_file, basename);
746 
747  /* If we just filled the heap, make it a valid one. */
750  }
752  CStringGetDatum(basename), NULL) > 0)
753  {
754  /*
755  * Remove the lowest priority file and add the current one to
756  * the heap.
757  */
759  strcpy(arch_file, basename);
761  }
762  }
763  FreeDir(rldir);
764 
765  /* If no files were found, simply return. */
766  if (arch_files->arch_heap->bh_size == 0)
767  return false;
768 
769  /*
770  * If we didn't fill the heap, we didn't make it a valid one. Do that
771  * now.
772  */
775 
776  /*
777  * Fill arch_files array with the files to archive in ascending order
778  * of priority.
779  */
781  for (int i = 0; i < arch_files->arch_files_size; i++)
783 
784  /* Return the highest priority file. */
787 
void binaryheap_build(binaryheap *heap)
Definition: binaryheap.c:125
void binaryheap_add_unordered(binaryheap *heap, Datum d)
Definition: binaryheap.c:109
void binaryheap_reset(binaryheap *heap)
Definition: binaryheap.c:56
Datum binaryheap_remove_first(binaryheap *heap)
Definition: binaryheap.c:173
Datum binaryheap_first(binaryheap *heap)
Definition: binaryheap.c:158
void binaryheap_add(binaryheap *heap, Datum d)
Definition: binaryheap.c:141
int errcode_for_file_access(void)
Definition: elog.c:716
#define ERROR
Definition: elog.h:33
struct dirent * ReadDir(DIR *dir, const char *dirname)
Definition: fd.c:2788
int FreeDir(DIR *dir)
Definition: fd.c:2840
DIR * AllocateDir(const char *dirname)
Definition: fd.c:2722
int i
Definition: isn.c:73
static PgArchData * PgArch
Definition: pgarch.c:101
static int ready_file_comparator(Datum a, Datum b, void *arg)
Definition: pgarch.c:798
#define NUM_FILES_PER_DIRECTORY_SCAN
Definition: pgarch.c:79
#define MIN_XFN_CHARS
Definition: pgarch.h:25
#define VALID_XFN_CHARS
Definition: pgarch.h:27
#define CStringGetDatum(X)
Definition: postgres.h:622
#define DatumGetCString(X)
Definition: postgres.h:610
#define SpinLockRelease(lock)
Definition: spin.h:64
#define SpinLockAcquire(lock)
Definition: spin.h:62
Definition: dirent.c:26
bool force_dir_scan
Definition: pgarch.c:90
slock_t arch_lck
Definition: pgarch.c:92
char arch_filenames[NUM_FILES_PER_DIRECTORY_SCAN][MAX_XFN_CHARS+1]
Definition: pgarch.c:123
char * arch_files[NUM_FILES_PER_DIRECTORY_SCAN]
Definition: pgarch.c:121
binaryheap * arch_heap
Definition: pgarch.c:119
int bh_size
Definition: binaryheap.h:32
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, PgArchData::arch_lck, 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, PgArch, ReadDir(), ready_file_comparator(), snprintf, SpinLockAcquire, SpinLockRelease, 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 276 of file pgarch.c.

279 {
280  int save_errno = errno;
281 
282  /* set flag to do a final cycle and shut down afterwards */
283  ready_to_stop = true;
284  SetLatch(MyLatch);
285 
void SetLatch(Latch *latch)
Definition: latch.c:567

References MyLatch, ready_to_stop, and SetLatch().

Referenced by PgArchiverMain().

◆ PgArchCanRestart()

bool PgArchCanRestart ( void  )

Definition at line 189 of file pgarch.c.

192 {
193  static time_t last_pgarch_start_time = 0;
194  time_t curtime = time(NULL);
195 
196  /*
197  * Return false and don't restart archiver if too soon since last archiver
198  * start.
199  */
200  if ((unsigned int) (curtime - last_pgarch_start_time) <
201  (unsigned int) PGARCH_RESTART_INTERVAL)
202  return false;
203 
204  last_pgarch_start_time = curtime;
#define PGARCH_RESTART_INTERVAL
Definition: pgarch.c:62

References PGARCH_RESTART_INTERVAL.

◆ PgArchForceDirScan()

void PgArchForceDirScan ( void  )

Definition at line 821 of file pgarch.c.

824 {
826  PgArch->force_dir_scan = true;

References PgArchData::arch_lck, PgArchData::force_dir_scan, PgArch, SpinLockAcquire, and SpinLockRelease.

Referenced by XLogArchiveNotify().

◆ PgArchiverMain()

void PgArchiverMain ( void  )

Definition at line 209 of file pgarch.c.

212 {
213  /*
214  * Ignore all signals usually bound to some action in the postmaster,
215  * except for SIGHUP, SIGTERM, SIGUSR1, SIGUSR2, and SIGQUIT.
216  */
218  pqsignal(SIGINT, SIG_IGN);
220  /* SIGQUIT handler was already set up by InitPostmasterChild */
225 
226  /* Reset some signals that are accepted by postmaster but not here */
228 
229  /* Unblock signals (they were blocked when the postmaster forked us) */
231 
232  /* We shouldn't be launched unnecessarily. */
234 
235  /* Arrange to clean up at archiver exit */
237 
238  /*
239  * Advertise our pgprocno so that backends can use our latch to wake us up
240  * while we're sleeping.
241  */
243 
244  /* Create workspace for pgarch_readyXlog() */
245  arch_files = palloc(sizeof(struct arch_files_state));
247 
248  /* Initialize our max-heap for prioritizing files to archive. */
250  ready_file_comparator, NULL);
251 
252  pgarch_MainLoop();
253 
sigset_t UnBlockSig
Definition: pqsignal.c:22
binaryheap * binaryheap_allocate(int capacity, binaryheap_comparator compare, void *arg)
Definition: binaryheap.c:32
void SignalHandlerForShutdownRequest(SIGNAL_ARGS)
Definition: interrupt.c:109
void SignalHandlerForConfigReload(SIGNAL_ARGS)
Definition: interrupt.c:61
void on_shmem_exit(pg_on_exit_callback function, Datum arg)
Definition: ipc.c:361
Assert(fmt[strlen(fmt) - 1] !='\n')
void * palloc(Size size)
Definition: mcxt.c:1062
static void pgarch_die(int code, Datum arg)
Definition: pgarch.c:854
static void pgarch_MainLoop(void)
Definition: pgarch.c:293
static void pgarch_waken_stop(SIGNAL_ARGS)
Definition: pgarch.c:276
#define PG_SETMASK(mask)
Definition: pqsignal.h:19
void procsignal_sigusr1_handler(SIGNAL_ARGS)
Definition: procsignal.c:642
pqsigfunc pqsignal(int signum, pqsigfunc handler)
Definition: signal.c:180
PGPROC * MyProc
Definition: proc.c:68
int pgprocno
Definition: proc.h:153
int pgprocno
Definition: pgarch.c:84
#define SIGCHLD
Definition: win32_port.h:177
#define SIGHUP
Definition: win32_port.h:167
#define SIG_DFL
Definition: win32_port.h:162
#define SIGPIPE
Definition: win32_port.h:172
#define SIGUSR1
Definition: win32_port.h:179
#define SIGALRM
Definition: win32_port.h:173
#define SIGUSR2
Definition: win32_port.h:180
#define SIG_IGN
Definition: win32_port.h:164
#define XLogArchivingActive()
Definition: xlog.h:153

References arch_files, arch_files_state::arch_files_size, arch_files_state::arch_heap, Assert(), binaryheap_allocate(), MyProc, NUM_FILES_PER_DIRECTORY_SCAN, on_shmem_exit(), palloc(), PG_SETMASK, PgArch, pgarch_die(), pgarch_MainLoop(), pgarch_waken_stop(), PgArchData::pgprocno, PGPROC::pgprocno, pqsignal(), proc_exit(), procsignal_sigusr1_handler(), ready_file_comparator(), SIG_DFL, SIG_IGN, SIGALRM, SIGCHLD, SIGHUP, SignalHandlerForConfigReload(), SignalHandlerForShutdownRequest(), SIGPIPE, SIGUSR1, SIGUSR2, UnBlockSig, and XLogArchivingActive.

Referenced by AuxiliaryProcessMain().

◆ PgArchShmemInit()

void PgArchShmemInit ( void  )

Definition at line 160 of file pgarch.c.

163 {
164  bool found;
165 
166  PgArch = (PgArchData *)
167  ShmemInitStruct("Archiver Data", PgArchShmemSize(), &found);
168 
169  if (!found)
170  {
171  /* First time through, so initialize */
#define MemSet(start, val, len)
Definition: c.h:1008
Size PgArchShmemSize(void)
Definition: pgarch.c:149
#define INVALID_PGPROCNO
Definition: proc.h:83
void * ShmemInitStruct(const char *name, Size size, bool *foundPtr)
Definition: shmem.c:396
#define SpinLockInit(lock)
Definition: spin.h:60

References PgArchData::arch_lck, INVALID_PGPROCNO, MemSet, PgArch, PgArchShmemSize(), PgArchData::pgprocno, ShmemInitStruct(), and SpinLockInit.

Referenced by CreateSharedMemoryAndSemaphores().

◆ PgArchShmemSize()

Size PgArchShmemSize ( void  )

Definition at line 149 of file pgarch.c.

152 {
153  Size size = 0;
154 
155  size = add_size(size, sizeof(PgArchData));
156 
size_t Size
Definition: c.h:540
Size add_size(Size s1, Size s2)
Definition: shmem.c:502

References add_size().

Referenced by CalculateShmemSize(), and PgArchShmemInit().

◆ PgArchWakeup()

void PgArchWakeup ( void  )

Definition at line 259 of file pgarch.c.

262 {
263  int arch_pgprocno = PgArch->pgprocno;
264 
265  /*
266  * We don't acquire ProcArrayLock here. It's actually fine because
267  * procLatch isn't ever freed, so we just can potentially set the wrong
268  * process' (or no process') latch. Even in that case the archiver will
269  * be relaunched shortly and will start archiving.
270  */
271  if (arch_pgprocno != INVALID_PGPROCNO)

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

Referenced by XLogArchiveNotify().

◆ ready_file_comparator()

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

Definition at line 798 of file pgarch.c.

801 {
802  char *a_str = DatumGetCString(a);
803  char *b_str = DatumGetCString(b);
804  bool a_history = IsTLHistoryFileName(a_str);
805  bool b_history = IsTLHistoryFileName(b_str);
806 
807  /* Timeline history files always have the highest priority. */
808  if (a_history != b_history)
809  return a_history ? -1 : 1;
810 
811  /* Priority is given to older files. */
int b
Definition: isn.c:70
int a
Definition: isn.c:69
#define IsTLHistoryFileName(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 126 of file pgarch.c.

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

◆ last_sigterm_time

time_t last_sigterm_time = 0
static

Definition at line 100 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 131 of file pgarch.c.

Referenced by pgarch_MainLoop(), and pgarch_waken_stop().