1 /*-------------------------------------------------------------------------
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-2008, PostgreSQL Global Development Group
54 * Portions Copyright (c) 1994, Regents of the University of California
60 *-------------------------------------------------------------------------
65 #include <sys/types.h>
70 #include "access/genam.h"
71 #include "access/heapam.h"
72 #include "access/transam.h"
73 #include "access/xact.h"
74 #include "catalog/indexing.h"
75 #include "catalog/namespace.h"
76 #include "catalog/pg_autovacuum.h"
77 #include "catalog/pg_database.h"
78 #include "commands/dbcommands.h"
79 #include "commands/vacuum.h"
80 #include "libpq/hba.h"
81 #include "libpq/pqsignal.h"
82 #include "miscadmin.h"
84 #include "postmaster/autovacuum.h"
85 #include "postmaster/fork_process.h"
86 #include "postmaster/postmaster.h"
87 #include "storage/fd.h"
88 #include "storage/ipc.h"
89 #include "storage/pmsignal.h"
90 #include "storage/proc.h"
91 #include "storage/procarray.h"
92 #include "storage/sinval.h"
93 #include "tcop/tcopprot.h"
94 #include "utils/flatfiles.h"
95 #include "utils/fmgroids.h"
96 #include "utils/lsyscache.h"
97 #include "utils/memutils.h"
98 #include "utils/ps_status.h"
99 #include "utils/syscache.h"
100 #include "utils/tqual.h"
106 bool autovacuum_start_daemon
= false;
107 int autovacuum_max_workers
;
108 int autovacuum_naptime
;
109 int autovacuum_vac_thresh
;
110 double autovacuum_vac_scale
;
111 int autovacuum_anl_thresh
;
112 double autovacuum_anl_scale
;
113 int autovacuum_freeze_max_age
;
115 int autovacuum_vac_cost_delay
;
116 int autovacuum_vac_cost_limit
;
118 int Log_autovacuum_min_duration
= -1;
120 /* how long to keep pgstat data in the launcher, in milliseconds */
121 #define STATS_READ_DELAY 1000
124 /* Flags to tell if we are in an autovacuum process */
125 static bool am_autovacuum_launcher
= false;
126 static bool am_autovacuum_worker
= false;
128 /* Flags set by signal handlers */
129 static volatile sig_atomic_t got_SIGHUP
= false;
130 static volatile sig_atomic_t got_SIGUSR1
= false;
131 static volatile sig_atomic_t got_SIGTERM
= false;
133 /* Comparison point for determining whether freeze_max_age is exceeded */
134 static TransactionId recentXid
;
136 /* Default freeze_min_age to use for autovacuum (varies by database) */
137 static int default_freeze_min_age
;
139 /* Memory context for long-lived data */
140 static MemoryContext AutovacMemCxt
;
142 /* struct to keep track of databases in launcher */
143 typedef struct avl_dbase
145 Oid adl_datid
; /* hash key -- must be first */
146 TimestampTz adl_next_worker
;
150 /* struct to keep track of databases in worker */
151 typedef struct avw_dbase
155 TransactionId adw_frozenxid
;
156 PgStat_StatDBEntry
*adw_entry
;
159 /* struct to keep track of tables to vacuum and/or analyze, in 1st pass */
160 typedef struct av_relation
166 /* struct to keep track of tables to vacuum and/or analyze, after rechecking */
167 typedef struct autovac_table
173 int at_freeze_min_age
;
174 int at_vacuum_cost_delay
;
175 int at_vacuum_cost_limit
;
180 * This struct holds information about a single worker's whereabouts. We keep
181 * an array of these in shared memory, sized according to
182 * autovacuum_max_workers.
184 * wi_links entry into free list or running list
185 * wi_dboid OID of the database this worker is supposed to work on
186 * wi_tableoid OID of the table currently being vacuumed
187 * wi_proc pointer to PGPROC of the running worker, NULL if not started
188 * wi_launchtime Time at which this worker was launched
189 * wi_cost_* Vacuum cost-based delay parameters current in this worker
191 * All fields are protected by AutovacuumLock, except for wi_tableoid which is
192 * protected by AutovacuumScheduleLock (which is read-only for everyone except
193 * that worker itself).
196 typedef struct WorkerInfoData
202 TimestampTz wi_launchtime
;
205 int wi_cost_limit_base
;
208 typedef struct WorkerInfoData
*WorkerInfo
;
211 * Possible signals received by the launcher from remote processes. These are
212 * stored atomically in shared memory so that other processes can set them
217 AutoVacForkFailed
, /* failed trying to start a worker */
218 AutoVacRebalance
, /* rebalance the cost limits */
219 AutoVacNumSignals
= AutoVacRebalance
/* must be last */
223 * The main autovacuum shmem struct. On shared memory we store this main
224 * struct and the array of WorkerInfo structs. This struct keeps:
226 * av_signal set by other processes to indicate various conditions
227 * av_launcherpid the PID of the autovacuum launcher
228 * av_freeWorkers the WorkerInfo freelist
229 * av_runningWorkers the WorkerInfo non-free queue
230 * av_startingWorker pointer to WorkerInfo currently being started (cleared by
231 * the worker itself as soon as it's up and running)
233 * This struct is protected by AutovacuumLock, except for av_signal and parts
234 * of the worker list (see above).
239 sig_atomic_t av_signal
[AutoVacNumSignals
];
240 pid_t av_launcherpid
;
241 SHMEM_OFFSET av_freeWorkers
;
242 SHM_QUEUE av_runningWorkers
;
243 SHMEM_OFFSET av_startingWorker
;
244 } AutoVacuumShmemStruct
;
246 static AutoVacuumShmemStruct
*AutoVacuumShmem
;
248 /* the database list in the launcher, and the context that contains it */
249 static Dllist
*DatabaseList
= NULL
;
250 static MemoryContext DatabaseListCxt
= NULL
;
252 /* Pointer to my own WorkerInfo, valid on each worker */
253 static WorkerInfo MyWorkerInfo
= NULL
;
255 /* PID of launcher, valid only in worker while shutting down */
256 int AutovacuumLauncherPid
= 0;
259 static pid_t
avlauncher_forkexec(void);
260 static pid_t
avworker_forkexec(void);
262 NON_EXEC_STATIC
void AutoVacWorkerMain(int argc
, char *argv
[]);
263 NON_EXEC_STATIC
void AutoVacLauncherMain(int argc
, char *argv
[]);
265 static Oid
do_start_worker(void);
266 static void launcher_determine_sleep(bool canlaunch
, bool recursing
,
267 struct timeval
* nap
);
268 static void launch_worker(TimestampTz now
);
269 static List
*get_database_list(void);
270 static void rebuild_database_list(Oid newdb
);
271 static int db_comparator(const void *a
, const void *b
);
272 static void autovac_balance_cost(void);
274 static void do_autovacuum(void);
275 static void FreeWorkerInfo(int code
, Datum arg
);
277 static void relation_check_autovac(Oid relid
, Form_pg_class classForm
,
278 Form_pg_autovacuum avForm
, PgStat_StatTabEntry
*tabentry
,
279 List
**table_oids
, List
**table_toast_list
,
281 static autovac_table
*table_recheck_autovac(Oid relid
);
282 static void relation_needs_vacanalyze(Oid relid
, Form_pg_autovacuum avForm
,
283 Form_pg_class classForm
,
284 PgStat_StatTabEntry
*tabentry
, bool *dovacuum
,
285 bool *doanalyze
, bool *wraparound
);
287 static void autovacuum_do_vac_analyze(Oid relid
, bool dovacuum
,
288 bool doanalyze
, int freeze_min_age
,
290 BufferAccessStrategy bstrategy
);
291 static HeapTuple
get_pg_autovacuum_tuple_relid(Relation avRel
, Oid relid
);
292 static PgStat_StatTabEntry
*get_pgstat_tabentry_relid(Oid relid
, bool isshared
,
293 PgStat_StatDBEntry
*shared
,
294 PgStat_StatDBEntry
*dbentry
);
295 static void autovac_report_activity(VacuumStmt
*vacstmt
, Oid relid
);
296 static void avl_sighup_handler(SIGNAL_ARGS
);
297 static void avl_sigusr1_handler(SIGNAL_ARGS
);
298 static void avl_sigterm_handler(SIGNAL_ARGS
);
299 static void avl_quickdie(SIGNAL_ARGS
);
300 static void autovac_refresh_stats(void);
304 /********************************************************************
305 * AUTOVACUUM LAUNCHER CODE
306 ********************************************************************/
310 * forkexec routine for the autovacuum launcher process.
312 * Format up the arglist, then fork and exec.
315 avlauncher_forkexec(void)
320 av
[ac
++] = "postgres";
321 av
[ac
++] = "--forkavlauncher";
322 av
[ac
++] = NULL
; /* filled in by postmaster_forkexec */
325 Assert(ac
< lengthof(av
));
327 return postmaster_forkexec(ac
, av
);
331 * We need this set from the outside, before InitProcess is called
334 AutovacuumLauncherIAm(void)
336 am_autovacuum_launcher
= true;
341 * Main entry point for autovacuum launcher process, to be called from the
345 StartAutoVacLauncher(void)
350 switch ((AutoVacPID
= avlauncher_forkexec()))
352 switch ((AutoVacPID
= fork_process()))
357 (errmsg("could not fork autovacuum launcher process: %m")));
362 /* in postmaster child ... */
363 /* Close the postmaster's sockets */
364 ClosePostmasterPorts(false);
366 /* Lose the postmaster's on-exit routines */
369 AutoVacLauncherMain(0, NULL
);
373 return (int) AutoVacPID
;
376 /* shouldn't get here */
381 * Main loop for the autovacuum launcher process.
384 AutoVacLauncherMain(int argc
, char *argv
[])
386 sigjmp_buf local_sigjmp_buf
;
388 /* we are a postmaster subprocess now */
389 IsUnderPostmaster
= true;
390 am_autovacuum_launcher
= true;
392 /* reset MyProcPid */
393 MyProcPid
= getpid();
395 /* record Start Time for logging */
396 MyStartTime
= time(NULL
);
398 /* Identify myself via ps */
399 init_ps_display("autovacuum launcher process", "", "", "");
402 pg_usleep(PostAuthDelay
* 1000000L);
404 SetProcessingMode(InitProcessing
);
407 * If possible, make this process a group leader, so that the postmaster
408 * can signal any child processes too. (autovacuum probably never has any
409 * child processes, but for consistency we make all postmaster child
410 * processes do this.)
414 elog(FATAL
, "setsid() failed: %m");
418 * Set up signal handlers. Since this is an auxiliary process, it has
419 * particular signal requirements -- no deadlock checker or sinval
420 * catchup, for example.
422 pqsignal(SIGHUP
, avl_sighup_handler
);
424 pqsignal(SIGINT
, SIG_IGN
);
425 pqsignal(SIGTERM
, avl_sigterm_handler
);
426 pqsignal(SIGQUIT
, avl_quickdie
);
427 pqsignal(SIGALRM
, SIG_IGN
);
429 pqsignal(SIGPIPE
, SIG_IGN
);
430 pqsignal(SIGUSR1
, avl_sigusr1_handler
);
431 /* We don't listen for async notifies */
432 pqsignal(SIGUSR2
, SIG_IGN
);
433 pqsignal(SIGFPE
, FloatExceptionHandler
);
434 pqsignal(SIGCHLD
, SIG_DFL
);
436 /* Early initialization */
440 * Create a per-backend PGPROC struct in shared memory, except in the
441 * EXEC_BACKEND case where this was done in SubPostmasterMain. We must do
442 * this before we can use LWLocks (and in the EXEC_BACKEND case we already
443 * had to do some stuff with LWLocks).
446 InitAuxiliaryProcess();
450 * Create a memory context that we will do all our work in. We do this so
451 * that we can reset the context during error recovery and thereby avoid
452 * possible memory leaks.
454 AutovacMemCxt
= AllocSetContextCreate(TopMemoryContext
,
455 "Autovacuum Launcher",
456 ALLOCSET_DEFAULT_MINSIZE
,
457 ALLOCSET_DEFAULT_INITSIZE
,
458 ALLOCSET_DEFAULT_MAXSIZE
);
459 MemoryContextSwitchTo(AutovacMemCxt
);
463 * If an exception is encountered, processing resumes here.
465 * This code is heavily based on bgwriter.c, q.v.
467 if (sigsetjmp(local_sigjmp_buf
, 1) != 0)
469 /* since not using PG_TRY, must reset error stack by hand */
470 error_context_stack
= NULL
;
472 /* Prevents interrupts while cleaning up */
475 /* Report the error to the server log */
479 * These operations are really just a minimal subset of
480 * AbortTransaction(). We don't have very many resources to worry
481 * about, but we do have LWLocks.
485 AtEOXact_HashTables(false);
488 * Now return to normal top-level context and clear ErrorContext for
491 MemoryContextSwitchTo(AutovacMemCxt
);
494 /* Flush any leaked data in the top-level context */
495 MemoryContextResetAndDeleteChildren(AutovacMemCxt
);
497 /* don't leave dangling pointers to freed memory */
498 DatabaseListCxt
= NULL
;
502 * Make sure pgstat also considers our stat data as gone. Note: we
503 * mustn't use autovac_refresh_stats here.
505 pgstat_clear_snapshot();
507 /* Now we can allow interrupts again */
511 * Sleep at least 1 second after any error. We don't want to be
512 * filling the error logs as fast as we can.
517 /* We can now handle ereport(ERROR) */
518 PG_exception_stack
= &local_sigjmp_buf
;
521 (errmsg("autovacuum launcher started")));
523 /* must unblock signals before calling rebuild_database_list */
524 PG_SETMASK(&UnBlockSig
);
526 /* in emergency mode, just start a worker and go away */
527 if (!AutoVacuumingActive())
530 proc_exit(0); /* done */
533 AutoVacuumShmem
->av_launcherpid
= MyProcPid
;
536 * Create the initial database list. The invariant we want this list to
537 * keep is that it's ordered by decreasing next_time. As soon as an entry
538 * is updated to a higher time, it will be moved to the front (which is
539 * correct because the only operation is to add autovacuum_naptime to the
540 * entry, and time always increases).
542 rebuild_database_list(InvalidOid
);
547 TimestampTz current_time
= 0;
552 * Emergency bailout if postmaster has died. This is to avoid the
553 * necessity for manual cleanup of all postmaster children.
555 if (!PostmasterIsAlive(true))
558 launcher_determine_sleep(AutoVacuumShmem
->av_freeWorkers
!=
559 INVALID_OFFSET
, false, &nap
);
562 * Sleep for a while according to schedule.
564 * On some platforms, signals won't interrupt the sleep. To ensure we
565 * respond reasonably promptly when someone signals us, break down the
566 * sleep into 1-second increments, and check for interrupts after each
569 while (nap
.tv_sec
> 0 || nap
.tv_usec
> 0)
580 sleeptime
= nap
.tv_usec
;
583 pg_usleep(sleeptime
);
586 * Emergency bailout if postmaster has died. This is to avoid the
587 * necessity for manual cleanup of all postmaster children.
589 if (!PostmasterIsAlive(true))
592 if (got_SIGTERM
|| got_SIGHUP
|| got_SIGUSR1
)
596 /* the normal shutdown case */
603 ProcessConfigFile(PGC_SIGHUP
);
605 /* shutdown requested in config file */
606 if (!AutoVacuumingActive())
609 /* rebalance in case the default cost parameters changed */
610 LWLockAcquire(AutovacuumLock
, LW_EXCLUSIVE
);
611 autovac_balance_cost();
612 LWLockRelease(AutovacuumLock
);
614 /* rebuild the list in case the naptime changed */
615 rebuild_database_list(InvalidOid
);
619 * a worker finished, or postmaster signalled failure to start a
626 /* rebalance cost limits, if needed */
627 if (AutoVacuumShmem
->av_signal
[AutoVacRebalance
])
629 LWLockAcquire(AutovacuumLock
, LW_EXCLUSIVE
);
630 AutoVacuumShmem
->av_signal
[AutoVacRebalance
] = false;
631 autovac_balance_cost();
632 LWLockRelease(AutovacuumLock
);
635 if (AutoVacuumShmem
->av_signal
[AutoVacForkFailed
])
638 * If the postmaster failed to start a new worker, we sleep
639 * for a little while and resend the signal. The new worker's
640 * state is still in memory, so this is sufficient. After
641 * that, we restart the main loop.
643 * XXX should we put a limit to the number of times we retry?
644 * I don't think it makes much sense, because a future start
645 * of a worker will continue to fail in the same way.
647 AutoVacuumShmem
->av_signal
[AutoVacForkFailed
] = false;
648 pg_usleep(100000L); /* 100ms */
649 SendPostmasterSignal(PMSIGNAL_START_AUTOVAC_WORKER
);
655 * There are some conditions that we need to check before trying to
656 * start a launcher. First, we need to make sure that there is a
657 * launcher slot available. Second, we need to make sure that no
658 * other worker failed while starting up.
661 current_time
= GetCurrentTimestamp();
662 LWLockAcquire(AutovacuumLock
, LW_SHARED
);
664 can_launch
= (AutoVacuumShmem
->av_freeWorkers
!= INVALID_OFFSET
);
666 if (AutoVacuumShmem
->av_startingWorker
!= INVALID_OFFSET
)
670 WorkerInfo worker
= (WorkerInfo
) MAKE_PTR(AutoVacuumShmem
->av_startingWorker
);
673 * We can't launch another worker when another one is still
674 * starting up (or failed while doing so), so just sleep for a bit
675 * more; that worker will wake us up again as soon as it's ready.
676 * We will only wait autovacuum_naptime seconds (up to a maximum
677 * of 60 seconds) for this to happen however. Note that failure
678 * to connect to a particular database is not a problem here,
679 * because the worker removes itself from the startingWorker
680 * pointer before trying to connect. Problems detected by the
681 * postmaster (like fork() failure) are also reported and handled
682 * differently. The only problems that may cause this code to
683 * fire are errors in the earlier sections of AutoVacWorkerMain,
684 * before the worker removes the WorkerInfo from the
685 * startingWorker pointer.
687 waittime
= Min(autovacuum_naptime
, 60) * 1000;
688 if (TimestampDifferenceExceeds(worker
->wi_launchtime
, current_time
,
691 LWLockRelease(AutovacuumLock
);
692 LWLockAcquire(AutovacuumLock
, LW_EXCLUSIVE
);
695 * No other process can put a worker in starting mode, so if
696 * startingWorker is still INVALID after exchanging our lock,
697 * we assume it's the same one we saw above (so we don't
698 * recheck the launch time).
700 if (AutoVacuumShmem
->av_startingWorker
!= INVALID_OFFSET
)
702 worker
= (WorkerInfo
) MAKE_PTR(AutoVacuumShmem
->av_startingWorker
);
703 worker
->wi_dboid
= InvalidOid
;
704 worker
->wi_tableoid
= InvalidOid
;
705 worker
->wi_proc
= NULL
;
706 worker
->wi_launchtime
= 0;
707 worker
->wi_links
.next
= AutoVacuumShmem
->av_freeWorkers
;
708 AutoVacuumShmem
->av_freeWorkers
= MAKE_OFFSET(worker
);
709 AutoVacuumShmem
->av_startingWorker
= INVALID_OFFSET
;
710 elog(WARNING
, "worker took too long to start; cancelled");
716 LWLockRelease(AutovacuumLock
); /* either shared or exclusive */
718 /* if we can't do anything, just go back to sleep */
722 /* We're OK to start a new worker */
724 elem
= DLGetTail(DatabaseList
);
727 avl_dbase
*avdb
= DLE_VAL(elem
);
730 * launch a worker if next_worker is right now or it is in the
733 if (TimestampDifferenceExceeds(avdb
->adl_next_worker
,
735 launch_worker(current_time
);
740 * Special case when the list is empty: start a worker right away.
741 * This covers the initial case, when no database is in pgstats
742 * (thus the list is empty). Note that the constraints in
743 * launcher_determine_sleep keep us from starting workers too
744 * quickly (at most once every autovacuum_naptime when the list is
747 launch_worker(current_time
);
751 /* Normal exit from the autovac launcher is here */
753 (errmsg("autovacuum launcher shutting down")));
754 AutoVacuumShmem
->av_launcherpid
= 0;
756 proc_exit(0); /* done */
760 * Determine the time to sleep, based on the database list.
762 * The "canlaunch" parameter indicates whether we can start a worker right now,
763 * for example due to the workers being all busy. If this is false, we will
764 * cause a long sleep, which will be interrupted when a worker exits.
767 launcher_determine_sleep(bool canlaunch
, bool recursing
, struct timeval
* nap
)
772 * We sleep until the next scheduled vacuum. We trust that when the
773 * database list was built, care was taken so that no entries have times
774 * in the past; if the first entry has too close a next_worker value, or a
775 * time in the past, we will sleep a small nominal time.
779 nap
->tv_sec
= autovacuum_naptime
;
782 else if ((elem
= DLGetTail(DatabaseList
)) != NULL
)
784 avl_dbase
*avdb
= DLE_VAL(elem
);
785 TimestampTz current_time
= GetCurrentTimestamp();
786 TimestampTz next_wakeup
;
790 next_wakeup
= avdb
->adl_next_worker
;
791 TimestampDifference(current_time
, next_wakeup
, &secs
, &usecs
);
794 nap
->tv_usec
= usecs
;
798 /* list is empty, sleep for whole autovacuum_naptime seconds */
799 nap
->tv_sec
= autovacuum_naptime
;
804 * If the result is exactly zero, it means a database had an entry with
805 * time in the past. Rebuild the list so that the databases are evenly
806 * distributed again, and recalculate the time to sleep. This can happen
807 * if there are more tables needing vacuum than workers, and they all take
808 * longer to vacuum than autovacuum_naptime.
810 * We only recurse once. rebuild_database_list should always return times
811 * in the future, but it seems best not to trust too much on that.
813 if (nap
->tv_sec
== 0 && nap
->tv_usec
== 0 && !recursing
)
815 rebuild_database_list(InvalidOid
);
816 launcher_determine_sleep(canlaunch
, true, nap
);
820 /* 100ms is the smallest time we'll allow the launcher to sleep */
821 if (nap
->tv_sec
<= 0 && nap
->tv_usec
<= 100000)
824 nap
->tv_usec
= 100000; /* 100 ms */
829 * Build an updated DatabaseList. It must only contain databases that appear
830 * in pgstats, and must be sorted by next_worker from highest to lowest,
831 * distributed regularly across the next autovacuum_naptime interval.
833 * Receives the Oid of the database that made this list be generated (we call
834 * this the "new" database, because when the database was already present on
835 * the list, we expect that this function is not called at all). The
836 * preexisting list, if any, will be used to preserve the order of the
837 * databases in the autovacuum_naptime period. The new database is put at the
838 * end of the interval. The actual values are not saved, which should not be
842 rebuild_database_list(Oid newdb
)
846 MemoryContext newcxt
;
847 MemoryContext oldcxt
;
848 MemoryContext tmpcxt
;
854 /* use fresh stats */
855 autovac_refresh_stats();
857 newcxt
= AllocSetContextCreate(AutovacMemCxt
,
859 ALLOCSET_DEFAULT_MINSIZE
,
860 ALLOCSET_DEFAULT_INITSIZE
,
861 ALLOCSET_DEFAULT_MAXSIZE
);
862 tmpcxt
= AllocSetContextCreate(newcxt
,
864 ALLOCSET_DEFAULT_MINSIZE
,
865 ALLOCSET_DEFAULT_INITSIZE
,
866 ALLOCSET_DEFAULT_MAXSIZE
);
867 oldcxt
= MemoryContextSwitchTo(tmpcxt
);
870 * Implementing this is not as simple as it sounds, because we need to put
871 * the new database at the end of the list; next the databases that were
872 * already on the list, and finally (at the tail of the list) all the
873 * other databases that are not on the existing list.
875 * To do this, we build an empty hash table of scored databases. We will
876 * start with the lowest score (zero) for the new database, then
877 * increasing scores for the databases in the existing list, in order, and
878 * lastly increasing scores for all databases gotten via
879 * get_database_list() that are not already on the hash.
881 * Then we will put all the hash elements into an array, sort the array by
882 * score, and finally put the array elements into the new doubly linked
885 hctl
.keysize
= sizeof(Oid
);
886 hctl
.entrysize
= sizeof(avl_dbase
);
887 hctl
.hash
= oid_hash
;
889 dbhash
= hash_create("db hash", 20, &hctl
, /* magic number here FIXME */
890 HASH_ELEM
| HASH_FUNCTION
| HASH_CONTEXT
);
892 /* start by inserting the new database */
894 if (OidIsValid(newdb
))
897 PgStat_StatDBEntry
*entry
;
899 /* only consider this database if it has a pgstat entry */
900 entry
= pgstat_fetch_stat_dbentry(newdb
);
903 /* we assume it isn't found because the hash was just created */
904 db
= hash_search(dbhash
, &newdb
, HASH_ENTER
, NULL
);
906 /* hash_search already filled in the key */
907 db
->adl_score
= score
++;
908 /* next_worker is filled in later */
912 /* Now insert the databases from the existing list */
913 if (DatabaseList
!= NULL
)
917 elem
= DLGetHead(DatabaseList
);
920 avl_dbase
*avdb
= DLE_VAL(elem
);
923 PgStat_StatDBEntry
*entry
;
925 elem
= DLGetSucc(elem
);
928 * skip databases with no stat entries -- in particular, this gets
929 * rid of dropped databases
931 entry
= pgstat_fetch_stat_dbentry(avdb
->adl_datid
);
935 db
= hash_search(dbhash
, &(avdb
->adl_datid
), HASH_ENTER
, &found
);
939 /* hash_search already filled in the key */
940 db
->adl_score
= score
++;
941 /* next_worker is filled in later */
946 /* finally, insert all qualifying databases not previously inserted */
947 dblist
= get_database_list();
948 foreach(cell
, dblist
)
950 avw_dbase
*avdb
= lfirst(cell
);
953 PgStat_StatDBEntry
*entry
;
955 /* only consider databases with a pgstat entry */
956 entry
= pgstat_fetch_stat_dbentry(avdb
->adw_datid
);
960 db
= hash_search(dbhash
, &(avdb
->adw_datid
), HASH_ENTER
, &found
);
961 /* only update the score if the database was not already on the hash */
964 /* hash_search already filled in the key */
965 db
->adl_score
= score
++;
966 /* next_worker is filled in later */
971 /* from here on, the allocated memory belongs to the new list */
972 MemoryContextSwitchTo(newcxt
);
973 DatabaseList
= DLNewList();
977 TimestampTz current_time
;
978 int millis_increment
;
984 /* put all the hash elements into an array */
985 dbary
= palloc(nelems
* sizeof(avl_dbase
));
988 hash_seq_init(&seq
, dbhash
);
989 while ((db
= hash_seq_search(&seq
)) != NULL
)
990 memcpy(&(dbary
[i
++]), db
, sizeof(avl_dbase
));
993 qsort(dbary
, nelems
, sizeof(avl_dbase
), db_comparator
);
995 /* this is the time interval between databases in the schedule */
996 millis_increment
= 1000.0 * autovacuum_naptime
/ nelems
;
997 current_time
= GetCurrentTimestamp();
1000 * move the elements from the array into the dllist, setting the
1001 * next_worker while walking the array
1003 for (i
= 0; i
< nelems
; i
++)
1005 avl_dbase
*db
= &(dbary
[i
]);
1008 current_time
= TimestampTzPlusMilliseconds(current_time
,
1010 db
->adl_next_worker
= current_time
;
1012 elem
= DLNewElem(db
);
1013 /* later elements should go closer to the head of the list */
1014 DLAddHead(DatabaseList
, elem
);
1018 /* all done, clean up memory */
1019 if (DatabaseListCxt
!= NULL
)
1020 MemoryContextDelete(DatabaseListCxt
);
1021 MemoryContextDelete(tmpcxt
);
1022 DatabaseListCxt
= newcxt
;
1023 MemoryContextSwitchTo(oldcxt
);
1026 /* qsort comparator for avl_dbase, using adl_score */
1028 db_comparator(const void *a
, const void *b
)
1030 if (((avl_dbase
*) a
)->adl_score
== ((avl_dbase
*) b
)->adl_score
)
1033 return (((avl_dbase
*) a
)->adl_score
< ((avl_dbase
*) b
)->adl_score
) ? 1 : -1;
1039 * Bare-bones procedure for starting an autovacuum worker from the launcher.
1040 * It determines what database to work on, sets up shared memory stuff and
1041 * signals postmaster to start the worker. It fails gracefully if invoked when
1042 * autovacuum_workers are already active.
1044 * Return value is the OID of the database that the worker is going to process,
1045 * or InvalidOid if no worker was actually started.
1048 do_start_worker(void)
1052 TransactionId xidForceLimit
;
1055 TimestampTz current_time
;
1056 bool skipit
= false;
1057 Oid retval
= InvalidOid
;
1058 MemoryContext tmpcxt
,
1061 /* return quickly when there are no free workers */
1062 LWLockAcquire(AutovacuumLock
, LW_SHARED
);
1063 if (AutoVacuumShmem
->av_freeWorkers
== INVALID_OFFSET
)
1065 LWLockRelease(AutovacuumLock
);
1068 LWLockRelease(AutovacuumLock
);
1071 * Create and switch to a temporary context to avoid leaking the memory
1072 * allocated for the database list.
1074 tmpcxt
= AllocSetContextCreate(CurrentMemoryContext
,
1075 "Start worker tmp cxt",
1076 ALLOCSET_DEFAULT_MINSIZE
,
1077 ALLOCSET_DEFAULT_INITSIZE
,
1078 ALLOCSET_DEFAULT_MAXSIZE
);
1079 oldcxt
= MemoryContextSwitchTo(tmpcxt
);
1081 /* use fresh stats */
1082 autovac_refresh_stats();
1084 /* Get a list of databases */
1085 dblist
= get_database_list();
1088 * Determine the oldest datfrozenxid/relfrozenxid that we will allow to
1089 * pass without forcing a vacuum. (This limit can be tightened for
1090 * particular tables, but not loosened.)
1092 recentXid
= ReadNewTransactionId();
1093 xidForceLimit
= recentXid
- autovacuum_freeze_max_age
;
1094 /* ensure it's a "normal" XID, else TransactionIdPrecedes misbehaves */
1095 if (xidForceLimit
< FirstNormalTransactionId
)
1096 xidForceLimit
-= FirstNormalTransactionId
;
1099 * Choose a database to connect to. We pick the database that was least
1100 * recently auto-vacuumed, or one that needs vacuuming to prevent Xid
1101 * wraparound-related data loss. If any db at risk of wraparound is
1102 * found, we pick the one with oldest datfrozenxid, independently of
1105 * Note that a database with no stats entry is not considered, except for
1106 * Xid wraparound purposes. The theory is that if no one has ever
1107 * connected to it since the stats were last initialized, it doesn't need
1110 * XXX This could be improved if we had more info about whether it needs
1111 * vacuuming before connecting to it. Perhaps look through the pgstats
1112 * data for the database's tables? One idea is to keep track of the
1113 * number of new and dead tuples per database in pgstats. However it
1114 * isn't clear how to construct a metric that measures that and not cause
1115 * starvation for less busy databases.
1118 for_xid_wrap
= false;
1119 current_time
= GetCurrentTimestamp();
1120 foreach(cell
, dblist
)
1122 avw_dbase
*tmp
= lfirst(cell
);
1125 /* Check to see if this one is at risk of wraparound */
1126 if (TransactionIdPrecedes(tmp
->adw_frozenxid
, xidForceLimit
))
1129 TransactionIdPrecedes(tmp
->adw_frozenxid
, avdb
->adw_frozenxid
))
1131 for_xid_wrap
= true;
1134 else if (for_xid_wrap
)
1135 continue; /* ignore not-at-risk DBs */
1137 /* Find pgstat entry if any */
1138 tmp
->adw_entry
= pgstat_fetch_stat_dbentry(tmp
->adw_datid
);
1141 * Skip a database with no pgstat entry; it means it hasn't seen any
1144 if (!tmp
->adw_entry
)
1148 * Also, skip a database that appears on the database list as having
1149 * been processed recently (less than autovacuum_naptime seconds ago).
1150 * We do this so that we don't select a database which we just
1151 * selected, but that pgstat hasn't gotten around to updating the last
1152 * autovacuum time yet.
1155 elem
= DatabaseList
? DLGetTail(DatabaseList
) : NULL
;
1157 while (elem
!= NULL
)
1159 avl_dbase
*dbp
= DLE_VAL(elem
);
1161 if (dbp
->adl_datid
== tmp
->adw_datid
)
1164 * Skip this database if its next_worker value falls between
1165 * the current time and the current time plus naptime.
1167 if (!TimestampDifferenceExceeds(dbp
->adl_next_worker
,
1169 !TimestampDifferenceExceeds(current_time
,
1170 dbp
->adl_next_worker
,
1171 autovacuum_naptime
* 1000))
1176 elem
= DLGetPred(elem
);
1182 * Remember the db with oldest autovac time. (If we are here, both
1183 * tmp->entry and db->entry must be non-null.)
1186 tmp
->adw_entry
->last_autovac_time
< avdb
->adw_entry
->last_autovac_time
)
1190 /* Found a database -- process it */
1194 SHMEM_OFFSET sworker
;
1196 LWLockAcquire(AutovacuumLock
, LW_EXCLUSIVE
);
1199 * Get a worker entry from the freelist. We checked above, so there
1200 * really should be a free slot -- complain very loudly if there
1203 sworker
= AutoVacuumShmem
->av_freeWorkers
;
1204 if (sworker
== INVALID_OFFSET
)
1205 elog(FATAL
, "no free worker found");
1207 worker
= (WorkerInfo
) MAKE_PTR(sworker
);
1208 AutoVacuumShmem
->av_freeWorkers
= worker
->wi_links
.next
;
1210 worker
->wi_dboid
= avdb
->adw_datid
;
1211 worker
->wi_proc
= NULL
;
1212 worker
->wi_launchtime
= GetCurrentTimestamp();
1214 AutoVacuumShmem
->av_startingWorker
= sworker
;
1216 LWLockRelease(AutovacuumLock
);
1218 SendPostmasterSignal(PMSIGNAL_START_AUTOVAC_WORKER
);
1220 retval
= avdb
->adw_datid
;
1225 * If we skipped all databases on the list, rebuild it, because it
1226 * probably contains a dropped database.
1228 rebuild_database_list(InvalidOid
);
1231 MemoryContextSwitchTo(oldcxt
);
1232 MemoryContextDelete(tmpcxt
);
1240 * Wrapper for starting a worker from the launcher. Besides actually starting
1241 * it, update the database list to reflect the next time that another one will
1242 * need to be started on the selected database. The actual database choice is
1243 * left to do_start_worker.
1245 * This routine is also expected to insert an entry into the database list if
1246 * the selected database was previously absent from the list. It returns the
1247 * new database list.
1250 launch_worker(TimestampTz now
)
1255 dbid
= do_start_worker();
1256 if (OidIsValid(dbid
))
1259 * Walk the database list and update the corresponding entry. If the
1260 * database is not on the list, we'll recreate the list.
1262 elem
= (DatabaseList
== NULL
) ? NULL
: DLGetHead(DatabaseList
);
1263 while (elem
!= NULL
)
1265 avl_dbase
*avdb
= DLE_VAL(elem
);
1267 if (avdb
->adl_datid
== dbid
)
1270 * add autovacuum_naptime seconds to the current time, and use
1271 * that as the new "next_worker" field for this database.
1273 avdb
->adl_next_worker
=
1274 TimestampTzPlusMilliseconds(now
, autovacuum_naptime
* 1000);
1276 DLMoveToFront(elem
);
1279 elem
= DLGetSucc(elem
);
1283 * If the database was not present in the database list, we rebuild
1284 * the list. It's possible that the database does not get into the
1285 * list anyway, for example if it's a database that doesn't have a
1286 * pgstat entry, but this is not a problem because we don't want to
1287 * schedule workers regularly into those in any case.
1290 rebuild_database_list(dbid
);
1295 * Called from postmaster to signal a failure to fork a process to become
1296 * worker. The postmaster should kill(SIGUSR1) the launcher shortly
1297 * after calling this function.
1300 AutoVacWorkerFailed(void)
1302 AutoVacuumShmem
->av_signal
[AutoVacForkFailed
] = true;
1305 /* SIGHUP: set flag to re-read config file at next convenient time */
1307 avl_sighup_handler(SIGNAL_ARGS
)
1312 /* SIGUSR1: a worker is up and running, or just finished */
1314 avl_sigusr1_handler(SIGNAL_ARGS
)
1319 /* SIGTERM: time to die */
1321 avl_sigterm_handler(SIGNAL_ARGS
)
1327 * avl_quickdie occurs when signalled SIGQUIT from postmaster.
1329 * Some backend has bought the farm, so we need to stop what we're doing
1333 avl_quickdie(SIGNAL_ARGS
)
1335 PG_SETMASK(&BlockSig
);
1338 * DO NOT proc_exit() -- we're here because shared memory may be
1339 * corrupted, so we don't want to try to clean up our transaction. Just
1340 * nail the windows shut and get out of town.
1342 * Note we do exit(2) not exit(0). This is to force the postmaster into a
1343 * system reset cycle if some idiot DBA sends a manual SIGQUIT to a random
1344 * backend. This is necessary precisely because we don't clean up our
1345 * shared memory state.
1351 /********************************************************************
1352 * AUTOVACUUM WORKER CODE
1353 ********************************************************************/
1357 * forkexec routines for the autovacuum worker.
1359 * Format up the arglist, then fork and exec.
1362 avworker_forkexec(void)
1367 av
[ac
++] = "postgres";
1368 av
[ac
++] = "--forkavworker";
1369 av
[ac
++] = NULL
; /* filled in by postmaster_forkexec */
1372 Assert(ac
< lengthof(av
));
1374 return postmaster_forkexec(ac
, av
);
1378 * We need this set from the outside, before InitProcess is called
1381 AutovacuumWorkerIAm(void)
1383 am_autovacuum_worker
= true;
1388 * Main entry point for autovacuum worker process.
1390 * This code is heavily based on pgarch.c, q.v.
1393 StartAutoVacWorker(void)
1398 switch ((worker_pid
= avworker_forkexec()))
1400 switch ((worker_pid
= fork_process()))
1405 (errmsg("could not fork autovacuum worker process: %m")));
1408 #ifndef EXEC_BACKEND
1410 /* in postmaster child ... */
1411 /* Close the postmaster's sockets */
1412 ClosePostmasterPorts(false);
1414 /* Lose the postmaster's on-exit routines */
1417 AutoVacWorkerMain(0, NULL
);
1421 return (int) worker_pid
;
1424 /* shouldn't get here */
1431 NON_EXEC_STATIC
void
1432 AutoVacWorkerMain(int argc
, char *argv
[])
1434 sigjmp_buf local_sigjmp_buf
;
1437 /* we are a postmaster subprocess now */
1438 IsUnderPostmaster
= true;
1439 am_autovacuum_worker
= true;
1441 /* reset MyProcPid */
1442 MyProcPid
= getpid();
1444 /* record Start Time for logging */
1445 MyStartTime
= time(NULL
);
1447 /* Identify myself via ps */
1448 init_ps_display("autovacuum worker process", "", "", "");
1450 SetProcessingMode(InitProcessing
);
1453 * If possible, make this process a group leader, so that the postmaster
1454 * can signal any child processes too. (autovacuum probably never has any
1455 * child processes, but for consistency we make all postmaster child
1456 * processes do this.)
1460 elog(FATAL
, "setsid() failed: %m");
1464 * Set up signal handlers. We operate on databases much like a regular
1465 * backend, so we use the same signal handling. See equivalent code in
1468 * Currently, we don't pay attention to postgresql.conf changes that
1469 * happen during a single daemon iteration, so we can ignore SIGHUP.
1471 pqsignal(SIGHUP
, SIG_IGN
);
1474 * SIGINT is used to signal cancelling the current table's vacuum; SIGTERM
1475 * means abort and exit cleanly, and SIGQUIT means abandon ship.
1477 pqsignal(SIGINT
, StatementCancelHandler
);
1478 pqsignal(SIGTERM
, die
);
1479 pqsignal(SIGQUIT
, quickdie
);
1480 pqsignal(SIGALRM
, handle_sig_alarm
);
1482 pqsignal(SIGPIPE
, SIG_IGN
);
1483 pqsignal(SIGUSR1
, CatchupInterruptHandler
);
1484 /* We don't listen for async notifies */
1485 pqsignal(SIGUSR2
, SIG_IGN
);
1486 pqsignal(SIGFPE
, FloatExceptionHandler
);
1487 pqsignal(SIGCHLD
, SIG_DFL
);
1489 /* Early initialization */
1493 * Create a per-backend PGPROC struct in shared memory, except in the
1494 * EXEC_BACKEND case where this was done in SubPostmasterMain. We must do
1495 * this before we can use LWLocks (and in the EXEC_BACKEND case we already
1496 * had to do some stuff with LWLocks).
1498 #ifndef EXEC_BACKEND
1503 * If an exception is encountered, processing resumes here.
1505 * See notes in postgres.c about the design of this coding.
1507 if (sigsetjmp(local_sigjmp_buf
, 1) != 0)
1509 /* Prevents interrupts while cleaning up */
1512 /* Report the error to the server log */
1516 * We can now go away. Note that because we called InitProcess, a
1517 * callback was registered to do ProcKill, which will clean up
1523 /* We can now handle ereport(ERROR) */
1524 PG_exception_stack
= &local_sigjmp_buf
;
1526 PG_SETMASK(&UnBlockSig
);
1529 * Force zero_damaged_pages OFF in the autovac process, even if it is set
1530 * in postgresql.conf. We don't really want such a dangerous option being
1531 * applied non-interactively.
1533 SetConfigOption("zero_damaged_pages", "false", PGC_SUSET
, PGC_S_OVERRIDE
);
1536 * Force statement_timeout to zero to avoid a timeout setting from
1537 * preventing regular maintenance from being executed.
1539 SetConfigOption("statement_timeout", "0", PGC_SUSET
, PGC_S_OVERRIDE
);
1542 * Get the info about the database we're going to work on.
1544 LWLockAcquire(AutovacuumLock
, LW_EXCLUSIVE
);
1547 * beware of startingWorker being INVALID; this should normally not
1548 * happen, but if a worker fails after forking and before this, the
1549 * launcher might have decided to remove it from the queue and start
1552 if (AutoVacuumShmem
->av_startingWorker
!= INVALID_OFFSET
)
1554 MyWorkerInfo
= (WorkerInfo
) MAKE_PTR(AutoVacuumShmem
->av_startingWorker
);
1555 dbid
= MyWorkerInfo
->wi_dboid
;
1556 MyWorkerInfo
->wi_proc
= MyProc
;
1558 /* insert into the running list */
1559 SHMQueueInsertBefore(&AutoVacuumShmem
->av_runningWorkers
,
1560 &MyWorkerInfo
->wi_links
);
1563 * remove from the "starting" pointer, so that the launcher can start
1564 * a new worker if required
1566 AutoVacuumShmem
->av_startingWorker
= INVALID_OFFSET
;
1567 LWLockRelease(AutovacuumLock
);
1569 on_shmem_exit(FreeWorkerInfo
, 0);
1571 /* wake up the launcher */
1572 if (AutoVacuumShmem
->av_launcherpid
!= 0)
1573 kill(AutoVacuumShmem
->av_launcherpid
, SIGUSR1
);
1577 /* no worker entry for me, go away */
1578 elog(WARNING
, "autovacuum worker started without a worker entry");
1580 LWLockRelease(AutovacuumLock
);
1583 if (OidIsValid(dbid
))
1588 * Report autovac startup to the stats collector. We deliberately do
1589 * this before InitPostgres, so that the last_autovac_time will get
1590 * updated even if the connection attempt fails. This is to prevent
1591 * autovac from getting "stuck" repeatedly selecting an unopenable
1592 * database, rather than making any progress on stuff it can connect
1595 pgstat_report_autovac(dbid
);
1598 * Connect to the selected database
1600 * Note: if we have selected a just-deleted database (due to using
1601 * stale stats info), we'll fail and exit here.
1603 InitPostgres(NULL
, dbid
, NULL
, &dbname
);
1604 SetProcessingMode(NormalProcessing
);
1605 set_ps_display(dbname
, false);
1607 (errmsg("autovacuum: processing database \"%s\"", dbname
)));
1610 pg_usleep(PostAuthDelay
* 1000000L);
1612 /* And do an appropriate amount of work */
1613 recentXid
= ReadNewTransactionId();
1618 * The launcher will be notified of my death in ProcKill, *if* we managed
1619 * to get a worker slot at all
1622 /* All done, go away */
1627 * Return a WorkerInfo to the free list
1630 FreeWorkerInfo(int code
, Datum arg
)
1632 if (MyWorkerInfo
!= NULL
)
1634 LWLockAcquire(AutovacuumLock
, LW_EXCLUSIVE
);
1637 * Wake the launcher up so that he can launch a new worker immediately
1638 * if required. We only save the launcher's PID in local memory here;
1639 * the actual signal will be sent when the PGPROC is recycled. Note
1640 * that we always do this, so that the launcher can rebalance the cost
1641 * limit setting of the remaining workers.
1643 * We somewhat ignore the risk that the launcher changes its PID
1644 * between we reading it and the actual kill; we expect ProcKill to be
1645 * called shortly after us, and we assume that PIDs are not reused too
1646 * quickly after a process exits.
1648 AutovacuumLauncherPid
= AutoVacuumShmem
->av_launcherpid
;
1650 SHMQueueDelete(&MyWorkerInfo
->wi_links
);
1651 MyWorkerInfo
->wi_links
.next
= AutoVacuumShmem
->av_freeWorkers
;
1652 MyWorkerInfo
->wi_dboid
= InvalidOid
;
1653 MyWorkerInfo
->wi_tableoid
= InvalidOid
;
1654 MyWorkerInfo
->wi_proc
= NULL
;
1655 MyWorkerInfo
->wi_launchtime
= 0;
1656 MyWorkerInfo
->wi_cost_delay
= 0;
1657 MyWorkerInfo
->wi_cost_limit
= 0;
1658 MyWorkerInfo
->wi_cost_limit_base
= 0;
1659 AutoVacuumShmem
->av_freeWorkers
= MAKE_OFFSET(MyWorkerInfo
);
1660 /* not mine anymore */
1661 MyWorkerInfo
= NULL
;
1664 * now that we're inactive, cause a rebalancing of the surviving
1667 AutoVacuumShmem
->av_signal
[AutoVacRebalance
] = true;
1668 LWLockRelease(AutovacuumLock
);
1673 * Update the cost-based delay parameters, so that multiple workers consume
1674 * each a fraction of the total available I/O.
1677 AutoVacuumUpdateDelay(void)
1681 VacuumCostDelay
= MyWorkerInfo
->wi_cost_delay
;
1682 VacuumCostLimit
= MyWorkerInfo
->wi_cost_limit
;
1687 * autovac_balance_cost
1688 * Recalculate the cost limit setting for each active workers.
1690 * Caller must hold the AutovacuumLock in exclusive mode.
1693 autovac_balance_cost(void)
1698 * note: in cost_limit, zero also means use value from elsewhere, because
1699 * zero is not a valid value.
1701 int vac_cost_limit
= (autovacuum_vac_cost_limit
> 0 ?
1702 autovacuum_vac_cost_limit
: VacuumCostLimit
);
1703 int vac_cost_delay
= (autovacuum_vac_cost_delay
>= 0 ?
1704 autovacuum_vac_cost_delay
: VacuumCostDelay
);
1708 /* not set? nothing to do */
1709 if (vac_cost_limit
<= 0 || vac_cost_delay
<= 0)
1712 /* caculate the total base cost limit of active workers */
1714 worker
= (WorkerInfo
) SHMQueueNext(&AutoVacuumShmem
->av_runningWorkers
,
1715 &AutoVacuumShmem
->av_runningWorkers
,
1716 offsetof(WorkerInfoData
, wi_links
));
1719 if (worker
->wi_proc
!= NULL
&&
1720 worker
->wi_cost_limit_base
> 0 && worker
->wi_cost_delay
> 0)
1722 (double) worker
->wi_cost_limit_base
/ worker
->wi_cost_delay
;
1724 worker
= (WorkerInfo
) SHMQueueNext(&AutoVacuumShmem
->av_runningWorkers
,
1726 offsetof(WorkerInfoData
, wi_links
));
1728 /* there are no cost limits -- nothing to do */
1729 if (cost_total
<= 0)
1733 * Adjust each cost limit of active workers to balance the total of cost
1734 * limit to autovacuum_vacuum_cost_limit.
1736 cost_avail
= (double) vac_cost_limit
/ vac_cost_delay
;
1737 worker
= (WorkerInfo
) SHMQueueNext(&AutoVacuumShmem
->av_runningWorkers
,
1738 &AutoVacuumShmem
->av_runningWorkers
,
1739 offsetof(WorkerInfoData
, wi_links
));
1742 if (worker
->wi_proc
!= NULL
&&
1743 worker
->wi_cost_limit_base
> 0 && worker
->wi_cost_delay
> 0)
1746 (cost_avail
* worker
->wi_cost_limit_base
/ cost_total
);
1749 * We put a lower bound of 1 to the cost_limit, to avoid division-
1750 * by-zero in the vacuum code.
1752 worker
->wi_cost_limit
= Max(Min(limit
, worker
->wi_cost_limit_base
), 1);
1754 elog(DEBUG2
, "autovac_balance_cost(pid=%u db=%u, rel=%u, cost_limit=%d, cost_delay=%d)",
1755 worker
->wi_proc
->pid
, worker
->wi_dboid
,
1756 worker
->wi_tableoid
, worker
->wi_cost_limit
, worker
->wi_cost_delay
);
1759 worker
= (WorkerInfo
) SHMQueueNext(&AutoVacuumShmem
->av_runningWorkers
,
1761 offsetof(WorkerInfoData
, wi_links
));
1768 * Return a list of all databases. Note we cannot use pg_database,
1769 * because we aren't connected; we use the flat database file.
1772 get_database_list(void)
1776 char thisname
[NAMEDATALEN
];
1780 TransactionId db_frozenxid
;
1782 filename
= database_getflatfilename();
1783 db_file
= AllocateFile(filename
, "r");
1784 if (db_file
== NULL
)
1786 (errcode_for_file_access(),
1787 errmsg("could not open file \"%s\": %m", filename
)));
1789 while (read_pg_database_line(db_file
, thisname
, &db_id
,
1790 &db_tablespace
, &db_frozenxid
))
1794 avdb
= (avw_dbase
*) palloc(sizeof(avw_dbase
));
1796 avdb
->adw_datid
= db_id
;
1797 avdb
->adw_name
= pstrdup(thisname
);
1798 avdb
->adw_frozenxid
= db_frozenxid
;
1799 /* this gets set later: */
1800 avdb
->adw_entry
= NULL
;
1802 dblist
= lappend(dblist
, avdb
);
1812 * Process a database table-by-table
1814 * Note that CHECK_FOR_INTERRUPTS is supposed to be used in certain spots in
1815 * order not to ignore shutdown commands for too long.
1823 HeapScanDesc relScan
;
1824 Form_pg_database dbForm
;
1825 List
*table_oids
= NIL
;
1826 List
*toast_oids
= NIL
;
1827 List
*table_toast_list
= NIL
;
1828 ListCell
*volatile cell
;
1829 PgStat_StatDBEntry
*shared
;
1830 PgStat_StatDBEntry
*dbentry
;
1831 BufferAccessStrategy bstrategy
;
1834 * StartTransactionCommand and CommitTransactionCommand will automatically
1835 * switch to other contexts. We need this one to keep the list of
1836 * relations to vacuum/analyze across transactions.
1838 AutovacMemCxt
= AllocSetContextCreate(TopMemoryContext
,
1840 ALLOCSET_DEFAULT_MINSIZE
,
1841 ALLOCSET_DEFAULT_INITSIZE
,
1842 ALLOCSET_DEFAULT_MAXSIZE
);
1843 MemoryContextSwitchTo(AutovacMemCxt
);
1846 * may be NULL if we couldn't find an entry (only happens if we are
1847 * forcing a vacuum for anti-wrap purposes).
1849 dbentry
= pgstat_fetch_stat_dbentry(MyDatabaseId
);
1851 /* Start a transaction so our commands have one to play into. */
1852 StartTransactionCommand();
1855 * Clean up any dead statistics collector entries for this DB. We always
1856 * want to do this exactly once per DB-processing cycle, even if we find
1857 * nothing worth vacuuming in the database.
1859 pgstat_vacuum_tabstat();
1862 * Find the pg_database entry and select the default freeze_min_age. We
1863 * use zero in template and nonconnectable databases, else the system-wide
1866 tuple
= SearchSysCache(DATABASEOID
,
1867 ObjectIdGetDatum(MyDatabaseId
),
1869 if (!HeapTupleIsValid(tuple
))
1870 elog(ERROR
, "cache lookup failed for database %u", MyDatabaseId
);
1871 dbForm
= (Form_pg_database
) GETSTRUCT(tuple
);
1873 if (dbForm
->datistemplate
|| !dbForm
->datallowconn
)
1874 default_freeze_min_age
= 0;
1876 default_freeze_min_age
= vacuum_freeze_min_age
;
1878 ReleaseSysCache(tuple
);
1880 /* StartTransactionCommand changed elsewhere */
1881 MemoryContextSwitchTo(AutovacMemCxt
);
1883 /* The database hash where pgstat keeps shared relations */
1884 shared
= pgstat_fetch_stat_dbentry(InvalidOid
);
1886 classRel
= heap_open(RelationRelationId
, AccessShareLock
);
1887 avRel
= heap_open(AutovacuumRelationId
, AccessShareLock
);
1890 * Scan pg_class and determine which tables to vacuum.
1892 * The stats subsystem collects stats for toast tables independently of
1893 * the stats for their parent tables. We need to check those stats since
1894 * in cases with short, wide tables there might be proportionally much
1895 * more activity in the toast table than in its parent.
1897 * Since we can only issue VACUUM against the parent table, we need to
1898 * transpose a decision to vacuum a toast table into a decision to vacuum
1899 * its parent. There's no point in considering ANALYZE on a toast table,
1900 * either. To support this, we keep a list of OIDs of toast tables that
1901 * need vacuuming alongside the list of regular tables. Regular tables
1902 * will be entered into the table list even if they appear not to need
1903 * vacuuming; we go back and re-mark them after finding all the vacuumable
1906 relScan
= heap_beginscan(classRel
, SnapshotNow
, 0, NULL
);
1908 while ((tuple
= heap_getnext(relScan
, ForwardScanDirection
)) != NULL
)
1910 Form_pg_class classForm
= (Form_pg_class
) GETSTRUCT(tuple
);
1911 Form_pg_autovacuum avForm
= NULL
;
1912 PgStat_StatTabEntry
*tabentry
;
1916 /* Consider only regular and toast tables. */
1917 if (classForm
->relkind
!= RELKIND_RELATION
&&
1918 classForm
->relkind
!= RELKIND_TOASTVALUE
)
1922 * Skip temp tables (i.e. those in temp namespaces). We cannot safely
1923 * process other backends' temp tables.
1925 if (isAnyTempNamespace(classForm
->relnamespace
))
1928 relid
= HeapTupleGetOid(tuple
);
1930 /* Fetch the pg_autovacuum tuple for the relation, if any */
1931 avTup
= get_pg_autovacuum_tuple_relid(avRel
, relid
);
1932 if (HeapTupleIsValid(avTup
))
1933 avForm
= (Form_pg_autovacuum
) GETSTRUCT(avTup
);
1935 /* Fetch the pgstat entry for this table */
1936 tabentry
= get_pgstat_tabentry_relid(relid
, classForm
->relisshared
,
1939 relation_check_autovac(relid
, classForm
, avForm
, tabentry
,
1940 &table_oids
, &table_toast_list
, &toast_oids
);
1942 if (HeapTupleIsValid(avTup
))
1943 heap_freetuple(avTup
);
1946 heap_endscan(relScan
);
1947 heap_close(avRel
, AccessShareLock
);
1948 heap_close(classRel
, AccessShareLock
);
1951 * Add to the list of tables to vacuum, the OIDs of the tables that
1952 * correspond to the saved OIDs of toast tables needing vacuum.
1954 foreach(cell
, toast_oids
)
1956 Oid toastoid
= lfirst_oid(cell
);
1959 foreach(cell2
, table_toast_list
)
1961 av_relation
*ar
= lfirst(cell2
);
1963 if (ar
->ar_toastrelid
== toastoid
)
1965 table_oids
= lappend_oid(table_oids
, ar
->ar_relid
);
1971 list_free_deep(table_toast_list
);
1972 table_toast_list
= NIL
;
1973 list_free(toast_oids
);
1977 * Create a buffer access strategy object for VACUUM to use. We want to
1978 * use the same one across all the vacuum operations we perform, since the
1979 * point is for VACUUM not to blow out the shared cache.
1981 bstrategy
= GetAccessStrategy(BAS_VACUUM
);
1984 * create a memory context to act as fake PortalContext, so that the
1985 * contexts created in the vacuum code are cleaned up for each table.
1987 PortalContext
= AllocSetContextCreate(AutovacMemCxt
,
1988 "Autovacuum Portal",
1989 ALLOCSET_DEFAULT_INITSIZE
,
1990 ALLOCSET_DEFAULT_MINSIZE
,
1991 ALLOCSET_DEFAULT_MAXSIZE
);
1994 * Perform operations on collected tables.
1996 foreach(cell
, table_oids
)
1998 Oid relid
= lfirst_oid(cell
);
2006 CHECK_FOR_INTERRUPTS();
2009 * hold schedule lock from here until we're sure that this table still
2010 * needs vacuuming. We also need the AutovacuumLock to walk the
2011 * worker array, but we'll let go of that one quickly.
2013 LWLockAcquire(AutovacuumScheduleLock
, LW_EXCLUSIVE
);
2014 LWLockAcquire(AutovacuumLock
, LW_SHARED
);
2017 * Check whether the table is being vacuumed concurrently by another
2021 worker
= (WorkerInfo
) SHMQueueNext(&AutoVacuumShmem
->av_runningWorkers
,
2022 &AutoVacuumShmem
->av_runningWorkers
,
2023 offsetof(WorkerInfoData
, wi_links
));
2027 if (worker
== MyWorkerInfo
)
2030 /* ignore workers in other databases */
2031 if (worker
->wi_dboid
!= MyDatabaseId
)
2034 if (worker
->wi_tableoid
== relid
)
2041 worker
= (WorkerInfo
) SHMQueueNext(&AutoVacuumShmem
->av_runningWorkers
,
2043 offsetof(WorkerInfoData
, wi_links
));
2045 LWLockRelease(AutovacuumLock
);
2048 LWLockRelease(AutovacuumScheduleLock
);
2053 * Check whether pgstat data still says we need to vacuum this table.
2054 * It could have changed if something else processed the table while
2055 * we weren't looking.
2057 * FIXME we ignore the possibility that the table was finished being
2058 * vacuumed in the last 500ms (PGSTAT_STAT_INTERVAL). This is a bug.
2060 MemoryContextSwitchTo(AutovacMemCxt
);
2061 tab
= table_recheck_autovac(relid
);
2064 /* someone else vacuumed the table */
2065 LWLockRelease(AutovacuumScheduleLock
);
2070 * Ok, good to go. Store the table in shared memory before releasing
2071 * the lock so that other workers don't vacuum it concurrently.
2073 MyWorkerInfo
->wi_tableoid
= relid
;
2074 LWLockRelease(AutovacuumScheduleLock
);
2076 /* Set the initial vacuum cost parameters for this table */
2077 VacuumCostDelay
= tab
->at_vacuum_cost_delay
;
2078 VacuumCostLimit
= tab
->at_vacuum_cost_limit
;
2080 /* Last fixups before actually starting to work */
2081 LWLockAcquire(AutovacuumLock
, LW_EXCLUSIVE
);
2083 /* advertise my cost delay parameters for the balancing algorithm */
2084 MyWorkerInfo
->wi_cost_delay
= tab
->at_vacuum_cost_delay
;
2085 MyWorkerInfo
->wi_cost_limit
= tab
->at_vacuum_cost_limit
;
2086 MyWorkerInfo
->wi_cost_limit_base
= tab
->at_vacuum_cost_limit
;
2089 autovac_balance_cost();
2092 LWLockRelease(AutovacuumLock
);
2094 /* clean up memory before each iteration */
2095 MemoryContextResetAndDeleteChildren(PortalContext
);
2098 * Save the relation name for a possible error message, to avoid a
2099 * catalog lookup in case of an error. Note: they must live in a
2100 * long-lived memory context because we call vacuum and analyze in
2101 * different transactions.
2103 datname
= get_database_name(MyDatabaseId
);
2104 nspname
= get_namespace_name(get_rel_namespace(tab
->at_relid
));
2105 relname
= get_rel_name(tab
->at_relid
);
2108 * We will abort vacuuming the current table if something errors out,
2109 * and continue with the next one in schedule; in particular, this
2110 * happens if we are interrupted with SIGINT.
2115 MemoryContextSwitchTo(TopTransactionContext
);
2116 autovacuum_do_vac_analyze(tab
->at_relid
,
2119 tab
->at_freeze_min_age
,
2124 * Clear a possible query-cancel signal, to avoid a late reaction
2125 * to an automatically-sent signal because of vacuuming the
2126 * current table (we're done with it, so it would make no sense to
2127 * cancel at this point.)
2129 QueryCancelPending
= false;
2134 * Abort the transaction, start a new one, and proceed with the
2135 * next table in our list.
2138 if (tab
->at_dovacuum
)
2139 errcontext("automatic vacuum of table \"%s.%s.%s\"",
2140 datname
, nspname
, relname
);
2142 errcontext("automatic analyze of table \"%s.%s.%s\"",
2143 datname
, nspname
, relname
);
2146 /* this resets the PGPROC flags too */
2147 AbortOutOfAnyTransaction();
2149 MemoryContextResetAndDeleteChildren(PortalContext
);
2151 /* restart our transaction for the following operations */
2152 StartTransactionCommand();
2153 RESUME_INTERRUPTS();
2157 /* the PGPROC flags are reset at the next end of transaction */
2165 /* remove my info from shared memory */
2166 LWLockAcquire(AutovacuumLock
, LW_EXCLUSIVE
);
2167 MyWorkerInfo
->wi_tableoid
= InvalidOid
;
2168 LWLockRelease(AutovacuumLock
);
2172 * Update pg_database.datfrozenxid, and truncate pg_clog if possible. We
2173 * only need to do this once, not after each table.
2175 vac_update_datfrozenxid();
2177 /* Finally close out the last transaction. */
2178 CommitTransactionCommand();
2182 * Returns a copy of the pg_autovacuum tuple for the given relid, or NULL if
2183 * there isn't any. avRel is pg_autovacuum, already open and suitably locked.
2186 get_pg_autovacuum_tuple_relid(Relation avRel
, Oid relid
)
2188 ScanKeyData entry
[1];
2192 ScanKeyInit(&entry
[0],
2193 Anum_pg_autovacuum_vacrelid
,
2194 BTEqualStrategyNumber
, F_OIDEQ
,
2195 ObjectIdGetDatum(relid
));
2197 avScan
= systable_beginscan(avRel
, AutovacuumRelidIndexId
, true,
2198 SnapshotNow
, 1, entry
);
2200 avTup
= systable_getnext(avScan
);
2202 if (HeapTupleIsValid(avTup
))
2203 avTup
= heap_copytuple(avTup
);
2205 systable_endscan(avScan
);
2211 * get_pgstat_tabentry_relid
2213 * Fetch the pgstat entry of a table, either local to a database or shared.
2215 static PgStat_StatTabEntry
*
2216 get_pgstat_tabentry_relid(Oid relid
, bool isshared
, PgStat_StatDBEntry
*shared
,
2217 PgStat_StatDBEntry
*dbentry
)
2219 PgStat_StatTabEntry
*tabentry
= NULL
;
2223 if (PointerIsValid(shared
))
2224 tabentry
= hash_search(shared
->tables
, &relid
,
2227 else if (PointerIsValid(dbentry
))
2228 tabentry
= hash_search(dbentry
->tables
, &relid
,
2235 * relation_check_autovac
2237 * For a given relation (either a plain table or TOAST table), check whether it
2238 * needs vacuum or analyze.
2240 * Plain tables that need either are added to the table_list. TOAST tables
2241 * that need vacuum are added to toast_list. Plain tables that don't need
2242 * either but which have a TOAST table are added, as a struct, to
2243 * table_toast_list. The latter is to allow appending the OIDs of the plain
2244 * tables whose TOAST table needs vacuuming into the plain tables list, which
2245 * allows us to substantially reduce the number of "rechecks" that we need to
2249 relation_check_autovac(Oid relid
, Form_pg_class classForm
,
2250 Form_pg_autovacuum avForm
, PgStat_StatTabEntry
*tabentry
,
2251 List
**table_oids
, List
**table_toast_list
,
2258 relation_needs_vacanalyze(relid
, avForm
, classForm
, tabentry
,
2259 &dovacuum
, &doanalyze
, &dummy
);
2261 if (classForm
->relkind
== RELKIND_TOASTVALUE
)
2264 *toast_oids
= lappend_oid(*toast_oids
, relid
);
2268 Assert(classForm
->relkind
== RELKIND_RELATION
);
2270 if (dovacuum
|| doanalyze
)
2271 *table_oids
= lappend_oid(*table_oids
, relid
);
2272 else if (OidIsValid(classForm
->reltoastrelid
))
2274 av_relation
*rel
= palloc(sizeof(av_relation
));
2276 rel
->ar_relid
= relid
;
2277 rel
->ar_toastrelid
= classForm
->reltoastrelid
;
2279 *table_toast_list
= lappend(*table_toast_list
, rel
);
2285 * table_recheck_autovac
2287 * Recheck whether a plain table still needs vacuum or analyze; be it because
2288 * it does directly, or because its TOAST table does. Return value is a valid
2289 * autovac_table pointer if it does, NULL otherwise.
2291 static autovac_table
*
2292 table_recheck_autovac(Oid relid
)
2294 Form_pg_autovacuum avForm
= NULL
;
2295 Form_pg_class classForm
;
2301 autovac_table
*tab
= NULL
;
2302 PgStat_StatTabEntry
*tabentry
;
2304 PgStat_StatDBEntry
*shared
;
2305 PgStat_StatDBEntry
*dbentry
;
2307 toast_wraparound
= false;
2309 /* use fresh stats */
2310 autovac_refresh_stats();
2312 shared
= pgstat_fetch_stat_dbentry(InvalidOid
);
2313 dbentry
= pgstat_fetch_stat_dbentry(MyDatabaseId
);
2315 /* fetch the relation's relcache entry */
2316 classTup
= SearchSysCacheCopy(RELOID
,
2317 ObjectIdGetDatum(relid
),
2319 if (!HeapTupleIsValid(classTup
))
2321 classForm
= (Form_pg_class
) GETSTRUCT(classTup
);
2323 /* fetch the pg_autovacuum entry, if any */
2324 avRel
= heap_open(AutovacuumRelationId
, AccessShareLock
);
2325 avTup
= get_pg_autovacuum_tuple_relid(avRel
, relid
);
2326 if (HeapTupleIsValid(avTup
))
2327 avForm
= (Form_pg_autovacuum
) GETSTRUCT(avTup
);
2329 /* fetch the pgstat table entry */
2330 tabentry
= get_pgstat_tabentry_relid(relid
, classForm
->relisshared
,
2333 relation_needs_vacanalyze(relid
, avForm
, classForm
, tabentry
,
2334 &dovacuum
, &doanalyze
, &wraparound
);
2336 /* OK, it needs vacuum by itself */
2339 /* it doesn't need vacuum, but what about it's TOAST table? */
2340 else if (OidIsValid(classForm
->reltoastrelid
))
2342 Oid toastrelid
= classForm
->reltoastrelid
;
2343 HeapTuple toastClassTup
;
2345 toastClassTup
= SearchSysCacheCopy(RELOID
,
2346 ObjectIdGetDatum(toastrelid
),
2348 if (HeapTupleIsValid(toastClassTup
))
2350 bool toast_dovacuum
;
2351 bool toast_doanalyze
;
2352 bool toast_wraparound
;
2353 Form_pg_class toastClassForm
;
2354 PgStat_StatTabEntry
*toasttabentry
;
2356 toastClassForm
= (Form_pg_class
) GETSTRUCT(toastClassTup
);
2357 toasttabentry
= get_pgstat_tabentry_relid(toastrelid
,
2358 toastClassForm
->relisshared
,
2361 /* note we use the pg_autovacuum entry for the main table */
2362 relation_needs_vacanalyze(toastrelid
, avForm
,
2363 toastClassForm
, toasttabentry
,
2364 &toast_dovacuum
, &toast_doanalyze
,
2366 /* we only consider VACUUM for toast tables */
2373 heap_freetuple(toastClassTup
);
2387 * Calculate the vacuum cost parameters and the minimum freeze age. If
2388 * there is a tuple in pg_autovacuum, use it; else, use the GUC
2389 * defaults. Note that the fields may contain "-1" (or indeed any
2390 * negative value), which means use the GUC defaults for each setting.
2391 * In cost_limit, the value 0 also means to use the value from
2396 vac_cost_limit
= (avForm
->vac_cost_limit
> 0) ?
2397 avForm
->vac_cost_limit
:
2398 ((autovacuum_vac_cost_limit
> 0) ?
2399 autovacuum_vac_cost_limit
: VacuumCostLimit
);
2401 vac_cost_delay
= (avForm
->vac_cost_delay
>= 0) ?
2402 avForm
->vac_cost_delay
:
2403 ((autovacuum_vac_cost_delay
>= 0) ?
2404 autovacuum_vac_cost_delay
: VacuumCostDelay
);
2406 freeze_min_age
= (avForm
->freeze_min_age
>= 0) ?
2407 avForm
->freeze_min_age
: default_freeze_min_age
;
2411 vac_cost_limit
= (autovacuum_vac_cost_limit
> 0) ?
2412 autovacuum_vac_cost_limit
: VacuumCostLimit
;
2414 vac_cost_delay
= (autovacuum_vac_cost_delay
>= 0) ?
2415 autovacuum_vac_cost_delay
: VacuumCostDelay
;
2417 freeze_min_age
= default_freeze_min_age
;
2420 tab
= palloc(sizeof(autovac_table
));
2421 tab
->at_relid
= relid
;
2422 tab
->at_dovacuum
= dovacuum
;
2423 tab
->at_doanalyze
= doanalyze
;
2424 tab
->at_freeze_min_age
= freeze_min_age
;
2425 tab
->at_vacuum_cost_limit
= vac_cost_limit
;
2426 tab
->at_vacuum_cost_delay
= vac_cost_delay
;
2427 tab
->at_wraparound
= wraparound
|| toast_wraparound
;
2430 heap_close(avRel
, AccessShareLock
);
2431 if (HeapTupleIsValid(avTup
))
2432 heap_freetuple(avTup
);
2433 heap_freetuple(classTup
);
2439 * relation_needs_vacanalyze
2441 * Check whether a relation needs to be vacuumed or analyzed; return each into
2442 * "dovacuum" and "doanalyze", respectively. Also return whether the vacuum is
2443 * being forced because of Xid wraparound. avForm and tabentry can be NULL,
2444 * classForm shouldn't.
2446 * A table needs to be vacuumed if the number of dead tuples exceeds a
2447 * threshold. This threshold is calculated as
2449 * threshold = vac_base_thresh + vac_scale_factor * reltuples
2451 * For analyze, the analysis done is that the number of tuples inserted,
2452 * deleted and updated since the last analyze exceeds a threshold calculated
2453 * in the same fashion as above. Note that the collector actually stores
2454 * the number of tuples (both live and dead) that there were as of the last
2455 * analyze. This is asymmetric to the VACUUM case.
2457 * We also force vacuum if the table's relfrozenxid is more than freeze_max_age
2458 * transactions back.
2460 * A table whose pg_autovacuum.enabled value is false, is automatically
2461 * skipped (unless we have to vacuum it due to freeze_max_age). Thus
2462 * autovacuum can be disabled for specific tables. Also, when the stats
2463 * collector does not have data about a table, it will be skipped.
2465 * A table whose vac_base_thresh value is <0 takes the base value from the
2466 * autovacuum_vacuum_threshold GUC variable. Similarly, a vac_scale_factor
2467 * value <0 is substituted with the value of
2468 * autovacuum_vacuum_scale_factor GUC variable. Ditto for analyze.
2471 relation_needs_vacanalyze(Oid relid
,
2472 Form_pg_autovacuum avForm
,
2473 Form_pg_class classForm
,
2474 PgStat_StatTabEntry
*tabentry
,
2475 /* output params below */
2481 float4 reltuples
; /* pg_class.reltuples */
2483 /* constants from pg_autovacuum or GUC variables */
2484 int vac_base_thresh
,
2486 float4 vac_scale_factor
,
2489 /* thresholds calculated from above constants */
2493 /* number of vacuum (resp. analyze) tuples at this time */
2497 /* freeze parameters */
2499 TransactionId xidForceLimit
;
2501 AssertArg(classForm
!= NULL
);
2502 AssertArg(OidIsValid(relid
));
2505 * Determine vacuum/analyze equation parameters. If there is a tuple in
2506 * pg_autovacuum, use it; else, use the GUC defaults. Note that the
2507 * fields may contain "-1" (or indeed any negative value), which means use
2508 * the GUC defaults for each setting.
2512 vac_scale_factor
= (avForm
->vac_scale_factor
>= 0) ?
2513 avForm
->vac_scale_factor
: autovacuum_vac_scale
;
2514 vac_base_thresh
= (avForm
->vac_base_thresh
>= 0) ?
2515 avForm
->vac_base_thresh
: autovacuum_vac_thresh
;
2517 anl_scale_factor
= (avForm
->anl_scale_factor
>= 0) ?
2518 avForm
->anl_scale_factor
: autovacuum_anl_scale
;
2519 anl_base_thresh
= (avForm
->anl_base_thresh
>= 0) ?
2520 avForm
->anl_base_thresh
: autovacuum_anl_thresh
;
2522 freeze_max_age
= (avForm
->freeze_max_age
>= 0) ?
2523 Min(avForm
->freeze_max_age
, autovacuum_freeze_max_age
) :
2524 autovacuum_freeze_max_age
;
2528 vac_scale_factor
= autovacuum_vac_scale
;
2529 vac_base_thresh
= autovacuum_vac_thresh
;
2531 anl_scale_factor
= autovacuum_anl_scale
;
2532 anl_base_thresh
= autovacuum_anl_thresh
;
2534 freeze_max_age
= autovacuum_freeze_max_age
;
2537 /* Force vacuum if table is at risk of wraparound */
2538 xidForceLimit
= recentXid
- freeze_max_age
;
2539 if (xidForceLimit
< FirstNormalTransactionId
)
2540 xidForceLimit
-= FirstNormalTransactionId
;
2541 force_vacuum
= (TransactionIdIsNormal(classForm
->relfrozenxid
) &&
2542 TransactionIdPrecedes(classForm
->relfrozenxid
,
2544 *wraparound
= force_vacuum
;
2546 /* User disabled it in pg_autovacuum? (But ignore if at risk) */
2547 if (avForm
&& !avForm
->enabled
&& !force_vacuum
)
2554 if (PointerIsValid(tabentry
))
2556 reltuples
= classForm
->reltuples
;
2557 vactuples
= tabentry
->n_dead_tuples
;
2558 anltuples
= tabentry
->n_live_tuples
+ tabentry
->n_dead_tuples
-
2559 tabentry
->last_anl_tuples
;
2561 vacthresh
= (float4
) vac_base_thresh
+ vac_scale_factor
* reltuples
;
2562 anlthresh
= (float4
) anl_base_thresh
+ anl_scale_factor
* reltuples
;
2565 * Note that we don't need to take special consideration for stat
2566 * reset, because if that happens, the last vacuum and analyze counts
2567 * will be reset too.
2569 elog(DEBUG3
, "%s: vac: %.0f (threshold %.0f), anl: %.0f (threshold %.0f)",
2570 NameStr(classForm
->relname
),
2571 vactuples
, vacthresh
, anltuples
, anlthresh
);
2573 /* Determine if this table needs vacuum or analyze. */
2574 *dovacuum
= force_vacuum
|| (vactuples
> vacthresh
);
2575 *doanalyze
= (anltuples
> anlthresh
);
2580 * Skip a table not found in stat hash, unless we have to force vacuum
2581 * for anti-wrap purposes. If it's not acted upon, there's no need to
2584 *dovacuum
= force_vacuum
;
2588 /* ANALYZE refuses to work with pg_statistics */
2589 if (relid
== StatisticRelationId
)
2594 * autovacuum_do_vac_analyze
2595 * Vacuum and/or analyze the specified table
2598 autovacuum_do_vac_analyze(Oid relid
, bool dovacuum
, bool doanalyze
,
2599 int freeze_min_age
, bool for_wraparound
,
2600 BufferAccessStrategy bstrategy
)
2604 MemoryContext old_cxt
;
2606 /* Set up command parameters --- use a local variable instead of palloc */
2607 MemSet(&vacstmt
, 0, sizeof(vacstmt
));
2609 vacstmt
.type
= T_VacuumStmt
;
2610 vacstmt
.vacuum
= dovacuum
;
2611 vacstmt
.full
= false;
2612 vacstmt
.analyze
= doanalyze
;
2613 vacstmt
.freeze_min_age
= freeze_min_age
;
2614 vacstmt
.verbose
= false;
2615 vacstmt
.relation
= NULL
; /* not used since we pass a relids list */
2616 vacstmt
.va_cols
= NIL
;
2619 * The list must survive transaction boundaries, so make sure we create it
2620 * in a long-lived context
2622 old_cxt
= MemoryContextSwitchTo(AutovacMemCxt
);
2623 relids
= list_make1_oid(relid
);
2624 MemoryContextSwitchTo(old_cxt
);
2626 /* Let pgstat know what we're doing */
2627 autovac_report_activity(&vacstmt
, relid
);
2629 vacuum(&vacstmt
, relids
, bstrategy
, for_wraparound
, true);
2633 * autovac_report_activity
2634 * Report to pgstat what autovacuum is doing
2636 * We send a SQL string corresponding to what the user would see if the
2637 * equivalent command was to be issued manually.
2639 * Note we assume that we are going to report the next command as soon as we're
2640 * done with the current one, and exit right after the last one, so we don't
2641 * bother to report "<IDLE>" or some such.
2644 autovac_report_activity(VacuumStmt
*vacstmt
, Oid relid
)
2646 char *relname
= get_rel_name(relid
);
2647 char *nspname
= get_namespace_name(get_rel_namespace(relid
));
2649 #define MAX_AUTOVAC_ACTIV_LEN (NAMEDATALEN * 2 + 32)
2650 char activity
[MAX_AUTOVAC_ACTIV_LEN
];
2652 /* Report the command and possible options */
2653 if (vacstmt
->vacuum
)
2654 snprintf(activity
, MAX_AUTOVAC_ACTIV_LEN
,
2655 "autovacuum: VACUUM%s",
2656 vacstmt
->analyze
? " ANALYZE" : "");
2658 snprintf(activity
, MAX_AUTOVAC_ACTIV_LEN
,
2659 "autovacuum: ANALYZE");
2662 * Report the qualified name of the relation.
2664 * Paranoia is appropriate here in case relation was recently dropped ---
2665 * the lsyscache routines we just invoked will return NULL rather than
2668 if (relname
&& nspname
)
2670 int len
= strlen(activity
);
2672 snprintf(activity
+ len
, MAX_AUTOVAC_ACTIV_LEN
- len
,
2673 " %s.%s", nspname
, relname
);
2676 /* Set statement_timestamp() to current time for pg_stat_activity */
2677 SetCurrentStatementStartTimestamp();
2679 pgstat_report_activity(activity
);
2683 * AutoVacuumingActive
2684 * Check GUC vars and report whether the autovacuum process should be
2688 AutoVacuumingActive(void)
2690 if (!autovacuum_start_daemon
|| !pgstat_track_counts
)
2697 * This is called at postmaster initialization.
2699 * All we do here is annoy the user if he got it wrong.
2704 if (autovacuum_start_daemon
&& !pgstat_track_counts
)
2706 (errmsg("autovacuum not started because of misconfiguration"),
2707 errhint("Enable the \"track_counts\" option.")));
2711 * IsAutoVacuum functions
2712 * Return whether this is either a launcher autovacuum process or a worker
2716 IsAutoVacuumLauncherProcess(void)
2718 return am_autovacuum_launcher
;
2722 IsAutoVacuumWorkerProcess(void)
2724 return am_autovacuum_worker
;
2729 * AutoVacuumShmemSize
2730 * Compute space needed for autovacuum-related shared memory
2733 AutoVacuumShmemSize(void)
2738 * Need the fixed struct and the array of WorkerInfoData.
2740 size
= sizeof(AutoVacuumShmemStruct
);
2741 size
= MAXALIGN(size
);
2742 size
= add_size(size
, mul_size(autovacuum_max_workers
,
2743 sizeof(WorkerInfoData
)));
2748 * AutoVacuumShmemInit
2749 * Allocate and initialize autovacuum-related shared memory
2752 AutoVacuumShmemInit(void)
2756 AutoVacuumShmem
= (AutoVacuumShmemStruct
*)
2757 ShmemInitStruct("AutoVacuum Data",
2758 AutoVacuumShmemSize(),
2760 if (AutoVacuumShmem
== NULL
)
2762 (errcode(ERRCODE_OUT_OF_MEMORY
),
2763 errmsg("not enough shared memory for autovacuum")));
2765 if (!IsUnderPostmaster
)
2772 AutoVacuumShmem
->av_launcherpid
= 0;
2773 AutoVacuumShmem
->av_freeWorkers
= INVALID_OFFSET
;
2774 SHMQueueInit(&AutoVacuumShmem
->av_runningWorkers
);
2775 AutoVacuumShmem
->av_startingWorker
= INVALID_OFFSET
;
2777 worker
= (WorkerInfo
) ((char *) AutoVacuumShmem
+
2778 MAXALIGN(sizeof(AutoVacuumShmemStruct
)));
2780 /* initialize the WorkerInfo free list */
2781 for (i
= 0; i
< autovacuum_max_workers
; i
++)
2783 worker
[i
].wi_links
.next
= AutoVacuumShmem
->av_freeWorkers
;
2784 AutoVacuumShmem
->av_freeWorkers
= MAKE_OFFSET(&worker
[i
]);
2792 * autovac_refresh_stats
2793 * Refresh pgstats data for an autovacuum process
2795 * Cause the next pgstats read operation to obtain fresh data, but throttle
2796 * such refreshing in the autovacuum launcher. This is mostly to avoid
2797 * rereading the pgstats files too many times in quick succession when there
2798 * are many databases.
2800 * Note: we avoid throttling in the autovac worker, as it would be
2801 * counterproductive in the recheck logic.
2804 autovac_refresh_stats(void)
2806 if (IsAutoVacuumLauncherProcess())
2808 static TimestampTz last_read
= 0;
2809 TimestampTz current_time
;
2811 current_time
= GetCurrentTimestamp();
2813 if (!TimestampDifferenceExceeds(last_read
, current_time
,
2817 last_read
= current_time
;
2820 pgstat_clear_snapshot();