PostgreSQL Source Code  git master
vacuumdb.c File Reference
#include "postgres_fe.h"
#include <limits.h>
#include "catalog/pg_class_d.h"
#include "common.h"
#include "common/connect.h"
#include "common/logging.h"
#include "fe_utils/cancel.h"
#include "fe_utils/option_utils.h"
#include "fe_utils/parallel_slot.h"
#include "fe_utils/query_utils.h"
#include "fe_utils/simple_list.h"
#include "fe_utils/string_utils.h"
Include dependency graph for vacuumdb.c:

Go to the source code of this file.

Data Structures

struct  vacuumingOptions
 

Macros

#define ANALYZE_NO_STAGE   -1
 
#define ANALYZE_NUM_STAGES   3
 

Typedefs

typedef struct vacuumingOptions vacuumingOptions
 

Enumerations

enum  VacObjFilter {
  OBJFILTER_NONE = 0 , OBJFILTER_ALL_DBS = (1 << 0) , OBJFILTER_DATABASE = (1 << 1) , OBJFILTER_TABLE = (1 << 2) ,
  OBJFILTER_SCHEMA = (1 << 3) , OBJFILTER_SCHEMA_EXCLUDE = (1 << 4)
}
 

Functions

static void vacuum_one_database (ConnParams *cparams, vacuumingOptions *vacopts, int stage, SimpleStringList *objects, int concurrentCons, const char *progname, bool echo, bool quiet)
 
static void vacuum_all_databases (ConnParams *cparams, vacuumingOptions *vacopts, bool analyze_in_stages, int concurrentCons, const char *progname, bool echo, bool quiet)
 
static void prepare_vacuum_command (PQExpBuffer sql, int serverVersion, vacuumingOptions *vacopts, const char *table)
 
static void run_vacuum_command (PGconn *conn, const char *sql, bool echo, const char *table)
 
static void help (const char *progname)
 
void check_objfilter (void)
 
int main (int argc, char *argv[])
 

Variables

VacObjFilter objfilter = OBJFILTER_NONE
 

Macro Definition Documentation

◆ ANALYZE_NO_STAGE

#define ANALYZE_NO_STAGE   -1

Definition at line 88 of file vacuumdb.c.

◆ ANALYZE_NUM_STAGES

#define ANALYZE_NUM_STAGES   3

Definition at line 89 of file vacuumdb.c.

Typedef Documentation

◆ vacuumingOptions

Enumeration Type Documentation

◆ VacObjFilter

Enumerator
OBJFILTER_NONE 
OBJFILTER_ALL_DBS 
OBJFILTER_DATABASE 
OBJFILTER_TABLE 
OBJFILTER_SCHEMA 
OBJFILTER_SCHEMA_EXCLUDE 

Definition at line 52 of file vacuumdb.c.

53 {
54  OBJFILTER_NONE = 0, /* no filter used */
55  OBJFILTER_ALL_DBS = (1 << 0), /* -a | --all */
56  OBJFILTER_DATABASE = (1 << 1), /* -d | --dbname */
57  OBJFILTER_TABLE = (1 << 2), /* -t | --table */
58  OBJFILTER_SCHEMA = (1 << 3), /* -n | --schema */
59  OBJFILTER_SCHEMA_EXCLUDE = (1 << 4) /* -N | --exclude-schema */
60 } VacObjFilter;
VacObjFilter
Definition: vacuumdb.c:53
@ OBJFILTER_DATABASE
Definition: vacuumdb.c:56
@ OBJFILTER_ALL_DBS
Definition: vacuumdb.c:55
@ OBJFILTER_SCHEMA
Definition: vacuumdb.c:58
@ OBJFILTER_SCHEMA_EXCLUDE
Definition: vacuumdb.c:59
@ OBJFILTER_TABLE
Definition: vacuumdb.c:57
@ OBJFILTER_NONE
Definition: vacuumdb.c:54

Function Documentation

◆ check_objfilter()

void check_objfilter ( void  )

Definition at line 410 of file vacuumdb.c.

411 {
412  if ((objfilter & OBJFILTER_ALL_DBS) &&
414  pg_fatal("cannot vacuum all databases and a specific one at the same time");
415 
416  if ((objfilter & OBJFILTER_ALL_DBS) &&
418  pg_fatal("cannot vacuum specific table(s) in all databases");
419 
420  if ((objfilter & OBJFILTER_ALL_DBS) &&
422  pg_fatal("cannot vacuum specific schema(s) in all databases");
423 
424  if ((objfilter & OBJFILTER_ALL_DBS) &&
426  pg_fatal("cannot exclude specific schema(s) in all databases");
427 
428  if ((objfilter & OBJFILTER_TABLE) &&
430  pg_fatal("cannot vacuum all tables in schema(s) and specific table(s) at the same time");
431 
432  if ((objfilter & OBJFILTER_TABLE) &&
434  pg_fatal("cannot vacuum specific table(s) and exclude schema(s) at the same time");
435 
436  if ((objfilter & OBJFILTER_SCHEMA) &&
438  pg_fatal("cannot vacuum all tables in schema(s) and exclude schema(s) at the same time");
439 }
#define pg_fatal(...)
VacObjFilter objfilter
Definition: vacuumdb.c:62

References objfilter, OBJFILTER_ALL_DBS, OBJFILTER_DATABASE, OBJFILTER_SCHEMA, OBJFILTER_SCHEMA_EXCLUDE, OBJFILTER_TABLE, and pg_fatal.

Referenced by main().

◆ help()

static void help ( const char *  progname)
static

Definition at line 1099 of file vacuumdb.c.

1100 {
1101  printf(_("%s cleans and analyzes a PostgreSQL database.\n\n"), progname);
1102  printf(_("Usage:\n"));
1103  printf(_(" %s [OPTION]... [DBNAME]\n"), progname);
1104  printf(_("\nOptions:\n"));
1105  printf(_(" -a, --all vacuum all databases\n"));
1106  printf(_(" -d, --dbname=DBNAME database to vacuum\n"));
1107  printf(_(" --disable-page-skipping disable all page-skipping behavior\n"));
1108  printf(_(" -e, --echo show the commands being sent to the server\n"));
1109  printf(_(" -f, --full do full vacuuming\n"));
1110  printf(_(" -F, --freeze freeze row transaction information\n"));
1111  printf(_(" --force-index-cleanup always remove index entries that point to dead tuples\n"));
1112  printf(_(" -j, --jobs=NUM use this many concurrent connections to vacuum\n"));
1113  printf(_(" --min-mxid-age=MXID_AGE minimum multixact ID age of tables to vacuum\n"));
1114  printf(_(" --min-xid-age=XID_AGE minimum transaction ID age of tables to vacuum\n"));
1115  printf(_(" --no-index-cleanup don't remove index entries that point to dead tuples\n"));
1116  printf(_(" --no-process-main skip the main relation\n"));
1117  printf(_(" --no-process-toast skip the TOAST table associated with the table to vacuum\n"));
1118  printf(_(" --no-truncate don't truncate empty pages at the end of the table\n"));
1119  printf(_(" -n, --schema=PATTERN vacuum tables in the specified schema(s) only\n"));
1120  printf(_(" -N, --exclude-schema=PATTERN do not vacuum tables in the specified schema(s)\n"));
1121  printf(_(" -P, --parallel=PARALLEL_WORKERS use this many background workers for vacuum, if available\n"));
1122  printf(_(" -q, --quiet don't write any messages\n"));
1123  printf(_(" --skip-locked skip relations that cannot be immediately locked\n"));
1124  printf(_(" -t, --table='TABLE[(COLUMNS)]' vacuum specific table(s) only\n"));
1125  printf(_(" -v, --verbose write a lot of output\n"));
1126  printf(_(" -V, --version output version information, then exit\n"));
1127  printf(_(" -z, --analyze update optimizer statistics\n"));
1128  printf(_(" -Z, --analyze-only only update optimizer statistics; no vacuum\n"));
1129  printf(_(" --analyze-in-stages only update optimizer statistics, in multiple\n"
1130  " stages for faster results; no vacuum\n"));
1131  printf(_(" -?, --help show this help, then exit\n"));
1132  printf(_("\nConnection options:\n"));
1133  printf(_(" -h, --host=HOSTNAME database server host or socket directory\n"));
1134  printf(_(" -p, --port=PORT database server port\n"));
1135  printf(_(" -U, --username=USERNAME user name to connect as\n"));
1136  printf(_(" -w, --no-password never prompt for password\n"));
1137  printf(_(" -W, --password force password prompt\n"));
1138  printf(_(" --maintenance-db=DBNAME alternate maintenance database\n"));
1139  printf(_("\nRead the description of the SQL command VACUUM for details.\n"));
1140  printf(_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT);
1141  printf(_("%s home page: <%s>\n"), PACKAGE_NAME, PACKAGE_URL);
1142 }
#define _(x)
Definition: elog.c:91
const char * progname
Definition: main.c:45
#define printf(...)
Definition: port.h:244

References _, printf, and progname.

Referenced by main().

◆ main()

int main ( int  argc,
char *  argv[] 
)

Definition at line 93 of file vacuumdb.c.

94 {
95  static struct option long_options[] = {
96  {"host", required_argument, NULL, 'h'},
97  {"port", required_argument, NULL, 'p'},
98  {"username", required_argument, NULL, 'U'},
99  {"no-password", no_argument, NULL, 'w'},
100  {"password", no_argument, NULL, 'W'},
101  {"echo", no_argument, NULL, 'e'},
102  {"quiet", no_argument, NULL, 'q'},
103  {"dbname", required_argument, NULL, 'd'},
104  {"analyze", no_argument, NULL, 'z'},
105  {"analyze-only", no_argument, NULL, 'Z'},
106  {"freeze", no_argument, NULL, 'F'},
107  {"all", no_argument, NULL, 'a'},
108  {"table", required_argument, NULL, 't'},
109  {"full", no_argument, NULL, 'f'},
110  {"verbose", no_argument, NULL, 'v'},
111  {"jobs", required_argument, NULL, 'j'},
112  {"parallel", required_argument, NULL, 'P'},
113  {"schema", required_argument, NULL, 'n'},
114  {"exclude-schema", required_argument, NULL, 'N'},
115  {"maintenance-db", required_argument, NULL, 2},
116  {"analyze-in-stages", no_argument, NULL, 3},
117  {"disable-page-skipping", no_argument, NULL, 4},
118  {"skip-locked", no_argument, NULL, 5},
119  {"min-xid-age", required_argument, NULL, 6},
120  {"min-mxid-age", required_argument, NULL, 7},
121  {"no-index-cleanup", no_argument, NULL, 8},
122  {"force-index-cleanup", no_argument, NULL, 9},
123  {"no-truncate", no_argument, NULL, 10},
124  {"no-process-toast", no_argument, NULL, 11},
125  {"no-process-main", no_argument, NULL, 12},
126  {NULL, 0, NULL, 0}
127  };
128 
129  const char *progname;
130  int optindex;
131  int c;
132  const char *dbname = NULL;
133  const char *maintenance_db = NULL;
134  char *host = NULL;
135  char *port = NULL;
136  char *username = NULL;
137  enum trivalue prompt_password = TRI_DEFAULT;
138  ConnParams cparams;
139  bool echo = false;
140  bool quiet = false;
141  vacuumingOptions vacopts;
142  bool analyze_in_stages = false;
143  SimpleStringList objects = {NULL, NULL};
144  int concurrentCons = 1;
145  int tbl_count = 0;
146 
147  /* initialize options */
148  memset(&vacopts, 0, sizeof(vacopts));
149  vacopts.parallel_workers = -1;
150  vacopts.no_index_cleanup = false;
151  vacopts.force_index_cleanup = false;
152  vacopts.do_truncate = true;
153  vacopts.process_main = true;
154  vacopts.process_toast = true;
155 
156  pg_logging_init(argv[0]);
157  progname = get_progname(argv[0]);
158  set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pgscripts"));
159 
160  handle_help_version_opts(argc, argv, "vacuumdb", help);
161 
162  while ((c = getopt_long(argc, argv, "ad:efFh:j:n:N:p:P:qt:U:vwWzZ", long_options, &optindex)) != -1)
163  {
164  switch (c)
165  {
166  case 'a':
168  break;
169  case 'd':
172  break;
173  case 'e':
174  echo = true;
175  break;
176  case 'f':
177  vacopts.full = true;
178  break;
179  case 'F':
180  vacopts.freeze = true;
181  break;
182  case 'h':
183  host = pg_strdup(optarg);
184  break;
185  case 'j':
186  if (!option_parse_int(optarg, "-j/--jobs", 1, INT_MAX,
187  &concurrentCons))
188  exit(1);
189  break;
190  case 'n':
193  break;
194  case 'N':
197  break;
198  case 'p':
199  port = pg_strdup(optarg);
200  break;
201  case 'P':
202  if (!option_parse_int(optarg, "-P/--parallel", 0, INT_MAX,
203  &vacopts.parallel_workers))
204  exit(1);
205  break;
206  case 'q':
207  quiet = true;
208  break;
209  case 't':
212  tbl_count++;
213  break;
214  case 'U':
216  break;
217  case 'v':
218  vacopts.verbose = true;
219  break;
220  case 'w':
221  prompt_password = TRI_NO;
222  break;
223  case 'W':
224  prompt_password = TRI_YES;
225  break;
226  case 'z':
227  vacopts.and_analyze = true;
228  break;
229  case 'Z':
230  vacopts.analyze_only = true;
231  break;
232  case 2:
233  maintenance_db = pg_strdup(optarg);
234  break;
235  case 3:
236  analyze_in_stages = vacopts.analyze_only = true;
237  break;
238  case 4:
239  vacopts.disable_page_skipping = true;
240  break;
241  case 5:
242  vacopts.skip_locked = true;
243  break;
244  case 6:
245  if (!option_parse_int(optarg, "--min-xid-age", 1, INT_MAX,
246  &vacopts.min_xid_age))
247  exit(1);
248  break;
249  case 7:
250  if (!option_parse_int(optarg, "--min-mxid-age", 1, INT_MAX,
251  &vacopts.min_mxid_age))
252  exit(1);
253  break;
254  case 8:
255  vacopts.no_index_cleanup = true;
256  break;
257  case 9:
258  vacopts.force_index_cleanup = true;
259  break;
260  case 10:
261  vacopts.do_truncate = false;
262  break;
263  case 11:
264  vacopts.process_toast = false;
265  break;
266  case 12:
267  vacopts.process_main = false;
268  break;
269  default:
270  /* getopt_long already emitted a complaint */
271  pg_log_error_hint("Try \"%s --help\" for more information.", progname);
272  exit(1);
273  }
274  }
275 
276  /*
277  * Non-option argument specifies database name as long as it wasn't
278  * already specified with -d / --dbname
279  */
280  if (optind < argc && dbname == NULL)
281  {
283  dbname = argv[optind];
284  optind++;
285  }
286 
287  if (optind < argc)
288  {
289  pg_log_error("too many command-line arguments (first is \"%s\")",
290  argv[optind]);
291  pg_log_error_hint("Try \"%s --help\" for more information.", progname);
292  exit(1);
293  }
294 
295  /*
296  * Validate the combination of filters specified in the command-line
297  * options.
298  */
299  check_objfilter();
300 
301  if (vacopts.analyze_only)
302  {
303  if (vacopts.full)
304  pg_fatal("cannot use the \"%s\" option when performing only analyze",
305  "full");
306  if (vacopts.freeze)
307  pg_fatal("cannot use the \"%s\" option when performing only analyze",
308  "freeze");
309  if (vacopts.disable_page_skipping)
310  pg_fatal("cannot use the \"%s\" option when performing only analyze",
311  "disable-page-skipping");
312  if (vacopts.no_index_cleanup)
313  pg_fatal("cannot use the \"%s\" option when performing only analyze",
314  "no-index-cleanup");
315  if (vacopts.force_index_cleanup)
316  pg_fatal("cannot use the \"%s\" option when performing only analyze",
317  "force-index-cleanup");
318  if (!vacopts.do_truncate)
319  pg_fatal("cannot use the \"%s\" option when performing only analyze",
320  "no-truncate");
321  if (!vacopts.process_main)
322  pg_fatal("cannot use the \"%s\" option when performing only analyze",
323  "no-process-main");
324  if (!vacopts.process_toast)
325  pg_fatal("cannot use the \"%s\" option when performing only analyze",
326  "no-process-toast");
327  /* allow 'and_analyze' with 'analyze_only' */
328  }
329 
330  /* Prohibit full and analyze_only options with parallel option */
331  if (vacopts.parallel_workers >= 0)
332  {
333  if (vacopts.analyze_only)
334  pg_fatal("cannot use the \"%s\" option when performing only analyze",
335  "parallel");
336  if (vacopts.full)
337  pg_fatal("cannot use the \"%s\" option when performing full vacuum",
338  "parallel");
339  }
340 
341  /* Prohibit --no-index-cleanup and --force-index-cleanup together */
342  if (vacopts.no_index_cleanup && vacopts.force_index_cleanup)
343  pg_fatal("cannot use the \"%s\" option with the \"%s\" option",
344  "no-index-cleanup", "force-index-cleanup");
345 
346  /* fill cparams except for dbname, which is set below */
347  cparams.pghost = host;
348  cparams.pgport = port;
349  cparams.pguser = username;
350  cparams.prompt_password = prompt_password;
351  cparams.override_dbname = NULL;
352 
353  setup_cancel_handler(NULL);
354 
355  /* Avoid opening extra connections. */
356  if (tbl_count && (concurrentCons > tbl_count))
357  concurrentCons = tbl_count;
358 
360  {
361  cparams.dbname = maintenance_db;
362 
363  vacuum_all_databases(&cparams, &vacopts,
364  analyze_in_stages,
365  concurrentCons,
366  progname, echo, quiet);
367  }
368  else
369  {
370  if (dbname == NULL)
371  {
372  if (getenv("PGDATABASE"))
373  dbname = getenv("PGDATABASE");
374  else if (getenv("PGUSER"))
375  dbname = getenv("PGUSER");
376  else
378  }
379 
380  cparams.dbname = dbname;
381 
382  if (analyze_in_stages)
383  {
384  int stage;
385 
386  for (stage = 0; stage < ANALYZE_NUM_STAGES; stage++)
387  {
388  vacuum_one_database(&cparams, &vacopts,
389  stage,
390  &objects,
391  concurrentCons,
392  progname, echo, quiet);
393  }
394  }
395  else
396  vacuum_one_database(&cparams, &vacopts,
398  &objects,
399  concurrentCons,
400  progname, echo, quiet);
401  }
402 
403  exit(0);
404 }
static void setup_cancel_handler(void)
Definition: parallel.c:608
#define PG_TEXTDOMAIN(domain)
Definition: c.h:1204
void set_pglocale_pgservice(const char *argv0, const char *app)
Definition: exec.c:460
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
int getopt_long(int argc, char *const argv[], const char *optstring, const struct option *longopts, int *longindex)
Definition: getopt_long.c:57
#define no_argument
Definition: getopt_long.h:24
#define required_argument
Definition: getopt_long.h:25
exit(1)
void pg_logging_init(const char *argv0)
Definition: logging.c:83
#define pg_log_error(...)
Definition: logging.h:106
#define pg_log_error_hint(...)
Definition: logging.h:112
bool option_parse_int(const char *optarg, const char *optname, int min_range, int max_range, int *result)
Definition: option_utils.c:50
void handle_help_version_opts(int argc, char *argv[], const char *fixed_progname, help_handler hlp)
Definition: option_utils.c:24
PGDLLIMPORT int optind
Definition: getopt.c:50
PGDLLIMPORT char * optarg
Definition: getopt.c:52
static int port
Definition: pg_regress.c:90
const char * username
Definition: pgbench.c:306
const char * get_progname(const char *argv0)
Definition: path.c:574
char * c
void simple_string_list_append(SimpleStringList *list, const char *val)
Definition: simple_list.c:63
char * dbname
Definition: streamutil.c:51
const char * pguser
Definition: connect_utils.h:31
char * override_dbname
Definition: pg_backup.h:90
char * pgport
Definition: pg_backup.h:84
char * pghost
Definition: pg_backup.h:85
char * dbname
Definition: pg_backup.h:83
enum trivalue prompt_password
Definition: connect_utils.h:32
bool force_index_cleanup
Definition: vacuumdb.c:44
bool no_index_cleanup
Definition: vacuumdb.c:43
int parallel_workers
Definition: vacuumdb.c:41
bool disable_page_skipping
Definition: vacuumdb.c:37
bool skip_locked
Definition: vacuumdb.c:38
bool process_toast
Definition: vacuumdb.c:47
bool do_truncate
Definition: vacuumdb.c:45
bool process_main
Definition: vacuumdb.c:46
bool and_analyze
Definition: vacuumdb.c:34
bool analyze_only
Definition: vacuumdb.c:32
const char * get_user_name_or_exit(const char *progname)
Definition: username.c:74
void check_objfilter(void)
Definition: vacuumdb.c:410
static void help(const char *progname)
Definition: vacuumdb.c:1099
#define ANALYZE_NUM_STAGES
Definition: vacuumdb.c:89
static void vacuum_all_databases(ConnParams *cparams, vacuumingOptions *vacopts, bool analyze_in_stages, int concurrentCons, const char *progname, bool echo, bool quiet)
Definition: vacuumdb.c:855
#define ANALYZE_NO_STAGE
Definition: vacuumdb.c:88
static void vacuum_one_database(ConnParams *cparams, vacuumingOptions *vacopts, int stage, SimpleStringList *objects, int concurrentCons, const char *progname, bool echo, bool quiet)
Definition: vacuumdb.c:455
trivalue
Definition: vacuumlo.c:35
@ TRI_YES
Definition: vacuumlo.c:38
@ TRI_DEFAULT
Definition: vacuumlo.c:36
@ TRI_NO
Definition: vacuumlo.c:37

References ANALYZE_NO_STAGE, ANALYZE_NUM_STAGES, vacuumingOptions::analyze_only, vacuumingOptions::and_analyze, check_objfilter(), dbname, _connParams::dbname, vacuumingOptions::disable_page_skipping, vacuumingOptions::do_truncate, exit(), vacuumingOptions::force_index_cleanup, vacuumingOptions::freeze, vacuumingOptions::full, get_progname(), get_user_name_or_exit(), getopt_long(), handle_help_version_opts(), help(), vacuumingOptions::min_mxid_age, vacuumingOptions::min_xid_age, no_argument, vacuumingOptions::no_index_cleanup, objfilter, OBJFILTER_ALL_DBS, OBJFILTER_DATABASE, OBJFILTER_SCHEMA, OBJFILTER_SCHEMA_EXCLUDE, OBJFILTER_TABLE, optarg, optind, option_parse_int(), _connParams::override_dbname, vacuumingOptions::parallel_workers, pg_fatal, pg_log_error, pg_log_error_hint, pg_logging_init(), pg_strdup(), PG_TEXTDOMAIN, _connParams::pghost, _connParams::pgport, _connParams::pguser, port, vacuumingOptions::process_main, vacuumingOptions::process_toast, progname, _connParams::prompt_password, required_argument, set_pglocale_pgservice(), setup_cancel_handler(), simple_string_list_append(), vacuumingOptions::skip_locked, TRI_DEFAULT, TRI_NO, TRI_YES, username, vacuum_all_databases(), vacuum_one_database(), and vacuumingOptions::verbose.

◆ prepare_vacuum_command()

static void prepare_vacuum_command ( PQExpBuffer  sql,
int  serverVersion,
vacuumingOptions vacopts,
const char *  table 
)
static

Definition at line 921 of file vacuumdb.c.

923 {
924  const char *paren = " (";
925  const char *comma = ", ";
926  const char *sep = paren;
927 
928  resetPQExpBuffer(sql);
929 
930  if (vacopts->analyze_only)
931  {
932  appendPQExpBufferStr(sql, "ANALYZE");
933 
934  /* parenthesized grammar of ANALYZE is supported since v11 */
935  if (serverVersion >= 110000)
936  {
937  if (vacopts->skip_locked)
938  {
939  /* SKIP_LOCKED is supported since v12 */
940  Assert(serverVersion >= 120000);
941  appendPQExpBuffer(sql, "%sSKIP_LOCKED", sep);
942  sep = comma;
943  }
944  if (vacopts->verbose)
945  {
946  appendPQExpBuffer(sql, "%sVERBOSE", sep);
947  sep = comma;
948  }
949  if (sep != paren)
950  appendPQExpBufferChar(sql, ')');
951  }
952  else
953  {
954  if (vacopts->verbose)
955  appendPQExpBufferStr(sql, " VERBOSE");
956  }
957  }
958  else
959  {
960  appendPQExpBufferStr(sql, "VACUUM");
961 
962  /* parenthesized grammar of VACUUM is supported since v9.0 */
963  if (serverVersion >= 90000)
964  {
965  if (vacopts->disable_page_skipping)
966  {
967  /* DISABLE_PAGE_SKIPPING is supported since v9.6 */
968  Assert(serverVersion >= 90600);
969  appendPQExpBuffer(sql, "%sDISABLE_PAGE_SKIPPING", sep);
970  sep = comma;
971  }
972  if (vacopts->no_index_cleanup)
973  {
974  /* "INDEX_CLEANUP FALSE" has been supported since v12 */
975  Assert(serverVersion >= 120000);
976  Assert(!vacopts->force_index_cleanup);
977  appendPQExpBuffer(sql, "%sINDEX_CLEANUP FALSE", sep);
978  sep = comma;
979  }
980  if (vacopts->force_index_cleanup)
981  {
982  /* "INDEX_CLEANUP TRUE" has been supported since v12 */
983  Assert(serverVersion >= 120000);
984  Assert(!vacopts->no_index_cleanup);
985  appendPQExpBuffer(sql, "%sINDEX_CLEANUP TRUE", sep);
986  sep = comma;
987  }
988  if (!vacopts->do_truncate)
989  {
990  /* TRUNCATE is supported since v12 */
991  Assert(serverVersion >= 120000);
992  appendPQExpBuffer(sql, "%sTRUNCATE FALSE", sep);
993  sep = comma;
994  }
995  if (!vacopts->process_main)
996  {
997  /* PROCESS_MAIN is supported since v16 */
998  Assert(serverVersion >= 160000);
999  appendPQExpBuffer(sql, "%sPROCESS_MAIN FALSE", sep);
1000  sep = comma;
1001  }
1002  if (!vacopts->process_toast)
1003  {
1004  /* PROCESS_TOAST is supported since v14 */
1005  Assert(serverVersion >= 140000);
1006  appendPQExpBuffer(sql, "%sPROCESS_TOAST FALSE", sep);
1007  sep = comma;
1008  }
1009  if (vacopts->skip_database_stats)
1010  {
1011  /* SKIP_DATABASE_STATS is supported since v16 */
1012  Assert(serverVersion >= 160000);
1013  appendPQExpBuffer(sql, "%sSKIP_DATABASE_STATS", sep);
1014  sep = comma;
1015  }
1016  if (vacopts->skip_locked)
1017  {
1018  /* SKIP_LOCKED is supported since v12 */
1019  Assert(serverVersion >= 120000);
1020  appendPQExpBuffer(sql, "%sSKIP_LOCKED", sep);
1021  sep = comma;
1022  }
1023  if (vacopts->full)
1024  {
1025  appendPQExpBuffer(sql, "%sFULL", sep);
1026  sep = comma;
1027  }
1028  if (vacopts->freeze)
1029  {
1030  appendPQExpBuffer(sql, "%sFREEZE", sep);
1031  sep = comma;
1032  }
1033  if (vacopts->verbose)
1034  {
1035  appendPQExpBuffer(sql, "%sVERBOSE", sep);
1036  sep = comma;
1037  }
1038  if (vacopts->and_analyze)
1039  {
1040  appendPQExpBuffer(sql, "%sANALYZE", sep);
1041  sep = comma;
1042  }
1043  if (vacopts->parallel_workers >= 0)
1044  {
1045  /* PARALLEL is supported since v13 */
1046  Assert(serverVersion >= 130000);
1047  appendPQExpBuffer(sql, "%sPARALLEL %d", sep,
1048  vacopts->parallel_workers);
1049  sep = comma;
1050  }
1051  if (sep != paren)
1052  appendPQExpBufferChar(sql, ')');
1053  }
1054  else
1055  {
1056  if (vacopts->full)
1057  appendPQExpBufferStr(sql, " FULL");
1058  if (vacopts->freeze)
1059  appendPQExpBufferStr(sql, " FREEZE");
1060  if (vacopts->verbose)
1061  appendPQExpBufferStr(sql, " VERBOSE");
1062  if (vacopts->and_analyze)
1063  appendPQExpBufferStr(sql, " ANALYZE");
1064  }
1065  }
1066 
1067  appendPQExpBuffer(sql, " %s;", table);
1068 }
#define comma
Definition: indent_codes.h:48
Assert(fmt[strlen(fmt) - 1] !='\n')
void resetPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:146
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:265
void appendPQExpBufferChar(PQExpBuffer str, char ch)
Definition: pqexpbuffer.c:378
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:367
bool skip_database_stats
Definition: vacuumdb.c:48

References vacuumingOptions::analyze_only, vacuumingOptions::and_analyze, appendPQExpBuffer(), appendPQExpBufferChar(), appendPQExpBufferStr(), Assert(), comma, vacuumingOptions::disable_page_skipping, vacuumingOptions::do_truncate, vacuumingOptions::force_index_cleanup, vacuumingOptions::freeze, vacuumingOptions::full, vacuumingOptions::no_index_cleanup, vacuumingOptions::parallel_workers, vacuumingOptions::process_main, vacuumingOptions::process_toast, resetPQExpBuffer(), vacuumingOptions::skip_database_stats, vacuumingOptions::skip_locked, and vacuumingOptions::verbose.

Referenced by vacuum_one_database().

◆ run_vacuum_command()

static void run_vacuum_command ( PGconn conn,
const char *  sql,
bool  echo,
const char *  table 
)
static

Definition at line 1077 of file vacuumdb.c.

1079 {
1080  bool status;
1081 
1082  if (echo)
1083  printf("%s\n", sql);
1084 
1085  status = PQsendQuery(conn, sql) == 1;
1086 
1087  if (!status)
1088  {
1089  if (table)
1090  pg_log_error("vacuuming of table \"%s\" in database \"%s\" failed: %s",
1091  table, PQdb(conn), PQerrorMessage(conn));
1092  else
1093  pg_log_error("vacuuming of database \"%s\" failed: %s",
1095  }
1096 }
char * PQdb(const PGconn *conn)
Definition: fe-connect.c:6811
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:6965
int PQsendQuery(PGconn *conn, const char *query)
Definition: fe-exec.c:1418
static void static void status(const char *fmt,...) pg_attribute_printf(1
Definition: pg_regress.c:224
PGconn * conn
Definition: streamutil.c:54

References conn, pg_log_error, PQdb(), PQerrorMessage(), PQsendQuery(), printf, and status().

Referenced by vacuum_one_database().

◆ vacuum_all_databases()

static void vacuum_all_databases ( ConnParams cparams,
vacuumingOptions vacopts,
bool  analyze_in_stages,
int  concurrentCons,
const char *  progname,
bool  echo,
bool  quiet 
)
static

Definition at line 855 of file vacuumdb.c.

860 {
861  PGconn *conn;
862  PGresult *result;
863  int stage;
864  int i;
865 
866  conn = connectMaintenanceDatabase(cparams, progname, echo);
867  result = executeQuery(conn,
868  "SELECT datname FROM pg_database WHERE datallowconn ORDER BY 1;",
869  echo);
870  PQfinish(conn);
871 
872  if (analyze_in_stages)
873  {
874  /*
875  * When analyzing all databases in stages, we analyze them all in the
876  * fastest stage first, so that initial statistics become available
877  * for all of them as soon as possible.
878  *
879  * This means we establish several times as many connections, but
880  * that's a secondary consideration.
881  */
882  for (stage = 0; stage < ANALYZE_NUM_STAGES; stage++)
883  {
884  for (i = 0; i < PQntuples(result); i++)
885  {
886  cparams->override_dbname = PQgetvalue(result, i, 0);
887 
888  vacuum_one_database(cparams, vacopts,
889  stage,
890  NULL,
891  concurrentCons,
892  progname, echo, quiet);
893  }
894  }
895  }
896  else
897  {
898  for (i = 0; i < PQntuples(result); i++)
899  {
900  cparams->override_dbname = PQgetvalue(result, i, 0);
901 
902  vacuum_one_database(cparams, vacopts,
904  NULL,
905  concurrentCons,
906  progname, echo, quiet);
907  }
908  }
909 
910  PQclear(result);
911 }
PGconn * connectMaintenanceDatabase(ConnParams *cparams, const char *progname, bool echo)
void PQfinish(PGconn *conn)
Definition: fe-connect.c:4352
int PQntuples(const PGresult *res)
Definition: fe-exec.c:3310
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3705
int i
Definition: isn.c:73
static PGresult * executeQuery(PGconn *conn, const char *query)
Definition: pg_dumpall.c:1869

References ANALYZE_NO_STAGE, ANALYZE_NUM_STAGES, conn, connectMaintenanceDatabase(), executeQuery(), i, _connParams::override_dbname, PQclear(), PQfinish(), PQgetvalue(), PQntuples(), progname, and vacuum_one_database().

Referenced by main().

◆ vacuum_one_database()

static void vacuum_one_database ( ConnParams cparams,
vacuumingOptions vacopts,
int  stage,
SimpleStringList objects,
int  concurrentCons,
const char *  progname,
bool  echo,
bool  quiet 
)
static

Definition at line 455 of file vacuumdb.c.

461 {
462  PQExpBufferData sql;
464  PQExpBufferData catalog_query;
465  PGresult *res;
466  PGconn *conn;
467  SimpleStringListCell *cell;
469  SimpleStringList dbtables = {NULL, NULL};
470  int i;
471  int ntups;
472  bool failed = false;
473  bool objects_listed = false;
474  bool has_where = false;
475  const char *initcmd;
476  const char *stage_commands[] = {
477  "SET default_statistics_target=1; SET vacuum_cost_delay=0;",
478  "SET default_statistics_target=10; RESET vacuum_cost_delay;",
479  "RESET default_statistics_target;"
480  };
481  const char *stage_messages[] = {
482  gettext_noop("Generating minimal optimizer statistics (1 target)"),
483  gettext_noop("Generating medium optimizer statistics (10 targets)"),
484  gettext_noop("Generating default (full) optimizer statistics")
485  };
486 
487  Assert(stage == ANALYZE_NO_STAGE ||
488  (stage >= 0 && stage < ANALYZE_NUM_STAGES));
489 
490  conn = connectDatabase(cparams, progname, echo, false, true);
491 
492  if (vacopts->disable_page_skipping && PQserverVersion(conn) < 90600)
493  {
494  PQfinish(conn);
495  pg_fatal("cannot use the \"%s\" option on server versions older than PostgreSQL %s",
496  "disable-page-skipping", "9.6");
497  }
498 
499  if (vacopts->no_index_cleanup && PQserverVersion(conn) < 120000)
500  {
501  PQfinish(conn);
502  pg_fatal("cannot use the \"%s\" option on server versions older than PostgreSQL %s",
503  "no-index-cleanup", "12");
504  }
505 
506  if (vacopts->force_index_cleanup && PQserverVersion(conn) < 120000)
507  {
508  PQfinish(conn);
509  pg_fatal("cannot use the \"%s\" option on server versions older than PostgreSQL %s",
510  "force-index-cleanup", "12");
511  }
512 
513  if (!vacopts->do_truncate && PQserverVersion(conn) < 120000)
514  {
515  PQfinish(conn);
516  pg_fatal("cannot use the \"%s\" option on server versions older than PostgreSQL %s",
517  "no-truncate", "12");
518  }
519 
520  if (!vacopts->process_main && PQserverVersion(conn) < 160000)
521  {
522  PQfinish(conn);
523  pg_fatal("cannot use the \"%s\" option on server versions older than PostgreSQL %s",
524  "no-process-main", "16");
525  }
526 
527  if (!vacopts->process_toast && PQserverVersion(conn) < 140000)
528  {
529  PQfinish(conn);
530  pg_fatal("cannot use the \"%s\" option on server versions older than PostgreSQL %s",
531  "no-process-toast", "14");
532  }
533 
534  if (vacopts->skip_locked && PQserverVersion(conn) < 120000)
535  {
536  PQfinish(conn);
537  pg_fatal("cannot use the \"%s\" option on server versions older than PostgreSQL %s",
538  "skip-locked", "12");
539  }
540 
541  if (vacopts->min_xid_age != 0 && PQserverVersion(conn) < 90600)
542  pg_fatal("cannot use the \"%s\" option on server versions older than PostgreSQL %s",
543  "--min-xid-age", "9.6");
544 
545  if (vacopts->min_mxid_age != 0 && PQserverVersion(conn) < 90600)
546  pg_fatal("cannot use the \"%s\" option on server versions older than PostgreSQL %s",
547  "--min-mxid-age", "9.6");
548 
549  if (vacopts->parallel_workers >= 0 && PQserverVersion(conn) < 130000)
550  pg_fatal("cannot use the \"%s\" option on server versions older than PostgreSQL %s",
551  "--parallel", "13");
552 
553  /* skip_database_stats is used automatically if server supports it */
554  vacopts->skip_database_stats = (PQserverVersion(conn) >= 160000);
555 
556  if (!quiet)
557  {
558  if (stage != ANALYZE_NO_STAGE)
559  printf(_("%s: processing database \"%s\": %s\n"),
560  progname, PQdb(conn), _(stage_messages[stage]));
561  else
562  printf(_("%s: vacuuming database \"%s\"\n"),
563  progname, PQdb(conn));
564  fflush(stdout);
565  }
566 
567  /*
568  * Prepare the list of tables to process by querying the catalogs.
569  *
570  * Since we execute the constructed query with the default search_path
571  * (which could be unsafe), everything in this query MUST be fully
572  * qualified.
573  *
574  * First, build a WITH clause for the catalog query if any tables were
575  * specified, with a set of values made of relation names and their
576  * optional set of columns. This is used to match any provided column
577  * lists with the generated qualified identifiers and to filter for the
578  * tables provided via --table. If a listed table does not exist, the
579  * catalog query will fail.
580  */
581  initPQExpBuffer(&catalog_query);
582  for (cell = objects ? objects->head : NULL; cell; cell = cell->next)
583  {
584  char *just_table = NULL;
585  const char *just_columns = NULL;
586 
587  if (!objects_listed)
588  {
589  appendPQExpBufferStr(&catalog_query,
590  "WITH listed_objects (object_oid, column_list) "
591  "AS (\n VALUES (");
592  objects_listed = true;
593  }
594  else
595  appendPQExpBufferStr(&catalog_query, ",\n (");
596 
598  {
599  appendStringLiteralConn(&catalog_query, cell->val, conn);
600  appendPQExpBufferStr(&catalog_query, "::pg_catalog.regnamespace, ");
601  }
602 
604  {
605  /*
606  * Split relation and column names given by the user, this is used
607  * to feed the CTE with values on which are performed pre-run
608  * validity checks as well. For now these happen only on the
609  * relation name.
610  */
612  &just_table, &just_columns);
613 
614  appendStringLiteralConn(&catalog_query, just_table, conn);
615  appendPQExpBufferStr(&catalog_query, "::pg_catalog.regclass, ");
616  }
617 
618  if (just_columns && just_columns[0] != '\0')
619  appendStringLiteralConn(&catalog_query, just_columns, conn);
620  else
621  appendPQExpBufferStr(&catalog_query, "NULL");
622 
623  appendPQExpBufferStr(&catalog_query, "::pg_catalog.text)");
624 
625  pg_free(just_table);
626  }
627 
628  /* Finish formatting the CTE */
629  if (objects_listed)
630  appendPQExpBufferStr(&catalog_query, "\n)\n");
631 
632  appendPQExpBufferStr(&catalog_query, "SELECT c.relname, ns.nspname");
633 
634  if (objects_listed)
635  appendPQExpBufferStr(&catalog_query, ", listed_objects.column_list");
636 
637  appendPQExpBufferStr(&catalog_query,
638  " FROM pg_catalog.pg_class c\n"
639  " JOIN pg_catalog.pg_namespace ns"
640  " ON c.relnamespace OPERATOR(pg_catalog.=) ns.oid\n"
641  " LEFT JOIN pg_catalog.pg_class t"
642  " ON c.reltoastrelid OPERATOR(pg_catalog.=) t.oid\n");
643 
644  /* Used to match the tables or schemas listed by the user */
645  if (objects_listed)
646  {
647  appendPQExpBufferStr(&catalog_query, " JOIN listed_objects"
648  " ON listed_objects.object_oid ");
649 
651  appendPQExpBufferStr(&catalog_query, "OPERATOR(pg_catalog.!=) ");
652  else
653  appendPQExpBufferStr(&catalog_query, "OPERATOR(pg_catalog.=) ");
654 
656  appendPQExpBufferStr(&catalog_query, "c.oid\n");
657  else
658  appendPQExpBufferStr(&catalog_query, "ns.oid\n");
659  }
660 
661  /*
662  * If no tables were listed, filter for the relevant relation types. If
663  * tables were given via --table, don't bother filtering by relation type.
664  * Instead, let the server decide whether a given relation can be
665  * processed in which case the user will know about it.
666  */
667  if ((objfilter & OBJFILTER_TABLE) == 0)
668  {
669  appendPQExpBufferStr(&catalog_query, " WHERE c.relkind OPERATOR(pg_catalog.=) ANY (array["
670  CppAsString2(RELKIND_RELATION) ", "
671  CppAsString2(RELKIND_MATVIEW) "])\n");
672  has_where = true;
673  }
674 
675  /*
676  * For --min-xid-age and --min-mxid-age, the age of the relation is the
677  * greatest of the ages of the main relation and its associated TOAST
678  * table. The commands generated by vacuumdb will also process the TOAST
679  * table for the relation if necessary, so it does not need to be
680  * considered separately.
681  */
682  if (vacopts->min_xid_age != 0)
683  {
684  appendPQExpBuffer(&catalog_query,
685  " %s GREATEST(pg_catalog.age(c.relfrozenxid),"
686  " pg_catalog.age(t.relfrozenxid)) "
687  " OPERATOR(pg_catalog.>=) '%d'::pg_catalog.int4\n"
688  " AND c.relfrozenxid OPERATOR(pg_catalog.!=)"
689  " '0'::pg_catalog.xid\n",
690  has_where ? "AND" : "WHERE", vacopts->min_xid_age);
691  has_where = true;
692  }
693 
694  if (vacopts->min_mxid_age != 0)
695  {
696  appendPQExpBuffer(&catalog_query,
697  " %s GREATEST(pg_catalog.mxid_age(c.relminmxid),"
698  " pg_catalog.mxid_age(t.relminmxid)) OPERATOR(pg_catalog.>=)"
699  " '%d'::pg_catalog.int4\n"
700  " AND c.relminmxid OPERATOR(pg_catalog.!=)"
701  " '0'::pg_catalog.xid\n",
702  has_where ? "AND" : "WHERE", vacopts->min_mxid_age);
703  has_where = true;
704  }
705 
706  /*
707  * Execute the catalog query. We use the default search_path for this
708  * query for consistency with table lookups done elsewhere by the user.
709  */
710  appendPQExpBufferStr(&catalog_query, " ORDER BY c.relpages DESC;");
711  executeCommand(conn, "RESET search_path;", echo);
712  res = executeQuery(conn, catalog_query.data, echo);
713  termPQExpBuffer(&catalog_query);
715 
716  /*
717  * If no rows are returned, there are no matching tables, so we are done.
718  */
719  ntups = PQntuples(res);
720  if (ntups == 0)
721  {
722  PQclear(res);
723  PQfinish(conn);
724  return;
725  }
726 
727  /*
728  * Build qualified identifiers for each table, including the column list
729  * if given.
730  */
732  for (i = 0; i < ntups; i++)
733  {
736  PQgetvalue(res, i, 0)));
737 
738  if (objects_listed && !PQgetisnull(res, i, 2))
740 
741  simple_string_list_append(&dbtables, buf.data);
743  }
745  PQclear(res);
746 
747  /*
748  * Ensure concurrentCons is sane. If there are more connections than
749  * vacuumable relations, we don't need to use them all.
750  */
751  if (concurrentCons > ntups)
752  concurrentCons = ntups;
753  if (concurrentCons <= 0)
754  concurrentCons = 1;
755 
756  /*
757  * All slots need to be prepared to run the appropriate analyze stage, if
758  * caller requested that mode. We have to prepare the initial connection
759  * ourselves before setting up the slots.
760  */
761  if (stage == ANALYZE_NO_STAGE)
762  initcmd = NULL;
763  else
764  {
765  initcmd = stage_commands[stage];
766  executeCommand(conn, initcmd, echo);
767  }
768 
769  /*
770  * Setup the database connections. We reuse the connection we already have
771  * for the first slot. If not in parallel mode, the first slot in the
772  * array contains the connection.
773  */
774  sa = ParallelSlotsSetup(concurrentCons, cparams, progname, echo, initcmd);
776 
777  initPQExpBuffer(&sql);
778 
779  cell = dbtables.head;
780  do
781  {
782  const char *tabname = cell->val;
783  ParallelSlot *free_slot;
784 
785  if (CancelRequested)
786  {
787  failed = true;
788  goto finish;
789  }
790 
791  free_slot = ParallelSlotsGetIdle(sa, NULL);
792  if (!free_slot)
793  {
794  failed = true;
795  goto finish;
796  }
797 
799  vacopts, tabname);
800 
801  /*
802  * Execute the vacuum. All errors are handled in processQueryResult
803  * through ParallelSlotsGetIdle.
804  */
806  run_vacuum_command(free_slot->connection, sql.data,
807  echo, tabname);
808 
809  cell = cell->next;
810  } while (cell != NULL);
811 
813  {
814  failed = true;
815  goto finish;
816  }
817 
818  /* If we used SKIP_DATABASE_STATS, mop up with ONLY_DATABASE_STATS */
819  if (vacopts->skip_database_stats && stage == ANALYZE_NO_STAGE)
820  {
821  const char *cmd = "VACUUM (ONLY_DATABASE_STATS);";
822  ParallelSlot *free_slot = ParallelSlotsGetIdle(sa, NULL);
823 
824  if (!free_slot)
825  {
826  failed = true;
827  goto finish;
828  }
829 
831  run_vacuum_command(free_slot->connection, cmd, echo, NULL);
832 
834  failed = true;
835  }
836 
837 finish:
839  pg_free(sa);
840 
841  termPQExpBuffer(&sql);
842 
843  if (failed)
844  exit(1);
845 }
void splitTableColumnsSpec(const char *spec, int encoding, char **table, const char **columns)
Definition: common.c:34
#define gettext_noop(x)
Definition: c.h:1186
#define CppAsString2(x)
Definition: c.h:311
volatile sig_atomic_t CancelRequested
Definition: cancel.c:59
#define ALWAYS_SECURE_SEARCH_PATH_SQL
Definition: connect.h:25
int PQserverVersion(const PGconn *conn)
Definition: fe-connect.c:6955
int PQclientEncoding(const PGconn *conn)
Definition: fe-connect.c:7042
int PQgetisnull(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3730
void pg_free(void *ptr)
Definition: fe_memutils.c:105
static void const char fflush(stdout)
ParallelSlot * ParallelSlotsGetIdle(ParallelSlotArray *sa, const char *dbname)
bool ParallelSlotsWaitCompletion(ParallelSlotArray *sa)
ParallelSlotArray * ParallelSlotsSetup(int numslots, ConnParams *cparams, const char *progname, bool echo, const char *initcmd)
bool TableCommandResultHandler(PGresult *res, PGconn *conn, void *context)
void ParallelSlotsTerminate(ParallelSlotArray *sa)
void ParallelSlotsAdoptConn(ParallelSlotArray *sa, PGconn *conn)
static void ParallelSlotSetHandler(ParallelSlot *slot, ParallelSlotResultHandler handler, void *context)
Definition: parallel_slot.h:47
static PGconn * connectDatabase(const char *dbname, const char *connection_string, const char *pghost, const char *pgport, const char *pguser, trivalue prompt_password, bool fail_on_error)
Definition: pg_dumpall.c:1649
static void executeCommand(PGconn *conn, const char *query)
Definition: pg_dumpall.c:1892
static char * buf
Definition: pg_test_fsync.c:67
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:90
void termPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:129
void appendStringLiteralConn(PQExpBuffer buf, const char *str, PGconn *conn)
Definition: string_utils.c:293
const char * fmtQualifiedId(const char *schema, const char *id)
Definition: string_utils.c:145
PGconn * connection
Definition: parallel_slot.h:23
char val[FLEXIBLE_ARRAY_MEMBER]
Definition: simple_list.h:37
struct SimpleStringListCell * next
Definition: simple_list.h:34
SimpleStringListCell * head
Definition: simple_list.h:42
static void run_vacuum_command(PGconn *conn, const char *sql, bool echo, const char *table)
Definition: vacuumdb.c:1077
static void prepare_vacuum_command(PQExpBuffer sql, int serverVersion, vacuumingOptions *vacopts, const char *table)
Definition: vacuumdb.c:921

References _, ALWAYS_SECURE_SEARCH_PATH_SQL, ANALYZE_NO_STAGE, ANALYZE_NUM_STAGES, appendPQExpBuffer(), appendPQExpBufferStr(), appendStringLiteralConn(), Assert(), buf, CancelRequested, conn, connectDatabase(), ParallelSlot::connection, CppAsString2, PQExpBufferData::data, vacuumingOptions::disable_page_skipping, vacuumingOptions::do_truncate, executeCommand(), executeQuery(), exit(), fflush(), fmtQualifiedId(), vacuumingOptions::force_index_cleanup, gettext_noop, SimpleStringList::head, i, initPQExpBuffer(), vacuumingOptions::min_mxid_age, vacuumingOptions::min_xid_age, SimpleStringListCell::next, vacuumingOptions::no_index_cleanup, objfilter, OBJFILTER_SCHEMA, OBJFILTER_SCHEMA_EXCLUDE, OBJFILTER_TABLE, vacuumingOptions::parallel_workers, ParallelSlotsAdoptConn(), ParallelSlotSetHandler(), ParallelSlotsGetIdle(), ParallelSlotsSetup(), ParallelSlotsTerminate(), ParallelSlotsWaitCompletion(), pg_fatal, pg_free(), PQclear(), PQclientEncoding(), PQdb(), PQfinish(), PQgetisnull(), PQgetvalue(), PQntuples(), PQserverVersion(), prepare_vacuum_command(), printf, vacuumingOptions::process_main, vacuumingOptions::process_toast, progname, res, resetPQExpBuffer(), run_vacuum_command(), simple_string_list_append(), vacuumingOptions::skip_database_stats, vacuumingOptions::skip_locked, splitTableColumnsSpec(), generate_unaccent_rules::stdout, TableCommandResultHandler(), termPQExpBuffer(), and SimpleStringListCell::val.

Referenced by main(), and vacuum_all_databases().

Variable Documentation

◆ objfilter

Definition at line 62 of file vacuumdb.c.

Referenced by check_objfilter(), main(), and vacuum_one_database().