]> granicus.if.org Git - postgresql/blob - src/backend/commands/vacuum.c
Stamp copyrights for year 2011.
[postgresql] / src / backend / commands / vacuum.c
1 /*-------------------------------------------------------------------------
2  *
3  * vacuum.c
4  *        The postgres vacuum cleaner.
5  *
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
9  * in cluster.c.
10  *
11  *
12  * Portions Copyright (c) 1996-2011, PostgreSQL Global Development Group
13  * Portions Copyright (c) 1994, Regents of the University of California
14  *
15  *
16  * IDENTIFICATION
17  *        src/backend/commands/vacuum.c
18  *
19  *-------------------------------------------------------------------------
20  */
21 #include "postgres.h"
22
23 #include "access/clog.h"
24 #include "access/genam.h"
25 #include "access/heapam.h"
26 #include "access/transam.h"
27 #include "access/xact.h"
28 #include "catalog/namespace.h"
29 #include "catalog/pg_database.h"
30 #include "catalog/pg_namespace.h"
31 #include "commands/cluster.h"
32 #include "commands/vacuum.h"
33 #include "miscadmin.h"
34 #include "pgstat.h"
35 #include "postmaster/autovacuum.h"
36 #include "storage/bufmgr.h"
37 #include "storage/lmgr.h"
38 #include "storage/proc.h"
39 #include "storage/procarray.h"
40 #include "utils/acl.h"
41 #include "utils/fmgroids.h"
42 #include "utils/guc.h"
43 #include "utils/memutils.h"
44 #include "utils/snapmgr.h"
45 #include "utils/syscache.h"
46 #include "utils/tqual.h"
47
48
49 /*
50  * GUC parameters
51  */
52 int                     vacuum_freeze_min_age;
53 int                     vacuum_freeze_table_age;
54
55
56 /* A few variables that don't seem worth passing around as parameters */
57 static MemoryContext vac_context = NULL;
58 static BufferAccessStrategy vac_strategy;
59
60
61 /* non-export function prototypes */
62 static List *get_rel_oids(Oid relid, const RangeVar *vacrel);
63 static void vac_truncate_clog(TransactionId frozenXID);
64 static void vacuum_rel(Oid relid, VacuumStmt *vacstmt, bool do_toast,
65                    bool for_wraparound, bool *scanned_all);
66
67
68 /*
69  * Primary entry point for VACUUM and ANALYZE commands.
70  *
71  * relid is normally InvalidOid; if it is not, then it provides the relation
72  * OID to be processed, and vacstmt->relation is ignored.  (The non-invalid
73  * case is currently only used by autovacuum.)
74  *
75  * do_toast is passed as FALSE by autovacuum, because it processes TOAST
76  * tables separately.
77  *
78  * for_wraparound is used by autovacuum to let us know when it's forcing
79  * a vacuum for wraparound, which should not be auto-cancelled.
80  *
81  * bstrategy is normally given as NULL, but in autovacuum it can be passed
82  * in to use the same buffer strategy object across multiple vacuum() calls.
83  *
84  * isTopLevel should be passed down from ProcessUtility.
85  *
86  * It is the caller's responsibility that vacstmt and bstrategy
87  * (if given) be allocated in a memory context that won't disappear
88  * at transaction commit.
89  */
90 void
91 vacuum(VacuumStmt *vacstmt, Oid relid, bool do_toast,
92            BufferAccessStrategy bstrategy, bool for_wraparound, bool isTopLevel)
93 {
94         const char *stmttype;
95         volatile bool all_rels,
96                                 in_outer_xact,
97                                 use_own_xacts;
98         List       *relations;
99
100         /* sanity checks on options */
101         Assert(vacstmt->options & (VACOPT_VACUUM | VACOPT_ANALYZE));
102         Assert((vacstmt->options & VACOPT_VACUUM) ||
103                    !(vacstmt->options & (VACOPT_FULL | VACOPT_FREEZE)));
104         Assert((vacstmt->options & VACOPT_ANALYZE) || vacstmt->va_cols == NIL);
105
106         stmttype = (vacstmt->options & VACOPT_VACUUM) ? "VACUUM" : "ANALYZE";
107
108         /*
109          * We cannot run VACUUM inside a user transaction block; if we were inside
110          * a transaction, then our commit- and start-transaction-command calls
111          * would not have the intended effect!  There are numerous other subtle
112          * dependencies on this, too.
113          *
114          * ANALYZE (without VACUUM) can run either way.
115          */
116         if (vacstmt->options & VACOPT_VACUUM)
117         {
118                 PreventTransactionChain(isTopLevel, stmttype);
119                 in_outer_xact = false;
120         }
121         else
122                 in_outer_xact = IsInTransactionChain(isTopLevel);
123
124         /*
125          * Send info about dead objects to the statistics collector, unless we are
126          * in autovacuum --- autovacuum.c does this for itself.
127          */
128         if ((vacstmt->options & VACOPT_VACUUM) && !IsAutoVacuumWorkerProcess())
129                 pgstat_vacuum_stat();
130
131         /*
132          * Create special memory context for cross-transaction storage.
133          *
134          * Since it is a child of PortalContext, it will go away eventually even
135          * if we suffer an error; there's no need for special abort cleanup logic.
136          */
137         vac_context = AllocSetContextCreate(PortalContext,
138                                                                                 "Vacuum",
139                                                                                 ALLOCSET_DEFAULT_MINSIZE,
140                                                                                 ALLOCSET_DEFAULT_INITSIZE,
141                                                                                 ALLOCSET_DEFAULT_MAXSIZE);
142
143         /*
144          * If caller didn't give us a buffer strategy object, make one in the
145          * cross-transaction memory context.
146          */
147         if (bstrategy == NULL)
148         {
149                 MemoryContext old_context = MemoryContextSwitchTo(vac_context);
150
151                 bstrategy = GetAccessStrategy(BAS_VACUUM);
152                 MemoryContextSwitchTo(old_context);
153         }
154         vac_strategy = bstrategy;
155
156         /* Remember whether we are processing everything in the DB */
157         all_rels = (!OidIsValid(relid) && vacstmt->relation == NULL);
158
159         /*
160          * Build list of relations to process, unless caller gave us one. (If we
161          * build one, we put it in vac_context for safekeeping.)
162          */
163         relations = get_rel_oids(relid, vacstmt->relation);
164
165         /*
166          * Decide whether we need to start/commit our own transactions.
167          *
168          * For VACUUM (with or without ANALYZE): always do so, so that we can
169          * release locks as soon as possible.  (We could possibly use the outer
170          * transaction for a one-table VACUUM, but handling TOAST tables would be
171          * problematic.)
172          *
173          * For ANALYZE (no VACUUM): if inside a transaction block, we cannot
174          * start/commit our own transactions.  Also, there's no need to do so if
175          * only processing one relation.  For multiple relations when not within a
176          * transaction block, and also in an autovacuum worker, use own
177          * transactions so we can release locks sooner.
178          */
179         if (vacstmt->options & VACOPT_VACUUM)
180                 use_own_xacts = true;
181         else
182         {
183                 Assert(vacstmt->options & VACOPT_ANALYZE);
184                 if (IsAutoVacuumWorkerProcess())
185                         use_own_xacts = true;
186                 else if (in_outer_xact)
187                         use_own_xacts = false;
188                 else if (list_length(relations) > 1)
189                         use_own_xacts = true;
190                 else
191                         use_own_xacts = false;
192         }
193
194         /*
195          * vacuum_rel expects to be entered with no transaction active; it will
196          * start and commit its own transaction.  But we are called by an SQL
197          * command, and so we are executing inside a transaction already. We
198          * commit the transaction started in PostgresMain() here, and start
199          * another one before exiting to match the commit waiting for us back in
200          * PostgresMain().
201          */
202         if (use_own_xacts)
203         {
204                 /* ActiveSnapshot is not set by autovacuum */
205                 if (ActiveSnapshotSet())
206                         PopActiveSnapshot();
207
208                 /* matches the StartTransaction in PostgresMain() */
209                 CommitTransactionCommand();
210         }
211
212         /* Turn vacuum cost accounting on or off */
213         PG_TRY();
214         {
215                 ListCell   *cur;
216
217                 VacuumCostActive = (VacuumCostDelay > 0);
218                 VacuumCostBalance = 0;
219
220                 /*
221                  * Loop to process each selected relation.
222                  */
223                 foreach(cur, relations)
224                 {
225                         Oid                     relid = lfirst_oid(cur);
226                         bool            scanned_all = false;
227
228                         if (vacstmt->options & VACOPT_VACUUM)
229                                 vacuum_rel(relid, vacstmt, do_toast, for_wraparound,
230                                                    &scanned_all);
231
232                         if (vacstmt->options & VACOPT_ANALYZE)
233                         {
234                                 /*
235                                  * If using separate xacts, start one for analyze. Otherwise,
236                                  * we can use the outer transaction.
237                                  */
238                                 if (use_own_xacts)
239                                 {
240                                         StartTransactionCommand();
241                                         /* functions in indexes may want a snapshot set */
242                                         PushActiveSnapshot(GetTransactionSnapshot());
243                                 }
244
245                                 analyze_rel(relid, vacstmt, vac_strategy, !scanned_all);
246
247                                 if (use_own_xacts)
248                                 {
249                                         PopActiveSnapshot();
250                                         CommitTransactionCommand();
251                                 }
252                         }
253                 }
254         }
255         PG_CATCH();
256         {
257                 /* Make sure cost accounting is turned off after error */
258                 VacuumCostActive = false;
259                 PG_RE_THROW();
260         }
261         PG_END_TRY();
262
263         /* Turn off vacuum cost accounting */
264         VacuumCostActive = false;
265
266         /*
267          * Finish up processing.
268          */
269         if (use_own_xacts)
270         {
271                 /* here, we are not in a transaction */
272
273                 /*
274                  * This matches the CommitTransaction waiting for us in
275                  * PostgresMain().
276                  */
277                 StartTransactionCommand();
278         }
279
280         if ((vacstmt->options & VACOPT_VACUUM) && !IsAutoVacuumWorkerProcess())
281         {
282                 /*
283                  * Update pg_database.datfrozenxid, and truncate pg_clog if possible.
284                  * (autovacuum.c does this for itself.)
285                  */
286                 vac_update_datfrozenxid();
287         }
288
289         /*
290          * Clean up working storage --- note we must do this after
291          * StartTransactionCommand, else we might be trying to delete the active
292          * context!
293          */
294         MemoryContextDelete(vac_context);
295         vac_context = NULL;
296 }
297
298 /*
299  * Build a list of Oids for each relation to be processed
300  *
301  * The list is built in vac_context so that it will survive across our
302  * per-relation transactions.
303  */
304 static List *
305 get_rel_oids(Oid relid, const RangeVar *vacrel)
306 {
307         List       *oid_list = NIL;
308         MemoryContext oldcontext;
309
310         /* OID supplied by VACUUM's caller? */
311         if (OidIsValid(relid))
312         {
313                 oldcontext = MemoryContextSwitchTo(vac_context);
314                 oid_list = lappend_oid(oid_list, relid);
315                 MemoryContextSwitchTo(oldcontext);
316         }
317         else if (vacrel)
318         {
319                 /* Process a specific relation */
320                 Oid                     relid;
321
322                 relid = RangeVarGetRelid(vacrel, false);
323
324                 /* Make a relation list entry for this guy */
325                 oldcontext = MemoryContextSwitchTo(vac_context);
326                 oid_list = lappend_oid(oid_list, relid);
327                 MemoryContextSwitchTo(oldcontext);
328         }
329         else
330         {
331                 /* Process all plain relations listed in pg_class */
332                 Relation        pgclass;
333                 HeapScanDesc scan;
334                 HeapTuple       tuple;
335                 ScanKeyData key;
336
337                 ScanKeyInit(&key,
338                                         Anum_pg_class_relkind,
339                                         BTEqualStrategyNumber, F_CHAREQ,
340                                         CharGetDatum(RELKIND_RELATION));
341
342                 pgclass = heap_open(RelationRelationId, AccessShareLock);
343
344                 scan = heap_beginscan(pgclass, SnapshotNow, 1, &key);
345
346                 while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
347                 {
348                         /* Make a relation list entry for this guy */
349                         oldcontext = MemoryContextSwitchTo(vac_context);
350                         oid_list = lappend_oid(oid_list, HeapTupleGetOid(tuple));
351                         MemoryContextSwitchTo(oldcontext);
352                 }
353
354                 heap_endscan(scan);
355                 heap_close(pgclass, AccessShareLock);
356         }
357
358         return oid_list;
359 }
360
361 /*
362  * vacuum_set_xid_limits() -- compute oldest-Xmin and freeze cutoff points
363  */
364 void
365 vacuum_set_xid_limits(int freeze_min_age,
366                                           int freeze_table_age,
367                                           bool sharedRel,
368                                           TransactionId *oldestXmin,
369                                           TransactionId *freezeLimit,
370                                           TransactionId *freezeTableLimit)
371 {
372         int                     freezemin;
373         TransactionId limit;
374         TransactionId safeLimit;
375
376         /*
377          * We can always ignore processes running lazy vacuum.  This is because we
378          * use these values only for deciding which tuples we must keep in the
379          * tables.      Since lazy vacuum doesn't write its XID anywhere, it's safe to
380          * ignore it.  In theory it could be problematic to ignore lazy vacuums in
381          * a full vacuum, but keep in mind that only one vacuum process can be
382          * working on a particular table at any time, and that each vacuum is
383          * always an independent transaction.
384          */
385         *oldestXmin = GetOldestXmin(sharedRel, true);
386
387         Assert(TransactionIdIsNormal(*oldestXmin));
388
389         /*
390          * Determine the minimum freeze age to use: as specified by the caller, or
391          * vacuum_freeze_min_age, but in any case not more than half
392          * autovacuum_freeze_max_age, so that autovacuums to prevent XID
393          * wraparound won't occur too frequently.
394          */
395         freezemin = freeze_min_age;
396         if (freezemin < 0)
397                 freezemin = vacuum_freeze_min_age;
398         freezemin = Min(freezemin, autovacuum_freeze_max_age / 2);
399         Assert(freezemin >= 0);
400
401         /*
402          * Compute the cutoff XID, being careful not to generate a "permanent" XID
403          */
404         limit = *oldestXmin - freezemin;
405         if (!TransactionIdIsNormal(limit))
406                 limit = FirstNormalTransactionId;
407
408         /*
409          * If oldestXmin is very far back (in practice, more than
410          * autovacuum_freeze_max_age / 2 XIDs old), complain and force a minimum
411          * freeze age of zero.
412          */
413         safeLimit = ReadNewTransactionId() - autovacuum_freeze_max_age;
414         if (!TransactionIdIsNormal(safeLimit))
415                 safeLimit = FirstNormalTransactionId;
416
417         if (TransactionIdPrecedes(limit, safeLimit))
418         {
419                 ereport(WARNING,
420                                 (errmsg("oldest xmin is far in the past"),
421                                  errhint("Close open transactions soon to avoid wraparound problems.")));
422                 limit = *oldestXmin;
423         }
424
425         *freezeLimit = limit;
426
427         if (freezeTableLimit != NULL)
428         {
429                 int                     freezetable;
430
431                 /*
432                  * Determine the table freeze age to use: as specified by the caller,
433                  * or vacuum_freeze_table_age, but in any case not more than
434                  * autovacuum_freeze_max_age * 0.95, so that if you have e.g nightly
435                  * VACUUM schedule, the nightly VACUUM gets a chance to freeze tuples
436                  * before anti-wraparound autovacuum is launched.
437                  */
438                 freezetable = freeze_min_age;
439                 if (freezetable < 0)
440                         freezetable = vacuum_freeze_table_age;
441                 freezetable = Min(freezetable, autovacuum_freeze_max_age * 0.95);
442                 Assert(freezetable >= 0);
443
444                 /*
445                  * Compute the cutoff XID, being careful not to generate a "permanent"
446                  * XID.
447                  */
448                 limit = ReadNewTransactionId() - freezetable;
449                 if (!TransactionIdIsNormal(limit))
450                         limit = FirstNormalTransactionId;
451
452                 *freezeTableLimit = limit;
453         }
454 }
455
456
457 /*
458  *      vac_update_relstats() -- update statistics for one relation
459  *
460  *              Update the whole-relation statistics that are kept in its pg_class
461  *              row.  There are additional stats that will be updated if we are
462  *              doing ANALYZE, but we always update these stats.  This routine works
463  *              for both index and heap relation entries in pg_class.
464  *
465  *              We violate transaction semantics here by overwriting the rel's
466  *              existing pg_class tuple with the new values.  This is reasonably
467  *              safe since the new values are correct whether or not this transaction
468  *              commits.  The reason for this is that if we updated these tuples in
469  *              the usual way, vacuuming pg_class itself wouldn't work very well ---
470  *              by the time we got done with a vacuum cycle, most of the tuples in
471  *              pg_class would've been obsoleted.  Of course, this only works for
472  *              fixed-size never-null columns, but these are.
473  *
474  *              Note another assumption: that two VACUUMs/ANALYZEs on a table can't
475  *              run in parallel, nor can VACUUM/ANALYZE run in parallel with a
476  *              schema alteration such as adding an index, rule, or trigger.  Otherwise
477  *              our updates of relhasindex etc might overwrite uncommitted updates.
478  *
479  *              Another reason for doing it this way is that when we are in a lazy
480  *              VACUUM and have PROC_IN_VACUUM set, we mustn't do any updates ---
481  *              somebody vacuuming pg_class might think they could delete a tuple
482  *              marked with xmin = our xid.
483  *
484  *              This routine is shared by VACUUM and stand-alone ANALYZE.
485  */
486 void
487 vac_update_relstats(Relation relation,
488                                         BlockNumber num_pages, double num_tuples,
489                                         bool hasindex, TransactionId frozenxid)
490 {
491         Oid                     relid = RelationGetRelid(relation);
492         Relation        rd;
493         HeapTuple       ctup;
494         Form_pg_class pgcform;
495         bool            dirty;
496
497         rd = heap_open(RelationRelationId, RowExclusiveLock);
498
499         /* Fetch a copy of the tuple to scribble on */
500         ctup = SearchSysCacheCopy1(RELOID, ObjectIdGetDatum(relid));
501         if (!HeapTupleIsValid(ctup))
502                 elog(ERROR, "pg_class entry for relid %u vanished during vacuuming",
503                          relid);
504         pgcform = (Form_pg_class) GETSTRUCT(ctup);
505
506         /* Apply required updates, if any, to copied tuple */
507
508         dirty = false;
509         if (pgcform->relpages != (int32) num_pages)
510         {
511                 pgcform->relpages = (int32) num_pages;
512                 dirty = true;
513         }
514         if (pgcform->reltuples != (float4) num_tuples)
515         {
516                 pgcform->reltuples = (float4) num_tuples;
517                 dirty = true;
518         }
519         if (pgcform->relhasindex != hasindex)
520         {
521                 pgcform->relhasindex = hasindex;
522                 dirty = true;
523         }
524
525         /*
526          * If we have discovered that there are no indexes, then there's no
527          * primary key either, nor any exclusion constraints.  This could be done
528          * more thoroughly...
529          */
530         if (!hasindex)
531         {
532                 if (pgcform->relhaspkey)
533                 {
534                         pgcform->relhaspkey = false;
535                         dirty = true;
536                 }
537                 if (pgcform->relhasexclusion && pgcform->relkind != RELKIND_INDEX)
538                 {
539                         pgcform->relhasexclusion = false;
540                         dirty = true;
541                 }
542         }
543
544         /* We also clear relhasrules and relhastriggers if needed */
545         if (pgcform->relhasrules && relation->rd_rules == NULL)
546         {
547                 pgcform->relhasrules = false;
548                 dirty = true;
549         }
550         if (pgcform->relhastriggers && relation->trigdesc == NULL)
551         {
552                 pgcform->relhastriggers = false;
553                 dirty = true;
554         }
555
556         /*
557          * relfrozenxid should never go backward.  Caller can pass
558          * InvalidTransactionId if it has no new data.
559          */
560         if (TransactionIdIsNormal(frozenxid) &&
561                 TransactionIdPrecedes(pgcform->relfrozenxid, frozenxid))
562         {
563                 pgcform->relfrozenxid = frozenxid;
564                 dirty = true;
565         }
566
567         /* If anything changed, write out the tuple. */
568         if (dirty)
569                 heap_inplace_update(rd, ctup);
570
571         heap_close(rd, RowExclusiveLock);
572 }
573
574
575 /*
576  *      vac_update_datfrozenxid() -- update pg_database.datfrozenxid for our DB
577  *
578  *              Update pg_database's datfrozenxid entry for our database to be the
579  *              minimum of the pg_class.relfrozenxid values.  If we are able to
580  *              advance pg_database.datfrozenxid, also try to truncate pg_clog.
581  *
582  *              We violate transaction semantics here by overwriting the database's
583  *              existing pg_database tuple with the new value.  This is reasonably
584  *              safe since the new value is correct whether or not this transaction
585  *              commits.  As with vac_update_relstats, this avoids leaving dead tuples
586  *              behind after a VACUUM.
587  */
588 void
589 vac_update_datfrozenxid(void)
590 {
591         HeapTuple       tuple;
592         Form_pg_database dbform;
593         Relation        relation;
594         SysScanDesc scan;
595         HeapTuple       classTup;
596         TransactionId newFrozenXid;
597         bool            dirty = false;
598
599         /*
600          * Initialize the "min" calculation with GetOldestXmin, which is a
601          * reasonable approximation to the minimum relfrozenxid for not-yet-
602          * committed pg_class entries for new tables; see AddNewRelationTuple().
603          * Se we cannot produce a wrong minimum by starting with this.
604          */
605         newFrozenXid = GetOldestXmin(true, true);
606
607         /*
608          * We must seqscan pg_class to find the minimum Xid, because there is no
609          * index that can help us here.
610          */
611         relation = heap_open(RelationRelationId, AccessShareLock);
612
613         scan = systable_beginscan(relation, InvalidOid, false,
614                                                           SnapshotNow, 0, NULL);
615
616         while ((classTup = systable_getnext(scan)) != NULL)
617         {
618                 Form_pg_class classForm = (Form_pg_class) GETSTRUCT(classTup);
619
620                 /*
621                  * Only consider heap and TOAST tables (anything else should have
622                  * InvalidTransactionId in relfrozenxid anyway.)
623                  */
624                 if (classForm->relkind != RELKIND_RELATION &&
625                         classForm->relkind != RELKIND_TOASTVALUE)
626                         continue;
627
628                 Assert(TransactionIdIsNormal(classForm->relfrozenxid));
629
630                 if (TransactionIdPrecedes(classForm->relfrozenxid, newFrozenXid))
631                         newFrozenXid = classForm->relfrozenxid;
632         }
633
634         /* we're done with pg_class */
635         systable_endscan(scan);
636         heap_close(relation, AccessShareLock);
637
638         Assert(TransactionIdIsNormal(newFrozenXid));
639
640         /* Now fetch the pg_database tuple we need to update. */
641         relation = heap_open(DatabaseRelationId, RowExclusiveLock);
642
643         /* Fetch a copy of the tuple to scribble on */
644         tuple = SearchSysCacheCopy1(DATABASEOID, ObjectIdGetDatum(MyDatabaseId));
645         if (!HeapTupleIsValid(tuple))
646                 elog(ERROR, "could not find tuple for database %u", MyDatabaseId);
647         dbform = (Form_pg_database) GETSTRUCT(tuple);
648
649         /*
650          * Don't allow datfrozenxid to go backward (probably can't happen anyway);
651          * and detect the common case where it doesn't go forward either.
652          */
653         if (TransactionIdPrecedes(dbform->datfrozenxid, newFrozenXid))
654         {
655                 dbform->datfrozenxid = newFrozenXid;
656                 dirty = true;
657         }
658
659         if (dirty)
660                 heap_inplace_update(relation, tuple);
661
662         heap_freetuple(tuple);
663         heap_close(relation, RowExclusiveLock);
664
665         /*
666          * If we were able to advance datfrozenxid, see if we can truncate
667          * pg_clog. Also do it if the shared XID-wrap-limit info is stale, since
668          * this action will update that too.
669          */
670         if (dirty || ForceTransactionIdLimitUpdate())
671                 vac_truncate_clog(newFrozenXid);
672 }
673
674
675 /*
676  *      vac_truncate_clog() -- attempt to truncate the commit log
677  *
678  *              Scan pg_database to determine the system-wide oldest datfrozenxid,
679  *              and use it to truncate the transaction commit log (pg_clog).
680  *              Also update the XID wrap limit info maintained by varsup.c.
681  *
682  *              The passed XID is simply the one I just wrote into my pg_database
683  *              entry.  It's used to initialize the "min" calculation.
684  *
685  *              This routine is only invoked when we've managed to change our
686  *              DB's datfrozenxid entry, or we found that the shared XID-wrap-limit
687  *              info is stale.
688  */
689 static void
690 vac_truncate_clog(TransactionId frozenXID)
691 {
692         TransactionId myXID = GetCurrentTransactionId();
693         Relation        relation;
694         HeapScanDesc scan;
695         HeapTuple       tuple;
696         Oid                     oldest_datoid;
697         bool            frozenAlreadyWrapped = false;
698
699         /* init oldest_datoid to sync with my frozenXID */
700         oldest_datoid = MyDatabaseId;
701
702         /*
703          * Scan pg_database to compute the minimum datfrozenxid
704          *
705          * Note: we need not worry about a race condition with new entries being
706          * inserted by CREATE DATABASE.  Any such entry will have a copy of some
707          * existing DB's datfrozenxid, and that source DB cannot be ours because
708          * of the interlock against copying a DB containing an active backend.
709          * Hence the new entry will not reduce the minimum.  Also, if two VACUUMs
710          * concurrently modify the datfrozenxid's of different databases, the
711          * worst possible outcome is that pg_clog is not truncated as aggressively
712          * as it could be.
713          */
714         relation = heap_open(DatabaseRelationId, AccessShareLock);
715
716         scan = heap_beginscan(relation, SnapshotNow, 0, NULL);
717
718         while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
719         {
720                 Form_pg_database dbform = (Form_pg_database) GETSTRUCT(tuple);
721
722                 Assert(TransactionIdIsNormal(dbform->datfrozenxid));
723
724                 if (TransactionIdPrecedes(myXID, dbform->datfrozenxid))
725                         frozenAlreadyWrapped = true;
726                 else if (TransactionIdPrecedes(dbform->datfrozenxid, frozenXID))
727                 {
728                         frozenXID = dbform->datfrozenxid;
729                         oldest_datoid = HeapTupleGetOid(tuple);
730                 }
731         }
732
733         heap_endscan(scan);
734
735         heap_close(relation, AccessShareLock);
736
737         /*
738          * Do not truncate CLOG if we seem to have suffered wraparound already;
739          * the computed minimum XID might be bogus.  This case should now be
740          * impossible due to the defenses in GetNewTransactionId, but we keep the
741          * test anyway.
742          */
743         if (frozenAlreadyWrapped)
744         {
745                 ereport(WARNING,
746                                 (errmsg("some databases have not been vacuumed in over 2 billion transactions"),
747                                  errdetail("You might have already suffered transaction-wraparound data loss.")));
748                 return;
749         }
750
751         /* Truncate CLOG to the oldest frozenxid */
752         TruncateCLOG(frozenXID);
753
754         /*
755          * Update the wrap limit for GetNewTransactionId.  Note: this function
756          * will also signal the postmaster for an(other) autovac cycle if needed.
757          */
758         SetTransactionIdLimit(frozenXID, oldest_datoid);
759 }
760
761
762 /*
763  *      vacuum_rel() -- vacuum one heap relation
764  *
765  *              Doing one heap at a time incurs extra overhead, since we need to
766  *              check that the heap exists again just before we vacuum it.      The
767  *              reason that we do this is so that vacuuming can be spread across
768  *              many small transactions.  Otherwise, two-phase locking would require
769  *              us to lock the entire database during one pass of the vacuum cleaner.
770  *
771  *              We'll return true in *scanned_all if the vacuum scanned all heap
772  *              pages, and updated pg_class.
773  *
774  *              At entry and exit, we are not inside a transaction.
775  */
776 static void
777 vacuum_rel(Oid relid, VacuumStmt *vacstmt, bool do_toast, bool for_wraparound,
778                    bool *scanned_all)
779 {
780         LOCKMODE        lmode;
781         Relation        onerel;
782         LockRelId       onerelid;
783         Oid                     toast_relid;
784         Oid                     save_userid;
785         int                     save_sec_context;
786         int                     save_nestlevel;
787
788         if (scanned_all)
789                 *scanned_all = false;
790
791         /* Begin a transaction for vacuuming this relation */
792         StartTransactionCommand();
793
794         /*
795          * Functions in indexes may want a snapshot set.  Also, setting a snapshot
796          * ensures that RecentGlobalXmin is kept truly recent.
797          */
798         PushActiveSnapshot(GetTransactionSnapshot());
799
800         if (!(vacstmt->options & VACOPT_FULL))
801         {
802                 /*
803                  * In lazy vacuum, we can set the PROC_IN_VACUUM flag, which lets
804                  * other concurrent VACUUMs know that they can ignore this one while
805                  * determining their OldestXmin.  (The reason we don't set it during a
806                  * full VACUUM is exactly that we may have to run user-defined
807                  * functions for functional indexes, and we want to make sure that if
808                  * they use the snapshot set above, any tuples it requires can't get
809                  * removed from other tables.  An index function that depends on the
810                  * contents of other tables is arguably broken, but we won't break it
811                  * here by violating transaction semantics.)
812                  *
813                  * We also set the VACUUM_FOR_WRAPAROUND flag, which is passed down by
814                  * autovacuum; it's used to avoid cancelling a vacuum that was invoked
815                  * in an emergency.
816                  *
817                  * Note: these flags remain set until CommitTransaction or
818                  * AbortTransaction.  We don't want to clear them until we reset
819                  * MyProc->xid/xmin, else OldestXmin might appear to go backwards,
820                  * which is probably Not Good.
821                  */
822                 LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
823                 MyProc->vacuumFlags |= PROC_IN_VACUUM;
824                 if (for_wraparound)
825                         MyProc->vacuumFlags |= PROC_VACUUM_FOR_WRAPAROUND;
826                 LWLockRelease(ProcArrayLock);
827         }
828
829         /*
830          * Check for user-requested abort.      Note we want this to be inside a
831          * transaction, so xact.c doesn't issue useless WARNING.
832          */
833         CHECK_FOR_INTERRUPTS();
834
835         /*
836          * Determine the type of lock we want --- hard exclusive lock for a FULL
837          * vacuum, but just ShareUpdateExclusiveLock for concurrent vacuum. Either
838          * way, we can be sure that no other backend is vacuuming the same table.
839          */
840         lmode = (vacstmt->options & VACOPT_FULL) ? AccessExclusiveLock : ShareUpdateExclusiveLock;
841
842         /*
843          * Open the relation and get the appropriate lock on it.
844          *
845          * There's a race condition here: the rel may have gone away since the
846          * last time we saw it.  If so, we don't need to vacuum it.
847          */
848         onerel = try_relation_open(relid, lmode);
849
850         if (!onerel)
851         {
852                 PopActiveSnapshot();
853                 CommitTransactionCommand();
854                 return;
855         }
856
857         /*
858          * Check permissions.
859          *
860          * We allow the user to vacuum a table if he is superuser, the table
861          * owner, or the database owner (but in the latter case, only if it's not
862          * a shared relation).  pg_class_ownercheck includes the superuser case.
863          *
864          * Note we choose to treat permissions failure as a WARNING and keep
865          * trying to vacuum the rest of the DB --- is this appropriate?
866          */
867         if (!(pg_class_ownercheck(RelationGetRelid(onerel), GetUserId()) ||
868                   (pg_database_ownercheck(MyDatabaseId, GetUserId()) && !onerel->rd_rel->relisshared)))
869         {
870                 if (onerel->rd_rel->relisshared)
871                         ereport(WARNING,
872                                   (errmsg("skipping \"%s\" --- only superuser can vacuum it",
873                                                   RelationGetRelationName(onerel))));
874                 else if (onerel->rd_rel->relnamespace == PG_CATALOG_NAMESPACE)
875                         ereport(WARNING,
876                                         (errmsg("skipping \"%s\" --- only superuser or database owner can vacuum it",
877                                                         RelationGetRelationName(onerel))));
878                 else
879                         ereport(WARNING,
880                                         (errmsg("skipping \"%s\" --- only table or database owner can vacuum it",
881                                                         RelationGetRelationName(onerel))));
882                 relation_close(onerel, lmode);
883                 PopActiveSnapshot();
884                 CommitTransactionCommand();
885                 return;
886         }
887
888         /*
889          * Check that it's a vacuumable table; we used to do this in
890          * get_rel_oids() but seems safer to check after we've locked the
891          * relation.
892          */
893         if (onerel->rd_rel->relkind != RELKIND_RELATION &&
894                 onerel->rd_rel->relkind != RELKIND_TOASTVALUE)
895         {
896                 ereport(WARNING,
897                                 (errmsg("skipping \"%s\" --- cannot vacuum indexes, views, or special system tables",
898                                                 RelationGetRelationName(onerel))));
899                 relation_close(onerel, lmode);
900                 PopActiveSnapshot();
901                 CommitTransactionCommand();
902                 return;
903         }
904
905         /*
906          * Silently ignore tables that are temp tables of other backends ---
907          * trying to vacuum these will lead to great unhappiness, since their
908          * contents are probably not up-to-date on disk.  (We don't throw a
909          * warning here; it would just lead to chatter during a database-wide
910          * VACUUM.)
911          */
912         if (RELATION_IS_OTHER_TEMP(onerel))
913         {
914                 relation_close(onerel, lmode);
915                 PopActiveSnapshot();
916                 CommitTransactionCommand();
917                 return;
918         }
919
920         /*
921          * Get a session-level lock too. This will protect our access to the
922          * relation across multiple transactions, so that we can vacuum the
923          * relation's TOAST table (if any) secure in the knowledge that no one is
924          * deleting the parent relation.
925          *
926          * NOTE: this cannot block, even if someone else is waiting for access,
927          * because the lock manager knows that both lock requests are from the
928          * same process.
929          */
930         onerelid = onerel->rd_lockInfo.lockRelId;
931         LockRelationIdForSession(&onerelid, lmode);
932
933         /*
934          * Remember the relation's TOAST relation for later, if the caller asked
935          * us to process it.  In VACUUM FULL, though, the toast table is
936          * automatically rebuilt by cluster_rel so we shouldn't recurse to it.
937          */
938         if (do_toast && !(vacstmt->options & VACOPT_FULL))
939                 toast_relid = onerel->rd_rel->reltoastrelid;
940         else
941                 toast_relid = InvalidOid;
942
943         /*
944          * Switch to the table owner's userid, so that any index functions are run
945          * as that user.  Also lock down security-restricted operations and
946          * arrange to make GUC variable changes local to this command. (This is
947          * unnecessary, but harmless, for lazy VACUUM.)
948          */
949         GetUserIdAndSecContext(&save_userid, &save_sec_context);
950         SetUserIdAndSecContext(onerel->rd_rel->relowner,
951                                                    save_sec_context | SECURITY_RESTRICTED_OPERATION);
952         save_nestlevel = NewGUCNestLevel();
953
954         /*
955          * Do the actual work --- either FULL or "lazy" vacuum
956          */
957         if (vacstmt->options & VACOPT_FULL)
958         {
959                 /* close relation before vacuuming, but hold lock until commit */
960                 relation_close(onerel, NoLock);
961                 onerel = NULL;
962
963                 /* VACUUM FULL is now a variant of CLUSTER; see cluster.c */
964                 cluster_rel(relid, InvalidOid, false,
965                                         (vacstmt->options & VACOPT_VERBOSE) != 0,
966                                         vacstmt->freeze_min_age, vacstmt->freeze_table_age);
967         }
968         else
969                 lazy_vacuum_rel(onerel, vacstmt, vac_strategy, scanned_all);
970
971         /* Roll back any GUC changes executed by index functions */
972         AtEOXact_GUC(false, save_nestlevel);
973
974         /* Restore userid and security context */
975         SetUserIdAndSecContext(save_userid, save_sec_context);
976
977         /* all done with this class, but hold lock until commit */
978         if (onerel)
979                 relation_close(onerel, NoLock);
980
981         /*
982          * Complete the transaction and free all temporary memory used.
983          */
984         PopActiveSnapshot();
985         CommitTransactionCommand();
986
987         /*
988          * If the relation has a secondary toast rel, vacuum that too while we
989          * still hold the session lock on the master table.  Note however that
990          * "analyze" will not get done on the toast table.      This is good, because
991          * the toaster always uses hardcoded index access and statistics are
992          * totally unimportant for toast relations.
993          */
994         if (toast_relid != InvalidOid)
995                 vacuum_rel(toast_relid, vacstmt, false, for_wraparound, NULL);
996
997         /*
998          * Now release the session-level lock on the master table.
999          */
1000         UnlockRelationIdForSession(&onerelid, lmode);
1001 }
1002
1003
1004 /*
1005  * Open all the indexes of the given relation, obtaining the specified kind
1006  * of lock on each.  Return an array of Relation pointers for the indexes
1007  * into *Irel, and the number of indexes into *nindexes.
1008  */
1009 void
1010 vac_open_indexes(Relation relation, LOCKMODE lockmode,
1011                                  int *nindexes, Relation **Irel)
1012 {
1013         List       *indexoidlist;
1014         ListCell   *indexoidscan;
1015         int                     i;
1016
1017         Assert(lockmode != NoLock);
1018
1019         indexoidlist = RelationGetIndexList(relation);
1020
1021         *nindexes = list_length(indexoidlist);
1022
1023         if (*nindexes > 0)
1024                 *Irel = (Relation *) palloc(*nindexes * sizeof(Relation));
1025         else
1026                 *Irel = NULL;
1027
1028         i = 0;
1029         foreach(indexoidscan, indexoidlist)
1030         {
1031                 Oid                     indexoid = lfirst_oid(indexoidscan);
1032
1033                 (*Irel)[i++] = index_open(indexoid, lockmode);
1034         }
1035
1036         list_free(indexoidlist);
1037 }
1038
1039 /*
1040  * Release the resources acquired by vac_open_indexes.  Optionally release
1041  * the locks (say NoLock to keep 'em).
1042  */
1043 void
1044 vac_close_indexes(int nindexes, Relation *Irel, LOCKMODE lockmode)
1045 {
1046         if (Irel == NULL)
1047                 return;
1048
1049         while (nindexes--)
1050         {
1051                 Relation        ind = Irel[nindexes];
1052
1053                 index_close(ind, lockmode);
1054         }
1055         pfree(Irel);
1056 }
1057
1058 /*
1059  * vacuum_delay_point --- check for interrupts and cost-based delay.
1060  *
1061  * This should be called in each major loop of VACUUM processing,
1062  * typically once per page processed.
1063  */
1064 void
1065 vacuum_delay_point(void)
1066 {
1067         /* Always check for interrupts */
1068         CHECK_FOR_INTERRUPTS();
1069
1070         /* Nap if appropriate */
1071         if (VacuumCostActive && !InterruptPending &&
1072                 VacuumCostBalance >= VacuumCostLimit)
1073         {
1074                 int                     msec;
1075
1076                 msec = VacuumCostDelay * VacuumCostBalance / VacuumCostLimit;
1077                 if (msec > VacuumCostDelay * 4)
1078                         msec = VacuumCostDelay * 4;
1079
1080                 pg_usleep(msec * 1000L);
1081
1082                 VacuumCostBalance = 0;
1083
1084                 /* update balance values for workers */
1085                 AutoVacuumUpdateDelay();
1086
1087                 /* Might have gotten an interrupt while sleeping */
1088                 CHECK_FOR_INTERRUPTS();
1089         }
1090 }