1 /***************************************************************************** 2 3 Copyright (c) 2007, 2015, Oracle and/or its affiliates. All Rights Reserved. 4 Copyright (c) 2017, 2021, 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/trx0i_s.h 22 INFORMATION SCHEMA innodb_trx, innodb_locks and 23 innodb_lock_waits tables cache structures and public 24 functions. 25 26 Created July 17, 2007 Vasil Dimov 27 *******************************************************/ 28 29 #ifndef trx0i_s_h 30 #define trx0i_s_h 31 32 #include "trx0types.h" 33 #include "dict0types.h" 34 #include "buf0types.h" 35 36 /** The maximum amount of memory that can be consumed by innodb_trx, 37 innodb_locks and innodb_lock_waits information schema tables. */ 38 #define TRX_I_S_MEM_LIMIT 16777216 /* 16 MiB */ 39 40 /** The maximum length of a string that can be stored in 41 i_s_locks_row_t::lock_data */ 42 #define TRX_I_S_LOCK_DATA_MAX_LEN 8192 43 44 /** The maximum length of a string that can be stored in 45 i_s_trx_row_t::trx_query */ 46 #define TRX_I_S_TRX_QUERY_MAX_LEN 1024 47 48 /** The maximum length of a string that can be stored in 49 i_s_trx_row_t::trx_foreign_key_error */ 50 #define TRX_I_S_TRX_FK_ERROR_MAX_LEN 256 51 52 /** Safely copy strings in to the INNODB_TRX table's 53 string based columns */ 54 #define TRX_I_S_STRING_COPY(data, field, constraint, tcache) \ 55 do { \ 56 if (strlen(data) > constraint) { \ 57 char buff[constraint + 1]; \ 58 strncpy(buff, data, constraint); \ 59 buff[constraint] = '\0'; \ 60 \ 61 field = static_cast<const char*>( \ 62 ha_storage_put_memlim( \ 63 (tcache)->storage, buff, constraint + 1,\ 64 MAX_ALLOWED_FOR_STORAGE(tcache))); \ 65 } else { \ 66 field = static_cast<const char*>( \ 67 ha_storage_put_str_memlim( \ 68 (tcache)->storage, data, \ 69 MAX_ALLOWED_FOR_STORAGE(tcache))); \ 70 } \ 71 } while (0) 72 73 /** A row of INFORMATION_SCHEMA.innodb_locks */ 74 struct i_s_locks_row_t; 75 76 /** Objects of trx_i_s_cache_t::locks_hash */ 77 struct i_s_hash_chain_t; 78 79 /** Objects of this type are added to the hash table 80 trx_i_s_cache_t::locks_hash */ 81 struct i_s_hash_chain_t { 82 i_s_locks_row_t* value; /*!< row of 83 INFORMATION_SCHEMA.innodb_locks*/ 84 i_s_hash_chain_t* next; /*!< next item in the hash chain */ 85 }; 86 87 /** This structure represents INFORMATION_SCHEMA.innodb_locks row */ 88 struct i_s_locks_row_t { 89 trx_id_t lock_trx_id; /*!< transaction identifier */ 90 const char* lock_table; /*!< table name from 91 lock_get_table_name() */ 92 /** index name of a record lock; NULL for table locks */ 93 const char* lock_index; 94 /** page identifier of the record; (0,0) if !lock_index */ 95 page_id_t lock_page; 96 /** heap number of the record; 0 if !lock_index */ 97 uint16_t lock_rec; 98 /** lock mode corresponding to lock_mode_values_typelib */ 99 uint8_t lock_mode; 100 /** (some) content of the record, if available in the buffer pool; 101 NULL if !lock_index */ 102 const char* lock_data; 103 104 /** The following are auxiliary and not included in the table */ 105 /* @{ */ 106 table_id_t lock_table_id; 107 /*!< table identifier from 108 lock_get_table_id */ 109 i_s_hash_chain_t hash_chain; /*!< hash table chain node for 110 trx_i_s_cache_t::locks_hash */ 111 /* @} */ 112 }; 113 114 /** This structure represents INFORMATION_SCHEMA.innodb_trx row */ 115 struct i_s_trx_row_t { 116 trx_id_t trx_id; /*!< transaction identifier */ 117 const char* trx_state; /*!< transaction state from 118 trx_get_que_state_str() */ 119 time_t trx_started; /*!< trx_t::start_time */ 120 const i_s_locks_row_t* requested_lock_row; 121 /*!< pointer to a row 122 in innodb_locks if trx 123 is waiting, or NULL */ 124 time_t trx_wait_started; /*!< trx_t->lock.wait_started */ 125 uintmax_t trx_weight; /*!< TRX_WEIGHT() */ 126 ulint trx_mysql_thread_id; /*!< thd_get_thread_id() */ 127 const char* trx_query; /*!< MySQL statement being 128 executed in the transaction */ 129 CHARSET_INFO* trx_query_cs; /*!< the charset of trx_query */ 130 const char* trx_operation_state; /*!< trx_t::op_info */ 131 ulint trx_tables_in_use;/*!< n_mysql_tables_in_use in 132 trx_t */ 133 ulint trx_tables_locked; 134 /*!< mysql_n_tables_locked in 135 trx_t */ 136 ulint trx_lock_structs;/*!< list len of trx_locks in 137 trx_t */ 138 ulint trx_lock_memory_bytes; 139 /*!< mem_heap_get_size( 140 trx->lock_heap) */ 141 ulint trx_rows_locked;/*!< lock_number_of_rows_locked() */ 142 uintmax_t trx_rows_modified;/*!< trx_t::undo_no */ 143 uint trx_isolation_level; 144 /*!< trx_t::isolation_level */ 145 bool trx_unique_checks; 146 /*!< check_unique_secondary in trx_t*/ 147 bool trx_foreign_key_checks; 148 /*!< check_foreigns in trx_t */ 149 const char* trx_foreign_key_error; 150 /*!< detailed_error in trx_t */ 151 bool trx_is_read_only; 152 /*!< trx_t::read_only */ 153 bool trx_is_autocommit_non_locking; 154 /*!< trx:t::is_autocommit_non_locking() 155 */ 156 }; 157 158 /** This structure represents INFORMATION_SCHEMA.innodb_lock_waits row */ 159 struct i_s_lock_waits_row_t { 160 const i_s_locks_row_t* requested_lock_row; /*!< requested lock */ 161 const i_s_locks_row_t* blocking_lock_row; /*!< blocking lock */ 162 }; 163 164 /** Cache of INFORMATION_SCHEMA table data */ 165 struct trx_i_s_cache_t; 166 167 /** Auxiliary enum used by functions that need to select one of the 168 INFORMATION_SCHEMA tables */ 169 enum i_s_table { 170 I_S_INNODB_TRX, /*!< INFORMATION_SCHEMA.innodb_trx */ 171 I_S_INNODB_LOCKS, /*!< INFORMATION_SCHEMA.innodb_locks */ 172 I_S_INNODB_LOCK_WAITS /*!< INFORMATION_SCHEMA.innodb_lock_waits */ 173 }; 174 175 /** This is the intermediate buffer where data needed to fill the 176 INFORMATION SCHEMA tables is fetched and later retrieved by the C++ 177 code in handler/i_s.cc. */ 178 extern trx_i_s_cache_t* trx_i_s_cache; 179 180 /*******************************************************************//** 181 Initialize INFORMATION SCHEMA trx related cache. */ 182 void 183 trx_i_s_cache_init( 184 /*===============*/ 185 trx_i_s_cache_t* cache); /*!< out: cache to init */ 186 /*******************************************************************//** 187 Free the INFORMATION SCHEMA trx related cache. */ 188 void 189 trx_i_s_cache_free( 190 /*===============*/ 191 trx_i_s_cache_t* cache); /*!< in/out: cache to free */ 192 193 /*******************************************************************//** 194 Issue a shared/read lock on the tables cache. */ 195 void 196 trx_i_s_cache_start_read( 197 /*=====================*/ 198 trx_i_s_cache_t* cache); /*!< in: cache */ 199 200 /*******************************************************************//** 201 Release a shared/read lock on the tables cache. */ 202 void 203 trx_i_s_cache_end_read( 204 /*===================*/ 205 trx_i_s_cache_t* cache); /*!< in: cache */ 206 207 /*******************************************************************//** 208 Issue an exclusive/write lock on the tables cache. */ 209 void 210 trx_i_s_cache_start_write( 211 /*======================*/ 212 trx_i_s_cache_t* cache); /*!< in: cache */ 213 214 /*******************************************************************//** 215 Release an exclusive/write lock on the tables cache. */ 216 void 217 trx_i_s_cache_end_write( 218 /*====================*/ 219 trx_i_s_cache_t* cache); /*!< in: cache */ 220 221 222 /*******************************************************************//** 223 Retrieves the number of used rows in the cache for a given 224 INFORMATION SCHEMA table. 225 @return number of rows */ 226 ulint 227 trx_i_s_cache_get_rows_used( 228 /*========================*/ 229 trx_i_s_cache_t* cache, /*!< in: cache */ 230 enum i_s_table table); /*!< in: which table */ 231 232 /*******************************************************************//** 233 Retrieves the nth row in the cache for a given INFORMATION SCHEMA 234 table. 235 @return row */ 236 void* 237 trx_i_s_cache_get_nth_row( 238 /*======================*/ 239 trx_i_s_cache_t* cache, /*!< in: cache */ 240 enum i_s_table table, /*!< in: which table */ 241 ulint n); /*!< in: row number */ 242 243 /*******************************************************************//** 244 Update the transactions cache if it has not been read for some time. 245 @return 0 - fetched, 1 - not */ 246 int 247 trx_i_s_possibly_fetch_data_into_cache( 248 /*===================================*/ 249 trx_i_s_cache_t* cache); /*!< in/out: cache */ 250 251 /*******************************************************************//** 252 Returns true, if the data in the cache is truncated due to the memory 253 limit posed by TRX_I_S_MEM_LIMIT. 254 @return TRUE if truncated */ 255 bool 256 trx_i_s_cache_is_truncated( 257 /*=======================*/ 258 trx_i_s_cache_t* cache); /*!< in: cache */ 259 /** The maximum length of a resulting lock_id_size in 260 trx_i_s_create_lock_id(), not including the terminating NUL. 261 ":%lu:%lu:%lu" -> 63 chars */ 262 #define TRX_I_S_LOCK_ID_MAX_LEN (TRX_ID_MAX_LEN + 63) 263 264 /*******************************************************************//** 265 Crafts a lock id string from a i_s_locks_row_t object. Returns its 266 second argument. This function aborts if there is not enough space in 267 lock_id. Be sure to provide at least TRX_I_S_LOCK_ID_MAX_LEN + 1 if you 268 want to be 100% sure that it will not abort. 269 @return resulting lock id */ 270 char* 271 trx_i_s_create_lock_id( 272 /*===================*/ 273 const i_s_locks_row_t* row, /*!< in: innodb_locks row */ 274 char* lock_id,/*!< out: resulting lock_id */ 275 ulint lock_id_size);/*!< in: size of the lock id 276 buffer */ 277 278 #endif /* trx0i_s_h */ 279