Skip to content

Commit c92c3d5

Browse files
committed
vacuumdb: Add option --analyze-in-stages
Add vacuumdb option --analyze-in-stages which runs ANALYZE three times with different configuration settings, adopting the logic from the analyze_new_cluster.sh script that pg_upgrade generates. That way, users of pg_dump/pg_restore can also use that functionality. Change pg_upgrade to create the script so that it calls vacuumdb instead of implementing the logic itself.
1 parent 0d3b2b8 commit c92c3d5

File tree

4 files changed

+94
-70
lines changed

4 files changed

+94
-70
lines changed

contrib/pg_upgrade/check.c

Lines changed: 4 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -565,62 +565,12 @@ create_script_for_cluster_analyze(char **analyze_script_file_name)
565565
"--analyze-only" : "--analyze", ECHO_QUOTE);
566566
fprintf(script, "echo%s\n\n", ECHO_BLANK);
567567

568-
#ifndef WIN32
569-
fprintf(script, "sleep 2\n");
570-
fprintf(script, "PGOPTIONS='-c default_statistics_target=1 -c vacuum_cost_delay=0'\n");
571-
/* only need to export once */
572-
fprintf(script, "export PGOPTIONS\n");
573-
#else
574-
fprintf(script, "REM simulate sleep 2\n");
575-
fprintf(script, "PING 1.1.1.1 -n 1 -w 2000 > nul\n");
576-
fprintf(script, "SET PGOPTIONS=-c default_statistics_target=1 -c vacuum_cost_delay=0\n");
577-
#endif
578-
579-
fprintf(script, "echo %sGenerating minimal optimizer statistics (1 target)%s\n",
580-
ECHO_QUOTE, ECHO_QUOTE);
581-
fprintf(script, "echo %s--------------------------------------------------%s\n",
582-
ECHO_QUOTE, ECHO_QUOTE);
583-
fprintf(script, "\"%s/vacuumdb\" %s--all --analyze-only\n",
584-
new_cluster.bindir, user_specification);
585-
fprintf(script, "echo%s\n", ECHO_BLANK);
586-
fprintf(script, "echo %sThe server is now available with minimal optimizer statistics.%s\n",
587-
ECHO_QUOTE, ECHO_QUOTE);
588-
fprintf(script, "echo %sQuery performance will be optimal once this script completes.%s\n",
589-
ECHO_QUOTE, ECHO_QUOTE);
590-
fprintf(script, "echo%s\n\n", ECHO_BLANK);
591-
592-
#ifndef WIN32
593-
fprintf(script, "sleep 2\n");
594-
fprintf(script, "PGOPTIONS='-c default_statistics_target=10'\n");
595-
#else
596-
fprintf(script, "REM simulate sleep\n");
597-
fprintf(script, "PING 1.1.1.1 -n 1 -w 2000 > nul\n");
598-
fprintf(script, "SET PGOPTIONS=-c default_statistics_target=10\n");
599-
#endif
600-
601-
fprintf(script, "echo %sGenerating medium optimizer statistics (10 targets)%s\n",
602-
ECHO_QUOTE, ECHO_QUOTE);
603-
fprintf(script, "echo %s---------------------------------------------------%s\n",
604-
ECHO_QUOTE, ECHO_QUOTE);
605-
fprintf(script, "\"%s/vacuumdb\" %s--all --analyze-only\n",
568+
fprintf(script, "\"%s/vacuumdb\" %s--all --analyze-in-stages\n",
606569
new_cluster.bindir, user_specification);
607-
fprintf(script, "echo%s\n\n", ECHO_BLANK);
608-
609-
#ifndef WIN32
610-
fprintf(script, "unset PGOPTIONS\n");
611-
#else
612-
fprintf(script, "SET PGOPTIONS\n");
613-
#endif
614-
615-
fprintf(script, "echo %sGenerating default (full) optimizer statistics (100 targets?)%s\n",
616-
ECHO_QUOTE, ECHO_QUOTE);
617-
fprintf(script, "echo %s-------------------------------------------------------------%s\n",
618-
ECHO_QUOTE, ECHO_QUOTE);
619-
fprintf(script, "\"%s/vacuumdb\" %s--all %s\n", new_cluster.bindir,
620-
user_specification,
621570
/* Did we copy the free space files? */
622-
(GET_MAJOR_VERSION(old_cluster.major_version) >= 804) ?
623-
"--analyze-only" : "--analyze");
571+
if (GET_MAJOR_VERSION(old_cluster.major_version) < 804)
572+
fprintf(script, "\"%s/vacuumdb\" %s--all\n", new_cluster.bindir,
573+
user_specification);
624574

625575
fprintf(script, "echo%s\n\n", ECHO_BLANK);
626576
fprintf(script, "echo %sDone%s\n",

doc/src/sgml/ref/vacuumdb.sgml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,26 @@ PostgreSQL documentation
203203
</listitem>
204204
</varlistentry>
205205

206+
<varlistentry>
207+
<term><option>--analyze-in-stages</option></term>
208+
<listitem>
209+
<para>
210+
Only calculate statistics for use by the optimizer (no vacuum),
211+
like <option>--analyze-only</option>. Run several (currently three)
212+
stages of analyze with different configuration settings, to produce
213+
usable statistics faster.
214+
</para>
215+
216+
<para>
217+
This option is useful to analyze a database that was newly populated
218+
from a restored dump or by <command>pg_upgrade</command>. This option
219+
will try to create some statistics as fast as possible, to make the
220+
database usable, and then produce full statistics in the subsequent
221+
stages.
222+
</para>
223+
</listitem>
224+
</varlistentry>
225+
206226
<varlistentry>
207227
<term><option>-?</></term>
208228
<term><option>--help</></term>
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
use strict;
2+
use warnings;
3+
use TestLib;
4+
use Test::More tests => 1;
5+
6+
my $tempdir = tempdir;
7+
start_test_server $tempdir;
8+
9+
issues_sql_like(['vacuumdb', '--analyze-in-stages', 'postgres'],
10+
qr/.*statement:\ SET\ default_statistics_target=1;\ SET\ vacuum_cost_delay=0;
11+
.*statement:\ ANALYZE.*
12+
.*statement:\ SET\ default_statistics_target=10;\ RESET\ vacuum_cost_delay;
13+
.*statement:\ ANALYZE.*
14+
.*statement:\ RESET\ default_statistics_target;
15+
.*statement:\ ANALYZE/sx,
16+
'analyze three times');

src/bin/scripts/vacuumdb.c

Lines changed: 54 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,12 @@
1616

1717

1818
static void vacuum_one_database(const char *dbname, bool full, bool verbose,
19-
bool and_analyze, bool analyze_only, bool freeze,
19+
bool and_analyze, bool analyze_only, bool analyze_in_stages, bool freeze,
2020
const char *table, const char *host, const char *port,
2121
const char *username, enum trivalue prompt_password,
2222
const char *progname, bool echo);
2323
static void vacuum_all_databases(bool full, bool verbose, bool and_analyze,
24-
bool analyze_only, bool freeze,
24+
bool analyze_only, bool analyze_in_stages, bool freeze,
2525
const char *maintenance_db,
2626
const char *host, const char *port,
2727
const char *username, enum trivalue prompt_password,
@@ -50,6 +50,7 @@ main(int argc, char *argv[])
5050
{"full", no_argument, NULL, 'f'},
5151
{"verbose", no_argument, NULL, 'v'},
5252
{"maintenance-db", required_argument, NULL, 2},
53+
{"analyze-in-stages", no_argument, NULL, 3},
5354
{NULL, 0, NULL, 0}
5455
};
5556

@@ -67,6 +68,7 @@ main(int argc, char *argv[])
6768
bool quiet = false;
6869
bool and_analyze = false;
6970
bool analyze_only = false;
71+
bool analyze_in_stages = false;
7072
bool freeze = false;
7173
bool alldb = false;
7274
bool full = false;
@@ -130,6 +132,9 @@ main(int argc, char *argv[])
130132
case 2:
131133
maintenance_db = pg_strdup(optarg);
132134
break;
135+
case 3:
136+
analyze_in_stages = analyze_only = true;
137+
break;
133138
default:
134139
fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
135140
exit(1);
@@ -189,7 +194,7 @@ main(int argc, char *argv[])
189194
exit(1);
190195
}
191196

192-
vacuum_all_databases(full, verbose, and_analyze, analyze_only, freeze,
197+
vacuum_all_databases(full, verbose, and_analyze, analyze_only, analyze_in_stages, freeze,
193198
maintenance_db, host, port, username,
194199
prompt_password, progname, echo, quiet);
195200
}
@@ -212,15 +217,15 @@ main(int argc, char *argv[])
212217
for (cell = tables.head; cell; cell = cell->next)
213218
{
214219
vacuum_one_database(dbname, full, verbose, and_analyze,
215-
analyze_only,
220+
analyze_only, analyze_in_stages,
216221
freeze, cell->val,
217222
host, port, username, prompt_password,
218223
progname, echo);
219224
}
220225
}
221226
else
222227
vacuum_one_database(dbname, full, verbose, and_analyze,
223-
analyze_only,
228+
analyze_only, analyze_in_stages,
224229
freeze, NULL,
225230
host, port, username, prompt_password,
226231
progname, echo);
@@ -230,9 +235,26 @@ main(int argc, char *argv[])
230235
}
231236

232237

238+
static void
239+
run_vacuum_command(PGconn *conn, const char *sql, bool echo, const char *dbname, const char *table, const char *progname)
240+
{
241+
if (!executeMaintenanceCommand(conn, sql, echo))
242+
{
243+
if (table)
244+
fprintf(stderr, _("%s: vacuuming of table \"%s\" in database \"%s\" failed: %s"),
245+
progname, table, dbname, PQerrorMessage(conn));
246+
else
247+
fprintf(stderr, _("%s: vacuuming of database \"%s\" failed: %s"),
248+
progname, dbname, PQerrorMessage(conn));
249+
PQfinish(conn);
250+
exit(1);
251+
}
252+
}
253+
254+
233255
static void
234256
vacuum_one_database(const char *dbname, bool full, bool verbose, bool and_analyze,
235-
bool analyze_only, bool freeze, const char *table,
257+
bool analyze_only, bool analyze_in_stages, bool freeze, const char *table,
236258
const char *host, const char *port,
237259
const char *username, enum trivalue prompt_password,
238260
const char *progname, bool echo)
@@ -300,25 +322,38 @@ vacuum_one_database(const char *dbname, bool full, bool verbose, bool and_analyz
300322
appendPQExpBuffer(&sql, " %s", table);
301323
appendPQExpBufferStr(&sql, ";");
302324

303-
if (!executeMaintenanceCommand(conn, sql.data, echo))
325+
if (analyze_in_stages)
304326
{
305-
if (table)
306-
fprintf(stderr, _("%s: vacuuming of table \"%s\" in database \"%s\" failed: %s"),
307-
progname, table, dbname, PQerrorMessage(conn));
308-
else
309-
fprintf(stderr, _("%s: vacuuming of database \"%s\" failed: %s"),
310-
progname, dbname, PQerrorMessage(conn));
311-
PQfinish(conn);
312-
exit(1);
327+
const char *stage_commands[] = {
328+
"SET default_statistics_target=1; SET vacuum_cost_delay=0;",
329+
"SET default_statistics_target=10; RESET vacuum_cost_delay;",
330+
"RESET default_statistics_target;"
331+
};
332+
const char *stage_messages[] = {
333+
gettext_noop("Generating minimal optimizer statistics (1 target)"),
334+
gettext_noop("Generating medium optimizer statistics (10 targets)"),
335+
gettext_noop("Generating default (full) optimizer statistics")
336+
};
337+
int i;
338+
339+
for (i = 0; i < 3; i++)
340+
{
341+
puts(gettext(stage_messages[i]));
342+
executeCommand(conn, stage_commands[i], progname, echo);
343+
run_vacuum_command(conn, sql.data, echo, dbname, table, progname);
344+
}
313345
}
346+
else
347+
run_vacuum_command(conn, sql.data, echo, dbname, NULL, progname);
348+
314349
PQfinish(conn);
315350
termPQExpBuffer(&sql);
316351
}
317352

318353

319354
static void
320355
vacuum_all_databases(bool full, bool verbose, bool and_analyze, bool analyze_only,
321-
bool freeze, const char *maintenance_db,
356+
bool analyze_in_stages, bool freeze, const char *maintenance_db,
322357
const char *host, const char *port,
323358
const char *username, enum trivalue prompt_password,
324359
const char *progname, bool echo, bool quiet)
@@ -343,6 +378,7 @@ vacuum_all_databases(bool full, bool verbose, bool and_analyze, bool analyze_onl
343378
}
344379

345380
vacuum_one_database(dbname, full, verbose, and_analyze, analyze_only,
381+
analyze_in_stages,
346382
freeze, NULL, host, port, username, prompt_password,
347383
progname, echo);
348384
}
@@ -369,6 +405,8 @@ help(const char *progname)
369405
printf(_(" -V, --version output version information, then exit\n"));
370406
printf(_(" -z, --analyze update optimizer statistics\n"));
371407
printf(_(" -Z, --analyze-only only update optimizer statistics\n"));
408+
printf(_(" --analyze-in-stages only update optimizer statistics, in multiple\n"
409+
" stages for faster results\n"));
372410
printf(_(" -?, --help show this help, then exit\n"));
373411
printf(_("\nConnection options:\n"));
374412
printf(_(" -h, --host=HOSTNAME database server host or socket directory\n"));

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy