mirror of
https://github.com/postgres/postgres.git
synced 2025-12-10 14:22:35 +03:00
vacuumdb: Add --dry-run.
This new option instructs vacuumdb to print, but not execute, the VACUUM and ANALYZE commands that would've been sent to the server. Author: Corey Huinker <corey.huinker@gmail.com> Reviewed-by: Chao Li <li.evan.chao@gmail.com> Reviewed-by: Kirill Reshke <reshkekirill@gmail.com> Reviewed-by: Álvaro Herrera <alvherre@kurilemu.de> Discussion: https://postgr.es/m/CADkLM%3DckHkX7Of5SrK7g0LokPUwJ%3Dkk8JU1GXGF5pZ1eBVr0%3DQ%40mail.gmail.com
This commit is contained in:
@@ -171,6 +171,16 @@ PostgreSQL documentation
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>--dry-run</option></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Print, but do not execute, the vacuum and analyze commands that would
|
||||
have been sent to the server.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>-e</option></term>
|
||||
<term><option>--echo</option></term>
|
||||
|
||||
@@ -169,6 +169,10 @@ $node->issues_sql_like(
|
||||
[ 'vacuumdb', '--schema' => '"Foo"', 'postgres' ],
|
||||
qr/VACUUM \(SKIP_DATABASE_STATS\) "Foo".bar/,
|
||||
'vacuumdb --schema');
|
||||
$node->issues_sql_unlike(
|
||||
[ 'vacuumdb', '--schema' => '"Foo"', 'postgres', '--dry-run' ],
|
||||
qr/VACUUM \(SKIP_DATABASE_STATS\) "Foo".bar/,
|
||||
'vacuumdb --dry-run');
|
||||
$node->issues_sql_like(
|
||||
[ 'vacuumdb', '--schema' => '"Foo"', '--schema' => '"Bar"', 'postgres' ],
|
||||
qr/VACUUM\ \(SKIP_DATABASE_STATS\)\ "Foo".bar
|
||||
@@ -241,6 +245,14 @@ $node->safe_psql('postgres', q|
|
||||
CREATE TABLE regression_vacuumdb_test AS select generate_series(1, 10) a, generate_series(2, 11) b;
|
||||
ALTER TABLE regression_vacuumdb_test ADD COLUMN c INT GENERATED ALWAYS AS (a + b);
|
||||
|);
|
||||
$node->issues_sql_unlike(
|
||||
[
|
||||
'vacuumdb', '--analyze-only', '--dry-run',
|
||||
'--missing-stats-only', '-t',
|
||||
'regression_vacuumdb_test', 'postgres'
|
||||
],
|
||||
qr/statement:\ ANALYZE/sx,
|
||||
'--missing-stats-only --dry-run');
|
||||
$node->issues_sql_like(
|
||||
[
|
||||
'vacuumdb', '--analyze-only',
|
||||
|
||||
@@ -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}
|
||||
};
|
||||
|
||||
@@ -207,6 +208,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);
|
||||
@@ -303,6 +307,10 @@ main(int argc, char *argv[])
|
||||
pg_fatal("cannot use the \"%s\" option without \"%s\" or \"%s\"",
|
||||
"missing-stats-only", "analyze-only", "analyze-in-stages");
|
||||
|
||||
if (vacopts.dry_run && !vacopts.quiet)
|
||||
pg_log_info("Executing in dry-run mode.\n"
|
||||
"No commands will be sent to the server.");
|
||||
|
||||
ret = vacuuming_main(&cparams, dbname, maintenance_db, &vacopts,
|
||||
&objects, tbl_count,
|
||||
concurrentCons,
|
||||
@@ -345,6 +353,7 @@ help(const char *progname)
|
||||
printf(_(" --buffer-usage-limit=SIZE size of ring buffer used for vacuum\n"));
|
||||
printf(_(" -d, --dbname=DBNAME database to vacuum\n"));
|
||||
printf(_(" --disable-page-skipping disable all page-skipping behavior\n"));
|
||||
printf(_(" --dry-run show the commands that would be sent to the server\n"));
|
||||
printf(_(" -e, --echo show the commands being sent to the server\n"));
|
||||
printf(_(" -f, --full do full vacuuming\n"));
|
||||
printf(_(" -F, --freeze freeze row transaction information\n"));
|
||||
|
||||
@@ -42,8 +42,9 @@ static SimpleStringList *retrieve_objects(PGconn *conn,
|
||||
static void free_retrieved_objects(SimpleStringList *list);
|
||||
static void prepare_vacuum_command(PGconn *conn, PQExpBuffer sql,
|
||||
vacuumingOptions *vacopts, const char *table);
|
||||
static void run_vacuum_command(PGconn *conn, vacuumingOptions *vacopts,
|
||||
const char *sql, const char *table);
|
||||
static void run_vacuum_command(ParallelSlot *free_slot,
|
||||
vacuumingOptions *vacopts, const char *sql,
|
||||
const char *table);
|
||||
|
||||
/*
|
||||
* Executes vacuum/analyze as indicated. Returns 0 if the plan is carried
|
||||
@@ -340,6 +341,10 @@ vacuum_one_database(ConnParams *cparams,
|
||||
if (vacopts->mode == MODE_ANALYZE_IN_STAGES)
|
||||
{
|
||||
initcmd = stage_commands[stage];
|
||||
|
||||
if (vacopts->dry_run)
|
||||
printf("%s\n", initcmd);
|
||||
else
|
||||
executeCommand(conn, initcmd, vacopts->echo);
|
||||
}
|
||||
else
|
||||
@@ -383,7 +388,7 @@ vacuum_one_database(ConnParams *cparams,
|
||||
* through ParallelSlotsGetIdle.
|
||||
*/
|
||||
ParallelSlotSetHandler(free_slot, TableCommandResultHandler, NULL);
|
||||
run_vacuum_command(free_slot->connection, vacopts, sql.data, tabname);
|
||||
run_vacuum_command(free_slot, vacopts, sql.data, tabname);
|
||||
|
||||
cell = cell->next;
|
||||
} while (cell != NULL);
|
||||
@@ -407,7 +412,7 @@ vacuum_one_database(ConnParams *cparams,
|
||||
}
|
||||
|
||||
ParallelSlotSetHandler(free_slot, TableCommandResultHandler, NULL);
|
||||
run_vacuum_command(free_slot->connection, vacopts, cmd, NULL);
|
||||
run_vacuum_command(free_slot, vacopts, cmd, NULL);
|
||||
|
||||
if (!ParallelSlotsWaitCompletion(sa))
|
||||
ret = EXIT_FAILURE; /* error already reported by handler */
|
||||
@@ -995,19 +1000,24 @@ prepare_vacuum_command(PGconn *conn, PQExpBuffer sql,
|
||||
|
||||
/*
|
||||
* Send a vacuum/analyze command to the server, returning after sending the
|
||||
* command.
|
||||
* command. If dry_run is true, the command is printed but not sent to the
|
||||
* server.
|
||||
*
|
||||
* Any errors during command execution are reported to stderr.
|
||||
*/
|
||||
static void
|
||||
run_vacuum_command(PGconn *conn, vacuumingOptions *vacopts,
|
||||
run_vacuum_command(ParallelSlot *free_slot, vacuumingOptions *vacopts,
|
||||
const char *sql, const char *table)
|
||||
{
|
||||
bool status;
|
||||
bool status = true;
|
||||
PGconn *conn = free_slot->connection;
|
||||
|
||||
if (vacopts->echo)
|
||||
if (vacopts->echo || vacopts->dry_run)
|
||||
printf("%s\n", sql);
|
||||
|
||||
if (vacopts->dry_run)
|
||||
ParallelSlotSetIdle(free_slot);
|
||||
else
|
||||
status = PQsendQuery(conn, sql) == 1;
|
||||
|
||||
if (!status)
|
||||
|
||||
@@ -53,6 +53,7 @@ typedef struct vacuumingOptions
|
||||
bool missing_stats_only;
|
||||
bool echo;
|
||||
bool quiet;
|
||||
bool dry_run;
|
||||
} vacuumingOptions;
|
||||
|
||||
/* Valid values for vacuumingOptions->objfilter */
|
||||
|
||||
Reference in New Issue
Block a user