1 /*-------------------------------------------------------------------------
5 * PostgreSQL Integrated Autovacuum Daemon
8 * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
9 * Portions Copyright (c) 1994, Regents of the University of California
13 * $PostgreSQL: pgsql/src/backend/postmaster/autovacuum.c,v 1.8 2005/11/28 17:23:11 alvherre Exp $
15 *-------------------------------------------------------------------------
20 #include <sys/types.h>
24 #include "access/genam.h"
25 #include "access/heapam.h"
26 #include "access/xlog.h"
27 #include "catalog/indexing.h"
28 #include "catalog/namespace.h"
29 #include "catalog/pg_autovacuum.h"
30 #include "catalog/pg_database.h"
31 #include "commands/vacuum.h"
32 #include "libpq/hba.h"
33 #include "libpq/pqsignal.h"
34 #include "miscadmin.h"
36 #include "postmaster/autovacuum.h"
37 #include "postmaster/fork_process.h"
38 #include "postmaster/postmaster.h"
39 #include "storage/fd.h"
40 #include "storage/ipc.h"
41 #include "storage/proc.h"
42 #include "storage/sinval.h"
43 #include "tcop/tcopprot.h"
44 #include "utils/flatfiles.h"
45 #include "utils/fmgroids.h"
46 #include "utils/memutils.h"
47 #include "utils/ps_status.h"
48 #include "utils/relcache.h"
54 bool autovacuum_start_daemon = false;
55 int autovacuum_naptime;
56 int autovacuum_vac_thresh;
57 double autovacuum_vac_scale;
58 int autovacuum_anl_thresh;
59 double autovacuum_anl_scale;
61 int autovacuum_vac_cost_delay;
62 int autovacuum_vac_cost_limit;
64 /* Flag to tell if we are in the autovacuum daemon process */
65 static bool am_autovacuum = false;
67 /* Last time autovac daemon started/stopped (only valid in postmaster) */
68 static time_t last_autovac_start_time = 0;
69 static time_t last_autovac_stop_time = 0;
71 /* Memory context for long-lived data */
72 static MemoryContext AutovacMemCxt;
74 /* struct to keep list of candidate databases for vacuum */
75 typedef struct autovac_dbase
79 TransactionId frozenxid;
80 TransactionId vacuumxid;
81 PgStat_StatDBEntry *entry;
85 /* struct to keep track of tables to vacuum and/or analyze */
86 typedef struct autovac_table
92 int vacuum_cost_delay;
93 int vacuum_cost_limit;
98 static pid_t autovac_forkexec(void);
100 NON_EXEC_STATIC void AutoVacMain(int argc, char *argv[]);
101 static void process_whole_db(void);
102 static void do_autovacuum(PgStat_StatDBEntry *dbentry);
103 static List *autovac_get_database_list(void);
104 static void test_rel_for_autovac(Oid relid, PgStat_StatTabEntry *tabentry,
105 Form_pg_class classForm,
106 Form_pg_autovacuum avForm,
107 List **vacuum_tables,
108 List **toast_table_ids);
109 static void autovacuum_do_vac_analyze(List *relids, bool dovacuum,
110 bool doanalyze, bool freeze);
114 * Main entry point for autovacuum controller process.
116 * This code is heavily based on pgarch.c, q.v.
124 /* Do nothing if no autovacuum process needed */
125 if (!AutoVacuumingActive())
129 * Do nothing if too soon since last autovacuum exit. This limits how
130 * often the daemon runs. Since the time per iteration can be quite
131 * variable, it seems more useful to measure/control the time since last
132 * subprocess exit than since last subprocess launch.
134 * However, we *also* check the time since last subprocess launch; this
135 * prevents thrashing under fork-failure conditions.
137 * Note that since we will be re-called from the postmaster main loop, we
138 * will get another chance later if we do nothing now.
140 * XXX todo: implement sleep scale factor that existed in contrib code.
142 curtime = time(NULL);
143 if ((unsigned int) (curtime - last_autovac_stop_time) <
144 (unsigned int) autovacuum_naptime)
147 if ((unsigned int) (curtime - last_autovac_start_time) <
148 (unsigned int) autovacuum_naptime)
151 last_autovac_start_time = curtime;
154 switch ((AutoVacPID = autovac_forkexec()))
156 switch ((AutoVacPID = fork_process()))
161 (errmsg("could not fork autovacuum process: %m")));
166 /* in postmaster child ... */
167 /* Close the postmaster's sockets */
168 ClosePostmasterPorts(false);
170 AutoVacMain(0, NULL);
174 return (int) AutoVacPID;
177 /* shouldn't get here */
182 * autovac_stopped --- called by postmaster when subprocess exit is detected
185 autovac_stopped(void)
187 last_autovac_stop_time = time(NULL);
194 * Format up the arglist for the autovacuum process, then fork and exec.
197 autovac_forkexec(void)
202 av[ac++] = "postgres";
203 av[ac++] = "-forkautovac";
204 av[ac++] = NULL; /* filled in by postmaster_forkexec */
207 Assert(ac < lengthof(av));
209 return postmaster_forkexec(ac, av);
211 #endif /* EXEC_BACKEND */
217 AutoVacMain(int argc, char *argv[])
221 TransactionId nextXid;
224 sigjmp_buf local_sigjmp_buf;
226 /* we are a postmaster subprocess now */
227 IsUnderPostmaster = true;
228 am_autovacuum = true;
230 /* reset MyProcPid */
231 MyProcPid = getpid();
233 /* Lose the postmaster's on-exit routines */
236 /* Identify myself via ps */
237 init_ps_display("autovacuum process", "", "");
240 SetProcessingMode(InitProcessing);
243 * Set up signal handlers. We operate on databases much like a regular
244 * backend, so we use the same signal handling. See equivalent code in
247 * Currently, we don't pay attention to postgresql.conf changes that
248 * happen during a single daemon iteration, so we can ignore SIGHUP.
250 pqsignal(SIGHUP, SIG_IGN);
253 * Presently, SIGINT will lead to autovacuum shutdown, because that's how
254 * we handle ereport(ERROR). It could be improved however.
256 pqsignal(SIGINT, StatementCancelHandler);
257 pqsignal(SIGTERM, die);
258 pqsignal(SIGQUIT, quickdie);
259 pqsignal(SIGALRM, handle_sig_alarm);
261 pqsignal(SIGPIPE, SIG_IGN);
262 pqsignal(SIGUSR1, CatchupInterruptHandler);
263 /* We don't listen for async notifies */
264 pqsignal(SIGUSR2, SIG_IGN);
265 pqsignal(SIGFPE, FloatExceptionHandler);
266 pqsignal(SIGCHLD, SIG_DFL);
268 /* Early initialization */
272 * If an exception is encountered, processing resumes here.
274 * See notes in postgres.c about the design of this coding.
276 if (sigsetjmp(local_sigjmp_buf, 1) != 0)
278 /* Prevents interrupts while cleaning up */
281 /* Report the error to the server log */
285 * We can now go away. Note that because we'll call InitProcess, a
286 * callback will be registered to do ProcKill, which will clean up
292 /* We can now handle ereport(ERROR) */
293 PG_exception_stack = &local_sigjmp_buf;
295 PG_SETMASK(&UnBlockSig);
297 /* Get a list of databases */
298 dblist = autovac_get_database_list();
301 * Get the next Xid that was current as of the last checkpoint. We need it
302 * to determine whether databases are about to need database-wide vacuums.
304 nextXid = GetRecentNextXid();
307 * Choose a database to connect to. We pick the database that was least
308 * recently auto-vacuumed, or one that needs database-wide vacuum (to
309 * prevent Xid wraparound-related data loss).
311 * Note that a database with no stats entry is not considered, except for
312 * Xid wraparound purposes. The theory is that if no one has ever
313 * connected to it since the stats were last initialized, it doesn't need
316 * XXX This could be improved if we had more info about whether it needs
317 * vacuuming before connecting to it. Perhaps look through the pgstats
318 * data for the database's tables? One idea is to keep track of the
319 * number of new and dead tuples per database in pgstats. However it
320 * isn't clear how to construct a metric that measures that and not cause
321 * starvation for less busy databases.
326 foreach(cell, dblist)
328 autovac_dbase *tmp = lfirst(cell);
334 * We look for the database that most urgently needs a database-wide
335 * vacuum. We decide that a database-wide vacuum is needed 100000
336 * transactions sooner than vacuum.c's vac_truncate_clog() would
337 * decide to start giving warnings. If any such db is found, we
338 * ignore all other dbs.
340 * Unlike vacuum.c, we also look at vacuumxid. This is so that
341 * pg_clog can be kept trimmed to a reasonable size.
343 freeze_age = (int32) (nextXid - tmp->frozenxid);
344 vacuum_age = (int32) (nextXid - tmp->vacuumxid);
345 tmp->age = Max(freeze_age, vacuum_age);
347 this_whole_db = (tmp->age >
348 (int32) ((MaxTransactionId >> 3) * 3 - 100000));
349 if (whole_db || this_whole_db)
353 if (db == NULL || tmp->age > db->age)
362 * Otherwise, skip a database with no pgstat entry; it means it hasn't
365 tmp->entry = pgstat_fetch_stat_dbentry(tmp->oid);
370 * Don't try to access a database that was dropped. This could only
371 * happen if we read the pg_database flat file right before it was
372 * modified, after the database was dropped from the pg_database
373 * table. (This is of course a not-very-bulletproof test, but it's
374 * cheap to make. If we do mistakenly choose a recently dropped
375 * database, InitPostgres will fail and we'll drop out until the next
378 if (tmp->entry->destroy != 0)
382 * Else remember the db with oldest autovac time.
385 tmp->entry->last_autovac_time < db->entry->last_autovac_time)
392 * Report autovac startup to the stats collector. We deliberately do
393 * this before InitPostgres, so that the last_autovac_time will get
394 * updated even if the connection attempt fails. This is to prevent
395 * autovac from getting "stuck" repeatedly selecting an unopenable
396 * database, rather than making any progress on stuff it can connect
399 pgstat_report_autovac(db->oid);
402 * Connect to the selected database
404 InitPostgres(db->name, NULL);
405 SetProcessingMode(NormalProcessing);
406 set_ps_display(db->name);
408 (errmsg("autovacuum: processing database \"%s\"", db->name)));
410 /* Create the memory context where cross-transaction state is stored */
411 AutovacMemCxt = AllocSetContextCreate(TopMemoryContext,
412 "Autovacuum context",
413 ALLOCSET_DEFAULT_MINSIZE,
414 ALLOCSET_DEFAULT_INITSIZE,
415 ALLOCSET_DEFAULT_MAXSIZE);
418 * And do an appropriate amount of work
423 do_autovacuum(db->entry);
426 /* One iteration done, go away */
431 * autovac_get_database_list
433 * Return a list of all databases. Note we cannot use pg_database,
434 * because we aren't connected yet; we use the flat database file.
437 autovac_get_database_list(void)
441 char thisname[NAMEDATALEN];
445 TransactionId db_frozenxid;
446 TransactionId db_vacuumxid;
448 filename = database_getflatfilename();
449 db_file = AllocateFile(filename, "r");
452 (errcode_for_file_access(),
453 errmsg("could not open file \"%s\": %m", filename)));
455 while (read_pg_database_line(db_file, thisname, &db_id,
456 &db_tablespace, &db_frozenxid,
461 db = (autovac_dbase *) palloc(sizeof(autovac_dbase));
464 db->name = pstrdup(thisname);
465 db->frozenxid = db_frozenxid;
466 db->vacuumxid = db_vacuumxid;
467 /* these get set later: */
471 dblist = lappend(dblist, db);
481 * Process a whole database. If it's a template database or is disallowing
482 * connection by means of datallowconn=false, then issue a VACUUM FREEZE.
483 * Else use a plain VACUUM.
486 process_whole_db(void)
489 ScanKeyData entry[1];
492 Form_pg_database dbForm;
495 /* Start a transaction so our commands have one to play into. */
496 StartTransactionCommand();
498 /* functions in indexes may want a snapshot set */
499 ActiveSnapshot = CopySnapshot(GetTransactionSnapshot());
501 dbRel = heap_open(DatabaseRelationId, AccessShareLock);
503 /* Must use a table scan, since there's no syscache for pg_database */
504 ScanKeyInit(&entry[0],
505 ObjectIdAttributeNumber,
506 BTEqualStrategyNumber, F_OIDEQ,
507 ObjectIdGetDatum(MyDatabaseId));
509 scan = systable_beginscan(dbRel, DatabaseOidIndexId, true,
510 SnapshotNow, 1, entry);
512 tup = systable_getnext(scan);
514 if (!HeapTupleIsValid(tup))
515 elog(ERROR, "could not find tuple for database %u", MyDatabaseId);
517 dbForm = (Form_pg_database) GETSTRUCT(tup);
519 if (!dbForm->datallowconn || dbForm->datistemplate)
524 systable_endscan(scan);
526 heap_close(dbRel, AccessShareLock);
528 elog(DEBUG2, "autovacuum: VACUUM%s whole database",
529 (freeze) ? " FREEZE" : "");
531 autovacuum_do_vac_analyze(NIL, true, false, freeze);
533 /* Finally close out the last transaction. */
534 CommitTransactionCommand();
538 * Process a database table-by-table
540 * dbentry must be a valid pointer to the database entry in the stats
541 * databases' hash table, and it will be used to determine whether vacuum or
542 * analyze is needed on a per-table basis.
544 * Note that CHECK_FOR_INTERRUPTS is supposed to be used in certain spots in
545 * order not to ignore shutdown commands for too long.
548 do_autovacuum(PgStat_StatDBEntry *dbentry)
553 HeapScanDesc relScan;
554 List *vacuum_tables = NIL;
555 List *toast_table_ids = NIL;
557 PgStat_StatDBEntry *shared;
559 /* Start a transaction so our commands have one to play into. */
560 StartTransactionCommand();
562 /* functions in indexes may want a snapshot set */
563 ActiveSnapshot = CopySnapshot(GetTransactionSnapshot());
566 * StartTransactionCommand and CommitTransactionCommand will automatically
567 * switch to other contexts. We need this one to keep the list of
568 * relations to vacuum/analyze across transactions.
570 MemoryContextSwitchTo(AutovacMemCxt);
572 /* The database hash where pgstat keeps shared relations */
573 shared = pgstat_fetch_stat_dbentry(InvalidOid);
575 classRel = heap_open(RelationRelationId, AccessShareLock);
576 avRel = heap_open(AutovacuumRelationId, AccessShareLock);
579 * Scan pg_class and determine which tables to vacuum.
581 * The stats subsystem collects stats for toast tables independently of
582 * the stats for their parent tables. We need to check those stats since
583 * in cases with short, wide tables there might be proportionally much
584 * more activity in the toast table than in its parent.
586 * Since we can only issue VACUUM against the parent table, we need to
587 * transpose a decision to vacuum a toast table into a decision to vacuum
588 * its parent. There's no point in considering ANALYZE on a toast table,
589 * either. To support this, we keep a list of OIDs of toast tables that
590 * need vacuuming alongside the list of regular tables. Regular tables
591 * will be entered into the table list even if they appear not to need
592 * vacuuming; we go back and re-mark them after finding all the vacuumable
595 relScan = heap_beginscan(classRel, SnapshotNow, 0, NULL);
597 while ((tuple = heap_getnext(relScan, ForwardScanDirection)) != NULL)
599 Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple);
600 Form_pg_autovacuum avForm = NULL;
601 PgStat_StatTabEntry *tabentry;
604 ScanKeyData entry[1];
607 /* Consider only regular and toast tables. */
608 if (classForm->relkind != RELKIND_RELATION &&
609 classForm->relkind != RELKIND_TOASTVALUE)
613 * Skip temp tables (i.e. those in temp namespaces). We cannot safely
614 * process other backends' temp tables.
616 if (isTempNamespace(classForm->relnamespace))
619 relid = HeapTupleGetOid(tuple);
621 /* See if we have a pg_autovacuum entry for this relation. */
622 ScanKeyInit(&entry[0],
623 Anum_pg_autovacuum_vacrelid,
624 BTEqualStrategyNumber, F_OIDEQ,
625 ObjectIdGetDatum(relid));
627 avScan = systable_beginscan(avRel, AutovacuumRelidIndexId, true,
628 SnapshotNow, 1, entry);
630 avTup = systable_getnext(avScan);
632 if (HeapTupleIsValid(avTup))
633 avForm = (Form_pg_autovacuum) GETSTRUCT(avTup);
635 if (classForm->relisshared && PointerIsValid(shared))
636 tabentry = hash_search(shared->tables, &relid,
639 tabentry = hash_search(dbentry->tables, &relid,
642 test_rel_for_autovac(relid, tabentry, classForm, avForm,
643 &vacuum_tables, &toast_table_ids);
645 systable_endscan(avScan);
648 heap_endscan(relScan);
649 heap_close(avRel, AccessShareLock);
650 heap_close(classRel, AccessShareLock);
653 * Perform operations on collected tables.
655 foreach(cell, vacuum_tables)
657 autovac_table *tab = lfirst(cell);
659 CHECK_FOR_INTERRUPTS();
662 * Check to see if we need to force vacuuming of this table because
663 * its toast table needs it.
665 if (OidIsValid(tab->toastrelid) && !tab->dovacuum &&
666 list_member_oid(toast_table_ids, tab->toastrelid))
668 tab->dovacuum = true;
669 elog(DEBUG2, "autovac: VACUUM %u because of TOAST table",
673 /* Otherwise, ignore table if it needs no work */
674 if (!tab->dovacuum && !tab->doanalyze)
677 /* Set the vacuum cost parameters for this table */
678 VacuumCostDelay = tab->vacuum_cost_delay;
679 VacuumCostLimit = tab->vacuum_cost_limit;
681 autovacuum_do_vac_analyze(list_make1_oid(tab->relid),
687 /* Finally close out the last transaction. */
688 CommitTransactionCommand();
692 * test_rel_for_autovac
694 * Check whether a table needs to be vacuumed or analyzed. Add it to the
695 * appropriate output list if so.
697 * A table needs to be vacuumed if the number of dead tuples exceeds a
698 * threshold. This threshold is calculated as
700 * threshold = vac_base_thresh + vac_scale_factor * reltuples
702 * For analyze, the analysis done is that the number of tuples inserted,
703 * deleted and updated since the last analyze exceeds a threshold calculated
704 * in the same fashion as above. Note that the collector actually stores
705 * the number of tuples (both live and dead) that there were as of the last
706 * analyze. This is asymmetric to the VACUUM case.
708 * A table whose pg_autovacuum.enabled value is false, is automatically
709 * skipped. Thus autovacuum can be disabled for specific tables. Also,
710 * when the stats collector does not have data about a table, it will be
713 * A table whose vac_base_thresh value is <0 takes the base value from the
714 * autovacuum_vacuum_threshold GUC variable. Similarly, a vac_scale_factor
715 * value <0 is substituted with the value of
716 * autovacuum_vacuum_scale_factor GUC variable. Ditto for analyze.
719 test_rel_for_autovac(Oid relid, PgStat_StatTabEntry *tabentry,
720 Form_pg_class classForm,
721 Form_pg_autovacuum avForm,
722 List **vacuum_tables,
723 List **toast_table_ids)
726 float4 reltuples; /* pg_class.reltuples */
728 /* constants from pg_autovacuum or GUC variables */
731 float4 vac_scale_factor,
734 /* thresholds calculated from above constants */
738 /* number of vacuum (resp. analyze) tuples at this time */
742 /* cost-based vacuum delay parameters */
748 /* User disabled it in pg_autovacuum? */
749 if (avForm && !avForm->enabled)
753 * Skip a table not found in stat hash. If it's not acted upon, there's
754 * no need to vacuum it. (Note that database-level check will take care
755 * of Xid wraparound.)
757 if (!PointerIsValid(tabentry))
760 rel = RelationIdGetRelation(relid);
761 /* The table was recently dropped? */
762 if (!PointerIsValid(rel))
765 reltuples = rel->rd_rel->reltuples;
766 vactuples = tabentry->n_dead_tuples;
767 anltuples = tabentry->n_live_tuples + tabentry->n_dead_tuples -
768 tabentry->last_anl_tuples;
771 * If there is a tuple in pg_autovacuum, use it; else, use the GUC
772 * defaults. Note that the fields may contain "-1" (or indeed any
773 * negative value), which means use the GUC defaults for each setting.
777 vac_scale_factor = (avForm->vac_scale_factor >= 0) ?
778 avForm->vac_scale_factor : autovacuum_vac_scale;
779 vac_base_thresh = (avForm->vac_base_thresh >= 0) ?
780 avForm->vac_base_thresh : autovacuum_vac_thresh;
782 anl_scale_factor = (avForm->anl_scale_factor >= 0) ?
783 avForm->anl_scale_factor : autovacuum_anl_scale;
784 anl_base_thresh = (avForm->anl_base_thresh >= 0) ?
785 avForm->anl_base_thresh : autovacuum_anl_thresh;
787 vac_cost_limit = (avForm->vac_cost_limit >= 0) ?
788 avForm->vac_cost_limit :
789 ((autovacuum_vac_cost_limit >= 0) ?
790 autovacuum_vac_cost_limit : VacuumCostLimit);
792 vac_cost_delay = (avForm->vac_cost_delay >= 0) ?
793 avForm->vac_cost_delay :
794 ((autovacuum_vac_cost_delay >= 0) ?
795 autovacuum_vac_cost_delay : VacuumCostDelay);
799 vac_scale_factor = autovacuum_vac_scale;
800 vac_base_thresh = autovacuum_vac_thresh;
802 anl_scale_factor = autovacuum_anl_scale;
803 anl_base_thresh = autovacuum_anl_thresh;
805 vac_cost_limit = (autovacuum_vac_cost_limit >= 0) ?
806 autovacuum_vac_cost_limit : VacuumCostLimit;
808 vac_cost_delay = (autovacuum_vac_cost_delay >= 0) ?
809 autovacuum_vac_cost_delay : VacuumCostDelay;
812 vacthresh = (float4) vac_base_thresh + vac_scale_factor * reltuples;
813 anlthresh = (float4) anl_base_thresh + anl_scale_factor * reltuples;
816 * Note that we don't need to take special consideration for stat reset,
817 * because if that happens, the last vacuum and analyze counts will be
821 elog(DEBUG3, "%s: vac: %.0f (threshold %.0f), anl: %.0f (threshold %.0f)",
822 RelationGetRelationName(rel),
823 vactuples, vacthresh, anltuples, anlthresh);
825 /* Determine if this table needs vacuum or analyze. */
826 dovacuum = (vactuples > vacthresh);
827 doanalyze = (anltuples > anlthresh);
829 /* ANALYZE refuses to work with pg_statistics */
830 if (relid == StatisticRelationId)
833 Assert(CurrentMemoryContext == AutovacMemCxt);
835 if (classForm->relkind == RELKIND_RELATION)
837 if (dovacuum || doanalyze)
838 elog(DEBUG2, "autovac: will%s%s %s",
839 (dovacuum ? " VACUUM" : ""),
840 (doanalyze ? " ANALYZE" : ""),
841 RelationGetRelationName(rel));
844 * we must record tables that have a toast table, even if we currently
845 * don't think they need vacuuming.
847 if (dovacuum || doanalyze || OidIsValid(classForm->reltoastrelid))
851 tab = (autovac_table *) palloc(sizeof(autovac_table));
853 tab->toastrelid = classForm->reltoastrelid;
854 tab->dovacuum = dovacuum;
855 tab->doanalyze = doanalyze;
856 tab->vacuum_cost_limit = vac_cost_limit;
857 tab->vacuum_cost_delay = vac_cost_delay;
859 *vacuum_tables = lappend(*vacuum_tables, tab);
864 Assert(classForm->relkind == RELKIND_TOASTVALUE);
866 *toast_table_ids = lappend_oid(*toast_table_ids, relid);
873 * autovacuum_do_vac_analyze
874 * Vacuum and/or analyze a list of tables; or all tables if relids = NIL
877 autovacuum_do_vac_analyze(List *relids, bool dovacuum, bool doanalyze,
881 MemoryContext old_cxt;
884 * The node must survive transaction boundaries, so make sure we create it
885 * in a long-lived context
887 old_cxt = MemoryContextSwitchTo(AutovacMemCxt);
889 vacstmt = makeNode(VacuumStmt);
892 * Point QueryContext to the autovac memory context to fake out the
893 * PreventTransactionChain check inside vacuum(). Note that this is also
894 * why we palloc vacstmt instead of just using a local variable.
896 QueryContext = CurrentMemoryContext;
898 /* Set up command parameters */
899 vacstmt->vacuum = dovacuum;
900 vacstmt->full = false;
901 vacstmt->analyze = doanalyze;
902 vacstmt->freeze = freeze;
903 vacstmt->verbose = false;
904 vacstmt->relation = NULL; /* all tables, or not used if relids != NIL */
905 vacstmt->va_cols = NIL;
907 vacuum(vacstmt, relids);
910 MemoryContextSwitchTo(old_cxt);
914 * AutoVacuumingActive
915 * Check GUC vars and report whether the autovacuum process should be
919 AutoVacuumingActive(void)
921 if (!autovacuum_start_daemon || !pgstat_collect_startcollector ||
922 !pgstat_collect_tuplelevel)
929 * This is called at postmaster initialization.
931 * Annoy the user if he got it wrong.
936 if (!autovacuum_start_daemon)
939 if (!pgstat_collect_startcollector || !pgstat_collect_tuplelevel)
942 (errmsg("autovacuum not started because of misconfiguration"),
943 errhint("Enable options \"stats_start_collector\" and \"stats_row_level\".")));
946 * Set the GUC var so we don't fork autovacuum uselessly, and also to
949 autovacuum_start_daemon = false;
954 * IsAutoVacuumProcess
955 * Return whether this process is an autovacuum process.
958 IsAutoVacuumProcess(void)
960 return am_autovacuum;