]> granicus.if.org Git - postgresql/commitdiff
Add --disable-page-skipping and --skip-locked to vacuumdb
authorMichael Paquier <michael@paquier.xyz>
Tue, 8 Jan 2019 01:52:29 +0000 (10:52 +0900)
committerMichael Paquier <michael@paquier.xyz>
Tue, 8 Jan 2019 01:52:29 +0000 (10:52 +0900)
DISABLE_PAGE_SKIPPING is available since v9.6, and SKIP_LOCKED since
v12.  They lacked equivalents for vacuumdb, so this closes the gap.

Author: Nathan Bossart
Reviewed-by: Michael Paquier, Masahiko Sawada
Discussion: https://postgr.es/m/FFE5373C-E26A-495B-B5C8-911EC4A41C5E@amazon.com

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

index 955a17a849b0c7fc01eb8fac4e58b1d4cabef442..da4d51e76359296d154d50206d840499012a7ff1 100644 (file)
@@ -102,6 +102,23 @@ PostgreSQL documentation
       </listitem>
      </varlistentry>
 
+     <varlistentry>
+      <term><option>--disable-page-skipping</option></term>
+      <listitem>
+       <para>
+        Disable all page-skipping behavior during processing based on
+        the visibility map, similarly to the option
+        <literal>DISABLE_PAGE_SKIPPING</literal> for <command>VACUUM</command>.
+       </para>
+       <note>
+        <para>
+         This option is only available for servers running
+         <productname>PostgreSQL</productname> 9.6 and later.
+        </para>
+       </note>
+      </listitem>
+     </varlistentry>
+
      <varlistentry>
       <term><option>-e</option></term>
       <term><option>--echo</option></term>
@@ -167,6 +184,21 @@ PostgreSQL documentation
       </listitem>
      </varlistentry>
 
+     <varlistentry>
+      <term><option>--skip-locked</option></term>
+      <listitem>
+       <para>
+        Skip relations that cannot be immediately locked for processing.
+       </para>
+       <note>
+        <para>
+         This option is only available for servers running
+         <productname>PostgreSQL</productname> 12 and later.
+        </para>
+       </note>
+      </listitem>
+     </varlistentry>
+
      <varlistentry>
       <term><option>-t <replaceable class="parameter">table</replaceable> [ (<replaceable class="parameter">column</replaceable> [,...]) ]</option></term>
       <term><option>--table=<replaceable class="parameter">table</replaceable> [ (<replaceable class="parameter">column</replaceable> [,...]) ]</option></term>
index 4c477a27aa80d58bf27669953f5fba0483e44b69..7cb2542e4735aa43d419c7e7c560fb0a6b770619 100644 (file)
@@ -3,7 +3,7 @@ use warnings;
 
 use PostgresNode;
 use TestLib;
-use Test::More tests => 23;
+use Test::More tests => 30;
 
 program_help_ok('vacuumdb');
 program_version_ok('vacuumdb');
@@ -33,6 +33,21 @@ $node->issues_sql_like(
        [ 'vacuumdb', '-Z', 'postgres' ],
        qr/statement: ANALYZE;/,
        'vacuumdb -Z');
+$node->issues_sql_like(
+       [ 'vacuumdb', '--disable-page-skipping', 'postgres' ],
+       qr/statement: VACUUM \(DISABLE_PAGE_SKIPPING\);/,
+       'vacuumdb --disable-page-skipping');
+$node->issues_sql_like(
+       [ 'vacuumdb', '--skip-locked', 'postgres' ],
+       qr/statement: VACUUM \(SKIP_LOCKED\);/,
+       'vacuumdb --skip-locked');
+$node->issues_sql_like(
+       [ 'vacuumdb', '--skip-locked', '--analyze-only', 'postgres' ],
+       qr/statement: ANALYZE \(SKIP_LOCKED\);/,
+       'vacuumdb --skip-locked --analyze-only');
+$node->command_fails(
+       [ 'vacuumdb', '--analyze-only', '--disable-page-skipping', 'postgres' ],
+       '--analyze-only and --disable-page-skipping specified together');
 $node->command_ok([qw(vacuumdb -Z --table=pg_am dbname=template1)],
        'vacuumdb with connection string');
 
index e0a8303f3e94d92b8e764abda2f85ca81d9c5c44..127b75e0b43737d840eda2f534267b27bd141258 100644 (file)
@@ -40,6 +40,8 @@ typedef struct vacuumingOptions
        bool            and_analyze;
        bool            full;
        bool            freeze;
+       bool            disable_page_skipping;
+       bool            skip_locked;
 } vacuumingOptions;
 
 
@@ -110,6 +112,8 @@ main(int argc, char *argv[])
                {"jobs", required_argument, NULL, 'j'},
                {"maintenance-db", required_argument, NULL, 2},
                {"analyze-in-stages", no_argument, NULL, 3},
+               {"disable-page-skipping", no_argument, NULL, 4},
+               {"skip-locked", no_argument, NULL, 5},
                {NULL, 0, NULL, 0}
        };
 
@@ -213,6 +217,12 @@ main(int argc, char *argv[])
                        case 3:
                                analyze_in_stages = vacopts.analyze_only = true;
                                break;
+                       case 4:
+                               vacopts.disable_page_skipping = true;
+                               break;
+                       case 5:
+                               vacopts.skip_locked = true;
+                               break;
                        default:
                                fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
                                exit(1);
@@ -251,6 +261,12 @@ main(int argc, char *argv[])
                                        progname, "freeze");
                        exit(1);
                }
+               if (vacopts.disable_page_skipping)
+               {
+                       fprintf(stderr, _("%s: cannot use the \"%s\" option when performing only analyze\n"),
+                                       progname, "disable-page-skipping");
+                       exit(1);
+               }
                /* allow 'and_analyze' with 'analyze_only' */
        }
 
@@ -367,6 +383,22 @@ vacuum_one_database(const char *dbname, vacuumingOptions *vacopts,
        conn = connectDatabase(dbname, host, port, username, prompt_password,
                                                   progname, echo, false, true);
 
+       if (vacopts->disable_page_skipping && PQserverVersion(conn) < 90600)
+       {
+               PQfinish(conn);
+               fprintf(stderr, _("%s: cannot use the \"%s\" option on server versions older than PostgreSQL 9.6\n"),
+                               progname, "disable-page-skipping");
+               exit(1);
+       }
+
+       if (vacopts->skip_locked && PQserverVersion(conn) < 120000)
+       {
+               PQfinish(conn);
+               fprintf(stderr, _("%s: cannot use the \"%s\" option on server versions older than PostgreSQL 12\n"),
+                               progname, "skip-locked");
+               exit(1);
+       }
+
        if (!quiet)
        {
                if (stage != ANALYZE_NO_STAGE)
@@ -630,23 +662,61 @@ prepare_vacuum_command(PQExpBuffer sql, PGconn *conn,
                                           bool table_pre_qualified,
                                           const char *progname, bool echo)
 {
+       const char *paren = " (";
+       const char *comma = ", ";
+       const char *sep = paren;
+
        resetPQExpBuffer(sql);
 
        if (vacopts->analyze_only)
        {
                appendPQExpBufferStr(sql, "ANALYZE");
-               if (vacopts->verbose)
-                       appendPQExpBufferStr(sql, " VERBOSE");
+
+               /* parenthesized grammar of ANALYZE is supported since v11 */
+               if (PQserverVersion(conn) >= 110000)
+               {
+                       if (vacopts->skip_locked)
+                       {
+                               /* SKIP_LOCKED is supported since v12 */
+                               Assert(PQserverVersion(conn) >= 120000);
+                               appendPQExpBuffer(sql, "%sSKIP_LOCKED", sep);
+                               sep = comma;
+                       }
+                       if (vacopts->verbose)
+                       {
+                               appendPQExpBuffer(sql, "%sVERBOSE", sep);
+                               sep = comma;
+                       }
+                       if (sep != paren)
+                               appendPQExpBufferChar(sql, ')');
+               }
+               else
+               {
+                       if (vacopts->verbose)
+                               appendPQExpBufferStr(sql, " VERBOSE");
+               }
        }
        else
        {
                appendPQExpBufferStr(sql, "VACUUM");
+
+               /* parenthesized grammar of VACUUM is supported since v9.0 */
                if (PQserverVersion(conn) >= 90000)
                {
-                       const char *paren = " (";
-                       const char *comma = ", ";
-                       const char *sep = paren;
-
+                       if (vacopts->disable_page_skipping)
+                       {
+                               /* DISABLE_PAGE_SKIPPING is supported since v9.6 */
+                               Assert(PQserverVersion(conn) >= 90600);
+                               appendPQExpBuffer(sql, "%sDISABLE_PAGE_SKIPPING", sep);
+                               sep = comma;
+                       }
+                       if (vacopts->skip_locked)
+                       {
+                               /* SKIP_LOCKED is supported since v12 */
+                               Assert(PQserverVersion(conn) >= 120000);
+                               appendPQExpBuffer(sql, "%sSKIP_LOCKED", sep);
+                               sep = comma;
+                       }
                        if (vacopts->full)
                        {
                                appendPQExpBuffer(sql, "%sFULL", sep);
@@ -1000,11 +1070,13 @@ help(const char *progname)
        printf(_("\nOptions:\n"));
        printf(_("  -a, --all                       vacuum all databases\n"));
        printf(_("  -d, --dbname=DBNAME             database to vacuum\n"));
+       printf(_("      --disable-page-skipping     disable all page-skipping behavior\n"));
        printf(_("  -e, --echo                      show the commands being sent to the server\n"));
        printf(_("  -f, --full                      do full vacuuming\n"));
        printf(_("  -F, --freeze                    freeze row transaction information\n"));
        printf(_("  -j, --jobs=NUM                  use this many concurrent connections to vacuum\n"));
        printf(_("  -q, --quiet                     don't write any messages\n"));
+       printf(_("      --skip-locked               skip relations that cannot be immediately locked\n"));
        printf(_("  -t, --table='TABLE[(COLUMNS)]'  vacuum specific table(s) only\n"));
        printf(_("  -v, --verbose                   write a lot of output\n"));
        printf(_("  -V, --version                   output version information, then exit\n"));