Add --no-index-cleanup and --no-truncate to vacuumdb.
authorMichael Paquier <michael@paquier.xyz>
Mon, 22 Jun 2020 04:23:38 +0000 (13:23 +0900)
committerMichael Paquier <michael@paquier.xyz>
Mon, 22 Jun 2020 04:23:38 +0000 (13:23 +0900)
Both INDEX_CLEANUP and TRUNCATE have been available since v12, and are
enabled by default except if respectively vacuum_index_cleanup and
vacuum_truncate are disabled for a given relation.  This change adds
support for disabling these options from vacuumdb.

Author: Nathan Bossart
Reviewed-by: Michael Paquier, Masahiko Sawada
Discussion: https://postgr.es/m/6F7F17EF-B1F2-4681-8D03-BA96365717C0@amazon.com

doc/src/sgml/ref/vacuumdb.sgml
src/bin/scripts/t/100_vacuumdb.pl
src/bin/scripts/vacuumdb.c

index fd1dc140abadf2ce0259cc89200445488420191f..95d6894cb03a6d663e1fd53e20ee47853616325f 100644 (file)
@@ -226,6 +226,36 @@ PostgreSQL documentation
       </listitem>
      </varlistentry>
 
+     <varlistentry>
+      <term><option>--no-index-cleanup</option></term>
+      <listitem>
+       <para>
+        Do not remove index entries pointing to dead tuples.
+       </para>
+       <note>
+        <para>
+         This option is only available for servers running
+         <productname>PostgreSQL</productname> 12 and later.
+        </para>
+       </note>
+      </listitem>
+     </varlistentry>
+
+     <varlistentry>
+      <term><option>--no-truncate</option></term>
+      <listitem>
+       <para>
+        Do not truncate empty pages at the end of the table.
+       </para>
+       <note>
+        <para>
+         This option is only available for servers running
+         <productname>PostgreSQL</productname> 12 and later.
+        </para>
+       </note>
+      </listitem>
+     </varlistentry>
+
      <varlistentry>
       <term><option>-P <replaceable class="parameter">parallel_degree</replaceable></option></term>
       <term><option>--parallel=<replaceable class="parameter">parallel_degree</replaceable></option></term>
index b136bd4457084d677e2e39220a68ab2eb0c6652e..9e36b6d2b05fe8ecb19185188ecf74a52226928a 100644 (file)
@@ -3,7 +3,7 @@ use warnings;
 
 use PostgresNode;
 use TestLib;
-use Test::More tests => 49;
+use Test::More tests => 55;
 
 program_help_ok('vacuumdb');
 program_version_ok('vacuumdb');
@@ -48,6 +48,20 @@ $node->issues_sql_like(
 $node->command_fails(
        [ 'vacuumdb', '--analyze-only', '--disable-page-skipping', 'postgres' ],
        '--analyze-only and --disable-page-skipping specified together');
+$node->issues_sql_like(
+       [ 'vacuumdb', '--no-index-cleanup', 'postgres' ],
+       qr/statement: VACUUM \(INDEX_CLEANUP FALSE\).*;/,
+       'vacuumdb --no-index-cleanup');
+$node->command_fails(
+       [ 'vacuumdb', '--analyze-only', '--no-index-cleanup', 'postgres' ],
+       '--analyze-only and --no-index-cleanup specified together');
+$node->issues_sql_like(
+    [ 'vacuumdb', '--no-truncate', 'postgres' ],
+    qr/statement: VACUUM \(TRUNCATE FALSE\).*;/,
+    'vacuumdb --no-truncate');
+$node->command_fails(
+    [ 'vacuumdb', '--analyze-only', '--no-truncate', 'postgres' ],
+    '--analyze-only and --no-truncate specified together');
 $node->issues_sql_like(
        [ 'vacuumdb', '-P', 2, 'postgres' ],
        qr/statement: VACUUM \(PARALLEL 2\).*;/,
index 154084a086e1ea584af1f0fe14fefe8e7e1a6ac7..6a3c941158fb76bff2432f4dc9f1dba01ae8280d 100644 (file)
@@ -37,6 +37,8 @@ typedef struct vacuumingOptions
        int                     min_mxid_age;
        int                     parallel_workers;       /* >= 0 indicates user specified the
                                                                         * parallel degree, otherwise -1 */
+       bool            do_index_cleanup;
+       bool            do_truncate;
 } vacuumingOptions;
 
 
@@ -96,6 +98,8 @@ main(int argc, char *argv[])
                {"skip-locked", no_argument, NULL, 5},
                {"min-xid-age", required_argument, NULL, 6},
                {"min-mxid-age", required_argument, NULL, 7},
+               {"no-index-cleanup", no_argument, NULL, 8},
+               {"no-truncate", no_argument, NULL, 9},
                {NULL, 0, NULL, 0}
        };
 
@@ -117,9 +121,11 @@ main(int argc, char *argv[])
        int                     concurrentCons = 1;
        int                     tbl_count = 0;
 
-       /* initialize options to all false */
+       /* initialize options */
        memset(&vacopts, 0, sizeof(vacopts));
        vacopts.parallel_workers = -1;
+       vacopts.do_index_cleanup = true;
+       vacopts.do_truncate = true;
 
        pg_logging_init(argv[0]);
        progname = get_progname(argv[0]);
@@ -223,6 +229,12 @@ main(int argc, char *argv[])
                                        exit(1);
                                }
                                break;
+                       case 8:
+                               vacopts.do_index_cleanup = false;
+                               break;
+                       case 9:
+                               vacopts.do_truncate = false;
+                               break;
                        default:
                                fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
                                exit(1);
@@ -267,6 +279,18 @@ main(int argc, char *argv[])
                                                 "disable-page-skipping");
                        exit(1);
                }
+               if (!vacopts.do_index_cleanup)
+               {
+                       pg_log_error("cannot use the \"%s\" option when performing only analyze",
+                                                "no-index-cleanup");
+                       exit(1);
+               }
+               if (!vacopts.do_truncate)
+               {
+                       pg_log_error("cannot use the \"%s\" option when performing only analyze",
+                                                "no-truncate");
+                       exit(1);
+               }
                /* allow 'and_analyze' with 'analyze_only' */
        }
 
@@ -412,6 +436,22 @@ vacuum_one_database(const char *dbname, vacuumingOptions *vacopts,
                exit(1);
        }
 
+       if (!vacopts->do_index_cleanup && PQserverVersion(conn) < 120000)
+       {
+               PQfinish(conn);
+               pg_log_error("cannot use the \"%s\" option on server versions older than PostgreSQL %s",
+                                        "no-index-cleanup", "12");
+               exit(1);
+       }
+
+       if (!vacopts->do_truncate && PQserverVersion(conn) < 120000)
+       {
+               PQfinish(conn);
+               pg_log_error("cannot use the \"%s\" option on server versions older than PostgreSQL %s",
+                                        "no-truncate", "12");
+               exit(1);
+       }
+
        if (vacopts->skip_locked && PQserverVersion(conn) < 120000)
        {
                PQfinish(conn);
@@ -832,6 +872,20 @@ prepare_vacuum_command(PQExpBuffer sql, int serverVersion,
                                appendPQExpBuffer(sql, "%sDISABLE_PAGE_SKIPPING", sep);
                                sep = comma;
                        }
+                       if (!vacopts->do_index_cleanup)
+                       {
+                               /* INDEX_CLEANUP is supported since v12 */
+                               Assert(serverVersion >= 120000);
+                               appendPQExpBuffer(sql, "%sINDEX_CLEANUP FALSE", sep);
+                               sep = comma;
+                       }
+                       if (!vacopts->do_truncate)
+                       {
+                               /* TRUNCATE is supported since v12 */
+                               Assert(serverVersion >= 120000);
+                               appendPQExpBuffer(sql, "%sTRUNCATE FALSE", sep);
+                               sep = comma;
+                       }
                        if (vacopts->skip_locked)
                        {
                                /* SKIP_LOCKED is supported since v12 */
@@ -930,6 +984,8 @@ help(const char *progname)
        printf(_("  -j, --jobs=NUM                  use this many concurrent connections to vacuum\n"));
        printf(_("      --min-mxid-age=MXID_AGE     minimum multixact ID age of tables to vacuum\n"));
        printf(_("      --min-xid-age=XID_AGE       minimum transaction ID age of tables to vacuum\n"));
+       printf(_("      --no-index-cleanup          don't remove index entries that point to dead tuples\n"));
+       printf(_("      --no-truncate               don't truncate empty pages at the end of the table\n"));
        printf(_("  -P, --parallel=PARALLEL_DEGREE  use this many background workers for vacuum, if available\n"));
        printf(_("  -q, --quiet                     don't write any messages\n"));
        printf(_("      --skip-locked               skip relations that cannot be immediately locked\n"));