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

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

Referenced by pgarch_ArchiverCopyLoop().

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

◆ pgarch_ArchiverCopyLoop()

static void pgarch_ArchiverCopyLoop ( void  )
static

Definition at line 389 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().

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

◆ pgarch_archiveXlog()

static bool pgarch_archiveXlog ( char *  xlog)
static

Definition at line 520 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().

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

◆ pgarch_exit()

static void pgarch_exit ( SIGNAL_ARGS  )
static

Definition at line 251 of file pgarch.c.

Referenced by PgArchiverMain().

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

◆ pgarch_MainLoop()

static void pgarch_MainLoop ( void  )
static

Definition at line 289 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().

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

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

◆ 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:91
#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:2559
void PGSharedMemoryDetach(void)
Definition: sysv_shmem.c:881
#define ereport(elevel,...)
Definition: elog.h:144
#define XLogArchivingActive()
Definition: xlog.h:180
void dsm_detach_all(void)
Definition: dsm.c:630
int errmsg(const char *fmt,...)
Definition: elog.c:824
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 259 of file pgarch.c.

References MyLatch, SetLatch(), and wakened.

Referenced by PgArchiverMain().

260 {
261  int save_errno = errno;
262 
263  /* set flag that there is work to be done */
264  wakened = true;
265  SetLatch(MyLatch);
266 
267  errno = save_errno;
268 }
void SetLatch(Latch *latch)
Definition: latch.c:457
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 272 of file pgarch.c.

References MyLatch, ready_to_stop, and SetLatch().

Referenced by PgArchiverMain().

273 {
274  int save_errno = errno;
275 
276  /* set flag to do a final cycle and shut down afterwards */
277  ready_to_stop = true;
278  SetLatch(MyLatch);
279 
280  errno = save_errno;
281 }
void SetLatch(Latch *latch)
Definition: latch.c:457
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 B_ARCHIVER, init_ps_display(), MyBackendType, 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 
242  init_ps_display(NULL);
243 
244  pgarch_MainLoop();
245 
246  exit(0);
247 }
#define SIGQUIT
Definition: win32_port.h:154
static void pgarch_exit(SIGNAL_ARGS)
Definition: pgarch.c:251
#define SIGUSR1
Definition: win32_port.h:165
BackendType MyBackendType
Definition: miscinit.c:60
#define SIGCHLD
Definition: win32_port.h:163
void SignalHandlerForConfigReload(SIGNAL_ARGS)
Definition: interrupt.c:56
static void pgarch_waken_stop(SIGNAL_ARGS)
Definition: pgarch.c:272
#define SIGPIPE
Definition: win32_port.h:158
#define SIGUSR2
Definition: win32_port.h:166
#define PG_SETMASK(mask)
Definition: pqsignal.h:19
#define SIGHUP
Definition: win32_port.h:153
sigset_t UnBlockSig
Definition: pqsignal.c:22
void SignalHandlerForShutdownRequest(SIGNAL_ARGS)
Definition: interrupt.c:104
#define SIG_IGN
Definition: win32_port.h:150
static void pgarch_MainLoop(void)
Definition: pgarch.c:289
pqsigfunc pqsignal(int signum, pqsigfunc handler)
Definition: signal.c:170
#define SIG_DFL
Definition: win32_port.h:148
#define SIGALRM
Definition: win32_port.h:159
void init_ps_display(const char *fixed_part)
Definition: ps_status.c:258
static void pgarch_waken(SIGNAL_ARGS)
Definition: pgarch.c:259

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().