1/*-------------------------------------------------------------------------
4 * header file for postgres vacuum cleaner and statistics analyzer
7 * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
8 * Portions Copyright (c) 1994, Regents of the University of California
10 * src/include/commands/vacuum.h
12 *-------------------------------------------------------------------------
30 * Flags for amparallelvacuumoptions to control the participation of bulkdelete
31 * and vacuumcleanup in parallel vacuum.
35 * Both bulkdelete and vacuumcleanup are disabled by default. This will be
36 * used by IndexAM's that don't want to or cannot participate in parallel
37 * vacuum. For example, if an index AM doesn't have a way to communicate the
38 * index statistics allocated by the first ambulkdelete call to the subsequent
39 * ones until amvacuumcleanup, the index AM cannot participate in parallel
42 #define VACUUM_OPTION_NO_PARALLEL 0
45 * bulkdelete can be performed in parallel. This option can be used by
46 * index AMs that need to scan indexes to delete tuples.
48 #define VACUUM_OPTION_PARALLEL_BULKDEL (1 << 0)
51 * vacuumcleanup can be performed in parallel if bulkdelete is not performed
52 * yet. This will be used by IndexAM's that can scan the index if the
53 * bulkdelete is not performed.
55 #define VACUUM_OPTION_PARALLEL_COND_CLEANUP (1 << 1)
58 * vacuumcleanup can be performed in parallel even if bulkdelete has already
59 * processed the index. This will be used by IndexAM's that scan the index
60 * during the cleanup phase of index irrespective of whether the index is
61 * already scanned or not during bulkdelete phase.
63 #define VACUUM_OPTION_PARALLEL_CLEANUP (1 << 2)
65/* value for checking vacuum flags */
66 #define VACUUM_OPTION_MAX_VALID_VALUE ((1 << 3) - 1)
68/* Abstract type for parallel vacuum state */
72 * ANALYZE builds one of these structs for each attribute (column) that is
73 * to be analyzed. The struct and subsidiary data are in anl_context,
74 * so they live until the end of the ANALYZE operation.
76 * The type-specific typanalyze function is passed a pointer to this struct
77 * and must return true to continue analysis, false to skip analysis of this
78 * column. In the true case it must set the compute_stats and minrows fields,
79 * and can optionally set extra_data to pass additional info to compute_stats.
80 * minrows is its request for the minimum number of sample rows to be gathered
81 * (but note this request might not be honored, eg if there are fewer rows
82 * than that in the table).
84 * The compute_stats routine will be called after sample rows have been
85 * gathered. Aside from this struct, it is passed:
86 * fetchfunc: a function for accessing the column values from the
88 * samplerows: the number of sample tuples
89 * totalrows: estimated total number of rows in relation
90 * The fetchfunc may be called with rownum running from 0 to samplerows-1.
91 * It returns a Datum and an isNull flag.
93 * compute_stats should set stats_valid true if it is able to compute
94 * any useful statistics. If it does, the remainder of the struct holds
95 * the information to be stored in a pg_statistic row for the column. Be
96 * careful to allocate any pointed-to data in anl_context, which will NOT
97 * be CurrentMemoryContext when compute_stats is called.
99 * Note: all comparisons done for statistical purposes should use the
100 * underlying column's collation (attcollation), except in situations
101 * where a noncollatable container type contains a collatable type;
102 * in that case use the type's default collation. Be sure to record
103 * the appropriate collation in stacoll.
119 * These fields are set up by the main ANALYZE code before invoking the
120 * type-specific typanalyze function. They don't necessarily match what
121 * is in pg_attribute, because some index opclasses store a different type
122 * than the underlying column/expression. Therefore, use these fields for
123 * information about the datatype being fed to the typanalyze function.
133 * These fields must be filled in by the typanalyze routine, unless it
137 int minrows;
/* Minimum # of rows wanted for stats */
141 * These fields are to be filled in by the compute_stats routine. (They
142 * are initialized to zero when the struct is created.)
157 * These fields describe the stavalues[n] element types. They will be
158 * initialized to match attrtypid, but a custom typanalyze function might
159 * want to store an array of something other than the analyzed column's
160 * elements. It should then overwrite these fields.
168 * These fields are private to the main ANALYZE code and should not be
169 * looked at by type-specific functions.
179/* flag bits for VacuumParams->options */
180 #define VACOPT_VACUUM 0x01 /* do VACUUM */
181 #define VACOPT_ANALYZE 0x02 /* do ANALYZE */
182 #define VACOPT_VERBOSE 0x04 /* output INFO instrumentation messages */
183 #define VACOPT_FREEZE 0x08 /* FREEZE option */
184 #define VACOPT_FULL 0x10 /* FULL (non-concurrent) vacuum */
185 #define VACOPT_SKIP_LOCKED 0x20 /* skip if cannot get lock */
186 #define VACOPT_PROCESS_MAIN 0x40 /* process main relation */
187 #define VACOPT_PROCESS_TOAST 0x80 /* process the TOAST table, if any */
188 #define VACOPT_DISABLE_PAGE_SKIPPING 0x100 /* don't skip any pages */
189 #define VACOPT_SKIP_DATABASE_STATS 0x200 /* skip vac_update_datfrozenxid() */
190 #define VACOPT_ONLY_DATABASE_STATS 0x400 /* only vac_update_datfrozenxid() */
193 * Values used by index_cleanup and truncate params.
195 * VACOPTVALUE_UNSPECIFIED is used as an initial placeholder when VACUUM
196 * command has no explicit value. When that happens the final usable value
197 * comes from the corresponding reloption (though the reloption default is
209 * Parameters customizing behavior of VACUUM and ANALYZE.
211 * Note that at least one of VACOPT_VACUUM and VACOPT_ANALYZE must be set
214 * When adding a new VacuumParam member, consider adding it to vacuumdb as
228 * which autovacuum is logged, -1 to use
235 * Fraction of pages in a relation that vacuum can eagerly scan and fail
236 * to freeze. Only applicable for table AMs using visibility maps. Derived
237 * from GUC or table storage parameter. 0 if disabled.
242 * The number of parallel vacuum workers. 0 by default which means choose
243 * based on the number of indexes. -1 indicates parallel vacuum is
250 * VacuumCutoffs is immutable state that describes the cutoffs used by VACUUM.
251 * Established at the beginning of each VACUUM operation.
256 * Existing pg_class fields at start of VACUUM
262 * OldestXmin is the Xid below which tuples deleted by any xact (that
263 * committed) should be considered DEAD, not just RECENTLY_DEAD.
265 * OldestMxact is the Mxid below which MultiXacts are definitely not seen
266 * as visible by any running transaction.
268 * OldestXmin and OldestMxact are also the most recent values that can
269 * ever be passed to vac_update_relstats() as frozenxid and minmulti
270 * arguments at the end of VACUUM. These same values should be passed
271 * when it turns out that VACUUM will leave no unfrozen XIDs/MXIDs behind
278 * FreezeLimit is the Xid below which all Xids are definitely frozen or
279 * removed in pages VACUUM scans and cleanup locks.
281 * MultiXactCutoff is the value below which all MultiXactIds are
282 * definitely removed from Xmax in pages VACUUM scans and cleanup locks.
289 * VacDeadItemsInfo stores supplemental information for dead tuple TID
290 * storage (i.e. TidStore).
294 size_t max_bytes;
/* the maximum bytes TidStore can use */
310 * Relevant for vacuums implementing eager scanning. Normal vacuums may
311 * eagerly scan some all-visible but not all-frozen pages. Since the goal
312 * is to freeze these pages, an eager scan that fails to set the page
313 * all-frozen in the VM is considered to have "failed". This is the
314 * fraction of pages in the relation vacuum may scan and fail to freeze
315 * before disabling eager scanning.
320 * Maximum value for default_statistics_target and per-column statistics
321 * targets. This is fairly arbitrary, mainly to prevent users from creating
322 * unreasonably large statistics that the system cannot handle well.
324 #define MAX_STATISTICS_TARGET 10000
326/* Variables for cost-based parallel vacuum */
337/* in commands/vacuum.c */
348 double scanned_tuples);
357 bool *frozenxid_updated,
358 bool *minmulti_updated,
377/* In postmaster/autovacuum.c */
381/* in commands/vacuumparallel.c */
383 int nindexes,
int nrequested_workers,
384 int vac_work_mem,
int elevel,
391 long num_table_tuples,
392 int num_index_scans);
394 long num_table_tuples,
396 bool estimated_count);
399/* in commands/analyze.c */
405/* in utils/misc/sampling.c --- duplicate of declarations in utils/sampling.h */
TransactionId MultiXactId
FormData_pg_class * Form_pg_class
#define STATISTIC_NUM_SLOTS
FormData_pg_type * Form_pg_type
int16 stakind[STATISTIC_NUM_SLOTS]
MemoryContext anl_context
Oid statypid[STATISTIC_NUM_SLOTS]
Oid staop[STATISTIC_NUM_SLOTS]
Oid stacoll[STATISTIC_NUM_SLOTS]
char statypalign[STATISTIC_NUM_SLOTS]
float4 * stanumbers[STATISTIC_NUM_SLOTS]
bool statypbyval[STATISTIC_NUM_SLOTS]
int16 statyplen[STATISTIC_NUM_SLOTS]
int numvalues[STATISTIC_NUM_SLOTS]
Datum * stavalues[STATISTIC_NUM_SLOTS]
int numnumbers[STATISTIC_NUM_SLOTS]
AnalyzeAttrComputeStatsFunc compute_stats
TransactionId FreezeLimit
TransactionId relfrozenxid
MultiXactId MultiXactCutoff
int multixact_freeze_min_age
int multixact_freeze_table_age
VacOptValue index_cleanup
double max_eager_freeze_failure_rate
void ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
void VacuumUpdateCosts(void)
PGDLLIMPORT int VacuumCostBalanceLocal
TidStore * parallel_vacuum_get_dead_items(ParallelVacuumState *pvs, VacDeadItemsInfo **dead_items_info_p)
void vacuum(List *relations, const VacuumParams params, BufferAccessStrategy bstrategy, MemoryContext vac_context, bool isTopLevel)
PGDLLIMPORT int vacuum_freeze_table_age
PGDLLIMPORT pg_atomic_uint32 * VacuumSharedCostBalance
PGDLLIMPORT int vacuum_cost_limit
bool std_typanalyze(VacAttrStats *stats)
void vac_open_indexes(Relation relation, LOCKMODE lockmode, int *nindexes, Relation **Irel)
PGDLLIMPORT pg_atomic_uint32 * VacuumActiveNWorkers
PGDLLIMPORT double vacuum_cost_delay
double anl_get_next_S(double t, int n, double *stateptr)
PGDLLIMPORT int vacuum_failsafe_age
IndexBulkDeleteResult * vac_cleanup_one_index(IndexVacuumInfo *ivinfo, IndexBulkDeleteResult *istat)
ParallelVacuumState * parallel_vacuum_init(Relation rel, Relation *indrels, int nindexes, int nrequested_workers, int vac_work_mem, int elevel, BufferAccessStrategy bstrategy)
struct VacAttrStats VacAttrStats
PGDLLIMPORT bool VacuumFailsafeActive
PGDLLIMPORT int vacuum_freeze_min_age
void parallel_vacuum_bulkdel_all_indexes(ParallelVacuumState *pvs, long num_table_tuples, int num_index_scans)
PGDLLIMPORT int64 parallel_vacuum_worker_delay_ns
Relation vacuum_open_relation(Oid relid, RangeVar *relation, bits32 options, bool verbose, LOCKMODE lmode)
void parallel_vacuum_reset_dead_items(ParallelVacuumState *pvs)
void vac_close_indexes(int nindexes, Relation *Irel, LOCKMODE lockmode)
void parallel_vacuum_cleanup_all_indexes(ParallelVacuumState *pvs, long num_table_tuples, int num_index_scans, bool estimated_count)
void analyze_rel(Oid relid, RangeVar *relation, const VacuumParams params, List *va_cols, bool in_outer_xact, BufferAccessStrategy bstrategy)
Datum(* AnalyzeAttrFetchFunc)(VacAttrStatsP stats, int rownum, bool *isNull)
void vac_update_datfrozenxid(void)
void vacuum_delay_point(bool is_analyze)
PGDLLIMPORT bool vacuum_truncate
bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs)
@ VACOPTVALUE_UNSPECIFIED
PGDLLIMPORT int default_statistics_target
void parallel_vacuum_main(dsm_segment *seg, shm_toc *toc)
struct VacDeadItemsInfo VacDeadItemsInfo
struct VacAttrStats * VacAttrStatsP
PGDLLIMPORT int vacuum_multixact_freeze_table_age
PGDLLIMPORT int vacuum_multixact_freeze_min_age
double vac_estimate_reltuples(Relation relation, BlockNumber total_pages, BlockNumber scanned_pages, double scanned_tuples)
double anl_init_selection_state(int n)
PGDLLIMPORT bool track_cost_delay_timing
void(* AnalyzeAttrComputeStatsFunc)(VacAttrStatsP stats, AnalyzeAttrFetchFunc fetchfunc, int samplerows, double totalrows)
void AutoVacuumUpdateCostLimit(void)
struct VacuumParams VacuumParams
void parallel_vacuum_end(ParallelVacuumState *pvs, IndexBulkDeleteResult **istats)
bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple, bits32 options)
PGDLLIMPORT int vacuum_multixact_failsafe_age
void vac_update_relstats(Relation relation, BlockNumber num_pages, double num_tuples, BlockNumber num_all_visible_pages, BlockNumber num_all_frozen_pages, bool hasindex, TransactionId frozenxid, MultiXactId minmulti, bool *frozenxid_updated, bool *minmulti_updated, bool in_outer_xact)
bool vacuum_get_cutoffs(Relation rel, const VacuumParams params, struct VacuumCutoffs *cutoffs)
double anl_random_fract(void)
IndexBulkDeleteResult * vac_bulkdel_one_index(IndexVacuumInfo *ivinfo, IndexBulkDeleteResult *istat, TidStore *dead_items, VacDeadItemsInfo *dead_items_info)
PGDLLIMPORT double vacuum_max_eager_freeze_failure_rate