Hi,

attached is a patch that does $SUBJECT.

It's a usability enhancement, to take a backup, write
a minimalistic recovery.conf and start the streaming
standby in one go.

Comments?

Best regards,
Zoltán Böszörményi

--
----------------------------------
Zoltán Böszörményi
Cybertec Schönig & Schönig GmbH
Gröhrmühlgasse 26
A-2700 Wiener Neustadt, Austria
Web: http://www.postgresql-support.de
     http://www.postgresql.at/

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
      </varlistentry>
 
      <varlistentry>
+      <term><option>-R</option></term>
+      <term><option>--write-recovery-conf</option></term>
+      <listitem>
+       <para>
+        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 <option>--xlog</option>
+       </para>
+      </listitem>
+     </varlistentry>
+
+     <varlistentry>
+      <term><option>-S</option></term>
+      <term><option>--start-standby</option></term>
+      <listitem>
+       <para>
+        Start the standby database server. Implies <option>-R</option>.
+       </para>
+      </listitem>
+     </varlistentry>
+
+     <varlistentry>
       <term><option>-X <replaceable class="parameter">method</replaceable></option></term>
       <term><option>--xlog-method=<replaceable class="parameter">method</replaceable></option></term>
       <listitem>
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;
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to