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)
 
static void HandlePgArchInterrupts (void)
 
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

◆ HandlePgArchInterrupts()

static void HandlePgArchInterrupts ( void  )
static

Definition at line 708 of file pgarch.c.

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

Referenced by pgarch_ArchiverCopyLoop(), and pgarch_MainLoop().

709 {
712 
714  {
715  ConfigReloadPending = false;
717  }
718 }
void ProcessConfigFile(GucContext context)
void ProcessProcSignalBarrier(void)
Definition: procsignal.c:453
Definition: guc.h:72
volatile sig_atomic_t ProcSignalBarrierPending
Definition: globals.c:37
volatile sig_atomic_t ConfigReloadPending
Definition: interrupt.c:26

◆ pgarch_archiveDone()

static void pgarch_archiveDone ( char *  xlog)
static

Definition at line 678 of file pgarch.c.

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

Referenced by pgarch_ArchiverCopyLoop().

679 {
680  char rlogready[MAXPGPATH];
681  char rlogdone[MAXPGPATH];
682 
683  StatusFilePath(rlogready, xlog, ".ready");
684  StatusFilePath(rlogdone, xlog, ".done");
685  (void) durable_rename(rlogready, rlogdone, WARNING);
686 }
#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 324 of file pgarch.c.

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

Referenced by pgarch_MainLoop().

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

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

References INVALID_PGPROCNO, and PgArchData::pgprocno.

Referenced by PgArchiverMain().

696 {
698 }
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 244 of file pgarch.c.

References HandlePgArchInterrupts(), last_sigterm_time, MyLatch, pgarch_ArchiverCopyLoop(), PGARCH_AUTOWAKE_INTERVAL, ready_to_stop, ResetLatch(), ShutdownRequestPending, time_to_stop, WAIT_EVENT_ARCHIVER_MAIN, WaitLatch(), WL_LATCH_SET, WL_POSTMASTER_DEATH, and WL_TIMEOUT.

Referenced by PgArchiverMain().

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

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

◆ pgarch_waken_stop()

static void pgarch_waken_stop ( SIGNAL_ARGS  )
static

Definition at line 227 of file pgarch.c.

References MyLatch, ready_to_stop, and SetLatch().

Referenced by PgArchiverMain().

228 {
229  int save_errno = errno;
230 
231  /* set flag to do a final cycle and shut down afterwards */
232  ready_to_stop = true;
233  SetLatch(MyLatch);
234 
235  errno = save_errno;
236 }
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 148 of file pgarch.c.

References PGARCH_RESTART_INTERVAL.

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

◆ PgArchiverMain()

void PgArchiverMain ( void  )

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

169 {
170  /*
171  * Ignore all signals usually bound to some action in the postmaster,
172  * except for SIGHUP, SIGTERM, SIGUSR1, SIGUSR2, and SIGQUIT.
173  */
175  pqsignal(SIGINT, SIG_IGN);
177  /* SIGQUIT handler was already set up by InitPostmasterChild */
182 
183  /* Reset some signals that are accepted by postmaster but not here */
185 
186  /* Unblock signals (they were blocked when the postmaster forked us) */
188 
189  /* We shouldn't be launched unnecessarily. */
191 
192  /* Arrange to clean up at archiver exit */
194 
195  /*
196  * Advertise our pgprocno so that backends can use our latch to wake us up
197  * while we're sleeping.
198  */
200 
201  pgarch_MainLoop();
202 
203  proc_exit(0);
204 }
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:227
#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:695
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:244
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:197
#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 120 of file pgarch.c.

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

Referenced by CreateSharedMemoryAndSemaphores().

121 {
122  bool found;
123 
124  PgArch = (PgArchData *)
125  ShmemInitStruct("Archiver Data", PgArchShmemSize(), &found);
126 
127  if (!found)
128  {
129  /* First time through, so initialize */
132  }
133 }
Size PgArchShmemSize(void)
Definition: pgarch.c:109
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 109 of file pgarch.c.

References add_size().

Referenced by CreateSharedMemoryAndSemaphores(), and PgArchShmemInit().

110 {
111  Size size = 0;
112 
113  size = add_size(size, sizeof(PgArchData));
114 
115  return size;
116 }
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 210 of file pgarch.c.

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

Referenced by XLogArchiveNotify().

211 {
212  int arch_pgprocno = PgArch->pgprocno;
213 
214  /*
215  * We don't acquire ProcArrayLock here. It's actually fine because
216  * procLatch isn't ever freed, so we just can potentially set the wrong
217  * process' (or no process') latch. Even in that case the archiver will
218  * be relaunched shortly and will start archiving.
219  */
220  if (arch_pgprocno != INVALID_PGPROCNO)
221  SetLatch(&ProcGlobal->allProcs[arch_pgprocno].procLatch);
222 }
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().