Improve command line options for pg_waldump.
authorThomas Munro <tmunro@postgresql.org>
Fri, 25 Mar 2022 00:44:10 +0000 (13:44 +1300)
committerThomas Munro <tmunro@postgresql.org>
Fri, 25 Mar 2022 00:52:27 +0000 (13:52 +1300)
Follow-up improvements for commit 127aea2a based on discussion:

* use fork name for --fork, not number
* use -R, -B as short switches for --relation, --block
* re-alphabetize the list of switches (code, --help and docs)

Suggested-by: Peter Eisentraut <peter.eisentraut@enterprisedb.com> (fork name part)
Reviewed-by: David Christensen <david.christensen@crunchydata.com>
Reviewed-by: Japin Li <japinli@hotmail.com>
Discussion: https://postgr.es/m/3a4c2e93-7976-2320-fc0a-32097fe148a7%40enterprisedb.com

doc/src/sgml/ref/pg_waldump.sgml
src/bin/pg_waldump/pg_waldump.c

index 981d3c90382dff0d5b5f9657d27e7e3e4335ace8..4e86f44c5b3bef01e94ccd458ab72219b8d479a8 100644 (file)
@@ -78,6 +78,18 @@ PostgreSQL documentation
       </listitem>
      </varlistentry>
 
+     <varlistentry>
+      <term><option>-B <replaceable>block</replaceable></option></term>
+      <term><option>--block=<replaceable>block</replaceable></option></term>
+      <listitem>
+       <para>
+        Only display records that modify the given block.  The relation must
+        also be provided with <option>--relation</option> or
+        <option>-l</option>.
+       </para>
+      </listitem>
+     </varlistentry>
+
      <varlistentry>
       <term><option>-e <replaceable>end</replaceable></option></term>
       <term><option>--end=<replaceable>end</replaceable></option></term>
@@ -100,41 +112,16 @@ PostgreSQL documentation
       </listitem>
      </varlistentry>
 
-     <varlistentry>
-      <term><option>-k <replaceable>block</replaceable></option></term>
-      <term><option>--block=<replaceable>block</replaceable></option></term>
-      <listitem>
-       <para>
-        Only display records that modify the given block.  The relation must
-        also be provided with <option>--relation</option> or
-        <option>-l</option>.
-       </para>
-      </listitem>
-     </varlistentry>
-
      <varlistentry>
       <term><option>-F <replaceable>fork</replaceable></option></term>
       <term><option>--fork=<replaceable>fork</replaceable></option></term>
       <listitem>
        <para>
         If provided, only display records that modify blocks in the given fork.
-        The valid values are <literal>0</literal> for the main fork,
-        <literal>1</literal> for the free space map,
-        <literal>2</literal> for the visibility map,
-        and <literal>3</literal> for the init fork.
-       </para>
-      </listitem>
-     </varlistentry>
-
-     <varlistentry>
-      <term><option>-l <replaceable>tblspc</replaceable>/<replaceable>db</replaceable>/<replaceable>rel</replaceable></option></term>
-      <term><option>--relation=<replaceable>tblspc</replaceable>/<replaceable>db</replaceable>/<replaceable>rel</replaceable></option></term>
-      <listitem>
-       <para>
-        Only display records that modify blocks in the given relation.  The
-        relation is specified with tablespace OID, database OID, and relfilenode
-        separated by slashes, for example <literal>1234/12345/12345</literal>.
-        This is the same format used for relations in the program's output.
+        The valid values are <literal>main</literal> for the main fork,
+        <literal>fsm</literal> for the free space map,
+        <literal>vm</literal> for the visibility map,
+        and <literal>init</literal> for the init fork.
        </para>
       </listitem>
      </varlistentry>
@@ -189,6 +176,19 @@ PostgreSQL documentation
       </listitem>
      </varlistentry>
 
+     <varlistentry>
+      <term><option>-R <replaceable>tblspc</replaceable>/<replaceable>db</replaceable>/<replaceable>rel</replaceable></option></term>
+      <term><option>--relation=<replaceable>tblspc</replaceable>/<replaceable>db</replaceable>/<replaceable>rel</replaceable></option></term>
+      <listitem>
+       <para>
+        Only display records that modify blocks in the given relation.  The
+        relation is specified with tablespace OID, database OID, and relfilenode
+        separated by slashes, for example <literal>1234/12345/12345</literal>.
+        This is the same format used for relations in the program's output.
+       </para>
+      </listitem>
+     </varlistentry>
+
      <varlistentry>
       <term><option>-s <replaceable>start</replaceable></option></term>
       <term><option>--start=<replaceable>start</replaceable></option></term>
index 92238f30c9ee8cb6dd3b77b903b24127432b2842..9ffe9e55bd9d393ca5c7bef9494300c14746b33c 100644 (file)
@@ -825,12 +825,11 @@ usage(void)
    printf(_("  %s [OPTION]... [STARTSEG [ENDSEG]]\n"), progname);
    printf(_("\nOptions:\n"));
    printf(_("  -b, --bkp-details      output detailed information about backup blocks\n"));
+   printf(_("  -B, --block=N          with --relation, only show records that modify block N\n"));
    printf(_("  -e, --end=RECPTR       stop reading at WAL location RECPTR\n"));
    printf(_("  -f, --follow           keep retrying after reaching end of WAL\n"));
-   printf(_("  -k, --block=N          with --relation, only show records matching this block\n"));
-   printf(_("  -F, --fork=N           only show records matching a specific fork number\n"
-            "                         (defaults to showing all)\n"));
-   printf(_("  -l, --relation=N/N/N   only show records that affect a specific relation\n"));
+   printf(_("  -F, --fork=FORK        only show records that modify blocks in fork FORK;\n"
+            "                         valid names are main, fsm, vm, init\n"));
    printf(_("  -n, --limit=N          number of records to display\n"));
    printf(_("  -p, --path=PATH        directory in which to find log segment files or a\n"
             "                         directory with a ./pg_wal that contains such files\n"
@@ -838,12 +837,13 @@ usage(void)
    printf(_("  -q, --quiet            do not print any output, except for errors\n"));
    printf(_("  -r, --rmgr=RMGR        only show records generated by resource manager RMGR;\n"
             "                         use --rmgr=list to list valid resource manager names\n"));
+   printf(_("  -R, --relation=T/D/R   only show records that modify blocks in relation T/D/R\n"));
    printf(_("  -s, --start=RECPTR     start reading at WAL location RECPTR\n"));
    printf(_("  -t, --timeline=TLI     timeline from which to read log records\n"
             "                         (default: 1 or the value used in STARTSEG)\n"));
    printf(_("  -V, --version          output version information, then exit\n"));
-   printf(_("  -x, --xid=XID          only show records with transaction ID XID\n"));
    printf(_("  -w, --fullpage         only show records with a full page write\n"));
+   printf(_("  -x, --xid=XID          only show records with transaction ID XID\n"));
    printf(_("  -z, --stats[=record]   show statistics instead of records\n"
             "                         (optionally, show per-record statistics)\n"));
    printf(_("  -?, --help             show this help, then exit\n"));
@@ -867,7 +867,7 @@ main(int argc, char **argv)
 
    static struct option long_options[] = {
        {"bkp-details", no_argument, NULL, 'b'},
-       {"block", required_argument, NULL, 'k'},
+       {"block", required_argument, NULL, 'B'},
        {"end", required_argument, NULL, 'e'},
        {"follow", no_argument, NULL, 'f'},
        {"fork", required_argument, NULL, 'F'},
@@ -876,7 +876,7 @@ main(int argc, char **argv)
        {"limit", required_argument, NULL, 'n'},
        {"path", required_argument, NULL, 'p'},
        {"quiet", no_argument, NULL, 'q'},
-       {"relation", required_argument, NULL, 'l'},
+       {"relation", required_argument, NULL, 'R'},
        {"rmgr", required_argument, NULL, 'r'},
        {"start", required_argument, NULL, 's'},
        {"timeline", required_argument, NULL, 't'},
@@ -946,7 +946,7 @@ main(int argc, char **argv)
        goto bad_argument;
    }
 
-   while ((option = getopt_long(argc, argv, "be:fF:k:l:n:p:qr:s:t:wx:z",
+   while ((option = getopt_long(argc, argv, "bB:e:fF:n:p:qr:R:s:t:wx:z",
                                 long_options, &optindex)) != -1)
    {
        switch (option)
@@ -954,6 +954,16 @@ main(int argc, char **argv)
            case 'b':
                config.bkp_details = true;
                break;
+           case 'B':
+               if (sscanf(optarg, "%u", &config.filter_by_relation_block) != 1 ||
+                   !BlockNumberIsValid(config.filter_by_relation_block))
+               {
+                   pg_log_error("could not parse valid block number \"%s\"", optarg);
+                   goto bad_argument;
+               }
+               config.filter_by_relation_block_enabled = true;
+               config.filter_by_extended = true;
+               break;
            case 'e':
                if (sscanf(optarg, "%X/%X", &xlogid, &xrecoff) != 2)
                {
@@ -967,44 +977,12 @@ main(int argc, char **argv)
                config.follow = true;
                break;
            case 'F':
+               config.filter_by_relation_forknum = forkname_to_number(optarg);
+               if (config.filter_by_relation_forknum == InvalidForkNumber)
                {
-                   unsigned int forknum;
-
-                   if (sscanf(optarg, "%u", &forknum) != 1 ||
-                       forknum > MAX_FORKNUM)
-                   {
-                       pg_log_error("could not parse valid fork number (0..%d) \"%s\"",
-                                    MAX_FORKNUM, optarg);
-                       goto bad_argument;
-                   }
-                   config.filter_by_relation_forknum = (ForkNumber) forknum;
-                   config.filter_by_extended = true;
-               }
-               break;
-           case 'k':
-               if (sscanf(optarg, "%u", &config.filter_by_relation_block) != 1 ||
-                   !BlockNumberIsValid(config.filter_by_relation_block))
-               {
-                   pg_log_error("could not parse valid block number \"%s\"", optarg);
-                   goto bad_argument;
-               }
-               config.filter_by_relation_block_enabled = true;
-               config.filter_by_extended = true;
-               break;
-           case 'l':
-               if (sscanf(optarg, "%u/%u/%u",
-                          &config.filter_by_relation.spcNode,
-                          &config.filter_by_relation.dbNode,
-                          &config.filter_by_relation.relNode) != 3 ||
-                   !OidIsValid(config.filter_by_relation.spcNode) ||
-                   !OidIsValid(config.filter_by_relation.relNode))
-               {
-                   pg_log_error("could not parse valid relation from \"%s\""
-                                " (expecting \"tablespace OID/database OID/"
-                                "relation filenode\")", optarg);
+                   pg_log_error("could not parse fork \"%s\"", optarg);
                    goto bad_argument;
                }
-               config.filter_by_relation_enabled = true;
                config.filter_by_extended = true;
                break;
            case 'n':
@@ -1047,6 +1025,22 @@ main(int argc, char **argv)
                    }
                }
                break;
+           case 'R':
+               if (sscanf(optarg, "%u/%u/%u",
+                          &config.filter_by_relation.spcNode,
+                          &config.filter_by_relation.dbNode,
+                          &config.filter_by_relation.relNode) != 3 ||
+                   !OidIsValid(config.filter_by_relation.spcNode) ||
+                   !OidIsValid(config.filter_by_relation.relNode))
+               {
+                   pg_log_error("could not parse valid relation from \"%s\""
+                                " (expecting \"tablespace OID/database OID/"
+                                "relation filenode\")", optarg);
+                   goto bad_argument;
+               }
+               config.filter_by_relation_enabled = true;
+               config.filter_by_extended = true;
+               break;
            case 's':
                if (sscanf(optarg, "%X/%X", &xlogid, &xrecoff) != 2)
                {