From 5dbfd59c5d4a89c4559f9ee0e49b69ab29ecc714 Mon Sep 17 00:00:00 2001 From: Masahiko Sawada Date: Tue, 18 Dec 2018 16:08:24 +0900 Subject: [PATCH v12 2/2] Add -P option to vacuumdb command. --- doc/src/sgml/ref/vacuumdb.sgml | 16 ++++++++++++ src/backend/access/heap/vacuumlazy.c | 9 +++---- src/bin/scripts/t/100_vacuumdb.pl | 8 ++++++ src/bin/scripts/vacuumdb.c | 49 +++++++++++++++++++++++++++++++++++- 4 files changed, 75 insertions(+), 7 deletions(-) diff --git a/doc/src/sgml/ref/vacuumdb.sgml b/doc/src/sgml/ref/vacuumdb.sgml index da4d51e..aa5f120 100644 --- a/doc/src/sgml/ref/vacuumdb.sgml +++ b/doc/src/sgml/ref/vacuumdb.sgml @@ -175,6 +175,22 @@ PostgreSQL documentation + + + + + Execute parallel vacuum with PostgreSQL's + workers background workers. + + + vacuumdb will require background workers, + so make sure your + setting is more than one. + + + + + diff --git a/src/backend/access/heap/vacuumlazy.c b/src/backend/access/heap/vacuumlazy.c index d12df24..d2caf5f 100644 --- a/src/backend/access/heap/vacuumlazy.c +++ b/src/backend/access/heap/vacuumlazy.c @@ -2642,12 +2642,9 @@ lazy_prepare_parallel(LVState *lvstate, long maxtuples, int request) * Finally, estimate VACUUM_KEY_QUERY_TEXT space. Auto vacuums don't have * debug_query_string. */ - if (debug_query_string) - { - querylen = strlen(debug_query_string); - shm_toc_estimate_chunk(&pcxt->estimator, querylen + 1); - shm_toc_estimate_keys(&pcxt->estimator, 1); - } + querylen = strlen(debug_query_string); + shm_toc_estimate_chunk(&pcxt->estimator, querylen + 1); + shm_toc_estimate_keys(&pcxt->estimator, 1); /* create the DSM */ InitializeParallelDSM(pcxt); diff --git a/src/bin/scripts/t/100_vacuumdb.pl b/src/bin/scripts/t/100_vacuumdb.pl index 3d0ba58..16a68af 100644 --- a/src/bin/scripts/t/100_vacuumdb.pl +++ b/src/bin/scripts/t/100_vacuumdb.pl @@ -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', '-P2', 'postgres' ], + qr/statement: VACUUM \(PARALLEL 2\);/, + 'vacuumdb -P2'); +$node->issues_sql_like( + [ 'vacuumdb', '-P', 'postgres' ], + qr/statement: VACUUM \(PARALLEL\);/, + 'vacuumdb -P2'); $node->command_ok([qw(vacuumdb -Z --table=pg_am dbname=template1)], 'vacuumdb with connection string'); diff --git a/src/bin/scripts/vacuumdb.c b/src/bin/scripts/vacuumdb.c index 127b75e..e2bdddd 100644 --- a/src/bin/scripts/vacuumdb.c +++ b/src/bin/scripts/vacuumdb.c @@ -42,6 +42,8 @@ typedef struct vacuumingOptions bool freeze; bool disable_page_skipping; bool skip_locked; + int parallel_workers; /* -1: disabled, 0: PARALLEL without number of + * workers. */ } vacuumingOptions; @@ -110,6 +112,7 @@ main(int argc, char *argv[]) {"full", no_argument, NULL, 'f'}, {"verbose", no_argument, NULL, 'v'}, {"jobs", required_argument, NULL, 'j'}, + {"parallel", optional_argument, NULL, 'P'}, {"maintenance-db", required_argument, NULL, 2}, {"analyze-in-stages", no_argument, NULL, 3}, {"disable-page-skipping", no_argument, NULL, 4}, @@ -137,6 +140,7 @@ main(int argc, char *argv[]) /* initialize options to all false */ memset(&vacopts, 0, sizeof(vacopts)); + vacopts.parallel_workers = -1; progname = get_progname(argv[0]); @@ -144,7 +148,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:P::U:wWeqd:zZFat:fvj:", long_options, &optindex)) != -1) { switch (c) { @@ -211,6 +215,25 @@ main(int argc, char *argv[]) exit(1); } break; + case 'P': + { + int parallel_workers = 0; + + if (optarg != NULL) + { + parallel_workers = atoi(optarg); + if (parallel_workers <= 0) + { + fprintf(stderr, _("%s: number of parallel workers must be at least 1\n"), + progname); + exit(1); + } + } + + /* allow to set 0, meaning PARALLEL without the parallel degree */ + vacopts.parallel_workers = parallel_workers; + break; + } case 2: maintenance_db = pg_strdup(optarg); break; @@ -267,9 +290,22 @@ main(int argc, char *argv[]) progname, "disable-page-skipping"); exit(1); } + if (vacopts.parallel_workers >= 0) + { + fprintf(stderr, _("%s: cannot use the \"%s\" option when performing only analyze\n"), + progname, "parallel"); + exit(1); + } /* allow 'and_analyze' with 'analyze_only' */ } + if (vacopts.full && vacopts.parallel_workers >= 0) + { + fprintf(stderr, _("%s: cannot use the \"%s\" option with \"%s\" option"), + progname, "full", "parallel"); + exit(1); + } + setup_cancel_handler(); /* Avoid opening extra connections. */ @@ -737,6 +773,16 @@ prepare_vacuum_command(PQExpBuffer sql, PGconn *conn, appendPQExpBuffer(sql, "%sANALYZE", sep); sep = comma; } + if (vacopts->parallel_workers > 0) + { + appendPQExpBuffer(sql, "%sPARALLEL %d", sep, vacopts->parallel_workers); + sep = comma; + } + if (vacopts->parallel_workers == 0) + { + appendPQExpBuffer(sql, "%sPARALLEL", sep); + sep = comma; + } if (sep != paren) appendPQExpBufferChar(sql, ')'); } @@ -1075,6 +1121,7 @@ help(const char *progname) 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(_(" -P, --parallel=NUM do parallel vacuuming\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")); -- 1.8.3.1