From 59e3146f585e288d41738daa9a1d18687e2851d1 Mon Sep 17 00:00:00 2001 From: Masahiko Sawada Date: Wed, 15 May 2019 15:27:51 +0900 Subject: [PATCH v3 2/2] Add --truncate option to vacuumdb. --- doc/src/sgml/ref/vacuumdb.sgml | 18 ++++++++++++++++++ src/bin/scripts/t/100_vacuumdb.pl | 13 ++++++++++++- src/bin/scripts/vacuumdb.c | 28 ++++++++++++++++++++++++++++ 3 files changed, 58 insertions(+), 1 deletion(-) diff --git a/doc/src/sgml/ref/vacuumdb.sgml b/doc/src/sgml/ref/vacuumdb.sgml index 5ec043e..6bb63c7 100644 --- a/doc/src/sgml/ref/vacuumdb.sgml +++ b/doc/src/sgml/ref/vacuumdb.sgml @@ -290,6 +290,24 @@ PostgreSQL documentation + + + + Specify that VACUUM should attempt to truncate off + any empty pages at the end of the table. If this option is not specified + the behavior depends on vacuum_truncate option + for the table to be vacuumed. + + + + 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 984f2a8..555e9b6 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 => 50; +use Test::More tests => 55; program_help_ok('vacuumdb'); program_version_ok('vacuumdb'); @@ -53,6 +53,14 @@ $node->issues_sql_like( [ 'vacuumdb', '--index-cleanup=true', 'postgres' ], qr/statement: VACUUM \(INDEX_CLEANUP true\).*;/, 'vacuumdb --index-cleanup=true'); +$node->issues_sql_like( + [ 'vacuumdb', '--truncate=false', 'postgres' ], + qr/statement: VACUUM \(TRUNCATE false\).*;/, + 'vacuumdb --truncate=false'); +$node->issues_sql_like( + [ 'vacuumdb', '--truncate=true', 'postgres' ], + qr/statement: VACUUM \(TRUNCATE true\).*;/, + 'vacuumdb --truncate=true'); $node->command_fails( [ 'vacuumdb', '--analyze-only', '--disable-page-skipping', 'postgres' ], '--analyze-only and --disable-page-skipping specified together'); @@ -60,6 +68,9 @@ $node->command_fails( [ 'vacuumdb', '--analyze-only', '--index-cleanup=true', 'postgres' ], '--analyze-only and --index-cleanup specified together'); $node->command_fails( + [ 'vacuumdb', '--analyze-only', '--truncate=true', 'postgres' ], + '--analyze-only and --truncate specified together'); +$node->command_fails( [ 'vacuumdb', '--index-cleanup=invalid', 'postgres' ], '--index-cleanup with an invalid argument'); $node->command_ok([qw(vacuumdb -Z --table=pg_am dbname=template1)], diff --git a/src/bin/scripts/vacuumdb.c b/src/bin/scripts/vacuumdb.c index 7f91d18..a7aaa82 100644 --- a/src/bin/scripts/vacuumdb.c +++ b/src/bin/scripts/vacuumdb.c @@ -47,6 +47,7 @@ typedef struct vacuumingOptions int min_xid_age; int min_mxid_age; char *index_cleanup; + char *truncate; } vacuumingOptions; @@ -121,6 +122,7 @@ main(int argc, char *argv[]) {"min-xid-age", required_argument, NULL, 6}, {"min-mxid-age", required_argument, NULL, 7}, {"index-cleanup", required_argument, NULL, 8}, + {"truncate", required_argument, NULL, 9}, {NULL, 0, NULL, 0} }; @@ -248,6 +250,9 @@ main(int argc, char *argv[]) case 8: vacopts.index_cleanup = pg_strdup(optarg); break; + case 9: + vacopts.truncate = pg_strdup(optarg); + break; default: fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); exit(1); @@ -298,6 +303,12 @@ main(int argc, char *argv[]) "index-cleanup"); exit(1); } + if (vacopts.truncate != NULL) + { + pg_log_error("cannot use the \"%s\" option when performing only analyze", + "truncate"); + exit(1); + } /* allow 'and_analyze' with 'analyze_only' */ } @@ -434,6 +445,14 @@ vacuum_one_database(const char *dbname, vacuumingOptions *vacopts, exit(1); } + if (vacopts->truncate != NULL && PQserverVersion(conn) < 120000) + { + PQfinish(conn); + pg_log_error("cannot use the \"%s\" option on server versions older than PostgreSQL 12", + "truncate"); + exit(1); + } + if (vacopts->skip_locked && PQserverVersion(conn) < 120000) { PQfinish(conn); @@ -902,6 +921,14 @@ prepare_vacuum_command(PQExpBuffer sql, int serverVersion, vacopts->index_cleanup); sep = comma; } + if (vacopts->truncate) + { + /* TRUNCATE is supported since 12 */ + Assert(serverVersion >= 120000); + appendPQExpBuffer(sql, "%sTRUNCATE %s", sep, + vacopts->truncate); + sep = comma; + } if (vacopts->full) { appendPQExpBuffer(sql, "%sFULL", sep); @@ -1257,6 +1284,7 @@ help(const char *progname) 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(_(" --truncate=BOOLEAN do or do not truncate off empty pages at the end of the table\n")); printf(_(" -v, --verbose write a lot of output\n")); printf(_(" -V, --version output version information, then exit\n")); printf(_(" -z, --analyze update optimizer statistics\n")); -- 2.10.5