diff -durpN postgresql.orig/doc/src/sgml/ref/pg_basebackup.sgml postgresql/doc/src/sgml/ref/pg_basebackup.sgml
--- postgresql.orig/doc/src/sgml/ref/pg_basebackup.sgml 2012-06-18 07:06:42.774009894 +0200
+++ postgresql/doc/src/sgml/ref/pg_basebackup.sgml 2012-07-01 12:51:51.050652170 +0200
@@ -186,6 +186,28 @@ PostgreSQL documentation
+
+
+
+
+ Write a minimal recovery.conf into the output directory using
+ the connection parameters from the command line to ease
+ setting up the standby. Conflicts with
+
+
+
+
+
+
+
+
+
+ Start the standby database server. Implies .
+
+
+
+
+
diff -durpN postgresql.orig/src/bin/pg_basebackup/pg_basebackup.c postgresql/src/bin/pg_basebackup/pg_basebackup.c
--- postgresql.orig/src/bin/pg_basebackup/pg_basebackup.c 2012-06-26 09:10:21.301759598 +0200
+++ postgresql/src/bin/pg_basebackup/pg_basebackup.c 2012-07-01 12:44:36.920813960 +0200
@@ -46,6 +46,8 @@ int compresslevel = 0;
bool includewal = false;
bool streamwal = false;
bool fastcheckpoint = false;
+bool writerecoveryconf = false;
+bool startstandby = false;
int standby_message_timeout = 10 * 1000; /* 10 sec = default */
/* Progress counters */
@@ -107,6 +109,10 @@ usage(void)
printf(_("\nOptions controlling the output:\n"));
printf(_(" -D, --pgdata=DIRECTORY receive base backup into directory\n"));
printf(_(" -F, --format=p|t output format (plain (default), tar)\n"));
+ printf(_(" -R, --write-recovery-conf\n"
+ " write recovery.conf after backup\n"));
+ printf(_(" -S, --start-standby start standby after backup, implies -R\n"
+ " conflicts with -x\n"));
printf(_(" -x, --xlog include required WAL files in backup (fetch mode)\n"));
printf(_(" -X, --xlog-method=fetch|stream\n"
" include required WAL files with specified method\n"));
@@ -1193,6 +1199,85 @@ BaseBackup(void)
fprintf(stderr, "%s: base backup completed\n", progname);
}
+static void WriteRecoveryConf(void)
+{
+ char filename[MAXPGPATH];
+ char cfhost[MAXPGPATH] = "";
+ char cfport[MAXPGPATH] = "";
+ char cfuser[MAXPGPATH] = "";
+ char cfpass[MAXPGPATH] = "";
+ FILE *cf;
+
+ if (!writerecoveryconf)
+ return;
+
+ memset(cfhost, 0, MAXPGPATH);
+ if (dbhost)
+ snprintf(cfhost, MAXPGPATH-1, "host=%s", dbhost);
+
+ memset(cfport, 0, MAXPGPATH);
+ if (dbport)
+ snprintf(cfport, MAXPGPATH-1, "port=%s", dbport);
+
+ memset(cfuser, 0, MAXPGPATH);
+ if (dbuser)
+ snprintf(cfuser, MAXPGPATH-1, "user=%s", dbuser);
+
+ memset(cfpass, 0, MAXPGPATH);
+ if (dbpassword)
+ snprintf(cfpass, MAXPGPATH-1, "password='%s'", dbpassword);
+ else
+ printf("add password to primary_conninfo in %s if needed\n", filename);
+
+ sprintf(filename, "%s/recovery.conf", basedir);
+
+ cf = fopen(filename, "w");
+ if (cf == NULL)
+ {
+ fprintf(stderr, _("cannot create %s"), filename);
+ exit(1);
+ }
+
+ fprintf(cf, "standby_mode = 'on'\n");
+ fprintf(cf, "primary_conninfo = '%s %s %s'\n", cfhost, cfport, cfuser);
+
+ fclose(cf);
+}
+
+static void StartStandby(const char *command)
+{
+ char *path;
+ char *args[5];
+ int pos, len;
+
+ if (!startstandby)
+ return;
+
+ path = xstrdup(command);
+ len = strlen(path);
+
+ for (pos = len; pos > 0; pos--)
+ {
+ if (path[pos - 1] == '/'
+#ifdef WIN32
+ || path[pos - 1] == '\\'
+#endif
+ )
+ break;
+ }
+
+ sprintf(&path[pos], "pg_ctl");
+
+ args[0] = path;
+ args[1] = "-D";
+ args[2] = basedir;
+ args[3] = "start";
+ args[4] = NULL;
+
+ if (execvp(path, args) < 0)
+ fprintf(stderr, _("Cannot execute pg_ctl: %s"),
+ strerror(errno));
+}
int
main(int argc, char **argv)
@@ -1203,6 +1288,8 @@ main(int argc, char **argv)
{"pgdata", required_argument, NULL, 'D'},
{"format", required_argument, NULL, 'F'},
{"checkpoint", required_argument, NULL, 'c'},
+ {"write-recovery-conf", no_argument, NULL, 'R'},
+ {"start-standby", no_argument, NULL, 'S'},
{"xlog", no_argument, NULL, 'x'},
{"xlog-method", required_argument, NULL, 'X'},
{"gzip", no_argument, NULL, 'z'},
@@ -1240,7 +1327,7 @@ main(int argc, char **argv)
}
}
- while ((c = getopt_long(argc, argv, "D:F:xX:l:zZ:c:h:p:U:s:wWvP",
+ while ((c = getopt_long(argc, argv, "D:F:RSxX:l:zZ:c:h:p:U:s:wWvP",
long_options, &option_index)) != -1)
{
switch (c)
@@ -1260,6 +1347,12 @@ main(int argc, char **argv)
exit(1);
}
break;
+ case 'R':
+ writerecoveryconf = true;
+ break;
+ case 'S':
+ startstandby = true;
+ break;
case 'x':
if (includewal)
{
@@ -1422,6 +1515,16 @@ main(int argc, char **argv)
}
#endif
+ if (startstandby)
+ writerecoveryconf = true;
+
+ if (writerecoveryconf && includewal)
+ {
+ fprintf(stderr,
+ _("--xlog and --writerecoveryconf are mutually exclusive\n"));
+ exit(1);
+ }
+
/*
* Verify that the target directory exists, or create it. For plaintext
* backups, always require the directory. For tar backups, require it
@@ -1433,5 +1536,9 @@ main(int argc, char **argv)
BaseBackup();
+ WriteRecoveryConf();
+
+ StartStandby(argv[0]);
+
return 0;
}
diff -durpN postgresql.orig/src/bin/pg_basebackup/streamutil.c postgresql/src/bin/pg_basebackup/streamutil.c
--- postgresql.orig/src/bin/pg_basebackup/streamutil.c 2012-06-11 06:22:48.200921787 +0200
+++ postgresql/src/bin/pg_basebackup/streamutil.c 2012-07-01 12:09:56.938418170 +0200
@@ -28,7 +28,7 @@ char *dbhost = NULL;
char *dbuser = NULL;
char *dbport = NULL;
int dbgetpassword = 0; /* 0=auto, -1=never, 1=always */
-static char *dbpassword = NULL;
+char *dbpassword = NULL;
PGconn *conn = NULL;
/*
diff -durpN postgresql.orig/src/bin/pg_basebackup/streamutil.h postgresql/src/bin/pg_basebackup/streamutil.h
--- postgresql.orig/src/bin/pg_basebackup/streamutil.h 2012-04-16 19:57:22.589917242 +0200
+++ postgresql/src/bin/pg_basebackup/streamutil.h 2012-07-01 12:09:42.562326418 +0200
@@ -5,6 +5,7 @@ extern char *dbhost;
extern char *dbuser;
extern char *dbport;
extern int dbgetpassword;
+extern char *dbpassword;
/* Connection kept global so we can disconnect easily */
extern PGconn *conn;