summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAmit Kapila2020-01-29 05:38:50 +0000
committerAmit Kapila2020-01-29 05:38:50 +0000
commit47bc9ced0d0e96523e2c639c7066c9aede189ed7 (patch)
treea7753690cf761e3866c6378a66e0127c740bbe63
parent01d9676a53af075feb42d2f83ddb8c61186812fc (diff)
Add --parallel option to vacuumdb command.
Commit 40d964ec99 allowed vacuum command to leverage multiple CPUs by invoking parallel workers to process indexes. This commit provides a '--parallel' option to specify the parallel degree used by vacuum command. Author: Masahiko Sawada, with few modifications by me Reviewed-by: Mahendra Singh and Amit Kapila Discussion: https://postgr.es/m/CAD21AoDTPMgzSkV4E3SFo1CH_x50bf5PqZFQf4jmqjk-C03BWg@mail.gmail.com
-rw-r--r--doc/src/sgml/ref/vacuumdb.sgml18
-rw-r--r--src/bin/scripts/t/100_vacuumdb.pl13
-rw-r--r--src/bin/scripts/vacuumdb.c47
3 files changed, 76 insertions, 2 deletions
diff --git a/doc/src/sgml/ref/vacuumdb.sgml b/doc/src/sgml/ref/vacuumdb.sgml
index 47d93456f86..775c9ec651b 100644
--- a/doc/src/sgml/ref/vacuumdb.sgml
+++ b/doc/src/sgml/ref/vacuumdb.sgml
@@ -227,6 +227,24 @@ PostgreSQL documentation
</varlistentry>
<varlistentry>
+ <term><option>-P <replaceable class="parameter">parallel_degree</replaceable></option></term>
+ <term><option>--parallel=<replaceable class="parameter">parallel_degree</replaceable></option></term>
+ <listitem>
+ <para>
+ Specify the parallel degree of <firstterm>parallel vacuum</firstterm>.
+ This allows the vacuum to leverage multiple CPUs to process indexes.
+ See <xref linkend="sql-vacuum"/>.
+ </para>
+ <note>
+ <para>
+ This option is only available for servers running
+ <productname>PostgreSQL</productname> 13 and later.
+ </para>
+ </note>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term><option>-q</option></term>
<term><option>--quiet</option></term>
<listitem>
diff --git a/src/bin/scripts/t/100_vacuumdb.pl b/src/bin/scripts/t/100_vacuumdb.pl
index b685b352828..c2284c8195f 100644
--- a/src/bin/scripts/t/100_vacuumdb.pl
+++ b/src/bin/scripts/t/100_vacuumdb.pl
@@ -3,7 +3,7 @@ use warnings;
use PostgresNode;
use TestLib;
-use Test::More tests => 44;
+use Test::More tests => 49;
program_help_ok('vacuumdb');
program_version_ok('vacuumdb');
@@ -48,6 +48,14 @@ $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', '-P', 2, 'postgres' ],
+ qr/statement: VACUUM \(PARALLEL 2\).*;/,
+ 'vacuumdb -P 2');
+$node->issues_sql_like(
+ [ 'vacuumdb', '-P', 0, 'postgres' ],
+ qr/statement: VACUUM \(PARALLEL 0\).*;/,
+ 'vacuumdb -P 0');
$node->command_ok([qw(vacuumdb -Z --table=pg_am dbname=template1)],
'vacuumdb with connection string');
@@ -81,6 +89,9 @@ $node->command_fails(
$node->command_fails(
[ 'vacuumdb', '--analyze', '--table', 'vactable(c)', 'postgres' ],
'incorrect column name with ANALYZE');
+$node->command_fails(
+ [ 'vacuumdb', '-P', -1, 'postgres' ],
+ 'negative parallel degree');
$node->issues_sql_like(
[ 'vacuumdb', '--analyze', '--table', 'vactable(a, b)', 'postgres' ],
qr/statement: VACUUM \(ANALYZE\) public.vactable\(a, b\);/,
diff --git a/src/bin/scripts/vacuumdb.c b/src/bin/scripts/vacuumdb.c
index bfa6ac63553..0560f6304ff 100644
--- a/src/bin/scripts/vacuumdb.c
+++ b/src/bin/scripts/vacuumdb.c
@@ -35,6 +35,8 @@ typedef struct vacuumingOptions
bool skip_locked;
int min_xid_age;
int min_mxid_age;
+ int parallel_workers; /* >= 0 indicates user specified the
+ * parallel degree, otherwise -1 */
} vacuumingOptions;
@@ -87,6 +89,7 @@ main(int argc, char *argv[])
{"full", no_argument, NULL, 'f'},
{"verbose", no_argument, NULL, 'v'},
{"jobs", required_argument, NULL, 'j'},
+ {"parallel", required_argument, NULL, 'P'},
{"maintenance-db", required_argument, NULL, 2},
{"analyze-in-stages", no_argument, NULL, 3},
{"disable-page-skipping", no_argument, NULL, 4},
@@ -116,6 +119,7 @@ main(int argc, char *argv[])
/* initialize options to all false */
memset(&vacopts, 0, sizeof(vacopts));
+ vacopts.parallel_workers = -1;
pg_logging_init(argv[0]);
progname = get_progname(argv[0]);
@@ -123,7 +127,7 @@ main(int argc, char *argv[])
handle_help_version_opts(argc, argv, "vacuumdb", help);
- while ((c = getopt_long(argc, argv, "h:p:U:wWeqd:zZFat:fvj:", long_options, &optindex)) != -1)
+ while ((c = getopt_long(argc, argv, "h:p:U:wWeqd:zZFat:fvj:P:", long_options, &optindex)) != -1)
{
switch (c)
{
@@ -183,6 +187,14 @@ main(int argc, char *argv[])
exit(1);
}
break;
+ case 'P':
+ vacopts.parallel_workers = atoi(optarg);
+ if (vacopts.parallel_workers < 0)
+ {
+ pg_log_error("parallel vacuum degree must be a non-negative integer");
+ exit(1);
+ }
+ break;
case 2:
maintenance_db = pg_strdup(optarg);
break;
@@ -258,6 +270,23 @@ main(int argc, char *argv[])
/* allow 'and_analyze' with 'analyze_only' */
}
+ /* Prohibit full and analyze_only options with parallel option */
+ if (vacopts.parallel_workers >= 0)
+ {
+ if (vacopts.analyze_only)
+ {
+ pg_log_error("cannot use the \"%s\" option when performing only analyze",
+ "parallel");
+ exit(1);
+ }
+ if (vacopts.full)
+ {
+ pg_log_error("cannot use the \"%s\" option when performing full",
+ "parallel");
+ exit(1);
+ }
+ }
+
setup_cancel_handler(NULL);
/* Avoid opening extra connections. */
@@ -405,6 +434,13 @@ vacuum_one_database(const char *dbname, vacuumingOptions *vacopts,
exit(1);
}
+ if (vacopts->parallel_workers >= 0 && PQserverVersion(conn) < 130000)
+ {
+ pg_log_error("cannot use the \"%s\" option on server versions older than PostgreSQL %s",
+ "--parallel", "13");
+ exit(1);
+ }
+
if (!quiet)
{
if (stage != ANALYZE_NO_STAGE)
@@ -823,6 +859,14 @@ prepare_vacuum_command(PQExpBuffer sql, int serverVersion,
appendPQExpBuffer(sql, "%sANALYZE", sep);
sep = comma;
}
+ if (vacopts->parallel_workers >= 0)
+ {
+ /* PARALLEL is supported since v13 */
+ Assert(serverVersion >= 130000);
+ appendPQExpBuffer(sql, "%sPARALLEL %d", sep,
+ vacopts->parallel_workers);
+ sep = comma;
+ }
if (sep != paren)
appendPQExpBufferChar(sql, ')');
}
@@ -886,6 +930,7 @@ 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(_(" -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"));
printf(_(" -t, --table='TABLE[(COLUMNS)]' vacuum specific table(s) only\n"));