1 /*****************************************************************************
2
3 Copyright (c) 2007, 2013, Innobase Oy. All Rights Reserved.
4
5 This program is free software; you can redistribute it and/or modify it under
6 the terms of the GNU General Public License as published by the Free Software
7 Foundation; version 2 of the License.
8
9 This program is distributed in the hope that it will be useful, but WITHOUT
10 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License along with
14 this program; if not, write to the Free Software Foundation, Inc.,
15 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
16
17 *****************************************************************************/
18
19 /**************************************************//**
20 @file handler/i_s.cc
21 InnoDB INFORMATION SCHEMA tables interface to MySQL.
22
23 Created July 18, 2007 Vasil Dimov
24 *******************************************************/
25
26 #include <mysqld_error.h>
27 #include <sql_acl.h>
28
29 #include <m_ctype.h>
30 #include <hash.h>
31 #include <myisampack.h>
32 #include <mysys_err.h>
33 #include <my_sys.h>
34 #include "i_s.h"
35 #include <sql_plugin.h>
36 #include <mysql/innodb_priv.h>
37
38 extern "C" {
39 #include "btr0types.h"
40 #include "buf0buddy.h"
41 #include "buf0buf.h"
42 #include "ibuf0ibuf.h"
43 #include "dict0mem.h"
44 #include "dict0types.h"
45 #include "dict0boot.h"
46 #include "ha_prototypes.h"
47 #include "srv0start.h"
48 #include "trx0i_s.h"
49 #include "trx0trx.h"
50 #include "btr0btr.h"
51 #include "page0zip.h"
52 #include "log0log.h"
53 }
54
55 /** structure associates a name string with a file page type and/or buffer
56 page state. */
57 struct buffer_page_desc_str_struct{
58 const char* type_str; /*!< String explain the page
59 type/state */
60 ulint type_value; /*!< Page type or page state */
61 };
62
63 typedef struct buffer_page_desc_str_struct buf_page_desc_str_t;
64
65 /** Change buffer B-tree page */
66 #define I_S_PAGE_TYPE_IBUF (FIL_PAGE_TYPE_LAST + 1)
67
68 /** Any states greater than I_S_PAGE_TYPE_IBUF would be treated as
69 unknown. */
70 #define I_S_PAGE_TYPE_UNKNOWN (I_S_PAGE_TYPE_IBUF + 1)
71
72 /** We also define I_S_PAGE_TYPE_INDEX as the Index Page's position
73 in i_s_page_type[] array */
74 #define I_S_PAGE_TYPE_INDEX 1
75
76 /** Name string for File Page Types */
77 static buf_page_desc_str_t i_s_page_type[] = {
78 {"ALLOCATED", FIL_PAGE_TYPE_ALLOCATED},
79 {"INDEX", FIL_PAGE_INDEX},
80 {"UNDO_LOG", FIL_PAGE_UNDO_LOG},
81 {"INODE", FIL_PAGE_INODE},
82 {"IBUF_FREE_LIST", FIL_PAGE_IBUF_FREE_LIST},
83 {"IBUF_BITMAP", FIL_PAGE_IBUF_BITMAP},
84 {"SYSTEM", FIL_PAGE_TYPE_SYS},
85 {"TRX_SYSTEM", FIL_PAGE_TYPE_TRX_SYS},
86 {"FILE_SPACE_HEADER", FIL_PAGE_TYPE_FSP_HDR},
87 {"EXTENT_DESCRIPTOR", FIL_PAGE_TYPE_XDES},
88 {"BLOB", FIL_PAGE_TYPE_BLOB},
89 {"COMPRESSED_BLOB", FIL_PAGE_TYPE_ZBLOB},
90 {"COMPRESSED_BLOB2", FIL_PAGE_TYPE_ZBLOB2},
91 {"IBUF_INDEX", I_S_PAGE_TYPE_IBUF},
92 {"UNKNOWN", I_S_PAGE_TYPE_UNKNOWN}
93 };
94
95 /* Check if we can hold all page type in a 4 bit value */
96 #if I_S_PAGE_TYPE_UNKNOWN > 1<<4
97 # error "i_s_page_type[] is too large"
98 #endif
99
100 /** This structure defines information we will fetch from pages
101 currently cached in the buffer pool. It will be used to populate
102 table INFORMATION_SCHEMA.INNODB_BUFFER_PAGE */
103 struct buffer_page_info_struct{
104 ulint block_id; /*!< Buffer Pool block ID */
105 unsigned space_id:32; /*!< Tablespace ID */
106 unsigned page_num:32; /*!< Page number/offset */
107 unsigned access_time:32; /*!< Time of first access */
108 unsigned pool_id:MAX_BUFFER_POOLS_BITS;
109 /*!< Buffer Pool ID. Must be less than
110 MAX_BUFFER_POOLS */
111 unsigned flush_type:2; /*!< Flush type */
112 unsigned io_fix:2; /*!< type of pending I/O operation */
113 unsigned fix_count:19; /*!< Count of how manyfold this block
114 is bufferfixed */
115 unsigned hashed:1; /*!< Whether hash index has been
116 built on this page */
117 unsigned is_old:1; /*!< TRUE if the block is in the old
118 blocks in buf_pool->LRU_old */
119 unsigned freed_page_clock:31; /*!< the value of
120 buf_pool->freed_page_clock */
121 unsigned zip_ssize:PAGE_ZIP_SSIZE_BITS;
122 /*!< Compressed page size */
123 unsigned page_state:BUF_PAGE_STATE_BITS; /*!< Page state */
124 unsigned page_type:4; /*!< Page type */
125 unsigned num_recs:UNIV_PAGE_SIZE_SHIFT-2;
126 /*!< Number of records on Page */
127 unsigned data_size:UNIV_PAGE_SIZE_SHIFT;
128 /*!< Sum of the sizes of the records */
129 lsn_t newest_mod; /*!< Log sequence number of
130 the youngest modification */
131 lsn_t oldest_mod; /*!< Log sequence number of
132 the oldest modification */
133 index_id_t index_id; /*!< Index ID if a index page */
134 };
135
136 typedef struct buffer_page_info_struct buf_page_info_t;
137
138 /** maximum number of buffer page info we would cache. */
139 #define MAX_BUF_INFO_CACHED 10000
140
141
142 #define OK(expr) \
143 if ((expr) != 0) { \
144 DBUG_RETURN(1); \
145 }
146
147 #define RETURN_IF_INNODB_NOT_STARTED(plugin_name) \
148 do { \
149 if (!srv_was_started) { \
150 push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, \
151 ER_CANT_FIND_SYSTEM_REC, \
152 "InnoDB: SELECTing from " \
153 "INFORMATION_SCHEMA.%s but " \
154 "the InnoDB storage engine " \
155 "is not installed", plugin_name); \
156 DBUG_RETURN(0); \
157 } \
158 } while (0)
159
160 #if !defined __STRICT_ANSI__ && defined __GNUC__ && (__GNUC__) > 2 && !defined __INTEL_COMPILER
161 #define STRUCT_FLD(name, value) name: value
162 #else
163 #define STRUCT_FLD(name, value) value
164 #endif
165
166 /* Don't use a static const variable here, as some C++ compilers (notably
167 HPUX aCC: HP ANSI C++ B3910B A.03.65) can't handle it. */
168 #define END_OF_ST_FIELD_INFO \
169 {STRUCT_FLD(field_name, NULL), \
170 STRUCT_FLD(field_length, 0), \
171 STRUCT_FLD(field_type, MYSQL_TYPE_NULL), \
172 STRUCT_FLD(value, 0), \
173 STRUCT_FLD(field_flags, 0), \
174 STRUCT_FLD(old_name, ""), \
175 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}
176
177 /*
178 Use the following types mapping:
179
180 C type ST_FIELD_INFO::field_type
181 ---------------------------------
182 long MYSQL_TYPE_LONGLONG
183 (field_length=MY_INT64_NUM_DECIMAL_DIGITS)
184
185 long unsigned MYSQL_TYPE_LONGLONG
186 (field_length=MY_INT64_NUM_DECIMAL_DIGITS, field_flags=MY_I_S_UNSIGNED)
187
188 char* MYSQL_TYPE_STRING
189 (field_length=n)
190
191 float MYSQL_TYPE_FLOAT
192 (field_length=0 is ignored)
193
194 void* MYSQL_TYPE_LONGLONG
195 (field_length=MY_INT64_NUM_DECIMAL_DIGITS, field_flags=MY_I_S_UNSIGNED)
196
197 boolean (if else) MYSQL_TYPE_LONG
198 (field_length=1)
199
200 time_t MYSQL_TYPE_DATETIME
201 (field_length=0 ignored)
202 ---------------------------------
203 */
204
205 /*******************************************************************//**
206 Common function to fill any of the dynamic tables:
207 INFORMATION_SCHEMA.innodb_trx
208 INFORMATION_SCHEMA.innodb_locks
209 INFORMATION_SCHEMA.innodb_lock_waits
210 @return 0 on success */
211 static
212 int
213 trx_i_s_common_fill_table(
214 /*======================*/
215 THD* thd, /*!< in: thread */
216 TABLE_LIST* tables, /*!< in/out: tables to fill */
217 COND* cond); /*!< in: condition (not used) */
218
219 /*******************************************************************//**
220 Unbind a dynamic INFORMATION_SCHEMA table.
221 @return 0 on success */
222 static
223 int
224 i_s_common_deinit(
225 /*==============*/
226 void* p); /*!< in/out: table schema object */
227 /*******************************************************************//**
228 Auxiliary function to store time_t value in MYSQL_TYPE_DATETIME
229 field.
230 @return 0 on success */
231 static
232 int
field_store_time_t(Field * field,time_t time)233 field_store_time_t(
234 /*===============*/
235 Field* field, /*!< in/out: target field for storage */
236 time_t time) /*!< in: value to store */
237 {
238 MYSQL_TIME my_time;
239 struct tm tm_time;
240
241 #if 0
242 /* use this if you are sure that `variables' and `time_zone'
243 are always initialized */
244 thd->variables.time_zone->gmt_sec_to_TIME(
245 &my_time, (my_time_t) time);
246 #else
247 localtime_r(&time, &tm_time);
248 localtime_to_TIME(&my_time, &tm_time);
249 my_time.time_type = MYSQL_TIMESTAMP_DATETIME;
250 #endif
251
252 return(field->store_time(&my_time, MYSQL_TIMESTAMP_DATETIME));
253 }
254
255 /*******************************************************************//**
256 Auxiliary function to store char* value in MYSQL_TYPE_STRING field.
257 @return 0 on success */
258 static
259 int
field_store_string(Field * field,const char * str)260 field_store_string(
261 /*===============*/
262 Field* field, /*!< in/out: target field for storage */
263 const char* str) /*!< in: NUL-terminated utf-8 string,
264 or NULL */
265 {
266 int ret;
267
268 if (str != NULL) {
269
270 ret = field->store(str, strlen(str),
271 system_charset_info);
272 field->set_notnull();
273 } else {
274
275 ret = 0; /* success */
276 field->set_null();
277 }
278
279 return(ret);
280 }
281
282 /*******************************************************************//**
283 Auxiliary function to store ulint value in MYSQL_TYPE_LONGLONG field.
284 If the value is ULINT_UNDEFINED then the field it set to NULL.
285 @return 0 on success */
286 static
287 int
field_store_ulint(Field * field,ulint n)288 field_store_ulint(
289 /*==============*/
290 Field* field, /*!< in/out: target field for storage */
291 ulint n) /*!< in: value to store */
292 {
293 int ret;
294
295 if (n != ULINT_UNDEFINED) {
296
297 ret = field->store(n);
298 field->set_notnull();
299 } else {
300
301 ret = 0; /* success */
302 field->set_null();
303 }
304
305 return(ret);
306 }
307
308 /* Fields of the dynamic table INFORMATION_SCHEMA.innodb_trx */
309 static ST_FIELD_INFO innodb_trx_fields_info[] =
310 {
311 #define IDX_TRX_ID 0
312 {STRUCT_FLD(field_name, "trx_id"),
313 STRUCT_FLD(field_length, TRX_ID_MAX_LEN + 1),
314 STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
315 STRUCT_FLD(value, 0),
316 STRUCT_FLD(field_flags, 0),
317 STRUCT_FLD(old_name, ""),
318 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
319
320 #define IDX_TRX_STATE 1
321 {STRUCT_FLD(field_name, "trx_state"),
322 STRUCT_FLD(field_length, TRX_QUE_STATE_STR_MAX_LEN + 1),
323 STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
324 STRUCT_FLD(value, 0),
325 STRUCT_FLD(field_flags, 0),
326 STRUCT_FLD(old_name, ""),
327 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
328
329 #define IDX_TRX_STARTED 2
330 {STRUCT_FLD(field_name, "trx_started"),
331 STRUCT_FLD(field_length, 0),
332 STRUCT_FLD(field_type, MYSQL_TYPE_DATETIME),
333 STRUCT_FLD(value, 0),
334 STRUCT_FLD(field_flags, 0),
335 STRUCT_FLD(old_name, ""),
336 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
337
338 #define IDX_TRX_REQUESTED_LOCK_ID 3
339 {STRUCT_FLD(field_name, "trx_requested_lock_id"),
340 STRUCT_FLD(field_length, TRX_I_S_LOCK_ID_MAX_LEN + 1),
341 STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
342 STRUCT_FLD(value, 0),
343 STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
344 STRUCT_FLD(old_name, ""),
345 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
346
347 #define IDX_TRX_WAIT_STARTED 4
348 {STRUCT_FLD(field_name, "trx_wait_started"),
349 STRUCT_FLD(field_length, 0),
350 STRUCT_FLD(field_type, MYSQL_TYPE_DATETIME),
351 STRUCT_FLD(value, 0),
352 STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
353 STRUCT_FLD(old_name, ""),
354 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
355
356 #define IDX_TRX_WEIGHT 5
357 {STRUCT_FLD(field_name, "trx_weight"),
358 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
359 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
360 STRUCT_FLD(value, 0),
361 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
362 STRUCT_FLD(old_name, ""),
363 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
364
365 #define IDX_TRX_MYSQL_THREAD_ID 6
366 {STRUCT_FLD(field_name, "trx_mysql_thread_id"),
367 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
368 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
369 STRUCT_FLD(value, 0),
370 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
371 STRUCT_FLD(old_name, ""),
372 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
373
374 #define IDX_TRX_QUERY 7
375 {STRUCT_FLD(field_name, "trx_query"),
376 STRUCT_FLD(field_length, TRX_I_S_TRX_QUERY_MAX_LEN),
377 STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
378 STRUCT_FLD(value, 0),
379 STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
380 STRUCT_FLD(old_name, ""),
381 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
382
383 #define IDX_TRX_OPERATION_STATE 8
384 {STRUCT_FLD(field_name, "trx_operation_state"),
385 STRUCT_FLD(field_length, TRX_I_S_TRX_OP_STATE_MAX_LEN),
386 STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
387 STRUCT_FLD(value, 0),
388 STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
389 STRUCT_FLD(old_name, ""),
390 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
391
392 #define IDX_TRX_TABLES_IN_USE 9
393 {STRUCT_FLD(field_name, "trx_tables_in_use"),
394 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
395 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
396 STRUCT_FLD(value, 0),
397 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
398 STRUCT_FLD(old_name, ""),
399 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
400
401 #define IDX_TRX_TABLES_LOCKED 10
402 {STRUCT_FLD(field_name, "trx_tables_locked"),
403 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
404 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
405 STRUCT_FLD(value, 0),
406 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
407 STRUCT_FLD(old_name, ""),
408 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
409
410 #define IDX_TRX_LOCK_STRUCTS 11
411 {STRUCT_FLD(field_name, "trx_lock_structs"),
412 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
413 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
414 STRUCT_FLD(value, 0),
415 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
416 STRUCT_FLD(old_name, ""),
417 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
418
419 #define IDX_TRX_LOCK_MEMORY_BYTES 12
420 {STRUCT_FLD(field_name, "trx_lock_memory_bytes"),
421 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
422 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
423 STRUCT_FLD(value, 0),
424 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
425 STRUCT_FLD(old_name, ""),
426 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
427
428 #define IDX_TRX_ROWS_LOCKED 13
429 {STRUCT_FLD(field_name, "trx_rows_locked"),
430 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
431 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
432 STRUCT_FLD(value, 0),
433 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
434 STRUCT_FLD(old_name, ""),
435 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
436
437 #define IDX_TRX_ROWS_MODIFIED 14
438 {STRUCT_FLD(field_name, "trx_rows_modified"),
439 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
440 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
441 STRUCT_FLD(value, 0),
442 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
443 STRUCT_FLD(old_name, ""),
444 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
445
446 #define IDX_TRX_CONNCURRENCY_TICKETS 15
447 {STRUCT_FLD(field_name, "trx_concurrency_tickets"),
448 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
449 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
450 STRUCT_FLD(value, 0),
451 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
452 STRUCT_FLD(old_name, ""),
453 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
454
455 #define IDX_TRX_ISOLATION_LEVEL 16
456 {STRUCT_FLD(field_name, "trx_isolation_level"),
457 STRUCT_FLD(field_length, TRX_I_S_TRX_ISOLATION_LEVEL_MAX_LEN),
458 STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
459 STRUCT_FLD(value, 0),
460 STRUCT_FLD(field_flags, 0),
461 STRUCT_FLD(old_name, ""),
462 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
463
464 #define IDX_TRX_UNIQUE_CHECKS 17
465 {STRUCT_FLD(field_name, "trx_unique_checks"),
466 STRUCT_FLD(field_length, 1),
467 STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
468 STRUCT_FLD(value, 1),
469 STRUCT_FLD(field_flags, 0),
470 STRUCT_FLD(old_name, ""),
471 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
472
473 #define IDX_TRX_FOREIGN_KEY_CHECKS 18
474 {STRUCT_FLD(field_name, "trx_foreign_key_checks"),
475 STRUCT_FLD(field_length, 1),
476 STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
477 STRUCT_FLD(value, 1),
478 STRUCT_FLD(field_flags, 0),
479 STRUCT_FLD(old_name, ""),
480 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
481
482 #define IDX_TRX_LAST_FOREIGN_KEY_ERROR 19
483 {STRUCT_FLD(field_name, "trx_last_foreign_key_error"),
484 STRUCT_FLD(field_length, TRX_I_S_TRX_FK_ERROR_MAX_LEN),
485 STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
486 STRUCT_FLD(value, 0),
487 STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
488 STRUCT_FLD(old_name, ""),
489 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
490
491 #define IDX_TRX_ADAPTIVE_HASH_LATCHED 20
492 {STRUCT_FLD(field_name, "trx_adaptive_hash_latched"),
493 STRUCT_FLD(field_length, 1),
494 STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
495 STRUCT_FLD(value, 0),
496 STRUCT_FLD(field_flags, 0),
497 STRUCT_FLD(old_name, ""),
498 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
499
500 #define IDX_TRX_ADAPTIVE_HASH_TIMEOUT 21
501 {STRUCT_FLD(field_name, "trx_adaptive_hash_timeout"),
502 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
503 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
504 STRUCT_FLD(value, 0),
505 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
506 STRUCT_FLD(old_name, ""),
507 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
508
509 END_OF_ST_FIELD_INFO
510 };
511
512 /*******************************************************************//**
513 Read data from cache buffer and fill the INFORMATION_SCHEMA.innodb_trx
514 table with it.
515 @return 0 on success */
516 static
517 int
fill_innodb_trx_from_cache(trx_i_s_cache_t * cache,THD * thd,TABLE * table)518 fill_innodb_trx_from_cache(
519 /*=======================*/
520 trx_i_s_cache_t* cache, /*!< in: cache to read from */
521 THD* thd, /*!< in: used to call
522 schema_table_store_record() */
523 TABLE* table) /*!< in/out: fill this table */
524 {
525 Field** fields;
526 ulint rows_num;
527 char lock_id[TRX_I_S_LOCK_ID_MAX_LEN + 1];
528 ulint i;
529
530 DBUG_ENTER("fill_innodb_trx_from_cache");
531
532 fields = table->field;
533
534 rows_num = trx_i_s_cache_get_rows_used(cache,
535 I_S_INNODB_TRX);
536
537 for (i = 0; i < rows_num; i++) {
538
539 i_s_trx_row_t* row;
540 char trx_id[TRX_ID_MAX_LEN + 1];
541
542 row = (i_s_trx_row_t*)
543 trx_i_s_cache_get_nth_row(
544 cache, I_S_INNODB_TRX, i);
545
546 /* trx_id */
547 ut_snprintf(trx_id, sizeof(trx_id), TRX_ID_FMT, row->trx_id);
548 OK(field_store_string(fields[IDX_TRX_ID], trx_id));
549
550 /* trx_state */
551 OK(field_store_string(fields[IDX_TRX_STATE],
552 row->trx_state));
553
554 /* trx_started */
555 OK(field_store_time_t(fields[IDX_TRX_STARTED],
556 (time_t) row->trx_started));
557
558 /* trx_requested_lock_id */
559 /* trx_wait_started */
560 if (row->trx_wait_started != 0) {
561
562 OK(field_store_string(
563 fields[IDX_TRX_REQUESTED_LOCK_ID],
564 trx_i_s_create_lock_id(
565 row->requested_lock_row,
566 lock_id, sizeof(lock_id))));
567 /* field_store_string() sets it no notnull */
568
569 OK(field_store_time_t(
570 fields[IDX_TRX_WAIT_STARTED],
571 (time_t) row->trx_wait_started));
572 fields[IDX_TRX_WAIT_STARTED]->set_notnull();
573 } else {
574
575 fields[IDX_TRX_REQUESTED_LOCK_ID]->set_null();
576 fields[IDX_TRX_WAIT_STARTED]->set_null();
577 }
578
579 /* trx_weight */
580 OK(fields[IDX_TRX_WEIGHT]->store((longlong) row->trx_weight,
581 true));
582
583 /* trx_mysql_thread_id */
584 OK(fields[IDX_TRX_MYSQL_THREAD_ID]->store(
585 row->trx_mysql_thread_id));
586
587 /* trx_query */
588 if (row->trx_query) {
589 /* store will do appropriate character set
590 conversion check */
591 fields[IDX_TRX_QUERY]->store(
592 row->trx_query, strlen(row->trx_query),
593 row->trx_query_cs);
594 fields[IDX_TRX_QUERY]->set_notnull();
595 } else {
596 fields[IDX_TRX_QUERY]->set_null();
597 }
598
599 /* trx_operation_state */
600 OK(field_store_string(fields[IDX_TRX_OPERATION_STATE],
601 row->trx_operation_state));
602
603 /* trx_tables_in_use */
604 OK(fields[IDX_TRX_TABLES_IN_USE]->store(
605 (longlong) row->trx_tables_in_use, true));
606
607 /* trx_tables_locked */
608 OK(fields[IDX_TRX_TABLES_LOCKED]->store(
609 (longlong) row->trx_tables_locked, true));
610
611 /* trx_lock_structs */
612 OK(fields[IDX_TRX_LOCK_STRUCTS]->store(
613 (longlong) row->trx_lock_structs, true));
614
615 /* trx_lock_memory_bytes */
616 OK(fields[IDX_TRX_LOCK_MEMORY_BYTES]->store(
617 (longlong) row->trx_lock_memory_bytes, true));
618
619 /* trx_rows_locked */
620 OK(fields[IDX_TRX_ROWS_LOCKED]->store(
621 (longlong) row->trx_rows_locked, true));
622
623 /* trx_rows_modified */
624 OK(fields[IDX_TRX_ROWS_MODIFIED]->store(
625 (longlong) row->trx_rows_modified, true));
626
627 /* trx_concurrency_tickets */
628 OK(fields[IDX_TRX_CONNCURRENCY_TICKETS]->store(
629 (longlong) row->trx_concurrency_tickets, true));
630
631 /* trx_isolation_level */
632 OK(field_store_string(fields[IDX_TRX_ISOLATION_LEVEL],
633 row->trx_isolation_level));
634
635 /* trx_unique_checks */
636 OK(fields[IDX_TRX_UNIQUE_CHECKS]->store(
637 row->trx_unique_checks));
638
639 /* trx_foreign_key_checks */
640 OK(fields[IDX_TRX_FOREIGN_KEY_CHECKS]->store(
641 row->trx_foreign_key_checks));
642
643 /* trx_last_foreign_key_error */
644 OK(field_store_string(fields[IDX_TRX_LAST_FOREIGN_KEY_ERROR],
645 row->trx_foreign_key_error));
646
647 /* trx_adaptive_hash_latched */
648 OK(fields[IDX_TRX_ADAPTIVE_HASH_LATCHED]->store(
649 row->trx_has_search_latch));
650
651 /* trx_adaptive_hash_timeout */
652 OK(fields[IDX_TRX_ADAPTIVE_HASH_TIMEOUT]->store(
653 (longlong) row->trx_search_latch_timeout, true));
654
655 OK(schema_table_store_record(thd, table));
656 }
657
658 DBUG_RETURN(0);
659 }
660
661 /*******************************************************************//**
662 Bind the dynamic table INFORMATION_SCHEMA.innodb_trx
663 @return 0 on success */
664 static
665 int
innodb_trx_init(void * p)666 innodb_trx_init(
667 /*============*/
668 void* p) /*!< in/out: table schema object */
669 {
670 ST_SCHEMA_TABLE* schema;
671
672 DBUG_ENTER("innodb_trx_init");
673
674 schema = (ST_SCHEMA_TABLE*) p;
675
676 schema->fields_info = innodb_trx_fields_info;
677 schema->fill_table = trx_i_s_common_fill_table;
678
679 DBUG_RETURN(0);
680 }
681
682 static struct st_mysql_information_schema i_s_info =
683 {
684 MYSQL_INFORMATION_SCHEMA_INTERFACE_VERSION
685 };
686
687 UNIV_INTERN struct st_mysql_plugin i_s_innodb_trx =
688 {
689 /* the plugin type (a MYSQL_XXX_PLUGIN value) */
690 /* int */
691 STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
692
693 /* pointer to type-specific plugin descriptor */
694 /* void* */
695 STRUCT_FLD(info, &i_s_info),
696
697 /* plugin name */
698 /* const char* */
699 STRUCT_FLD(name, "INNODB_TRX"),
700
701 /* plugin author (for SHOW PLUGINS) */
702 /* const char* */
703 STRUCT_FLD(author, plugin_author),
704
705 /* general descriptive text (for SHOW PLUGINS) */
706 /* const char* */
707 STRUCT_FLD(descr, "InnoDB transactions"),
708
709 /* the plugin license (PLUGIN_LICENSE_XXX) */
710 /* int */
711 STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
712
713 /* the function to invoke when plugin is loaded */
714 /* int (*)(void*); */
715 STRUCT_FLD(init, innodb_trx_init),
716
717 /* the function to invoke when plugin is unloaded */
718 /* int (*)(void*); */
719 STRUCT_FLD(deinit, i_s_common_deinit),
720
721 /* plugin version (for SHOW PLUGINS) */
722 /* unsigned int */
723 STRUCT_FLD(version, INNODB_VERSION_SHORT),
724
725 /* struct st_mysql_show_var* */
726 STRUCT_FLD(status_vars, NULL),
727
728 /* struct st_mysql_sys_var** */
729 STRUCT_FLD(system_vars, NULL),
730
731 /* reserved for dependency checking */
732 /* void* */
733 STRUCT_FLD(__reserved1, NULL),
734
735 /* Plugin flags */
736 /* unsigned long */
737 STRUCT_FLD(flags, 0UL),
738 };
739
740 /* Fields of the dynamic table INFORMATION_SCHEMA.innodb_locks */
741 static ST_FIELD_INFO innodb_locks_fields_info[] =
742 {
743 #define IDX_LOCK_ID 0
744 {STRUCT_FLD(field_name, "lock_id"),
745 STRUCT_FLD(field_length, TRX_I_S_LOCK_ID_MAX_LEN + 1),
746 STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
747 STRUCT_FLD(value, 0),
748 STRUCT_FLD(field_flags, 0),
749 STRUCT_FLD(old_name, ""),
750 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
751
752 #define IDX_LOCK_TRX_ID 1
753 {STRUCT_FLD(field_name, "lock_trx_id"),
754 STRUCT_FLD(field_length, TRX_ID_MAX_LEN + 1),
755 STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
756 STRUCT_FLD(value, 0),
757 STRUCT_FLD(field_flags, 0),
758 STRUCT_FLD(old_name, ""),
759 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
760
761 #define IDX_LOCK_MODE 2
762 {STRUCT_FLD(field_name, "lock_mode"),
763 /* S[,GAP] X[,GAP] IS[,GAP] IX[,GAP] AUTO_INC UNKNOWN */
764 STRUCT_FLD(field_length, 32),
765 STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
766 STRUCT_FLD(value, 0),
767 STRUCT_FLD(field_flags, 0),
768 STRUCT_FLD(old_name, ""),
769 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
770
771 #define IDX_LOCK_TYPE 3
772 {STRUCT_FLD(field_name, "lock_type"),
773 STRUCT_FLD(field_length, 32 /* RECORD|TABLE|UNKNOWN */),
774 STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
775 STRUCT_FLD(value, 0),
776 STRUCT_FLD(field_flags, 0),
777 STRUCT_FLD(old_name, ""),
778 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
779
780 #define IDX_LOCK_TABLE 4
781 {STRUCT_FLD(field_name, "lock_table"),
782 STRUCT_FLD(field_length, 1024),
783 STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
784 STRUCT_FLD(value, 0),
785 STRUCT_FLD(field_flags, 0),
786 STRUCT_FLD(old_name, ""),
787 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
788
789 #define IDX_LOCK_INDEX 5
790 {STRUCT_FLD(field_name, "lock_index"),
791 STRUCT_FLD(field_length, 1024),
792 STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
793 STRUCT_FLD(value, 0),
794 STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
795 STRUCT_FLD(old_name, ""),
796 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
797
798 #define IDX_LOCK_SPACE 6
799 {STRUCT_FLD(field_name, "lock_space"),
800 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
801 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
802 STRUCT_FLD(value, 0),
803 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED | MY_I_S_MAYBE_NULL),
804 STRUCT_FLD(old_name, ""),
805 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
806
807 #define IDX_LOCK_PAGE 7
808 {STRUCT_FLD(field_name, "lock_page"),
809 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
810 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
811 STRUCT_FLD(value, 0),
812 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED | MY_I_S_MAYBE_NULL),
813 STRUCT_FLD(old_name, ""),
814 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
815
816 #define IDX_LOCK_REC 8
817 {STRUCT_FLD(field_name, "lock_rec"),
818 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
819 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
820 STRUCT_FLD(value, 0),
821 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED | MY_I_S_MAYBE_NULL),
822 STRUCT_FLD(old_name, ""),
823 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
824
825 #define IDX_LOCK_DATA 9
826 {STRUCT_FLD(field_name, "lock_data"),
827 STRUCT_FLD(field_length, TRX_I_S_LOCK_DATA_MAX_LEN),
828 STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
829 STRUCT_FLD(value, 0),
830 STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
831 STRUCT_FLD(old_name, ""),
832 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
833
834 END_OF_ST_FIELD_INFO
835 };
836
837 /*******************************************************************//**
838 Read data from cache buffer and fill the INFORMATION_SCHEMA.innodb_locks
839 table with it.
840 @return 0 on success */
841 static
842 int
fill_innodb_locks_from_cache(trx_i_s_cache_t * cache,THD * thd,TABLE * table)843 fill_innodb_locks_from_cache(
844 /*=========================*/
845 trx_i_s_cache_t* cache, /*!< in: cache to read from */
846 THD* thd, /*!< in: MySQL client connection */
847 TABLE* table) /*!< in/out: fill this table */
848 {
849 Field** fields;
850 ulint rows_num;
851 char lock_id[TRX_I_S_LOCK_ID_MAX_LEN + 1];
852 ulint i;
853
854 DBUG_ENTER("fill_innodb_locks_from_cache");
855
856 fields = table->field;
857
858 rows_num = trx_i_s_cache_get_rows_used(cache,
859 I_S_INNODB_LOCKS);
860
861 for (i = 0; i < rows_num; i++) {
862
863 i_s_locks_row_t* row;
864 char buf[MAX_FULL_NAME_LEN + 1];
865 const char* bufend;
866
867 char lock_trx_id[TRX_ID_MAX_LEN + 1];
868
869 row = (i_s_locks_row_t*)
870 trx_i_s_cache_get_nth_row(
871 cache, I_S_INNODB_LOCKS, i);
872
873 /* lock_id */
874 trx_i_s_create_lock_id(row, lock_id, sizeof(lock_id));
875 OK(field_store_string(fields[IDX_LOCK_ID],
876 lock_id));
877
878 /* lock_trx_id */
879 ut_snprintf(lock_trx_id, sizeof(lock_trx_id),
880 TRX_ID_FMT, row->lock_trx_id);
881 OK(field_store_string(fields[IDX_LOCK_TRX_ID], lock_trx_id));
882
883 /* lock_mode */
884 OK(field_store_string(fields[IDX_LOCK_MODE],
885 row->lock_mode));
886
887 /* lock_type */
888 OK(field_store_string(fields[IDX_LOCK_TYPE],
889 row->lock_type));
890
891 /* lock_table */
892 bufend = innobase_convert_name(buf, sizeof(buf),
893 row->lock_table,
894 strlen(row->lock_table),
895 thd, TRUE);
896 OK(fields[IDX_LOCK_TABLE]->store(buf, bufend - buf,
897 system_charset_info));
898
899 /* lock_index */
900 if (row->lock_index != NULL) {
901
902 bufend = innobase_convert_name(buf, sizeof(buf),
903 row->lock_index,
904 strlen(row->lock_index),
905 thd, FALSE);
906 OK(fields[IDX_LOCK_INDEX]->store(buf, bufend - buf,
907 system_charset_info));
908 fields[IDX_LOCK_INDEX]->set_notnull();
909 } else {
910
911 fields[IDX_LOCK_INDEX]->set_null();
912 }
913
914 /* lock_space */
915 OK(field_store_ulint(fields[IDX_LOCK_SPACE],
916 row->lock_space));
917
918 /* lock_page */
919 OK(field_store_ulint(fields[IDX_LOCK_PAGE],
920 row->lock_page));
921
922 /* lock_rec */
923 OK(field_store_ulint(fields[IDX_LOCK_REC],
924 row->lock_rec));
925
926 /* lock_data */
927 OK(field_store_string(fields[IDX_LOCK_DATA],
928 row->lock_data));
929
930 OK(schema_table_store_record(thd, table));
931 }
932
933 DBUG_RETURN(0);
934 }
935
936 /*******************************************************************//**
937 Bind the dynamic table INFORMATION_SCHEMA.innodb_locks
938 @return 0 on success */
939 static
940 int
innodb_locks_init(void * p)941 innodb_locks_init(
942 /*==============*/
943 void* p) /*!< in/out: table schema object */
944 {
945 ST_SCHEMA_TABLE* schema;
946
947 DBUG_ENTER("innodb_locks_init");
948
949 schema = (ST_SCHEMA_TABLE*) p;
950
951 schema->fields_info = innodb_locks_fields_info;
952 schema->fill_table = trx_i_s_common_fill_table;
953
954 DBUG_RETURN(0);
955 }
956
957 UNIV_INTERN struct st_mysql_plugin i_s_innodb_locks =
958 {
959 /* the plugin type (a MYSQL_XXX_PLUGIN value) */
960 /* int */
961 STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
962
963 /* pointer to type-specific plugin descriptor */
964 /* void* */
965 STRUCT_FLD(info, &i_s_info),
966
967 /* plugin name */
968 /* const char* */
969 STRUCT_FLD(name, "INNODB_LOCKS"),
970
971 /* plugin author (for SHOW PLUGINS) */
972 /* const char* */
973 STRUCT_FLD(author, plugin_author),
974
975 /* general descriptive text (for SHOW PLUGINS) */
976 /* const char* */
977 STRUCT_FLD(descr, "InnoDB conflicting locks"),
978
979 /* the plugin license (PLUGIN_LICENSE_XXX) */
980 /* int */
981 STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
982
983 /* the function to invoke when plugin is loaded */
984 /* int (*)(void*); */
985 STRUCT_FLD(init, innodb_locks_init),
986
987 /* the function to invoke when plugin is unloaded */
988 /* int (*)(void*); */
989 STRUCT_FLD(deinit, i_s_common_deinit),
990
991 /* plugin version (for SHOW PLUGINS) */
992 /* unsigned int */
993 STRUCT_FLD(version, INNODB_VERSION_SHORT),
994
995 /* struct st_mysql_show_var* */
996 STRUCT_FLD(status_vars, NULL),
997
998 /* struct st_mysql_sys_var** */
999 STRUCT_FLD(system_vars, NULL),
1000
1001 /* reserved for dependency checking */
1002 /* void* */
1003 STRUCT_FLD(__reserved1, NULL),
1004
1005 /* Plugin flags */
1006 /* unsigned long */
1007 STRUCT_FLD(flags, 0UL),
1008 };
1009
1010 /* Fields of the dynamic table INFORMATION_SCHEMA.innodb_lock_waits */
1011 static ST_FIELD_INFO innodb_lock_waits_fields_info[] =
1012 {
1013 #define IDX_REQUESTING_TRX_ID 0
1014 {STRUCT_FLD(field_name, "requesting_trx_id"),
1015 STRUCT_FLD(field_length, TRX_ID_MAX_LEN + 1),
1016 STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
1017 STRUCT_FLD(value, 0),
1018 STRUCT_FLD(field_flags, 0),
1019 STRUCT_FLD(old_name, ""),
1020 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1021
1022 #define IDX_REQUESTED_LOCK_ID 1
1023 {STRUCT_FLD(field_name, "requested_lock_id"),
1024 STRUCT_FLD(field_length, TRX_I_S_LOCK_ID_MAX_LEN + 1),
1025 STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
1026 STRUCT_FLD(value, 0),
1027 STRUCT_FLD(field_flags, 0),
1028 STRUCT_FLD(old_name, ""),
1029 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1030
1031 #define IDX_BLOCKING_TRX_ID 2
1032 {STRUCT_FLD(field_name, "blocking_trx_id"),
1033 STRUCT_FLD(field_length, TRX_ID_MAX_LEN + 1),
1034 STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
1035 STRUCT_FLD(value, 0),
1036 STRUCT_FLD(field_flags, 0),
1037 STRUCT_FLD(old_name, ""),
1038 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1039
1040 #define IDX_BLOCKING_LOCK_ID 3
1041 {STRUCT_FLD(field_name, "blocking_lock_id"),
1042 STRUCT_FLD(field_length, TRX_I_S_LOCK_ID_MAX_LEN + 1),
1043 STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
1044 STRUCT_FLD(value, 0),
1045 STRUCT_FLD(field_flags, 0),
1046 STRUCT_FLD(old_name, ""),
1047 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1048
1049 END_OF_ST_FIELD_INFO
1050 };
1051
1052 /*******************************************************************//**
1053 Read data from cache buffer and fill the
1054 INFORMATION_SCHEMA.innodb_lock_waits table with it.
1055 @return 0 on success */
1056 static
1057 int
fill_innodb_lock_waits_from_cache(trx_i_s_cache_t * cache,THD * thd,TABLE * table)1058 fill_innodb_lock_waits_from_cache(
1059 /*==============================*/
1060 trx_i_s_cache_t* cache, /*!< in: cache to read from */
1061 THD* thd, /*!< in: used to call
1062 schema_table_store_record() */
1063 TABLE* table) /*!< in/out: fill this table */
1064 {
1065 Field** fields;
1066 ulint rows_num;
1067 char requested_lock_id[TRX_I_S_LOCK_ID_MAX_LEN + 1];
1068 char blocking_lock_id[TRX_I_S_LOCK_ID_MAX_LEN + 1];
1069 ulint i;
1070
1071 DBUG_ENTER("fill_innodb_lock_waits_from_cache");
1072
1073 fields = table->field;
1074
1075 rows_num = trx_i_s_cache_get_rows_used(cache,
1076 I_S_INNODB_LOCK_WAITS);
1077
1078 for (i = 0; i < rows_num; i++) {
1079
1080 i_s_lock_waits_row_t* row;
1081
1082 char requesting_trx_id[TRX_ID_MAX_LEN + 1];
1083 char blocking_trx_id[TRX_ID_MAX_LEN + 1];
1084
1085 row = (i_s_lock_waits_row_t*)
1086 trx_i_s_cache_get_nth_row(
1087 cache, I_S_INNODB_LOCK_WAITS, i);
1088
1089 /* requesting_trx_id */
1090 ut_snprintf(requesting_trx_id, sizeof(requesting_trx_id),
1091 TRX_ID_FMT, row->requested_lock_row->lock_trx_id);
1092 OK(field_store_string(fields[IDX_REQUESTING_TRX_ID],
1093 requesting_trx_id));
1094
1095 /* requested_lock_id */
1096 OK(field_store_string(
1097 fields[IDX_REQUESTED_LOCK_ID],
1098 trx_i_s_create_lock_id(
1099 row->requested_lock_row,
1100 requested_lock_id,
1101 sizeof(requested_lock_id))));
1102
1103 /* blocking_trx_id */
1104 ut_snprintf(blocking_trx_id, sizeof(blocking_trx_id),
1105 TRX_ID_FMT, row->blocking_lock_row->lock_trx_id);
1106 OK(field_store_string(fields[IDX_BLOCKING_TRX_ID],
1107 blocking_trx_id));
1108
1109 /* blocking_lock_id */
1110 OK(field_store_string(
1111 fields[IDX_BLOCKING_LOCK_ID],
1112 trx_i_s_create_lock_id(
1113 row->blocking_lock_row,
1114 blocking_lock_id,
1115 sizeof(blocking_lock_id))));
1116
1117 OK(schema_table_store_record(thd, table));
1118 }
1119
1120 DBUG_RETURN(0);
1121 }
1122
1123 /*******************************************************************//**
1124 Bind the dynamic table INFORMATION_SCHEMA.innodb_lock_waits
1125 @return 0 on success */
1126 static
1127 int
innodb_lock_waits_init(void * p)1128 innodb_lock_waits_init(
1129 /*===================*/
1130 void* p) /*!< in/out: table schema object */
1131 {
1132 ST_SCHEMA_TABLE* schema;
1133
1134 DBUG_ENTER("innodb_lock_waits_init");
1135
1136 schema = (ST_SCHEMA_TABLE*) p;
1137
1138 schema->fields_info = innodb_lock_waits_fields_info;
1139 schema->fill_table = trx_i_s_common_fill_table;
1140
1141 DBUG_RETURN(0);
1142 }
1143
1144 UNIV_INTERN struct st_mysql_plugin i_s_innodb_lock_waits =
1145 {
1146 /* the plugin type (a MYSQL_XXX_PLUGIN value) */
1147 /* int */
1148 STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
1149
1150 /* pointer to type-specific plugin descriptor */
1151 /* void* */
1152 STRUCT_FLD(info, &i_s_info),
1153
1154 /* plugin name */
1155 /* const char* */
1156 STRUCT_FLD(name, "INNODB_LOCK_WAITS"),
1157
1158 /* plugin author (for SHOW PLUGINS) */
1159 /* const char* */
1160 STRUCT_FLD(author, plugin_author),
1161
1162 /* general descriptive text (for SHOW PLUGINS) */
1163 /* const char* */
1164 STRUCT_FLD(descr, "InnoDB which lock is blocking which"),
1165
1166 /* the plugin license (PLUGIN_LICENSE_XXX) */
1167 /* int */
1168 STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
1169
1170 /* the function to invoke when plugin is loaded */
1171 /* int (*)(void*); */
1172 STRUCT_FLD(init, innodb_lock_waits_init),
1173
1174 /* the function to invoke when plugin is unloaded */
1175 /* int (*)(void*); */
1176 STRUCT_FLD(deinit, i_s_common_deinit),
1177
1178 /* plugin version (for SHOW PLUGINS) */
1179 /* unsigned int */
1180 STRUCT_FLD(version, INNODB_VERSION_SHORT),
1181
1182 /* struct st_mysql_show_var* */
1183 STRUCT_FLD(status_vars, NULL),
1184
1185 /* struct st_mysql_sys_var** */
1186 STRUCT_FLD(system_vars, NULL),
1187
1188 /* reserved for dependency checking */
1189 /* void* */
1190 STRUCT_FLD(__reserved1, NULL),
1191
1192 /* Plugin flags */
1193 /* unsigned long */
1194 STRUCT_FLD(flags, 0UL),
1195 };
1196
1197 /*******************************************************************//**
1198 Common function to fill any of the dynamic tables:
1199 INFORMATION_SCHEMA.innodb_trx
1200 INFORMATION_SCHEMA.innodb_locks
1201 INFORMATION_SCHEMA.innodb_lock_waits
1202 @return 0 on success */
1203 static
1204 int
trx_i_s_common_fill_table(THD * thd,TABLE_LIST * tables,COND * cond)1205 trx_i_s_common_fill_table(
1206 /*======================*/
1207 THD* thd, /*!< in: thread */
1208 TABLE_LIST* tables, /*!< in/out: tables to fill */
1209 COND* cond) /*!< in: condition (not used) */
1210 {
1211 const char* table_name;
1212 int ret;
1213 trx_i_s_cache_t* cache;
1214
1215 DBUG_ENTER("trx_i_s_common_fill_table");
1216
1217 /* deny access to non-superusers */
1218 if (check_global_access(thd, PROCESS_ACL)) {
1219
1220 DBUG_RETURN(0);
1221 }
1222
1223 /* minimize the number of places where global variables are
1224 referenced */
1225 cache = trx_i_s_cache;
1226
1227 /* which table we have to fill? */
1228 table_name = tables->schema_table_name;
1229 /* or table_name = tables->schema_table->table_name; */
1230
1231 RETURN_IF_INNODB_NOT_STARTED(table_name);
1232
1233 /* update the cache */
1234 trx_i_s_cache_start_write(cache);
1235 trx_i_s_possibly_fetch_data_into_cache(cache);
1236 trx_i_s_cache_end_write(cache);
1237
1238 if (trx_i_s_cache_is_truncated(cache)) {
1239
1240 /* XXX show warning to user if possible */
1241 fprintf(stderr, "Warning: data in %s truncated due to "
1242 "memory limit of %d bytes\n", table_name,
1243 TRX_I_S_MEM_LIMIT);
1244 }
1245
1246 ret = 0;
1247
1248 trx_i_s_cache_start_read(cache);
1249
1250 if (innobase_strcasecmp(table_name, "innodb_trx") == 0) {
1251
1252 if (fill_innodb_trx_from_cache(
1253 cache, thd, tables->table) != 0) {
1254
1255 ret = 1;
1256 }
1257
1258 } else if (innobase_strcasecmp(table_name, "innodb_locks") == 0) {
1259
1260 if (fill_innodb_locks_from_cache(
1261 cache, thd, tables->table) != 0) {
1262
1263 ret = 1;
1264 }
1265
1266 } else if (innobase_strcasecmp(table_name, "innodb_lock_waits") == 0) {
1267
1268 if (fill_innodb_lock_waits_from_cache(
1269 cache, thd, tables->table) != 0) {
1270
1271 ret = 1;
1272 }
1273
1274 } else {
1275
1276 /* huh! what happened!? */
1277 fprintf(stderr,
1278 "InnoDB: trx_i_s_common_fill_table() was "
1279 "called to fill unknown table: %s.\n"
1280 "This function only knows how to fill "
1281 "innodb_trx, innodb_locks and "
1282 "innodb_lock_waits tables.\n", table_name);
1283
1284 ret = 1;
1285 }
1286
1287 trx_i_s_cache_end_read(cache);
1288
1289 #if 0
1290 DBUG_RETURN(ret);
1291 #else
1292 /* if this function returns something else than 0 then a
1293 deadlock occurs between the mysqld server and mysql client,
1294 see http://bugs.mysql.com/29900 ; when that bug is resolved
1295 we can enable the DBUG_RETURN(ret) above */
1296 ret++; // silence a gcc46 warning
1297 DBUG_RETURN(0);
1298 #endif
1299 }
1300
1301 /* Fields of the dynamic table information_schema.innodb_cmp. */
1302 static ST_FIELD_INFO i_s_cmp_fields_info[] =
1303 {
1304 {STRUCT_FLD(field_name, "page_size"),
1305 STRUCT_FLD(field_length, 5),
1306 STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
1307 STRUCT_FLD(value, 0),
1308 STRUCT_FLD(field_flags, 0),
1309 STRUCT_FLD(old_name, "Compressed Page Size"),
1310 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1311
1312 {STRUCT_FLD(field_name, "compress_ops"),
1313 STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS),
1314 STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
1315 STRUCT_FLD(value, 0),
1316 STRUCT_FLD(field_flags, 0),
1317 STRUCT_FLD(old_name, "Total Number of Compressions"),
1318 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1319
1320 {STRUCT_FLD(field_name, "compress_ops_ok"),
1321 STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS),
1322 STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
1323 STRUCT_FLD(value, 0),
1324 STRUCT_FLD(field_flags, 0),
1325 STRUCT_FLD(old_name, "Total Number of"
1326 " Successful Compressions"),
1327 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1328
1329 {STRUCT_FLD(field_name, "compress_time"),
1330 STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS),
1331 STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
1332 STRUCT_FLD(value, 0),
1333 STRUCT_FLD(field_flags, 0),
1334 STRUCT_FLD(old_name, "Total Duration of Compressions,"
1335 " in Seconds"),
1336 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1337
1338 {STRUCT_FLD(field_name, "uncompress_ops"),
1339 STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS),
1340 STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
1341 STRUCT_FLD(value, 0),
1342 STRUCT_FLD(field_flags, 0),
1343 STRUCT_FLD(old_name, "Total Number of Decompressions"),
1344 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1345
1346 {STRUCT_FLD(field_name, "uncompress_time"),
1347 STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS),
1348 STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
1349 STRUCT_FLD(value, 0),
1350 STRUCT_FLD(field_flags, 0),
1351 STRUCT_FLD(old_name, "Total Duration of Decompressions,"
1352 " in Seconds"),
1353 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1354
1355 END_OF_ST_FIELD_INFO
1356 };
1357
1358
1359 /*******************************************************************//**
1360 Fill the dynamic table information_schema.innodb_cmp or
1361 innodb_cmp_reset.
1362 @return 0 on success, 1 on failure */
1363 static
1364 int
i_s_cmp_fill_low(THD * thd,TABLE_LIST * tables,COND * cond,ibool reset)1365 i_s_cmp_fill_low(
1366 /*=============*/
1367 THD* thd, /*!< in: thread */
1368 TABLE_LIST* tables, /*!< in/out: tables to fill */
1369 COND* cond, /*!< in: condition (ignored) */
1370 ibool reset) /*!< in: TRUE=reset cumulated counts */
1371 {
1372 TABLE* table = (TABLE *) tables->table;
1373 int status = 0;
1374
1375 DBUG_ENTER("i_s_cmp_fill_low");
1376
1377 /* deny access to non-superusers */
1378 if (check_global_access(thd, PROCESS_ACL)) {
1379
1380 DBUG_RETURN(0);
1381 }
1382
1383 RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name);
1384
1385 for (uint i = 0; i < PAGE_ZIP_NUM_SSIZE - 1; i++) {
1386 page_zip_stat_t* zip_stat = &page_zip_stat[i];
1387
1388 table->field[0]->store(PAGE_ZIP_MIN_SIZE << i);
1389
1390 /* The cumulated counts are not protected by any
1391 mutex. Thus, some operation in page0zip.c could
1392 increment a counter between the time we read it and
1393 clear it. We could introduce mutex protection, but it
1394 could cause a measureable performance hit in
1395 page0zip.c. */
1396 table->field[1]->store(zip_stat->compressed);
1397 table->field[2]->store(zip_stat->compressed_ok);
1398 table->field[3]->store(
1399 (ulong) (zip_stat->compressed_usec / 1000000));
1400 table->field[4]->store(zip_stat->decompressed);
1401 table->field[5]->store(
1402 (ulong) (zip_stat->decompressed_usec / 1000000));
1403
1404 if (reset) {
1405 memset(zip_stat, 0, sizeof *zip_stat);
1406 }
1407
1408 if (schema_table_store_record(thd, table)) {
1409 status = 1;
1410 break;
1411 }
1412 }
1413
1414 DBUG_RETURN(status);
1415 }
1416
1417 /*******************************************************************//**
1418 Fill the dynamic table information_schema.innodb_cmp.
1419 @return 0 on success, 1 on failure */
1420 static
1421 int
i_s_cmp_fill(THD * thd,TABLE_LIST * tables,COND * cond)1422 i_s_cmp_fill(
1423 /*=========*/
1424 THD* thd, /*!< in: thread */
1425 TABLE_LIST* tables, /*!< in/out: tables to fill */
1426 COND* cond) /*!< in: condition (ignored) */
1427 {
1428 return(i_s_cmp_fill_low(thd, tables, cond, FALSE));
1429 }
1430
1431 /*******************************************************************//**
1432 Fill the dynamic table information_schema.innodb_cmp_reset.
1433 @return 0 on success, 1 on failure */
1434 static
1435 int
i_s_cmp_reset_fill(THD * thd,TABLE_LIST * tables,COND * cond)1436 i_s_cmp_reset_fill(
1437 /*===============*/
1438 THD* thd, /*!< in: thread */
1439 TABLE_LIST* tables, /*!< in/out: tables to fill */
1440 COND* cond) /*!< in: condition (ignored) */
1441 {
1442 return(i_s_cmp_fill_low(thd, tables, cond, TRUE));
1443 }
1444
1445 /*******************************************************************//**
1446 Bind the dynamic table information_schema.innodb_cmp.
1447 @return 0 on success */
1448 static
1449 int
i_s_cmp_init(void * p)1450 i_s_cmp_init(
1451 /*=========*/
1452 void* p) /*!< in/out: table schema object */
1453 {
1454 DBUG_ENTER("i_s_cmp_init");
1455 ST_SCHEMA_TABLE* schema = (ST_SCHEMA_TABLE*) p;
1456
1457 schema->fields_info = i_s_cmp_fields_info;
1458 schema->fill_table = i_s_cmp_fill;
1459
1460 DBUG_RETURN(0);
1461 }
1462
1463 /*******************************************************************//**
1464 Bind the dynamic table information_schema.innodb_cmp_reset.
1465 @return 0 on success */
1466 static
1467 int
i_s_cmp_reset_init(void * p)1468 i_s_cmp_reset_init(
1469 /*===============*/
1470 void* p) /*!< in/out: table schema object */
1471 {
1472 DBUG_ENTER("i_s_cmp_reset_init");
1473 ST_SCHEMA_TABLE* schema = (ST_SCHEMA_TABLE*) p;
1474
1475 schema->fields_info = i_s_cmp_fields_info;
1476 schema->fill_table = i_s_cmp_reset_fill;
1477
1478 DBUG_RETURN(0);
1479 }
1480
1481 UNIV_INTERN struct st_mysql_plugin i_s_innodb_cmp =
1482 {
1483 /* the plugin type (a MYSQL_XXX_PLUGIN value) */
1484 /* int */
1485 STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
1486
1487 /* pointer to type-specific plugin descriptor */
1488 /* void* */
1489 STRUCT_FLD(info, &i_s_info),
1490
1491 /* plugin name */
1492 /* const char* */
1493 STRUCT_FLD(name, "INNODB_CMP"),
1494
1495 /* plugin author (for SHOW PLUGINS) */
1496 /* const char* */
1497 STRUCT_FLD(author, plugin_author),
1498
1499 /* general descriptive text (for SHOW PLUGINS) */
1500 /* const char* */
1501 STRUCT_FLD(descr, "Statistics for the InnoDB compression"),
1502
1503 /* the plugin license (PLUGIN_LICENSE_XXX) */
1504 /* int */
1505 STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
1506
1507 /* the function to invoke when plugin is loaded */
1508 /* int (*)(void*); */
1509 STRUCT_FLD(init, i_s_cmp_init),
1510
1511 /* the function to invoke when plugin is unloaded */
1512 /* int (*)(void*); */
1513 STRUCT_FLD(deinit, i_s_common_deinit),
1514
1515 /* plugin version (for SHOW PLUGINS) */
1516 /* unsigned int */
1517 STRUCT_FLD(version, INNODB_VERSION_SHORT),
1518
1519 /* struct st_mysql_show_var* */
1520 STRUCT_FLD(status_vars, NULL),
1521
1522 /* struct st_mysql_sys_var** */
1523 STRUCT_FLD(system_vars, NULL),
1524
1525 /* reserved for dependency checking */
1526 /* void* */
1527 STRUCT_FLD(__reserved1, NULL),
1528
1529 /* Plugin flags */
1530 /* unsigned long */
1531 STRUCT_FLD(flags, 0UL),
1532 };
1533
1534 UNIV_INTERN struct st_mysql_plugin i_s_innodb_cmp_reset =
1535 {
1536 /* the plugin type (a MYSQL_XXX_PLUGIN value) */
1537 /* int */
1538 STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
1539
1540 /* pointer to type-specific plugin descriptor */
1541 /* void* */
1542 STRUCT_FLD(info, &i_s_info),
1543
1544 /* plugin name */
1545 /* const char* */
1546 STRUCT_FLD(name, "INNODB_CMP_RESET"),
1547
1548 /* plugin author (for SHOW PLUGINS) */
1549 /* const char* */
1550 STRUCT_FLD(author, plugin_author),
1551
1552 /* general descriptive text (for SHOW PLUGINS) */
1553 /* const char* */
1554 STRUCT_FLD(descr, "Statistics for the InnoDB compression;"
1555 " reset cumulated counts"),
1556
1557 /* the plugin license (PLUGIN_LICENSE_XXX) */
1558 /* int */
1559 STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
1560
1561 /* the function to invoke when plugin is loaded */
1562 /* int (*)(void*); */
1563 STRUCT_FLD(init, i_s_cmp_reset_init),
1564
1565 /* the function to invoke when plugin is unloaded */
1566 /* int (*)(void*); */
1567 STRUCT_FLD(deinit, i_s_common_deinit),
1568
1569 /* plugin version (for SHOW PLUGINS) */
1570 /* unsigned int */
1571 STRUCT_FLD(version, INNODB_VERSION_SHORT),
1572
1573 /* struct st_mysql_show_var* */
1574 STRUCT_FLD(status_vars, NULL),
1575
1576 /* struct st_mysql_sys_var** */
1577 STRUCT_FLD(system_vars, NULL),
1578
1579 /* reserved for dependency checking */
1580 /* void* */
1581 STRUCT_FLD(__reserved1, NULL),
1582
1583 /* Plugin flags */
1584 /* unsigned long */
1585 STRUCT_FLD(flags, 0UL),
1586 };
1587
1588 /* Fields of the dynamic table information_schema.innodb_cmpmem. */
1589 static ST_FIELD_INFO i_s_cmpmem_fields_info[] =
1590 {
1591 {STRUCT_FLD(field_name, "page_size"),
1592 STRUCT_FLD(field_length, 5),
1593 STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
1594 STRUCT_FLD(value, 0),
1595 STRUCT_FLD(field_flags, 0),
1596 STRUCT_FLD(old_name, "Buddy Block Size"),
1597 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1598
1599 {STRUCT_FLD(field_name, "buffer_pool_instance"),
1600 STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS),
1601 STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
1602 STRUCT_FLD(value, 0),
1603 STRUCT_FLD(field_flags, 0),
1604 STRUCT_FLD(old_name, "Buffer Pool Id"),
1605 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1606
1607 {STRUCT_FLD(field_name, "pages_used"),
1608 STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS),
1609 STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
1610 STRUCT_FLD(value, 0),
1611 STRUCT_FLD(field_flags, 0),
1612 STRUCT_FLD(old_name, "Currently in Use"),
1613 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1614
1615 {STRUCT_FLD(field_name, "pages_free"),
1616 STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS),
1617 STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
1618 STRUCT_FLD(value, 0),
1619 STRUCT_FLD(field_flags, 0),
1620 STRUCT_FLD(old_name, "Currently Available"),
1621 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1622
1623 {STRUCT_FLD(field_name, "relocation_ops"),
1624 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
1625 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
1626 STRUCT_FLD(value, 0),
1627 STRUCT_FLD(field_flags, 0),
1628 STRUCT_FLD(old_name, "Total Number of Relocations"),
1629 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1630
1631 {STRUCT_FLD(field_name, "relocation_time"),
1632 STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS),
1633 STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
1634 STRUCT_FLD(value, 0),
1635 STRUCT_FLD(field_flags, 0),
1636 STRUCT_FLD(old_name, "Total Duration of Relocations,"
1637 " in Seconds"),
1638 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1639
1640 END_OF_ST_FIELD_INFO
1641 };
1642
1643 /*******************************************************************//**
1644 Fill the dynamic table information_schema.innodb_cmpmem or
1645 innodb_cmpmem_reset.
1646 @return 0 on success, 1 on failure */
1647 static
1648 int
i_s_cmpmem_fill_low(THD * thd,TABLE_LIST * tables,COND * cond,ibool reset)1649 i_s_cmpmem_fill_low(
1650 /*================*/
1651 THD* thd, /*!< in: thread */
1652 TABLE_LIST* tables, /*!< in/out: tables to fill */
1653 COND* cond, /*!< in: condition (ignored) */
1654 ibool reset) /*!< in: TRUE=reset cumulated counts */
1655 {
1656 int status = 0;
1657 TABLE* table = (TABLE *) tables->table;
1658
1659 DBUG_ENTER("i_s_cmpmem_fill_low");
1660
1661 /* deny access to non-superusers */
1662 if (check_global_access(thd, PROCESS_ACL)) {
1663
1664 DBUG_RETURN(0);
1665 }
1666
1667 RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name);
1668
1669 for (ulint i = 0; i < srv_buf_pool_instances; i++) {
1670 buf_pool_t* buf_pool;
1671
1672 status = 0;
1673
1674 buf_pool = buf_pool_from_array(i);
1675
1676 buf_pool_mutex_enter(buf_pool);
1677
1678 for (uint x = 0; x <= BUF_BUDDY_SIZES; x++) {
1679 buf_buddy_stat_t* buddy_stat;
1680
1681 buddy_stat = &buf_pool->buddy_stat[x];
1682
1683 table->field[0]->store(BUF_BUDDY_LOW << x);
1684 table->field[1]->store(i);
1685 table->field[2]->store(buddy_stat->used);
1686 table->field[3]->store(UNIV_LIKELY(x < BUF_BUDDY_SIZES)
1687 ? UT_LIST_GET_LEN(buf_pool->zip_free[x])
1688 : 0);
1689 table->field[4]->store((longlong)
1690 buddy_stat->relocated, true);
1691 table->field[5]->store(
1692 (ulong) (buddy_stat->relocated_usec / 1000000));
1693
1694 if (reset) {
1695 /* This is protected by buf_pool->mutex. */
1696 buddy_stat->relocated = 0;
1697 buddy_stat->relocated_usec = 0;
1698 }
1699
1700 if (schema_table_store_record(thd, table)) {
1701 status = 1;
1702 break;
1703 }
1704 }
1705
1706 buf_pool_mutex_exit(buf_pool);
1707
1708 if (status) {
1709 break;
1710 }
1711 }
1712
1713 DBUG_RETURN(status);
1714 }
1715
1716 /*******************************************************************//**
1717 Fill the dynamic table information_schema.innodb_cmpmem.
1718 @return 0 on success, 1 on failure */
1719 static
1720 int
i_s_cmpmem_fill(THD * thd,TABLE_LIST * tables,COND * cond)1721 i_s_cmpmem_fill(
1722 /*============*/
1723 THD* thd, /*!< in: thread */
1724 TABLE_LIST* tables, /*!< in/out: tables to fill */
1725 COND* cond) /*!< in: condition (ignored) */
1726 {
1727 return(i_s_cmpmem_fill_low(thd, tables, cond, FALSE));
1728 }
1729
1730 /*******************************************************************//**
1731 Fill the dynamic table information_schema.innodb_cmpmem_reset.
1732 @return 0 on success, 1 on failure */
1733 static
1734 int
i_s_cmpmem_reset_fill(THD * thd,TABLE_LIST * tables,COND * cond)1735 i_s_cmpmem_reset_fill(
1736 /*==================*/
1737 THD* thd, /*!< in: thread */
1738 TABLE_LIST* tables, /*!< in/out: tables to fill */
1739 COND* cond) /*!< in: condition (ignored) */
1740 {
1741 return(i_s_cmpmem_fill_low(thd, tables, cond, TRUE));
1742 }
1743
1744 /*******************************************************************//**
1745 Bind the dynamic table information_schema.innodb_cmpmem.
1746 @return 0 on success */
1747 static
1748 int
i_s_cmpmem_init(void * p)1749 i_s_cmpmem_init(
1750 /*============*/
1751 void* p) /*!< in/out: table schema object */
1752 {
1753 DBUG_ENTER("i_s_cmpmem_init");
1754 ST_SCHEMA_TABLE* schema = (ST_SCHEMA_TABLE*) p;
1755
1756 schema->fields_info = i_s_cmpmem_fields_info;
1757 schema->fill_table = i_s_cmpmem_fill;
1758
1759 DBUG_RETURN(0);
1760 }
1761
1762 /*******************************************************************//**
1763 Bind the dynamic table information_schema.innodb_cmpmem_reset.
1764 @return 0 on success */
1765 static
1766 int
i_s_cmpmem_reset_init(void * p)1767 i_s_cmpmem_reset_init(
1768 /*==================*/
1769 void* p) /*!< in/out: table schema object */
1770 {
1771 DBUG_ENTER("i_s_cmpmem_reset_init");
1772 ST_SCHEMA_TABLE* schema = (ST_SCHEMA_TABLE*) p;
1773
1774 schema->fields_info = i_s_cmpmem_fields_info;
1775 schema->fill_table = i_s_cmpmem_reset_fill;
1776
1777 DBUG_RETURN(0);
1778 }
1779
1780 UNIV_INTERN struct st_mysql_plugin i_s_innodb_cmpmem =
1781 {
1782 /* the plugin type (a MYSQL_XXX_PLUGIN value) */
1783 /* int */
1784 STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
1785
1786 /* pointer to type-specific plugin descriptor */
1787 /* void* */
1788 STRUCT_FLD(info, &i_s_info),
1789
1790 /* plugin name */
1791 /* const char* */
1792 STRUCT_FLD(name, "INNODB_CMPMEM"),
1793
1794 /* plugin author (for SHOW PLUGINS) */
1795 /* const char* */
1796 STRUCT_FLD(author, plugin_author),
1797
1798 /* general descriptive text (for SHOW PLUGINS) */
1799 /* const char* */
1800 STRUCT_FLD(descr, "Statistics for the InnoDB compressed buffer pool"),
1801
1802 /* the plugin license (PLUGIN_LICENSE_XXX) */
1803 /* int */
1804 STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
1805
1806 /* the function to invoke when plugin is loaded */
1807 /* int (*)(void*); */
1808 STRUCT_FLD(init, i_s_cmpmem_init),
1809
1810 /* the function to invoke when plugin is unloaded */
1811 /* int (*)(void*); */
1812 STRUCT_FLD(deinit, i_s_common_deinit),
1813
1814 /* plugin version (for SHOW PLUGINS) */
1815 /* unsigned int */
1816 STRUCT_FLD(version, INNODB_VERSION_SHORT),
1817
1818 /* struct st_mysql_show_var* */
1819 STRUCT_FLD(status_vars, NULL),
1820
1821 /* struct st_mysql_sys_var** */
1822 STRUCT_FLD(system_vars, NULL),
1823
1824 /* reserved for dependency checking */
1825 /* void* */
1826 STRUCT_FLD(__reserved1, NULL),
1827
1828 /* Plugin flags */
1829 /* unsigned long */
1830 STRUCT_FLD(flags, 0UL),
1831 };
1832
1833 UNIV_INTERN struct st_mysql_plugin i_s_innodb_cmpmem_reset =
1834 {
1835 /* the plugin type (a MYSQL_XXX_PLUGIN value) */
1836 /* int */
1837 STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
1838
1839 /* pointer to type-specific plugin descriptor */
1840 /* void* */
1841 STRUCT_FLD(info, &i_s_info),
1842
1843 /* plugin name */
1844 /* const char* */
1845 STRUCT_FLD(name, "INNODB_CMPMEM_RESET"),
1846
1847 /* plugin author (for SHOW PLUGINS) */
1848 /* const char* */
1849 STRUCT_FLD(author, plugin_author),
1850
1851 /* general descriptive text (for SHOW PLUGINS) */
1852 /* const char* */
1853 STRUCT_FLD(descr, "Statistics for the InnoDB compressed buffer pool;"
1854 " reset cumulated counts"),
1855
1856 /* the plugin license (PLUGIN_LICENSE_XXX) */
1857 /* int */
1858 STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
1859
1860 /* the function to invoke when plugin is loaded */
1861 /* int (*)(void*); */
1862 STRUCT_FLD(init, i_s_cmpmem_reset_init),
1863
1864 /* the function to invoke when plugin is unloaded */
1865 /* int (*)(void*); */
1866 STRUCT_FLD(deinit, i_s_common_deinit),
1867
1868 /* plugin version (for SHOW PLUGINS) */
1869 /* unsigned int */
1870 STRUCT_FLD(version, INNODB_VERSION_SHORT),
1871
1872 /* struct st_mysql_show_var* */
1873 STRUCT_FLD(status_vars, NULL),
1874
1875 /* struct st_mysql_sys_var** */
1876 STRUCT_FLD(system_vars, NULL),
1877
1878 /* reserved for dependency checking */
1879 /* void* */
1880 STRUCT_FLD(__reserved1, NULL),
1881
1882 /* Plugin flags */
1883 /* unsigned long */
1884 STRUCT_FLD(flags, 0UL),
1885 };
1886
1887 /* Fields of the dynamic table INNODB_BUFFER_POOL_STATS. */
1888 static ST_FIELD_INFO i_s_innodb_buffer_stats_fields_info[] =
1889 {
1890 #define IDX_BUF_STATS_POOL_ID 0
1891 {STRUCT_FLD(field_name, "POOL_ID"),
1892 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
1893 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
1894 STRUCT_FLD(value, 0),
1895 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
1896 STRUCT_FLD(old_name, ""),
1897 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1898
1899 #define IDX_BUF_STATS_POOL_SIZE 1
1900 {STRUCT_FLD(field_name, "POOL_SIZE"),
1901 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
1902 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
1903 STRUCT_FLD(value, 0),
1904 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
1905 STRUCT_FLD(old_name, ""),
1906 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1907
1908 #define IDX_BUF_STATS_FREE_BUFFERS 2
1909 {STRUCT_FLD(field_name, "FREE_BUFFERS"),
1910 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
1911 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
1912 STRUCT_FLD(value, 0),
1913 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
1914 STRUCT_FLD(old_name, ""),
1915 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1916
1917 #define IDX_BUF_STATS_LRU_LEN 3
1918 {STRUCT_FLD(field_name, "DATABASE_PAGES"),
1919 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
1920 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
1921 STRUCT_FLD(value, 0),
1922 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
1923 STRUCT_FLD(old_name, ""),
1924 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1925
1926 #define IDX_BUF_STATS_OLD_LRU_LEN 4
1927 {STRUCT_FLD(field_name, "OLD_DATABASE_PAGES"),
1928 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
1929 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
1930 STRUCT_FLD(value, 0),
1931 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
1932 STRUCT_FLD(old_name, ""),
1933 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1934
1935 #define IDX_BUF_STATS_FLUSH_LIST_LEN 5
1936 {STRUCT_FLD(field_name, "MODIFIED_DATABASE_PAGES"),
1937 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
1938 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
1939 STRUCT_FLD(value, 0),
1940 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
1941 STRUCT_FLD(old_name, ""),
1942 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1943
1944 #define IDX_BUF_STATS_PENDING_ZIP 6
1945 {STRUCT_FLD(field_name, "PENDING_DECOMPRESS"),
1946 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
1947 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
1948 STRUCT_FLD(value, 0),
1949 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
1950 STRUCT_FLD(old_name, ""),
1951 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1952
1953 #define IDX_BUF_STATS_PENDING_READ 7
1954 {STRUCT_FLD(field_name, "PENDING_READS"),
1955 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
1956 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
1957 STRUCT_FLD(value, 0),
1958 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
1959 STRUCT_FLD(old_name, ""),
1960 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1961
1962 #define IDX_BUF_STATS_FLUSH_LRU 8
1963 {STRUCT_FLD(field_name, "PENDING_FLUSH_LRU"),
1964 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
1965 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
1966 STRUCT_FLD(value, 0),
1967 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
1968 STRUCT_FLD(old_name, ""),
1969 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1970
1971 #define IDX_BUF_STATS_FLUSH_LIST 9
1972 {STRUCT_FLD(field_name, "PENDING_FLUSH_LIST"),
1973 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
1974 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
1975 STRUCT_FLD(value, 0),
1976 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
1977 STRUCT_FLD(old_name, ""),
1978 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1979
1980 #define IDX_BUF_STATS_PAGE_YOUNG 10
1981 {STRUCT_FLD(field_name, "PAGES_MADE_YOUNG"),
1982 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
1983 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
1984 STRUCT_FLD(value, 0),
1985 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
1986 STRUCT_FLD(old_name, ""),
1987 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1988
1989 #define IDX_BUF_STATS_PAGE_NOT_YOUNG 11
1990 {STRUCT_FLD(field_name, "PAGES_NOT_MADE_YOUNG"),
1991 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
1992 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
1993 STRUCT_FLD(value, 0),
1994 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
1995 STRUCT_FLD(old_name, ""),
1996 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1997
1998 #define IDX_BUF_STATS_PAGE_YOUNG_RATE 12
1999 {STRUCT_FLD(field_name, "PAGES_MADE_YOUNG_RATE"),
2000 STRUCT_FLD(field_length, MAX_FLOAT_STR_LENGTH),
2001 STRUCT_FLD(field_type, MYSQL_TYPE_FLOAT),
2002 STRUCT_FLD(value, 0),
2003 STRUCT_FLD(field_flags, 0),
2004 STRUCT_FLD(old_name, ""),
2005 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2006
2007 #define IDX_BUF_STATS_PAGE_NOT_YOUNG_RATE 13
2008 {STRUCT_FLD(field_name, "PAGES_MADE_NOT_YOUNG_RATE"),
2009 STRUCT_FLD(field_length, MAX_FLOAT_STR_LENGTH),
2010 STRUCT_FLD(field_type, MYSQL_TYPE_FLOAT),
2011 STRUCT_FLD(value, 0),
2012 STRUCT_FLD(field_flags, 0),
2013 STRUCT_FLD(old_name, ""),
2014 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2015
2016 #define IDX_BUF_STATS_PAGE_READ 14
2017 {STRUCT_FLD(field_name, "NUMBER_PAGES_READ"),
2018 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
2019 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
2020 STRUCT_FLD(value, 0),
2021 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
2022 STRUCT_FLD(old_name, ""),
2023 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2024
2025 #define IDX_BUF_STATS_PAGE_CREATED 15
2026 {STRUCT_FLD(field_name, "NUMBER_PAGES_CREATED"),
2027 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
2028 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
2029 STRUCT_FLD(value, 0),
2030 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
2031 STRUCT_FLD(old_name, ""),
2032 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2033
2034 #define IDX_BUF_STATS_PAGE_WRITTEN 16
2035 {STRUCT_FLD(field_name, "NUMBER_PAGES_WRITTEN"),
2036 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
2037 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
2038 STRUCT_FLD(value, 0),
2039 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
2040 STRUCT_FLD(old_name, ""),
2041 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2042
2043 #define IDX_BUF_STATS_PAGE_READ_RATE 17
2044 {STRUCT_FLD(field_name, "PAGES_READ_RATE"),
2045 STRUCT_FLD(field_length, MAX_FLOAT_STR_LENGTH),
2046 STRUCT_FLD(field_type, MYSQL_TYPE_FLOAT),
2047 STRUCT_FLD(value, 0),
2048 STRUCT_FLD(field_flags, 0),
2049 STRUCT_FLD(old_name, ""),
2050 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2051
2052 #define IDX_BUF_STATS_PAGE_CREATE_RATE 18
2053 {STRUCT_FLD(field_name, "PAGES_CREATE_RATE"),
2054 STRUCT_FLD(field_length, MAX_FLOAT_STR_LENGTH),
2055 STRUCT_FLD(field_type, MYSQL_TYPE_FLOAT),
2056 STRUCT_FLD(value, 0),
2057 STRUCT_FLD(field_flags, 0),
2058 STRUCT_FLD(old_name, ""),
2059 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2060
2061 #define IDX_BUF_STATS_PAGE_WRITTEN_RATE 19
2062 {STRUCT_FLD(field_name, "PAGES_WRITTEN_RATE"),
2063 STRUCT_FLD(field_length, MAX_FLOAT_STR_LENGTH),
2064 STRUCT_FLD(field_type, MYSQL_TYPE_FLOAT),
2065 STRUCT_FLD(value, 0),
2066 STRUCT_FLD(field_flags, 0),
2067 STRUCT_FLD(old_name, ""),
2068 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2069
2070 #define IDX_BUF_STATS_GET 20
2071 {STRUCT_FLD(field_name, "NUMBER_PAGES_GET"),
2072 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
2073 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
2074 STRUCT_FLD(value, 0),
2075 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
2076 STRUCT_FLD(old_name, ""),
2077 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2078
2079 #define IDX_BUF_STATS_HIT_RATE 21
2080 {STRUCT_FLD(field_name, "HIT_RATE"),
2081 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
2082 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
2083 STRUCT_FLD(value, 0),
2084 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
2085 STRUCT_FLD(old_name, ""),
2086 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2087
2088 #define IDX_BUF_STATS_MADE_YOUNG_PCT 22
2089 {STRUCT_FLD(field_name, "YOUNG_MAKE_PER_THOUSAND_GETS"),
2090 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
2091 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
2092 STRUCT_FLD(value, 0),
2093 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
2094 STRUCT_FLD(old_name, ""),
2095 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2096
2097 #define IDX_BUF_STATS_NOT_MADE_YOUNG_PCT 23
2098 {STRUCT_FLD(field_name, "NOT_YOUNG_MAKE_PER_THOUSAND_GETS"),
2099 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
2100 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
2101 STRUCT_FLD(value, 0),
2102 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
2103 STRUCT_FLD(old_name, ""),
2104 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2105
2106 #define IDX_BUF_STATS_READ_AHREAD 24
2107 {STRUCT_FLD(field_name, "NUMBER_PAGES_READ_AHEAD"),
2108 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
2109 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
2110 STRUCT_FLD(value, 0),
2111 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
2112 STRUCT_FLD(old_name, ""),
2113 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2114
2115 #define IDX_BUF_STATS_READ_AHEAD_EVICTED 25
2116 {STRUCT_FLD(field_name, "NUMBER_READ_AHEAD_EVICTED"),
2117 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
2118 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
2119 STRUCT_FLD(value, 0),
2120 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
2121 STRUCT_FLD(old_name, ""),
2122 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2123
2124 #define IDX_BUF_STATS_READ_AHEAD_RATE 26
2125 {STRUCT_FLD(field_name, "READ_AHEAD_RATE"),
2126 STRUCT_FLD(field_length, MAX_FLOAT_STR_LENGTH),
2127 STRUCT_FLD(field_type, MYSQL_TYPE_FLOAT),
2128 STRUCT_FLD(value, 0),
2129 STRUCT_FLD(field_flags, 0),
2130 STRUCT_FLD(old_name, ""),
2131 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2132
2133 #define IDX_BUF_STATS_READ_AHEAD_EVICT_RATE 27
2134 {STRUCT_FLD(field_name, "READ_AHEAD_EVICTED_RATE"),
2135 STRUCT_FLD(field_length, MAX_FLOAT_STR_LENGTH),
2136 STRUCT_FLD(field_type, MYSQL_TYPE_FLOAT),
2137 STRUCT_FLD(value, 0),
2138 STRUCT_FLD(field_flags, 0),
2139 STRUCT_FLD(old_name, ""),
2140 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2141
2142 #define IDX_BUF_STATS_LRU_IO_SUM 28
2143 {STRUCT_FLD(field_name, "LRU_IO_TOTAL"),
2144 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
2145 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
2146 STRUCT_FLD(value, 0),
2147 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
2148 STRUCT_FLD(old_name, ""),
2149 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2150
2151 #define IDX_BUF_STATS_LRU_IO_CUR 29
2152 {STRUCT_FLD(field_name, "LRU_IO_CURRENT"),
2153 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
2154 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
2155 STRUCT_FLD(value, 0),
2156 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
2157 STRUCT_FLD(old_name, ""),
2158 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2159
2160 #define IDX_BUF_STATS_UNZIP_SUM 30
2161 {STRUCT_FLD(field_name, "UNCOMPRESS_TOTAL"),
2162 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
2163 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
2164 STRUCT_FLD(value, 0),
2165 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
2166 STRUCT_FLD(old_name, ""),
2167 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2168
2169 #define IDX_BUF_STATS_UNZIP_CUR 31
2170 {STRUCT_FLD(field_name, "UNCOMPRESS_CURRENT"),
2171 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
2172 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
2173 STRUCT_FLD(value, 0),
2174 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
2175 STRUCT_FLD(old_name, ""),
2176 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2177
2178 END_OF_ST_FIELD_INFO
2179 };
2180
2181 /*******************************************************************//**
2182 Fill Information Schema table INNODB_BUFFER_POOL_STATS for a particular
2183 buffer pool
2184 @return 0 on success, 1 on failure */
2185 static
2186 int
i_s_innodb_stats_fill(THD * thd,TABLE_LIST * tables,const buf_pool_info_t * info)2187 i_s_innodb_stats_fill(
2188 /*==================*/
2189 THD* thd, /*!< in: thread */
2190 TABLE_LIST* tables, /*!< in/out: tables to fill */
2191 const buf_pool_info_t* info) /*!< in: buffer pool
2192 information */
2193 {
2194 TABLE* table;
2195 Field** fields;
2196
2197 DBUG_ENTER("i_s_innodb_stats_fill");
2198
2199 table = tables->table;
2200
2201 fields = table->field;
2202
2203 OK(fields[IDX_BUF_STATS_POOL_ID]->store(info->pool_unique_id));
2204
2205 OK(fields[IDX_BUF_STATS_POOL_SIZE]->store(info->pool_size));
2206
2207 OK(fields[IDX_BUF_STATS_LRU_LEN]->store(info->lru_len));
2208
2209 OK(fields[IDX_BUF_STATS_OLD_LRU_LEN]->store(info->old_lru_len));
2210
2211 OK(fields[IDX_BUF_STATS_FREE_BUFFERS]->store(info->free_list_len));
2212
2213 OK(fields[IDX_BUF_STATS_FLUSH_LIST_LEN]->store(
2214 info->flush_list_len));
2215
2216 OK(fields[IDX_BUF_STATS_PENDING_ZIP]->store(info->n_pend_unzip));
2217
2218 OK(fields[IDX_BUF_STATS_PENDING_READ]->store(info->n_pend_reads));
2219
2220 OK(fields[IDX_BUF_STATS_FLUSH_LRU]->store(info->n_pending_flush_lru));
2221
2222 OK(fields[IDX_BUF_STATS_FLUSH_LIST]->store(info->n_pending_flush_list));
2223
2224 OK(fields[IDX_BUF_STATS_PAGE_YOUNG]->store(info->n_pages_made_young));
2225
2226 OK(fields[IDX_BUF_STATS_PAGE_NOT_YOUNG]->store(
2227 info->n_pages_not_made_young));
2228
2229 OK(fields[IDX_BUF_STATS_PAGE_YOUNG_RATE]->store(
2230 info->page_made_young_rate));
2231
2232 OK(fields[IDX_BUF_STATS_PAGE_NOT_YOUNG_RATE]->store(
2233 info->page_not_made_young_rate));
2234
2235 OK(fields[IDX_BUF_STATS_PAGE_READ]->store(info->n_pages_read));
2236
2237 OK(fields[IDX_BUF_STATS_PAGE_CREATED]->store(info->n_pages_created));
2238
2239 OK(fields[IDX_BUF_STATS_PAGE_WRITTEN]->store(info->n_pages_written));
2240
2241 OK(fields[IDX_BUF_STATS_GET]->store(info->n_page_gets));
2242
2243 OK(fields[IDX_BUF_STATS_PAGE_READ_RATE]->store(info->pages_read_rate));
2244
2245 OK(fields[IDX_BUF_STATS_PAGE_CREATE_RATE]->store(info->pages_created_rate));
2246
2247 OK(fields[IDX_BUF_STATS_PAGE_WRITTEN_RATE]->store(info->pages_written_rate));
2248
2249 if (info->n_page_get_delta) {
2250 OK(fields[IDX_BUF_STATS_HIT_RATE]->store(
2251 1000 - (1000 * info->page_read_delta
2252 / info->n_page_get_delta)));
2253
2254 OK(fields[IDX_BUF_STATS_MADE_YOUNG_PCT]->store(
2255 1000 * info->young_making_delta
2256 / info->n_page_get_delta));
2257
2258 OK(fields[IDX_BUF_STATS_NOT_MADE_YOUNG_PCT]->store(
2259 1000 * info->not_young_making_delta
2260 / info->n_page_get_delta));
2261 } else {
2262 OK(fields[IDX_BUF_STATS_HIT_RATE]->store(0));
2263 OK(fields[IDX_BUF_STATS_MADE_YOUNG_PCT]->store(0));
2264 OK(fields[IDX_BUF_STATS_NOT_MADE_YOUNG_PCT]->store(0));
2265 }
2266
2267 OK(fields[IDX_BUF_STATS_READ_AHREAD]->store(info->n_ra_pages_read));
2268
2269 OK(fields[IDX_BUF_STATS_READ_AHEAD_EVICTED]->store(
2270 info->n_ra_pages_evicted));
2271
2272 OK(fields[IDX_BUF_STATS_READ_AHEAD_RATE]->store(
2273 info->pages_readahead_rate));
2274
2275 OK(fields[IDX_BUF_STATS_READ_AHEAD_EVICT_RATE]->store(
2276 info->pages_evicted_rate));
2277
2278 OK(fields[IDX_BUF_STATS_LRU_IO_SUM]->store(info->io_sum));
2279
2280 OK(fields[IDX_BUF_STATS_LRU_IO_CUR]->store(info->io_cur));
2281
2282 OK(fields[IDX_BUF_STATS_UNZIP_SUM]->store(info->unzip_sum));
2283
2284 OK(fields[IDX_BUF_STATS_UNZIP_CUR]->store( info->unzip_cur));
2285
2286 DBUG_RETURN(schema_table_store_record(thd, table));
2287 }
2288
2289 /*******************************************************************//**
2290 This is the function that loops through each buffer pool and fetch buffer
2291 pool stats to information schema table: I_S_INNODB_BUFFER_POOL_STATS
2292 @return 0 on success, 1 on failure */
2293 static
2294 int
i_s_innodb_buffer_stats_fill_table(THD * thd,TABLE_LIST * tables,Item *)2295 i_s_innodb_buffer_stats_fill_table(
2296 /*===============================*/
2297 THD* thd, /*!< in: thread */
2298 TABLE_LIST* tables, /*!< in/out: tables to fill */
2299 Item* ) /*!< in: condition (ignored) */
2300 {
2301 int status = 0;
2302 buf_pool_info_t* pool_info;
2303
2304 DBUG_ENTER("i_s_innodb_buffer_fill_general");
2305 RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name);
2306
2307 /* Only allow the PROCESS privilege holder to access the stats */
2308 if (check_global_access(thd, PROCESS_ACL)) {
2309 DBUG_RETURN(0);
2310 }
2311
2312 pool_info = (buf_pool_info_t*) mem_zalloc(
2313 srv_buf_pool_instances * sizeof *pool_info);
2314
2315 /* Walk through each buffer pool */
2316 for (ulint i = 0; i < srv_buf_pool_instances; i++) {
2317 buf_pool_t* buf_pool;
2318
2319 buf_pool = buf_pool_from_array(i);
2320
2321 /* Fetch individual buffer pool info */
2322 buf_stats_get_pool_info(buf_pool, i, pool_info);
2323
2324 status = i_s_innodb_stats_fill(thd, tables, &pool_info[i]);
2325
2326 /* If something goes wrong, break and return */
2327 if (status) {
2328 break;
2329 }
2330 }
2331
2332 mem_free(pool_info);
2333
2334 DBUG_RETURN(status);
2335 }
2336
2337 /*******************************************************************//**
2338 Bind the dynamic table INFORMATION_SCHEMA.INNODB_BUFFER_POOL_STATS.
2339 @return 0 on success, 1 on failure */
2340 static
2341 int
i_s_innodb_buffer_pool_stats_init(void * p)2342 i_s_innodb_buffer_pool_stats_init(
2343 /*==============================*/
2344 void* p) /*!< in/out: table schema object */
2345 {
2346 ST_SCHEMA_TABLE* schema;
2347
2348 DBUG_ENTER("i_s_innodb_buffer_pool_stats_init");
2349
2350 schema = reinterpret_cast<ST_SCHEMA_TABLE*>(p);
2351
2352 schema->fields_info = i_s_innodb_buffer_stats_fields_info;
2353 schema->fill_table = i_s_innodb_buffer_stats_fill_table;
2354
2355 DBUG_RETURN(0);
2356 }
2357
2358 UNIV_INTERN struct st_mysql_plugin i_s_innodb_buffer_stats =
2359 {
2360 /* the plugin type (a MYSQL_XXX_PLUGIN value) */
2361 /* int */
2362 STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
2363
2364 /* pointer to type-specific plugin descriptor */
2365 /* void* */
2366 STRUCT_FLD(info, &i_s_info),
2367
2368 /* plugin name */
2369 /* const char* */
2370 STRUCT_FLD(name, "INNODB_BUFFER_POOL_STATS"),
2371
2372 /* plugin author (for SHOW PLUGINS) */
2373 /* const char* */
2374 STRUCT_FLD(author, plugin_author),
2375
2376 /* general descriptive text (for SHOW PLUGINS) */
2377 /* const char* */
2378 STRUCT_FLD(descr, "InnoDB Buffer Pool Statistics Information "),
2379
2380 /* the plugin license (PLUGIN_LICENSE_XXX) */
2381 /* int */
2382 STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
2383
2384 /* the function to invoke when plugin is loaded */
2385 /* int (*)(void*); */
2386 STRUCT_FLD(init, i_s_innodb_buffer_pool_stats_init),
2387
2388 /* the function to invoke when plugin is unloaded */
2389 /* int (*)(void*); */
2390 STRUCT_FLD(deinit, i_s_common_deinit),
2391
2392 /* plugin version (for SHOW PLUGINS) */
2393 /* unsigned int */
2394 STRUCT_FLD(version, INNODB_VERSION_SHORT),
2395
2396 /* struct st_mysql_show_var* */
2397 STRUCT_FLD(status_vars, NULL),
2398
2399 /* struct st_mysql_sys_var** */
2400 STRUCT_FLD(system_vars, NULL),
2401
2402 /* reserved for dependency checking */
2403 /* void* */
2404 STRUCT_FLD(__reserved1, NULL),
2405
2406 /* Plugin flags */
2407 /* unsigned long */
2408 STRUCT_FLD(flags, 0UL),
2409 };
2410
2411 /* Fields of the dynamic table INNODB_BUFFER_POOL_PAGE. */
2412 static ST_FIELD_INFO i_s_innodb_buffer_page_fields_info[] =
2413 {
2414 #define IDX_BUFFER_POOL_ID 0
2415 {STRUCT_FLD(field_name, "POOL_ID"),
2416 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
2417 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
2418 STRUCT_FLD(value, 0),
2419 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
2420 STRUCT_FLD(old_name, ""),
2421 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2422
2423 #define IDX_BUFFER_BLOCK_ID 1
2424 {STRUCT_FLD(field_name, "BLOCK_ID"),
2425 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
2426 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
2427 STRUCT_FLD(value, 0),
2428 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
2429 STRUCT_FLD(old_name, ""),
2430 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2431
2432 #define IDX_BUFFER_PAGE_SPACE 2
2433 {STRUCT_FLD(field_name, "SPACE"),
2434 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
2435 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
2436 STRUCT_FLD(value, 0),
2437 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
2438 STRUCT_FLD(old_name, ""),
2439 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2440
2441 #define IDX_BUFFER_PAGE_NUM 3
2442 {STRUCT_FLD(field_name, "PAGE_NUMBER"),
2443 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
2444 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
2445 STRUCT_FLD(value, 0),
2446 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
2447 STRUCT_FLD(old_name, ""),
2448 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2449
2450 #define IDX_BUFFER_PAGE_TYPE 4
2451 {STRUCT_FLD(field_name, "PAGE_TYPE"),
2452 STRUCT_FLD(field_length, 64),
2453 STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
2454 STRUCT_FLD(value, 0),
2455 STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
2456 STRUCT_FLD(old_name, ""),
2457 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2458
2459 #define IDX_BUFFER_PAGE_FLUSH_TYPE 5
2460 {STRUCT_FLD(field_name, "FLUSH_TYPE"),
2461 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
2462 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
2463 STRUCT_FLD(value, 0),
2464 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
2465 STRUCT_FLD(old_name, ""),
2466 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2467
2468 #define IDX_BUFFER_PAGE_FIX_COUNT 6
2469 {STRUCT_FLD(field_name, "FIX_COUNT"),
2470 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
2471 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
2472 STRUCT_FLD(value, 0),
2473 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
2474 STRUCT_FLD(old_name, ""),
2475 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2476
2477 #define IDX_BUFFER_PAGE_HASHED 7
2478 {STRUCT_FLD(field_name, "IS_HASHED"),
2479 STRUCT_FLD(field_length, 3),
2480 STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
2481 STRUCT_FLD(value, 0),
2482 STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
2483 STRUCT_FLD(old_name, ""),
2484 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2485
2486 #define IDX_BUFFER_PAGE_NEWEST_MOD 8
2487 {STRUCT_FLD(field_name, "NEWEST_MODIFICATION"),
2488 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
2489 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
2490 STRUCT_FLD(value, 0),
2491 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
2492 STRUCT_FLD(old_name, ""),
2493 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2494
2495 #define IDX_BUFFER_PAGE_OLDEST_MOD 9
2496 {STRUCT_FLD(field_name, "OLDEST_MODIFICATION"),
2497 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
2498 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
2499 STRUCT_FLD(value, 0),
2500 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
2501 STRUCT_FLD(old_name, ""),
2502 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2503
2504 #define IDX_BUFFER_PAGE_ACCESS_TIME 10
2505 {STRUCT_FLD(field_name, "ACCESS_TIME"),
2506 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
2507 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
2508 STRUCT_FLD(value, 0),
2509 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
2510 STRUCT_FLD(old_name, ""),
2511 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2512
2513 #define IDX_BUFFER_PAGE_TABLE_NAME 11
2514 {STRUCT_FLD(field_name, "TABLE_NAME"),
2515 STRUCT_FLD(field_length, 1024),
2516 STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
2517 STRUCT_FLD(value, 0),
2518 STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
2519 STRUCT_FLD(old_name, ""),
2520 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2521
2522 #define IDX_BUFFER_PAGE_INDEX_NAME 12
2523 {STRUCT_FLD(field_name, "INDEX_NAME"),
2524 STRUCT_FLD(field_length, 1024),
2525 STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
2526 STRUCT_FLD(value, 0),
2527 STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
2528 STRUCT_FLD(old_name, ""),
2529 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2530
2531 #define IDX_BUFFER_PAGE_NUM_RECS 13
2532 {STRUCT_FLD(field_name, "NUMBER_RECORDS"),
2533 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
2534 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
2535 STRUCT_FLD(value, 0),
2536 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
2537 STRUCT_FLD(old_name, ""),
2538 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2539
2540 #define IDX_BUFFER_PAGE_DATA_SIZE 14
2541 {STRUCT_FLD(field_name, "DATA_SIZE"),
2542 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
2543 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
2544 STRUCT_FLD(value, 0),
2545 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
2546 STRUCT_FLD(old_name, ""),
2547 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2548
2549 #define IDX_BUFFER_PAGE_ZIP_SIZE 15
2550 {STRUCT_FLD(field_name, "COMPRESSED_SIZE"),
2551 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
2552 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
2553 STRUCT_FLD(value, 0),
2554 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
2555 STRUCT_FLD(old_name, ""),
2556 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2557
2558 #define IDX_BUFFER_PAGE_STATE 16
2559 {STRUCT_FLD(field_name, "PAGE_STATE"),
2560 STRUCT_FLD(field_length, 64),
2561 STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
2562 STRUCT_FLD(value, 0),
2563 STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
2564 STRUCT_FLD(old_name, ""),
2565 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2566
2567 #define IDX_BUFFER_PAGE_IO_FIX 17
2568 {STRUCT_FLD(field_name, "IO_FIX"),
2569 STRUCT_FLD(field_length, 64),
2570 STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
2571 STRUCT_FLD(value, 0),
2572 STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
2573 STRUCT_FLD(old_name, ""),
2574 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2575
2576 #define IDX_BUFFER_PAGE_IS_OLD 18
2577 {STRUCT_FLD(field_name, "IS_OLD"),
2578 STRUCT_FLD(field_length, 3),
2579 STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
2580 STRUCT_FLD(value, 0),
2581 STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
2582 STRUCT_FLD(old_name, ""),
2583 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2584
2585 #define IDX_BUFFER_PAGE_FREE_CLOCK 19
2586 {STRUCT_FLD(field_name, "FREE_PAGE_CLOCK"),
2587 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
2588 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
2589 STRUCT_FLD(value, 0),
2590 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
2591 STRUCT_FLD(old_name, ""),
2592 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2593
2594 END_OF_ST_FIELD_INFO
2595 };
2596
2597 /*******************************************************************//**
2598 Fill Information Schema table INNODB_BUFFER_PAGE with information
2599 cached in the buf_page_info_t array
2600 @return 0 on success, 1 on failure */
2601 static
2602 int
i_s_innodb_buffer_page_fill(THD * thd,TABLE_LIST * tables,const buf_page_info_t * info_array,ulint num_page,mem_heap_t * heap)2603 i_s_innodb_buffer_page_fill(
2604 /*========================*/
2605 THD* thd, /*!< in: thread */
2606 TABLE_LIST* tables, /*!< in/out: tables to fill */
2607 const buf_page_info_t* info_array, /*!< in: array cached page
2608 info */
2609 ulint num_page, /*!< in: number of page info
2610 cached */
2611 mem_heap_t* heap) /*!< in: temp heap memory */
2612 {
2613 TABLE* table;
2614 Field** fields;
2615
2616 DBUG_ENTER("i_s_innodb_buffer_page_fill");
2617
2618 table = tables->table;
2619
2620 fields = table->field;
2621
2622 /* Iterate through the cached array and fill the I_S table rows */
2623 for (ulint i = 0; i < num_page; i++) {
2624 const buf_page_info_t* page_info;
2625 const char* table_name;
2626 const char* index_name;
2627 const char* state_str;
2628 enum buf_page_state state;
2629
2630 page_info = info_array + i;
2631
2632 table_name = NULL;
2633 index_name = NULL;
2634 state_str = NULL;
2635
2636 OK(fields[IDX_BUFFER_POOL_ID]->store(page_info->pool_id));
2637
2638 OK(fields[IDX_BUFFER_BLOCK_ID]->store(page_info->block_id));
2639
2640 OK(fields[IDX_BUFFER_PAGE_SPACE]->store(page_info->space_id));
2641
2642 OK(fields[IDX_BUFFER_PAGE_NUM]->store(page_info->page_num));
2643
2644 OK(field_store_string(
2645 fields[IDX_BUFFER_PAGE_TYPE],
2646 i_s_page_type[page_info->page_type].type_str));
2647
2648 OK(fields[IDX_BUFFER_PAGE_FLUSH_TYPE]->store(
2649 page_info->flush_type));
2650
2651 OK(fields[IDX_BUFFER_PAGE_FIX_COUNT]->store(
2652 page_info->fix_count));
2653
2654 if (page_info->hashed) {
2655 OK(field_store_string(
2656 fields[IDX_BUFFER_PAGE_HASHED], "YES"));
2657 } else {
2658 OK(field_store_string(
2659 fields[IDX_BUFFER_PAGE_HASHED], "NO"));
2660 }
2661
2662 OK(fields[IDX_BUFFER_PAGE_NEWEST_MOD]->store(
2663 (longlong) page_info->newest_mod, true));
2664
2665 OK(fields[IDX_BUFFER_PAGE_OLDEST_MOD]->store(
2666 (longlong) page_info->oldest_mod, true));
2667
2668 OK(fields[IDX_BUFFER_PAGE_ACCESS_TIME]->store(
2669 page_info->access_time));
2670
2671 /* If this is an index page, fetch the index name
2672 and table name */
2673 if (page_info->page_type == I_S_PAGE_TYPE_INDEX) {
2674 const dict_index_t* index;
2675
2676 mutex_enter(&dict_sys->mutex);
2677 index = dict_index_get_if_in_cache_low(
2678 page_info->index_id);
2679
2680 /* Copy the index/table name under mutex. We
2681 do not want to hold the InnoDB mutex while
2682 filling the IS table */
2683 if (index) {
2684 const char* name_ptr = index->name;
2685
2686 if (name_ptr[0] == TEMP_INDEX_PREFIX) {
2687 name_ptr++;
2688 }
2689
2690 index_name = mem_heap_strdup(heap, name_ptr);
2691
2692 table_name = mem_heap_strdup(heap,
2693 index->table_name);
2694
2695 DBUG_EXECUTE_IF("mysql_test_print_index_type",
2696 {
2697 char idx_type[3];
2698
2699 ut_snprintf(idx_type,
2700 sizeof(idx_type),
2701 "%d",
2702 index->type);
2703
2704 index_name=mem_heap_strcat(heap,
2705 index_name,
2706 idx_type);
2707 };);
2708 }
2709
2710 mutex_exit(&dict_sys->mutex);
2711 }
2712
2713 OK(field_store_string(
2714 fields[IDX_BUFFER_PAGE_TABLE_NAME], table_name));
2715
2716 OK(field_store_string(
2717 fields[IDX_BUFFER_PAGE_INDEX_NAME], index_name));
2718
2719 OK(fields[IDX_BUFFER_PAGE_NUM_RECS]->store(
2720 page_info->num_recs));
2721
2722 OK(fields[IDX_BUFFER_PAGE_DATA_SIZE]->store(
2723 page_info->data_size));
2724
2725 OK(fields[IDX_BUFFER_PAGE_ZIP_SIZE]->store(
2726 page_info->zip_ssize
2727 ? (PAGE_ZIP_MIN_SIZE >> 1) << page_info->zip_ssize
2728 : 0));
2729
2730 #if BUF_PAGE_STATE_BITS > 3
2731 # error "BUF_PAGE_STATE_BITS > 3, please ensure that all 1<<BUF_PAGE_STATE_BITS values are checked for"
2732 #endif
2733 state = static_cast<enum buf_page_state>(page_info->page_state);
2734
2735 switch (state) {
2736 /* First three states are for compression pages and
2737 are not states we would get as we scan pages through
2738 buffer blocks */
2739 case BUF_BLOCK_ZIP_FREE:
2740 case BUF_BLOCK_ZIP_PAGE:
2741 case BUF_BLOCK_ZIP_DIRTY:
2742 state_str = NULL;
2743 break;
2744 case BUF_BLOCK_NOT_USED:
2745 state_str = "NOT_USED";
2746 break;
2747 case BUF_BLOCK_READY_FOR_USE:
2748 state_str = "READY_FOR_USE";
2749 break;
2750 case BUF_BLOCK_FILE_PAGE:
2751 state_str = "FILE_PAGE";
2752 break;
2753 case BUF_BLOCK_MEMORY:
2754 state_str = "MEMORY";
2755 break;
2756 case BUF_BLOCK_REMOVE_HASH:
2757 state_str = "REMOVE_HASH";
2758 break;
2759 };
2760
2761 OK(field_store_string(fields[IDX_BUFFER_PAGE_STATE],
2762 state_str));
2763
2764 switch (page_info->io_fix) {
2765 case BUF_IO_NONE:
2766 OK(field_store_string(fields[IDX_BUFFER_PAGE_IO_FIX],
2767 "IO_NONE"));
2768 break;
2769 case BUF_IO_READ:
2770 OK(field_store_string(fields[IDX_BUFFER_PAGE_IO_FIX],
2771 "IO_READ"));
2772 break;
2773 case BUF_IO_WRITE:
2774 OK(field_store_string(fields[IDX_BUFFER_PAGE_IO_FIX],
2775 "IO_WRITE"));
2776 break;
2777 case BUF_IO_PIN:
2778 OK(field_store_string(fields[IDX_BUFFER_PAGE_IO_FIX],
2779 "IO_PIN"));
2780 break;
2781 }
2782
2783 OK(field_store_string(fields[IDX_BUFFER_PAGE_IS_OLD],
2784 (page_info->is_old) ? "YES" : "NO"));
2785
2786 OK(fields[IDX_BUFFER_PAGE_FREE_CLOCK]->store(
2787 page_info->freed_page_clock));
2788
2789 if (schema_table_store_record(thd, table)) {
2790 DBUG_RETURN(1);
2791 }
2792 }
2793
2794 DBUG_RETURN(0);
2795 }
2796
2797 /*******************************************************************//**
2798 Set appropriate page type to a buf_page_info_t structure */
2799 static
2800 void
i_s_innodb_set_page_type(buf_page_info_t * page_info,ulint page_type,const byte * frame)2801 i_s_innodb_set_page_type(
2802 /*=====================*/
2803 buf_page_info_t*page_info, /*!< in/out: structure to fill with
2804 scanned info */
2805 ulint page_type, /*!< in: page type */
2806 const byte* frame) /*!< in: buffer frame */
2807 {
2808 if (page_type == FIL_PAGE_INDEX) {
2809 const page_t* page = (const page_t*) frame;
2810
2811 page_info->index_id = btr_page_get_index_id(page);
2812
2813 /* FIL_PAGE_INDEX is a bit special, its value
2814 is defined as 17855, so we cannot use FIL_PAGE_INDEX
2815 to index into i_s_page_type[] array, its array index
2816 in the i_s_page_type[] array is I_S_PAGE_TYPE_INDEX
2817 (1) for index pages or I_S_PAGE_TYPE_IBUF for
2818 change buffer index pages */
2819 if (page_info->index_id
2820 == static_cast<index_id_t>(DICT_IBUF_ID_MIN
2821 + IBUF_SPACE_ID)) {
2822 page_info->page_type = I_S_PAGE_TYPE_IBUF;
2823 } else {
2824 page_info->page_type = I_S_PAGE_TYPE_INDEX;
2825 }
2826
2827 page_info->data_size = (ulint)(page_header_get_field(
2828 page, PAGE_HEAP_TOP) - (page_is_comp(page)
2829 ? PAGE_NEW_SUPREMUM_END
2830 : PAGE_OLD_SUPREMUM_END)
2831 - page_header_get_field(page, PAGE_GARBAGE));
2832
2833 page_info->num_recs = page_get_n_recs(page);
2834 } else if (page_type > FIL_PAGE_TYPE_LAST) {
2835 /* Encountered an unknown page type */
2836 page_info->page_type = I_S_PAGE_TYPE_UNKNOWN;
2837 } else {
2838 /* Make sure we get the right index into the
2839 i_s_page_type[] array */
2840 ut_a(page_type == i_s_page_type[page_type].type_value);
2841
2842 page_info->page_type = page_type;
2843 }
2844
2845 if (page_info->page_type == FIL_PAGE_TYPE_ZBLOB
2846 || page_info->page_type == FIL_PAGE_TYPE_ZBLOB2) {
2847 page_info->page_num = mach_read_from_4(
2848 frame + FIL_PAGE_OFFSET);
2849 page_info->space_id = mach_read_from_4(
2850 frame + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
2851 }
2852 }
2853 /*******************************************************************//**
2854 Scans pages in the buffer cache, and collect their general information
2855 into the buf_page_info_t array which is zero-filled. So any fields
2856 that are not initialized in the function will default to 0 */
2857 static
2858 void
i_s_innodb_buffer_page_get_info(const buf_page_t * bpage,ulint pool_id,ulint pos,buf_page_info_t * page_info)2859 i_s_innodb_buffer_page_get_info(
2860 /*============================*/
2861 const buf_page_t*bpage, /*!< in: buffer pool page to scan */
2862 ulint pool_id, /*!< in: buffer pool id */
2863 ulint pos, /*!< in: buffer block position in
2864 buffer pool or in the LRU list */
2865 buf_page_info_t*page_info) /*!< in: zero filled info structure;
2866 out: structure filled with scanned
2867 info */
2868 {
2869 ut_ad(pool_id < MAX_BUFFER_POOLS);
2870
2871 page_info->pool_id = pool_id;
2872
2873 page_info->block_id = pos;
2874
2875 page_info->page_state = buf_page_get_state(bpage);
2876
2877 /* Only fetch information for buffers that map to a tablespace,
2878 that is, buffer page with state BUF_BLOCK_ZIP_PAGE,
2879 BUF_BLOCK_ZIP_DIRTY or BUF_BLOCK_FILE_PAGE */
2880 if (buf_page_in_file(bpage)) {
2881 const byte* frame;
2882 ulint page_type;
2883
2884 page_info->space_id = buf_page_get_space(bpage);
2885
2886 page_info->page_num = buf_page_get_page_no(bpage);
2887
2888 page_info->flush_type = bpage->flush_type;
2889
2890 page_info->fix_count = bpage->buf_fix_count;
2891
2892 page_info->newest_mod = bpage->newest_modification;
2893
2894 page_info->oldest_mod = bpage->oldest_modification;
2895
2896 page_info->access_time = bpage->access_time;
2897
2898 page_info->zip_ssize = bpage->zip.ssize;
2899
2900 page_info->io_fix = bpage->io_fix;
2901
2902 page_info->is_old = bpage->old;
2903
2904 page_info->freed_page_clock = bpage->freed_page_clock;
2905
2906 switch (buf_page_get_io_fix(bpage)) {
2907 case BUF_IO_NONE:
2908 case BUF_IO_WRITE:
2909 case BUF_IO_PIN:
2910 break;
2911 case BUF_IO_READ:
2912 page_info->page_type = I_S_PAGE_TYPE_UNKNOWN;
2913 return;
2914 }
2915
2916 if (page_info->page_state == BUF_BLOCK_FILE_PAGE) {
2917 const buf_block_t*block;
2918
2919 block = reinterpret_cast<const buf_block_t*>(bpage);
2920 frame = block->frame;
2921 page_info->hashed = (block->index != NULL);
2922 } else {
2923 ut_ad(page_info->zip_ssize);
2924 frame = bpage->zip.data;
2925 }
2926
2927 page_type = fil_page_get_type(frame);
2928
2929 i_s_innodb_set_page_type(page_info, page_type, frame);
2930 } else {
2931 page_info->page_type = I_S_PAGE_TYPE_UNKNOWN;
2932 }
2933 }
2934
2935 /*******************************************************************//**
2936 This is the function that goes through each block of the buffer pool
2937 and fetch information to information schema tables: INNODB_BUFFER_PAGE.
2938 @return 0 on success, 1 on failure */
2939 static
2940 int
i_s_innodb_fill_buffer_pool(THD * thd,TABLE_LIST * tables,buf_pool_t * buf_pool,const ulint pool_id)2941 i_s_innodb_fill_buffer_pool(
2942 /*========================*/
2943 THD* thd, /*!< in: thread */
2944 TABLE_LIST* tables, /*!< in/out: tables to fill */
2945 buf_pool_t* buf_pool, /*!< in: buffer pool to scan */
2946 const ulint pool_id) /*!< in: buffer pool id */
2947 {
2948 int status = 0;
2949 mem_heap_t* heap;
2950
2951 DBUG_ENTER("i_s_innodb_fill_buffer_pool");
2952 RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name);
2953
2954 heap = mem_heap_create(10000);
2955
2956 /* Go through each chunk of buffer pool. Currently, we only
2957 have one single chunk for each buffer pool */
2958 for (ulint n = 0; n < buf_pool->n_chunks; n++) {
2959 const buf_block_t* block;
2960 ulint n_blocks;
2961 buf_page_info_t* info_buffer;
2962 ulint num_page;
2963 ulint mem_size;
2964 ulint chunk_size;
2965 ulint num_to_process = 0;
2966 ulint block_id = 0;
2967
2968 /* Get buffer block of the nth chunk */
2969 block = buf_get_nth_chunk_block(buf_pool, n, &chunk_size);
2970 num_page = 0;
2971
2972 while (chunk_size > 0) {
2973 /* we cache maximum MAX_BUF_INFO_CACHED number of
2974 buffer page info */
2975 num_to_process = ut_min(chunk_size,
2976 MAX_BUF_INFO_CACHED);
2977
2978 mem_size = num_to_process * sizeof(buf_page_info_t);
2979
2980 /* For each chunk, we'll pre-allocate information
2981 structures to cache the page information read from
2982 the buffer pool. Doing so before obtain any mutex */
2983 info_buffer = (buf_page_info_t*) mem_heap_zalloc(
2984 heap, mem_size);
2985
2986 /* Obtain appropriate mutexes. Since this is diagnostic
2987 buffer pool info printout, we are not required to
2988 preserve the overall consistency, so we can
2989 release mutex periodically */
2990 buf_pool_mutex_enter(buf_pool);
2991
2992 /* GO through each block in the chunk */
2993 for (n_blocks = num_to_process; n_blocks--; block++) {
2994 i_s_innodb_buffer_page_get_info(
2995 &block->page, pool_id, block_id,
2996 info_buffer + num_page);
2997 block_id++;
2998 num_page++;
2999 }
3000
3001 buf_pool_mutex_exit(buf_pool);
3002
3003 /* Fill in information schema table with information
3004 just collected from the buffer chunk scan */
3005 status = i_s_innodb_buffer_page_fill(
3006 thd, tables, info_buffer,
3007 num_page, heap);
3008
3009 /* If something goes wrong, break and return */
3010 if (status) {
3011 break;
3012 }
3013
3014 mem_heap_empty(heap);
3015 chunk_size -= num_to_process;
3016 num_page = 0;
3017 }
3018 }
3019
3020 mem_heap_free(heap);
3021
3022 DBUG_RETURN(status);
3023 }
3024
3025 /*******************************************************************//**
3026 Fill page information for pages in InnoDB buffer pool to the
3027 dynamic table INFORMATION_SCHEMA.INNODB_BUFFER_PAGE
3028 @return 0 on success, 1 on failure */
3029 static
3030 int
i_s_innodb_buffer_page_fill_table(THD * thd,TABLE_LIST * tables,Item *)3031 i_s_innodb_buffer_page_fill_table(
3032 /*==============================*/
3033 THD* thd, /*!< in: thread */
3034 TABLE_LIST* tables, /*!< in/out: tables to fill */
3035 Item* ) /*!< in: condition (ignored) */
3036 {
3037 int status = 0;
3038
3039 DBUG_ENTER("i_s_innodb_buffer_page_fill_table");
3040
3041 /* deny access to user without PROCESS privilege */
3042 if (check_global_access(thd, PROCESS_ACL)) {
3043 DBUG_RETURN(0);
3044 }
3045
3046 /* Walk through each buffer pool */
3047 for (ulint i = 0; i < srv_buf_pool_instances; i++) {
3048 buf_pool_t* buf_pool;
3049
3050 buf_pool = buf_pool_from_array(i);
3051
3052 /* Fetch information from pages in this buffer pool,
3053 and fill the corresponding I_S table */
3054 status = i_s_innodb_fill_buffer_pool(thd, tables, buf_pool, i);
3055
3056 /* If something wrong, break and return */
3057 if (status) {
3058 break;
3059 }
3060 }
3061
3062 DBUG_RETURN(status);
3063 }
3064
3065 /*******************************************************************//**
3066 Bind the dynamic table INFORMATION_SCHEMA.INNODB_BUFFER_PAGE.
3067 @return 0 on success, 1 on failure */
3068 static
3069 int
i_s_innodb_buffer_page_init(void * p)3070 i_s_innodb_buffer_page_init(
3071 /*========================*/
3072 void* p) /*!< in/out: table schema object */
3073 {
3074 ST_SCHEMA_TABLE* schema;
3075
3076 DBUG_ENTER("i_s_innodb_buffer_page_init");
3077
3078 schema = reinterpret_cast<ST_SCHEMA_TABLE*>(p);
3079
3080 schema->fields_info = i_s_innodb_buffer_page_fields_info;
3081 schema->fill_table = i_s_innodb_buffer_page_fill_table;
3082
3083 DBUG_RETURN(0);
3084 }
3085
3086 UNIV_INTERN struct st_mysql_plugin i_s_innodb_buffer_page =
3087 {
3088 /* the plugin type (a MYSQL_XXX_PLUGIN value) */
3089 /* int */
3090 STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
3091
3092 /* pointer to type-specific plugin descriptor */
3093 /* void* */
3094 STRUCT_FLD(info, &i_s_info),
3095
3096 /* plugin name */
3097 /* const char* */
3098 STRUCT_FLD(name, "INNODB_BUFFER_PAGE"),
3099
3100 /* plugin author (for SHOW PLUGINS) */
3101 /* const char* */
3102 STRUCT_FLD(author, plugin_author),
3103
3104 /* general descriptive text (for SHOW PLUGINS) */
3105 /* const char* */
3106 STRUCT_FLD(descr, "InnoDB Buffer Page Information"),
3107
3108 /* the plugin license (PLUGIN_LICENSE_XXX) */
3109 /* int */
3110 STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
3111
3112 /* the function to invoke when plugin is loaded */
3113 /* int (*)(void*); */
3114 STRUCT_FLD(init, i_s_innodb_buffer_page_init),
3115
3116 /* the function to invoke when plugin is unloaded */
3117 /* int (*)(void*); */
3118 STRUCT_FLD(deinit, i_s_common_deinit),
3119
3120 /* plugin version (for SHOW PLUGINS) */
3121 /* unsigned int */
3122 STRUCT_FLD(version, INNODB_VERSION_SHORT),
3123
3124 /* struct st_mysql_show_var* */
3125 STRUCT_FLD(status_vars, NULL),
3126
3127 /* struct st_mysql_sys_var** */
3128 STRUCT_FLD(system_vars, NULL),
3129
3130 /* reserved for dependency checking */
3131 /* void* */
3132 STRUCT_FLD(__reserved1, NULL),
3133
3134 /* Plugin flags */
3135 /* unsigned long */
3136 STRUCT_FLD(flags, 0UL),
3137 };
3138
3139 static ST_FIELD_INFO i_s_innodb_buf_page_lru_fields_info[] =
3140 {
3141 #define IDX_BUF_LRU_POOL_ID 0
3142 {STRUCT_FLD(field_name, "POOL_ID"),
3143 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
3144 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
3145 STRUCT_FLD(value, 0),
3146 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
3147 STRUCT_FLD(old_name, ""),
3148 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
3149
3150 #define IDX_BUF_LRU_POS 1
3151 {STRUCT_FLD(field_name, "LRU_POSITION"),
3152 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
3153 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
3154 STRUCT_FLD(value, 0),
3155 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
3156 STRUCT_FLD(old_name, ""),
3157 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
3158
3159 #define IDX_BUF_LRU_PAGE_SPACE 2
3160 {STRUCT_FLD(field_name, "SPACE"),
3161 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
3162 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
3163 STRUCT_FLD(value, 0),
3164 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
3165 STRUCT_FLD(old_name, ""),
3166 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
3167
3168 #define IDX_BUF_LRU_PAGE_NUM 3
3169 {STRUCT_FLD(field_name, "PAGE_NUMBER"),
3170 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
3171 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
3172 STRUCT_FLD(value, 0),
3173 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
3174 STRUCT_FLD(old_name, ""),
3175 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
3176
3177 #define IDX_BUF_LRU_PAGE_TYPE 4
3178 {STRUCT_FLD(field_name, "PAGE_TYPE"),
3179 STRUCT_FLD(field_length, 64),
3180 STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
3181 STRUCT_FLD(value, 0),
3182 STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
3183 STRUCT_FLD(old_name, ""),
3184 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
3185
3186 #define IDX_BUF_LRU_PAGE_FLUSH_TYPE 5
3187 {STRUCT_FLD(field_name, "FLUSH_TYPE"),
3188 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
3189 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
3190 STRUCT_FLD(value, 0),
3191 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
3192 STRUCT_FLD(old_name, ""),
3193 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
3194
3195 #define IDX_BUF_LRU_PAGE_FIX_COUNT 6
3196 {STRUCT_FLD(field_name, "FIX_COUNT"),
3197 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
3198 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
3199 STRUCT_FLD(value, 0),
3200 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
3201 STRUCT_FLD(old_name, ""),
3202 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
3203
3204 #define IDX_BUF_LRU_PAGE_HASHED 7
3205 {STRUCT_FLD(field_name, "IS_HASHED"),
3206 STRUCT_FLD(field_length, 3),
3207 STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
3208 STRUCT_FLD(value, 0),
3209 STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
3210 STRUCT_FLD(old_name, ""),
3211 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
3212
3213 #define IDX_BUF_LRU_PAGE_NEWEST_MOD 8
3214 {STRUCT_FLD(field_name, "NEWEST_MODIFICATION"),
3215 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
3216 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
3217 STRUCT_FLD(value, 0),
3218 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
3219 STRUCT_FLD(old_name, ""),
3220 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
3221
3222 #define IDX_BUF_LRU_PAGE_OLDEST_MOD 9
3223 {STRUCT_FLD(field_name, "OLDEST_MODIFICATION"),
3224 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
3225 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
3226 STRUCT_FLD(value, 0),
3227 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
3228 STRUCT_FLD(old_name, ""),
3229 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
3230
3231 #define IDX_BUF_LRU_PAGE_ACCESS_TIME 10
3232 {STRUCT_FLD(field_name, "ACCESS_TIME"),
3233 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
3234 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
3235 STRUCT_FLD(value, 0),
3236 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
3237 STRUCT_FLD(old_name, ""),
3238 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
3239
3240 #define IDX_BUF_LRU_PAGE_TABLE_NAME 11
3241 {STRUCT_FLD(field_name, "TABLE_NAME"),
3242 STRUCT_FLD(field_length, 1024),
3243 STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
3244 STRUCT_FLD(value, 0),
3245 STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
3246 STRUCT_FLD(old_name, ""),
3247 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
3248
3249 #define IDX_BUF_LRU_PAGE_INDEX_NAME 12
3250 {STRUCT_FLD(field_name, "INDEX_NAME"),
3251 STRUCT_FLD(field_length, 1024),
3252 STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
3253 STRUCT_FLD(value, 0),
3254 STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
3255 STRUCT_FLD(old_name, ""),
3256 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
3257
3258 #define IDX_BUF_LRU_PAGE_NUM_RECS 13
3259 {STRUCT_FLD(field_name, "NUMBER_RECORDS"),
3260 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
3261 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
3262 STRUCT_FLD(value, 0),
3263 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
3264 STRUCT_FLD(old_name, ""),
3265 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
3266
3267 #define IDX_BUF_LRU_PAGE_DATA_SIZE 14
3268 {STRUCT_FLD(field_name, "DATA_SIZE"),
3269 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
3270 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
3271 STRUCT_FLD(value, 0),
3272 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
3273 STRUCT_FLD(old_name, ""),
3274 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
3275
3276 #define IDX_BUF_LRU_PAGE_ZIP_SIZE 15
3277 {STRUCT_FLD(field_name, "COMPRESSED_SIZE"),
3278 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
3279 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
3280 STRUCT_FLD(value, 0),
3281 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
3282 STRUCT_FLD(old_name, ""),
3283 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
3284
3285 #define IDX_BUF_LRU_PAGE_STATE 16
3286 {STRUCT_FLD(field_name, "COMPRESSED"),
3287 STRUCT_FLD(field_length, 3),
3288 STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
3289 STRUCT_FLD(value, 0),
3290 STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
3291 STRUCT_FLD(old_name, ""),
3292 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
3293
3294 #define IDX_BUF_LRU_PAGE_IO_FIX 17
3295 {STRUCT_FLD(field_name, "IO_FIX"),
3296 STRUCT_FLD(field_length, 64),
3297 STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
3298 STRUCT_FLD(value, 0),
3299 STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
3300 STRUCT_FLD(old_name, ""),
3301 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
3302
3303 #define IDX_BUF_LRU_PAGE_IS_OLD 18
3304 {STRUCT_FLD(field_name, "IS_OLD"),
3305 STRUCT_FLD(field_length, 3),
3306 STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
3307 STRUCT_FLD(value, 0),
3308 STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
3309 STRUCT_FLD(old_name, ""),
3310 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
3311
3312 #define IDX_BUF_LRU_PAGE_FREE_CLOCK 19
3313 {STRUCT_FLD(field_name, "FREE_PAGE_CLOCK"),
3314 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
3315 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
3316 STRUCT_FLD(value, 0),
3317 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
3318 STRUCT_FLD(old_name, ""),
3319 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
3320
3321 END_OF_ST_FIELD_INFO
3322 };
3323
3324 /*******************************************************************//**
3325 Fill Information Schema table INNODB_BUFFER_PAGE_LRU with information
3326 cached in the buf_page_info_t array
3327 @return 0 on success, 1 on failure */
3328 static
3329 int
i_s_innodb_buf_page_lru_fill(THD * thd,TABLE_LIST * tables,const buf_page_info_t * info_array,ulint num_page)3330 i_s_innodb_buf_page_lru_fill(
3331 /*=========================*/
3332 THD* thd, /*!< in: thread */
3333 TABLE_LIST* tables, /*!< in/out: tables to fill */
3334 const buf_page_info_t* info_array, /*!< in: array cached page
3335 info */
3336 ulint num_page) /*!< in: number of page info
3337 cached */
3338 {
3339 TABLE* table;
3340 Field** fields;
3341 mem_heap_t* heap;
3342
3343 DBUG_ENTER("i_s_innodb_buf_page_lru_fill");
3344
3345 table = tables->table;
3346
3347 fields = table->field;
3348
3349 heap = mem_heap_create(1000);
3350
3351 /* Iterate through the cached array and fill the I_S table rows */
3352 for (ulint i = 0; i < num_page; i++) {
3353 const buf_page_info_t* page_info;
3354 const char* table_name;
3355 const char* index_name;
3356 const char* state_str;
3357 enum buf_page_state state;
3358
3359 table_name = NULL;
3360 index_name = NULL;
3361 state_str = NULL;
3362
3363 page_info = info_array + i;
3364
3365 OK(fields[IDX_BUF_LRU_POOL_ID]->store(page_info->pool_id));
3366
3367 OK(fields[IDX_BUF_LRU_POS]->store(page_info->block_id));
3368
3369 OK(fields[IDX_BUF_LRU_PAGE_SPACE]->store(page_info->space_id));
3370
3371 OK(fields[IDX_BUF_LRU_PAGE_NUM]->store(page_info->page_num));
3372
3373 OK(field_store_string(
3374 fields[IDX_BUF_LRU_PAGE_TYPE],
3375 i_s_page_type[page_info->page_type].type_str));
3376
3377 OK(fields[IDX_BUF_LRU_PAGE_FLUSH_TYPE]->store(
3378 page_info->flush_type));
3379
3380 OK(fields[IDX_BUF_LRU_PAGE_FIX_COUNT]->store(
3381 page_info->fix_count));
3382
3383 if (page_info->hashed) {
3384 OK(field_store_string(
3385 fields[IDX_BUF_LRU_PAGE_HASHED], "YES"));
3386 } else {
3387 OK(field_store_string(
3388 fields[IDX_BUF_LRU_PAGE_HASHED], "NO"));
3389 }
3390
3391 OK(fields[IDX_BUF_LRU_PAGE_NEWEST_MOD]->store(
3392 page_info->newest_mod, true));
3393
3394 OK(fields[IDX_BUF_LRU_PAGE_OLDEST_MOD]->store(
3395 page_info->oldest_mod, true));
3396
3397 OK(fields[IDX_BUF_LRU_PAGE_ACCESS_TIME]->store(
3398 page_info->access_time));
3399
3400 /* If this is an index page, fetch the index name
3401 and table name */
3402 if (page_info->page_type == I_S_PAGE_TYPE_INDEX) {
3403 const dict_index_t* index;
3404
3405 mutex_enter(&dict_sys->mutex);
3406 index = dict_index_get_if_in_cache_low(
3407 page_info->index_id);
3408
3409 /* Copy the index/table name under mutex. We
3410 do not want to hold the InnoDB mutex while
3411 filling the IS table */
3412 if (index) {
3413 const char* name_ptr = index->name;
3414
3415 if (name_ptr[0] == TEMP_INDEX_PREFIX) {
3416 name_ptr++;
3417 }
3418
3419 index_name = mem_heap_strdup(heap, name_ptr);
3420
3421 table_name = mem_heap_strdup(heap,
3422 index->table_name);
3423 }
3424
3425 mutex_exit(&dict_sys->mutex);
3426 }
3427
3428 OK(field_store_string(
3429 fields[IDX_BUF_LRU_PAGE_TABLE_NAME], table_name));
3430
3431 OK(field_store_string(
3432 fields[IDX_BUF_LRU_PAGE_INDEX_NAME], index_name));
3433 OK(fields[IDX_BUF_LRU_PAGE_NUM_RECS]->store(
3434 page_info->num_recs));
3435
3436 OK(fields[IDX_BUF_LRU_PAGE_DATA_SIZE]->store(
3437 page_info->data_size));
3438
3439 OK(fields[IDX_BUF_LRU_PAGE_ZIP_SIZE]->store(
3440 page_info->zip_ssize ?
3441 512 << page_info->zip_ssize : 0));
3442
3443 state = static_cast<enum buf_page_state>(page_info->page_state);
3444
3445 switch (state) {
3446 /* Compressed page */
3447 case BUF_BLOCK_ZIP_PAGE:
3448 case BUF_BLOCK_ZIP_DIRTY:
3449 state_str = "YES";
3450 break;
3451 /* Uncompressed page */
3452 case BUF_BLOCK_FILE_PAGE:
3453 state_str = "NO";
3454 break;
3455 /* We should not see following states */
3456 case BUF_BLOCK_ZIP_FREE:
3457 case BUF_BLOCK_READY_FOR_USE:
3458 case BUF_BLOCK_NOT_USED:
3459 case BUF_BLOCK_MEMORY:
3460 case BUF_BLOCK_REMOVE_HASH:
3461 state_str = NULL;
3462 break;
3463 };
3464
3465 OK(field_store_string(fields[IDX_BUF_LRU_PAGE_STATE],
3466 state_str));
3467
3468 switch (page_info->io_fix) {
3469 case BUF_IO_NONE:
3470 OK(field_store_string(fields[IDX_BUF_LRU_PAGE_IO_FIX],
3471 "IO_NONE"));
3472 break;
3473 case BUF_IO_READ:
3474 OK(field_store_string(fields[IDX_BUF_LRU_PAGE_IO_FIX],
3475 "IO_READ"));
3476 break;
3477 case BUF_IO_WRITE:
3478 OK(field_store_string(fields[IDX_BUF_LRU_PAGE_IO_FIX],
3479 "IO_WRITE"));
3480 break;
3481 }
3482
3483 OK(field_store_string(fields[IDX_BUF_LRU_PAGE_IS_OLD],
3484 (page_info->is_old) ? "YES" : "NO"));
3485
3486 OK(fields[IDX_BUF_LRU_PAGE_FREE_CLOCK]->store(
3487 page_info->freed_page_clock));
3488
3489 if (schema_table_store_record(thd, table)) {
3490 mem_heap_free(heap);
3491 DBUG_RETURN(1);
3492 }
3493
3494 mem_heap_empty(heap);
3495 }
3496
3497 mem_heap_free(heap);
3498
3499 DBUG_RETURN(0);
3500 }
3501
3502 /*******************************************************************//**
3503 This is the function that goes through buffer pool's LRU list
3504 and fetch information to INFORMATION_SCHEMA.INNODB_BUFFER_PAGE_LRU.
3505 @return 0 on success, 1 on failure */
3506 static
3507 int
i_s_innodb_fill_buffer_lru(THD * thd,TABLE_LIST * tables,buf_pool_t * buf_pool,const ulint pool_id)3508 i_s_innodb_fill_buffer_lru(
3509 /*=======================*/
3510 THD* thd, /*!< in: thread */
3511 TABLE_LIST* tables, /*!< in/out: tables to fill */
3512 buf_pool_t* buf_pool, /*!< in: buffer pool to scan */
3513 const ulint pool_id) /*!< in: buffer pool id */
3514 {
3515 int status = 0;
3516 buf_page_info_t* info_buffer;
3517 ulint lru_pos = 0;
3518 const buf_page_t* bpage;
3519 ulint lru_len;
3520
3521 DBUG_ENTER("i_s_innodb_fill_buffer_lru");
3522 RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name);
3523
3524 /* Obtain buf_pool mutex before allocate info_buffer, since
3525 UT_LIST_GET_LEN(buf_pool->LRU) could change */
3526 buf_pool_mutex_enter(buf_pool);
3527
3528 lru_len = UT_LIST_GET_LEN(buf_pool->LRU);
3529
3530 /* Print error message if malloc fail */
3531 info_buffer = (buf_page_info_t*) my_malloc(
3532 lru_len * sizeof *info_buffer, MYF(MY_WME));
3533
3534 if (!info_buffer) {
3535 status = 1;
3536 goto exit;
3537 }
3538
3539 memset(info_buffer, 0, lru_len * sizeof *info_buffer);
3540
3541 /* Walk through Pool's LRU list and print the buffer page
3542 information */
3543 bpage = UT_LIST_GET_LAST(buf_pool->LRU);
3544
3545 while (bpage != NULL) {
3546 /* Use the same function that collect buffer info for
3547 INNODB_BUFFER_PAGE to get buffer page info */
3548 i_s_innodb_buffer_page_get_info(bpage, pool_id, lru_pos,
3549 (info_buffer + lru_pos));
3550
3551 bpage = UT_LIST_GET_PREV(LRU, bpage);
3552
3553 lru_pos++;
3554 }
3555
3556 ut_ad(lru_pos == lru_len);
3557 ut_ad(lru_pos == UT_LIST_GET_LEN(buf_pool->LRU));
3558
3559 exit:
3560 buf_pool_mutex_exit(buf_pool);
3561
3562 if (info_buffer) {
3563 status = i_s_innodb_buf_page_lru_fill(
3564 thd, tables, info_buffer, lru_len);
3565
3566 my_free(info_buffer);
3567 }
3568
3569 DBUG_RETURN(status);
3570 }
3571
3572 /*******************************************************************//**
3573 Fill page information for pages in InnoDB buffer pool to the
3574 dynamic table INFORMATION_SCHEMA.INNODB_BUFFER_PAGE_LRU
3575 @return 0 on success, 1 on failure */
3576 static
3577 int
i_s_innodb_buf_page_lru_fill_table(THD * thd,TABLE_LIST * tables,Item *)3578 i_s_innodb_buf_page_lru_fill_table(
3579 /*===============================*/
3580 THD* thd, /*!< in: thread */
3581 TABLE_LIST* tables, /*!< in/out: tables to fill */
3582 Item* ) /*!< in: condition (ignored) */
3583 {
3584 int status = 0;
3585
3586 DBUG_ENTER("i_s_innodb_buf_page_lru_fill_table");
3587
3588 /* deny access to any users that do not hold PROCESS_ACL */
3589 if (check_global_access(thd, PROCESS_ACL)) {
3590 DBUG_RETURN(0);
3591 }
3592
3593 /* Walk through each buffer pool */
3594 for (ulint i = 0; i < srv_buf_pool_instances; i++) {
3595 buf_pool_t* buf_pool;
3596
3597 buf_pool = buf_pool_from_array(i);
3598
3599 /* Fetch information from pages in this buffer pool's LRU list,
3600 and fill the corresponding I_S table */
3601 status = i_s_innodb_fill_buffer_lru(thd, tables, buf_pool, i);
3602
3603 /* If something wrong, break and return */
3604 if (status) {
3605 break;
3606 }
3607 }
3608
3609 DBUG_RETURN(status);
3610 }
3611
3612 /*******************************************************************//**
3613 Bind the dynamic table INFORMATION_SCHEMA.INNODB_BUFFER_PAGE_LRU.
3614 @return 0 on success, 1 on failure */
3615 static
3616 int
i_s_innodb_buffer_page_lru_init(void * p)3617 i_s_innodb_buffer_page_lru_init(
3618 /*============================*/
3619 void* p) /*!< in/out: table schema object */
3620 {
3621 ST_SCHEMA_TABLE* schema;
3622
3623 DBUG_ENTER("i_s_innodb_buffer_page_lru_init");
3624
3625 schema = reinterpret_cast<ST_SCHEMA_TABLE*>(p);
3626
3627 schema->fields_info = i_s_innodb_buf_page_lru_fields_info;
3628 schema->fill_table = i_s_innodb_buf_page_lru_fill_table;
3629
3630 DBUG_RETURN(0);
3631 }
3632
3633 UNIV_INTERN struct st_mysql_plugin i_s_innodb_buffer_page_lru =
3634 {
3635 /* the plugin type (a MYSQL_XXX_PLUGIN value) */
3636 /* int */
3637 STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
3638
3639 /* pointer to type-specific plugin descriptor */
3640 /* void* */
3641 STRUCT_FLD(info, &i_s_info),
3642
3643 /* plugin name */
3644 /* const char* */
3645 STRUCT_FLD(name, "INNODB_BUFFER_PAGE_LRU"),
3646
3647 /* plugin author (for SHOW PLUGINS) */
3648 /* const char* */
3649 STRUCT_FLD(author, plugin_author),
3650
3651 /* general descriptive text (for SHOW PLUGINS) */
3652 /* const char* */
3653 STRUCT_FLD(descr, "InnoDB Buffer Page in LRU"),
3654
3655 /* the plugin license (PLUGIN_LICENSE_XXX) */
3656 /* int */
3657 STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
3658
3659 /* the function to invoke when plugin is loaded */
3660 /* int (*)(void*); */
3661 STRUCT_FLD(init, i_s_innodb_buffer_page_lru_init),
3662
3663 /* the function to invoke when plugin is unloaded */
3664 /* int (*)(void*); */
3665 STRUCT_FLD(deinit, i_s_common_deinit),
3666
3667 /* plugin version (for SHOW PLUGINS) */
3668 /* unsigned int */
3669 STRUCT_FLD(version, INNODB_VERSION_SHORT),
3670
3671 /* struct st_mysql_show_var* */
3672 STRUCT_FLD(status_vars, NULL),
3673
3674 /* struct st_mysql_sys_var** */
3675 STRUCT_FLD(system_vars, NULL),
3676
3677 /* reserved for dependency checking */
3678 /* void* */
3679 STRUCT_FLD(__reserved1, NULL),
3680
3681 /* Plugin flags */
3682 /* unsigned long */
3683 STRUCT_FLD(flags, 0UL),
3684 };
3685
3686 /*******************************************************************//**
3687 Unbind a dynamic INFORMATION_SCHEMA table.
3688 @return 0 on success */
3689 static
3690 int
i_s_common_deinit(void * p)3691 i_s_common_deinit(
3692 /*==============*/
3693 void* p) /*!< in/out: table schema object */
3694 {
3695 DBUG_ENTER("i_s_common_deinit");
3696
3697 /* Do nothing */
3698
3699 DBUG_RETURN(0);
3700 }
3701
3702
3703