1 /*------------------------------------------------------------------------- 2 * 3 * vacuum.h 4 * header file for postgres vacuum cleaner and statistics analyzer 5 * 6 * 7 * Portions Copyright (c) 1996-2017, 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_statistic.h" 19 #include "catalog/pg_type.h" 20 #include "nodes/parsenodes.h" 21 #include "storage/buf.h" 22 #include "storage/lock.h" 23 #include "utils/relcache.h" 24 25 26 /*---------- 27 * ANALYZE builds one of these structs for each attribute (column) that is 28 * to be analyzed. The struct and subsidiary data are in anl_context, 29 * so they live until the end of the ANALYZE operation. 30 * 31 * The type-specific typanalyze function is passed a pointer to this struct 32 * and must return TRUE to continue analysis, FALSE to skip analysis of this 33 * column. In the TRUE case it must set the compute_stats and minrows fields, 34 * and can optionally set extra_data to pass additional info to compute_stats. 35 * minrows is its request for the minimum number of sample rows to be gathered 36 * (but note this request might not be honored, eg if there are fewer rows 37 * than that in the table). 38 * 39 * The compute_stats routine will be called after sample rows have been 40 * gathered. Aside from this struct, it is passed: 41 * fetchfunc: a function for accessing the column values from the 42 * sample rows 43 * samplerows: the number of sample tuples 44 * totalrows: estimated total number of rows in relation 45 * The fetchfunc may be called with rownum running from 0 to samplerows-1. 46 * It returns a Datum and an isNull flag. 47 * 48 * compute_stats should set stats_valid TRUE if it is able to compute 49 * any useful statistics. If it does, the remainder of the struct holds 50 * the information to be stored in a pg_statistic row for the column. Be 51 * careful to allocate any pointed-to data in anl_context, which will NOT 52 * be CurrentMemoryContext when compute_stats is called. 53 * 54 * Note: for the moment, all comparisons done for statistical purposes 55 * should use the database's default collation (DEFAULT_COLLATION_OID). 56 * This might change in some future release. 57 *---------- 58 */ 59 typedef struct VacAttrStats *VacAttrStatsP; 60 61 typedef Datum (*AnalyzeAttrFetchFunc) (VacAttrStatsP stats, int rownum, 62 bool *isNull); 63 64 typedef void (*AnalyzeAttrComputeStatsFunc) (VacAttrStatsP stats, 65 AnalyzeAttrFetchFunc fetchfunc, 66 int samplerows, 67 double totalrows); 68 69 typedef struct VacAttrStats 70 { 71 /* 72 * These fields are set up by the main ANALYZE code before invoking the 73 * type-specific typanalyze function. 74 * 75 * Note: do not assume that the data being analyzed has the same datatype 76 * shown in attr, ie do not trust attr->atttypid, attlen, etc. This is 77 * because some index opclasses store a different type than the underlying 78 * column/expression. Instead use attrtypid, attrtypmod, and attrtype for 79 * information about the datatype being fed to the typanalyze function. 80 */ 81 Form_pg_attribute attr; /* copy of pg_attribute row for column */ 82 Oid attrtypid; /* type of data being analyzed */ 83 int32 attrtypmod; /* typmod of data being analyzed */ 84 Form_pg_type attrtype; /* copy of pg_type row for attrtypid */ 85 MemoryContext anl_context; /* where to save long-lived data */ 86 87 /* 88 * These fields must be filled in by the typanalyze routine, unless it 89 * returns FALSE. 90 */ 91 AnalyzeAttrComputeStatsFunc compute_stats; /* function pointer */ 92 int minrows; /* Minimum # of rows wanted for stats */ 93 void *extra_data; /* for extra type-specific data */ 94 95 /* 96 * These fields are to be filled in by the compute_stats routine. (They 97 * are initialized to zero when the struct is created.) 98 */ 99 bool stats_valid; 100 float4 stanullfrac; /* fraction of entries that are NULL */ 101 int32 stawidth; /* average width of column values */ 102 float4 stadistinct; /* # distinct values */ 103 int16 stakind[STATISTIC_NUM_SLOTS]; 104 Oid staop[STATISTIC_NUM_SLOTS]; 105 int numnumbers[STATISTIC_NUM_SLOTS]; 106 float4 *stanumbers[STATISTIC_NUM_SLOTS]; 107 int numvalues[STATISTIC_NUM_SLOTS]; 108 Datum *stavalues[STATISTIC_NUM_SLOTS]; 109 110 /* 111 * These fields describe the stavalues[n] element types. They will be 112 * initialized to match attrtypid, but a custom typanalyze function might 113 * want to store an array of something other than the analyzed column's 114 * elements. It should then overwrite these fields. 115 */ 116 Oid statypid[STATISTIC_NUM_SLOTS]; 117 int16 statyplen[STATISTIC_NUM_SLOTS]; 118 bool statypbyval[STATISTIC_NUM_SLOTS]; 119 char statypalign[STATISTIC_NUM_SLOTS]; 120 121 /* 122 * These fields are private to the main ANALYZE code and should not be 123 * looked at by type-specific functions. 124 */ 125 int tupattnum; /* attribute number within tuples */ 126 HeapTuple *rows; /* access info for std fetch function */ 127 TupleDesc tupDesc; 128 Datum *exprvals; /* access info for index fetch function */ 129 bool *exprnulls; 130 int rowstride; 131 } VacAttrStats; 132 133 /* 134 * Parameters customizing behavior of VACUUM and ANALYZE. 135 */ 136 typedef struct VacuumParams 137 { 138 int freeze_min_age; /* min freeze age, -1 to use default */ 139 int freeze_table_age; /* age at which to scan whole table */ 140 int multixact_freeze_min_age; /* min multixact freeze age, -1 to 141 * use default */ 142 int multixact_freeze_table_age; /* multixact age at which to scan 143 * whole table */ 144 bool is_wraparound; /* force a for-wraparound vacuum */ 145 int log_min_duration; /* minimum execution threshold in ms at 146 * which verbose logs are activated, -1 147 * to use default */ 148 } VacuumParams; 149 150 /* GUC parameters */ 151 extern PGDLLIMPORT int default_statistics_target; /* PGDLLIMPORT for PostGIS */ 152 extern int vacuum_freeze_min_age; 153 extern int vacuum_freeze_table_age; 154 extern int vacuum_multixact_freeze_min_age; 155 extern int vacuum_multixact_freeze_table_age; 156 157 158 /* in commands/vacuum.c */ 159 extern void ExecVacuum(VacuumStmt *vacstmt, bool isTopLevel); 160 extern void vacuum(int options, RangeVar *relation, Oid relid, 161 VacuumParams *params, List *va_cols, 162 BufferAccessStrategy bstrategy, bool isTopLevel); 163 extern void vac_open_indexes(Relation relation, LOCKMODE lockmode, 164 int *nindexes, Relation **Irel); 165 extern void vac_close_indexes(int nindexes, Relation *Irel, LOCKMODE lockmode); 166 extern double vac_estimate_reltuples(Relation relation, bool is_analyze, 167 BlockNumber total_pages, 168 BlockNumber scanned_pages, 169 double scanned_tuples); 170 extern void vac_update_relstats(Relation relation, 171 BlockNumber num_pages, 172 double num_tuples, 173 BlockNumber num_all_visible_pages, 174 bool hasindex, 175 TransactionId frozenxid, 176 MultiXactId minmulti, 177 bool in_outer_xact); 178 extern void vacuum_set_xid_limits(Relation rel, 179 int freeze_min_age, int freeze_table_age, 180 int multixact_freeze_min_age, 181 int multixact_freeze_table_age, 182 TransactionId *oldestXmin, 183 TransactionId *freezeLimit, 184 TransactionId *xidFullScanLimit, 185 MultiXactId *multiXactCutoff, 186 MultiXactId *mxactFullScanLimit); 187 extern void vac_update_datfrozenxid(void); 188 extern void vacuum_delay_point(void); 189 190 /* in commands/vacuumlazy.c */ 191 extern void lazy_vacuum_rel(Relation onerel, int options, 192 VacuumParams *params, BufferAccessStrategy bstrategy); 193 194 /* in commands/analyze.c */ 195 extern void analyze_rel(Oid relid, RangeVar *relation, int options, 196 VacuumParams *params, List *va_cols, bool in_outer_xact, 197 BufferAccessStrategy bstrategy); 198 extern bool std_typanalyze(VacAttrStats *stats); 199 200 /* in utils/misc/sampling.c --- duplicate of declarations in utils/sampling.h */ 201 extern double anl_random_fract(void); 202 extern double anl_init_selection_state(int n); 203 extern double anl_get_next_S(double t, int n, double *stateptr); 204 205 #endif /* VACUUM_H */ 206