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