On 13.09.23 16:36, Aleksander Alekseev wrote:
All in all the patch looks OK but I have a couple of nitpicks.

```
+   working on a data directory in an unclean shutdown state or with a corrupt
+   control file.
```

```
+   After running this command on a data directory with corrupted WAL or a
+   corrupt control file,
```

I'm not a native English speaker but shouldn't it be "corruptED control file"?

fixed


```
+      Force <command>pg_resetwal</command> to proceed even in situations where
+      it could be dangerous,
```

"where" is probably fine but wouldn't "WHEN it could be dangerous" be better?

Hmm, I think I like "where" better.

Attached is an updated patch set where I have split the changes into smaller pieces. The last two patches still have some open questions about what certain constants mean etc. The other patches should be settled.
From 0922727410313e37c1ffaad4f6fbf90f9990923b Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <pe...@eisentraut.org>
Date: Tue, 19 Sep 2023 15:54:37 +0200
Subject: [PATCH v2 1/7] pg_resetwal: Update an obsolete comment

---
 src/bin/pg_resetwal/pg_resetwal.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/src/bin/pg_resetwal/pg_resetwal.c 
b/src/bin/pg_resetwal/pg_resetwal.c
index 25ecdaaa15..b7885e34f3 100644
--- a/src/bin/pg_resetwal/pg_resetwal.c
+++ b/src/bin/pg_resetwal/pg_resetwal.c
@@ -6,8 +6,7 @@
  *
  * The theory of operation is fairly simple:
  *       1. Read the existing pg_control (which will include the last
- *              checkpoint record).  If it is an old format then update to
- *              current format.
+ *              checkpoint record).
  *       2. If pg_control is corrupt, attempt to intuit reasonable values,
  *              by scanning the old xlog if necessary.
  *       3. Modify pg_control to reflect a "shutdown" state with a checkpoint

base-commit: bf094372d14bf00f1c04f70f6ec5790f8b2c8801
-- 
2.42.0

From 8fee9806bfa94fc999e730d3fb55946c656e6c64 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <pe...@eisentraut.org>
Date: Tue, 19 Sep 2023 15:58:49 +0200
Subject: [PATCH v2 2/7] pg_resetwal: Improve error with wrong/missing data
 directory

Run chdir() before permission check to get a less confusing error
message if the specified data directory does not exist.
---
 src/bin/pg_resetwal/pg_resetwal.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/bin/pg_resetwal/pg_resetwal.c 
b/src/bin/pg_resetwal/pg_resetwal.c
index b7885e34f3..e344c9284d 100644
--- a/src/bin/pg_resetwal/pg_resetwal.c
+++ b/src/bin/pg_resetwal/pg_resetwal.c
@@ -345,6 +345,10 @@ main(int argc, char *argv[])
 
        get_restricted_token();
 
+       if (chdir(DataDir) < 0)
+               pg_fatal("could not change directory to \"%s\": %m",
+                                DataDir);
+
        /* Set mask based on PGDATA permissions */
        if (!GetDataDirectoryCreatePerm(DataDir))
                pg_fatal("could not read permissions of directory \"%s\": %m",
@@ -352,10 +356,6 @@ main(int argc, char *argv[])
 
        umask(pg_mode_mask);
 
-       if (chdir(DataDir) < 0)
-               pg_fatal("could not change directory to \"%s\": %m",
-                                DataDir);
-
        /* Check that data directory matches our server version */
        CheckDataVersion();
 
-- 
2.42.0

From 241dc252f314ee32ebf853f236a17029ec477d50 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <pe...@eisentraut.org>
Date: Tue, 19 Sep 2023 16:02:35 +0200
Subject: [PATCH v2 3/7] pg_resetwal: Regroup --help output

Put the options to modify the control values into a separate group.
This matches the outline of the man page.
---
 src/bin/pg_resetwal/pg_resetwal.c | 19 ++++++++++++-------
 1 file changed, 12 insertions(+), 7 deletions(-)

diff --git a/src/bin/pg_resetwal/pg_resetwal.c 
b/src/bin/pg_resetwal/pg_resetwal.c
index e344c9284d..12e0869251 100644
--- a/src/bin/pg_resetwal/pg_resetwal.c
+++ b/src/bin/pg_resetwal/pg_resetwal.c
@@ -1128,24 +1128,29 @@ static void
 usage(void)
 {
        printf(_("%s resets the PostgreSQL write-ahead log.\n\n"), progname);
-       printf(_("Usage:\n  %s [OPTION]... DATADIR\n\n"), progname);
-       printf(_("Options:\n"));
+       printf(_("Usage:\n"));
+       printf(_("  %s [OPTION]... DATADIR\n"), progname);
+
+       printf(_("\nOptions:\n"));
+       printf(_(" [-D, --pgdata=]DATADIR  data directory\n"));
+       printf(_("  -f, --force            force update to be done\n"));
+       printf(_("  -n, --dry-run          no update, just show what would be 
done\n"));
+       printf(_("  -V, --version          output version information, then 
exit\n"));
+       printf(_("  -?, --help             show this help, then exit\n"));
+
+       printf(_("\nOptions to override control file values:\n"));
        printf(_("  -c, --commit-timestamp-ids=XID,XID\n"
                         "                                   set oldest and 
newest transactions bearing\n"
                         "                                   commit timestamp 
(zero means no change)\n"));
-       printf(_(" [-D, --pgdata=]DATADIR            data directory\n"));
        printf(_("  -e, --epoch=XIDEPOCH             set next transaction ID 
epoch\n"));
-       printf(_("  -f, --force                      force update to be 
done\n"));
        printf(_("  -l, --next-wal-file=WALFILE      set minimum starting 
location for new WAL\n"));
        printf(_("  -m, --multixact-ids=MXID,MXID    set next and oldest 
multitransaction ID\n"));
-       printf(_("  -n, --dry-run                    no update, just show what 
would be done\n"));
        printf(_("  -o, --next-oid=OID               set next OID\n"));
        printf(_("  -O, --multixact-offset=OFFSET    set next multitransaction 
offset\n"));
        printf(_("  -u, --oldest-transaction-id=XID  set oldest transaction 
ID\n"));
-       printf(_("  -V, --version                    output version 
information, then exit\n"));
        printf(_("  -x, --next-transaction-id=XID    set next transaction 
ID\n"));
        printf(_("      --wal-segsize=SIZE           size of WAL segments, in 
megabytes\n"));
-       printf(_("  -?, --help                       show this help, then 
exit\n"));
+
        printf(_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT);
        printf(_("%s home page: <%s>\n"), PACKAGE_NAME, PACKAGE_URL);
 }
-- 
2.42.0

From ff81acdd646c64efcae8b6cf083daff0494f6f82 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <pe...@eisentraut.org>
Date: Tue, 19 Sep 2023 16:06:22 +0200
Subject: [PATCH v2 4/7] pg_resetwal: Use frontend logging API

This now causes error messages related to the lack of the -f option to
appear on standard error rather than standard output.
---
 src/bin/pg_resetwal/pg_resetwal.c | 26 ++++++++++++++------------
 1 file changed, 14 insertions(+), 12 deletions(-)

diff --git a/src/bin/pg_resetwal/pg_resetwal.c 
b/src/bin/pg_resetwal/pg_resetwal.c
index 12e0869251..35876e1c95 100644
--- a/src/bin/pg_resetwal/pg_resetwal.c
+++ b/src/bin/pg_resetwal/pg_resetwal.c
@@ -458,20 +458,22 @@ main(int argc, char *argv[])
        if (minXlogSegNo > newXlogSegNo)
                newXlogSegNo = minXlogSegNo;
 
+       if (noupdate)
+       {
+               PrintNewControlValues();
+               exit(0);
+       }
+
        /*
         * If we had to guess anything, and -f was not given, just print the
-        * guessed values and exit.  Also print if -n is given.
+        * guessed values and exit.
         */
-       if ((guessed && !force) || noupdate)
+       if (guessed && !force)
        {
                PrintNewControlValues();
-               if (!noupdate)
-               {
-                       printf(_("\nIf these values seem acceptable, use -f to 
force reset.\n"));
-                       exit(1);
-               }
-               else
-                       exit(0);
+               pg_log_error("not proceeding because control file values were 
guessed");
+               pg_log_error_hint("If these values seem acceptable, use -f to 
force reset.");
+               exit(1);
        }
 
        /*
@@ -479,9 +481,9 @@ main(int argc, char *argv[])
         */
        if (ControlFile.state != DB_SHUTDOWNED && !force)
        {
-               printf(_("The database server was not shut down cleanly.\n"
-                                "Resetting the write-ahead log might cause 
data to be lost.\n"
-                                "If you want to proceed anyway, use -f to 
force reset.\n"));
+               pg_log_error("database server was not shut down cleanly");
+               pg_log_error_detail("Resetting the write-ahead log might cause 
data to be lost.");
+               pg_log_error_hint("If you want to proceed anyway, use -f to 
force reset.");
                exit(1);
        }
 
-- 
2.42.0

From fda162ae9864b121c386e07fabed520de089a3f5 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <pe...@eisentraut.org>
Date: Tue, 19 Sep 2023 16:09:32 +0200
Subject: [PATCH v2 5/7] doc: Improve documentation about pg_resetwal -f option

---
 doc/src/sgml/ref/pg_resetwal.sgml | 62 +++++++++++++++++++++++++------
 src/bin/pg_resetwal/pg_resetwal.c |  3 +-
 2 files changed, 53 insertions(+), 12 deletions(-)

diff --git a/doc/src/sgml/ref/pg_resetwal.sgml 
b/doc/src/sgml/ref/pg_resetwal.sgml
index fd539f5604..1f9c4b69dd 100644
--- a/doc/src/sgml/ref/pg_resetwal.sgml
+++ b/doc/src/sgml/ref/pg_resetwal.sgml
@@ -52,21 +52,33 @@ <title>Description</title>
   </para>
 
   <para>
-   After running this command, it should be possible to start the server,
+   Some options, such as <option>--wal-segsize</option> (see below), can also
+   be used to modify certain global settings of a database cluster without the
+   need to rerun <command>initdb</command>.  This can be done safely on an
+   otherwise sound database cluster, if none of the dangerous modes mentioned
+   below are used.
+  </para>
+
+  <para>
+   If <command>pg_resetwal</command> is used on a data directory where the
+   server has been cleanly shut down and the control file is sound, then it
+   will have no effect on the contents of the database system, except that no
+   longer used WAL files are cleared away.  Any other use is potentially
+   dangerous and must be done with great care.  <command>pg_resetwal</command>
+   will require the <option>-f</option> (force) option to be specified before
+   working on a data directory in an unclean shutdown state or with a
+   corrupted control file.
+  </para>
+
+  <para>
+   After running this command on a data directory with corrupted WAL or a
+   corrupted control file, it should be possible to start the server,
    but bear in mind that the database might contain inconsistent data due to
    partially-committed transactions.  You should immediately dump your data,
    run <command>initdb</command>, and restore.  After restore, check for
    inconsistencies and repair as needed.
   </para>
 
-  <para>
-   This utility can only be run by the user who installed the server, because
-   it requires read/write access to the data directory.
-   For safety reasons, you must specify the data directory on the command line.
-   <command>pg_resetwal</command> does not use the environment variable
-   <envar>PGDATA</envar>.
-  </para>
-
   <para>
    If <command>pg_resetwal</command> complains that it cannot determine
    valid data for <filename>pg_control</filename>, you can force it to proceed 
anyway
@@ -82,19 +94,41 @@ <title>Description</title>
    execute any data-modifying operations in the database before you dump,
    as any such action is likely to make the corruption worse.
   </para>
+
+  <para>
+   This utility can only be run by the user who installed the server, because
+   it requires read/write access to the data directory.
+  </para>
  </refsect1>
 
  <refsect1>
   <title>Options</title>
 
   <variablelist>
+   <varlistentry>
+    <term><replaceable class="parameter">datadir</replaceable></term>
+    <term><option>-D <replaceable 
class="parameter">datadir</replaceable></option></term>
+    <term><option>--pgdata=<replaceable 
class="parameter">datadir</replaceable></option></term>
+    <listitem>
+     <para>
+      Specifies the location of the database directory.
+      For safety reasons, you must specify the data directory on the command
+      line.  <command>pg_resetwal</command> does not use the environment
+      variable <envar>PGDATA</envar>.
+     </para>
+    </listitem>
+   </varlistentry>
+
    <varlistentry>
     <term><option>-f</option></term>
     <term><option>--force</option></term>
     <listitem>
      <para>
-      Force <command>pg_resetwal</command> to proceed even if it cannot 
determine
-      valid data for <filename>pg_control</filename>, as explained above.
+      Force <command>pg_resetwal</command> to proceed even in situations where
+      it could be dangerous, as explained above.  Specifically, this option is
+      required to proceed if the server had not been cleanly shut down, or if
+      <command>pg_resetwal</command> cannot determine valid data for
+      <filename>pg_control</filename>.
      </para>
     </listitem>
    </varlistentry>
@@ -284,6 +318,12 @@ <title>Options</title>
       linkend="app-initdb"/> for more information.
      </para>
 
+     <para>
+      This option can also be used to change the WAL segment size of an
+      existing database cluster, avoiding the need to
+      re-<command>initdb</command>.
+     </para>
+
      <note>
       <para>
        While <command>pg_resetwal</command> will set the WAL starting address
diff --git a/src/bin/pg_resetwal/pg_resetwal.c 
b/src/bin/pg_resetwal/pg_resetwal.c
index 35876e1c95..47e05bd2c9 100644
--- a/src/bin/pg_resetwal/pg_resetwal.c
+++ b/src/bin/pg_resetwal/pg_resetwal.c
@@ -1135,7 +1135,8 @@ usage(void)
 
        printf(_("\nOptions:\n"));
        printf(_(" [-D, --pgdata=]DATADIR  data directory\n"));
-       printf(_("  -f, --force            force update to be done\n"));
+       printf(_("  -f, --force            force update to be done even after 
unclean shutdown or\n"
+                        "                         if pg_control values had to 
be guessed\n"));
        printf(_("  -n, --dry-run          no update, just show what would be 
done\n"));
        printf(_("  -V, --version          output version information, then 
exit\n"));
        printf(_("  -?, --help             show this help, then exit\n"));
-- 
2.42.0

From bc62da6173e029e1fd25d13bbbe648f008be6b68 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <pe...@eisentraut.org>
Date: Tue, 19 Sep 2023 16:11:38 +0200
Subject: [PATCH v2 6/7] doc: pg_resetwal: Add comments how the multipliers are
 derived

---
 doc/src/sgml/ref/pg_resetwal.sgml | 8 +++++++-
 src/bin/pg_resetwal/pg_resetwal.c | 1 +
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/doc/src/sgml/ref/pg_resetwal.sgml 
b/doc/src/sgml/ref/pg_resetwal.sgml
index 1f9c4b69dd..8380f97c04 100644
--- a/doc/src/sgml/ref/pg_resetwal.sgml
+++ b/doc/src/sgml/ref/pg_resetwal.sgml
@@ -166,7 +166,8 @@ <title>Options</title>
    <command>pg_resetwal</command> is unable to determine appropriate values
    by reading <filename>pg_control</filename>.  Safe values can be determined 
as
    described below.  For values that take numeric arguments, hexadecimal
-   values can be specified by using the prefix <literal>0x</literal>.
+   values can be specified by using the prefix <literal>0x</literal>.  Note
+   that these instructions only apply with the standard block size of 8 kB.
   </para>
 
   <variablelist>
@@ -189,6 +190,7 @@ <title>Options</title>
       greatest file name in the same directory.  The file names are in
       hexadecimal.
      </para>
+      <!-- FIXME: multiplier? -->
     </listitem>
    </varlistentry>
 
@@ -272,6 +274,7 @@ <title>Options</title>
       names are in hexadecimal, so the easiest way to do this is to specify
       the option value in hexadecimal and append four zeroes.
      </para>
+     <!-- 65536 = SLRU_PAGES_PER_SEGMENT * BLCKSZ / sizeof(MultiXactOffset) -->
     </listitem>
    </varlistentry>
 
@@ -306,6 +309,7 @@ <title>Options</title>
       The file names are in hexadecimal.  There is no simple recipe such as
       the ones for other options of appending zeroes.
      </para>
+     <!-- 52352 = SLRU_PAGES_PER_SEGMENT * floor(BLCKSZ/20) * 4; see 
multixact.c -->
     </listitem>
    </varlistentry>
 
@@ -354,6 +358,7 @@ <title>Options</title>
       in <filename>pg_xact</filename>, <literal>-u 0x700000</literal> will 
work (five
       trailing zeroes provide the proper multiplier).
      </para>
+     <!-- 1048576 = SLRU_PAGES_PER_SEGMENT * BLCKSZ * CLOG_XACTS_PER_BYTE -->
     </listitem>
    </varlistentry>
 
@@ -375,6 +380,7 @@ <title>Options</title>
       in <filename>pg_xact</filename>, <literal>-x 0x1200000</literal> will 
work (five
       trailing zeroes provide the proper multiplier).
      </para>
+     <!-- 1048576 = SLRU_PAGES_PER_SEGMENT * BLCKSZ * CLOG_XACTS_PER_BYTE -->
     </listitem>
    </varlistentry>
   </variablelist>
diff --git a/src/bin/pg_resetwal/pg_resetwal.c 
b/src/bin/pg_resetwal/pg_resetwal.c
index 47e05bd2c9..89b35c2748 100644
--- a/src/bin/pg_resetwal/pg_resetwal.c
+++ b/src/bin/pg_resetwal/pg_resetwal.c
@@ -211,6 +211,7 @@ main(int argc, char *argv[])
                                        exit(1);
                                }
 
+                               // FIXME: why 2?
                                if (set_oldest_commit_ts_xid < 2 &&
                                        set_oldest_commit_ts_xid != 0)
                                        pg_fatal("transaction ID (-c) must be 
either 0 or greater than or equal to 2");
-- 
2.42.0

From e3874416d63113668ac67cffd92765531a5df697 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <pe...@eisentraut.org>
Date: Tue, 19 Sep 2023 16:12:52 +0200
Subject: [PATCH v2 7/7] pg_resetwal: Add more tests and test coverage

---
 src/bin/pg_resetwal/t/001_basic.pl     | 114 +++++++++++++++++++++++++
 src/bin/pg_resetwal/t/002_corrupted.pl |   4 +
 2 files changed, 118 insertions(+)

diff --git a/src/bin/pg_resetwal/t/001_basic.pl 
b/src/bin/pg_resetwal/t/001_basic.pl
index 7e5efbf56b..001bb455ef 100644
--- a/src/bin/pg_resetwal/t/001_basic.pl
+++ b/src/bin/pg_resetwal/t/001_basic.pl
@@ -14,6 +14,7 @@
 
 my $node = PostgreSQL::Test::Cluster->new('main');
 $node->init;
+$node->append_conf('postgresql.conf', 'track_commit_timestamp = on');
 
 command_like([ 'pg_resetwal', '-n', $node->data_dir ],
        qr/checkpoint/, 'pg_resetwal -n produces output');
@@ -29,4 +30,117 @@
                'check PGDATA permissions');
 }
 
+command_ok([ 'pg_resetwal', '-D', $node->data_dir ], 'pg_resetwal runs');
+$node->start;
+is($node->safe_psql("postgres", "SELECT 1;"), 1, 'server running and working 
after reset');
+
+command_fails_like([ 'pg_resetwal', $node->data_dir ], qr/lock file .* 
exists/, 'fails if server running');
+
+$node->stop('immediate');
+command_fails_like([ 'pg_resetwal', $node->data_dir ], qr/database server was 
not shut down cleanly/, 'does not run after immediate shutdown');
+command_ok([ 'pg_resetwal', '-f', $node->data_dir ], 'runs after immediate 
shutdown with force');
+$node->start;
+is($node->safe_psql("postgres", "SELECT 1;"), 1, 'server running and working 
after forced reset');
+
+$node->stop;
+
+# check various command-line handling
+
+command_fails_like([ 'pg_resetwal', 'foo' ], qr/error: could not change 
directory/, 'fails with nonexistent data directory');
+command_fails_like([ 'pg_resetwal', 'foo', 'bar'], qr/too many command-line 
arguments/, 'fails with too many command-line arguments');
+
+$ENV{PGDATA} = $node->data_dir;  # not used
+command_fails_like([ 'pg_resetwal' ], qr/no data directory specified/, 'fails 
with too few command-line arguments');
+
+# error cases
+# -c
+command_fails_like([ 'pg_resetwal', '-c', 'foo', $node->data_dir], qr/error: 
invalid argument for option -c/, 'fails with incorrect -c option');
+command_fails_like([ 'pg_resetwal', '-c', '10,bar', $node->data_dir], 
qr/error: invalid argument for option -c/, 'fails with incorrect -c option part 
2');
+command_fails_like([ 'pg_resetwal', '-c', '1,10', $node->data_dir], qr/greater 
than/, 'fails with -c value 1 part 1');
+command_fails_like([ 'pg_resetwal', '-c', '10,1', $node->data_dir], qr/greater 
than/, 'fails with -c value 1 part 2');
+# -e
+command_fails_like([ 'pg_resetwal', '-e', 'foo', $node->data_dir], qr/error: 
invalid argument for option -e/, 'fails with incorrect -e option');
+command_fails_like([ 'pg_resetwal', '-e', '-1', $node->data_dir], qr/must not 
be -1/, 'fails with -e value -1');
+# -l
+command_fails_like([ 'pg_resetwal', '-l', 'foo', $node->data_dir], qr/error: 
invalid argument for option -l/, 'fails with incorrect -l option');
+# -m
+command_fails_like([ 'pg_resetwal', '-m', 'foo', $node->data_dir], qr/error: 
invalid argument for option -m/, 'fails with incorrect -m option');
+command_fails_like([ 'pg_resetwal', '-m', '10,bar', $node->data_dir], 
qr/error: invalid argument for option -m/, 'fails with incorrect -m option part 
2');
+command_fails_like([ 'pg_resetwal', '-m', '0,10', $node->data_dir], qr/must 
not be 0/, 'fails with -m value 0 part 1');
+command_fails_like([ 'pg_resetwal', '-m', '10,0', $node->data_dir], qr/must 
not be 0/, 'fails with -m value 0 part 2');
+# -o
+command_fails_like([ 'pg_resetwal', '-o', 'foo', $node->data_dir], qr/error: 
invalid argument for option -o/, 'fails with incorrect -o option');
+command_fails_like([ 'pg_resetwal', '-o', '0', $node->data_dir], qr/must not 
be 0/, 'fails with -o value 0');
+# -O
+command_fails_like([ 'pg_resetwal', '-O', 'foo', $node->data_dir], qr/error: 
invalid argument for option -O/, 'fails with incorrect -O option');
+command_fails_like([ 'pg_resetwal', '-O', '-1', $node->data_dir], qr/must not 
be -1/, 'fails with -O value -1');
+# --wal-segsize
+command_fails_like([ 'pg_resetwal', '--wal-segsize', 'foo', $node->data_dir], 
qr/error: invalid value/, 'fails with incorrect --wal-segsize option');
+command_fails_like([ 'pg_resetwal', '--wal-segsize', '13', $node->data_dir], 
qr/must be a power/, 'fails with invalid --wal-segsize value');
+# -u
+command_fails_like([ 'pg_resetwal', '-u', 'foo', $node->data_dir], qr/error: 
invalid argument for option -u/, 'fails with incorrect -u option');
+command_fails_like([ 'pg_resetwal', '-u', '1', $node->data_dir], qr/must be 
greater than/, 'fails with -u value too small');
+# -x
+command_fails_like([ 'pg_resetwal', '-x', 'foo', $node->data_dir], qr/error: 
invalid argument for option -x/, 'fails with incorrect -x option');
+command_fails_like([ 'pg_resetwal', '-x', '1', $node->data_dir], qr/must be 
greater than/, 'fails with -x value too small');
+
+# run with control override options
+
+my $out = (run_command([ 'pg_resetwal', '-n', $node->data_dir ]))[0];
+$out =~ /^Database block size: *(\d+)$/m or die;
+my $blcksz = $1;
+
+my @cmd = ('pg_resetwal', '-D', $node->data_dir);
+
+# some not-so-critical hardcoded values
+push @cmd, '-e', 1;
+push @cmd, '-l', '00000001000000320000004B';
+push @cmd, '-o', 100_000;
+push @cmd, '--wal-segsize', 1;
+
+# these use the guidance from the documentation
+
+sub get_slru_files
+{
+       opendir(my $dh, $node->data_dir . '/' . $_[0]) or die $!;
+       my @files = sort grep { /[0-9A-F]+/ } readdir $dh;
+       closedir $dh;
+       return @files;
+}
+
+my (@files, $mult);
+
+@files = get_slru_files('pg_commit_ts');
+$mult = 32 * $blcksz * 4; # FIXME
+# -c argument is "old,new"
+push @cmd,
+  '-c', sprintf("%d,%d",
+         hex($files[0]) == 0 ? 2 : hex($files[0]), hex($files[-1]));
+
+@files = get_slru_files('pg_multixact/offsets');
+$mult = 32 * $blcksz / 4;
+# -m argument is "new,old"
+push @cmd,
+  '-m', sprintf("%d,%d",
+         (hex($files[-1]) + 1) * $mult,
+         hex($files[0]) == 0 ? 1 : hex($files[0] * $mult));
+
+@files = get_slru_files('pg_multixact/members');
+$mult = 32 * int($blcksz/20) * 4;
+push @cmd,
+  '-O', (hex($files[-1]) + 1) * $mult;
+
+@files = get_slru_files('pg_xact');
+$mult = 32 * $blcksz * 4;
+push @cmd,
+  '-u', (hex($files[0]) == 0 ? 3 : hex($files[0]) * $mult),
+  '-x', ((hex($files[-1]) + 1) * $mult);
+
+command_ok([@cmd, '-n'], 'runs with control override options, dry run');
+command_ok(\@cmd, 'runs with control override options');
+command_like([ 'pg_resetwal', '-n', $node->data_dir ], qr/^Latest checkpoint's 
NextOID: *100000$/m, 'spot check that control changes were applied');
+
+$node->start;
+ok(1, 'server started after reset');
+
 done_testing();
diff --git a/src/bin/pg_resetwal/t/002_corrupted.pl 
b/src/bin/pg_resetwal/t/002_corrupted.pl
index 6d19a1efd5..ddbd0556bb 100644
--- a/src/bin/pg_resetwal/t/002_corrupted.pl
+++ b/src/bin/pg_resetwal/t/002_corrupted.pl
@@ -55,4 +55,8 @@
        ],
        'processes zero WAL segment size');
 
+# now try to run it
+command_fails_like([ 'pg_resetwal', $node->data_dir ], qr/not proceeding 
because control file values were guessed/, 'does not run when control file 
values were guessed');
+command_ok([ 'pg_resetwal', '-f', $node->data_dir ], 'runs with force when 
control file values were guessed');
+
 done_testing();
-- 
2.42.0

Reply via email to