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