1/*****************************************************************************
2
3Copyright (c) 2009, 2016, Oracle and/or its affiliates. All Rights Reserved.
4Copyright (c) 2017, 2018, MariaDB Corporation.
5
6This program is free software; you can redistribute it and/or modify it under
7the terms of the GNU General Public License as published by the Free Software
8Foundation; version 2 of the License.
9
10This program is distributed in the hope that it will be useful, but WITHOUT
11ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License along with
15this program; if not, write to the Free Software Foundation, Inc.,
1651 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
17
18*****************************************************************************/
19
20/**************************************************//**
21@file include/dict0stats.h
22Code used for calculating and manipulating table statistics.
23
24Created Jan 06, 2010 Vasil Dimov
25*******************************************************/
26
27#ifndef dict0stats_h
28#define dict0stats_h
29
30#include "univ.i"
31
32#include "dict0types.h"
33#include "trx0types.h"
34
35enum dict_stats_upd_option_t {
36 DICT_STATS_RECALC_PERSISTENT,/* (re) calculate the
37 statistics using a precise and slow
38 algo and save them to the persistent
39 storage, if the persistent storage is
40 not present then emit a warning and
41 fall back to transient stats */
42 DICT_STATS_RECALC_TRANSIENT,/* (re) calculate the statistics
43 using an imprecise quick algo
44 without saving the results
45 persistently */
46 DICT_STATS_EMPTY_TABLE, /* Write all zeros (or 1 where it makes sense)
47 into a table and its indexes' statistics
48 members. The resulting stats correspond to an
49 empty table. If the table is using persistent
50 statistics, then they are saved on disk. */
51 DICT_STATS_FETCH_ONLY_IF_NOT_IN_MEMORY /* fetch the stats
52 from the persistent storage if the in-memory
53 structures have not been initialized yet,
54 otherwise do nothing */
55};
56
57/*********************************************************************//**
58Set the persistent statistics flag for a given table. This is set only
59in the in-memory table object and is not saved on disk. It will be read
60from the .frm file upon first open from MySQL after a server restart. */
61UNIV_INLINE
62void
63dict_stats_set_persistent(
64/*======================*/
65 dict_table_t* table, /*!< in/out: table */
66 ibool ps_on, /*!< in: persistent stats explicitly enabled */
67 ibool ps_off) /*!< in: persistent stats explicitly disabled */
68 MY_ATTRIBUTE((nonnull));
69
70/** @return whether persistent statistics is enabled for a given table */
71UNIV_INLINE
72bool
73dict_stats_is_persistent_enabled(const dict_table_t* table)
74 MY_ATTRIBUTE((nonnull, warn_unused_result));
75
76/*********************************************************************//**
77Set the auto recalc flag for a given table (only honored for a persistent
78stats enabled table). The flag is set only in the in-memory table object
79and is not saved in InnoDB files. It will be read from the .frm file upon
80first open from MySQL after a server restart. */
81UNIV_INLINE
82void
83dict_stats_auto_recalc_set(
84/*=======================*/
85 dict_table_t* table, /*!< in/out: table */
86 ibool auto_recalc_on, /*!< in: explicitly enabled */
87 ibool auto_recalc_off); /*!< in: explicitly disabled */
88
89/** @return whether auto recalc is enabled for a given table*/
90UNIV_INLINE
91bool
92dict_stats_auto_recalc_is_enabled(const dict_table_t* table)
93 MY_ATTRIBUTE((nonnull, warn_unused_result));
94
95/*********************************************************************//**
96Initialize table's stats for the first time when opening a table. */
97UNIV_INLINE
98void
99dict_stats_init(
100/*============*/
101 dict_table_t* table); /*!< in/out: table */
102
103/*********************************************************************//**
104Deinitialize table's stats after the last close of the table. This is
105used to detect "FLUSH TABLE" and refresh the stats upon next open. */
106UNIV_INLINE
107void
108dict_stats_deinit(
109/*==============*/
110 dict_table_t* table) /*!< in/out: table */
111 MY_ATTRIBUTE((nonnull));
112
113/** Update the table modification counter and if necessary,
114schedule new estimates for table and index statistics to be calculated.
115@param[in,out] table persistent or temporary table */
116void
117dict_stats_update_if_needed(dict_table_t* table)
118 MY_ATTRIBUTE((nonnull));
119
120/*********************************************************************//**
121Calculates new estimates for table and index statistics. The statistics
122are used in query optimization.
123@return DB_* error code or DB_SUCCESS */
124dberr_t
125dict_stats_update(
126/*==============*/
127 dict_table_t* table, /*!< in/out: table */
128 dict_stats_upd_option_t stats_upd_option);
129 /*!< in: whether to (re) calc
130 the stats or to fetch them from
131 the persistent storage */
132
133/*********************************************************************//**
134Removes the information for a particular index's stats from the persistent
135storage if it exists and if there is data stored for this index.
136This function creates its own trx and commits it.
137@return DB_SUCCESS or error code */
138dberr_t
139dict_stats_drop_index(
140/*==================*/
141 const char* tname, /*!< in: table name */
142 const char* iname, /*!< in: index name */
143 char* errstr, /*!< out: error message if != DB_SUCCESS
144 is returned */
145 ulint errstr_sz);/*!< in: size of the errstr buffer */
146
147/*********************************************************************//**
148Removes the statistics for a table and all of its indexes from the
149persistent storage if it exists and if there is data stored for the table.
150This function creates its own transaction and commits it.
151@return DB_SUCCESS or error code */
152dberr_t
153dict_stats_drop_table(
154/*==================*/
155 const char* table_name, /*!< in: table name */
156 char* errstr, /*!< out: error message
157 if != DB_SUCCESS is returned */
158 ulint errstr_sz); /*!< in: size of errstr buffer */
159
160/*********************************************************************//**
161Fetches or calculates new estimates for index statistics. */
162void
163dict_stats_update_for_index(
164/*========================*/
165 dict_index_t* index) /*!< in/out: index */
166 MY_ATTRIBUTE((nonnull));
167
168/*********************************************************************//**
169Renames a table in InnoDB persistent stats storage.
170This function creates its own transaction and commits it.
171@return DB_SUCCESS or error code */
172dberr_t
173dict_stats_rename_table(
174/*====================*/
175 const char* old_name, /*!< in: old table name */
176 const char* new_name, /*!< in: new table name */
177 char* errstr, /*!< out: error string if != DB_SUCCESS
178 is returned */
179 size_t errstr_sz); /*!< in: errstr size */
180#ifdef MYSQL_RENAME_INDEX
181/*********************************************************************//**
182Renames an index in InnoDB persistent stats storage.
183This function creates its own transaction and commits it.
184@return DB_SUCCESS or error code. DB_STATS_DO_NOT_EXIST will be returned
185if the persistent stats do not exist. */
186dberr_t
187dict_stats_rename_index(
188/*====================*/
189 const dict_table_t* table, /*!< in: table whose index
190 is renamed */
191 const char* old_index_name, /*!< in: old index name */
192 const char* new_index_name) /*!< in: new index name */
193 __attribute__((warn_unused_result));
194#endif /* MYSQL_RENAME_INDEX */
195
196/** Save an individual index's statistic into the persistent statistics
197storage.
198@param[in] index index to be updated
199@param[in] last_update timestamp of the stat
200@param[in] stat_name name of the stat
201@param[in] stat_value value of the stat
202@param[in] sample_size n pages sampled or NULL
203@param[in] stat_description description of the stat
204@param[in,out] trx in case of NULL the function will
205allocate and free the trx object. If it is not NULL then it will be
206rolled back only in the case of error, but not freed.
207@return DB_SUCCESS or error code */
208dberr_t
209dict_stats_save_index_stat(
210 dict_index_t* index,
211 ib_time_t last_update,
212 const char* stat_name,
213 ib_uint64_t stat_value,
214 ib_uint64_t* sample_size,
215 const char* stat_description,
216 trx_t* trx);
217
218/** Report an error if updating table statistics failed because
219.ibd file is missing, table decryption failed or table is corrupted.
220@param[in,out] table Table
221@param[in] defragment true if statistics is for defragment
222@retval DB_DECRYPTION_FAILED if decryption of the table failed
223@retval DB_TABLESPACE_DELETED if .ibd file is missing
224@retval DB_CORRUPTION if table is marked as corrupted */
225dberr_t
226dict_stats_report_error(dict_table_t* table, bool defragment = false)
227 MY_ATTRIBUTE((nonnull, warn_unused_result));
228
229#include "dict0stats.ic"
230
231#ifdef UNIV_ENABLE_UNIT_TEST_DICT_STATS
232void test_dict_stats_all();
233#endif /* UNIV_ENABLE_UNIT_TEST_DICT_STATS */
234
235#endif /* dict0stats_h */
236