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