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/transam.h"
32 #include "access/xact.h"
33 #include "catalog/namespace.h"
34 #include "catalog/pg_database.h"
35 #include "catalog/pg_inherits.h"
36 #include "catalog/pg_namespace.h"
37 #include "commands/cluster.h"
38 #include "commands/vacuum.h"
39 #include "miscadmin.h"
40 #include "nodes/makefuncs.h"
42 #include "postmaster/autovacuum.h"
43 #include "storage/bufmgr.h"
44 #include "storage/lmgr.h"
45 #include "storage/proc.h"
46 #include "storage/procarray.h"
47 #include "utils/acl.h"
48 #include "utils/fmgroids.h"
49 #include "utils/guc.h"
50 #include "utils/memutils.h"
51 #include "utils/snapmgr.h"
52 #include "utils/syscache.h"
58 int vacuum_freeze_min_age;
59 int vacuum_freeze_table_age;
60 int vacuum_multixact_freeze_min_age;
61 int vacuum_multixact_freeze_table_age;
64 /* A few variables that don't seem worth passing around as parameters */
65 static MemoryContext vac_context = NULL;
66 static BufferAccessStrategy vac_strategy;
69 /* non-export function prototypes */
70 static List *expand_vacuum_rel(VacuumRelation *vrel, int options);
71 static List *get_all_vacuum_rels(int options);
72 static void vac_truncate_clog(TransactionId frozenXID,
74 TransactionId lastSaneFrozenXid,
75 MultiXactId lastSaneMinMulti);
76 static bool vacuum_rel(Oid relid, RangeVar *relation, int options,
77 VacuumParams *params);
80 * Primary entry point for manual VACUUM and ANALYZE commands
82 * This is mainly a preparation wrapper for the real operations that will
86 ExecVacuum(VacuumStmt *vacstmt, bool isTopLevel)
90 /* sanity checks on options */
91 Assert(vacstmt->options & (VACOPT_VACUUM | VACOPT_ANALYZE));
92 Assert((vacstmt->options & VACOPT_VACUUM) ||
93 !(vacstmt->options & (VACOPT_FULL | VACOPT_FREEZE)));
94 Assert(!(vacstmt->options & VACOPT_SKIPTOAST));
97 * Make sure VACOPT_ANALYZE is specified if any column lists are present.
99 if (!(vacstmt->options & VACOPT_ANALYZE))
103 foreach(lc, vacstmt->rels)
105 VacuumRelation *vrel = lfirst_node(VacuumRelation, lc);
107 if (vrel->va_cols != NIL)
109 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
110 errmsg("ANALYZE option must be specified when a column list is provided")));
115 * All freeze ages are zero if the FREEZE option is given; otherwise pass
116 * them as -1 which means to use the default values.
118 if (vacstmt->options & VACOPT_FREEZE)
120 params.freeze_min_age = 0;
121 params.freeze_table_age = 0;
122 params.multixact_freeze_min_age = 0;
123 params.multixact_freeze_table_age = 0;
127 params.freeze_min_age = -1;
128 params.freeze_table_age = -1;
129 params.multixact_freeze_min_age = -1;
130 params.multixact_freeze_table_age = -1;
133 /* user-invoked vacuum is never "for wraparound" */
134 params.is_wraparound = false;
136 /* user-invoked vacuum never uses this parameter */
137 params.log_min_duration = -1;
139 /* Now go through the common routine */
140 vacuum(vacstmt->options, vacstmt->rels, ¶ms, NULL, isTopLevel);
144 * Internal entry point for VACUUM and ANALYZE commands.
146 * options is a bitmask of VacuumOption flags, indicating what to do.
148 * relations, if not NIL, is a list of VacuumRelation to process; otherwise,
149 * we process all relevant tables in the database. For each VacuumRelation,
150 * if a valid OID is supplied, the table with that OID is what to process;
151 * otherwise, the VacuumRelation's RangeVar indicates what to process.
153 * params contains a set of parameters that can be used to customize the
156 * bstrategy is normally given as NULL, but in autovacuum it can be passed
157 * in to use the same buffer strategy object across multiple vacuum() calls.
159 * isTopLevel should be passed down from ProcessUtility.
161 * It is the caller's responsibility that all parameters are allocated in a
162 * memory context that will not disappear at transaction commit.
165 vacuum(int options, List *relations, VacuumParams *params,
166 BufferAccessStrategy bstrategy, bool isTopLevel)
168 static bool in_vacuum = false;
170 const char *stmttype;
171 volatile bool in_outer_xact,
174 Assert(params != NULL);
176 stmttype = (options & VACOPT_VACUUM) ? "VACUUM" : "ANALYZE";
179 * We cannot run VACUUM inside a user transaction block; if we were inside
180 * a transaction, then our commit- and start-transaction-command calls
181 * would not have the intended effect! There are numerous other subtle
182 * dependencies on this, too.
184 * ANALYZE (without VACUUM) can run either way.
186 if (options & VACOPT_VACUUM)
188 PreventInTransactionBlock(isTopLevel, stmttype);
189 in_outer_xact = false;
192 in_outer_xact = IsInTransactionBlock(isTopLevel);
195 * Due to static variables vac_context, anl_context and vac_strategy,
196 * vacuum() is not reentrant. This matters when VACUUM FULL or ANALYZE
197 * calls a hostile index expression that itself calls ANALYZE.
201 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
202 errmsg("%s cannot be executed from VACUUM or ANALYZE",
206 * Sanity check DISABLE_PAGE_SKIPPING option.
208 if ((options & VACOPT_FULL) != 0 &&
209 (options & VACOPT_DISABLE_PAGE_SKIPPING) != 0)
211 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
212 errmsg("VACUUM option DISABLE_PAGE_SKIPPING cannot be used with FULL")));
215 * Send info about dead objects to the statistics collector, unless we are
216 * in autovacuum --- autovacuum.c does this for itself.
218 if ((options & VACOPT_VACUUM) && !IsAutoVacuumWorkerProcess())
219 pgstat_vacuum_stat();
222 * Create special memory context for cross-transaction storage.
224 * Since it is a child of PortalContext, it will go away eventually even
225 * if we suffer an error; there's no need for special abort cleanup logic.
227 vac_context = AllocSetContextCreate(PortalContext,
229 ALLOCSET_DEFAULT_SIZES);
232 * If caller didn't give us a buffer strategy object, make one in the
233 * cross-transaction memory context.
235 if (bstrategy == NULL)
237 MemoryContext old_context = MemoryContextSwitchTo(vac_context);
239 bstrategy = GetAccessStrategy(BAS_VACUUM);
240 MemoryContextSwitchTo(old_context);
242 vac_strategy = bstrategy;
245 * Build list of relation(s) to process, putting any new data in
246 * vac_context for safekeeping.
248 if (relations != NIL)
253 foreach(lc, relations)
255 VacuumRelation *vrel = lfirst_node(VacuumRelation, lc);
257 MemoryContext old_context;
259 sublist = expand_vacuum_rel(vrel, options);
260 old_context = MemoryContextSwitchTo(vac_context);
261 newrels = list_concat(newrels, sublist);
262 MemoryContextSwitchTo(old_context);
267 relations = get_all_vacuum_rels(options);
270 * Decide whether we need to start/commit our own transactions.
272 * For VACUUM (with or without ANALYZE): always do so, so that we can
273 * release locks as soon as possible. (We could possibly use the outer
274 * transaction for a one-table VACUUM, but handling TOAST tables would be
277 * For ANALYZE (no VACUUM): if inside a transaction block, we cannot
278 * start/commit our own transactions. Also, there's no need to do so if
279 * only processing one relation. For multiple relations when not within a
280 * transaction block, and also in an autovacuum worker, use own
281 * transactions so we can release locks sooner.
283 if (options & VACOPT_VACUUM)
284 use_own_xacts = true;
287 Assert(options & VACOPT_ANALYZE);
288 if (IsAutoVacuumWorkerProcess())
289 use_own_xacts = true;
290 else if (in_outer_xact)
291 use_own_xacts = false;
292 else if (list_length(relations) > 1)
293 use_own_xacts = true;
295 use_own_xacts = false;
299 * vacuum_rel expects to be entered with no transaction active; it will
300 * start and commit its own transaction. But we are called by an SQL
301 * command, and so we are executing inside a transaction already. We
302 * commit the transaction started in PostgresMain() here, and start
303 * another one before exiting to match the commit waiting for us back in
308 Assert(!in_outer_xact);
310 /* ActiveSnapshot is not set by autovacuum */
311 if (ActiveSnapshotSet())
314 /* matches the StartTransaction in PostgresMain() */
315 CommitTransactionCommand();
318 /* Turn vacuum cost accounting on or off, and set/clear in_vacuum */
324 VacuumCostActive = (VacuumCostDelay > 0);
325 VacuumCostBalance = 0;
331 * Loop to process each selected relation.
333 foreach(cur, relations)
335 VacuumRelation *vrel = lfirst_node(VacuumRelation, cur);
337 if (options & VACOPT_VACUUM)
339 if (!vacuum_rel(vrel->oid, vrel->relation, options, params))
343 if (options & VACOPT_ANALYZE)
346 * If using separate xacts, start one for analyze. Otherwise,
347 * we can use the outer transaction.
351 StartTransactionCommand();
352 /* functions in indexes may want a snapshot set */
353 PushActiveSnapshot(GetTransactionSnapshot());
356 analyze_rel(vrel->oid, vrel->relation, options, params,
357 vrel->va_cols, in_outer_xact, vac_strategy);
362 CommitTransactionCommand();
370 VacuumCostActive = false;
376 VacuumCostActive = false;
379 * Finish up processing.
383 /* here, we are not in a transaction */
386 * This matches the CommitTransaction waiting for us in
389 StartTransactionCommand();
392 if ((options & VACOPT_VACUUM) && !IsAutoVacuumWorkerProcess())
395 * Update pg_database.datfrozenxid, and truncate pg_xact if possible.
396 * (autovacuum.c does this for itself.)
398 vac_update_datfrozenxid();
402 * Clean up working storage --- note we must do this after
403 * StartTransactionCommand, else we might be trying to delete the active
406 MemoryContextDelete(vac_context);
411 * Check if a given relation can be safely vacuumed or analyzed. If the
412 * user is not the relation owner, issue a WARNING log message and return
413 * false to let the caller decide what to do with this relation. This
414 * routine is used to decide if a relation can be processed for VACUUM or
418 vacuum_is_relation_owner(Oid relid, Form_pg_class reltuple, int options)
422 Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0);
427 * We allow the user to vacuum or analyze a table if he is superuser, the
428 * table owner, or the database owner (but in the latter case, only if
429 * it's not a shared relation). pg_class_ownercheck includes the
432 * Note we choose to treat permissions failure as a WARNING and keep
433 * trying to vacuum or analyze the rest of the DB --- is this appropriate?
435 if (pg_class_ownercheck(relid, GetUserId()) ||
436 (pg_database_ownercheck(MyDatabaseId, GetUserId()) && !reltuple->relisshared))
439 relname = NameStr(reltuple->relname);
441 if ((options & VACOPT_VACUUM) != 0)
443 if (reltuple->relisshared)
445 (errmsg("skipping \"%s\" --- only superuser can vacuum it",
447 else if (reltuple->relnamespace == PG_CATALOG_NAMESPACE)
449 (errmsg("skipping \"%s\" --- only superuser or database owner can vacuum it",
453 (errmsg("skipping \"%s\" --- only table or database owner can vacuum it",
457 * For VACUUM ANALYZE, both logs could show up, but just generate
458 * information for VACUUM as that would be the first one to be
464 if ((options & VACOPT_ANALYZE) != 0)
466 if (reltuple->relisshared)
468 (errmsg("skipping \"%s\" --- only superuser can analyze it",
470 else if (reltuple->relnamespace == PG_CATALOG_NAMESPACE)
472 (errmsg("skipping \"%s\" --- only superuser or database owner can analyze it",
476 (errmsg("skipping \"%s\" --- only table or database owner can analyze it",
485 * vacuum_open_relation
487 * This routine is used for attempting to open and lock a relation which
488 * is going to be vacuumed or analyzed. If the relation cannot be opened
489 * or locked, a log is emitted if possible.
492 vacuum_open_relation(Oid relid, RangeVar *relation, VacuumParams *params,
493 int options, LOCKMODE lmode)
496 bool rel_lock = true;
499 Assert(params != NULL);
500 Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0);
503 * Open the relation and get the appropriate lock on it.
505 * There's a race condition here: the relation may have gone away since
506 * the last time we saw it. If so, we don't need to vacuum or analyze it.
508 * If we've been asked not to wait for the relation lock, acquire it first
509 * in non-blocking mode, before calling try_relation_open().
511 if (!(options & VACOPT_SKIP_LOCKED))
512 onerel = try_relation_open(relid, lmode);
513 else if (ConditionalLockRelationOid(relid, lmode))
514 onerel = try_relation_open(relid, NoLock);
521 /* if relation is opened, leave */
526 * Relation could not be opened, hence generate if possible a log
527 * informing on the situation.
529 * If the RangeVar is not defined, we do not have enough information to
530 * provide a meaningful log statement. Chances are that the caller has
531 * intentionally not provided this information so that this logging is
534 if (relation == NULL)
538 * Determine the log level.
540 * For autovacuum logs, we emit a LOG if log_autovacuum_min_duration is
541 * not disabled. For manual VACUUM or ANALYZE, we emit a WARNING to match
542 * the log statements in the permission checks.
544 if (!IsAutoVacuumWorkerProcess())
546 else if (params->log_min_duration >= 0)
551 if ((options & VACOPT_VACUUM) != 0)
555 (errcode(ERRCODE_LOCK_NOT_AVAILABLE),
556 errmsg("skipping vacuum of \"%s\" --- lock not available",
557 relation->relname)));
560 (errcode(ERRCODE_UNDEFINED_TABLE),
561 errmsg("skipping vacuum of \"%s\" --- relation no longer exists",
562 relation->relname)));
565 * For VACUUM ANALYZE, both logs could show up, but just generate
566 * information for VACUUM as that would be the first one to be
572 if ((options & VACOPT_ANALYZE) != 0)
576 (errcode(ERRCODE_LOCK_NOT_AVAILABLE),
577 errmsg("skipping analyze of \"%s\" --- lock not available",
578 relation->relname)));
581 (errcode(ERRCODE_UNDEFINED_TABLE),
582 errmsg("skipping analyze of \"%s\" --- relation no longer exists",
583 relation->relname)));
591 * Given a VacuumRelation, fill in the table OID if it wasn't specified,
592 * and optionally add VacuumRelations for partitions of the table.
594 * If a VacuumRelation does not have an OID supplied and is a partitioned
595 * table, an extra entry will be added to the output for each partition.
596 * Presently, only autovacuum supplies OIDs when calling vacuum(), and
597 * it does not want us to expand partitioned tables.
599 * We take care not to modify the input data structure, but instead build
600 * new VacuumRelation(s) to return. (But note that they will reference
601 * unmodified parts of the input, eg column lists.) New data structures
602 * are made in vac_context.
605 expand_vacuum_rel(VacuumRelation *vrel, int options)
608 MemoryContext oldcontext;
610 /* If caller supplied OID, there's nothing we need do here. */
611 if (OidIsValid(vrel->oid))
613 oldcontext = MemoryContextSwitchTo(vac_context);
614 vacrels = lappend(vacrels, vrel);
615 MemoryContextSwitchTo(oldcontext);
619 /* Process a specific relation, and possibly partitions thereof */
622 Form_pg_class classForm;
627 * Since autovacuum workers supply OIDs when calling vacuum(), no
628 * autovacuum worker should reach this code.
630 Assert(!IsAutoVacuumWorkerProcess());
633 * We transiently take AccessShareLock to protect the syscache lookup
634 * below, as well as find_all_inheritors's expectation that the caller
635 * holds some lock on the starting relation.
637 rvr_opts = (options & VACOPT_SKIP_LOCKED) ? RVR_SKIP_LOCKED : 0;
638 relid = RangeVarGetRelidExtended(vrel->relation,
644 * If the lock is unavailable, emit the same log statement that
645 * vacuum_rel() and analyze_rel() would.
647 if (!OidIsValid(relid))
649 if (options & VACOPT_VACUUM)
651 (errcode(ERRCODE_LOCK_NOT_AVAILABLE),
652 errmsg("skipping vacuum of \"%s\" --- lock not available",
653 vrel->relation->relname)));
656 (errcode(ERRCODE_LOCK_NOT_AVAILABLE),
657 errmsg("skipping analyze of \"%s\" --- lock not available",
658 vrel->relation->relname)));
663 * To check whether the relation is a partitioned table and its
664 * ownership, fetch its syscache entry.
666 tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
667 if (!HeapTupleIsValid(tuple))
668 elog(ERROR, "cache lookup failed for relation %u", relid);
669 classForm = (Form_pg_class) GETSTRUCT(tuple);
672 * Make a returnable VacuumRelation for this rel if user is a proper
675 if (vacuum_is_relation_owner(relid, classForm, options))
677 oldcontext = MemoryContextSwitchTo(vac_context);
678 vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation,
681 MemoryContextSwitchTo(oldcontext);
685 include_parts = (classForm->relkind == RELKIND_PARTITIONED_TABLE);
686 ReleaseSysCache(tuple);
689 * If it is, make relation list entries for its partitions. Note that
690 * the list returned by find_all_inheritors() includes the passed-in
691 * OID, so we have to skip that. There's no point in taking locks on
692 * the individual partitions yet, and doing so would just add
693 * unnecessary deadlock risk. For this last reason we do not check
694 * yet the ownership of the partitions, which get added to the list to
695 * process. Ownership will be checked later on anyway.
699 List *part_oids = find_all_inheritors(relid, NoLock, NULL);
702 foreach(part_lc, part_oids)
704 Oid part_oid = lfirst_oid(part_lc);
706 if (part_oid == relid)
707 continue; /* ignore original table */
710 * We omit a RangeVar since it wouldn't be appropriate to
711 * complain about failure to open one of these relations
714 oldcontext = MemoryContextSwitchTo(vac_context);
715 vacrels = lappend(vacrels, makeVacuumRelation(NULL,
718 MemoryContextSwitchTo(oldcontext);
723 * Release lock again. This means that by the time we actually try to
724 * process the table, it might be gone or renamed. In the former case
725 * we'll silently ignore it; in the latter case we'll process it
726 * anyway, but we must beware that the RangeVar doesn't necessarily
727 * identify it anymore. This isn't ideal, perhaps, but there's little
728 * practical alternative, since we're typically going to commit this
729 * transaction and begin a new one between now and then. Moreover,
730 * holding locks on multiple relations would create significant risk
733 UnlockRelationOid(relid, AccessShareLock);
740 * Construct a list of VacuumRelations for all vacuumable rels in
741 * the current database. The list is built in vac_context.
744 get_all_vacuum_rels(int options)
751 pgclass = table_open(RelationRelationId, AccessShareLock);
753 scan = heap_beginscan_catalog(pgclass, 0, NULL);
755 while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
757 Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple);
758 MemoryContext oldcontext;
759 Oid relid = classForm->oid;
761 /* check permissions of relation */
762 if (!vacuum_is_relation_owner(relid, classForm, options))
766 * We include partitioned tables here; depending on which operation is
767 * to be performed, caller will decide whether to process or ignore
770 if (classForm->relkind != RELKIND_RELATION &&
771 classForm->relkind != RELKIND_MATVIEW &&
772 classForm->relkind != RELKIND_PARTITIONED_TABLE)
776 * Build VacuumRelation(s) specifying the table OIDs to be processed.
777 * We omit a RangeVar since it wouldn't be appropriate to complain
778 * about failure to open one of these relations later.
780 oldcontext = MemoryContextSwitchTo(vac_context);
781 vacrels = lappend(vacrels, makeVacuumRelation(NULL,
784 MemoryContextSwitchTo(oldcontext);
788 table_close(pgclass, AccessShareLock);
794 * vacuum_set_xid_limits() -- compute oldest-Xmin and freeze cutoff points
796 * The output parameters are:
797 * - oldestXmin is the cutoff value used to distinguish whether tuples are
798 * DEAD or RECENTLY_DEAD (see HeapTupleSatisfiesVacuum).
799 * - freezeLimit is the Xid below which all Xids are replaced by
800 * FrozenTransactionId during vacuum.
801 * - xidFullScanLimit (computed from table_freeze_age parameter)
802 * represents a minimum Xid value; a table whose relfrozenxid is older than
803 * this will have a full-table vacuum applied to it, to freeze tuples across
804 * the whole table. Vacuuming a table younger than this value can use a
806 * - multiXactCutoff is the value below which all MultiXactIds are removed from
808 * - mxactFullScanLimit is a value against which a table's relminmxid value is
809 * compared to produce a full-table vacuum, as with xidFullScanLimit.
811 * xidFullScanLimit and mxactFullScanLimit can be passed as NULL if caller is
815 vacuum_set_xid_limits(Relation rel,
817 int freeze_table_age,
818 int multixact_freeze_min_age,
819 int multixact_freeze_table_age,
820 TransactionId *oldestXmin,
821 TransactionId *freezeLimit,
822 TransactionId *xidFullScanLimit,
823 MultiXactId *multiXactCutoff,
824 MultiXactId *mxactFullScanLimit)
828 int effective_multixact_freeze_max_age;
830 TransactionId safeLimit;
831 MultiXactId mxactLimit;
832 MultiXactId safeMxactLimit;
835 * We can always ignore processes running lazy vacuum. This is because we
836 * use these values only for deciding which tuples we must keep in the
837 * tables. Since lazy vacuum doesn't write its XID anywhere, it's safe to
838 * ignore it. In theory it could be problematic to ignore lazy vacuums in
839 * a full vacuum, but keep in mind that only one vacuum process can be
840 * working on a particular table at any time, and that each vacuum is
841 * always an independent transaction.
844 TransactionIdLimitedForOldSnapshots(GetOldestXmin(rel, PROCARRAY_FLAGS_VACUUM), rel);
846 Assert(TransactionIdIsNormal(*oldestXmin));
849 * Determine the minimum freeze age to use: as specified by the caller, or
850 * vacuum_freeze_min_age, but in any case not more than half
851 * autovacuum_freeze_max_age, so that autovacuums to prevent XID
852 * wraparound won't occur too frequently.
854 freezemin = freeze_min_age;
856 freezemin = vacuum_freeze_min_age;
857 freezemin = Min(freezemin, autovacuum_freeze_max_age / 2);
858 Assert(freezemin >= 0);
861 * Compute the cutoff XID, being careful not to generate a "permanent" XID
863 limit = *oldestXmin - freezemin;
864 if (!TransactionIdIsNormal(limit))
865 limit = FirstNormalTransactionId;
868 * If oldestXmin is very far back (in practice, more than
869 * autovacuum_freeze_max_age / 2 XIDs old), complain and force a minimum
870 * freeze age of zero.
872 safeLimit = ReadNewTransactionId() - autovacuum_freeze_max_age;
873 if (!TransactionIdIsNormal(safeLimit))
874 safeLimit = FirstNormalTransactionId;
876 if (TransactionIdPrecedes(limit, safeLimit))
879 (errmsg("oldest xmin is far in the past"),
880 errhint("Close open transactions soon to avoid wraparound problems.\n"
881 "You might also need to commit or roll back old prepared transactions, or drop stale replication slots.")));
885 *freezeLimit = limit;
888 * Compute the multixact age for which freezing is urgent. This is
889 * normally autovacuum_multixact_freeze_max_age, but may be less if we are
890 * short of multixact member space.
892 effective_multixact_freeze_max_age = MultiXactMemberFreezeThreshold();
895 * Determine the minimum multixact freeze age to use: as specified by
896 * caller, or vacuum_multixact_freeze_min_age, but in any case not more
897 * than half effective_multixact_freeze_max_age, so that autovacuums to
898 * prevent MultiXact wraparound won't occur too frequently.
900 mxid_freezemin = multixact_freeze_min_age;
901 if (mxid_freezemin < 0)
902 mxid_freezemin = vacuum_multixact_freeze_min_age;
903 mxid_freezemin = Min(mxid_freezemin,
904 effective_multixact_freeze_max_age / 2);
905 Assert(mxid_freezemin >= 0);
907 /* compute the cutoff multi, being careful to generate a valid value */
908 mxactLimit = GetOldestMultiXactId() - mxid_freezemin;
909 if (mxactLimit < FirstMultiXactId)
910 mxactLimit = FirstMultiXactId;
913 ReadNextMultiXactId() - effective_multixact_freeze_max_age;
914 if (safeMxactLimit < FirstMultiXactId)
915 safeMxactLimit = FirstMultiXactId;
917 if (MultiXactIdPrecedes(mxactLimit, safeMxactLimit))
920 (errmsg("oldest multixact is far in the past"),
921 errhint("Close open transactions with multixacts soon to avoid wraparound problems.")));
922 mxactLimit = safeMxactLimit;
925 *multiXactCutoff = mxactLimit;
927 if (xidFullScanLimit != NULL)
931 Assert(mxactFullScanLimit != NULL);
934 * Determine the table freeze age to use: as specified by the caller,
935 * or vacuum_freeze_table_age, but in any case not more than
936 * autovacuum_freeze_max_age * 0.95, so that if you have e.g nightly
937 * VACUUM schedule, the nightly VACUUM gets a chance to freeze tuples
938 * before anti-wraparound autovacuum is launched.
940 freezetable = freeze_table_age;
942 freezetable = vacuum_freeze_table_age;
943 freezetable = Min(freezetable, autovacuum_freeze_max_age * 0.95);
944 Assert(freezetable >= 0);
947 * Compute XID limit causing a full-table vacuum, being careful not to
948 * generate a "permanent" XID.
950 limit = ReadNewTransactionId() - freezetable;
951 if (!TransactionIdIsNormal(limit))
952 limit = FirstNormalTransactionId;
954 *xidFullScanLimit = limit;
957 * Similar to the above, determine the table freeze age to use for
958 * multixacts: as specified by the caller, or
959 * vacuum_multixact_freeze_table_age, but in any case not more than
960 * autovacuum_multixact_freeze_table_age * 0.95, so that if you have
961 * e.g. nightly VACUUM schedule, the nightly VACUUM gets a chance to
962 * freeze multixacts before anti-wraparound autovacuum is launched.
964 freezetable = multixact_freeze_table_age;
966 freezetable = vacuum_multixact_freeze_table_age;
967 freezetable = Min(freezetable,
968 effective_multixact_freeze_max_age * 0.95);
969 Assert(freezetable >= 0);
972 * Compute MultiXact limit causing a full-table vacuum, being careful
973 * to generate a valid MultiXact value.
975 mxactLimit = ReadNextMultiXactId() - freezetable;
976 if (mxactLimit < FirstMultiXactId)
977 mxactLimit = FirstMultiXactId;
979 *mxactFullScanLimit = mxactLimit;
983 Assert(mxactFullScanLimit == NULL);
988 * vac_estimate_reltuples() -- estimate the new value for pg_class.reltuples
990 * If we scanned the whole relation then we should just use the count of
991 * live tuples seen; but if we did not, we should not blindly extrapolate
992 * from that number, since VACUUM may have scanned a quite nonrandom
993 * subset of the table. When we have only partial information, we take
994 * the old value of pg_class.reltuples as a measurement of the
995 * tuple density in the unscanned pages.
997 * Note: scanned_tuples should count only *live* tuples, since
998 * pg_class.reltuples is defined that way.
1001 vac_estimate_reltuples(Relation relation,
1002 BlockNumber total_pages,
1003 BlockNumber scanned_pages,
1004 double scanned_tuples)
1006 BlockNumber old_rel_pages = relation->rd_rel->relpages;
1007 double old_rel_tuples = relation->rd_rel->reltuples;
1009 double unscanned_pages;
1010 double total_tuples;
1012 /* If we did scan the whole table, just use the count as-is */
1013 if (scanned_pages >= total_pages)
1014 return scanned_tuples;
1017 * If scanned_pages is zero but total_pages isn't, keep the existing value
1018 * of reltuples. (Note: callers should avoid updating the pg_class
1019 * statistics in this situation, since no new information has been
1022 if (scanned_pages == 0)
1023 return old_rel_tuples;
1026 * If old value of relpages is zero, old density is indeterminate; we
1027 * can't do much except scale up scanned_tuples to match total_pages.
1029 if (old_rel_pages == 0)
1030 return floor((scanned_tuples / scanned_pages) * total_pages + 0.5);
1033 * Okay, we've covered the corner cases. The normal calculation is to
1034 * convert the old measurement to a density (tuples per page), then
1035 * estimate the number of tuples in the unscanned pages using that figure,
1036 * and finally add on the number of tuples in the scanned pages.
1038 old_density = old_rel_tuples / old_rel_pages;
1039 unscanned_pages = (double) total_pages - (double) scanned_pages;
1040 total_tuples = old_density * unscanned_pages + scanned_tuples;
1041 return floor(total_tuples + 0.5);
1046 * vac_update_relstats() -- update statistics for one relation
1048 * Update the whole-relation statistics that are kept in its pg_class
1049 * row. There are additional stats that will be updated if we are
1050 * doing ANALYZE, but we always update these stats. This routine works
1051 * for both index and heap relation entries in pg_class.
1053 * We violate transaction semantics here by overwriting the rel's
1054 * existing pg_class tuple with the new values. This is reasonably
1055 * safe as long as we're sure that the new values are correct whether or
1056 * not this transaction commits. The reason for doing this is that if
1057 * we updated these tuples in the usual way, vacuuming pg_class itself
1058 * wouldn't work very well --- by the time we got done with a vacuum
1059 * cycle, most of the tuples in pg_class would've been obsoleted. Of
1060 * course, this only works for fixed-size not-null columns, but these are.
1062 * Another reason for doing it this way is that when we are in a lazy
1063 * VACUUM and have PROC_IN_VACUUM set, we mustn't do any regular updates.
1064 * Somebody vacuuming pg_class might think they could delete a tuple
1065 * marked with xmin = our xid.
1067 * In addition to fundamentally nontransactional statistics such as
1068 * relpages and relallvisible, we try to maintain certain lazily-updated
1069 * DDL flags such as relhasindex, by clearing them if no longer correct.
1070 * It's safe to do this in VACUUM, which can't run in parallel with
1071 * CREATE INDEX/RULE/TRIGGER and can't be part of a transaction block.
1072 * However, it's *not* safe to do it in an ANALYZE that's within an
1073 * outer transaction, because for example the current transaction might
1074 * have dropped the last index; then we'd think relhasindex should be
1075 * cleared, but if the transaction later rolls back this would be wrong.
1076 * So we refrain from updating the DDL flags if we're inside an outer
1077 * transaction. This is OK since postponing the flag maintenance is
1080 * Note: num_tuples should count only *live* tuples, since
1081 * pg_class.reltuples is defined that way.
1083 * This routine is shared by VACUUM and ANALYZE.
1086 vac_update_relstats(Relation relation,
1087 BlockNumber num_pages, double num_tuples,
1088 BlockNumber num_all_visible_pages,
1089 bool hasindex, TransactionId frozenxid,
1090 MultiXactId minmulti,
1093 Oid relid = RelationGetRelid(relation);
1096 Form_pg_class pgcform;
1099 rd = table_open(RelationRelationId, RowExclusiveLock);
1101 /* Fetch a copy of the tuple to scribble on */
1102 ctup = SearchSysCacheCopy1(RELOID, ObjectIdGetDatum(relid));
1103 if (!HeapTupleIsValid(ctup))
1104 elog(ERROR, "pg_class entry for relid %u vanished during vacuuming",
1106 pgcform = (Form_pg_class) GETSTRUCT(ctup);
1108 /* Apply statistical updates, if any, to copied tuple */
1111 if (pgcform->relpages != (int32) num_pages)
1113 pgcform->relpages = (int32) num_pages;
1116 if (pgcform->reltuples != (float4) num_tuples)
1118 pgcform->reltuples = (float4) num_tuples;
1121 if (pgcform->relallvisible != (int32) num_all_visible_pages)
1123 pgcform->relallvisible = (int32) num_all_visible_pages;
1127 /* Apply DDL updates, but not inside an outer transaction (see above) */
1132 * If we didn't find any indexes, reset relhasindex.
1134 if (pgcform->relhasindex && !hasindex)
1136 pgcform->relhasindex = false;
1140 /* We also clear relhasrules and relhastriggers if needed */
1141 if (pgcform->relhasrules && relation->rd_rules == NULL)
1143 pgcform->relhasrules = false;
1146 if (pgcform->relhastriggers && relation->trigdesc == NULL)
1148 pgcform->relhastriggers = false;
1154 * Update relfrozenxid, unless caller passed InvalidTransactionId
1155 * indicating it has no new data.
1157 * Ordinarily, we don't let relfrozenxid go backwards: if things are
1158 * working correctly, the only way the new frozenxid could be older would
1159 * be if a previous VACUUM was done with a tighter freeze_min_age, in
1160 * which case we don't want to forget the work it already did. However,
1161 * if the stored relfrozenxid is "in the future", then it must be corrupt
1162 * and it seems best to overwrite it with the cutoff we used this time.
1163 * This should match vac_update_datfrozenxid() concerning what we consider
1164 * to be "in the future".
1166 if (TransactionIdIsNormal(frozenxid) &&
1167 pgcform->relfrozenxid != frozenxid &&
1168 (TransactionIdPrecedes(pgcform->relfrozenxid, frozenxid) ||
1169 TransactionIdPrecedes(ReadNewTransactionId(),
1170 pgcform->relfrozenxid)))
1172 pgcform->relfrozenxid = frozenxid;
1176 /* Similarly for relminmxid */
1177 if (MultiXactIdIsValid(minmulti) &&
1178 pgcform->relminmxid != minmulti &&
1179 (MultiXactIdPrecedes(pgcform->relminmxid, minmulti) ||
1180 MultiXactIdPrecedes(ReadNextMultiXactId(), pgcform->relminmxid)))
1182 pgcform->relminmxid = minmulti;
1186 /* If anything changed, write out the tuple. */
1188 heap_inplace_update(rd, ctup);
1190 table_close(rd, RowExclusiveLock);
1195 * vac_update_datfrozenxid() -- update pg_database.datfrozenxid for our DB
1197 * Update pg_database's datfrozenxid entry for our database to be the
1198 * minimum of the pg_class.relfrozenxid values.
1200 * Similarly, update our datminmxid to be the minimum of the
1201 * pg_class.relminmxid values.
1203 * If we are able to advance either pg_database value, also try to
1204 * truncate pg_xact and pg_multixact.
1206 * We violate transaction semantics here by overwriting the database's
1207 * existing pg_database tuple with the new values. This is reasonably
1208 * safe since the new values are correct whether or not this transaction
1209 * commits. As with vac_update_relstats, this avoids leaving dead tuples
1210 * behind after a VACUUM.
1213 vac_update_datfrozenxid(void)
1216 Form_pg_database dbform;
1220 TransactionId newFrozenXid;
1221 MultiXactId newMinMulti;
1222 TransactionId lastSaneFrozenXid;
1223 MultiXactId lastSaneMinMulti;
1228 * Initialize the "min" calculation with GetOldestXmin, which is a
1229 * reasonable approximation to the minimum relfrozenxid for not-yet-
1230 * committed pg_class entries for new tables; see AddNewRelationTuple().
1231 * So we cannot produce a wrong minimum by starting with this.
1233 newFrozenXid = GetOldestXmin(NULL, PROCARRAY_FLAGS_VACUUM);
1236 * Similarly, initialize the MultiXact "min" with the value that would be
1237 * used on pg_class for new tables. See AddNewRelationTuple().
1239 newMinMulti = GetOldestMultiXactId();
1242 * Identify the latest relfrozenxid and relminmxid values that we could
1243 * validly see during the scan. These are conservative values, but it's
1244 * not really worth trying to be more exact.
1246 lastSaneFrozenXid = ReadNewTransactionId();
1247 lastSaneMinMulti = ReadNextMultiXactId();
1250 * We must seqscan pg_class to find the minimum Xid, because there is no
1251 * index that can help us here.
1253 relation = table_open(RelationRelationId, AccessShareLock);
1255 scan = systable_beginscan(relation, InvalidOid, false,
1258 while ((classTup = systable_getnext(scan)) != NULL)
1260 Form_pg_class classForm = (Form_pg_class) GETSTRUCT(classTup);
1263 * Only consider relations able to hold unfrozen XIDs (anything else
1264 * should have InvalidTransactionId in relfrozenxid anyway.)
1266 if (classForm->relkind != RELKIND_RELATION &&
1267 classForm->relkind != RELKIND_MATVIEW &&
1268 classForm->relkind != RELKIND_TOASTVALUE)
1271 Assert(TransactionIdIsNormal(classForm->relfrozenxid));
1272 Assert(MultiXactIdIsValid(classForm->relminmxid));
1275 * If things are working properly, no relation should have a
1276 * relfrozenxid or relminmxid that is "in the future". However, such
1277 * cases have been known to arise due to bugs in pg_upgrade. If we
1278 * see any entries that are "in the future", chicken out and don't do
1279 * anything. This ensures we won't truncate clog before those
1280 * relations have been scanned and cleaned up.
1282 if (TransactionIdPrecedes(lastSaneFrozenXid, classForm->relfrozenxid) ||
1283 MultiXactIdPrecedes(lastSaneMinMulti, classForm->relminmxid))
1289 if (TransactionIdPrecedes(classForm->relfrozenxid, newFrozenXid))
1290 newFrozenXid = classForm->relfrozenxid;
1292 if (MultiXactIdPrecedes(classForm->relminmxid, newMinMulti))
1293 newMinMulti = classForm->relminmxid;
1296 /* we're done with pg_class */
1297 systable_endscan(scan);
1298 table_close(relation, AccessShareLock);
1300 /* chicken out if bogus data found */
1304 Assert(TransactionIdIsNormal(newFrozenXid));
1305 Assert(MultiXactIdIsValid(newMinMulti));
1307 /* Now fetch the pg_database tuple we need to update. */
1308 relation = table_open(DatabaseRelationId, RowExclusiveLock);
1310 /* Fetch a copy of the tuple to scribble on */
1311 tuple = SearchSysCacheCopy1(DATABASEOID, ObjectIdGetDatum(MyDatabaseId));
1312 if (!HeapTupleIsValid(tuple))
1313 elog(ERROR, "could not find tuple for database %u", MyDatabaseId);
1314 dbform = (Form_pg_database) GETSTRUCT(tuple);
1317 * As in vac_update_relstats(), we ordinarily don't want to let
1318 * datfrozenxid go backward; but if it's "in the future" then it must be
1319 * corrupt and it seems best to overwrite it.
1321 if (dbform->datfrozenxid != newFrozenXid &&
1322 (TransactionIdPrecedes(dbform->datfrozenxid, newFrozenXid) ||
1323 TransactionIdPrecedes(lastSaneFrozenXid, dbform->datfrozenxid)))
1325 dbform->datfrozenxid = newFrozenXid;
1329 newFrozenXid = dbform->datfrozenxid;
1331 /* Ditto for datminmxid */
1332 if (dbform->datminmxid != newMinMulti &&
1333 (MultiXactIdPrecedes(dbform->datminmxid, newMinMulti) ||
1334 MultiXactIdPrecedes(lastSaneMinMulti, dbform->datminmxid)))
1336 dbform->datminmxid = newMinMulti;
1340 newMinMulti = dbform->datminmxid;
1343 heap_inplace_update(relation, tuple);
1345 heap_freetuple(tuple);
1346 table_close(relation, RowExclusiveLock);
1349 * If we were able to advance datfrozenxid or datminmxid, see if we can
1350 * truncate pg_xact and/or pg_multixact. Also do it if the shared
1351 * XID-wrap-limit info is stale, since this action will update that too.
1353 if (dirty || ForceTransactionIdLimitUpdate())
1354 vac_truncate_clog(newFrozenXid, newMinMulti,
1355 lastSaneFrozenXid, lastSaneMinMulti);
1360 * vac_truncate_clog() -- attempt to truncate the commit log
1362 * Scan pg_database to determine the system-wide oldest datfrozenxid,
1363 * and use it to truncate the transaction commit log (pg_xact).
1364 * Also update the XID wrap limit info maintained by varsup.c.
1365 * Likewise for datminmxid.
1367 * The passed frozenXID and minMulti are the updated values for my own
1368 * pg_database entry. They're used to initialize the "min" calculations.
1369 * The caller also passes the "last sane" XID and MXID, since it has
1370 * those at hand already.
1372 * This routine is only invoked when we've managed to change our
1373 * DB's datfrozenxid/datminmxid values, or we found that the shared
1374 * XID-wrap-limit info is stale.
1377 vac_truncate_clog(TransactionId frozenXID,
1378 MultiXactId minMulti,
1379 TransactionId lastSaneFrozenXid,
1380 MultiXactId lastSaneMinMulti)
1382 TransactionId nextXID = ReadNewTransactionId();
1386 Oid oldestxid_datoid;
1387 Oid minmulti_datoid;
1389 bool frozenAlreadyWrapped = false;
1391 /* init oldest datoids to sync with my frozenXID/minMulti values */
1392 oldestxid_datoid = MyDatabaseId;
1393 minmulti_datoid = MyDatabaseId;
1396 * Scan pg_database to compute the minimum datfrozenxid/datminmxid
1398 * Since vac_update_datfrozenxid updates datfrozenxid/datminmxid in-place,
1399 * the values could change while we look at them. Fetch each one just
1400 * once to ensure sane behavior of the comparison logic. (Here, as in
1401 * many other places, we assume that fetching or updating an XID in shared
1402 * storage is atomic.)
1404 * Note: we need not worry about a race condition with new entries being
1405 * inserted by CREATE DATABASE. Any such entry will have a copy of some
1406 * existing DB's datfrozenxid, and that source DB cannot be ours because
1407 * of the interlock against copying a DB containing an active backend.
1408 * Hence the new entry will not reduce the minimum. Also, if two VACUUMs
1409 * concurrently modify the datfrozenxid's of different databases, the
1410 * worst possible outcome is that pg_xact is not truncated as aggressively
1413 relation = table_open(DatabaseRelationId, AccessShareLock);
1415 scan = heap_beginscan_catalog(relation, 0, NULL);
1417 while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
1419 volatile FormData_pg_database *dbform = (Form_pg_database) GETSTRUCT(tuple);
1420 TransactionId datfrozenxid = dbform->datfrozenxid;
1421 TransactionId datminmxid = dbform->datminmxid;
1423 Assert(TransactionIdIsNormal(datfrozenxid));
1424 Assert(MultiXactIdIsValid(datminmxid));
1427 * If things are working properly, no database should have a
1428 * datfrozenxid or datminmxid that is "in the future". However, such
1429 * cases have been known to arise due to bugs in pg_upgrade. If we
1430 * see any entries that are "in the future", chicken out and don't do
1431 * anything. This ensures we won't truncate clog before those
1432 * databases have been scanned and cleaned up. (We will issue the
1433 * "already wrapped" warning if appropriate, though.)
1435 if (TransactionIdPrecedes(lastSaneFrozenXid, datfrozenxid) ||
1436 MultiXactIdPrecedes(lastSaneMinMulti, datminmxid))
1439 if (TransactionIdPrecedes(nextXID, datfrozenxid))
1440 frozenAlreadyWrapped = true;
1441 else if (TransactionIdPrecedes(datfrozenxid, frozenXID))
1443 frozenXID = datfrozenxid;
1444 oldestxid_datoid = dbform->oid;
1447 if (MultiXactIdPrecedes(datminmxid, minMulti))
1449 minMulti = datminmxid;
1450 minmulti_datoid = dbform->oid;
1456 table_close(relation, AccessShareLock);
1459 * Do not truncate CLOG if we seem to have suffered wraparound already;
1460 * the computed minimum XID might be bogus. This case should now be
1461 * impossible due to the defenses in GetNewTransactionId, but we keep the
1464 if (frozenAlreadyWrapped)
1467 (errmsg("some databases have not been vacuumed in over 2 billion transactions"),
1468 errdetail("You might have already suffered transaction-wraparound data loss.")));
1472 /* chicken out if data is bogus in any other way */
1477 * Advance the oldest value for commit timestamps before truncating, so
1478 * that if a user requests a timestamp for a transaction we're truncating
1479 * away right after this point, they get NULL instead of an ugly "file not
1480 * found" error from slru.c. This doesn't matter for xact/multixact
1481 * because they are not subject to arbitrary lookups from users.
1483 AdvanceOldestCommitTsXid(frozenXID);
1486 * Truncate CLOG, multixact and CommitTs to the oldest computed value.
1488 TruncateCLOG(frozenXID, oldestxid_datoid);
1489 TruncateCommitTs(frozenXID);
1490 TruncateMultiXact(minMulti, minmulti_datoid);
1493 * Update the wrap limit for GetNewTransactionId and creation of new
1494 * MultiXactIds. Note: these functions will also signal the postmaster
1495 * for an(other) autovac cycle if needed. XXX should we avoid possibly
1498 SetTransactionIdLimit(frozenXID, oldestxid_datoid);
1499 SetMultiXactIdLimit(minMulti, minmulti_datoid, false);
1504 * vacuum_rel() -- vacuum one heap relation
1506 * relid identifies the relation to vacuum. If relation is supplied,
1507 * use the name therein for reporting any failure to open/lock the rel;
1508 * do not use it once we've successfully opened the rel, since it might
1511 * Returns true if it's okay to proceed with a requested ANALYZE
1512 * operation on this table.
1514 * Doing one heap at a time incurs extra overhead, since we need to
1515 * check that the heap exists again just before we vacuum it. The
1516 * reason that we do this is so that vacuuming can be spread across
1517 * many small transactions. Otherwise, two-phase locking would require
1518 * us to lock the entire database during one pass of the vacuum cleaner.
1520 * At entry and exit, we are not inside a transaction.
1523 vacuum_rel(Oid relid, RangeVar *relation, int options, VacuumParams *params)
1530 int save_sec_context;
1533 Assert(params != NULL);
1535 /* Begin a transaction for vacuuming this relation */
1536 StartTransactionCommand();
1539 * Functions in indexes may want a snapshot set. Also, setting a snapshot
1540 * ensures that RecentGlobalXmin is kept truly recent.
1542 PushActiveSnapshot(GetTransactionSnapshot());
1544 if (!(options & VACOPT_FULL))
1547 * In lazy vacuum, we can set the PROC_IN_VACUUM flag, which lets
1548 * other concurrent VACUUMs know that they can ignore this one while
1549 * determining their OldestXmin. (The reason we don't set it during a
1550 * full VACUUM is exactly that we may have to run user-defined
1551 * functions for functional indexes, and we want to make sure that if
1552 * they use the snapshot set above, any tuples it requires can't get
1553 * removed from other tables. An index function that depends on the
1554 * contents of other tables is arguably broken, but we won't break it
1555 * here by violating transaction semantics.)
1557 * We also set the VACUUM_FOR_WRAPAROUND flag, which is passed down by
1558 * autovacuum; it's used to avoid canceling a vacuum that was invoked
1561 * Note: these flags remain set until CommitTransaction or
1562 * AbortTransaction. We don't want to clear them until we reset
1563 * MyPgXact->xid/xmin, else OldestXmin might appear to go backwards,
1564 * which is probably Not Good.
1566 LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
1567 MyPgXact->vacuumFlags |= PROC_IN_VACUUM;
1568 if (params->is_wraparound)
1569 MyPgXact->vacuumFlags |= PROC_VACUUM_FOR_WRAPAROUND;
1570 LWLockRelease(ProcArrayLock);
1574 * Check for user-requested abort. Note we want this to be inside a
1575 * transaction, so xact.c doesn't issue useless WARNING.
1577 CHECK_FOR_INTERRUPTS();
1580 * Determine the type of lock we want --- hard exclusive lock for a FULL
1581 * vacuum, but just ShareUpdateExclusiveLock for concurrent vacuum. Either
1582 * way, we can be sure that no other backend is vacuuming the same table.
1584 lmode = (options & VACOPT_FULL) ? AccessExclusiveLock : ShareUpdateExclusiveLock;
1586 /* open the relation and get the appropriate lock on it */
1587 onerel = vacuum_open_relation(relid, relation, params, options, lmode);
1589 /* leave if relation could not be opened or locked */
1592 PopActiveSnapshot();
1593 CommitTransactionCommand();
1598 * Check if relation needs to be skipped based on ownership. This check
1599 * happens also when building the relation list to vacuum for a manual
1600 * operation, and needs to be done additionally here as VACUUM could
1601 * happen across multiple transactions where relation ownership could have
1602 * changed in-between. Make sure to only generate logs for VACUUM in this
1605 if (!vacuum_is_relation_owner(RelationGetRelid(onerel),
1607 options & VACOPT_VACUUM))
1609 relation_close(onerel, lmode);
1610 PopActiveSnapshot();
1611 CommitTransactionCommand();
1616 * Check that it's of a vacuumable relkind.
1618 if (onerel->rd_rel->relkind != RELKIND_RELATION &&
1619 onerel->rd_rel->relkind != RELKIND_MATVIEW &&
1620 onerel->rd_rel->relkind != RELKIND_TOASTVALUE &&
1621 onerel->rd_rel->relkind != RELKIND_PARTITIONED_TABLE)
1624 (errmsg("skipping \"%s\" --- cannot vacuum non-tables or special system tables",
1625 RelationGetRelationName(onerel))));
1626 relation_close(onerel, lmode);
1627 PopActiveSnapshot();
1628 CommitTransactionCommand();
1633 * Silently ignore tables that are temp tables of other backends ---
1634 * trying to vacuum these will lead to great unhappiness, since their
1635 * contents are probably not up-to-date on disk. (We don't throw a
1636 * warning here; it would just lead to chatter during a database-wide
1639 if (RELATION_IS_OTHER_TEMP(onerel))
1641 relation_close(onerel, lmode);
1642 PopActiveSnapshot();
1643 CommitTransactionCommand();
1648 * Silently ignore partitioned tables as there is no work to be done. The
1649 * useful work is on their child partitions, which have been queued up for
1652 if (onerel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
1654 relation_close(onerel, lmode);
1655 PopActiveSnapshot();
1656 CommitTransactionCommand();
1657 /* It's OK to proceed with ANALYZE on this table */
1662 * Get a session-level lock too. This will protect our access to the
1663 * relation across multiple transactions, so that we can vacuum the
1664 * relation's TOAST table (if any) secure in the knowledge that no one is
1665 * deleting the parent relation.
1667 * NOTE: this cannot block, even if someone else is waiting for access,
1668 * because the lock manager knows that both lock requests are from the
1671 onerelid = onerel->rd_lockInfo.lockRelId;
1672 LockRelationIdForSession(&onerelid, lmode);
1675 * Remember the relation's TOAST relation for later, if the caller asked
1676 * us to process it. In VACUUM FULL, though, the toast table is
1677 * automatically rebuilt by cluster_rel so we shouldn't recurse to it.
1679 if (!(options & VACOPT_SKIPTOAST) && !(options & VACOPT_FULL))
1680 toast_relid = onerel->rd_rel->reltoastrelid;
1682 toast_relid = InvalidOid;
1685 * Switch to the table owner's userid, so that any index functions are run
1686 * as that user. Also lock down security-restricted operations and
1687 * arrange to make GUC variable changes local to this command. (This is
1688 * unnecessary, but harmless, for lazy VACUUM.)
1690 GetUserIdAndSecContext(&save_userid, &save_sec_context);
1691 SetUserIdAndSecContext(onerel->rd_rel->relowner,
1692 save_sec_context | SECURITY_RESTRICTED_OPERATION);
1693 save_nestlevel = NewGUCNestLevel();
1696 * Do the actual work --- either FULL or "lazy" vacuum
1698 if (options & VACOPT_FULL)
1700 int cluster_options = 0;
1702 /* close relation before vacuuming, but hold lock until commit */
1703 relation_close(onerel, NoLock);
1706 if ((options & VACOPT_VERBOSE) != 0)
1707 cluster_options |= CLUOPT_VERBOSE;
1709 /* VACUUM FULL is now a variant of CLUSTER; see cluster.c */
1710 cluster_rel(relid, InvalidOid, cluster_options);
1713 heap_vacuum_rel(onerel, options, params, vac_strategy);
1715 /* Roll back any GUC changes executed by index functions */
1716 AtEOXact_GUC(false, save_nestlevel);
1718 /* Restore userid and security context */
1719 SetUserIdAndSecContext(save_userid, save_sec_context);
1721 /* all done with this class, but hold lock until commit */
1723 relation_close(onerel, NoLock);
1726 * Complete the transaction and free all temporary memory used.
1728 PopActiveSnapshot();
1729 CommitTransactionCommand();
1732 * If the relation has a secondary toast rel, vacuum that too while we
1733 * still hold the session lock on the master table. Note however that
1734 * "analyze" will not get done on the toast table. This is good, because
1735 * the toaster always uses hardcoded index access and statistics are
1736 * totally unimportant for toast relations.
1738 if (toast_relid != InvalidOid)
1739 vacuum_rel(toast_relid, NULL, options, params);
1742 * Now release the session-level lock on the master table.
1744 UnlockRelationIdForSession(&onerelid, lmode);
1746 /* Report that we really did it. */
1752 * Open all the vacuumable indexes of the given relation, obtaining the
1753 * specified kind of lock on each. Return an array of Relation pointers for
1754 * the indexes into *Irel, and the number of indexes into *nindexes.
1756 * We consider an index vacuumable if it is marked insertable (indisready).
1757 * If it isn't, probably a CREATE INDEX CONCURRENTLY command failed early in
1758 * execution, and what we have is too corrupt to be processable. We will
1759 * vacuum even if the index isn't indisvalid; this is important because in a
1760 * unique index, uniqueness checks will be performed anyway and had better not
1761 * hit dangling index pointers.
1764 vac_open_indexes(Relation relation, LOCKMODE lockmode,
1765 int *nindexes, Relation **Irel)
1768 ListCell *indexoidscan;
1771 Assert(lockmode != NoLock);
1773 indexoidlist = RelationGetIndexList(relation);
1775 /* allocate enough memory for all indexes */
1776 i = list_length(indexoidlist);
1779 *Irel = (Relation *) palloc(i * sizeof(Relation));
1783 /* collect just the ready indexes */
1785 foreach(indexoidscan, indexoidlist)
1787 Oid indexoid = lfirst_oid(indexoidscan);
1790 indrel = index_open(indexoid, lockmode);
1791 if (indrel->rd_index->indisready)
1792 (*Irel)[i++] = indrel;
1794 index_close(indrel, lockmode);
1799 list_free(indexoidlist);
1803 * Release the resources acquired by vac_open_indexes. Optionally release
1804 * the locks (say NoLock to keep 'em).
1807 vac_close_indexes(int nindexes, Relation *Irel, LOCKMODE lockmode)
1814 Relation ind = Irel[nindexes];
1816 index_close(ind, lockmode);
1822 * vacuum_delay_point --- check for interrupts and cost-based delay.
1824 * This should be called in each major loop of VACUUM processing,
1825 * typically once per page processed.
1828 vacuum_delay_point(void)
1830 /* Always check for interrupts */
1831 CHECK_FOR_INTERRUPTS();
1833 /* Nap if appropriate */
1834 if (VacuumCostActive && !InterruptPending &&
1835 VacuumCostBalance >= VacuumCostLimit)
1839 msec = VacuumCostDelay * VacuumCostBalance / VacuumCostLimit;
1840 if (msec > VacuumCostDelay * 4)
1841 msec = VacuumCostDelay * 4;
1843 pg_usleep(msec * 1000L);
1845 VacuumCostBalance = 0;
1847 /* update balance values for workers */
1848 AutoVacuumUpdateDelay();
1850 /* Might have gotten an interrupt while sleeping */
1851 CHECK_FOR_INTERRUPTS();