1 /*-------------------------------------------------------------------------
4 * The postgres vacuum cleaner.
6 * This file now includes only control and dispatch code for VACUUM and
7 * ANALYZE commands. Regular VACUUM is implemented in vacuumlazy.c,
8 * ANALYZE in analyze.c, and VACUUM FULL is a variant of CLUSTER, handled
12 * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group
13 * Portions Copyright (c) 1994, Regents of the University of California
17 * src/backend/commands/vacuum.c
19 *-------------------------------------------------------------------------
25 #include "access/clog.h"
26 #include "access/commit_ts.h"
27 #include "access/genam.h"
28 #include "access/heapam.h"
29 #include "access/htup_details.h"
30 #include "access/multixact.h"
31 #include "access/tableam.h"
32 #include "access/transam.h"
33 #include "access/xact.h"
34 #include "catalog/namespace.h"
35 #include "catalog/pg_database.h"
36 #include "catalog/pg_inherits.h"
37 #include "catalog/pg_namespace.h"
38 #include "commands/cluster.h"
39 #include "commands/defrem.h"
40 #include "commands/vacuum.h"
41 #include "miscadmin.h"
42 #include "nodes/makefuncs.h"
44 #include "postmaster/autovacuum.h"
45 #include "storage/bufmgr.h"
46 #include "storage/lmgr.h"
47 #include "storage/proc.h"
48 #include "storage/procarray.h"
49 #include "utils/acl.h"
50 #include "utils/fmgroids.h"
51 #include "utils/guc.h"
52 #include "utils/memutils.h"
53 #include "utils/snapmgr.h"
54 #include "utils/syscache.h"
60 int vacuum_freeze_min_age;
61 int vacuum_freeze_table_age;
62 int vacuum_multixact_freeze_min_age;
63 int vacuum_multixact_freeze_table_age;
66 /* A few variables that don't seem worth passing around as parameters */
67 static MemoryContext vac_context = NULL;
68 static BufferAccessStrategy vac_strategy;
71 /* non-export function prototypes */
72 static List *expand_vacuum_rel(VacuumRelation *vrel, int options);
73 static List *get_all_vacuum_rels(int options);
74 static void vac_truncate_clog(TransactionId frozenXID,
76 TransactionId lastSaneFrozenXid,
77 MultiXactId lastSaneMinMulti);
78 static bool vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params);
79 static VacOptTernaryValue get_vacopt_ternary_value(DefElem *def);
82 * Primary entry point for manual VACUUM and ANALYZE commands
84 * This is mainly a preparation wrapper for the real operations that will
88 ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
92 bool skip_locked = false;
96 bool disable_page_skipping = false;
99 /* Set default value */
100 params.index_cleanup = VACOPT_TERNARY_DEFAULT;
102 /* Parse options list */
103 foreach(lc, vacstmt->options)
105 DefElem *opt = (DefElem *) lfirst(lc);
107 /* Parse common options for VACUUM and ANALYZE */
108 if (strcmp(opt->defname, "verbose") == 0)
109 verbose = defGetBoolean(opt);
110 else if (strcmp(opt->defname, "skip_locked") == 0)
111 skip_locked = defGetBoolean(opt);
112 else if (!vacstmt->is_vacuumcmd)
114 (errcode(ERRCODE_SYNTAX_ERROR),
115 errmsg("unrecognized ANALYZE option \"%s\"", opt->defname),
116 parser_errposition(pstate, opt->location)));
118 /* Parse options available on VACUUM */
119 else if (strcmp(opt->defname, "analyze") == 0)
120 analyze = defGetBoolean(opt);
121 else if (strcmp(opt->defname, "freeze") == 0)
122 freeze = defGetBoolean(opt);
123 else if (strcmp(opt->defname, "full") == 0)
124 full = defGetBoolean(opt);
125 else if (strcmp(opt->defname, "disable_page_skipping") == 0)
126 disable_page_skipping = defGetBoolean(opt);
127 else if (strcmp(opt->defname, "index_cleanup") == 0)
128 params.index_cleanup = get_vacopt_ternary_value(opt);
131 (errcode(ERRCODE_SYNTAX_ERROR),
132 errmsg("unrecognized VACUUM option \"%s\"", opt->defname),
133 parser_errposition(pstate, opt->location)));
136 /* Set vacuum options */
138 (vacstmt->is_vacuumcmd ? VACOPT_VACUUM : VACOPT_ANALYZE) |
139 (verbose ? VACOPT_VERBOSE : 0) |
140 (skip_locked ? VACOPT_SKIP_LOCKED : 0) |
141 (analyze ? VACOPT_ANALYZE : 0) |
142 (freeze ? VACOPT_FREEZE : 0) |
143 (full ? VACOPT_FULL : 0) |
144 (disable_page_skipping ? VACOPT_DISABLE_PAGE_SKIPPING : 0);
146 /* sanity checks on options */
147 Assert(params.options & (VACOPT_VACUUM | VACOPT_ANALYZE));
148 Assert((params.options & VACOPT_VACUUM) ||
149 !(params.options & (VACOPT_FULL | VACOPT_FREEZE)));
150 Assert(!(params.options & VACOPT_SKIPTOAST));
153 * Make sure VACOPT_ANALYZE is specified if any column lists are present.
155 if (!(params.options & VACOPT_ANALYZE))
159 foreach(lc, vacstmt->rels)
161 VacuumRelation *vrel = lfirst_node(VacuumRelation, lc);
163 if (vrel->va_cols != NIL)
165 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
166 errmsg("ANALYZE option must be specified when a column list is provided")));
171 * All freeze ages are zero if the FREEZE option is given; otherwise pass
172 * them as -1 which means to use the default values.
174 if (params.options & VACOPT_FREEZE)
176 params.freeze_min_age = 0;
177 params.freeze_table_age = 0;
178 params.multixact_freeze_min_age = 0;
179 params.multixact_freeze_table_age = 0;
183 params.freeze_min_age = -1;
184 params.freeze_table_age = -1;
185 params.multixact_freeze_min_age = -1;
186 params.multixact_freeze_table_age = -1;
189 /* user-invoked vacuum is never "for wraparound" */
190 params.is_wraparound = false;
192 /* user-invoked vacuum never uses this parameter */
193 params.log_min_duration = -1;
195 /* Now go through the common routine */
196 vacuum(vacstmt->rels, ¶ms, NULL, isTopLevel);
200 * Internal entry point for VACUUM and ANALYZE commands.
202 * relations, if not NIL, is a list of VacuumRelation to process; otherwise,
203 * we process all relevant tables in the database. For each VacuumRelation,
204 * if a valid OID is supplied, the table with that OID is what to process;
205 * otherwise, the VacuumRelation's RangeVar indicates what to process.
207 * params contains a set of parameters that can be used to customize the
210 * bstrategy is normally given as NULL, but in autovacuum it can be passed
211 * in to use the same buffer strategy object across multiple vacuum() calls.
213 * isTopLevel should be passed down from ProcessUtility.
215 * It is the caller's responsibility that all parameters are allocated in a
216 * memory context that will not disappear at transaction commit.
219 vacuum(List *relations, VacuumParams *params,
220 BufferAccessStrategy bstrategy, bool isTopLevel)
222 static bool in_vacuum = false;
224 const char *stmttype;
225 volatile bool in_outer_xact,
228 Assert(params != NULL);
230 stmttype = (params->options & VACOPT_VACUUM) ? "VACUUM" : "ANALYZE";
233 * We cannot run VACUUM inside a user transaction block; if we were inside
234 * a transaction, then our commit- and start-transaction-command calls
235 * would not have the intended effect! There are numerous other subtle
236 * dependencies on this, too.
238 * ANALYZE (without VACUUM) can run either way.
240 if (params->options & VACOPT_VACUUM)
242 PreventInTransactionBlock(isTopLevel, stmttype);
243 in_outer_xact = false;
246 in_outer_xact = IsInTransactionBlock(isTopLevel);
249 * Due to static variables vac_context, anl_context and vac_strategy,
250 * vacuum() is not reentrant. This matters when VACUUM FULL or ANALYZE
251 * calls a hostile index expression that itself calls ANALYZE.
255 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
256 errmsg("%s cannot be executed from VACUUM or ANALYZE",
260 * Sanity check DISABLE_PAGE_SKIPPING option.
262 if ((params->options & VACOPT_FULL) != 0 &&
263 (params->options & VACOPT_DISABLE_PAGE_SKIPPING) != 0)
265 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
266 errmsg("VACUUM option DISABLE_PAGE_SKIPPING cannot be used with FULL")));
269 * Send info about dead objects to the statistics collector, unless we are
270 * in autovacuum --- autovacuum.c does this for itself.
272 if ((params->options & VACOPT_VACUUM) && !IsAutoVacuumWorkerProcess())
273 pgstat_vacuum_stat();
276 * Create special memory context for cross-transaction storage.
278 * Since it is a child of PortalContext, it will go away eventually even
279 * if we suffer an error; there's no need for special abort cleanup logic.
281 vac_context = AllocSetContextCreate(PortalContext,
283 ALLOCSET_DEFAULT_SIZES);
286 * If caller didn't give us a buffer strategy object, make one in the
287 * cross-transaction memory context.
289 if (bstrategy == NULL)
291 MemoryContext old_context = MemoryContextSwitchTo(vac_context);
293 bstrategy = GetAccessStrategy(BAS_VACUUM);
294 MemoryContextSwitchTo(old_context);
296 vac_strategy = bstrategy;
299 * Build list of relation(s) to process, putting any new data in
300 * vac_context for safekeeping.
302 if (relations != NIL)
307 foreach(lc, relations)
309 VacuumRelation *vrel = lfirst_node(VacuumRelation, lc);
311 MemoryContext old_context;
313 sublist = expand_vacuum_rel(vrel, params->options);
314 old_context = MemoryContextSwitchTo(vac_context);
315 newrels = list_concat(newrels, sublist);
316 MemoryContextSwitchTo(old_context);
321 relations = get_all_vacuum_rels(params->options);
324 * Decide whether we need to start/commit our own transactions.
326 * For VACUUM (with or without ANALYZE): always do so, so that we can
327 * release locks as soon as possible. (We could possibly use the outer
328 * transaction for a one-table VACUUM, but handling TOAST tables would be
331 * For ANALYZE (no VACUUM): if inside a transaction block, we cannot
332 * start/commit our own transactions. Also, there's no need to do so if
333 * only processing one relation. For multiple relations when not within a
334 * transaction block, and also in an autovacuum worker, use own
335 * transactions so we can release locks sooner.
337 if (params->options & VACOPT_VACUUM)
338 use_own_xacts = true;
341 Assert(params->options & VACOPT_ANALYZE);
342 if (IsAutoVacuumWorkerProcess())
343 use_own_xacts = true;
344 else if (in_outer_xact)
345 use_own_xacts = false;
346 else if (list_length(relations) > 1)
347 use_own_xacts = true;
349 use_own_xacts = false;
353 * vacuum_rel expects to be entered with no transaction active; it will
354 * start and commit its own transaction. But we are called by an SQL
355 * command, and so we are executing inside a transaction already. We
356 * commit the transaction started in PostgresMain() here, and start
357 * another one before exiting to match the commit waiting for us back in
362 Assert(!in_outer_xact);
364 /* ActiveSnapshot is not set by autovacuum */
365 if (ActiveSnapshotSet())
368 /* matches the StartTransaction in PostgresMain() */
369 CommitTransactionCommand();
372 /* Turn vacuum cost accounting on or off, and set/clear in_vacuum */
378 VacuumCostActive = (VacuumCostDelay > 0);
379 VacuumCostBalance = 0;
385 * Loop to process each selected relation.
387 foreach(cur, relations)
389 VacuumRelation *vrel = lfirst_node(VacuumRelation, cur);
391 if (params->options & VACOPT_VACUUM)
393 if (!vacuum_rel(vrel->oid, vrel->relation, params))
397 if (params->options & VACOPT_ANALYZE)
400 * If using separate xacts, start one for analyze. Otherwise,
401 * we can use the outer transaction.
405 StartTransactionCommand();
406 /* functions in indexes may want a snapshot set */
407 PushActiveSnapshot(GetTransactionSnapshot());
410 analyze_rel(vrel->oid, vrel->relation, params,
411 vrel->va_cols, in_outer_xact, vac_strategy);
416 CommitTransactionCommand();
424 VacuumCostActive = false;
430 VacuumCostActive = false;
433 * Finish up processing.
437 /* here, we are not in a transaction */
440 * This matches the CommitTransaction waiting for us in
443 StartTransactionCommand();
446 if ((params->options & VACOPT_VACUUM) && !IsAutoVacuumWorkerProcess())
449 * Update pg_database.datfrozenxid, and truncate pg_xact if possible.
450 * (autovacuum.c does this for itself.)
452 vac_update_datfrozenxid();
456 * Clean up working storage --- note we must do this after
457 * StartTransactionCommand, else we might be trying to delete the active
460 MemoryContextDelete(vac_context);
465 * Check if a given relation can be safely vacuumed or analyzed. If the
466 * user is not the relation owner, issue a WARNING log message and return
467 * false to let the caller decide what to do with this relation. This
468 * routine is used to decide if a relation can be processed for VACUUM or
472 vacuum_is_relation_owner(Oid relid, Form_pg_class reltuple, int options)
476 Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0);
481 * We allow the user to vacuum or analyze a table if he is superuser, the
482 * table owner, or the database owner (but in the latter case, only if
483 * it's not a shared relation). pg_class_ownercheck includes the
486 * Note we choose to treat permissions failure as a WARNING and keep
487 * trying to vacuum or analyze the rest of the DB --- is this appropriate?
489 if (pg_class_ownercheck(relid, GetUserId()) ||
490 (pg_database_ownercheck(MyDatabaseId, GetUserId()) && !reltuple->relisshared))
493 relname = NameStr(reltuple->relname);
495 if ((options & VACOPT_VACUUM) != 0)
497 if (reltuple->relisshared)
499 (errmsg("skipping \"%s\" --- only superuser can vacuum it",
501 else if (reltuple->relnamespace == PG_CATALOG_NAMESPACE)
503 (errmsg("skipping \"%s\" --- only superuser or database owner can vacuum it",
507 (errmsg("skipping \"%s\" --- only table or database owner can vacuum it",
511 * For VACUUM ANALYZE, both logs could show up, but just generate
512 * information for VACUUM as that would be the first one to be
518 if ((options & VACOPT_ANALYZE) != 0)
520 if (reltuple->relisshared)
522 (errmsg("skipping \"%s\" --- only superuser can analyze it",
524 else if (reltuple->relnamespace == PG_CATALOG_NAMESPACE)
526 (errmsg("skipping \"%s\" --- only superuser or database owner can analyze it",
530 (errmsg("skipping \"%s\" --- only table or database owner can analyze it",
539 * vacuum_open_relation
541 * This routine is used for attempting to open and lock a relation which
542 * is going to be vacuumed or analyzed. If the relation cannot be opened
543 * or locked, a log is emitted if possible.
546 vacuum_open_relation(Oid relid, RangeVar *relation, int options,
547 bool verbose, LOCKMODE lmode)
550 bool rel_lock = true;
553 Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0);
556 * Open the relation and get the appropriate lock on it.
558 * There's a race condition here: the relation may have gone away since
559 * the last time we saw it. If so, we don't need to vacuum or analyze it.
561 * If we've been asked not to wait for the relation lock, acquire it first
562 * in non-blocking mode, before calling try_relation_open().
564 if (!(options & VACOPT_SKIP_LOCKED))
565 onerel = try_relation_open(relid, lmode);
566 else if (ConditionalLockRelationOid(relid, lmode))
567 onerel = try_relation_open(relid, NoLock);
574 /* if relation is opened, leave */
579 * Relation could not be opened, hence generate if possible a log
580 * informing on the situation.
582 * If the RangeVar is not defined, we do not have enough information to
583 * provide a meaningful log statement. Chances are that the caller has
584 * intentionally not provided this information so that this logging is
587 if (relation == NULL)
591 * Determine the log level.
593 * For manual VACUUM or ANALYZE, we emit a WARNING to match the log statements
594 * in the permission checks; otherwise, only log if the caller so requested.
596 if (!IsAutoVacuumWorkerProcess())
603 if ((options & VACOPT_VACUUM) != 0)
607 (errcode(ERRCODE_LOCK_NOT_AVAILABLE),
608 errmsg("skipping vacuum of \"%s\" --- lock not available",
609 relation->relname)));
612 (errcode(ERRCODE_UNDEFINED_TABLE),
613 errmsg("skipping vacuum of \"%s\" --- relation no longer exists",
614 relation->relname)));
617 * For VACUUM ANALYZE, both logs could show up, but just generate
618 * information for VACUUM as that would be the first one to be
624 if ((options & VACOPT_ANALYZE) != 0)
628 (errcode(ERRCODE_LOCK_NOT_AVAILABLE),
629 errmsg("skipping analyze of \"%s\" --- lock not available",
630 relation->relname)));
633 (errcode(ERRCODE_UNDEFINED_TABLE),
634 errmsg("skipping analyze of \"%s\" --- relation no longer exists",
635 relation->relname)));
643 * Given a VacuumRelation, fill in the table OID if it wasn't specified,
644 * and optionally add VacuumRelations for partitions of the table.
646 * If a VacuumRelation does not have an OID supplied and is a partitioned
647 * table, an extra entry will be added to the output for each partition.
648 * Presently, only autovacuum supplies OIDs when calling vacuum(), and
649 * it does not want us to expand partitioned tables.
651 * We take care not to modify the input data structure, but instead build
652 * new VacuumRelation(s) to return. (But note that they will reference
653 * unmodified parts of the input, eg column lists.) New data structures
654 * are made in vac_context.
657 expand_vacuum_rel(VacuumRelation *vrel, int options)
660 MemoryContext oldcontext;
662 /* If caller supplied OID, there's nothing we need do here. */
663 if (OidIsValid(vrel->oid))
665 oldcontext = MemoryContextSwitchTo(vac_context);
666 vacrels = lappend(vacrels, vrel);
667 MemoryContextSwitchTo(oldcontext);
671 /* Process a specific relation, and possibly partitions thereof */
674 Form_pg_class classForm;
679 * Since autovacuum workers supply OIDs when calling vacuum(), no
680 * autovacuum worker should reach this code.
682 Assert(!IsAutoVacuumWorkerProcess());
685 * We transiently take AccessShareLock to protect the syscache lookup
686 * below, as well as find_all_inheritors's expectation that the caller
687 * holds some lock on the starting relation.
689 rvr_opts = (options & VACOPT_SKIP_LOCKED) ? RVR_SKIP_LOCKED : 0;
690 relid = RangeVarGetRelidExtended(vrel->relation,
696 * If the lock is unavailable, emit the same log statement that
697 * vacuum_rel() and analyze_rel() would.
699 if (!OidIsValid(relid))
701 if (options & VACOPT_VACUUM)
703 (errcode(ERRCODE_LOCK_NOT_AVAILABLE),
704 errmsg("skipping vacuum of \"%s\" --- lock not available",
705 vrel->relation->relname)));
708 (errcode(ERRCODE_LOCK_NOT_AVAILABLE),
709 errmsg("skipping analyze of \"%s\" --- lock not available",
710 vrel->relation->relname)));
715 * To check whether the relation is a partitioned table and its
716 * ownership, fetch its syscache entry.
718 tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
719 if (!HeapTupleIsValid(tuple))
720 elog(ERROR, "cache lookup failed for relation %u", relid);
721 classForm = (Form_pg_class) GETSTRUCT(tuple);
724 * Make a returnable VacuumRelation for this rel if user is a proper
727 if (vacuum_is_relation_owner(relid, classForm, options))
729 oldcontext = MemoryContextSwitchTo(vac_context);
730 vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation,
733 MemoryContextSwitchTo(oldcontext);
737 include_parts = (classForm->relkind == RELKIND_PARTITIONED_TABLE);
738 ReleaseSysCache(tuple);
741 * If it is, make relation list entries for its partitions. Note that
742 * the list returned by find_all_inheritors() includes the passed-in
743 * OID, so we have to skip that. There's no point in taking locks on
744 * the individual partitions yet, and doing so would just add
745 * unnecessary deadlock risk. For this last reason we do not check
746 * yet the ownership of the partitions, which get added to the list to
747 * process. Ownership will be checked later on anyway.
751 List *part_oids = find_all_inheritors(relid, NoLock, NULL);
754 foreach(part_lc, part_oids)
756 Oid part_oid = lfirst_oid(part_lc);
758 if (part_oid == relid)
759 continue; /* ignore original table */
762 * We omit a RangeVar since it wouldn't be appropriate to
763 * complain about failure to open one of these relations
766 oldcontext = MemoryContextSwitchTo(vac_context);
767 vacrels = lappend(vacrels, makeVacuumRelation(NULL,
770 MemoryContextSwitchTo(oldcontext);
775 * Release lock again. This means that by the time we actually try to
776 * process the table, it might be gone or renamed. In the former case
777 * we'll silently ignore it; in the latter case we'll process it
778 * anyway, but we must beware that the RangeVar doesn't necessarily
779 * identify it anymore. This isn't ideal, perhaps, but there's little
780 * practical alternative, since we're typically going to commit this
781 * transaction and begin a new one between now and then. Moreover,
782 * holding locks on multiple relations would create significant risk
785 UnlockRelationOid(relid, AccessShareLock);
792 * Construct a list of VacuumRelations for all vacuumable rels in
793 * the current database. The list is built in vac_context.
796 get_all_vacuum_rels(int options)
803 pgclass = table_open(RelationRelationId, AccessShareLock);
805 scan = table_beginscan_catalog(pgclass, 0, NULL);
807 while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
809 Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple);
810 MemoryContext oldcontext;
811 Oid relid = classForm->oid;
813 /* check permissions of relation */
814 if (!vacuum_is_relation_owner(relid, classForm, options))
818 * We include partitioned tables here; depending on which operation is
819 * to be performed, caller will decide whether to process or ignore
822 if (classForm->relkind != RELKIND_RELATION &&
823 classForm->relkind != RELKIND_MATVIEW &&
824 classForm->relkind != RELKIND_PARTITIONED_TABLE)
828 * Build VacuumRelation(s) specifying the table OIDs to be processed.
829 * We omit a RangeVar since it wouldn't be appropriate to complain
830 * about failure to open one of these relations later.
832 oldcontext = MemoryContextSwitchTo(vac_context);
833 vacrels = lappend(vacrels, makeVacuumRelation(NULL,
836 MemoryContextSwitchTo(oldcontext);
840 table_close(pgclass, AccessShareLock);
846 * vacuum_set_xid_limits() -- compute oldest-Xmin and freeze cutoff points
848 * The output parameters are:
849 * - oldestXmin is the cutoff value used to distinguish whether tuples are
850 * DEAD or RECENTLY_DEAD (see HeapTupleSatisfiesVacuum).
851 * - freezeLimit is the Xid below which all Xids are replaced by
852 * FrozenTransactionId during vacuum.
853 * - xidFullScanLimit (computed from table_freeze_age parameter)
854 * represents a minimum Xid value; a table whose relfrozenxid is older than
855 * this will have a full-table vacuum applied to it, to freeze tuples across
856 * the whole table. Vacuuming a table younger than this value can use a
858 * - multiXactCutoff is the value below which all MultiXactIds are removed from
860 * - mxactFullScanLimit is a value against which a table's relminmxid value is
861 * compared to produce a full-table vacuum, as with xidFullScanLimit.
863 * xidFullScanLimit and mxactFullScanLimit can be passed as NULL if caller is
867 vacuum_set_xid_limits(Relation rel,
869 int freeze_table_age,
870 int multixact_freeze_min_age,
871 int multixact_freeze_table_age,
872 TransactionId *oldestXmin,
873 TransactionId *freezeLimit,
874 TransactionId *xidFullScanLimit,
875 MultiXactId *multiXactCutoff,
876 MultiXactId *mxactFullScanLimit)
880 int effective_multixact_freeze_max_age;
882 TransactionId safeLimit;
883 MultiXactId mxactLimit;
884 MultiXactId safeMxactLimit;
887 * We can always ignore processes running lazy vacuum. This is because we
888 * use these values only for deciding which tuples we must keep in the
889 * tables. Since lazy vacuum doesn't write its XID anywhere, it's safe to
890 * ignore it. In theory it could be problematic to ignore lazy vacuums in
891 * a full vacuum, but keep in mind that only one vacuum process can be
892 * working on a particular table at any time, and that each vacuum is
893 * always an independent transaction.
896 TransactionIdLimitedForOldSnapshots(GetOldestXmin(rel, PROCARRAY_FLAGS_VACUUM), rel);
898 Assert(TransactionIdIsNormal(*oldestXmin));
901 * Determine the minimum freeze age to use: as specified by the caller, or
902 * vacuum_freeze_min_age, but in any case not more than half
903 * autovacuum_freeze_max_age, so that autovacuums to prevent XID
904 * wraparound won't occur too frequently.
906 freezemin = freeze_min_age;
908 freezemin = vacuum_freeze_min_age;
909 freezemin = Min(freezemin, autovacuum_freeze_max_age / 2);
910 Assert(freezemin >= 0);
913 * Compute the cutoff XID, being careful not to generate a "permanent" XID
915 limit = *oldestXmin - freezemin;
916 if (!TransactionIdIsNormal(limit))
917 limit = FirstNormalTransactionId;
920 * If oldestXmin is very far back (in practice, more than
921 * autovacuum_freeze_max_age / 2 XIDs old), complain and force a minimum
922 * freeze age of zero.
924 safeLimit = ReadNewTransactionId() - autovacuum_freeze_max_age;
925 if (!TransactionIdIsNormal(safeLimit))
926 safeLimit = FirstNormalTransactionId;
928 if (TransactionIdPrecedes(limit, safeLimit))
931 (errmsg("oldest xmin is far in the past"),
932 errhint("Close open transactions soon to avoid wraparound problems.\n"
933 "You might also need to commit or roll back old prepared transactions, or drop stale replication slots.")));
937 *freezeLimit = limit;
940 * Compute the multixact age for which freezing is urgent. This is
941 * normally autovacuum_multixact_freeze_max_age, but may be less if we are
942 * short of multixact member space.
944 effective_multixact_freeze_max_age = MultiXactMemberFreezeThreshold();
947 * Determine the minimum multixact freeze age to use: as specified by
948 * caller, or vacuum_multixact_freeze_min_age, but in any case not more
949 * than half effective_multixact_freeze_max_age, so that autovacuums to
950 * prevent MultiXact wraparound won't occur too frequently.
952 mxid_freezemin = multixact_freeze_min_age;
953 if (mxid_freezemin < 0)
954 mxid_freezemin = vacuum_multixact_freeze_min_age;
955 mxid_freezemin = Min(mxid_freezemin,
956 effective_multixact_freeze_max_age / 2);
957 Assert(mxid_freezemin >= 0);
959 /* compute the cutoff multi, being careful to generate a valid value */
960 mxactLimit = GetOldestMultiXactId() - mxid_freezemin;
961 if (mxactLimit < FirstMultiXactId)
962 mxactLimit = FirstMultiXactId;
965 ReadNextMultiXactId() - effective_multixact_freeze_max_age;
966 if (safeMxactLimit < FirstMultiXactId)
967 safeMxactLimit = FirstMultiXactId;
969 if (MultiXactIdPrecedes(mxactLimit, safeMxactLimit))
972 (errmsg("oldest multixact is far in the past"),
973 errhint("Close open transactions with multixacts soon to avoid wraparound problems.")));
974 mxactLimit = safeMxactLimit;
977 *multiXactCutoff = mxactLimit;
979 if (xidFullScanLimit != NULL)
983 Assert(mxactFullScanLimit != NULL);
986 * Determine the table freeze age to use: as specified by the caller,
987 * or vacuum_freeze_table_age, but in any case not more than
988 * autovacuum_freeze_max_age * 0.95, so that if you have e.g nightly
989 * VACUUM schedule, the nightly VACUUM gets a chance to freeze tuples
990 * before anti-wraparound autovacuum is launched.
992 freezetable = freeze_table_age;
994 freezetable = vacuum_freeze_table_age;
995 freezetable = Min(freezetable, autovacuum_freeze_max_age * 0.95);
996 Assert(freezetable >= 0);
999 * Compute XID limit causing a full-table vacuum, being careful not to
1000 * generate a "permanent" XID.
1002 limit = ReadNewTransactionId() - freezetable;
1003 if (!TransactionIdIsNormal(limit))
1004 limit = FirstNormalTransactionId;
1006 *xidFullScanLimit = limit;
1009 * Similar to the above, determine the table freeze age to use for
1010 * multixacts: as specified by the caller, or
1011 * vacuum_multixact_freeze_table_age, but in any case not more than
1012 * autovacuum_multixact_freeze_table_age * 0.95, so that if you have
1013 * e.g. nightly VACUUM schedule, the nightly VACUUM gets a chance to
1014 * freeze multixacts before anti-wraparound autovacuum is launched.
1016 freezetable = multixact_freeze_table_age;
1017 if (freezetable < 0)
1018 freezetable = vacuum_multixact_freeze_table_age;
1019 freezetable = Min(freezetable,
1020 effective_multixact_freeze_max_age * 0.95);
1021 Assert(freezetable >= 0);
1024 * Compute MultiXact limit causing a full-table vacuum, being careful
1025 * to generate a valid MultiXact value.
1027 mxactLimit = ReadNextMultiXactId() - freezetable;
1028 if (mxactLimit < FirstMultiXactId)
1029 mxactLimit = FirstMultiXactId;
1031 *mxactFullScanLimit = mxactLimit;
1035 Assert(mxactFullScanLimit == NULL);
1040 * vac_estimate_reltuples() -- estimate the new value for pg_class.reltuples
1042 * If we scanned the whole relation then we should just use the count of
1043 * live tuples seen; but if we did not, we should not blindly extrapolate
1044 * from that number, since VACUUM may have scanned a quite nonrandom
1045 * subset of the table. When we have only partial information, we take
1046 * the old value of pg_class.reltuples as a measurement of the
1047 * tuple density in the unscanned pages.
1049 * Note: scanned_tuples should count only *live* tuples, since
1050 * pg_class.reltuples is defined that way.
1053 vac_estimate_reltuples(Relation relation,
1054 BlockNumber total_pages,
1055 BlockNumber scanned_pages,
1056 double scanned_tuples)
1058 BlockNumber old_rel_pages = relation->rd_rel->relpages;
1059 double old_rel_tuples = relation->rd_rel->reltuples;
1061 double unscanned_pages;
1062 double total_tuples;
1064 /* If we did scan the whole table, just use the count as-is */
1065 if (scanned_pages >= total_pages)
1066 return scanned_tuples;
1069 * If scanned_pages is zero but total_pages isn't, keep the existing value
1070 * of reltuples. (Note: callers should avoid updating the pg_class
1071 * statistics in this situation, since no new information has been
1074 if (scanned_pages == 0)
1075 return old_rel_tuples;
1078 * If old value of relpages is zero, old density is indeterminate; we
1079 * can't do much except scale up scanned_tuples to match total_pages.
1081 if (old_rel_pages == 0)
1082 return floor((scanned_tuples / scanned_pages) * total_pages + 0.5);
1085 * Okay, we've covered the corner cases. The normal calculation is to
1086 * convert the old measurement to a density (tuples per page), then
1087 * estimate the number of tuples in the unscanned pages using that figure,
1088 * and finally add on the number of tuples in the scanned pages.
1090 old_density = old_rel_tuples / old_rel_pages;
1091 unscanned_pages = (double) total_pages - (double) scanned_pages;
1092 total_tuples = old_density * unscanned_pages + scanned_tuples;
1093 return floor(total_tuples + 0.5);
1098 * vac_update_relstats() -- update statistics for one relation
1100 * Update the whole-relation statistics that are kept in its pg_class
1101 * row. There are additional stats that will be updated if we are
1102 * doing ANALYZE, but we always update these stats. This routine works
1103 * for both index and heap relation entries in pg_class.
1105 * We violate transaction semantics here by overwriting the rel's
1106 * existing pg_class tuple with the new values. This is reasonably
1107 * safe as long as we're sure that the new values are correct whether or
1108 * not this transaction commits. The reason for doing this is that if
1109 * we updated these tuples in the usual way, vacuuming pg_class itself
1110 * wouldn't work very well --- by the time we got done with a vacuum
1111 * cycle, most of the tuples in pg_class would've been obsoleted. Of
1112 * course, this only works for fixed-size not-null columns, but these are.
1114 * Another reason for doing it this way is that when we are in a lazy
1115 * VACUUM and have PROC_IN_VACUUM set, we mustn't do any regular updates.
1116 * Somebody vacuuming pg_class might think they could delete a tuple
1117 * marked with xmin = our xid.
1119 * In addition to fundamentally nontransactional statistics such as
1120 * relpages and relallvisible, we try to maintain certain lazily-updated
1121 * DDL flags such as relhasindex, by clearing them if no longer correct.
1122 * It's safe to do this in VACUUM, which can't run in parallel with
1123 * CREATE INDEX/RULE/TRIGGER and can't be part of a transaction block.
1124 * However, it's *not* safe to do it in an ANALYZE that's within an
1125 * outer transaction, because for example the current transaction might
1126 * have dropped the last index; then we'd think relhasindex should be
1127 * cleared, but if the transaction later rolls back this would be wrong.
1128 * So we refrain from updating the DDL flags if we're inside an outer
1129 * transaction. This is OK since postponing the flag maintenance is
1132 * Note: num_tuples should count only *live* tuples, since
1133 * pg_class.reltuples is defined that way.
1135 * This routine is shared by VACUUM and ANALYZE.
1138 vac_update_relstats(Relation relation,
1139 BlockNumber num_pages, double num_tuples,
1140 BlockNumber num_all_visible_pages,
1141 bool hasindex, TransactionId frozenxid,
1142 MultiXactId minmulti,
1145 Oid relid = RelationGetRelid(relation);
1148 Form_pg_class pgcform;
1151 rd = table_open(RelationRelationId, RowExclusiveLock);
1153 /* Fetch a copy of the tuple to scribble on */
1154 ctup = SearchSysCacheCopy1(RELOID, ObjectIdGetDatum(relid));
1155 if (!HeapTupleIsValid(ctup))
1156 elog(ERROR, "pg_class entry for relid %u vanished during vacuuming",
1158 pgcform = (Form_pg_class) GETSTRUCT(ctup);
1160 /* Apply statistical updates, if any, to copied tuple */
1163 if (pgcform->relpages != (int32) num_pages)
1165 pgcform->relpages = (int32) num_pages;
1168 if (pgcform->reltuples != (float4) num_tuples)
1170 pgcform->reltuples = (float4) num_tuples;
1173 if (pgcform->relallvisible != (int32) num_all_visible_pages)
1175 pgcform->relallvisible = (int32) num_all_visible_pages;
1179 /* Apply DDL updates, but not inside an outer transaction (see above) */
1184 * If we didn't find any indexes, reset relhasindex.
1186 if (pgcform->relhasindex && !hasindex)
1188 pgcform->relhasindex = false;
1192 /* We also clear relhasrules and relhastriggers if needed */
1193 if (pgcform->relhasrules && relation->rd_rules == NULL)
1195 pgcform->relhasrules = false;
1198 if (pgcform->relhastriggers && relation->trigdesc == NULL)
1200 pgcform->relhastriggers = false;
1206 * Update relfrozenxid, unless caller passed InvalidTransactionId
1207 * indicating it has no new data.
1209 * Ordinarily, we don't let relfrozenxid go backwards: if things are
1210 * working correctly, the only way the new frozenxid could be older would
1211 * be if a previous VACUUM was done with a tighter freeze_min_age, in
1212 * which case we don't want to forget the work it already did. However,
1213 * if the stored relfrozenxid is "in the future", then it must be corrupt
1214 * and it seems best to overwrite it with the cutoff we used this time.
1215 * This should match vac_update_datfrozenxid() concerning what we consider
1216 * to be "in the future".
1218 if (TransactionIdIsNormal(frozenxid) &&
1219 pgcform->relfrozenxid != frozenxid &&
1220 (TransactionIdPrecedes(pgcform->relfrozenxid, frozenxid) ||
1221 TransactionIdPrecedes(ReadNewTransactionId(),
1222 pgcform->relfrozenxid)))
1224 pgcform->relfrozenxid = frozenxid;
1228 /* Similarly for relminmxid */
1229 if (MultiXactIdIsValid(minmulti) &&
1230 pgcform->relminmxid != minmulti &&
1231 (MultiXactIdPrecedes(pgcform->relminmxid, minmulti) ||
1232 MultiXactIdPrecedes(ReadNextMultiXactId(), pgcform->relminmxid)))
1234 pgcform->relminmxid = minmulti;
1238 /* If anything changed, write out the tuple. */
1240 heap_inplace_update(rd, ctup);
1242 table_close(rd, RowExclusiveLock);
1247 * vac_update_datfrozenxid() -- update pg_database.datfrozenxid for our DB
1249 * Update pg_database's datfrozenxid entry for our database to be the
1250 * minimum of the pg_class.relfrozenxid values.
1252 * Similarly, update our datminmxid to be the minimum of the
1253 * pg_class.relminmxid values.
1255 * If we are able to advance either pg_database value, also try to
1256 * truncate pg_xact and pg_multixact.
1258 * We violate transaction semantics here by overwriting the database's
1259 * existing pg_database tuple with the new values. This is reasonably
1260 * safe since the new values are correct whether or not this transaction
1261 * commits. As with vac_update_relstats, this avoids leaving dead tuples
1262 * behind after a VACUUM.
1265 vac_update_datfrozenxid(void)
1268 Form_pg_database dbform;
1272 TransactionId newFrozenXid;
1273 MultiXactId newMinMulti;
1274 TransactionId lastSaneFrozenXid;
1275 MultiXactId lastSaneMinMulti;
1280 * Initialize the "min" calculation with GetOldestXmin, which is a
1281 * reasonable approximation to the minimum relfrozenxid for not-yet-
1282 * committed pg_class entries for new tables; see AddNewRelationTuple().
1283 * So we cannot produce a wrong minimum by starting with this.
1285 newFrozenXid = GetOldestXmin(NULL, PROCARRAY_FLAGS_VACUUM);
1288 * Similarly, initialize the MultiXact "min" with the value that would be
1289 * used on pg_class for new tables. See AddNewRelationTuple().
1291 newMinMulti = GetOldestMultiXactId();
1294 * Identify the latest relfrozenxid and relminmxid values that we could
1295 * validly see during the scan. These are conservative values, but it's
1296 * not really worth trying to be more exact.
1298 lastSaneFrozenXid = ReadNewTransactionId();
1299 lastSaneMinMulti = ReadNextMultiXactId();
1302 * We must seqscan pg_class to find the minimum Xid, because there is no
1303 * index that can help us here.
1305 relation = table_open(RelationRelationId, AccessShareLock);
1307 scan = systable_beginscan(relation, InvalidOid, false,
1310 while ((classTup = systable_getnext(scan)) != NULL)
1312 Form_pg_class classForm = (Form_pg_class) GETSTRUCT(classTup);
1315 * Only consider relations able to hold unfrozen XIDs (anything else
1316 * should have InvalidTransactionId in relfrozenxid anyway.)
1318 if (classForm->relkind != RELKIND_RELATION &&
1319 classForm->relkind != RELKIND_MATVIEW &&
1320 classForm->relkind != RELKIND_TOASTVALUE)
1323 Assert(TransactionIdIsNormal(classForm->relfrozenxid));
1324 Assert(MultiXactIdIsValid(classForm->relminmxid));
1327 * If things are working properly, no relation should have a
1328 * relfrozenxid or relminmxid that is "in the future". However, such
1329 * cases have been known to arise due to bugs in pg_upgrade. If we
1330 * see any entries that are "in the future", chicken out and don't do
1331 * anything. This ensures we won't truncate clog before those
1332 * relations have been scanned and cleaned up.
1334 if (TransactionIdPrecedes(lastSaneFrozenXid, classForm->relfrozenxid) ||
1335 MultiXactIdPrecedes(lastSaneMinMulti, classForm->relminmxid))
1341 if (TransactionIdPrecedes(classForm->relfrozenxid, newFrozenXid))
1342 newFrozenXid = classForm->relfrozenxid;
1344 if (MultiXactIdPrecedes(classForm->relminmxid, newMinMulti))
1345 newMinMulti = classForm->relminmxid;
1348 /* we're done with pg_class */
1349 systable_endscan(scan);
1350 table_close(relation, AccessShareLock);
1352 /* chicken out if bogus data found */
1356 Assert(TransactionIdIsNormal(newFrozenXid));
1357 Assert(MultiXactIdIsValid(newMinMulti));
1359 /* Now fetch the pg_database tuple we need to update. */
1360 relation = table_open(DatabaseRelationId, RowExclusiveLock);
1362 /* Fetch a copy of the tuple to scribble on */
1363 tuple = SearchSysCacheCopy1(DATABASEOID, ObjectIdGetDatum(MyDatabaseId));
1364 if (!HeapTupleIsValid(tuple))
1365 elog(ERROR, "could not find tuple for database %u", MyDatabaseId);
1366 dbform = (Form_pg_database) GETSTRUCT(tuple);
1369 * As in vac_update_relstats(), we ordinarily don't want to let
1370 * datfrozenxid go backward; but if it's "in the future" then it must be
1371 * corrupt and it seems best to overwrite it.
1373 if (dbform->datfrozenxid != newFrozenXid &&
1374 (TransactionIdPrecedes(dbform->datfrozenxid, newFrozenXid) ||
1375 TransactionIdPrecedes(lastSaneFrozenXid, dbform->datfrozenxid)))
1377 dbform->datfrozenxid = newFrozenXid;
1381 newFrozenXid = dbform->datfrozenxid;
1383 /* Ditto for datminmxid */
1384 if (dbform->datminmxid != newMinMulti &&
1385 (MultiXactIdPrecedes(dbform->datminmxid, newMinMulti) ||
1386 MultiXactIdPrecedes(lastSaneMinMulti, dbform->datminmxid)))
1388 dbform->datminmxid = newMinMulti;
1392 newMinMulti = dbform->datminmxid;
1395 heap_inplace_update(relation, tuple);
1397 heap_freetuple(tuple);
1398 table_close(relation, RowExclusiveLock);
1401 * If we were able to advance datfrozenxid or datminmxid, see if we can
1402 * truncate pg_xact and/or pg_multixact. Also do it if the shared
1403 * XID-wrap-limit info is stale, since this action will update that too.
1405 if (dirty || ForceTransactionIdLimitUpdate())
1406 vac_truncate_clog(newFrozenXid, newMinMulti,
1407 lastSaneFrozenXid, lastSaneMinMulti);
1412 * vac_truncate_clog() -- attempt to truncate the commit log
1414 * Scan pg_database to determine the system-wide oldest datfrozenxid,
1415 * and use it to truncate the transaction commit log (pg_xact).
1416 * Also update the XID wrap limit info maintained by varsup.c.
1417 * Likewise for datminmxid.
1419 * The passed frozenXID and minMulti are the updated values for my own
1420 * pg_database entry. They're used to initialize the "min" calculations.
1421 * The caller also passes the "last sane" XID and MXID, since it has
1422 * those at hand already.
1424 * This routine is only invoked when we've managed to change our
1425 * DB's datfrozenxid/datminmxid values, or we found that the shared
1426 * XID-wrap-limit info is stale.
1429 vac_truncate_clog(TransactionId frozenXID,
1430 MultiXactId minMulti,
1431 TransactionId lastSaneFrozenXid,
1432 MultiXactId lastSaneMinMulti)
1434 TransactionId nextXID = ReadNewTransactionId();
1438 Oid oldestxid_datoid;
1439 Oid minmulti_datoid;
1441 bool frozenAlreadyWrapped = false;
1443 /* init oldest datoids to sync with my frozenXID/minMulti values */
1444 oldestxid_datoid = MyDatabaseId;
1445 minmulti_datoid = MyDatabaseId;
1448 * Scan pg_database to compute the minimum datfrozenxid/datminmxid
1450 * Since vac_update_datfrozenxid updates datfrozenxid/datminmxid in-place,
1451 * the values could change while we look at them. Fetch each one just
1452 * once to ensure sane behavior of the comparison logic. (Here, as in
1453 * many other places, we assume that fetching or updating an XID in shared
1454 * storage is atomic.)
1456 * Note: we need not worry about a race condition with new entries being
1457 * inserted by CREATE DATABASE. Any such entry will have a copy of some
1458 * existing DB's datfrozenxid, and that source DB cannot be ours because
1459 * of the interlock against copying a DB containing an active backend.
1460 * Hence the new entry will not reduce the minimum. Also, if two VACUUMs
1461 * concurrently modify the datfrozenxid's of different databases, the
1462 * worst possible outcome is that pg_xact is not truncated as aggressively
1465 relation = table_open(DatabaseRelationId, AccessShareLock);
1467 scan = table_beginscan_catalog(relation, 0, NULL);
1469 while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
1471 volatile FormData_pg_database *dbform = (Form_pg_database) GETSTRUCT(tuple);
1472 TransactionId datfrozenxid = dbform->datfrozenxid;
1473 TransactionId datminmxid = dbform->datminmxid;
1475 Assert(TransactionIdIsNormal(datfrozenxid));
1476 Assert(MultiXactIdIsValid(datminmxid));
1479 * If things are working properly, no database should have a
1480 * datfrozenxid or datminmxid that is "in the future". However, such
1481 * cases have been known to arise due to bugs in pg_upgrade. If we
1482 * see any entries that are "in the future", chicken out and don't do
1483 * anything. This ensures we won't truncate clog before those
1484 * databases have been scanned and cleaned up. (We will issue the
1485 * "already wrapped" warning if appropriate, though.)
1487 if (TransactionIdPrecedes(lastSaneFrozenXid, datfrozenxid) ||
1488 MultiXactIdPrecedes(lastSaneMinMulti, datminmxid))
1491 if (TransactionIdPrecedes(nextXID, datfrozenxid))
1492 frozenAlreadyWrapped = true;
1493 else if (TransactionIdPrecedes(datfrozenxid, frozenXID))
1495 frozenXID = datfrozenxid;
1496 oldestxid_datoid = dbform->oid;
1499 if (MultiXactIdPrecedes(datminmxid, minMulti))
1501 minMulti = datminmxid;
1502 minmulti_datoid = dbform->oid;
1506 table_endscan(scan);
1508 table_close(relation, AccessShareLock);
1511 * Do not truncate CLOG if we seem to have suffered wraparound already;
1512 * the computed minimum XID might be bogus. This case should now be
1513 * impossible due to the defenses in GetNewTransactionId, but we keep the
1516 if (frozenAlreadyWrapped)
1519 (errmsg("some databases have not been vacuumed in over 2 billion transactions"),
1520 errdetail("You might have already suffered transaction-wraparound data loss.")));
1524 /* chicken out if data is bogus in any other way */
1529 * Advance the oldest value for commit timestamps before truncating, so
1530 * that if a user requests a timestamp for a transaction we're truncating
1531 * away right after this point, they get NULL instead of an ugly "file not
1532 * found" error from slru.c. This doesn't matter for xact/multixact
1533 * because they are not subject to arbitrary lookups from users.
1535 AdvanceOldestCommitTsXid(frozenXID);
1538 * Truncate CLOG, multixact and CommitTs to the oldest computed value.
1540 TruncateCLOG(frozenXID, oldestxid_datoid);
1541 TruncateCommitTs(frozenXID);
1542 TruncateMultiXact(minMulti, minmulti_datoid);
1545 * Update the wrap limit for GetNewTransactionId and creation of new
1546 * MultiXactIds. Note: these functions will also signal the postmaster
1547 * for an(other) autovac cycle if needed. XXX should we avoid possibly
1550 SetTransactionIdLimit(frozenXID, oldestxid_datoid);
1551 SetMultiXactIdLimit(minMulti, minmulti_datoid, false);
1556 * vacuum_rel() -- vacuum one heap relation
1558 * relid identifies the relation to vacuum. If relation is supplied,
1559 * use the name therein for reporting any failure to open/lock the rel;
1560 * do not use it once we've successfully opened the rel, since it might
1563 * Returns true if it's okay to proceed with a requested ANALYZE
1564 * operation on this table.
1566 * Doing one heap at a time incurs extra overhead, since we need to
1567 * check that the heap exists again just before we vacuum it. The
1568 * reason that we do this is so that vacuuming can be spread across
1569 * many small transactions. Otherwise, two-phase locking would require
1570 * us to lock the entire database during one pass of the vacuum cleaner.
1572 * At entry and exit, we are not inside a transaction.
1575 vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params)
1582 int save_sec_context;
1585 Assert(params != NULL);
1587 /* Begin a transaction for vacuuming this relation */
1588 StartTransactionCommand();
1591 * Functions in indexes may want a snapshot set. Also, setting a snapshot
1592 * ensures that RecentGlobalXmin is kept truly recent.
1594 PushActiveSnapshot(GetTransactionSnapshot());
1596 if (!(params->options & VACOPT_FULL))
1599 * In lazy vacuum, we can set the PROC_IN_VACUUM flag, which lets
1600 * other concurrent VACUUMs know that they can ignore this one while
1601 * determining their OldestXmin. (The reason we don't set it during a
1602 * full VACUUM is exactly that we may have to run user-defined
1603 * functions for functional indexes, and we want to make sure that if
1604 * they use the snapshot set above, any tuples it requires can't get
1605 * removed from other tables. An index function that depends on the
1606 * contents of other tables is arguably broken, but we won't break it
1607 * here by violating transaction semantics.)
1609 * We also set the VACUUM_FOR_WRAPAROUND flag, which is passed down by
1610 * autovacuum; it's used to avoid canceling a vacuum that was invoked
1613 * Note: these flags remain set until CommitTransaction or
1614 * AbortTransaction. We don't want to clear them until we reset
1615 * MyPgXact->xid/xmin, else OldestXmin might appear to go backwards,
1616 * which is probably Not Good.
1618 LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
1619 MyPgXact->vacuumFlags |= PROC_IN_VACUUM;
1620 if (params->is_wraparound)
1621 MyPgXact->vacuumFlags |= PROC_VACUUM_FOR_WRAPAROUND;
1622 LWLockRelease(ProcArrayLock);
1626 * Check for user-requested abort. Note we want this to be inside a
1627 * transaction, so xact.c doesn't issue useless WARNING.
1629 CHECK_FOR_INTERRUPTS();
1632 * Determine the type of lock we want --- hard exclusive lock for a FULL
1633 * vacuum, but just ShareUpdateExclusiveLock for concurrent vacuum. Either
1634 * way, we can be sure that no other backend is vacuuming the same table.
1636 lmode = (params->options & VACOPT_FULL) ?
1637 AccessExclusiveLock : ShareUpdateExclusiveLock;
1639 /* open the relation and get the appropriate lock on it */
1640 onerel = vacuum_open_relation(relid, relation, params->options,
1641 params->log_min_duration >= 0, lmode);
1643 /* leave if relation could not be opened or locked */
1646 PopActiveSnapshot();
1647 CommitTransactionCommand();
1652 * Check if relation needs to be skipped based on ownership. This check
1653 * happens also when building the relation list to vacuum for a manual
1654 * operation, and needs to be done additionally here as VACUUM could
1655 * happen across multiple transactions where relation ownership could have
1656 * changed in-between. Make sure to only generate logs for VACUUM in this
1659 if (!vacuum_is_relation_owner(RelationGetRelid(onerel),
1661 params->options & VACOPT_VACUUM))
1663 relation_close(onerel, lmode);
1664 PopActiveSnapshot();
1665 CommitTransactionCommand();
1670 * Check that it's of a vacuumable relkind.
1672 if (onerel->rd_rel->relkind != RELKIND_RELATION &&
1673 onerel->rd_rel->relkind != RELKIND_MATVIEW &&
1674 onerel->rd_rel->relkind != RELKIND_TOASTVALUE &&
1675 onerel->rd_rel->relkind != RELKIND_PARTITIONED_TABLE)
1678 (errmsg("skipping \"%s\" --- cannot vacuum non-tables or special system tables",
1679 RelationGetRelationName(onerel))));
1680 relation_close(onerel, lmode);
1681 PopActiveSnapshot();
1682 CommitTransactionCommand();
1687 * Silently ignore tables that are temp tables of other backends ---
1688 * trying to vacuum these will lead to great unhappiness, since their
1689 * contents are probably not up-to-date on disk. (We don't throw a
1690 * warning here; it would just lead to chatter during a database-wide
1693 if (RELATION_IS_OTHER_TEMP(onerel))
1695 relation_close(onerel, lmode);
1696 PopActiveSnapshot();
1697 CommitTransactionCommand();
1702 * Silently ignore partitioned tables as there is no work to be done. The
1703 * useful work is on their child partitions, which have been queued up for
1706 if (onerel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
1708 relation_close(onerel, lmode);
1709 PopActiveSnapshot();
1710 CommitTransactionCommand();
1711 /* It's OK to proceed with ANALYZE on this table */
1716 * Get a session-level lock too. This will protect our access to the
1717 * relation across multiple transactions, so that we can vacuum the
1718 * relation's TOAST table (if any) secure in the knowledge that no one is
1719 * deleting the parent relation.
1721 * NOTE: this cannot block, even if someone else is waiting for access,
1722 * because the lock manager knows that both lock requests are from the
1725 onerelid = onerel->rd_lockInfo.lockRelId;
1726 LockRelationIdForSession(&onerelid, lmode);
1728 /* Set index cleanup option based on reloptions if not yet */
1729 if (params->index_cleanup == VACOPT_TERNARY_DEFAULT)
1731 if (onerel->rd_options == NULL ||
1732 ((StdRdOptions *) onerel->rd_options)->vacuum_index_cleanup)
1733 params->index_cleanup = VACOPT_TERNARY_ENABLED;
1735 params->index_cleanup = VACOPT_TERNARY_DISABLED;
1739 * Remember the relation's TOAST relation for later, if the caller asked
1740 * us to process it. In VACUUM FULL, though, the toast table is
1741 * automatically rebuilt by cluster_rel so we shouldn't recurse to it.
1743 if (!(params->options & VACOPT_SKIPTOAST) && !(params->options & VACOPT_FULL))
1744 toast_relid = onerel->rd_rel->reltoastrelid;
1746 toast_relid = InvalidOid;
1749 * Switch to the table owner's userid, so that any index functions are run
1750 * as that user. Also lock down security-restricted operations and
1751 * arrange to make GUC variable changes local to this command. (This is
1752 * unnecessary, but harmless, for lazy VACUUM.)
1754 GetUserIdAndSecContext(&save_userid, &save_sec_context);
1755 SetUserIdAndSecContext(onerel->rd_rel->relowner,
1756 save_sec_context | SECURITY_RESTRICTED_OPERATION);
1757 save_nestlevel = NewGUCNestLevel();
1760 * Do the actual work --- either FULL or "lazy" vacuum
1762 if (params->options & VACOPT_FULL)
1764 int cluster_options = 0;
1766 /* close relation before vacuuming, but hold lock until commit */
1767 relation_close(onerel, NoLock);
1770 if ((params->options & VACOPT_VERBOSE) != 0)
1771 cluster_options |= CLUOPT_VERBOSE;
1773 /* VACUUM FULL is now a variant of CLUSTER; see cluster.c */
1774 cluster_rel(relid, InvalidOid, cluster_options);
1777 table_relation_vacuum(onerel, params, vac_strategy);
1779 /* Roll back any GUC changes executed by index functions */
1780 AtEOXact_GUC(false, save_nestlevel);
1782 /* Restore userid and security context */
1783 SetUserIdAndSecContext(save_userid, save_sec_context);
1785 /* all done with this class, but hold lock until commit */
1787 relation_close(onerel, NoLock);
1790 * Complete the transaction and free all temporary memory used.
1792 PopActiveSnapshot();
1793 CommitTransactionCommand();
1796 * If the relation has a secondary toast rel, vacuum that too while we
1797 * still hold the session lock on the master table. Note however that
1798 * "analyze" will not get done on the toast table. This is good, because
1799 * the toaster always uses hardcoded index access and statistics are
1800 * totally unimportant for toast relations.
1802 if (toast_relid != InvalidOid)
1803 vacuum_rel(toast_relid, NULL, params);
1806 * Now release the session-level lock on the master table.
1808 UnlockRelationIdForSession(&onerelid, lmode);
1810 /* Report that we really did it. */
1816 * Open all the vacuumable indexes of the given relation, obtaining the
1817 * specified kind of lock on each. Return an array of Relation pointers for
1818 * the indexes into *Irel, and the number of indexes into *nindexes.
1820 * We consider an index vacuumable if it is marked insertable (indisready).
1821 * If it isn't, probably a CREATE INDEX CONCURRENTLY command failed early in
1822 * execution, and what we have is too corrupt to be processable. We will
1823 * vacuum even if the index isn't indisvalid; this is important because in a
1824 * unique index, uniqueness checks will be performed anyway and had better not
1825 * hit dangling index pointers.
1828 vac_open_indexes(Relation relation, LOCKMODE lockmode,
1829 int *nindexes, Relation **Irel)
1832 ListCell *indexoidscan;
1835 Assert(lockmode != NoLock);
1837 indexoidlist = RelationGetIndexList(relation);
1839 /* allocate enough memory for all indexes */
1840 i = list_length(indexoidlist);
1843 *Irel = (Relation *) palloc(i * sizeof(Relation));
1847 /* collect just the ready indexes */
1849 foreach(indexoidscan, indexoidlist)
1851 Oid indexoid = lfirst_oid(indexoidscan);
1854 indrel = index_open(indexoid, lockmode);
1855 if (indrel->rd_index->indisready)
1856 (*Irel)[i++] = indrel;
1858 index_close(indrel, lockmode);
1863 list_free(indexoidlist);
1867 * Release the resources acquired by vac_open_indexes. Optionally release
1868 * the locks (say NoLock to keep 'em).
1871 vac_close_indexes(int nindexes, Relation *Irel, LOCKMODE lockmode)
1878 Relation ind = Irel[nindexes];
1880 index_close(ind, lockmode);
1886 * vacuum_delay_point --- check for interrupts and cost-based delay.
1888 * This should be called in each major loop of VACUUM processing,
1889 * typically once per page processed.
1892 vacuum_delay_point(void)
1894 /* Always check for interrupts */
1895 CHECK_FOR_INTERRUPTS();
1897 /* Nap if appropriate */
1898 if (VacuumCostActive && !InterruptPending &&
1899 VacuumCostBalance >= VacuumCostLimit)
1903 msec = VacuumCostDelay * VacuumCostBalance / VacuumCostLimit;
1904 if (msec > VacuumCostDelay * 4)
1905 msec = VacuumCostDelay * 4;
1907 pg_usleep((long) (msec * 1000));
1909 VacuumCostBalance = 0;
1911 /* update balance values for workers */
1912 AutoVacuumUpdateDelay();
1914 /* Might have gotten an interrupt while sleeping */
1915 CHECK_FOR_INTERRUPTS();
1920 * A wrapper function of defGetBoolean().
1922 * This function returns VACOPT_TERNARY_ENABLED and VACOPT_TERNARY_DISABLED
1923 * instead of true and false.
1925 static VacOptTernaryValue
1926 get_vacopt_ternary_value(DefElem *def)
1928 return defGetBoolean(def) ? VACOPT_TERNARY_ENABLED : VACOPT_TERNARY_DISABLED;