Update autovacuum to use reloptions instead of a system catalog, for
[PostgreSQL.git] / src / backend / postmaster / autovacuum.c
blob94bbb8dca9f0115e84e0057e640d98f4e950450c
1 /*-------------------------------------------------------------------------
3 * autovacuum.c
5 * PostgreSQL Integrated Autovacuum Daemon
7 * The autovacuum system is structured in two different kinds of processes: the
8 * autovacuum launcher and the autovacuum worker. The launcher is an
9 * always-running process, started by the postmaster when the autovacuum GUC
10 * parameter is set. The launcher schedules autovacuum workers to be started
11 * when appropriate. The workers are the processes which execute the actual
12 * vacuuming; they connect to a database as determined in the launcher, and
13 * once connected they examine the catalogs to select the tables to vacuum.
15 * The autovacuum launcher cannot start the worker processes by itself,
16 * because doing so would cause robustness issues (namely, failure to shut
17 * them down on exceptional conditions, and also, since the launcher is
18 * connected to shared memory and is thus subject to corruption there, it is
19 * not as robust as the postmaster). So it leaves that task to the postmaster.
21 * There is an autovacuum shared memory area, where the launcher stores
22 * information about the database it wants vacuumed. When it wants a new
23 * worker to start, it sets a flag in shared memory and sends a signal to the
24 * postmaster. Then postmaster knows nothing more than it must start a worker;
25 * so it forks a new child, which turns into a worker. This new process
26 * connects to shared memory, and there it can inspect the information that the
27 * launcher has set up.
29 * If the fork() call fails in the postmaster, it sets a flag in the shared
30 * memory area, and sends a signal to the launcher. The launcher, upon
31 * noticing the flag, can try starting the worker again by resending the
32 * signal. Note that the failure can only be transient (fork failure due to
33 * high load, memory pressure, too many processes, etc); more permanent
34 * problems, like failure to connect to a database, are detected later in the
35 * worker and dealt with just by having the worker exit normally. The launcher
36 * will launch a new worker again later, per schedule.
38 * When the worker is done vacuuming it sends SIGUSR1 to the launcher. The
39 * launcher then wakes up and is able to launch another worker, if the schedule
40 * is so tight that a new worker is needed immediately. At this time the
41 * launcher can also balance the settings for the various remaining workers'
42 * cost-based vacuum delay feature.
44 * Note that there can be more than one worker in a database concurrently.
45 * They will store the table they are currently vacuuming in shared memory, so
46 * that other workers avoid being blocked waiting for the vacuum lock for that
47 * table. They will also reload the pgstats data just before vacuuming each
48 * table, to avoid vacuuming a table that was just finished being vacuumed by
49 * another worker and thus is no longer noted in shared memory. However,
50 * there is a window (caused by pgstat delay) on which a worker may choose a
51 * table that was already vacuumed; this is a bug in the current design.
53 * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
54 * Portions Copyright (c) 1994, Regents of the University of California
57 * IDENTIFICATION
58 * $PostgreSQL$
60 *-------------------------------------------------------------------------
62 #include "postgres.h"
64 #include <signal.h>
65 #include <sys/types.h>
66 #include <sys/time.h>
67 #include <time.h>
68 #include <unistd.h>
70 #include "access/genam.h"
71 #include "access/heapam.h"
72 #include "access/reloptions.h"
73 #include "access/transam.h"
74 #include "access/xact.h"
75 #include "catalog/dependency.h"
76 #include "catalog/indexing.h"
77 #include "catalog/namespace.h"
78 #include "catalog/pg_database.h"
79 #include "commands/dbcommands.h"
80 #include "commands/vacuum.h"
81 #include "libpq/hba.h"
82 #include "libpq/pqsignal.h"
83 #include "miscadmin.h"
84 #include "pgstat.h"
85 #include "postmaster/autovacuum.h"
86 #include "postmaster/fork_process.h"
87 #include "postmaster/postmaster.h"
88 #include "storage/bufmgr.h"
89 #include "storage/fd.h"
90 #include "storage/ipc.h"
91 #include "storage/pmsignal.h"
92 #include "storage/proc.h"
93 #include "storage/procarray.h"
94 #include "storage/sinvaladt.h"
95 #include "tcop/tcopprot.h"
96 #include "utils/dynahash.h"
97 #include "utils/flatfiles.h"
98 #include "utils/fmgroids.h"
99 #include "utils/lsyscache.h"
100 #include "utils/memutils.h"
101 #include "utils/ps_status.h"
102 #include "utils/syscache.h"
103 #include "utils/tqual.h"
107 * GUC parameters
109 bool autovacuum_start_daemon = false;
110 int autovacuum_max_workers;
111 int autovacuum_naptime;
112 int autovacuum_vac_thresh;
113 double autovacuum_vac_scale;
114 int autovacuum_anl_thresh;
115 double autovacuum_anl_scale;
116 int autovacuum_freeze_max_age;
118 int autovacuum_vac_cost_delay;
119 int autovacuum_vac_cost_limit;
121 int Log_autovacuum_min_duration = -1;
123 /* how long to keep pgstat data in the launcher, in milliseconds */
124 #define STATS_READ_DELAY 1000
127 /* Flags to tell if we are in an autovacuum process */
128 static bool am_autovacuum_launcher = false;
129 static bool am_autovacuum_worker = false;
131 /* Flags set by signal handlers */
132 static volatile sig_atomic_t got_SIGHUP = false;
133 static volatile sig_atomic_t got_SIGUSR1 = false;
134 static volatile sig_atomic_t got_SIGTERM = false;
136 /* Comparison point for determining whether freeze_max_age is exceeded */
137 static TransactionId recentXid;
139 /* Default freeze ages to use for autovacuum (varies by database) */
140 static int default_freeze_min_age;
141 static int default_freeze_table_age;
143 /* Memory context for long-lived data */
144 static MemoryContext AutovacMemCxt;
146 /* struct to keep track of databases in launcher */
147 typedef struct avl_dbase
149 Oid adl_datid; /* hash key -- must be first */
150 TimestampTz adl_next_worker;
151 int adl_score;
152 } avl_dbase;
154 /* struct to keep track of databases in worker */
155 typedef struct avw_dbase
157 Oid adw_datid;
158 char *adw_name;
159 TransactionId adw_frozenxid;
160 PgStat_StatDBEntry *adw_entry;
161 } avw_dbase;
163 /* struct to keep track of tables to vacuum and/or analyze, in 1st pass */
164 typedef struct av_relation
166 Oid ar_toastrelid; /* hash key - must be first */
167 Oid ar_relid;
168 bool ar_hasrelopts;
169 AutoVacOpts ar_reloptions; /* copy of AutoVacOpts from the main table's
170 reloptions, or NULL if none */
171 } av_relation;
173 /* struct to keep track of tables to vacuum and/or analyze, after rechecking */
174 typedef struct autovac_table
176 Oid at_relid;
177 bool at_dovacuum;
178 bool at_doanalyze;
179 int at_freeze_min_age;
180 int at_freeze_table_age;
181 int at_vacuum_cost_delay;
182 int at_vacuum_cost_limit;
183 bool at_wraparound;
184 char *at_relname;
185 char *at_nspname;
186 char *at_datname;
187 } autovac_table;
189 /*-------------
190 * This struct holds information about a single worker's whereabouts. We keep
191 * an array of these in shared memory, sized according to
192 * autovacuum_max_workers.
194 * wi_links entry into free list or running list
195 * wi_dboid OID of the database this worker is supposed to work on
196 * wi_tableoid OID of the table currently being vacuumed
197 * wi_proc pointer to PGPROC of the running worker, NULL if not started
198 * wi_launchtime Time at which this worker was launched
199 * wi_cost_* Vacuum cost-based delay parameters current in this worker
201 * All fields are protected by AutovacuumLock, except for wi_tableoid which is
202 * protected by AutovacuumScheduleLock (which is read-only for everyone except
203 * that worker itself).
204 *-------------
206 typedef struct WorkerInfoData
208 SHM_QUEUE wi_links;
209 Oid wi_dboid;
210 Oid wi_tableoid;
211 PGPROC *wi_proc;
212 TimestampTz wi_launchtime;
213 int wi_cost_delay;
214 int wi_cost_limit;
215 int wi_cost_limit_base;
216 } WorkerInfoData;
218 typedef struct WorkerInfoData *WorkerInfo;
221 * Possible signals received by the launcher from remote processes. These are
222 * stored atomically in shared memory so that other processes can set them
223 * without locking.
225 typedef enum
227 AutoVacForkFailed, /* failed trying to start a worker */
228 AutoVacRebalance, /* rebalance the cost limits */
229 AutoVacNumSignals /* must be last */
230 } AutoVacuumSignal;
232 /*-------------
233 * The main autovacuum shmem struct. On shared memory we store this main
234 * struct and the array of WorkerInfo structs. This struct keeps:
236 * av_signal set by other processes to indicate various conditions
237 * av_launcherpid the PID of the autovacuum launcher
238 * av_freeWorkers the WorkerInfo freelist
239 * av_runningWorkers the WorkerInfo non-free queue
240 * av_startingWorker pointer to WorkerInfo currently being started (cleared by
241 * the worker itself as soon as it's up and running)
243 * This struct is protected by AutovacuumLock, except for av_signal and parts
244 * of the worker list (see above).
245 *-------------
247 typedef struct
249 sig_atomic_t av_signal[AutoVacNumSignals];
250 pid_t av_launcherpid;
251 WorkerInfo av_freeWorkers;
252 SHM_QUEUE av_runningWorkers;
253 WorkerInfo av_startingWorker;
254 } AutoVacuumShmemStruct;
256 static AutoVacuumShmemStruct *AutoVacuumShmem;
258 /* the database list in the launcher, and the context that contains it */
259 static Dllist *DatabaseList = NULL;
260 static MemoryContext DatabaseListCxt = NULL;
262 /* Pointer to my own WorkerInfo, valid on each worker */
263 static WorkerInfo MyWorkerInfo = NULL;
265 /* PID of launcher, valid only in worker while shutting down */
266 int AutovacuumLauncherPid = 0;
268 #ifdef EXEC_BACKEND
269 static pid_t avlauncher_forkexec(void);
270 static pid_t avworker_forkexec(void);
271 #endif
272 NON_EXEC_STATIC void AutoVacWorkerMain(int argc, char *argv[]);
273 NON_EXEC_STATIC void AutoVacLauncherMain(int argc, char *argv[]);
275 static Oid do_start_worker(void);
276 static void launcher_determine_sleep(bool canlaunch, bool recursing,
277 struct timeval * nap);
278 static void launch_worker(TimestampTz now);
279 static List *get_database_list(void);
280 static void rebuild_database_list(Oid newdb);
281 static int db_comparator(const void *a, const void *b);
282 static void autovac_balance_cost(void);
284 static void do_autovacuum(void);
285 static void FreeWorkerInfo(int code, Datum arg);
287 static autovac_table *table_recheck_autovac(Oid relid, HTAB *table_toast_map,
288 TupleDesc pg_class_desc);
289 static void relation_needs_vacanalyze(Oid relid, AutoVacOpts *relopts,
290 Form_pg_class classForm,
291 PgStat_StatTabEntry *tabentry,
292 bool *dovacuum, bool *doanalyze, bool *wraparound);
294 static void autovacuum_do_vac_analyze(autovac_table *tab,
295 BufferAccessStrategy bstrategy);
296 static AutoVacOpts *extract_autovac_opts(HeapTuple tup,
297 TupleDesc pg_class_desc);
298 static PgStat_StatTabEntry *get_pgstat_tabentry_relid(Oid relid, bool isshared,
299 PgStat_StatDBEntry *shared,
300 PgStat_StatDBEntry *dbentry);
301 static void autovac_report_activity(autovac_table *tab);
302 static void avl_sighup_handler(SIGNAL_ARGS);
303 static void avl_sigusr1_handler(SIGNAL_ARGS);
304 static void avl_sigterm_handler(SIGNAL_ARGS);
305 static void avl_quickdie(SIGNAL_ARGS);
306 static void autovac_refresh_stats(void);
310 /********************************************************************
311 * AUTOVACUUM LAUNCHER CODE
312 ********************************************************************/
314 #ifdef EXEC_BACKEND
316 * forkexec routine for the autovacuum launcher process.
318 * Format up the arglist, then fork and exec.
320 static pid_t
321 avlauncher_forkexec(void)
323 char *av[10];
324 int ac = 0;
326 av[ac++] = "postgres";
327 av[ac++] = "--forkavlauncher";
328 av[ac++] = NULL; /* filled in by postmaster_forkexec */
329 av[ac] = NULL;
331 Assert(ac < lengthof(av));
333 return postmaster_forkexec(ac, av);
337 * We need this set from the outside, before InitProcess is called
339 void
340 AutovacuumLauncherIAm(void)
342 am_autovacuum_launcher = true;
344 #endif
347 * Main entry point for autovacuum launcher process, to be called from the
348 * postmaster.
351 StartAutoVacLauncher(void)
353 pid_t AutoVacPID;
355 #ifdef EXEC_BACKEND
356 switch ((AutoVacPID = avlauncher_forkexec()))
357 #else
358 switch ((AutoVacPID = fork_process()))
359 #endif
361 case -1:
362 ereport(LOG,
363 (errmsg("could not fork autovacuum launcher process: %m")));
364 return 0;
366 #ifndef EXEC_BACKEND
367 case 0:
368 /* in postmaster child ... */
369 /* Close the postmaster's sockets */
370 ClosePostmasterPorts(false);
372 /* Lose the postmaster's on-exit routines */
373 on_exit_reset();
375 AutoVacLauncherMain(0, NULL);
376 break;
377 #endif
378 default:
379 return (int) AutoVacPID;
382 /* shouldn't get here */
383 return 0;
387 * Main loop for the autovacuum launcher process.
389 NON_EXEC_STATIC void
390 AutoVacLauncherMain(int argc, char *argv[])
392 sigjmp_buf local_sigjmp_buf;
394 /* we are a postmaster subprocess now */
395 IsUnderPostmaster = true;
396 am_autovacuum_launcher = true;
398 /* reset MyProcPid */
399 MyProcPid = getpid();
401 /* record Start Time for logging */
402 MyStartTime = time(NULL);
404 /* Identify myself via ps */
405 init_ps_display("autovacuum launcher process", "", "", "");
407 if (PostAuthDelay)
408 pg_usleep(PostAuthDelay * 1000000L);
410 SetProcessingMode(InitProcessing);
413 * If possible, make this process a group leader, so that the postmaster
414 * can signal any child processes too. (autovacuum probably never has any
415 * child processes, but for consistency we make all postmaster child
416 * processes do this.)
418 #ifdef HAVE_SETSID
419 if (setsid() < 0)
420 elog(FATAL, "setsid() failed: %m");
421 #endif
424 * Set up signal handlers. Since this is an auxiliary process, it has
425 * particular signal requirements -- no deadlock checker or sinval
426 * catchup, for example.
428 pqsignal(SIGHUP, avl_sighup_handler);
430 pqsignal(SIGINT, SIG_IGN);
431 pqsignal(SIGTERM, avl_sigterm_handler);
432 pqsignal(SIGQUIT, avl_quickdie);
433 pqsignal(SIGALRM, SIG_IGN);
435 pqsignal(SIGPIPE, SIG_IGN);
436 pqsignal(SIGUSR1, avl_sigusr1_handler);
437 /* We don't listen for async notifies */
438 pqsignal(SIGUSR2, SIG_IGN);
439 pqsignal(SIGFPE, FloatExceptionHandler);
440 pqsignal(SIGCHLD, SIG_DFL);
442 /* Early initialization */
443 BaseInit();
446 * Create a per-backend PGPROC struct in shared memory, except in the
447 * EXEC_BACKEND case where this was done in SubPostmasterMain. We must do
448 * this before we can use LWLocks (and in the EXEC_BACKEND case we already
449 * had to do some stuff with LWLocks).
451 #ifndef EXEC_BACKEND
452 InitAuxiliaryProcess();
453 #endif
456 * Create a memory context that we will do all our work in. We do this so
457 * that we can reset the context during error recovery and thereby avoid
458 * possible memory leaks.
460 AutovacMemCxt = AllocSetContextCreate(TopMemoryContext,
461 "Autovacuum Launcher",
462 ALLOCSET_DEFAULT_MINSIZE,
463 ALLOCSET_DEFAULT_INITSIZE,
464 ALLOCSET_DEFAULT_MAXSIZE);
465 MemoryContextSwitchTo(AutovacMemCxt);
469 * If an exception is encountered, processing resumes here.
471 * This code is heavily based on bgwriter.c, q.v.
473 if (sigsetjmp(local_sigjmp_buf, 1) != 0)
475 /* since not using PG_TRY, must reset error stack by hand */
476 error_context_stack = NULL;
478 /* Prevents interrupts while cleaning up */
479 HOLD_INTERRUPTS();
481 /* Report the error to the server log */
482 EmitErrorReport();
485 * These operations are really just a minimal subset of
486 * AbortTransaction(). We don't have very many resources to worry
487 * about, but we do have LWLocks.
489 LWLockReleaseAll();
490 AtEOXact_Files();
491 AtEOXact_HashTables(false);
494 * Now return to normal top-level context and clear ErrorContext for
495 * next time.
497 MemoryContextSwitchTo(AutovacMemCxt);
498 FlushErrorState();
500 /* Flush any leaked data in the top-level context */
501 MemoryContextResetAndDeleteChildren(AutovacMemCxt);
503 /* don't leave dangling pointers to freed memory */
504 DatabaseListCxt = NULL;
505 DatabaseList = NULL;
508 * Make sure pgstat also considers our stat data as gone. Note: we
509 * mustn't use autovac_refresh_stats here.
511 pgstat_clear_snapshot();
513 /* Now we can allow interrupts again */
514 RESUME_INTERRUPTS();
517 * Sleep at least 1 second after any error. We don't want to be
518 * filling the error logs as fast as we can.
520 pg_usleep(1000000L);
523 /* We can now handle ereport(ERROR) */
524 PG_exception_stack = &local_sigjmp_buf;
526 ereport(LOG,
527 (errmsg("autovacuum launcher started")));
529 /* must unblock signals before calling rebuild_database_list */
530 PG_SETMASK(&UnBlockSig);
532 /* in emergency mode, just start a worker and go away */
533 if (!AutoVacuumingActive())
535 do_start_worker();
536 proc_exit(0); /* done */
539 AutoVacuumShmem->av_launcherpid = MyProcPid;
542 * Create the initial database list. The invariant we want this list to
543 * keep is that it's ordered by decreasing next_time. As soon as an entry
544 * is updated to a higher time, it will be moved to the front (which is
545 * correct because the only operation is to add autovacuum_naptime to the
546 * entry, and time always increases).
548 rebuild_database_list(InvalidOid);
550 for (;;)
552 struct timeval nap;
553 TimestampTz current_time = 0;
554 bool can_launch;
555 Dlelem *elem;
558 * Emergency bailout if postmaster has died. This is to avoid the
559 * necessity for manual cleanup of all postmaster children.
561 if (!PostmasterIsAlive(true))
562 exit(1);
564 launcher_determine_sleep((AutoVacuumShmem->av_freeWorkers != NULL),
565 false, &nap);
568 * Sleep for a while according to schedule.
570 * On some platforms, signals won't interrupt the sleep. To ensure we
571 * respond reasonably promptly when someone signals us, break down the
572 * sleep into 1-second increments, and check for interrupts after each
573 * nap.
575 while (nap.tv_sec > 0 || nap.tv_usec > 0)
577 uint32 sleeptime;
579 if (nap.tv_sec > 0)
581 sleeptime = 1000000;
582 nap.tv_sec--;
584 else
586 sleeptime = nap.tv_usec;
587 nap.tv_usec = 0;
589 pg_usleep(sleeptime);
592 * Emergency bailout if postmaster has died. This is to avoid the
593 * necessity for manual cleanup of all postmaster children.
595 if (!PostmasterIsAlive(true))
596 exit(1);
598 if (got_SIGTERM || got_SIGHUP || got_SIGUSR1)
599 break;
602 /* the normal shutdown case */
603 if (got_SIGTERM)
604 break;
606 if (got_SIGHUP)
608 got_SIGHUP = false;
609 ProcessConfigFile(PGC_SIGHUP);
611 /* shutdown requested in config file */
612 if (!AutoVacuumingActive())
613 break;
615 /* rebalance in case the default cost parameters changed */
616 LWLockAcquire(AutovacuumLock, LW_EXCLUSIVE);
617 autovac_balance_cost();
618 LWLockRelease(AutovacuumLock);
620 /* rebuild the list in case the naptime changed */
621 rebuild_database_list(InvalidOid);
625 * a worker finished, or postmaster signalled failure to start a
626 * worker
628 if (got_SIGUSR1)
630 got_SIGUSR1 = false;
632 /* rebalance cost limits, if needed */
633 if (AutoVacuumShmem->av_signal[AutoVacRebalance])
635 LWLockAcquire(AutovacuumLock, LW_EXCLUSIVE);
636 AutoVacuumShmem->av_signal[AutoVacRebalance] = false;
637 autovac_balance_cost();
638 LWLockRelease(AutovacuumLock);
641 if (AutoVacuumShmem->av_signal[AutoVacForkFailed])
644 * If the postmaster failed to start a new worker, we sleep
645 * for a little while and resend the signal. The new worker's
646 * state is still in memory, so this is sufficient. After
647 * that, we restart the main loop.
649 * XXX should we put a limit to the number of times we retry?
650 * I don't think it makes much sense, because a future start
651 * of a worker will continue to fail in the same way.
653 AutoVacuumShmem->av_signal[AutoVacForkFailed] = false;
654 pg_usleep(100000L); /* 100ms */
655 SendPostmasterSignal(PMSIGNAL_START_AUTOVAC_WORKER);
656 continue;
661 * There are some conditions that we need to check before trying to
662 * start a launcher. First, we need to make sure that there is a
663 * launcher slot available. Second, we need to make sure that no
664 * other worker failed while starting up.
667 current_time = GetCurrentTimestamp();
668 LWLockAcquire(AutovacuumLock, LW_SHARED);
670 can_launch = (AutoVacuumShmem->av_freeWorkers != NULL);
672 if (AutoVacuumShmem->av_startingWorker != NULL)
674 int waittime;
675 WorkerInfo worker = AutoVacuumShmem->av_startingWorker;
678 * We can't launch another worker when another one is still
679 * starting up (or failed while doing so), so just sleep for a bit
680 * more; that worker will wake us up again as soon as it's ready.
681 * We will only wait autovacuum_naptime seconds (up to a maximum
682 * of 60 seconds) for this to happen however. Note that failure
683 * to connect to a particular database is not a problem here,
684 * because the worker removes itself from the startingWorker
685 * pointer before trying to connect. Problems detected by the
686 * postmaster (like fork() failure) are also reported and handled
687 * differently. The only problems that may cause this code to
688 * fire are errors in the earlier sections of AutoVacWorkerMain,
689 * before the worker removes the WorkerInfo from the
690 * startingWorker pointer.
692 waittime = Min(autovacuum_naptime, 60) * 1000;
693 if (TimestampDifferenceExceeds(worker->wi_launchtime, current_time,
694 waittime))
696 LWLockRelease(AutovacuumLock);
697 LWLockAcquire(AutovacuumLock, LW_EXCLUSIVE);
700 * No other process can put a worker in starting mode, so if
701 * startingWorker is still INVALID after exchanging our lock,
702 * we assume it's the same one we saw above (so we don't
703 * recheck the launch time).
705 if (AutoVacuumShmem->av_startingWorker != NULL)
707 worker = AutoVacuumShmem->av_startingWorker;
708 worker->wi_dboid = InvalidOid;
709 worker->wi_tableoid = InvalidOid;
710 worker->wi_proc = NULL;
711 worker->wi_launchtime = 0;
712 worker->wi_links.next = (SHM_QUEUE *) AutoVacuumShmem->av_freeWorkers;
713 AutoVacuumShmem->av_freeWorkers = worker;
714 AutoVacuumShmem->av_startingWorker = NULL;
715 elog(WARNING, "worker took too long to start; cancelled");
718 else
719 can_launch = false;
721 LWLockRelease(AutovacuumLock); /* either shared or exclusive */
723 /* if we can't do anything, just go back to sleep */
724 if (!can_launch)
725 continue;
727 /* We're OK to start a new worker */
729 elem = DLGetTail(DatabaseList);
730 if (elem != NULL)
732 avl_dbase *avdb = DLE_VAL(elem);
735 * launch a worker if next_worker is right now or it is in the
736 * past
738 if (TimestampDifferenceExceeds(avdb->adl_next_worker,
739 current_time, 0))
740 launch_worker(current_time);
742 else
745 * Special case when the list is empty: start a worker right away.
746 * This covers the initial case, when no database is in pgstats
747 * (thus the list is empty). Note that the constraints in
748 * launcher_determine_sleep keep us from starting workers too
749 * quickly (at most once every autovacuum_naptime when the list is
750 * empty).
752 launch_worker(current_time);
756 /* Normal exit from the autovac launcher is here */
757 ereport(LOG,
758 (errmsg("autovacuum launcher shutting down")));
759 AutoVacuumShmem->av_launcherpid = 0;
761 proc_exit(0); /* done */
765 * Determine the time to sleep, based on the database list.
767 * The "canlaunch" parameter indicates whether we can start a worker right now,
768 * for example due to the workers being all busy. If this is false, we will
769 * cause a long sleep, which will be interrupted when a worker exits.
771 static void
772 launcher_determine_sleep(bool canlaunch, bool recursing, struct timeval * nap)
774 Dlelem *elem;
777 * We sleep until the next scheduled vacuum. We trust that when the
778 * database list was built, care was taken so that no entries have times
779 * in the past; if the first entry has too close a next_worker value, or a
780 * time in the past, we will sleep a small nominal time.
782 if (!canlaunch)
784 nap->tv_sec = autovacuum_naptime;
785 nap->tv_usec = 0;
787 else if ((elem = DLGetTail(DatabaseList)) != NULL)
789 avl_dbase *avdb = DLE_VAL(elem);
790 TimestampTz current_time = GetCurrentTimestamp();
791 TimestampTz next_wakeup;
792 long secs;
793 int usecs;
795 next_wakeup = avdb->adl_next_worker;
796 TimestampDifference(current_time, next_wakeup, &secs, &usecs);
798 nap->tv_sec = secs;
799 nap->tv_usec = usecs;
801 else
803 /* list is empty, sleep for whole autovacuum_naptime seconds */
804 nap->tv_sec = autovacuum_naptime;
805 nap->tv_usec = 0;
809 * If the result is exactly zero, it means a database had an entry with
810 * time in the past. Rebuild the list so that the databases are evenly
811 * distributed again, and recalculate the time to sleep. This can happen
812 * if there are more tables needing vacuum than workers, and they all take
813 * longer to vacuum than autovacuum_naptime.
815 * We only recurse once. rebuild_database_list should always return times
816 * in the future, but it seems best not to trust too much on that.
818 if (nap->tv_sec == 0 && nap->tv_usec == 0 && !recursing)
820 rebuild_database_list(InvalidOid);
821 launcher_determine_sleep(canlaunch, true, nap);
822 return;
825 /* 100ms is the smallest time we'll allow the launcher to sleep */
826 if (nap->tv_sec <= 0 && nap->tv_usec <= 100000)
828 nap->tv_sec = 0;
829 nap->tv_usec = 100000; /* 100 ms */
834 * Build an updated DatabaseList. It must only contain databases that appear
835 * in pgstats, and must be sorted by next_worker from highest to lowest,
836 * distributed regularly across the next autovacuum_naptime interval.
838 * Receives the Oid of the database that made this list be generated (we call
839 * this the "new" database, because when the database was already present on
840 * the list, we expect that this function is not called at all). The
841 * preexisting list, if any, will be used to preserve the order of the
842 * databases in the autovacuum_naptime period. The new database is put at the
843 * end of the interval. The actual values are not saved, which should not be
844 * much of a problem.
846 static void
847 rebuild_database_list(Oid newdb)
849 List *dblist;
850 ListCell *cell;
851 MemoryContext newcxt;
852 MemoryContext oldcxt;
853 MemoryContext tmpcxt;
854 HASHCTL hctl;
855 int score;
856 int nelems;
857 HTAB *dbhash;
859 /* use fresh stats */
860 autovac_refresh_stats();
862 newcxt = AllocSetContextCreate(AutovacMemCxt,
863 "AV dblist",
864 ALLOCSET_DEFAULT_MINSIZE,
865 ALLOCSET_DEFAULT_INITSIZE,
866 ALLOCSET_DEFAULT_MAXSIZE);
867 tmpcxt = AllocSetContextCreate(newcxt,
868 "tmp AV dblist",
869 ALLOCSET_DEFAULT_MINSIZE,
870 ALLOCSET_DEFAULT_INITSIZE,
871 ALLOCSET_DEFAULT_MAXSIZE);
872 oldcxt = MemoryContextSwitchTo(tmpcxt);
875 * Implementing this is not as simple as it sounds, because we need to put
876 * the new database at the end of the list; next the databases that were
877 * already on the list, and finally (at the tail of the list) all the
878 * other databases that are not on the existing list.
880 * To do this, we build an empty hash table of scored databases. We will
881 * start with the lowest score (zero) for the new database, then
882 * increasing scores for the databases in the existing list, in order, and
883 * lastly increasing scores for all databases gotten via
884 * get_database_list() that are not already on the hash.
886 * Then we will put all the hash elements into an array, sort the array by
887 * score, and finally put the array elements into the new doubly linked
888 * list.
890 hctl.keysize = sizeof(Oid);
891 hctl.entrysize = sizeof(avl_dbase);
892 hctl.hash = oid_hash;
893 hctl.hcxt = tmpcxt;
894 dbhash = hash_create("db hash", 20, &hctl, /* magic number here FIXME */
895 HASH_ELEM | HASH_FUNCTION | HASH_CONTEXT);
897 /* start by inserting the new database */
898 score = 0;
899 if (OidIsValid(newdb))
901 avl_dbase *db;
902 PgStat_StatDBEntry *entry;
904 /* only consider this database if it has a pgstat entry */
905 entry = pgstat_fetch_stat_dbentry(newdb);
906 if (entry != NULL)
908 /* we assume it isn't found because the hash was just created */
909 db = hash_search(dbhash, &newdb, HASH_ENTER, NULL);
911 /* hash_search already filled in the key */
912 db->adl_score = score++;
913 /* next_worker is filled in later */
917 /* Now insert the databases from the existing list */
918 if (DatabaseList != NULL)
920 Dlelem *elem;
922 elem = DLGetHead(DatabaseList);
923 while (elem != NULL)
925 avl_dbase *avdb = DLE_VAL(elem);
926 avl_dbase *db;
927 bool found;
928 PgStat_StatDBEntry *entry;
930 elem = DLGetSucc(elem);
933 * skip databases with no stat entries -- in particular, this gets
934 * rid of dropped databases
936 entry = pgstat_fetch_stat_dbentry(avdb->adl_datid);
937 if (entry == NULL)
938 continue;
940 db = hash_search(dbhash, &(avdb->adl_datid), HASH_ENTER, &found);
942 if (!found)
944 /* hash_search already filled in the key */
945 db->adl_score = score++;
946 /* next_worker is filled in later */
951 /* finally, insert all qualifying databases not previously inserted */
952 dblist = get_database_list();
953 foreach(cell, dblist)
955 avw_dbase *avdb = lfirst(cell);
956 avl_dbase *db;
957 bool found;
958 PgStat_StatDBEntry *entry;
960 /* only consider databases with a pgstat entry */
961 entry = pgstat_fetch_stat_dbentry(avdb->adw_datid);
962 if (entry == NULL)
963 continue;
965 db = hash_search(dbhash, &(avdb->adw_datid), HASH_ENTER, &found);
966 /* only update the score if the database was not already on the hash */
967 if (!found)
969 /* hash_search already filled in the key */
970 db->adl_score = score++;
971 /* next_worker is filled in later */
974 nelems = score;
976 /* from here on, the allocated memory belongs to the new list */
977 MemoryContextSwitchTo(newcxt);
978 DatabaseList = DLNewList();
980 if (nelems > 0)
982 TimestampTz current_time;
983 int millis_increment;
984 avl_dbase *dbary;
985 avl_dbase *db;
986 HASH_SEQ_STATUS seq;
987 int i;
989 /* put all the hash elements into an array */
990 dbary = palloc(nelems * sizeof(avl_dbase));
992 i = 0;
993 hash_seq_init(&seq, dbhash);
994 while ((db = hash_seq_search(&seq)) != NULL)
995 memcpy(&(dbary[i++]), db, sizeof(avl_dbase));
997 /* sort the array */
998 qsort(dbary, nelems, sizeof(avl_dbase), db_comparator);
1000 /* this is the time interval between databases in the schedule */
1001 millis_increment = 1000.0 * autovacuum_naptime / nelems;
1002 current_time = GetCurrentTimestamp();
1005 * move the elements from the array into the dllist, setting the
1006 * next_worker while walking the array
1008 for (i = 0; i < nelems; i++)
1010 avl_dbase *db = &(dbary[i]);
1011 Dlelem *elem;
1013 current_time = TimestampTzPlusMilliseconds(current_time,
1014 millis_increment);
1015 db->adl_next_worker = current_time;
1017 elem = DLNewElem(db);
1018 /* later elements should go closer to the head of the list */
1019 DLAddHead(DatabaseList, elem);
1023 /* all done, clean up memory */
1024 if (DatabaseListCxt != NULL)
1025 MemoryContextDelete(DatabaseListCxt);
1026 MemoryContextDelete(tmpcxt);
1027 DatabaseListCxt = newcxt;
1028 MemoryContextSwitchTo(oldcxt);
1031 /* qsort comparator for avl_dbase, using adl_score */
1032 static int
1033 db_comparator(const void *a, const void *b)
1035 if (((avl_dbase *) a)->adl_score == ((avl_dbase *) b)->adl_score)
1036 return 0;
1037 else
1038 return (((avl_dbase *) a)->adl_score < ((avl_dbase *) b)->adl_score) ? 1 : -1;
1042 * do_start_worker
1044 * Bare-bones procedure for starting an autovacuum worker from the launcher.
1045 * It determines what database to work on, sets up shared memory stuff and
1046 * signals postmaster to start the worker. It fails gracefully if invoked when
1047 * autovacuum_workers are already active.
1049 * Return value is the OID of the database that the worker is going to process,
1050 * or InvalidOid if no worker was actually started.
1052 static Oid
1053 do_start_worker(void)
1055 List *dblist;
1056 ListCell *cell;
1057 TransactionId xidForceLimit;
1058 bool for_xid_wrap;
1059 avw_dbase *avdb;
1060 TimestampTz current_time;
1061 bool skipit = false;
1062 Oid retval = InvalidOid;
1063 MemoryContext tmpcxt,
1064 oldcxt;
1066 /* return quickly when there are no free workers */
1067 LWLockAcquire(AutovacuumLock, LW_SHARED);
1068 if (AutoVacuumShmem->av_freeWorkers == NULL)
1070 LWLockRelease(AutovacuumLock);
1071 return InvalidOid;
1073 LWLockRelease(AutovacuumLock);
1076 * Create and switch to a temporary context to avoid leaking the memory
1077 * allocated for the database list.
1079 tmpcxt = AllocSetContextCreate(CurrentMemoryContext,
1080 "Start worker tmp cxt",
1081 ALLOCSET_DEFAULT_MINSIZE,
1082 ALLOCSET_DEFAULT_INITSIZE,
1083 ALLOCSET_DEFAULT_MAXSIZE);
1084 oldcxt = MemoryContextSwitchTo(tmpcxt);
1086 /* use fresh stats */
1087 autovac_refresh_stats();
1089 /* Get a list of databases */
1090 dblist = get_database_list();
1093 * Determine the oldest datfrozenxid/relfrozenxid that we will allow to
1094 * pass without forcing a vacuum. (This limit can be tightened for
1095 * particular tables, but not loosened.)
1097 recentXid = ReadNewTransactionId();
1098 xidForceLimit = recentXid - autovacuum_freeze_max_age;
1099 /* ensure it's a "normal" XID, else TransactionIdPrecedes misbehaves */
1100 if (xidForceLimit < FirstNormalTransactionId)
1101 xidForceLimit -= FirstNormalTransactionId;
1104 * Choose a database to connect to. We pick the database that was least
1105 * recently auto-vacuumed, or one that needs vacuuming to prevent Xid
1106 * wraparound-related data loss. If any db at risk of wraparound is
1107 * found, we pick the one with oldest datfrozenxid, independently of
1108 * autovacuum times.
1110 * Note that a database with no stats entry is not considered, except for
1111 * Xid wraparound purposes. The theory is that if no one has ever
1112 * connected to it since the stats were last initialized, it doesn't need
1113 * vacuuming.
1115 * XXX This could be improved if we had more info about whether it needs
1116 * vacuuming before connecting to it. Perhaps look through the pgstats
1117 * data for the database's tables? One idea is to keep track of the
1118 * number of new and dead tuples per database in pgstats. However it
1119 * isn't clear how to construct a metric that measures that and not cause
1120 * starvation for less busy databases.
1122 avdb = NULL;
1123 for_xid_wrap = false;
1124 current_time = GetCurrentTimestamp();
1125 foreach(cell, dblist)
1127 avw_dbase *tmp = lfirst(cell);
1128 Dlelem *elem;
1130 /* Check to see if this one is at risk of wraparound */
1131 if (TransactionIdPrecedes(tmp->adw_frozenxid, xidForceLimit))
1133 if (avdb == NULL ||
1134 TransactionIdPrecedes(tmp->adw_frozenxid, avdb->adw_frozenxid))
1135 avdb = tmp;
1136 for_xid_wrap = true;
1137 continue;
1139 else if (for_xid_wrap)
1140 continue; /* ignore not-at-risk DBs */
1142 /* Find pgstat entry if any */
1143 tmp->adw_entry = pgstat_fetch_stat_dbentry(tmp->adw_datid);
1146 * Skip a database with no pgstat entry; it means it hasn't seen any
1147 * activity.
1149 if (!tmp->adw_entry)
1150 continue;
1153 * Also, skip a database that appears on the database list as having
1154 * been processed recently (less than autovacuum_naptime seconds ago).
1155 * We do this so that we don't select a database which we just
1156 * selected, but that pgstat hasn't gotten around to updating the last
1157 * autovacuum time yet.
1159 skipit = false;
1160 elem = DatabaseList ? DLGetTail(DatabaseList) : NULL;
1162 while (elem != NULL)
1164 avl_dbase *dbp = DLE_VAL(elem);
1166 if (dbp->adl_datid == tmp->adw_datid)
1169 * Skip this database if its next_worker value falls between
1170 * the current time and the current time plus naptime.
1172 if (!TimestampDifferenceExceeds(dbp->adl_next_worker,
1173 current_time, 0) &&
1174 !TimestampDifferenceExceeds(current_time,
1175 dbp->adl_next_worker,
1176 autovacuum_naptime * 1000))
1177 skipit = true;
1179 break;
1181 elem = DLGetPred(elem);
1183 if (skipit)
1184 continue;
1187 * Remember the db with oldest autovac time. (If we are here, both
1188 * tmp->entry and db->entry must be non-null.)
1190 if (avdb == NULL ||
1191 tmp->adw_entry->last_autovac_time < avdb->adw_entry->last_autovac_time)
1192 avdb = tmp;
1195 /* Found a database -- process it */
1196 if (avdb != NULL)
1198 WorkerInfo worker;
1200 LWLockAcquire(AutovacuumLock, LW_EXCLUSIVE);
1203 * Get a worker entry from the freelist. We checked above, so there
1204 * really should be a free slot -- complain very loudly if there
1205 * isn't.
1207 worker = AutoVacuumShmem->av_freeWorkers;
1208 if (worker == NULL)
1209 elog(FATAL, "no free worker found");
1211 AutoVacuumShmem->av_freeWorkers = (WorkerInfo) worker->wi_links.next;
1213 worker->wi_dboid = avdb->adw_datid;
1214 worker->wi_proc = NULL;
1215 worker->wi_launchtime = GetCurrentTimestamp();
1217 AutoVacuumShmem->av_startingWorker = worker;
1219 LWLockRelease(AutovacuumLock);
1221 SendPostmasterSignal(PMSIGNAL_START_AUTOVAC_WORKER);
1223 retval = avdb->adw_datid;
1225 else if (skipit)
1228 * If we skipped all databases on the list, rebuild it, because it
1229 * probably contains a dropped database.
1231 rebuild_database_list(InvalidOid);
1234 MemoryContextSwitchTo(oldcxt);
1235 MemoryContextDelete(tmpcxt);
1237 return retval;
1241 * launch_worker
1243 * Wrapper for starting a worker from the launcher. Besides actually starting
1244 * it, update the database list to reflect the next time that another one will
1245 * need to be started on the selected database. The actual database choice is
1246 * left to do_start_worker.
1248 * This routine is also expected to insert an entry into the database list if
1249 * the selected database was previously absent from the list.
1251 static void
1252 launch_worker(TimestampTz now)
1254 Oid dbid;
1255 Dlelem *elem;
1257 dbid = do_start_worker();
1258 if (OidIsValid(dbid))
1261 * Walk the database list and update the corresponding entry. If the
1262 * database is not on the list, we'll recreate the list.
1264 elem = (DatabaseList == NULL) ? NULL : DLGetHead(DatabaseList);
1265 while (elem != NULL)
1267 avl_dbase *avdb = DLE_VAL(elem);
1269 if (avdb->adl_datid == dbid)
1272 * add autovacuum_naptime seconds to the current time, and use
1273 * that as the new "next_worker" field for this database.
1275 avdb->adl_next_worker =
1276 TimestampTzPlusMilliseconds(now, autovacuum_naptime * 1000);
1278 DLMoveToFront(elem);
1279 break;
1281 elem = DLGetSucc(elem);
1285 * If the database was not present in the database list, we rebuild
1286 * the list. It's possible that the database does not get into the
1287 * list anyway, for example if it's a database that doesn't have a
1288 * pgstat entry, but this is not a problem because we don't want to
1289 * schedule workers regularly into those in any case.
1291 if (elem == NULL)
1292 rebuild_database_list(dbid);
1297 * Called from postmaster to signal a failure to fork a process to become
1298 * worker. The postmaster should kill(SIGUSR1) the launcher shortly
1299 * after calling this function.
1301 void
1302 AutoVacWorkerFailed(void)
1304 AutoVacuumShmem->av_signal[AutoVacForkFailed] = true;
1307 /* SIGHUP: set flag to re-read config file at next convenient time */
1308 static void
1309 avl_sighup_handler(SIGNAL_ARGS)
1311 got_SIGHUP = true;
1314 /* SIGUSR1: a worker is up and running, or just finished */
1315 static void
1316 avl_sigusr1_handler(SIGNAL_ARGS)
1318 got_SIGUSR1 = true;
1321 /* SIGTERM: time to die */
1322 static void
1323 avl_sigterm_handler(SIGNAL_ARGS)
1325 got_SIGTERM = true;
1329 * avl_quickdie occurs when signalled SIGQUIT from postmaster.
1331 * Some backend has bought the farm, so we need to stop what we're doing
1332 * and exit.
1334 static void
1335 avl_quickdie(SIGNAL_ARGS)
1337 PG_SETMASK(&BlockSig);
1340 * DO NOT proc_exit() -- we're here because shared memory may be
1341 * corrupted, so we don't want to try to clean up our transaction. Just
1342 * nail the windows shut and get out of town.
1344 * Note we do exit(2) not exit(0). This is to force the postmaster into a
1345 * system reset cycle if some idiot DBA sends a manual SIGQUIT to a random
1346 * backend. This is necessary precisely because we don't clean up our
1347 * shared memory state.
1349 exit(2);
1353 /********************************************************************
1354 * AUTOVACUUM WORKER CODE
1355 ********************************************************************/
1357 #ifdef EXEC_BACKEND
1359 * forkexec routines for the autovacuum worker.
1361 * Format up the arglist, then fork and exec.
1363 static pid_t
1364 avworker_forkexec(void)
1366 char *av[10];
1367 int ac = 0;
1369 av[ac++] = "postgres";
1370 av[ac++] = "--forkavworker";
1371 av[ac++] = NULL; /* filled in by postmaster_forkexec */
1372 av[ac] = NULL;
1374 Assert(ac < lengthof(av));
1376 return postmaster_forkexec(ac, av);
1380 * We need this set from the outside, before InitProcess is called
1382 void
1383 AutovacuumWorkerIAm(void)
1385 am_autovacuum_worker = true;
1387 #endif
1390 * Main entry point for autovacuum worker process.
1392 * This code is heavily based on pgarch.c, q.v.
1395 StartAutoVacWorker(void)
1397 pid_t worker_pid;
1399 #ifdef EXEC_BACKEND
1400 switch ((worker_pid = avworker_forkexec()))
1401 #else
1402 switch ((worker_pid = fork_process()))
1403 #endif
1405 case -1:
1406 ereport(LOG,
1407 (errmsg("could not fork autovacuum worker process: %m")));
1408 return 0;
1410 #ifndef EXEC_BACKEND
1411 case 0:
1412 /* in postmaster child ... */
1413 /* Close the postmaster's sockets */
1414 ClosePostmasterPorts(false);
1416 /* Lose the postmaster's on-exit routines */
1417 on_exit_reset();
1419 AutoVacWorkerMain(0, NULL);
1420 break;
1421 #endif
1422 default:
1423 return (int) worker_pid;
1426 /* shouldn't get here */
1427 return 0;
1431 * AutoVacWorkerMain
1433 NON_EXEC_STATIC void
1434 AutoVacWorkerMain(int argc, char *argv[])
1436 sigjmp_buf local_sigjmp_buf;
1437 Oid dbid;
1439 /* we are a postmaster subprocess now */
1440 IsUnderPostmaster = true;
1441 am_autovacuum_worker = true;
1443 /* reset MyProcPid */
1444 MyProcPid = getpid();
1446 /* record Start Time for logging */
1447 MyStartTime = time(NULL);
1449 /* Identify myself via ps */
1450 init_ps_display("autovacuum worker process", "", "", "");
1452 SetProcessingMode(InitProcessing);
1455 * If possible, make this process a group leader, so that the postmaster
1456 * can signal any child processes too. (autovacuum probably never has any
1457 * child processes, but for consistency we make all postmaster child
1458 * processes do this.)
1460 #ifdef HAVE_SETSID
1461 if (setsid() < 0)
1462 elog(FATAL, "setsid() failed: %m");
1463 #endif
1466 * Set up signal handlers. We operate on databases much like a regular
1467 * backend, so we use the same signal handling. See equivalent code in
1468 * tcop/postgres.c.
1470 * Currently, we don't pay attention to postgresql.conf changes that
1471 * happen during a single daemon iteration, so we can ignore SIGHUP.
1473 pqsignal(SIGHUP, SIG_IGN);
1476 * SIGINT is used to signal cancelling the current table's vacuum; SIGTERM
1477 * means abort and exit cleanly, and SIGQUIT means abandon ship.
1479 pqsignal(SIGINT, StatementCancelHandler);
1480 pqsignal(SIGTERM, die);
1481 pqsignal(SIGQUIT, quickdie);
1482 pqsignal(SIGALRM, handle_sig_alarm);
1484 pqsignal(SIGPIPE, SIG_IGN);
1485 pqsignal(SIGUSR1, CatchupInterruptHandler);
1486 /* We don't listen for async notifies */
1487 pqsignal(SIGUSR2, SIG_IGN);
1488 pqsignal(SIGFPE, FloatExceptionHandler);
1489 pqsignal(SIGCHLD, SIG_DFL);
1491 /* Early initialization */
1492 BaseInit();
1495 * Create a per-backend PGPROC struct in shared memory, except in the
1496 * EXEC_BACKEND case where this was done in SubPostmasterMain. We must do
1497 * this before we can use LWLocks (and in the EXEC_BACKEND case we already
1498 * had to do some stuff with LWLocks).
1500 #ifndef EXEC_BACKEND
1501 InitProcess();
1502 #endif
1505 * If an exception is encountered, processing resumes here.
1507 * See notes in postgres.c about the design of this coding.
1509 if (sigsetjmp(local_sigjmp_buf, 1) != 0)
1511 /* Prevents interrupts while cleaning up */
1512 HOLD_INTERRUPTS();
1514 /* Report the error to the server log */
1515 EmitErrorReport();
1518 * We can now go away. Note that because we called InitProcess, a
1519 * callback was registered to do ProcKill, which will clean up
1520 * necessary state.
1522 proc_exit(0);
1525 /* We can now handle ereport(ERROR) */
1526 PG_exception_stack = &local_sigjmp_buf;
1528 PG_SETMASK(&UnBlockSig);
1531 * Force zero_damaged_pages OFF in the autovac process, even if it is set
1532 * in postgresql.conf. We don't really want such a dangerous option being
1533 * applied non-interactively.
1535 SetConfigOption("zero_damaged_pages", "false", PGC_SUSET, PGC_S_OVERRIDE);
1538 * Force statement_timeout to zero to avoid a timeout setting from
1539 * preventing regular maintenance from being executed.
1541 SetConfigOption("statement_timeout", "0", PGC_SUSET, PGC_S_OVERRIDE);
1544 * Get the info about the database we're going to work on.
1546 LWLockAcquire(AutovacuumLock, LW_EXCLUSIVE);
1549 * beware of startingWorker being INVALID; this should normally not
1550 * happen, but if a worker fails after forking and before this, the
1551 * launcher might have decided to remove it from the queue and start
1552 * again.
1554 if (AutoVacuumShmem->av_startingWorker != NULL)
1556 MyWorkerInfo = AutoVacuumShmem->av_startingWorker;
1557 dbid = MyWorkerInfo->wi_dboid;
1558 MyWorkerInfo->wi_proc = MyProc;
1560 /* insert into the running list */
1561 SHMQueueInsertBefore(&AutoVacuumShmem->av_runningWorkers,
1562 &MyWorkerInfo->wi_links);
1565 * remove from the "starting" pointer, so that the launcher can start
1566 * a new worker if required
1568 AutoVacuumShmem->av_startingWorker = NULL;
1569 LWLockRelease(AutovacuumLock);
1571 on_shmem_exit(FreeWorkerInfo, 0);
1573 /* wake up the launcher */
1574 if (AutoVacuumShmem->av_launcherpid != 0)
1575 kill(AutoVacuumShmem->av_launcherpid, SIGUSR1);
1577 else
1579 /* no worker entry for me, go away */
1580 elog(WARNING, "autovacuum worker started without a worker entry");
1581 dbid = InvalidOid;
1582 LWLockRelease(AutovacuumLock);
1585 if (OidIsValid(dbid))
1587 char *dbname;
1590 * Report autovac startup to the stats collector. We deliberately do
1591 * this before InitPostgres, so that the last_autovac_time will get
1592 * updated even if the connection attempt fails. This is to prevent
1593 * autovac from getting "stuck" repeatedly selecting an unopenable
1594 * database, rather than making any progress on stuff it can connect
1595 * to.
1597 pgstat_report_autovac(dbid);
1600 * Connect to the selected database
1602 * Note: if we have selected a just-deleted database (due to using
1603 * stale stats info), we'll fail and exit here.
1605 InitPostgres(NULL, dbid, NULL, &dbname);
1606 SetProcessingMode(NormalProcessing);
1607 set_ps_display(dbname, false);
1608 ereport(DEBUG1,
1609 (errmsg("autovacuum: processing database \"%s\"", dbname)));
1611 if (PostAuthDelay)
1612 pg_usleep(PostAuthDelay * 1000000L);
1614 /* And do an appropriate amount of work */
1615 recentXid = ReadNewTransactionId();
1616 do_autovacuum();
1620 * The launcher will be notified of my death in ProcKill, *if* we managed
1621 * to get a worker slot at all
1624 /* All done, go away */
1625 proc_exit(0);
1629 * Return a WorkerInfo to the free list
1631 static void
1632 FreeWorkerInfo(int code, Datum arg)
1634 if (MyWorkerInfo != NULL)
1636 LWLockAcquire(AutovacuumLock, LW_EXCLUSIVE);
1639 * Wake the launcher up so that he can launch a new worker immediately
1640 * if required. We only save the launcher's PID in local memory here;
1641 * the actual signal will be sent when the PGPROC is recycled. Note
1642 * that we always do this, so that the launcher can rebalance the cost
1643 * limit setting of the remaining workers.
1645 * We somewhat ignore the risk that the launcher changes its PID
1646 * between we reading it and the actual kill; we expect ProcKill to be
1647 * called shortly after us, and we assume that PIDs are not reused too
1648 * quickly after a process exits.
1650 AutovacuumLauncherPid = AutoVacuumShmem->av_launcherpid;
1652 SHMQueueDelete(&MyWorkerInfo->wi_links);
1653 MyWorkerInfo->wi_links.next = (SHM_QUEUE *) AutoVacuumShmem->av_freeWorkers;
1654 MyWorkerInfo->wi_dboid = InvalidOid;
1655 MyWorkerInfo->wi_tableoid = InvalidOid;
1656 MyWorkerInfo->wi_proc = NULL;
1657 MyWorkerInfo->wi_launchtime = 0;
1658 MyWorkerInfo->wi_cost_delay = 0;
1659 MyWorkerInfo->wi_cost_limit = 0;
1660 MyWorkerInfo->wi_cost_limit_base = 0;
1661 AutoVacuumShmem->av_freeWorkers = MyWorkerInfo;
1662 /* not mine anymore */
1663 MyWorkerInfo = NULL;
1666 * now that we're inactive, cause a rebalancing of the surviving
1667 * workers
1669 AutoVacuumShmem->av_signal[AutoVacRebalance] = true;
1670 LWLockRelease(AutovacuumLock);
1675 * Update the cost-based delay parameters, so that multiple workers consume
1676 * each a fraction of the total available I/O.
1678 void
1679 AutoVacuumUpdateDelay(void)
1681 if (MyWorkerInfo)
1683 VacuumCostDelay = MyWorkerInfo->wi_cost_delay;
1684 VacuumCostLimit = MyWorkerInfo->wi_cost_limit;
1689 * autovac_balance_cost
1690 * Recalculate the cost limit setting for each active workers.
1692 * Caller must hold the AutovacuumLock in exclusive mode.
1694 static void
1695 autovac_balance_cost(void)
1697 WorkerInfo worker;
1700 * note: in cost_limit, zero also means use value from elsewhere, because
1701 * zero is not a valid value.
1703 int vac_cost_limit = (autovacuum_vac_cost_limit > 0 ?
1704 autovacuum_vac_cost_limit : VacuumCostLimit);
1705 int vac_cost_delay = (autovacuum_vac_cost_delay >= 0 ?
1706 autovacuum_vac_cost_delay : VacuumCostDelay);
1707 double cost_total;
1708 double cost_avail;
1710 /* not set? nothing to do */
1711 if (vac_cost_limit <= 0 || vac_cost_delay <= 0)
1712 return;
1714 /* caculate the total base cost limit of active workers */
1715 cost_total = 0.0;
1716 worker = (WorkerInfo) SHMQueueNext(&AutoVacuumShmem->av_runningWorkers,
1717 &AutoVacuumShmem->av_runningWorkers,
1718 offsetof(WorkerInfoData, wi_links));
1719 while (worker)
1721 if (worker->wi_proc != NULL &&
1722 worker->wi_cost_limit_base > 0 && worker->wi_cost_delay > 0)
1723 cost_total +=
1724 (double) worker->wi_cost_limit_base / worker->wi_cost_delay;
1726 worker = (WorkerInfo) SHMQueueNext(&AutoVacuumShmem->av_runningWorkers,
1727 &worker->wi_links,
1728 offsetof(WorkerInfoData, wi_links));
1730 /* there are no cost limits -- nothing to do */
1731 if (cost_total <= 0)
1732 return;
1735 * Adjust each cost limit of active workers to balance the total of cost
1736 * limit to autovacuum_vacuum_cost_limit.
1738 cost_avail = (double) vac_cost_limit / vac_cost_delay;
1739 worker = (WorkerInfo) SHMQueueNext(&AutoVacuumShmem->av_runningWorkers,
1740 &AutoVacuumShmem->av_runningWorkers,
1741 offsetof(WorkerInfoData, wi_links));
1742 while (worker)
1744 if (worker->wi_proc != NULL &&
1745 worker->wi_cost_limit_base > 0 && worker->wi_cost_delay > 0)
1747 int limit = (int)
1748 (cost_avail * worker->wi_cost_limit_base / cost_total);
1751 * We put a lower bound of 1 to the cost_limit, to avoid division-
1752 * by-zero in the vacuum code.
1754 worker->wi_cost_limit = Max(Min(limit, worker->wi_cost_limit_base), 1);
1756 elog(DEBUG2, "autovac_balance_cost(pid=%u db=%u, rel=%u, cost_limit=%d, cost_delay=%d)",
1757 worker->wi_proc->pid, worker->wi_dboid,
1758 worker->wi_tableoid, worker->wi_cost_limit, worker->wi_cost_delay);
1761 worker = (WorkerInfo) SHMQueueNext(&AutoVacuumShmem->av_runningWorkers,
1762 &worker->wi_links,
1763 offsetof(WorkerInfoData, wi_links));
1768 * get_database_list
1770 * Return a list of all databases. Note we cannot use pg_database,
1771 * because we aren't connected; we use the flat database file.
1773 static List *
1774 get_database_list(void)
1776 char *filename;
1777 List *dblist = NIL;
1778 char thisname[NAMEDATALEN];
1779 FILE *db_file;
1780 Oid db_id;
1781 Oid db_tablespace;
1782 TransactionId db_frozenxid;
1784 filename = database_getflatfilename();
1785 db_file = AllocateFile(filename, "r");
1786 if (db_file == NULL)
1787 ereport(FATAL,
1788 (errcode_for_file_access(),
1789 errmsg("could not open file \"%s\": %m", filename)));
1791 while (read_pg_database_line(db_file, thisname, &db_id,
1792 &db_tablespace, &db_frozenxid))
1794 avw_dbase *avdb;
1796 avdb = (avw_dbase *) palloc(sizeof(avw_dbase));
1798 avdb->adw_datid = db_id;
1799 avdb->adw_name = pstrdup(thisname);
1800 avdb->adw_frozenxid = db_frozenxid;
1801 /* this gets set later: */
1802 avdb->adw_entry = NULL;
1804 dblist = lappend(dblist, avdb);
1807 FreeFile(db_file);
1808 pfree(filename);
1810 return dblist;
1814 * Process a database table-by-table
1816 * Note that CHECK_FOR_INTERRUPTS is supposed to be used in certain spots in
1817 * order not to ignore shutdown commands for too long.
1819 static void
1820 do_autovacuum(void)
1822 Relation classRel;
1823 HeapTuple tuple;
1824 HeapScanDesc relScan;
1825 Form_pg_database dbForm;
1826 List *table_oids = NIL;
1827 HASHCTL ctl;
1828 HTAB *table_toast_map;
1829 ListCell *volatile cell;
1830 PgStat_StatDBEntry *shared;
1831 PgStat_StatDBEntry *dbentry;
1832 BufferAccessStrategy bstrategy;
1833 ScanKeyData key;
1834 TupleDesc pg_class_desc;
1837 * StartTransactionCommand and CommitTransactionCommand will automatically
1838 * switch to other contexts. We need this one to keep the list of
1839 * relations to vacuum/analyze across transactions.
1841 AutovacMemCxt = AllocSetContextCreate(TopMemoryContext,
1842 "AV worker",
1843 ALLOCSET_DEFAULT_MINSIZE,
1844 ALLOCSET_DEFAULT_INITSIZE,
1845 ALLOCSET_DEFAULT_MAXSIZE);
1846 MemoryContextSwitchTo(AutovacMemCxt);
1849 * may be NULL if we couldn't find an entry (only happens if we are
1850 * forcing a vacuum for anti-wrap purposes).
1852 dbentry = pgstat_fetch_stat_dbentry(MyDatabaseId);
1854 /* Start a transaction so our commands have one to play into. */
1855 StartTransactionCommand();
1858 * Clean up any dead statistics collector entries for this DB. We always
1859 * want to do this exactly once per DB-processing cycle, even if we find
1860 * nothing worth vacuuming in the database.
1862 pgstat_vacuum_stat();
1865 * Find the pg_database entry and select the default freeze ages. We
1866 * use zero in template and nonconnectable databases, else the system-wide
1867 * default.
1869 tuple = SearchSysCache(DATABASEOID,
1870 ObjectIdGetDatum(MyDatabaseId),
1871 0, 0, 0);
1872 if (!HeapTupleIsValid(tuple))
1873 elog(ERROR, "cache lookup failed for database %u", MyDatabaseId);
1874 dbForm = (Form_pg_database) GETSTRUCT(tuple);
1876 if (dbForm->datistemplate || !dbForm->datallowconn)
1878 default_freeze_min_age = 0;
1879 default_freeze_table_age = 0;
1881 else
1883 default_freeze_min_age = vacuum_freeze_min_age;
1884 default_freeze_table_age = vacuum_freeze_table_age;
1887 ReleaseSysCache(tuple);
1889 /* StartTransactionCommand changed elsewhere */
1890 MemoryContextSwitchTo(AutovacMemCxt);
1892 /* The database hash where pgstat keeps shared relations */
1893 shared = pgstat_fetch_stat_dbentry(InvalidOid);
1895 classRel = heap_open(RelationRelationId, AccessShareLock);
1897 /* create a copy so we can use it after closing pg_class */
1898 pg_class_desc = CreateTupleDescCopy(RelationGetDescr(classRel));
1900 /* create hash table for toast <-> main relid mapping */
1901 MemSet(&ctl, 0, sizeof(ctl));
1902 ctl.keysize = sizeof(Oid);
1903 ctl.entrysize = sizeof(av_relation);
1904 ctl.hash = oid_hash;
1906 table_toast_map = hash_create("TOAST to main relid map",
1907 100,
1908 &ctl,
1909 HASH_ELEM | HASH_FUNCTION);
1912 * Scan pg_class to determine which tables to vacuum.
1914 * We do this in two passes: on the first one we collect the list of
1915 * plain relations, and on the second one we collect TOAST tables.
1916 * The reason for doing the second pass is that during it we want to use
1917 * the main relation's pg_class.reloptions entry if the TOAST table does
1918 * not have any, and we cannot obtain it unless we know beforehand what's
1919 * the main table OID.
1921 * We need to check TOAST tables separately because in cases with short,
1922 * wide tables there might be proportionally much more activity in the
1923 * TOAST table than in its parent.
1925 ScanKeyInit(&key,
1926 Anum_pg_class_relkind,
1927 BTEqualStrategyNumber, F_CHAREQ,
1928 CharGetDatum(RELKIND_RELATION));
1930 relScan = heap_beginscan(classRel, SnapshotNow, 1, &key);
1933 * On the first pass, we collect main tables to vacuum, and also the
1934 * main table relid to TOAST relid mapping.
1936 while ((tuple = heap_getnext(relScan, ForwardScanDirection)) != NULL)
1938 Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple);
1939 PgStat_StatTabEntry *tabentry;
1940 AutoVacOpts *relopts;
1941 Oid relid;
1942 bool dovacuum;
1943 bool doanalyze;
1944 bool wraparound;
1945 int backendID;
1947 relid = HeapTupleGetOid(tuple);
1949 /* Fetch reloptions and the pgstat entry for this table */
1950 relopts = extract_autovac_opts(tuple, pg_class_desc);
1951 tabentry = get_pgstat_tabentry_relid(relid, classForm->relisshared,
1952 shared, dbentry);
1954 /* Check if it needs vacuum or analyze */
1955 relation_needs_vacanalyze(relid, relopts, classForm, tabentry,
1956 &dovacuum, &doanalyze, &wraparound);
1959 * Check if it is a temp table (presumably, of some other backend's).
1960 * We cannot safely process other backends' temp tables.
1962 backendID = GetTempNamespaceBackendId(classForm->relnamespace);
1964 if (backendID > 0)
1966 /* We just ignore it if the owning backend is still active */
1967 if (backendID == MyBackendId || !BackendIdIsActive(backendID))
1970 * We found an orphan temp table (which was probably left
1971 * behind by a crashed backend). If it's so old as to need
1972 * vacuum for wraparound, forcibly drop it. Otherwise just
1973 * log a complaint.
1975 if (wraparound)
1977 ObjectAddress object;
1979 ereport(LOG,
1980 (errmsg("autovacuum: dropping orphan temp table \"%s\".\"%s\" in database \"%s\"",
1981 get_namespace_name(classForm->relnamespace),
1982 NameStr(classForm->relname),
1983 get_database_name(MyDatabaseId))));
1984 object.classId = RelationRelationId;
1985 object.objectId = relid;
1986 object.objectSubId = 0;
1987 performDeletion(&object, DROP_CASCADE);
1989 else
1991 ereport(LOG,
1992 (errmsg("autovacuum: found orphan temp table \"%s\".\"%s\" in database \"%s\"",
1993 get_namespace_name(classForm->relnamespace),
1994 NameStr(classForm->relname),
1995 get_database_name(MyDatabaseId))));
1999 else
2001 /* relations that need work are added to table_oids */
2002 if (dovacuum || doanalyze)
2003 table_oids = lappend_oid(table_oids, relid);
2006 * Remember the association for the second pass. Note: we must do
2007 * this even if the table is going to be vacuumed, because we
2008 * don't automatically vacuum toast tables along the parent table.
2010 if (OidIsValid(classForm->reltoastrelid))
2012 av_relation *hentry;
2013 bool found;
2015 hentry = hash_search(table_toast_map,
2016 &classForm->reltoastrelid,
2017 HASH_ENTER, &found);
2019 if (!found)
2021 /* hash_search already filled in the key */
2022 hentry->ar_relid = relid;
2023 hentry->ar_hasrelopts = false;
2024 if (relopts != NULL)
2026 hentry->ar_hasrelopts = true;
2027 memcpy(&hentry->ar_reloptions, relopts,
2028 sizeof(AutoVacOpts));
2035 heap_endscan(relScan);
2037 /* second pass: check TOAST tables */
2038 ScanKeyInit(&key,
2039 Anum_pg_class_relkind,
2040 BTEqualStrategyNumber, F_CHAREQ,
2041 CharGetDatum(RELKIND_TOASTVALUE));
2043 relScan = heap_beginscan(classRel, SnapshotNow, 1, &key);
2044 while ((tuple = heap_getnext(relScan, ForwardScanDirection)) != NULL)
2046 Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple);
2047 PgStat_StatTabEntry *tabentry;
2048 Oid relid;
2049 AutoVacOpts *relopts = NULL;
2050 bool dovacuum;
2051 bool doanalyze;
2052 bool wraparound;
2055 * Skip temp tables (i.e. those in temp namespaces). We cannot safely
2056 * process other backends' temp tables.
2058 if (isAnyTempNamespace(classForm->relnamespace))
2059 continue;
2061 relid = HeapTupleGetOid(tuple);
2064 * fetch reloptions -- if this toast table does not have them,
2065 * try the main rel
2067 relopts = extract_autovac_opts(tuple, pg_class_desc);
2068 if (relopts == NULL)
2070 av_relation *hentry;
2071 bool found;
2073 hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found);
2074 if (found && hentry->ar_hasrelopts)
2075 relopts = &hentry->ar_reloptions;
2078 /* Fetch the pgstat entry for this table */
2079 tabentry = get_pgstat_tabentry_relid(relid, classForm->relisshared,
2080 shared, dbentry);
2082 relation_needs_vacanalyze(relid, relopts, classForm, tabentry,
2083 &dovacuum, &doanalyze, &wraparound);
2085 /* ignore analyze for toast tables */
2086 if (dovacuum)
2087 table_oids = lappend_oid(table_oids, relid);
2090 heap_endscan(relScan);
2091 heap_close(classRel, AccessShareLock);
2094 * Create a buffer access strategy object for VACUUM to use. We want to
2095 * use the same one across all the vacuum operations we perform, since the
2096 * point is for VACUUM not to blow out the shared cache.
2098 bstrategy = GetAccessStrategy(BAS_VACUUM);
2101 * create a memory context to act as fake PortalContext, so that the
2102 * contexts created in the vacuum code are cleaned up for each table.
2104 PortalContext = AllocSetContextCreate(AutovacMemCxt,
2105 "Autovacuum Portal",
2106 ALLOCSET_DEFAULT_INITSIZE,
2107 ALLOCSET_DEFAULT_MINSIZE,
2108 ALLOCSET_DEFAULT_MAXSIZE);
2111 * Perform operations on collected tables.
2113 foreach(cell, table_oids)
2115 Oid relid = lfirst_oid(cell);
2116 autovac_table *tab;
2117 WorkerInfo worker;
2118 bool skipit;
2120 CHECK_FOR_INTERRUPTS();
2123 * hold schedule lock from here until we're sure that this table still
2124 * needs vacuuming. We also need the AutovacuumLock to walk the
2125 * worker array, but we'll let go of that one quickly.
2127 LWLockAcquire(AutovacuumScheduleLock, LW_EXCLUSIVE);
2128 LWLockAcquire(AutovacuumLock, LW_SHARED);
2131 * Check whether the table is being vacuumed concurrently by another
2132 * worker.
2134 skipit = false;
2135 worker = (WorkerInfo) SHMQueueNext(&AutoVacuumShmem->av_runningWorkers,
2136 &AutoVacuumShmem->av_runningWorkers,
2137 offsetof(WorkerInfoData, wi_links));
2138 while (worker)
2140 /* ignore myself */
2141 if (worker == MyWorkerInfo)
2142 goto next_worker;
2144 /* ignore workers in other databases */
2145 if (worker->wi_dboid != MyDatabaseId)
2146 goto next_worker;
2148 if (worker->wi_tableoid == relid)
2150 skipit = true;
2151 break;
2154 next_worker:
2155 worker = (WorkerInfo) SHMQueueNext(&AutoVacuumShmem->av_runningWorkers,
2156 &worker->wi_links,
2157 offsetof(WorkerInfoData, wi_links));
2159 LWLockRelease(AutovacuumLock);
2160 if (skipit)
2162 LWLockRelease(AutovacuumScheduleLock);
2163 continue;
2167 * Check whether pgstat data still says we need to vacuum this table.
2168 * It could have changed if something else processed the table while
2169 * we weren't looking.
2171 * Note: we have a special case in pgstat code to ensure that the stats
2172 * we read are as up-to-date as possible, to avoid the problem that
2173 * somebody just finished vacuuming this table. The window to the race
2174 * condition is not closed but it is very small.
2176 MemoryContextSwitchTo(AutovacMemCxt);
2177 tab = table_recheck_autovac(relid, table_toast_map, pg_class_desc);
2178 if (tab == NULL)
2180 /* someone else vacuumed the table, or it went away */
2181 LWLockRelease(AutovacuumScheduleLock);
2182 continue;
2186 * Ok, good to go. Store the table in shared memory before releasing
2187 * the lock so that other workers don't vacuum it concurrently.
2189 MyWorkerInfo->wi_tableoid = relid;
2190 LWLockRelease(AutovacuumScheduleLock);
2192 /* Set the initial vacuum cost parameters for this table */
2193 VacuumCostDelay = tab->at_vacuum_cost_delay;
2194 VacuumCostLimit = tab->at_vacuum_cost_limit;
2196 /* Last fixups before actually starting to work */
2197 LWLockAcquire(AutovacuumLock, LW_EXCLUSIVE);
2199 /* advertise my cost delay parameters for the balancing algorithm */
2200 MyWorkerInfo->wi_cost_delay = tab->at_vacuum_cost_delay;
2201 MyWorkerInfo->wi_cost_limit = tab->at_vacuum_cost_limit;
2202 MyWorkerInfo->wi_cost_limit_base = tab->at_vacuum_cost_limit;
2204 /* do a balance */
2205 autovac_balance_cost();
2207 /* done */
2208 LWLockRelease(AutovacuumLock);
2210 /* clean up memory before each iteration */
2211 MemoryContextResetAndDeleteChildren(PortalContext);
2214 * Save the relation name for a possible error message, to avoid a
2215 * catalog lookup in case of an error. If any of these return NULL,
2216 * then the relation has been dropped since last we checked; skip it.
2217 * Note: they must live in a long-lived memory context because we call
2218 * vacuum and analyze in different transactions.
2221 tab->at_relname = get_rel_name(tab->at_relid);
2222 tab->at_nspname = get_namespace_name(get_rel_namespace(tab->at_relid));
2223 tab->at_datname = get_database_name(MyDatabaseId);
2224 if (!tab->at_relname || !tab->at_nspname || !tab->at_datname)
2225 goto deleted;
2228 * We will abort vacuuming the current table if something errors out,
2229 * and continue with the next one in schedule; in particular, this
2230 * happens if we are interrupted with SIGINT.
2232 PG_TRY();
2234 /* have at it */
2235 MemoryContextSwitchTo(TopTransactionContext);
2236 autovacuum_do_vac_analyze(tab, bstrategy);
2239 * Clear a possible query-cancel signal, to avoid a late reaction
2240 * to an automatically-sent signal because of vacuuming the
2241 * current table (we're done with it, so it would make no sense to
2242 * cancel at this point.)
2244 QueryCancelPending = false;
2246 PG_CATCH();
2249 * Abort the transaction, start a new one, and proceed with the
2250 * next table in our list.
2252 HOLD_INTERRUPTS();
2253 if (tab->at_dovacuum)
2254 errcontext("automatic vacuum of table \"%s.%s.%s\"",
2255 tab->at_datname, tab->at_nspname, tab->at_relname);
2256 else
2257 errcontext("automatic analyze of table \"%s.%s.%s\"",
2258 tab->at_datname, tab->at_nspname, tab->at_relname);
2259 EmitErrorReport();
2261 /* this resets the PGPROC flags too */
2262 AbortOutOfAnyTransaction();
2263 FlushErrorState();
2264 MemoryContextResetAndDeleteChildren(PortalContext);
2266 /* restart our transaction for the following operations */
2267 StartTransactionCommand();
2268 RESUME_INTERRUPTS();
2270 PG_END_TRY();
2272 /* the PGPROC flags are reset at the next end of transaction */
2274 /* be tidy */
2275 deleted:
2276 if (tab->at_datname != NULL)
2277 pfree(tab->at_datname);
2278 if (tab->at_nspname != NULL)
2279 pfree(tab->at_nspname);
2280 if (tab->at_relname != NULL)
2281 pfree(tab->at_relname);
2282 pfree(tab);
2284 /* remove my info from shared memory */
2285 LWLockAcquire(AutovacuumLock, LW_EXCLUSIVE);
2286 MyWorkerInfo->wi_tableoid = InvalidOid;
2287 LWLockRelease(AutovacuumLock);
2291 * We leak table_toast_map here (among other things), but since we're going
2292 * away soon, it's not a problem.
2296 * Update pg_database.datfrozenxid, and truncate pg_clog if possible. We
2297 * only need to do this once, not after each table.
2299 vac_update_datfrozenxid();
2301 /* Finally close out the last transaction. */
2302 CommitTransactionCommand();
2306 * extract_autovac_opts
2308 * Given a relation's pg_class tuple, return the AutoVacOpts portion of
2309 * reloptions, if set; otherwise, return NULL.
2311 AutoVacOpts *
2312 extract_autovac_opts(HeapTuple tup, TupleDesc pg_class_desc)
2314 bytea *relopts;
2315 AutoVacOpts *av;
2317 Assert(((Form_pg_class) GETSTRUCT(tup))->relkind == RELKIND_RELATION ||
2318 ((Form_pg_class) GETSTRUCT(tup))->relkind == RELKIND_TOASTVALUE);
2320 relopts = extractRelOptions(tup, pg_class_desc, InvalidOid);
2321 if (relopts == NULL)
2322 return NULL;
2324 av = palloc(sizeof(AutoVacOpts));
2325 memcpy(av, &(((StdRdOptions *) relopts)->autovacuum), sizeof(AutoVacOpts));
2326 pfree(relopts);
2328 return av;
2332 * get_pgstat_tabentry_relid
2334 * Fetch the pgstat entry of a table, either local to a database or shared.
2336 static PgStat_StatTabEntry *
2337 get_pgstat_tabentry_relid(Oid relid, bool isshared, PgStat_StatDBEntry *shared,
2338 PgStat_StatDBEntry *dbentry)
2340 PgStat_StatTabEntry *tabentry = NULL;
2342 if (isshared)
2344 if (PointerIsValid(shared))
2345 tabentry = hash_search(shared->tables, &relid,
2346 HASH_FIND, NULL);
2348 else if (PointerIsValid(dbentry))
2349 tabentry = hash_search(dbentry->tables, &relid,
2350 HASH_FIND, NULL);
2352 return tabentry;
2356 * table_recheck_autovac
2358 * Recheck whether a table still needs vacuum or analyze. Return value is a
2359 * valid autovac_table pointer if it does, NULL otherwise.
2361 * Note that the returned autovac_table does not have the name fields set.
2363 static autovac_table *
2364 table_recheck_autovac(Oid relid, HTAB *table_toast_map,
2365 TupleDesc pg_class_desc)
2367 Form_pg_class classForm;
2368 HeapTuple classTup;
2369 bool dovacuum;
2370 bool doanalyze;
2371 autovac_table *tab = NULL;
2372 PgStat_StatTabEntry *tabentry;
2373 PgStat_StatDBEntry *shared;
2374 PgStat_StatDBEntry *dbentry;
2375 bool wraparound;
2376 AutoVacOpts *avopts;
2378 /* use fresh stats */
2379 autovac_refresh_stats();
2381 shared = pgstat_fetch_stat_dbentry(InvalidOid);
2382 dbentry = pgstat_fetch_stat_dbentry(MyDatabaseId);
2384 /* fetch the relation's relcache entry */
2385 classTup = SearchSysCacheCopy(RELOID,
2386 ObjectIdGetDatum(relid),
2387 0, 0, 0);
2388 if (!HeapTupleIsValid(classTup))
2389 return NULL;
2390 classForm = (Form_pg_class) GETSTRUCT(classTup);
2393 * Get the applicable reloptions. If it is a TOAST table, try to get the
2394 * main table reloptions if the toast table itself doesn't have.
2396 avopts = extract_autovac_opts(classTup, pg_class_desc);
2397 if (classForm->relkind == RELKIND_TOASTVALUE &&
2398 avopts == NULL && table_toast_map != NULL)
2400 av_relation *hentry;
2401 bool found;
2403 hentry = hash_search(table_toast_map, &relid, HASH_FIND, &found);
2404 if (found && hentry->ar_hasrelopts)
2405 avopts = &hentry->ar_reloptions;
2408 /* fetch the pgstat table entry */
2409 tabentry = get_pgstat_tabentry_relid(relid, classForm->relisshared,
2410 shared, dbentry);
2412 relation_needs_vacanalyze(relid, avopts, classForm, tabentry,
2413 &dovacuum, &doanalyze, &wraparound);
2415 /* ignore ANALYZE for toast tables */
2416 if (classForm->relkind == RELKIND_TOASTVALUE)
2417 doanalyze = false;
2419 /* OK, it needs something done */
2420 if (doanalyze || dovacuum)
2422 int freeze_min_age;
2423 int freeze_table_age;
2424 int vac_cost_limit;
2425 int vac_cost_delay;
2428 * Calculate the vacuum cost parameters and the freeze ages. If there
2429 * are options set in pg_class.reloptions, use them; in the case of a
2430 * toast table, try the main table too. Otherwise use the GUC
2431 * defaults, autovacuum's own first and plain vacuum second.
2433 if (avopts)
2435 vac_cost_delay = avopts->vacuum_cost_delay;
2436 vac_cost_limit = avopts->vacuum_cost_limit;
2437 freeze_min_age = avopts->freeze_min_age;
2438 freeze_table_age = avopts->freeze_table_age;
2440 else
2442 /* -1 in autovac setting means use plain vacuum_cost_delay */
2443 vac_cost_delay = autovacuum_vac_cost_delay >= 0 ?
2444 autovacuum_vac_cost_delay : VacuumCostDelay;
2445 /* 0 or -1 in autovac setting means use plain vacuum_cost_limit */
2446 vac_cost_limit = autovacuum_vac_cost_limit > 0 ?
2447 autovacuum_vac_cost_limit : VacuumCostLimit;
2448 /* these do not have autovacuum-specific settings */
2449 freeze_min_age = default_freeze_min_age;
2450 freeze_table_age = default_freeze_table_age;
2453 tab = palloc(sizeof(autovac_table));
2454 tab->at_relid = relid;
2455 tab->at_dovacuum = dovacuum;
2456 tab->at_doanalyze = doanalyze;
2457 tab->at_freeze_min_age = freeze_min_age;
2458 tab->at_freeze_table_age = freeze_table_age;
2459 tab->at_vacuum_cost_limit = vac_cost_limit;
2460 tab->at_vacuum_cost_delay = vac_cost_delay;
2461 tab->at_wraparound = wraparound;
2462 tab->at_relname = NULL;
2463 tab->at_nspname = NULL;
2464 tab->at_datname = NULL;
2467 heap_freetuple(classTup);
2469 return tab;
2473 * relation_needs_vacanalyze
2475 * Check whether a relation needs to be vacuumed or analyzed; return each into
2476 * "dovacuum" and "doanalyze", respectively. Also return whether the vacuum is
2477 * being forced because of Xid wraparound.
2479 * relopts is a pointer to the AutoVacOpts options (either for itself in the
2480 * case of a plain table, or for either itself or its parent table in the case
2481 * of a TOAST table), NULL if none; tabentry is the pgstats entry, which can be
2482 * NULL.
2484 * A table needs to be vacuumed if the number of dead tuples exceeds a
2485 * threshold. This threshold is calculated as
2487 * threshold = vac_base_thresh + vac_scale_factor * reltuples
2489 * For analyze, the analysis done is that the number of tuples inserted,
2490 * deleted and updated since the last analyze exceeds a threshold calculated
2491 * in the same fashion as above. Note that the collector actually stores
2492 * the number of tuples (both live and dead) that there were as of the last
2493 * analyze. This is asymmetric to the VACUUM case.
2495 * We also force vacuum if the table's relfrozenxid is more than freeze_max_age
2496 * transactions back.
2498 * A table whose autovacuum_enabled option is false is
2499 * automatically skipped (unless we have to vacuum it due to freeze_max_age).
2500 * Thus autovacuum can be disabled for specific tables. Also, when the stats
2501 * collector does not have data about a table, it will be skipped.
2503 * A table whose vac_base_thresh value is < 0 takes the base value from the
2504 * autovacuum_vacuum_threshold GUC variable. Similarly, a vac_scale_factor
2505 * value < 0 is substituted with the value of
2506 * autovacuum_vacuum_scale_factor GUC variable. Ditto for analyze.
2508 static void
2509 relation_needs_vacanalyze(Oid relid,
2510 AutoVacOpts *relopts,
2511 Form_pg_class classForm,
2512 PgStat_StatTabEntry *tabentry,
2513 /* output params below */
2514 bool *dovacuum,
2515 bool *doanalyze,
2516 bool *wraparound)
2518 bool force_vacuum;
2519 bool av_enabled;
2520 float4 reltuples; /* pg_class.reltuples */
2522 /* constants from reloptions or GUC variables */
2523 int vac_base_thresh,
2524 anl_base_thresh;
2525 float4 vac_scale_factor,
2526 anl_scale_factor;
2528 /* thresholds calculated from above constants */
2529 float4 vacthresh,
2530 anlthresh;
2532 /* number of vacuum (resp. analyze) tuples at this time */
2533 float4 vactuples,
2534 anltuples;
2536 /* freeze parameters */
2537 int freeze_max_age;
2538 TransactionId xidForceLimit;
2540 AssertArg(classForm != NULL);
2541 AssertArg(OidIsValid(relid));
2544 * Determine vacuum/analyze equation parameters. We have two possible
2545 * sources: the passed reloptions (which could be a main table or a toast
2546 * table), or the autovacuum GUC variables.
2548 if (relopts)
2550 vac_scale_factor = relopts->vacuum_scale_factor;
2551 vac_base_thresh = relopts->vacuum_threshold;
2552 anl_scale_factor = relopts->analyze_scale_factor;
2553 anl_base_thresh = relopts->analyze_threshold;
2554 freeze_max_age = Min(relopts->freeze_max_age,
2555 autovacuum_freeze_max_age);
2556 av_enabled = relopts->enabled;
2558 else
2560 vac_scale_factor = autovacuum_vac_scale;
2561 vac_base_thresh = autovacuum_vac_thresh;
2562 anl_scale_factor = autovacuum_anl_scale;
2563 anl_base_thresh = autovacuum_anl_thresh;
2564 freeze_max_age = autovacuum_freeze_max_age;
2565 av_enabled = true;
2568 /* Force vacuum if table is at risk of wraparound */
2569 xidForceLimit = recentXid - freeze_max_age;
2570 if (xidForceLimit < FirstNormalTransactionId)
2571 xidForceLimit -= FirstNormalTransactionId;
2572 force_vacuum = (TransactionIdIsNormal(classForm->relfrozenxid) &&
2573 TransactionIdPrecedes(classForm->relfrozenxid,
2574 xidForceLimit));
2575 *wraparound = force_vacuum;
2577 /* User disabled it in pg_class.reloptions? (But ignore if at risk) */
2578 if (!force_vacuum && !av_enabled)
2580 *doanalyze = false;
2581 *dovacuum = false;
2582 return;
2585 if (PointerIsValid(tabentry))
2587 reltuples = classForm->reltuples;
2588 vactuples = tabentry->n_dead_tuples;
2589 anltuples = tabentry->n_live_tuples + tabentry->n_dead_tuples -
2590 tabentry->last_anl_tuples;
2592 vacthresh = (float4) vac_base_thresh + vac_scale_factor * reltuples;
2593 anlthresh = (float4) anl_base_thresh + anl_scale_factor * reltuples;
2596 * Note that we don't need to take special consideration for stat
2597 * reset, because if that happens, the last vacuum and analyze counts
2598 * will be reset too.
2600 elog(DEBUG3, "%s: vac: %.0f (threshold %.0f), anl: %.0f (threshold %.0f)",
2601 NameStr(classForm->relname),
2602 vactuples, vacthresh, anltuples, anlthresh);
2604 /* Determine if this table needs vacuum or analyze. */
2605 *dovacuum = force_vacuum || (vactuples > vacthresh);
2606 *doanalyze = (anltuples > anlthresh);
2608 else
2611 * Skip a table not found in stat hash, unless we have to force vacuum
2612 * for anti-wrap purposes. If it's not acted upon, there's no need to
2613 * vacuum it.
2615 *dovacuum = force_vacuum;
2616 *doanalyze = false;
2619 /* ANALYZE refuses to work with pg_statistics */
2620 if (relid == StatisticRelationId)
2621 *doanalyze = false;
2625 * autovacuum_do_vac_analyze
2626 * Vacuum and/or analyze the specified table
2628 static void
2629 autovacuum_do_vac_analyze(autovac_table *tab,
2630 BufferAccessStrategy bstrategy)
2632 VacuumStmt vacstmt;
2634 /* Set up command parameters --- use a local variable instead of palloc */
2635 MemSet(&vacstmt, 0, sizeof(vacstmt));
2637 vacstmt.type = T_VacuumStmt;
2638 vacstmt.vacuum = tab->at_dovacuum;
2639 vacstmt.full = false;
2640 vacstmt.analyze = tab->at_doanalyze;
2641 vacstmt.freeze_min_age = tab->at_freeze_min_age;
2642 vacstmt.freeze_table_age = tab->at_freeze_table_age;
2643 vacstmt.verbose = false;
2644 vacstmt.relation = NULL; /* not used since we pass a relid */
2645 vacstmt.va_cols = NIL;
2647 /* Let pgstat know what we're doing */
2648 autovac_report_activity(tab);
2650 vacuum(&vacstmt, tab->at_relid, false, bstrategy, tab->at_wraparound, true);
2654 * autovac_report_activity
2655 * Report to pgstat what autovacuum is doing
2657 * We send a SQL string corresponding to what the user would see if the
2658 * equivalent command was to be issued manually.
2660 * Note we assume that we are going to report the next command as soon as we're
2661 * done with the current one, and exit right after the last one, so we don't
2662 * bother to report "<IDLE>" or some such.
2664 static void
2665 autovac_report_activity(autovac_table *tab)
2667 #define MAX_AUTOVAC_ACTIV_LEN (NAMEDATALEN * 2 + 56)
2668 char activity[MAX_AUTOVAC_ACTIV_LEN];
2669 int len;
2671 /* Report the command and possible options */
2672 if (tab->at_dovacuum)
2673 snprintf(activity, MAX_AUTOVAC_ACTIV_LEN,
2674 "autovacuum: VACUUM%s",
2675 tab->at_doanalyze ? " ANALYZE" : "");
2676 else
2677 snprintf(activity, MAX_AUTOVAC_ACTIV_LEN,
2678 "autovacuum: ANALYZE");
2681 * Report the qualified name of the relation.
2683 len = strlen(activity);
2685 snprintf(activity + len, MAX_AUTOVAC_ACTIV_LEN - len,
2686 " %s.%s%s", tab->at_nspname, tab->at_relname,
2687 tab->at_wraparound ? " (to prevent wraparound)" : "");
2689 /* Set statement_timestamp() to current time for pg_stat_activity */
2690 SetCurrentStatementStartTimestamp();
2692 pgstat_report_activity(activity);
2696 * AutoVacuumingActive
2697 * Check GUC vars and report whether the autovacuum process should be
2698 * running.
2700 bool
2701 AutoVacuumingActive(void)
2703 if (!autovacuum_start_daemon || !pgstat_track_counts)
2704 return false;
2705 return true;
2709 * autovac_init
2710 * This is called at postmaster initialization.
2712 * All we do here is annoy the user if he got it wrong.
2714 void
2715 autovac_init(void)
2717 if (autovacuum_start_daemon && !pgstat_track_counts)
2718 ereport(WARNING,
2719 (errmsg("autovacuum not started because of misconfiguration"),
2720 errhint("Enable the \"track_counts\" option.")));
2724 * IsAutoVacuum functions
2725 * Return whether this is either a launcher autovacuum process or a worker
2726 * process.
2728 bool
2729 IsAutoVacuumLauncherProcess(void)
2731 return am_autovacuum_launcher;
2734 bool
2735 IsAutoVacuumWorkerProcess(void)
2737 return am_autovacuum_worker;
2742 * AutoVacuumShmemSize
2743 * Compute space needed for autovacuum-related shared memory
2745 Size
2746 AutoVacuumShmemSize(void)
2748 Size size;
2751 * Need the fixed struct and the array of WorkerInfoData.
2753 size = sizeof(AutoVacuumShmemStruct);
2754 size = MAXALIGN(size);
2755 size = add_size(size, mul_size(autovacuum_max_workers,
2756 sizeof(WorkerInfoData)));
2757 return size;
2761 * AutoVacuumShmemInit
2762 * Allocate and initialize autovacuum-related shared memory
2764 void
2765 AutoVacuumShmemInit(void)
2767 bool found;
2769 AutoVacuumShmem = (AutoVacuumShmemStruct *)
2770 ShmemInitStruct("AutoVacuum Data",
2771 AutoVacuumShmemSize(),
2772 &found);
2773 if (AutoVacuumShmem == NULL)
2774 ereport(FATAL,
2775 (errcode(ERRCODE_OUT_OF_MEMORY),
2776 errmsg("not enough shared memory for autovacuum")));
2778 if (!IsUnderPostmaster)
2780 WorkerInfo worker;
2781 int i;
2783 Assert(!found);
2785 AutoVacuumShmem->av_launcherpid = 0;
2786 AutoVacuumShmem->av_freeWorkers = NULL;
2787 SHMQueueInit(&AutoVacuumShmem->av_runningWorkers);
2788 AutoVacuumShmem->av_startingWorker = NULL;
2790 worker = (WorkerInfo) ((char *) AutoVacuumShmem +
2791 MAXALIGN(sizeof(AutoVacuumShmemStruct)));
2793 /* initialize the WorkerInfo free list */
2794 for (i = 0; i < autovacuum_max_workers; i++)
2796 worker[i].wi_links.next = (SHM_QUEUE *) AutoVacuumShmem->av_freeWorkers;
2797 AutoVacuumShmem->av_freeWorkers = &worker[i];
2800 else
2801 Assert(found);
2805 * autovac_refresh_stats
2806 * Refresh pgstats data for an autovacuum process
2808 * Cause the next pgstats read operation to obtain fresh data, but throttle
2809 * such refreshing in the autovacuum launcher. This is mostly to avoid
2810 * rereading the pgstats files too many times in quick succession when there
2811 * are many databases.
2813 * Note: we avoid throttling in the autovac worker, as it would be
2814 * counterproductive in the recheck logic.
2816 static void
2817 autovac_refresh_stats(void)
2819 if (IsAutoVacuumLauncherProcess())
2821 static TimestampTz last_read = 0;
2822 TimestampTz current_time;
2824 current_time = GetCurrentTimestamp();
2826 if (!TimestampDifferenceExceeds(last_read, current_time,
2827 STATS_READ_DELAY))
2828 return;
2830 last_read = current_time;
2833 pgstat_clear_snapshot();