| 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 | |