84 #define SmartFailover 1 85 #define FastFailover 2 89 #define RESTORE_COMMAND_COPY 0 90 #define RESTORE_COMMAND_LINK 1 94 #define XLOG_HISTORY 1 97 #define SET_RESTORE_COMMAND(cmd, arg1, arg2) \ 98 snprintf(restoreCommand, MAXPGPATH, cmd " \"%s\" \"%s\"", arg1, arg2) 197 fprintf(stderr,
"Keep archive history: ");
200 fprintf(stderr,
"%s and later\n",
203 fprintf(stderr,
"no cleanup required\n");
235 fprintf(stderr,
"file size greater than expected\n");
264 while (errno = 0, (xlde =
readdir(xldir)) != NULL)
295 fprintf(stderr,
"\n%s: ERROR: could not remove file \"%s\": %s\n",
303 fprintf(stderr,
"%s: could not read archive location \"%s\": %s\n",
309 fprintf(stderr,
"%s: could not open archive location \"%s\": %s\n",
313 fprintf(stderr,
"%s: could not close archive location \"%s\": %s\n",
340 int max_segments_per_logfile = (0xFFFFFFFF /
WalSegSz);
360 if (tli > 0 && seg > 0)
362 log_diff =
keepfiles / max_segments_per_logfile;
363 seg_diff =
keepfiles % max_segments_per_logfile;
367 seg = max_segments_per_logfile - (seg_diff - seg);
398 bool ret_val =
false;
406 fprintf(stderr,
"%s: could not open WAL file \"%s\": %s\n",
412 if (
read(fd, buf.
data, XLOG_BLCKSZ) == XLOG_BLCKSZ)
425 "%s: WAL segment size must be a power of two between 1MB and 1GB, but the WAL file header specifies %d bytes\n",
437 fprintf(stderr,
"could not read file \"%s\": %s\n",
443 fprintf(stderr,
"not enough data in file \"%s\"\n",
488 fprintf(stderr,
"trigger file found: smart failover\n");
495 fprintf(stderr,
"WARNING: could not open \"%s\": %s\n",
501 if ((len =
read(fd, buf,
sizeof(buf) - 1)) < 0)
503 fprintf(stderr,
"WARNING: could not read \"%s\": %s\n",
511 if (strncmp(buf,
"smart", 5) == 0)
514 fprintf(stderr,
"trigger file found: smart failover\n");
520 if (strncmp(buf,
"fast", 4) == 0)
524 fprintf(stderr,
"trigger file found: fast failover\n");
534 fprintf(stderr,
"WARNING: could not read \"%s\": %s\n",
561 fprintf(stderr,
"running restore: ");
584 fprintf(stderr,
"not restored\n");
591 printf(
"%s allows PostgreSQL warm standby servers to be configured.\n\n",
progname);
593 printf(
" %s [OPTION]... ARCHIVELOCATION NEXTWALFILE XLOGFILEPATH [RESTARTWALFILE]\n",
progname);
595 printf(
" -c copy file from archive (default)\n");
596 printf(
" -d generate lots of debugging output (testing only)\n");
597 printf(
" -k NUMFILESTOKEEP if RESTARTWALFILE is not used, remove files prior to limit\n" 599 printf(
" -l does nothing; use of link is now deprecated\n");
600 printf(
" -r MAXRETRIES max number of times to retry, with progressive wait\n" 602 printf(
" -s SLEEPTIME seconds to wait between file checks (min=1, max=60,\n" 604 printf(
" -t TRIGGERFILE trigger file to initiate failover (no default)\n");
605 printf(
" -V, --version output version information, then exit\n");
606 printf(
" -w MAXWAITTIME max seconds to wait for a file (0=no limit) (default=0)\n");
607 printf(
" -?, --help show this help, then exit\n");
609 "Main intended use as restore_command in postgresql.conf:\n" 610 " restore_command = 'pg_standby [OPTION]... ARCHIVELOCATION %%f %%p %%r'\n" 612 " restore_command = 'pg_standby /mnt/server/archiverdir %%f %%p %%r'\n");
613 printf(
"\nReport bugs to <%s>.\n", PACKAGE_BUGREPORT);
614 printf(
"%s home page: <%s>\n", PACKAGE_NAME, PACKAGE_URL);
629 kill(getpid(), SIGINT);
643 if (strcmp(argv[1],
"--help") == 0 || strcmp(argv[1],
"-?") == 0)
648 if (strcmp(argv[1],
"--version") == 0 || strcmp(argv[1],
"-V") == 0)
650 puts(
"pg_standby (PostgreSQL) " PG_VERSION);
676 while ((c =
getopt(argc, argv,
"cdk:lr:s:t:w:")) != -1)
715 if (sleeptime <= 0 || sleeptime > 60)
733 fprintf(stderr,
"Try \"%s --help\" for more information.\n",
progname);
762 fprintf(stderr,
"Try \"%s --help\" for more information.\n",
progname);
773 fprintf(stderr,
"%s: must specify WAL file name as second non-option argument (use \"%%f\")\n",
progname);
774 fprintf(stderr,
"Try \"%s --help\" for more information.\n",
progname);
785 fprintf(stderr,
"%s: must specify xlog destination as third non-option argument (use \"%%p\")\n",
progname);
786 fprintf(stderr,
"Try \"%s --help\" for more information.\n",
progname);
804 fprintf(stderr,
"Sleep interval: %d second%s\n",
806 fprintf(stderr,
"Max wait interval: %d %s\n",
825 fprintf(stderr,
"history file not found\n");
845 fprintf(stderr,
"signaled to exit: fast failover\n");
893 fprintf(stderr,
"Timed out after %d seconds: fast failover\n",
900 fprintf(stderr,
"WAL file not present yet.");
902 fprintf(stderr,
" Checking for trigger file...");
#define IsValidWalSegSize(size)
int main(int argc, char **argv)
static void CheckForExternalTrigger(void)
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)
static int fd(const char *x, int i)
int getopt(int nargc, char *const *nargv, const char *ostr)
static void CustomizableInitialize(void)
XLogLongPageHeaderData * XLogLongPageHeader
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]
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)
char * restartWALFileName
static bool SetWALFileNameForCleanup(void)
static volatile sig_atomic_t signaled
static bool SetWALSegSize(void)