1 /*****************************************************************************
2 
3 Copyright (c) 2007, 2011, Oracle and/or its affiliates. All Rights Reserved.
4 
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License, version 2.0,
7 as published by the Free Software Foundation.
8 
9 This program is also distributed with certain software (including
10 but not limited to OpenSSL) that is licensed under separate terms,
11 as designated in a particular file or component or in included license
12 documentation.  The authors of MySQL hereby grant you an additional
13 permission to link the program and your derivative works with the
14 separately licensed software that they have included with MySQL.
15 
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 GNU General Public License, version 2.0, for more details.
20 
21 You should have received a copy of the GNU General Public License along with
22 this program; if not, write to the Free Software Foundation, Inc.,
23 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
24 
25 *****************************************************************************/
26 
27 /**************************************************//**
28 @file include/trx0i_s.h
29 INFORMATION SCHEMA innodb_trx, innodb_locks and
30 innodb_lock_waits tables cache structures and public
31 functions.
32 
33 Created July 17, 2007 Vasil Dimov
34 *******************************************************/
35 
36 #ifndef trx0i_s_h
37 #define trx0i_s_h
38 
39 #include "univ.i"
40 #include "trx0types.h"
41 #include "dict0types.h"
42 #include "ut0ut.h"
43 
44 /** The maximum amount of memory that can be consumed by innodb_trx,
45 innodb_locks and innodb_lock_waits information schema tables. */
46 #define TRX_I_S_MEM_LIMIT		16777216 /* 16 MiB */
47 
48 /** The maximum length of a string that can be stored in
49 i_s_locks_row_t::lock_data */
50 #define TRX_I_S_LOCK_DATA_MAX_LEN	8192
51 
52 /** The maximum length of a string that can be stored in
53 i_s_trx_row_t::trx_query */
54 #define TRX_I_S_TRX_QUERY_MAX_LEN	1024
55 
56 /** The maximum length of a string that can be stored in
57 i_s_trx_row_t::trx_operation_state */
58 #define TRX_I_S_TRX_OP_STATE_MAX_LEN	64
59 
60 /** The maximum length of a string that can be stored in
61 i_s_trx_row_t::trx_foreign_key_error */
62 #define TRX_I_S_TRX_FK_ERROR_MAX_LEN	256
63 
64 /** The maximum length of a string that can be stored in
65 i_s_trx_row_t::trx_isolation_level */
66 #define TRX_I_S_TRX_ISOLATION_LEVEL_MAX_LEN	16
67 
68 /** Safely copy strings in to the INNODB_TRX table's
69 string based columns */
70 #define TRX_I_S_STRING_COPY(data, field, constraint, tcache)	\
71 do {								\
72 	if (strlen(data) > constraint) {			\
73 		char	buff[constraint + 1];			\
74 		strncpy(buff, data, constraint);		\
75 		buff[constraint] = '\0';			\
76 								\
77 		field = static_cast<const char*>(		\
78 			ha_storage_put_memlim(			\
79 			(tcache)->storage, buff, constraint + 1,\
80 			MAX_ALLOWED_FOR_STORAGE(tcache)));	\
81 	} else {						\
82 		field = static_cast<const char*>(		\
83 			ha_storage_put_str_memlim(		\
84 			(tcache)->storage, data,		\
85 			MAX_ALLOWED_FOR_STORAGE(tcache)));	\
86 	}							\
87 } while (0)
88 
89 /** A row of INFORMATION_SCHEMA.innodb_locks */
90 struct i_s_locks_row_t;
91 
92 /** Objects of trx_i_s_cache_t::locks_hash */
93 struct i_s_hash_chain_t;
94 
95 /** Objects of this type are added to the hash table
96 trx_i_s_cache_t::locks_hash */
97 struct i_s_hash_chain_t {
98 	i_s_locks_row_t*	value;	/*!< row of
99 					INFORMATION_SCHEMA.innodb_locks*/
100 	i_s_hash_chain_t*	next;	/*!< next item in the hash chain */
101 };
102 
103 /** This structure represents INFORMATION_SCHEMA.innodb_locks row */
104 struct i_s_locks_row_t {
105 	trx_id_t	lock_trx_id;	/*!< transaction identifier */
106 	const char*	lock_mode;	/*!< lock mode from
107 					lock_get_mode_str() */
108 	const char*	lock_type;	/*!< lock type from
109 					lock_get_type_str() */
110 	const char*	lock_table;	/*!< table name from
111 					lock_get_table_name() */
112 	const char*	lock_index;	/*!< index name from
113 					lock_rec_get_index_name() */
114 	/** Information for record locks.  All these are
115 	ULINT_UNDEFINED for table locks. */
116 	/* @{ */
117 	ulint		lock_space;	/*!< tablespace identifier */
118 	ulint		lock_page;	/*!< page number within the_space */
119 	ulint		lock_rec;	/*!< heap number of the record
120 					on the page */
121 	const char*	lock_data;	/*!< (some) content of the record */
122 	/* @} */
123 
124 	/** The following are auxiliary and not included in the table */
125 	/* @{ */
126 	table_id_t	lock_table_id;
127 					/*!< table identifier from
128 					lock_get_table_id */
129 	i_s_hash_chain_t hash_chain;	/*!< hash table chain node for
130 					trx_i_s_cache_t::locks_hash */
131 	/* @} */
132 };
133 
134 /** This structure represents INFORMATION_SCHEMA.innodb_trx row */
135 struct i_s_trx_row_t {
136 	trx_id_t		trx_id;		/*!< transaction identifier */
137 	const char*		trx_state;	/*!< transaction state from
138 						trx_get_que_state_str() */
139 	ib_time_t		trx_started;	/*!< trx_t::start_time */
140 	const i_s_locks_row_t*	requested_lock_row;
141 					/*!< pointer to a row
142 					in innodb_locks if trx
143 					is waiting, or NULL */
144 	ib_time_t	trx_wait_started; /*!< trx_t::wait_started */
145 	ullint		trx_weight;	/*!< TRX_WEIGHT() */
146 	ulint		trx_mysql_thread_id; /*!< thd_get_thread_id() */
147 	const char*	trx_query;	/*!< MySQL statement being
148 					executed in the transaction */
149 	struct charset_info_st*	trx_query_cs;
150 					/*!< charset encode the MySQL
151 					statement */
152 	const char*	trx_operation_state; /*!< trx_t::op_info */
153 	ulint		trx_tables_in_use;/*!< n_mysql_tables_in_use in
154 					 trx_t */
155 	ulint		trx_tables_locked;
156 					/*!< mysql_n_tables_locked in
157 					trx_t */
158 	ulint		trx_lock_structs;/*!< list len of trx_locks in
159 					trx_t */
160 	ulint		trx_lock_memory_bytes;
161 					/*!< mem_heap_get_size(
162 					trx->lock_heap) */
163 	ulint		trx_rows_locked;/*!< lock_number_of_rows_locked() */
164 	ullint		trx_rows_modified;/*!< trx_t::undo_no */
165 	ulint		trx_concurrency_tickets;
166 					/*!< n_tickets_to_enter_innodb in
167 					trx_t */
168 	const char*	trx_isolation_level;
169 					/*!< isolation_level in trx_t */
170 	ibool		trx_unique_checks;
171 					/*!< check_unique_secondary in trx_t*/
172 	ibool		trx_foreign_key_checks;
173 					/*!< check_foreigns in trx_t */
174 	const char*	trx_foreign_key_error;
175 					/*!< detailed_error in trx_t */
176 	ibool		trx_has_search_latch;
177 					/*!< has_search_latch in trx_t */
178 	ulint		trx_search_latch_timeout;
179 					/*!< search_latch_timeout in trx_t */
180 	ulint		trx_is_read_only;
181 					/*!< trx_t::read_only */
182 	ulint		trx_is_autocommit_non_locking;
183 					/*!< trx_is_autocommit_non_locking(trx)
184 					*/
185 };
186 
187 /** This structure represents INFORMATION_SCHEMA.innodb_lock_waits row */
188 struct i_s_lock_waits_row_t {
189 	const i_s_locks_row_t*	requested_lock_row;	/*!< requested lock */
190 	const i_s_locks_row_t*	blocking_lock_row;	/*!< blocking lock */
191 };
192 
193 /** Cache of INFORMATION_SCHEMA table data */
194 struct trx_i_s_cache_t;
195 
196 /** Auxiliary enum used by functions that need to select one of the
197 INFORMATION_SCHEMA tables */
198 enum i_s_table {
199 	I_S_INNODB_TRX,		/*!< INFORMATION_SCHEMA.innodb_trx */
200 	I_S_INNODB_LOCKS,	/*!< INFORMATION_SCHEMA.innodb_locks */
201 	I_S_INNODB_LOCK_WAITS	/*!< INFORMATION_SCHEMA.innodb_lock_waits */
202 };
203 
204 /** This is the intermediate buffer where data needed to fill the
205 INFORMATION SCHEMA tables is fetched and later retrieved by the C++
206 code in handler/i_s.cc. */
207 extern trx_i_s_cache_t*	trx_i_s_cache;
208 
209 /*******************************************************************//**
210 Initialize INFORMATION SCHEMA trx related cache. */
211 UNIV_INTERN
212 void
213 trx_i_s_cache_init(
214 /*===============*/
215 	trx_i_s_cache_t*	cache);	/*!< out: cache to init */
216 /*******************************************************************//**
217 Free the INFORMATION SCHEMA trx related cache. */
218 UNIV_INTERN
219 void
220 trx_i_s_cache_free(
221 /*===============*/
222 	trx_i_s_cache_t*	cache);	/*!< in/out: cache to free */
223 
224 /*******************************************************************//**
225 Issue a shared/read lock on the tables cache. */
226 UNIV_INTERN
227 void
228 trx_i_s_cache_start_read(
229 /*=====================*/
230 	trx_i_s_cache_t*	cache);	/*!< in: cache */
231 
232 /*******************************************************************//**
233 Release a shared/read lock on the tables cache. */
234 UNIV_INTERN
235 void
236 trx_i_s_cache_end_read(
237 /*===================*/
238 	trx_i_s_cache_t*	cache);	/*!< in: cache */
239 
240 /*******************************************************************//**
241 Issue an exclusive/write lock on the tables cache. */
242 UNIV_INTERN
243 void
244 trx_i_s_cache_start_write(
245 /*======================*/
246 	trx_i_s_cache_t*	cache);	/*!< in: cache */
247 
248 /*******************************************************************//**
249 Release an exclusive/write lock on the tables cache. */
250 UNIV_INTERN
251 void
252 trx_i_s_cache_end_write(
253 /*====================*/
254 	trx_i_s_cache_t*	cache);	/*!< in: cache */
255 
256 
257 /*******************************************************************//**
258 Retrieves the number of used rows in the cache for a given
259 INFORMATION SCHEMA table.
260 @return	number of rows */
261 UNIV_INTERN
262 ulint
263 trx_i_s_cache_get_rows_used(
264 /*========================*/
265 	trx_i_s_cache_t*	cache,	/*!< in: cache */
266 	enum i_s_table		table);	/*!< in: which table */
267 
268 /*******************************************************************//**
269 Retrieves the nth row in the cache for a given INFORMATION SCHEMA
270 table.
271 @return	row */
272 UNIV_INTERN
273 void*
274 trx_i_s_cache_get_nth_row(
275 /*======================*/
276 	trx_i_s_cache_t*	cache,	/*!< in: cache */
277 	enum i_s_table		table,	/*!< in: which table */
278 	ulint			n);	/*!< in: row number */
279 
280 /*******************************************************************//**
281 Update the transactions cache if it has not been read for some time.
282 @return	0 - fetched, 1 - not */
283 UNIV_INTERN
284 int
285 trx_i_s_possibly_fetch_data_into_cache(
286 /*===================================*/
287 	trx_i_s_cache_t*	cache);	/*!< in/out: cache */
288 
289 /*******************************************************************//**
290 Returns TRUE if the data in the cache is truncated due to the memory
291 limit posed by TRX_I_S_MEM_LIMIT.
292 @return	TRUE if truncated */
293 UNIV_INTERN
294 ibool
295 trx_i_s_cache_is_truncated(
296 /*=======================*/
297 	trx_i_s_cache_t*	cache);	/*!< in: cache */
298 
299 /** The maximum length of a resulting lock_id_size in
300 trx_i_s_create_lock_id(), not including the terminating NUL.
301 ":%lu:%lu:%lu" -> 63 chars */
302 #define TRX_I_S_LOCK_ID_MAX_LEN	(TRX_ID_MAX_LEN + 63)
303 
304 /*******************************************************************//**
305 Crafts a lock id string from a i_s_locks_row_t object. Returns its
306 second argument. This function aborts if there is not enough space in
307 lock_id. Be sure to provide at least TRX_I_S_LOCK_ID_MAX_LEN + 1 if you
308 want to be 100% sure that it will not abort.
309 @return	resulting lock id */
310 UNIV_INTERN
311 char*
312 trx_i_s_create_lock_id(
313 /*===================*/
314 	const i_s_locks_row_t*	row,	/*!< in: innodb_locks row */
315 	char*			lock_id,/*!< out: resulting lock_id */
316 	ulint			lock_id_size);/*!< in: size of the lock id
317 					buffer */
318 
319 #endif /* trx0i_s_h */
320