PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
pg_standby.c File Reference
#include "postgres_fe.h"
#include <ctype.h>
#include <dirent.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <signal.h>
#include <sys/time.h>
#include "pg_getopt.h"
#include "access/xlog_internal.h"
Include dependency graph for pg_standby.c:

Go to the source code of this file.

Macros

#define NoFailover   0
 
#define SmartFailover   1
 
#define FastFailover   2
 
#define RESTORE_COMMAND_COPY   0
 
#define RESTORE_COMMAND_LINK   1
 
#define XLOG_DATA   0
 
#define XLOG_HISTORY   1
 
#define XLOG_BACKUP_LABEL   2
 
#define SET_RESTORE_COMMAND(cmd, arg1, arg2)   snprintf(restoreCommand, MAXPGPATH, cmd " \"%s\" \"%s\"", arg1, arg2)
 
#define MaxSegmentsPerLogFile   ( 0xFFFFFFFF / XLOG_SEG_SIZE )
 

Functions

static void CustomizableInitialize (void)
 
static bool CustomizableNextWALFileReady (void)
 
static void CustomizableCleanupPriorWALFiles (void)
 
static bool SetWALFileNameForCleanup (void)
 
static void CheckForExternalTrigger (void)
 
static bool RestoreWALFileForRecovery (void)
 
static void usage (void)
 
static void sighandler (int sig)
 
static void sigquit_handler (int sig)
 
int main (int argc, char **argv)
 

Variables

const char * progname
 
int sleeptime = 5
 
int waittime = -1
 
int maxwaittime = 0
 
int keepfiles = 0
 
int maxretries = 3
 
bool debug = false
 
bool need_cleanup = false
 
static volatile sig_atomic_t signaled = false
 
char * archiveLocation
 
char * triggerPath
 
char * xlogFilePath
 
char * nextWALFileName
 
char * restartWALFileName
 
char * priorWALFileName
 
char WALFilePath [MAXPGPATH *2]
 
char restoreCommand [MAXPGPATH]
 
char exclusiveCleanupFileName [MAXFNAMELEN]
 
static int Failover = NoFailover
 
int restoreCommandType
 
int nextWALFileType
 
struct stat stat_buf
 

Macro Definition Documentation

#define FastFailover   2

Definition at line 85 of file pg_standby.c.

Referenced by CheckForExternalTrigger(), and main().

#define MaxSegmentsPerLogFile   ( 0xFFFFFFFF / XLOG_SEG_SIZE )

Definition at line 221 of file pg_standby.c.

Referenced by SetWALFileNameForCleanup().

#define NoFailover   0

Definition at line 83 of file pg_standby.c.

#define RESTORE_COMMAND_COPY   0

Definition at line 89 of file pg_standby.c.

Referenced by CustomizableInitialize(), and main().

#define RESTORE_COMMAND_LINK   1

Definition at line 90 of file pg_standby.c.

Referenced by CustomizableInitialize(), and main().

#define SET_RESTORE_COMMAND (   cmd,
  arg1,
  arg2 
)    snprintf(restoreCommand, MAXPGPATH, cmd " \"%s\" \"%s\"", arg1, arg2)

Definition at line 98 of file pg_standby.c.

Referenced by CustomizableInitialize().

#define SmartFailover   1

Definition at line 84 of file pg_standby.c.

Referenced by CheckForExternalTrigger(), and main().

#define XLOG_BACKUP_LABEL   2

Definition at line 95 of file pg_standby.c.

Referenced by CustomizableNextWALFileReady().

#define XLOG_DATA   0

Definition at line 93 of file pg_standby.c.

Referenced by CustomizableCleanupPriorWALFiles(), and CustomizableNextWALFileReady().

#define XLOG_HISTORY   1

Definition at line 94 of file pg_standby.c.

Referenced by main().

Function Documentation

static void CheckForExternalTrigger ( void  )
static

Definition at line 375 of file pg_standby.c.

References buf, close, Failover, FastFailover, fd(), ftruncate, read, SmartFailover, stat_buf, strerror(), and triggerPath.

Referenced by main().

376 {
377  char buf[32];
378  int fd;
379  int len;
380 
381  /*
382  * Look for a trigger file, if that option has been selected
383  *
384  * We use stat() here because triggerPath is always a file rather than
385  * potentially being in an archive
386  */
387  if (!triggerPath || stat(triggerPath, &stat_buf) != 0)
388  return;
389 
390  /*
391  * An empty trigger file performs smart failover. There's a little race
392  * condition here: if the writer of the trigger file has just created the
393  * file, but not yet written anything to it, we'll treat that as smart
394  * shutdown even if the other process was just about to write "fast" to
395  * it. But that's fine: we'll restore one more WAL file, and when we're
396  * invoked next time, we'll see the word "fast" and fail over immediately.
397  */
398  if (stat_buf.st_size == 0)
399  {
401  fprintf(stderr, "trigger file found: smart failover\n");
402  fflush(stderr);
403  return;
404  }
405 
406  if ((fd = open(triggerPath, O_RDWR, 0)) < 0)
407  {
408  fprintf(stderr, "WARNING: could not open \"%s\": %s\n",
409  triggerPath, strerror(errno));
410  fflush(stderr);
411  return;
412  }
413 
414  if ((len = read(fd, buf, sizeof(buf) - 1)) < 0)
415  {
416  fprintf(stderr, "WARNING: could not read \"%s\": %s\n",
417  triggerPath, strerror(errno));
418  fflush(stderr);
419  close(fd);
420  return;
421  }
422  buf[len] = '\0';
423 
424  if (strncmp(buf, "smart", 5) == 0)
425  {
427  fprintf(stderr, "trigger file found: smart failover\n");
428  fflush(stderr);
429  close(fd);
430  return;
431  }
432 
433  if (strncmp(buf, "fast", 4) == 0)
434  {
436 
437  fprintf(stderr, "trigger file found: fast failover\n");
438  fflush(stderr);
439 
440  /*
441  * Turn it into a "smart" trigger by truncating the file. Otherwise if
442  * the server asks us again to restore a segment that was restored
443  * already, we would return "not found" and upset the server.
444  */
445  if (ftruncate(fd, 0) < 0)
446  {
447  fprintf(stderr, "WARNING: could not read \"%s\": %s\n",
448  triggerPath, strerror(errno));
449  fflush(stderr);
450  }
451  close(fd);
452 
453  return;
454  }
455  close(fd);
456 
457  fprintf(stderr, "WARNING: invalid content in \"%s\"\n", triggerPath);
458  fflush(stderr);
459  return;
460 }
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define SmartFailover
Definition: pg_standby.c:84
struct stat stat_buf
Definition: pg_standby.c:101
static int Failover
Definition: pg_standby.c:87
static char * buf
Definition: pg_test_fsync.c:66
#define FastFailover
Definition: pg_standby.c:85
#define ftruncate(a, b)
Definition: win32.h:59
const char * strerror(int errnum)
Definition: strerror.c:19
char * triggerPath
Definition: pg_standby.c:55
#define close(a)
Definition: win32.h:12
#define read(a, b, c)
Definition: win32.h:13
static void CustomizableCleanupPriorWALFiles ( void  )
static

Definition at line 224 of file pg_standby.c.

References archiveLocation, closedir(), dirent::d_name, debug, exclusiveCleanupFileName, IsXLogFileName, nextWALFileType, NULL, opendir(), progname, readdir(), snprintf(), strerror(), unlink(), WALFilePath, and XLOG_DATA.

Referenced by main().

225 {
226  /*
227  * Work out name of prior file from current filename
228  */
229  if (nextWALFileType == XLOG_DATA)
230  {
231  int rc;
232  DIR *xldir;
233  struct dirent *xlde;
234 
235  /*
236  * Assume it's OK to keep failing. The failure situation may change
237  * over time, so we'd rather keep going on the main processing than
238  * fail because we couldn't clean up yet.
239  */
240  if ((xldir = opendir(archiveLocation)) != NULL)
241  {
242  while (errno = 0, (xlde = readdir(xldir)) != NULL)
243  {
244  /*
245  * We ignore the timeline part of the XLOG segment identifiers
246  * in deciding whether a segment is still needed. This
247  * ensures that we won't prematurely remove a segment from a
248  * parent timeline. We could probably be a little more
249  * proactive about removing segments of non-parent timelines,
250  * but that would be a whole lot more complicated.
251  *
252  * We use the alphanumeric sorting property of the filenames
253  * to decide which ones are earlier than the
254  * exclusiveCleanupFileName file. Note that this means files
255  * are not removed in the order they were originally written,
256  * in case this worries you.
257  */
258  if (IsXLogFileName(xlde->d_name) &&
259  strcmp(xlde->d_name + 8, exclusiveCleanupFileName + 8) < 0)
260  {
261 #ifdef WIN32
262  snprintf(WALFilePath, sizeof(WALFilePath), "%s\\%s", archiveLocation, xlde->d_name);
263 #else
264  snprintf(WALFilePath, sizeof(WALFilePath), "%s/%s", archiveLocation, xlde->d_name);
265 #endif
266 
267  if (debug)
268  fprintf(stderr, "\nremoving file \"%s\"", WALFilePath);
269 
270  rc = unlink(WALFilePath);
271  if (rc != 0)
272  {
273  fprintf(stderr, "\n%s: ERROR: could not remove file \"%s\": %s\n",
274  progname, WALFilePath, strerror(errno));
275  break;
276  }
277  }
278  }
279 
280  if (errno)
281  fprintf(stderr, "%s: could not read archive location \"%s\": %s\n",
283  if (debug)
284  fprintf(stderr, "\n");
285  }
286  else
287  fprintf(stderr, "%s: could not open archive location \"%s\": %s\n",
289 
290  if (closedir(xldir))
291  fprintf(stderr, "%s: could not close archive location \"%s\": %s\n",
293 
294  fflush(stderr);
295  }
296 }
char exclusiveCleanupFileName[MAXFNAMELEN]
Definition: pg_standby.c:62
int closedir(DIR *)
Definition: dirent.c:111
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
const char * progname
Definition: pg_standby.c:37
Definition: dirent.h:9
Definition: dirent.c:25
bool debug
Definition: pg_standby.c:46
#define IsXLogFileName(fname)
#define XLOG_DATA
Definition: pg_standby.c:93
DIR * opendir(const char *)
Definition: dirent.c:33
int unlink(const char *filename)
#define NULL
Definition: c.h:229
char WALFilePath[MAXPGPATH *2]
Definition: pg_standby.c:60
struct dirent * readdir(DIR *)
Definition: dirent.c:77
const char * strerror(int errnum)
Definition: strerror.c:19
char d_name[MAX_PATH]
Definition: dirent.h:14
char * archiveLocation
Definition: pg_standby.c:54
int nextWALFileType
Definition: pg_standby.c:96
static void CustomizableInitialize ( void  )
static

Definition at line 125 of file pg_standby.c.

References archiveLocation, MAXPGPATH, nextWALFileName, progname, RESTORE_COMMAND_COPY, RESTORE_COMMAND_LINK, restoreCommandType, SET_RESTORE_COMMAND, snprintf(), stat_buf, WALFilePath, and xlogFilePath.

Referenced by main().

126 {
127 #ifdef WIN32
129  switch (restoreCommandType)
130  {
133  break;
135  default:
137  break;
138  }
139 #else
141  switch (restoreCommandType)
142  {
144 #if HAVE_WORKING_LINK
146  break;
147 #endif
149  default:
151  break;
152  }
153 #endif
154 
155  /*
156  * This code assumes that archiveLocation is a directory You may wish to
157  * add code to check for tape libraries, etc.. So, since it is a
158  * directory, we use stat to test if it's accessible
159  */
160  if (stat(archiveLocation, &stat_buf) != 0)
161  {
162  fprintf(stderr, "%s: archive location \"%s\" does not exist\n", progname, archiveLocation);
163  fflush(stderr);
164  exit(2);
165  }
166 }
int restoreCommandType
Definition: pg_standby.c:91
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
const char * progname
Definition: pg_standby.c:37
#define RESTORE_COMMAND_COPY
Definition: pg_standby.c:89
struct stat stat_buf
Definition: pg_standby.c:101
#define MAXPGPATH
#define SET_RESTORE_COMMAND(cmd, arg1, arg2)
Definition: pg_standby.c:98
char WALFilePath[MAXPGPATH *2]
Definition: pg_standby.c:60
#define RESTORE_COMMAND_LINK
Definition: pg_standby.c:90
char * nextWALFileName
Definition: pg_standby.c:57
char * xlogFilePath
Definition: pg_standby.c:56
char * archiveLocation
Definition: pg_standby.c:54
static bool CustomizableNextWALFileReady ( void  )
static

Definition at line 174 of file pg_standby.c.

References debug, IsBackupHistoryFileName, nextWALFileName, nextWALFileType, pg_usleep(), sleeptime, stat_buf, WALFilePath, XLOG_BACKUP_LABEL, and XLOG_DATA.

Referenced by main().

175 {
176  if (stat(WALFilePath, &stat_buf) == 0)
177  {
178  /*
179  * If it's a backup file, return immediately. If it's a regular file
180  * return only if it's the right size already.
181  */
183  {
185  return true;
186  }
187  else if (stat_buf.st_size == XLOG_SEG_SIZE)
188  {
189 #ifdef WIN32
190 
191  /*
192  * Windows 'cp' sets the final file size before the copy is
193  * complete, and not yet ready to be opened by pg_standby. So we
194  * wait for sleeptime secs before attempting to restore. If that
195  * is not enough, we will rely on the retry/holdoff mechanism.
196  * GNUWin32's cp does not have this problem.
197  */
198  pg_usleep(sleeptime * 1000000L);
199 #endif
201  return true;
202  }
203 
204  /*
205  * If still too small, wait until it is the correct size
206  */
207  if (stat_buf.st_size > XLOG_SEG_SIZE)
208  {
209  if (debug)
210  {
211  fprintf(stderr, "file size greater than expected\n");
212  fflush(stderr);
213  }
214  exit(3);
215  }
216  }
217 
218  return false;
219 }
int sleeptime
Definition: pg_standby.c:40
#define XLOG_BACKUP_LABEL
Definition: pg_standby.c:95
void pg_usleep(long microsec)
Definition: signal.c:53
bool debug
Definition: pg_standby.c:46
struct stat stat_buf
Definition: pg_standby.c:101
#define XLOG_DATA
Definition: pg_standby.c:93
#define IsBackupHistoryFileName(fname)
char WALFilePath[MAXPGPATH *2]
Definition: pg_standby.c:60
char * nextWALFileName
Definition: pg_standby.c:57
int nextWALFileType
Definition: pg_standby.c:96
int main ( int  argc,
char **  argv 
)

Definition at line 548 of file pg_standby.c.

References archiveLocation, CheckForExternalTrigger(), CustomizableCleanupPriorWALFiles(), CustomizableInitialize(), CustomizableNextWALFileReady(), debug, exclusiveCleanupFileName, Failover, FastFailover, get_progname(), getopt(), IsTLHistoryFileName, keepfiles, maxretries, maxwaittime, need_cleanup, nextWALFileName, nextWALFileType, optarg, optind, pg_strdup(), pg_usleep(), pqsignal(), progname, restartWALFileName, RESTORE_COMMAND_COPY, RESTORE_COMMAND_LINK, restoreCommand, restoreCommandType, RestoreWALFileForRecovery(), SetWALFileNameForCleanup(), sighandler(), signaled, SIGQUIT, sigquit_handler(), SIGUSR1, sleeptime, SmartFailover, triggerPath, usage(), waittime, WALFilePath, XLOG_HISTORY, and xlogFilePath.

549 {
550  int c;
551 
552  progname = get_progname(argv[0]);
553 
554  if (argc > 1)
555  {
556  if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
557  {
558  usage();
559  exit(0);
560  }
561  if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0)
562  {
563  puts("pg_standby (PostgreSQL) " PG_VERSION);
564  exit(0);
565  }
566  }
567 
568 #ifndef WIN32
569 
570  /*
571  * You can send SIGUSR1 to trigger failover.
572  *
573  * Postmaster uses SIGQUIT to request immediate shutdown. The default
574  * action is to core dump, but we don't want that, so trap it and commit
575  * suicide without core dump.
576  *
577  * We used to use SIGINT and SIGQUIT to trigger failover, but that turned
578  * out to be a bad idea because postmaster uses SIGQUIT to request
579  * immediate shutdown. We still trap SIGINT, but that may change in a
580  * future release.
581  *
582  * There's no way to trigger failover via signal on Windows.
583  */
584  (void) pqsignal(SIGUSR1, sighandler);
585  (void) pqsignal(SIGINT, sighandler); /* deprecated, use SIGUSR1 */
587 #endif
588 
589  while ((c = getopt(argc, argv, "cdk:lr:s:t:w:")) != -1)
590  {
591  switch (c)
592  {
593  case 'c': /* Use copy */
595  break;
596  case 'd': /* Debug mode */
597  debug = true;
598  break;
599  case 'k': /* keepfiles */
600  keepfiles = atoi(optarg);
601  if (keepfiles < 0)
602  {
603  fprintf(stderr, "%s: -k keepfiles must be >= 0\n", progname);
604  exit(2);
605  }
606  break;
607  case 'l': /* Use link */
608 
609  /*
610  * Link feature disabled, possibly permanently. Linking causes
611  * a problem after recovery ends that is not currently
612  * resolved by PostgreSQL. 25 Jun 2009
613  */
614 #ifdef NOT_USED
616 #endif
617  break;
618  case 'r': /* Retries */
619  maxretries = atoi(optarg);
620  if (maxretries < 0)
621  {
622  fprintf(stderr, "%s: -r maxretries must be >= 0\n", progname);
623  exit(2);
624  }
625  break;
626  case 's': /* Sleep time */
627  sleeptime = atoi(optarg);
628  if (sleeptime <= 0 || sleeptime > 60)
629  {
630  fprintf(stderr, "%s: -s sleeptime incorrectly set\n", progname);
631  exit(2);
632  }
633  break;
634  case 't': /* Trigger file */
636  break;
637  case 'w': /* Max wait time */
638  maxwaittime = atoi(optarg);
639  if (maxwaittime < 0)
640  {
641  fprintf(stderr, "%s: -w maxwaittime incorrectly set\n", progname);
642  exit(2);
643  }
644  break;
645  default:
646  fprintf(stderr, "Try \"%s --help\" for more information.\n", progname);
647  exit(2);
648  break;
649  }
650  }
651 
652  /*
653  * Parameter checking - after checking to see if trigger file present
654  */
655  if (argc == 1)
656  {
657  fprintf(stderr, "%s: not enough command-line arguments\n", progname);
658  exit(2);
659  }
660 
661  /*
662  * We will go to the archiveLocation to get nextWALFileName.
663  * nextWALFileName may not exist yet, which would not be an error, so we
664  * separate the archiveLocation and nextWALFileName so we can check
665  * separately whether archiveLocation exists, if not that is an error
666  */
667  if (optind < argc)
668  {
669  archiveLocation = argv[optind];
670  optind++;
671  }
672  else
673  {
674  fprintf(stderr, "%s: must specify archive location\n", progname);
675  fprintf(stderr, "Try \"%s --help\" for more information.\n", progname);
676  exit(2);
677  }
678 
679  if (optind < argc)
680  {
681  nextWALFileName = argv[optind];
682  optind++;
683  }
684  else
685  {
686  fprintf(stderr, "%s: must specify WAL file name as second non-option argument (use \"%%f\")\n", progname);
687  fprintf(stderr, "Try \"%s --help\" for more information.\n", progname);
688  exit(2);
689  }
690 
691  if (optind < argc)
692  {
693  xlogFilePath = argv[optind];
694  optind++;
695  }
696  else
697  {
698  fprintf(stderr, "%s: must specify xlog destination as third non-option argument (use \"%%p\")\n", progname);
699  fprintf(stderr, "Try \"%s --help\" for more information.\n", progname);
700  exit(2);
701  }
702 
703  if (optind < argc)
704  {
705  restartWALFileName = argv[optind];
706  optind++;
707  }
708 
710 
712 
713  if (debug)
714  {
715  fprintf(stderr, "Trigger file: %s\n", triggerPath ? triggerPath : "<not set>");
716  fprintf(stderr, "Waiting for WAL file: %s\n", nextWALFileName);
717  fprintf(stderr, "WAL file path: %s\n", WALFilePath);
718  fprintf(stderr, "Restoring to: %s\n", xlogFilePath);
719  fprintf(stderr, "Sleep interval: %d second%s\n",
720  sleeptime, (sleeptime > 1 ? "s" : " "));
721  fprintf(stderr, "Max wait interval: %d %s\n",
722  maxwaittime, (maxwaittime > 0 ? "seconds" : "forever"));
723  fprintf(stderr, "Command for restore: %s\n", restoreCommand);
724  fprintf(stderr, "Keep archive history: ");
725  if (need_cleanup)
726  fprintf(stderr, "%s and later\n", exclusiveCleanupFileName);
727  else
728  fprintf(stderr, "no cleanup required\n");
729  fflush(stderr);
730  }
731 
732  /*
733  * Check for initial history file: always the first file to be requested
734  * It's OK if the file isn't there - all other files need to wait
735  */
737  {
740  exit(0);
741  else
742  {
743  if (debug)
744  {
745  fprintf(stderr, "history file not found\n");
746  fflush(stderr);
747  }
748  exit(1);
749  }
750  }
751 
752  /*
753  * Main wait loop
754  */
755  for (;;)
756  {
757  /* Check for trigger file or signal first */
759 #ifndef WIN32
760  if (signaled)
761  {
763  if (debug)
764  {
765  fprintf(stderr, "signaled to exit: fast failover\n");
766  fflush(stderr);
767  }
768  }
769 #endif
770 
771  /*
772  * Check for fast failover immediately, before checking if the
773  * requested WAL file is available
774  */
775  if (Failover == FastFailover)
776  exit(1);
777 
779  {
780  /*
781  * Once we have restored this file successfully we can remove some
782  * prior WAL files. If this restore fails we mustn't remove any
783  * file because some of them will be requested again immediately
784  * after the failed restore, or when we restart recovery.
785  */
787  {
788  if (need_cleanup)
790 
791  exit(0);
792  }
793  else
794  {
795  /* Something went wrong in copying the file */
796  exit(1);
797  }
798  }
799 
800  /* Check for smart failover if the next WAL file was not available */
801  if (Failover == SmartFailover)
802  exit(1);
803 
804  if (sleeptime <= 60)
805  pg_usleep(sleeptime * 1000000L);
806 
807  waittime += sleeptime;
808  if (waittime >= maxwaittime && maxwaittime > 0)
809  {
811  if (debug)
812  {
813  fprintf(stderr, "Timed out after %d seconds: fast failover\n",
814  waittime);
815  fflush(stderr);
816  }
817  }
818  if (debug)
819  {
820  fprintf(stderr, "WAL file not present yet.");
821  if (triggerPath)
822  fprintf(stderr, " Checking for trigger file...");
823  fprintf(stderr, "\n");
824  fflush(stderr);
825  }
826  }
827 }
static void usage(void)
Definition: pg_standby.c:503
#define SIGUSR1
Definition: win32.h:202
static void CheckForExternalTrigger(void)
Definition: pg_standby.c:375
int waittime
Definition: pg_standby.c:41
int keepfiles
Definition: pg_standby.c:44
const char * get_progname(const char *argv0)
Definition: path.c:453
static bool CustomizableNextWALFileReady(void)
Definition: pg_standby.c:174
int restoreCommandType
Definition: pg_standby.c:91
static void sigquit_handler(int sig)
Definition: pg_standby.c:539
char exclusiveCleanupFileName[MAXFNAMELEN]
Definition: pg_standby.c:62
int sleeptime
Definition: pg_standby.c:40
const char * progname
Definition: pg_standby.c:37
#define SIGQUIT
Definition: win32.h:189
int getopt(int nargc, char *const *nargv, const char *ostr)
Definition: getopt.c:72
static void CustomizableInitialize(void)
Definition: pg_standby.c:125
void pg_usleep(long microsec)
Definition: signal.c:53
#define SmartFailover
Definition: pg_standby.c:84
#define RESTORE_COMMAND_COPY
Definition: pg_standby.c:89
int maxretries
Definition: pg_standby.c:45
int optind
Definition: getopt.c:51
static bool RestoreWALFileForRecovery(void)
Definition: pg_standby.c:468
bool debug
Definition: pg_standby.c:46
static int Failover
Definition: pg_standby.c:87
char * c
static void CustomizableCleanupPriorWALFiles(void)
Definition: pg_standby.c:224
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
char restoreCommand[MAXPGPATH]
Definition: pg_standby.c:61
#define FastFailover
Definition: pg_standby.c:85
#define XLOG_HISTORY
Definition: pg_standby.c:94
pqsigfunc pqsignal(int signum, pqsigfunc handler)
Definition: signal.c:168
bool need_cleanup
Definition: pg_standby.c:47
char WALFilePath[MAXPGPATH *2]
Definition: pg_standby.c:60
#define RESTORE_COMMAND_LINK
Definition: pg_standby.c:90
char * nextWALFileName
Definition: pg_standby.c:57
#define IsTLHistoryFileName(fname)
static void sighandler(int sig)
Definition: pg_standby.c:532
char * optarg
Definition: getopt.c:53
char * xlogFilePath
Definition: pg_standby.c:56
char * triggerPath
Definition: pg_standby.c:55
char * archiveLocation
Definition: pg_standby.c:54
char * restartWALFileName
Definition: pg_standby.c:58
int nextWALFileType
Definition: pg_standby.c:96
static bool SetWALFileNameForCleanup(void)
Definition: pg_standby.c:310
static volatile sig_atomic_t signaled
Definition: pg_standby.c:51
int maxwaittime
Definition: pg_standby.c:43
static bool RestoreWALFileForRecovery ( void  )
static

Definition at line 468 of file pg_standby.c.

References debug, maxretries, pg_usleep(), restoreCommand, and sleeptime.

Referenced by main().

469 {
470  int rc = 0;
471  int numretries = 0;
472 
473  if (debug)
474  {
475  fprintf(stderr, "running restore: ");
476  fflush(stderr);
477  }
478 
479  while (numretries <= maxretries)
480  {
481  rc = system(restoreCommand);
482  if (rc == 0)
483  {
484  if (debug)
485  {
486  fprintf(stderr, "OK\n");
487  fflush(stderr);
488  }
489  return true;
490  }
491  pg_usleep(numretries++ * sleeptime * 1000000L);
492  }
493 
494  /*
495  * Allow caller to add additional info
496  */
497  if (debug)
498  fprintf(stderr, "not restored\n");
499  return false;
500 }
int sleeptime
Definition: pg_standby.c:40
void pg_usleep(long microsec)
Definition: signal.c:53
int maxretries
Definition: pg_standby.c:45
bool debug
Definition: pg_standby.c:46
char restoreCommand[MAXPGPATH]
Definition: pg_standby.c:61
static bool SetWALFileNameForCleanup ( void  )
static

Definition at line 310 of file pg_standby.c.

References cleanup(), exclusiveCleanupFileName, keepfiles, MaxSegmentsPerLogFile, nextWALFileName, restartWALFileName, strlcpy(), and XLogFileNameById.

Referenced by main().

311 {
312  uint32 tli = 1,
313  log = 0,
314  seg = 0;
315  uint32 log_diff = 0,
316  seg_diff = 0;
317  bool cleanup = false;
318 
319  if (restartWALFileName)
320  {
321  /*
322  * Don't do cleanup if the restartWALFileName provided is later than
323  * the xlog file requested. This is an error and we must not remove
324  * these files from archive. This shouldn't happen, but better safe
325  * than sorry.
326  */
327  if (strcmp(restartWALFileName, nextWALFileName) > 0)
328  return false;
329 
331  return true;
332  }
333 
334  if (keepfiles > 0)
335  {
336  sscanf(nextWALFileName, "%08X%08X%08X", &tli, &log, &seg);
337  if (tli > 0 && seg > 0)
338  {
339  log_diff = keepfiles / MaxSegmentsPerLogFile;
340  seg_diff = keepfiles % MaxSegmentsPerLogFile;
341  if (seg_diff > seg)
342  {
343  log_diff++;
344  seg = MaxSegmentsPerLogFile - (seg_diff - seg);
345  }
346  else
347  seg -= seg_diff;
348 
349  if (log >= log_diff)
350  {
351  log -= log_diff;
352  cleanup = true;
353  }
354  else
355  {
356  log = 0;
357  seg = 0;
358  }
359  }
360  }
361 
363 
364  return cleanup;
365 }
int keepfiles
Definition: pg_standby.c:44
char exclusiveCleanupFileName[MAXFNAMELEN]
Definition: pg_standby.c:62
#define XLogFileNameById(fname, tli, log, seg)
#define MaxSegmentsPerLogFile
Definition: pg_standby.c:221
unsigned int uint32
Definition: c.h:268
static void cleanup(void)
Definition: bootstrap.c:860
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45
char * nextWALFileName
Definition: pg_standby.c:57
char * restartWALFileName
Definition: pg_standby.c:58
static void sighandler ( int  sig)
static

Definition at line 532 of file pg_standby.c.

References signaled.

Referenced by main().

533 {
534  signaled = true;
535 }
static volatile sig_atomic_t signaled
Definition: pg_standby.c:51
static void sigquit_handler ( int  sig)
static

Definition at line 539 of file pg_standby.c.

References pqsignal(), and SIG_DFL.

Referenced by main().

540 {
541  pqsignal(SIGINT, SIG_DFL);
542  kill(getpid(), SIGINT);
543 }
#define SIG_DFL
Definition: win32.h:183
pqsigfunc pqsignal(int signum, pqsigfunc handler)
Definition: signal.c:168
static void usage ( void  )
static

Definition at line 503 of file pg_standby.c.

References progname.

Referenced by exec_command_slash_command_help(), main(), parse_psql_options(), and pg_notification_queue_usage().

504 {
505  printf("%s allows PostgreSQL warm standby servers to be configured.\n\n", progname);
506  printf("Usage:\n");
507  printf(" %s [OPTION]... ARCHIVELOCATION NEXTWALFILE XLOGFILEPATH [RESTARTWALFILE]\n", progname);
508  printf("\nOptions:\n");
509  printf(" -c copy file from archive (default)\n");
510  printf(" -d generate lots of debugging output (testing only)\n");
511  printf(" -k NUMFILESTOKEEP if RESTARTWALFILE is not used, remove files prior to limit\n"
512  " (0 keeps all)\n");
513  printf(" -l does nothing; use of link is now deprecated\n");
514  printf(" -r MAXRETRIES max number of times to retry, with progressive wait\n"
515  " (default=3)\n");
516  printf(" -s SLEEPTIME seconds to wait between file checks (min=1, max=60,\n"
517  " default=5)\n");
518  printf(" -t TRIGGERFILE trigger file to initiate failover (no default)\n");
519  printf(" -V, --version output version information, then exit\n");
520  printf(" -w MAXWAITTIME max seconds to wait for a file (0=no limit) (default=0)\n");
521  printf(" -?, --help show this help, then exit\n");
522  printf("\n"
523  "Main intended use as restore_command in recovery.conf:\n"
524  " restore_command = 'pg_standby [OPTION]... ARCHIVELOCATION %%f %%p %%r'\n"
525  "e.g.\n"
526  " restore_command = 'pg_standby /mnt/server/archiverdir %%f %%p %%r'\n");
527  printf("\nReport bugs to <pgsql-bugs@postgresql.org>.\n");
528 }
const char * progname
Definition: pg_standby.c:37

Variable Documentation

char* archiveLocation

Definition at line 54 of file pg_standby.c.

Referenced by CustomizableCleanupPriorWALFiles(), CustomizableInitialize(), and main().

char exclusiveCleanupFileName[MAXFNAMELEN]

Definition at line 62 of file pg_standby.c.

Referenced by CustomizableCleanupPriorWALFiles(), main(), and SetWALFileNameForCleanup().

int Failover = NoFailover
static

Definition at line 87 of file pg_standby.c.

Referenced by CheckForExternalTrigger(), and main().

int keepfiles = 0

Definition at line 44 of file pg_standby.c.

Referenced by main(), and SetWALFileNameForCleanup().

int maxretries = 3

Definition at line 45 of file pg_standby.c.

Referenced by main(), and RestoreWALFileForRecovery().

int maxwaittime = 0

Definition at line 43 of file pg_standby.c.

Referenced by main().

bool need_cleanup = false

Definition at line 47 of file pg_standby.c.

Referenced by main().

char* nextWALFileName
int nextWALFileType
char* priorWALFileName

Definition at line 59 of file pg_standby.c.

char* restartWALFileName

Definition at line 58 of file pg_standby.c.

Referenced by main(), and SetWALFileNameForCleanup().

char restoreCommand[MAXPGPATH]

Definition at line 61 of file pg_standby.c.

Referenced by main(), and RestoreWALFileForRecovery().

int restoreCommandType

Definition at line 91 of file pg_standby.c.

Referenced by CustomizableInitialize(), and main().

volatile sig_atomic_t signaled = false
static
struct stat stat_buf
char* triggerPath

Definition at line 55 of file pg_standby.c.

Referenced by CheckForExternalTrigger(), and main().

int waittime = -1

Definition at line 41 of file pg_standby.c.

Referenced by AutoVacLauncherMain(), main(), and pg_timer_thread().

char WALFilePath[MAXPGPATH *2]
char* xlogFilePath

Definition at line 56 of file pg_standby.c.

Referenced by CustomizableInitialize(), and main().