86 #define SmartFailover 1 87 #define FastFailover 2 91 #define RESTORE_COMMAND_COPY 0 92 #define RESTORE_COMMAND_LINK 1 96 #define XLOG_HISTORY 1 97 #define XLOG_BACKUP_LABEL 2 100 #define SET_RESTORE_COMMAND(cmd, arg1, arg2) \ 101 snprintf(restoreCommand, MAXPGPATH, cmd " \"%s\" \"%s\"", arg1, arg2) 150 #if HAVE_WORKING_LINK 202 fprintf(stderr,
"Keep archive history: ");
205 fprintf(stderr,
"%s and later\n",
208 fprintf(stderr,
"no cleanup required\n");
246 fprintf(stderr,
"file size greater than expected\n");
275 while (errno = 0, (xlde =
readdir(xldir)) != NULL)
301 fprintf(stderr,
"\nremoving file \"%s\"",
WALFilePath);
306 fprintf(stderr,
"\n%s: ERROR: could not remove file \"%s\": %s\n",
314 fprintf(stderr,
"%s: could not read archive location \"%s\": %s\n",
317 fprintf(stderr,
"\n");
320 fprintf(stderr,
"%s: could not open archive location \"%s\": %s\n",
324 fprintf(stderr,
"%s: could not close archive location \"%s\": %s\n",
351 int max_segments_per_logfile = (0xFFFFFFFF /
WalSegSz);
371 if (tli > 0 && seg > 0)
373 log_diff =
keepfiles / max_segments_per_logfile;
374 seg_diff =
keepfiles % max_segments_per_logfile;
378 seg = max_segments_per_logfile - (seg_diff - seg);
409 bool ret_val =
false;
419 fprintf(stderr,
"%s: could not open WAL file \"%s\": %s\n",
426 if (
read(fd, buf, XLOG_BLCKSZ) == XLOG_BLCKSZ)
439 "%s: WAL segment size must be a power of two between 1MB and 1GB, but the WAL file header specifies %d bytes\n",
451 fprintf(stderr,
"could not read file \"%s\": %s\n",
457 fprintf(stderr,
"not enough data in file \"%s\"\n",
503 fprintf(stderr,
"trigger file found: smart failover\n");
510 fprintf(stderr,
"WARNING: could not open \"%s\": %s\n",
516 if ((len =
read(fd, buf,
sizeof(buf) - 1)) < 0)
518 fprintf(stderr,
"WARNING: could not read \"%s\": %s\n",
526 if (strncmp(buf,
"smart", 5) == 0)
529 fprintf(stderr,
"trigger file found: smart failover\n");
535 if (strncmp(buf,
"fast", 4) == 0)
539 fprintf(stderr,
"trigger file found: fast failover\n");
549 fprintf(stderr,
"WARNING: could not read \"%s\": %s\n",
559 fprintf(stderr,
"WARNING: invalid content in \"%s\"\n",
triggerPath);
577 fprintf(stderr,
"running restore: ");
588 fprintf(stderr,
"OK\n");
600 fprintf(stderr,
"not restored\n");
607 printf(
"%s allows PostgreSQL warm standby servers to be configured.\n\n",
progname);
609 printf(
" %s [OPTION]... ARCHIVELOCATION NEXTWALFILE XLOGFILEPATH [RESTARTWALFILE]\n",
progname);
610 printf(
"\nOptions:\n");
611 printf(
" -c copy file from archive (default)\n");
612 printf(
" -d generate lots of debugging output (testing only)\n");
613 printf(
" -k NUMFILESTOKEEP if RESTARTWALFILE is not used, remove files prior to limit\n" 615 printf(
" -l does nothing; use of link is now deprecated\n");
616 printf(
" -r MAXRETRIES max number of times to retry, with progressive wait\n" 618 printf(
" -s SLEEPTIME seconds to wait between file checks (min=1, max=60,\n" 620 printf(
" -t TRIGGERFILE trigger file to initiate failover (no default)\n");
621 printf(
" -V, --version output version information, then exit\n");
622 printf(
" -w MAXWAITTIME max seconds to wait for a file (0=no limit) (default=0)\n");
623 printf(
" -?, --help show this help, then exit\n");
625 "Main intended use as restore_command in recovery.conf:\n" 626 " restore_command = 'pg_standby [OPTION]... ARCHIVELOCATION %%f %%p %%r'\n" 628 " restore_command = 'pg_standby /mnt/server/archiverdir %%f %%p %%r'\n");
629 printf(
"\nReport bugs to <pgsql-bugs@postgresql.org>.\n");
644 kill(getpid(), SIGINT);
658 if (strcmp(argv[1],
"--help") == 0 || strcmp(argv[1],
"-?") == 0)
663 if (strcmp(argv[1],
"--version") == 0 || strcmp(argv[1],
"-V") == 0)
665 puts(
"pg_standby (PostgreSQL) " PG_VERSION);
691 while ((c =
getopt(argc, argv,
"cdk:lr:s:t:w:")) != -1)
705 fprintf(stderr,
"%s: -k keepfiles must be >= 0\n",
progname);
724 fprintf(stderr,
"%s: -r maxretries must be >= 0\n",
progname);
730 if (sleeptime <= 0 || sleeptime > 60)
732 fprintf(stderr,
"%s: -s sleeptime incorrectly set\n",
progname);
743 fprintf(stderr,
"%s: -w maxwaittime incorrectly set\n",
progname);
748 fprintf(stderr,
"Try \"%s --help\" for more information.\n",
progname);
759 fprintf(stderr,
"%s: not enough command-line arguments\n",
progname);
776 fprintf(stderr,
"%s: must specify archive location\n",
progname);
777 fprintf(stderr,
"Try \"%s --help\" for more information.\n",
progname);
788 fprintf(stderr,
"%s: must specify WAL file name as second non-option argument (use \"%%f\")\n",
progname);
789 fprintf(stderr,
"Try \"%s --help\" for more information.\n",
progname);
800 fprintf(stderr,
"%s: must specify xlog destination as third non-option argument (use \"%%p\")\n",
progname);
801 fprintf(stderr,
"Try \"%s --help\" for more information.\n",
progname);
817 fprintf(stderr,
"WAL file path: %s\n",
WALFilePath);
819 fprintf(stderr,
"Sleep interval: %d second%s\n",
821 fprintf(stderr,
"Max wait interval: %d %s\n",
840 fprintf(stderr,
"history file not found\n");
860 fprintf(stderr,
"signaled to exit: fast failover\n");
908 fprintf(stderr,
"Timed out after %d seconds: fast failover\n",
915 fprintf(stderr,
"WAL file not present yet.");
917 fprintf(stderr,
" Checking for trigger file...");
918 fprintf(stderr,
"\n");
#define IsValidWalSegSize(size)
int main(int argc, char **argv)
static void CheckForExternalTrigger(void)
void * pg_malloc(size_t size)
const char * get_progname(const char *argv0)
static bool CustomizableNextWALFileReady(void)
static void sigquit_handler(int sig)
char exclusiveCleanupFileName[MAXFNAMELEN]
#define XLogFileNameById(fname, tli, log, seg)
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
static int fd(const char *x, int i)
int getopt(int nargc, char *const *nargv, const char *ostr)
static void CustomizableInitialize(void)
XLogLongPageHeaderData * XLogLongPageHeader
#define XLOG_BACKUP_LABEL
void pg_usleep(long microsec)
#define RESTORE_COMMAND_COPY
static bool RestoreWALFileForRecovery(void)
#define IsXLogFileName(fname)
DIR * opendir(const char *)
#define SET_RESTORE_COMMAND(cmd, arg1, arg2)
static void CustomizableCleanupPriorWALFiles(void)
char * pg_strdup(const char *in)
char restoreCommand[MAXPGPATH]
#define IsBackupHistoryFileName(fname)
static void cleanup(void)
pqsigfunc pqsignal(int signum, pqsigfunc handler)
size_t strlcpy(char *dst, const char *src, size_t siz)
#define Assert(condition)
char WALFilePath[MAXPGPATH *2]
struct dirent * readdir(DIR *)
#define RESTORE_COMMAND_LINK
#define IsTLHistoryFileName(fname)
static void sighandler(int sig)
const char * strerror(int errnum)
char * restartWALFileName
static bool SetWALFileNameForCleanup(void)
static volatile sig_atomic_t signaled
static bool SetWALSegSize(void)