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 "libpq/pqsignal.h"
#include "miscadmin.h"
#include "pgstat.h"
#include "postmaster/fork_process.h"
#include "postmaster/interrupt.h"
#include "postmaster/pgarch.h"
#include "postmaster/postmaster.h"
#include "storage/dsm.h"
#include "storage/fd.h"
#include "storage/ipc.h"
#include "storage/latch.h"
#include "storage/pg_shmem.h"
#include "storage/pmsignal.h"
#include "utils/guc.h"
#include "utils/ps_status.h"
Include dependency graph for pgarch.c:

Go to the source code of this file.

Macros

#define PGARCH_AUTOWAKE_INTERVAL
 
#define PGARCH_RESTART_INTERVAL
 
#define NUM_ARCHIVE_RETRIES   3
 
#define NUM_ORPHAN_CLEANUP_RETRIES   3
 

Functions

NON_EXEC_STATIC void PgArchiverMain (int argc, char *argv[]) pg_attribute_noreturn()
 
static void pgarch_exit (SIGNAL_ARGS)
 
static void pgarch_waken (SIGNAL_ARGS)
 
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)
 
int pgarch_start (void)
 

Variables

static time_t last_pgarch_start_time
 
static time_t last_sigterm_time = 0
 
static volatile sig_atomic_t wakened = false
 
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.

Referenced by pgarch_ArchiverCopyLoop().

◆ NUM_ORPHAN_CLEANUP_RETRIES

#define NUM_ORPHAN_CLEANUP_RETRIES   3

Definition at line 74 of file pgarch.c.

Referenced by pgarch_ArchiverCopyLoop().

◆ 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 59 of file pgarch.c.

Referenced by pgarch_MainLoop().

◆ PGARCH_RESTART_INTERVAL

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

Definition at line 61 of file pgarch.c.

Referenced by pgarch_start().

Function Documentation

◆ pgarch_archiveDone()

static void pgarch_archiveDone ( char *  xlog)
static

Definition at line 749 of file pgarch.c.

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

Referenced by pgarch_ArchiverCopyLoop().

750 {
751  char rlogready[MAXPGPATH];
752  char rlogdone[MAXPGPATH];
753 
754  StatusFilePath(rlogready, xlog, ".ready");
755  StatusFilePath(rlogdone, xlog, ".done");
756  (void) durable_rename(rlogready, rlogdone, WARNING);
757 }
#define StatusFilePath(path, xlog, suffix)
#define MAXPGPATH
int durable_rename(const char *oldfile, const char *newfile, int elevel)
Definition: fd.c:642
#define WARNING
Definition: elog.h:40

◆ pgarch_ArchiverCopyLoop()

static void pgarch_ArchiverCopyLoop ( void  )
static

Definition at line 391 of file pgarch.c.

References ConfigReloadPending, ereport, errmsg(), MAX_XFN_CHARS, MAXPGPATH, NUM_ARCHIVE_RETRIES, NUM_ORPHAN_CLEANUP_RETRIES, pg_usleep(), pgarch_archiveDone(), pgarch_archiveXlog(), pgarch_readyXlog(), PGC_SIGHUP, pgstat_send_archiver(), PostmasterIsAlive, ProcessConfigFile(), ShutdownRequestPending, snprintf, stat, StatusFilePath, WARNING, XLogArchiveCommandSet, and XLOGDIR.

Referenced by pgarch_MainLoop().

392 {
393  char xlog[MAX_XFN_CHARS + 1];
394 
395  /*
396  * loop through all xlogs with archive_status of .ready and archive
397  * them...mostly we expect this to be a single file, though it is possible
398  * some backend will add files onto the list of those that need archiving
399  * while we are still copying earlier archives
400  */
401  while (pgarch_readyXlog(xlog))
402  {
403  int failures = 0;
404  int failures_orphan = 0;
405 
406  for (;;)
407  {
408  struct stat stat_buf;
409  char pathname[MAXPGPATH];
410 
411  /*
412  * Do not initiate any more archive commands after receiving
413  * SIGTERM, nor after the postmaster has died unexpectedly. The
414  * first condition is to try to keep from having init SIGKILL the
415  * command, and the second is to avoid conflicts with another
416  * archiver spawned by a newer postmaster.
417  */
419  return;
420 
421  /*
422  * Check for config update. This is so that we'll adopt a new
423  * setting for archive_command as soon as possible, even if there
424  * is a backlog of files to be archived.
425  */
427  {
428  ConfigReloadPending = false;
430  }
431 
432  /* can't do anything if no command ... */
433  if (!XLogArchiveCommandSet())
434  {
436  (errmsg("archive_mode enabled, yet archive_command is not set")));
437  return;
438  }
439 
440  /*
441  * Since archive status files are not removed in a durable manner,
442  * a system crash could leave behind .ready files for WAL segments
443  * that have already been recycled or removed. In this case,
444  * simply remove the orphan status file and move on. unlink() is
445  * used here as even on subsequent crashes the same orphan files
446  * would get removed, so there is no need to worry about
447  * durability.
448  */
449  snprintf(pathname, MAXPGPATH, XLOGDIR "/%s", xlog);
450  if (stat(pathname, &stat_buf) != 0 && errno == ENOENT)
451  {
452  char xlogready[MAXPGPATH];
453 
454  StatusFilePath(xlogready, xlog, ".ready");
455  if (unlink(xlogready) == 0)
456  {
458  (errmsg("removed orphan archive status file \"%s\"",
459  xlogready)));
460 
461  /* leave loop and move to the next status file */
462  break;
463  }
464 
465  if (++failures_orphan >= NUM_ORPHAN_CLEANUP_RETRIES)
466  {
468  (errmsg("removal of orphan archive status file \"%s\" failed too many times, will try again later",
469  xlogready)));
470 
471  /* give up cleanup of orphan status files */
472  return;
473  }
474 
475  /* wait a bit before retrying */
476  pg_usleep(1000000L);
477  continue;
478  }
479 
480  if (pgarch_archiveXlog(xlog))
481  {
482  /* successful */
483  pgarch_archiveDone(xlog);
484 
485  /*
486  * Tell the collector about the WAL file that we successfully
487  * archived
488  */
489  pgstat_send_archiver(xlog, false);
490 
491  break; /* out of inner retry loop */
492  }
493  else
494  {
495  /*
496  * Tell the collector about the WAL file that we failed to
497  * archive
498  */
499  pgstat_send_archiver(xlog, true);
500 
501  if (++failures >= NUM_ARCHIVE_RETRIES)
502  {
504  (errmsg("archiving write-ahead log file \"%s\" failed too many times, will try again later",
505  xlog)));
506  return; /* give up archiving for now */
507  }
508  pg_usleep(1000000L); /* wait a bit before retrying */
509  }
510  }
511  }
512 }
#define StatusFilePath(path, xlog, suffix)
#define NUM_ORPHAN_CLEANUP_RETRIES
Definition: pgarch.c:74
void ProcessConfigFile(GucContext context)
#define XLogArchiveCommandSet()
Definition: xlog.h:175
void pg_usleep(long microsec)
Definition: signal.c:53
struct stat stat_buf
Definition: pg_standby.c:100
#define MAXPGPATH
static bool pgarch_readyXlog(char *xlog)
Definition: pgarch.c:672
#define NUM_ARCHIVE_RETRIES
Definition: pgarch.c:68
static bool pgarch_archiveXlog(char *xlog)
Definition: pgarch.c:522
#define PostmasterIsAlive()
Definition: pmsignal.h:91
static void pgarch_archiveDone(char *xlog)
Definition: pgarch.c:749
#define ereport(elevel, rest)
Definition: elog.h:141
volatile sig_atomic_t ShutdownRequestPending
Definition: interrupt.c:27
Definition: guc.h:72
#define WARNING
Definition: elog.h:40
#define stat(a, b)
Definition: win32_port.h:255
#define XLOGDIR
#define MAX_XFN_CHARS
Definition: pgarch.h:26
void pgstat_send_archiver(const char *xlog, bool failed)
Definition: pgstat.c:4367
int errmsg(const char *fmt,...)
Definition: elog.c:822
volatile sig_atomic_t ConfigReloadPending
Definition: interrupt.c:26
#define snprintf
Definition: port.h:192

◆ pgarch_archiveXlog()

static bool pgarch_archiveXlog ( char *  xlog)
static

Definition at line 522 of file pgarch.c.

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

Referenced by pgarch_ArchiverCopyLoop().

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

◆ pgarch_exit()

static void pgarch_exit ( SIGNAL_ARGS  )
static

Definition at line 253 of file pgarch.c.

Referenced by PgArchiverMain().

254 {
255  /* SIGQUIT means curl up and die ... */
256  exit(1);
257 }

◆ pgarch_MainLoop()

static void pgarch_MainLoop ( void  )
static

Definition at line 291 of file pgarch.c.

References ConfigReloadPending, last_sigterm_time, MyLatch, pgarch_ArchiverCopyLoop(), PGARCH_AUTOWAKE_INTERVAL, PGC_SIGHUP, ProcessConfigFile(), ready_to_stop, ResetLatch(), ShutdownRequestPending, time_to_stop, WAIT_EVENT_ARCHIVER_MAIN, WaitLatch(), wakened, WL_LATCH_SET, WL_POSTMASTER_DEATH, and WL_TIMEOUT.

Referenced by PgArchiverMain().

292 {
293  pg_time_t last_copy_time = 0;
294  bool time_to_stop;
295 
296  /*
297  * We run the copy loop immediately upon entry, in case there are
298  * unarchived files left over from a previous database run (or maybe the
299  * archiver died unexpectedly). After that we wait for a signal or
300  * timeout before doing more.
301  */
302  wakened = true;
303 
304  /*
305  * There shouldn't be anything for the archiver to do except to wait for a
306  * signal ... however, the archiver exists to protect our data, so she
307  * wakes up occasionally to allow herself to be proactive.
308  */
309  do
310  {
312 
313  /* When we get SIGUSR2, we do one more archive cycle, then exit */
314  time_to_stop = ready_to_stop;
315 
316  /* Check for config update */
318  {
319  ConfigReloadPending = false;
321  }
322 
323  /*
324  * If we've gotten SIGTERM, we normally just sit and do nothing until
325  * SIGUSR2 arrives. However, that means a random SIGTERM would
326  * disable archiving indefinitely, which doesn't seem like a good
327  * idea. If more than 60 seconds pass since SIGTERM, exit anyway, so
328  * that the postmaster can start a new archiver if needed.
329  */
331  {
332  time_t curtime = time(NULL);
333 
334  if (last_sigterm_time == 0)
335  last_sigterm_time = curtime;
336  else if ((unsigned int) (curtime - last_sigterm_time) >=
337  (unsigned int) 60)
338  break;
339  }
340 
341  /* Do what we're here for */
342  if (wakened || time_to_stop)
343  {
344  wakened = false;
346  last_copy_time = time(NULL);
347  }
348 
349  /*
350  * Sleep until a signal is received, or until a poll is forced by
351  * PGARCH_AUTOWAKE_INTERVAL having passed since last_copy_time, or
352  * until postmaster dies.
353  */
354  if (!time_to_stop) /* Don't wait during last iteration */
355  {
356  pg_time_t curtime = (pg_time_t) time(NULL);
357  int timeout;
358 
359  timeout = PGARCH_AUTOWAKE_INTERVAL - (curtime - last_copy_time);
360  if (timeout > 0)
361  {
362  int rc;
363 
364  rc = WaitLatch(MyLatch,
366  timeout * 1000L,
368  if (rc & WL_TIMEOUT)
369  wakened = true;
370  if (rc & WL_POSTMASTER_DEATH)
371  time_to_stop = true;
372  }
373  else
374  wakened = true;
375  }
376 
377  /*
378  * The archiver quits either when the postmaster dies (not expected)
379  * or after completing one more archiving cycle after receiving
380  * SIGUSR2.
381  */
382  } while (!time_to_stop);
383 }
int64 pg_time_t
Definition: pgtime.h:23
#define WL_TIMEOUT
Definition: latch.h:127
void ProcessConfigFile(GucContext context)
static time_t last_sigterm_time
Definition: pgarch.c:82
void ResetLatch(Latch *latch)
Definition: latch.c:519
#define PGARCH_AUTOWAKE_INTERVAL
Definition: pgarch.c:59
int WaitLatch(Latch *latch, int wakeEvents, long timeout, uint32 wait_event_info)
Definition: latch.c:344
static volatile sig_atomic_t wakened
Definition: pgarch.c:87
static void pgarch_ArchiverCopyLoop(void)
Definition: pgarch.c:391
static volatile bool time_to_stop
Definition: pg_receivewal.c:39
volatile sig_atomic_t ShutdownRequestPending
Definition: interrupt.c:27
Definition: guc.h:72
#define WL_POSTMASTER_DEATH
Definition: latch.h:128
volatile sig_atomic_t ConfigReloadPending
Definition: interrupt.c:26
struct Latch * MyLatch
Definition: globals.c:54
static volatile sig_atomic_t ready_to_stop
Definition: pgarch.c:88
#define WL_LATCH_SET
Definition: latch.h:124

◆ pgarch_readyXlog()

static bool pgarch_readyXlog ( char *  xlog)
static

Definition at line 672 of file pgarch.c.

References AllocateDir(), dirent::d_name, FreeDir(), IsTLHistoryFileName, MAX_XFN_CHARS, MAXPGPATH, MIN_XFN_CHARS, ReadDir(), snprintf, VALID_XFN_CHARS, and XLOGDIR.

Referenced by pgarch_ArchiverCopyLoop().

673 {
674  /*
675  * open xlog status directory and read through list of xlogs that have the
676  * .ready suffix, looking for earliest file. It is possible to optimise
677  * this code, though only a single file is expected on the vast majority
678  * of calls, so....
679  */
680  char XLogArchiveStatusDir[MAXPGPATH];
681  DIR *rldir;
682  struct dirent *rlde;
683  bool found = false;
684  bool historyFound = false;
685 
686  snprintf(XLogArchiveStatusDir, MAXPGPATH, XLOGDIR "/archive_status");
687  rldir = AllocateDir(XLogArchiveStatusDir);
688 
689  while ((rlde = ReadDir(rldir, XLogArchiveStatusDir)) != NULL)
690  {
691  int basenamelen = (int) strlen(rlde->d_name) - 6;
692  char basename[MAX_XFN_CHARS + 1];
693  bool ishistory;
694 
695  /* Ignore entries with unexpected number of characters */
696  if (basenamelen < MIN_XFN_CHARS ||
697  basenamelen > MAX_XFN_CHARS)
698  continue;
699 
700  /* Ignore entries with unexpected characters */
701  if (strspn(rlde->d_name, VALID_XFN_CHARS) < basenamelen)
702  continue;
703 
704  /* Ignore anything not suffixed with .ready */
705  if (strcmp(rlde->d_name + basenamelen, ".ready") != 0)
706  continue;
707 
708  /* Truncate off the .ready */
709  memcpy(basename, rlde->d_name, basenamelen);
710  basename[basenamelen] = '\0';
711 
712  /* Is this a history file? */
713  ishistory = IsTLHistoryFileName(basename);
714 
715  /*
716  * Consume the file to archive. History files have the highest
717  * priority. If this is the first file or the first history file
718  * ever, copy it. In the presence of a history file already chosen as
719  * target, ignore all other files except history files which have been
720  * generated for an older timeline than what is already chosen as
721  * target to archive.
722  */
723  if (!found || (ishistory && !historyFound))
724  {
725  strcpy(xlog, basename);
726  found = true;
727  historyFound = ishistory;
728  }
729  else if (ishistory || !historyFound)
730  {
731  if (strcmp(basename, xlog) < 0)
732  strcpy(xlog, basename);
733  }
734  }
735  FreeDir(rldir);
736 
737  return found;
738 }
Definition: dirent.h:9
Definition: dirent.c:25
#define MAXPGPATH
#define MIN_XFN_CHARS
Definition: pgarch.h:25
DIR * AllocateDir(const char *dirname)
Definition: fd.c:2502
#define XLOGDIR
#define VALID_XFN_CHARS
Definition: pgarch.h:27
#define MAX_XFN_CHARS
Definition: pgarch.h:26
struct dirent * ReadDir(DIR *dir, const char *dirname)
Definition: fd.c:2568
#define IsTLHistoryFileName(fname)
char d_name[MAX_PATH]
Definition: dirent.h:14
#define snprintf
Definition: port.h:192
int FreeDir(DIR *dir)
Definition: fd.c:2620

◆ pgarch_start()

int pgarch_start ( void  )

Definition at line 125 of file pgarch.c.

References Assert, av, ClosePostmasterPorts(), dsm_detach_all(), ereport, errmsg(), fork_process(), InitPostmasterChild(), last_pgarch_start_time, lengthof, LOG, NON_EXEC_STATIC, PGARCH_RESTART_INTERVAL, PgArchiverMain(), PGSharedMemoryDetach(), and XLogArchivingActive.

Referenced by reaper(), ServerLoop(), and sigusr1_handler().

126 {
127  time_t curtime;
128  pid_t pgArchPid;
129 
130  /*
131  * Do nothing if no archiver needed
132  */
133  if (!XLogArchivingActive())
134  return 0;
135 
136  /*
137  * Do nothing if too soon since last archiver start. This is a safety
138  * valve to protect against continuous respawn attempts if the archiver is
139  * dying immediately at launch. Note that since we will be re-called from
140  * the postmaster main loop, we will get another chance later.
141  */
142  curtime = time(NULL);
143  if ((unsigned int) (curtime - last_pgarch_start_time) <
144  (unsigned int) PGARCH_RESTART_INTERVAL)
145  return 0;
146  last_pgarch_start_time = curtime;
147 
148 #ifdef EXEC_BACKEND
149  switch ((pgArchPid = pgarch_forkexec()))
150 #else
151  switch ((pgArchPid = fork_process()))
152 #endif
153  {
154  case -1:
155  ereport(LOG,
156  (errmsg("could not fork archiver: %m")));
157  return 0;
158 
159 #ifndef EXEC_BACKEND
160  case 0:
161  /* in postmaster child ... */
163 
164  /* Close the postmaster's sockets */
165  ClosePostmasterPorts(false);
166 
167  /* Drop our connection to postmaster's shared memory, as well */
168  dsm_detach_all();
170 
171  PgArchiverMain(0, NULL);
172  break;
173 #endif
174 
175  default:
176  return (int) pgArchPid;
177  }
178 
179  /* shouldn't get here */
180  return 0;
181 }
void InitPostmasterChild(void)
Definition: miscinit.c:273
#define PGARCH_RESTART_INTERVAL
Definition: pgarch.c:61
pid_t fork_process(void)
Definition: fork_process.c:32
static time_t last_pgarch_start_time
Definition: pgarch.c:81
#define LOG
Definition: elog.h:26
void ClosePostmasterPorts(bool am_syslogger)
Definition: postmaster.c:2541
void PGSharedMemoryDetach(void)
Definition: sysv_shmem.c:881
#define ereport(elevel, rest)
Definition: elog.h:141
#define XLogArchivingActive()
Definition: xlog.h:170
void dsm_detach_all(void)
Definition: dsm.c:636
int errmsg(const char *fmt,...)
Definition: elog.c:822
NON_EXEC_STATIC void PgArchiverMain(int argc, char *argv[]) pg_attribute_noreturn()
Definition: pgarch.c:223

◆ pgarch_waken()

static void pgarch_waken ( SIGNAL_ARGS  )
static

Definition at line 261 of file pgarch.c.

References MyLatch, SetLatch(), and wakened.

Referenced by PgArchiverMain().

262 {
263  int save_errno = errno;
264 
265  /* set flag that there is work to be done */
266  wakened = true;
267  SetLatch(MyLatch);
268 
269  errno = save_errno;
270 }
void SetLatch(Latch *latch)
Definition: latch.c:436
static volatile sig_atomic_t wakened
Definition: pgarch.c:87
struct Latch * MyLatch
Definition: globals.c:54

◆ pgarch_waken_stop()

static void pgarch_waken_stop ( SIGNAL_ARGS  )
static

Definition at line 274 of file pgarch.c.

References MyLatch, ready_to_stop, and SetLatch().

Referenced by PgArchiverMain().

275 {
276  int save_errno = errno;
277 
278  /* set flag to do a final cycle and shut down afterwards */
279  ready_to_stop = true;
280  SetLatch(MyLatch);
281 
282  errno = save_errno;
283 }
void SetLatch(Latch *latch)
Definition: latch.c:436
struct Latch * MyLatch
Definition: globals.c:54
static volatile sig_atomic_t ready_to_stop
Definition: pgarch.c:88

◆ PgArchiverMain()

NON_EXEC_STATIC void PgArchiverMain ( int  argc,
char *  argv[] 
)

Definition at line 223 of file pgarch.c.

References init_ps_display(), PG_SETMASK, pgarch_exit(), pgarch_MainLoop(), pgarch_waken(), pgarch_waken_stop(), pqsignal(), SIG_DFL, SIG_IGN, SIGALRM, SIGCHLD, SIGHUP, SignalHandlerForConfigReload(), SignalHandlerForShutdownRequest(), SIGPIPE, SIGQUIT, SIGUSR1, SIGUSR2, and UnBlockSig.

Referenced by BackendRun(), and pgarch_start().

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);
237  /* Reset some signals that are accepted by postmaster but not here */
240 
241  /*
242  * Identify myself via ps
243  */
244  init_ps_display("archiver", "", "", "");
245 
246  pgarch_MainLoop();
247 
248  exit(0);
249 }
#define SIGQUIT
Definition: win32_port.h:155
static void pgarch_exit(SIGNAL_ARGS)
Definition: pgarch.c:253
#define SIGUSR1
Definition: win32_port.h:166
#define SIGCHLD
Definition: win32_port.h:164
void SignalHandlerForConfigReload(SIGNAL_ARGS)
Definition: interrupt.c:56
static void pgarch_waken_stop(SIGNAL_ARGS)
Definition: pgarch.c:274
#define SIGPIPE
Definition: win32_port.h:159
#define SIGUSR2
Definition: win32_port.h:167
#define PG_SETMASK(mask)
Definition: pqsignal.h:19
#define SIGHUP
Definition: win32_port.h:154
sigset_t UnBlockSig
Definition: pqsignal.c:22
void SignalHandlerForShutdownRequest(SIGNAL_ARGS)
Definition: interrupt.c:104
#define SIG_IGN
Definition: win32_port.h:151
static void pgarch_MainLoop(void)
Definition: pgarch.c:291
pqsigfunc pqsignal(int signum, pqsigfunc handler)
Definition: signal.c:170
#define SIG_DFL
Definition: win32_port.h:149
#define SIGALRM
Definition: win32_port.h:160
static void pgarch_waken(SIGNAL_ARGS)
Definition: pgarch.c:261
void init_ps_display(const char *username, const char *dbname, const char *host_info, const char *initial_str)
Definition: ps_status.c:253

Variable Documentation

◆ last_pgarch_start_time

time_t last_pgarch_start_time
static

Definition at line 81 of file pgarch.c.

Referenced by pgarch_start().

◆ last_sigterm_time

time_t last_sigterm_time = 0
static

Definition at line 82 of file pgarch.c.

Referenced by pgarch_MainLoop().

◆ ready_to_stop

volatile sig_atomic_t ready_to_stop = false
static

Definition at line 88 of file pgarch.c.

Referenced by pgarch_MainLoop(), and pgarch_waken_stop().

◆ wakened

volatile sig_atomic_t wakened = false
static

Definition at line 87 of file pgarch.c.

Referenced by pgarch_MainLoop(), and pgarch_waken().