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/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 ArchSigHupHandler (SIGNAL_ARGS)
 
static void ArchSigTermHandler (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 got_SIGHUP = false
 
static volatile sig_atomic_t got_SIGTERM = false
 
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 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 pgarch_start().

Function Documentation

◆ ArchSigHupHandler()

static void ArchSigHupHandler ( SIGNAL_ARGS  )
static

Definition at line 264 of file pgarch.c.

References got_SIGHUP, MyLatch, and SetLatch().

Referenced by PgArchiverMain().

265 {
266  int save_errno = errno;
267 
268  /* set flag to re-read config file at next convenient time */
269  got_SIGHUP = true;
270  SetLatch(MyLatch);
271 
272  errno = save_errno;
273 }
void SetLatch(Latch *latch)
Definition: latch.c:436
static volatile sig_atomic_t got_SIGHUP
Definition: pgarch.c:86
struct Latch * MyLatch
Definition: globals.c:54

◆ ArchSigTermHandler()

static void ArchSigTermHandler ( SIGNAL_ARGS  )
static

Definition at line 277 of file pgarch.c.

References got_SIGTERM, MyLatch, and SetLatch().

Referenced by PgArchiverMain().

278 {
279  int save_errno = errno;
280 
281  /*
282  * The postmaster never sends us SIGTERM, so we assume that this means
283  * that init is trying to shut down the whole system. If we hang around
284  * too long we'll get SIGKILL'd. Set flag to prevent starting any more
285  * archive commands.
286  */
287  got_SIGTERM = true;
288  SetLatch(MyLatch);
289 
290  errno = save_errno;
291 }
void SetLatch(Latch *latch)
Definition: latch.c:436
static volatile sig_atomic_t got_SIGTERM
Definition: pgarch.c:87
struct Latch * MyLatch
Definition: globals.c:54

◆ pgarch_archiveDone()

static void pgarch_archiveDone ( char *  xlog)
static

Definition at line 783 of file pgarch.c.

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

Referenced by pgarch_ArchiverCopyLoop().

784 {
785  char rlogready[MAXPGPATH];
786  char rlogdone[MAXPGPATH];
787 
788  StatusFilePath(rlogready, xlog, ".ready");
789  StatusFilePath(rlogdone, xlog, ".done");
790  (void) durable_rename(rlogready, rlogdone, WARNING);
791 }
#define StatusFilePath(path, xlog, suffix)
#define MAXPGPATH
int durable_rename(const char *oldfile, const char *newfile, int elevel)
Definition: fd.c:608
#define WARNING
Definition: elog.h:40

◆ pgarch_ArchiverCopyLoop()

static void pgarch_ArchiverCopyLoop ( void  )
static

Definition at line 425 of file pgarch.c.

References ereport, errmsg(), got_SIGHUP, got_SIGTERM, 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(), snprintf, stat, StatusFilePath, WARNING, XLogArchiveCommandSet, and XLOGDIR.

Referenced by pgarch_MainLoop().

426 {
427  char xlog[MAX_XFN_CHARS + 1];
428 
429  /*
430  * loop through all xlogs with archive_status of .ready and archive
431  * them...mostly we expect this to be a single file, though it is possible
432  * some backend will add files onto the list of those that need archiving
433  * while we are still copying earlier archives
434  */
435  while (pgarch_readyXlog(xlog))
436  {
437  int failures = 0;
438  int failures_orphan = 0;
439 
440  for (;;)
441  {
442  struct stat stat_buf;
443  char pathname[MAXPGPATH];
444 
445  /*
446  * Do not initiate any more archive commands after receiving
447  * SIGTERM, nor after the postmaster has died unexpectedly. The
448  * first condition is to try to keep from having init SIGKILL the
449  * command, and the second is to avoid conflicts with another
450  * archiver spawned by a newer postmaster.
451  */
452  if (got_SIGTERM || !PostmasterIsAlive())
453  return;
454 
455  /*
456  * Check for config update. This is so that we'll adopt a new
457  * setting for archive_command as soon as possible, even if there
458  * is a backlog of files to be archived.
459  */
460  if (got_SIGHUP)
461  {
462  got_SIGHUP = false;
464  }
465 
466  /* can't do anything if no command ... */
467  if (!XLogArchiveCommandSet())
468  {
470  (errmsg("archive_mode enabled, yet archive_command is not set")));
471  return;
472  }
473 
474  /*
475  * Since archive status files are not removed in a durable manner,
476  * a system crash could leave behind .ready files for WAL segments
477  * that have already been recycled or removed. In this case,
478  * simply remove the orphan status file and move on. unlink() is
479  * used here as even on subsequent crashes the same orphan files
480  * would get removed, so there is no need to worry about
481  * durability.
482  */
483  snprintf(pathname, MAXPGPATH, XLOGDIR "/%s", xlog);
484  if (stat(pathname, &stat_buf) != 0 && errno == ENOENT)
485  {
486  char xlogready[MAXPGPATH];
487 
488  StatusFilePath(xlogready, xlog, ".ready");
489  if (unlink(xlogready) == 0)
490  {
492  (errmsg("removed orphan archive status file \"%s\"",
493  xlogready)));
494 
495  /* leave loop and move to the next status file */
496  break;
497  }
498 
499  if (++failures_orphan >= NUM_ORPHAN_CLEANUP_RETRIES)
500  {
502  (errmsg("removal of orphan archive status file \"%s\" failed too many times, will try again later",
503  xlogready)));
504 
505  /* give up cleanup of orphan status files */
506  return;
507  }
508 
509  /* wait a bit before retrying */
510  pg_usleep(1000000L);
511  continue;
512  }
513 
514  if (pgarch_archiveXlog(xlog))
515  {
516  /* successful */
517  pgarch_archiveDone(xlog);
518 
519  /*
520  * Tell the collector about the WAL file that we successfully
521  * archived
522  */
523  pgstat_send_archiver(xlog, false);
524 
525  break; /* out of inner retry loop */
526  }
527  else
528  {
529  /*
530  * Tell the collector about the WAL file that we failed to
531  * archive
532  */
533  pgstat_send_archiver(xlog, true);
534 
535  if (++failures >= NUM_ARCHIVE_RETRIES)
536  {
538  (errmsg("archiving write-ahead log file \"%s\" failed too many times, will try again later",
539  xlog)));
540  return; /* give up archiving for now */
541  }
542  pg_usleep(1000000L); /* wait a bit before retrying */
543  }
544  }
545  }
546 }
#define StatusFilePath(path, xlog, suffix)
#define NUM_ORPHAN_CLEANUP_RETRIES
Definition: pgarch.c:73
void ProcessConfigFile(GucContext context)
#define XLogArchiveCommandSet()
Definition: xlog.h:175
static volatile sig_atomic_t got_SIGHUP
Definition: pgarch.c:86
void pg_usleep(long microsec)
Definition: signal.c:53
struct stat stat_buf
Definition: pg_standby.c:101
#define MAXPGPATH
static bool pgarch_readyXlog(char *xlog)
Definition: pgarch.c:706
#define NUM_ARCHIVE_RETRIES
Definition: pgarch.c:67
static bool pgarch_archiveXlog(char *xlog)
Definition: pgarch.c:556
#define PostmasterIsAlive()
Definition: pmsignal.h:91
static void pgarch_archiveDone(char *xlog)
Definition: pgarch.c:783
#define ereport(elevel, rest)
Definition: elog.h:141
Definition: guc.h:72
#define WARNING
Definition: elog.h:40
#define stat(a, b)
Definition: win32_port.h:264
#define XLOGDIR
#define MAX_XFN_CHARS
Definition: pgarch.h:26
static volatile sig_atomic_t got_SIGTERM
Definition: pgarch.c:87
void pgstat_send_archiver(const char *xlog, bool failed)
Definition: pgstat.c:4371
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define snprintf
Definition: port.h:192

◆ pgarch_archiveXlog()

static bool pgarch_archiveXlog ( char *  xlog)
static

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

557 {
558  char xlogarchcmd[MAXPGPATH];
559  char pathname[MAXPGPATH];
560  char activitymsg[MAXFNAMELEN + 16];
561  char *dp;
562  char *endp;
563  const char *sp;
564  int rc;
565 
566  snprintf(pathname, MAXPGPATH, XLOGDIR "/%s", xlog);
567 
568  /*
569  * construct the command to be executed
570  */
571  dp = xlogarchcmd;
572  endp = xlogarchcmd + MAXPGPATH - 1;
573  *endp = '\0';
574 
575  for (sp = XLogArchiveCommand; *sp; sp++)
576  {
577  if (*sp == '%')
578  {
579  switch (sp[1])
580  {
581  case 'p':
582  /* %p: relative path of source file */
583  sp++;
584  strlcpy(dp, pathname, endp - dp);
585  make_native_path(dp);
586  dp += strlen(dp);
587  break;
588  case 'f':
589  /* %f: filename of source file */
590  sp++;
591  strlcpy(dp, xlog, endp - dp);
592  dp += strlen(dp);
593  break;
594  case '%':
595  /* convert %% to a single % */
596  sp++;
597  if (dp < endp)
598  *dp++ = *sp;
599  break;
600  default:
601  /* otherwise treat the % as not special */
602  if (dp < endp)
603  *dp++ = *sp;
604  break;
605  }
606  }
607  else
608  {
609  if (dp < endp)
610  *dp++ = *sp;
611  }
612  }
613  *dp = '\0';
614 
615  ereport(DEBUG3,
616  (errmsg_internal("executing archive command \"%s\"",
617  xlogarchcmd)));
618 
619  /* Report archive activity in PS display */
620  snprintf(activitymsg, sizeof(activitymsg), "archiving %s", xlog);
621  set_ps_display(activitymsg, false);
622 
623  rc = system(xlogarchcmd);
624  if (rc != 0)
625  {
626  /*
627  * If either the shell itself, or a called command, died on a signal,
628  * abort the archiver. We do this because system() ignores SIGINT and
629  * SIGQUIT while waiting; so a signal is very likely something that
630  * should have interrupted us too. Also die if the shell got a hard
631  * "command not found" type of error. If we overreact it's no big
632  * deal, the postmaster will just start the archiver again.
633  */
634  int lev = wait_result_is_any_signal(rc, true) ? FATAL : LOG;
635 
636  if (WIFEXITED(rc))
637  {
638  ereport(lev,
639  (errmsg("archive command failed with exit code %d",
640  WEXITSTATUS(rc)),
641  errdetail("The failed archive command was: %s",
642  xlogarchcmd)));
643  }
644  else if (WIFSIGNALED(rc))
645  {
646 #if defined(WIN32)
647  ereport(lev,
648  (errmsg("archive command was terminated by exception 0x%X",
649  WTERMSIG(rc)),
650  errhint("See C include file \"ntstatus.h\" for a description of the hexadecimal value."),
651  errdetail("The failed archive command was: %s",
652  xlogarchcmd)));
653 #else
654  ereport(lev,
655  (errmsg("archive command was terminated by signal %d: %s",
656  WTERMSIG(rc), pg_strsignal(WTERMSIG(rc))),
657  errdetail("The failed archive command was: %s",
658  xlogarchcmd)));
659 #endif
660  }
661  else
662  {
663  ereport(lev,
664  (errmsg("archive command exited with unrecognized status %d",
665  rc),
666  errdetail("The failed archive command was: %s",
667  xlogarchcmd)));
668  }
669 
670  snprintf(activitymsg, sizeof(activitymsg), "failed on %s", xlog);
671  set_ps_display(activitymsg, false);
672 
673  return false;
674  }
675  elog(DEBUG1, "archived write-ahead log file \"%s\"", xlog);
676 
677  snprintf(activitymsg, sizeof(activitymsg), "last was %s", xlog);
678  set_ps_display(activitymsg, false);
679 
680  return true;
681 }
#define DEBUG1
Definition: elog.h:25
int errhint(const char *fmt,...)
Definition: elog.c:974
#define WTERMSIG(w)
Definition: win32_port.h:150
#define DEBUG3
Definition: elog.h:23
void make_native_path(char *path)
Definition: path.c:166
void set_ps_display(const char *activity, bool force)
Definition: ps_status.c:331
#define LOG
Definition: elog.h:26
#define FATAL
Definition: elog.h:52
#define MAXPGPATH
char * XLogArchiveCommand
Definition: xlog.c:92
int errdetail(const char *fmt,...)
Definition: elog.c:860
#define ereport(elevel, rest)
Definition: elog.h:141
#define MAXFNAMELEN
#define WIFEXITED(w)
Definition: win32_port.h:147
#define XLOGDIR
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45
int errmsg_internal(const char *fmt,...)
Definition: elog.c:814
const char * pg_strsignal(int signum)
Definition: pgstrsignal.c:37
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define elog(elevel,...)
Definition: elog.h:226
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:148
#define snprintf
Definition: port.h:192
#define WEXITSTATUS(w)
Definition: win32_port.h:149

◆ pgarch_exit()

static void pgarch_exit ( SIGNAL_ARGS  )
static

Definition at line 256 of file pgarch.c.

Referenced by PgArchiverMain().

257 {
258  /* SIGQUIT means curl up and die ... */
259  exit(1);
260 }

◆ pgarch_MainLoop()

static void pgarch_MainLoop ( void  )
static

Definition at line 325 of file pgarch.c.

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

Referenced by PgArchiverMain().

326 {
327  pg_time_t last_copy_time = 0;
328  bool time_to_stop;
329 
330  /*
331  * We run the copy loop immediately upon entry, in case there are
332  * unarchived files left over from a previous database run (or maybe the
333  * archiver died unexpectedly). After that we wait for a signal or
334  * timeout before doing more.
335  */
336  wakened = true;
337 
338  /*
339  * There shouldn't be anything for the archiver to do except to wait for a
340  * signal ... however, the archiver exists to protect our data, so she
341  * wakes up occasionally to allow herself to be proactive.
342  */
343  do
344  {
346 
347  /* When we get SIGUSR2, we do one more archive cycle, then exit */
348  time_to_stop = ready_to_stop;
349 
350  /* Check for config update */
351  if (got_SIGHUP)
352  {
353  got_SIGHUP = false;
355  }
356 
357  /*
358  * If we've gotten SIGTERM, we normally just sit and do nothing until
359  * SIGUSR2 arrives. However, that means a random SIGTERM would
360  * disable archiving indefinitely, which doesn't seem like a good
361  * idea. If more than 60 seconds pass since SIGTERM, exit anyway, so
362  * that the postmaster can start a new archiver if needed.
363  */
364  if (got_SIGTERM)
365  {
366  time_t curtime = time(NULL);
367 
368  if (last_sigterm_time == 0)
369  last_sigterm_time = curtime;
370  else if ((unsigned int) (curtime - last_sigterm_time) >=
371  (unsigned int) 60)
372  break;
373  }
374 
375  /* Do what we're here for */
376  if (wakened || time_to_stop)
377  {
378  wakened = false;
380  last_copy_time = time(NULL);
381  }
382 
383  /*
384  * Sleep until a signal is received, or until a poll is forced by
385  * PGARCH_AUTOWAKE_INTERVAL having passed since last_copy_time, or
386  * until postmaster dies.
387  */
388  if (!time_to_stop) /* Don't wait during last iteration */
389  {
390  pg_time_t curtime = (pg_time_t) time(NULL);
391  int timeout;
392 
393  timeout = PGARCH_AUTOWAKE_INTERVAL - (curtime - last_copy_time);
394  if (timeout > 0)
395  {
396  int rc;
397 
398  rc = WaitLatch(MyLatch,
400  timeout * 1000L,
402  if (rc & WL_TIMEOUT)
403  wakened = true;
404  if (rc & WL_POSTMASTER_DEATH)
405  time_to_stop = true;
406  }
407  else
408  wakened = true;
409  }
410 
411  /*
412  * The archiver quits either when the postmaster dies (not expected)
413  * or after completing one more archiving cycle after receiving
414  * SIGUSR2.
415  */
416  } while (!time_to_stop);
417 }
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:81
static volatile sig_atomic_t got_SIGHUP
Definition: pgarch.c:86
void ResetLatch(Latch *latch)
Definition: latch.c:519
#define PGARCH_AUTOWAKE_INTERVAL
Definition: pgarch.c:58
int WaitLatch(Latch *latch, int wakeEvents, long timeout, uint32 wait_event_info)
Definition: latch.c:344
static volatile sig_atomic_t wakened
Definition: pgarch.c:88
static void pgarch_ArchiverCopyLoop(void)
Definition: pgarch.c:425
static volatile bool time_to_stop
Definition: pg_receivewal.c:41
Definition: guc.h:72
#define WL_POSTMASTER_DEATH
Definition: latch.h:128
static volatile sig_atomic_t got_SIGTERM
Definition: pgarch.c:87
struct Latch * MyLatch
Definition: globals.c:54
static volatile sig_atomic_t ready_to_stop
Definition: pgarch.c:89
#define WL_LATCH_SET
Definition: latch.h:124

◆ pgarch_readyXlog()

static bool pgarch_readyXlog ( char *  xlog)
static

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

707 {
708  /*
709  * open xlog status directory and read through list of xlogs that have the
710  * .ready suffix, looking for earliest file. It is possible to optimise
711  * this code, though only a single file is expected on the vast majority
712  * of calls, so....
713  */
714  char XLogArchiveStatusDir[MAXPGPATH];
715  DIR *rldir;
716  struct dirent *rlde;
717  bool found = false;
718  bool historyFound = false;
719 
720  snprintf(XLogArchiveStatusDir, MAXPGPATH, XLOGDIR "/archive_status");
721  rldir = AllocateDir(XLogArchiveStatusDir);
722 
723  while ((rlde = ReadDir(rldir, XLogArchiveStatusDir)) != NULL)
724  {
725  int basenamelen = (int) strlen(rlde->d_name) - 6;
726  char basename[MAX_XFN_CHARS + 1];
727  bool ishistory;
728 
729  /* Ignore entries with unexpected number of characters */
730  if (basenamelen < MIN_XFN_CHARS ||
731  basenamelen > MAX_XFN_CHARS)
732  continue;
733 
734  /* Ignore entries with unexpected characters */
735  if (strspn(rlde->d_name, VALID_XFN_CHARS) < basenamelen)
736  continue;
737 
738  /* Ignore anything not suffixed with .ready */
739  if (strcmp(rlde->d_name + basenamelen, ".ready") != 0)
740  continue;
741 
742  /* Truncate off the .ready */
743  memcpy(basename, rlde->d_name, basenamelen);
744  basename[basenamelen] = '\0';
745 
746  /* Is this a history file? */
747  ishistory = IsTLHistoryFileName(basename);
748 
749  /*
750  * Consume the file to archive. History files have the highest
751  * priority. If this is the first file or the first history file
752  * ever, copy it. In the presence of a history file already chosen as
753  * target, ignore all other files except history files which have been
754  * generated for an older timeline than what is already chosen as
755  * target to archive.
756  */
757  if (!found || (ishistory && !historyFound))
758  {
759  strcpy(xlog, basename);
760  found = true;
761  historyFound = ishistory;
762  }
763  else if (ishistory || !historyFound)
764  {
765  if (strcmp(basename, xlog) < 0)
766  strcpy(xlog, basename);
767  }
768  }
769  FreeDir(rldir);
770 
771  return found;
772 }
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:2468
#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:2534
#define IsTLHistoryFileName(fname)
char d_name[MAX_PATH]
Definition: dirent.h:14
#define snprintf
Definition: port.h:192
int FreeDir(DIR *dir)
Definition: fd.c:2586

◆ pgarch_start()

int pgarch_start ( void  )

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

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

◆ pgarch_waken()

static void pgarch_waken ( SIGNAL_ARGS  )
static

Definition at line 295 of file pgarch.c.

References MyLatch, SetLatch(), and wakened.

Referenced by PgArchiverMain().

296 {
297  int save_errno = errno;
298 
299  /* set flag that there is work to be done */
300  wakened = true;
301  SetLatch(MyLatch);
302 
303  errno = save_errno;
304 }
void SetLatch(Latch *latch)
Definition: latch.c:436
static volatile sig_atomic_t wakened
Definition: pgarch.c:88
struct Latch * MyLatch
Definition: globals.c:54

◆ pgarch_waken_stop()

static void pgarch_waken_stop ( SIGNAL_ARGS  )
static

Definition at line 308 of file pgarch.c.

References MyLatch, ready_to_stop, and SetLatch().

Referenced by PgArchiverMain().

309 {
310  int save_errno = errno;
311 
312  /* set flag to do a final cycle and shut down afterwards */
313  ready_to_stop = true;
314  SetLatch(MyLatch);
315 
316  errno = save_errno;
317 }
void SetLatch(Latch *latch)
Definition: latch.c:436
struct Latch * MyLatch
Definition: globals.c:54
static volatile sig_atomic_t ready_to_stop
Definition: pgarch.c:89

◆ PgArchiverMain()

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

Definition at line 226 of file pgarch.c.

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

Referenced by BackendRun(), and pgarch_start().

227 {
228  /*
229  * Ignore all signals usually bound to some action in the postmaster,
230  * except for SIGHUP, SIGTERM, SIGUSR1, SIGUSR2, and SIGQUIT.
231  */
233  pqsignal(SIGINT, SIG_IGN);
234  pqsignal(SIGTERM, ArchSigTermHandler);
240  /* Reset some signals that are accepted by postmaster but not here */
243 
244  /*
245  * Identify myself via ps
246  */
247  init_ps_display("archiver", "", "", "");
248 
249  pgarch_MainLoop();
250 
251  exit(0);
252 }
#define SIGQUIT
Definition: win32_port.h:164
static void ArchSigTermHandler(SIGNAL_ARGS)
Definition: pgarch.c:277
static void pgarch_exit(SIGNAL_ARGS)
Definition: pgarch.c:256
#define SIGUSR1
Definition: win32_port.h:175
#define SIGCHLD
Definition: win32_port.h:173
static void pgarch_waken_stop(SIGNAL_ARGS)
Definition: pgarch.c:308
#define SIGPIPE
Definition: win32_port.h:168
#define SIGUSR2
Definition: win32_port.h:176
#define PG_SETMASK(mask)
Definition: pqsignal.h:19
#define SIGHUP
Definition: win32_port.h:163
sigset_t UnBlockSig
Definition: pqsignal.c:22
#define SIG_IGN
Definition: win32_port.h:160
static void pgarch_MainLoop(void)
Definition: pgarch.c:325
pqsigfunc pqsignal(int signum, pqsigfunc handler)
Definition: signal.c:170
#define SIG_DFL
Definition: win32_port.h:158
#define SIGALRM
Definition: win32_port.h:169
static void ArchSigHupHandler(SIGNAL_ARGS)
Definition: pgarch.c:264
static void pgarch_waken(SIGNAL_ARGS)
Definition: pgarch.c:295
void init_ps_display(const char *username, const char *dbname, const char *host_info, const char *initial_str)
Definition: ps_status.c:249

Variable Documentation

◆ got_SIGHUP

volatile sig_atomic_t got_SIGHUP = false
static

Definition at line 86 of file pgarch.c.

Referenced by ArchSigHupHandler(), pgarch_ArchiverCopyLoop(), and pgarch_MainLoop().

◆ got_SIGTERM

volatile sig_atomic_t got_SIGTERM = false
static

Definition at line 87 of file pgarch.c.

Referenced by ArchSigTermHandler(), pgarch_ArchiverCopyLoop(), and pgarch_MainLoop().

◆ last_pgarch_start_time

time_t last_pgarch_start_time
static

Definition at line 80 of file pgarch.c.

Referenced by pgarch_start().

◆ last_sigterm_time

time_t last_sigterm_time = 0
static

Definition at line 81 of file pgarch.c.

Referenced by pgarch_MainLoop().

◆ ready_to_stop

volatile sig_atomic_t ready_to_stop = false
static

Definition at line 89 of file pgarch.c.

Referenced by pgarch_MainLoop(), and pgarch_waken_stop().

◆ wakened

volatile sig_atomic_t wakened = false
static

Definition at line 88 of file pgarch.c.

Referenced by pgarch_MainLoop(), and pgarch_waken().