This is a small patch to add a new option to vacuumdb to answer the question "what commands will actually be run by this combination of command-line switches against this database?" without actually running the commands.
Including Nathan because we had previously discussed the utility of just such a thing.
From e64b1795a6a41827b8152e62c05bbbba1dac7dc4 Mon Sep 17 00:00:00 2001 From: Corey Huinker <[email protected]> Date: Mon, 10 Nov 2025 14:33:41 -0500 Subject: [PATCH v1] Add --dry-run to vacuumdb. This option answers the question "what tables would be affected if I ran a command using these options" without actually initiating those actions. --- src/bin/scripts/vacuumdb.c | 6 ++++++ src/bin/scripts/vacuuming.c | 7 +++++-- src/bin/scripts/vacuuming.h | 1 + doc/src/sgml/ref/vacuumdb.sgml | 11 +++++++++++ 4 files changed, 23 insertions(+), 2 deletions(-) diff --git a/src/bin/scripts/vacuumdb.c b/src/bin/scripts/vacuumdb.c index e117dac2242..aa0dc366eb0 100644 --- a/src/bin/scripts/vacuumdb.c +++ b/src/bin/scripts/vacuumdb.c @@ -59,6 +59,7 @@ main(int argc, char *argv[]) {"no-process-main", no_argument, NULL, 12}, {"buffer-usage-limit", required_argument, NULL, 13}, {"missing-stats-only", no_argument, NULL, 14}, + {"dry-run", no_argument, NULL, 15}, {NULL, 0, NULL, 0} }; @@ -86,6 +87,7 @@ main(int argc, char *argv[]) vacopts.do_truncate = true; vacopts.process_main = true; vacopts.process_toast = true; + vacopts.dry_run = false; /* the same for connection parameters */ memset(&cparams, 0, sizeof(cparams)); @@ -213,6 +215,9 @@ main(int argc, char *argv[]) case 14: vacopts.missing_stats_only = true; break; + case 15: + vacopts.dry_run = true; + break; default: /* getopt_long already emitted a complaint */ pg_log_error_hint("Try \"%s --help\" for more information.", progname); @@ -375,6 +380,7 @@ help(const char *progname) printf(_(" -Z, --analyze-only only update optimizer statistics; no vacuum\n")); printf(_(" --analyze-in-stages only update optimizer statistics, in multiple\n" " stages for faster results; no vacuum\n")); + printf(_(" --dry-run do not vacuum/analyze the selected tables, only print\n")); printf(_(" -?, --help show this help, then exit\n")); printf(_("\nConnection options:\n")); printf(_(" -h, --host=HOSTNAME database server host or socket directory\n")); diff --git a/src/bin/scripts/vacuuming.c b/src/bin/scripts/vacuuming.c index f836f21fb03..6255d2bac47 100644 --- a/src/bin/scripts/vacuuming.c +++ b/src/bin/scripts/vacuuming.c @@ -383,8 +383,11 @@ vacuum_one_database(ConnParams *cparams, * through ParallelSlotsGetIdle. */ ParallelSlotSetHandler(free_slot, TableCommandResultHandler, NULL); - run_vacuum_command(free_slot->connection, sql.data, - echo, tabname); + if (vacopts->dry_run) + printf("%s (not executed)\n", sql.data); + else + run_vacuum_command(free_slot->connection, sql.data, + echo, tabname); cell = cell->next; } while (cell != NULL); diff --git a/src/bin/scripts/vacuuming.h b/src/bin/scripts/vacuuming.h index 49f968b32e5..50155239e7e 100644 --- a/src/bin/scripts/vacuuming.h +++ b/src/bin/scripts/vacuuming.h @@ -51,6 +51,7 @@ typedef struct vacuumingOptions bool skip_database_stats; char *buffer_usage_limit; bool missing_stats_only; + bool dry_run; } vacuumingOptions; /* Valid values for vacuumingOptions->objfilter */ diff --git a/doc/src/sgml/ref/vacuumdb.sgml b/doc/src/sgml/ref/vacuumdb.sgml index 84c76d7350c..100691b579a 100644 --- a/doc/src/sgml/ref/vacuumdb.sgml +++ b/doc/src/sgml/ref/vacuumdb.sgml @@ -171,6 +171,17 @@ PostgreSQL documentation </listitem> </varlistentry> + <varlistentry> + <term><option>--dry-run</option></term> + <listitem> + <para> + Print but do not execute the vacuum or analyze commands generated. + This is useful for testing the effects of various command-line options + before actually running the commands. + </para> + </listitem> + </varlistentry> + <varlistentry> <term><option>-e</option></term> <term><option>--echo</option></term> base-commit: e510378358540703a13b77090a0021853bae0745 -- 2.51.1
