PostgreSQL Source Code  git master
vacuum.c
Go to the documentation of this file.
1 /*-------------------------------------------------------------------------
2  *
3  * vacuum.c
4  * The postgres vacuum cleaner.
5  *
6  * This file includes (a) control and dispatch code for VACUUM and ANALYZE
7  * commands, (b) code to compute various vacuum thresholds, and (c) index
8  * vacuum code.
9  *
10  * VACUUM for heap AM is implemented in vacuumlazy.c, parallel vacuum in
11  * vacuumparallel.c, ANALYZE in analyze.c, and VACUUM FULL is a variant of
12  * CLUSTER, handled in cluster.c.
13  *
14  *
15  * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group
16  * Portions Copyright (c) 1994, Regents of the University of California
17  *
18  *
19  * IDENTIFICATION
20  * src/backend/commands/vacuum.c
21  *
22  *-------------------------------------------------------------------------
23  */
24 #include "postgres.h"
25 
26 #include <math.h>
27 
28 #include "access/clog.h"
29 #include "access/commit_ts.h"
30 #include "access/genam.h"
31 #include "access/heapam.h"
32 #include "access/htup_details.h"
33 #include "access/multixact.h"
34 #include "access/tableam.h"
35 #include "access/transam.h"
36 #include "access/xact.h"
37 #include "catalog/namespace.h"
38 #include "catalog/index.h"
39 #include "catalog/pg_database.h"
40 #include "catalog/pg_inherits.h"
41 #include "catalog/pg_namespace.h"
42 #include "commands/cluster.h"
43 #include "commands/defrem.h"
44 #include "commands/vacuum.h"
45 #include "miscadmin.h"
46 #include "nodes/makefuncs.h"
47 #include "pgstat.h"
48 #include "postmaster/autovacuum.h"
50 #include "postmaster/interrupt.h"
51 #include "storage/bufmgr.h"
52 #include "storage/lmgr.h"
53 #include "storage/pmsignal.h"
54 #include "storage/proc.h"
55 #include "storage/procarray.h"
56 #include "utils/acl.h"
57 #include "utils/fmgroids.h"
58 #include "utils/guc.h"
59 #include "utils/guc_hooks.h"
60 #include "utils/memutils.h"
61 #include "utils/pg_rusage.h"
62 #include "utils/snapmgr.h"
63 #include "utils/syscache.h"
64 
65 
66 /*
67  * GUC parameters
68  */
75 
76 /*
77  * Variables for cost-based vacuum delay. The defaults differ between
78  * autovacuum and vacuum. They should be set with the appropriate GUC value in
79  * vacuum code. They are initialized here to the defaults for client backends
80  * executing VACUUM or ANALYZE.
81  */
82 double vacuum_cost_delay = 0;
84 
85 /*
86  * VacuumFailsafeActive is a defined as a global so that we can determine
87  * whether or not to re-enable cost-based vacuum delay when vacuuming a table.
88  * If failsafe mode has been engaged, we will not re-enable cost-based delay
89  * for the table until after vacuuming has completed, regardless of other
90  * settings.
91  *
92  * Only VACUUM code should inspect this variable and only table access methods
93  * should set it to true. In Table AM-agnostic VACUUM code, this variable is
94  * inspected to determine whether or not to allow cost-based delays. Table AMs
95  * are free to set it if they desire this behavior, but it is false by default
96  * and reset to false in between vacuuming each relation.
97  */
98 bool VacuumFailsafeActive = false;
99 
100 /*
101  * Variables for cost-based parallel vacuum. See comments atop
102  * compute_parallel_delay to understand how it works.
103  */
107 
108 /* non-export function prototypes */
110  MemoryContext vac_context, int options);
111 static List *get_all_vacuum_rels(MemoryContext vac_context, int options);
112 static void vac_truncate_clog(TransactionId frozenXID,
113  MultiXactId minMulti,
114  TransactionId lastSaneFrozenXid,
115  MultiXactId lastSaneMinMulti);
116 static bool vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
117  BufferAccessStrategy bstrategy);
118 static double compute_parallel_delay(void);
120 static bool vac_tid_reaped(ItemPointer itemptr, void *state);
121 static int vac_cmp_itemptr(const void *left, const void *right);
122 
123 /*
124  * GUC check function to ensure GUC value specified is within the allowable
125  * range.
126  */
127 bool
130 {
131  /* Value upper and lower hard limits are inclusive */
132  if (*newval == 0 || (*newval >= MIN_BAS_VAC_RING_SIZE_KB &&
134  return true;
135 
136  /* Value does not fall within any allowable range */
137  GUC_check_errdetail("\"vacuum_buffer_usage_limit\" must be 0 or between %d kB and %d kB",
139 
140  return false;
141 }
142 
143 /*
144  * Primary entry point for manual VACUUM and ANALYZE commands
145  *
146  * This is mainly a preparation wrapper for the real operations that will
147  * happen in vacuum().
148  */
149 void
150 ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
151 {
152  VacuumParams params;
153  BufferAccessStrategy bstrategy = NULL;
154  bool verbose = false;
155  bool skip_locked = false;
156  bool analyze = false;
157  bool freeze = false;
158  bool full = false;
159  bool disable_page_skipping = false;
160  bool process_main = true;
161  bool process_toast = true;
162  int ring_size;
163  bool skip_database_stats = false;
164  bool only_database_stats = false;
165  MemoryContext vac_context;
166  ListCell *lc;
167 
168  /* index_cleanup and truncate values unspecified for now */
171 
172  /* By default parallel vacuum is enabled */
173  params.nworkers = 0;
174 
175  /*
176  * Set this to an invalid value so it is clear whether or not a
177  * BUFFER_USAGE_LIMIT was specified when making the access strategy.
178  */
179  ring_size = -1;
180 
181  /* Parse options list */
182  foreach(lc, vacstmt->options)
183  {
184  DefElem *opt = (DefElem *) lfirst(lc);
185 
186  /* Parse common options for VACUUM and ANALYZE */
187  if (strcmp(opt->defname, "verbose") == 0)
188  verbose = defGetBoolean(opt);
189  else if (strcmp(opt->defname, "skip_locked") == 0)
190  skip_locked = defGetBoolean(opt);
191  else if (strcmp(opt->defname, "buffer_usage_limit") == 0)
192  {
193  const char *hintmsg;
194  int result;
195  char *vac_buffer_size;
196 
197  vac_buffer_size = defGetString(opt);
198 
199  /*
200  * Check that the specified value is valid and the size falls
201  * within the hard upper and lower limits if it is not 0.
202  */
203  if (!parse_int(vac_buffer_size, &result, GUC_UNIT_KB, &hintmsg) ||
204  (result != 0 &&
205  (result < MIN_BAS_VAC_RING_SIZE_KB || result > MAX_BAS_VAC_RING_SIZE_KB)))
206  {
207  ereport(ERROR,
208  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
209  errmsg("BUFFER_USAGE_LIMIT option must be 0 or between %d kB and %d kB",
211  hintmsg ? errhint("%s", _(hintmsg)) : 0));
212  }
213 
214  ring_size = result;
215  }
216  else if (!vacstmt->is_vacuumcmd)
217  ereport(ERROR,
218  (errcode(ERRCODE_SYNTAX_ERROR),
219  errmsg("unrecognized ANALYZE option \"%s\"", opt->defname),
220  parser_errposition(pstate, opt->location)));
221 
222  /* Parse options available on VACUUM */
223  else if (strcmp(opt->defname, "analyze") == 0)
224  analyze = defGetBoolean(opt);
225  else if (strcmp(opt->defname, "freeze") == 0)
226  freeze = defGetBoolean(opt);
227  else if (strcmp(opt->defname, "full") == 0)
228  full = defGetBoolean(opt);
229  else if (strcmp(opt->defname, "disable_page_skipping") == 0)
230  disable_page_skipping = defGetBoolean(opt);
231  else if (strcmp(opt->defname, "index_cleanup") == 0)
232  {
233  /* Interpret no string as the default, which is 'auto' */
234  if (!opt->arg)
236  else
237  {
238  char *sval = defGetString(opt);
239 
240  /* Try matching on 'auto' string, or fall back on boolean */
241  if (pg_strcasecmp(sval, "auto") == 0)
243  else
245  }
246  }
247  else if (strcmp(opt->defname, "process_main") == 0)
248  process_main = defGetBoolean(opt);
249  else if (strcmp(opt->defname, "process_toast") == 0)
250  process_toast = defGetBoolean(opt);
251  else if (strcmp(opt->defname, "truncate") == 0)
252  params.truncate = get_vacoptval_from_boolean(opt);
253  else if (strcmp(opt->defname, "parallel") == 0)
254  {
255  if (opt->arg == NULL)
256  {
257  ereport(ERROR,
258  (errcode(ERRCODE_SYNTAX_ERROR),
259  errmsg("parallel option requires a value between 0 and %d",
261  parser_errposition(pstate, opt->location)));
262  }
263  else
264  {
265  int nworkers;
266 
267  nworkers = defGetInt32(opt);
268  if (nworkers < 0 || nworkers > MAX_PARALLEL_WORKER_LIMIT)
269  ereport(ERROR,
270  (errcode(ERRCODE_SYNTAX_ERROR),
271  errmsg("parallel workers for vacuum must be between 0 and %d",
273  parser_errposition(pstate, opt->location)));
274 
275  /*
276  * Disable parallel vacuum, if user has specified parallel
277  * degree as zero.
278  */
279  if (nworkers == 0)
280  params.nworkers = -1;
281  else
282  params.nworkers = nworkers;
283  }
284  }
285  else if (strcmp(opt->defname, "skip_database_stats") == 0)
286  skip_database_stats = defGetBoolean(opt);
287  else if (strcmp(opt->defname, "only_database_stats") == 0)
288  only_database_stats = defGetBoolean(opt);
289  else
290  ereport(ERROR,
291  (errcode(ERRCODE_SYNTAX_ERROR),
292  errmsg("unrecognized VACUUM option \"%s\"", opt->defname),
293  parser_errposition(pstate, opt->location)));
294  }
295 
296  /* Set vacuum options */
297  params.options =
298  (vacstmt->is_vacuumcmd ? VACOPT_VACUUM : VACOPT_ANALYZE) |
299  (verbose ? VACOPT_VERBOSE : 0) |
300  (skip_locked ? VACOPT_SKIP_LOCKED : 0) |
301  (analyze ? VACOPT_ANALYZE : 0) |
302  (freeze ? VACOPT_FREEZE : 0) |
303  (full ? VACOPT_FULL : 0) |
304  (disable_page_skipping ? VACOPT_DISABLE_PAGE_SKIPPING : 0) |
305  (process_main ? VACOPT_PROCESS_MAIN : 0) |
306  (process_toast ? VACOPT_PROCESS_TOAST : 0) |
307  (skip_database_stats ? VACOPT_SKIP_DATABASE_STATS : 0) |
308  (only_database_stats ? VACOPT_ONLY_DATABASE_STATS : 0);
309 
310  /* sanity checks on options */
312  Assert((params.options & VACOPT_VACUUM) ||
313  !(params.options & (VACOPT_FULL | VACOPT_FREEZE)));
314 
315  if ((params.options & VACOPT_FULL) && params.nworkers > 0)
316  ereport(ERROR,
317  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
318  errmsg("VACUUM FULL cannot be performed in parallel")));
319 
320  /*
321  * BUFFER_USAGE_LIMIT does nothing for VACUUM (FULL) so just raise an
322  * ERROR for that case. VACUUM (FULL, ANALYZE) does make use of it, so
323  * we'll permit that.
324  */
325  if (ring_size != -1 && (params.options & VACOPT_FULL) &&
326  !(params.options & VACOPT_ANALYZE))
327  ereport(ERROR,
328  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
329  errmsg("BUFFER_USAGE_LIMIT cannot be specified for VACUUM FULL")));
330 
331  /*
332  * Make sure VACOPT_ANALYZE is specified if any column lists are present.
333  */
334  if (!(params.options & VACOPT_ANALYZE))
335  {
336  foreach(lc, vacstmt->rels)
337  {
339 
340  if (vrel->va_cols != NIL)
341  ereport(ERROR,
342  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
343  errmsg("ANALYZE option must be specified when a column list is provided")));
344  }
345  }
346 
347 
348  /*
349  * Sanity check DISABLE_PAGE_SKIPPING option.
350  */
351  if ((params.options & VACOPT_FULL) != 0 &&
352  (params.options & VACOPT_DISABLE_PAGE_SKIPPING) != 0)
353  ereport(ERROR,
354  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
355  errmsg("VACUUM option DISABLE_PAGE_SKIPPING cannot be used with FULL")));
356 
357  /* sanity check for PROCESS_TOAST */
358  if ((params.options & VACOPT_FULL) != 0 &&
359  (params.options & VACOPT_PROCESS_TOAST) == 0)
360  ereport(ERROR,
361  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
362  errmsg("PROCESS_TOAST required with VACUUM FULL")));
363 
364  /* sanity check for ONLY_DATABASE_STATS */
365  if (params.options & VACOPT_ONLY_DATABASE_STATS)
366  {
367  Assert(params.options & VACOPT_VACUUM);
368  if (vacstmt->rels != NIL)
369  ereport(ERROR,
370  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
371  errmsg("ONLY_DATABASE_STATS cannot be specified with a list of tables")));
372  /* don't require people to turn off PROCESS_TOAST/MAIN explicitly */
373  if (params.options & ~(VACOPT_VACUUM |
378  ereport(ERROR,
379  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
380  errmsg("ONLY_DATABASE_STATS cannot be specified with other VACUUM options")));
381  }
382 
383  /*
384  * All freeze ages are zero if the FREEZE option is given; otherwise pass
385  * them as -1 which means to use the default values.
386  */
387  if (params.options & VACOPT_FREEZE)
388  {
389  params.freeze_min_age = 0;
390  params.freeze_table_age = 0;
391  params.multixact_freeze_min_age = 0;
392  params.multixact_freeze_table_age = 0;
393  }
394  else
395  {
396  params.freeze_min_age = -1;
397  params.freeze_table_age = -1;
398  params.multixact_freeze_min_age = -1;
399  params.multixact_freeze_table_age = -1;
400  }
401 
402  /* user-invoked vacuum is never "for wraparound" */
403  params.is_wraparound = false;
404 
405  /* user-invoked vacuum uses VACOPT_VERBOSE instead of log_min_duration */
406  params.log_min_duration = -1;
407 
408  /*
409  * Create special memory context for cross-transaction storage.
410  *
411  * Since it is a child of PortalContext, it will go away eventually even
412  * if we suffer an error; there's no need for special abort cleanup logic.
413  */
414  vac_context = AllocSetContextCreate(PortalContext,
415  "Vacuum",
417 
418  /*
419  * Make a buffer strategy object in the cross-transaction memory context.
420  * We needn't bother making this for VACUUM (FULL) or VACUUM
421  * (ONLY_DATABASE_STATS) as they'll not make use of it. VACUUM (FULL,
422  * ANALYZE) is possible, so we'd better ensure that we make a strategy
423  * when we see ANALYZE.
424  */
425  if ((params.options & (VACOPT_ONLY_DATABASE_STATS |
426  VACOPT_FULL)) == 0 ||
427  (params.options & VACOPT_ANALYZE) != 0)
428  {
429 
430  MemoryContext old_context = MemoryContextSwitchTo(vac_context);
431 
432  Assert(ring_size >= -1);
433 
434  /*
435  * If BUFFER_USAGE_LIMIT was specified by the VACUUM or ANALYZE
436  * command, it overrides the value of VacuumBufferUsageLimit. Either
437  * value may be 0, in which case GetAccessStrategyWithSize() will
438  * return NULL, effectively allowing full use of shared buffers.
439  */
440  if (ring_size == -1)
441  ring_size = VacuumBufferUsageLimit;
442 
443  bstrategy = GetAccessStrategyWithSize(BAS_VACUUM, ring_size);
444 
445  MemoryContextSwitchTo(old_context);
446  }
447 
448  /* Now go through the common routine */
449  vacuum(vacstmt->rels, &params, bstrategy, vac_context, isTopLevel);
450 
451  /* Finally, clean up the vacuum memory context */
452  MemoryContextDelete(vac_context);
453 }
454 
455 /*
456  * Internal entry point for autovacuum and the VACUUM / ANALYZE commands.
457  *
458  * relations, if not NIL, is a list of VacuumRelation to process; otherwise,
459  * we process all relevant tables in the database. For each VacuumRelation,
460  * if a valid OID is supplied, the table with that OID is what to process;
461  * otherwise, the VacuumRelation's RangeVar indicates what to process.
462  *
463  * params contains a set of parameters that can be used to customize the
464  * behavior.
465  *
466  * bstrategy may be passed in as NULL when the caller does not want to
467  * restrict the number of shared_buffers that VACUUM / ANALYZE can use,
468  * otherwise, the caller must build a BufferAccessStrategy with the number of
469  * shared_buffers that VACUUM / ANALYZE should try to limit themselves to
470  * using.
471  *
472  * isTopLevel should be passed down from ProcessUtility.
473  *
474  * It is the caller's responsibility that all parameters are allocated in a
475  * memory context that will not disappear at transaction commit.
476  */
477 void
478 vacuum(List *relations, VacuumParams *params, BufferAccessStrategy bstrategy,
479  MemoryContext vac_context, bool isTopLevel)
480 {
481  static bool in_vacuum = false;
482 
483  const char *stmttype;
484  volatile bool in_outer_xact,
485  use_own_xacts;
486 
487  Assert(params != NULL);
488 
489  stmttype = (params->options & VACOPT_VACUUM) ? "VACUUM" : "ANALYZE";
490 
491  /*
492  * We cannot run VACUUM inside a user transaction block; if we were inside
493  * a transaction, then our commit- and start-transaction-command calls
494  * would not have the intended effect! There are numerous other subtle
495  * dependencies on this, too.
496  *
497  * ANALYZE (without VACUUM) can run either way.
498  */
499  if (params->options & VACOPT_VACUUM)
500  {
501  PreventInTransactionBlock(isTopLevel, stmttype);
502  in_outer_xact = false;
503  }
504  else
505  in_outer_xact = IsInTransactionBlock(isTopLevel);
506 
507  /*
508  * Check for and disallow recursive calls. This could happen when VACUUM
509  * FULL or ANALYZE calls a hostile index expression that itself calls
510  * ANALYZE.
511  */
512  if (in_vacuum)
513  ereport(ERROR,
514  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
515  errmsg("%s cannot be executed from VACUUM or ANALYZE",
516  stmttype)));
517 
518  /*
519  * Build list of relation(s) to process, putting any new data in
520  * vac_context for safekeeping.
521  */
522  if (params->options & VACOPT_ONLY_DATABASE_STATS)
523  {
524  /* We don't process any tables in this case */
525  Assert(relations == NIL);
526  }
527  else if (relations != NIL)
528  {
529  List *newrels = NIL;
530  ListCell *lc;
531 
532  foreach(lc, relations)
533  {
535  List *sublist;
536  MemoryContext old_context;
537 
538  sublist = expand_vacuum_rel(vrel, vac_context, params->options);
539  old_context = MemoryContextSwitchTo(vac_context);
540  newrels = list_concat(newrels, sublist);
541  MemoryContextSwitchTo(old_context);
542  }
543  relations = newrels;
544  }
545  else
546  relations = get_all_vacuum_rels(vac_context, params->options);
547 
548  /*
549  * Decide whether we need to start/commit our own transactions.
550  *
551  * For VACUUM (with or without ANALYZE): always do so, so that we can
552  * release locks as soon as possible. (We could possibly use the outer
553  * transaction for a one-table VACUUM, but handling TOAST tables would be
554  * problematic.)
555  *
556  * For ANALYZE (no VACUUM): if inside a transaction block, we cannot
557  * start/commit our own transactions. Also, there's no need to do so if
558  * only processing one relation. For multiple relations when not within a
559  * transaction block, and also in an autovacuum worker, use own
560  * transactions so we can release locks sooner.
561  */
562  if (params->options & VACOPT_VACUUM)
563  use_own_xacts = true;
564  else
565  {
566  Assert(params->options & VACOPT_ANALYZE);
568  use_own_xacts = true;
569  else if (in_outer_xact)
570  use_own_xacts = false;
571  else if (list_length(relations) > 1)
572  use_own_xacts = true;
573  else
574  use_own_xacts = false;
575  }
576 
577  /*
578  * vacuum_rel expects to be entered with no transaction active; it will
579  * start and commit its own transaction. But we are called by an SQL
580  * command, and so we are executing inside a transaction already. We
581  * commit the transaction started in PostgresMain() here, and start
582  * another one before exiting to match the commit waiting for us back in
583  * PostgresMain().
584  */
585  if (use_own_xacts)
586  {
587  Assert(!in_outer_xact);
588 
589  /* ActiveSnapshot is not set by autovacuum */
590  if (ActiveSnapshotSet())
592 
593  /* matches the StartTransaction in PostgresMain() */
595  }
596 
597  /* Turn vacuum cost accounting on or off, and set/clear in_vacuum */
598  PG_TRY();
599  {
600  ListCell *cur;
601 
602  in_vacuum = true;
603  VacuumFailsafeActive = false;
605  VacuumCostBalance = 0;
606  VacuumPageHit = 0;
607  VacuumPageMiss = 0;
608  VacuumPageDirty = 0;
611  VacuumActiveNWorkers = NULL;
612 
613  /*
614  * Loop to process each selected relation.
615  */
616  foreach(cur, relations)
617  {
619 
620  if (params->options & VACOPT_VACUUM)
621  {
622  if (!vacuum_rel(vrel->oid, vrel->relation, params, bstrategy))
623  continue;
624  }
625 
626  if (params->options & VACOPT_ANALYZE)
627  {
628  /*
629  * If using separate xacts, start one for analyze. Otherwise,
630  * we can use the outer transaction.
631  */
632  if (use_own_xacts)
633  {
635  /* functions in indexes may want a snapshot set */
637  }
638 
639  analyze_rel(vrel->oid, vrel->relation, params,
640  vrel->va_cols, in_outer_xact, bstrategy);
641 
642  if (use_own_xacts)
643  {
646  }
647  else
648  {
649  /*
650  * If we're not using separate xacts, better separate the
651  * ANALYZE actions with CCIs. This avoids trouble if user
652  * says "ANALYZE t, t".
653  */
655  }
656  }
657 
658  /*
659  * Ensure VacuumFailsafeActive has been reset before vacuuming the
660  * next relation.
661  */
662  VacuumFailsafeActive = false;
663  }
664  }
665  PG_FINALLY();
666  {
667  in_vacuum = false;
668  VacuumCostActive = false;
669  VacuumFailsafeActive = false;
670  VacuumCostBalance = 0;
671  }
672  PG_END_TRY();
673 
674  /*
675  * Finish up processing.
676  */
677  if (use_own_xacts)
678  {
679  /* here, we are not in a transaction */
680 
681  /*
682  * This matches the CommitTransaction waiting for us in
683  * PostgresMain().
684  */
686  }
687 
688  if ((params->options & VACOPT_VACUUM) &&
689  !(params->options & VACOPT_SKIP_DATABASE_STATS))
690  {
691  /*
692  * Update pg_database.datfrozenxid, and truncate pg_xact if possible.
693  */
695  }
696 
697 }
698 
699 /*
700  * Check if a given relation can be safely vacuumed or analyzed. If the
701  * user is not the relation owner, issue a WARNING log message and return
702  * false to let the caller decide what to do with this relation. This
703  * routine is used to decide if a relation can be processed for VACUUM or
704  * ANALYZE.
705  */
706 bool
708 {
709  char *relname;
710 
712 
713  /*
714  * Check permissions.
715  *
716  * We allow the user to vacuum or analyze a table if he is superuser, the
717  * table owner, or the database owner (but in the latter case, only if
718  * it's not a shared relation). object_ownercheck includes the superuser
719  * case.
720  *
721  * Note we choose to treat permissions failure as a WARNING and keep
722  * trying to vacuum or analyze the rest of the DB --- is this appropriate?
723  */
724  if (object_ownercheck(RelationRelationId, relid, GetUserId()) ||
725  (object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared))
726  return true;
727 
728  relname = NameStr(reltuple->relname);
729 
730  if ((options & VACOPT_VACUUM) != 0)
731  {
733  (errmsg("permission denied to vacuum \"%s\", skipping it",
734  relname)));
735 
736  /*
737  * For VACUUM ANALYZE, both logs could show up, but just generate
738  * information for VACUUM as that would be the first one to be
739  * processed.
740  */
741  return false;
742  }
743 
744  if ((options & VACOPT_ANALYZE) != 0)
746  (errmsg("permission denied to analyze \"%s\", skipping it",
747  relname)));
748 
749  return false;
750 }
751 
752 
753 /*
754  * vacuum_open_relation
755  *
756  * This routine is used for attempting to open and lock a relation which
757  * is going to be vacuumed or analyzed. If the relation cannot be opened
758  * or locked, a log is emitted if possible.
759  */
760 Relation
762  bool verbose, LOCKMODE lmode)
763 {
764  Relation rel;
765  bool rel_lock = true;
766  int elevel;
767 
769 
770  /*
771  * Open the relation and get the appropriate lock on it.
772  *
773  * There's a race condition here: the relation may have gone away since
774  * the last time we saw it. If so, we don't need to vacuum or analyze it.
775  *
776  * If we've been asked not to wait for the relation lock, acquire it first
777  * in non-blocking mode, before calling try_relation_open().
778  */
779  if (!(options & VACOPT_SKIP_LOCKED))
780  rel = try_relation_open(relid, lmode);
781  else if (ConditionalLockRelationOid(relid, lmode))
782  rel = try_relation_open(relid, NoLock);
783  else
784  {
785  rel = NULL;
786  rel_lock = false;
787  }
788 
789  /* if relation is opened, leave */
790  if (rel)
791  return rel;
792 
793  /*
794  * Relation could not be opened, hence generate if possible a log
795  * informing on the situation.
796  *
797  * If the RangeVar is not defined, we do not have enough information to
798  * provide a meaningful log statement. Chances are that the caller has
799  * intentionally not provided this information so that this logging is
800  * skipped, anyway.
801  */
802  if (relation == NULL)
803  return NULL;
804 
805  /*
806  * Determine the log level.
807  *
808  * For manual VACUUM or ANALYZE, we emit a WARNING to match the log
809  * statements in the permission checks; otherwise, only log if the caller
810  * so requested.
811  */
813  elevel = WARNING;
814  else if (verbose)
815  elevel = LOG;
816  else
817  return NULL;
818 
819  if ((options & VACOPT_VACUUM) != 0)
820  {
821  if (!rel_lock)
822  ereport(elevel,
823  (errcode(ERRCODE_LOCK_NOT_AVAILABLE),
824  errmsg("skipping vacuum of \"%s\" --- lock not available",
825  relation->relname)));
826  else
827  ereport(elevel,
829  errmsg("skipping vacuum of \"%s\" --- relation no longer exists",
830  relation->relname)));
831 
832  /*
833  * For VACUUM ANALYZE, both logs could show up, but just generate
834  * information for VACUUM as that would be the first one to be
835  * processed.
836  */
837  return NULL;
838  }
839 
840  if ((options & VACOPT_ANALYZE) != 0)
841  {
842  if (!rel_lock)
843  ereport(elevel,
844  (errcode(ERRCODE_LOCK_NOT_AVAILABLE),
845  errmsg("skipping analyze of \"%s\" --- lock not available",
846  relation->relname)));
847  else
848  ereport(elevel,
850  errmsg("skipping analyze of \"%s\" --- relation no longer exists",
851  relation->relname)));
852  }
853 
854  return NULL;
855 }
856 
857 
858 /*
859  * Given a VacuumRelation, fill in the table OID if it wasn't specified,
860  * and optionally add VacuumRelations for partitions of the table.
861  *
862  * If a VacuumRelation does not have an OID supplied and is a partitioned
863  * table, an extra entry will be added to the output for each partition.
864  * Presently, only autovacuum supplies OIDs when calling vacuum(), and
865  * it does not want us to expand partitioned tables.
866  *
867  * We take care not to modify the input data structure, but instead build
868  * new VacuumRelation(s) to return. (But note that they will reference
869  * unmodified parts of the input, eg column lists.) New data structures
870  * are made in vac_context.
871  */
872 static List *
874  int options)
875 {
876  List *vacrels = NIL;
877  MemoryContext oldcontext;
878 
879  /* If caller supplied OID, there's nothing we need do here. */
880  if (OidIsValid(vrel->oid))
881  {
882  oldcontext = MemoryContextSwitchTo(vac_context);
883  vacrels = lappend(vacrels, vrel);
884  MemoryContextSwitchTo(oldcontext);
885  }
886  else
887  {
888  /* Process a specific relation, and possibly partitions thereof */
889  Oid relid;
890  HeapTuple tuple;
891  Form_pg_class classForm;
892  bool include_parts;
893  int rvr_opts;
894 
895  /*
896  * Since autovacuum workers supply OIDs when calling vacuum(), no
897  * autovacuum worker should reach this code.
898  */
900 
901  /*
902  * We transiently take AccessShareLock to protect the syscache lookup
903  * below, as well as find_all_inheritors's expectation that the caller
904  * holds some lock on the starting relation.
905  */
906  rvr_opts = (options & VACOPT_SKIP_LOCKED) ? RVR_SKIP_LOCKED : 0;
907  relid = RangeVarGetRelidExtended(vrel->relation,
909  rvr_opts,
910  NULL, NULL);
911 
912  /*
913  * If the lock is unavailable, emit the same log statement that
914  * vacuum_rel() and analyze_rel() would.
915  */
916  if (!OidIsValid(relid))
917  {
918  if (options & VACOPT_VACUUM)
920  (errcode(ERRCODE_LOCK_NOT_AVAILABLE),
921  errmsg("skipping vacuum of \"%s\" --- lock not available",
922  vrel->relation->relname)));
923  else
925  (errcode(ERRCODE_LOCK_NOT_AVAILABLE),
926  errmsg("skipping analyze of \"%s\" --- lock not available",
927  vrel->relation->relname)));
928  return vacrels;
929  }
930 
931  /*
932  * To check whether the relation is a partitioned table and its
933  * ownership, fetch its syscache entry.
934  */
935  tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
936  if (!HeapTupleIsValid(tuple))
937  elog(ERROR, "cache lookup failed for relation %u", relid);
938  classForm = (Form_pg_class) GETSTRUCT(tuple);
939 
940  /*
941  * Make a returnable VacuumRelation for this rel if user is a proper
942  * owner.
943  */
944  if (vacuum_is_relation_owner(relid, classForm, options))
945  {
946  oldcontext = MemoryContextSwitchTo(vac_context);
947  vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation,
948  relid,
949  vrel->va_cols));
950  MemoryContextSwitchTo(oldcontext);
951  }
952 
953 
954  include_parts = (classForm->relkind == RELKIND_PARTITIONED_TABLE);
955  ReleaseSysCache(tuple);
956 
957  /*
958  * If it is, make relation list entries for its partitions. Note that
959  * the list returned by find_all_inheritors() includes the passed-in
960  * OID, so we have to skip that. There's no point in taking locks on
961  * the individual partitions yet, and doing so would just add
962  * unnecessary deadlock risk. For this last reason we do not check
963  * yet the ownership of the partitions, which get added to the list to
964  * process. Ownership will be checked later on anyway.
965  */
966  if (include_parts)
967  {
968  List *part_oids = find_all_inheritors(relid, NoLock, NULL);
969  ListCell *part_lc;
970 
971  foreach(part_lc, part_oids)
972  {
973  Oid part_oid = lfirst_oid(part_lc);
974 
975  if (part_oid == relid)
976  continue; /* ignore original table */
977 
978  /*
979  * We omit a RangeVar since it wouldn't be appropriate to
980  * complain about failure to open one of these relations
981  * later.
982  */
983  oldcontext = MemoryContextSwitchTo(vac_context);
984  vacrels = lappend(vacrels, makeVacuumRelation(NULL,
985  part_oid,
986  vrel->va_cols));
987  MemoryContextSwitchTo(oldcontext);
988  }
989  }
990 
991  /*
992  * Release lock again. This means that by the time we actually try to
993  * process the table, it might be gone or renamed. In the former case
994  * we'll silently ignore it; in the latter case we'll process it
995  * anyway, but we must beware that the RangeVar doesn't necessarily
996  * identify it anymore. This isn't ideal, perhaps, but there's little
997  * practical alternative, since we're typically going to commit this
998  * transaction and begin a new one between now and then. Moreover,
999  * holding locks on multiple relations would create significant risk
1000  * of deadlock.
1001  */
1003  }
1004 
1005  return vacrels;
1006 }
1007 
1008 /*
1009  * Construct a list of VacuumRelations for all vacuumable rels in
1010  * the current database. The list is built in vac_context.
1011  */
1012 static List *
1014 {
1015  List *vacrels = NIL;
1016  Relation pgclass;
1017  TableScanDesc scan;
1018  HeapTuple tuple;
1019 
1020  pgclass = table_open(RelationRelationId, AccessShareLock);
1021 
1022  scan = table_beginscan_catalog(pgclass, 0, NULL);
1023 
1024  while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
1025  {
1026  Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple);
1027  MemoryContext oldcontext;
1028  Oid relid = classForm->oid;
1029 
1030  /*
1031  * We include partitioned tables here; depending on which operation is
1032  * to be performed, caller will decide whether to process or ignore
1033  * them.
1034  */
1035  if (classForm->relkind != RELKIND_RELATION &&
1036  classForm->relkind != RELKIND_MATVIEW &&
1037  classForm->relkind != RELKIND_PARTITIONED_TABLE)
1038  continue;
1039 
1040  /* check permissions of relation */
1041  if (!vacuum_is_relation_owner(relid, classForm, options))
1042  continue;
1043 
1044  /*
1045  * Build VacuumRelation(s) specifying the table OIDs to be processed.
1046  * We omit a RangeVar since it wouldn't be appropriate to complain
1047  * about failure to open one of these relations later.
1048  */
1049  oldcontext = MemoryContextSwitchTo(vac_context);
1050  vacrels = lappend(vacrels, makeVacuumRelation(NULL,
1051  relid,
1052  NIL));
1053  MemoryContextSwitchTo(oldcontext);
1054  }
1055 
1056  table_endscan(scan);
1057  table_close(pgclass, AccessShareLock);
1058 
1059  return vacrels;
1060 }
1061 
1062 /*
1063  * vacuum_get_cutoffs() -- compute OldestXmin and freeze cutoff points
1064  *
1065  * The target relation and VACUUM parameters are our inputs.
1066  *
1067  * Output parameters are the cutoffs that VACUUM caller should use.
1068  *
1069  * Return value indicates if vacuumlazy.c caller should make its VACUUM
1070  * operation aggressive. An aggressive VACUUM must advance relfrozenxid up to
1071  * FreezeLimit (at a minimum), and relminmxid up to MultiXactCutoff (at a
1072  * minimum).
1073  */
1074 bool
1076  struct VacuumCutoffs *cutoffs)
1077 {
1078  int freeze_min_age,
1079  multixact_freeze_min_age,
1080  freeze_table_age,
1081  multixact_freeze_table_age,
1082  effective_multixact_freeze_max_age;
1083  TransactionId nextXID,
1084  safeOldestXmin,
1085  aggressiveXIDCutoff;
1086  MultiXactId nextMXID,
1087  safeOldestMxact,
1088  aggressiveMXIDCutoff;
1089 
1090  /* Use mutable copies of freeze age parameters */
1091  freeze_min_age = params->freeze_min_age;
1092  multixact_freeze_min_age = params->multixact_freeze_min_age;
1093  freeze_table_age = params->freeze_table_age;
1094  multixact_freeze_table_age = params->multixact_freeze_table_age;
1095 
1096  /* Set pg_class fields in cutoffs */
1097  cutoffs->relfrozenxid = rel->rd_rel->relfrozenxid;
1098  cutoffs->relminmxid = rel->rd_rel->relminmxid;
1099 
1100  /*
1101  * Acquire OldestXmin.
1102  *
1103  * We can always ignore processes running lazy vacuum. This is because we
1104  * use these values only for deciding which tuples we must keep in the
1105  * tables. Since lazy vacuum doesn't write its XID anywhere (usually no
1106  * XID assigned), it's safe to ignore it. In theory it could be
1107  * problematic to ignore lazy vacuums in a full vacuum, but keep in mind
1108  * that only one vacuum process can be working on a particular table at
1109  * any time, and that each vacuum is always an independent transaction.
1110  */
1112 
1114 
1115  /* Acquire OldestMxact */
1116  cutoffs->OldestMxact = GetOldestMultiXactId();
1118 
1119  /* Acquire next XID/next MXID values used to apply age-based settings */
1120  nextXID = ReadNextTransactionId();
1121  nextMXID = ReadNextMultiXactId();
1122 
1123  /*
1124  * Also compute the multixact age for which freezing is urgent. This is
1125  * normally autovacuum_multixact_freeze_max_age, but may be less if we are
1126  * short of multixact member space.
1127  */
1128  effective_multixact_freeze_max_age = MultiXactMemberFreezeThreshold();
1129 
1130  /*
1131  * Almost ready to set freeze output parameters; check if OldestXmin or
1132  * OldestMxact are held back to an unsafe degree before we start on that
1133  */
1134  safeOldestXmin = nextXID - autovacuum_freeze_max_age;
1135  if (!TransactionIdIsNormal(safeOldestXmin))
1136  safeOldestXmin = FirstNormalTransactionId;
1137  safeOldestMxact = nextMXID - effective_multixact_freeze_max_age;
1138  if (safeOldestMxact < FirstMultiXactId)
1139  safeOldestMxact = FirstMultiXactId;
1140  if (TransactionIdPrecedes(cutoffs->OldestXmin, safeOldestXmin))
1141  ereport(WARNING,
1142  (errmsg("cutoff for removing and freezing tuples is far in the past"),
1143  errhint("Close open transactions soon to avoid wraparound problems.\n"
1144  "You might also need to commit or roll back old prepared transactions, or drop stale replication slots.")));
1145  if (MultiXactIdPrecedes(cutoffs->OldestMxact, safeOldestMxact))
1146  ereport(WARNING,
1147  (errmsg("cutoff for freezing multixacts is far in the past"),
1148  errhint("Close open transactions soon to avoid wraparound problems.\n"
1149  "You might also need to commit or roll back old prepared transactions, or drop stale replication slots.")));
1150 
1151  /*
1152  * Determine the minimum freeze age to use: as specified by the caller, or
1153  * vacuum_freeze_min_age, but in any case not more than half
1154  * autovacuum_freeze_max_age, so that autovacuums to prevent XID
1155  * wraparound won't occur too frequently.
1156  */
1157  if (freeze_min_age < 0)
1158  freeze_min_age = vacuum_freeze_min_age;
1159  freeze_min_age = Min(freeze_min_age, autovacuum_freeze_max_age / 2);
1160  Assert(freeze_min_age >= 0);
1161 
1162  /* Compute FreezeLimit, being careful to generate a normal XID */
1163  cutoffs->FreezeLimit = nextXID - freeze_min_age;
1164  if (!TransactionIdIsNormal(cutoffs->FreezeLimit))
1166  /* FreezeLimit must always be <= OldestXmin */
1167  if (TransactionIdPrecedes(cutoffs->OldestXmin, cutoffs->FreezeLimit))
1168  cutoffs->FreezeLimit = cutoffs->OldestXmin;
1169 
1170  /*
1171  * Determine the minimum multixact freeze age to use: as specified by
1172  * caller, or vacuum_multixact_freeze_min_age, but in any case not more
1173  * than half effective_multixact_freeze_max_age, so that autovacuums to
1174  * prevent MultiXact wraparound won't occur too frequently.
1175  */
1176  if (multixact_freeze_min_age < 0)
1177  multixact_freeze_min_age = vacuum_multixact_freeze_min_age;
1178  multixact_freeze_min_age = Min(multixact_freeze_min_age,
1179  effective_multixact_freeze_max_age / 2);
1180  Assert(multixact_freeze_min_age >= 0);
1181 
1182  /* Compute MultiXactCutoff, being careful to generate a valid value */
1183  cutoffs->MultiXactCutoff = nextMXID - multixact_freeze_min_age;
1184  if (cutoffs->MultiXactCutoff < FirstMultiXactId)
1185  cutoffs->MultiXactCutoff = FirstMultiXactId;
1186  /* MultiXactCutoff must always be <= OldestMxact */
1187  if (MultiXactIdPrecedes(cutoffs->OldestMxact, cutoffs->MultiXactCutoff))
1188  cutoffs->MultiXactCutoff = cutoffs->OldestMxact;
1189 
1190  /*
1191  * Finally, figure out if caller needs to do an aggressive VACUUM or not.
1192  *
1193  * Determine the table freeze age to use: as specified by the caller, or
1194  * the value of the vacuum_freeze_table_age GUC, but in any case not more
1195  * than autovacuum_freeze_max_age * 0.95, so that if you have e.g nightly
1196  * VACUUM schedule, the nightly VACUUM gets a chance to freeze XIDs before
1197  * anti-wraparound autovacuum is launched.
1198  */
1199  if (freeze_table_age < 0)
1200  freeze_table_age = vacuum_freeze_table_age;
1201  freeze_table_age = Min(freeze_table_age, autovacuum_freeze_max_age * 0.95);
1202  Assert(freeze_table_age >= 0);
1203  aggressiveXIDCutoff = nextXID - freeze_table_age;
1204  if (!TransactionIdIsNormal(aggressiveXIDCutoff))
1205  aggressiveXIDCutoff = FirstNormalTransactionId;
1206  if (TransactionIdPrecedesOrEquals(rel->rd_rel->relfrozenxid,
1207  aggressiveXIDCutoff))
1208  return true;
1209 
1210  /*
1211  * Similar to the above, determine the table freeze age to use for
1212  * multixacts: as specified by the caller, or the value of the
1213  * vacuum_multixact_freeze_table_age GUC, but in any case not more than
1214  * effective_multixact_freeze_max_age * 0.95, so that if you have e.g.
1215  * nightly VACUUM schedule, the nightly VACUUM gets a chance to freeze
1216  * multixacts before anti-wraparound autovacuum is launched.
1217  */
1218  if (multixact_freeze_table_age < 0)
1219  multixact_freeze_table_age = vacuum_multixact_freeze_table_age;
1220  multixact_freeze_table_age =
1221  Min(multixact_freeze_table_age,
1222  effective_multixact_freeze_max_age * 0.95);
1223  Assert(multixact_freeze_table_age >= 0);
1224  aggressiveMXIDCutoff = nextMXID - multixact_freeze_table_age;
1225  if (aggressiveMXIDCutoff < FirstMultiXactId)
1226  aggressiveMXIDCutoff = FirstMultiXactId;
1227  if (MultiXactIdPrecedesOrEquals(rel->rd_rel->relminmxid,
1228  aggressiveMXIDCutoff))
1229  return true;
1230 
1231  /* Non-aggressive VACUUM */
1232  return false;
1233 }
1234 
1235 /*
1236  * vacuum_xid_failsafe_check() -- Used by VACUUM's wraparound failsafe
1237  * mechanism to determine if its table's relfrozenxid and relminmxid are now
1238  * dangerously far in the past.
1239  *
1240  * When we return true, VACUUM caller triggers the failsafe.
1241  */
1242 bool
1244 {
1245  TransactionId relfrozenxid = cutoffs->relfrozenxid;
1246  MultiXactId relminmxid = cutoffs->relminmxid;
1247  TransactionId xid_skip_limit;
1248  MultiXactId multi_skip_limit;
1249  int skip_index_vacuum;
1250 
1251  Assert(TransactionIdIsNormal(relfrozenxid));
1252  Assert(MultiXactIdIsValid(relminmxid));
1253 
1254  /*
1255  * Determine the index skipping age to use. In any case no less than
1256  * autovacuum_freeze_max_age * 1.05.
1257  */
1258  skip_index_vacuum = Max(vacuum_failsafe_age, autovacuum_freeze_max_age * 1.05);
1259 
1260  xid_skip_limit = ReadNextTransactionId() - skip_index_vacuum;
1261  if (!TransactionIdIsNormal(xid_skip_limit))
1262  xid_skip_limit = FirstNormalTransactionId;
1263 
1264  if (TransactionIdPrecedes(relfrozenxid, xid_skip_limit))
1265  {
1266  /* The table's relfrozenxid is too old */
1267  return true;
1268  }
1269 
1270  /*
1271  * Similar to above, determine the index skipping age to use for
1272  * multixact. In any case no less than autovacuum_multixact_freeze_max_age *
1273  * 1.05.
1274  */
1275  skip_index_vacuum = Max(vacuum_multixact_failsafe_age,
1277 
1278  multi_skip_limit = ReadNextMultiXactId() - skip_index_vacuum;
1279  if (multi_skip_limit < FirstMultiXactId)
1280  multi_skip_limit = FirstMultiXactId;
1281 
1282  if (MultiXactIdPrecedes(relminmxid, multi_skip_limit))
1283  {
1284  /* The table's relminmxid is too old */
1285  return true;
1286  }
1287 
1288  return false;
1289 }
1290 
1291 /*
1292  * vac_estimate_reltuples() -- estimate the new value for pg_class.reltuples
1293  *
1294  * If we scanned the whole relation then we should just use the count of
1295  * live tuples seen; but if we did not, we should not blindly extrapolate
1296  * from that number, since VACUUM may have scanned a quite nonrandom
1297  * subset of the table. When we have only partial information, we take
1298  * the old value of pg_class.reltuples/pg_class.relpages as a measurement
1299  * of the tuple density in the unscanned pages.
1300  *
1301  * Note: scanned_tuples should count only *live* tuples, since
1302  * pg_class.reltuples is defined that way.
1303  */
1304 double
1306  BlockNumber total_pages,
1307  BlockNumber scanned_pages,
1308  double scanned_tuples)
1309 {
1310  BlockNumber old_rel_pages = relation->rd_rel->relpages;
1311  double old_rel_tuples = relation->rd_rel->reltuples;
1312  double old_density;
1313  double unscanned_pages;
1314  double total_tuples;
1315 
1316  /* If we did scan the whole table, just use the count as-is */
1317  if (scanned_pages >= total_pages)
1318  return scanned_tuples;
1319 
1320  /*
1321  * When successive VACUUM commands scan the same few pages again and
1322  * again, without anything from the table really changing, there is a risk
1323  * that our beliefs about tuple density will gradually become distorted.
1324  * This might be caused by vacuumlazy.c implementation details, such as
1325  * its tendency to always scan the last heap page. Handle that here.
1326  *
1327  * If the relation is _exactly_ the same size according to the existing
1328  * pg_class entry, and only a few of its pages (less than 2%) were
1329  * scanned, keep the existing value of reltuples. Also keep the existing
1330  * value when only a subset of rel's pages <= a single page were scanned.
1331  *
1332  * (Note: we might be returning -1 here.)
1333  */
1334  if (old_rel_pages == total_pages &&
1335  scanned_pages < (double) total_pages * 0.02)
1336  return old_rel_tuples;
1337  if (scanned_pages <= 1)
1338  return old_rel_tuples;
1339 
1340  /*
1341  * If old density is unknown, we can't do much except scale up
1342  * scanned_tuples to match total_pages.
1343  */
1344  if (old_rel_tuples < 0 || old_rel_pages == 0)
1345  return floor((scanned_tuples / scanned_pages) * total_pages + 0.5);
1346 
1347  /*
1348  * Okay, we've covered the corner cases. The normal calculation is to
1349  * convert the old measurement to a density (tuples per page), then
1350  * estimate the number of tuples in the unscanned pages using that figure,
1351  * and finally add on the number of tuples in the scanned pages.
1352  */
1353  old_density = old_rel_tuples / old_rel_pages;
1354  unscanned_pages = (double) total_pages - (double) scanned_pages;
1355  total_tuples = old_density * unscanned_pages + scanned_tuples;
1356  return floor(total_tuples + 0.5);
1357 }
1358 
1359 
1360 /*
1361  * vac_update_relstats() -- update statistics for one relation
1362  *
1363  * Update the whole-relation statistics that are kept in its pg_class
1364  * row. There are additional stats that will be updated if we are
1365  * doing ANALYZE, but we always update these stats. This routine works
1366  * for both index and heap relation entries in pg_class.
1367  *
1368  * We violate transaction semantics here by overwriting the rel's
1369  * existing pg_class tuple with the new values. This is reasonably
1370  * safe as long as we're sure that the new values are correct whether or
1371  * not this transaction commits. The reason for doing this is that if
1372  * we updated these tuples in the usual way, vacuuming pg_class itself
1373  * wouldn't work very well --- by the time we got done with a vacuum
1374  * cycle, most of the tuples in pg_class would've been obsoleted. Of
1375  * course, this only works for fixed-size not-null columns, but these are.
1376  *
1377  * Another reason for doing it this way is that when we are in a lazy
1378  * VACUUM and have PROC_IN_VACUUM set, we mustn't do any regular updates.
1379  * Somebody vacuuming pg_class might think they could delete a tuple
1380  * marked with xmin = our xid.
1381  *
1382  * In addition to fundamentally nontransactional statistics such as
1383  * relpages and relallvisible, we try to maintain certain lazily-updated
1384  * DDL flags such as relhasindex, by clearing them if no longer correct.
1385  * It's safe to do this in VACUUM, which can't run in parallel with
1386  * CREATE INDEX/RULE/TRIGGER and can't be part of a transaction block.
1387  * However, it's *not* safe to do it in an ANALYZE that's within an
1388  * outer transaction, because for example the current transaction might
1389  * have dropped the last index; then we'd think relhasindex should be
1390  * cleared, but if the transaction later rolls back this would be wrong.
1391  * So we refrain from updating the DDL flags if we're inside an outer
1392  * transaction. This is OK since postponing the flag maintenance is
1393  * always allowable.
1394  *
1395  * Note: num_tuples should count only *live* tuples, since
1396  * pg_class.reltuples is defined that way.
1397  *
1398  * This routine is shared by VACUUM and ANALYZE.
1399  */
1400 void
1402  BlockNumber num_pages, double num_tuples,
1403  BlockNumber num_all_visible_pages,
1404  bool hasindex, TransactionId frozenxid,
1405  MultiXactId minmulti,
1406  bool *frozenxid_updated, bool *minmulti_updated,
1407  bool in_outer_xact)
1408 {
1409  Oid relid = RelationGetRelid(relation);
1410  Relation rd;
1411  HeapTuple ctup;
1412  Form_pg_class pgcform;
1413  bool dirty,
1414  futurexid,
1415  futuremxid;
1416  TransactionId oldfrozenxid;
1417  MultiXactId oldminmulti;
1418 
1419  rd = table_open(RelationRelationId, RowExclusiveLock);
1420 
1421  /* Fetch a copy of the tuple to scribble on */
1423  if (!HeapTupleIsValid(ctup))
1424  elog(ERROR, "pg_class entry for relid %u vanished during vacuuming",
1425  relid);
1426  pgcform = (Form_pg_class) GETSTRUCT(ctup);
1427 
1428  /* Apply statistical updates, if any, to copied tuple */
1429 
1430  dirty = false;
1431  if (pgcform->relpages != (int32) num_pages)
1432  {
1433  pgcform->relpages = (int32) num_pages;
1434  dirty = true;
1435  }
1436  if (pgcform->reltuples != (float4) num_tuples)
1437  {
1438  pgcform->reltuples = (float4) num_tuples;
1439  dirty = true;
1440  }
1441  if (pgcform->relallvisible != (int32) num_all_visible_pages)
1442  {
1443  pgcform->relallvisible = (int32) num_all_visible_pages;
1444  dirty = true;
1445  }
1446 
1447  /* Apply DDL updates, but not inside an outer transaction (see above) */
1448 
1449  if (!in_outer_xact)
1450  {
1451  /*
1452  * If we didn't find any indexes, reset relhasindex.
1453  */
1454  if (pgcform->relhasindex && !hasindex)
1455  {
1456  pgcform->relhasindex = false;
1457  dirty = true;
1458  }
1459 
1460  /* We also clear relhasrules and relhastriggers if needed */
1461  if (pgcform->relhasrules && relation->rd_rules == NULL)
1462  {
1463  pgcform->relhasrules = false;
1464  dirty = true;
1465  }
1466  if (pgcform->relhastriggers && relation->trigdesc == NULL)
1467  {
1468  pgcform->relhastriggers = false;
1469  dirty = true;
1470  }
1471  }
1472 
1473  /*
1474  * Update relfrozenxid, unless caller passed InvalidTransactionId
1475  * indicating it has no new data.
1476  *
1477  * Ordinarily, we don't let relfrozenxid go backwards. However, if the
1478  * stored relfrozenxid is "in the future" then it seems best to assume
1479  * it's corrupt, and overwrite with the oldest remaining XID in the table.
1480  * This should match vac_update_datfrozenxid() concerning what we consider
1481  * to be "in the future".
1482  */
1483  oldfrozenxid = pgcform->relfrozenxid;
1484  futurexid = false;
1485  if (frozenxid_updated)
1486  *frozenxid_updated = false;
1487  if (TransactionIdIsNormal(frozenxid) && oldfrozenxid != frozenxid)
1488  {
1489  bool update = false;
1490 
1491  if (TransactionIdPrecedes(oldfrozenxid, frozenxid))
1492  update = true;
1493  else if (TransactionIdPrecedes(ReadNextTransactionId(), oldfrozenxid))
1494  futurexid = update = true;
1495 
1496  if (update)
1497  {
1498  pgcform->relfrozenxid = frozenxid;
1499  dirty = true;
1500  if (frozenxid_updated)
1501  *frozenxid_updated = true;
1502  }
1503  }
1504 
1505  /* Similarly for relminmxid */
1506  oldminmulti = pgcform->relminmxid;
1507  futuremxid = false;
1508  if (minmulti_updated)
1509  *minmulti_updated = false;
1510  if (MultiXactIdIsValid(minmulti) && oldminmulti != minmulti)
1511  {
1512  bool update = false;
1513 
1514  if (MultiXactIdPrecedes(oldminmulti, minmulti))
1515  update = true;
1516  else if (MultiXactIdPrecedes(ReadNextMultiXactId(), oldminmulti))
1517  futuremxid = update = true;
1518 
1519  if (update)
1520  {
1521  pgcform->relminmxid = minmulti;
1522  dirty = true;
1523  if (minmulti_updated)
1524  *minmulti_updated = true;
1525  }
1526  }
1527 
1528  /* If anything changed, write out the tuple. */
1529  if (dirty)
1530  heap_inplace_update(rd, ctup);
1531 
1533 
1534  if (futurexid)
1535  ereport(WARNING,
1537  errmsg_internal("overwrote invalid relfrozenxid value %u with new value %u for table \"%s\"",
1538  oldfrozenxid, frozenxid,
1539  RelationGetRelationName(relation))));
1540  if (futuremxid)
1541  ereport(WARNING,
1543  errmsg_internal("overwrote invalid relminmxid value %u with new value %u for table \"%s\"",
1544  oldminmulti, minmulti,
1545  RelationGetRelationName(relation))));
1546 }
1547 
1548 
1549 /*
1550  * vac_update_datfrozenxid() -- update pg_database.datfrozenxid for our DB
1551  *
1552  * Update pg_database's datfrozenxid entry for our database to be the
1553  * minimum of the pg_class.relfrozenxid values.
1554  *
1555  * Similarly, update our datminmxid to be the minimum of the
1556  * pg_class.relminmxid values.
1557  *
1558  * If we are able to advance either pg_database value, also try to
1559  * truncate pg_xact and pg_multixact.
1560  *
1561  * We violate transaction semantics here by overwriting the database's
1562  * existing pg_database tuple with the new values. This is reasonably
1563  * safe since the new values are correct whether or not this transaction
1564  * commits. As with vac_update_relstats, this avoids leaving dead tuples
1565  * behind after a VACUUM.
1566  */
1567 void
1569 {
1570  HeapTuple tuple;
1571  Form_pg_database dbform;
1572  Relation relation;
1573  SysScanDesc scan;
1574  HeapTuple classTup;
1575  TransactionId newFrozenXid;
1576  MultiXactId newMinMulti;
1577  TransactionId lastSaneFrozenXid;
1578  MultiXactId lastSaneMinMulti;
1579  bool bogus = false;
1580  bool dirty = false;
1581  ScanKeyData key[1];
1582 
1583  /*
1584  * Restrict this task to one backend per database. This avoids race
1585  * conditions that would move datfrozenxid or datminmxid backward. It
1586  * avoids calling vac_truncate_clog() with a datfrozenxid preceding a
1587  * datfrozenxid passed to an earlier vac_truncate_clog() call.
1588  */
1590 
1591  /*
1592  * Initialize the "min" calculation with
1593  * GetOldestNonRemovableTransactionId(), which is a reasonable
1594  * approximation to the minimum relfrozenxid for not-yet-committed
1595  * pg_class entries for new tables; see AddNewRelationTuple(). So we
1596  * cannot produce a wrong minimum by starting with this.
1597  */
1598  newFrozenXid = GetOldestNonRemovableTransactionId(NULL);
1599 
1600  /*
1601  * Similarly, initialize the MultiXact "min" with the value that would be
1602  * used on pg_class for new tables. See AddNewRelationTuple().
1603  */
1604  newMinMulti = GetOldestMultiXactId();
1605 
1606  /*
1607  * Identify the latest relfrozenxid and relminmxid values that we could
1608  * validly see during the scan. These are conservative values, but it's
1609  * not really worth trying to be more exact.
1610  */
1611  lastSaneFrozenXid = ReadNextTransactionId();
1612  lastSaneMinMulti = ReadNextMultiXactId();
1613 
1614  /*
1615  * We must seqscan pg_class to find the minimum Xid, because there is no
1616  * index that can help us here.
1617  */
1618  relation = table_open(RelationRelationId, AccessShareLock);
1619 
1620  scan = systable_beginscan(relation, InvalidOid, false,
1621  NULL, 0, NULL);
1622 
1623  while ((classTup = systable_getnext(scan)) != NULL)
1624  {
1625  Form_pg_class classForm = (Form_pg_class) GETSTRUCT(classTup);
1626 
1627  /*
1628  * Only consider relations able to hold unfrozen XIDs (anything else
1629  * should have InvalidTransactionId in relfrozenxid anyway).
1630  */
1631  if (classForm->relkind != RELKIND_RELATION &&
1632  classForm->relkind != RELKIND_MATVIEW &&
1633  classForm->relkind != RELKIND_TOASTVALUE)
1634  {
1635  Assert(!TransactionIdIsValid(classForm->relfrozenxid));
1636  Assert(!MultiXactIdIsValid(classForm->relminmxid));
1637  continue;
1638  }
1639 
1640  /*
1641  * Some table AMs might not need per-relation xid / multixid horizons.
1642  * It therefore seems reasonable to allow relfrozenxid and relminmxid
1643  * to not be set (i.e. set to their respective Invalid*Id)
1644  * independently. Thus validate and compute horizon for each only if
1645  * set.
1646  *
1647  * If things are working properly, no relation should have a
1648  * relfrozenxid or relminmxid that is "in the future". However, such
1649  * cases have been known to arise due to bugs in pg_upgrade. If we
1650  * see any entries that are "in the future", chicken out and don't do
1651  * anything. This ensures we won't truncate clog & multixact SLRUs
1652  * before those relations have been scanned and cleaned up.
1653  */
1654 
1655  if (TransactionIdIsValid(classForm->relfrozenxid))
1656  {
1657  Assert(TransactionIdIsNormal(classForm->relfrozenxid));
1658 
1659  /* check for values in the future */
1660  if (TransactionIdPrecedes(lastSaneFrozenXid, classForm->relfrozenxid))
1661  {
1662  bogus = true;
1663  break;
1664  }
1665 
1666  /* determine new horizon */
1667  if (TransactionIdPrecedes(classForm->relfrozenxid, newFrozenXid))
1668  newFrozenXid = classForm->relfrozenxid;
1669  }
1670 
1671  if (MultiXactIdIsValid(classForm->relminmxid))
1672  {
1673  /* check for values in the future */
1674  if (MultiXactIdPrecedes(lastSaneMinMulti, classForm->relminmxid))
1675  {
1676  bogus = true;
1677  break;
1678  }
1679 
1680  /* determine new horizon */
1681  if (MultiXactIdPrecedes(classForm->relminmxid, newMinMulti))
1682  newMinMulti = classForm->relminmxid;
1683  }
1684  }
1685 
1686  /* we're done with pg_class */
1687  systable_endscan(scan);
1688  table_close(relation, AccessShareLock);
1689 
1690  /* chicken out if bogus data found */
1691  if (bogus)
1692  return;
1693 
1694  Assert(TransactionIdIsNormal(newFrozenXid));
1695  Assert(MultiXactIdIsValid(newMinMulti));
1696 
1697  /* Now fetch the pg_database tuple we need to update. */
1698  relation = table_open(DatabaseRelationId, RowExclusiveLock);
1699 
1700  /*
1701  * Get the pg_database tuple to scribble on. Note that this does not
1702  * directly rely on the syscache to avoid issues with flattened toast
1703  * values for the in-place update.
1704  */
1705  ScanKeyInit(&key[0],
1706  Anum_pg_database_oid,
1707  BTEqualStrategyNumber, F_OIDEQ,
1709 
1710  scan = systable_beginscan(relation, DatabaseOidIndexId, true,
1711  NULL, 1, key);
1712  tuple = systable_getnext(scan);
1713  tuple = heap_copytuple(tuple);
1714  systable_endscan(scan);
1715 
1716  if (!HeapTupleIsValid(tuple))
1717  elog(ERROR, "could not find tuple for database %u", MyDatabaseId);
1718 
1719  dbform = (Form_pg_database) GETSTRUCT(tuple);
1720 
1721  /*
1722  * As in vac_update_relstats(), we ordinarily don't want to let
1723  * datfrozenxid go backward; but if it's "in the future" then it must be
1724  * corrupt and it seems best to overwrite it.
1725  */
1726  if (dbform->datfrozenxid != newFrozenXid &&
1727  (TransactionIdPrecedes(dbform->datfrozenxid, newFrozenXid) ||
1728  TransactionIdPrecedes(lastSaneFrozenXid, dbform->datfrozenxid)))
1729  {
1730  dbform->datfrozenxid = newFrozenXid;
1731  dirty = true;
1732  }
1733  else
1734  newFrozenXid = dbform->datfrozenxid;
1735 
1736  /* Ditto for datminmxid */
1737  if (dbform->datminmxid != newMinMulti &&
1738  (MultiXactIdPrecedes(dbform->datminmxid, newMinMulti) ||
1739  MultiXactIdPrecedes(lastSaneMinMulti, dbform->datminmxid)))
1740  {
1741  dbform->datminmxid = newMinMulti;
1742  dirty = true;
1743  }
1744  else
1745  newMinMulti = dbform->datminmxid;
1746 
1747  if (dirty)
1748  heap_inplace_update(relation, tuple);
1749 
1750  heap_freetuple(tuple);
1751  table_close(relation, RowExclusiveLock);
1752 
1753  /*
1754  * If we were able to advance datfrozenxid or datminmxid, see if we can
1755  * truncate pg_xact and/or pg_multixact. Also do it if the shared
1756  * XID-wrap-limit info is stale, since this action will update that too.
1757  */
1758  if (dirty || ForceTransactionIdLimitUpdate())
1759  vac_truncate_clog(newFrozenXid, newMinMulti,
1760  lastSaneFrozenXid, lastSaneMinMulti);
1761 }
1762 
1763 
1764 /*
1765  * vac_truncate_clog() -- attempt to truncate the commit log
1766  *
1767  * Scan pg_database to determine the system-wide oldest datfrozenxid,
1768  * and use it to truncate the transaction commit log (pg_xact).
1769  * Also update the XID wrap limit info maintained by varsup.c.
1770  * Likewise for datminmxid.
1771  *
1772  * The passed frozenXID and minMulti are the updated values for my own
1773  * pg_database entry. They're used to initialize the "min" calculations.
1774  * The caller also passes the "last sane" XID and MXID, since it has
1775  * those at hand already.
1776  *
1777  * This routine is only invoked when we've managed to change our
1778  * DB's datfrozenxid/datminmxid values, or we found that the shared
1779  * XID-wrap-limit info is stale.
1780  */
1781 static void
1783  MultiXactId minMulti,
1784  TransactionId lastSaneFrozenXid,
1785  MultiXactId lastSaneMinMulti)
1786 {
1788  Relation relation;
1789  TableScanDesc scan;
1790  HeapTuple tuple;
1791  Oid oldestxid_datoid;
1792  Oid minmulti_datoid;
1793  bool bogus = false;
1794  bool frozenAlreadyWrapped = false;
1795 
1796  /* Restrict task to one backend per cluster; see SimpleLruTruncate(). */
1797  LWLockAcquire(WrapLimitsVacuumLock, LW_EXCLUSIVE);
1798 
1799  /* init oldest datoids to sync with my frozenXID/minMulti values */
1800  oldestxid_datoid = MyDatabaseId;
1801  minmulti_datoid = MyDatabaseId;
1802 
1803  /*
1804  * Scan pg_database to compute the minimum datfrozenxid/datminmxid
1805  *
1806  * Since vac_update_datfrozenxid updates datfrozenxid/datminmxid in-place,
1807  * the values could change while we look at them. Fetch each one just
1808  * once to ensure sane behavior of the comparison logic. (Here, as in
1809  * many other places, we assume that fetching or updating an XID in shared
1810  * storage is atomic.)
1811  *
1812  * Note: we need not worry about a race condition with new entries being
1813  * inserted by CREATE DATABASE. Any such entry will have a copy of some
1814  * existing DB's datfrozenxid, and that source DB cannot be ours because
1815  * of the interlock against copying a DB containing an active backend.
1816  * Hence the new entry will not reduce the minimum. Also, if two VACUUMs
1817  * concurrently modify the datfrozenxid's of different databases, the
1818  * worst possible outcome is that pg_xact is not truncated as aggressively
1819  * as it could be.
1820  */
1821  relation = table_open(DatabaseRelationId, AccessShareLock);
1822 
1823  scan = table_beginscan_catalog(relation, 0, NULL);
1824 
1825  while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
1826  {
1827  volatile FormData_pg_database *dbform = (Form_pg_database) GETSTRUCT(tuple);
1828  TransactionId datfrozenxid = dbform->datfrozenxid;
1829  TransactionId datminmxid = dbform->datminmxid;
1830 
1833 
1834  /*
1835  * If database is in the process of getting dropped, or has been
1836  * interrupted while doing so, no connections to it are possible
1837  * anymore. Therefore we don't need to take it into account here.
1838  * Which is good, because it can't be processed by autovacuum either.
1839  */
1841  {
1842  elog(DEBUG2,
1843  "skipping invalid database \"%s\" while computing relfrozenxid",
1844  NameStr(dbform->datname));
1845  continue;
1846  }
1847 
1848  /*
1849  * If things are working properly, no database should have a
1850  * datfrozenxid or datminmxid that is "in the future". However, such
1851  * cases have been known to arise due to bugs in pg_upgrade. If we
1852  * see any entries that are "in the future", chicken out and don't do
1853  * anything. This ensures we won't truncate clog before those
1854  * databases have been scanned and cleaned up. (We will issue the
1855  * "already wrapped" warning if appropriate, though.)
1856  */
1857  if (TransactionIdPrecedes(lastSaneFrozenXid, datfrozenxid) ||
1858  MultiXactIdPrecedes(lastSaneMinMulti, datminmxid))
1859  bogus = true;
1860 
1861  if (TransactionIdPrecedes(nextXID, datfrozenxid))
1862  frozenAlreadyWrapped = true;
1863  else if (TransactionIdPrecedes(datfrozenxid, frozenXID))
1864  {
1865  frozenXID = datfrozenxid;
1866  oldestxid_datoid = dbform->oid;
1867  }
1868 
1869  if (MultiXactIdPrecedes(datminmxid, minMulti))
1870  {
1871  minMulti = datminmxid;
1872  minmulti_datoid = dbform->oid;
1873  }
1874  }
1875 
1876  table_endscan(scan);
1877 
1878  table_close(relation, AccessShareLock);
1879 
1880  /*
1881  * Do not truncate CLOG if we seem to have suffered wraparound already;
1882  * the computed minimum XID might be bogus. This case should now be
1883  * impossible due to the defenses in GetNewTransactionId, but we keep the
1884  * test anyway.
1885  */
1886  if (frozenAlreadyWrapped)
1887  {
1888  ereport(WARNING,
1889  (errmsg("some databases have not been vacuumed in over 2 billion transactions"),
1890  errdetail("You might have already suffered transaction-wraparound data loss.")));
1891  LWLockRelease(WrapLimitsVacuumLock);
1892  return;
1893  }
1894 
1895  /* chicken out if data is bogus in any other way */
1896  if (bogus)
1897  {
1898  LWLockRelease(WrapLimitsVacuumLock);
1899  return;
1900  }
1901 
1902  /*
1903  * Advance the oldest value for commit timestamps before truncating, so
1904  * that if a user requests a timestamp for a transaction we're truncating
1905  * away right after this point, they get NULL instead of an ugly "file not
1906  * found" error from slru.c. This doesn't matter for xact/multixact
1907  * because they are not subject to arbitrary lookups from users.
1908  */
1909  AdvanceOldestCommitTsXid(frozenXID);
1910 
1911  /*
1912  * Truncate CLOG, multixact and CommitTs to the oldest computed value.
1913  */
1914  TruncateCLOG(frozenXID, oldestxid_datoid);
1915  TruncateCommitTs(frozenXID);
1916  TruncateMultiXact(minMulti, minmulti_datoid);
1917 
1918  /*
1919  * Update the wrap limit for GetNewTransactionId and creation of new
1920  * MultiXactIds. Note: these functions will also signal the postmaster
1921  * for an(other) autovac cycle if needed. XXX should we avoid possibly
1922  * signaling twice?
1923  */
1924  SetTransactionIdLimit(frozenXID, oldestxid_datoid);
1925  SetMultiXactIdLimit(minMulti, minmulti_datoid, false);
1926 
1927  LWLockRelease(WrapLimitsVacuumLock);
1928 }
1929 
1930 
1931 /*
1932  * vacuum_rel() -- vacuum one heap relation
1933  *
1934  * relid identifies the relation to vacuum. If relation is supplied,
1935  * use the name therein for reporting any failure to open/lock the rel;
1936  * do not use it once we've successfully opened the rel, since it might
1937  * be stale.
1938  *
1939  * Returns true if it's okay to proceed with a requested ANALYZE
1940  * operation on this table.
1941  *
1942  * Doing one heap at a time incurs extra overhead, since we need to
1943  * check that the heap exists again just before we vacuum it. The
1944  * reason that we do this is so that vacuuming can be spread across
1945  * many small transactions. Otherwise, two-phase locking would require
1946  * us to lock the entire database during one pass of the vacuum cleaner.
1947  *
1948  * At entry and exit, we are not inside a transaction.
1949  */
1950 static bool
1951 vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
1952  BufferAccessStrategy bstrategy)
1953 {
1954  LOCKMODE lmode;
1955  Relation rel;
1956  LockRelId lockrelid;
1957  Oid toast_relid;
1958  Oid save_userid;
1959  int save_sec_context;
1960  int save_nestlevel;
1961 
1962  Assert(params != NULL);
1963 
1964  /* Begin a transaction for vacuuming this relation */
1966 
1967  if (!(params->options & VACOPT_FULL))
1968  {
1969  /*
1970  * In lazy vacuum, we can set the PROC_IN_VACUUM flag, which lets
1971  * other concurrent VACUUMs know that they can ignore this one while
1972  * determining their OldestXmin. (The reason we don't set it during a
1973  * full VACUUM is exactly that we may have to run user-defined
1974  * functions for functional indexes, and we want to make sure that if
1975  * they use the snapshot set above, any tuples it requires can't get
1976  * removed from other tables. An index function that depends on the
1977  * contents of other tables is arguably broken, but we won't break it
1978  * here by violating transaction semantics.)
1979  *
1980  * We also set the VACUUM_FOR_WRAPAROUND flag, which is passed down by
1981  * autovacuum; it's used to avoid canceling a vacuum that was invoked
1982  * in an emergency.
1983  *
1984  * Note: these flags remain set until CommitTransaction or
1985  * AbortTransaction. We don't want to clear them until we reset
1986  * MyProc->xid/xmin, otherwise GetOldestNonRemovableTransactionId()
1987  * might appear to go backwards, which is probably Not Good. (We also
1988  * set PROC_IN_VACUUM *before* taking our own snapshot, so that our
1989  * xmin doesn't become visible ahead of setting the flag.)
1990  */
1991  LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
1993  if (params->is_wraparound)
1996  LWLockRelease(ProcArrayLock);
1997  }
1998 
1999  /*
2000  * Need to acquire a snapshot to prevent pg_subtrans from being truncated,
2001  * cutoff xids in local memory wrapping around, and to have updated xmin
2002  * horizons.
2003  */
2005 
2006  /*
2007  * Check for user-requested abort. Note we want this to be inside a
2008  * transaction, so xact.c doesn't issue useless WARNING.
2009  */
2011 
2012  /*
2013  * Determine the type of lock we want --- hard exclusive lock for a FULL
2014  * vacuum, but just ShareUpdateExclusiveLock for concurrent vacuum. Either
2015  * way, we can be sure that no other backend is vacuuming the same table.
2016  */
2017  lmode = (params->options & VACOPT_FULL) ?
2019 
2020  /* open the relation and get the appropriate lock on it */
2021  rel = vacuum_open_relation(relid, relation, params->options,
2022  params->log_min_duration >= 0, lmode);
2023 
2024  /* leave if relation could not be opened or locked */
2025  if (!rel)
2026  {
2029  return false;
2030  }
2031 
2032  /*
2033  * Check if relation needs to be skipped based on ownership. This check
2034  * happens also when building the relation list to vacuum for a manual
2035  * operation, and needs to be done additionally here as VACUUM could
2036  * happen across multiple transactions where relation ownership could have
2037  * changed in-between. Make sure to only generate logs for VACUUM in this
2038  * case.
2039  */
2041  rel->rd_rel,
2042  params->options & VACOPT_VACUUM))
2043  {
2044  relation_close(rel, lmode);
2047  return false;
2048  }
2049 
2050  /*
2051  * Check that it's of a vacuumable relkind.
2052  */
2053  if (rel->rd_rel->relkind != RELKIND_RELATION &&
2054  rel->rd_rel->relkind != RELKIND_MATVIEW &&
2055  rel->rd_rel->relkind != RELKIND_TOASTVALUE &&
2056  rel->rd_rel->relkind != RELKIND_PARTITIONED_TABLE)
2057  {
2058  ereport(WARNING,
2059  (errmsg("skipping \"%s\" --- cannot vacuum non-tables or special system tables",
2060  RelationGetRelationName(rel))));
2061  relation_close(rel, lmode);
2064  return false;
2065  }
2066 
2067  /*
2068  * Silently ignore tables that are temp tables of other backends ---
2069  * trying to vacuum these will lead to great unhappiness, since their
2070  * contents are probably not up-to-date on disk. (We don't throw a
2071  * warning here; it would just lead to chatter during a database-wide
2072  * VACUUM.)
2073  */
2074  if (RELATION_IS_OTHER_TEMP(rel))
2075  {
2076  relation_close(rel, lmode);
2079  return false;
2080  }
2081 
2082  /*
2083  * Silently ignore partitioned tables as there is no work to be done. The
2084  * useful work is on their child partitions, which have been queued up for
2085  * us separately.
2086  */
2087  if (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
2088  {
2089  relation_close(rel, lmode);
2092  /* It's OK to proceed with ANALYZE on this table */
2093  return true;
2094  }
2095 
2096  /*
2097  * Get a session-level lock too. This will protect our access to the
2098  * relation across multiple transactions, so that we can vacuum the
2099  * relation's TOAST table (if any) secure in the knowledge that no one is
2100  * deleting the parent relation.
2101  *
2102  * NOTE: this cannot block, even if someone else is waiting for access,
2103  * because the lock manager knows that both lock requests are from the
2104  * same process.
2105  */
2106  lockrelid = rel->rd_lockInfo.lockRelId;
2107  LockRelationIdForSession(&lockrelid, lmode);
2108 
2109  /*
2110  * Set index_cleanup option based on index_cleanup reloption if it wasn't
2111  * specified in VACUUM command, or when running in an autovacuum worker
2112  */
2113  if (params->index_cleanup == VACOPTVALUE_UNSPECIFIED)
2114  {
2115  StdRdOptIndexCleanup vacuum_index_cleanup;
2116 
2117  if (rel->rd_options == NULL)
2118  vacuum_index_cleanup = STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO;
2119  else
2120  vacuum_index_cleanup =
2121  ((StdRdOptions *) rel->rd_options)->vacuum_index_cleanup;
2122 
2123  if (vacuum_index_cleanup == STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO)
2124  params->index_cleanup = VACOPTVALUE_AUTO;
2125  else if (vacuum_index_cleanup == STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON)
2127  else
2128  {
2129  Assert(vacuum_index_cleanup ==
2132  }
2133  }
2134 
2135  /*
2136  * Set truncate option based on truncate reloption if it wasn't specified
2137  * in VACUUM command, or when running in an autovacuum worker
2138  */
2139  if (params->truncate == VACOPTVALUE_UNSPECIFIED)
2140  {
2141  if (rel->rd_options == NULL ||
2142  ((StdRdOptions *) rel->rd_options)->vacuum_truncate)
2143  params->truncate = VACOPTVALUE_ENABLED;
2144  else
2145  params->truncate = VACOPTVALUE_DISABLED;
2146  }
2147 
2148  /*
2149  * Remember the relation's TOAST relation for later, if the caller asked
2150  * us to process it. In VACUUM FULL, though, the toast table is
2151  * automatically rebuilt by cluster_rel so we shouldn't recurse to it,
2152  * unless PROCESS_MAIN is disabled.
2153  */
2154  if ((params->options & VACOPT_PROCESS_TOAST) != 0 &&
2155  ((params->options & VACOPT_FULL) == 0 ||
2156  (params->options & VACOPT_PROCESS_MAIN) == 0))
2157  toast_relid = rel->rd_rel->reltoastrelid;
2158  else
2159  toast_relid = InvalidOid;
2160 
2161  /*
2162  * Switch to the table owner's userid, so that any index functions are run
2163  * as that user. Also lock down security-restricted operations and
2164  * arrange to make GUC variable changes local to this command. (This is
2165  * unnecessary, but harmless, for lazy VACUUM.)
2166  */
2167  GetUserIdAndSecContext(&save_userid, &save_sec_context);
2168  SetUserIdAndSecContext(rel->rd_rel->relowner,
2169  save_sec_context | SECURITY_RESTRICTED_OPERATION);
2170  save_nestlevel = NewGUCNestLevel();
2171 
2172  /*
2173  * If PROCESS_MAIN is set (the default), it's time to vacuum the main
2174  * relation. Otherwise, we can skip this part. If processing the TOAST
2175  * table is required (e.g., PROCESS_TOAST is set), we force PROCESS_MAIN
2176  * to be set when we recurse to the TOAST table.
2177  */
2178  if (params->options & VACOPT_PROCESS_MAIN)
2179  {
2180  /*
2181  * Do the actual work --- either FULL or "lazy" vacuum
2182  */
2183  if (params->options & VACOPT_FULL)
2184  {
2185  ClusterParams cluster_params = {0};
2186 
2187  /* close relation before vacuuming, but hold lock until commit */
2188  relation_close(rel, NoLock);
2189  rel = NULL;
2190 
2191  if ((params->options & VACOPT_VERBOSE) != 0)
2192  cluster_params.options |= CLUOPT_VERBOSE;
2193 
2194  /* VACUUM FULL is now a variant of CLUSTER; see cluster.c */
2195  cluster_rel(relid, InvalidOid, &cluster_params);
2196  }
2197  else
2198  table_relation_vacuum(rel, params, bstrategy);
2199  }
2200 
2201  /* Roll back any GUC changes executed by index functions */
2202  AtEOXact_GUC(false, save_nestlevel);
2203 
2204  /* Restore userid and security context */
2205  SetUserIdAndSecContext(save_userid, save_sec_context);
2206 
2207  /* all done with this class, but hold lock until commit */
2208  if (rel)
2209  relation_close(rel, NoLock);
2210 
2211  /*
2212  * Complete the transaction and free all temporary memory used.
2213  */
2216 
2217  /*
2218  * If the relation has a secondary toast rel, vacuum that too while we
2219  * still hold the session lock on the main table. Note however that
2220  * "analyze" will not get done on the toast table. This is good, because
2221  * the toaster always uses hardcoded index access and statistics are
2222  * totally unimportant for toast relations.
2223  */
2224  if (toast_relid != InvalidOid)
2225  {
2226  VacuumParams toast_vacuum_params;
2227 
2228  /* force VACOPT_PROCESS_MAIN so vacuum_rel() processes it */
2229  memcpy(&toast_vacuum_params, params, sizeof(VacuumParams));
2230  toast_vacuum_params.options |= VACOPT_PROCESS_MAIN;
2231 
2232  vacuum_rel(toast_relid, NULL, &toast_vacuum_params, bstrategy);
2233  }
2234 
2235  /*
2236  * Now release the session-level lock on the main table.
2237  */
2238  UnlockRelationIdForSession(&lockrelid, lmode);
2239 
2240  /* Report that we really did it. */
2241  return true;
2242 }
2243 
2244 
2245 /*
2246  * Open all the vacuumable indexes of the given relation, obtaining the
2247  * specified kind of lock on each. Return an array of Relation pointers for
2248  * the indexes into *Irel, and the number of indexes into *nindexes.
2249  *
2250  * We consider an index vacuumable if it is marked insertable (indisready).
2251  * If it isn't, probably a CREATE INDEX CONCURRENTLY command failed early in
2252  * execution, and what we have is too corrupt to be processable. We will
2253  * vacuum even if the index isn't indisvalid; this is important because in a
2254  * unique index, uniqueness checks will be performed anyway and had better not
2255  * hit dangling index pointers.
2256  */
2257 void
2259  int *nindexes, Relation **Irel)
2260 {
2261  List *indexoidlist;
2262  ListCell *indexoidscan;
2263  int i;
2264 
2265  Assert(lockmode != NoLock);
2266 
2267  indexoidlist = RelationGetIndexList(relation);
2268 
2269  /* allocate enough memory for all indexes */
2270  i = list_length(indexoidlist);
2271 
2272  if (i > 0)
2273  *Irel = (Relation *) palloc(i * sizeof(Relation));
2274  else
2275  *Irel = NULL;
2276 
2277  /* collect just the ready indexes */
2278  i = 0;
2279  foreach(indexoidscan, indexoidlist)
2280  {
2281  Oid indexoid = lfirst_oid(indexoidscan);
2282  Relation indrel;
2283 
2284  indrel = index_open(indexoid, lockmode);
2285  if (indrel->rd_index->indisready)
2286  (*Irel)[i++] = indrel;
2287  else
2288  index_close(indrel, lockmode);
2289  }
2290 
2291  *nindexes = i;
2292 
2293  list_free(indexoidlist);
2294 }
2295 
2296 /*
2297  * Release the resources acquired by vac_open_indexes. Optionally release
2298  * the locks (say NoLock to keep 'em).
2299  */
2300 void
2301 vac_close_indexes(int nindexes, Relation *Irel, LOCKMODE lockmode)
2302 {
2303  if (Irel == NULL)
2304  return;
2305 
2306  while (nindexes--)
2307  {
2308  Relation ind = Irel[nindexes];
2309 
2310  index_close(ind, lockmode);
2311  }
2312  pfree(Irel);
2313 }
2314 
2315 /*
2316  * vacuum_delay_point --- check for interrupts and cost-based delay.
2317  *
2318  * This should be called in each major loop of VACUUM processing,
2319  * typically once per page processed.
2320  */
2321 void
2323 {
2324  double msec = 0;
2325 
2326  /* Always check for interrupts */
2328 
2329  if (InterruptPending ||
2331  return;
2332 
2333  /*
2334  * Autovacuum workers should reload the configuration file if requested.
2335  * This allows changes to [autovacuum_]vacuum_cost_limit and
2336  * [autovacuum_]vacuum_cost_delay to take effect while a table is being
2337  * vacuumed or analyzed.
2338  */
2340  {
2341  ConfigReloadPending = false;
2344  }
2345 
2346  /*
2347  * If we disabled cost-based delays after reloading the config file,
2348  * return.
2349  */
2350  if (!VacuumCostActive)
2351  return;
2352 
2353  /*
2354  * For parallel vacuum, the delay is computed based on the shared cost
2355  * balance. See compute_parallel_delay.
2356  */
2357  if (VacuumSharedCostBalance != NULL)
2358  msec = compute_parallel_delay();
2361 
2362  /* Nap if appropriate */
2363  if (msec > 0)
2364  {
2365  if (msec > vacuum_cost_delay * 4)
2366  msec = vacuum_cost_delay * 4;
2367 
2368  pgstat_report_wait_start(WAIT_EVENT_VACUUM_DELAY);
2369  pg_usleep(msec * 1000);
2371 
2372  /*
2373  * We don't want to ignore postmaster death during very long vacuums
2374  * with vacuum_cost_delay configured. We can't use the usual
2375  * WaitLatch() approach here because we want microsecond-based sleep
2376  * durations above.
2377  */
2379  exit(1);
2380 
2381  VacuumCostBalance = 0;
2382 
2383  /*
2384  * Balance and update limit values for autovacuum workers. We must do
2385  * this periodically, as the number of workers across which we are
2386  * balancing the limit may have changed.
2387  *
2388  * TODO: There may be better criteria for determining when to do this
2389  * besides "check after napping".
2390  */
2392 
2393  /* Might have gotten an interrupt while sleeping */
2395  }
2396 }
2397 
2398 /*
2399  * Computes the vacuum delay for parallel workers.
2400  *
2401  * The basic idea of a cost-based delay for parallel vacuum is to allow each
2402  * worker to sleep in proportion to the share of work it's done. We achieve this
2403  * by allowing all parallel vacuum workers including the leader process to
2404  * have a shared view of cost related parameters (mainly VacuumCostBalance).
2405  * We allow each worker to update it as and when it has incurred any cost and
2406  * then based on that decide whether it needs to sleep. We compute the time
2407  * to sleep for a worker based on the cost it has incurred
2408  * (VacuumCostBalanceLocal) and then reduce the VacuumSharedCostBalance by
2409  * that amount. This avoids putting to sleep those workers which have done less
2410  * I/O than other workers and therefore ensure that workers
2411  * which are doing more I/O got throttled more.
2412  *
2413  * We allow a worker to sleep only if it has performed I/O above a certain
2414  * threshold, which is calculated based on the number of active workers
2415  * (VacuumActiveNWorkers), and the overall cost balance is more than
2416  * VacuumCostLimit set by the system. Testing reveals that we achieve
2417  * the required throttling if we force a worker that has done more than 50%
2418  * of its share of work to sleep.
2419  */
2420 static double
2422 {
2423  double msec = 0;
2424  uint32 shared_balance;
2425  int nworkers;
2426 
2427  /* Parallel vacuum must be active */
2429 
2431 
2432  /* At least count itself */
2433  Assert(nworkers >= 1);
2434 
2435  /* Update the shared cost balance value atomically */
2437 
2438  /* Compute the total local balance for the current worker */
2440 
2441  if ((shared_balance >= vacuum_cost_limit) &&
2442  (VacuumCostBalanceLocal > 0.5 * ((double) vacuum_cost_limit / nworkers)))
2443  {
2444  /* Compute sleep time based on the local cost balance */
2448  }
2449 
2450  /*
2451  * Reset the local balance as we accumulated it into the shared value.
2452  */
2453  VacuumCostBalance = 0;
2454 
2455  return msec;
2456 }
2457 
2458 /*
2459  * A wrapper function of defGetBoolean().
2460  *
2461  * This function returns VACOPTVALUE_ENABLED and VACOPTVALUE_DISABLED instead
2462  * of true and false.
2463  */
2464 static VacOptValue
2466 {
2468 }
2469 
2470 /*
2471  * vac_bulkdel_one_index() -- bulk-deletion for index relation.
2472  *
2473  * Returns bulk delete stats derived from input stats
2474  */
2477  VacDeadItems *dead_items)
2478 {
2479  /* Do bulk deletion */
2480  istat = index_bulk_delete(ivinfo, istat, vac_tid_reaped,
2481  (void *) dead_items);
2482 
2483  ereport(ivinfo->message_level,
2484  (errmsg("scanned index \"%s\" to remove %d row versions",
2485  RelationGetRelationName(ivinfo->index),
2486  dead_items->num_items)));
2487 
2488  return istat;
2489 }
2490 
2491 /*
2492  * vac_cleanup_one_index() -- do post-vacuum cleanup for index relation.
2493  *
2494  * Returns bulk delete stats derived from input stats
2495  */
2498 {
2499  istat = index_vacuum_cleanup(ivinfo, istat);
2500 
2501  if (istat)
2502  ereport(ivinfo->message_level,
2503  (errmsg("index \"%s\" now contains %.0f row versions in %u pages",
2504  RelationGetRelationName(ivinfo->index),
2505  istat->num_index_tuples,
2506  istat->num_pages),
2507  errdetail("%.0f index row versions were removed.\n"
2508  "%u index pages were newly deleted.\n"
2509  "%u index pages are currently deleted, of which %u are currently reusable.",
2510  istat->tuples_removed,
2511  istat->pages_newly_deleted,
2512  istat->pages_deleted, istat->pages_free)));
2513 
2514  return istat;
2515 }
2516 
2517 /*
2518  * Returns the total required space for VACUUM's dead_items array given a
2519  * max_items value.
2520  */
2521 Size
2523 {
2524  Assert(max_items <= MAXDEADITEMS(MaxAllocSize));
2525 
2526  return offsetof(VacDeadItems, items) + sizeof(ItemPointerData) * max_items;
2527 }
2528 
2529 /*
2530  * vac_tid_reaped() -- is a particular tid deletable?
2531  *
2532  * This has the right signature to be an IndexBulkDeleteCallback.
2533  *
2534  * Assumes dead_items array is sorted (in ascending TID order).
2535  */
2536 static bool
2538 {
2539  VacDeadItems *dead_items = (VacDeadItems *) state;
2540  int64 litem,
2541  ritem,
2542  item;
2543  ItemPointer res;
2544 
2545  litem = itemptr_encode(&dead_items->items[0]);
2546  ritem = itemptr_encode(&dead_items->items[dead_items->num_items - 1]);
2547  item = itemptr_encode(itemptr);
2548 
2549  /*
2550  * Doing a simple bound check before bsearch() is useful to avoid the
2551  * extra cost of bsearch(), especially if dead items on the heap are
2552  * concentrated in a certain range. Since this function is called for
2553  * every index tuple, it pays to be really fast.
2554  */
2555  if (item < litem || item > ritem)
2556  return false;
2557 
2558  res = (ItemPointer) bsearch(itemptr,
2559  dead_items->items,
2560  dead_items->num_items,
2561  sizeof(ItemPointerData),
2562  vac_cmp_itemptr);
2563 
2564  return (res != NULL);
2565 }
2566 
2567 /*
2568  * Comparator routines for use with qsort() and bsearch().
2569  */
2570 static int
2571 vac_cmp_itemptr(const void *left, const void *right)
2572 {
2573  BlockNumber lblk,
2574  rblk;
2575  OffsetNumber loff,
2576  roff;
2577 
2578  lblk = ItemPointerGetBlockNumber((ItemPointer) left);
2579  rblk = ItemPointerGetBlockNumber((ItemPointer) right);
2580 
2581  if (lblk < rblk)
2582  return -1;
2583  if (lblk > rblk)
2584  return 1;
2585 
2586  loff = ItemPointerGetOffsetNumber((ItemPointer) left);
2587  roff = ItemPointerGetOffsetNumber((ItemPointer) right);
2588 
2589  if (loff < roff)
2590  return -1;
2591  if (loff > roff)
2592  return 1;
2593 
2594  return 0;
2595 }
bool object_ownercheck(Oid classid, Oid objectid, Oid roleid)
Definition: aclchk.c:3961
static uint32 pg_atomic_sub_fetch_u32(volatile pg_atomic_uint32 *ptr, int32 sub_)
Definition: atomics.h:396
static uint32 pg_atomic_add_fetch_u32(volatile pg_atomic_uint32 *ptr, int32 add_)
Definition: atomics.h:381
static uint32 pg_atomic_read_u32(volatile pg_atomic_uint32 *ptr)
Definition: atomics.h:236
void VacuumUpdateCosts(void)
Definition: autovacuum.c:1786
int autovacuum_multixact_freeze_max_age
Definition: autovacuum.c:127
int autovacuum_freeze_max_age
Definition: autovacuum.c:126
bool IsAutoVacuumWorkerProcess(void)
Definition: autovacuum.c:3397
void AutoVacuumUpdateCostLimit(void)
Definition: autovacuum.c:1855
#define MAX_PARALLEL_WORKER_LIMIT
uint32 BlockNumber
Definition: block.h:31
@ BAS_VACUUM
Definition: bufmgr.h:38
#define NameStr(name)
Definition: c.h:735
unsigned int uint32
Definition: c.h:495
#define Min(x, y)
Definition: c.h:993
signed int int32
Definition: c.h:483
#define Max(x, y)
Definition: c.h:987
TransactionId MultiXactId
Definition: c.h:651
uint32 bits32
Definition: c.h:504
float float4
Definition: c.h:618
uint32 TransactionId
Definition: c.h:641
#define OidIsValid(objectId)
Definition: c.h:764
size_t Size
Definition: c.h:594
void TruncateCLOG(TransactionId oldestXact, Oid oldestxid_datoid)
Definition: clog.c:878
void cluster_rel(Oid tableOid, Oid indexOid, ClusterParams *params)
Definition: cluster.c:312
#define CLUOPT_VERBOSE
Definition: cluster.h:23
void analyze_rel(Oid relid, RangeVar *relation, VacuumParams *params, List *va_cols, bool in_outer_xact, BufferAccessStrategy bstrategy)
Definition: analyze.c:121
void AdvanceOldestCommitTsXid(TransactionId oldestXact)
Definition: commit_ts.c:887
void TruncateCommitTs(TransactionId oldestXact)
Definition: commit_ts.c:834
bool database_is_invalid_form(Form_pg_database datform)
Definition: dbcommands.c:3108
int32 defGetInt32(DefElem *def)
Definition: define.c:163
bool defGetBoolean(DefElem *def)
Definition: define.c:108
char * defGetString(DefElem *def)
Definition: define.c:49
struct cursor * cur
Definition: ecpg.c:28
int errmsg_internal(const char *fmt,...)
Definition: elog.c:1156
int errdetail(const char *fmt,...)
Definition: elog.c:1202
int errhint(const char *fmt,...)
Definition: elog.c:1316
int errcode(int sqlerrcode)
Definition: elog.c:858
int errmsg(const char *fmt,...)
Definition: elog.c:1069
#define _(x)
Definition: elog.c:91
#define LOG
Definition: elog.h:31
#define PG_TRY(...)
Definition: elog.h:370
#define WARNING
Definition: elog.h:36
#define DEBUG2
Definition: elog.h:29
#define PG_END_TRY(...)
Definition: elog.h:395
#define ERROR
Definition: elog.h:39
#define PG_FINALLY(...)
Definition: elog.h:387
#define ereport(elevel,...)
Definition: elog.h:149
BufferAccessStrategy GetAccessStrategyWithSize(BufferAccessStrategyType btype, int ring_size_kb)
Definition: freelist.c:584
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:599
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:506
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:387
volatile sig_atomic_t InterruptPending
Definition: globals.c:30
int64 VacuumPageHit
Definition: globals.c:151
int64 VacuumPageMiss
Definition: globals.c:152
bool VacuumCostActive
Definition: globals.c:156
bool IsUnderPostmaster
Definition: globals.c:113
int64 VacuumPageDirty
Definition: globals.c:153
int VacuumCostBalance
Definition: globals.c:155
int VacuumBufferUsageLimit
Definition: globals.c:143
Oid MyDatabaseId
Definition: globals.c:89
bool parse_int(const char *value, int *result, int flags, const char **hintmsg)
Definition: guc.c:2824
int NewGUCNestLevel(void)
Definition: guc.c:2201
#define newval
void AtEOXact_GUC(bool isCommit, int nestLevel)
Definition: guc.c:2215
#define GUC_check_errdetail
Definition: guc.h:436
GucSource
Definition: guc.h:108
@ PGC_SIGHUP
Definition: guc.h:71
#define GUC_UNIT_KB
Definition: guc.h:225
void ProcessConfigFile(GucContext context)
void heap_inplace_update(Relation relation, HeapTuple tuple)
Definition: heapam.c:5875
HeapTuple heap_getnext(TableScanDesc sscan, ScanDirection direction)
Definition: heapam.c:1086
HeapTuple heap_copytuple(HeapTuple tuple)
Definition: heaptuple.c:768
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1426
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define GETSTRUCT(TUP)
Definition: htup_details.h:653
int verbose
static int64 itemptr_encode(ItemPointer itemptr)
Definition: index.h:185
IndexBulkDeleteResult * index_vacuum_cleanup(IndexVacuumInfo *info, IndexBulkDeleteResult *istat)
Definition: indexam.c:720
void index_close(Relation relation, LOCKMODE lockmode)
Definition: indexam.c:158
IndexBulkDeleteResult * index_bulk_delete(IndexVacuumInfo *info, IndexBulkDeleteResult *istat, IndexBulkDeleteCallback callback, void *callback_state)
Definition: indexam.c:699
Relation index_open(Oid relationId, LOCKMODE lockmode)
Definition: indexam.c:132
volatile sig_atomic_t ConfigReloadPending
Definition: interrupt.c:27
int i
Definition: isn.c:73
static OffsetNumber ItemPointerGetOffsetNumber(const ItemPointerData *pointer)
Definition: itemptr.h:124
static BlockNumber ItemPointerGetBlockNumber(const ItemPointerData *pointer)
Definition: itemptr.h:103
ItemPointerData * ItemPointer
Definition: itemptr.h:49
struct ItemPointerData ItemPointerData
Assert(fmt[strlen(fmt) - 1] !='\n')
exit(1)
List * lappend(List *list, void *datum)
Definition: list.c:338
void list_free(List *list)
Definition: list.c:1545
List * list_concat(List *list1, const List *list2)
Definition: list.c:560
bool ConditionalLockRelationOid(Oid relid, LOCKMODE lockmode)
Definition: lmgr.c:152
void UnlockRelationOid(Oid relid, LOCKMODE lockmode)
Definition: lmgr.c:228
void LockRelationIdForSession(LockRelId *relid, LOCKMODE lockmode)
Definition: lmgr.c:398
void UnlockRelationIdForSession(LockRelId *relid, LOCKMODE lockmode)
Definition: lmgr.c:411
void LockDatabaseFrozenIds(LOCKMODE lockmode)
Definition: lmgr.c:498
int LOCKMODE
Definition: lockdefs.h:26
#define NoLock
Definition: lockdefs.h:34
#define AccessExclusiveLock
Definition: lockdefs.h:43
#define AccessShareLock
Definition: lockdefs.h:36
#define ShareUpdateExclusiveLock
Definition: lockdefs.h:39
#define ExclusiveLock
Definition: lockdefs.h:42
#define RowExclusiveLock
Definition: lockdefs.h:38
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1195
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1808
@ LW_EXCLUSIVE
Definition: lwlock.h:116
VacuumRelation * makeVacuumRelation(RangeVar *relation, Oid oid, List *va_cols)
Definition: makefuncs.c:820
void pfree(void *pointer)
Definition: mcxt.c:1456
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:403
void * palloc(Size size)
Definition: mcxt.c:1226
MemoryContext PortalContext
Definition: mcxt.c:150
#define AllocSetContextCreate
Definition: memutils.h:129
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:153
#define MaxAllocSize
Definition: memutils.h:40
#define MIN_BAS_VAC_RING_SIZE_KB
Definition: miscadmin.h:271
#define MAX_BAS_VAC_RING_SIZE_KB
Definition: miscadmin.h:272
#define SECURITY_RESTRICTED_OPERATION
Definition: miscadmin.h:314
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:121
void GetUserIdAndSecContext(Oid *userid, int *sec_context)
Definition: miscinit.c:630
Oid GetUserId(void)
Definition: miscinit.c:509
void SetUserIdAndSecContext(Oid userid, int sec_context)
Definition: miscinit.c:637
bool MultiXactIdPrecedes(MultiXactId multi1, MultiXactId multi2)
Definition: multixact.c:3156
bool MultiXactIdPrecedesOrEquals(MultiXactId multi1, MultiXactId multi2)
Definition: multixact.c:3170
void SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, bool is_startup)
Definition: multixact.c:2213
MultiXactId GetOldestMultiXactId(void)
Definition: multixact.c:2507
int MultiXactMemberFreezeThreshold(void)
Definition: multixact.c:2825
MultiXactId ReadNextMultiXactId(void)
Definition: multixact.c:724
void TruncateMultiXact(MultiXactId newOldestMulti, Oid newOldestMultiDB)
Definition: multixact.c:2941
#define MultiXactIdIsValid(multi)
Definition: multixact.h:28
#define FirstMultiXactId
Definition: multixact.h:25
Oid RangeVarGetRelidExtended(const RangeVar *relation, LOCKMODE lockmode, uint32 flags, RangeVarGetRelidCallback callback, void *callback_arg)
Definition: namespace.c:221
@ RVR_SKIP_LOCKED
Definition: namespace.h:73
uint16 OffsetNumber
Definition: off.h:24
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:138
int parser_errposition(ParseState *pstate, int location)
Definition: parse_node.c:111
#define ERRCODE_DATA_CORRUPTED
Definition: pg_basebackup.c:41
NameData relname
Definition: pg_class.h:38
FormData_pg_class * Form_pg_class
Definition: pg_class.h:153
TransactionId datfrozenxid
Definition: pg_database.h:59
TransactionId datminmxid
Definition: pg_database.h:62
FormData_pg_database * Form_pg_database
Definition: pg_database.h:93
FormData_pg_database
Definition: pg_database.h:86
List * find_all_inheritors(Oid parentrelId, LOCKMODE lockmode, List **numparents)
Definition: pg_inherits.c:256
#define lfirst(lc)
Definition: pg_list.h:172
#define lfirst_node(type, lc)
Definition: pg_list.h:176
static int list_length(const List *l)
Definition: pg_list.h:152
#define NIL
Definition: pg_list.h:68
#define lfirst_oid(lc)
Definition: pg_list.h:174
static rewind_source * source
Definition: pg_rewind.c:89
#define ERRCODE_UNDEFINED_TABLE
Definition: pgbench.c:78
#define PostmasterIsAlive()
Definition: pmsignal.h:102
int pg_strcasecmp(const char *s1, const char *s2)
Definition: pgstrcasecmp.c:36
static Datum ObjectIdGetDatum(Oid X)
Definition: postgres.h:252
#define InvalidOid
Definition: postgres_ext.h:36
unsigned int Oid
Definition: postgres_ext.h:31
#define PROC_IN_VACUUM
Definition: proc.h:57
#define PROC_VACUUM_FOR_WRAPAROUND
Definition: proc.h:59
TransactionId GetOldestNonRemovableTransactionId(Relation rel)
Definition: procarray.c:1986
static long analyze(struct nfa *nfa)
Definition: regc_nfa.c:3016
#define RelationGetRelid(relation)
Definition: rel.h:504
#define RelationGetRelationName(relation)
Definition: rel.h:538
#define RELATION_IS_OTHER_TEMP(relation)
Definition: rel.h:659
StdRdOptIndexCleanup
Definition: rel.h:329
@ STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO
Definition: rel.h:330
@ STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF
Definition: rel.h:331
@ STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON
Definition: rel.h:332
List * RelationGetIndexList(Relation relation)
Definition: relcache.c:4740
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
@ ForwardScanDirection
Definition: sdir.h:28
void pg_usleep(long microsec)
Definition: signal.c:53
Snapshot GetTransactionSnapshot(void)
Definition: snapmgr.c:197
void PushActiveSnapshot(Snapshot snapshot)
Definition: snapmgr.c:629
bool ActiveSnapshotSet(void)
Definition: snapmgr.c:763
void PopActiveSnapshot(void)
Definition: snapmgr.c:724
void relation_close(Relation relation, LOCKMODE lockmode)
Definition: relation.c:206
Relation try_relation_open(Oid relationId, LOCKMODE lockmode)
Definition: relation.c:89
PGPROC * MyProc
Definition: proc.c:66
PROC_HDR * ProcGlobal
Definition: proc.c:78
#define BTEqualStrategyNumber
Definition: stratnum.h:31
bits32 options
Definition: cluster.h:30
char * defname
Definition: parsenodes.h:809
int location
Definition: parsenodes.h:813
Node * arg
Definition: parsenodes.h:810
BlockNumber pages_deleted
Definition: genam.h:82
BlockNumber pages_newly_deleted
Definition: genam.h:81
BlockNumber pages_free
Definition: genam.h:83
BlockNumber num_pages
Definition: genam.h:77
double tuples_removed
Definition: genam.h:80
double num_index_tuples
Definition: genam.h:79
Relation index
Definition: genam.h:46
int message_level
Definition: genam.h:51
Definition: pg_list.h:54
LockRelId lockRelId
Definition: rel.h:46
Definition: rel.h:39
uint8 statusFlags
Definition: proc.h:233
int pgxactoff
Definition: proc.h:188
uint8 * statusFlags
Definition: proc.h:377
char * relname
Definition: primnodes.h:74
LockInfoData rd_lockInfo
Definition: rel.h:114
TriggerDesc * trigdesc
Definition: rel.h:117
Form_pg_index rd_index
Definition: rel.h:191
RuleLock * rd_rules
Definition: rel.h:115
bytea * rd_options
Definition: rel.h:174
Form_pg_class rd_rel
Definition: rel.h:111
ItemPointerData items[FLEXIBLE_ARRAY_MEMBER]
Definition: vacuum.h:288
int num_items
Definition: vacuum.h:285
TransactionId FreezeLimit
Definition: vacuum.h:275
TransactionId OldestXmin
Definition: vacuum.h:265
TransactionId relfrozenxid
Definition: vacuum.h:249
MultiXactId relminmxid
Definition: vacuum.h:250
MultiXactId MultiXactCutoff
Definition: vacuum.h:276
MultiXactId OldestMxact
Definition: vacuum.h:266
int nworkers
Definition: vacuum.h:237
int freeze_table_age
Definition: vacuum.h:220
VacOptValue truncate
Definition: vacuum.h:230
bits32 options
Definition: vacuum.h:218
int freeze_min_age
Definition: vacuum.h:219
bool is_wraparound
Definition: vacuum.h:225
int multixact_freeze_min_age
Definition: vacuum.h:221
int multixact_freeze_table_age
Definition: vacuum.h:223
int log_min_duration
Definition: vacuum.h:226
VacOptValue index_cleanup
Definition: vacuum.h:229
RangeVar * relation
Definition: parsenodes.h:3729
List * options
Definition: parsenodes.h:3714
bool is_vacuumcmd
Definition: parsenodes.h:3716
List * rels
Definition: parsenodes.h:3715
Definition: regguts.h:323
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:868
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:820
#define SearchSysCacheCopy1(cacheId, key1)
Definition: syscache.h:182
@ RELOID
Definition: syscache.h:89
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:126
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:40
TableScanDesc table_beginscan_catalog(Relation relation, int nkeys, struct ScanKeyData *key)
Definition: tableam.c:112
static void table_endscan(TableScanDesc scan)
Definition: tableam.h:1009
static void table_relation_vacuum(Relation rel, struct VacuumParams *params, BufferAccessStrategy bstrategy)
Definition: tableam.h:1702
bool TransactionIdPrecedes(TransactionId id1, TransactionId id2)
Definition: transam.c:280
bool TransactionIdPrecedesOrEquals(TransactionId id1, TransactionId id2)
Definition: transam.c:299
static TransactionId ReadNextTransactionId(void)
Definition: transam.h:315
#define FirstNormalTransactionId
Definition: transam.h:34
#define TransactionIdIsValid(xid)
Definition: transam.h:41
#define TransactionIdIsNormal(xid)
Definition: transam.h:42
static bool vac_tid_reaped(ItemPointer itemptr, void *state)
Definition: vacuum.c:2537
IndexBulkDeleteResult * vac_bulkdel_one_index(IndexVacuumInfo *ivinfo, IndexBulkDeleteResult *istat, VacDeadItems *dead_items)
Definition: vacuum.c:2476
void ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
Definition: vacuum.c:150
pg_atomic_uint32 * VacuumActiveNWorkers
Definition: vacuum.c:105
static void vac_truncate_clog(TransactionId frozenXID, MultiXactId minMulti, TransactionId lastSaneFrozenXid, MultiXactId lastSaneMinMulti)
Definition: vacuum.c:1782
Size vac_max_items_to_alloc_size(int max_items)
Definition: vacuum.c:2522
int vacuum_freeze_min_age
Definition: vacuum.c:69
static List * expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context, int options)
Definition: vacuum.c:873
double vacuum_cost_delay
Definition: vacuum.c:82
static double compute_parallel_delay(void)
Definition: vacuum.c:2421
static VacOptValue get_vacoptval_from_boolean(DefElem *def)
Definition: vacuum.c:2465
void vac_open_indexes(Relation relation, LOCKMODE lockmode, int *nindexes, Relation **Irel)
Definition: vacuum.c:2258
void vacuum(List *relations, VacuumParams *params, BufferAccessStrategy bstrategy, MemoryContext vac_context, bool isTopLevel)
Definition: vacuum.c:478
bool check_vacuum_buffer_usage_limit(int *newval, void **extra, GucSource source)
Definition: vacuum.c:128
int VacuumCostBalanceLocal
Definition: vacuum.c:106
static List * get_all_vacuum_rels(MemoryContext vac_context, int options)
Definition: vacuum.c:1013
void vac_update_relstats(Relation relation, BlockNumber num_pages, double num_tuples, BlockNumber num_all_visible_pages, bool hasindex, TransactionId frozenxid, MultiXactId minmulti, bool *frozenxid_updated, bool *minmulti_updated, bool in_outer_xact)
Definition: vacuum.c:1401
int vacuum_multixact_freeze_table_age
Definition: vacuum.c:72
int vacuum_freeze_table_age
Definition: vacuum.c:70
int vacuum_multixact_failsafe_age
Definition: vacuum.c:74
int vacuum_multixact_freeze_min_age
Definition: vacuum.c:71
Relation vacuum_open_relation(Oid relid, RangeVar *relation, bits32 options, bool verbose, LOCKMODE lmode)
Definition: vacuum.c:761
static bool vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params, BufferAccessStrategy bstrategy)
Definition: vacuum.c:1951
void vac_close_indexes(int nindexes, Relation *Irel, LOCKMODE lockmode)
Definition: vacuum.c:2301
void vacuum_delay_point(void)
Definition: vacuum.c:2322
bool vacuum_is_relation_owner(Oid relid, Form_pg_class reltuple, bits32 options)
Definition: vacuum.c:707
void vac_update_datfrozenxid(void)
Definition: vacuum.c:1568
bool vacuum_get_cutoffs(Relation rel, const VacuumParams *params, struct VacuumCutoffs *cutoffs)
Definition: vacuum.c:1075
bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs)
Definition: vacuum.c:1243
pg_atomic_uint32 * VacuumSharedCostBalance
Definition: vacuum.c:104
bool VacuumFailsafeActive
Definition: vacuum.c:98
int vacuum_cost_limit
Definition: vacuum.c:83
int vacuum_failsafe_age
Definition: vacuum.c:73
double vac_estimate_reltuples(Relation relation, BlockNumber total_pages, BlockNumber scanned_pages, double scanned_tuples)
Definition: vacuum.c:1305
IndexBulkDeleteResult * vac_cleanup_one_index(IndexVacuumInfo *ivinfo, IndexBulkDeleteResult *istat)
Definition: vacuum.c:2497
static int vac_cmp_itemptr(const void *left, const void *right)
Definition: vacuum.c:2571
#define VACOPT_FREEZE
Definition: vacuum.h:182
#define VACOPT_SKIP_LOCKED
Definition: vacuum.h:184
#define VACOPT_VACUUM
Definition: vacuum.h:179
#define VACOPT_VERBOSE
Definition: vacuum.h:181
#define MAXDEADITEMS(avail_mem)
Definition: vacuum.h:291
#define VACOPT_FULL
Definition: vacuum.h:183
#define VACOPT_SKIP_DATABASE_STATS
Definition: vacuum.h:188
VacOptValue
Definition: vacuum.h:200
@ VACOPTVALUE_AUTO
Definition: vacuum.h:202
@ VACOPTVALUE_ENABLED
Definition: vacuum.h:204
@ VACOPTVALUE_UNSPECIFIED
Definition: vacuum.h:201
@ VACOPTVALUE_DISABLED
Definition: vacuum.h:203
#define VACOPT_PROCESS_TOAST
Definition: vacuum.h:186
#define VACOPT_DISABLE_PAGE_SKIPPING
Definition: vacuum.h:187
#define VACOPT_ONLY_DATABASE_STATS
Definition: vacuum.h:189
#define VACOPT_PROCESS_MAIN
Definition: vacuum.h:185
#define VACOPT_ANALYZE
Definition: vacuum.h:180
void SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid)
Definition: varsup.c:345
bool ForceTransactionIdLimitUpdate(void)
Definition: varsup.c:490
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: wait_event.h:88
static void pgstat_report_wait_end(void)
Definition: wait_event.h:104
bool IsInTransactionBlock(bool isTopLevel)
Definition: xact.c:3612
void CommandCounterIncrement(void)
Definition: xact.c:1078
void PreventInTransactionBlock(bool isTopLevel, const char *stmtType)
Definition: xact.c:3481
void StartTransactionCommand(void)
Definition: xact.c:2937
void CommitTransactionCommand(void)
Definition: xact.c:3034