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 | */ |
62 | typedef struct VacAttrStats *VacAttrStatsP; |
63 | |
64 | typedef Datum (*AnalyzeAttrFetchFunc) (VacAttrStatsP stats, int rownum, |
65 | bool *isNull); |
66 | |
67 | typedef void (*AnalyzeAttrComputeStatsFunc) (VacAttrStatsP stats, |
68 | AnalyzeAttrFetchFunc fetchfunc, |
69 | int samplerows, |
70 | double totalrows); |
71 | |
72 | typedef 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 *; /* 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 | |
139 | typedef 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 | */ |
157 | typedef 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 | */ |
170 | typedef 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 */ |
190 | extern PGDLLIMPORT int default_statistics_target; /* PGDLLIMPORT for PostGIS */ |
191 | extern int vacuum_freeze_min_age; |
192 | extern int vacuum_freeze_table_age; |
193 | extern int vacuum_multixact_freeze_min_age; |
194 | extern int vacuum_multixact_freeze_table_age; |
195 | |
196 | |
197 | /* in commands/vacuum.c */ |
198 | extern void ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel); |
199 | extern void vacuum(List *relations, VacuumParams *params, |
200 | BufferAccessStrategy bstrategy, bool isTopLevel); |
201 | extern void vac_open_indexes(Relation relation, LOCKMODE lockmode, |
202 | int *nindexes, Relation **Irel); |
203 | extern void vac_close_indexes(int nindexes, Relation *Irel, LOCKMODE lockmode); |
204 | extern double vac_estimate_reltuples(Relation relation, |
205 | BlockNumber total_pages, |
206 | BlockNumber scanned_pages, |
207 | double scanned_tuples); |
208 | extern 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); |
216 | extern 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); |
225 | extern void vac_update_datfrozenxid(void); |
226 | extern void vacuum_delay_point(void); |
227 | extern bool vacuum_is_relation_owner(Oid relid, Form_pg_class reltuple, |
228 | int options); |
229 | extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, |
230 | int options, bool verbose, LOCKMODE lmode); |
231 | |
232 | /* in commands/analyze.c */ |
233 | extern void analyze_rel(Oid relid, RangeVar *relation, |
234 | VacuumParams *params, List *va_cols, bool in_outer_xact, |
235 | BufferAccessStrategy bstrategy); |
236 | extern bool std_typanalyze(VacAttrStats *stats); |
237 | |
238 | /* in utils/misc/sampling.c --- duplicate of declarations in utils/sampling.h */ |
239 | extern double anl_random_fract(void); |
240 | extern double anl_init_selection_state(int n); |
241 | extern double anl_get_next_S(double t, int n, double *stateptr); |
242 | |
243 | #endif /* VACUUM_H */ |
244 | |