On 26/06/14 19:57, Sawada Masahiko wrote:
$ pg_resetxlog  -s0 data
Transaction log reset
$ pg_controldata data | grep "Database system identifier"
Database system identifier:           6029284919152642525

this patch dose not works fine with -s0.


Yes, this is a bug, 0 input should throw error, which it does now.

Also based on Alvaro's comment, I replaced the scanf parsing code with strtoul(l) function.


--
 Petr Jelinek                  http://www.2ndQuadrant.com/
 PostgreSQL Development, 24x7 Support, Training & Services
diff --git a/doc/src/sgml/ref/pg_resetxlog.sgml b/doc/src/sgml/ref/pg_resetxlog.sgml
index 34b0606..39ae574 100644
--- a/doc/src/sgml/ref/pg_resetxlog.sgml
+++ b/doc/src/sgml/ref/pg_resetxlog.sgml
@@ -30,6 +30,7 @@ PostgreSQL documentation
    <arg choice="opt"><option>-m</option> <replaceable class="parameter">mxid</replaceable>,<replaceable class="parameter">mxid</replaceable></arg>
    <arg choice="opt"><option>-O</option> <replaceable class="parameter">mxoff</replaceable></arg>
    <arg choice="opt"><option>-l</option> <replaceable class="parameter">xlogfile</replaceable></arg>
+   <arg choice="opt"><option>-s</option> [<replaceable class="parameter">sysid</replaceable>]</arg>
    <arg choice="plain"><replaceable>datadir</replaceable></arg>
   </cmdsynopsis>
  </refsynopsisdiv>
@@ -184,6 +185,13 @@ PostgreSQL documentation
   </para>
 
   <para>
+   The <option>-s</> option instructs <command>pg_resetxlog</command> to 
+   set the system identifier of the cluster to specified <replaceable>sysid</>.
+   If the <replaceable>sysid</> is not provided new one will be generated using
+   same algorithm <command>initdb</> uses.
+  </para>
+
+  <para>
    The <option>-V</> and <option>--version</> options print
    the <application>pg_resetxlog</application> version and exit.  The
    options <option>-?</> and <option>--help</> show supported arguments,
diff --git a/src/bin/pg_resetxlog/pg_resetxlog.c b/src/bin/pg_resetxlog/pg_resetxlog.c
index 915a1ed..0b28bc0 100644
--- a/src/bin/pg_resetxlog/pg_resetxlog.c
+++ b/src/bin/pg_resetxlog/pg_resetxlog.c
@@ -67,7 +67,9 @@ static MultiXactId set_mxid = 0;
 static MultiXactOffset set_mxoff = (MultiXactOffset) -1;
 static uint32 minXlogTli = 0;
 static XLogSegNo minXlogSegNo = 0;
+static uint64 set_sysid = 0;
 
+static uint64 GenerateSystemIdentifier(void);
 static bool ReadControlFile(void);
 static void GuessControlValues(void);
 static void PrintControlValues(bool guessed);
@@ -111,7 +113,7 @@ main(int argc, char *argv[])
 	}
 
 
-	while ((c = getopt(argc, argv, "fl:m:no:O:x:e:")) != -1)
+	while ((c = getopt(argc, argv, "fl:m:no:O:x:e:s::")) != -1)
 	{
 		switch (c)
 		{
@@ -227,6 +229,33 @@ main(int argc, char *argv[])
 				XLogFromFileName(optarg, &minXlogTli, &minXlogSegNo);
 				break;
 
+			case 's':
+				if (optarg)
+				{
+#ifdef HAVE_STRTOULL
+					set_sysid = strtoull(optarg, &endptr, 10);
+#else
+					set_sysid = strtoul(optarg, &endptr, 10);
+#endif
+					/*
+					 * Validate input, we use strspn because strtoul(l) accepts
+					 * negative numbers and silently converts them to unsigned
+					 */
+					if (set_sysid == 0 || errno != 0 ||
+						endptr == optarg || *endptr != '\0' ||
+						strspn(optarg, "0123456789") != strlen(optarg))
+					{
+						fprintf(stderr, _("%s: invalid argument for option -s\n"), progname);
+						fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
+						exit(1);
+					}
+				}
+				else
+				{
+					set_sysid = GenerateSystemIdentifier();
+				}
+				break;
+
 			default:
 				fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
 				exit(1);
@@ -354,6 +383,9 @@ main(int argc, char *argv[])
 	if (minXlogSegNo > newXlogSegNo)
 		newXlogSegNo = minXlogSegNo;
 
+	if (set_sysid != 0)
+		ControlFile.system_identifier = set_sysid;
+
 	/*
 	 * If we had to guess anything, and -f was not given, just print the
 	 * guessed values and exit.  Also print if -n is given.
@@ -395,6 +427,26 @@ main(int argc, char *argv[])
 
 
 /*
+ * Create a new unique installation identifier.
+ *
+ * See notes in xlog.c about the algorithm.
+ */
+static uint64
+GenerateSystemIdentifier(void)
+{
+	uint64			sysidentifier;
+	struct timeval	tv;
+
+	gettimeofday(&tv, NULL);
+	sysidentifier = ((uint64) tv.tv_sec) << 32;
+	sysidentifier |= ((uint64) tv.tv_usec) << 12;
+	sysidentifier |= getpid() & 0xFFF;
+
+	return sysidentifier;
+}
+
+
+/*
  * Try to read the existing pg_control file.
  *
  * This routine is also responsible for updating old pg_control versions
@@ -475,9 +527,6 @@ ReadControlFile(void)
 static void
 GuessControlValues(void)
 {
-	uint64		sysidentifier;
-	struct timeval tv;
-
 	/*
 	 * Set up a completely default set of pg_control values.
 	 */
@@ -489,14 +538,10 @@ GuessControlValues(void)
 
 	/*
 	 * Create a new unique installation identifier, since we can no longer use
-	 * any old XLOG records.  See notes in xlog.c about the algorithm.
+	 * any old XLOG records.
 	 */
-	gettimeofday(&tv, NULL);
-	sysidentifier = ((uint64) tv.tv_sec) << 32;
-	sysidentifier |= ((uint64) tv.tv_usec) << 12;
-	sysidentifier |= getpid() & 0xFFF;
 
-	ControlFile.system_identifier = sysidentifier;
+	ControlFile.system_identifier = GenerateSystemIdentifier();
 
 	ControlFile.checkPointCopy.redo = SizeOfXLogLongPHD;
 	ControlFile.checkPointCopy.ThisTimeLineID = 1;
@@ -649,6 +694,21 @@ PrintNewControlValues()
 	XLogFileName(fname, ControlFile.checkPointCopy.ThisTimeLineID, newXlogSegNo);
 	printf(_("First log segment after reset:        %s\n"), fname);
 
+	if (set_sysid != 0)
+	{
+		char		sysident_str[32];
+
+		/*
+		 * Format system_identifier separately to keep platform-dependent format
+		 * code out of the translatable message string.
+		 */
+		snprintf(sysident_str, sizeof(sysident_str), UINT64_FORMAT,
+			 ControlFile.system_identifier);
+
+		printf(_("Database system identifier:           %s\n"),
+			   sysident_str);
+	}
+
 	if (set_mxid != 0)
 	{
 		printf(_("NextMultiXactId:                      %u\n"),
@@ -1087,6 +1147,7 @@ usage(void)
 	printf(_("  -o OID           set next OID\n"));
 	printf(_("  -O OFFSET        set next multitransaction offset\n"));
 	printf(_("  -V, --version    output version information, then exit\n"));
+	printf(_("  -s [SYSID]       set system identifier (or generate one)\n"));
 	printf(_("  -x XID           set next transaction ID\n"));
 	printf(_("  -?, --help       show this help, then exit\n"));
 	printf(_("\nReport bugs to <pgsql-b...@postgresql.org>.\n"));
-- 
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