100#include "utils/fmgroids.h"
101#include "utils/fmgrprotos.h"
139#define MIN_AUTOVAC_SLEEPTIME 100.0
140#define MAX_AUTOVAC_SLEEPTIME 300
255#define AutoVacNumSignals (AutoVacRebalance + 1)
273#define NUM_WORKITEMS 256
360 const char *nspname,
const char *
relname);
436 "Autovacuum Launcher",
601 (
nap.tv_sec * 1000L) + (
nap.tv_usec / 1000L),
700 errmsg(
"autovacuum worker took too long to start; canceled"));
862 if (
nap->tv_sec == 0 &&
nap->tv_usec == 0 && !recursing)
914 "Autovacuum database list",
917 "Autovacuum database list (tmp)",
1060 for (
i = 0;
i < nelems;
i++)
1130 "Autovacuum start worker (tmp)",
1190 avdb->adw_frozenxid))
1240 dbp->adl_next_worker,
1284 retval =
avdb->adw_datid;
1331 if (
avdb->adl_datid == dbid)
1339 avdb->adl_next_worker =
1560 elog(
WARNING,
"autovacuum worker started without a worker entry");
1698 "Autovacuum VacuumUpdateCosts(db=%u, rel=%u, dobalance=%s, cost_limit=%d, cost_delay=%g active=%s failsafe=%s)",
1746 elog(
ERROR,
"nworkers_for_balance must be > 0");
1833 "autovacuum: skipping invalid database \"%s\"",
1902 "Autovacuum worker",
1958 ctl.keysize =
sizeof(
Oid);
2058 hentry->ar_relid = relid;
2059 hentry->ar_hasrelopts =
false;
2062 hentry->ar_hasrelopts =
true;
2117 if (found &&
hentry->ar_hasrelopts)
2224 (
errmsg(
"autovacuum: dropping orphan temp table \"%s.%s.%s\"",
2236 object.objectId = relid;
2237 object.objectSubId = 0;
2277 "Autovacuum Portal",
2467 errcontext(
"automatic vacuum of table \"%s.%s.%s\"",
2470 errcontext(
"automatic analyze of table \"%s.%s.%s\"",
2611 char *cur_relname =
NULL;
2659 elog(
WARNING,
"unrecognized work item found: type %d",
2679 errcontext(
"processing work entry for relation \"%s.%s.%s\"",
2784 if (found &&
hentry->ar_hasrelopts)
2796 int freeze_table_age;
2797 int multixact_freeze_min_age;
2798 int multixact_freeze_table_age;
2799 int log_vacuum_min_duration;
2800 int log_analyze_min_duration;
2810 log_vacuum_min_duration = (
avopts &&
avopts->log_vacuum_min_duration >= 0)
2811 ?
avopts->log_vacuum_min_duration
2815 log_analyze_min_duration = (
avopts &&
avopts->log_analyze_min_duration >= 0)
2816 ?
avopts->log_analyze_min_duration
2820 freeze_min_age = (
avopts &&
avopts->freeze_min_age >= 0)
2824 freeze_table_age = (
avopts &&
avopts->freeze_table_age >= 0)
2825 ?
avopts->freeze_table_age
2828 multixact_freeze_min_age = (
avopts &&
2829 avopts->multixact_freeze_min_age >= 0)
2830 ?
avopts->multixact_freeze_min_age
2833 multixact_freeze_table_age = (
avopts &&
2834 avopts->multixact_freeze_table_age >= 0)
2835 ?
avopts->multixact_freeze_table_age
2878 avopts->vacuum_cost_limit : 0;
2880 avopts->vacuum_cost_delay : -1;
2891 avopts->vacuum_cost_delay >= 0));
3010 int multixact_freeze_max_age;
3026 ?
relopts->vacuum_scale_factor
3035 ?
relopts->vacuum_max_threshold
3039 ?
relopts->vacuum_ins_scale_factor
3044 ?
relopts->vacuum_ins_threshold
3048 ?
relopts->analyze_scale_factor
3059 multixact_freeze_max_age = (
relopts &&
relopts->multixact_freeze_max_age >= 0)
3120 if (relpages > 0 && relallfrozen > 0)
3127 relallfrozen =
Min(relallfrozen, relpages);
3140 elog(
DEBUG3,
"%s: vac: %.0f (threshold %.0f), ins: %.0f (threshold %.0f), anl: %.0f (threshold %.0f)",
3144 elog(
DEBUG3,
"%s: vac: %.0f (threshold %.0f), ins: (disabled), anl: %.0f (threshold %.0f)",
3219#define MAX_AUTOVAC_ACTIV_LEN (NAMEDATALEN * 2 + 56)
3226 "autovacuum: VACUUM%s",
3230 "autovacuum: ANALYZE");
3253 const char *nspname,
const char *
relname)
3263 "autovacuum: BRIN summarize");
3308 bool result =
false;
3352 (
errmsg(
"autovacuum not started because of misconfiguration"),
3353 errhint(
"Enable the \"track_counts\" option.")));
3475 errmsg(
"\"autovacuum_max_workers\" (%d) should be less than or equal to \"autovacuum_worker_slots\" (%d)",
3477 errdetail(
"The server will only start up to \"autovacuum_worker_slots\" (%d) autovacuum workers at a given time.",
void pgaio_error_cleanup(void)
static void pg_atomic_clear_flag(volatile pg_atomic_flag *ptr)
static void pg_atomic_init_u32(volatile pg_atomic_uint32 *ptr, uint32 val)
static bool pg_atomic_test_set_flag(volatile pg_atomic_flag *ptr)
static bool pg_atomic_unlocked_test_flag(volatile pg_atomic_flag *ptr)
static void pg_atomic_write_u32(volatile pg_atomic_uint32 *ptr, uint32 val)
static uint32 pg_atomic_read_u32(volatile pg_atomic_uint32 *ptr)
static void pg_atomic_init_flag(volatile pg_atomic_flag *ptr)
static void relation_needs_vacanalyze(Oid relid, AutoVacOpts *relopts, Form_pg_class classForm, PgStat_StatTabEntry *tabentry, int effective_multixact_freeze_max_age, bool *dovacuum, bool *doanalyze, bool *wraparound)
static Oid do_start_worker(void)
static void launcher_determine_sleep(bool canlaunch, bool recursing, struct timeval *nap)
int autovacuum_worker_slots
void VacuumUpdateCosts(void)
void AutoVacLauncherMain(const void *startup_data, size_t startup_data_len)
static volatile sig_atomic_t got_SIGUSR2
static void avl_sigusr2_handler(SIGNAL_ARGS)
int autovacuum_multixact_freeze_max_age
static bool av_worker_available(void)
static int default_multixact_freeze_table_age
double autovacuum_vac_scale
void AutoVacWorkerMain(const void *startup_data, size_t startup_data_len)
static void FreeWorkerInfo(int code, Datum arg)
int Log_autovacuum_min_duration
int autovacuum_anl_thresh
static TransactionId recentXid
Size AutoVacuumShmemSize(void)
static List * get_database_list(void)
void AutoVacuumShmemInit(void)
bool check_autovacuum_work_mem(int *newval, void **extra, GucSource source)
static void autovac_report_activity(autovac_table *tab)
static int default_multixact_freeze_min_age
static void do_autovacuum(void)
int autovacuum_vac_cost_limit
static double av_storage_param_cost_delay
bool AutoVacuumRequestWork(AutoVacuumWorkItemType type, Oid relationId, BlockNumber blkno)
bool AutoVacuumingActive(void)
int autovacuum_max_workers
int autovacuum_freeze_max_age
static int db_comparator(const void *a, const void *b)
static int av_storage_param_cost_limit
double autovacuum_vac_cost_delay
static pg_noreturn void AutoVacLauncherShutdown(void)
#define AutoVacNumSignals
int autovacuum_vac_thresh
static void launch_worker(TimestampTz now)
static dlist_head DatabaseList
static void rebuild_database_list(Oid newdb)
static AutoVacuumShmemStruct * AutoVacuumShmem
static void check_av_worker_gucs(void)
#define MIN_AUTOVAC_SLEEPTIME
#define MAX_AUTOVAC_ACTIV_LEN
double autovacuum_anl_scale
int autovacuum_vac_ins_thresh
#define MAX_AUTOVAC_SLEEPTIME
static MemoryContext DatabaseListCxt
void AutoVacWorkerFailed(void)
struct WorkerInfoData * WorkerInfo
bool autovacuum_start_daemon
static void perform_work_item(AutoVacuumWorkItem *workitem)
double autovacuum_vac_ins_scale
static MultiXactId recentMulti
static int default_freeze_min_age
static void autovac_recalculate_workers_for_balance(void)
int autovacuum_vac_max_thresh
void AutoVacuumUpdateCostLimit(void)
static WorkerInfo MyWorkerInfo
static void autovac_report_workitem(AutoVacuumWorkItem *workitem, const char *nspname, const char *relname)
static void recheck_relation_needs_vacanalyze(Oid relid, AutoVacOpts *avopts, Form_pg_class classForm, int effective_multixact_freeze_max_age, bool *dovacuum, bool *doanalyze, bool *wraparound)
static autovac_table * table_recheck_autovac(Oid relid, HTAB *table_toast_map, TupleDesc pg_class_desc, int effective_multixact_freeze_max_age)
static MemoryContext AutovacMemCxt
static void ProcessAutoVacLauncherInterrupts(void)
static AutoVacOpts * extract_autovac_opts(HeapTuple tup, TupleDesc pg_class_desc)
static int default_freeze_table_age
static void autovacuum_do_vac_analyze(autovac_table *tab, BufferAccessStrategy bstrategy)
int Log_autoanalyze_min_duration
void TimestampDifference(TimestampTz start_time, TimestampTz stop_time, long *secs, int *microsecs)
bool TimestampDifferenceExceeds(TimestampTz start_time, TimestampTz stop_time, int msec)
TimestampTz GetCurrentTimestamp(void)
Datum now(PG_FUNCTION_ARGS)
void pgstat_report_activity(BackendState state, const char *cmd_str)
static bool BlockNumberIsValid(BlockNumber blockNumber)
Datum brin_summarize_range(PG_FUNCTION_ARGS)
void AtEOXact_Buffers(bool isCommit)
#define Assert(condition)
TransactionId MultiXactId
#define OidIsValid(objectId)
bool database_is_invalid_form(Form_pg_database datform)
void performDeletion(const ObjectAddress *object, DropBehavior behavior, int flags)
#define PERFORM_DELETION_SKIP_EXTENSIONS
#define PERFORM_DELETION_QUIETLY
#define PERFORM_DELETION_INTERNAL
void * hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action, bool *foundPtr)
void AtEOXact_HashTables(bool isCommit)
HTAB * hash_create(const char *tabname, int64 nelem, const HASHCTL *info, int flags)
void hash_destroy(HTAB *hashp)
void * hash_seq_search(HASH_SEQ_STATUS *status)
void hash_seq_init(HASH_SEQ_STATUS *status, HTAB *hashp)
int errmsg_internal(const char *fmt,...)
void EmitErrorReport(void)
int errdetail(const char *fmt,...)
ErrorContextCallback * error_context_stack
void FlushErrorState(void)
int errhint(const char *fmt,...)
bool message_level_is_interesting(int elevel)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
sigjmp_buf * PG_exception_stack
#define ereport(elevel,...)
void AtEOXact_Files(bool isCommit)
#define palloc_object(type)
#define DirectFunctionCall2(func, arg1, arg2)
BufferAccessStrategy GetAccessStrategyWithSize(BufferAccessStrategyType btype, int ring_size_kb)
volatile sig_atomic_t LogMemoryContextPending
volatile sig_atomic_t ProcSignalBarrierPending
volatile sig_atomic_t QueryCancelPending
int VacuumBufferUsageLimit
void ProcessConfigFile(GucContext context)
void SetConfigOption(const char *name, const char *value, GucContext context, GucSource source)
HeapTuple heap_getnext(TableScanDesc sscan, ScanDirection direction)
void heap_freetuple(HeapTuple htup)
#define HeapTupleIsValid(tuple)
static void * GETSTRUCT(const HeapTupleData *tuple)
#define dlist_foreach(iter, lhead)
static void dlist_init(dlist_head *head)
static void dlist_delete(dlist_node *node)
static uint32 dclist_count(const dclist_head *head)
#define dlist_reverse_foreach(iter, lhead)
#define dlist_tail_element(type, membername, lhead)
static void dlist_push_head(dlist_head *head, dlist_node *node)
static bool dlist_is_empty(const dlist_head *head)
static dlist_node * dclist_pop_head_node(dclist_head *head)
static void dclist_push_head(dclist_head *head, dlist_node *node)
static void dclist_init(dclist_head *head)
static void dlist_move_head(dlist_head *head, dlist_node *node)
#define DLIST_STATIC_INIT(name)
#define dlist_container(type, membername, ptr)
#define INJECTION_POINT(name, arg)
static int pg_cmp_s32(int32 a, int32 b)
void SignalHandlerForShutdownRequest(SIGNAL_ARGS)
volatile sig_atomic_t ShutdownRequestPending
volatile sig_atomic_t ConfigReloadPending
void SignalHandlerForConfigReload(SIGNAL_ARGS)
void on_shmem_exit(pg_on_exit_callback function, Datum arg)
void SetLatch(Latch *latch)
void ResetLatch(Latch *latch)
int WaitLatch(Latch *latch, int wakeEvents, long timeout, uint32 wait_event_info)
List * lappend(List *list, void *datum)
List * lappend_oid(List *list, Oid datum)
void list_free(List *list)
bool ConditionalLockRelationOid(Oid relid, LOCKMODE lockmode)
void UnlockRelationOid(Oid relid, LOCKMODE lockmode)
bool ConditionalLockDatabaseObject(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode)
#define AccessExclusiveLock
char * get_rel_name(Oid relid)
char * get_database_name(Oid dbid)
Oid get_rel_namespace(Oid relid)
char * get_namespace_name(Oid nspid)
bool LWLockHeldByMe(LWLock *lock)
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
void LWLockRelease(LWLock *lock)
void LWLockReleaseAll(void)
VacuumRelation * makeVacuumRelation(RangeVar *relation, Oid oid, List *va_cols)
RangeVar * makeRangeVar(char *schemaname, char *relname, int location)
void MemoryContextReset(MemoryContext context)
MemoryContext TopTransactionContext
char * pstrdup(const char *in)
void pfree(void *pointer)
MemoryContext TopMemoryContext
MemoryContext CurrentMemoryContext
MemoryContext PostmasterContext
void ProcessLogMemoryContextInterrupt(void)
void MemoryContextDelete(MemoryContext context)
MemoryContext PortalContext
#define AllocSetContextCreate
#define ALLOCSET_DEFAULT_SIZES
#define RESUME_INTERRUPTS()
#define GetProcessingMode()
#define CHECK_FOR_INTERRUPTS()
#define HOLD_INTERRUPTS()
#define SetProcessingMode(mode)
#define INIT_PG_OVERRIDE_ALLOW_CONNS
BackendType MyBackendType
bool MultiXactIdPrecedes(MultiXactId multi1, MultiXactId multi2)
int MultiXactMemberFreezeThreshold(void)
MultiXactId ReadNextMultiXactId(void)
#define MultiXactIdIsValid(multi)
TempNamespaceStatus checkTempNamespaceStatus(Oid namespaceId)
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
FormData_pg_class * Form_pg_class
FormData_pg_database * Form_pg_database
static rewind_source * source
void pgstat_report_autovac(Oid dboid)
PgStat_StatDBEntry * pgstat_fetch_stat_dbentry(Oid dboid)
PgStat_StatTabEntry * pgstat_fetch_stat_tabentry_ext(bool shared, Oid reloid)
void SendPostmasterSignal(PMSignalReason reason)
@ PMSIGNAL_START_AUTOVAC_WORKER
#define qsort(a, b, c, d)
void FloatExceptionHandler(SIGNAL_ARGS)
void StatementCancelHandler(SIGNAL_ARGS)
static Datum Int64GetDatum(int64 X)
static Datum ObjectIdGetDatum(Oid X)
static Datum CharGetDatum(char X)
void InitPostgres(const char *in_dbname, Oid dboid, const char *username, Oid useroid, bits32 flags, char *out_dbname)
void ProcessProcSignalBarrier(void)
void procsignal_sigusr1_handler(SIGNAL_ARGS)
void init_ps_display(const char *fixed_part)
static void set_ps_display(const char *activity)
#define RelationGetDescr(relation)
bytea * extractRelOptions(HeapTuple tuple, TupleDesc tupdesc, amoptions_function amoptions)
void ReleaseAuxProcessResources(bool isCommit)
ResourceOwner AuxProcessResourceOwner
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Size add_size(Size s1, Size s2)
Size mul_size(Size s1, Size s2)
void * ShmemInitStruct(const char *name, Size size, bool *foundPtr)
void pg_usleep(long microsec)
void ProcessCatchupInterrupt(void)
Snapshot GetTransactionSnapshot(void)
void PushActiveSnapshot(Snapshot snapshot)
bool ActiveSnapshotSet(void)
void PopActiveSnapshot(void)
#define BTEqualStrategyNumber
dclist_head av_freeWorkers
WorkerInfo av_startingWorker
sig_atomic_t av_signal[AutoVacNumSignals]
AutoVacuumWorkItem av_workItems[NUM_WORKITEMS]
pg_atomic_uint32 av_nworkersForBalance
dlist_head av_runningWorkers
BlockNumber avw_blockNumber
AutoVacuumWorkItemType avw_type
TimestampTz last_autovac_time
int log_vacuum_min_duration
int multixact_freeze_min_age
int multixact_freeze_table_age
VacOptValue index_cleanup
int log_analyze_min_duration
double max_eager_freeze_failure_rate
TimestampTz wi_launchtime
pg_atomic_flag wi_dobalance
double at_storage_param_vac_cost_delay
int at_storage_param_vac_cost_limit
AutoVacOpts ar_reloptions
TimestampTz adl_next_worker
PgStat_StatDBEntry * adw_entry
TransactionId adw_frozenxid
void ReleaseSysCache(HeapTuple tuple)
HeapTuple SearchSysCache1(int cacheId, Datum key1)
#define SearchSysCacheCopy1(cacheId, key1)
void table_close(Relation relation, LOCKMODE lockmode)
Relation table_open(Oid relationId, LOCKMODE lockmode)
TableScanDesc table_beginscan_catalog(Relation relation, int nkeys, ScanKeyData *key)
static void table_endscan(TableScanDesc scan)
void disable_all_timeouts(bool keep_indicators)
void InitializeTimeouts(void)
static TransactionId ReadNextTransactionId(void)
#define FirstNormalTransactionId
#define TransactionIdIsNormal(xid)
static bool TransactionIdPrecedes(TransactionId id1, TransactionId id2)
void FreeTupleDesc(TupleDesc tupdesc)
TupleDesc CreateTupleDescCopy(TupleDesc tupdesc)
#define TimestampTzPlusMilliseconds(tz, ms)
void vacuum(List *relations, const VacuumParams params, BufferAccessStrategy bstrategy, MemoryContext vac_context, bool isTopLevel)
int vacuum_freeze_min_age
double vacuum_max_eager_freeze_failure_rate
int vacuum_multixact_freeze_table_age
int vacuum_freeze_table_age
int vacuum_multixact_freeze_min_age
void vac_update_datfrozenxid(void)
bool VacuumFailsafeActive
#define VACOPT_SKIP_LOCKED
#define VACOPT_SKIP_DATABASE_STATS
@ VACOPTVALUE_UNSPECIFIED
#define VACOPT_PROCESS_MAIN
static void pgstat_report_wait_end(void)
#define WL_EXIT_ON_PM_DEATH
void StartTransactionCommand(void)
void SetCurrentStatementStartTimestamp(void)
void CommitTransactionCommand(void)
void AbortOutOfAnyTransaction(void)
void AbortCurrentTransaction(void)
@ SYNCHRONOUS_COMMIT_LOCAL_FLUSH