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

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

Referenced by pgarch_ArchiverCopyLoop().

739 {
740  char rlogready[MAXPGPATH];
741  char rlogdone[MAXPGPATH];
742 
743  StatusFilePath(rlogready, xlog, ".ready");
744  StatusFilePath(rlogdone, xlog, ".done");
745  (void) durable_rename(rlogready, rlogdone, WARNING);
746 }
#define StatusFilePath(path, xlog, suffix)
#define MAXPGPATH
int durable_rename(const char *oldfile, const char *newfile, int elevel)
Definition: fd.c:659
#define WARNING
Definition: elog.h:40

◆ pgarch_ArchiverCopyLoop()

static void pgarch_ArchiverCopyLoop ( void  )
static

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

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

◆ pgarch_archiveXlog()

static bool pgarch_archiveXlog ( char *  xlog)
static

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

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

◆ pgarch_MainLoop()

static void pgarch_MainLoop ( void  )
static

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

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

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

◆ pgarch_start()

int pgarch_start ( void  )

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

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

◆ pgarch_waken()

static void pgarch_waken ( SIGNAL_ARGS  )
static

Definition at line 250 of file pgarch.c.

References MyLatch, SetLatch(), and wakened.

Referenced by PgArchiverMain().

251 {
252  int save_errno = errno;
253 
254  /* set flag that there is work to be done */
255  wakened = true;
256  SetLatch(MyLatch);
257 
258  errno = save_errno;
259 }
void SetLatch(Latch *latch)
Definition: latch.c:505
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 263 of file pgarch.c.

References MyLatch, ready_to_stop, and SetLatch().

Referenced by PgArchiverMain().

264 {
265  int save_errno = errno;
266 
267  /* set flag to do a final cycle and shut down afterwards */
268  ready_to_stop = true;
269  SetLatch(MyLatch);
270 
271  errno = save_errno;
272 }
void SetLatch(Latch *latch)
Definition: latch.c:505
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 222 of file pgarch.c.

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

Referenced by BackendRun(), and pgarch_start().

223 {
224  /*
225  * Ignore all signals usually bound to some action in the postmaster,
226  * except for SIGHUP, SIGTERM, SIGUSR1, SIGUSR2, and SIGQUIT.
227  */
229  pqsignal(SIGINT, SIG_IGN);
231  /* SIGQUIT handler was already set up by InitPostmasterChild */
236  /* Reset some signals that are accepted by postmaster but not here */
239 
241  init_ps_display(NULL);
242 
243  pgarch_MainLoop();
244 
245  exit(0);
246 }
#define SIGUSR1
Definition: win32_port.h:171
BackendType MyBackendType
Definition: miscinit.c:62
#define SIGCHLD
Definition: win32_port.h:169
void SignalHandlerForConfigReload(SIGNAL_ARGS)
Definition: interrupt.c:56
static void pgarch_waken_stop(SIGNAL_ARGS)
Definition: pgarch.c:263
#define SIGPIPE
Definition: win32_port.h:164
#define SIGUSR2
Definition: win32_port.h:172
#define PG_SETMASK(mask)
Definition: pqsignal.h:19
#define SIGHUP
Definition: win32_port.h:159
sigset_t UnBlockSig
Definition: pqsignal.c:22
void SignalHandlerForShutdownRequest(SIGNAL_ARGS)
Definition: interrupt.c:104
#define SIG_IGN
Definition: win32_port.h:156
static void pgarch_MainLoop(void)
Definition: pgarch.c:280
pqsigfunc pqsignal(int signum, pqsigfunc handler)
Definition: signal.c:170
#define SIG_DFL
Definition: win32_port.h:154
#define SIGALRM
Definition: win32_port.h:165
void init_ps_display(const char *fixed_part)
Definition: ps_status.c:258
static void pgarch_waken(SIGNAL_ARGS)
Definition: pgarch.c:250

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