| 1 | /***************************************************************************** |
| 2 | |
| 3 | Copyright (c) 2009, 2016, Oracle and/or its affiliates. All Rights Reserved. |
| 4 | Copyright (c) 2017, 2018, 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, Suite 500, 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 "univ.i" |
| 31 | |
| 32 | #include "dict0types.h" |
| 33 | #include "trx0types.h" |
| 34 | |
| 35 | enum 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 | /*********************************************************************//** |
| 58 | Set the persistent statistics flag for a given table. This is set only |
| 59 | in the in-memory table object and is not saved on disk. It will be read |
| 60 | from the .frm file upon first open from MySQL after a server restart. */ |
| 61 | UNIV_INLINE |
| 62 | void |
| 63 | dict_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 */ |
| 71 | UNIV_INLINE |
| 72 | bool |
| 73 | dict_stats_is_persistent_enabled(const dict_table_t* table) |
| 74 | MY_ATTRIBUTE((nonnull, warn_unused_result)); |
| 75 | |
| 76 | /*********************************************************************//** |
| 77 | Set the auto recalc flag for a given table (only honored for a persistent |
| 78 | stats enabled table). The flag is set only in the in-memory table object |
| 79 | and is not saved in InnoDB files. It will be read from the .frm file upon |
| 80 | first open from MySQL after a server restart. */ |
| 81 | UNIV_INLINE |
| 82 | void |
| 83 | dict_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*/ |
| 90 | UNIV_INLINE |
| 91 | bool |
| 92 | dict_stats_auto_recalc_is_enabled(const dict_table_t* table) |
| 93 | MY_ATTRIBUTE((nonnull, warn_unused_result)); |
| 94 | |
| 95 | /*********************************************************************//** |
| 96 | Initialize table's stats for the first time when opening a table. */ |
| 97 | UNIV_INLINE |
| 98 | void |
| 99 | dict_stats_init( |
| 100 | /*============*/ |
| 101 | dict_table_t* table); /*!< in/out: table */ |
| 102 | |
| 103 | /*********************************************************************//** |
| 104 | Deinitialize table's stats after the last close of the table. This is |
| 105 | used to detect "FLUSH TABLE" and refresh the stats upon next open. */ |
| 106 | UNIV_INLINE |
| 107 | void |
| 108 | dict_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, |
| 114 | schedule new estimates for table and index statistics to be calculated. |
| 115 | @param[in,out] table persistent or temporary table */ |
| 116 | void |
| 117 | dict_stats_update_if_needed(dict_table_t* table) |
| 118 | MY_ATTRIBUTE((nonnull)); |
| 119 | |
| 120 | /*********************************************************************//** |
| 121 | Calculates new estimates for table and index statistics. The statistics |
| 122 | are used in query optimization. |
| 123 | @return DB_* error code or DB_SUCCESS */ |
| 124 | dberr_t |
| 125 | dict_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 | /*********************************************************************//** |
| 134 | Removes the information for a particular index's stats from the persistent |
| 135 | storage if it exists and if there is data stored for this index. |
| 136 | This function creates its own trx and commits it. |
| 137 | @return DB_SUCCESS or error code */ |
| 138 | dberr_t |
| 139 | dict_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 | /*********************************************************************//** |
| 148 | Removes the statistics for a table and all of its indexes from the |
| 149 | persistent storage if it exists and if there is data stored for the table. |
| 150 | This function creates its own transaction and commits it. |
| 151 | @return DB_SUCCESS or error code */ |
| 152 | dberr_t |
| 153 | dict_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 | /*********************************************************************//** |
| 161 | Fetches or calculates new estimates for index statistics. */ |
| 162 | void |
| 163 | dict_stats_update_for_index( |
| 164 | /*========================*/ |
| 165 | dict_index_t* index) /*!< in/out: index */ |
| 166 | MY_ATTRIBUTE((nonnull)); |
| 167 | |
| 168 | /*********************************************************************//** |
| 169 | Renames a table in InnoDB persistent stats storage. |
| 170 | This function creates its own transaction and commits it. |
| 171 | @return DB_SUCCESS or error code */ |
| 172 | dberr_t |
| 173 | dict_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 | /*********************************************************************//** |
| 182 | Renames an index in InnoDB persistent stats storage. |
| 183 | This function creates its own transaction and commits it. |
| 184 | @return DB_SUCCESS or error code. DB_STATS_DO_NOT_EXIST will be returned |
| 185 | if the persistent stats do not exist. */ |
| 186 | dberr_t |
| 187 | dict_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 |
| 197 | storage. |
| 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 |
| 205 | allocate and free the trx object. If it is not NULL then it will be |
| 206 | rolled back only in the case of error, but not freed. |
| 207 | @return DB_SUCCESS or error code */ |
| 208 | dberr_t |
| 209 | dict_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 */ |
| 225 | dberr_t |
| 226 | dict_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 |
| 232 | void test_dict_stats_all(); |
| 233 | #endif /* UNIV_ENABLE_UNIT_TEST_DICT_STATS */ |
| 234 | |
| 235 | #endif /* dict0stats_h */ |
| 236 | |