pg_resetwal_segsize_v1.patch

application/octet-stream

Filename: pg_resetwal_segsize_v1.patch
Type: application/octet-stream
Part: 0
Message: Re: [HACKERS] pg_upgrade to clusters with a different WAL segment size

Patch

Format: unified
Series: patch v1
File+
doc/src/sgml/ref/pg_resetwal.sgml 24 0
src/bin/pg_resetwal/pg_resetwal.c 31 9
diff --git a/doc/src/sgml/ref/pg_resetwal.sgml b/doc/src/sgml/ref/pg_resetwal.sgml
index 43b58a4..2bffb59 100644
--- a/doc/src/sgml/ref/pg_resetwal.sgml
+++ b/doc/src/sgml/ref/pg_resetwal.sgml
@@ -248,6 +248,30 @@ PostgreSQL documentation
    </varlistentry>
 
    <varlistentry>
+    <term><option>-s</option> <replaceable class="parameter">wal_segment_size</replaceable></term>
+    <listitem>
+     <para>
+      Manually set the WAL segment size (in megabytes).
+     </para>
+
+     <para>
+      The WAL segment size must be set to a power of 2 between 1 and 1024 (megabytes).
+     </para>
+
+     <note>
+      <para>
+       While <command>pg_resetwal</command> will set the WAL starting address
+       beyond the latest existing WAL segment file, some segment size changes
+       can cause previous WAL file names to be reused.  It is recommended to use
+       <option>-l</option> together with <option>-s</option> to manually set the
+       WAL starting address if WAL file name overlap will cause problems with
+       your archiving strategy.
+      </para>
+     </note>
+    </listitem>
+   </varlistentry>
+
+   <varlistentry>
     <term><option>-x</option> <replaceable class="parameter">xid</replaceable></term>
     <listitem>
      <para>
diff --git a/src/bin/pg_resetwal/pg_resetwal.c b/src/bin/pg_resetwal/pg_resetwal.c
index a132cf2..4bb7cd7 100644
--- a/src/bin/pg_resetwal/pg_resetwal.c
+++ b/src/bin/pg_resetwal/pg_resetwal.c
@@ -71,6 +71,7 @@ static MultiXactOffset set_mxoff = (MultiXactOffset) -1;
 static uint32 minXlogTli = 0;
 static XLogSegNo minXlogSegNo = 0;
 static int	WalSegSz;
+static bool walSegSizeChanged = false;
 
 static void CheckDataVersion(void);
 static bool ReadControlFile(void);
@@ -117,7 +118,7 @@ main(int argc, char *argv[])
 	}
 
 
-	while ((c = getopt(argc, argv, "c:D:e:fl:m:no:O:x:")) != -1)
+	while ((c = getopt(argc, argv, "c:D:e:fl:m:no:O:x:s:")) != -1)
 	{
 		switch (c)
 		{
@@ -275,6 +276,15 @@ main(int argc, char *argv[])
 				log_fname = pg_strdup(optarg);
 				break;
 
+			case 's':
+				WalSegSz = strtol(optarg, &endptr, 10) * 1024 * 1024;
+				if (*endptr != '\0' || !IsValidWalSegSize(WalSegSz))
+				{
+					fprintf(stderr, _("%s: WAL segment size (-s) must be a power of 2 between 1 and 1024 (megabytes)\n"), progname);
+					exit(1);
+				}
+				break;
+
 			default:
 				fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
 				exit(1);
@@ -357,6 +367,9 @@ main(int argc, char *argv[])
 	if (!ReadControlFile())
 		GuessControlValues();
 
+	if (WalSegSz == 0)
+		WalSegSz = ControlFile.xlog_seg_size;
+
 	if (log_fname != NULL)
 		XLogFromFileName(log_fname, &minXlogTli, &minXlogSegNo, WalSegSz);
 
@@ -423,6 +436,12 @@ main(int argc, char *argv[])
 		ControlFile.checkPointCopy.PrevTimeLineID = minXlogTli;
 	}
 
+	if (WalSegSz != ControlFile.xlog_seg_size)
+	{
+		ControlFile.xlog_seg_size = WalSegSz;
+		walSegSizeChanged = true;
+	}
+
 	if (minXlogSegNo > newXlogSegNo)
 		newXlogSegNo = minXlogSegNo;
 
@@ -593,14 +612,13 @@ ReadControlFile(void)
 		}
 
 		memcpy(&ControlFile, buffer, sizeof(ControlFile));
-		WalSegSz = ControlFile.xlog_seg_size;
 
-		/* return false if WalSegSz is not valid */
-		if (!IsValidWalSegSize(WalSegSz))
+		/* return false if segment size is not valid */
+		if (!IsValidWalSegSize(ControlFile.xlog_seg_size))
 		{
 			fprintf(stderr,
 					_("%s: pg_control specifies invalid WAL segment size (%d bytes); proceed with caution \n"),
-					progname, WalSegSz);
+					progname, ControlFile.xlog_seg_size);
 			guessed = true;
 		}
 
@@ -844,6 +862,12 @@ PrintNewControlValues(void)
 		printf(_("newestCommitTsXid:                    %u\n"),
 			   ControlFile.checkPointCopy.newestCommitTsXid);
 	}
+
+	if (walSegSizeChanged)
+	{
+		printf(_("Bytes per WAL segment:                %u\n"),
+			   ControlFile.xlog_seg_size);
+	}
 }
 
 
@@ -895,9 +919,6 @@ RewriteControlFile(void)
 	ControlFile.max_prepared_xacts = 0;
 	ControlFile.max_locks_per_xact = 64;
 
-	/* Now we can force the recorded xlog seg size to the right thing. */
-	ControlFile.xlog_seg_size = WalSegSz;
-
 	/* Contents are protected with a CRC */
 	INIT_CRC32C(ControlFile.crc);
 	COMP_CRC32C(ControlFile.crc,
@@ -1033,7 +1054,7 @@ FindEndOfXLOG(void)
 	 * are in virgin territory.
 	 */
 	xlogbytepos = newXlogSegNo * ControlFile.xlog_seg_size;
-	newXlogSegNo = (xlogbytepos + WalSegSz - 1) / WalSegSz;
+	newXlogSegNo = (xlogbytepos + ControlFile.xlog_seg_size - 1) / WalSegSz;
 	newXlogSegNo++;
 }
 
@@ -1263,6 +1284,7 @@ usage(void)
 	printf(_("  -O OFFSET        set next multitransaction offset\n"));
 	printf(_("  -V, --version    output version information, then exit\n"));
 	printf(_("  -x XID           set next transaction ID\n"));
+	printf(_("  -s SEGMENTSIZE   set WAL segment size (in megabytes)\n"));
 	printf(_("  -?, --help       show this help, then exit\n"));
 	printf(_("\nReport bugs to <pgsql-bugs@postgresql.org>.\n"));
 }