From 8c5a914d14dacfce36ced1877ac392abd28d545b Mon Sep 17 00:00:00 2001 From: Nathan Bossart Date: Thu, 11 Jun 2020 00:05:31 +0000 Subject: [PATCH v1 1/1] Add --skip-index-cleanup and --skip-truncate to vacuumdb. Both INDEX_CLEANUP and TRUNCATE have been available since v12. This change adds support for disabling these options from vacuumdb. --- doc/src/sgml/ref/vacuumdb.sgml | 26 ++++++++++++++++ src/bin/scripts/t/100_vacuumdb.pl | 16 +++++++++- src/bin/scripts/vacuumdb.c | 63 +++++++++++++++++++++++++++++++++++---- 3 files changed, 99 insertions(+), 6 deletions(-) diff --git a/doc/src/sgml/ref/vacuumdb.sgml b/doc/src/sgml/ref/vacuumdb.sgml index fd1dc140ab..980cd3e9db 100644 --- a/doc/src/sgml/ref/vacuumdb.sgml +++ b/doc/src/sgml/ref/vacuumdb.sgml @@ -254,6 +254,19 @@ PostgreSQL documentation + + + + + Skip removing index entries pointing to dead tuples. + + + This option is only available for servers running + PostgreSQL 12 and later. + + + + @@ -269,6 +282,19 @@ PostgreSQL documentation + + + + + Skip truncating empty pages at the end of the table. + + + This option is only available for servers running + PostgreSQL 12 and later. + + + + diff --git a/src/bin/scripts/t/100_vacuumdb.pl b/src/bin/scripts/t/100_vacuumdb.pl index b136bd4457..bc15803c2f 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 => 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', '--skip-index-cleanup', 'postgres' ], + qr/statement: VACUUM \(INDEX_CLEANUP FALSE\).*;/, + 'vacuumdb --skip-index-cleanup'); +$node->command_fails( + [ 'vacuumdb', '--analyze-only', '--skip-index-cleanup', 'postgres' ], + '--analyze-only and --skip-index-cleanup specified together'); +$node->issues_sql_like( + [ 'vacuumdb', '--skip-truncate', 'postgres' ], + qr/statement: VACUUM \(TRUNCATE FALSE\).*;/, + 'vacuumdb --skip-truncate'); +$node->command_fails( + [ 'vacuumdb', '--analyze-only', '--skip-truncate', 'postgres' ], + '--analyze-only and --skip-truncate specified together'); $node->issues_sql_like( [ 'vacuumdb', '-P', 2, 'postgres' ], qr/statement: VACUUM \(PARALLEL 2\).*;/, diff --git a/src/bin/scripts/vacuumdb.c b/src/bin/scripts/vacuumdb.c index 154084a086..9f9ebc9f36 100644 --- a/src/bin/scripts/vacuumdb.c +++ b/src/bin/scripts/vacuumdb.c @@ -32,7 +32,9 @@ typedef struct vacuumingOptions bool full; bool freeze; bool disable_page_skipping; + bool skip_index_cleanup; bool skip_locked; + bool skip_truncate; int min_xid_age; int min_mxid_age; int parallel_workers; /* >= 0 indicates user specified the @@ -93,9 +95,11 @@ main(int argc, char *argv[]) {"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}, - {"min-xid-age", required_argument, NULL, 6}, - {"min-mxid-age", required_argument, NULL, 7}, + {"skip-index-cleanup", no_argument, NULL, 5}, + {"skip-locked", no_argument, NULL, 6}, + {"skip-truncate", no_argument, NULL, 7}, + {"min-xid-age", required_argument, NULL, 8}, + {"min-mxid-age", required_argument, NULL, 9}, {NULL, 0, NULL, 0} }; @@ -205,9 +209,15 @@ main(int argc, char *argv[]) vacopts.disable_page_skipping = true; break; case 5: - vacopts.skip_locked = true; + vacopts.skip_index_cleanup = true; break; case 6: + vacopts.skip_locked = true; + break; + case 7: + vacopts.skip_truncate = true; + break; + case 8: vacopts.min_xid_age = atoi(optarg); if (vacopts.min_xid_age <= 0) { @@ -215,7 +225,7 @@ main(int argc, char *argv[]) exit(1); } break; - case 7: + case 9: vacopts.min_mxid_age = atoi(optarg); if (vacopts.min_mxid_age <= 0) { @@ -267,6 +277,18 @@ main(int argc, char *argv[]) "disable-page-skipping"); exit(1); } + if (vacopts.skip_index_cleanup) + { + pg_log_error("cannot use the \"%s\" option when performing only analyze", + "skip-index-cleanup"); + exit(1); + } + if (vacopts.skip_truncate) + { + pg_log_error("cannot use the \"%s\" option when performing only analyze", + "skip-truncate"); + exit(1); + } /* allow 'and_analyze' with 'analyze_only' */ } @@ -412,6 +434,13 @@ vacuum_one_database(const char *dbname, vacuumingOptions *vacopts, exit(1); } + if (vacopts->skip_index_cleanup && PQserverVersion(conn) < 120000) + { + PQfinish(conn); + pg_log_error("cannot use the \"%s\" option on server versions older than PostgreSQL %s", + "skip-index-cleanup", "12"); + } + if (vacopts->skip_locked && PQserverVersion(conn) < 120000) { PQfinish(conn); @@ -420,6 +449,14 @@ vacuum_one_database(const char *dbname, vacuumingOptions *vacopts, exit(1); } + if (vacopts->skip_truncate && PQserverVersion(conn) < 120000) + { + PQfinish(conn); + pg_log_error("cannot use the \"%s\" option on server versions older than PostgreSQL %s", + "skip-truncate", "12"); + exit(1); + } + if (vacopts->min_xid_age != 0 && PQserverVersion(conn) < 90600) { pg_log_error("cannot use the \"%s\" option on server versions older than PostgreSQL %s", @@ -832,6 +869,13 @@ prepare_vacuum_command(PQExpBuffer sql, int serverVersion, appendPQExpBuffer(sql, "%sDISABLE_PAGE_SKIPPING", sep); sep = comma; } + if (vacopts->skip_index_cleanup) + { + /* INDEX_CLEANUP is supported since v12 */ + Assert(serverVersion >= 120000); + appendPQExpBuffer(sql, "%sINDEX_CLEANUP FALSE", sep); + sep = comma; + } if (vacopts->skip_locked) { /* SKIP_LOCKED is supported since v12 */ @@ -839,6 +883,13 @@ prepare_vacuum_command(PQExpBuffer sql, int serverVersion, appendPQExpBuffer(sql, "%sSKIP_LOCKED", sep); sep = comma; } + if (vacopts->skip_truncate) + { + /* TRUNCATE is supported since v12 */ + Assert(serverVersion >= 120000); + appendPQExpBuffer(sql, "%sTRUNCATE FALSE", sep); + sep = comma; + } if (vacopts->full) { appendPQExpBuffer(sql, "%sFULL", sep); @@ -932,7 +983,9 @@ help(const char *progname) 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-index-cleanup skip removing index entries that point to dead tuples\n")); printf(_(" --skip-locked skip relations that cannot be immediately locked\n")); + printf(_(" --skip-truncate skip truncating empty pages at the end of the table\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")); -- 2.16.6