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/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 "utils/guc.h"
#include "utils/ps_status.h"
Include dependency graph for pgarch.c:

Go to the source code of this file.

Data Structures

struct  PgArchData
 

Macros

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

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)
 
Size PgArchShmemSize (void)
 
void PgArchShmemInit (void)
 
bool PgArchCanRestart (void)
 
void PgArchiverMain (void)
 
void PgArchWakeup (void)
 

Variables

static time_t last_sigterm_time = 0
 
static PgArchDataPgArch = NULL
 
static volatile sig_atomic_t ready_to_stop = false
 

Macro Definition Documentation

◆ NUM_ARCHIVE_RETRIES

#define NUM_ARCHIVE_RETRIES   3

Definition at line 67 of file pgarch.c.

Referenced by pgarch_ArchiverCopyLoop().

◆ NUM_ORPHAN_CLEANUP_RETRIES

#define NUM_ORPHAN_CLEANUP_RETRIES   3

Definition at line 73 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 58 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 60 of file pgarch.c.

Referenced by PgArchCanRestart().

Typedef Documentation

◆ PgArchData

typedef struct PgArchData PgArchData

Function Documentation

◆ pgarch_archiveDone()

static void pgarch_archiveDone ( char *  xlog)
static

Definition at line 685 of file pgarch.c.

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

Referenced by pgarch_ArchiverCopyLoop().

686 {
687  char rlogready[MAXPGPATH];
688  char rlogdone[MAXPGPATH];
689 
690  StatusFilePath(rlogready, xlog, ".ready");
691  StatusFilePath(rlogdone, xlog, ".done");
692  (void) durable_rename(rlogready, rlogdone, WARNING);
693 }
#define StatusFilePath(path, xlog, suffix)
#define MAXPGPATH
int durable_rename(const char *oldfile, const char *newfile, int elevel)
Definition: fd.c:692
#define WARNING
Definition: elog.h:40

◆ pgarch_ArchiverCopyLoop()

static void pgarch_ArchiverCopyLoop ( void  )
static

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

328 {
329  char xlog[MAX_XFN_CHARS + 1];
330 
331  /*
332  * loop through all xlogs with archive_status of .ready and archive
333  * them...mostly we expect this to be a single file, though it is possible
334  * some backend will add files onto the list of those that need archiving
335  * while we are still copying earlier archives
336  */
337  while (pgarch_readyXlog(xlog))
338  {
339  int failures = 0;
340  int failures_orphan = 0;
341 
342  for (;;)
343  {
344  struct stat stat_buf;
345  char pathname[MAXPGPATH];
346 
347  /*
348  * Do not initiate any more archive commands after receiving
349  * SIGTERM, nor after the postmaster has died unexpectedly. The
350  * first condition is to try to keep from having init SIGKILL the
351  * command, and the second is to avoid conflicts with another
352  * archiver spawned by a newer postmaster.
353  */
355  return;
356 
357  /*
358  * Check for config update. This is so that we'll adopt a new
359  * setting for archive_command as soon as possible, even if there
360  * is a backlog of files to be archived.
361  */
363  {
364  ConfigReloadPending = false;
366  }
367 
368  /* can't do anything if no command ... */
369  if (!XLogArchiveCommandSet())
370  {
372  (errmsg("archive_mode enabled, yet archive_command is not set")));
373  return;
374  }
375 
376  /*
377  * Since archive status files are not removed in a durable manner,
378  * a system crash could leave behind .ready files for WAL segments
379  * that have already been recycled or removed. In this case,
380  * simply remove the orphan status file and move on. unlink() is
381  * used here as even on subsequent crashes the same orphan files
382  * would get removed, so there is no need to worry about
383  * durability.
384  */
385  snprintf(pathname, MAXPGPATH, XLOGDIR "/%s", xlog);
386  if (stat(pathname, &stat_buf) != 0 && errno == ENOENT)
387  {
388  char xlogready[MAXPGPATH];
389 
390  StatusFilePath(xlogready, xlog, ".ready");
391  if (unlink(xlogready) == 0)
392  {
394  (errmsg("removed orphan archive status file \"%s\"",
395  xlogready)));
396 
397  /* leave loop and move to the next status file */
398  break;
399  }
400 
401  if (++failures_orphan >= NUM_ORPHAN_CLEANUP_RETRIES)
402  {
404  (errmsg("removal of orphan archive status file \"%s\" failed too many times, will try again later",
405  xlogready)));
406 
407  /* give up cleanup of orphan status files */
408  return;
409  }
410 
411  /* wait a bit before retrying */
412  pg_usleep(1000000L);
413  continue;
414  }
415 
416  if (pgarch_archiveXlog(xlog))
417  {
418  /* successful */
419  pgarch_archiveDone(xlog);
420 
421  /*
422  * Tell the collector about the WAL file that we successfully
423  * archived
424  */
425  pgstat_send_archiver(xlog, false);
426 
427  break; /* out of inner retry loop */
428  }
429  else
430  {
431  /*
432  * Tell the collector about the WAL file that we failed to
433  * archive
434  */
435  pgstat_send_archiver(xlog, true);
436 
437  if (++failures >= NUM_ARCHIVE_RETRIES)
438  {
440  (errmsg("archiving write-ahead log file \"%s\" failed too many times, will try again later",
441  xlog)));
442  return; /* give up archiving for now */
443  }
444  pg_usleep(1000000L); /* wait a bit before retrying */
445  }
446  }
447  }
448 }
#define StatusFilePath(path, xlog, suffix)
#define NUM_ORPHAN_CLEANUP_RETRIES
Definition: pgarch.c:73
void ProcessConfigFile(GucContext context)
#define XLogArchiveCommandSet()
Definition: xlog.h:195
void pg_usleep(long microsec)
Definition: signal.c:53
#define MAXPGPATH
static bool pgarch_readyXlog(char *xlog)
Definition: pgarch.c:608
#define NUM_ARCHIVE_RETRIES
Definition: pgarch.c:67
static bool pgarch_archiveXlog(char *xlog)
Definition: pgarch.c:458
#define PostmasterIsAlive()
Definition: pmsignal.h:102
static void pgarch_archiveDone(char *xlog)
Definition: pgarch.c:685
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:157
void pgstat_send_archiver(const char *xlog, bool failed)
Definition: pgstat.c:3015
int errmsg(const char *fmt,...)
Definition: elog.c:909
volatile sig_atomic_t ConfigReloadPending
Definition: interrupt.c:26
#define snprintf
Definition: port.h:216
#define stat
Definition: win32_port.h:275

◆ pgarch_archiveXlog()

static bool pgarch_archiveXlog ( char *  xlog)
static

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

459 {
460  char xlogarchcmd[MAXPGPATH];
461  char pathname[MAXPGPATH];
462  char activitymsg[MAXFNAMELEN + 16];
463  char *dp;
464  char *endp;
465  const char *sp;
466  int rc;
467 
468  snprintf(pathname, MAXPGPATH, XLOGDIR "/%s", xlog);
469 
470  /*
471  * construct the command to be executed
472  */
473  dp = xlogarchcmd;
474  endp = xlogarchcmd + MAXPGPATH - 1;
475  *endp = '\0';
476 
477  for (sp = XLogArchiveCommand; *sp; sp++)
478  {
479  if (*sp == '%')
480  {
481  switch (sp[1])
482  {
483  case 'p':
484  /* %p: relative path of source file */
485  sp++;
486  strlcpy(dp, pathname, endp - dp);
487  make_native_path(dp);
488  dp += strlen(dp);
489  break;
490  case 'f':
491  /* %f: filename of source file */
492  sp++;
493  strlcpy(dp, xlog, endp - dp);
494  dp += strlen(dp);
495  break;
496  case '%':
497  /* convert %% to a single % */
498  sp++;
499  if (dp < endp)
500  *dp++ = *sp;
501  break;
502  default:
503  /* otherwise treat the % as not special */
504  if (dp < endp)
505  *dp++ = *sp;
506  break;
507  }
508  }
509  else
510  {
511  if (dp < endp)
512  *dp++ = *sp;
513  }
514  }
515  *dp = '\0';
516 
517  ereport(DEBUG3,
518  (errmsg_internal("executing archive command \"%s\"",
519  xlogarchcmd)));
520 
521  /* Report archive activity in PS display */
522  snprintf(activitymsg, sizeof(activitymsg), "archiving %s", xlog);
523  set_ps_display(activitymsg);
524 
525  rc = system(xlogarchcmd);
526  if (rc != 0)
527  {
528  /*
529  * If either the shell itself, or a called command, died on a signal,
530  * abort the archiver. We do this because system() ignores SIGINT and
531  * SIGQUIT while waiting; so a signal is very likely something that
532  * should have interrupted us too. Also die if the shell got a hard
533  * "command not found" type of error. If we overreact it's no big
534  * deal, the postmaster will just start the archiver again.
535  */
536  int lev = wait_result_is_any_signal(rc, true) ? FATAL : LOG;
537 
538  if (WIFEXITED(rc))
539  {
540  ereport(lev,
541  (errmsg("archive command failed with exit code %d",
542  WEXITSTATUS(rc)),
543  errdetail("The failed archive command was: %s",
544  xlogarchcmd)));
545  }
546  else if (WIFSIGNALED(rc))
547  {
548 #if defined(WIN32)
549  ereport(lev,
550  (errmsg("archive command was terminated by exception 0x%X",
551  WTERMSIG(rc)),
552  errhint("See C include file \"ntstatus.h\" for a description of the hexadecimal value."),
553  errdetail("The failed archive command was: %s",
554  xlogarchcmd)));
555 #else
556  ereport(lev,
557  (errmsg("archive command was terminated by signal %d: %s",
558  WTERMSIG(rc), pg_strsignal(WTERMSIG(rc))),
559  errdetail("The failed archive command was: %s",
560  xlogarchcmd)));
561 #endif
562  }
563  else
564  {
565  ereport(lev,
566  (errmsg("archive command exited with unrecognized status %d",
567  rc),
568  errdetail("The failed archive command was: %s",
569  xlogarchcmd)));
570  }
571 
572  snprintf(activitymsg, sizeof(activitymsg), "failed on %s", xlog);
573  set_ps_display(activitymsg);
574 
575  return false;
576  }
577  elog(DEBUG1, "archived write-ahead log file \"%s\"", xlog);
578 
579  snprintf(activitymsg, sizeof(activitymsg), "last was %s", xlog);
580  set_ps_display(activitymsg);
581 
582  return true;
583 }
#define DEBUG1
Definition: elog.h:25
int errhint(const char *fmt,...)
Definition: elog.c:1156
#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:49
#define MAXPGPATH
char * XLogArchiveCommand
Definition: xlog.c:98
int errdetail(const char *fmt,...)
Definition: elog.c:1042
#define MAXFNAMELEN
#define WIFEXITED(w)
Definition: win32_port.h:143
#define XLOGDIR
#define ereport(elevel,...)
Definition: elog.h:157
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45
int errmsg_internal(const char *fmt,...)
Definition: elog.c:996
const char * pg_strsignal(int signum)
Definition: pgstrsignal.c:42
int errmsg(const char *fmt,...)
Definition: elog.c:909
#define elog(elevel,...)
Definition: elog.h:232
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:216
#define WEXITSTATUS(w)
Definition: win32_port.h:145

◆ pgarch_die()

static void pgarch_die ( int  code,
Datum  arg 
)
static

Definition at line 702 of file pgarch.c.

References INVALID_PGPROCNO, and PgArchData::pgprocno.

Referenced by PgArchiverMain().

703 {
705 }
static PgArchData * PgArch
Definition: pgarch.c:87
#define INVALID_PGPROCNO
Definition: proc.h:80
int pgprocno
Definition: pgarch.c:78

◆ pgarch_MainLoop()

static void pgarch_MainLoop ( void  )
static

Definition at line 243 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(), WL_LATCH_SET, WL_POSTMASTER_DEATH, and WL_TIMEOUT.

Referenced by PgArchiverMain().

244 {
245  pg_time_t last_copy_time = 0;
246  bool time_to_stop;
247 
248  /*
249  * There shouldn't be anything for the archiver to do except to wait for a
250  * signal ... however, the archiver exists to protect our data, so she
251  * wakes up occasionally to allow herself to be proactive.
252  */
253  do
254  {
256 
257  /* When we get SIGUSR2, we do one more archive cycle, then exit */
258  time_to_stop = ready_to_stop;
259 
260  /* Check for config update */
262  {
263  ConfigReloadPending = false;
265  }
266 
267  /*
268  * If we've gotten SIGTERM, we normally just sit and do nothing until
269  * SIGUSR2 arrives. However, that means a random SIGTERM would
270  * disable archiving indefinitely, which doesn't seem like a good
271  * idea. If more than 60 seconds pass since SIGTERM, exit anyway, so
272  * that the postmaster can start a new archiver if needed.
273  */
275  {
276  time_t curtime = time(NULL);
277 
278  if (last_sigterm_time == 0)
279  last_sigterm_time = curtime;
280  else if ((unsigned int) (curtime - last_sigterm_time) >=
281  (unsigned int) 60)
282  break;
283  }
284 
285  /* Do what we're here for */
287  last_copy_time = time(NULL);
288 
289  /*
290  * Sleep until a signal is received, or until a poll is forced by
291  * PGARCH_AUTOWAKE_INTERVAL having passed since last_copy_time, or
292  * until postmaster dies.
293  */
294  if (!time_to_stop) /* Don't wait during last iteration */
295  {
296  pg_time_t curtime = (pg_time_t) time(NULL);
297  int timeout;
298 
299  timeout = PGARCH_AUTOWAKE_INTERVAL - (curtime - last_copy_time);
300  if (timeout > 0)
301  {
302  int rc;
303 
304  rc = WaitLatch(MyLatch,
306  timeout * 1000L,
308  if (rc & WL_POSTMASTER_DEATH)
309  time_to_stop = true;
310  }
311  }
312 
313  /*
314  * The archiver quits either when the postmaster dies (not expected)
315  * or after completing one more archiving cycle after receiving
316  * SIGUSR2.
317  */
318  } while (!time_to_stop);
319 }
int64 pg_time_t
Definition: pgtime.h:23
#define WL_TIMEOUT
Definition: latch.h:128
void ProcessConfigFile(GucContext context)
static time_t last_sigterm_time
Definition: pgarch.c:86
void ResetLatch(Latch *latch)
Definition: latch.c:660
#define PGARCH_AUTOWAKE_INTERVAL
Definition: pgarch.c:58
int WaitLatch(Latch *latch, int wakeEvents, long timeout, uint32 wait_event_info)
Definition: latch.c:452
static void pgarch_ArchiverCopyLoop(void)
Definition: pgarch.c:327
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:129
volatile sig_atomic_t ConfigReloadPending
Definition: interrupt.c:26
struct Latch * MyLatch
Definition: globals.c:57
static volatile sig_atomic_t ready_to_stop
Definition: pgarch.c:92
#define WL_LATCH_SET
Definition: latch.h:125

◆ pgarch_readyXlog()

static bool pgarch_readyXlog ( char *  xlog)
static

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

609 {
610  /*
611  * open xlog status directory and read through list of xlogs that have the
612  * .ready suffix, looking for earliest file. It is possible to optimise
613  * this code, though only a single file is expected on the vast majority
614  * of calls, so....
615  */
616  char XLogArchiveStatusDir[MAXPGPATH];
617  DIR *rldir;
618  struct dirent *rlde;
619  bool found = false;
620  bool historyFound = false;
621 
622  snprintf(XLogArchiveStatusDir, MAXPGPATH, XLOGDIR "/archive_status");
623  rldir = AllocateDir(XLogArchiveStatusDir);
624 
625  while ((rlde = ReadDir(rldir, XLogArchiveStatusDir)) != NULL)
626  {
627  int basenamelen = (int) strlen(rlde->d_name) - 6;
628  char basename[MAX_XFN_CHARS + 1];
629  bool ishistory;
630 
631  /* Ignore entries with unexpected number of characters */
632  if (basenamelen < MIN_XFN_CHARS ||
633  basenamelen > MAX_XFN_CHARS)
634  continue;
635 
636  /* Ignore entries with unexpected characters */
637  if (strspn(rlde->d_name, VALID_XFN_CHARS) < basenamelen)
638  continue;
639 
640  /* Ignore anything not suffixed with .ready */
641  if (strcmp(rlde->d_name + basenamelen, ".ready") != 0)
642  continue;
643 
644  /* Truncate off the .ready */
645  memcpy(basename, rlde->d_name, basenamelen);
646  basename[basenamelen] = '\0';
647 
648  /* Is this a history file? */
649  ishistory = IsTLHistoryFileName(basename);
650 
651  /*
652  * Consume the file to archive. History files have the highest
653  * priority. If this is the first file or the first history file
654  * ever, copy it. In the presence of a history file already chosen as
655  * target, ignore all other files except history files which have been
656  * generated for an older timeline than what is already chosen as
657  * target to archive.
658  */
659  if (!found || (ishistory && !historyFound))
660  {
661  strcpy(xlog, basename);
662  found = true;
663  historyFound = ishistory;
664  }
665  else if (ishistory || !historyFound)
666  {
667  if (strcmp(basename, xlog) < 0)
668  strcpy(xlog, basename);
669  }
670  }
671  FreeDir(rldir);
672 
673  return found;
674 }
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:2634
#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:2700
#define IsTLHistoryFileName(fname)
char d_name[MAX_PATH]
Definition: dirent.h:15
#define snprintf
Definition: port.h:216
int FreeDir(DIR *dir)
Definition: fd.c:2752

◆ pgarch_waken_stop()

static void pgarch_waken_stop ( SIGNAL_ARGS  )
static

Definition at line 226 of file pgarch.c.

References MyLatch, ready_to_stop, and SetLatch().

Referenced by PgArchiverMain().

227 {
228  int save_errno = errno;
229 
230  /* set flag to do a final cycle and shut down afterwards */
231  ready_to_stop = true;
232  SetLatch(MyLatch);
233 
234  errno = save_errno;
235 }
void SetLatch(Latch *latch)
Definition: latch.c:567
struct Latch * MyLatch
Definition: globals.c:57
static volatile sig_atomic_t ready_to_stop
Definition: pgarch.c:92

◆ PgArchCanRestart()

bool PgArchCanRestart ( void  )

Definition at line 147 of file pgarch.c.

References PGARCH_RESTART_INTERVAL.

148 {
149  static time_t last_pgarch_start_time = 0;
150  time_t curtime = time(NULL);
151 
152  /*
153  * Return false and don't restart archiver if too soon since last archiver
154  * start.
155  */
156  if ((unsigned int) (curtime - last_pgarch_start_time) <
157  (unsigned int) PGARCH_RESTART_INTERVAL)
158  return false;
159 
160  last_pgarch_start_time = curtime;
161  return true;
162 }
#define PGARCH_RESTART_INTERVAL
Definition: pgarch.c:60

◆ PgArchiverMain()

void PgArchiverMain ( void  )

Definition at line 167 of file pgarch.c.

References Assert, MyProc, on_shmem_exit(), PG_SETMASK, pgarch_die(), pgarch_MainLoop(), pgarch_waken_stop(), PgArchData::pgprocno, PGPROC::pgprocno, pqsignal(), proc_exit(), procsignal_sigusr1_handler(), SIG_DFL, SIG_IGN, SIGALRM, SIGCHLD, SIGHUP, SignalHandlerForConfigReload(), SignalHandlerForShutdownRequest(), SIGPIPE, SIGUSR1, SIGUSR2, UnBlockSig, and XLogArchivingActive.

Referenced by AuxiliaryProcessMain().

168 {
169  /*
170  * Ignore all signals usually bound to some action in the postmaster,
171  * except for SIGHUP, SIGTERM, SIGUSR1, SIGUSR2, and SIGQUIT.
172  */
174  pqsignal(SIGINT, SIG_IGN);
176  /* SIGQUIT handler was already set up by InitPostmasterChild */
181 
182  /* Reset some signals that are accepted by postmaster but not here */
184 
185  /* Unblock signals (they were blocked when the postmaster forked us) */
187 
188  /* We shouldn't be launched unnecessarily. */
190 
191  /* Arrange to clean up at archiver exit */
193 
194  /*
195  * Advertise our pgprocno so that backends can use our latch to wake us up
196  * while we're sleeping.
197  */
199 
200  pgarch_MainLoop();
201 
202  proc_exit(0);
203 }
static PgArchData * PgArch
Definition: pgarch.c:87
#define SIGUSR1
Definition: win32_port.h:171
#define SIGCHLD
Definition: win32_port.h:169
PGPROC * MyProc
Definition: proc.c:68
void SignalHandlerForConfigReload(SIGNAL_ARGS)
Definition: interrupt.c:56
void proc_exit(int code)
Definition: ipc.c:104
static void pgarch_waken_stop(SIGNAL_ARGS)
Definition: pgarch.c:226
#define SIGPIPE
Definition: win32_port.h:164
#define SIGUSR2
Definition: win32_port.h:172
#define PG_SETMASK(mask)
Definition: pqsignal.h:19
static void pgarch_die(int code, Datum arg)
Definition: pgarch.c:702
void on_shmem_exit(pg_on_exit_callback function, Datum arg)
Definition: ipc.c:361
#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:243
pqsigfunc pqsignal(int signum, pqsigfunc handler)
Definition: signal.c:170
#define SIG_DFL
Definition: win32_port.h:154
#define Assert(condition)
Definition: c.h:804
#define XLogArchivingActive()
Definition: xlog.h:190
#define SIGALRM
Definition: win32_port.h:165
int pgprocno
Definition: pgarch.c:78
int pgprocno
Definition: proc.h:150
void procsignal_sigusr1_handler(SIGNAL_ARGS)
Definition: procsignal.c:642

◆ PgArchShmemInit()

void PgArchShmemInit ( void  )

Definition at line 119 of file pgarch.c.

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

Referenced by CreateSharedMemoryAndSemaphores().

120 {
121  bool found;
122 
123  PgArch = (PgArchData *)
124  ShmemInitStruct("Archiver Data", PgArchShmemSize(), &found);
125 
126  if (!found)
127  {
128  /* First time through, so initialize */
131  }
132 }
Size PgArchShmemSize(void)
Definition: pgarch.c:108
static PgArchData * PgArch
Definition: pgarch.c:87
#define MemSet(start, val, len)
Definition: c.h:1008
void * ShmemInitStruct(const char *name, Size size, bool *foundPtr)
Definition: shmem.c:396
#define INVALID_PGPROCNO
Definition: proc.h:80
int pgprocno
Definition: pgarch.c:78

◆ PgArchShmemSize()

Size PgArchShmemSize ( void  )

Definition at line 108 of file pgarch.c.

References add_size().

Referenced by CreateSharedMemoryAndSemaphores(), and PgArchShmemInit().

109 {
110  Size size = 0;
111 
112  size = add_size(size, sizeof(PgArchData));
113 
114  return size;
115 }
Size add_size(Size s1, Size s2)
Definition: shmem.c:502
size_t Size
Definition: c.h:540

◆ PgArchWakeup()

void PgArchWakeup ( void  )

Definition at line 209 of file pgarch.c.

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

Referenced by XLogArchiveNotify().

210 {
211  int arch_pgprocno = PgArch->pgprocno;
212 
213  /*
214  * We don't acquire ProcArrayLock here. It's actually fine because
215  * procLatch isn't ever freed, so we just can potentially set the wrong
216  * process' (or no process') latch. Even in that case the archiver will
217  * be relaunched shortly and will start archiving.
218  */
219  if (arch_pgprocno != INVALID_PGPROCNO)
220  SetLatch(&ProcGlobal->allProcs[arch_pgprocno].procLatch);
221 }
static PgArchData * PgArch
Definition: pgarch.c:87
PROC_HDR * ProcGlobal
Definition: proc.c:80
void SetLatch(Latch *latch)
Definition: latch.c:567
Latch procLatch
Definition: proc.h:130
#define INVALID_PGPROCNO
Definition: proc.h:80
int pgprocno
Definition: pgarch.c:78
PGPROC * allProcs
Definition: proc.h:318

Variable Documentation

◆ last_sigterm_time

time_t last_sigterm_time = 0
static

Definition at line 86 of file pgarch.c.

Referenced by pgarch_MainLoop().

◆ PgArch

PgArchData* PgArch = NULL
static

Definition at line 87 of file pgarch.c.

◆ ready_to_stop

volatile sig_atomic_t ready_to_stop = false
static

Definition at line 92 of file pgarch.c.

Referenced by pgarch_MainLoop(), and pgarch_waken_stop().