1 /*-------------------------------------------------------------------------
5 * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group
6 * Portions Copyright (c) 1994, Regents of the University of California
8 * src/bin/scripts/vacuumdb.c
10 *-------------------------------------------------------------------------
13 #include "postgres_fe.h"
17 static void vacuum_one_database(const char *dbname, bool full, bool verbose,
18 bool and_analyze, bool analyze_only, bool freeze,
19 const char *table, const char *host, const char *port,
20 const char *username, enum trivalue prompt_password,
21 const char *progname, bool echo);
22 static void vacuum_all_databases(bool full, bool verbose, bool and_analyze,
23 bool analyze_only, bool freeze,
24 const char *maintenance_db,
25 const char *host, const char *port,
26 const char *username, enum trivalue prompt_password,
27 const char *progname, bool echo, bool quiet);
29 static void help(const char *progname);
33 main(int argc, char *argv[])
35 static struct option long_options[] = {
36 {"host", required_argument, NULL, 'h'},
37 {"port", required_argument, NULL, 'p'},
38 {"username", required_argument, NULL, 'U'},
39 {"no-password", no_argument, NULL, 'w'},
40 {"password", no_argument, NULL, 'W'},
41 {"echo", no_argument, NULL, 'e'},
42 {"quiet", no_argument, NULL, 'q'},
43 {"dbname", required_argument, NULL, 'd'},
44 {"analyze", no_argument, NULL, 'z'},
45 {"analyze-only", no_argument, NULL, 'Z'},
46 {"freeze", no_argument, NULL, 'F'},
47 {"all", no_argument, NULL, 'a'},
48 {"table", required_argument, NULL, 't'},
49 {"full", no_argument, NULL, 'f'},
50 {"verbose", no_argument, NULL, 'v'},
51 {"maintenance-db", required_argument, NULL, 2},
59 const char *dbname = NULL;
60 const char *maintenance_db = NULL;
63 char *username = NULL;
64 enum trivalue prompt_password = TRI_DEFAULT;
67 bool and_analyze = false;
68 bool analyze_only = false;
75 progname = get_progname(argv[0]);
76 set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pgscripts"));
78 handle_help_version_opts(argc, argv, "vacuumdb", help);
80 while ((c = getopt_long(argc, argv, "h:p:U:wWeqd:zZFat:fv", long_options, &optindex)) != -1)
85 host = pg_strdup(optarg);
88 port = pg_strdup(optarg);
91 username = pg_strdup(optarg);
94 prompt_password = TRI_NO;
97 prompt_password = TRI_YES;
106 dbname = pg_strdup(optarg);
121 table = pg_strdup(optarg);
130 maintenance_db = pg_strdup(optarg);
133 fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
140 * Non-option argument specifies database name as long as it wasn't
141 * already specified with -d / --dbname
143 if (optind < argc && dbname == NULL)
145 dbname = argv[optind];
151 fprintf(stderr, _("%s: too many command-line arguments (first is \"%s\")\n"),
152 progname, argv[optind]);
153 fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
161 fprintf(stderr, _("%s: cannot use the \"full\" option when performing only analyze\n"),
167 fprintf(stderr, _("%s: cannot use the \"freeze\" option when performing only analyze\n"),
171 /* allow 'and_analyze' with 'analyze_only' */
174 setup_cancel_handler();
180 fprintf(stderr, _("%s: cannot vacuum all databases and a specific one at the same time\n"),
186 fprintf(stderr, _("%s: cannot vacuum a specific table in all databases\n"),
191 vacuum_all_databases(full, verbose, and_analyze, analyze_only, freeze,
192 maintenance_db, host, port, username,
193 prompt_password, progname, echo, quiet);
199 if (getenv("PGDATABASE"))
200 dbname = getenv("PGDATABASE");
201 else if (getenv("PGUSER"))
202 dbname = getenv("PGUSER");
204 dbname = get_user_name(progname);
207 vacuum_one_database(dbname, full, verbose, and_analyze, analyze_only,
209 host, port, username, prompt_password,
218 vacuum_one_database(const char *dbname, bool full, bool verbose, bool and_analyze,
219 bool analyze_only, bool freeze, const char *table,
220 const char *host, const char *port,
221 const char *username, enum trivalue prompt_password,
222 const char *progname, bool echo)
228 initPQExpBuffer(&sql);
230 conn = connectDatabase(dbname, host, port, username, prompt_password,
235 appendPQExpBuffer(&sql, "ANALYZE");
237 appendPQExpBuffer(&sql, " VERBOSE");
241 appendPQExpBuffer(&sql, "VACUUM");
242 if (PQserverVersion(conn) >= 90000)
244 const char *paren = " (";
245 const char *comma = ", ";
246 const char *sep = paren;
250 appendPQExpBuffer(&sql, "%sFULL", sep);
255 appendPQExpBuffer(&sql, "%sFREEZE", sep);
260 appendPQExpBuffer(&sql, "%sVERBOSE", sep);
265 appendPQExpBuffer(&sql, "%sANALYZE", sep);
269 appendPQExpBuffer(&sql, ")");
274 appendPQExpBuffer(&sql, " FULL");
276 appendPQExpBuffer(&sql, " FREEZE");
278 appendPQExpBuffer(&sql, " VERBOSE");
280 appendPQExpBuffer(&sql, " ANALYZE");
284 appendPQExpBuffer(&sql, " %s", table);
285 appendPQExpBuffer(&sql, ";\n");
287 if (!executeMaintenanceCommand(conn, sql.data, echo))
290 fprintf(stderr, _("%s: vacuuming of table \"%s\" in database \"%s\" failed: %s"),
291 progname, table, dbname, PQerrorMessage(conn));
293 fprintf(stderr, _("%s: vacuuming of database \"%s\" failed: %s"),
294 progname, dbname, PQerrorMessage(conn));
299 termPQExpBuffer(&sql);
304 vacuum_all_databases(bool full, bool verbose, bool and_analyze, bool analyze_only,
305 bool freeze, const char *maintenance_db,
306 const char *host, const char *port,
307 const char *username, enum trivalue prompt_password,
308 const char *progname, bool echo, bool quiet)
314 conn = connectMaintenanceDatabase(maintenance_db, host, port,
315 username, prompt_password, progname);
316 result = executeQuery(conn, "SELECT datname FROM pg_database WHERE datallowconn ORDER BY 1;", progname, echo);
319 for (i = 0; i < PQntuples(result); i++)
321 char *dbname = PQgetvalue(result, i, 0);
325 printf(_("%s: vacuuming database \"%s\"\n"), progname, dbname);
329 vacuum_one_database(dbname, full, verbose, and_analyze, analyze_only,
330 freeze, NULL, host, port, username, prompt_password,
339 help(const char *progname)
341 printf(_("%s cleans and analyzes a PostgreSQL database.\n\n"), progname);
342 printf(_("Usage:\n"));
343 printf(_(" %s [OPTION]... [DBNAME]\n"), progname);
344 printf(_("\nOptions:\n"));
345 printf(_(" -a, --all vacuum all databases\n"));
346 printf(_(" -d, --dbname=DBNAME database to vacuum\n"));
347 printf(_(" -e, --echo show the commands being sent to the server\n"));
348 printf(_(" -f, --full do full vacuuming\n"));
349 printf(_(" -F, --freeze freeze row transaction information\n"));
350 printf(_(" -q, --quiet don't write any messages\n"));
351 printf(_(" -t, --table='TABLE[(COLUMNS)]' vacuum specific table only\n"));
352 printf(_(" -v, --verbose write a lot of output\n"));
353 printf(_(" -V, --version output version information, then exit\n"));
354 printf(_(" -z, --analyze update optimizer statistics\n"));
355 printf(_(" -Z, --analyze-only only update optimizer statistics\n"));
356 printf(_(" -?, --help show this help, then exit\n"));
357 printf(_("\nConnection options:\n"));
358 printf(_(" -h, --host=HOSTNAME database server host or socket directory\n"));
359 printf(_(" -p, --port=PORT database server port\n"));
360 printf(_(" -U, --username=USERNAME user name to connect as\n"));
361 printf(_(" -w, --no-password never prompt for password\n"));
362 printf(_(" -W, --password force password prompt\n"));
363 printf(_(" --maintenance-db=DBNAME alternate maintenance database\n"));
364 printf(_("\nRead the description of the SQL command VACUUM for details.\n"));
365 printf(_("\nReport bugs to <pgsql-bugs@postgresql.org>.\n"));