1/*-------------------------------------------------------------------------
2 *
3 * vacuum.h
4 * header file for postgres vacuum cleaner and statistics analyzer
5 *
6 *
7 * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group
8 * Portions Copyright (c) 1994, Regents of the University of California
9 *
10 * src/include/commands/vacuum.h
11 *
12 *-------------------------------------------------------------------------
13 */
14#ifndef VACUUM_H
15#define VACUUM_H
16
17#include "access/htup.h"
18#include "catalog/pg_class.h"
19#include "catalog/pg_statistic.h"
20#include "catalog/pg_type.h"
21#include "nodes/parsenodes.h"
22#include "storage/buf.h"
23#include "storage/lock.h"
24#include "utils/relcache.h"
25
26
27/*----------
28 * ANALYZE builds one of these structs for each attribute (column) that is
29 * to be analyzed. The struct and subsidiary data are in anl_context,
30 * so they live until the end of the ANALYZE operation.
31 *
32 * The type-specific typanalyze function is passed a pointer to this struct
33 * and must return true to continue analysis, false to skip analysis of this
34 * column. In the true case it must set the compute_stats and minrows fields,
35 * and can optionally set extra_data to pass additional info to compute_stats.
36 * minrows is its request for the minimum number of sample rows to be gathered
37 * (but note this request might not be honored, eg if there are fewer rows
38 * than that in the table).
39 *
40 * The compute_stats routine will be called after sample rows have been
41 * gathered. Aside from this struct, it is passed:
42 * fetchfunc: a function for accessing the column values from the
43 * sample rows
44 * samplerows: the number of sample tuples
45 * totalrows: estimated total number of rows in relation
46 * The fetchfunc may be called with rownum running from 0 to samplerows-1.
47 * It returns a Datum and an isNull flag.
48 *
49 * compute_stats should set stats_valid true if it is able to compute
50 * any useful statistics. If it does, the remainder of the struct holds
51 * the information to be stored in a pg_statistic row for the column. Be
52 * careful to allocate any pointed-to data in anl_context, which will NOT
53 * be CurrentMemoryContext when compute_stats is called.
54 *
55 * Note: all comparisons done for statistical purposes should use the
56 * underlying column's collation (attcollation), except in situations
57 * where a noncollatable container type contains a collatable type;
58 * in that case use the type's default collation. Be sure to record
59 * the appropriate collation in stacoll.
60 *----------
61 */
62typedef struct VacAttrStats *VacAttrStatsP;
63
64typedef Datum (*AnalyzeAttrFetchFunc) (VacAttrStatsP stats, int rownum,
65 bool *isNull);
66
67typedef void (*AnalyzeAttrComputeStatsFunc) (VacAttrStatsP stats,
68 AnalyzeAttrFetchFunc fetchfunc,
69 int samplerows,
70 double totalrows);
71
72typedef struct VacAttrStats
73{
74 /*
75 * These fields are set up by the main ANALYZE code before invoking the
76 * type-specific typanalyze function.
77 *
78 * Note: do not assume that the data being analyzed has the same datatype
79 * shown in attr, ie do not trust attr->atttypid, attlen, etc. This is
80 * because some index opclasses store a different type than the underlying
81 * column/expression. Instead use attrtypid, attrtypmod, and attrtype for
82 * information about the datatype being fed to the typanalyze function.
83 * Likewise, use attrcollid not attr->attcollation.
84 */
85 Form_pg_attribute attr; /* copy of pg_attribute row for column */
86 Oid attrtypid; /* type of data being analyzed */
87 int32 attrtypmod; /* typmod of data being analyzed */
88 Form_pg_type attrtype; /* copy of pg_type row for attrtypid */
89 Oid attrcollid; /* collation of data being analyzed */
90 MemoryContext anl_context; /* where to save long-lived data */
91
92 /*
93 * These fields must be filled in by the typanalyze routine, unless it
94 * returns false.
95 */
96 AnalyzeAttrComputeStatsFunc compute_stats; /* function pointer */
97 int minrows; /* Minimum # of rows wanted for stats */
98 void *extra_data; /* for extra type-specific data */
99
100 /*
101 * These fields are to be filled in by the compute_stats routine. (They
102 * are initialized to zero when the struct is created.)
103 */
104 bool stats_valid;
105 float4 stanullfrac; /* fraction of entries that are NULL */
106 int32 stawidth; /* average width of column values */
107 float4 stadistinct; /* # distinct values */
108 int16 stakind[STATISTIC_NUM_SLOTS];
109 Oid staop[STATISTIC_NUM_SLOTS];
110 Oid stacoll[STATISTIC_NUM_SLOTS];
111 int numnumbers[STATISTIC_NUM_SLOTS];
112 float4 *stanumbers[STATISTIC_NUM_SLOTS];
113 int numvalues[STATISTIC_NUM_SLOTS];
114 Datum *stavalues[STATISTIC_NUM_SLOTS];
115
116 /*
117 * These fields describe the stavalues[n] element types. They will be
118 * initialized to match attrtypid, but a custom typanalyze function might
119 * want to store an array of something other than the analyzed column's
120 * elements. It should then overwrite these fields.
121 */
122 Oid statypid[STATISTIC_NUM_SLOTS];
123 int16 statyplen[STATISTIC_NUM_SLOTS];
124 bool statypbyval[STATISTIC_NUM_SLOTS];
125 char statypalign[STATISTIC_NUM_SLOTS];
126
127 /*
128 * These fields are private to the main ANALYZE code and should not be
129 * looked at by type-specific functions.
130 */
131 int tupattnum; /* attribute number within tuples */
132 HeapTuple *rows; /* access info for std fetch function */
133 TupleDesc tupDesc;
134 Datum *exprvals; /* access info for index fetch function */
135 bool *exprnulls;
136 int rowstride;
137} VacAttrStats;
138
139typedef enum VacuumOption
140{
141 VACOPT_VACUUM = 1 << 0, /* do VACUUM */
142 VACOPT_ANALYZE = 1 << 1, /* do ANALYZE */
143 VACOPT_VERBOSE = 1 << 2, /* print progress info */
144 VACOPT_FREEZE = 1 << 3, /* FREEZE option */
145 VACOPT_FULL = 1 << 4, /* FULL (non-concurrent) vacuum */
146 VACOPT_SKIP_LOCKED = 1 << 5, /* skip if cannot get lock */
147 VACOPT_SKIPTOAST = 1 << 6, /* don't process the TOAST table, if any */
148 VACOPT_DISABLE_PAGE_SKIPPING = 1 << 7 /* don't skip any pages */
149} VacuumOption;
150
151/*
152 * A ternary value used by vacuum parameters.
153 *
154 * DEFAULT value is used to determine the value based on other
155 * configurations, e.g. reloptions.
156 */
157typedef enum VacOptTernaryValue
158{
159 VACOPT_TERNARY_DEFAULT = 0,
160 VACOPT_TERNARY_DISABLED,
161 VACOPT_TERNARY_ENABLED,
162} VacOptTernaryValue;
163
164/*
165 * Parameters customizing behavior of VACUUM and ANALYZE.
166 *
167 * Note that at least one of VACOPT_VACUUM and VACOPT_ANALYZE must be set
168 * in options.
169 */
170typedef struct VacuumParams
171{
172 int options; /* bitmask of VacuumOption */
173 int freeze_min_age; /* min freeze age, -1 to use default */
174 int freeze_table_age; /* age at which to scan whole table */
175 int multixact_freeze_min_age; /* min multixact freeze age, -1 to
176 * use default */
177 int multixact_freeze_table_age; /* multixact age at which to scan
178 * whole table */
179 bool is_wraparound; /* force a for-wraparound vacuum */
180 int log_min_duration; /* minimum execution threshold in ms at
181 * which verbose logs are activated, -1
182 * to use default */
183 VacOptTernaryValue index_cleanup; /* Do index vacuum and cleanup,
184 * default value depends on reloptions */
185 VacOptTernaryValue truncate; /* Truncate empty pages at the end,
186 * default value depends on reloptions */
187} VacuumParams;
188
189/* GUC parameters */
190extern PGDLLIMPORT int default_statistics_target; /* PGDLLIMPORT for PostGIS */
191extern int vacuum_freeze_min_age;
192extern int vacuum_freeze_table_age;
193extern int vacuum_multixact_freeze_min_age;
194extern int vacuum_multixact_freeze_table_age;
195
196
197/* in commands/vacuum.c */
198extern void ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel);
199extern void vacuum(List *relations, VacuumParams *params,
200 BufferAccessStrategy bstrategy, bool isTopLevel);
201extern void vac_open_indexes(Relation relation, LOCKMODE lockmode,
202 int *nindexes, Relation **Irel);
203extern void vac_close_indexes(int nindexes, Relation *Irel, LOCKMODE lockmode);
204extern double vac_estimate_reltuples(Relation relation,
205 BlockNumber total_pages,
206 BlockNumber scanned_pages,
207 double scanned_tuples);
208extern void vac_update_relstats(Relation relation,
209 BlockNumber num_pages,
210 double num_tuples,
211 BlockNumber num_all_visible_pages,
212 bool hasindex,
213 TransactionId frozenxid,
214 MultiXactId minmulti,
215 bool in_outer_xact);
216extern void vacuum_set_xid_limits(Relation rel,
217 int freeze_min_age, int freeze_table_age,
218 int multixact_freeze_min_age,
219 int multixact_freeze_table_age,
220 TransactionId *oldestXmin,
221 TransactionId *freezeLimit,
222 TransactionId *xidFullScanLimit,
223 MultiXactId *multiXactCutoff,
224 MultiXactId *mxactFullScanLimit);
225extern void vac_update_datfrozenxid(void);
226extern void vacuum_delay_point(void);
227extern bool vacuum_is_relation_owner(Oid relid, Form_pg_class reltuple,
228 int options);
229extern Relation vacuum_open_relation(Oid relid, RangeVar *relation,
230 int options, bool verbose, LOCKMODE lmode);
231
232/* in commands/analyze.c */
233extern void analyze_rel(Oid relid, RangeVar *relation,
234 VacuumParams *params, List *va_cols, bool in_outer_xact,
235 BufferAccessStrategy bstrategy);
236extern bool std_typanalyze(VacAttrStats *stats);
237
238/* in utils/misc/sampling.c --- duplicate of declarations in utils/sampling.h */
239extern double anl_random_fract(void);
240extern double anl_init_selection_state(int n);
241extern double anl_get_next_S(double t, int n, double *stateptr);
242
243#endif /* VACUUM_H */
244