mySQL 5.0.11 sources for tomato
[tomato.git] / release / src / router / mysql / storage / innodb_plugin / handler / i_s.cc
blob6758fd15e2959d140f952ab4b50d0dee253ffc84
1 /*****************************************************************************
3 Copyright (c) 2007, 2009, Innobase Oy. All Rights Reserved.
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.
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.
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
17 *****************************************************************************/
19 /**************************************************//**
20 @file handler/i_s.cc
21 InnoDB INFORMATION SCHEMA tables interface to MySQL.
23 Created July 18, 2007 Vasil Dimov
24 *******************************************************/
26 #include <mysql_priv.h>
27 #include <mysqld_error.h>
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 <mysql/plugin.h>
37 extern "C" {
38 #include "trx0i_s.h"
39 #include "trx0trx.h" /* for TRX_QUE_STATE_STR_MAX_LEN */
40 #include "buf0buddy.h" /* for i_s_cmpmem */
41 #include "buf0buf.h" /* for buf_pool and PAGE_ZIP_MIN_SIZE */
42 #include "ha_prototypes.h" /* for innobase_convert_name() */
43 #include "srv0start.h" /* for srv_was_started */
44 #include "btr0btr.h"
45 #include "log0log.h"
48 static const char plugin_author[] = "Innobase Oy";
50 /** structure associates a name string with a file page type and/or buffer
51 page state. */
52 struct buffer_page_desc_str_struct{
53 const char* type_str; /*!< String explain the page
54 type/state */
55 ulint type_value; /*!< Page type or page state */
58 typedef struct buffer_page_desc_str_struct buf_page_desc_str_t;
60 /** Any states greater than FIL_PAGE_TYPE_LAST would be treated as unknown. */
61 #define I_S_PAGE_TYPE_UNKNOWN (FIL_PAGE_TYPE_LAST + 1)
63 /** We also define I_S_PAGE_TYPE_INDEX as the Index Page's position
64 in i_s_page_type[] array */
65 #define I_S_PAGE_TYPE_INDEX 1
67 /** Name string for File Page Types */
68 static buf_page_desc_str_t i_s_page_type[] = {
69 {"ALLOCATED", FIL_PAGE_TYPE_ALLOCATED},
70 {"INDEX", FIL_PAGE_INDEX},
71 {"UNDO_LOG", FIL_PAGE_UNDO_LOG},
72 {"INODE", FIL_PAGE_INODE},
73 {"IBUF_FREE_LIST", FIL_PAGE_IBUF_FREE_LIST},
74 {"IBUF_BITMAP", FIL_PAGE_IBUF_BITMAP},
75 {"SYSTEM", FIL_PAGE_TYPE_SYS},
76 {"TRX_SYSTEM", FIL_PAGE_TYPE_TRX_SYS},
77 {"FILE_SPACE_HEADER", FIL_PAGE_TYPE_FSP_HDR},
78 {"EXTENT_DESCRIPTOR", FIL_PAGE_TYPE_XDES},
79 {"BLOB", FIL_PAGE_TYPE_BLOB},
80 {"COMPRESSED_BLOB", FIL_PAGE_TYPE_ZBLOB},
81 {"COMPRESSED_BLOB2", FIL_PAGE_TYPE_ZBLOB2},
82 {"UNKNOWN", I_S_PAGE_TYPE_UNKNOWN}
85 /* Check if we can hold all page type in a 4 bit value */
86 #if I_S_PAGE_TYPE_UNKNOWN > 1<<4
87 # error "i_s_page_type[] is too large"
88 #endif
90 /** This structure defines information we will fetch from pages
91 currently cached in the buffer pool. It will be used to populate
92 table INFORMATION_SCHEMA.INNODB_BUFFER_PAGE */
93 struct buffer_page_info_struct{
94 ulint block_id; /*!< Buffer Pool block ID */
95 unsigned space_id:32; /*!< Tablespace ID */
96 unsigned page_num:32; /*!< Page number/offset */
97 unsigned access_time:32; /*!< Time of first access */
98 unsigned flush_type:2; /*!< Flush type */
99 unsigned io_fix:2; /*!< type of pending I/O operation */
100 unsigned fix_count:19; /*!< Count of how manyfold this block
101 is bufferfixed */
102 unsigned hashed:1; /*!< Whether hash index has been
103 built on this page */
104 unsigned is_old:1; /*!< TRUE if the block is in the old
105 blocks in buf_pool->LRU_old */
106 unsigned freed_page_clock:31; /*!< the value of
107 buf_pool->freed_page_clock */
108 unsigned zip_ssize:PAGE_ZIP_SSIZE_BITS;
109 /*!< Compressed page size */
110 unsigned page_state:BUF_PAGE_STATE_BITS; /*!< Page state */
111 unsigned page_type:4; /*!< Page type */
112 unsigned num_recs:UNIV_PAGE_SIZE_SHIFT-2;
113 /*!< Number of records on Page */
114 unsigned data_size:UNIV_PAGE_SIZE_SHIFT;
115 /*!< Sum of the sizes of the records */
116 lsn_t newest_mod; /*!< Log sequence number of
117 the youngest modification */
118 lsn_t oldest_mod; /*!< Log sequence number of
119 the oldest modification */
120 dulint index_id; /*!< Index ID if a index page */
123 typedef struct buffer_page_info_struct buf_page_info_t;
125 /** maximum number of buffer page info we would cache. */
126 #define MAX_BUF_INFO_CACHED 10000
128 #define OK(expr) \
129 if ((expr) != 0) { \
130 DBUG_RETURN(1); \
133 #define RETURN_IF_INNODB_NOT_STARTED(plugin_name) \
134 do { \
135 if (!srv_was_started) { \
136 push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, \
137 ER_CANT_FIND_SYSTEM_REC, \
138 "InnoDB: SELECTing from " \
139 "INFORMATION_SCHEMA.%s but " \
140 "the InnoDB storage engine " \
141 "is not installed", plugin_name); \
142 DBUG_RETURN(0); \
144 } while (0)
146 #if !defined __STRICT_ANSI__ && defined __GNUC__ && (__GNUC__) > 2 && !defined __INTEL_COMPILER
147 #define STRUCT_FLD(name, value) name: value
148 #else
149 #define STRUCT_FLD(name, value) value
150 #endif
152 /* Don't use a static const variable here, as some C++ compilers (notably
153 HPUX aCC: HP ANSI C++ B3910B A.03.65) can't handle it. */
154 #define END_OF_ST_FIELD_INFO \
155 {STRUCT_FLD(field_name, NULL), \
156 STRUCT_FLD(field_length, 0), \
157 STRUCT_FLD(field_type, MYSQL_TYPE_NULL), \
158 STRUCT_FLD(value, 0), \
159 STRUCT_FLD(field_flags, 0), \
160 STRUCT_FLD(old_name, ""), \
161 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}
164 Use the following types mapping:
166 C type ST_FIELD_INFO::field_type
167 ---------------------------------
168 long MYSQL_TYPE_LONGLONG
169 (field_length=MY_INT64_NUM_DECIMAL_DIGITS)
171 long unsigned MYSQL_TYPE_LONGLONG
172 (field_length=MY_INT64_NUM_DECIMAL_DIGITS, field_flags=MY_I_S_UNSIGNED)
174 char* MYSQL_TYPE_STRING
175 (field_length=n)
177 float MYSQL_TYPE_FLOAT
178 (field_length=0 is ignored)
180 void* MYSQL_TYPE_LONGLONG
181 (field_length=MY_INT64_NUM_DECIMAL_DIGITS, field_flags=MY_I_S_UNSIGNED)
183 boolean (if else) MYSQL_TYPE_LONG
184 (field_length=1)
186 time_t MYSQL_TYPE_DATETIME
187 (field_length=0 ignored)
188 ---------------------------------
191 /* XXX these are defined in mysql_priv.h inside #ifdef MYSQL_SERVER */
192 bool schema_table_store_record(THD *thd, TABLE *table);
193 void localtime_to_TIME(MYSQL_TIME *to, struct tm *from);
194 bool check_global_access(THD *thd, ulong want_access);
196 /*******************************************************************//**
197 Common function to fill any of the dynamic tables:
198 INFORMATION_SCHEMA.innodb_trx
199 INFORMATION_SCHEMA.innodb_locks
200 INFORMATION_SCHEMA.innodb_lock_waits
201 @return 0 on success */
202 static
204 trx_i_s_common_fill_table(
205 /*======================*/
206 THD* thd, /*!< in: thread */
207 TABLE_LIST* tables, /*!< in/out: tables to fill */
208 COND* cond); /*!< in: condition (not used) */
210 /*******************************************************************//**
211 Unbind a dynamic INFORMATION_SCHEMA table.
212 @return 0 on success */
213 static
215 i_s_common_deinit(
216 /*==============*/
217 void* p); /*!< in/out: table schema object */
219 /*******************************************************************//**
220 Auxiliary function to store time_t value in MYSQL_TYPE_DATETIME
221 field.
222 @return 0 on success */
223 static
225 field_store_time_t(
226 /*===============*/
227 Field* field, /*!< in/out: target field for storage */
228 time_t time) /*!< in: value to store */
230 MYSQL_TIME my_time;
231 struct tm tm_time;
233 #if 0
234 /* use this if you are sure that `variables' and `time_zone'
235 are always initialized */
236 thd->variables.time_zone->gmt_sec_to_TIME(
237 &my_time, (my_time_t) time);
238 #else
239 localtime_r(&time, &tm_time);
240 localtime_to_TIME(&my_time, &tm_time);
241 my_time.time_type = MYSQL_TIMESTAMP_DATETIME;
242 #endif
244 return(field->store_time(&my_time, MYSQL_TIMESTAMP_DATETIME));
247 /*******************************************************************//**
248 Auxiliary function to store char* value in MYSQL_TYPE_STRING field.
249 @return 0 on success */
250 static
252 field_store_string(
253 /*===============*/
254 Field* field, /*!< in/out: target field for storage */
255 const char* str) /*!< in: NUL-terminated utf-8 string,
256 or NULL */
258 int ret;
260 if (str != NULL) {
262 ret = field->store(str, strlen(str),
263 system_charset_info);
264 field->set_notnull();
265 } else {
267 ret = 0; /* success */
268 field->set_null();
271 return(ret);
274 /*******************************************************************//**
275 Auxiliary function to store ulint value in MYSQL_TYPE_LONGLONG field.
276 If the value is ULINT_UNDEFINED then the field it set to NULL.
277 @return 0 on success */
278 static
280 field_store_ulint(
281 /*==============*/
282 Field* field, /*!< in/out: target field for storage */
283 ulint n) /*!< in: value to store */
285 int ret;
287 if (n != ULINT_UNDEFINED) {
289 ret = field->store(n);
290 field->set_notnull();
291 } else {
293 ret = 0; /* success */
294 field->set_null();
297 return(ret);
300 /* Fields of the dynamic table INFORMATION_SCHEMA.innodb_trx */
301 static ST_FIELD_INFO innodb_trx_fields_info[] =
303 #define IDX_TRX_ID 0
304 {STRUCT_FLD(field_name, "trx_id"),
305 STRUCT_FLD(field_length, TRX_ID_MAX_LEN + 1),
306 STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
307 STRUCT_FLD(value, 0),
308 STRUCT_FLD(field_flags, 0),
309 STRUCT_FLD(old_name, ""),
310 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
312 #define IDX_TRX_STATE 1
313 {STRUCT_FLD(field_name, "trx_state"),
314 STRUCT_FLD(field_length, TRX_QUE_STATE_STR_MAX_LEN + 1),
315 STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
316 STRUCT_FLD(value, 0),
317 STRUCT_FLD(field_flags, 0),
318 STRUCT_FLD(old_name, ""),
319 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
321 #define IDX_TRX_STARTED 2
322 {STRUCT_FLD(field_name, "trx_started"),
323 STRUCT_FLD(field_length, 0),
324 STRUCT_FLD(field_type, MYSQL_TYPE_DATETIME),
325 STRUCT_FLD(value, 0),
326 STRUCT_FLD(field_flags, 0),
327 STRUCT_FLD(old_name, ""),
328 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
330 #define IDX_TRX_REQUESTED_LOCK_ID 3
331 {STRUCT_FLD(field_name, "trx_requested_lock_id"),
332 STRUCT_FLD(field_length, TRX_I_S_LOCK_ID_MAX_LEN + 1),
333 STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
334 STRUCT_FLD(value, 0),
335 STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
336 STRUCT_FLD(old_name, ""),
337 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
339 #define IDX_TRX_WAIT_STARTED 4
340 {STRUCT_FLD(field_name, "trx_wait_started"),
341 STRUCT_FLD(field_length, 0),
342 STRUCT_FLD(field_type, MYSQL_TYPE_DATETIME),
343 STRUCT_FLD(value, 0),
344 STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
345 STRUCT_FLD(old_name, ""),
346 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
348 #define IDX_TRX_WEIGHT 5
349 {STRUCT_FLD(field_name, "trx_weight"),
350 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
351 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
352 STRUCT_FLD(value, 0),
353 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
354 STRUCT_FLD(old_name, ""),
355 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
357 #define IDX_TRX_MYSQL_THREAD_ID 6
358 {STRUCT_FLD(field_name, "trx_mysql_thread_id"),
359 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
360 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
361 STRUCT_FLD(value, 0),
362 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
363 STRUCT_FLD(old_name, ""),
364 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
366 #define IDX_TRX_QUERY 7
367 {STRUCT_FLD(field_name, "trx_query"),
368 STRUCT_FLD(field_length, TRX_I_S_TRX_QUERY_MAX_LEN),
369 STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
370 STRUCT_FLD(value, 0),
371 STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
372 STRUCT_FLD(old_name, ""),
373 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
375 END_OF_ST_FIELD_INFO
378 /*******************************************************************//**
379 Read data from cache buffer and fill the INFORMATION_SCHEMA.innodb_trx
380 table with it.
381 @return 0 on success */
382 static
384 fill_innodb_trx_from_cache(
385 /*=======================*/
386 trx_i_s_cache_t* cache, /*!< in: cache to read from */
387 THD* thd, /*!< in: used to call
388 schema_table_store_record() */
389 TABLE* table) /*!< in/out: fill this table */
391 Field** fields;
392 ulint rows_num;
393 char lock_id[TRX_I_S_LOCK_ID_MAX_LEN + 1];
394 ulint i;
396 DBUG_ENTER("fill_innodb_trx_from_cache");
398 fields = table->field;
400 rows_num = trx_i_s_cache_get_rows_used(cache,
401 I_S_INNODB_TRX);
403 for (i = 0; i < rows_num; i++) {
405 i_s_trx_row_t* row;
406 char trx_id[TRX_ID_MAX_LEN + 1];
408 row = (i_s_trx_row_t*)
409 trx_i_s_cache_get_nth_row(
410 cache, I_S_INNODB_TRX, i);
412 /* trx_id */
413 ut_snprintf(trx_id, sizeof(trx_id), TRX_ID_FMT, row->trx_id);
414 OK(field_store_string(fields[IDX_TRX_ID], trx_id));
416 /* trx_state */
417 OK(field_store_string(fields[IDX_TRX_STATE],
418 row->trx_state));
420 /* trx_started */
421 OK(field_store_time_t(fields[IDX_TRX_STARTED],
422 (time_t) row->trx_started));
424 /* trx_requested_lock_id */
425 /* trx_wait_started */
426 if (row->trx_wait_started != 0) {
428 OK(field_store_string(
429 fields[IDX_TRX_REQUESTED_LOCK_ID],
430 trx_i_s_create_lock_id(
431 row->requested_lock_row,
432 lock_id, sizeof(lock_id))));
433 /* field_store_string() sets it no notnull */
435 OK(field_store_time_t(
436 fields[IDX_TRX_WAIT_STARTED],
437 (time_t) row->trx_wait_started));
438 fields[IDX_TRX_WAIT_STARTED]->set_notnull();
439 } else {
441 fields[IDX_TRX_REQUESTED_LOCK_ID]->set_null();
442 fields[IDX_TRX_WAIT_STARTED]->set_null();
445 /* trx_weight */
446 OK(fields[IDX_TRX_WEIGHT]->store((longlong) row->trx_weight,
447 true));
449 /* trx_mysql_thread_id */
450 OK(fields[IDX_TRX_MYSQL_THREAD_ID]->store(
451 row->trx_mysql_thread_id));
453 /* trx_query */
454 if (row->trx_query) {
455 /* store will do appropriate character set
456 conversion check */
457 fields[IDX_TRX_QUERY]->store(
458 row->trx_query, strlen(row->trx_query),
459 row->trx_query_cs);
460 fields[IDX_TRX_QUERY]->set_notnull();
461 } else {
462 fields[IDX_TRX_QUERY]->set_null();
465 OK(schema_table_store_record(thd, table));
468 DBUG_RETURN(0);
471 /*******************************************************************//**
472 Bind the dynamic table INFORMATION_SCHEMA.innodb_trx
473 @return 0 on success */
474 static
476 innodb_trx_init(
477 /*============*/
478 void* p) /*!< in/out: table schema object */
480 ST_SCHEMA_TABLE* schema;
482 DBUG_ENTER("innodb_trx_init");
484 schema = (ST_SCHEMA_TABLE*) p;
486 schema->fields_info = innodb_trx_fields_info;
487 schema->fill_table = trx_i_s_common_fill_table;
489 DBUG_RETURN(0);
492 static struct st_mysql_information_schema i_s_info =
494 MYSQL_INFORMATION_SCHEMA_INTERFACE_VERSION
497 UNIV_INTERN struct st_mysql_plugin i_s_innodb_trx =
499 /* the plugin type (a MYSQL_XXX_PLUGIN value) */
500 /* int */
501 STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
503 /* pointer to type-specific plugin descriptor */
504 /* void* */
505 STRUCT_FLD(info, &i_s_info),
507 /* plugin name */
508 /* const char* */
509 STRUCT_FLD(name, "INNODB_TRX"),
511 /* plugin author (for SHOW PLUGINS) */
512 /* const char* */
513 STRUCT_FLD(author, plugin_author),
515 /* general descriptive text (for SHOW PLUGINS) */
516 /* const char* */
517 STRUCT_FLD(descr, "InnoDB transactions"),
519 /* the plugin license (PLUGIN_LICENSE_XXX) */
520 /* int */
521 STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
523 /* the function to invoke when plugin is loaded */
524 /* int (*)(void*); */
525 STRUCT_FLD(init, innodb_trx_init),
527 /* the function to invoke when plugin is unloaded */
528 /* int (*)(void*); */
529 STRUCT_FLD(deinit, i_s_common_deinit),
531 /* plugin version (for SHOW PLUGINS) */
532 /* unsigned int */
533 STRUCT_FLD(version, INNODB_VERSION_SHORT),
535 /* struct st_mysql_show_var* */
536 STRUCT_FLD(status_vars, NULL),
538 /* struct st_mysql_sys_var** */
539 STRUCT_FLD(system_vars, NULL),
541 /* reserved for dependency checking */
542 /* void* */
543 STRUCT_FLD(__reserved1, NULL)
546 /* Fields of the dynamic table INFORMATION_SCHEMA.innodb_locks */
547 static ST_FIELD_INFO innodb_locks_fields_info[] =
549 #define IDX_LOCK_ID 0
550 {STRUCT_FLD(field_name, "lock_id"),
551 STRUCT_FLD(field_length, TRX_I_S_LOCK_ID_MAX_LEN + 1),
552 STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
553 STRUCT_FLD(value, 0),
554 STRUCT_FLD(field_flags, 0),
555 STRUCT_FLD(old_name, ""),
556 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
558 #define IDX_LOCK_TRX_ID 1
559 {STRUCT_FLD(field_name, "lock_trx_id"),
560 STRUCT_FLD(field_length, TRX_ID_MAX_LEN + 1),
561 STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
562 STRUCT_FLD(value, 0),
563 STRUCT_FLD(field_flags, 0),
564 STRUCT_FLD(old_name, ""),
565 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
567 #define IDX_LOCK_MODE 2
568 {STRUCT_FLD(field_name, "lock_mode"),
569 /* S[,GAP] X[,GAP] IS[,GAP] IX[,GAP] AUTO_INC UNKNOWN */
570 STRUCT_FLD(field_length, 32),
571 STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
572 STRUCT_FLD(value, 0),
573 STRUCT_FLD(field_flags, 0),
574 STRUCT_FLD(old_name, ""),
575 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
577 #define IDX_LOCK_TYPE 3
578 {STRUCT_FLD(field_name, "lock_type"),
579 STRUCT_FLD(field_length, 32 /* RECORD|TABLE|UNKNOWN */),
580 STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
581 STRUCT_FLD(value, 0),
582 STRUCT_FLD(field_flags, 0),
583 STRUCT_FLD(old_name, ""),
584 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
586 #define IDX_LOCK_TABLE 4
587 {STRUCT_FLD(field_name, "lock_table"),
588 STRUCT_FLD(field_length, 1024),
589 STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
590 STRUCT_FLD(value, 0),
591 STRUCT_FLD(field_flags, 0),
592 STRUCT_FLD(old_name, ""),
593 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
595 #define IDX_LOCK_INDEX 5
596 {STRUCT_FLD(field_name, "lock_index"),
597 STRUCT_FLD(field_length, 1024),
598 STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
599 STRUCT_FLD(value, 0),
600 STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
601 STRUCT_FLD(old_name, ""),
602 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
604 #define IDX_LOCK_SPACE 6
605 {STRUCT_FLD(field_name, "lock_space"),
606 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
607 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
608 STRUCT_FLD(value, 0),
609 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED | MY_I_S_MAYBE_NULL),
610 STRUCT_FLD(old_name, ""),
611 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
613 #define IDX_LOCK_PAGE 7
614 {STRUCT_FLD(field_name, "lock_page"),
615 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
616 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
617 STRUCT_FLD(value, 0),
618 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED | MY_I_S_MAYBE_NULL),
619 STRUCT_FLD(old_name, ""),
620 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
622 #define IDX_LOCK_REC 8
623 {STRUCT_FLD(field_name, "lock_rec"),
624 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
625 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
626 STRUCT_FLD(value, 0),
627 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED | MY_I_S_MAYBE_NULL),
628 STRUCT_FLD(old_name, ""),
629 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
631 #define IDX_LOCK_DATA 9
632 {STRUCT_FLD(field_name, "lock_data"),
633 STRUCT_FLD(field_length, TRX_I_S_LOCK_DATA_MAX_LEN),
634 STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
635 STRUCT_FLD(value, 0),
636 STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
637 STRUCT_FLD(old_name, ""),
638 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
640 END_OF_ST_FIELD_INFO
643 /*******************************************************************//**
644 Read data from cache buffer and fill the INFORMATION_SCHEMA.innodb_locks
645 table with it.
646 @return 0 on success */
647 static
649 fill_innodb_locks_from_cache(
650 /*=========================*/
651 trx_i_s_cache_t* cache, /*!< in: cache to read from */
652 THD* thd, /*!< in: MySQL client connection */
653 TABLE* table) /*!< in/out: fill this table */
655 Field** fields;
656 ulint rows_num;
657 char lock_id[TRX_I_S_LOCK_ID_MAX_LEN + 1];
658 ulint i;
660 DBUG_ENTER("fill_innodb_locks_from_cache");
662 fields = table->field;
664 rows_num = trx_i_s_cache_get_rows_used(cache,
665 I_S_INNODB_LOCKS);
667 for (i = 0; i < rows_num; i++) {
669 i_s_locks_row_t* row;
670 char buf[MAX_FULL_NAME_LEN + 1];
671 const char* bufend;
673 char lock_trx_id[TRX_ID_MAX_LEN + 1];
675 row = (i_s_locks_row_t*)
676 trx_i_s_cache_get_nth_row(
677 cache, I_S_INNODB_LOCKS, i);
679 /* lock_id */
680 trx_i_s_create_lock_id(row, lock_id, sizeof(lock_id));
681 OK(field_store_string(fields[IDX_LOCK_ID],
682 lock_id));
684 /* lock_trx_id */
685 ut_snprintf(lock_trx_id, sizeof(lock_trx_id),
686 TRX_ID_FMT, row->lock_trx_id);
687 OK(field_store_string(fields[IDX_LOCK_TRX_ID], lock_trx_id));
689 /* lock_mode */
690 OK(field_store_string(fields[IDX_LOCK_MODE],
691 row->lock_mode));
693 /* lock_type */
694 OK(field_store_string(fields[IDX_LOCK_TYPE],
695 row->lock_type));
697 /* lock_table */
698 bufend = innobase_convert_name(buf, sizeof(buf),
699 row->lock_table,
700 strlen(row->lock_table),
701 thd, TRUE);
702 OK(fields[IDX_LOCK_TABLE]->store(buf, bufend - buf,
703 system_charset_info));
705 /* lock_index */
706 if (row->lock_index != NULL) {
708 bufend = innobase_convert_name(buf, sizeof(buf),
709 row->lock_index,
710 strlen(row->lock_index),
711 thd, FALSE);
712 OK(fields[IDX_LOCK_INDEX]->store(buf, bufend - buf,
713 system_charset_info));
714 fields[IDX_LOCK_INDEX]->set_notnull();
715 } else {
717 fields[IDX_LOCK_INDEX]->set_null();
720 /* lock_space */
721 OK(field_store_ulint(fields[IDX_LOCK_SPACE],
722 row->lock_space));
724 /* lock_page */
725 OK(field_store_ulint(fields[IDX_LOCK_PAGE],
726 row->lock_page));
728 /* lock_rec */
729 OK(field_store_ulint(fields[IDX_LOCK_REC],
730 row->lock_rec));
732 /* lock_data */
733 OK(field_store_string(fields[IDX_LOCK_DATA],
734 row->lock_data));
736 OK(schema_table_store_record(thd, table));
739 DBUG_RETURN(0);
742 /*******************************************************************//**
743 Bind the dynamic table INFORMATION_SCHEMA.innodb_locks
744 @return 0 on success */
745 static
747 innodb_locks_init(
748 /*==============*/
749 void* p) /*!< in/out: table schema object */
751 ST_SCHEMA_TABLE* schema;
753 DBUG_ENTER("innodb_locks_init");
755 schema = (ST_SCHEMA_TABLE*) p;
757 schema->fields_info = innodb_locks_fields_info;
758 schema->fill_table = trx_i_s_common_fill_table;
760 DBUG_RETURN(0);
763 UNIV_INTERN struct st_mysql_plugin i_s_innodb_locks =
765 /* the plugin type (a MYSQL_XXX_PLUGIN value) */
766 /* int */
767 STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
769 /* pointer to type-specific plugin descriptor */
770 /* void* */
771 STRUCT_FLD(info, &i_s_info),
773 /* plugin name */
774 /* const char* */
775 STRUCT_FLD(name, "INNODB_LOCKS"),
777 /* plugin author (for SHOW PLUGINS) */
778 /* const char* */
779 STRUCT_FLD(author, plugin_author),
781 /* general descriptive text (for SHOW PLUGINS) */
782 /* const char* */
783 STRUCT_FLD(descr, "InnoDB conflicting locks"),
785 /* the plugin license (PLUGIN_LICENSE_XXX) */
786 /* int */
787 STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
789 /* the function to invoke when plugin is loaded */
790 /* int (*)(void*); */
791 STRUCT_FLD(init, innodb_locks_init),
793 /* the function to invoke when plugin is unloaded */
794 /* int (*)(void*); */
795 STRUCT_FLD(deinit, i_s_common_deinit),
797 /* plugin version (for SHOW PLUGINS) */
798 /* unsigned int */
799 STRUCT_FLD(version, INNODB_VERSION_SHORT),
801 /* struct st_mysql_show_var* */
802 STRUCT_FLD(status_vars, NULL),
804 /* struct st_mysql_sys_var** */
805 STRUCT_FLD(system_vars, NULL),
807 /* reserved for dependency checking */
808 /* void* */
809 STRUCT_FLD(__reserved1, NULL)
812 /* Fields of the dynamic table INFORMATION_SCHEMA.innodb_lock_waits */
813 static ST_FIELD_INFO innodb_lock_waits_fields_info[] =
815 #define IDX_REQUESTING_TRX_ID 0
816 {STRUCT_FLD(field_name, "requesting_trx_id"),
817 STRUCT_FLD(field_length, TRX_ID_MAX_LEN + 1),
818 STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
819 STRUCT_FLD(value, 0),
820 STRUCT_FLD(field_flags, 0),
821 STRUCT_FLD(old_name, ""),
822 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
824 #define IDX_REQUESTED_LOCK_ID 1
825 {STRUCT_FLD(field_name, "requested_lock_id"),
826 STRUCT_FLD(field_length, TRX_I_S_LOCK_ID_MAX_LEN + 1),
827 STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
828 STRUCT_FLD(value, 0),
829 STRUCT_FLD(field_flags, 0),
830 STRUCT_FLD(old_name, ""),
831 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
833 #define IDX_BLOCKING_TRX_ID 2
834 {STRUCT_FLD(field_name, "blocking_trx_id"),
835 STRUCT_FLD(field_length, TRX_ID_MAX_LEN + 1),
836 STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
837 STRUCT_FLD(value, 0),
838 STRUCT_FLD(field_flags, 0),
839 STRUCT_FLD(old_name, ""),
840 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
842 #define IDX_BLOCKING_LOCK_ID 3
843 {STRUCT_FLD(field_name, "blocking_lock_id"),
844 STRUCT_FLD(field_length, TRX_I_S_LOCK_ID_MAX_LEN + 1),
845 STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
846 STRUCT_FLD(value, 0),
847 STRUCT_FLD(field_flags, 0),
848 STRUCT_FLD(old_name, ""),
849 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
851 END_OF_ST_FIELD_INFO
854 /*******************************************************************//**
855 Read data from cache buffer and fill the
856 INFORMATION_SCHEMA.innodb_lock_waits table with it.
857 @return 0 on success */
858 static
860 fill_innodb_lock_waits_from_cache(
861 /*==============================*/
862 trx_i_s_cache_t* cache, /*!< in: cache to read from */
863 THD* thd, /*!< in: used to call
864 schema_table_store_record() */
865 TABLE* table) /*!< in/out: fill this table */
867 Field** fields;
868 ulint rows_num;
869 char requested_lock_id[TRX_I_S_LOCK_ID_MAX_LEN + 1];
870 char blocking_lock_id[TRX_I_S_LOCK_ID_MAX_LEN + 1];
871 ulint i;
873 DBUG_ENTER("fill_innodb_lock_waits_from_cache");
875 fields = table->field;
877 rows_num = trx_i_s_cache_get_rows_used(cache,
878 I_S_INNODB_LOCK_WAITS);
880 for (i = 0; i < rows_num; i++) {
882 i_s_lock_waits_row_t* row;
884 char requesting_trx_id[TRX_ID_MAX_LEN + 1];
885 char blocking_trx_id[TRX_ID_MAX_LEN + 1];
887 row = (i_s_lock_waits_row_t*)
888 trx_i_s_cache_get_nth_row(
889 cache, I_S_INNODB_LOCK_WAITS, i);
891 /* requesting_trx_id */
892 ut_snprintf(requesting_trx_id, sizeof(requesting_trx_id),
893 TRX_ID_FMT, row->requested_lock_row->lock_trx_id);
894 OK(field_store_string(fields[IDX_REQUESTING_TRX_ID],
895 requesting_trx_id));
897 /* requested_lock_id */
898 OK(field_store_string(
899 fields[IDX_REQUESTED_LOCK_ID],
900 trx_i_s_create_lock_id(
901 row->requested_lock_row,
902 requested_lock_id,
903 sizeof(requested_lock_id))));
905 /* blocking_trx_id */
906 ut_snprintf(blocking_trx_id, sizeof(blocking_trx_id),
907 TRX_ID_FMT, row->blocking_lock_row->lock_trx_id);
908 OK(field_store_string(fields[IDX_BLOCKING_TRX_ID],
909 blocking_trx_id));
911 /* blocking_lock_id */
912 OK(field_store_string(
913 fields[IDX_BLOCKING_LOCK_ID],
914 trx_i_s_create_lock_id(
915 row->blocking_lock_row,
916 blocking_lock_id,
917 sizeof(blocking_lock_id))));
919 OK(schema_table_store_record(thd, table));
922 DBUG_RETURN(0);
925 /*******************************************************************//**
926 Bind the dynamic table INFORMATION_SCHEMA.innodb_lock_waits
927 @return 0 on success */
928 static
930 innodb_lock_waits_init(
931 /*===================*/
932 void* p) /*!< in/out: table schema object */
934 ST_SCHEMA_TABLE* schema;
936 DBUG_ENTER("innodb_lock_waits_init");
938 schema = (ST_SCHEMA_TABLE*) p;
940 schema->fields_info = innodb_lock_waits_fields_info;
941 schema->fill_table = trx_i_s_common_fill_table;
943 DBUG_RETURN(0);
946 UNIV_INTERN struct st_mysql_plugin i_s_innodb_lock_waits =
948 /* the plugin type (a MYSQL_XXX_PLUGIN value) */
949 /* int */
950 STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
952 /* pointer to type-specific plugin descriptor */
953 /* void* */
954 STRUCT_FLD(info, &i_s_info),
956 /* plugin name */
957 /* const char* */
958 STRUCT_FLD(name, "INNODB_LOCK_WAITS"),
960 /* plugin author (for SHOW PLUGINS) */
961 /* const char* */
962 STRUCT_FLD(author, "Innobase Oy"),
964 /* general descriptive text (for SHOW PLUGINS) */
965 /* const char* */
966 STRUCT_FLD(descr, "InnoDB which lock is blocking which"),
968 /* the plugin license (PLUGIN_LICENSE_XXX) */
969 /* int */
970 STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
972 /* the function to invoke when plugin is loaded */
973 /* int (*)(void*); */
974 STRUCT_FLD(init, innodb_lock_waits_init),
976 /* the function to invoke when plugin is unloaded */
977 /* int (*)(void*); */
978 STRUCT_FLD(deinit, i_s_common_deinit),
980 /* plugin version (for SHOW PLUGINS) */
981 /* unsigned int */
982 STRUCT_FLD(version, INNODB_VERSION_SHORT),
984 /* struct st_mysql_show_var* */
985 STRUCT_FLD(status_vars, NULL),
987 /* struct st_mysql_sys_var** */
988 STRUCT_FLD(system_vars, NULL),
990 /* reserved for dependency checking */
991 /* void* */
992 STRUCT_FLD(__reserved1, NULL)
995 /*******************************************************************//**
996 Common function to fill any of the dynamic tables:
997 INFORMATION_SCHEMA.innodb_trx
998 INFORMATION_SCHEMA.innodb_locks
999 INFORMATION_SCHEMA.innodb_lock_waits
1000 @return 0 on success */
1001 static
1003 trx_i_s_common_fill_table(
1004 /*======================*/
1005 THD* thd, /*!< in: thread */
1006 TABLE_LIST* tables, /*!< in/out: tables to fill */
1007 COND* cond) /*!< in: condition (not used) */
1009 const char* table_name;
1010 int ret;
1011 trx_i_s_cache_t* cache;
1013 DBUG_ENTER("trx_i_s_common_fill_table");
1015 /* deny access to non-superusers */
1016 if (check_global_access(thd, PROCESS_ACL)) {
1018 DBUG_RETURN(0);
1021 /* minimize the number of places where global variables are
1022 referenced */
1023 cache = trx_i_s_cache;
1025 /* which table we have to fill? */
1026 table_name = tables->schema_table_name;
1027 /* or table_name = tables->schema_table->table_name; */
1029 RETURN_IF_INNODB_NOT_STARTED(table_name);
1031 /* update the cache */
1032 trx_i_s_cache_start_write(cache);
1033 trx_i_s_possibly_fetch_data_into_cache(cache);
1034 trx_i_s_cache_end_write(cache);
1036 if (trx_i_s_cache_is_truncated(cache)) {
1038 /* XXX show warning to user if possible */
1039 fprintf(stderr, "Warning: data in %s truncated due to "
1040 "memory limit of %d bytes\n", table_name,
1041 TRX_I_S_MEM_LIMIT);
1044 ret = 0;
1046 trx_i_s_cache_start_read(cache);
1048 if (innobase_strcasecmp(table_name, "innodb_trx") == 0) {
1050 if (fill_innodb_trx_from_cache(
1051 cache, thd, tables->table) != 0) {
1053 ret = 1;
1056 } else if (innobase_strcasecmp(table_name, "innodb_locks") == 0) {
1058 if (fill_innodb_locks_from_cache(
1059 cache, thd, tables->table) != 0) {
1061 ret = 1;
1064 } else if (innobase_strcasecmp(table_name, "innodb_lock_waits") == 0) {
1066 if (fill_innodb_lock_waits_from_cache(
1067 cache, thd, tables->table) != 0) {
1069 ret = 1;
1072 } else {
1074 /* huh! what happened!? */
1075 fprintf(stderr,
1076 "InnoDB: trx_i_s_common_fill_table() was "
1077 "called to fill unknown table: %s.\n"
1078 "This function only knows how to fill "
1079 "innodb_trx, innodb_locks and "
1080 "innodb_lock_waits tables.\n", table_name);
1082 ret = 1;
1085 trx_i_s_cache_end_read(cache);
1087 #if 0
1088 DBUG_RETURN(ret);
1089 #else
1090 /* if this function returns something else than 0 then a
1091 deadlock occurs between the mysqld server and mysql client,
1092 see http://bugs.mysql.com/29900 ; when that bug is resolved
1093 we can enable the DBUG_RETURN(ret) above */
1094 ret++; // silence a gcc46 warning
1095 DBUG_RETURN(0);
1096 #endif
1099 /* Fields of the dynamic table information_schema.innodb_cmp. */
1100 static ST_FIELD_INFO i_s_cmp_fields_info[] =
1102 {STRUCT_FLD(field_name, "page_size"),
1103 STRUCT_FLD(field_length, 5),
1104 STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
1105 STRUCT_FLD(value, 0),
1106 STRUCT_FLD(field_flags, 0),
1107 STRUCT_FLD(old_name, "Compressed Page Size"),
1108 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1110 {STRUCT_FLD(field_name, "compress_ops"),
1111 STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS),
1112 STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
1113 STRUCT_FLD(value, 0),
1114 STRUCT_FLD(field_flags, 0),
1115 STRUCT_FLD(old_name, "Total Number of Compressions"),
1116 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1118 {STRUCT_FLD(field_name, "compress_ops_ok"),
1119 STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS),
1120 STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
1121 STRUCT_FLD(value, 0),
1122 STRUCT_FLD(field_flags, 0),
1123 STRUCT_FLD(old_name, "Total Number of"
1124 " Successful Compressions"),
1125 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1127 {STRUCT_FLD(field_name, "compress_time"),
1128 STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS),
1129 STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
1130 STRUCT_FLD(value, 0),
1131 STRUCT_FLD(field_flags, 0),
1132 STRUCT_FLD(old_name, "Total Duration of Compressions,"
1133 " in Seconds"),
1134 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1136 {STRUCT_FLD(field_name, "uncompress_ops"),
1137 STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS),
1138 STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
1139 STRUCT_FLD(value, 0),
1140 STRUCT_FLD(field_flags, 0),
1141 STRUCT_FLD(old_name, "Total Number of Decompressions"),
1142 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1144 {STRUCT_FLD(field_name, "uncompress_time"),
1145 STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS),
1146 STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
1147 STRUCT_FLD(value, 0),
1148 STRUCT_FLD(field_flags, 0),
1149 STRUCT_FLD(old_name, "Total Duration of Decompressions,"
1150 " in Seconds"),
1151 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1153 END_OF_ST_FIELD_INFO
1157 /*******************************************************************//**
1158 Fill the dynamic table information_schema.innodb_cmp or
1159 innodb_cmp_reset.
1160 @return 0 on success, 1 on failure */
1161 static
1163 i_s_cmp_fill_low(
1164 /*=============*/
1165 THD* thd, /*!< in: thread */
1166 TABLE_LIST* tables, /*!< in/out: tables to fill */
1167 COND* cond, /*!< in: condition (ignored) */
1168 ibool reset) /*!< in: TRUE=reset cumulated counts */
1170 TABLE* table = (TABLE *) tables->table;
1171 int status = 0;
1173 DBUG_ENTER("i_s_cmp_fill_low");
1175 /* deny access to non-superusers */
1176 if (check_global_access(thd, PROCESS_ACL)) {
1178 DBUG_RETURN(0);
1181 RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name);
1183 for (uint i = 0; i < PAGE_ZIP_NUM_SSIZE - 1; i++) {
1184 page_zip_stat_t* zip_stat = &page_zip_stat[i];
1186 table->field[0]->store(PAGE_ZIP_MIN_SIZE << i);
1188 /* The cumulated counts are not protected by any
1189 mutex. Thus, some operation in page0zip.c could
1190 increment a counter between the time we read it and
1191 clear it. We could introduce mutex protection, but it
1192 could cause a measureable performance hit in
1193 page0zip.c. */
1194 table->field[1]->store(zip_stat->compressed);
1195 table->field[2]->store(zip_stat->compressed_ok);
1196 table->field[3]->store(
1197 (ulong) (zip_stat->compressed_usec / 1000000));
1198 table->field[4]->store(zip_stat->decompressed);
1199 table->field[5]->store(
1200 (ulong) (zip_stat->decompressed_usec / 1000000));
1202 if (reset) {
1203 memset(zip_stat, 0, sizeof *zip_stat);
1206 if (schema_table_store_record(thd, table)) {
1207 status = 1;
1208 break;
1212 DBUG_RETURN(status);
1215 /*******************************************************************//**
1216 Fill the dynamic table information_schema.innodb_cmp.
1217 @return 0 on success, 1 on failure */
1218 static
1220 i_s_cmp_fill(
1221 /*=========*/
1222 THD* thd, /*!< in: thread */
1223 TABLE_LIST* tables, /*!< in/out: tables to fill */
1224 COND* cond) /*!< in: condition (ignored) */
1226 return(i_s_cmp_fill_low(thd, tables, cond, FALSE));
1229 /*******************************************************************//**
1230 Fill the dynamic table information_schema.innodb_cmp_reset.
1231 @return 0 on success, 1 on failure */
1232 static
1234 i_s_cmp_reset_fill(
1235 /*===============*/
1236 THD* thd, /*!< in: thread */
1237 TABLE_LIST* tables, /*!< in/out: tables to fill */
1238 COND* cond) /*!< in: condition (ignored) */
1240 return(i_s_cmp_fill_low(thd, tables, cond, TRUE));
1243 /*******************************************************************//**
1244 Bind the dynamic table information_schema.innodb_cmp.
1245 @return 0 on success */
1246 static
1248 i_s_cmp_init(
1249 /*=========*/
1250 void* p) /*!< in/out: table schema object */
1252 DBUG_ENTER("i_s_cmp_init");
1253 ST_SCHEMA_TABLE* schema = (ST_SCHEMA_TABLE*) p;
1255 schema->fields_info = i_s_cmp_fields_info;
1256 schema->fill_table = i_s_cmp_fill;
1258 DBUG_RETURN(0);
1261 /*******************************************************************//**
1262 Bind the dynamic table information_schema.innodb_cmp_reset.
1263 @return 0 on success */
1264 static
1266 i_s_cmp_reset_init(
1267 /*===============*/
1268 void* p) /*!< in/out: table schema object */
1270 DBUG_ENTER("i_s_cmp_reset_init");
1271 ST_SCHEMA_TABLE* schema = (ST_SCHEMA_TABLE*) p;
1273 schema->fields_info = i_s_cmp_fields_info;
1274 schema->fill_table = i_s_cmp_reset_fill;
1276 DBUG_RETURN(0);
1279 UNIV_INTERN struct st_mysql_plugin i_s_innodb_cmp =
1281 /* the plugin type (a MYSQL_XXX_PLUGIN value) */
1282 /* int */
1283 STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
1285 /* pointer to type-specific plugin descriptor */
1286 /* void* */
1287 STRUCT_FLD(info, &i_s_info),
1289 /* plugin name */
1290 /* const char* */
1291 STRUCT_FLD(name, "INNODB_CMP"),
1293 /* plugin author (for SHOW PLUGINS) */
1294 /* const char* */
1295 STRUCT_FLD(author, plugin_author),
1297 /* general descriptive text (for SHOW PLUGINS) */
1298 /* const char* */
1299 STRUCT_FLD(descr, "Statistics for the InnoDB compression"),
1301 /* the plugin license (PLUGIN_LICENSE_XXX) */
1302 /* int */
1303 STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
1305 /* the function to invoke when plugin is loaded */
1306 /* int (*)(void*); */
1307 STRUCT_FLD(init, i_s_cmp_init),
1309 /* the function to invoke when plugin is unloaded */
1310 /* int (*)(void*); */
1311 STRUCT_FLD(deinit, i_s_common_deinit),
1313 /* plugin version (for SHOW PLUGINS) */
1314 /* unsigned int */
1315 STRUCT_FLD(version, INNODB_VERSION_SHORT),
1317 /* struct st_mysql_show_var* */
1318 STRUCT_FLD(status_vars, NULL),
1320 /* struct st_mysql_sys_var** */
1321 STRUCT_FLD(system_vars, NULL),
1323 /* reserved for dependency checking */
1324 /* void* */
1325 STRUCT_FLD(__reserved1, NULL)
1328 UNIV_INTERN struct st_mysql_plugin i_s_innodb_cmp_reset =
1330 /* the plugin type (a MYSQL_XXX_PLUGIN value) */
1331 /* int */
1332 STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
1334 /* pointer to type-specific plugin descriptor */
1335 /* void* */
1336 STRUCT_FLD(info, &i_s_info),
1338 /* plugin name */
1339 /* const char* */
1340 STRUCT_FLD(name, "INNODB_CMP_RESET"),
1342 /* plugin author (for SHOW PLUGINS) */
1343 /* const char* */
1344 STRUCT_FLD(author, plugin_author),
1346 /* general descriptive text (for SHOW PLUGINS) */
1347 /* const char* */
1348 STRUCT_FLD(descr, "Statistics for the InnoDB compression;"
1349 " reset cumulated counts"),
1351 /* the plugin license (PLUGIN_LICENSE_XXX) */
1352 /* int */
1353 STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
1355 /* the function to invoke when plugin is loaded */
1356 /* int (*)(void*); */
1357 STRUCT_FLD(init, i_s_cmp_reset_init),
1359 /* the function to invoke when plugin is unloaded */
1360 /* int (*)(void*); */
1361 STRUCT_FLD(deinit, i_s_common_deinit),
1363 /* plugin version (for SHOW PLUGINS) */
1364 /* unsigned int */
1365 STRUCT_FLD(version, INNODB_VERSION_SHORT),
1367 /* struct st_mysql_show_var* */
1368 STRUCT_FLD(status_vars, NULL),
1370 /* struct st_mysql_sys_var** */
1371 STRUCT_FLD(system_vars, NULL),
1373 /* reserved for dependency checking */
1374 /* void* */
1375 STRUCT_FLD(__reserved1, NULL)
1378 /* Fields of the dynamic table information_schema.innodb_cmpmem. */
1379 static ST_FIELD_INFO i_s_cmpmem_fields_info[] =
1381 {STRUCT_FLD(field_name, "page_size"),
1382 STRUCT_FLD(field_length, 5),
1383 STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
1384 STRUCT_FLD(value, 0),
1385 STRUCT_FLD(field_flags, 0),
1386 STRUCT_FLD(old_name, "Buddy Block Size"),
1387 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1389 {STRUCT_FLD(field_name, "pages_used"),
1390 STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS),
1391 STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
1392 STRUCT_FLD(value, 0),
1393 STRUCT_FLD(field_flags, 0),
1394 STRUCT_FLD(old_name, "Currently in Use"),
1395 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1397 {STRUCT_FLD(field_name, "pages_free"),
1398 STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS),
1399 STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
1400 STRUCT_FLD(value, 0),
1401 STRUCT_FLD(field_flags, 0),
1402 STRUCT_FLD(old_name, "Currently Available"),
1403 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1405 {STRUCT_FLD(field_name, "relocation_ops"),
1406 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
1407 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
1408 STRUCT_FLD(value, 0),
1409 STRUCT_FLD(field_flags, 0),
1410 STRUCT_FLD(old_name, "Total Number of Relocations"),
1411 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1413 {STRUCT_FLD(field_name, "relocation_time"),
1414 STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS),
1415 STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
1416 STRUCT_FLD(value, 0),
1417 STRUCT_FLD(field_flags, 0),
1418 STRUCT_FLD(old_name, "Total Duration of Relocations,"
1419 " in Seconds"),
1420 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1422 END_OF_ST_FIELD_INFO
1425 /*******************************************************************//**
1426 Fill the dynamic table information_schema.innodb_cmpmem or
1427 innodb_cmpmem_reset.
1428 @return 0 on success, 1 on failure */
1429 static
1431 i_s_cmpmem_fill_low(
1432 /*================*/
1433 THD* thd, /*!< in: thread */
1434 TABLE_LIST* tables, /*!< in/out: tables to fill */
1435 COND* cond, /*!< in: condition (ignored) */
1436 ibool reset) /*!< in: TRUE=reset cumulated counts */
1438 TABLE* table = (TABLE *) tables->table;
1439 int status = 0;
1441 DBUG_ENTER("i_s_cmpmem_fill_low");
1443 /* deny access to non-superusers */
1444 if (check_global_access(thd, PROCESS_ACL)) {
1446 DBUG_RETURN(0);
1449 RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name);
1451 buf_pool_mutex_enter();
1453 for (uint x = 0; x <= BUF_BUDDY_SIZES; x++) {
1454 buf_buddy_stat_t* buddy_stat = &buf_buddy_stat[x];
1456 table->field[0]->store(BUF_BUDDY_LOW << x);
1457 table->field[1]->store(buddy_stat->used);
1458 table->field[2]->store(UNIV_LIKELY(x < BUF_BUDDY_SIZES)
1459 ? UT_LIST_GET_LEN(buf_pool->zip_free[x])
1460 : 0);
1461 table->field[3]->store((longlong) buddy_stat->relocated, true);
1462 table->field[4]->store(
1463 (ulong) (buddy_stat->relocated_usec / 1000000));
1465 if (reset) {
1466 /* This is protected by buf_pool_mutex. */
1467 buddy_stat->relocated = 0;
1468 buddy_stat->relocated_usec = 0;
1471 if (schema_table_store_record(thd, table)) {
1472 status = 1;
1473 break;
1477 buf_pool_mutex_exit();
1478 DBUG_RETURN(status);
1481 /*******************************************************************//**
1482 Fill the dynamic table information_schema.innodb_cmpmem.
1483 @return 0 on success, 1 on failure */
1484 static
1486 i_s_cmpmem_fill(
1487 /*============*/
1488 THD* thd, /*!< in: thread */
1489 TABLE_LIST* tables, /*!< in/out: tables to fill */
1490 COND* cond) /*!< in: condition (ignored) */
1492 return(i_s_cmpmem_fill_low(thd, tables, cond, FALSE));
1495 /*******************************************************************//**
1496 Fill the dynamic table information_schema.innodb_cmpmem_reset.
1497 @return 0 on success, 1 on failure */
1498 static
1500 i_s_cmpmem_reset_fill(
1501 /*==================*/
1502 THD* thd, /*!< in: thread */
1503 TABLE_LIST* tables, /*!< in/out: tables to fill */
1504 COND* cond) /*!< in: condition (ignored) */
1506 return(i_s_cmpmem_fill_low(thd, tables, cond, TRUE));
1509 /*******************************************************************//**
1510 Bind the dynamic table information_schema.innodb_cmpmem.
1511 @return 0 on success */
1512 static
1514 i_s_cmpmem_init(
1515 /*============*/
1516 void* p) /*!< in/out: table schema object */
1518 DBUG_ENTER("i_s_cmpmem_init");
1519 ST_SCHEMA_TABLE* schema = (ST_SCHEMA_TABLE*) p;
1521 schema->fields_info = i_s_cmpmem_fields_info;
1522 schema->fill_table = i_s_cmpmem_fill;
1524 DBUG_RETURN(0);
1527 /*******************************************************************//**
1528 Bind the dynamic table information_schema.innodb_cmpmem_reset.
1529 @return 0 on success */
1530 static
1532 i_s_cmpmem_reset_init(
1533 /*==================*/
1534 void* p) /*!< in/out: table schema object */
1536 DBUG_ENTER("i_s_cmpmem_reset_init");
1537 ST_SCHEMA_TABLE* schema = (ST_SCHEMA_TABLE*) p;
1539 schema->fields_info = i_s_cmpmem_fields_info;
1540 schema->fill_table = i_s_cmpmem_reset_fill;
1542 DBUG_RETURN(0);
1545 UNIV_INTERN struct st_mysql_plugin i_s_innodb_cmpmem =
1547 /* the plugin type (a MYSQL_XXX_PLUGIN value) */
1548 /* int */
1549 STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
1551 /* pointer to type-specific plugin descriptor */
1552 /* void* */
1553 STRUCT_FLD(info, &i_s_info),
1555 /* plugin name */
1556 /* const char* */
1557 STRUCT_FLD(name, "INNODB_CMPMEM"),
1559 /* plugin author (for SHOW PLUGINS) */
1560 /* const char* */
1561 STRUCT_FLD(author, plugin_author),
1563 /* general descriptive text (for SHOW PLUGINS) */
1564 /* const char* */
1565 STRUCT_FLD(descr, "Statistics for the InnoDB compressed buffer pool"),
1567 /* the plugin license (PLUGIN_LICENSE_XXX) */
1568 /* int */
1569 STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
1571 /* the function to invoke when plugin is loaded */
1572 /* int (*)(void*); */
1573 STRUCT_FLD(init, i_s_cmpmem_init),
1575 /* the function to invoke when plugin is unloaded */
1576 /* int (*)(void*); */
1577 STRUCT_FLD(deinit, i_s_common_deinit),
1579 /* plugin version (for SHOW PLUGINS) */
1580 /* unsigned int */
1581 STRUCT_FLD(version, INNODB_VERSION_SHORT),
1583 /* struct st_mysql_show_var* */
1584 STRUCT_FLD(status_vars, NULL),
1586 /* struct st_mysql_sys_var** */
1587 STRUCT_FLD(system_vars, NULL),
1589 /* reserved for dependency checking */
1590 /* void* */
1591 STRUCT_FLD(__reserved1, NULL)
1594 UNIV_INTERN struct st_mysql_plugin i_s_innodb_cmpmem_reset =
1596 /* the plugin type (a MYSQL_XXX_PLUGIN value) */
1597 /* int */
1598 STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
1600 /* pointer to type-specific plugin descriptor */
1601 /* void* */
1602 STRUCT_FLD(info, &i_s_info),
1604 /* plugin name */
1605 /* const char* */
1606 STRUCT_FLD(name, "INNODB_CMPMEM_RESET"),
1608 /* plugin author (for SHOW PLUGINS) */
1609 /* const char* */
1610 STRUCT_FLD(author, plugin_author),
1612 /* general descriptive text (for SHOW PLUGINS) */
1613 /* const char* */
1614 STRUCT_FLD(descr, "Statistics for the InnoDB compressed buffer pool;"
1615 " reset cumulated counts"),
1617 /* the plugin license (PLUGIN_LICENSE_XXX) */
1618 /* int */
1619 STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
1621 /* the function to invoke when plugin is loaded */
1622 /* int (*)(void*); */
1623 STRUCT_FLD(init, i_s_cmpmem_reset_init),
1625 /* the function to invoke when plugin is unloaded */
1626 /* int (*)(void*); */
1627 STRUCT_FLD(deinit, i_s_common_deinit),
1629 /* plugin version (for SHOW PLUGINS) */
1630 /* unsigned int */
1631 STRUCT_FLD(version, INNODB_VERSION_SHORT),
1633 /* struct st_mysql_show_var* */
1634 STRUCT_FLD(status_vars, NULL),
1636 /* struct st_mysql_sys_var** */
1637 STRUCT_FLD(system_vars, NULL),
1639 /* reserved for dependency checking */
1640 /* void* */
1641 STRUCT_FLD(__reserved1, NULL)
1644 /*******************************************************************//**
1645 Unbind a dynamic INFORMATION_SCHEMA table.
1646 @return 0 on success */
1647 static
1649 i_s_common_deinit(
1650 /*==============*/
1651 void* p) /*!< in/out: table schema object */
1653 DBUG_ENTER("i_s_common_deinit");
1655 /* Do nothing */
1657 DBUG_RETURN(0);
1661 /* Fields of the dynamic table INNODB_BUFFER_POOL_STATS. */
1662 static ST_FIELD_INFO i_s_innodb_buffer_stats_fields_info[] =
1664 #define IDX_BUF_STATS_POOL_SIZE 0
1665 {STRUCT_FLD(field_name, "POOL_SIZE"),
1666 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
1667 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
1668 STRUCT_FLD(value, 0),
1669 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
1670 STRUCT_FLD(old_name, ""),
1671 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1673 #define IDX_BUF_STATS_FREE_BUFFERS 1
1674 {STRUCT_FLD(field_name, "FREE_BUFFERS"),
1675 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
1676 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
1677 STRUCT_FLD(value, 0),
1678 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
1679 STRUCT_FLD(old_name, ""),
1680 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1682 #define IDX_BUF_STATS_LRU_LEN 2
1683 {STRUCT_FLD(field_name, "DATABASE_PAGES"),
1684 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
1685 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
1686 STRUCT_FLD(value, 0),
1687 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
1688 STRUCT_FLD(old_name, ""),
1689 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1691 #define IDX_BUF_STATS_OLD_LRU_LEN 3
1692 {STRUCT_FLD(field_name, "OLD_DATABASE_PAGES"),
1693 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
1694 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
1695 STRUCT_FLD(value, 0),
1696 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
1697 STRUCT_FLD(old_name, ""),
1698 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1700 #define IDX_BUF_STATS_FLUSH_LIST_LEN 4
1701 {STRUCT_FLD(field_name, "MODIFIED_DATABASE_PAGES"),
1702 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
1703 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
1704 STRUCT_FLD(value, 0),
1705 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
1706 STRUCT_FLD(old_name, ""),
1707 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1709 #define IDX_BUF_STATS_PENDING_ZIP 5
1710 {STRUCT_FLD(field_name, "PENDING_DECOMPRESS"),
1711 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
1712 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
1713 STRUCT_FLD(value, 0),
1714 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
1715 STRUCT_FLD(old_name, ""),
1716 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1718 #define IDX_BUF_STATS_PENDING_READ 6
1719 {STRUCT_FLD(field_name, "PENDING_READS"),
1720 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
1721 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
1722 STRUCT_FLD(value, 0),
1723 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
1724 STRUCT_FLD(old_name, ""),
1725 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1727 #define IDX_BUF_STATS_FLUSH_LRU 7
1728 {STRUCT_FLD(field_name, "PENDING_FLUSH_LRU"),
1729 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
1730 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
1731 STRUCT_FLD(value, 0),
1732 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
1733 STRUCT_FLD(old_name, ""),
1734 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1736 #define IDX_BUF_STATS_FLUSH_LIST 8
1737 {STRUCT_FLD(field_name, "PENDING_FLUSH_LIST"),
1738 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
1739 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
1740 STRUCT_FLD(value, 0),
1741 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
1742 STRUCT_FLD(old_name, ""),
1743 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1745 #define IDX_BUF_STATS_PAGE_YOUNG 9
1746 {STRUCT_FLD(field_name, "PAGES_MADE_YOUNG"),
1747 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
1748 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
1749 STRUCT_FLD(value, 0),
1750 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
1751 STRUCT_FLD(old_name, ""),
1752 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1754 #define IDX_BUF_STATS_PAGE_NOT_YOUNG 10
1755 {STRUCT_FLD(field_name, "PAGES_NOT_MADE_YOUNG"),
1756 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
1757 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
1758 STRUCT_FLD(value, 0),
1759 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
1760 STRUCT_FLD(old_name, ""),
1761 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1763 #define IDX_BUF_STATS_PAGE_YOUNG_RATE 11
1764 {STRUCT_FLD(field_name, "PAGES_MADE_YOUNG_RATE"),
1765 STRUCT_FLD(field_length, MAX_FLOAT_STR_LENGTH),
1766 STRUCT_FLD(field_type, MYSQL_TYPE_FLOAT),
1767 STRUCT_FLD(value, 0),
1768 STRUCT_FLD(field_flags, 0),
1769 STRUCT_FLD(old_name, ""),
1770 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1772 #define IDX_BUF_STATS_PAGE_NOT_YOUNG_RATE 12
1773 {STRUCT_FLD(field_name, "PAGES_MADE_NOT_YOUNG_RATE"),
1774 STRUCT_FLD(field_length, MAX_FLOAT_STR_LENGTH),
1775 STRUCT_FLD(field_type, MYSQL_TYPE_FLOAT),
1776 STRUCT_FLD(value, 0),
1777 STRUCT_FLD(field_flags, 0),
1778 STRUCT_FLD(old_name, ""),
1779 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1781 #define IDX_BUF_STATS_PAGE_READ 13
1782 {STRUCT_FLD(field_name, "NUMBER_PAGES_READ"),
1783 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
1784 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
1785 STRUCT_FLD(value, 0),
1786 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
1787 STRUCT_FLD(old_name, ""),
1788 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1790 #define IDX_BUF_STATS_PAGE_CREATED 14
1791 {STRUCT_FLD(field_name, "NUMBER_PAGES_CREATED"),
1792 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
1793 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
1794 STRUCT_FLD(value, 0),
1795 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
1796 STRUCT_FLD(old_name, ""),
1797 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1799 #define IDX_BUF_STATS_PAGE_WRITTEN 15
1800 {STRUCT_FLD(field_name, "NUMBER_PAGES_WRITTEN"),
1801 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
1802 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
1803 STRUCT_FLD(value, 0),
1804 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
1805 STRUCT_FLD(old_name, ""),
1806 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1808 #define IDX_BUF_STATS_PAGE_READ_RATE 16
1809 {STRUCT_FLD(field_name, "PAGES_READ_RATE"),
1810 STRUCT_FLD(field_length, MAX_FLOAT_STR_LENGTH),
1811 STRUCT_FLD(field_type, MYSQL_TYPE_FLOAT),
1812 STRUCT_FLD(value, 0),
1813 STRUCT_FLD(field_flags, 0),
1814 STRUCT_FLD(old_name, ""),
1815 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1817 #define IDX_BUF_STATS_PAGE_CREATE_RATE 17
1818 {STRUCT_FLD(field_name, "PAGES_CREATE_RATE"),
1819 STRUCT_FLD(field_length, MAX_FLOAT_STR_LENGTH),
1820 STRUCT_FLD(field_type, MYSQL_TYPE_FLOAT),
1821 STRUCT_FLD(value, 0),
1822 STRUCT_FLD(field_flags, 0),
1823 STRUCT_FLD(old_name, ""),
1824 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1826 #define IDX_BUF_STATS_PAGE_WRITTEN_RATE 18
1827 {STRUCT_FLD(field_name, "PAGES_WRITTEN_RATE"),
1828 STRUCT_FLD(field_length, MAX_FLOAT_STR_LENGTH),
1829 STRUCT_FLD(field_type, MYSQL_TYPE_FLOAT),
1830 STRUCT_FLD(value, 0),
1831 STRUCT_FLD(field_flags, 0),
1832 STRUCT_FLD(old_name, ""),
1833 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1835 #define IDX_BUF_STATS_GET 19
1836 {STRUCT_FLD(field_name, "NUMBER_PAGES_GET"),
1837 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
1838 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
1839 STRUCT_FLD(value, 0),
1840 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
1841 STRUCT_FLD(old_name, ""),
1842 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1844 #define IDX_BUF_STATS_HIT_RATE 20
1845 {STRUCT_FLD(field_name, "HIT_RATE"),
1846 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
1847 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
1848 STRUCT_FLD(value, 0),
1849 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
1850 STRUCT_FLD(old_name, ""),
1851 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1853 #define IDX_BUF_STATS_MADE_YOUNG_PCT 21
1854 {STRUCT_FLD(field_name, "YOUNG_MAKE_PER_THOUSAND_GETS"),
1855 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
1856 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
1857 STRUCT_FLD(value, 0),
1858 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
1859 STRUCT_FLD(old_name, ""),
1860 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1862 #define IDX_BUF_STATS_NOT_MADE_YOUNG_PCT 22
1863 {STRUCT_FLD(field_name, "NOT_YOUNG_MAKE_PER_THOUSAND_GETS"),
1864 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
1865 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
1866 STRUCT_FLD(value, 0),
1867 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
1868 STRUCT_FLD(old_name, ""),
1869 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1871 #define IDX_BUF_STATS_READ_AHREAD 23
1872 {STRUCT_FLD(field_name, "NUMBER_PAGES_READ_AHEAD"),
1873 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
1874 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
1875 STRUCT_FLD(value, 0),
1876 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
1877 STRUCT_FLD(old_name, ""),
1878 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1880 #define IDX_BUF_STATS_READ_AHEAD_EVICTED 24
1881 {STRUCT_FLD(field_name, "NUMBER_READ_AHEAD_EVICTED"),
1882 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
1883 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
1884 STRUCT_FLD(value, 0),
1885 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
1886 STRUCT_FLD(old_name, ""),
1887 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1889 #define IDX_BUF_STATS_READ_AHEAD_RATE 25
1890 {STRUCT_FLD(field_name, "READ_AHEAD_RATE"),
1891 STRUCT_FLD(field_length, MAX_FLOAT_STR_LENGTH),
1892 STRUCT_FLD(field_type, MYSQL_TYPE_FLOAT),
1893 STRUCT_FLD(value, 0),
1894 STRUCT_FLD(field_flags, 0),
1895 STRUCT_FLD(old_name, ""),
1896 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1898 #define IDX_BUF_STATS_READ_AHEAD_EVICT_RATE 26
1899 {STRUCT_FLD(field_name, "READ_AHEAD_EVICTED_RATE"),
1900 STRUCT_FLD(field_length, MAX_FLOAT_STR_LENGTH),
1901 STRUCT_FLD(field_type, MYSQL_TYPE_FLOAT),
1902 STRUCT_FLD(value, 0),
1903 STRUCT_FLD(field_flags, 0),
1904 STRUCT_FLD(old_name, ""),
1905 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1907 #define IDX_BUF_STATS_LRU_IO_SUM 27
1908 {STRUCT_FLD(field_name, "LRU_IO_TOTAL"),
1909 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
1910 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
1911 STRUCT_FLD(value, 0),
1912 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
1913 STRUCT_FLD(old_name, ""),
1914 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1916 #define IDX_BUF_STATS_LRU_IO_CUR 28
1917 {STRUCT_FLD(field_name, "LRU_IO_CURRENT"),
1918 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
1919 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
1920 STRUCT_FLD(value, 0),
1921 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
1922 STRUCT_FLD(old_name, ""),
1923 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1925 #define IDX_BUF_STATS_UNZIP_SUM 29
1926 {STRUCT_FLD(field_name, "UNCOMPRESS_TOTAL"),
1927 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
1928 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
1929 STRUCT_FLD(value, 0),
1930 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
1931 STRUCT_FLD(old_name, ""),
1932 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1934 #define IDX_BUF_STATS_UNZIP_CUR 30
1935 {STRUCT_FLD(field_name, "UNCOMPRESS_CURRENT"),
1936 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
1937 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
1938 STRUCT_FLD(value, 0),
1939 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
1940 STRUCT_FLD(old_name, ""),
1941 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1943 END_OF_ST_FIELD_INFO
1946 /*******************************************************************//**
1947 Fill Information Schema table INNODB_BUFFER_POOL_STATS for a particular
1948 buffer pool
1949 @return 0 on success, 1 on failure */
1950 static
1952 i_s_innodb_stats_fill(
1953 /*==================*/
1954 THD* thd, /*!< in: thread */
1955 TABLE_LIST* tables, /*!< in/out: tables to fill */
1956 const buf_pool_info_t* info) /*!< in: buffer pool
1957 information */
1959 TABLE* table;
1960 Field** fields;
1962 DBUG_ENTER("i_s_innodb_stats_fill");
1964 table = tables->table;
1966 fields = table->field;
1968 OK(fields[IDX_BUF_STATS_POOL_SIZE]->store(info->pool_size));
1970 OK(fields[IDX_BUF_STATS_LRU_LEN]->store(info->lru_len));
1972 OK(fields[IDX_BUF_STATS_OLD_LRU_LEN]->store(info->old_lru_len));
1974 OK(fields[IDX_BUF_STATS_FREE_BUFFERS]->store(info->free_list_len));
1976 OK(fields[IDX_BUF_STATS_FLUSH_LIST_LEN]->store(
1977 info->flush_list_len));
1979 OK(fields[IDX_BUF_STATS_PENDING_ZIP]->store(info->n_pend_unzip));
1981 OK(fields[IDX_BUF_STATS_PENDING_READ]->store(info->n_pend_reads));
1983 OK(fields[IDX_BUF_STATS_FLUSH_LRU]->store(info->n_pending_flush_lru));
1985 OK(fields[IDX_BUF_STATS_FLUSH_LIST]->store(info->n_pending_flush_list));
1987 OK(fields[IDX_BUF_STATS_PAGE_YOUNG]->store(info->n_pages_made_young));
1989 OK(fields[IDX_BUF_STATS_PAGE_NOT_YOUNG]->store(
1990 info->n_pages_not_made_young));
1992 OK(fields[IDX_BUF_STATS_PAGE_YOUNG_RATE]->store(
1993 info->page_made_young_rate));
1995 OK(fields[IDX_BUF_STATS_PAGE_NOT_YOUNG_RATE]->store(
1996 info->page_not_made_young_rate));
1998 OK(fields[IDX_BUF_STATS_PAGE_READ]->store(info->n_pages_read));
2000 OK(fields[IDX_BUF_STATS_PAGE_CREATED]->store(info->n_pages_created));
2002 OK(fields[IDX_BUF_STATS_PAGE_WRITTEN]->store(info->n_pages_written));
2004 OK(fields[IDX_BUF_STATS_GET]->store(info->n_page_gets));
2006 OK(fields[IDX_BUF_STATS_PAGE_READ_RATE]->store(info->pages_read_rate));
2008 OK(fields[IDX_BUF_STATS_PAGE_CREATE_RATE]->store(info->pages_created_rate));
2010 OK(fields[IDX_BUF_STATS_PAGE_WRITTEN_RATE]->store(info->pages_written_rate));
2012 if (info->n_page_get_delta) {
2013 OK(fields[IDX_BUF_STATS_HIT_RATE]->store(
2014 1000 - (1000 * info->page_read_delta
2015 / info->n_page_get_delta)));
2017 OK(fields[IDX_BUF_STATS_MADE_YOUNG_PCT]->store(
2018 1000 * info->young_making_delta
2019 / info->n_page_get_delta));
2021 OK(fields[IDX_BUF_STATS_NOT_MADE_YOUNG_PCT]->store(
2022 1000 * info->not_young_making_delta
2023 / info->n_page_get_delta));
2024 } else {
2025 OK(fields[IDX_BUF_STATS_HIT_RATE]->store(0));
2026 OK(fields[IDX_BUF_STATS_MADE_YOUNG_PCT]->store(0));
2027 OK(fields[IDX_BUF_STATS_NOT_MADE_YOUNG_PCT]->store(0));
2030 OK(fields[IDX_BUF_STATS_READ_AHREAD]->store(info->n_ra_pages_read));
2032 OK(fields[IDX_BUF_STATS_READ_AHEAD_EVICTED]->store(
2033 info->n_ra_pages_evicted));
2035 OK(fields[IDX_BUF_STATS_READ_AHEAD_RATE]->store(
2036 info->pages_readahead_rate));
2038 OK(fields[IDX_BUF_STATS_READ_AHEAD_EVICT_RATE]->store(
2039 info->pages_evicted_rate));
2041 OK(fields[IDX_BUF_STATS_LRU_IO_SUM]->store(info->io_sum));
2043 OK(fields[IDX_BUF_STATS_LRU_IO_CUR]->store(info->io_cur));
2045 OK(fields[IDX_BUF_STATS_UNZIP_SUM]->store(info->unzip_sum));
2047 OK(fields[IDX_BUF_STATS_UNZIP_CUR]->store( info->unzip_cur));
2049 DBUG_RETURN(schema_table_store_record(thd, table));
2052 /*******************************************************************//**
2053 This is the function that loops through each buffer pool and fetch buffer
2054 pool stats to information schema table: I_S_INNODB_BUFFER_POOL_STATS
2055 @return 0 on success, 1 on failure */
2056 static
2058 i_s_innodb_buffer_stats_fill_table(
2059 /*===============================*/
2060 THD* thd, /*!< in: thread */
2061 TABLE_LIST* tables, /*!< in/out: tables to fill */
2062 Item* ) /*!< in: condition (ignored) */
2064 int status = 0;
2065 buf_pool_info_t* pool_info;
2067 DBUG_ENTER("i_s_innodb_buffer_fill_general");
2069 /* Only allow the PROCESS privilege holder to access the stats */
2070 if (check_global_access(thd, PROCESS_ACL)) {
2071 DBUG_RETURN(0);
2074 pool_info = (buf_pool_info_t*) mem_zalloc(sizeof *pool_info);
2076 /* Fetch individual buffer pool info */
2077 buf_stats_get_pool_info(pool_info);
2078 status = i_s_innodb_stats_fill(thd, tables, pool_info);
2080 mem_free(pool_info);
2082 DBUG_RETURN(status);
2085 /*******************************************************************//**
2086 Bind the dynamic table INFORMATION_SCHEMA.INNODB_BUFFER_POOL_STATS.
2087 @return 0 on success, 1 on failure */
2088 static
2090 i_s_innodb_buffer_pool_stats_init(
2091 /*==============================*/
2092 void* p) /*!< in/out: table schema object */
2094 ST_SCHEMA_TABLE* schema;
2096 DBUG_ENTER("i_s_innodb_buffer_pool_stats_init");
2098 schema = reinterpret_cast<ST_SCHEMA_TABLE*>(p);
2100 schema->fields_info = i_s_innodb_buffer_stats_fields_info;
2101 schema->fill_table = i_s_innodb_buffer_stats_fill_table;
2103 DBUG_RETURN(0);
2106 UNIV_INTERN struct st_mysql_plugin i_s_innodb_buffer_stats =
2108 /* the plugin type (a MYSQL_XXX_PLUGIN value) */
2109 /* int */
2110 STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
2112 /* pointer to type-specific plugin descriptor */
2113 /* void* */
2114 STRUCT_FLD(info, &i_s_info),
2116 /* plugin name */
2117 /* const char* */
2118 STRUCT_FLD(name, "INNODB_BUFFER_POOL_STATS"),
2120 /* plugin author (for SHOW PLUGINS) */
2121 /* const char* */
2122 STRUCT_FLD(author, plugin_author),
2124 /* general descriptive text (for SHOW PLUGINS) */
2125 /* const char* */
2126 STRUCT_FLD(descr, "InnoDB Buffer Pool Statistics Information "),
2128 /* the plugin license (PLUGIN_LICENSE_XXX) */
2129 /* int */
2130 STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
2132 /* the function to invoke when plugin is loaded */
2133 /* int (*)(void*); */
2134 STRUCT_FLD(init, i_s_innodb_buffer_pool_stats_init),
2136 /* the function to invoke when plugin is unloaded */
2137 /* int (*)(void*); */
2138 STRUCT_FLD(deinit, i_s_common_deinit),
2140 /* plugin version (for SHOW PLUGINS) */
2141 /* unsigned int */
2142 STRUCT_FLD(version, INNODB_VERSION_SHORT),
2144 /* struct st_mysql_show_var* */
2145 STRUCT_FLD(status_vars, NULL),
2147 /* struct st_mysql_sys_var** */
2148 STRUCT_FLD(system_vars, NULL),
2150 /* reserved for dependency checking */
2151 /* void* */
2152 STRUCT_FLD(__reserved1, NULL),
2155 /* Fields of the dynamic table INNODB_BUFFER_POOL_PAGE. */
2156 static ST_FIELD_INFO i_s_innodb_buffer_page_fields_info[] =
2158 #define IDX_BUFFER_BLOCK_ID 0
2159 {STRUCT_FLD(field_name, "BLOCK_ID"),
2160 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
2161 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
2162 STRUCT_FLD(value, 0),
2163 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
2164 STRUCT_FLD(old_name, ""),
2165 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2167 #define IDX_BUFFER_PAGE_SPACE 1
2168 {STRUCT_FLD(field_name, "SPACE"),
2169 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
2170 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
2171 STRUCT_FLD(value, 0),
2172 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
2173 STRUCT_FLD(old_name, ""),
2174 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2176 #define IDX_BUFFER_PAGE_NUM 2
2177 {STRUCT_FLD(field_name, "PAGE_NUMBER"),
2178 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
2179 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
2180 STRUCT_FLD(value, 0),
2181 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
2182 STRUCT_FLD(old_name, ""),
2183 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2185 #define IDX_BUFFER_PAGE_TYPE 3
2186 {STRUCT_FLD(field_name, "PAGE_TYPE"),
2187 STRUCT_FLD(field_length, 64),
2188 STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
2189 STRUCT_FLD(value, 0),
2190 STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
2191 STRUCT_FLD(old_name, ""),
2192 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2194 #define IDX_BUFFER_PAGE_FLUSH_TYPE 4
2195 {STRUCT_FLD(field_name, "FLUSH_TYPE"),
2196 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
2197 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
2198 STRUCT_FLD(value, 0),
2199 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
2200 STRUCT_FLD(old_name, ""),
2201 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2203 #define IDX_BUFFER_PAGE_FIX_COUNT 5
2204 {STRUCT_FLD(field_name, "FIX_COUNT"),
2205 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
2206 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
2207 STRUCT_FLD(value, 0),
2208 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
2209 STRUCT_FLD(old_name, ""),
2210 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2212 #define IDX_BUFFER_PAGE_HASHED 6
2213 {STRUCT_FLD(field_name, "IS_HASHED"),
2214 STRUCT_FLD(field_length, 3),
2215 STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
2216 STRUCT_FLD(value, 0),
2217 STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
2218 STRUCT_FLD(old_name, ""),
2219 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2221 #define IDX_BUFFER_PAGE_NEWEST_MOD 7
2222 {STRUCT_FLD(field_name, "NEWEST_MODIFICATION"),
2223 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
2224 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
2225 STRUCT_FLD(value, 0),
2226 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
2227 STRUCT_FLD(old_name, ""),
2228 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2230 #define IDX_BUFFER_PAGE_OLDEST_MOD 8
2231 {STRUCT_FLD(field_name, "OLDEST_MODIFICATION"),
2232 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
2233 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
2234 STRUCT_FLD(value, 0),
2235 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
2236 STRUCT_FLD(old_name, ""),
2237 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2239 #define IDX_BUFFER_PAGE_ACCESS_TIME 9
2240 {STRUCT_FLD(field_name, "ACCESS_TIME"),
2241 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
2242 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
2243 STRUCT_FLD(value, 0),
2244 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
2245 STRUCT_FLD(old_name, ""),
2246 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2248 #define IDX_BUFFER_PAGE_TABLE_NAME 10
2249 {STRUCT_FLD(field_name, "TABLE_NAME"),
2250 STRUCT_FLD(field_length, 1024),
2251 STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
2252 STRUCT_FLD(value, 0),
2253 STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
2254 STRUCT_FLD(old_name, ""),
2255 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2257 #define IDX_BUFFER_PAGE_INDEX_NAME 11
2258 {STRUCT_FLD(field_name, "INDEX_NAME"),
2259 STRUCT_FLD(field_length, 1024),
2260 STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
2261 STRUCT_FLD(value, 0),
2262 STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
2263 STRUCT_FLD(old_name, ""),
2264 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2266 #define IDX_BUFFER_PAGE_NUM_RECS 12
2267 {STRUCT_FLD(field_name, "NUMBER_RECORDS"),
2268 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
2269 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
2270 STRUCT_FLD(value, 0),
2271 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
2272 STRUCT_FLD(old_name, ""),
2273 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2275 #define IDX_BUFFER_PAGE_DATA_SIZE 13
2276 {STRUCT_FLD(field_name, "DATA_SIZE"),
2277 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
2278 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
2279 STRUCT_FLD(value, 0),
2280 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
2281 STRUCT_FLD(old_name, ""),
2282 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2284 #define IDX_BUFFER_PAGE_ZIP_SIZE 14
2285 {STRUCT_FLD(field_name, "COMPRESSED_SIZE"),
2286 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
2287 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
2288 STRUCT_FLD(value, 0),
2289 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
2290 STRUCT_FLD(old_name, ""),
2291 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2293 #define IDX_BUFFER_PAGE_STATE 15
2294 {STRUCT_FLD(field_name, "PAGE_STATE"),
2295 STRUCT_FLD(field_length, 64),
2296 STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
2297 STRUCT_FLD(value, 0),
2298 STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
2299 STRUCT_FLD(old_name, ""),
2300 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2302 #define IDX_BUFFER_PAGE_IO_FIX 16
2303 {STRUCT_FLD(field_name, "IO_FIX"),
2304 STRUCT_FLD(field_length, 64),
2305 STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
2306 STRUCT_FLD(value, 0),
2307 STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
2308 STRUCT_FLD(old_name, ""),
2309 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2311 #define IDX_BUFFER_PAGE_IS_OLD 17
2312 {STRUCT_FLD(field_name, "IS_OLD"),
2313 STRUCT_FLD(field_length, 3),
2314 STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
2315 STRUCT_FLD(value, 0),
2316 STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
2317 STRUCT_FLD(old_name, ""),
2318 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2320 #define IDX_BUFFER_PAGE_FREE_CLOCK 18
2321 {STRUCT_FLD(field_name, "FREE_PAGE_CLOCK"),
2322 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
2323 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
2324 STRUCT_FLD(value, 0),
2325 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
2326 STRUCT_FLD(old_name, ""),
2327 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2329 END_OF_ST_FIELD_INFO
2332 /*******************************************************************//**
2333 Fill Information Schema table INNODB_BUFFER_PAGE with information
2334 cached in the buf_page_info_t array
2335 @return 0 on success, 1 on failure */
2336 static
2338 i_s_innodb_buffer_page_fill(
2339 /*========================*/
2340 THD* thd, /*!< in: thread */
2341 TABLE_LIST* tables, /*!< in/out: tables to fill */
2342 const buf_page_info_t* info_array, /*!< in: array cached page
2343 info */
2344 ulint num_page, /*!< in: number of page info
2345 cached */
2346 mem_heap_t* heap) /*!< in: temp heap memory */
2348 TABLE* table;
2349 Field** fields;
2351 DBUG_ENTER("i_s_innodb_buffer_page_fill");
2353 table = tables->table;
2355 fields = table->field;
2357 /* Iterate through the cached array and fill the I_S table rows */
2358 for (ulint i = 0; i < num_page; i++) {
2359 const buf_page_info_t* page_info;
2360 const char* table_name;
2361 const char* index_name;
2362 const char* state_str;
2363 enum buf_page_state state;
2365 page_info = info_array + i;
2367 table_name = NULL;
2368 index_name = NULL;
2369 state_str = NULL;
2371 OK(fields[IDX_BUFFER_BLOCK_ID]->store(page_info->block_id));
2373 OK(fields[IDX_BUFFER_PAGE_SPACE]->store(page_info->space_id));
2375 OK(fields[IDX_BUFFER_PAGE_NUM]->store(page_info->page_num));
2377 OK(field_store_string(
2378 fields[IDX_BUFFER_PAGE_TYPE],
2379 i_s_page_type[page_info->page_type].type_str));
2381 OK(fields[IDX_BUFFER_PAGE_FLUSH_TYPE]->store(
2382 page_info->flush_type));
2384 OK(fields[IDX_BUFFER_PAGE_FIX_COUNT]->store(
2385 page_info->fix_count));
2387 if (page_info->hashed) {
2388 OK(field_store_string(
2389 fields[IDX_BUFFER_PAGE_HASHED], "YES"));
2390 } else {
2391 OK(field_store_string(
2392 fields[IDX_BUFFER_PAGE_HASHED], "NO"));
2395 OK(fields[IDX_BUFFER_PAGE_NEWEST_MOD]->store(
2396 (longlong) page_info->newest_mod, true));
2398 OK(fields[IDX_BUFFER_PAGE_OLDEST_MOD]->store(
2399 (longlong) page_info->oldest_mod, true));
2401 OK(fields[IDX_BUFFER_PAGE_ACCESS_TIME]->store(
2402 page_info->access_time));
2404 /* If this is an index page, fetch the index name
2405 and table name */
2406 if (page_info->page_type == I_S_PAGE_TYPE_INDEX) {
2407 const dict_index_t* index;
2409 mutex_enter(&dict_sys->mutex);
2410 index = dict_index_get_if_in_cache_low(
2411 page_info->index_id);
2413 /* Copy the index/table name under mutex. We
2414 do not want to hold the InnoDB mutex while
2415 filling the IS table */
2416 if (index) {
2417 const char* name_ptr = index->name;
2419 if (name_ptr[0] == TEMP_INDEX_PREFIX) {
2420 name_ptr++;
2423 index_name = mem_heap_strdup(heap, name_ptr);
2425 table_name = mem_heap_strdup(heap,
2426 index->table_name);
2430 mutex_exit(&dict_sys->mutex);
2433 OK(field_store_string(
2434 fields[IDX_BUFFER_PAGE_TABLE_NAME], table_name));
2436 OK(field_store_string(
2437 fields[IDX_BUFFER_PAGE_INDEX_NAME], index_name));
2439 OK(fields[IDX_BUFFER_PAGE_NUM_RECS]->store(
2440 page_info->num_recs));
2442 OK(fields[IDX_BUFFER_PAGE_DATA_SIZE]->store(
2443 page_info->data_size));
2445 OK(fields[IDX_BUFFER_PAGE_ZIP_SIZE]->store(
2446 page_info->zip_ssize
2447 ? (PAGE_ZIP_MIN_SIZE >> 1) << page_info->zip_ssize
2448 : 0));
2450 #if BUF_PAGE_STATE_BITS > 3
2451 # error "BUF_PAGE_STATE_BITS > 3, please ensure that all 1<<BUF_PAGE_STATE_BITS values are checked for"
2452 #endif
2453 state = static_cast<enum buf_page_state>(page_info->page_state);
2455 switch (state) {
2456 /* First three states are for compression pages and
2457 are not states we would get as we scan pages through
2458 buffer blocks */
2459 case BUF_BLOCK_ZIP_FREE:
2460 case BUF_BLOCK_ZIP_PAGE:
2461 case BUF_BLOCK_ZIP_DIRTY:
2462 state_str = NULL;
2463 break;
2464 case BUF_BLOCK_NOT_USED:
2465 state_str = "NOT_USED";
2466 break;
2467 case BUF_BLOCK_READY_FOR_USE:
2468 state_str = "READY_FOR_USE";
2469 break;
2470 case BUF_BLOCK_FILE_PAGE:
2471 state_str = "FILE_PAGE";
2472 break;
2473 case BUF_BLOCK_MEMORY:
2474 state_str = "MEMORY";
2475 break;
2476 case BUF_BLOCK_REMOVE_HASH:
2477 state_str = "REMOVE_HASH";
2478 break;
2481 OK(field_store_string(fields[IDX_BUFFER_PAGE_STATE],
2482 state_str));
2484 switch (page_info->io_fix) {
2485 case BUF_IO_NONE:
2486 OK(field_store_string(fields[IDX_BUFFER_PAGE_IO_FIX],
2487 "IO_NONE"));
2488 break;
2489 case BUF_IO_READ:
2490 OK(field_store_string(fields[IDX_BUFFER_PAGE_IO_FIX],
2491 "IO_READ"));
2492 break;
2493 case BUF_IO_WRITE:
2494 OK(field_store_string(fields[IDX_BUFFER_PAGE_IO_FIX],
2495 "IO_WRITE"));
2496 break;
2499 OK(field_store_string(fields[IDX_BUFFER_PAGE_IS_OLD],
2500 (page_info->is_old) ? "YES" : "NO"));
2502 OK(fields[IDX_BUFFER_PAGE_FREE_CLOCK]->store(
2503 page_info->freed_page_clock));
2505 if (schema_table_store_record(thd, table)) {
2506 DBUG_RETURN(1);
2510 DBUG_RETURN(0);
2513 /*******************************************************************//**
2514 Set appropriate page type to a buf_page_info_t structure */
2515 static
2516 void
2517 i_s_innodb_set_page_type(
2518 /*=====================*/
2519 buf_page_info_t*page_info, /*!< in/out: structure to fill with
2520 scanned info */
2521 ulint page_type, /*!< in: page type */
2522 const byte* frame) /*!< in: buffer frame */
2524 if (page_type == FIL_PAGE_INDEX) {
2525 const page_t* page = (const page_t*) frame;
2527 /* FIL_PAGE_INDEX is a bit special, its value
2528 is defined as 17855, so we cannot use FIL_PAGE_INDEX
2529 to index into i_s_page_type[] array, its array index
2530 in the i_s_page_type[] array is I_S_PAGE_TYPE_INDEX
2531 (1) */
2532 page_info->page_type = I_S_PAGE_TYPE_INDEX;
2534 page_info->index_id = btr_page_get_index_id(page);
2536 page_info->data_size = (ulint)(page_header_get_field(
2537 page, PAGE_HEAP_TOP) - (page_is_comp(page)
2538 ? PAGE_NEW_SUPREMUM_END
2539 : PAGE_OLD_SUPREMUM_END)
2540 - page_header_get_field(page, PAGE_GARBAGE));
2542 page_info->num_recs = page_get_n_recs(page);
2543 } else if (page_type >= I_S_PAGE_TYPE_UNKNOWN) {
2544 /* Encountered an unknown page type */
2545 page_info->page_type = I_S_PAGE_TYPE_UNKNOWN;
2546 } else {
2547 /* Make sure we get the right index into the
2548 i_s_page_type[] array */
2549 ut_a(page_type == i_s_page_type[page_type].type_value);
2551 page_info->page_type = page_type;
2554 if (page_info->page_type == FIL_PAGE_TYPE_ZBLOB
2555 || page_info->page_type == FIL_PAGE_TYPE_ZBLOB2) {
2556 page_info->page_num = mach_read_from_4(
2557 frame + FIL_PAGE_OFFSET);
2558 page_info->space_id = mach_read_from_4(
2559 frame + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
2563 /*******************************************************************//**
2564 Scans pages in the buffer cache, and collect their general information
2565 into the buf_page_info_t array which is zero-filled. So any fields
2566 that are not initialized in the function will default to 0 */
2567 static
2568 void
2569 i_s_innodb_buffer_page_get_info(
2570 /*============================*/
2571 const buf_page_t*bpage, /*!< in: buffer pool page to scan */
2572 ulint pos, /*!< in: buffer block position in
2573 buffer pool or in the LRU list */
2574 buf_page_info_t*page_info) /*!< in: zero filled info structure;
2575 out: structure filled with scanned
2576 info */
2578 page_info->block_id = pos;
2580 page_info->page_state = buf_page_get_state(bpage);
2582 /* Only fetch information for buffers that map to a tablespace,
2583 that is, buffer page with state BUF_BLOCK_ZIP_PAGE,
2584 BUF_BLOCK_ZIP_DIRTY or BUF_BLOCK_FILE_PAGE */
2585 if (buf_page_in_file(bpage)) {
2586 const byte* frame;
2587 ulint page_type;
2589 page_info->space_id = buf_page_get_space(bpage);
2591 page_info->page_num = buf_page_get_page_no(bpage);
2593 page_info->flush_type = bpage->flush_type;
2595 page_info->fix_count = bpage->buf_fix_count;
2597 page_info->newest_mod = bpage->newest_modification;
2599 page_info->oldest_mod = bpage->oldest_modification;
2601 page_info->access_time = bpage->access_time;
2603 page_info->zip_ssize = bpage->zip.ssize;
2605 page_info->io_fix = bpage->io_fix;
2607 page_info->is_old = bpage->old;
2609 page_info->freed_page_clock = bpage->freed_page_clock;
2611 if (page_info->page_state == BUF_BLOCK_FILE_PAGE) {
2612 const buf_block_t*block;
2614 block = reinterpret_cast<const buf_block_t*>(bpage);
2615 frame = block->frame;
2616 page_info->hashed = (block->index != NULL);
2617 } else {
2618 ut_ad(page_info->zip_ssize);
2619 frame = bpage->zip.data;
2622 page_type = fil_page_get_type(frame);
2624 i_s_innodb_set_page_type(page_info, page_type, frame);
2625 } else {
2626 page_info->page_type = I_S_PAGE_TYPE_UNKNOWN;
2630 /*******************************************************************//**
2631 This is the function that goes through each block of the buffer pool
2632 and fetch information to information schema tables: INNODB_BUFFER_PAGE.
2633 @return 0 on success, 1 on failure */
2634 static
2636 i_s_innodb_fill_buffer_pool(
2637 /*========================*/
2638 THD* thd, /*!< in: thread */
2639 TABLE_LIST* tables) /*!< in/out: tables to fill */
2641 int status = 0;
2642 mem_heap_t* heap;
2644 DBUG_ENTER("i_s_innodb_fill_buffer_pool");
2646 heap = mem_heap_create(10000);
2648 /* Go through each chunk of buffer pool. Currently, we only
2649 have one single chunk for each buffer pool */
2650 for (ulint n = 0; n < buf_pool->n_chunks; n++) {
2651 const buf_block_t* block;
2652 ulint n_blocks;
2653 buf_page_info_t* info_buffer;
2654 ulint num_page;
2655 ulint mem_size;
2656 ulint chunk_size;
2657 ulint num_to_process = 0;
2658 ulint block_id = 0;
2660 /* Get buffer block of the nth chunk */
2661 block = buf_get_nth_chunk_block(buf_pool, n, &chunk_size);
2662 num_page = 0;
2664 while (chunk_size > 0) {
2665 /* we cache maximum MAX_BUF_INFO_CACHED number of
2666 buffer page info */
2667 num_to_process = ut_min(chunk_size,
2668 MAX_BUF_INFO_CACHED);
2670 mem_size = num_to_process * sizeof(buf_page_info_t);
2672 /* For each chunk, we'll pre-allocate information
2673 structures to cache the page information read from
2674 the buffer pool. Doing so before obtain any mutex */
2675 info_buffer = (buf_page_info_t*) mem_heap_zalloc(
2676 heap, mem_size);
2678 /* Obtain appropriate mutexes. Since this is diagnostic
2679 buffer pool info printout, we are not required to
2680 preserve the overall consistency, so we can
2681 release mutex periodically */
2682 buf_pool_mutex_enter();
2684 /* GO through each block in the chunk */
2685 for (n_blocks = num_to_process; n_blocks--; block++) {
2686 i_s_innodb_buffer_page_get_info(
2687 &block->page, block_id,
2688 info_buffer + num_page);
2689 block_id++;
2690 num_page++;
2693 buf_pool_mutex_exit();
2695 /* Fill in information schema table with information
2696 just collected from the buffer chunk scan */
2697 status = i_s_innodb_buffer_page_fill(
2698 thd, tables, info_buffer,
2699 num_page, heap);
2701 /* If something goes wrong, break and return */
2702 if (status) {
2703 break;
2706 mem_heap_empty(heap);
2707 chunk_size -= num_to_process;
2708 num_page = 0;
2712 mem_heap_free(heap);
2714 DBUG_RETURN(status);
2717 /*******************************************************************//**
2718 Fill page information for pages in InnoDB buffer pool to the
2719 dynamic table INFORMATION_SCHEMA.INNODB_BUFFER_PAGE
2720 @return 0 on success, 1 on failure */
2721 static
2723 i_s_innodb_buffer_page_fill_table(
2724 /*==============================*/
2725 THD* thd, /*!< in: thread */
2726 TABLE_LIST* tables, /*!< in/out: tables to fill */
2727 Item* ) /*!< in: condition (ignored) */
2729 int status = 0;
2731 DBUG_ENTER("i_s_innodb_buffer_page_fill_table");
2733 /* deny access to user without PROCESS privilege */
2734 if (check_global_access(thd, PROCESS_ACL)) {
2735 DBUG_RETURN(0);
2738 /* Fetch information from pages in this buffer pool,
2739 and fill the corresponding I_S table */
2740 status = i_s_innodb_fill_buffer_pool(thd, tables);
2742 DBUG_RETURN(status);
2745 /*******************************************************************//**
2746 Bind the dynamic table INFORMATION_SCHEMA.INNODB_BUFFER_PAGE.
2747 @return 0 on success, 1 on failure */
2748 static
2750 i_s_innodb_buffer_page_init(
2751 /*========================*/
2752 void* p) /*!< in/out: table schema object */
2754 ST_SCHEMA_TABLE* schema;
2756 DBUG_ENTER("i_s_innodb_buffer_page_init");
2758 schema = reinterpret_cast<ST_SCHEMA_TABLE*>(p);
2760 schema->fields_info = i_s_innodb_buffer_page_fields_info;
2761 schema->fill_table = i_s_innodb_buffer_page_fill_table;
2763 DBUG_RETURN(0);
2766 UNIV_INTERN struct st_mysql_plugin i_s_innodb_buffer_page =
2768 /* the plugin type (a MYSQL_XXX_PLUGIN value) */
2769 /* int */
2770 STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
2772 /* pointer to type-specific plugin descriptor */
2773 /* void* */
2774 STRUCT_FLD(info, &i_s_info),
2776 /* plugin name */
2777 /* const char* */
2778 STRUCT_FLD(name, "INNODB_BUFFER_PAGE"),
2780 /* plugin author (for SHOW PLUGINS) */
2781 /* const char* */
2782 STRUCT_FLD(author, plugin_author),
2784 /* general descriptive text (for SHOW PLUGINS) */
2785 /* const char* */
2786 STRUCT_FLD(descr, "InnoDB Buffer Page Information"),
2788 /* the plugin license (PLUGIN_LICENSE_XXX) */
2789 /* int */
2790 STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
2792 /* the function to invoke when plugin is loaded */
2793 /* int (*)(void*); */
2794 STRUCT_FLD(init, i_s_innodb_buffer_page_init),
2796 /* the function to invoke when plugin is unloaded */
2797 /* int (*)(void*); */
2798 STRUCT_FLD(deinit, i_s_common_deinit),
2800 /* plugin version (for SHOW PLUGINS) */
2801 /* unsigned int */
2802 STRUCT_FLD(version, INNODB_VERSION_SHORT),
2804 /* struct st_mysql_show_var* */
2805 STRUCT_FLD(status_vars, NULL),
2807 /* struct st_mysql_sys_var** */
2808 STRUCT_FLD(system_vars, NULL),
2810 /* reserved for dependency checking */
2811 /* void* */
2812 STRUCT_FLD(__reserved1, NULL),
2815 static ST_FIELD_INFO i_s_innodb_buf_page_lru_fields_info[] =
2817 #define IDX_BUF_LRU_POS 0
2818 {STRUCT_FLD(field_name, "LRU_POSITION"),
2819 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
2820 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
2821 STRUCT_FLD(value, 0),
2822 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
2823 STRUCT_FLD(old_name, ""),
2824 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2826 #define IDX_BUF_LRU_PAGE_SPACE 1
2827 {STRUCT_FLD(field_name, "SPACE"),
2828 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
2829 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
2830 STRUCT_FLD(value, 0),
2831 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
2832 STRUCT_FLD(old_name, ""),
2833 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2835 #define IDX_BUF_LRU_PAGE_NUM 2
2836 {STRUCT_FLD(field_name, "PAGE_NUMBER"),
2837 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
2838 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
2839 STRUCT_FLD(value, 0),
2840 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
2841 STRUCT_FLD(old_name, ""),
2842 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2844 #define IDX_BUF_LRU_PAGE_TYPE 3
2845 {STRUCT_FLD(field_name, "PAGE_TYPE"),
2846 STRUCT_FLD(field_length, 64),
2847 STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
2848 STRUCT_FLD(value, 0),
2849 STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
2850 STRUCT_FLD(old_name, ""),
2851 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2853 #define IDX_BUF_LRU_PAGE_FLUSH_TYPE 4
2854 {STRUCT_FLD(field_name, "FLUSH_TYPE"),
2855 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
2856 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
2857 STRUCT_FLD(value, 0),
2858 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
2859 STRUCT_FLD(old_name, ""),
2860 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2862 #define IDX_BUF_LRU_PAGE_FIX_COUNT 5
2863 {STRUCT_FLD(field_name, "FIX_COUNT"),
2864 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
2865 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
2866 STRUCT_FLD(value, 0),
2867 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
2868 STRUCT_FLD(old_name, ""),
2869 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2871 #define IDX_BUF_LRU_PAGE_HASHED 6
2872 {STRUCT_FLD(field_name, "IS_HASHED"),
2873 STRUCT_FLD(field_length, 3),
2874 STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
2875 STRUCT_FLD(value, 0),
2876 STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
2877 STRUCT_FLD(old_name, ""),
2878 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2880 #define IDX_BUF_LRU_PAGE_NEWEST_MOD 7
2881 {STRUCT_FLD(field_name, "NEWEST_MODIFICATION"),
2882 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
2883 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
2884 STRUCT_FLD(value, 0),
2885 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
2886 STRUCT_FLD(old_name, ""),
2887 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2889 #define IDX_BUF_LRU_PAGE_OLDEST_MOD 8
2890 {STRUCT_FLD(field_name, "OLDEST_MODIFICATION"),
2891 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
2892 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
2893 STRUCT_FLD(value, 0),
2894 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
2895 STRUCT_FLD(old_name, ""),
2896 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2898 #define IDX_BUF_LRU_PAGE_ACCESS_TIME 9
2899 {STRUCT_FLD(field_name, "ACCESS_TIME"),
2900 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
2901 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
2902 STRUCT_FLD(value, 0),
2903 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
2904 STRUCT_FLD(old_name, ""),
2905 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2907 #define IDX_BUF_LRU_PAGE_TABLE_NAME 10
2908 {STRUCT_FLD(field_name, "TABLE_NAME"),
2909 STRUCT_FLD(field_length, 1024),
2910 STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
2911 STRUCT_FLD(value, 0),
2912 STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
2913 STRUCT_FLD(old_name, ""),
2914 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2916 #define IDX_BUF_LRU_PAGE_INDEX_NAME 11
2917 {STRUCT_FLD(field_name, "INDEX_NAME"),
2918 STRUCT_FLD(field_length, 1024),
2919 STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
2920 STRUCT_FLD(value, 0),
2921 STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
2922 STRUCT_FLD(old_name, ""),
2923 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2925 #define IDX_BUF_LRU_PAGE_NUM_RECS 12
2926 {STRUCT_FLD(field_name, "NUMBER_RECORDS"),
2927 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
2928 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
2929 STRUCT_FLD(value, 0),
2930 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
2931 STRUCT_FLD(old_name, ""),
2932 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2934 #define IDX_BUF_LRU_PAGE_DATA_SIZE 13
2935 {STRUCT_FLD(field_name, "DATA_SIZE"),
2936 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
2937 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
2938 STRUCT_FLD(value, 0),
2939 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
2940 STRUCT_FLD(old_name, ""),
2941 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2943 #define IDX_BUF_LRU_PAGE_ZIP_SIZE 14
2944 {STRUCT_FLD(field_name, "COMPRESSED_SIZE"),
2945 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
2946 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
2947 STRUCT_FLD(value, 0),
2948 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
2949 STRUCT_FLD(old_name, ""),
2950 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2952 #define IDX_BUF_LRU_PAGE_STATE 15
2953 {STRUCT_FLD(field_name, "COMPRESSED"),
2954 STRUCT_FLD(field_length, 3),
2955 STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
2956 STRUCT_FLD(value, 0),
2957 STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
2958 STRUCT_FLD(old_name, ""),
2959 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2961 #define IDX_BUF_LRU_PAGE_IO_FIX 16
2962 {STRUCT_FLD(field_name, "IO_FIX"),
2963 STRUCT_FLD(field_length, 64),
2964 STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
2965 STRUCT_FLD(value, 0),
2966 STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
2967 STRUCT_FLD(old_name, ""),
2968 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2970 #define IDX_BUF_LRU_PAGE_IS_OLD 17
2971 {STRUCT_FLD(field_name, "IS_OLD"),
2972 STRUCT_FLD(field_length, 3),
2973 STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
2974 STRUCT_FLD(value, 0),
2975 STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
2976 STRUCT_FLD(old_name, ""),
2977 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2979 #define IDX_BUF_LRU_PAGE_FREE_CLOCK 18
2980 {STRUCT_FLD(field_name, "FREE_PAGE_CLOCK"),
2981 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
2982 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
2983 STRUCT_FLD(value, 0),
2984 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
2985 STRUCT_FLD(old_name, ""),
2986 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2988 END_OF_ST_FIELD_INFO
2991 /*******************************************************************//**
2992 Fill Information Schema table INNODB_BUFFER_PAGE_LRU with information
2993 cached in the buf_page_info_t array
2994 @return 0 on success, 1 on failure */
2995 static
2997 i_s_innodb_buf_page_lru_fill(
2998 /*=========================*/
2999 THD* thd, /*!< in: thread */
3000 TABLE_LIST* tables, /*!< in/out: tables to fill */
3001 const buf_page_info_t* info_array, /*!< in: array cached page
3002 info */
3003 ulint num_page) /*!< in: number of page info
3004 cached */
3006 TABLE* table;
3007 Field** fields;
3008 mem_heap_t* heap;
3010 DBUG_ENTER("i_s_innodb_buf_page_lru_fill");
3012 table = tables->table;
3014 fields = table->field;
3016 heap = mem_heap_create(1000);
3018 /* Iterate through the cached array and fill the I_S table rows */
3019 for (ulint i = 0; i < num_page; i++) {
3020 const buf_page_info_t* page_info;
3021 const char* table_name;
3022 const char* index_name;
3023 const char* state_str;
3024 enum buf_page_state state;
3026 table_name = NULL;
3027 index_name = NULL;
3028 state_str = NULL;
3030 page_info = info_array + i;
3032 OK(fields[IDX_BUF_LRU_POS]->store(page_info->block_id));
3034 OK(fields[IDX_BUF_LRU_PAGE_SPACE]->store(page_info->space_id));
3036 OK(fields[IDX_BUF_LRU_PAGE_NUM]->store(page_info->page_num));
3038 OK(field_store_string(
3039 fields[IDX_BUF_LRU_PAGE_TYPE],
3040 i_s_page_type[page_info->page_type].type_str));
3042 OK(fields[IDX_BUF_LRU_PAGE_FLUSH_TYPE]->store(
3043 page_info->flush_type));
3045 OK(fields[IDX_BUF_LRU_PAGE_FIX_COUNT]->store(
3046 page_info->fix_count));
3048 if (page_info->hashed) {
3049 OK(field_store_string(
3050 fields[IDX_BUF_LRU_PAGE_HASHED], "YES"));
3051 } else {
3052 OK(field_store_string(
3053 fields[IDX_BUF_LRU_PAGE_HASHED], "NO"));
3056 OK(fields[IDX_BUF_LRU_PAGE_NEWEST_MOD]->store(
3057 page_info->newest_mod, true));
3059 OK(fields[IDX_BUF_LRU_PAGE_OLDEST_MOD]->store(
3060 page_info->oldest_mod, true));
3062 OK(fields[IDX_BUF_LRU_PAGE_ACCESS_TIME]->store(
3063 page_info->access_time));
3065 /* If this is an index page, fetch the index name
3066 and table name */
3067 if (page_info->page_type == I_S_PAGE_TYPE_INDEX) {
3068 const dict_index_t* index;
3070 mutex_enter(&dict_sys->mutex);
3071 index = dict_index_get_if_in_cache_low(
3072 page_info->index_id);
3074 /* Copy the index/table name under mutex. We
3075 do not want to hold the InnoDB mutex while
3076 filling the IS table */
3077 if (index) {
3078 const char* name_ptr = index->name;
3080 if (name_ptr[0] == TEMP_INDEX_PREFIX) {
3081 name_ptr++;
3084 index_name = mem_heap_strdup(heap, name_ptr);
3086 table_name = mem_heap_strdup(heap,
3087 index->table_name);
3090 mutex_exit(&dict_sys->mutex);
3093 OK(field_store_string(
3094 fields[IDX_BUF_LRU_PAGE_TABLE_NAME], table_name));
3096 OK(field_store_string(
3097 fields[IDX_BUF_LRU_PAGE_INDEX_NAME], index_name));
3098 OK(fields[IDX_BUF_LRU_PAGE_NUM_RECS]->store(
3099 page_info->num_recs));
3101 OK(fields[IDX_BUF_LRU_PAGE_DATA_SIZE]->store(
3102 page_info->data_size));
3104 OK(fields[IDX_BUF_LRU_PAGE_ZIP_SIZE]->store(
3105 page_info->zip_ssize ?
3106 512 << page_info->zip_ssize : 0));
3108 state = static_cast<enum buf_page_state>(page_info->page_state);
3110 switch (state) {
3111 /* Compressed page */
3112 case BUF_BLOCK_ZIP_PAGE:
3113 case BUF_BLOCK_ZIP_DIRTY:
3114 state_str = "YES";
3115 break;
3116 /* Uncompressed page */
3117 case BUF_BLOCK_FILE_PAGE:
3118 state_str = "NO";
3119 break;
3120 /* We should not see following states */
3121 case BUF_BLOCK_ZIP_FREE:
3122 case BUF_BLOCK_READY_FOR_USE:
3123 case BUF_BLOCK_NOT_USED:
3124 case BUF_BLOCK_MEMORY:
3125 case BUF_BLOCK_REMOVE_HASH:
3126 state_str = NULL;
3127 break;
3130 OK(field_store_string(fields[IDX_BUF_LRU_PAGE_STATE],
3131 state_str));
3133 switch (page_info->io_fix) {
3134 case BUF_IO_NONE:
3135 OK(field_store_string(fields[IDX_BUF_LRU_PAGE_IO_FIX],
3136 "IO_NONE"));
3137 break;
3138 case BUF_IO_READ:
3139 OK(field_store_string(fields[IDX_BUF_LRU_PAGE_IO_FIX],
3140 "IO_READ"));
3141 break;
3142 case BUF_IO_WRITE:
3143 OK(field_store_string(fields[IDX_BUF_LRU_PAGE_IO_FIX],
3144 "IO_WRITE"));
3145 break;
3148 OK(field_store_string(fields[IDX_BUF_LRU_PAGE_IS_OLD],
3149 (page_info->is_old) ? "YES" : "NO"));
3151 OK(fields[IDX_BUF_LRU_PAGE_FREE_CLOCK]->store(
3152 page_info->freed_page_clock));
3154 if (schema_table_store_record(thd, table)) {
3155 mem_heap_free(heap);
3156 DBUG_RETURN(1);
3159 mem_heap_empty(heap);
3162 mem_heap_free(heap);
3164 DBUG_RETURN(0);
3167 /*******************************************************************//**
3168 This is the function that goes through buffer pool's LRU list
3169 and fetch information to INFORMATION_SCHEMA.INNODB_BUFFER_PAGE_LRU.
3170 @return 0 on success, 1 on failure */
3171 static
3173 i_s_innodb_fill_buffer_lru(
3174 /*=======================*/
3175 THD* thd, /*!< in: thread */
3176 TABLE_LIST* tables) /*!< in/out: tables to fill */
3178 int status = 0;
3179 buf_page_info_t* info_buffer;
3180 ulint lru_pos = 0;
3181 const buf_page_t* bpage;
3182 ulint lru_len;
3184 DBUG_ENTER("i_s_innodb_fill_buffer_lru");
3186 /* Obtain buf_pool mutex before allocate info_buffer, since
3187 UT_LIST_GET_LEN(buf_pool->LRU) could change */
3188 buf_pool_mutex_enter();
3190 lru_len = UT_LIST_GET_LEN(buf_pool->LRU);
3192 /* Print error message if malloc fail */
3193 info_buffer = (buf_page_info_t*) my_malloc(
3194 lru_len * sizeof *info_buffer, MYF(MY_WME));
3196 if (!info_buffer) {
3197 status = 1;
3198 goto exit;
3201 memset(info_buffer, 0, lru_len * sizeof *info_buffer);
3203 /* Walk through Pool's LRU list and print the buffer page
3204 information */
3205 bpage = UT_LIST_GET_LAST(buf_pool->LRU);
3207 while (bpage != NULL) {
3208 /* Use the same function that collect buffer info for
3209 INNODB_BUFFER_PAGE to get buffer page info */
3210 i_s_innodb_buffer_page_get_info(bpage, lru_pos,
3211 (info_buffer + lru_pos));
3213 bpage = UT_LIST_GET_PREV(LRU, bpage);
3215 lru_pos++;
3218 ut_ad(lru_pos == lru_len);
3219 ut_ad(lru_pos == UT_LIST_GET_LEN(buf_pool->LRU));
3221 exit:
3222 buf_pool_mutex_exit();
3224 if (info_buffer) {
3225 status = i_s_innodb_buf_page_lru_fill(
3226 thd, tables, info_buffer, lru_len);
3228 my_free(info_buffer, MYF(MY_ALLOW_ZERO_PTR));
3231 DBUG_RETURN(status);
3234 /*******************************************************************//**
3235 Fill page information for pages in InnoDB buffer pool to the
3236 dynamic table INFORMATION_SCHEMA.INNODB_BUFFER_PAGE_LRU
3237 @return 0 on success, 1 on failure */
3238 static
3240 i_s_innodb_buf_page_lru_fill_table(
3241 /*===============================*/
3242 THD* thd, /*!< in: thread */
3243 TABLE_LIST* tables, /*!< in/out: tables to fill */
3244 Item* ) /*!< in: condition (ignored) */
3246 int status = 0;
3248 DBUG_ENTER("i_s_innodb_buf_page_lru_fill_table");
3250 /* deny access to any users that do not hold PROCESS_ACL */
3251 if (check_global_access(thd, PROCESS_ACL)) {
3252 DBUG_RETURN(0);
3255 /* Fetch information from pages in this buffer pool's LRU list,
3256 and fill the corresponding I_S table */
3257 status = i_s_innodb_fill_buffer_lru(thd, tables);
3259 DBUG_RETURN(status);
3262 /*******************************************************************//**
3263 Bind the dynamic table INFORMATION_SCHEMA.INNODB_BUFFER_PAGE_LRU.
3264 @return 0 on success, 1 on failure */
3265 static
3267 i_s_innodb_buffer_page_lru_init(
3268 /*============================*/
3269 void* p) /*!< in/out: table schema object */
3271 ST_SCHEMA_TABLE* schema;
3273 DBUG_ENTER("i_s_innodb_buffer_page_lru_init");
3275 schema = reinterpret_cast<ST_SCHEMA_TABLE*>(p);
3277 schema->fields_info = i_s_innodb_buf_page_lru_fields_info;
3278 schema->fill_table = i_s_innodb_buf_page_lru_fill_table;
3280 DBUG_RETURN(0);
3283 UNIV_INTERN struct st_mysql_plugin i_s_innodb_buffer_page_lru =
3285 /* the plugin type (a MYSQL_XXX_PLUGIN value) */
3286 /* int */
3287 STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
3289 /* pointer to type-specific plugin descriptor */
3290 /* void* */
3291 STRUCT_FLD(info, &i_s_info),
3293 /* plugin name */
3294 /* const char* */
3295 STRUCT_FLD(name, "INNODB_BUFFER_PAGE_LRU"),
3297 /* plugin author (for SHOW PLUGINS) */
3298 /* const char* */
3299 STRUCT_FLD(author, plugin_author),
3301 /* general descriptive text (for SHOW PLUGINS) */
3302 /* const char* */
3303 STRUCT_FLD(descr, "InnoDB Buffer Page in LRU"),
3305 /* the plugin license (PLUGIN_LICENSE_XXX) */
3306 /* int */
3307 STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
3309 /* the function to invoke when plugin is loaded */
3310 /* int (*)(void*); */
3311 STRUCT_FLD(init, i_s_innodb_buffer_page_lru_init),
3313 /* the function to invoke when plugin is unloaded */
3314 /* int (*)(void*); */
3315 STRUCT_FLD(deinit, i_s_common_deinit),
3317 /* plugin version (for SHOW PLUGINS) */
3318 /* unsigned int */
3319 STRUCT_FLD(version, INNODB_VERSION_SHORT),
3321 /* struct st_mysql_show_var* */
3322 STRUCT_FLD(status_vars, NULL),
3324 /* struct st_mysql_sys_var** */
3325 STRUCT_FLD(system_vars, NULL),
3327 /* reserved for dependency checking */
3328 /* void* */
3329 STRUCT_FLD(__reserved1, NULL),