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