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-2009, 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/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"
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"
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
;
154 /* struct to keep track of databases in worker */
155 typedef struct avw_dbase
159 TransactionId adw_frozenxid
;
160 PgStat_StatDBEntry
*adw_entry
;
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 */
169 AutoVacOpts ar_reloptions
; /* copy of AutoVacOpts from the main table's
170 reloptions, or NULL if none */
173 /* struct to keep track of tables to vacuum and/or analyze, after rechecking */
174 typedef struct autovac_table
179 int at_freeze_min_age
;
180 int at_freeze_table_age
;
181 int at_vacuum_cost_delay
;
182 int at_vacuum_cost_limit
;
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).
206 typedef struct WorkerInfoData
212 TimestampTz wi_launchtime
;
215 int wi_cost_limit_base
;
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
227 AutoVacForkFailed
, /* failed trying to start a worker */
228 AutoVacRebalance
, /* rebalance the cost limits */
229 AutoVacNumSignals
/* must be last */
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).
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;
269 static pid_t
avlauncher_forkexec(void);
270 static pid_t
avworker_forkexec(void);
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 ********************************************************************/
316 * forkexec routine for the autovacuum launcher process.
318 * Format up the arglist, then fork and exec.
321 avlauncher_forkexec(void)
326 av
[ac
++] = "postgres";
327 av
[ac
++] = "--forkavlauncher";
328 av
[ac
++] = NULL
; /* filled in by postmaster_forkexec */
331 Assert(ac
< lengthof(av
));
333 return postmaster_forkexec(ac
, av
);
337 * We need this set from the outside, before InitProcess is called
340 AutovacuumLauncherIAm(void)
342 am_autovacuum_launcher
= true;
347 * Main entry point for autovacuum launcher process, to be called from the
351 StartAutoVacLauncher(void)
356 switch ((AutoVacPID
= avlauncher_forkexec()))
358 switch ((AutoVacPID
= fork_process()))
363 (errmsg("could not fork autovacuum launcher process: %m")));
368 /* in postmaster child ... */
369 /* Close the postmaster's sockets */
370 ClosePostmasterPorts(false);
372 /* Lose the postmaster's on-exit routines */
375 AutoVacLauncherMain(0, NULL
);
379 return (int) AutoVacPID
;
382 /* shouldn't get here */
387 * Main loop for the autovacuum launcher process.
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", "", "", "");
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.)
420 elog(FATAL
, "setsid() failed: %m");
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 */
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).
452 InitAuxiliaryProcess();
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 */
481 /* Report the error to the server log */
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.
491 AtEOXact_HashTables(false);
494 * Now return to normal top-level context and clear ErrorContext for
497 MemoryContextSwitchTo(AutovacMemCxt
);
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
;
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 */
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.
523 /* We can now handle ereport(ERROR) */
524 PG_exception_stack
= &local_sigjmp_buf
;
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())
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
);
553 TimestampTz current_time
= 0;
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))
564 launcher_determine_sleep((AutoVacuumShmem
->av_freeWorkers
!= NULL
),
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
575 while (nap
.tv_sec
> 0 || nap
.tv_usec
> 0)
586 sleeptime
= nap
.tv_usec
;
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))
598 if (got_SIGTERM
|| got_SIGHUP
|| got_SIGUSR1
)
602 /* the normal shutdown case */
609 ProcessConfigFile(PGC_SIGHUP
);
611 /* shutdown requested in config file */
612 if (!AutoVacuumingActive())
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
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
);
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
)
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
,
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");
721 LWLockRelease(AutovacuumLock
); /* either shared or exclusive */
723 /* if we can't do anything, just go back to sleep */
727 /* We're OK to start a new worker */
729 elem
= DLGetTail(DatabaseList
);
732 avl_dbase
*avdb
= DLE_VAL(elem
);
735 * launch a worker if next_worker is right now or it is in the
738 if (TimestampDifferenceExceeds(avdb
->adl_next_worker
,
740 launch_worker(current_time
);
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
752 launch_worker(current_time
);
756 /* Normal exit from the autovac launcher is here */
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.
772 launcher_determine_sleep(bool canlaunch
, bool recursing
, struct timeval
* nap
)
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.
784 nap
->tv_sec
= autovacuum_naptime
;
787 else if ((elem
= DLGetTail(DatabaseList
)) != NULL
)
789 avl_dbase
*avdb
= DLE_VAL(elem
);
790 TimestampTz current_time
= GetCurrentTimestamp();
791 TimestampTz next_wakeup
;
795 next_wakeup
= avdb
->adl_next_worker
;
796 TimestampDifference(current_time
, next_wakeup
, &secs
, &usecs
);
799 nap
->tv_usec
= usecs
;
803 /* list is empty, sleep for whole autovacuum_naptime seconds */
804 nap
->tv_sec
= autovacuum_naptime
;
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
);
825 /* 100ms is the smallest time we'll allow the launcher to sleep */
826 if (nap
->tv_sec
<= 0 && nap
->tv_usec
<= 100000)
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
847 rebuild_database_list(Oid newdb
)
851 MemoryContext newcxt
;
852 MemoryContext oldcxt
;
853 MemoryContext tmpcxt
;
859 /* use fresh stats */
860 autovac_refresh_stats();
862 newcxt
= AllocSetContextCreate(AutovacMemCxt
,
864 ALLOCSET_DEFAULT_MINSIZE
,
865 ALLOCSET_DEFAULT_INITSIZE
,
866 ALLOCSET_DEFAULT_MAXSIZE
);
867 tmpcxt
= AllocSetContextCreate(newcxt
,
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
890 hctl
.keysize
= sizeof(Oid
);
891 hctl
.entrysize
= sizeof(avl_dbase
);
892 hctl
.hash
= oid_hash
;
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 */
899 if (OidIsValid(newdb
))
902 PgStat_StatDBEntry
*entry
;
904 /* only consider this database if it has a pgstat entry */
905 entry
= pgstat_fetch_stat_dbentry(newdb
);
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
)
922 elem
= DLGetHead(DatabaseList
);
925 avl_dbase
*avdb
= DLE_VAL(elem
);
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
);
940 db
= hash_search(dbhash
, &(avdb
->adl_datid
), HASH_ENTER
, &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
);
958 PgStat_StatDBEntry
*entry
;
960 /* only consider databases with a pgstat entry */
961 entry
= pgstat_fetch_stat_dbentry(avdb
->adw_datid
);
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 */
969 /* hash_search already filled in the key */
970 db
->adl_score
= score
++;
971 /* next_worker is filled in later */
976 /* from here on, the allocated memory belongs to the new list */
977 MemoryContextSwitchTo(newcxt
);
978 DatabaseList
= DLNewList();
982 TimestampTz current_time
;
983 int millis_increment
;
989 /* put all the hash elements into an array */
990 dbary
= palloc(nelems
* sizeof(avl_dbase
));
993 hash_seq_init(&seq
, dbhash
);
994 while ((db
= hash_seq_search(&seq
)) != NULL
)
995 memcpy(&(dbary
[i
++]), db
, sizeof(avl_dbase
));
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
]);
1013 current_time
= TimestampTzPlusMilliseconds(current_time
,
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 */
1033 db_comparator(const void *a
, const void *b
)
1035 if (((avl_dbase
*) a
)->adl_score
== ((avl_dbase
*) b
)->adl_score
)
1038 return (((avl_dbase
*) a
)->adl_score
< ((avl_dbase
*) b
)->adl_score
) ? 1 : -1;
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.
1053 do_start_worker(void)
1057 TransactionId xidForceLimit
;
1060 TimestampTz current_time
;
1061 bool skipit
= false;
1062 Oid retval
= InvalidOid
;
1063 MemoryContext tmpcxt
,
1066 /* return quickly when there are no free workers */
1067 LWLockAcquire(AutovacuumLock
, LW_SHARED
);
1068 if (AutoVacuumShmem
->av_freeWorkers
== NULL
)
1070 LWLockRelease(AutovacuumLock
);
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
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
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.
1123 for_xid_wrap
= false;
1124 current_time
= GetCurrentTimestamp();
1125 foreach(cell
, dblist
)
1127 avw_dbase
*tmp
= lfirst(cell
);
1130 /* Check to see if this one is at risk of wraparound */
1131 if (TransactionIdPrecedes(tmp
->adw_frozenxid
, xidForceLimit
))
1134 TransactionIdPrecedes(tmp
->adw_frozenxid
, avdb
->adw_frozenxid
))
1136 for_xid_wrap
= true;
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
1149 if (!tmp
->adw_entry
)
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.
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
,
1174 !TimestampDifferenceExceeds(current_time
,
1175 dbp
->adl_next_worker
,
1176 autovacuum_naptime
* 1000))
1181 elem
= DLGetPred(elem
);
1187 * Remember the db with oldest autovac time. (If we are here, both
1188 * tmp->entry and db->entry must be non-null.)
1191 tmp
->adw_entry
->last_autovac_time
< avdb
->adw_entry
->last_autovac_time
)
1195 /* Found a database -- process it */
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
1207 worker
= AutoVacuumShmem
->av_freeWorkers
;
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
;
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
);
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.
1252 launch_worker(TimestampTz now
)
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
);
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.
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.
1302 AutoVacWorkerFailed(void)
1304 AutoVacuumShmem
->av_signal
[AutoVacForkFailed
] = true;
1307 /* SIGHUP: set flag to re-read config file at next convenient time */
1309 avl_sighup_handler(SIGNAL_ARGS
)
1314 /* SIGUSR1: a worker is up and running, or just finished */
1316 avl_sigusr1_handler(SIGNAL_ARGS
)
1321 /* SIGTERM: time to die */
1323 avl_sigterm_handler(SIGNAL_ARGS
)
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
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.
1353 /********************************************************************
1354 * AUTOVACUUM WORKER CODE
1355 ********************************************************************/
1359 * forkexec routines for the autovacuum worker.
1361 * Format up the arglist, then fork and exec.
1364 avworker_forkexec(void)
1369 av
[ac
++] = "postgres";
1370 av
[ac
++] = "--forkavworker";
1371 av
[ac
++] = NULL
; /* filled in by postmaster_forkexec */
1374 Assert(ac
< lengthof(av
));
1376 return postmaster_forkexec(ac
, av
);
1380 * We need this set from the outside, before InitProcess is called
1383 AutovacuumWorkerIAm(void)
1385 am_autovacuum_worker
= true;
1390 * Main entry point for autovacuum worker process.
1392 * This code is heavily based on pgarch.c, q.v.
1395 StartAutoVacWorker(void)
1400 switch ((worker_pid
= avworker_forkexec()))
1402 switch ((worker_pid
= fork_process()))
1407 (errmsg("could not fork autovacuum worker process: %m")));
1410 #ifndef EXEC_BACKEND
1412 /* in postmaster child ... */
1413 /* Close the postmaster's sockets */
1414 ClosePostmasterPorts(false);
1416 /* Lose the postmaster's on-exit routines */
1419 AutoVacWorkerMain(0, NULL
);
1423 return (int) worker_pid
;
1426 /* shouldn't get here */
1433 NON_EXEC_STATIC
void
1434 AutoVacWorkerMain(int argc
, char *argv
[])
1436 sigjmp_buf local_sigjmp_buf
;
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.)
1462 elog(FATAL
, "setsid() failed: %m");
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
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 */
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
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 */
1514 /* Report the error to the server log */
1518 * We can now go away. Note that because we called InitProcess, a
1519 * callback was registered to do ProcKill, which will clean up
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
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
);
1579 /* no worker entry for me, go away */
1580 elog(WARNING
, "autovacuum worker started without a worker entry");
1582 LWLockRelease(AutovacuumLock
);
1585 if (OidIsValid(dbid
))
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
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);
1609 (errmsg("autovacuum: processing database \"%s\"", dbname
)));
1612 pg_usleep(PostAuthDelay
* 1000000L);
1614 /* And do an appropriate amount of work */
1615 recentXid
= ReadNewTransactionId();
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 */
1629 * Return a WorkerInfo to the free list
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
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.
1679 AutoVacuumUpdateDelay(void)
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.
1695 autovac_balance_cost(void)
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
);
1710 /* not set? nothing to do */
1711 if (vac_cost_limit
<= 0 || vac_cost_delay
<= 0)
1714 /* caculate the total base cost limit of active workers */
1716 worker
= (WorkerInfo
) SHMQueueNext(&AutoVacuumShmem
->av_runningWorkers
,
1717 &AutoVacuumShmem
->av_runningWorkers
,
1718 offsetof(WorkerInfoData
, wi_links
));
1721 if (worker
->wi_proc
!= NULL
&&
1722 worker
->wi_cost_limit_base
> 0 && worker
->wi_cost_delay
> 0)
1724 (double) worker
->wi_cost_limit_base
/ worker
->wi_cost_delay
;
1726 worker
= (WorkerInfo
) SHMQueueNext(&AutoVacuumShmem
->av_runningWorkers
,
1728 offsetof(WorkerInfoData
, wi_links
));
1730 /* there are no cost limits -- nothing to do */
1731 if (cost_total
<= 0)
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
));
1744 if (worker
->wi_proc
!= NULL
&&
1745 worker
->wi_cost_limit_base
> 0 && worker
->wi_cost_delay
> 0)
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
,
1763 offsetof(WorkerInfoData
, wi_links
));
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.
1774 get_database_list(void)
1778 char thisname
[NAMEDATALEN
];
1782 TransactionId db_frozenxid
;
1784 filename
= database_getflatfilename();
1785 db_file
= AllocateFile(filename
, "r");
1786 if (db_file
== NULL
)
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
))
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
);
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.
1824 HeapScanDesc relScan
;
1825 Form_pg_database dbForm
;
1826 List
*table_oids
= NIL
;
1828 HTAB
*table_toast_map
;
1829 ListCell
*volatile cell
;
1830 PgStat_StatDBEntry
*shared
;
1831 PgStat_StatDBEntry
*dbentry
;
1832 BufferAccessStrategy bstrategy
;
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
,
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
1869 tuple
= SearchSysCache(DATABASEOID
,
1870 ObjectIdGetDatum(MyDatabaseId
),
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;
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",
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.
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
;
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
,
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
);
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
1977 ObjectAddress object
;
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
);
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
))));
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
;
2015 hentry
= hash_search(table_toast_map
,
2016 &classForm
->reltoastrelid
,
2017 HASH_ENTER
, &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 */
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
;
2049 AutoVacOpts
*relopts
= NULL
;
2055 * Skip temp tables (i.e. those in temp namespaces). We cannot safely
2056 * process other backends' temp tables.
2058 if (isAnyTempNamespace(classForm
->relnamespace
))
2061 relid
= HeapTupleGetOid(tuple
);
2064 * fetch reloptions -- if this toast table does not have them,
2067 relopts
= extract_autovac_opts(tuple
, pg_class_desc
);
2068 if (relopts
== NULL
)
2070 av_relation
*hentry
;
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
,
2082 relation_needs_vacanalyze(relid
, relopts
, classForm
, tabentry
,
2083 &dovacuum
, &doanalyze
, &wraparound
);
2085 /* ignore analyze for toast tables */
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
);
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
2135 worker
= (WorkerInfo
) SHMQueueNext(&AutoVacuumShmem
->av_runningWorkers
,
2136 &AutoVacuumShmem
->av_runningWorkers
,
2137 offsetof(WorkerInfoData
, wi_links
));
2141 if (worker
== MyWorkerInfo
)
2144 /* ignore workers in other databases */
2145 if (worker
->wi_dboid
!= MyDatabaseId
)
2148 if (worker
->wi_tableoid
== relid
)
2155 worker
= (WorkerInfo
) SHMQueueNext(&AutoVacuumShmem
->av_runningWorkers
,
2157 offsetof(WorkerInfoData
, wi_links
));
2159 LWLockRelease(AutovacuumLock
);
2162 LWLockRelease(AutovacuumScheduleLock
);
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
);
2180 /* someone else vacuumed the table, or it went away */
2181 LWLockRelease(AutovacuumScheduleLock
);
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
;
2205 autovac_balance_cost();
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
)
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.
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;
2249 * Abort the transaction, start a new one, and proceed with the
2250 * next table in our list.
2253 if (tab
->at_dovacuum
)
2254 errcontext("automatic vacuum of table \"%s.%s.%s\"",
2255 tab
->at_datname
, tab
->at_nspname
, tab
->at_relname
);
2257 errcontext("automatic analyze of table \"%s.%s.%s\"",
2258 tab
->at_datname
, tab
->at_nspname
, tab
->at_relname
);
2261 /* this resets the PGPROC flags too */
2262 AbortOutOfAnyTransaction();
2264 MemoryContextResetAndDeleteChildren(PortalContext
);
2266 /* restart our transaction for the following operations */
2267 StartTransactionCommand();
2268 RESUME_INTERRUPTS();
2272 /* the PGPROC flags are reset at the next end of transaction */
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
);
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.
2312 extract_autovac_opts(HeapTuple tup
, TupleDesc pg_class_desc
)
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
)
2324 av
= palloc(sizeof(AutoVacOpts
));
2325 memcpy(av
, &(((StdRdOptions
*) relopts
)->autovacuum
), sizeof(AutoVacOpts
));
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
;
2344 if (PointerIsValid(shared
))
2345 tabentry
= hash_search(shared
->tables
, &relid
,
2348 else if (PointerIsValid(dbentry
))
2349 tabentry
= hash_search(dbentry
->tables
, &relid
,
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
;
2371 autovac_table
*tab
= NULL
;
2372 PgStat_StatTabEntry
*tabentry
;
2373 PgStat_StatDBEntry
*shared
;
2374 PgStat_StatDBEntry
*dbentry
;
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
),
2388 if (!HeapTupleIsValid(classTup
))
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
;
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
,
2412 relation_needs_vacanalyze(relid
, avopts
, classForm
, tabentry
,
2413 &dovacuum
, &doanalyze
, &wraparound
);
2415 /* ignore ANALYZE for toast tables */
2416 if (classForm
->relkind
== RELKIND_TOASTVALUE
)
2419 /* OK, it needs something done */
2420 if (doanalyze
|| dovacuum
)
2423 int freeze_table_age
;
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.
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
;
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
);
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
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.
2509 relation_needs_vacanalyze(Oid relid
,
2510 AutoVacOpts
*relopts
,
2511 Form_pg_class classForm
,
2512 PgStat_StatTabEntry
*tabentry
,
2513 /* output params below */
2520 float4 reltuples
; /* pg_class.reltuples */
2522 /* constants from reloptions or GUC variables */
2523 int vac_base_thresh
,
2525 float4 vac_scale_factor
,
2528 /* thresholds calculated from above constants */
2532 /* number of vacuum (resp. analyze) tuples at this time */
2536 /* freeze parameters */
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.
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
;
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
;
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
,
2575 *wraparound
= force_vacuum
;
2577 /* User disabled it in pg_class.reloptions? (But ignore if at risk) */
2578 if (!force_vacuum
&& !av_enabled
)
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
);
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
2615 *dovacuum
= force_vacuum
;
2619 /* ANALYZE refuses to work with pg_statistics */
2620 if (relid
== StatisticRelationId
)
2625 * autovacuum_do_vac_analyze
2626 * Vacuum and/or analyze the specified table
2629 autovacuum_do_vac_analyze(autovac_table
*tab
,
2630 BufferAccessStrategy bstrategy
)
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.
2665 autovac_report_activity(autovac_table
*tab
)
2667 #define MAX_AUTOVAC_ACTIV_LEN (NAMEDATALEN * 2 + 56)
2668 char activity
[MAX_AUTOVAC_ACTIV_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" : "");
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
2701 AutoVacuumingActive(void)
2703 if (!autovacuum_start_daemon
|| !pgstat_track_counts
)
2710 * This is called at postmaster initialization.
2712 * All we do here is annoy the user if he got it wrong.
2717 if (autovacuum_start_daemon
&& !pgstat_track_counts
)
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
2729 IsAutoVacuumLauncherProcess(void)
2731 return am_autovacuum_launcher
;
2735 IsAutoVacuumWorkerProcess(void)
2737 return am_autovacuum_worker
;
2742 * AutoVacuumShmemSize
2743 * Compute space needed for autovacuum-related shared memory
2746 AutoVacuumShmemSize(void)
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
)));
2761 * AutoVacuumShmemInit
2762 * Allocate and initialize autovacuum-related shared memory
2765 AutoVacuumShmemInit(void)
2769 AutoVacuumShmem
= (AutoVacuumShmemStruct
*)
2770 ShmemInitStruct("AutoVacuum Data",
2771 AutoVacuumShmemSize(),
2773 if (AutoVacuumShmem
== NULL
)
2775 (errcode(ERRCODE_OUT_OF_MEMORY
),
2776 errmsg("not enough shared memory for autovacuum")));
2778 if (!IsUnderPostmaster
)
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
];
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.
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
,
2830 last_read
= current_time
;
2833 pgstat_clear_snapshot();