MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
i_s.cc
Go to the documentation of this file.
1 /*****************************************************************************
2 
3 Copyright (c) 2007, 2013, Oracle and/or its affiliates. All Rights Reserved.
4 
5 This program is free software; you can redistribute it and/or modify it under
6 the terms of the GNU General Public License as published by the Free Software
7 Foundation; version 2 of the License.
8 
9 This program is distributed in the hope that it will be useful, but WITHOUT
10 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12 
13 You should have received a copy of the GNU General Public License along with
14 this program; if not, write to the Free Software Foundation, Inc.,
15 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
16 
17 *****************************************************************************/
18 
19 /**************************************************/
26 #include <mysqld_error.h>
27 #include <sql_acl.h>
28 
29 #include <m_ctype.h>
30 #include <hash.h>
31 #include <myisampack.h>
32 #include <mysys_err.h>
33 #include <my_sys.h>
34 #include "i_s.h"
35 #include <sql_plugin.h>
36 #include <mysql/innodb_priv.h>
37 
38 #include "btr0pcur.h"
39 #include "btr0types.h"
40 #include "dict0dict.h"
41 #include "dict0load.h"
42 #include "buf0buddy.h"
43 #include "buf0buf.h"
44 #include "ibuf0ibuf.h"
45 #include "dict0mem.h"
46 #include "dict0types.h"
47 #include "ha_prototypes.h"
48 #include "srv0start.h"
49 #include "trx0i_s.h"
50 #include "trx0trx.h"
51 #include "srv0mon.h"
52 #include "fut0fut.h"
53 #include "pars0pars.h"
54 #include "fts0types.h"
55 #include "fts0opt.h"
56 #include "fts0priv.h"
57 #include "btr0btr.h"
58 #include "page0zip.h"
59 
63  const char* type_str;
65  ulint type_value;
66 };
67 
69 #define I_S_PAGE_TYPE_IBUF (FIL_PAGE_TYPE_LAST + 1)
70 
73 #define I_S_PAGE_TYPE_UNKNOWN (I_S_PAGE_TYPE_IBUF + 1)
74 
77 #define I_S_PAGE_TYPE_INDEX 1
78 
80 static buf_page_desc_t i_s_page_type[] = {
81  {"ALLOCATED", FIL_PAGE_TYPE_ALLOCATED},
82  {"INDEX", FIL_PAGE_INDEX},
83  {"UNDO_LOG", FIL_PAGE_UNDO_LOG},
84  {"INODE", FIL_PAGE_INODE},
85  {"IBUF_FREE_LIST", FIL_PAGE_IBUF_FREE_LIST},
86  {"IBUF_BITMAP", FIL_PAGE_IBUF_BITMAP},
87  {"SYSTEM", FIL_PAGE_TYPE_SYS},
88  {"TRX_SYSTEM", FIL_PAGE_TYPE_TRX_SYS},
89  {"FILE_SPACE_HEADER", FIL_PAGE_TYPE_FSP_HDR},
90  {"EXTENT_DESCRIPTOR", FIL_PAGE_TYPE_XDES},
91  {"BLOB", FIL_PAGE_TYPE_BLOB},
92  {"COMPRESSED_BLOB", FIL_PAGE_TYPE_ZBLOB},
93  {"COMPRESSED_BLOB2", FIL_PAGE_TYPE_ZBLOB2},
94  {"IBUF_INDEX", I_S_PAGE_TYPE_IBUF},
95  {"UNKNOWN", I_S_PAGE_TYPE_UNKNOWN}
96 };
97 
98 /* Check if we can hold all page type in a 4 bit value */
99 #if I_S_PAGE_TYPE_UNKNOWN > 1<<4
100 # error "i_s_page_type[] is too large"
101 #endif
102 
107  ulint block_id;
108  unsigned space_id:32;
109  unsigned page_num:32;
110  unsigned access_time:32;
114  unsigned flush_type:2;
115  unsigned io_fix:2;
116  unsigned fix_count:19;
118  unsigned hashed:1;
120  unsigned is_old:1;
122  unsigned freed_page_clock:31;
127  unsigned page_type:4;
128  unsigned num_recs:UNIV_PAGE_SIZE_SHIFT_MAX-2;
130  unsigned data_size:UNIV_PAGE_SIZE_SHIFT_MAX;
132  lsn_t newest_mod;
134  lsn_t oldest_mod;
136  index_id_t index_id;
137 };
138 
140 #define MAX_BUF_INFO_CACHED 10000
141 
142 #define OK(expr) \
143  if ((expr) != 0) { \
144  DBUG_RETURN(1); \
145  }
146 
147 #define RETURN_IF_INNODB_NOT_STARTED(plugin_name) \
148 do { \
149  if (!srv_was_started) { \
150  push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, \
151  ER_CANT_FIND_SYSTEM_REC, \
152  "InnoDB: SELECTing from " \
153  "INFORMATION_SCHEMA.%s but " \
154  "the InnoDB storage engine " \
155  "is not installed", plugin_name); \
156  DBUG_RETURN(0); \
157  } \
158 } while (0)
159 
160 #if !defined __STRICT_ANSI__ && defined __GNUC__ && (__GNUC__) > 2 && \
161  !defined __INTEL_COMPILER && !defined __clang__
162 #define STRUCT_FLD(name, value) name: value
163 #else
164 #define STRUCT_FLD(name, value) value
165 #endif
166 
167 /* Don't use a static const variable here, as some C++ compilers (notably
168 HPUX aCC: HP ANSI C++ B3910B A.03.65) can't handle it. */
169 #define END_OF_ST_FIELD_INFO \
170  {STRUCT_FLD(field_name, NULL), \
171  STRUCT_FLD(field_length, 0), \
172  STRUCT_FLD(field_type, MYSQL_TYPE_NULL), \
173  STRUCT_FLD(value, 0), \
174  STRUCT_FLD(field_flags, 0), \
175  STRUCT_FLD(old_name, ""), \
176  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}
177 
178 /*
179 Use the following types mapping:
180 
181 C type ST_FIELD_INFO::field_type
182 ---------------------------------
183 long MYSQL_TYPE_LONGLONG
184 (field_length=MY_INT64_NUM_DECIMAL_DIGITS)
185 
186 long unsigned MYSQL_TYPE_LONGLONG
187 (field_length=MY_INT64_NUM_DECIMAL_DIGITS, field_flags=MY_I_S_UNSIGNED)
188 
189 char* MYSQL_TYPE_STRING
190 (field_length=n)
191 
192 float MYSQL_TYPE_FLOAT
193 (field_length=0 is ignored)
194 
195 void* MYSQL_TYPE_LONGLONG
196 (field_length=MY_INT64_NUM_DECIMAL_DIGITS, field_flags=MY_I_S_UNSIGNED)
197 
198 boolean (if else) MYSQL_TYPE_LONG
199 (field_length=1)
200 
201 time_t MYSQL_TYPE_DATETIME
202 (field_length=0 ignored)
203 ---------------------------------
204 */
205 
206 /*******************************************************************/
212 static
213 int
214 trx_i_s_common_fill_table(
215 /*======================*/
216  THD* thd,
217  TABLE_LIST* tables,
218  Item* );
220 /*******************************************************************/
223 static
224 int
225 i_s_common_deinit(
226 /*==============*/
227  void* p);
228 /*******************************************************************/
232 static
233 int
234 field_store_time_t(
235 /*===============*/
236  Field* field,
237  time_t time)
238 {
239  MYSQL_TIME my_time;
240  struct tm tm_time;
241 
242  if (time) {
243 #if 0
244  /* use this if you are sure that `variables' and `time_zone'
245  are always initialized */
246  thd->variables.time_zone->gmt_sec_to_TIME(
247  &my_time, (my_time_t) time);
248 #else
249  localtime_r(&time, &tm_time);
250  localtime_to_TIME(&my_time, &tm_time);
251  my_time.time_type = MYSQL_TIMESTAMP_DATETIME;
252 #endif
253  } else {
254  memset(&my_time, 0, sizeof(my_time));
255  }
256 
257  return(field->store_time(&my_time, MYSQL_TIMESTAMP_DATETIME));
258 }
259 
260 /*******************************************************************/
263 static
264 int
265 field_store_string(
266 /*===============*/
267  Field* field,
268  const char* str)
270 {
271  int ret;
272 
273  if (str != NULL) {
274 
275  ret = field->store(str, strlen(str),
276  system_charset_info);
277  field->set_notnull();
278  } else {
279 
280  ret = 0; /* success */
281  field->set_null();
282  }
283 
284  return(ret);
285 }
286 
287 /*******************************************************************/
291 static
292 int
293 field_store_index_name(
294 /*===================*/
295  Field* field,
297  const char* index_name)
300 {
301  int ret;
302 
303  ut_ad(index_name != NULL);
304  ut_ad(field->real_type() == MYSQL_TYPE_VARCHAR);
305 
306  /* Since TEMP_INDEX_PREFIX is not a valid UTF8, we need to convert
307  it to something else. */
308  if (index_name[0] == TEMP_INDEX_PREFIX) {
309  char buf[NAME_LEN + 1];
310  buf[0] = '?';
311  memcpy(buf + 1, index_name + 1, strlen(index_name));
312  ret = field->store(buf, strlen(buf),
313  system_charset_info);
314  } else {
315  ret = field->store(index_name, strlen(index_name),
316  system_charset_info);
317  }
318 
319  field->set_notnull();
320 
321  return(ret);
322 }
323 
324 /*******************************************************************/
328 static
329 int
330 field_store_ulint(
331 /*==============*/
332  Field* field,
333  ulint n)
334 {
335  int ret;
336 
337  if (n != ULINT_UNDEFINED) {
338 
339  ret = field->store(n);
340  field->set_notnull();
341  } else {
342 
343  ret = 0; /* success */
344  field->set_null();
345  }
346 
347  return(ret);
348 }
349 
350 /* Fields of the dynamic table INFORMATION_SCHEMA.innodb_trx */
351 static ST_FIELD_INFO innodb_trx_fields_info[] =
352 {
353 #define IDX_TRX_ID 0
354  {STRUCT_FLD(field_name, "trx_id"),
355  STRUCT_FLD(field_length, TRX_ID_MAX_LEN + 1),
356  STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
357  STRUCT_FLD(value, 0),
358  STRUCT_FLD(field_flags, 0),
359  STRUCT_FLD(old_name, ""),
360  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
361 
362 #define IDX_TRX_STATE 1
363  {STRUCT_FLD(field_name, "trx_state"),
364  STRUCT_FLD(field_length, TRX_QUE_STATE_STR_MAX_LEN + 1),
365  STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
366  STRUCT_FLD(value, 0),
367  STRUCT_FLD(field_flags, 0),
368  STRUCT_FLD(old_name, ""),
369  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
370 
371 #define IDX_TRX_STARTED 2
372  {STRUCT_FLD(field_name, "trx_started"),
373  STRUCT_FLD(field_length, 0),
374  STRUCT_FLD(field_type, MYSQL_TYPE_DATETIME),
375  STRUCT_FLD(value, 0),
376  STRUCT_FLD(field_flags, 0),
377  STRUCT_FLD(old_name, ""),
378  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
379 
380 #define IDX_TRX_REQUESTED_LOCK_ID 3
381  {STRUCT_FLD(field_name, "trx_requested_lock_id"),
382  STRUCT_FLD(field_length, TRX_I_S_LOCK_ID_MAX_LEN + 1),
383  STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
384  STRUCT_FLD(value, 0),
385  STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
386  STRUCT_FLD(old_name, ""),
387  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
388 
389 #define IDX_TRX_WAIT_STARTED 4
390  {STRUCT_FLD(field_name, "trx_wait_started"),
391  STRUCT_FLD(field_length, 0),
392  STRUCT_FLD(field_type, MYSQL_TYPE_DATETIME),
393  STRUCT_FLD(value, 0),
394  STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
395  STRUCT_FLD(old_name, ""),
396  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
397 
398 #define IDX_TRX_WEIGHT 5
399  {STRUCT_FLD(field_name, "trx_weight"),
400  STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
401  STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
402  STRUCT_FLD(value, 0),
403  STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
404  STRUCT_FLD(old_name, ""),
405  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
406 
407 #define IDX_TRX_MYSQL_THREAD_ID 6
408  {STRUCT_FLD(field_name, "trx_mysql_thread_id"),
409  STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
410  STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
411  STRUCT_FLD(value, 0),
412  STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
413  STRUCT_FLD(old_name, ""),
414  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
415 
416 #define IDX_TRX_QUERY 7
417  {STRUCT_FLD(field_name, "trx_query"),
418  STRUCT_FLD(field_length, TRX_I_S_TRX_QUERY_MAX_LEN),
419  STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
420  STRUCT_FLD(value, 0),
421  STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
422  STRUCT_FLD(old_name, ""),
423  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
424 
425 #define IDX_TRX_OPERATION_STATE 8
426  {STRUCT_FLD(field_name, "trx_operation_state"),
427  STRUCT_FLD(field_length, TRX_I_S_TRX_OP_STATE_MAX_LEN),
428  STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
429  STRUCT_FLD(value, 0),
430  STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
431  STRUCT_FLD(old_name, ""),
432  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
433 
434 #define IDX_TRX_TABLES_IN_USE 9
435  {STRUCT_FLD(field_name, "trx_tables_in_use"),
436  STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
437  STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
438  STRUCT_FLD(value, 0),
439  STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
440  STRUCT_FLD(old_name, ""),
441  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
442 
443 #define IDX_TRX_TABLES_LOCKED 10
444  {STRUCT_FLD(field_name, "trx_tables_locked"),
445  STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
446  STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
447  STRUCT_FLD(value, 0),
448  STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
449  STRUCT_FLD(old_name, ""),
450  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
451 
452 #define IDX_TRX_LOCK_STRUCTS 11
453  {STRUCT_FLD(field_name, "trx_lock_structs"),
454  STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
455  STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
456  STRUCT_FLD(value, 0),
457  STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
458  STRUCT_FLD(old_name, ""),
459  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
460 
461 #define IDX_TRX_LOCK_MEMORY_BYTES 12
462  {STRUCT_FLD(field_name, "trx_lock_memory_bytes"),
463  STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
464  STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
465  STRUCT_FLD(value, 0),
466  STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
467  STRUCT_FLD(old_name, ""),
468  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
469 
470 #define IDX_TRX_ROWS_LOCKED 13
471  {STRUCT_FLD(field_name, "trx_rows_locked"),
472  STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
473  STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
474  STRUCT_FLD(value, 0),
475  STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
476  STRUCT_FLD(old_name, ""),
477  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
478 
479 #define IDX_TRX_ROWS_MODIFIED 14
480  {STRUCT_FLD(field_name, "trx_rows_modified"),
481  STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
482  STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
483  STRUCT_FLD(value, 0),
484  STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
485  STRUCT_FLD(old_name, ""),
486  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
487 
488 #define IDX_TRX_CONNCURRENCY_TICKETS 15
489  {STRUCT_FLD(field_name, "trx_concurrency_tickets"),
490  STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
491  STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
492  STRUCT_FLD(value, 0),
493  STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
494  STRUCT_FLD(old_name, ""),
495  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
496 
497 #define IDX_TRX_ISOLATION_LEVEL 16
498  {STRUCT_FLD(field_name, "trx_isolation_level"),
499  STRUCT_FLD(field_length, TRX_I_S_TRX_ISOLATION_LEVEL_MAX_LEN),
500  STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
501  STRUCT_FLD(value, 0),
502  STRUCT_FLD(field_flags, 0),
503  STRUCT_FLD(old_name, ""),
504  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
505 
506 #define IDX_TRX_UNIQUE_CHECKS 17
507  {STRUCT_FLD(field_name, "trx_unique_checks"),
508  STRUCT_FLD(field_length, 1),
509  STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
510  STRUCT_FLD(value, 1),
511  STRUCT_FLD(field_flags, 0),
512  STRUCT_FLD(old_name, ""),
513  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
514 
515 #define IDX_TRX_FOREIGN_KEY_CHECKS 18
516  {STRUCT_FLD(field_name, "trx_foreign_key_checks"),
517  STRUCT_FLD(field_length, 1),
518  STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
519  STRUCT_FLD(value, 1),
520  STRUCT_FLD(field_flags, 0),
521  STRUCT_FLD(old_name, ""),
522  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
523 
524 #define IDX_TRX_LAST_FOREIGN_KEY_ERROR 19
525  {STRUCT_FLD(field_name, "trx_last_foreign_key_error"),
526  STRUCT_FLD(field_length, TRX_I_S_TRX_FK_ERROR_MAX_LEN),
527  STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
528  STRUCT_FLD(value, 0),
529  STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
530  STRUCT_FLD(old_name, ""),
531  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
532 
533 #define IDX_TRX_ADAPTIVE_HASH_LATCHED 20
534  {STRUCT_FLD(field_name, "trx_adaptive_hash_latched"),
535  STRUCT_FLD(field_length, 1),
536  STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
537  STRUCT_FLD(value, 0),
538  STRUCT_FLD(field_flags, 0),
539  STRUCT_FLD(old_name, ""),
540  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
541 
542 #define IDX_TRX_ADAPTIVE_HASH_TIMEOUT 21
543  {STRUCT_FLD(field_name, "trx_adaptive_hash_timeout"),
544  STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
545  STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
546  STRUCT_FLD(value, 0),
547  STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
548  STRUCT_FLD(old_name, ""),
549  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
550 
551 #define IDX_TRX_READ_ONLY 22
552  {STRUCT_FLD(field_name, "trx_is_read_only"),
553  STRUCT_FLD(field_length, 1),
554  STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
555  STRUCT_FLD(value, 0),
556  STRUCT_FLD(field_flags, 0),
557  STRUCT_FLD(old_name, ""),
558  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
559 
560 #define IDX_TRX_AUTOCOMMIT_NON_LOCKING 23
561  {STRUCT_FLD(field_name, "trx_autocommit_non_locking"),
562  STRUCT_FLD(field_length, 1),
563  STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
564  STRUCT_FLD(value, 0),
565  STRUCT_FLD(field_flags, 0),
566  STRUCT_FLD(old_name, ""),
567  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
568 
569  END_OF_ST_FIELD_INFO
570 };
571 
572 /*******************************************************************/
576 static
577 int
578 fill_innodb_trx_from_cache(
579 /*=======================*/
580  trx_i_s_cache_t* cache,
581  THD* thd,
583  TABLE* table)
584 {
585  Field** fields;
586  ulint rows_num;
587  char lock_id[TRX_I_S_LOCK_ID_MAX_LEN + 1];
588  ulint i;
589 
590  DBUG_ENTER("fill_innodb_trx_from_cache");
591 
592  fields = table->field;
593 
594  rows_num = trx_i_s_cache_get_rows_used(cache,
596 
597  for (i = 0; i < rows_num; i++) {
598 
599  i_s_trx_row_t* row;
600  char trx_id[TRX_ID_MAX_LEN + 1];
601 
602  row = (i_s_trx_row_t*)
604  cache, I_S_INNODB_TRX, i);
605 
606  /* trx_id */
607  ut_snprintf(trx_id, sizeof(trx_id), TRX_ID_FMT, row->trx_id);
608  OK(field_store_string(fields[IDX_TRX_ID], trx_id));
609 
610  /* trx_state */
611  OK(field_store_string(fields[IDX_TRX_STATE],
612  row->trx_state));
613 
614  /* trx_started */
615  OK(field_store_time_t(fields[IDX_TRX_STARTED],
616  (time_t) row->trx_started));
617 
618  /* trx_requested_lock_id */
619  /* trx_wait_started */
620  if (row->trx_wait_started != 0) {
621 
622  OK(field_store_string(
623  fields[IDX_TRX_REQUESTED_LOCK_ID],
625  row->requested_lock_row,
626  lock_id, sizeof(lock_id))));
627  /* field_store_string() sets it no notnull */
628 
629  OK(field_store_time_t(
630  fields[IDX_TRX_WAIT_STARTED],
631  (time_t) row->trx_wait_started));
632  fields[IDX_TRX_WAIT_STARTED]->set_notnull();
633  } else {
634 
635  fields[IDX_TRX_REQUESTED_LOCK_ID]->set_null();
636  fields[IDX_TRX_WAIT_STARTED]->set_null();
637  }
638 
639  /* trx_weight */
640  OK(fields[IDX_TRX_WEIGHT]->store((longlong) row->trx_weight,
641  true));
642 
643  /* trx_mysql_thread_id */
644  OK(fields[IDX_TRX_MYSQL_THREAD_ID]->store(
645  row->trx_mysql_thread_id));
646 
647  /* trx_query */
648  if (row->trx_query) {
649  /* store will do appropriate character set
650  conversion check */
651  fields[IDX_TRX_QUERY]->store(
652  row->trx_query, strlen(row->trx_query),
653  row->trx_query_cs);
654  fields[IDX_TRX_QUERY]->set_notnull();
655  } else {
656  fields[IDX_TRX_QUERY]->set_null();
657  }
658 
659  /* trx_operation_state */
660  OK(field_store_string(fields[IDX_TRX_OPERATION_STATE],
661  row->trx_operation_state));
662 
663  /* trx_tables_in_use */
664  OK(fields[IDX_TRX_TABLES_IN_USE]->store(
665  (longlong) row->trx_tables_in_use, true));
666 
667  /* trx_tables_locked */
668  OK(fields[IDX_TRX_TABLES_LOCKED]->store(
669  (longlong) row->trx_tables_locked, true));
670 
671  /* trx_lock_structs */
672  OK(fields[IDX_TRX_LOCK_STRUCTS]->store(
673  (longlong) row->trx_lock_structs, true));
674 
675  /* trx_lock_memory_bytes */
676  OK(fields[IDX_TRX_LOCK_MEMORY_BYTES]->store(
677  (longlong) row->trx_lock_memory_bytes, true));
678 
679  /* trx_rows_locked */
680  OK(fields[IDX_TRX_ROWS_LOCKED]->store(
681  (longlong) row->trx_rows_locked, true));
682 
683  /* trx_rows_modified */
684  OK(fields[IDX_TRX_ROWS_MODIFIED]->store(
685  (longlong) row->trx_rows_modified, true));
686 
687  /* trx_concurrency_tickets */
688  OK(fields[IDX_TRX_CONNCURRENCY_TICKETS]->store(
689  (longlong) row->trx_concurrency_tickets, true));
690 
691  /* trx_isolation_level */
692  OK(field_store_string(fields[IDX_TRX_ISOLATION_LEVEL],
693  row->trx_isolation_level));
694 
695  /* trx_unique_checks */
696  OK(fields[IDX_TRX_UNIQUE_CHECKS]->store(
697  row->trx_unique_checks));
698 
699  /* trx_foreign_key_checks */
700  OK(fields[IDX_TRX_FOREIGN_KEY_CHECKS]->store(
701  row->trx_foreign_key_checks));
702 
703  /* trx_last_foreign_key_error */
704  OK(field_store_string(fields[IDX_TRX_LAST_FOREIGN_KEY_ERROR],
705  row->trx_foreign_key_error));
706 
707  /* trx_adaptive_hash_latched */
708  OK(fields[IDX_TRX_ADAPTIVE_HASH_LATCHED]->store(
709  row->trx_has_search_latch));
710 
711  /* trx_adaptive_hash_timeout */
712  OK(fields[IDX_TRX_ADAPTIVE_HASH_TIMEOUT]->store(
713  (longlong) row->trx_search_latch_timeout, true));
714 
715  /* trx_is_read_only*/
716  OK(fields[IDX_TRX_READ_ONLY]->store(
717  (long) row->trx_is_read_only, true));
718 
719  /* trx_is_autocommit_non_locking */
720  OK(fields[IDX_TRX_AUTOCOMMIT_NON_LOCKING]->store(
721  (long) row->trx_is_autocommit_non_locking,
722  true));
723 
724  OK(schema_table_store_record(thd, table));
725  }
726 
727  DBUG_RETURN(0);
728 }
729 
730 /*******************************************************************/
733 static
734 int
735 innodb_trx_init(
736 /*============*/
737  void* p)
738 {
739  ST_SCHEMA_TABLE* schema;
740 
741  DBUG_ENTER("innodb_trx_init");
742 
743  schema = (ST_SCHEMA_TABLE*) p;
744 
745  schema->fields_info = innodb_trx_fields_info;
746  schema->fill_table = trx_i_s_common_fill_table;
747 
748  DBUG_RETURN(0);
749 }
750 
751 static struct st_mysql_information_schema i_s_info =
752 {
753  MYSQL_INFORMATION_SCHEMA_INTERFACE_VERSION
754 };
755 
756 UNIV_INTERN struct st_mysql_plugin i_s_innodb_trx =
757 {
758  /* the plugin type (a MYSQL_XXX_PLUGIN value) */
759  /* int */
760  STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
761 
762  /* pointer to type-specific plugin descriptor */
763  /* void* */
764  STRUCT_FLD(info, &i_s_info),
765 
766  /* plugin name */
767  /* const char* */
768  STRUCT_FLD(name, "INNODB_TRX"),
769 
770  /* plugin author (for SHOW PLUGINS) */
771  /* const char* */
772  STRUCT_FLD(author, plugin_author),
773 
774  /* general descriptive text (for SHOW PLUGINS) */
775  /* const char* */
776  STRUCT_FLD(descr, "InnoDB transactions"),
777 
778  /* the plugin license (PLUGIN_LICENSE_XXX) */
779  /* int */
780  STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
781 
782  /* the function to invoke when plugin is loaded */
783  /* int (*)(void*); */
784  STRUCT_FLD(init, innodb_trx_init),
785 
786  /* the function to invoke when plugin is unloaded */
787  /* int (*)(void*); */
788  STRUCT_FLD(deinit, i_s_common_deinit),
789 
790  /* plugin version (for SHOW PLUGINS) */
791  /* unsigned int */
792  STRUCT_FLD(version, INNODB_VERSION_SHORT),
793 
794  /* struct st_mysql_show_var* */
795  STRUCT_FLD(status_vars, NULL),
796 
797  /* struct st_mysql_sys_var** */
798  STRUCT_FLD(system_vars, NULL),
799 
800  /* reserved for dependency checking */
801  /* void* */
802  STRUCT_FLD(__reserved1, NULL),
803 
804  /* Plugin flags */
805  /* unsigned long */
806  STRUCT_FLD(flags, 0UL),
807 };
808 
809 /* Fields of the dynamic table INFORMATION_SCHEMA.innodb_locks */
810 static ST_FIELD_INFO innodb_locks_fields_info[] =
811 {
812 #define IDX_LOCK_ID 0
813  {STRUCT_FLD(field_name, "lock_id"),
814  STRUCT_FLD(field_length, TRX_I_S_LOCK_ID_MAX_LEN + 1),
815  STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
816  STRUCT_FLD(value, 0),
817  STRUCT_FLD(field_flags, 0),
818  STRUCT_FLD(old_name, ""),
819  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
820 
821 #define IDX_LOCK_TRX_ID 1
822  {STRUCT_FLD(field_name, "lock_trx_id"),
823  STRUCT_FLD(field_length, TRX_ID_MAX_LEN + 1),
824  STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
825  STRUCT_FLD(value, 0),
826  STRUCT_FLD(field_flags, 0),
827  STRUCT_FLD(old_name, ""),
828  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
829 
830 #define IDX_LOCK_MODE 2
831  {STRUCT_FLD(field_name, "lock_mode"),
832  /* S[,GAP] X[,GAP] IS[,GAP] IX[,GAP] AUTO_INC UNKNOWN */
833  STRUCT_FLD(field_length, 32),
834  STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
835  STRUCT_FLD(value, 0),
836  STRUCT_FLD(field_flags, 0),
837  STRUCT_FLD(old_name, ""),
838  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
839 
840 #define IDX_LOCK_TYPE 3
841  {STRUCT_FLD(field_name, "lock_type"),
842  STRUCT_FLD(field_length, 32 /* RECORD|TABLE|UNKNOWN */),
843  STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
844  STRUCT_FLD(value, 0),
845  STRUCT_FLD(field_flags, 0),
846  STRUCT_FLD(old_name, ""),
847  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
848 
849 #define IDX_LOCK_TABLE 4
850  {STRUCT_FLD(field_name, "lock_table"),
851  STRUCT_FLD(field_length, 1024),
852  STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
853  STRUCT_FLD(value, 0),
854  STRUCT_FLD(field_flags, 0),
855  STRUCT_FLD(old_name, ""),
856  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
857 
858 #define IDX_LOCK_INDEX 5
859  {STRUCT_FLD(field_name, "lock_index"),
860  STRUCT_FLD(field_length, 1024),
861  STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
862  STRUCT_FLD(value, 0),
863  STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
864  STRUCT_FLD(old_name, ""),
865  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
866 
867 #define IDX_LOCK_SPACE 6
868  {STRUCT_FLD(field_name, "lock_space"),
869  STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
870  STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
871  STRUCT_FLD(value, 0),
872  STRUCT_FLD(field_flags, MY_I_S_UNSIGNED | MY_I_S_MAYBE_NULL),
873  STRUCT_FLD(old_name, ""),
874  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
875 
876 #define IDX_LOCK_PAGE 7
877  {STRUCT_FLD(field_name, "lock_page"),
878  STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
879  STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
880  STRUCT_FLD(value, 0),
881  STRUCT_FLD(field_flags, MY_I_S_UNSIGNED | MY_I_S_MAYBE_NULL),
882  STRUCT_FLD(old_name, ""),
883  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
884 
885 #define IDX_LOCK_REC 8
886  {STRUCT_FLD(field_name, "lock_rec"),
887  STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
888  STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
889  STRUCT_FLD(value, 0),
890  STRUCT_FLD(field_flags, MY_I_S_UNSIGNED | MY_I_S_MAYBE_NULL),
891  STRUCT_FLD(old_name, ""),
892  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
893 
894 #define IDX_LOCK_DATA 9
895  {STRUCT_FLD(field_name, "lock_data"),
896  STRUCT_FLD(field_length, TRX_I_S_LOCK_DATA_MAX_LEN),
897  STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
898  STRUCT_FLD(value, 0),
899  STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
900  STRUCT_FLD(old_name, ""),
901  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
902 
903  END_OF_ST_FIELD_INFO
904 };
905 
906 /*******************************************************************/
910 static
911 int
912 fill_innodb_locks_from_cache(
913 /*=========================*/
914  trx_i_s_cache_t* cache,
915  THD* thd,
916  TABLE* table)
917 {
918  Field** fields;
919  ulint rows_num;
920  char lock_id[TRX_I_S_LOCK_ID_MAX_LEN + 1];
921  ulint i;
922 
923  DBUG_ENTER("fill_innodb_locks_from_cache");
924 
925  fields = table->field;
926 
927  rows_num = trx_i_s_cache_get_rows_used(cache,
929 
930  for (i = 0; i < rows_num; i++) {
931 
932  i_s_locks_row_t* row;
933  char buf[MAX_FULL_NAME_LEN + 1];
934  const char* bufend;
935 
936  char lock_trx_id[TRX_ID_MAX_LEN + 1];
937 
938  row = (i_s_locks_row_t*)
940  cache, I_S_INNODB_LOCKS, i);
941 
942  /* lock_id */
943  trx_i_s_create_lock_id(row, lock_id, sizeof(lock_id));
944  OK(field_store_string(fields[IDX_LOCK_ID],
945  lock_id));
946 
947  /* lock_trx_id */
948  ut_snprintf(lock_trx_id, sizeof(lock_trx_id),
949  TRX_ID_FMT, row->lock_trx_id);
950  OK(field_store_string(fields[IDX_LOCK_TRX_ID], lock_trx_id));
951 
952  /* lock_mode */
953  OK(field_store_string(fields[IDX_LOCK_MODE],
954  row->lock_mode));
955 
956  /* lock_type */
957  OK(field_store_string(fields[IDX_LOCK_TYPE],
958  row->lock_type));
959 
960  /* lock_table */
961  bufend = innobase_convert_name(buf, sizeof(buf),
962  row->lock_table,
963  strlen(row->lock_table),
964  thd, TRUE);
965  OK(fields[IDX_LOCK_TABLE]->store(buf, bufend - buf,
966  system_charset_info));
967 
968  /* lock_index */
969  if (row->lock_index != NULL) {
970  OK(field_store_index_name(fields[IDX_LOCK_INDEX],
971  row->lock_index));
972  } else {
973  fields[IDX_LOCK_INDEX]->set_null();
974  }
975 
976  /* lock_space */
977  OK(field_store_ulint(fields[IDX_LOCK_SPACE],
978  row->lock_space));
979 
980  /* lock_page */
981  OK(field_store_ulint(fields[IDX_LOCK_PAGE],
982  row->lock_page));
983 
984  /* lock_rec */
985  OK(field_store_ulint(fields[IDX_LOCK_REC],
986  row->lock_rec));
987 
988  /* lock_data */
989  OK(field_store_string(fields[IDX_LOCK_DATA],
990  row->lock_data));
991 
992  OK(schema_table_store_record(thd, table));
993  }
994 
995  DBUG_RETURN(0);
996 }
997 
998 /*******************************************************************/
1001 static
1002 int
1003 innodb_locks_init(
1004 /*==============*/
1005  void* p)
1006 {
1007  ST_SCHEMA_TABLE* schema;
1008 
1009  DBUG_ENTER("innodb_locks_init");
1010 
1011  schema = (ST_SCHEMA_TABLE*) p;
1012 
1013  schema->fields_info = innodb_locks_fields_info;
1014  schema->fill_table = trx_i_s_common_fill_table;
1015 
1016  DBUG_RETURN(0);
1017 }
1018 
1019 UNIV_INTERN struct st_mysql_plugin i_s_innodb_locks =
1020 {
1021  /* the plugin type (a MYSQL_XXX_PLUGIN value) */
1022  /* int */
1023  STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
1024 
1025  /* pointer to type-specific plugin descriptor */
1026  /* void* */
1027  STRUCT_FLD(info, &i_s_info),
1028 
1029  /* plugin name */
1030  /* const char* */
1031  STRUCT_FLD(name, "INNODB_LOCKS"),
1032 
1033  /* plugin author (for SHOW PLUGINS) */
1034  /* const char* */
1035  STRUCT_FLD(author, plugin_author),
1036 
1037  /* general descriptive text (for SHOW PLUGINS) */
1038  /* const char* */
1039  STRUCT_FLD(descr, "InnoDB conflicting locks"),
1040 
1041  /* the plugin license (PLUGIN_LICENSE_XXX) */
1042  /* int */
1043  STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
1044 
1045  /* the function to invoke when plugin is loaded */
1046  /* int (*)(void*); */
1047  STRUCT_FLD(init, innodb_locks_init),
1048 
1049  /* the function to invoke when plugin is unloaded */
1050  /* int (*)(void*); */
1051  STRUCT_FLD(deinit, i_s_common_deinit),
1052 
1053  /* plugin version (for SHOW PLUGINS) */
1054  /* unsigned int */
1055  STRUCT_FLD(version, INNODB_VERSION_SHORT),
1056 
1057  /* struct st_mysql_show_var* */
1058  STRUCT_FLD(status_vars, NULL),
1059 
1060  /* struct st_mysql_sys_var** */
1061  STRUCT_FLD(system_vars, NULL),
1062 
1063  /* reserved for dependency checking */
1064  /* void* */
1065  STRUCT_FLD(__reserved1, NULL),
1066 
1067  /* Plugin flags */
1068  /* unsigned long */
1069  STRUCT_FLD(flags, 0UL),
1070 };
1071 
1072 /* Fields of the dynamic table INFORMATION_SCHEMA.innodb_lock_waits */
1073 static ST_FIELD_INFO innodb_lock_waits_fields_info[] =
1074 {
1075 #define IDX_REQUESTING_TRX_ID 0
1076  {STRUCT_FLD(field_name, "requesting_trx_id"),
1077  STRUCT_FLD(field_length, TRX_ID_MAX_LEN + 1),
1078  STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
1079  STRUCT_FLD(value, 0),
1080  STRUCT_FLD(field_flags, 0),
1081  STRUCT_FLD(old_name, ""),
1082  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1083 
1084 #define IDX_REQUESTED_LOCK_ID 1
1085  {STRUCT_FLD(field_name, "requested_lock_id"),
1086  STRUCT_FLD(field_length, TRX_I_S_LOCK_ID_MAX_LEN + 1),
1087  STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
1088  STRUCT_FLD(value, 0),
1089  STRUCT_FLD(field_flags, 0),
1090  STRUCT_FLD(old_name, ""),
1091  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1092 
1093 #define IDX_BLOCKING_TRX_ID 2
1094  {STRUCT_FLD(field_name, "blocking_trx_id"),
1095  STRUCT_FLD(field_length, TRX_ID_MAX_LEN + 1),
1096  STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
1097  STRUCT_FLD(value, 0),
1098  STRUCT_FLD(field_flags, 0),
1099  STRUCT_FLD(old_name, ""),
1100  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1101 
1102 #define IDX_BLOCKING_LOCK_ID 3
1103  {STRUCT_FLD(field_name, "blocking_lock_id"),
1104  STRUCT_FLD(field_length, TRX_I_S_LOCK_ID_MAX_LEN + 1),
1105  STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
1106  STRUCT_FLD(value, 0),
1107  STRUCT_FLD(field_flags, 0),
1108  STRUCT_FLD(old_name, ""),
1109  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1110 
1111  END_OF_ST_FIELD_INFO
1112 };
1113 
1114 /*******************************************************************/
1118 static
1119 int
1120 fill_innodb_lock_waits_from_cache(
1121 /*==============================*/
1122  trx_i_s_cache_t* cache,
1123  THD* thd,
1125  TABLE* table)
1126 {
1127  Field** fields;
1128  ulint rows_num;
1129  char requested_lock_id[TRX_I_S_LOCK_ID_MAX_LEN + 1];
1130  char blocking_lock_id[TRX_I_S_LOCK_ID_MAX_LEN + 1];
1131  ulint i;
1132 
1133  DBUG_ENTER("fill_innodb_lock_waits_from_cache");
1134 
1135  fields = table->field;
1136 
1137  rows_num = trx_i_s_cache_get_rows_used(cache,
1139 
1140  for (i = 0; i < rows_num; i++) {
1141 
1142  i_s_lock_waits_row_t* row;
1143 
1144  char requesting_trx_id[TRX_ID_MAX_LEN + 1];
1145  char blocking_trx_id[TRX_ID_MAX_LEN + 1];
1146 
1147  row = (i_s_lock_waits_row_t*)
1149  cache, I_S_INNODB_LOCK_WAITS, i);
1150 
1151  /* requesting_trx_id */
1152  ut_snprintf(requesting_trx_id, sizeof(requesting_trx_id),
1154  OK(field_store_string(fields[IDX_REQUESTING_TRX_ID],
1155  requesting_trx_id));
1156 
1157  /* requested_lock_id */
1158  OK(field_store_string(
1159  fields[IDX_REQUESTED_LOCK_ID],
1161  row->requested_lock_row,
1162  requested_lock_id,
1163  sizeof(requested_lock_id))));
1164 
1165  /* blocking_trx_id */
1166  ut_snprintf(blocking_trx_id, sizeof(blocking_trx_id),
1168  OK(field_store_string(fields[IDX_BLOCKING_TRX_ID],
1169  blocking_trx_id));
1170 
1171  /* blocking_lock_id */
1172  OK(field_store_string(
1173  fields[IDX_BLOCKING_LOCK_ID],
1175  row->blocking_lock_row,
1176  blocking_lock_id,
1177  sizeof(blocking_lock_id))));
1178 
1179  OK(schema_table_store_record(thd, table));
1180  }
1181 
1182  DBUG_RETURN(0);
1183 }
1184 
1185 /*******************************************************************/
1188 static
1189 int
1190 innodb_lock_waits_init(
1191 /*===================*/
1192  void* p)
1193 {
1194  ST_SCHEMA_TABLE* schema;
1195 
1196  DBUG_ENTER("innodb_lock_waits_init");
1197 
1198  schema = (ST_SCHEMA_TABLE*) p;
1199 
1200  schema->fields_info = innodb_lock_waits_fields_info;
1201  schema->fill_table = trx_i_s_common_fill_table;
1202 
1203  DBUG_RETURN(0);
1204 }
1205 
1206 UNIV_INTERN struct st_mysql_plugin i_s_innodb_lock_waits =
1207 {
1208  /* the plugin type (a MYSQL_XXX_PLUGIN value) */
1209  /* int */
1210  STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
1211 
1212  /* pointer to type-specific plugin descriptor */
1213  /* void* */
1214  STRUCT_FLD(info, &i_s_info),
1215 
1216  /* plugin name */
1217  /* const char* */
1218  STRUCT_FLD(name, "INNODB_LOCK_WAITS"),
1219 
1220  /* plugin author (for SHOW PLUGINS) */
1221  /* const char* */
1222  STRUCT_FLD(author, plugin_author),
1223 
1224  /* general descriptive text (for SHOW PLUGINS) */
1225  /* const char* */
1226  STRUCT_FLD(descr, "InnoDB which lock is blocking which"),
1227 
1228  /* the plugin license (PLUGIN_LICENSE_XXX) */
1229  /* int */
1230  STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
1231 
1232  /* the function to invoke when plugin is loaded */
1233  /* int (*)(void*); */
1234  STRUCT_FLD(init, innodb_lock_waits_init),
1235 
1236  /* the function to invoke when plugin is unloaded */
1237  /* int (*)(void*); */
1238  STRUCT_FLD(deinit, i_s_common_deinit),
1239 
1240  /* plugin version (for SHOW PLUGINS) */
1241  /* unsigned int */
1242  STRUCT_FLD(version, INNODB_VERSION_SHORT),
1243 
1244  /* struct st_mysql_show_var* */
1245  STRUCT_FLD(status_vars, NULL),
1246 
1247  /* struct st_mysql_sys_var** */
1248  STRUCT_FLD(system_vars, NULL),
1249 
1250  /* reserved for dependency checking */
1251  /* void* */
1252  STRUCT_FLD(__reserved1, NULL),
1253 
1254  /* Plugin flags */
1255  /* unsigned long */
1256  STRUCT_FLD(flags, 0UL),
1257 };
1258 
1259 /*******************************************************************/
1265 static
1266 int
1267 trx_i_s_common_fill_table(
1268 /*======================*/
1269  THD* thd,
1270  TABLE_LIST* tables,
1271  Item* )
1272 {
1273  const char* table_name;
1274  int ret;
1275  trx_i_s_cache_t* cache;
1276 
1277  DBUG_ENTER("trx_i_s_common_fill_table");
1278 
1279  /* deny access to non-superusers */
1280  if (check_global_access(thd, PROCESS_ACL)) {
1281 
1282  DBUG_RETURN(0);
1283  }
1284 
1285  /* minimize the number of places where global variables are
1286  referenced */
1287  cache = trx_i_s_cache;
1288 
1289  /* which table we have to fill? */
1290  table_name = tables->schema_table_name;
1291  /* or table_name = tables->schema_table->table_name; */
1292 
1293  RETURN_IF_INNODB_NOT_STARTED(table_name);
1294 
1295  /* update the cache */
1298  trx_i_s_cache_end_write(cache);
1299 
1300  if (trx_i_s_cache_is_truncated(cache)) {
1301 
1302  /* XXX show warning to user if possible */
1303  fprintf(stderr, "Warning: data in %s truncated due to "
1304  "memory limit of %d bytes\n", table_name,
1306  }
1307 
1308  ret = 0;
1309 
1310  trx_i_s_cache_start_read(cache);
1311 
1312  if (innobase_strcasecmp(table_name, "innodb_trx") == 0) {
1313 
1314  if (fill_innodb_trx_from_cache(
1315  cache, thd, tables->table) != 0) {
1316 
1317  ret = 1;
1318  }
1319 
1320  } else if (innobase_strcasecmp(table_name, "innodb_locks") == 0) {
1321 
1322  if (fill_innodb_locks_from_cache(
1323  cache, thd, tables->table) != 0) {
1324 
1325  ret = 1;
1326  }
1327 
1328  } else if (innobase_strcasecmp(table_name, "innodb_lock_waits") == 0) {
1329 
1330  if (fill_innodb_lock_waits_from_cache(
1331  cache, thd, tables->table) != 0) {
1332 
1333  ret = 1;
1334  }
1335 
1336  } else {
1337 
1338  /* huh! what happened!? */
1339  fprintf(stderr,
1340  "InnoDB: trx_i_s_common_fill_table() was "
1341  "called to fill unknown table: %s.\n"
1342  "This function only knows how to fill "
1343  "innodb_trx, innodb_locks and "
1344  "innodb_lock_waits tables.\n", table_name);
1345 
1346  ret = 1;
1347  }
1348 
1349  trx_i_s_cache_end_read(cache);
1350 
1351 #if 0
1352  DBUG_RETURN(ret);
1353 #else
1354  /* if this function returns something else than 0 then a
1355  deadlock occurs between the mysqld server and mysql client,
1356  see http://bugs.mysql.com/29900 ; when that bug is resolved
1357  we can enable the DBUG_RETURN(ret) above */
1358  ret++; // silence a gcc46 warning
1359  DBUG_RETURN(0);
1360 #endif
1361 }
1362 
1363 /* Fields of the dynamic table information_schema.innodb_cmp. */
1364 static ST_FIELD_INFO i_s_cmp_fields_info[] =
1365 {
1366  {STRUCT_FLD(field_name, "page_size"),
1367  STRUCT_FLD(field_length, 5),
1368  STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
1369  STRUCT_FLD(value, 0),
1370  STRUCT_FLD(field_flags, 0),
1371  STRUCT_FLD(old_name, "Compressed Page Size"),
1372  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1373 
1374  {STRUCT_FLD(field_name, "compress_ops"),
1375  STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS),
1376  STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
1377  STRUCT_FLD(value, 0),
1378  STRUCT_FLD(field_flags, 0),
1379  STRUCT_FLD(old_name, "Total Number of Compressions"),
1380  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1381 
1382  {STRUCT_FLD(field_name, "compress_ops_ok"),
1383  STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS),
1384  STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
1385  STRUCT_FLD(value, 0),
1386  STRUCT_FLD(field_flags, 0),
1387  STRUCT_FLD(old_name, "Total Number of"
1388  " Successful Compressions"),
1389  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1390 
1391  {STRUCT_FLD(field_name, "compress_time"),
1392  STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS),
1393  STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
1394  STRUCT_FLD(value, 0),
1395  STRUCT_FLD(field_flags, 0),
1396  STRUCT_FLD(old_name, "Total Duration of Compressions,"
1397  " in Seconds"),
1398  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1399 
1400  {STRUCT_FLD(field_name, "uncompress_ops"),
1401  STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS),
1402  STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
1403  STRUCT_FLD(value, 0),
1404  STRUCT_FLD(field_flags, 0),
1405  STRUCT_FLD(old_name, "Total Number of Decompressions"),
1406  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1407 
1408  {STRUCT_FLD(field_name, "uncompress_time"),
1409  STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS),
1410  STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
1411  STRUCT_FLD(value, 0),
1412  STRUCT_FLD(field_flags, 0),
1413  STRUCT_FLD(old_name, "Total Duration of Decompressions,"
1414  " in Seconds"),
1415  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1416 
1417  END_OF_ST_FIELD_INFO
1418 };
1419 
1420 
1421 /*******************************************************************/
1425 static
1426 int
1427 i_s_cmp_fill_low(
1428 /*=============*/
1429  THD* thd,
1430  TABLE_LIST* tables,
1431  Item* ,
1432  ibool reset)
1433 {
1434  TABLE* table = (TABLE*) tables->table;
1435  int status = 0;
1436 
1437  DBUG_ENTER("i_s_cmp_fill_low");
1438 
1439  /* deny access to non-superusers */
1440  if (check_global_access(thd, PROCESS_ACL)) {
1441 
1442  DBUG_RETURN(0);
1443  }
1444 
1445  RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name);
1446 
1447  for (uint i = 0; i < PAGE_ZIP_SSIZE_MAX; i++) {
1448  page_zip_stat_t* zip_stat = &page_zip_stat[i];
1449 
1450  table->field[0]->store(UNIV_ZIP_SIZE_MIN << i);
1451 
1452  /* The cumulated counts are not protected by any
1453  mutex. Thus, some operation in page0zip.cc could
1454  increment a counter between the time we read it and
1455  clear it. We could introduce mutex protection, but it
1456  could cause a measureable performance hit in
1457  page0zip.cc. */
1458  table->field[1]->store(zip_stat->compressed);
1459  table->field[2]->store(zip_stat->compressed_ok);
1460  table->field[3]->store(
1461  (ulong) (zip_stat->compressed_usec / 1000000));
1462  table->field[4]->store(zip_stat->decompressed);
1463  table->field[5]->store(
1464  (ulong) (zip_stat->decompressed_usec / 1000000));
1465 
1466  if (reset) {
1467  memset(zip_stat, 0, sizeof *zip_stat);
1468  }
1469 
1470  if (schema_table_store_record(thd, table)) {
1471  status = 1;
1472  break;
1473  }
1474  }
1475 
1476  DBUG_RETURN(status);
1477 }
1478 
1479 /*******************************************************************/
1482 static
1483 int
1484 i_s_cmp_fill(
1485 /*=========*/
1486  THD* thd,
1487  TABLE_LIST* tables,
1488  Item* cond)
1489 {
1490  return(i_s_cmp_fill_low(thd, tables, cond, FALSE));
1491 }
1492 
1493 /*******************************************************************/
1496 static
1497 int
1498 i_s_cmp_reset_fill(
1499 /*===============*/
1500  THD* thd,
1501  TABLE_LIST* tables,
1502  Item* cond)
1503 {
1504  return(i_s_cmp_fill_low(thd, tables, cond, TRUE));
1505 }
1506 
1507 /*******************************************************************/
1510 static
1511 int
1512 i_s_cmp_init(
1513 /*=========*/
1514  void* p)
1515 {
1516  DBUG_ENTER("i_s_cmp_init");
1517  ST_SCHEMA_TABLE* schema = (ST_SCHEMA_TABLE*) p;
1518 
1519  schema->fields_info = i_s_cmp_fields_info;
1520  schema->fill_table = i_s_cmp_fill;
1521 
1522  DBUG_RETURN(0);
1523 }
1524 
1525 /*******************************************************************/
1528 static
1529 int
1530 i_s_cmp_reset_init(
1531 /*===============*/
1532  void* p)
1533 {
1534  DBUG_ENTER("i_s_cmp_reset_init");
1535  ST_SCHEMA_TABLE* schema = (ST_SCHEMA_TABLE*) p;
1536 
1537  schema->fields_info = i_s_cmp_fields_info;
1538  schema->fill_table = i_s_cmp_reset_fill;
1539 
1540  DBUG_RETURN(0);
1541 }
1542 
1543 UNIV_INTERN struct st_mysql_plugin i_s_innodb_cmp =
1544 {
1545  /* the plugin type (a MYSQL_XXX_PLUGIN value) */
1546  /* int */
1547  STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
1548 
1549  /* pointer to type-specific plugin descriptor */
1550  /* void* */
1551  STRUCT_FLD(info, &i_s_info),
1552 
1553  /* plugin name */
1554  /* const char* */
1555  STRUCT_FLD(name, "INNODB_CMP"),
1556 
1557  /* plugin author (for SHOW PLUGINS) */
1558  /* const char* */
1559  STRUCT_FLD(author, plugin_author),
1560 
1561  /* general descriptive text (for SHOW PLUGINS) */
1562  /* const char* */
1563  STRUCT_FLD(descr, "Statistics for the InnoDB compression"),
1564 
1565  /* the plugin license (PLUGIN_LICENSE_XXX) */
1566  /* int */
1567  STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
1568 
1569  /* the function to invoke when plugin is loaded */
1570  /* int (*)(void*); */
1571  STRUCT_FLD(init, i_s_cmp_init),
1572 
1573  /* the function to invoke when plugin is unloaded */
1574  /* int (*)(void*); */
1575  STRUCT_FLD(deinit, i_s_common_deinit),
1576 
1577  /* plugin version (for SHOW PLUGINS) */
1578  /* unsigned int */
1579  STRUCT_FLD(version, INNODB_VERSION_SHORT),
1580 
1581  /* struct st_mysql_show_var* */
1582  STRUCT_FLD(status_vars, NULL),
1583 
1584  /* struct st_mysql_sys_var** */
1585  STRUCT_FLD(system_vars, NULL),
1586 
1587  /* reserved for dependency checking */
1588  /* void* */
1589  STRUCT_FLD(__reserved1, NULL),
1590 
1591  /* Plugin flags */
1592  /* unsigned long */
1593  STRUCT_FLD(flags, 0UL),
1594 };
1595 
1596 UNIV_INTERN struct st_mysql_plugin i_s_innodb_cmp_reset =
1597 {
1598  /* the plugin type (a MYSQL_XXX_PLUGIN value) */
1599  /* int */
1600  STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
1601 
1602  /* pointer to type-specific plugin descriptor */
1603  /* void* */
1604  STRUCT_FLD(info, &i_s_info),
1605 
1606  /* plugin name */
1607  /* const char* */
1608  STRUCT_FLD(name, "INNODB_CMP_RESET"),
1609 
1610  /* plugin author (for SHOW PLUGINS) */
1611  /* const char* */
1612  STRUCT_FLD(author, plugin_author),
1613 
1614  /* general descriptive text (for SHOW PLUGINS) */
1615  /* const char* */
1616  STRUCT_FLD(descr, "Statistics for the InnoDB compression;"
1617  " reset cumulated counts"),
1618 
1619  /* the plugin license (PLUGIN_LICENSE_XXX) */
1620  /* int */
1621  STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
1622 
1623  /* the function to invoke when plugin is loaded */
1624  /* int (*)(void*); */
1625  STRUCT_FLD(init, i_s_cmp_reset_init),
1626 
1627  /* the function to invoke when plugin is unloaded */
1628  /* int (*)(void*); */
1629  STRUCT_FLD(deinit, i_s_common_deinit),
1630 
1631  /* plugin version (for SHOW PLUGINS) */
1632  /* unsigned int */
1633  STRUCT_FLD(version, INNODB_VERSION_SHORT),
1634 
1635  /* struct st_mysql_show_var* */
1636  STRUCT_FLD(status_vars, NULL),
1637 
1638  /* struct st_mysql_sys_var** */
1639  STRUCT_FLD(system_vars, NULL),
1640 
1641  /* reserved for dependency checking */
1642  /* void* */
1643  STRUCT_FLD(__reserved1, NULL),
1644 
1645  /* Plugin flags */
1646  /* unsigned long */
1647  STRUCT_FLD(flags, 0UL),
1648 };
1649 
1650 /* Fields of the dynamic tables
1651 information_schema.innodb_cmp_per_index and
1652 information_schema.innodb_cmp_per_index_reset. */
1653 static ST_FIELD_INFO i_s_cmp_per_index_fields_info[] =
1654 {
1655 #define IDX_DATABASE_NAME 0
1656  {STRUCT_FLD(field_name, "database_name"),
1657  STRUCT_FLD(field_length, 192),
1658  STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
1659  STRUCT_FLD(value, 0),
1660  STRUCT_FLD(field_flags, 0),
1661  STRUCT_FLD(old_name, ""),
1662  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1663 
1664 #define IDX_TABLE_NAME 1
1665  {STRUCT_FLD(field_name, "table_name"),
1666  STRUCT_FLD(field_length, 192),
1667  STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
1668  STRUCT_FLD(value, 0),
1669  STRUCT_FLD(field_flags, 0),
1670  STRUCT_FLD(old_name, ""),
1671  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1672 
1673 #define IDX_INDEX_NAME 2
1674  {STRUCT_FLD(field_name, "index_name"),
1675  STRUCT_FLD(field_length, 192),
1676  STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
1677  STRUCT_FLD(value, 0),
1678  STRUCT_FLD(field_flags, 0),
1679  STRUCT_FLD(old_name, ""),
1680  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1681 
1682 #define IDX_COMPRESS_OPS 3
1683  {STRUCT_FLD(field_name, "compress_ops"),
1684  STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS),
1685  STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
1686  STRUCT_FLD(value, 0),
1687  STRUCT_FLD(field_flags, 0),
1688  STRUCT_FLD(old_name, ""),
1689  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1690 
1691 #define IDX_COMPRESS_OPS_OK 4
1692  {STRUCT_FLD(field_name, "compress_ops_ok"),
1693  STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS),
1694  STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
1695  STRUCT_FLD(value, 0),
1696  STRUCT_FLD(field_flags, 0),
1697  STRUCT_FLD(old_name, ""),
1698  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1699 
1700 #define IDX_COMPRESS_TIME 5
1701  {STRUCT_FLD(field_name, "compress_time"),
1702  STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS),
1703  STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
1704  STRUCT_FLD(value, 0),
1705  STRUCT_FLD(field_flags, 0),
1706  STRUCT_FLD(old_name, ""),
1707  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1708 
1709 #define IDX_UNCOMPRESS_OPS 6
1710  {STRUCT_FLD(field_name, "uncompress_ops"),
1711  STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS),
1712  STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
1713  STRUCT_FLD(value, 0),
1714  STRUCT_FLD(field_flags, 0),
1715  STRUCT_FLD(old_name, ""),
1716  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1717 
1718 #define IDX_UNCOMPRESS_TIME 7
1719  {STRUCT_FLD(field_name, "uncompress_time"),
1720  STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS),
1721  STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
1722  STRUCT_FLD(value, 0),
1723  STRUCT_FLD(field_flags, 0),
1724  STRUCT_FLD(old_name, ""),
1725  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1726 
1727  END_OF_ST_FIELD_INFO
1728 };
1729 
1730 /*******************************************************************/
1735 static
1736 int
1737 i_s_cmp_per_index_fill_low(
1738 /*=======================*/
1739  THD* thd,
1740  TABLE_LIST* tables,
1741  Item* ,
1742  ibool reset)
1743 {
1744  TABLE* table = tables->table;
1745  Field** fields = table->field;
1746  int status = 0;
1747 
1748  DBUG_ENTER("i_s_cmp_per_index_fill_low");
1749 
1750  /* deny access to non-superusers */
1751  if (check_global_access(thd, PROCESS_ACL)) {
1752 
1753  DBUG_RETURN(0);
1754  }
1755 
1756  RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name);
1757 
1758  /* Create a snapshot of the stats so we do not bump into lock
1759  order violations with dict_sys->mutex below. */
1760  mutex_enter(&page_zip_stat_per_index_mutex);
1762  mutex_exit(&page_zip_stat_per_index_mutex);
1763 
1764  mutex_enter(&dict_sys->mutex);
1765 
1766  page_zip_stat_per_index_t::iterator iter;
1767  ulint i;
1768 
1769  for (iter = snap.begin(), i = 0; iter != snap.end(); iter++, i++) {
1770 
1771  char name[192];
1773 
1774  if (index != NULL) {
1775  char db_utf8[MAX_DB_UTF8_LEN];
1776  char table_utf8[MAX_TABLE_UTF8_LEN];
1777 
1778  dict_fs2utf8(index->table_name,
1779  db_utf8, sizeof(db_utf8),
1780  table_utf8, sizeof(table_utf8));
1781 
1782  field_store_string(fields[IDX_DATABASE_NAME], db_utf8);
1783  field_store_string(fields[IDX_TABLE_NAME], table_utf8);
1784  field_store_index_name(fields[IDX_INDEX_NAME],
1785  index->name);
1786  } else {
1787  /* index not found */
1788  ut_snprintf(name, sizeof(name),
1789  "index_id:" IB_ID_FMT, iter->first);
1790  field_store_string(fields[IDX_DATABASE_NAME],
1791  "unknown");
1792  field_store_string(fields[IDX_TABLE_NAME],
1793  "unknown");
1794  field_store_string(fields[IDX_INDEX_NAME],
1795  name);
1796  }
1797 
1798  fields[IDX_COMPRESS_OPS]->store(
1799  iter->second.compressed);
1800 
1801  fields[IDX_COMPRESS_OPS_OK]->store(
1802  iter->second.compressed_ok);
1803 
1804  fields[IDX_COMPRESS_TIME]->store(
1805  (long) (iter->second.compressed_usec / 1000000));
1806 
1807  fields[IDX_UNCOMPRESS_OPS]->store(
1808  iter->second.decompressed);
1809 
1810  fields[IDX_UNCOMPRESS_TIME]->store(
1811  (long) (iter->second.decompressed_usec / 1000000));
1812 
1813  if (schema_table_store_record(thd, table)) {
1814  status = 1;
1815  break;
1816  }
1817 
1818  /* Release and reacquire the dict mutex to allow other
1819  threads to proceed. This could eventually result in the
1820  contents of INFORMATION_SCHEMA.innodb_cmp_per_index being
1821  inconsistent, but it is an acceptable compromise. */
1822  if (i % 1000 == 0) {
1823  mutex_exit(&dict_sys->mutex);
1824  mutex_enter(&dict_sys->mutex);
1825  }
1826  }
1827 
1828  mutex_exit(&dict_sys->mutex);
1829 
1830  if (reset) {
1832  }
1833 
1834  DBUG_RETURN(status);
1835 }
1836 
1837 /*******************************************************************/
1840 static
1841 int
1842 i_s_cmp_per_index_fill(
1843 /*===================*/
1844  THD* thd,
1845  TABLE_LIST* tables,
1846  Item* cond)
1847 {
1848  return(i_s_cmp_per_index_fill_low(thd, tables, cond, FALSE));
1849 }
1850 
1851 /*******************************************************************/
1854 static
1855 int
1856 i_s_cmp_per_index_reset_fill(
1857 /*=========================*/
1858  THD* thd,
1859  TABLE_LIST* tables,
1860  Item* cond)
1861 {
1862  return(i_s_cmp_per_index_fill_low(thd, tables, cond, TRUE));
1863 }
1864 
1865 /*******************************************************************/
1868 static
1869 int
1870 i_s_cmp_per_index_init(
1871 /*===================*/
1872  void* p)
1873 {
1874  DBUG_ENTER("i_s_cmp_init");
1875  ST_SCHEMA_TABLE* schema = (ST_SCHEMA_TABLE*) p;
1876 
1877  schema->fields_info = i_s_cmp_per_index_fields_info;
1878  schema->fill_table = i_s_cmp_per_index_fill;
1879 
1880  DBUG_RETURN(0);
1881 }
1882 
1883 /*******************************************************************/
1886 static
1887 int
1888 i_s_cmp_per_index_reset_init(
1889 /*=========================*/
1890  void* p)
1891 {
1892  DBUG_ENTER("i_s_cmp_reset_init");
1893  ST_SCHEMA_TABLE* schema = (ST_SCHEMA_TABLE*) p;
1894 
1895  schema->fields_info = i_s_cmp_per_index_fields_info;
1896  schema->fill_table = i_s_cmp_per_index_reset_fill;
1897 
1898  DBUG_RETURN(0);
1899 }
1900 
1901 UNIV_INTERN struct st_mysql_plugin i_s_innodb_cmp_per_index =
1902 {
1903  /* the plugin type (a MYSQL_XXX_PLUGIN value) */
1904  /* int */
1905  STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
1906 
1907  /* pointer to type-specific plugin descriptor */
1908  /* void* */
1909  STRUCT_FLD(info, &i_s_info),
1910 
1911  /* plugin name */
1912  /* const char* */
1913  STRUCT_FLD(name, "INNODB_CMP_PER_INDEX"),
1914 
1915  /* plugin author (for SHOW PLUGINS) */
1916  /* const char* */
1917  STRUCT_FLD(author, plugin_author),
1918 
1919  /* general descriptive text (for SHOW PLUGINS) */
1920  /* const char* */
1921  STRUCT_FLD(descr, "Statistics for the InnoDB compression (per index)"),
1922 
1923  /* the plugin license (PLUGIN_LICENSE_XXX) */
1924  /* int */
1925  STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
1926 
1927  /* the function to invoke when plugin is loaded */
1928  /* int (*)(void*); */
1929  STRUCT_FLD(init, i_s_cmp_per_index_init),
1930 
1931  /* the function to invoke when plugin is unloaded */
1932  /* int (*)(void*); */
1933  STRUCT_FLD(deinit, i_s_common_deinit),
1934 
1935  /* plugin version (for SHOW PLUGINS) */
1936  /* unsigned int */
1937  STRUCT_FLD(version, INNODB_VERSION_SHORT),
1938 
1939  /* struct st_mysql_show_var* */
1940  STRUCT_FLD(status_vars, NULL),
1941 
1942  /* struct st_mysql_sys_var** */
1943  STRUCT_FLD(system_vars, NULL),
1944 
1945  /* reserved for dependency checking */
1946  /* void* */
1947  STRUCT_FLD(__reserved1, NULL),
1948 
1949  /* Plugin flags */
1950  /* unsigned long */
1951  STRUCT_FLD(flags, 0UL),
1952 };
1953 
1954 UNIV_INTERN struct st_mysql_plugin i_s_innodb_cmp_per_index_reset =
1955 {
1956  /* the plugin type (a MYSQL_XXX_PLUGIN value) */
1957  /* int */
1958  STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
1959 
1960  /* pointer to type-specific plugin descriptor */
1961  /* void* */
1962  STRUCT_FLD(info, &i_s_info),
1963 
1964  /* plugin name */
1965  /* const char* */
1966  STRUCT_FLD(name, "INNODB_CMP_PER_INDEX_RESET"),
1967 
1968  /* plugin author (for SHOW PLUGINS) */
1969  /* const char* */
1970  STRUCT_FLD(author, plugin_author),
1971 
1972  /* general descriptive text (for SHOW PLUGINS) */
1973  /* const char* */
1974  STRUCT_FLD(descr, "Statistics for the InnoDB compression (per index);"
1975  " reset cumulated counts"),
1976 
1977  /* the plugin license (PLUGIN_LICENSE_XXX) */
1978  /* int */
1979  STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
1980 
1981  /* the function to invoke when plugin is loaded */
1982  /* int (*)(void*); */
1983  STRUCT_FLD(init, i_s_cmp_per_index_reset_init),
1984 
1985  /* the function to invoke when plugin is unloaded */
1986  /* int (*)(void*); */
1987  STRUCT_FLD(deinit, i_s_common_deinit),
1988 
1989  /* plugin version (for SHOW PLUGINS) */
1990  /* unsigned int */
1991  STRUCT_FLD(version, INNODB_VERSION_SHORT),
1992 
1993  /* struct st_mysql_show_var* */
1994  STRUCT_FLD(status_vars, NULL),
1995 
1996  /* struct st_mysql_sys_var** */
1997  STRUCT_FLD(system_vars, NULL),
1998 
1999  /* reserved for dependency checking */
2000  /* void* */
2001  STRUCT_FLD(__reserved1, NULL),
2002 
2003  /* Plugin flags */
2004  /* unsigned long */
2005  STRUCT_FLD(flags, 0UL),
2006 };
2007 
2008 /* Fields of the dynamic table information_schema.innodb_cmpmem. */
2009 static ST_FIELD_INFO i_s_cmpmem_fields_info[] =
2010 {
2011  {STRUCT_FLD(field_name, "page_size"),
2012  STRUCT_FLD(field_length, 5),
2013  STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
2014  STRUCT_FLD(value, 0),
2015  STRUCT_FLD(field_flags, 0),
2016  STRUCT_FLD(old_name, "Buddy Block Size"),
2017  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2018 
2019  {STRUCT_FLD(field_name, "buffer_pool_instance"),
2020  STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS),
2021  STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
2022  STRUCT_FLD(value, 0),
2023  STRUCT_FLD(field_flags, 0),
2024  STRUCT_FLD(old_name, "Buffer Pool Id"),
2025  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2026 
2027  {STRUCT_FLD(field_name, "pages_used"),
2028  STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS),
2029  STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
2030  STRUCT_FLD(value, 0),
2031  STRUCT_FLD(field_flags, 0),
2032  STRUCT_FLD(old_name, "Currently in Use"),
2033  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2034 
2035  {STRUCT_FLD(field_name, "pages_free"),
2036  STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS),
2037  STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
2038  STRUCT_FLD(value, 0),
2039  STRUCT_FLD(field_flags, 0),
2040  STRUCT_FLD(old_name, "Currently Available"),
2041  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2042 
2043  {STRUCT_FLD(field_name, "relocation_ops"),
2044  STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
2045  STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
2046  STRUCT_FLD(value, 0),
2047  STRUCT_FLD(field_flags, 0),
2048  STRUCT_FLD(old_name, "Total Number of Relocations"),
2049  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2050 
2051  {STRUCT_FLD(field_name, "relocation_time"),
2052  STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS),
2053  STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
2054  STRUCT_FLD(value, 0),
2055  STRUCT_FLD(field_flags, 0),
2056  STRUCT_FLD(old_name, "Total Duration of Relocations,"
2057  " in Seconds"),
2058  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2059 
2060  END_OF_ST_FIELD_INFO
2061 };
2062 
2063 /*******************************************************************/
2067 static
2068 int
2069 i_s_cmpmem_fill_low(
2070 /*================*/
2071  THD* thd,
2072  TABLE_LIST* tables,
2073  Item* ,
2074  ibool reset)
2075 {
2076  int status = 0;
2077  TABLE* table = (TABLE*) tables->table;
2078 
2079  DBUG_ENTER("i_s_cmpmem_fill_low");
2080 
2081  /* deny access to non-superusers */
2082  if (check_global_access(thd, PROCESS_ACL)) {
2083 
2084  DBUG_RETURN(0);
2085  }
2086 
2087  RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name);
2088 
2089  for (ulint i = 0; i < srv_buf_pool_instances; i++) {
2090  buf_pool_t* buf_pool;
2091 
2092  status = 0;
2093 
2094  buf_pool = buf_pool_from_array(i);
2095 
2096  buf_pool_mutex_enter(buf_pool);
2097 
2098  for (uint x = 0; x <= BUF_BUDDY_SIZES; x++) {
2099  buf_buddy_stat_t* buddy_stat;
2100 
2101  buddy_stat = &buf_pool->buddy_stat[x];
2102 
2103  table->field[0]->store(BUF_BUDDY_LOW << x);
2104  table->field[1]->store(i);
2105  table->field[2]->store(buddy_stat->used);
2106  table->field[3]->store(UNIV_LIKELY(x < BUF_BUDDY_SIZES)
2107  ? UT_LIST_GET_LEN(buf_pool->zip_free[x])
2108  : 0);
2109  table->field[4]->store(
2110  (longlong) buddy_stat->relocated, true);
2111  table->field[5]->store(
2112  (ulong) (buddy_stat->relocated_usec / 1000000));
2113 
2114  if (reset) {
2115  /* This is protected by buf_pool->mutex. */
2116  buddy_stat->relocated = 0;
2117  buddy_stat->relocated_usec = 0;
2118  }
2119 
2120  if (schema_table_store_record(thd, table)) {
2121  status = 1;
2122  break;
2123  }
2124  }
2125 
2126  buf_pool_mutex_exit(buf_pool);
2127 
2128  if (status) {
2129  break;
2130  }
2131  }
2132 
2133  DBUG_RETURN(status);
2134 }
2135 
2136 /*******************************************************************/
2139 static
2140 int
2141 i_s_cmpmem_fill(
2142 /*============*/
2143  THD* thd,
2144  TABLE_LIST* tables,
2145  Item* cond)
2146 {
2147  return(i_s_cmpmem_fill_low(thd, tables, cond, FALSE));
2148 }
2149 
2150 /*******************************************************************/
2153 static
2154 int
2155 i_s_cmpmem_reset_fill(
2156 /*==================*/
2157  THD* thd,
2158  TABLE_LIST* tables,
2159  Item* cond)
2160 {
2161  return(i_s_cmpmem_fill_low(thd, tables, cond, TRUE));
2162 }
2163 
2164 /*******************************************************************/
2167 static
2168 int
2169 i_s_cmpmem_init(
2170 /*============*/
2171  void* p)
2172 {
2173  DBUG_ENTER("i_s_cmpmem_init");
2174  ST_SCHEMA_TABLE* schema = (ST_SCHEMA_TABLE*) p;
2175 
2176  schema->fields_info = i_s_cmpmem_fields_info;
2177  schema->fill_table = i_s_cmpmem_fill;
2178 
2179  DBUG_RETURN(0);
2180 }
2181 
2182 /*******************************************************************/
2185 static
2186 int
2187 i_s_cmpmem_reset_init(
2188 /*==================*/
2189  void* p)
2190 {
2191  DBUG_ENTER("i_s_cmpmem_reset_init");
2192  ST_SCHEMA_TABLE* schema = (ST_SCHEMA_TABLE*) p;
2193 
2194  schema->fields_info = i_s_cmpmem_fields_info;
2195  schema->fill_table = i_s_cmpmem_reset_fill;
2196 
2197  DBUG_RETURN(0);
2198 }
2199 
2200 UNIV_INTERN struct st_mysql_plugin i_s_innodb_cmpmem =
2201 {
2202  /* the plugin type (a MYSQL_XXX_PLUGIN value) */
2203  /* int */
2204  STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
2205 
2206  /* pointer to type-specific plugin descriptor */
2207  /* void* */
2208  STRUCT_FLD(info, &i_s_info),
2209 
2210  /* plugin name */
2211  /* const char* */
2212  STRUCT_FLD(name, "INNODB_CMPMEM"),
2213 
2214  /* plugin author (for SHOW PLUGINS) */
2215  /* const char* */
2216  STRUCT_FLD(author, plugin_author),
2217 
2218  /* general descriptive text (for SHOW PLUGINS) */
2219  /* const char* */
2220  STRUCT_FLD(descr, "Statistics for the InnoDB compressed buffer pool"),
2221 
2222  /* the plugin license (PLUGIN_LICENSE_XXX) */
2223  /* int */
2224  STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
2225 
2226  /* the function to invoke when plugin is loaded */
2227  /* int (*)(void*); */
2228  STRUCT_FLD(init, i_s_cmpmem_init),
2229 
2230  /* the function to invoke when plugin is unloaded */
2231  /* int (*)(void*); */
2232  STRUCT_FLD(deinit, i_s_common_deinit),
2233 
2234  /* plugin version (for SHOW PLUGINS) */
2235  /* unsigned int */
2236  STRUCT_FLD(version, INNODB_VERSION_SHORT),
2237 
2238  /* struct st_mysql_show_var* */
2239  STRUCT_FLD(status_vars, NULL),
2240 
2241  /* struct st_mysql_sys_var** */
2242  STRUCT_FLD(system_vars, NULL),
2243 
2244  /* reserved for dependency checking */
2245  /* void* */
2246  STRUCT_FLD(__reserved1, NULL),
2247 
2248  /* Plugin flags */
2249  /* unsigned long */
2250  STRUCT_FLD(flags, 0UL),
2251 };
2252 
2253 UNIV_INTERN struct st_mysql_plugin i_s_innodb_cmpmem_reset =
2254 {
2255  /* the plugin type (a MYSQL_XXX_PLUGIN value) */
2256  /* int */
2257  STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
2258 
2259  /* pointer to type-specific plugin descriptor */
2260  /* void* */
2261  STRUCT_FLD(info, &i_s_info),
2262 
2263  /* plugin name */
2264  /* const char* */
2265  STRUCT_FLD(name, "INNODB_CMPMEM_RESET"),
2266 
2267  /* plugin author (for SHOW PLUGINS) */
2268  /* const char* */
2269  STRUCT_FLD(author, plugin_author),
2270 
2271  /* general descriptive text (for SHOW PLUGINS) */
2272  /* const char* */
2273  STRUCT_FLD(descr, "Statistics for the InnoDB compressed buffer pool;"
2274  " reset cumulated counts"),
2275 
2276  /* the plugin license (PLUGIN_LICENSE_XXX) */
2277  /* int */
2278  STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
2279 
2280  /* the function to invoke when plugin is loaded */
2281  /* int (*)(void*); */
2282  STRUCT_FLD(init, i_s_cmpmem_reset_init),
2283 
2284  /* the function to invoke when plugin is unloaded */
2285  /* int (*)(void*); */
2286  STRUCT_FLD(deinit, i_s_common_deinit),
2287 
2288  /* plugin version (for SHOW PLUGINS) */
2289  /* unsigned int */
2290  STRUCT_FLD(version, INNODB_VERSION_SHORT),
2291 
2292  /* struct st_mysql_show_var* */
2293  STRUCT_FLD(status_vars, NULL),
2294 
2295  /* struct st_mysql_sys_var** */
2296  STRUCT_FLD(system_vars, NULL),
2297 
2298  /* reserved for dependency checking */
2299  /* void* */
2300  STRUCT_FLD(__reserved1, NULL),
2301 
2302  /* Plugin flags */
2303  /* unsigned long */
2304  STRUCT_FLD(flags, 0UL),
2305 };
2306 
2307 /* Fields of the dynamic table INFORMATION_SCHEMA.innodb_metrics */
2308 static ST_FIELD_INFO innodb_metrics_fields_info[] =
2309 {
2310 #define METRIC_NAME 0
2311  {STRUCT_FLD(field_name, "NAME"),
2312  STRUCT_FLD(field_length, NAME_LEN + 1),
2313  STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
2314  STRUCT_FLD(value, 0),
2315  STRUCT_FLD(field_flags, 0),
2316  STRUCT_FLD(old_name, ""),
2317  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2318 
2319 #define METRIC_SUBSYS 1
2320  {STRUCT_FLD(field_name, "SUBSYSTEM"),
2321  STRUCT_FLD(field_length, NAME_LEN + 1),
2322  STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
2323  STRUCT_FLD(value, 0),
2324  STRUCT_FLD(field_flags, 0),
2325  STRUCT_FLD(old_name, ""),
2326  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2327 
2328 #define METRIC_VALUE_START 2
2329  {STRUCT_FLD(field_name, "COUNT"),
2330  STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
2331  STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
2332  STRUCT_FLD(value, 0),
2333  STRUCT_FLD(field_flags, 0),
2334  STRUCT_FLD(old_name, ""),
2335  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2336 
2337 #define METRIC_MAX_VALUE_START 3
2338  {STRUCT_FLD(field_name, "MAX_COUNT"),
2339  STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
2340  STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
2341  STRUCT_FLD(value, 0),
2342  STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
2343  STRUCT_FLD(old_name, ""),
2344  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2345 
2346 #define METRIC_MIN_VALUE_START 4
2347  {STRUCT_FLD(field_name, "MIN_COUNT"),
2348  STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
2349  STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
2350  STRUCT_FLD(value, 0),
2351  STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
2352  STRUCT_FLD(old_name, ""),
2353  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2354 
2355 #define METRIC_AVG_VALUE_START 5
2356  {STRUCT_FLD(field_name, "AVG_COUNT"),
2357  STRUCT_FLD(field_length, MAX_FLOAT_STR_LENGTH),
2358  STRUCT_FLD(field_type, MYSQL_TYPE_FLOAT),
2359  STRUCT_FLD(value, 0),
2360  STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
2361  STRUCT_FLD(old_name, ""),
2362  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2363 
2364 #define METRIC_VALUE_RESET 6
2365  {STRUCT_FLD(field_name, "COUNT_RESET"),
2366  STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
2367  STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
2368  STRUCT_FLD(value, 0),
2369  STRUCT_FLD(field_flags, 0),
2370  STRUCT_FLD(old_name, ""),
2371  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2372 
2373 #define METRIC_MAX_VALUE_RESET 7
2374  {STRUCT_FLD(field_name, "MAX_COUNT_RESET"),
2375  STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
2376  STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
2377  STRUCT_FLD(value, 0),
2378  STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
2379  STRUCT_FLD(old_name, ""),
2380  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2381 
2382 #define METRIC_MIN_VALUE_RESET 8
2383  {STRUCT_FLD(field_name, "MIN_COUNT_RESET"),
2384  STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
2385  STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
2386  STRUCT_FLD(value, 0),
2387  STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
2388  STRUCT_FLD(old_name, ""),
2389  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2390 
2391 #define METRIC_AVG_VALUE_RESET 9
2392  {STRUCT_FLD(field_name, "AVG_COUNT_RESET"),
2393  STRUCT_FLD(field_length, MAX_FLOAT_STR_LENGTH),
2394  STRUCT_FLD(field_type, MYSQL_TYPE_FLOAT),
2395  STRUCT_FLD(value, 0),
2396  STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
2397  STRUCT_FLD(old_name, ""),
2398  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2399 
2400 #define METRIC_START_TIME 10
2401  {STRUCT_FLD(field_name, "TIME_ENABLED"),
2402  STRUCT_FLD(field_length, 0),
2403  STRUCT_FLD(field_type, MYSQL_TYPE_DATETIME),
2404  STRUCT_FLD(value, 0),
2405  STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
2406  STRUCT_FLD(old_name, ""),
2407  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2408 
2409 #define METRIC_STOP_TIME 11
2410  {STRUCT_FLD(field_name, "TIME_DISABLED"),
2411  STRUCT_FLD(field_length, 0),
2412  STRUCT_FLD(field_type, MYSQL_TYPE_DATETIME),
2413  STRUCT_FLD(value, 0),
2414  STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
2415  STRUCT_FLD(old_name, ""),
2416  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2417 
2418 #define METRIC_TIME_ELAPSED 12
2419  {STRUCT_FLD(field_name, "TIME_ELAPSED"),
2420  STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
2421  STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
2422  STRUCT_FLD(value, 0),
2423  STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
2424  STRUCT_FLD(old_name, ""),
2425  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2426 
2427 #define METRIC_RESET_TIME 13
2428  {STRUCT_FLD(field_name, "TIME_RESET"),
2429  STRUCT_FLD(field_length, 0),
2430  STRUCT_FLD(field_type, MYSQL_TYPE_DATETIME),
2431  STRUCT_FLD(value, 0),
2432  STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
2433  STRUCT_FLD(old_name, ""),
2434  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2435 
2436 #define METRIC_STATUS 14
2437  {STRUCT_FLD(field_name, "STATUS"),
2438  STRUCT_FLD(field_length, NAME_LEN + 1),
2439  STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
2440  STRUCT_FLD(value, 0),
2441  STRUCT_FLD(field_flags, 0),
2442  STRUCT_FLD(old_name, ""),
2443  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2444 
2445 #define METRIC_TYPE 15
2446  {STRUCT_FLD(field_name, "TYPE"),
2447  STRUCT_FLD(field_length, NAME_LEN + 1),
2448  STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
2449  STRUCT_FLD(value, 0),
2450  STRUCT_FLD(field_flags, 0),
2451  STRUCT_FLD(old_name, ""),
2452  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2453 
2454 #define METRIC_DESC 16
2455  {STRUCT_FLD(field_name, "COMMENT"),
2456  STRUCT_FLD(field_length, NAME_LEN + 1),
2457  STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
2458  STRUCT_FLD(value, 0),
2459  STRUCT_FLD(field_flags, 0),
2460  STRUCT_FLD(old_name, ""),
2461  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2462 
2463  END_OF_ST_FIELD_INFO
2464 };
2465 
2466 /**********************************************************************/
2469 static
2470 int
2471 i_s_metrics_fill(
2472 /*=============*/
2473  THD* thd,
2474  TABLE* table_to_fill)
2475 {
2476  int count;
2477  Field** fields;
2478  double time_diff = 0;
2479  monitor_info_t* monitor_info;
2480  mon_type_t min_val;
2481  mon_type_t max_val;
2482 
2483  DBUG_ENTER("i_s_metrics_fill");
2484  fields = table_to_fill->field;
2485 
2486  for (count = 0; count < NUM_MONITOR; count++) {
2487  monitor_info = srv_mon_get_info((monitor_id_t) count);
2488 
2489  /* A good place to sanity check the Monitor ID */
2490  ut_a(count == monitor_info->monitor_id);
2491 
2492  /* If the item refers to a Module, nothing to fill,
2493  continue. */
2494  if ((monitor_info->monitor_type & MONITOR_MODULE)
2495  || (monitor_info->monitor_type & MONITOR_HIDDEN)) {
2496  continue;
2497  }
2498 
2499  /* If this is an existing "status variable", and
2500  its corresponding counter is still on, we need
2501  to calculate the result from its corresponding
2502  counter. */
2503  if (monitor_info->monitor_type & MONITOR_EXISTING
2504  && MONITOR_IS_ON(count)) {
2507  }
2508 
2509  /* Fill in counter's basic information */
2510  OK(field_store_string(fields[METRIC_NAME],
2511  monitor_info->monitor_name));
2512 
2513  OK(field_store_string(fields[METRIC_SUBSYS],
2514  monitor_info->monitor_module));
2515 
2516  OK(field_store_string(fields[METRIC_DESC],
2517  monitor_info->monitor_desc));
2518 
2519  /* Fill in counter values */
2520  OK(fields[METRIC_VALUE_RESET]->store(
2521  MONITOR_VALUE(count), FALSE));
2522 
2523  OK(fields[METRIC_VALUE_START]->store(
2524  MONITOR_VALUE_SINCE_START(count), FALSE));
2525 
2526  /* If the max value is MAX_RESERVED, counter max
2527  value has not been updated. Set the column value
2528  to NULL. */
2529  if (MONITOR_MAX_VALUE(count) == MAX_RESERVED
2530  || MONITOR_MAX_MIN_NOT_INIT(count)) {
2531  fields[METRIC_MAX_VALUE_RESET]->set_null();
2532  } else {
2533  OK(fields[METRIC_MAX_VALUE_RESET]->store(
2534  MONITOR_MAX_VALUE(count), FALSE));
2535  fields[METRIC_MAX_VALUE_RESET]->set_notnull();
2536  }
2537 
2538  /* If the min value is MAX_RESERVED, counter min
2539  value has not been updated. Set the column value
2540  to NULL. */
2541  if (MONITOR_MIN_VALUE(count) == MIN_RESERVED
2542  || MONITOR_MAX_MIN_NOT_INIT(count)) {
2543  fields[METRIC_MIN_VALUE_RESET]->set_null();
2544  } else {
2545  OK(fields[METRIC_MIN_VALUE_RESET]->store(
2546  MONITOR_MIN_VALUE(count), FALSE));
2547  fields[METRIC_MIN_VALUE_RESET]->set_notnull();
2548  }
2549 
2550  /* Calculate the max value since counter started */
2551  max_val = srv_mon_calc_max_since_start((monitor_id_t) count);
2552 
2553  if (max_val == MAX_RESERVED
2554  || MONITOR_MAX_MIN_NOT_INIT(count)) {
2555  fields[METRIC_MAX_VALUE_START]->set_null();
2556  } else {
2557  OK(fields[METRIC_MAX_VALUE_START]->store(
2558  max_val, FALSE));
2559  fields[METRIC_MAX_VALUE_START]->set_notnull();
2560  }
2561 
2562  /* Calculate the min value since counter started */
2563  min_val = srv_mon_calc_min_since_start((monitor_id_t) count);
2564 
2565  if (min_val == MIN_RESERVED
2566  || MONITOR_MAX_MIN_NOT_INIT(count)) {
2567  fields[METRIC_MIN_VALUE_START]->set_null();
2568  } else {
2569  OK(fields[METRIC_MIN_VALUE_START]->store(
2570  min_val, FALSE));
2571 
2572  fields[METRIC_MIN_VALUE_START]->set_notnull();
2573  }
2574 
2575  /* If monitor has been enabled (no matter it is disabled
2576  or not now), fill METRIC_START_TIME and METRIC_TIME_ELAPSED
2577  field */
2578  if (MONITOR_FIELD(count, mon_start_time)) {
2579  OK(field_store_time_t(fields[METRIC_START_TIME],
2580  (time_t)MONITOR_FIELD(count, mon_start_time)));
2581  fields[METRIC_START_TIME]->set_notnull();
2582 
2583  /* If monitor is enabled, the TIME_ELAPSED is the
2584  time difference between current and time when monitor
2585  is enabled. Otherwise, it is the time difference
2586  between time when monitor is enabled and time
2587  when it is disabled */
2588  if (MONITOR_IS_ON(count)) {
2589  time_diff = difftime(time(NULL),
2590  MONITOR_FIELD(count, mon_start_time));
2591  } else {
2592  time_diff = difftime(
2593  MONITOR_FIELD(count, mon_stop_time),
2594  MONITOR_FIELD(count, mon_start_time));
2595  }
2596 
2597  OK(fields[METRIC_TIME_ELAPSED]->store(
2598  time_diff));
2599  fields[METRIC_TIME_ELAPSED]->set_notnull();
2600  } else {
2601  fields[METRIC_START_TIME]->set_null();
2602  fields[METRIC_TIME_ELAPSED]->set_null();
2603  time_diff = 0;
2604  }
2605 
2606  /* Unless MONITOR__NO_AVERAGE is marked, we will need
2607  to calculate the average value. If this is a monitor set
2608  owner marked by MONITOR_SET_OWNER, divide
2609  the value by another counter (number of calls) designated
2610  by monitor_info->monitor_related_id.
2611  Otherwise average the counter value by the time between the
2612  time that the counter is enabled and time it is disabled
2613  or time it is sampled. */
2614  if (!(monitor_info->monitor_type & MONITOR_NO_AVERAGE)
2615  && (monitor_info->monitor_type & MONITOR_SET_OWNER)
2616  && monitor_info->monitor_related_id) {
2617  mon_type_t value_start
2618  = MONITOR_VALUE_SINCE_START(
2619  monitor_info->monitor_related_id);
2620 
2621  if (value_start) {
2622  OK(fields[METRIC_AVG_VALUE_START]->store(
2623  MONITOR_VALUE_SINCE_START(count)
2624  / value_start, FALSE));
2625 
2626  fields[METRIC_AVG_VALUE_START]->set_notnull();
2627  } else {
2628  fields[METRIC_AVG_VALUE_START]->set_null();
2629  }
2630 
2631  if (MONITOR_VALUE(monitor_info->monitor_related_id)) {
2632  OK(fields[METRIC_AVG_VALUE_RESET]->store(
2633  MONITOR_VALUE(count)
2634  / MONITOR_VALUE(
2635  monitor_info->monitor_related_id),
2636  FALSE));
2637  } else {
2638  fields[METRIC_AVG_VALUE_RESET]->set_null();
2639  }
2640  } else if (!(monitor_info->monitor_type & MONITOR_NO_AVERAGE)
2641  && !(monitor_info->monitor_type
2643  if (time_diff) {
2644  OK(fields[METRIC_AVG_VALUE_START]->store(
2645  (double) MONITOR_VALUE_SINCE_START(
2646  count) / time_diff));
2647  fields[METRIC_AVG_VALUE_START]->set_notnull();
2648  } else {
2649  fields[METRIC_AVG_VALUE_START]->set_null();
2650  }
2651 
2652  if (MONITOR_FIELD(count, mon_reset_time)) {
2653  /* calculate the time difference since last
2654  reset */
2655  if (MONITOR_IS_ON(count)) {
2656  time_diff = difftime(
2657  time(NULL), MONITOR_FIELD(
2658  count, mon_reset_time));
2659  } else {
2660  time_diff = difftime(
2661  MONITOR_FIELD(count, mon_stop_time),
2662  MONITOR_FIELD(count, mon_reset_time));
2663  }
2664  } else {
2665  time_diff = 0;
2666  }
2667 
2668  if (time_diff) {
2669  OK(fields[METRIC_AVG_VALUE_RESET]->store(
2670  (double )MONITOR_VALUE(count)
2671  / time_diff));
2672  fields[METRIC_AVG_VALUE_RESET]->set_notnull();
2673  } else {
2674  fields[METRIC_AVG_VALUE_RESET]->set_null();
2675  }
2676  } else {
2677  fields[METRIC_AVG_VALUE_START]->set_null();
2678  fields[METRIC_AVG_VALUE_RESET]->set_null();
2679  }
2680 
2681 
2682  if (MONITOR_IS_ON(count)) {
2683  /* If monitor is on, the stop time will set to NULL */
2684  fields[METRIC_STOP_TIME]->set_null();
2685 
2686  /* Display latest Monitor Reset Time only if Monitor
2687  counter is on. */
2688  if (MONITOR_FIELD(count, mon_reset_time)) {
2689  OK(field_store_time_t(
2690  fields[METRIC_RESET_TIME],
2691  (time_t)MONITOR_FIELD(
2692  count, mon_reset_time)));
2693  fields[METRIC_RESET_TIME]->set_notnull();
2694  } else {
2695  fields[METRIC_RESET_TIME]->set_null();
2696  }
2697 
2698  /* Display the monitor status as "enabled" */
2699  OK(field_store_string(fields[METRIC_STATUS],
2700  "enabled"));
2701  } else {
2702  if (MONITOR_FIELD(count, mon_stop_time)) {
2703  OK(field_store_time_t(fields[METRIC_STOP_TIME],
2704  (time_t)MONITOR_FIELD(count, mon_stop_time)));
2705  fields[METRIC_STOP_TIME]->set_notnull();
2706  } else {
2707  fields[METRIC_STOP_TIME]->set_null();
2708  }
2709 
2710  fields[METRIC_RESET_TIME]->set_null();
2711 
2712  OK(field_store_string(fields[METRIC_STATUS],
2713  "disabled"));
2714  }
2715 
2716  if (monitor_info->monitor_type & MONITOR_DISPLAY_CURRENT) {
2717  OK(field_store_string(fields[METRIC_TYPE],
2718  "value"));
2719  } else if (monitor_info->monitor_type & MONITOR_EXISTING) {
2720  OK(field_store_string(fields[METRIC_TYPE],
2721  "status_counter"));
2722  } else if (monitor_info->monitor_type & MONITOR_SET_OWNER) {
2723  OK(field_store_string(fields[METRIC_TYPE],
2724  "set_owner"));
2725  } else if ( monitor_info->monitor_type & MONITOR_SET_MEMBER) {
2726  OK(field_store_string(fields[METRIC_TYPE],
2727  "set_member"));
2728  } else {
2729  OK(field_store_string(fields[METRIC_TYPE],
2730  "counter"));
2731  }
2732 
2733  OK(schema_table_store_record(thd, table_to_fill));
2734  }
2735 
2736  DBUG_RETURN(0);
2737 }
2738 
2739 /*******************************************************************/
2742 static
2743 int
2744 i_s_metrics_fill_table(
2745 /*===================*/
2746  THD* thd,
2747  TABLE_LIST* tables,
2748  Item* )
2749 {
2750  DBUG_ENTER("i_s_metrics_fill_table");
2751 
2752  /* deny access to non-superusers */
2753  if (check_global_access(thd, PROCESS_ACL)) {
2754  DBUG_RETURN(0);
2755  }
2756 
2757  i_s_metrics_fill(thd, tables->table);
2758 
2759  DBUG_RETURN(0);
2760 }
2761 /*******************************************************************/
2764 static
2765 int
2766 innodb_metrics_init(
2767 /*================*/
2768  void* p)
2769 {
2770  ST_SCHEMA_TABLE* schema;
2771 
2772  DBUG_ENTER("innodb_metrics_init");
2773 
2774  schema = (ST_SCHEMA_TABLE*) p;
2775 
2776  schema->fields_info = innodb_metrics_fields_info;
2777  schema->fill_table = i_s_metrics_fill_table;
2778 
2779  DBUG_RETURN(0);
2780 }
2781 
2782 UNIV_INTERN struct st_mysql_plugin i_s_innodb_metrics =
2783 {
2784  /* the plugin type (a MYSQL_XXX_PLUGIN value) */
2785  /* int */
2786  STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
2787 
2788  /* pointer to type-specific plugin descriptor */
2789  /* void* */
2790  STRUCT_FLD(info, &i_s_info),
2791 
2792  /* plugin name */
2793  /* const char* */
2794  STRUCT_FLD(name, "INNODB_METRICS"),
2795 
2796  /* plugin author (for SHOW PLUGINS) */
2797  /* const char* */
2798  STRUCT_FLD(author, plugin_author),
2799 
2800  /* general descriptive text (for SHOW PLUGINS) */
2801  /* const char* */
2802  STRUCT_FLD(descr, "InnoDB Metrics Info"),
2803 
2804  /* the plugin license (PLUGIN_LICENSE_XXX) */
2805  /* int */
2806  STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
2807 
2808  /* the function to invoke when plugin is loaded */
2809  /* int (*)(void*); */
2810  STRUCT_FLD(init, innodb_metrics_init),
2811 
2812  /* the function to invoke when plugin is unloaded */
2813  /* int (*)(void*); */
2814  STRUCT_FLD(deinit, i_s_common_deinit),
2815 
2816  /* plugin version (for SHOW PLUGINS) */
2817  /* unsigned int */
2818  STRUCT_FLD(version, INNODB_VERSION_SHORT),
2819 
2820  /* struct st_mysql_show_var* */
2821  STRUCT_FLD(status_vars, NULL),
2822 
2823  /* struct st_mysql_sys_var** */
2824  STRUCT_FLD(system_vars, NULL),
2825 
2826  /* reserved for dependency checking */
2827  /* void* */
2828  STRUCT_FLD(__reserved1, NULL),
2829 
2830  /* Plugin flags */
2831  /* unsigned long */
2832  STRUCT_FLD(flags, 0UL),
2833 };
2834 /* Fields of the dynamic table INFORMATION_SCHEMA.innodb_ft_default_stopword */
2835 static ST_FIELD_INFO i_s_stopword_fields_info[] =
2836 {
2837 #define STOPWORD_VALUE 0
2838  {STRUCT_FLD(field_name, "value"),
2839  STRUCT_FLD(field_length, TRX_ID_MAX_LEN + 1),
2840  STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
2841  STRUCT_FLD(value, 0),
2842  STRUCT_FLD(field_flags, 0),
2843  STRUCT_FLD(old_name, ""),
2844  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2845 
2846  END_OF_ST_FIELD_INFO
2847 };
2848 
2849 /*******************************************************************/
2852 static
2853 int
2854 i_s_stopword_fill(
2855 /*==============*/
2856  THD* thd,
2857  TABLE_LIST* tables,
2858  Item* )
2859 {
2860  Field** fields;
2861  ulint i = 0;
2862  TABLE* table = (TABLE*) tables->table;
2863 
2864  DBUG_ENTER("i_s_stopword_fill");
2865 
2866  fields = table->field;
2867 
2868  /* Fill with server default stopword list in array
2869  fts_default_stopword */
2870  while (fts_default_stopword[i]) {
2871  OK(field_store_string(fields[STOPWORD_VALUE],
2872  fts_default_stopword[i]));
2873 
2874  OK(schema_table_store_record(thd, table));
2875  i++;
2876  }
2877 
2878  DBUG_RETURN(0);
2879 }
2880 
2881 /*******************************************************************/
2884 static
2885 int
2886 i_s_stopword_init(
2887 /*==============*/
2888  void* p)
2889 {
2890  DBUG_ENTER("i_s_stopword_init");
2891  ST_SCHEMA_TABLE* schema = (ST_SCHEMA_TABLE*) p;
2892 
2893  schema->fields_info = i_s_stopword_fields_info;
2894  schema->fill_table = i_s_stopword_fill;
2895 
2896  DBUG_RETURN(0);
2897 }
2898 
2899 UNIV_INTERN struct st_mysql_plugin i_s_innodb_ft_default_stopword =
2900 {
2901  /* the plugin type (a MYSQL_XXX_PLUGIN value) */
2902  /* int */
2903  STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
2904 
2905  /* pointer to type-specific plugin descriptor */
2906  /* void* */
2907  STRUCT_FLD(info, &i_s_stopword_fields_info),
2908 
2909  /* plugin name */
2910  /* const char* */
2911  STRUCT_FLD(name, "INNODB_FT_DEFAULT_STOPWORD"),
2912 
2913  /* plugin author (for SHOW PLUGINS) */
2914  /* const char* */
2915  STRUCT_FLD(author, plugin_author),
2916 
2917  /* general descriptive text (for SHOW PLUGINS) */
2918  /* const char* */
2919  STRUCT_FLD(descr, "Default stopword list for InnDB Full Text Search"),
2920 
2921  /* the plugin license (PLUGIN_LICENSE_XXX) */
2922  /* int */
2923  STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
2924 
2925  /* the function to invoke when plugin is loaded */
2926  /* int (*)(void*); */
2927  STRUCT_FLD(init, i_s_stopword_init),
2928 
2929  /* the function to invoke when plugin is unloaded */
2930  /* int (*)(void*); */
2931  STRUCT_FLD(deinit, i_s_common_deinit),
2932 
2933  /* plugin version (for SHOW PLUGINS) */
2934  /* unsigned int */
2935  STRUCT_FLD(version, INNODB_VERSION_SHORT),
2936 
2937  /* struct st_mysql_show_var* */
2938  STRUCT_FLD(status_vars, NULL),
2939 
2940  /* struct st_mysql_sys_var** */
2941  STRUCT_FLD(system_vars, NULL),
2942 
2943  /* reserved for dependency checking */
2944  /* void* */
2945  STRUCT_FLD(__reserved1, NULL),
2946 
2947  /* Plugin flags */
2948  /* unsigned long */
2949  STRUCT_FLD(flags, 0UL),
2950 };
2951 
2952 /* Fields of the dynamic table INFORMATION_SCHEMA.INNODB_FT_DELETED
2953 INFORMATION_SCHEMA.INNODB_FT_BEING_DELETED */
2954 static ST_FIELD_INFO i_s_fts_doc_fields_info[] =
2955 {
2956 #define I_S_FTS_DOC_ID 0
2957  {STRUCT_FLD(field_name, "DOC_ID"),
2958  STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
2959  STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
2960  STRUCT_FLD(value, 0),
2961  STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
2962  STRUCT_FLD(old_name, ""),
2963  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
2964 
2965  END_OF_ST_FIELD_INFO
2966 };
2967 
2968 /*******************************************************************/
2972 static
2973 int
2974 i_s_fts_deleted_generic_fill(
2975 /*=========================*/
2976  THD* thd,
2977  TABLE_LIST* tables,
2978  ibool being_deleted)
2979 {
2980  Field** fields;
2981  TABLE* table = (TABLE*) tables->table;
2982  trx_t* trx;
2984  fts_doc_ids_t* deleted;
2985  dict_table_t* user_table;
2986 
2987  DBUG_ENTER("i_s_fts_deleted_generic_fill");
2988 
2989  /* deny access to non-superusers */
2990  if (check_global_access(thd, PROCESS_ACL)) {
2991  DBUG_RETURN(0);
2992  }
2993 
2994  if (!fts_internal_tbl_name) {
2995  DBUG_RETURN(0);
2996  }
2997 
2998  deleted = fts_doc_ids_create();
2999 
3000  user_table = dict_table_open_on_name(
3002 
3003  if (!user_table) {
3004  DBUG_RETURN(0);
3005  }
3006 
3008  trx->op_info = "Select for FTS DELETE TABLE";
3009 
3011  (being_deleted) ? "BEING_DELETED" : "DELETED",
3012  FTS_COMMON_TABLE, user_table);
3013 
3015 
3016  fields = table->field;
3017 
3018  for (ulint j = 0; j < ib_vector_size(deleted->doc_ids); ++j) {
3019  doc_id_t doc_id;
3020 
3021  doc_id = *(doc_id_t*) ib_vector_get_const(deleted->doc_ids, j);
3022 
3023  OK(fields[I_S_FTS_DOC_ID]->store((longlong) doc_id, true));
3024 
3025  OK(schema_table_store_record(thd, table));
3026  }
3027 
3029 
3030  fts_doc_ids_free(deleted);
3031 
3032  dict_table_close(user_table, FALSE, FALSE);
3033 
3034  DBUG_RETURN(0);
3035 }
3036 
3037 /*******************************************************************/
3040 static
3041 int
3042 i_s_fts_deleted_fill(
3043 /*=================*/
3044  THD* thd,
3045  TABLE_LIST* tables,
3046  Item* )
3047 {
3048  DBUG_ENTER("i_s_fts_deleted_fill");
3049 
3050  DBUG_RETURN(i_s_fts_deleted_generic_fill(thd, tables, FALSE));
3051 }
3052 
3053 /*******************************************************************/
3056 static
3057 int
3058 i_s_fts_deleted_init(
3059 /*=================*/
3060  void* p)
3061 {
3062  DBUG_ENTER("i_s_fts_deleted_init");
3063  ST_SCHEMA_TABLE* schema = (ST_SCHEMA_TABLE*) p;
3064 
3065  schema->fields_info = i_s_fts_doc_fields_info;
3066  schema->fill_table = i_s_fts_deleted_fill;
3067 
3068  DBUG_RETURN(0);
3069 }
3070 
3071 UNIV_INTERN struct st_mysql_plugin i_s_innodb_ft_deleted =
3072 {
3073  /* the plugin type (a MYSQL_XXX_PLUGIN value) */
3074  /* int */
3075  STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
3076 
3077  /* pointer to type-specific plugin descriptor */
3078  /* void* */
3079  STRUCT_FLD(info, &i_s_fts_doc_fields_info),
3080 
3081  /* plugin name */
3082  /* const char* */
3083  STRUCT_FLD(name, "INNODB_FT_DELETED"),
3084 
3085  /* plugin author (for SHOW PLUGINS) */
3086  /* const char* */
3087  STRUCT_FLD(author, plugin_author),
3088 
3089  /* general descriptive text (for SHOW PLUGINS) */
3090  /* const char* */
3091  STRUCT_FLD(descr, "INNODB AUXILIARY FTS DELETED TABLE"),
3092 
3093  /* the plugin license (PLUGIN_LICENSE_XXX) */
3094  /* int */
3095  STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
3096 
3097  /* the function to invoke when plugin is loaded */
3098  /* int (*)(void*); */
3099  STRUCT_FLD(init, i_s_fts_deleted_init),
3100 
3101  /* the function to invoke when plugin is unloaded */
3102  /* int (*)(void*); */
3103  STRUCT_FLD(deinit, i_s_common_deinit),
3104 
3105  /* plugin version (for SHOW PLUGINS) */
3106  /* unsigned int */
3107  STRUCT_FLD(version, INNODB_VERSION_SHORT),
3108 
3109  /* struct st_mysql_show_var* */
3110  STRUCT_FLD(status_vars, NULL),
3111 
3112  /* struct st_mysql_sys_var** */
3113  STRUCT_FLD(system_vars, NULL),
3114 
3115  /* reserved for dependency checking */
3116  /* void* */
3117  STRUCT_FLD(__reserved1, NULL),
3118 
3119  /* Plugin flags */
3120  /* unsigned long */
3121  STRUCT_FLD(flags, 0UL),
3122 };
3123 
3124 /*******************************************************************/
3127 static
3128 int
3129 i_s_fts_being_deleted_fill(
3130 /*=======================*/
3131  THD* thd,
3132  TABLE_LIST* tables,
3133  Item* )
3134 {
3135  DBUG_ENTER("i_s_fts_being_deleted_fill");
3136 
3137  DBUG_RETURN(i_s_fts_deleted_generic_fill(thd, tables, TRUE));
3138 }
3139 
3140 /*******************************************************************/
3143 static
3144 int
3145 i_s_fts_being_deleted_init(
3146 /*=======================*/
3147  void* p)
3148 {
3149  DBUG_ENTER("i_s_fts_deleted_init");
3150  ST_SCHEMA_TABLE* schema = (ST_SCHEMA_TABLE*) p;
3151 
3152  schema->fields_info = i_s_fts_doc_fields_info;
3153  schema->fill_table = i_s_fts_being_deleted_fill;
3154 
3155  DBUG_RETURN(0);
3156 }
3157 
3158 UNIV_INTERN struct st_mysql_plugin i_s_innodb_ft_being_deleted =
3159 {
3160  /* the plugin type (a MYSQL_XXX_PLUGIN value) */
3161  /* int */
3162  STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
3163 
3164  /* pointer to type-specific plugin descriptor */
3165  /* void* */
3166  STRUCT_FLD(info, &i_s_fts_doc_fields_info),
3167 
3168  /* plugin name */
3169  /* const char* */
3170  STRUCT_FLD(name, "INNODB_FT_BEING_DELETED"),
3171 
3172  /* plugin author (for SHOW PLUGINS) */
3173  /* const char* */
3174  STRUCT_FLD(author, plugin_author),
3175 
3176  /* general descriptive text (for SHOW PLUGINS) */
3177  /* const char* */
3178  STRUCT_FLD(descr, "INNODB AUXILIARY FTS BEING DELETED TABLE"),
3179 
3180  /* the plugin license (PLUGIN_LICENSE_XXX) */
3181  /* int */
3182  STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
3183 
3184  /* the function to invoke when plugin is loaded */
3185  /* int (*)(void*); */
3186  STRUCT_FLD(init, i_s_fts_being_deleted_init),
3187 
3188  /* the function to invoke when plugin is unloaded */
3189  /* int (*)(void*); */
3190  STRUCT_FLD(deinit, i_s_common_deinit),
3191 
3192  /* plugin version (for SHOW PLUGINS) */
3193  /* unsigned int */
3194  STRUCT_FLD(version, INNODB_VERSION_SHORT),
3195 
3196  /* struct st_mysql_show_var* */
3197  STRUCT_FLD(status_vars, NULL),
3198 
3199  /* struct st_mysql_sys_var** */
3200  STRUCT_FLD(system_vars, NULL),
3201 
3202  /* reserved for dependency checking */
3203  /* void* */
3204  STRUCT_FLD(__reserved1, NULL),
3205 
3206  /* Plugin flags */
3207  /* unsigned long */
3208  STRUCT_FLD(flags, 0UL),
3209 };
3210 
3211 /* Fields of the dynamic table INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHED and
3212 INFORMATION_SCHEMA.INNODB_FT_INDEX_TABLE */
3213 static ST_FIELD_INFO i_s_fts_index_fields_info[] =
3214 {
3215 #define I_S_FTS_WORD 0
3216  {STRUCT_FLD(field_name, "WORD"),
3217  STRUCT_FLD(field_length, FTS_MAX_WORD_LEN + 1),
3218  STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
3219  STRUCT_FLD(value, 0),
3220  STRUCT_FLD(field_flags, 0),
3221  STRUCT_FLD(old_name, ""),
3222  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
3223 
3224 #define I_S_FTS_FIRST_DOC_ID 1
3225  {STRUCT_FLD(field_name, "FIRST_DOC_ID"),
3226  STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
3227  STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
3228  STRUCT_FLD(value, 0),
3229  STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
3230  STRUCT_FLD(old_name, ""),
3231  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
3232 
3233 #define I_S_FTS_LAST_DOC_ID 2
3234  {STRUCT_FLD(field_name, "LAST_DOC_ID"),
3235  STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
3236  STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
3237  STRUCT_FLD(value, 0),
3238  STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
3239  STRUCT_FLD(old_name, ""),
3240  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
3241 
3242 #define I_S_FTS_DOC_COUNT 3
3243  {STRUCT_FLD(field_name, "DOC_COUNT"),
3244  STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
3245  STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
3246  STRUCT_FLD(value, 0),
3247  STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
3248  STRUCT_FLD(old_name, ""),
3249  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
3250 
3251 #define I_S_FTS_ILIST_DOC_ID 4
3252  {STRUCT_FLD(field_name, "DOC_ID"),
3253  STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
3254  STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
3255  STRUCT_FLD(value, 0),
3256  STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
3257  STRUCT_FLD(old_name, ""),
3258  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
3259 
3260 #define I_S_FTS_ILIST_DOC_POS 5
3261  {STRUCT_FLD(field_name, "POSITION"),
3262  STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
3263  STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
3264  STRUCT_FLD(value, 0),
3265  STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
3266  STRUCT_FLD(old_name, ""),
3267  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
3268 
3269  END_OF_ST_FIELD_INFO
3270 };
3271 
3272 /*******************************************************************/
3276 static
3277 int
3278 i_s_fts_index_cache_fill_one_index(
3279 /*===============================*/
3280  fts_index_cache_t* index_cache,
3281  THD* thd,
3282  TABLE_LIST* tables)
3283 {
3284  TABLE* table = (TABLE*) tables->table;
3285  Field** fields;
3286  const ib_rbt_node_t* rbt_node;
3287 
3288  DBUG_ENTER("i_s_fts_index_cache_fill_one_index");
3289 
3290  fields = table->field;
3291 
3292  /* Go through each word in the index cache */
3293  for (rbt_node = rbt_first(index_cache->words);
3294  rbt_node;
3295  rbt_node = rbt_next(index_cache->words, rbt_node)) {
3296  doc_id_t doc_id = 0;
3297 
3299 
3300  word = rbt_value(fts_tokenizer_word_t, rbt_node);
3301 
3302  /* Decrypt the ilist, and display Dod ID and word position */
3303  for (ulint i = 0; i < ib_vector_size(word->nodes); i++) {
3304  fts_node_t* node;
3305  byte* ptr;
3306  ulint decoded = 0;
3307 
3308  node = static_cast<fts_node_t*> (ib_vector_get(
3309  word->nodes, i));
3310 
3311  ptr = node->ilist;
3312 
3313  while (decoded < node->ilist_size) {
3314  ulint pos = fts_decode_vlc(&ptr);
3315 
3316  doc_id += pos;
3317 
3318  /* Get position info */
3319  while (*ptr) {
3320  pos = fts_decode_vlc(&ptr);
3321 
3322  OK(field_store_string(
3323  fields[I_S_FTS_WORD],
3324  reinterpret_cast<const char*>
3325  (word->text.f_str)));
3326 
3327  OK(fields[I_S_FTS_FIRST_DOC_ID]->store(
3328  (longlong) node->first_doc_id,
3329  true));
3330 
3331  OK(fields[I_S_FTS_LAST_DOC_ID]->store(
3332  (longlong) node->last_doc_id,
3333  true));
3334 
3335  OK(fields[I_S_FTS_DOC_COUNT]->store(
3336  node->doc_count));
3337 
3338  OK(fields[I_S_FTS_ILIST_DOC_ID]->store(
3339  (longlong) doc_id, true));
3340 
3341  OK(fields[I_S_FTS_ILIST_DOC_POS]->store(
3342  pos));
3343 
3344  OK(schema_table_store_record(
3345  thd, table));
3346  }
3347 
3348  ++ptr;
3349 
3350  decoded = ptr - (byte*) node->ilist;
3351  }
3352  }
3353  }
3354 
3355  DBUG_RETURN(0);
3356 }
3357 /*******************************************************************/
3360 static
3361 int
3362 i_s_fts_index_cache_fill(
3363 /*=====================*/
3364  THD* thd,
3365  TABLE_LIST* tables,
3366  Item* )
3367 {
3368  dict_table_t* user_table;
3369  fts_cache_t* cache;
3370 
3371  DBUG_ENTER("i_s_fts_index_cache_fill");
3372 
3373  /* deny access to non-superusers */
3374  if (check_global_access(thd, PROCESS_ACL)) {
3375  DBUG_RETURN(0);
3376  }
3377 
3378  if (!fts_internal_tbl_name) {
3379  DBUG_RETURN(0);
3380  }
3381 
3382  user_table = dict_table_open_on_name(
3384 
3385  if (!user_table) {
3386  DBUG_RETURN(0);
3387  }
3388 
3389  cache = user_table->fts->cache;
3390 
3391  ut_a(cache);
3392 
3393  for (ulint i = 0; i < ib_vector_size(cache->indexes); i++) {
3394  fts_index_cache_t* index_cache;
3395 
3396  index_cache = static_cast<fts_index_cache_t*> (
3397  ib_vector_get(cache->indexes, i));
3398 
3399  i_s_fts_index_cache_fill_one_index(index_cache, thd, tables);
3400  }
3401 
3402  dict_table_close(user_table, FALSE, FALSE);
3403 
3404  DBUG_RETURN(0);
3405 }
3406 
3407 /*******************************************************************/
3410 static
3411 int
3412 i_s_fts_index_cache_init(
3413 /*=====================*/
3414  void* p)
3415 {
3416  DBUG_ENTER("i_s_fts_index_cache_init");
3417  ST_SCHEMA_TABLE* schema = (ST_SCHEMA_TABLE*) p;
3418 
3419  schema->fields_info = i_s_fts_index_fields_info;
3420  schema->fill_table = i_s_fts_index_cache_fill;
3421 
3422  DBUG_RETURN(0);
3423 }
3424 
3425 UNIV_INTERN struct st_mysql_plugin i_s_innodb_ft_index_cache =
3426 {
3427  /* the plugin type (a MYSQL_XXX_PLUGIN value) */
3428  /* int */
3429  STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
3430 
3431  /* pointer to type-specific plugin descriptor */
3432  /* void* */
3433  STRUCT_FLD(info, &i_s_fts_index_fields_info),
3434 
3435  /* plugin name */
3436  /* const char* */
3437  STRUCT_FLD(name, "INNODB_FT_INDEX_CACHE"),
3438 
3439  /* plugin author (for SHOW PLUGINS) */
3440  /* const char* */
3441  STRUCT_FLD(author, plugin_author),
3442 
3443  /* general descriptive text (for SHOW PLUGINS) */
3444  /* const char* */
3445  STRUCT_FLD(descr, "INNODB AUXILIARY FTS INDEX CACHED"),
3446 
3447  /* the plugin license (PLUGIN_LICENSE_XXX) */
3448  /* int */
3449  STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
3450 
3451  /* the function to invoke when plugin is loaded */
3452  /* int (*)(void*); */
3453  STRUCT_FLD(init, i_s_fts_index_cache_init),
3454 
3455  /* the function to invoke when plugin is unloaded */
3456  /* int (*)(void*); */
3457  STRUCT_FLD(deinit, i_s_common_deinit),
3458 
3459  /* plugin version (for SHOW PLUGINS) */
3460  /* unsigned int */
3461  STRUCT_FLD(version, INNODB_VERSION_SHORT),
3462 
3463  /* struct st_mysql_show_var* */
3464  STRUCT_FLD(status_vars, NULL),
3465 
3466  /* struct st_mysql_sys_var** */
3467  STRUCT_FLD(system_vars, NULL),
3468 
3469  /* reserved for dependency checking */
3470  /* void* */
3471  STRUCT_FLD(__reserved1, NULL),
3472 
3473  /* Plugin flags */
3474  /* unsigned long */
3475  STRUCT_FLD(flags, 0UL),
3476 };
3477 
3478 /*******************************************************************/
3482 static
3483 ulint
3484 i_s_fts_index_table_fill_selected(
3485 /*==============================*/
3486  dict_index_t* index,
3487  ib_vector_t* words,
3489  ulint selected)
3490 {
3491  pars_info_t* info;
3493  trx_t* trx;
3494  que_t* graph;
3495  ulint error;
3496  fts_fetch_t fetch;
3497 
3498  info = pars_info_create();
3499 
3500  fetch.read_arg = words;
3502 
3504 
3505  trx->op_info = "fetching FTS index nodes";
3506 
3507  pars_info_bind_function(info, "my_func", fetch.read_record, &fetch);
3508 
3509  FTS_INIT_INDEX_TABLE(&fts_table, fts_get_suffix(selected),
3510  FTS_INDEX_TABLE, index);
3511 
3512  graph = fts_parse_sql(
3513  &fts_table, info,
3514  "DECLARE FUNCTION my_func;\n"
3515  "DECLARE CURSOR c IS"
3516  " SELECT word, doc_count, first_doc_id, last_doc_id, "
3517  "ilist\n"
3518  " FROM %s;\n"
3519  "BEGIN\n"
3520  "\n"
3521  "OPEN c;\n"
3522  "WHILE 1 = 1 LOOP\n"
3523  " FETCH c INTO my_func();\n"
3524  " IF c % NOTFOUND THEN\n"
3525  " EXIT;\n"
3526  " END IF;\n"
3527  "END LOOP;\n"
3528  "CLOSE c;");
3529 
3530  for(;;) {
3531  error = fts_eval_sql(trx, graph);
3532 
3533  if (error == DB_SUCCESS) {
3534  fts_sql_commit(trx);
3535 
3536  break;
3537  } else {
3538  fts_sql_rollback(trx);
3539 
3540  ut_print_timestamp(stderr);
3541 
3542  if (error == DB_LOCK_WAIT_TIMEOUT) {
3543  fprintf(stderr, " InnoDB: Warning: "
3544  "lock wait timeout reading "
3545  "FTS index. Retrying!\n");
3546 
3547  trx->error_state = DB_SUCCESS;
3548  } else {
3549  fprintf(stderr, " InnoDB: Error: %lu "
3550  "while reading FTS index.\n", error);
3551  break;
3552  }
3553  }
3554  }
3555 
3556  mutex_enter(&dict_sys->mutex);
3557  que_graph_free(graph);
3558  mutex_exit(&dict_sys->mutex);
3559 
3561 
3562  return(error);
3563 }
3564 
3565 /*******************************************************************/
3569 static
3570 int
3571 i_s_fts_index_table_fill_one_index(
3572 /*===============================*/
3573  dict_index_t* index,
3574  THD* thd,
3575  TABLE_LIST* tables)
3576 {
3577  TABLE* table = (TABLE*) tables->table;
3578  Field** fields;
3579  ib_vector_t* words;
3580  mem_heap_t* heap;
3581  ulint num_row_fill;
3582 
3583  DBUG_ENTER("i_s_fts_index_cache_fill_one_index");
3584  DBUG_ASSERT(!dict_index_is_online_ddl(index));
3585 
3586  heap = mem_heap_create(1024);
3587 
3588  words = ib_vector_create(ib_heap_allocator_create(heap),
3589  sizeof(fts_word_t), 256);
3590 
3591  fields = table->field;
3592 
3593  /* Iterate through each auxiliary table as described in
3594  fts_index_selector */
3595  for (ulint selected = 0; fts_index_selector[selected].value;
3596  selected++) {
3597  i_s_fts_index_table_fill_selected(index, words, selected);
3598  }
3599 
3600  num_row_fill = ut_min(ib_vector_size(words), 500000);
3601 
3602  /* Go through each word in the index cache */
3603  for (ulint i = 0; i < num_row_fill; i++) {
3604  fts_word_t* word;
3605 
3606  word = (fts_word_t*) ib_vector_get(words, i);
3607 
3608  word->text.f_str[word->text.f_len] = 0;
3609 
3610  /* Decrypt the ilist, and display Dod ID and word position */
3611  for (ulint i = 0; i < ib_vector_size(word->nodes); i++) {
3612  fts_node_t* node;
3613  byte* ptr;
3614  ulint decoded = 0;
3615  doc_id_t doc_id = 0;
3616 
3617  node = static_cast<fts_node_t*> (ib_vector_get(
3618  word->nodes, i));
3619 
3620  ptr = node->ilist;
3621 
3622  while (decoded < node->ilist_size) {
3623  ulint pos = fts_decode_vlc(&ptr);
3624 
3625  doc_id += pos;
3626 
3627  /* Get position info */
3628  while (*ptr) {
3629  pos = fts_decode_vlc(&ptr);
3630 
3631  OK(field_store_string(
3632  fields[I_S_FTS_WORD],
3633  reinterpret_cast<const char*>
3634  (word->text.f_str)));
3635 
3636  OK(fields[I_S_FTS_FIRST_DOC_ID]->store(
3637  (longlong) node->first_doc_id,
3638  true));
3639 
3640  OK(fields[I_S_FTS_LAST_DOC_ID]->store(
3641  (longlong) node->last_doc_id,
3642  true));
3643 
3644  OK(fields[I_S_FTS_DOC_COUNT]->store(
3645  node->doc_count));
3646 
3647  OK(fields[I_S_FTS_ILIST_DOC_ID]->store(
3648  (longlong) doc_id, true));
3649 
3650  OK(fields[I_S_FTS_ILIST_DOC_POS]->store(
3651  pos));
3652 
3653  OK(schema_table_store_record(
3654  thd, table));
3655  }
3656 
3657  ++ptr;
3658 
3659  decoded = ptr - (byte*) node->ilist;
3660  }
3661  }
3662  }
3663 
3665 
3666  DBUG_RETURN(0);
3667 }
3668 /*******************************************************************/
3671 static
3672 int
3673 i_s_fts_index_table_fill(
3674 /*=====================*/
3675  THD* thd,
3676  TABLE_LIST* tables,
3677  Item* )
3678 {
3679  dict_table_t* user_table;
3681 
3682  DBUG_ENTER("i_s_fts_index_table_fill");
3683 
3684  /* deny access to non-superusers */
3685  if (check_global_access(thd, PROCESS_ACL)) {
3686  DBUG_RETURN(0);
3687  }
3688 
3689  if (!fts_internal_tbl_name) {
3690  DBUG_RETURN(0);
3691  }
3692 
3693  user_table = dict_table_open_on_name(
3695 
3696  if (!user_table) {
3697  DBUG_RETURN(0);
3698  }
3699 
3700  for (index = dict_table_get_first_index(user_table);
3701  index; index = dict_table_get_next_index(index)) {
3702  if (index->type & DICT_FTS) {
3703  i_s_fts_index_table_fill_one_index(index, thd, tables);
3704  }
3705  }
3706 
3707  dict_table_close(user_table, FALSE, FALSE);
3708 
3709  DBUG_RETURN(0);
3710 }
3711 
3712 /*******************************************************************/
3715 static
3716 int
3717 i_s_fts_index_table_init(
3718 /*=====================*/
3719  void* p)
3720 {
3721  DBUG_ENTER("i_s_fts_index_table_init");
3722  ST_SCHEMA_TABLE* schema = (ST_SCHEMA_TABLE*) p;
3723 
3724  schema->fields_info = i_s_fts_index_fields_info;
3725  schema->fill_table = i_s_fts_index_table_fill;
3726 
3727  DBUG_RETURN(0);
3728 }
3729 
3730 UNIV_INTERN struct st_mysql_plugin i_s_innodb_ft_index_table =
3731 {
3732  /* the plugin type (a MYSQL_XXX_PLUGIN value) */
3733  /* int */
3734  STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
3735 
3736  /* pointer to type-specific plugin descriptor */
3737  /* void* */
3738  STRUCT_FLD(info, &i_s_fts_index_fields_info),
3739 
3740  /* plugin name */
3741  /* const char* */
3742  STRUCT_FLD(name, "INNODB_FT_INDEX_TABLE"),
3743 
3744  /* plugin author (for SHOW PLUGINS) */
3745  /* const char* */
3746  STRUCT_FLD(author, plugin_author),
3747 
3748  /* general descriptive text (for SHOW PLUGINS) */
3749  /* const char* */
3750  STRUCT_FLD(descr, "INNODB AUXILIARY FTS INDEX TABLE"),
3751 
3752  /* the plugin license (PLUGIN_LICENSE_XXX) */
3753  /* int */
3754  STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
3755 
3756  /* the function to invoke when plugin is loaded */
3757  /* int (*)(void*); */
3758  STRUCT_FLD(init, i_s_fts_index_table_init),
3759 
3760  /* the function to invoke when plugin is unloaded */
3761  /* int (*)(void*); */
3762  STRUCT_FLD(deinit, i_s_common_deinit),
3763 
3764  /* plugin version (for SHOW PLUGINS) */
3765  /* unsigned int */
3766  STRUCT_FLD(version, INNODB_VERSION_SHORT),
3767 
3768  /* struct st_mysql_show_var* */
3769  STRUCT_FLD(status_vars, NULL),
3770 
3771  /* struct st_mysql_sys_var** */
3772  STRUCT_FLD(system_vars, NULL),
3773 
3774  /* reserved for dependency checking */
3775  /* void* */
3776  STRUCT_FLD(__reserved1, NULL),
3777 
3778  /* Plugin flags */
3779  /* unsigned long */
3780  STRUCT_FLD(flags, 0UL),
3781 };
3782 
3783 /* Fields of the dynamic table INFORMATION_SCHEMA.INNODB_FT_CONFIG */
3784 static ST_FIELD_INFO i_s_fts_config_fields_info[] =
3785 {
3786 #define FTS_CONFIG_KEY 0
3787  {STRUCT_FLD(field_name, "KEY"),
3788  STRUCT_FLD(field_length, NAME_LEN + 1),
3789  STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
3790  STRUCT_FLD(value, 0),
3791  STRUCT_FLD(field_flags, 0),
3792  STRUCT_FLD(old_name, ""),
3793  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
3794 
3795 #define FTS_CONFIG_VALUE 1
3796  {STRUCT_FLD(field_name, "VALUE"),
3797  STRUCT_FLD(field_length, NAME_LEN + 1),
3798  STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
3799  STRUCT_FLD(value, 0),
3800  STRUCT_FLD(field_flags, 0),
3801  STRUCT_FLD(old_name, ""),
3802  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
3803 
3804  END_OF_ST_FIELD_INFO
3805 };
3806 
3807 static const char* fts_config_key[] = {
3812  NULL
3813 };
3814 
3815 /*******************************************************************/
3818 static
3819 int
3820 i_s_fts_config_fill(
3821 /*================*/
3822  THD* thd,
3823  TABLE_LIST* tables,
3824  Item* )
3825 {
3826  Field** fields;
3827  TABLE* table = (TABLE*) tables->table;
3828  trx_t* trx;
3829  fts_table_t fts_table;
3830  dict_table_t* user_table;
3831  ulint i = 0;
3832  dict_index_t* index = NULL;
3833  unsigned char str[FTS_MAX_CONFIG_VALUE_LEN + 1];
3834 
3835  DBUG_ENTER("i_s_fts_config_fill");
3836 
3837  /* deny access to non-superusers */
3838  if (check_global_access(thd, PROCESS_ACL)) {
3839  DBUG_RETURN(0);
3840  }
3841 
3842  if (!fts_internal_tbl_name) {
3843  DBUG_RETURN(0);
3844  }
3845 
3846  fields = table->field;
3847 
3848  user_table = dict_table_open_on_name(
3850 
3851  if (!user_table) {
3852  DBUG_RETURN(0);
3853  }
3854 
3856  trx->op_info = "Select for FTS DELETE TABLE";
3857 
3858  FTS_INIT_FTS_TABLE(&fts_table, "CONFIG", FTS_COMMON_TABLE, user_table);
3859 
3860  if (!ib_vector_is_empty(user_table->fts->indexes)) {
3861  index = (dict_index_t*) ib_vector_getp_const(
3862  user_table->fts->indexes, 0);
3863  DBUG_ASSERT(!dict_index_is_online_ddl(index));
3864  }
3865 
3866  while (fts_config_key[i]) {
3867  fts_string_t value;
3868  char* key_name;
3869  ulint allocated = FALSE;
3870 
3872 
3873  value.f_str = str;
3874 
3875  if (index
3876  && strcmp(fts_config_key[i], FTS_TOTAL_WORD_COUNT) == 0) {
3878  fts_config_key[i], index);
3879  allocated = TRUE;
3880  } else {
3881  key_name = (char*) fts_config_key[i];
3882  }
3883 
3884  fts_config_get_value(trx, &fts_table, key_name, &value);
3885 
3886  if (allocated) {
3887  ut_free(key_name);
3888  }
3889 
3890  OK(field_store_string(
3891  fields[FTS_CONFIG_KEY], fts_config_key[i]));
3892 
3893  OK(field_store_string(
3894  fields[FTS_CONFIG_VALUE], (const char*) value.f_str));
3895 
3896  OK(schema_table_store_record(thd, table));
3897 
3898  i++;
3899  }
3900 
3901  fts_sql_commit(trx);
3902 
3904 
3905  dict_table_close(user_table, FALSE, FALSE);
3906 
3907  DBUG_RETURN(0);
3908 }
3909 
3910 /*******************************************************************/
3913 static
3914 int
3915 i_s_fts_config_init(
3916 /*=================*/
3917  void* p)
3918 {
3919  DBUG_ENTER("i_s_fts_config_init");
3920  ST_SCHEMA_TABLE* schema = (ST_SCHEMA_TABLE*) p;
3921 
3922  schema->fields_info = i_s_fts_config_fields_info;
3923  schema->fill_table = i_s_fts_config_fill;
3924 
3925  DBUG_RETURN(0);
3926 }
3927 
3928 UNIV_INTERN struct st_mysql_plugin i_s_innodb_ft_config =
3929 {
3930  /* the plugin type (a MYSQL_XXX_PLUGIN value) */
3931  /* int */
3932  STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
3933 
3934  /* pointer to type-specific plugin descriptor */
3935  /* void* */
3936  STRUCT_FLD(info, &i_s_fts_config_fields_info),
3937 
3938  /* plugin name */
3939  /* const char* */
3940  STRUCT_FLD(name, "INNODB_FT_CONFIG"),
3941 
3942  /* plugin author (for SHOW PLUGINS) */
3943  /* const char* */
3944  STRUCT_FLD(author, plugin_author),
3945 
3946  /* general descriptive text (for SHOW PLUGINS) */
3947  /* const char* */
3948  STRUCT_FLD(descr, "INNODB AUXILIARY FTS CONFIG TABLE"),
3949 
3950  /* the plugin license (PLUGIN_LICENSE_XXX) */
3951  /* int */
3952  STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
3953 
3954  /* the function to invoke when plugin is loaded */
3955  /* int (*)(void*); */
3956  STRUCT_FLD(init, i_s_fts_config_init),
3957 
3958  /* the function to invoke when plugin is unloaded */
3959  /* int (*)(void*); */
3960  STRUCT_FLD(deinit, i_s_common_deinit),
3961 
3962  /* plugin version (for SHOW PLUGINS) */
3963  /* unsigned int */
3964  STRUCT_FLD(version, INNODB_VERSION_SHORT),
3965 
3966  /* struct st_mysql_show_var* */
3967  STRUCT_FLD(status_vars, NULL),
3968 
3969  /* struct st_mysql_sys_var** */
3970  STRUCT_FLD(system_vars, NULL),
3971 
3972  /* reserved for dependency checking */
3973  /* void* */
3974  STRUCT_FLD(__reserved1, NULL),
3975 
3976  /* Plugin flags */
3977  /* unsigned long */
3978  STRUCT_FLD(flags, 0UL),
3979 };
3980 
3981 /* Fields of the dynamic table INNODB_BUFFER_POOL_STATS. */
3982 static ST_FIELD_INFO i_s_innodb_buffer_stats_fields_info[] =
3983 {
3984 #define IDX_BUF_STATS_POOL_ID 0
3985  {STRUCT_FLD(field_name, "POOL_ID"),
3986  STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
3987  STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
3988  STRUCT_FLD(value, 0),
3989  STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
3990  STRUCT_FLD(old_name, ""),
3991  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
3992 
3993 #define IDX_BUF_STATS_POOL_SIZE 1
3994  {STRUCT_FLD(field_name, "POOL_SIZE"),
3995  STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
3996  STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
3997  STRUCT_FLD(value, 0),
3998  STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
3999  STRUCT_FLD(old_name, ""),
4000  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
4001 
4002 #define IDX_BUF_STATS_FREE_BUFFERS 2
4003  {STRUCT_FLD(field_name, "FREE_BUFFERS"),
4004  STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
4005  STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
4006  STRUCT_FLD(value, 0),
4007  STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
4008  STRUCT_FLD(old_name, ""),
4009  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
4010 
4011 #define IDX_BUF_STATS_LRU_LEN 3
4012  {STRUCT_FLD(field_name, "DATABASE_PAGES"),
4013  STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
4014  STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
4015  STRUCT_FLD(value, 0),
4016  STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
4017  STRUCT_FLD(old_name, ""),
4018  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
4019 
4020 #define IDX_BUF_STATS_OLD_LRU_LEN 4
4021  {STRUCT_FLD(field_name, "OLD_DATABASE_PAGES"),
4022  STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
4023  STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
4024  STRUCT_FLD(value, 0),
4025  STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
4026  STRUCT_FLD(old_name, ""),
4027  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
4028 
4029 #define IDX_BUF_STATS_FLUSH_LIST_LEN 5
4030  {STRUCT_FLD(field_name, "MODIFIED_DATABASE_PAGES"),
4031  STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
4032  STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
4033  STRUCT_FLD(value, 0),
4034  STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
4035  STRUCT_FLD(old_name, ""),
4036  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
4037 
4038 #define IDX_BUF_STATS_PENDING_ZIP 6
4039  {STRUCT_FLD(field_name, "PENDING_DECOMPRESS"),
4040  STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
4041  STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
4042  STRUCT_FLD(value, 0),
4043  STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
4044  STRUCT_FLD(old_name, ""),
4045  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
4046 
4047 #define IDX_BUF_STATS_PENDING_READ 7
4048  {STRUCT_FLD(field_name, "PENDING_READS"),
4049  STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
4050  STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
4051  STRUCT_FLD(value, 0),
4052  STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
4053  STRUCT_FLD(old_name, ""),
4054  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
4055 
4056 #define IDX_BUF_STATS_FLUSH_LRU 8
4057  {STRUCT_FLD(field_name, "PENDING_FLUSH_LRU"),
4058  STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
4059  STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
4060  STRUCT_FLD(value, 0),
4061  STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
4062  STRUCT_FLD(old_name, ""),
4063  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
4064 
4065 #define IDX_BUF_STATS_FLUSH_LIST 9
4066  {STRUCT_FLD(field_name, "PENDING_FLUSH_LIST"),
4067  STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
4068  STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
4069  STRUCT_FLD(value, 0),
4070  STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
4071  STRUCT_FLD(old_name, ""),
4072  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
4073 
4074 #define IDX_BUF_STATS_PAGE_YOUNG 10
4075  {STRUCT_FLD(field_name, "PAGES_MADE_YOUNG"),
4076  STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
4077  STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
4078  STRUCT_FLD(value, 0),
4079  STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
4080  STRUCT_FLD(old_name, ""),
4081  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
4082 
4083 #define IDX_BUF_STATS_PAGE_NOT_YOUNG 11
4084  {STRUCT_FLD(field_name, "PAGES_NOT_MADE_YOUNG"),
4085  STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
4086  STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
4087  STRUCT_FLD(value, 0),
4088  STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
4089  STRUCT_FLD(old_name, ""),
4090  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
4091 
4092 #define IDX_BUF_STATS_PAGE_YOUNG_RATE 12
4093  {STRUCT_FLD(field_name, "PAGES_MADE_YOUNG_RATE"),
4094  STRUCT_FLD(field_length, MAX_FLOAT_STR_LENGTH),
4095  STRUCT_FLD(field_type, MYSQL_TYPE_FLOAT),
4096  STRUCT_FLD(value, 0),
4097  STRUCT_FLD(field_flags, 0),
4098  STRUCT_FLD(old_name, ""),
4099  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
4100 
4101 #define IDX_BUF_STATS_PAGE_NOT_YOUNG_RATE 13
4102  {STRUCT_FLD(field_name, "PAGES_MADE_NOT_YOUNG_RATE"),
4103  STRUCT_FLD(field_length, MAX_FLOAT_STR_LENGTH),
4104  STRUCT_FLD(field_type, MYSQL_TYPE_FLOAT),
4105  STRUCT_FLD(value, 0),
4106  STRUCT_FLD(field_flags, 0),
4107  STRUCT_FLD(old_name, ""),
4108  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
4109 
4110 #define IDX_BUF_STATS_PAGE_READ 14
4111  {STRUCT_FLD(field_name, "NUMBER_PAGES_READ"),
4112  STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
4113  STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
4114  STRUCT_FLD(value, 0),
4115  STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
4116  STRUCT_FLD(old_name, ""),
4117  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
4118 
4119 #define IDX_BUF_STATS_PAGE_CREATED 15
4120  {STRUCT_FLD(field_name, "NUMBER_PAGES_CREATED"),
4121  STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
4122  STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
4123  STRUCT_FLD(value, 0),
4124  STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
4125  STRUCT_FLD(old_name, ""),
4126  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
4127 
4128 #define IDX_BUF_STATS_PAGE_WRITTEN 16
4129  {STRUCT_FLD(field_name, "NUMBER_PAGES_WRITTEN"),
4130  STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
4131  STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
4132  STRUCT_FLD(value, 0),
4133  STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
4134  STRUCT_FLD(old_name, ""),
4135  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
4136 
4137 #define IDX_BUF_STATS_PAGE_READ_RATE 17
4138  {STRUCT_FLD(field_name, "PAGES_READ_RATE"),
4139  STRUCT_FLD(field_length, MAX_FLOAT_STR_LENGTH),
4140  STRUCT_FLD(field_type, MYSQL_TYPE_FLOAT),
4141  STRUCT_FLD(value, 0),
4142  STRUCT_FLD(field_flags, 0),
4143  STRUCT_FLD(old_name, ""),
4144  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
4145 
4146 #define IDX_BUF_STATS_PAGE_CREATE_RATE 18
4147  {STRUCT_FLD(field_name, "PAGES_CREATE_RATE"),
4148  STRUCT_FLD(field_length, MAX_FLOAT_STR_LENGTH),
4149  STRUCT_FLD(field_type, MYSQL_TYPE_FLOAT),
4150  STRUCT_FLD(value, 0),
4151  STRUCT_FLD(field_flags, 0),
4152  STRUCT_FLD(old_name, ""),
4153  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
4154 
4155 #define IDX_BUF_STATS_PAGE_WRITTEN_RATE 19
4156  {STRUCT_FLD(field_name, "PAGES_WRITTEN_RATE"),
4157  STRUCT_FLD(field_length, MAX_FLOAT_STR_LENGTH),
4158  STRUCT_FLD(field_type, MYSQL_TYPE_FLOAT),
4159  STRUCT_FLD(value, 0),
4160  STRUCT_FLD(field_flags, 0),
4161  STRUCT_FLD(old_name, ""),
4162  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
4163 
4164 #define IDX_BUF_STATS_GET 20
4165  {STRUCT_FLD(field_name, "NUMBER_PAGES_GET"),
4166  STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
4167  STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
4168  STRUCT_FLD(value, 0),
4169  STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
4170  STRUCT_FLD(old_name, ""),
4171  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
4172 
4173 #define IDX_BUF_STATS_HIT_RATE 21
4174  {STRUCT_FLD(field_name, "HIT_RATE"),
4175  STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
4176  STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
4177  STRUCT_FLD(value, 0),
4178  STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
4179  STRUCT_FLD(old_name, ""),
4180  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
4181 
4182 #define IDX_BUF_STATS_MADE_YOUNG_PCT 22
4183  {STRUCT_FLD(field_name, "YOUNG_MAKE_PER_THOUSAND_GETS"),
4184  STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
4185  STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
4186  STRUCT_FLD(value, 0),
4187  STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
4188  STRUCT_FLD(old_name, ""),
4189  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
4190 
4191 #define IDX_BUF_STATS_NOT_MADE_YOUNG_PCT 23
4192  {STRUCT_FLD(field_name, "NOT_YOUNG_MAKE_PER_THOUSAND_GETS"),
4193  STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
4194  STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
4195  STRUCT_FLD(value, 0),
4196  STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
4197  STRUCT_FLD(old_name, ""),
4198  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
4199 
4200 #define IDX_BUF_STATS_READ_AHREAD 24
4201  {STRUCT_FLD(field_name, "NUMBER_PAGES_READ_AHEAD"),
4202  STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
4203  STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
4204  STRUCT_FLD(value, 0),
4205  STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
4206  STRUCT_FLD(old_name, ""),
4207  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
4208 
4209 #define IDX_BUF_STATS_READ_AHEAD_EVICTED 25
4210  {STRUCT_FLD(field_name, "NUMBER_READ_AHEAD_EVICTED"),
4211  STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
4212  STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
4213  STRUCT_FLD(value, 0),
4214  STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
4215  STRUCT_FLD(old_name, ""),
4216  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
4217 
4218 #define IDX_BUF_STATS_READ_AHEAD_RATE 26
4219  {STRUCT_FLD(field_name, "READ_AHEAD_RATE"),
4220  STRUCT_FLD(field_length, MAX_FLOAT_STR_LENGTH),
4221  STRUCT_FLD(field_type, MYSQL_TYPE_FLOAT),
4222  STRUCT_FLD(value, 0),
4223  STRUCT_FLD(field_flags, 0),
4224  STRUCT_FLD(old_name, ""),
4225  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
4226 
4227 #define IDX_BUF_STATS_READ_AHEAD_EVICT_RATE 27
4228  {STRUCT_FLD(field_name, "READ_AHEAD_EVICTED_RATE"),
4229  STRUCT_FLD(field_length, MAX_FLOAT_STR_LENGTH),
4230  STRUCT_FLD(field_type, MYSQL_TYPE_FLOAT),
4231  STRUCT_FLD(value, 0),
4232  STRUCT_FLD(field_flags, 0),
4233  STRUCT_FLD(old_name, ""),
4234  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
4235 
4236 #define IDX_BUF_STATS_LRU_IO_SUM 28
4237  {STRUCT_FLD(field_name, "LRU_IO_TOTAL"),
4238  STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
4239  STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
4240  STRUCT_FLD(value, 0),
4241  STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
4242  STRUCT_FLD(old_name, ""),
4243  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
4244 
4245 #define IDX_BUF_STATS_LRU_IO_CUR 29
4246  {STRUCT_FLD(field_name, "LRU_IO_CURRENT"),
4247  STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
4248  STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
4249  STRUCT_FLD(value, 0),
4250  STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
4251  STRUCT_FLD(old_name, ""),
4252  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
4253 
4254 #define IDX_BUF_STATS_UNZIP_SUM 30
4255  {STRUCT_FLD(field_name, "UNCOMPRESS_TOTAL"),
4256  STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
4257  STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
4258  STRUCT_FLD(value, 0),
4259  STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
4260  STRUCT_FLD(old_name, ""),
4261  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
4262 
4263 #define IDX_BUF_STATS_UNZIP_CUR 31
4264  {STRUCT_FLD(field_name, "UNCOMPRESS_CURRENT"),
4265  STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
4266  STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
4267  STRUCT_FLD(value, 0),
4268  STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
4269  STRUCT_FLD(old_name, ""),
4270  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
4271 
4272  END_OF_ST_FIELD_INFO
4273 };
4274 
4275 /*******************************************************************/
4279 static
4280 int
4281 i_s_innodb_stats_fill(
4282 /*==================*/
4283  THD* thd,
4284  TABLE_LIST* tables,
4285  const buf_pool_info_t* info)
4287 {
4288  TABLE* table;
4289  Field** fields;
4290 
4291  DBUG_ENTER("i_s_innodb_stats_fill");
4292 
4293  table = tables->table;
4294 
4295  fields = table->field;
4296 
4297  OK(fields[IDX_BUF_STATS_POOL_ID]->store(info->pool_unique_id));
4298 
4299  OK(fields[IDX_BUF_STATS_POOL_SIZE]->store(info->pool_size));
4300 
4301  OK(fields[IDX_BUF_STATS_LRU_LEN]->store(info->lru_len));
4302 
4303  OK(fields[IDX_BUF_STATS_OLD_LRU_LEN]->store(info->old_lru_len));
4304 
4305  OK(fields[IDX_BUF_STATS_FREE_BUFFERS]->store(info->free_list_len));
4306 
4307  OK(fields[IDX_BUF_STATS_FLUSH_LIST_LEN]->store(
4308  info->flush_list_len));
4309 
4310  OK(fields[IDX_BUF_STATS_PENDING_ZIP]->store(info->n_pend_unzip));
4311 
4312  OK(fields[IDX_BUF_STATS_PENDING_READ]->store(info->n_pend_reads));
4313 
4314  OK(fields[IDX_BUF_STATS_FLUSH_LRU]->store(info->n_pending_flush_lru));
4315 
4316  OK(fields[IDX_BUF_STATS_FLUSH_LIST]->store(info->n_pending_flush_list));
4317 
4318  OK(fields[IDX_BUF_STATS_PAGE_YOUNG]->store(info->n_pages_made_young));
4319 
4320  OK(fields[IDX_BUF_STATS_PAGE_NOT_YOUNG]->store(
4321  info->n_pages_not_made_young));
4322 
4323  OK(fields[IDX_BUF_STATS_PAGE_YOUNG_RATE]->store(
4324  info->page_made_young_rate));
4325 
4326  OK(fields[IDX_BUF_STATS_PAGE_NOT_YOUNG_RATE]->store(
4327  info->page_not_made_young_rate));
4328 
4329  OK(fields[IDX_BUF_STATS_PAGE_READ]->store(info->n_pages_read));
4330 
4331  OK(fields[IDX_BUF_STATS_PAGE_CREATED]->store(info->n_pages_created));
4332 
4333  OK(fields[IDX_BUF_STATS_PAGE_WRITTEN]->store(info->n_pages_written));
4334 
4335  OK(fields[IDX_BUF_STATS_GET]->store(info->n_page_gets));
4336 
4337  OK(fields[IDX_BUF_STATS_PAGE_READ_RATE]->store(info->pages_read_rate));
4338 
4339  OK(fields[IDX_BUF_STATS_PAGE_CREATE_RATE]->store(info->pages_created_rate));
4340 
4341  OK(fields[IDX_BUF_STATS_PAGE_WRITTEN_RATE]->store(info->pages_written_rate));
4342 
4343  if (info->n_page_get_delta) {
4344  OK(fields[IDX_BUF_STATS_HIT_RATE]->store(
4345  1000 - (1000 * info->page_read_delta
4346  / info->n_page_get_delta)));
4347 
4348  OK(fields[IDX_BUF_STATS_MADE_YOUNG_PCT]->store(
4349  1000 * info->young_making_delta
4350  / info->n_page_get_delta));
4351 
4352  OK(fields[IDX_BUF_STATS_NOT_MADE_YOUNG_PCT]->store(
4353  1000 * info->not_young_making_delta
4354  / info->n_page_get_delta));
4355  } else {
4356  OK(fields[IDX_BUF_STATS_HIT_RATE]->store(0));
4357  OK(fields[IDX_BUF_STATS_MADE_YOUNG_PCT]->store(0));
4358  OK(fields[IDX_BUF_STATS_NOT_MADE_YOUNG_PCT]->store(0));
4359  }
4360 
4361  OK(fields[IDX_BUF_STATS_READ_AHREAD]->store(info->n_ra_pages_read));
4362 
4363  OK(fields[IDX_BUF_STATS_READ_AHEAD_EVICTED]->store(
4364  info->n_ra_pages_evicted));
4365 
4366  OK(fields[IDX_BUF_STATS_READ_AHEAD_RATE]->store(
4367  info->pages_readahead_rate));
4368 
4369  OK(fields[IDX_BUF_STATS_READ_AHEAD_EVICT_RATE]->store(
4370  info->pages_evicted_rate));
4371 
4372  OK(fields[IDX_BUF_STATS_LRU_IO_SUM]->store(info->io_sum));
4373 
4374  OK(fields[IDX_BUF_STATS_LRU_IO_CUR]->store(info->io_cur));
4375 
4376  OK(fields[IDX_BUF_STATS_UNZIP_SUM]->store(info->unzip_sum));
4377 
4378  OK(fields[IDX_BUF_STATS_UNZIP_CUR]->store( info->unzip_cur));
4379 
4380  DBUG_RETURN(schema_table_store_record(thd, table));
4381 }
4382 
4383 /*******************************************************************/
4387 static
4388 int
4389 i_s_innodb_buffer_stats_fill_table(
4390 /*===============================*/
4391  THD* thd,
4392  TABLE_LIST* tables,
4393  Item* )
4394 {
4395  int status = 0;
4396  buf_pool_info_t* pool_info;
4397 
4398  DBUG_ENTER("i_s_innodb_buffer_fill_general");
4399  RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name);
4400 
4401  /* Only allow the PROCESS privilege holder to access the stats */
4402  if (check_global_access(thd, PROCESS_ACL)) {
4403  DBUG_RETURN(0);
4404  }
4405 
4406  pool_info = (buf_pool_info_t*) mem_zalloc(
4407  srv_buf_pool_instances * sizeof *pool_info);
4408 
4409  /* Walk through each buffer pool */
4410  for (ulint i = 0; i < srv_buf_pool_instances; i++) {
4411  buf_pool_t* buf_pool;
4412 
4413  buf_pool = buf_pool_from_array(i);
4414 
4415  /* Fetch individual buffer pool info */
4416  buf_stats_get_pool_info(buf_pool, i, pool_info);
4417 
4418  status = i_s_innodb_stats_fill(thd, tables, &pool_info[i]);
4419 
4420  /* If something goes wrong, break and return */
4421  if (status) {
4422  break;
4423  }
4424  }
4425 
4426  mem_free(pool_info);
4427 
4428  DBUG_RETURN(status);
4429 }
4430 
4431 /*******************************************************************/
4434 static
4435 int
4436 i_s_innodb_buffer_pool_stats_init(
4437 /*==============================*/
4438  void* p)
4439 {
4440  ST_SCHEMA_TABLE* schema;
4441 
4442  DBUG_ENTER("i_s_innodb_buffer_pool_stats_init");
4443 
4444  schema = reinterpret_cast<ST_SCHEMA_TABLE*>(p);
4445 
4446  schema->fields_info = i_s_innodb_buffer_stats_fields_info;
4447  schema->fill_table = i_s_innodb_buffer_stats_fill_table;
4448 
4449  DBUG_RETURN(0);
4450 }
4451 
4452 UNIV_INTERN struct st_mysql_plugin i_s_innodb_buffer_stats =
4453 {
4454  /* the plugin type (a MYSQL_XXX_PLUGIN value) */
4455  /* int */
4456  STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
4457 
4458  /* pointer to type-specific plugin descriptor */
4459  /* void* */
4460  STRUCT_FLD(info, &i_s_info),
4461 
4462  /* plugin name */
4463  /* const char* */
4464  STRUCT_FLD(name, "INNODB_BUFFER_POOL_STATS"),
4465 
4466  /* plugin author (for SHOW PLUGINS) */
4467  /* const char* */
4468  STRUCT_FLD(author, plugin_author),
4469 
4470  /* general descriptive text (for SHOW PLUGINS) */
4471  /* const char* */
4472  STRUCT_FLD(descr, "InnoDB Buffer Pool Statistics Information "),
4473 
4474  /* the plugin license (PLUGIN_LICENSE_XXX) */
4475  /* int */
4476  STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
4477 
4478  /* the function to invoke when plugin is loaded */
4479  /* int (*)(void*); */
4480  STRUCT_FLD(init, i_s_innodb_buffer_pool_stats_init),
4481 
4482  /* the function to invoke when plugin is unloaded */
4483  /* int (*)(void*); */
4484  STRUCT_FLD(deinit, i_s_common_deinit),
4485 
4486  /* plugin version (for SHOW PLUGINS) */
4487  /* unsigned int */
4488  STRUCT_FLD(version, INNODB_VERSION_SHORT),
4489 
4490  /* struct st_mysql_show_var* */
4491  STRUCT_FLD(status_vars, NULL),
4492 
4493  /* struct st_mysql_sys_var** */
4494  STRUCT_FLD(system_vars, NULL),
4495 
4496  /* reserved for dependency checking */
4497  /* void* */
4498  STRUCT_FLD(__reserved1, NULL),
4499 
4500  /* Plugin flags */
4501  /* unsigned long */
4502  STRUCT_FLD(flags, 0UL),
4503 };
4504 
4505 /* Fields of the dynamic table INNODB_BUFFER_POOL_PAGE. */
4506 static ST_FIELD_INFO i_s_innodb_buffer_page_fields_info[] =
4507 {
4508 #define IDX_BUFFER_POOL_ID 0
4509  {STRUCT_FLD(field_name, "POOL_ID"),
4510  STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
4511  STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
4512  STRUCT_FLD(value, 0),
4513  STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
4514  STRUCT_FLD(old_name, ""),
4515  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
4516 
4517 #define IDX_BUFFER_BLOCK_ID 1
4518  {STRUCT_FLD(field_name, "BLOCK_ID"),
4519  STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
4520  STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
4521  STRUCT_FLD(value, 0),
4522  STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
4523  STRUCT_FLD(old_name, ""),
4524  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
4525 
4526 #define IDX_BUFFER_PAGE_SPACE 2
4527  {STRUCT_FLD(field_name, "SPACE"),
4528  STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
4529  STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
4530  STRUCT_FLD(value, 0),
4531  STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
4532  STRUCT_FLD(old_name, ""),
4533  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
4534 
4535 #define IDX_BUFFER_PAGE_NUM 3
4536  {STRUCT_FLD(field_name, "PAGE_NUMBER"),
4537  STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
4538  STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
4539  STRUCT_FLD(value, 0),
4540  STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
4541  STRUCT_FLD(old_name, ""),
4542  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
4543 
4544 #define IDX_BUFFER_PAGE_TYPE 4
4545  {STRUCT_FLD(field_name, "PAGE_TYPE"),
4546  STRUCT_FLD(field_length, 64),
4547  STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
4548  STRUCT_FLD(value, 0),
4549  STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
4550  STRUCT_FLD(old_name, ""),
4551  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
4552 
4553 #define IDX_BUFFER_PAGE_FLUSH_TYPE 5
4554  {STRUCT_FLD(field_name, "FLUSH_TYPE"),
4555  STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
4556  STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
4557  STRUCT_FLD(value, 0),
4558  STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
4559  STRUCT_FLD(old_name, ""),
4560  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
4561 
4562 #define IDX_BUFFER_PAGE_FIX_COUNT 6
4563  {STRUCT_FLD(field_name, "FIX_COUNT"),
4564  STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
4565  STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
4566  STRUCT_FLD(value, 0),
4567  STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
4568  STRUCT_FLD(old_name, ""),
4569  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
4570 
4571 #define IDX_BUFFER_PAGE_HASHED 7
4572  {STRUCT_FLD(field_name, "IS_HASHED"),
4573  STRUCT_FLD(field_length, 3),
4574  STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
4575  STRUCT_FLD(value, 0),
4576  STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
4577  STRUCT_FLD(old_name, ""),
4578  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
4579 
4580 #define IDX_BUFFER_PAGE_NEWEST_MOD 8
4581  {STRUCT_FLD(field_name, "NEWEST_MODIFICATION"),
4582  STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
4583  STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
4584  STRUCT_FLD(value, 0),
4585  STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
4586  STRUCT_FLD(old_name, ""),
4587  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
4588 
4589 #define IDX_BUFFER_PAGE_OLDEST_MOD 9
4590  {STRUCT_FLD(field_name, "OLDEST_MODIFICATION"),
4591  STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
4592  STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
4593  STRUCT_FLD(value, 0),
4594  STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
4595  STRUCT_FLD(old_name, ""),
4596  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
4597 
4598 #define IDX_BUFFER_PAGE_ACCESS_TIME 10
4599  {STRUCT_FLD(field_name, "ACCESS_TIME"),
4600  STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
4601  STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
4602  STRUCT_FLD(value, 0),
4603  STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
4604  STRUCT_FLD(old_name, ""),
4605  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
4606 
4607 #define IDX_BUFFER_PAGE_TABLE_NAME 11
4608  {STRUCT_FLD(field_name, "TABLE_NAME"),
4609  STRUCT_FLD(field_length, 1024),
4610  STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
4611  STRUCT_FLD(value, 0),
4612  STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
4613  STRUCT_FLD(old_name, ""),
4614  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
4615 
4616 #define IDX_BUFFER_PAGE_INDEX_NAME 12
4617  {STRUCT_FLD(field_name, "INDEX_NAME"),
4618  STRUCT_FLD(field_length, 1024),
4619  STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
4620  STRUCT_FLD(value, 0),
4621  STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
4622  STRUCT_FLD(old_name, ""),
4623  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
4624 
4625 #define IDX_BUFFER_PAGE_NUM_RECS 13
4626  {STRUCT_FLD(field_name, "NUMBER_RECORDS"),
4627  STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
4628  STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
4629  STRUCT_FLD(value, 0),
4630  STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
4631  STRUCT_FLD(old_name, ""),
4632  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
4633 
4634 #define IDX_BUFFER_PAGE_DATA_SIZE 14
4635  {STRUCT_FLD(field_name, "DATA_SIZE"),
4636  STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
4637  STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
4638  STRUCT_FLD(value, 0),
4639  STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
4640  STRUCT_FLD(old_name, ""),
4641  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
4642 
4643 #define IDX_BUFFER_PAGE_ZIP_SIZE 15
4644  {STRUCT_FLD(field_name, "COMPRESSED_SIZE"),
4645  STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
4646  STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
4647  STRUCT_FLD(value, 0),
4648  STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
4649  STRUCT_FLD(old_name, ""),
4650  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
4651 
4652 #define IDX_BUFFER_PAGE_STATE 16
4653  {STRUCT_FLD(field_name, "PAGE_STATE"),
4654  STRUCT_FLD(field_length, 64),
4655  STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
4656  STRUCT_FLD(value, 0),
4657  STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
4658  STRUCT_FLD(old_name, ""),
4659  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
4660 
4661 #define IDX_BUFFER_PAGE_IO_FIX 17
4662  {STRUCT_FLD(field_name, "IO_FIX"),
4663  STRUCT_FLD(field_length, 64),
4664  STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
4665  STRUCT_FLD(value, 0),
4666  STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
4667  STRUCT_FLD(old_name, ""),
4668  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
4669 
4670 #define IDX_BUFFER_PAGE_IS_OLD 18
4671  {STRUCT_FLD(field_name, "IS_OLD"),
4672  STRUCT_FLD(field_length, 3),
4673  STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
4674  STRUCT_FLD(value, 0),
4675  STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
4676  STRUCT_FLD(old_name, ""),
4677  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
4678 
4679 #define IDX_BUFFER_PAGE_FREE_CLOCK 19
4680  {STRUCT_FLD(field_name, "FREE_PAGE_CLOCK"),
4681  STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
4682  STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
4683  STRUCT_FLD(value, 0),
4684  STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
4685  STRUCT_FLD(old_name, ""),
4686  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
4687 
4688  END_OF_ST_FIELD_INFO
4689 };
4690 
4691 /*******************************************************************/
4695 static
4696 int
4697 i_s_innodb_buffer_page_fill(
4698 /*========================*/
4699  THD* thd,
4700  TABLE_LIST* tables,
4701  const buf_page_info_t* info_array,
4703  ulint num_page)
4705 {
4706  TABLE* table;
4707  Field** fields;
4708 
4709  DBUG_ENTER("i_s_innodb_buffer_page_fill");
4710 
4711  table = tables->table;
4712 
4713  fields = table->field;
4714 
4715  /* Iterate through the cached array and fill the I_S table rows */
4716  for (ulint i = 0; i < num_page; i++) {
4717  const buf_page_info_t* page_info;
4718  char table_name[MAX_FULL_NAME_LEN + 1];
4719  const char* table_name_end = NULL;
4720  const char* state_str;
4721  enum buf_page_state state;
4722 
4723  page_info = info_array + i;
4724 
4725  state_str = NULL;
4726 
4727  OK(fields[IDX_BUFFER_POOL_ID]->store(page_info->pool_id));
4728 
4729  OK(fields[IDX_BUFFER_BLOCK_ID]->store(page_info->block_id));
4730 
4731  OK(fields[IDX_BUFFER_PAGE_SPACE]->store(page_info->space_id));
4732 
4733  OK(fields[IDX_BUFFER_PAGE_NUM]->store(page_info->page_num));
4734 
4735  OK(field_store_string(
4736  fields[IDX_BUFFER_PAGE_TYPE],
4737  i_s_page_type[page_info->page_type].type_str));
4738 
4739  OK(fields[IDX_BUFFER_PAGE_FLUSH_TYPE]->store(
4740  page_info->flush_type));
4741 
4742  OK(fields[IDX_BUFFER_PAGE_FIX_COUNT]->store(
4743  page_info->fix_count));
4744 
4745  if (page_info->hashed) {
4746  OK(field_store_string(
4747  fields[IDX_BUFFER_PAGE_HASHED], "YES"));
4748  } else {
4749  OK(field_store_string(
4750  fields[IDX_BUFFER_PAGE_HASHED], "NO"));
4751  }
4752 
4753  OK(fields[IDX_BUFFER_PAGE_NEWEST_MOD]->store(
4754  (longlong) page_info->newest_mod, true));
4755 
4756  OK(fields[IDX_BUFFER_PAGE_OLDEST_MOD]->store(
4757  (longlong) page_info->oldest_mod, true));
4758 
4759  OK(fields[IDX_BUFFER_PAGE_ACCESS_TIME]->store(
4760  page_info->access_time));
4761 
4762  fields[IDX_BUFFER_PAGE_TABLE_NAME]->set_null();
4763 
4764  fields[IDX_BUFFER_PAGE_INDEX_NAME]->set_null();
4765 
4766  /* If this is an index page, fetch the index name
4767  and table name */
4768  if (page_info->page_type == I_S_PAGE_TYPE_INDEX) {
4769  const dict_index_t* index;
4770 
4771  mutex_enter(&dict_sys->mutex);
4773  page_info->index_id);
4774 
4775  if (index) {
4776 
4777  table_name_end = innobase_convert_name(
4778  table_name, sizeof(table_name),
4779  index->table_name,
4780  strlen(index->table_name),
4781  thd, TRUE);
4782 
4783  OK(fields[IDX_BUFFER_PAGE_TABLE_NAME]->store(
4784  table_name,
4785  table_name_end - table_name,
4786  system_charset_info));
4787  fields[IDX_BUFFER_PAGE_TABLE_NAME]->set_notnull();
4788 
4789  OK(field_store_index_name(
4790  fields[IDX_BUFFER_PAGE_INDEX_NAME],
4791  index->name));
4792  }
4793 
4794  mutex_exit(&dict_sys->mutex);
4795  }
4796 
4797  OK(fields[IDX_BUFFER_PAGE_NUM_RECS]->store(
4798  page_info->num_recs));
4799 
4800  OK(fields[IDX_BUFFER_PAGE_DATA_SIZE]->store(
4801  page_info->data_size));
4802 
4803  OK(fields[IDX_BUFFER_PAGE_ZIP_SIZE]->store(
4804  page_info->zip_ssize
4805  ? (UNIV_ZIP_SIZE_MIN >> 1) << page_info->zip_ssize
4806  : 0));
4807 
4808 #if BUF_PAGE_STATE_BITS > 3
4809 # error "BUF_PAGE_STATE_BITS > 3, please ensure that all 1<<BUF_PAGE_STATE_BITS values are checked for"
4810 #endif
4811  state = static_cast<enum buf_page_state>(page_info->page_state);
4812 
4813  switch (state) {
4814  /* First three states are for compression pages and
4815  are not states we would get as we scan pages through
4816  buffer blocks */
4817  case BUF_BLOCK_POOL_WATCH:
4818  case BUF_BLOCK_ZIP_PAGE:
4819  case BUF_BLOCK_ZIP_DIRTY:
4820  state_str = NULL;
4821  break;
4822  case BUF_BLOCK_NOT_USED:
4823  state_str = "NOT_USED";
4824  break;
4826  state_str = "READY_FOR_USE";
4827  break;
4828  case BUF_BLOCK_FILE_PAGE:
4829  state_str = "FILE_PAGE";
4830  break;
4831  case BUF_BLOCK_MEMORY:
4832  state_str = "MEMORY";
4833  break;
4834  case BUF_BLOCK_REMOVE_HASH:
4835  state_str = "REMOVE_HASH";
4836  break;
4837  };
4838 
4839  OK(field_store_string(fields[IDX_BUFFER_PAGE_STATE],
4840  state_str));
4841 
4842  switch (page_info->io_fix) {
4843  case BUF_IO_NONE:
4844  OK(field_store_string(fields[IDX_BUFFER_PAGE_IO_FIX],
4845  "IO_NONE"));
4846  break;
4847  case BUF_IO_READ:
4848  OK(field_store_string(fields[IDX_BUFFER_PAGE_IO_FIX],
4849  "IO_READ"));
4850  break;
4851  case BUF_IO_WRITE:
4852  OK(field_store_string(fields[IDX_BUFFER_PAGE_IO_FIX],
4853  "IO_WRITE"));
4854  break;
4855  case BUF_IO_PIN:
4856  OK(field_store_string(fields[IDX_BUFFER_PAGE_IO_FIX],
4857  "IO_PIN"));
4858  break;
4859  }
4860 
4861  OK(field_store_string(fields[IDX_BUFFER_PAGE_IS_OLD],
4862  (page_info->is_old) ? "YES" : "NO"));
4863 
4864  OK(fields[IDX_BUFFER_PAGE_FREE_CLOCK]->store(
4865  page_info->freed_page_clock));
4866 
4867  if (schema_table_store_record(thd, table)) {
4868  DBUG_RETURN(1);
4869  }
4870  }
4871 
4872  DBUG_RETURN(0);
4873 }
4874 
4875 /*******************************************************************/
4877 static
4878 void
4879 i_s_innodb_set_page_type(
4880 /*=====================*/
4881  buf_page_info_t*page_info,
4883  ulint page_type,
4884  const byte* frame)
4885 {
4886  if (page_type == FIL_PAGE_INDEX) {
4887  const page_t* page = (const page_t*) frame;
4888 
4889  page_info->index_id = btr_page_get_index_id(page);
4890 
4891  /* FIL_PAGE_INDEX is a bit special, its value
4892  is defined as 17855, so we cannot use FIL_PAGE_INDEX
4893  to index into i_s_page_type[] array, its array index
4894  in the i_s_page_type[] array is I_S_PAGE_TYPE_INDEX
4895  (1) for index pages or I_S_PAGE_TYPE_IBUF for
4896  change buffer index pages */
4897  if (page_info->index_id
4898  == static_cast<index_id_t>(DICT_IBUF_ID_MIN
4899  + IBUF_SPACE_ID)) {
4900  page_info->page_type = I_S_PAGE_TYPE_IBUF;
4901  } else {
4902  page_info->page_type = I_S_PAGE_TYPE_INDEX;
4903  }
4904 
4905  page_info->data_size = (ulint)(page_header_get_field(
4906  page, PAGE_HEAP_TOP) - (page_is_comp(page)
4907  ? PAGE_NEW_SUPREMUM_END
4908  : PAGE_OLD_SUPREMUM_END)
4909  - page_header_get_field(page, PAGE_GARBAGE));
4910 
4911  page_info->num_recs = page_get_n_recs(page);
4912  } else if (page_type > FIL_PAGE_TYPE_LAST) {
4913  /* Encountered an unknown page type */
4914  page_info->page_type = I_S_PAGE_TYPE_UNKNOWN;
4915  } else {
4916  /* Make sure we get the right index into the
4917  i_s_page_type[] array */
4918  ut_a(page_type == i_s_page_type[page_type].type_value);
4919 
4920  page_info->page_type = page_type;
4921  }
4922 
4923  if (page_info->page_type == FIL_PAGE_TYPE_ZBLOB
4924  || page_info->page_type == FIL_PAGE_TYPE_ZBLOB2) {
4925  page_info->page_num = mach_read_from_4(
4926  frame + FIL_PAGE_OFFSET);
4927  page_info->space_id = mach_read_from_4(
4929  }
4930 }
4931 /*******************************************************************/
4935 static
4936 void
4937 i_s_innodb_buffer_page_get_info(
4938 /*============================*/
4939  const buf_page_t*bpage,
4940  ulint pool_id,
4941  ulint pos,
4943  buf_page_info_t*page_info)
4946 {
4947  ut_ad(pool_id < MAX_BUFFER_POOLS);
4948 
4949  page_info->pool_id = pool_id;
4950 
4951  page_info->block_id = pos;
4952 
4953  page_info->page_state = buf_page_get_state(bpage);
4954 
4955  /* Only fetch information for buffers that map to a tablespace,
4956  that is, buffer page with state BUF_BLOCK_ZIP_PAGE,
4957  BUF_BLOCK_ZIP_DIRTY or BUF_BLOCK_FILE_PAGE */
4958  if (buf_page_in_file(bpage)) {
4959  const byte* frame;
4960  ulint page_type;
4961 
4962  page_info->space_id = buf_page_get_space(bpage);
4963 
4964  page_info->page_num = buf_page_get_page_no(bpage);
4965 
4966  page_info->flush_type = bpage->flush_type;
4967 
4968  page_info->fix_count = bpage->buf_fix_count;
4969 
4970  page_info->newest_mod = bpage->newest_modification;
4971 
4972  page_info->oldest_mod = bpage->oldest_modification;
4973 
4974  page_info->access_time = bpage->access_time;
4975 
4976  page_info->zip_ssize = bpage->zip.ssize;
4977 
4978  page_info->io_fix = bpage->io_fix;
4979 
4980  page_info->is_old = bpage->old;
4981 
4982  page_info->freed_page_clock = bpage->freed_page_clock;
4983 
4984  switch (buf_page_get_io_fix(bpage)) {
4985  case BUF_IO_NONE:
4986  case BUF_IO_WRITE:
4987  case BUF_IO_PIN:
4988  break;
4989  case BUF_IO_READ:
4990  page_info->page_type = I_S_PAGE_TYPE_UNKNOWN;
4991  return;
4992  }
4993 
4994  if (page_info->page_state == BUF_BLOCK_FILE_PAGE) {
4995  const buf_block_t*block;
4996 
4997  block = reinterpret_cast<const buf_block_t*>(bpage);
4998  frame = block->frame;
4999  page_info->hashed = (block->index != NULL);
5000  } else {
5001  ut_ad(page_info->zip_ssize);
5002  frame = bpage->zip.data;
5003  }
5004 
5005  page_type = fil_page_get_type(frame);
5006 
5007  i_s_innodb_set_page_type(page_info, page_type, frame);
5008  } else {
5009  page_info->page_type = I_S_PAGE_TYPE_UNKNOWN;
5010  }
5011 }
5012 
5013 /*******************************************************************/
5017 static
5018 int
5019 i_s_innodb_fill_buffer_pool(
5020 /*========================*/
5021  THD* thd,
5022  TABLE_LIST* tables,
5023  buf_pool_t* buf_pool,
5024  const ulint pool_id)
5025 {
5026  int status = 0;
5027  mem_heap_t* heap;
5028 
5029  DBUG_ENTER("i_s_innodb_fill_buffer_pool");
5030  RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name);
5031 
5032  heap = mem_heap_create(10000);
5033 
5034  /* Go through each chunk of buffer pool. Currently, we only
5035  have one single chunk for each buffer pool */
5036  for (ulint n = 0; n < buf_pool->n_chunks; n++) {
5037  const buf_block_t* block;
5038  ulint n_blocks;
5039  buf_page_info_t* info_buffer;
5040  ulint num_page;
5041  ulint mem_size;
5042  ulint chunk_size;
5043  ulint num_to_process = 0;
5044  ulint block_id = 0;
5045 
5046  /* Get buffer block of the nth chunk */
5047  block = buf_get_nth_chunk_block(buf_pool, n, &chunk_size);
5048  num_page = 0;
5049 
5050  while (chunk_size > 0) {
5051  /* we cache maximum MAX_BUF_INFO_CACHED number of
5052  buffer page info */
5053  num_to_process = ut_min(chunk_size,
5055 
5056  mem_size = num_to_process * sizeof(buf_page_info_t);
5057 
5058  /* For each chunk, we'll pre-allocate information
5059  structures to cache the page information read from
5060  the buffer pool. Doing so before obtain any mutex */
5061  info_buffer = (buf_page_info_t*) mem_heap_zalloc(
5062  heap, mem_size);
5063 
5064  /* Obtain appropriate mutexes. Since this is diagnostic
5065  buffer pool info printout, we are not required to
5066  preserve the overall consistency, so we can
5067  release mutex periodically */
5068  buf_pool_mutex_enter(buf_pool);
5069 
5070  /* GO through each block in the chunk */
5071  for (n_blocks = num_to_process; n_blocks--; block++) {
5072  i_s_innodb_buffer_page_get_info(
5073  &block->page, pool_id, block_id,
5074  info_buffer + num_page);
5075  block_id++;
5076  num_page++;
5077  }
5078 
5079  buf_pool_mutex_exit(buf_pool);
5080 
5081  /* Fill in information schema table with information
5082  just collected from the buffer chunk scan */
5083  status = i_s_innodb_buffer_page_fill(
5084  thd, tables, info_buffer,
5085  num_page);
5086 
5087  /* If something goes wrong, break and return */
5088  if (status) {
5089  break;
5090  }
5091 
5092  mem_heap_empty(heap);
5093  chunk_size -= num_to_process;
5094  num_page = 0;
5095  }
5096  }
5097 
5098  mem_heap_free(heap);
5099 
5100  DBUG_RETURN(status);
5101 }
5102 
5103 /*******************************************************************/
5107 static
5108 int
5109 i_s_innodb_buffer_page_fill_table(
5110 /*==============================*/
5111  THD* thd,
5112  TABLE_LIST* tables,
5113  Item* )
5114 {
5115  int status = 0;
5116 
5117  DBUG_ENTER("i_s_innodb_buffer_page_fill_table");
5118 
5119  /* deny access to user without PROCESS privilege */
5120  if (check_global_access(thd, PROCESS_ACL)) {
5121  DBUG_RETURN(0);
5122  }
5123 
5124  /* Walk through each buffer pool */
5125  for (ulint i = 0; i < srv_buf_pool_instances; i++) {
5126  buf_pool_t* buf_pool;
5127 
5128  buf_pool = buf_pool_from_array(i);
5129 
5130  /* Fetch information from pages in this buffer pool,
5131  and fill the corresponding I_S table */
5132  status = i_s_innodb_fill_buffer_pool(thd, tables, buf_pool, i);
5133 
5134  /* If something wrong, break and return */
5135  if (status) {
5136  break;
5137  }
5138  }
5139 
5140  DBUG_RETURN(status);
5141 }
5142 
5143 /*******************************************************************/
5146 static
5147 int
5148 i_s_innodb_buffer_page_init(
5149 /*========================*/
5150  void* p)
5151 {
5152  ST_SCHEMA_TABLE* schema;
5153 
5154  DBUG_ENTER("i_s_innodb_buffer_page_init");
5155 
5156  schema = reinterpret_cast<ST_SCHEMA_TABLE*>(p);
5157 
5158  schema->fields_info = i_s_innodb_buffer_page_fields_info;
5159  schema->fill_table = i_s_innodb_buffer_page_fill_table;
5160 
5161  DBUG_RETURN(0);
5162 }
5163 
5164 UNIV_INTERN struct st_mysql_plugin i_s_innodb_buffer_page =
5165 {
5166  /* the plugin type (a MYSQL_XXX_PLUGIN value) */
5167  /* int */
5168  STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
5169 
5170  /* pointer to type-specific plugin descriptor */
5171  /* void* */
5172  STRUCT_FLD(info, &i_s_info),
5173 
5174  /* plugin name */
5175  /* const char* */
5176  STRUCT_FLD(name, "INNODB_BUFFER_PAGE"),
5177 
5178  /* plugin author (for SHOW PLUGINS) */
5179  /* const char* */
5180  STRUCT_FLD(author, plugin_author),
5181 
5182  /* general descriptive text (for SHOW PLUGINS) */
5183  /* const char* */
5184  STRUCT_FLD(descr, "InnoDB Buffer Page Information"),
5185 
5186  /* the plugin license (PLUGIN_LICENSE_XXX) */
5187  /* int */
5188  STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
5189 
5190  /* the function to invoke when plugin is loaded */
5191  /* int (*)(void*); */
5192  STRUCT_FLD(init, i_s_innodb_buffer_page_init),
5193 
5194  /* the function to invoke when plugin is unloaded */
5195  /* int (*)(void*); */
5196  STRUCT_FLD(deinit, i_s_common_deinit),
5197 
5198  /* plugin version (for SHOW PLUGINS) */
5199  /* unsigned int */
5200  STRUCT_FLD(version, INNODB_VERSION_SHORT),
5201 
5202  /* struct st_mysql_show_var* */
5203  STRUCT_FLD(status_vars, NULL),
5204 
5205  /* struct st_mysql_sys_var** */
5206  STRUCT_FLD(system_vars, NULL),
5207 
5208  /* reserved for dependency checking */
5209  /* void* */
5210  STRUCT_FLD(__reserved1, NULL),
5211 
5212  /* Plugin flags */
5213  /* unsigned long */
5214  STRUCT_FLD(flags, 0UL),
5215 };
5216 
5217 static ST_FIELD_INFO i_s_innodb_buf_page_lru_fields_info[] =
5218 {
5219 #define IDX_BUF_LRU_POOL_ID 0
5220  {STRUCT_FLD(field_name, "POOL_ID"),
5221  STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
5222  STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
5223  STRUCT_FLD(value, 0),
5224  STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
5225  STRUCT_FLD(old_name, ""),
5226  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
5227 
5228 #define IDX_BUF_LRU_POS 1
5229  {STRUCT_FLD(field_name, "LRU_POSITION"),
5230  STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
5231  STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
5232  STRUCT_FLD(value, 0),
5233  STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
5234  STRUCT_FLD(old_name, ""),
5235  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
5236 
5237 #define IDX_BUF_LRU_PAGE_SPACE 2
5238  {STRUCT_FLD(field_name, "SPACE"),
5239  STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
5240  STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
5241  STRUCT_FLD(value, 0),
5242  STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
5243  STRUCT_FLD(old_name, ""),
5244  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
5245 
5246 #define IDX_BUF_LRU_PAGE_NUM 3
5247  {STRUCT_FLD(field_name, "PAGE_NUMBER"),
5248  STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
5249  STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
5250  STRUCT_FLD(value, 0),
5251  STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
5252  STRUCT_FLD(old_name, ""),
5253  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
5254 
5255 #define IDX_BUF_LRU_PAGE_TYPE 4
5256  {STRUCT_FLD(field_name, "PAGE_TYPE"),
5257  STRUCT_FLD(field_length, 64),
5258  STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
5259  STRUCT_FLD(value, 0),
5260  STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
5261  STRUCT_FLD(old_name, ""),
5262  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
5263 
5264 #define IDX_BUF_LRU_PAGE_FLUSH_TYPE 5
5265  {STRUCT_FLD(field_name, "FLUSH_TYPE"),
5266  STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
5267  STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
5268  STRUCT_FLD(value, 0),
5269  STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
5270  STRUCT_FLD(old_name, ""),
5271  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
5272 
5273 #define IDX_BUF_LRU_PAGE_FIX_COUNT 6
5274  {STRUCT_FLD(field_name, "FIX_COUNT"),
5275  STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
5276  STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
5277  STRUCT_FLD(value, 0),
5278  STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
5279  STRUCT_FLD(old_name, ""),
5280  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
5281 
5282 #define IDX_BUF_LRU_PAGE_HASHED 7
5283  {STRUCT_FLD(field_name, "IS_HASHED"),
5284  STRUCT_FLD(field_length, 3),
5285  STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
5286  STRUCT_FLD(value, 0),
5287  STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
5288  STRUCT_FLD(old_name, ""),
5289  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
5290 
5291 #define IDX_BUF_LRU_PAGE_NEWEST_MOD 8
5292  {STRUCT_FLD(field_name, "NEWEST_MODIFICATION"),
5293  STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
5294  STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
5295  STRUCT_FLD(value, 0),
5296  STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
5297  STRUCT_FLD(old_name, ""),
5298  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
5299 
5300 #define IDX_BUF_LRU_PAGE_OLDEST_MOD 9
5301  {STRUCT_FLD(field_name, "OLDEST_MODIFICATION"),
5302  STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
5303  STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
5304  STRUCT_FLD(value, 0),
5305  STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
5306  STRUCT_FLD(old_name, ""),
5307  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
5308 
5309 #define IDX_BUF_LRU_PAGE_ACCESS_TIME 10
5310  {STRUCT_FLD(field_name, "ACCESS_TIME"),
5311  STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
5312  STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
5313  STRUCT_FLD(value, 0),
5314  STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
5315  STRUCT_FLD(old_name, ""),
5316  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
5317 
5318 #define IDX_BUF_LRU_PAGE_TABLE_NAME 11
5319  {STRUCT_FLD(field_name, "TABLE_NAME"),
5320  STRUCT_FLD(field_length, 1024),
5321  STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
5322  STRUCT_FLD(value, 0),
5323  STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
5324  STRUCT_FLD(old_name, ""),
5325  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
5326 
5327 #define IDX_BUF_LRU_PAGE_INDEX_NAME 12
5328  {STRUCT_FLD(field_name, "INDEX_NAME"),
5329  STRUCT_FLD(field_length, 1024),
5330  STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
5331  STRUCT_FLD(value, 0),
5332  STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
5333  STRUCT_FLD(old_name, ""),
5334  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
5335 
5336 #define IDX_BUF_LRU_PAGE_NUM_RECS 13
5337  {STRUCT_FLD(field_name, "NUMBER_RECORDS"),
5338  STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
5339  STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
5340  STRUCT_FLD(value, 0),
5341  STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
5342  STRUCT_FLD(old_name, ""),
5343  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
5344 
5345 #define IDX_BUF_LRU_PAGE_DATA_SIZE 14
5346  {STRUCT_FLD(field_name, "DATA_SIZE"),
5347  STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
5348  STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
5349  STRUCT_FLD(value, 0),
5350  STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
5351  STRUCT_FLD(old_name, ""),
5352  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
5353 
5354 #define IDX_BUF_LRU_PAGE_ZIP_SIZE 15
5355  {STRUCT_FLD(field_name, "COMPRESSED_SIZE"),
5356  STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
5357  STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
5358  STRUCT_FLD(value, 0),
5359  STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
5360  STRUCT_FLD(old_name, ""),
5361  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
5362 
5363 #define IDX_BUF_LRU_PAGE_STATE 16
5364  {STRUCT_FLD(field_name, "COMPRESSED"),
5365  STRUCT_FLD(field_length, 3),
5366  STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
5367  STRUCT_FLD(value, 0),
5368  STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
5369  STRUCT_FLD(old_name, ""),
5370  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
5371 
5372 #define IDX_BUF_LRU_PAGE_IO_FIX 17
5373  {STRUCT_FLD(field_name, "IO_FIX"),
5374  STRUCT_FLD(field_length, 64),
5375  STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
5376  STRUCT_FLD(value, 0),
5377  STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
5378  STRUCT_FLD(old_name, ""),
5379  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
5380 
5381 #define IDX_BUF_LRU_PAGE_IS_OLD 18
5382  {STRUCT_FLD(field_name, "IS_OLD"),
5383  STRUCT_FLD(field_length, 3),
5384  STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
5385  STRUCT_FLD(value, 0),
5386  STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
5387  STRUCT_FLD(old_name, ""),
5388  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
5389 
5390 #define IDX_BUF_LRU_PAGE_FREE_CLOCK 19
5391  {STRUCT_FLD(field_name, "FREE_PAGE_CLOCK"),
5392  STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
5393  STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
5394  STRUCT_FLD(value, 0),
5395  STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
5396  STRUCT_FLD(old_name, ""),
5397  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
5398 
5399  END_OF_ST_FIELD_INFO
5400 };
5401 
5402 /*******************************************************************/
5406 static
5407 int
5408 i_s_innodb_buf_page_lru_fill(
5409 /*=========================*/
5410  THD* thd,
5411  TABLE_LIST* tables,
5412  const buf_page_info_t* info_array,
5414  ulint num_page)
5416 {
5417  TABLE* table;
5418  Field** fields;
5419  mem_heap_t* heap;
5420 
5421  DBUG_ENTER("i_s_innodb_buf_page_lru_fill");
5422 
5423  table = tables->table;
5424 
5425  fields = table->field;
5426 
5427  heap = mem_heap_create(1000);
5428 
5429  /* Iterate through the cached array and fill the I_S table rows */
5430  for (ulint i = 0; i < num_page; i++) {
5431  const buf_page_info_t* page_info;
5432  char table_name[MAX_FULL_NAME_LEN + 1];
5433  const char* table_name_end = NULL;
5434  const char* state_str;
5435  enum buf_page_state state;
5436 
5437  state_str = NULL;
5438 
5439  page_info = info_array + i;
5440 
5441  OK(fields[IDX_BUF_LRU_POOL_ID]->store(page_info->pool_id));
5442 
5443  OK(fields[IDX_BUF_LRU_POS]->store(page_info->block_id));
5444 
5445  OK(fields[IDX_BUF_LRU_PAGE_SPACE]->store(page_info->space_id));
5446 
5447  OK(fields[IDX_BUF_LRU_PAGE_NUM]->store(page_info->page_num));
5448 
5449  OK(field_store_string(
5450  fields[IDX_BUF_LRU_PAGE_TYPE],
5451  i_s_page_type[page_info->page_type].type_str));
5452 
5453  OK(fields[IDX_BUF_LRU_PAGE_FLUSH_TYPE]->store(
5454  page_info->flush_type));
5455 
5456  OK(fields[IDX_BUF_LRU_PAGE_FIX_COUNT]->store(
5457  page_info->fix_count));
5458 
5459  if (page_info->hashed) {
5460  OK(field_store_string(
5461  fields[IDX_BUF_LRU_PAGE_HASHED], "YES"));
5462  } else {
5463  OK(field_store_string(
5464  fields[IDX_BUF_LRU_PAGE_HASHED], "NO"));
5465  }
5466 
5467  OK(fields[IDX_BUF_LRU_PAGE_NEWEST_MOD]->store(
5468  page_info->newest_mod, true));
5469 
5470  OK(fields[IDX_BUF_LRU_PAGE_OLDEST_MOD]->store(
5471  page_info->oldest_mod, true));
5472 
5473  OK(fields[IDX_BUF_LRU_PAGE_ACCESS_TIME]->store(
5474  page_info->access_time));
5475 
5476  fields[IDX_BUF_LRU_PAGE_TABLE_NAME]->set_null();
5477 
5478  fields[IDX_BUF_LRU_PAGE_INDEX_NAME]->set_null();
5479 
5480  /* If this is an index page, fetch the index name
5481  and table name */
5482  if (page_info->page_type == I_S_PAGE_TYPE_INDEX) {
5483  const dict_index_t* index;
5484 
5485  mutex_enter(&dict_sys->mutex);
5487  page_info->index_id);
5488 
5489  if (index) {
5490 
5491  table_name_end = innobase_convert_name(
5492  table_name, sizeof(table_name),
5493  index->table_name,
5494  strlen(index->table_name),
5495  thd, TRUE);
5496 
5497  OK(fields[IDX_BUF_LRU_PAGE_TABLE_NAME]->store(
5498  table_name,
5499  table_name_end - table_name,
5500  system_charset_info));
5501  fields[IDX_BUF_LRU_PAGE_TABLE_NAME]->set_notnull();
5502 
5503  OK(field_store_index_name(
5504  fields[IDX_BUF_LRU_PAGE_INDEX_NAME],
5505  index->name));
5506  }
5507 
5508  mutex_exit(&dict_sys->mutex);
5509  }
5510 
5511  OK(fields[IDX_BUF_LRU_PAGE_NUM_RECS]->store(
5512  page_info->num_recs));
5513 
5514  OK(fields[IDX_BUF_LRU_PAGE_DATA_SIZE]->store(
5515  page_info->data_size));
5516 
5517  OK(fields[IDX_BUF_LRU_PAGE_ZIP_SIZE]->store(
5518  page_info->zip_ssize ?
5519  512 << page_info->zip_ssize : 0));
5520 
5521  state = static_cast<enum buf_page_state>(page_info->page_state);
5522 
5523  switch (state) {
5524  /* Compressed page */
5525  case BUF_BLOCK_ZIP_PAGE:
5526  case BUF_BLOCK_ZIP_DIRTY:
5527  state_str = "YES";
5528  break;
5529  /* Uncompressed page */
5530  case BUF_BLOCK_FILE_PAGE:
5531  state_str = "NO";
5532  break;
5533  /* We should not see following states */
5534  case BUF_BLOCK_POOL_WATCH:
5536  case BUF_BLOCK_NOT_USED:
5537  case BUF_BLOCK_MEMORY:
5538  case BUF_BLOCK_REMOVE_HASH:
5539  state_str = NULL;
5540  break;
5541  };
5542 
5543  OK(field_store_string(fields[IDX_BUF_LRU_PAGE_STATE],
5544  state_str));
5545 
5546  switch (page_info->io_fix) {
5547  case BUF_IO_NONE:
5548  OK(field_store_string(fields[IDX_BUF_LRU_PAGE_IO_FIX],
5549  "IO_NONE"));
5550  break;
5551  case BUF_IO_READ:
5552  OK(field_store_string(fields[IDX_BUF_LRU_PAGE_IO_FIX],
5553  "IO_READ"));
5554  break;
5555  case BUF_IO_WRITE:
5556  OK(field_store_string(fields[IDX_BUF_LRU_PAGE_IO_FIX],
5557  "IO_WRITE"));
5558  break;
5559  }
5560 
5561  OK(field_store_string(fields[IDX_BUF_LRU_PAGE_IS_OLD],
5562  (page_info->is_old) ? "YES" : "NO"));
5563 
5564  OK(fields[IDX_BUF_LRU_PAGE_FREE_CLOCK]->store(
5565  page_info->freed_page_clock));
5566 
5567  if (schema_table_store_record(thd, table)) {
5568  mem_heap_free(heap);
5569  DBUG_RETURN(1);
5570  }
5571 
5572  mem_heap_empty(heap);
5573  }
5574 
5575  mem_heap_free(heap);
5576 
5577  DBUG_RETURN(0);
5578 }
5579 
5580 /*******************************************************************/
5584 static
5585 int
5586 i_s_innodb_fill_buffer_lru(
5587 /*=======================*/
5588  THD* thd,
5589  TABLE_LIST* tables,
5590  buf_pool_t* buf_pool,
5591  const ulint pool_id)
5592 {
5593  int status = 0;
5594  buf_page_info_t* info_buffer;
5595  ulint lru_pos = 0;
5596  const buf_page_t* bpage;
5597  ulint lru_len;
5598 
5599  DBUG_ENTER("i_s_innodb_fill_buffer_lru");
5600  RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name);
5601 
5602  /* Obtain buf_pool mutex before allocate info_buffer, since
5603  UT_LIST_GET_LEN(buf_pool->LRU) could change */
5604  buf_pool_mutex_enter(buf_pool);
5605 
5606  lru_len = UT_LIST_GET_LEN(buf_pool->LRU);
5607 
5608  /* Print error message if malloc fail */
5609  info_buffer = (buf_page_info_t*) my_malloc(
5610  lru_len * sizeof *info_buffer, MYF(MY_WME));
5611 
5612  if (!info_buffer) {
5613  status = 1;
5614  goto exit;
5615  }
5616 
5617  memset(info_buffer, 0, lru_len * sizeof *info_buffer);
5618 
5619  /* Walk through Pool's LRU list and print the buffer page
5620  information */
5621  bpage = UT_LIST_GET_LAST(buf_pool->LRU);
5622 
5623  while (bpage != NULL) {
5624  /* Use the same function that collect buffer info for
5625  INNODB_BUFFER_PAGE to get buffer page info */
5626  i_s_innodb_buffer_page_get_info(bpage, pool_id, lru_pos,
5627  (info_buffer + lru_pos));
5628 
5629  bpage = UT_LIST_GET_PREV(LRU, bpage);
5630 
5631  lru_pos++;
5632  }
5633 
5634  ut_ad(lru_pos == lru_len);
5635  ut_ad(lru_pos == UT_LIST_GET_LEN(buf_pool->LRU));
5636 
5637 exit:
5638  buf_pool_mutex_exit(buf_pool);
5639 
5640  if (info_buffer) {
5641  status = i_s_innodb_buf_page_lru_fill(
5642  thd, tables, info_buffer, lru_len);
5643 
5644  my_free(info_buffer);
5645  }
5646 
5647  DBUG_RETURN(status);
5648 }
5649 
5650 /*******************************************************************/
5654 static
5655 int
5656 i_s_innodb_buf_page_lru_fill_table(
5657 /*===============================*/
5658  THD* thd,
5659  TABLE_LIST* tables,
5660  Item* )
5661 {
5662  int status = 0;
5663 
5664  DBUG_ENTER("i_s_innodb_buf_page_lru_fill_table");
5665 
5666  /* deny access to any users that do not hold PROCESS_ACL */
5667  if (check_global_access(thd, PROCESS_ACL)) {
5668  DBUG_RETURN(0);
5669  }
5670 
5671  /* Walk through each buffer pool */
5672  for (ulint i = 0; i < srv_buf_pool_instances; i++) {
5673  buf_pool_t* buf_pool;
5674 
5675  buf_pool = buf_pool_from_array(i);
5676 
5677  /* Fetch information from pages in this buffer pool's LRU list,
5678  and fill the corresponding I_S table */
5679  status = i_s_innodb_fill_buffer_lru(thd, tables, buf_pool, i);
5680 
5681  /* If something wrong, break and return */
5682  if (status) {
5683  break;
5684  }
5685  }
5686 
5687  DBUG_RETURN(status);
5688 }
5689 
5690 /*******************************************************************/
5693 static
5694 int
5695 i_s_innodb_buffer_page_lru_init(
5696 /*============================*/
5697  void* p)
5698 {
5699  ST_SCHEMA_TABLE* schema;
5700 
5701  DBUG_ENTER("i_s_innodb_buffer_page_lru_init");
5702 
5703  schema = reinterpret_cast<ST_SCHEMA_TABLE*>(p);
5704 
5705  schema->fields_info = i_s_innodb_buf_page_lru_fields_info;
5706  schema->fill_table = i_s_innodb_buf_page_lru_fill_table;
5707 
5708  DBUG_RETURN(0);
5709 }
5710 
5711 UNIV_INTERN struct st_mysql_plugin i_s_innodb_buffer_page_lru =
5712 {
5713  /* the plugin type (a MYSQL_XXX_PLUGIN value) */
5714  /* int */
5715  STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
5716 
5717  /* pointer to type-specific plugin descriptor */
5718  /* void* */
5719  STRUCT_FLD(info, &i_s_info),
5720 
5721  /* plugin name */
5722  /* const char* */
5723  STRUCT_FLD(name, "INNODB_BUFFER_PAGE_LRU"),
5724 
5725  /* plugin author (for SHOW PLUGINS) */
5726  /* const char* */
5727  STRUCT_FLD(author, plugin_author),
5728 
5729  /* general descriptive text (for SHOW PLUGINS) */
5730  /* const char* */
5731  STRUCT_FLD(descr, "InnoDB Buffer Page in LRU"),
5732 
5733  /* the plugin license (PLUGIN_LICENSE_XXX) */
5734  /* int */
5735  STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
5736 
5737  /* the function to invoke when plugin is loaded */
5738  /* int (*)(void*); */
5739  STRUCT_FLD(init, i_s_innodb_buffer_page_lru_init),
5740 
5741  /* the function to invoke when plugin is unloaded */
5742  /* int (*)(void*); */
5743  STRUCT_FLD(deinit, i_s_common_deinit),
5744 
5745  /* plugin version (for SHOW PLUGINS) */
5746  /* unsigned int */
5747  STRUCT_FLD(version, INNODB_VERSION_SHORT),
5748 
5749  /* struct st_mysql_show_var* */
5750  STRUCT_FLD(status_vars, NULL),
5751 
5752  /* struct st_mysql_sys_var** */
5753  STRUCT_FLD(system_vars, NULL),
5754 
5755  /* reserved for dependency checking */
5756  /* void* */
5757  STRUCT_FLD(__reserved1, NULL),
5758 
5759  /* Plugin flags */
5760  /* unsigned long */
5761  STRUCT_FLD(flags, 0UL),
5762 };
5763 
5764 /*******************************************************************/
5767 static
5768 int
5769 i_s_common_deinit(
5770 /*==============*/
5771  void* p)
5772 {
5773  DBUG_ENTER("i_s_common_deinit");
5774 
5775  /* Do nothing */
5776 
5777  DBUG_RETURN(0);
5778 }
5779 
5781 /* Fields of the dynamic table INFORMATION_SCHEMA.SYS_TABLES */
5782 static ST_FIELD_INFO innodb_sys_tables_fields_info[] =
5783 {
5784 #define SYS_TABLES_ID 0
5785  {STRUCT_FLD(field_name, "TABLE_ID"),
5786  STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
5787  STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
5788  STRUCT_FLD(value, 0),
5789  STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
5790  STRUCT_FLD(old_name, ""),
5791  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
5792 
5793 #define SYS_TABLES_NAME 1
5794  {STRUCT_FLD(field_name, "NAME"),
5795  STRUCT_FLD(field_length, MAX_FULL_NAME_LEN + 1),
5796  STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
5797  STRUCT_FLD(value, 0),
5798  STRUCT_FLD(field_flags, 0),
5799  STRUCT_FLD(old_name, ""),
5800  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
5801 
5802 #define SYS_TABLES_FLAG 2
5803  {STRUCT_FLD(field_name, "FLAG"),
5804  STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS),
5805  STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
5806  STRUCT_FLD(value, 0),
5807  STRUCT_FLD(field_flags, 0),
5808  STRUCT_FLD(old_name, ""),
5809  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
5810 
5811 #define SYS_TABLES_NUM_COLUMN 3
5812  {STRUCT_FLD(field_name, "N_COLS"),
5813  STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS),
5814  STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
5815  STRUCT_FLD(value, 0),
5816  STRUCT_FLD(field_flags, 0),
5817  STRUCT_FLD(old_name, ""),
5818  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
5819 
5820 #define SYS_TABLES_SPACE 4
5821  {STRUCT_FLD(field_name, "SPACE"),
5822  STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS),
5823  STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
5824  STRUCT_FLD(value, 0),
5825  STRUCT_FLD(field_flags, 0),
5826  STRUCT_FLD(old_name, ""),
5827  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
5828 
5829 #define SYS_TABLES_FILE_FORMAT 5
5830  {STRUCT_FLD(field_name, "FILE_FORMAT"),
5831  STRUCT_FLD(field_length, 10),
5832  STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
5833  STRUCT_FLD(value, 0),
5834  STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
5835  STRUCT_FLD(old_name, ""),
5836  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
5837 
5838 #define SYS_TABLES_ROW_FORMAT 6
5839  {STRUCT_FLD(field_name, "ROW_FORMAT"),
5840  STRUCT_FLD(field_length, 12),
5841  STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
5842  STRUCT_FLD(value, 0),
5843  STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
5844  STRUCT_FLD(old_name, ""),
5845  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
5846 
5847 #define SYS_TABLES_ZIP_PAGE_SIZE 7
5848  {STRUCT_FLD(field_name, "ZIP_PAGE_SIZE"),
5849  STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS),
5850  STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
5851  STRUCT_FLD(value, 0),
5852  STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
5853  STRUCT_FLD(old_name, ""),
5854  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
5855 
5856  END_OF_ST_FIELD_INFO
5857 };
5858 
5859 /**********************************************************************/
5863 static
5864 int
5865 i_s_dict_fill_sys_tables(
5866 /*=====================*/
5867  THD* thd,
5868  dict_table_t* table,
5869  TABLE* table_to_fill)
5870 {
5871  Field** fields;
5872  ulint compact = DICT_TF_GET_COMPACT(table->flags);
5873  ulint atomic_blobs = DICT_TF_HAS_ATOMIC_BLOBS(table->flags);
5874  ulint zip_size = dict_tf_get_zip_size(table->flags);
5875  const char* file_format;
5876  const char* row_format;
5877 
5878  file_format = trx_sys_file_format_id_to_name(atomic_blobs);
5879  if (!compact) {
5880  row_format = "Redundant";
5881  } else if (!atomic_blobs) {
5882  row_format = "Compact";
5883  } else if DICT_TF_GET_ZIP_SSIZE(table->flags) {
5884  row_format = "Compressed";
5885  } else {
5886  row_format = "Dynamic";
5887  }
5888 
5889  DBUG_ENTER("i_s_dict_fill_sys_tables");
5890 
5891  fields = table_to_fill->field;
5892 
5893  OK(fields[SYS_TABLES_ID]->store(longlong(table->id), TRUE));
5894 
5895  OK(field_store_string(fields[SYS_TABLES_NAME], table->name));
5896 
5897  OK(fields[SYS_TABLES_FLAG]->store(table->flags));
5898 
5899  OK(fields[SYS_TABLES_NUM_COLUMN]->store(table->n_cols));
5900 
5901  OK(fields[SYS_TABLES_SPACE]->store(table->space));
5902 
5903  OK(field_store_string(fields[SYS_TABLES_FILE_FORMAT], file_format));
5904 
5905  OK(field_store_string(fields[SYS_TABLES_ROW_FORMAT], row_format));
5906 
5907  OK(fields[SYS_TABLES_ZIP_PAGE_SIZE]->store(zip_size));
5908 
5909  OK(schema_table_store_record(thd, table_to_fill));
5910 
5911  DBUG_RETURN(0);
5912 }
5913 /*******************************************************************/
5917 static
5918 int
5919 i_s_sys_tables_fill_table(
5920 /*======================*/
5921  THD* thd,
5922  TABLE_LIST* tables,
5923  Item* )
5924 {
5925  btr_pcur_t pcur;
5926  const rec_t* rec;
5927  mem_heap_t* heap;
5928  mtr_t mtr;
5929 
5930  DBUG_ENTER("i_s_sys_tables_fill_table");
5931  RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name);
5932 
5933  /* deny access to user without PROCESS_ACL privilege */
5934  if (check_global_access(thd, PROCESS_ACL)) {
5935  DBUG_RETURN(0);
5936  }
5937 
5938  heap = mem_heap_create(1000);
5939  mutex_enter(&(dict_sys->mutex));
5940  mtr_start(&mtr);
5941 
5942  rec = dict_startscan_system(&pcur, &mtr, SYS_TABLES);
5943 
5944  while (rec) {
5945  const char* err_msg;
5946  dict_table_t* table_rec;
5947 
5948  /* Create and populate a dict_table_t structure with
5949  information from SYS_TABLES row */
5951  heap, rec, &table_rec,
5953 
5954  mutex_exit(&dict_sys->mutex);
5955 
5956  if (!err_msg) {
5957  i_s_dict_fill_sys_tables(thd, table_rec, tables->table);
5958  } else {
5959  push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
5960  ER_CANT_FIND_SYSTEM_REC, "%s",
5961  err_msg);
5962  }
5963 
5964  /* Since dict_process_sys_tables_rec_and_mtr_commit()
5965  is called with DICT_TABLE_LOAD_FROM_RECORD, the table_rec
5966  is created in dict_process_sys_tables_rec(), we will
5967  need to free it */
5968  if (table_rec) {
5969  dict_mem_table_free(table_rec);
5970  }
5971 
5972  mem_heap_empty(heap);
5973 
5974  /* Get the next record */
5975  mutex_enter(&dict_sys->mutex);
5976  mtr_start(&mtr);
5977  rec = dict_getnext_system(&pcur, &mtr);
5978  }
5979 
5980  mtr_commit(&mtr);
5981  mutex_exit(&dict_sys->mutex);
5982  mem_heap_free(heap);
5983 
5984  DBUG_RETURN(0);
5985 }
5986 
5987 /*******************************************************************/
5990 static
5991 int
5992 innodb_sys_tables_init(
5993 /*===================*/
5994  void* p)
5995 {
5996  ST_SCHEMA_TABLE* schema;
5997 
5998  DBUG_ENTER("innodb_sys_tables_init");
5999 
6000  schema = (ST_SCHEMA_TABLE*) p;
6001 
6002  schema->fields_info = innodb_sys_tables_fields_info;
6003  schema->fill_table = i_s_sys_tables_fill_table;
6004 
6005  DBUG_RETURN(0);
6006 }
6007 
6008 UNIV_INTERN struct st_mysql_plugin i_s_innodb_sys_tables =
6009 {
6010  /* the plugin type (a MYSQL_XXX_PLUGIN value) */
6011  /* int */
6012  STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
6013 
6014  /* pointer to type-specific plugin descriptor */
6015  /* void* */
6016  STRUCT_FLD(info, &i_s_info),
6017 
6018  /* plugin name */
6019  /* const char* */
6020  STRUCT_FLD(name, "INNODB_SYS_TABLES"),
6021 
6022  /* plugin author (for SHOW PLUGINS) */
6023  /* const char* */
6024  STRUCT_FLD(author, plugin_author),
6025 
6026  /* general descriptive text (for SHOW PLUGINS) */
6027  /* const char* */
6028  STRUCT_FLD(descr, "InnoDB SYS_TABLES"),
6029 
6030  /* the plugin license (PLUGIN_LICENSE_XXX) */
6031  /* int */
6032  STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
6033 
6034  /* the function to invoke when plugin is loaded */
6035  /* int (*)(void*); */
6036  STRUCT_FLD(init, innodb_sys_tables_init),
6037 
6038  /* the function to invoke when plugin is unloaded */
6039  /* int (*)(void*); */
6040  STRUCT_FLD(deinit, i_s_common_deinit),
6041 
6042  /* plugin version (for SHOW PLUGINS) */
6043  /* unsigned int */
6044  STRUCT_FLD(version, INNODB_VERSION_SHORT),
6045 
6046  /* struct st_mysql_show_var* */
6047  STRUCT_FLD(status_vars, NULL),
6048 
6049  /* struct st_mysql_sys_var** */
6050  STRUCT_FLD(system_vars, NULL),
6051 
6052  /* reserved for dependency checking */
6053  /* void* */
6054  STRUCT_FLD(__reserved1, NULL),
6055 
6056  /* Plugin flags */
6057  /* unsigned long */
6058  STRUCT_FLD(flags, 0UL),
6059 };
6060 
6062 /* Fields of the dynamic table INFORMATION_SCHEMA.SYS_TABLESTATS */
6063 static ST_FIELD_INFO innodb_sys_tablestats_fields_info[] =
6064 {
6065 #define SYS_TABLESTATS_ID 0
6066  {STRUCT_FLD(field_name, "TABLE_ID"),
6067  STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
6068  STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
6069  STRUCT_FLD(value, 0),
6070  STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
6071  STRUCT_FLD(old_name, ""),
6072  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
6073 
6074 #define SYS_TABLESTATS_NAME 1
6075  {STRUCT_FLD(field_name, "NAME"),
6076  STRUCT_FLD(field_length, NAME_LEN + 1),
6077  STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
6078  STRUCT_FLD(value, 0),
6079  STRUCT_FLD(field_flags, 0),
6080  STRUCT_FLD(old_name, ""),
6081  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
6082 
6083 #define SYS_TABLESTATS_INIT 2
6084  {STRUCT_FLD(field_name, "STATS_INITIALIZED"),
6085  STRUCT_FLD(field_length, NAME_LEN + 1),
6086  STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
6087  STRUCT_FLD(value, 0),
6088  STRUCT_FLD(field_flags, 0),
6089  STRUCT_FLD(old_name, ""),
6090  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
6091 
6092 #define SYS_TABLESTATS_NROW 3
6093  {STRUCT_FLD(field_name, "NUM_ROWS"),
6094  STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
6095  STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
6096  STRUCT_FLD(value, 0),
6097  STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
6098  STRUCT_FLD(old_name, ""),
6099  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
6100 
6101 #define SYS_TABLESTATS_CLUST_SIZE 4
6102  {STRUCT_FLD(field_name, "CLUST_INDEX_SIZE"),
6103  STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
6104  STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
6105  STRUCT_FLD(value, 0),
6106  STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
6107  STRUCT_FLD(old_name, ""),
6108  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
6109 
6110 #define SYS_TABLESTATS_INDEX_SIZE 5
6111  {STRUCT_FLD(field_name, "OTHER_INDEX_SIZE"),
6112  STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
6113  STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
6114  STRUCT_FLD(value, 0),
6115  STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
6116  STRUCT_FLD(old_name, ""),
6117  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
6118 
6119 #define SYS_TABLESTATS_MODIFIED 6
6120  {STRUCT_FLD(field_name, "MODIFIED_COUNTER"),
6121  STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
6122  STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
6123  STRUCT_FLD(value, 0),
6124  STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
6125  STRUCT_FLD(old_name, ""),
6126  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
6127 
6128 #define SYS_TABLESTATS_AUTONINC 7
6129  {STRUCT_FLD(field_name, "AUTOINC"),
6130  STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
6131  STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
6132  STRUCT_FLD(value, 0),
6133  STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
6134  STRUCT_FLD(old_name, ""),
6135  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
6136 
6137 #define SYS_TABLESTATS_TABLE_REF_COUNT 8
6138  {STRUCT_FLD(field_name, "REF_COUNT"),
6139  STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS),
6140  STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
6141  STRUCT_FLD(value, 0),
6142  STRUCT_FLD(field_flags, 0),
6143  STRUCT_FLD(old_name, ""),
6144  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
6145 
6146  END_OF_ST_FIELD_INFO
6147 };
6148 
6149 /**********************************************************************/
6153 static
6154 int
6155 i_s_dict_fill_sys_tablestats(
6156 /*=========================*/
6157  THD* thd,
6158  dict_table_t* table,
6159  TABLE* table_to_fill)
6160 {
6161  Field** fields;
6162 
6163  DBUG_ENTER("i_s_dict_fill_sys_tablestats");
6164 
6165  fields = table_to_fill->field;
6166 
6167  OK(fields[SYS_TABLESTATS_ID]->store(longlong(table->id), TRUE));
6168 
6169  OK(field_store_string(fields[SYS_TABLESTATS_NAME], table->name));
6170 
6171  dict_table_stats_lock(table, RW_S_LATCH);
6172 
6173  if (table->stat_initialized) {
6174  OK(field_store_string(fields[SYS_TABLESTATS_INIT],
6175  "Initialized"));
6176 
6177  OK(fields[SYS_TABLESTATS_NROW]->store(table->stat_n_rows,
6178  TRUE));
6179 
6180  OK(fields[SYS_TABLESTATS_CLUST_SIZE]->store(
6181  table->stat_clustered_index_size));
6182 
6183  OK(fields[SYS_TABLESTATS_INDEX_SIZE]->store(
6185 
6186  OK(fields[SYS_TABLESTATS_MODIFIED]->store(
6187  (ulint) table->stat_modified_counter));
6188  } else {
6189  OK(field_store_string(fields[SYS_TABLESTATS_INIT],
6190  "Uninitialized"));
6191 
6192  OK(fields[SYS_TABLESTATS_NROW]->store(0, TRUE));
6193 
6194  OK(fields[SYS_TABLESTATS_CLUST_SIZE]->store(0));
6195 
6196  OK(fields[SYS_TABLESTATS_INDEX_SIZE]->store(0));
6197 
6198  OK(fields[SYS_TABLESTATS_MODIFIED]->store(0));
6199  }
6200 
6201  dict_table_stats_unlock(table, RW_S_LATCH);
6202 
6203  OK(fields[SYS_TABLESTATS_AUTONINC]->store(table->autoinc, TRUE));
6204 
6205  OK(fields[SYS_TABLESTATS_TABLE_REF_COUNT]->store(
6206  table->n_ref_count));
6207 
6208  OK(schema_table_store_record(thd, table_to_fill));
6209 
6210  DBUG_RETURN(0);
6211 }
6212 
6213 /*******************************************************************/
6218 static
6219 int
6220 i_s_sys_tables_fill_table_stats(
6221 /*============================*/
6222  THD* thd,
6223  TABLE_LIST* tables,
6224  Item* )
6225 {
6226  btr_pcur_t pcur;
6227  const rec_t* rec;
6228  mem_heap_t* heap;
6229  mtr_t mtr;
6230 
6231  DBUG_ENTER("i_s_sys_tables_fill_table_stats");
6232  RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name);
6233 
6234  /* deny access to user without PROCESS_ACL privilege */
6235  if (check_global_access(thd, PROCESS_ACL)) {
6236  DBUG_RETURN(0);
6237  }
6238 
6239  heap = mem_heap_create(1000);
6240  mutex_enter(&dict_sys->mutex);
6241  mtr_start(&mtr);
6242 
6243  rec = dict_startscan_system(&pcur, &mtr, SYS_TABLES);
6244 
6245  while (rec) {
6246  const char* err_msg;
6247  dict_table_t* table_rec;
6248 
6249  /* Fetch the dict_table_t structure corresponding to
6250  this SYS_TABLES record */
6252  heap, rec, &table_rec,
6254 
6255  mutex_exit(&dict_sys->mutex);
6256 
6257  if (!err_msg) {
6258  i_s_dict_fill_sys_tablestats(thd, table_rec,
6259  tables->table);
6260  } else {
6261  push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
6262  ER_CANT_FIND_SYSTEM_REC, "%s",
6263  err_msg);
6264  }
6265 
6266  mem_heap_empty(heap);
6267 
6268  /* Get the next record */
6269  mutex_enter(&dict_sys->mutex);
6270  mtr_start(&mtr);
6271  rec = dict_getnext_system(&pcur, &mtr);
6272  }
6273 
6274  mtr_commit(&mtr);
6275  mutex_exit(&dict_sys->mutex);
6276  mem_heap_free(heap);
6277 
6278  DBUG_RETURN(0);
6279 }
6280 
6281 /*******************************************************************/
6284 static
6285 int
6286 innodb_sys_tablestats_init(
6287 /*=======================*/
6288  void* p)
6289 {
6290  ST_SCHEMA_TABLE* schema;
6291 
6292  DBUG_ENTER("innodb_sys_tablestats_init");
6293 
6294  schema = (ST_SCHEMA_TABLE*) p;
6295 
6296  schema->fields_info = innodb_sys_tablestats_fields_info;
6297  schema->fill_table = i_s_sys_tables_fill_table_stats;
6298 
6299  DBUG_RETURN(0);
6300 }
6301 
6302 UNIV_INTERN struct st_mysql_plugin i_s_innodb_sys_tablestats =
6303 {
6304  /* the plugin type (a MYSQL_XXX_PLUGIN value) */
6305  /* int */
6306  STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
6307 
6308  /* pointer to type-specific plugin descriptor */
6309  /* void* */
6310  STRUCT_FLD(info, &i_s_info),
6311 
6312  /* plugin name */
6313  /* const char* */
6314  STRUCT_FLD(name, "INNODB_SYS_TABLESTATS"),
6315 
6316  /* plugin author (for SHOW PLUGINS) */
6317  /* const char* */
6318  STRUCT_FLD(author, plugin_author),
6319 
6320  /* general descriptive text (for SHOW PLUGINS) */
6321  /* const char* */
6322  STRUCT_FLD(descr, "InnoDB SYS_TABLESTATS"),
6323 
6324  /* the plugin license (PLUGIN_LICENSE_XXX) */
6325  /* int */
6326  STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
6327 
6328  /* the function to invoke when plugin is loaded */
6329  /* int (*)(void*); */
6330  STRUCT_FLD(init, innodb_sys_tablestats_init),
6331 
6332  /* the function to invoke when plugin is unloaded */
6333  /* int (*)(void*); */
6334  STRUCT_FLD(deinit, i_s_common_deinit),
6335 
6336  /* plugin version (for SHOW PLUGINS) */
6337  /* unsigned int */
6338  STRUCT_FLD(version, INNODB_VERSION_SHORT),
6339 
6340  /* struct st_mysql_show_var* */
6341  STRUCT_FLD(status_vars, NULL),
6342 
6343  /* struct st_mysql_sys_var** */
6344  STRUCT_FLD(system_vars, NULL),
6345 
6346  /* reserved for dependency checking */
6347  /* void* */
6348  STRUCT_FLD(__reserved1, NULL),
6349 
6350  /* Plugin flags */
6351  /* unsigned long */
6352  STRUCT_FLD(flags, 0UL),
6353 };
6354 
6356 /* Fields of the dynamic table INFORMATION_SCHEMA.SYS_INDEXES */
6357 static ST_FIELD_INFO innodb_sysindex_fields_info[] =
6358 {
6359 #define SYS_INDEX_ID 0
6360  {STRUCT_FLD(field_name, "INDEX_ID"),
6361  STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
6362  STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
6363  STRUCT_FLD(value, 0),
6364  STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
6365  STRUCT_FLD(old_name, ""),
6366  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
6367 
6368 #define SYS_INDEX_NAME 1
6369  {STRUCT_FLD(field_name, "NAME"),
6370  STRUCT_FLD(field_length, NAME_LEN + 1),
6371  STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
6372  STRUCT_FLD(value, 0),
6373  STRUCT_FLD(field_flags, 0),
6374  STRUCT_FLD(old_name, ""),
6375  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
6376 
6377 #define SYS_INDEX_TABLE_ID 2
6378  {STRUCT_FLD(field_name, "TABLE_ID"),
6379  STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
6380  STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
6381  STRUCT_FLD(value, 0),
6382  STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
6383  STRUCT_FLD(old_name, ""),
6384  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
6385 
6386 #define SYS_INDEX_TYPE 3
6387  {STRUCT_FLD(field_name, "TYPE"),
6388  STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS),
6389  STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
6390  STRUCT_FLD(value, 0),
6391  STRUCT_FLD(field_flags, 0),
6392  STRUCT_FLD(old_name, ""),
6393  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
6394 
6395 #define SYS_INDEX_NUM_FIELDS 4
6396  {STRUCT_FLD(field_name, "N_FIELDS"),
6397  STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS),
6398  STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
6399  STRUCT_FLD(value, 0),
6400  STRUCT_FLD(field_flags, 0),
6401  STRUCT_FLD(old_name, ""),
6402  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
6403 
6404 #define SYS_INDEX_PAGE_NO 5
6405  {STRUCT_FLD(field_name, "PAGE_NO"),
6406  STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS),
6407  STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
6408  STRUCT_FLD(value, 0),
6409  STRUCT_FLD(field_flags, 0),
6410  STRUCT_FLD(old_name, ""),
6411  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
6412 
6413 #define SYS_INDEX_SPACE 6
6414  {STRUCT_FLD(field_name, "SPACE"),
6415  STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS),
6416  STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
6417  STRUCT_FLD(value, 0),
6418  STRUCT_FLD(field_flags, 0),
6419  STRUCT_FLD(old_name, ""),
6420  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
6421 
6422  END_OF_ST_FIELD_INFO
6423 };
6424 
6425 /**********************************************************************/
6429 static
6430 int
6431 i_s_dict_fill_sys_indexes(
6432 /*======================*/
6433  THD* thd,
6434  table_id_t table_id,
6435  dict_index_t* index,
6437  TABLE* table_to_fill)
6438 {
6439  Field** fields;
6440 
6441  DBUG_ENTER("i_s_dict_fill_sys_indexes");
6442 
6443  fields = table_to_fill->field;
6444 
6445  OK(field_store_index_name(fields[SYS_INDEX_NAME], index->name));
6446 
6447  OK(fields[SYS_INDEX_ID]->store(longlong(index->id), TRUE));
6448 
6449  OK(fields[SYS_INDEX_TABLE_ID]->store(longlong(table_id), TRUE));
6450 
6451  OK(fields[SYS_INDEX_TYPE]->store(index->type));
6452 
6453  OK(fields[SYS_INDEX_NUM_FIELDS]->store(index->n_fields));
6454 
6455  /* FIL_NULL is ULINT32_UNDEFINED */
6456  if (index->page == FIL_NULL) {
6457  OK(fields[SYS_INDEX_PAGE_NO]->store(-1));
6458  } else {
6459  OK(fields[SYS_INDEX_PAGE_NO]->store(index->page));
6460  }
6461 
6462  OK(fields[SYS_INDEX_SPACE]->store(index->space));
6463 
6464  OK(schema_table_store_record(thd, table_to_fill));
6465 
6466  DBUG_RETURN(0);
6467 }
6468 /*******************************************************************/
6472 static
6473 int
6474 i_s_sys_indexes_fill_table(
6475 /*=======================*/
6476  THD* thd,
6477  TABLE_LIST* tables,
6478  Item* )
6479 {
6480  btr_pcur_t pcur;
6481  const rec_t* rec;
6482  mem_heap_t* heap;
6483  mtr_t mtr;
6484 
6485  DBUG_ENTER("i_s_sys_indexes_fill_table");
6486  RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name);
6487 
6488  /* deny access to user without PROCESS_ACL privilege */
6489  if (check_global_access(thd, PROCESS_ACL)) {
6490  DBUG_RETURN(0);
6491  }
6492 
6493  heap = mem_heap_create(1000);
6494  mutex_enter(&dict_sys->mutex);
6495  mtr_start(&mtr);
6496 
6497  /* Start scan the SYS_INDEXES table */
6498  rec = dict_startscan_system(&pcur, &mtr, SYS_INDEXES);
6499 
6500  /* Process each record in the table */
6501  while (rec) {
6502  const char* err_msg;
6503  table_id_t table_id;
6504  dict_index_t index_rec;
6505 
6506  /* Populate a dict_index_t structure with information from
6507  a SYS_INDEXES row */
6508  err_msg = dict_process_sys_indexes_rec(heap, rec, &index_rec,
6509  &table_id);
6510 
6511  mtr_commit(&mtr);
6512  mutex_exit(&dict_sys->mutex);
6513 
6514  if (!err_msg) {
6515  i_s_dict_fill_sys_indexes(thd, table_id, &index_rec,
6516  tables->table);
6517  } else {
6518  push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
6519  ER_CANT_FIND_SYSTEM_REC, "%s",
6520  err_msg);
6521  }
6522 
6523  mem_heap_empty(heap);
6524 
6525  /* Get the next record */
6526  mutex_enter(&dict_sys->mutex);
6527  mtr_start(&mtr);
6528  rec = dict_getnext_system(&pcur, &mtr);
6529  }
6530 
6531  mtr_commit(&mtr);
6532  mutex_exit(&dict_sys->mutex);
6533  mem_heap_free(heap);
6534 
6535  DBUG_RETURN(0);
6536 }
6537 /*******************************************************************/
6540 static
6541 int
6542 innodb_sys_indexes_init(
6543 /*====================*/
6544  void* p)
6545 {
6546  ST_SCHEMA_TABLE* schema;
6547 
6548  DBUG_ENTER("innodb_sys_indexes_init");
6549 
6550  schema = (ST_SCHEMA_TABLE*) p;
6551 
6552  schema->fields_info = innodb_sysindex_fields_info;
6553  schema->fill_table = i_s_sys_indexes_fill_table;
6554 
6555  DBUG_RETURN(0);
6556 }
6557 
6558 UNIV_INTERN struct st_mysql_plugin i_s_innodb_sys_indexes =
6559 {
6560  /* the plugin type (a MYSQL_XXX_PLUGIN value) */
6561  /* int */
6562  STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
6563 
6564  /* pointer to type-specific plugin descriptor */
6565  /* void* */
6566  STRUCT_FLD(info, &i_s_info),
6567 
6568  /* plugin name */
6569  /* const char* */
6570  STRUCT_FLD(name, "INNODB_SYS_INDEXES"),
6571 
6572  /* plugin author (for SHOW PLUGINS) */
6573  /* const char* */
6574  STRUCT_FLD(author, plugin_author),
6575 
6576  /* general descriptive text (for SHOW PLUGINS) */
6577  /* const char* */
6578  STRUCT_FLD(descr, "InnoDB SYS_INDEXES"),
6579 
6580  /* the plugin license (PLUGIN_LICENSE_XXX) */
6581  /* int */
6582  STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
6583 
6584  /* the function to invoke when plugin is loaded */
6585  /* int (*)(void*); */
6586  STRUCT_FLD(init, innodb_sys_indexes_init),
6587 
6588  /* the function to invoke when plugin is unloaded */
6589  /* int (*)(void*); */
6590  STRUCT_FLD(deinit, i_s_common_deinit),
6591 
6592  /* plugin version (for SHOW PLUGINS) */
6593  /* unsigned int */
6594  STRUCT_FLD(version, INNODB_VERSION_SHORT),
6595 
6596  /* struct st_mysql_show_var* */
6597  STRUCT_FLD(status_vars, NULL),
6598 
6599  /* struct st_mysql_sys_var** */
6600  STRUCT_FLD(system_vars, NULL),
6601 
6602  /* reserved for dependency checking */
6603  /* void* */
6604  STRUCT_FLD(__reserved1, NULL),
6605 
6606  /* Plugin flags */
6607  /* unsigned long */
6608  STRUCT_FLD(flags, 0UL),
6609 };
6610 
6612 /* Fields of the dynamic table INFORMATION_SCHEMA.INNODB_SYS_COLUMNS */
6613 static ST_FIELD_INFO innodb_sys_columns_fields_info[] =
6614 {
6615 #define SYS_COLUMN_TABLE_ID 0
6616  {STRUCT_FLD(field_name, "TABLE_ID"),
6617  STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
6618  STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
6619  STRUCT_FLD(value, 0),
6620  STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
6621  STRUCT_FLD(old_name, ""),
6622  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
6623 
6624 #define SYS_COLUMN_NAME 1
6625  {STRUCT_FLD(field_name, "NAME"),
6626  STRUCT_FLD(field_length, NAME_LEN + 1),
6627  STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
6628  STRUCT_FLD(value, 0),
6629  STRUCT_FLD(field_flags, 0),
6630  STRUCT_FLD(old_name, ""),
6631  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
6632 
6633 #define SYS_COLUMN_POSITION 2
6634  {STRUCT_FLD(field_name, "POS"),
6635  STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
6636  STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
6637  STRUCT_FLD(value, 0),
6638  STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
6639  STRUCT_FLD(old_name, ""),
6640  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
6641 
6642 #define SYS_COLUMN_MTYPE 3
6643  {STRUCT_FLD(field_name, "MTYPE"),
6644  STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS),
6645  STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
6646  STRUCT_FLD(value, 0),
6647  STRUCT_FLD(field_flags, 0),
6648  STRUCT_FLD(old_name, ""),
6649  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
6650 
6651 #define SYS_COLUMN__PRTYPE 4
6652  {STRUCT_FLD(field_name, "PRTYPE"),
6653  STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS),
6654  STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
6655  STRUCT_FLD(value, 0),
6656  STRUCT_FLD(field_flags, 0),
6657  STRUCT_FLD(old_name, ""),
6658  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
6659 
6660 #define SYS_COLUMN_COLUMN_LEN 5
6661  {STRUCT_FLD(field_name, "LEN"),
6662  STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS),
6663  STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
6664  STRUCT_FLD(value, 0),
6665  STRUCT_FLD(field_flags, 0),
6666  STRUCT_FLD(old_name, ""),
6667  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
6668 
6669  END_OF_ST_FIELD_INFO
6670 };
6671 
6672 /**********************************************************************/
6676 static
6677 int
6678 i_s_dict_fill_sys_columns(
6679 /*======================*/
6680  THD* thd,
6681  table_id_t table_id,
6682  const char* col_name,
6683  dict_col_t* column,
6685  TABLE* table_to_fill)
6686 {
6687  Field** fields;
6688 
6689  DBUG_ENTER("i_s_dict_fill_sys_columns");
6690 
6691  fields = table_to_fill->field;
6692 
6693  OK(fields[SYS_COLUMN_TABLE_ID]->store(longlong(table_id), TRUE));
6694 
6695  OK(field_store_string(fields[SYS_COLUMN_NAME], col_name));
6696 
6697  OK(fields[SYS_COLUMN_POSITION]->store(column->ind));
6698 
6699  OK(fields[SYS_COLUMN_MTYPE]->store(column->mtype));
6700 
6701  OK(fields[SYS_COLUMN__PRTYPE]->store(column->prtype));
6702 
6703  OK(fields[SYS_COLUMN_COLUMN_LEN]->store(column->len));
6704 
6705  OK(schema_table_store_record(thd, table_to_fill));
6706 
6707  DBUG_RETURN(0);
6708 }
6709 /*******************************************************************/
6713 static
6714 int
6715 i_s_sys_columns_fill_table(
6716 /*=======================*/
6717  THD* thd,
6718  TABLE_LIST* tables,
6719  Item* )
6720 {
6721  btr_pcur_t pcur;
6722  const rec_t* rec;
6723  const char* col_name;
6724  mem_heap_t* heap;
6725  mtr_t mtr;
6726 
6727  DBUG_ENTER("i_s_sys_columns_fill_table");
6728  RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name);
6729 
6730  /* deny access to user without PROCESS_ACL privilege */
6731  if (check_global_access(thd, PROCESS_ACL)) {
6732  DBUG_RETURN(0);
6733  }
6734 
6735  heap = mem_heap_create(1000);
6736  mutex_enter(&dict_sys->mutex);
6737  mtr_start(&mtr);
6738 
6739  rec = dict_startscan_system(&pcur, &mtr, SYS_COLUMNS);
6740 
6741  while (rec) {
6742  const char* err_msg;
6743  dict_col_t column_rec;
6744  table_id_t table_id;
6745 
6746  /* populate a dict_col_t structure with information from
6747  a SYS_COLUMNS row */
6748  err_msg = dict_process_sys_columns_rec(heap, rec, &column_rec,
6749  &table_id, &col_name);
6750 
6751  mtr_commit(&mtr);
6752  mutex_exit(&dict_sys->mutex);
6753 
6754  if (!err_msg) {
6755  i_s_dict_fill_sys_columns(thd, table_id, col_name,
6756  &column_rec,
6757  tables->table);
6758  } else {
6759  push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
6760  ER_CANT_FIND_SYSTEM_REC, "%s",
6761  err_msg);
6762  }
6763 
6764  mem_heap_empty(heap);
6765 
6766  /* Get the next record */
6767  mutex_enter(&dict_sys->mutex);
6768  mtr_start(&mtr);
6769  rec = dict_getnext_system(&pcur, &mtr);
6770  }
6771 
6772  mtr_commit(&mtr);
6773  mutex_exit(&dict_sys->mutex);
6774  mem_heap_free(heap);
6775 
6776  DBUG_RETURN(0);
6777 }
6778 /*******************************************************************/
6781 static
6782 int
6783 innodb_sys_columns_init(
6784 /*====================*/
6785  void* p)
6786 {
6787  ST_SCHEMA_TABLE* schema;
6788 
6789  DBUG_ENTER("innodb_sys_columns_init");
6790 
6791  schema = (ST_SCHEMA_TABLE*) p;
6792 
6793  schema->fields_info = innodb_sys_columns_fields_info;
6794  schema->fill_table = i_s_sys_columns_fill_table;
6795 
6796  DBUG_RETURN(0);
6797 }
6798 
6799 UNIV_INTERN struct st_mysql_plugin i_s_innodb_sys_columns =
6800 {
6801  /* the plugin type (a MYSQL_XXX_PLUGIN value) */
6802  /* int */
6803  STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
6804 
6805  /* pointer to type-specific plugin descriptor */
6806  /* void* */
6807  STRUCT_FLD(info, &i_s_info),
6808 
6809  /* plugin name */
6810  /* const char* */
6811  STRUCT_FLD(name, "INNODB_SYS_COLUMNS"),
6812 
6813  /* plugin author (for SHOW PLUGINS) */
6814  /* const char* */
6815  STRUCT_FLD(author, plugin_author),
6816 
6817  /* general descriptive text (for SHOW PLUGINS) */
6818  /* const char* */
6819  STRUCT_FLD(descr, "InnoDB SYS_COLUMNS"),
6820 
6821  /* the plugin license (PLUGIN_LICENSE_XXX) */
6822  /* int */
6823  STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
6824 
6825  /* the function to invoke when plugin is loaded */
6826  /* int (*)(void*); */
6827  STRUCT_FLD(init, innodb_sys_columns_init),
6828 
6829  /* the function to invoke when plugin is unloaded */
6830  /* int (*)(void*); */
6831  STRUCT_FLD(deinit, i_s_common_deinit),
6832 
6833  /* plugin version (for SHOW PLUGINS) */
6834  /* unsigned int */
6835  STRUCT_FLD(version, INNODB_VERSION_SHORT),
6836 
6837  /* struct st_mysql_show_var* */
6838  STRUCT_FLD(status_vars, NULL),
6839 
6840  /* struct st_mysql_sys_var** */
6841  STRUCT_FLD(system_vars, NULL),
6842 
6843  /* reserved for dependency checking */
6844  /* void* */
6845  STRUCT_FLD(__reserved1, NULL),
6846 
6847  /* Plugin flags */
6848  /* unsigned long */
6849  STRUCT_FLD(flags, 0UL),
6850 };
6851 
6853 /* Fields of the dynamic table INFORMATION_SCHEMA.INNODB_SYS_FIELDS */
6854 static ST_FIELD_INFO innodb_sys_fields_fields_info[] =
6855 {
6856 #define SYS_FIELD_INDEX_ID 0
6857  {STRUCT_FLD(field_name, "INDEX_ID"),
6858  STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
6859  STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
6860  STRUCT_FLD(value, 0),
6861  STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
6862  STRUCT_FLD(old_name, ""),
6863  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
6864 
6865 #define SYS_FIELD_NAME 1
6866  {STRUCT_FLD(field_name, "NAME"),
6867  STRUCT_FLD(field_length, NAME_LEN + 1),
6868  STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
6869  STRUCT_FLD(value, 0),
6870  STRUCT_FLD(field_flags, 0),
6871  STRUCT_FLD(old_name, ""),
6872  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
6873 
6874 #define SYS_FIELD_POS 2
6875  {STRUCT_FLD(field_name, "POS"),
6876  STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS),
6877  STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
6878  STRUCT_FLD(value, 0),
6879  STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
6880  STRUCT_FLD(old_name, ""),
6881  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
6882 
6883  END_OF_ST_FIELD_INFO
6884 };
6885 
6886 /**********************************************************************/
6890 static
6891 int
6892 i_s_dict_fill_sys_fields(
6893 /*=====================*/
6894  THD* thd,
6895  index_id_t index_id,
6896  dict_field_t* field,
6897  ulint pos,
6898  TABLE* table_to_fill)
6899 {
6900  Field** fields;
6901 
6902  DBUG_ENTER("i_s_dict_fill_sys_fields");
6903 
6904  fields = table_to_fill->field;
6905 
6906  OK(fields[SYS_FIELD_INDEX_ID]->store(longlong(index_id), TRUE));
6907 
6908  OK(field_store_string(fields[SYS_FIELD_NAME], field->name));
6909 
6910  OK(fields[SYS_FIELD_POS]->store(pos));
6911 
6912  OK(schema_table_store_record(thd, table_to_fill));
6913 
6914  DBUG_RETURN(0);
6915 }
6916 /*******************************************************************/
6921 static
6922 int
6923 i_s_sys_fields_fill_table(
6924 /*======================*/
6925  THD* thd,
6926  TABLE_LIST* tables,
6927  Item* )
6928 {
6929  btr_pcur_t pcur;
6930  const rec_t* rec;
6931  mem_heap_t* heap;
6932  index_id_t last_id;
6933  mtr_t mtr;
6934 
6935  DBUG_ENTER("i_s_sys_fields_fill_table");
6936  RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name);
6937 
6938  /* deny access to user without PROCESS_ACL privilege */
6939  if (check_global_access(thd, PROCESS_ACL)) {
6940 
6941  DBUG_RETURN(0);
6942  }
6943 
6944  heap = mem_heap_create(1000);
6945  mutex_enter(&dict_sys->mutex);
6946  mtr_start(&mtr);
6947 
6948  /* will save last index id so that we know whether we move to
6949  the next index. This is used to calculate prefix length */
6950  last_id = 0;
6951 
6952  rec = dict_startscan_system(&pcur, &mtr, SYS_FIELDS);
6953 
6954  while (rec) {
6955  ulint pos;
6956  const char* err_msg;
6957  index_id_t index_id;
6958  dict_field_t field_rec;
6959 
6960  /* Populate a dict_field_t structure with information from
6961  a SYS_FIELDS row */
6962  err_msg = dict_process_sys_fields_rec(heap, rec, &field_rec,
6963  &pos, &index_id, last_id);
6964 
6965  mtr_commit(&mtr);
6966  mutex_exit(&dict_sys->mutex);
6967 
6968  if (!err_msg) {
6969  i_s_dict_fill_sys_fields(thd, index_id, &field_rec,
6970  pos, tables->table);
6971  last_id = index_id;
6972  } else {
6973  push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
6974  ER_CANT_FIND_SYSTEM_REC, "%s",
6975  err_msg);
6976  }
6977 
6978  mem_heap_empty(heap);
6979 
6980  /* Get the next record */
6981  mutex_enter(&dict_sys->mutex);
6982  mtr_start(&mtr);
6983  rec = dict_getnext_system(&pcur, &mtr);
6984  }
6985 
6986  mtr_commit(&mtr);
6987  mutex_exit(&dict_sys->mutex);
6988  mem_heap_free(heap);
6989 
6990  DBUG_RETURN(0);
6991 }
6992 /*******************************************************************/
6995 static
6996 int
6997 innodb_sys_fields_init(
6998 /*===================*/
6999  void* p)
7000 {
7001  ST_SCHEMA_TABLE* schema;
7002 
7003  DBUG_ENTER("innodb_sys_field_init");
7004 
7005  schema = (ST_SCHEMA_TABLE*) p;
7006 
7007  schema->fields_info = innodb_sys_fields_fields_info;
7008  schema->fill_table = i_s_sys_fields_fill_table;
7009 
7010  DBUG_RETURN(0);
7011 }
7012 
7013 UNIV_INTERN struct st_mysql_plugin i_s_innodb_sys_fields =
7014 {
7015  /* the plugin type (a MYSQL_XXX_PLUGIN value) */
7016  /* int */
7017  STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
7018 
7019  /* pointer to type-specific plugin descriptor */
7020  /* void* */
7021  STRUCT_FLD(info, &i_s_info),
7022 
7023  /* plugin name */
7024  /* const char* */
7025  STRUCT_FLD(name, "INNODB_SYS_FIELDS"),
7026 
7027  /* plugin author (for SHOW PLUGINS) */
7028  /* const char* */
7029  STRUCT_FLD(author, plugin_author),
7030 
7031  /* general descriptive text (for SHOW PLUGINS) */
7032  /* const char* */
7033  STRUCT_FLD(descr, "InnoDB SYS_FIELDS"),
7034 
7035  /* the plugin license (PLUGIN_LICENSE_XXX) */
7036  /* int */
7037  STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
7038 
7039  /* the function to invoke when plugin is loaded */
7040  /* int (*)(void*); */
7041  STRUCT_FLD(init, innodb_sys_fields_init),
7042 
7043  /* the function to invoke when plugin is unloaded */
7044  /* int (*)(void*); */
7045  STRUCT_FLD(deinit, i_s_common_deinit),
7046 
7047  /* plugin version (for SHOW PLUGINS) */
7048  /* unsigned int */
7049  STRUCT_FLD(version, INNODB_VERSION_SHORT),
7050 
7051  /* struct st_mysql_show_var* */
7052  STRUCT_FLD(status_vars, NULL),
7053 
7054  /* struct st_mysql_sys_var** */
7055  STRUCT_FLD(system_vars, NULL),
7056 
7057  /* reserved for dependency checking */
7058  /* void* */
7059  STRUCT_FLD(__reserved1, NULL),
7060 
7061  /* Plugin flags */
7062  /* unsigned long */
7063  STRUCT_FLD(flags, 0UL),
7064 };
7065 
7067 /* Fields of the dynamic table INFORMATION_SCHEMA.INNODB_SYS_FOREIGN */
7068 static ST_FIELD_INFO innodb_sys_foreign_fields_info[] =
7069 {
7070 #define SYS_FOREIGN_ID 0
7071  {STRUCT_FLD(field_name, "ID"),
7072  STRUCT_FLD(field_length, NAME_LEN + 1),
7073  STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
7074  STRUCT_FLD(value, 0),
7075  STRUCT_FLD(field_flags, 0),
7076  STRUCT_FLD(old_name, ""),
7077  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
7078 
7079 #define SYS_FOREIGN_FOR_NAME 1
7080  {STRUCT_FLD(field_name, "FOR_NAME"),
7081  STRUCT_FLD(field_length, NAME_LEN + 1),
7082  STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
7083  STRUCT_FLD(value, 0),
7084  STRUCT_FLD(field_flags, 0),
7085  STRUCT_FLD(old_name, ""),
7086  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
7087 
7088 #define SYS_FOREIGN_REF_NAME 2
7089  {STRUCT_FLD(field_name, "REF_NAME"),
7090  STRUCT_FLD(field_length, NAME_LEN + 1),
7091  STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
7092  STRUCT_FLD(value, 0),
7093  STRUCT_FLD(field_flags, 0),
7094  STRUCT_FLD(old_name, ""),
7095  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
7096 
7097 #define SYS_FOREIGN_NUM_COL 3
7098  {STRUCT_FLD(field_name, "N_COLS"),
7099  STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS),
7100  STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
7101  STRUCT_FLD(value, 0),
7102  STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
7103  STRUCT_FLD(old_name, ""),
7104  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
7105 
7106 #define SYS_FOREIGN_TYPE 4
7107  {STRUCT_FLD(field_name, "TYPE"),
7108  STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS),
7109  STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
7110  STRUCT_FLD(value, 0),
7111  STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
7112  STRUCT_FLD(old_name, ""),
7113  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
7114 
7115  END_OF_ST_FIELD_INFO
7116 };
7117 
7118 /**********************************************************************/
7122 static
7123 int
7124 i_s_dict_fill_sys_foreign(
7125 /*======================*/
7126  THD* thd,
7127  dict_foreign_t* foreign,
7128  TABLE* table_to_fill)
7129 {
7130  Field** fields;
7131 
7132  DBUG_ENTER("i_s_dict_fill_sys_foreign");
7133 
7134  fields = table_to_fill->field;
7135 
7136  OK(field_store_string(fields[SYS_FOREIGN_ID], foreign->id));
7137 
7138  OK(field_store_string(fields[SYS_FOREIGN_FOR_NAME],
7139  foreign->foreign_table_name));
7140 
7141  OK(field_store_string(fields[SYS_FOREIGN_REF_NAME],
7142  foreign->referenced_table_name));
7143 
7144  OK(fields[SYS_FOREIGN_NUM_COL]->store(foreign->n_fields));
7145 
7146  OK(fields[SYS_FOREIGN_TYPE]->store(foreign->type));
7147 
7148  OK(schema_table_store_record(thd, table_to_fill));
7149 
7150  DBUG_RETURN(0);
7151 }
7152 
7153 /*******************************************************************/
7158 static
7159 int
7160 i_s_sys_foreign_fill_table(
7161 /*=======================*/
7162  THD* thd,
7163  TABLE_LIST* tables,
7164  Item* )
7165 {
7166  btr_pcur_t pcur;
7167  const rec_t* rec;
7168  mem_heap_t* heap;
7169  mtr_t mtr;
7170 
7171  DBUG_ENTER("i_s_sys_foreign_fill_table");
7172  RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name);
7173 
7174  /* deny access to user without PROCESS_ACL privilege */
7175  if (check_global_access(thd, PROCESS_ACL)) {
7176 
7177  DBUG_RETURN(0);
7178  }
7179 
7180  heap = mem_heap_create(1000);
7181  mutex_enter(&dict_sys->mutex);
7182  mtr_start(&mtr);
7183 
7184  rec = dict_startscan_system(&pcur, &mtr, SYS_FOREIGN);
7185 
7186  while (rec) {
7187  const char* err_msg;
7188  dict_foreign_t foreign_rec;
7189 
7190  /* Populate a dict_foreign_t structure with information from
7191  a SYS_FOREIGN row */
7192  err_msg = dict_process_sys_foreign_rec(heap, rec, &foreign_rec);
7193 
7194  mtr_commit(&mtr);
7195  mutex_exit(&dict_sys->mutex);
7196 
7197  if (!err_msg) {
7198  i_s_dict_fill_sys_foreign(thd, &foreign_rec,
7199  tables->table);
7200  } else {
7201  push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
7202  ER_CANT_FIND_SYSTEM_REC, "%s",
7203  err_msg);
7204  }
7205 
7206  mem_heap_empty(heap);
7207 
7208  /* Get the next record */
7209  mtr_start(&mtr);
7210  mutex_enter(&dict_sys->mutex);
7211  rec = dict_getnext_system(&pcur, &mtr);
7212  }
7213 
7214  mtr_commit(&mtr);
7215  mutex_exit(&dict_sys->mutex);
7216  mem_heap_free(heap);
7217 
7218  DBUG_RETURN(0);
7219 }
7220 
7221 /*******************************************************************/
7224 static
7225 int
7226 innodb_sys_foreign_init(
7227 /*====================*/
7228  void* p)
7229 {
7230  ST_SCHEMA_TABLE* schema;
7231 
7232  DBUG_ENTER("innodb_sys_foreign_init");
7233 
7234  schema = (ST_SCHEMA_TABLE*) p;
7235 
7236  schema->fields_info = innodb_sys_foreign_fields_info;
7237  schema->fill_table = i_s_sys_foreign_fill_table;
7238 
7239  DBUG_RETURN(0);
7240 }
7241 
7242 UNIV_INTERN struct st_mysql_plugin i_s_innodb_sys_foreign =
7243 {
7244  /* the plugin type (a MYSQL_XXX_PLUGIN value) */
7245  /* int */
7246  STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
7247 
7248  /* pointer to type-specific plugin descriptor */
7249  /* void* */
7250  STRUCT_FLD(info, &i_s_info),
7251 
7252  /* plugin name */
7253  /* const char* */
7254  STRUCT_FLD(name, "INNODB_SYS_FOREIGN"),
7255 
7256  /* plugin author (for SHOW PLUGINS) */
7257  /* const char* */
7258  STRUCT_FLD(author, plugin_author),
7259 
7260  /* general descriptive text (for SHOW PLUGINS) */
7261  /* const char* */
7262  STRUCT_FLD(descr, "InnoDB SYS_FOREIGN"),
7263 
7264  /* the plugin license (PLUGIN_LICENSE_XXX) */
7265  /* int */
7266  STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
7267 
7268  /* the function to invoke when plugin is loaded */
7269  /* int (*)(void*); */
7270  STRUCT_FLD(init, innodb_sys_foreign_init),
7271 
7272  /* the function to invoke when plugin is unloaded */
7273  /* int (*)(void*); */
7274  STRUCT_FLD(deinit, i_s_common_deinit),
7275 
7276  /* plugin version (for SHOW PLUGINS) */
7277  /* unsigned int */
7278  STRUCT_FLD(version, INNODB_VERSION_SHORT),
7279 
7280  /* struct st_mysql_show_var* */
7281  STRUCT_FLD(status_vars, NULL),
7282 
7283  /* struct st_mysql_sys_var** */
7284  STRUCT_FLD(system_vars, NULL),
7285 
7286  /* reserved for dependency checking */
7287  /* void* */
7288  STRUCT_FLD(__reserved1, NULL),
7289 
7290  /* Plugin flags */
7291  /* unsigned long */
7292  STRUCT_FLD(flags, 0UL),
7293 };
7294 
7296 /* Fields of the dynamic table INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS */
7297 static ST_FIELD_INFO innodb_sys_foreign_cols_fields_info[] =
7298 {
7299 #define SYS_FOREIGN_COL_ID 0
7300  {STRUCT_FLD(field_name, "ID"),
7301  STRUCT_FLD(field_length, NAME_LEN + 1),
7302  STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
7303  STRUCT_FLD(value, 0),
7304  STRUCT_FLD(field_flags, 0),
7305  STRUCT_FLD(old_name, ""),
7306  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
7307 
7308 #define SYS_FOREIGN_COL_FOR_NAME 1
7309  {STRUCT_FLD(field_name, "FOR_COL_NAME"),
7310  STRUCT_FLD(field_length, NAME_LEN + 1),
7311  STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
7312  STRUCT_FLD(value, 0),
7313  STRUCT_FLD(field_flags, 0),
7314  STRUCT_FLD(old_name, ""),
7315  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
7316 
7317 #define SYS_FOREIGN_COL_REF_NAME 2
7318  {STRUCT_FLD(field_name, "REF_COL_NAME"),
7319  STRUCT_FLD(field_length, NAME_LEN + 1),
7320  STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
7321  STRUCT_FLD(value, 0),
7322  STRUCT_FLD(field_flags, 0),
7323  STRUCT_FLD(old_name, ""),
7324  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
7325 
7326 #define SYS_FOREIGN_COL_POS 3
7327  {STRUCT_FLD(field_name, "POS"),
7328  STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS),
7329  STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
7330  STRUCT_FLD(value, 0),
7331  STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
7332  STRUCT_FLD(old_name, ""),
7333  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
7334 
7335  END_OF_ST_FIELD_INFO
7336 };
7337 
7338 /**********************************************************************/
7342 static
7343 int
7344 i_s_dict_fill_sys_foreign_cols(
7345 /*==========================*/
7346  THD* thd,
7347  const char* name,
7348  const char* for_col_name,
7349  const char* ref_col_name,
7351  ulint pos,
7352  TABLE* table_to_fill)
7353 {
7354  Field** fields;
7355 
7356  DBUG_ENTER("i_s_dict_fill_sys_foreign_cols");
7357 
7358  fields = table_to_fill->field;
7359 
7360  OK(field_store_string(fields[SYS_FOREIGN_COL_ID], name));
7361 
7362  OK(field_store_string(fields[SYS_FOREIGN_COL_FOR_NAME], for_col_name));
7363 
7364  OK(field_store_string(fields[SYS_FOREIGN_COL_REF_NAME], ref_col_name));
7365 
7366  OK(fields[SYS_FOREIGN_COL_POS]->store(pos));
7367 
7368  OK(schema_table_store_record(thd, table_to_fill));
7369 
7370  DBUG_RETURN(0);
7371 }
7372 /*******************************************************************/
7377 static
7378 int
7379 i_s_sys_foreign_cols_fill_table(
7380 /*============================*/
7381  THD* thd,
7382  TABLE_LIST* tables,
7383  Item* )
7384 {
7385  btr_pcur_t pcur;
7386  const rec_t* rec;
7387  mem_heap_t* heap;
7388  mtr_t mtr;
7389 
7390  DBUG_ENTER("i_s_sys_foreign_cols_fill_table");
7391  RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name);
7392 
7393  /* deny access to user without PROCESS_ACL privilege */
7394  if (check_global_access(thd, PROCESS_ACL)) {
7395  DBUG_RETURN(0);
7396  }
7397 
7398  heap = mem_heap_create(1000);
7399  mutex_enter(&dict_sys->mutex);
7400  mtr_start(&mtr);
7401 
7402  rec = dict_startscan_system(&pcur, &mtr, SYS_FOREIGN_COLS);
7403 
7404  while (rec) {
7405  const char* err_msg;
7406  const char* name;
7407  const char* for_col_name;
7408  const char* ref_col_name;
7409  ulint pos;
7410 
7411  /* Extract necessary information from a SYS_FOREIGN_COLS row */
7413  heap, rec, &name, &for_col_name, &ref_col_name, &pos);
7414 
7415  mtr_commit(&mtr);
7416  mutex_exit(&dict_sys->mutex);
7417 
7418  if (!err_msg) {
7419  i_s_dict_fill_sys_foreign_cols(
7420  thd, name, for_col_name, ref_col_name, pos,
7421  tables->table);
7422  } else {
7423  push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
7424  ER_CANT_FIND_SYSTEM_REC, "%s",
7425  err_msg);
7426  }
7427 
7428  mem_heap_empty(heap);
7429 
7430  /* Get the next record */
7431  mutex_enter(&dict_sys->mutex);
7432  mtr_start(&mtr);
7433  rec = dict_getnext_system(&pcur, &mtr);
7434  }
7435 
7436  mtr_commit(&mtr);
7437  mutex_exit(&dict_sys->mutex);
7438  mem_heap_free(heap);
7439 
7440  DBUG_RETURN(0);
7441 }
7442 /*******************************************************************/
7445 static
7446 int
7447 innodb_sys_foreign_cols_init(
7448 /*========================*/
7449  void* p)
7450 {
7451  ST_SCHEMA_TABLE* schema;
7452 
7453  DBUG_ENTER("innodb_sys_foreign_cols_init");
7454 
7455  schema = (ST_SCHEMA_TABLE*) p;
7456 
7457  schema->fields_info = innodb_sys_foreign_cols_fields_info;
7458  schema->fill_table = i_s_sys_foreign_cols_fill_table;
7459 
7460  DBUG_RETURN(0);
7461 }
7462 
7463 UNIV_INTERN struct st_mysql_plugin i_s_innodb_sys_foreign_cols =
7464 {
7465  /* the plugin type (a MYSQL_XXX_PLUGIN value) */
7466  /* int */
7467  STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
7468 
7469  /* pointer to type-specific plugin descriptor */
7470  /* void* */
7471  STRUCT_FLD(info, &i_s_info),
7472 
7473  /* plugin name */
7474  /* const char* */
7475  STRUCT_FLD(name, "INNODB_SYS_FOREIGN_COLS"),
7476 
7477  /* plugin author (for SHOW PLUGINS) */
7478  /* const char* */
7479  STRUCT_FLD(author, plugin_author),
7480 
7481  /* general descriptive text (for SHOW PLUGINS) */
7482  /* const char* */
7483  STRUCT_FLD(descr, "InnoDB SYS_FOREIGN_COLS"),
7484 
7485  /* the plugin license (PLUGIN_LICENSE_XXX) */
7486  /* int */
7487  STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
7488 
7489  /* the function to invoke when plugin is loaded */
7490  /* int (*)(void*); */
7491  STRUCT_FLD(init, innodb_sys_foreign_cols_init),
7492 
7493  /* the function to invoke when plugin is unloaded */
7494  /* int (*)(void*); */
7495  STRUCT_FLD(deinit, i_s_common_deinit),
7496 
7497  /* plugin version (for SHOW PLUGINS) */
7498  /* unsigned int */
7499  STRUCT_FLD(version, INNODB_VERSION_SHORT),
7500 
7501  /* struct st_mysql_show_var* */
7502  STRUCT_FLD(status_vars, NULL),
7503 
7504  /* struct st_mysql_sys_var** */
7505  STRUCT_FLD(system_vars, NULL),
7506 
7507  /* reserved for dependency checking */
7508  /* void* */
7509  STRUCT_FLD(__reserved1, NULL),
7510 
7511  /* Plugin flags */
7512  /* unsigned long */
7513  STRUCT_FLD(flags, 0UL),
7514 };
7515 
7517 /* Fields of the dynamic table INFORMATION_SCHEMA.INNODB_SYS_TABLESPACES */
7518 static ST_FIELD_INFO innodb_sys_tablespaces_fields_info[] =
7519 {
7520 #define SYS_TABLESPACES_SPACE 0
7521  {STRUCT_FLD(field_name, "SPACE"),
7522  STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS),
7523  STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
7524  STRUCT_FLD(value, 0),
7525  STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
7526  STRUCT_FLD(old_name, ""),
7527  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
7528 
7529 #define SYS_TABLESPACES_NAME 1
7530  {STRUCT_FLD(field_name, "NAME"),
7531  STRUCT_FLD(field_length, MAX_FULL_NAME_LEN + 1),
7532  STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
7533  STRUCT_FLD(value, 0),
7534  STRUCT_FLD(field_flags, 0),
7535  STRUCT_FLD(old_name, ""),
7536  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
7537 
7538 #define SYS_TABLESPACES_FLAGS 2
7539  {STRUCT_FLD(field_name, "FLAG"),
7540  STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS),
7541  STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
7542  STRUCT_FLD(value, 0),
7543  STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
7544  STRUCT_FLD(old_name, ""),
7545  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
7546 
7547 #define SYS_TABLESPACES_FILE_FORMAT 3
7548  {STRUCT_FLD(field_name, "FILE_FORMAT"),
7549  STRUCT_FLD(field_length, 10),
7550  STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
7551  STRUCT_FLD(value, 0),
7552  STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
7553  STRUCT_FLD(old_name, ""),
7554  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
7555 
7556 #define SYS_TABLESPACES_ROW_FORMAT 4
7557  {STRUCT_FLD(field_name, "ROW_FORMAT"),
7558  STRUCT_FLD(field_length, 22),
7559  STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
7560  STRUCT_FLD(value, 0),
7561  STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
7562  STRUCT_FLD(old_name, ""),
7563  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
7564 
7565 #define SYS_TABLESPACES_PAGE_SIZE 5
7566  {STRUCT_FLD(field_name, "PAGE_SIZE"),
7567  STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS),
7568  STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
7569  STRUCT_FLD(value, 0),
7570  STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
7571  STRUCT_FLD(old_name, ""),
7572  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
7573 
7574 #define SYS_TABLESPACES_ZIP_PAGE_SIZE 6
7575  {STRUCT_FLD(field_name, "ZIP_PAGE_SIZE"),
7576  STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS),
7577  STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
7578  STRUCT_FLD(value, 0),
7579  STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
7580  STRUCT_FLD(old_name, ""),
7581  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
7582 
7583  END_OF_ST_FIELD_INFO
7584 
7585 };
7586 
7587 /**********************************************************************/
7591 static
7592 int
7593 i_s_dict_fill_sys_tablespaces(
7594 /*==========================*/
7595  THD* thd,
7596  ulint space,
7597  const char* name,
7598  ulint flags,
7599  TABLE* table_to_fill)
7600 {
7601  Field** fields;
7602  ulint atomic_blobs = FSP_FLAGS_HAS_ATOMIC_BLOBS(flags);
7603  ulint page_size = fsp_flags_get_page_size(flags);;
7604  ulint zip_size = fsp_flags_get_zip_size(flags);
7605  const char* file_format;
7606  const char* row_format;
7607 
7608  DBUG_ENTER("i_s_dict_fill_sys_tablespaces");
7609 
7610  file_format = trx_sys_file_format_id_to_name(atomic_blobs);
7611  if (!atomic_blobs) {
7612  row_format = "Compact or Redundant";
7613  } else if DICT_TF_GET_ZIP_SSIZE(flags) {
7614  row_format = "Compressed";
7615  } else {
7616  row_format = "Dynamic";
7617  }
7618 
7619  fields = table_to_fill->field;
7620 
7621  OK(fields[SYS_TABLESPACES_SPACE]->store(space));
7622 
7623  OK(field_store_string(fields[SYS_TABLESPACES_NAME], name));
7624 
7625  OK(fields[SYS_TABLESPACES_FLAGS]->store(flags));
7626 
7627  OK(field_store_string(fields[SYS_TABLESPACES_FILE_FORMAT],
7628  file_format));
7629 
7630  OK(field_store_string(fields[SYS_TABLESPACES_ROW_FORMAT],
7631  row_format));
7632 
7633  OK(fields[SYS_TABLESPACES_PAGE_SIZE]->store(page_size));
7634 
7635  OK(fields[SYS_TABLESPACES_ZIP_PAGE_SIZE]->store(zip_size));
7636 
7637  OK(schema_table_store_record(thd, table_to_fill));
7638 
7639  DBUG_RETURN(0);
7640 }
7641 /*******************************************************************/
7646 static
7647 int
7648 i_s_sys_tablespaces_fill_table(
7649 /*===========================*/
7650  THD* thd,
7651  TABLE_LIST* tables,
7652  Item* )
7653 {
7654  btr_pcur_t pcur;
7655  const rec_t* rec;
7656  mem_heap_t* heap;
7657  mtr_t mtr;
7658 
7659  DBUG_ENTER("i_s_sys_tablespaces_fill_table");
7660  RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name);
7661 
7662  /* deny access to user without PROCESS_ACL privilege */
7663  if (check_global_access(thd, PROCESS_ACL)) {
7664  DBUG_RETURN(0);
7665  }
7666 
7667  heap = mem_heap_create(1000);
7668  mutex_enter(&dict_sys->mutex);
7669  mtr_start(&mtr);
7670 
7671  rec = dict_startscan_system(&pcur, &mtr, SYS_TABLESPACES);
7672 
7673  while (rec) {
7674  const char* err_msg;
7675  ulint space;
7676  const char* name;
7677  ulint flags;
7678 
7679  /* Extract necessary information from a SYS_TABLESPACES row */
7680  err_msg = dict_process_sys_tablespaces(
7681  heap, rec, &space, &name, &flags);
7682 
7683  mtr_commit(&mtr);
7684  mutex_exit(&dict_sys->mutex);
7685 
7686  if (!err_msg) {
7687  i_s_dict_fill_sys_tablespaces(
7688  thd, space, name, flags,
7689  tables->table);
7690  } else {
7691  push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
7692  ER_CANT_FIND_SYSTEM_REC, "%s",
7693  err_msg);
7694  }
7695 
7696  mem_heap_empty(heap);
7697 
7698  /* Get the next record */
7699  mutex_enter(&dict_sys->mutex);
7700  mtr_start(&mtr);
7701  rec = dict_getnext_system(&pcur, &mtr);
7702  }
7703 
7704  mtr_commit(&mtr);
7705  mutex_exit(&dict_sys->mutex);
7706  mem_heap_free(heap);
7707 
7708  DBUG_RETURN(0);
7709 }
7710 /*******************************************************************/
7713 static
7714 int
7715 innodb_sys_tablespaces_init(
7716 /*========================*/
7717  void* p)
7718 {
7719  ST_SCHEMA_TABLE* schema;
7720 
7721  DBUG_ENTER("innodb_sys_tablespaces_init");
7722 
7723  schema = (ST_SCHEMA_TABLE*) p;
7724 
7725  schema->fields_info = innodb_sys_tablespaces_fields_info;
7726  schema->fill_table = i_s_sys_tablespaces_fill_table;
7727 
7728  DBUG_RETURN(0);
7729 }
7730 
7731 UNIV_INTERN struct st_mysql_plugin i_s_innodb_sys_tablespaces =
7732 {
7733  /* the plugin type (a MYSQL_XXX_PLUGIN value) */
7734  /* int */
7735  STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
7736 
7737  /* pointer to type-specific plugin descriptor */
7738  /* void* */
7739  STRUCT_FLD(info, &i_s_info),
7740 
7741  /* plugin name */
7742  /* const char* */
7743  STRUCT_FLD(name, "INNODB_SYS_TABLESPACES"),
7744 
7745  /* plugin author (for SHOW PLUGINS) */
7746  /* const char* */
7747  STRUCT_FLD(author, plugin_author),
7748 
7749  /* general descriptive text (for SHOW PLUGINS) */
7750  /* const char* */
7751  STRUCT_FLD(descr, "InnoDB SYS_TABLESPACES"),
7752 
7753  /* the plugin license (PLUGIN_LICENSE_XXX) */
7754  /* int */
7755  STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
7756 
7757  /* the function to invoke when plugin is loaded */
7758  /* int (*)(void*); */
7759  STRUCT_FLD(init, innodb_sys_tablespaces_init),
7760 
7761  /* the function to invoke when plugin is unloaded */
7762  /* int (*)(void*); */
7763  STRUCT_FLD(deinit, i_s_common_deinit),
7764 
7765  /* plugin version (for SHOW PLUGINS) */
7766  /* unsigned int */
7767  STRUCT_FLD(version, INNODB_VERSION_SHORT),
7768 
7769  /* struct st_mysql_show_var* */
7770  STRUCT_FLD(status_vars, NULL),
7771 
7772  /* struct st_mysql_sys_var** */
7773  STRUCT_FLD(system_vars, NULL),
7774 
7775  /* reserved for dependency checking */
7776  /* void* */
7777  STRUCT_FLD(__reserved1, NULL),
7778 
7779  /* Plugin flags */
7780  /* unsigned long */
7781  STRUCT_FLD(flags, 0UL),
7782 };
7783 
7785 /* Fields of the dynamic table INFORMATION_SCHEMA.INNODB_SYS_DATAFILES */
7786 static ST_FIELD_INFO innodb_sys_datafiles_fields_info[] =
7787 {
7788 #define SYS_DATAFILES_SPACE 0
7789  {STRUCT_FLD(field_name, "SPACE"),
7790  STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS),
7791  STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
7792  STRUCT_FLD(value, 0),
7793  STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
7794  STRUCT_FLD(old_name, ""),
7795  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
7796 
7797 #define SYS_DATAFILES_PATH 1
7798  {STRUCT_FLD(field_name, "PATH"),
7799  STRUCT_FLD(field_length, OS_FILE_MAX_PATH),
7800  STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
7801  STRUCT_FLD(value, 0),
7802  STRUCT_FLD(field_flags, 0),
7803  STRUCT_FLD(old_name, ""),
7804  STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
7805 
7806  END_OF_ST_FIELD_INFO
7807 };
7808 
7809 /**********************************************************************/
7813 static
7814 int
7815 i_s_dict_fill_sys_datafiles(
7816 /*========================*/
7817  THD* thd,
7818  ulint space,
7819  const char* path,
7820  TABLE* table_to_fill)
7821 {
7822  Field** fields;
7823 
7824  DBUG_ENTER("i_s_dict_fill_sys_datafiles");
7825 
7826  fields = table_to_fill->field;
7827 
7828  OK(field_store_ulint(fields[SYS_DATAFILES_SPACE], space));
7829 
7830  OK(field_store_string(fields[SYS_DATAFILES_PATH], path));
7831 
7832  OK(schema_table_store_record(thd, table_to_fill));
7833 
7834  DBUG_RETURN(0);
7835 }
7836 /*******************************************************************/
7841 static
7842 int
7843 i_s_sys_datafiles_fill_table(
7844 /*=========================*/
7845  THD* thd,
7846  TABLE_LIST* tables,
7847  Item* )
7848 {
7849  btr_pcur_t pcur;
7850  const rec_t* rec;
7851  mem_heap_t* heap;
7852  mtr_t mtr;
7853 
7854  DBUG_ENTER("i_s_sys_datafiles_fill_table");
7855  RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name);
7856 
7857  /* deny access to user without PROCESS_ACL privilege */
7858  if (check_global_access(thd, PROCESS_ACL)) {
7859  DBUG_RETURN(0);
7860  }
7861 
7862  heap = mem_heap_create(1000);
7863  mutex_enter(&dict_sys->mutex);
7864  mtr_start(&mtr);
7865 
7866  rec = dict_startscan_system(&pcur, &mtr, SYS_DATAFILES);
7867 
7868  while (rec) {
7869  const char* err_msg;
7870  ulint space;
7871  const char* path;
7872 
7873  /* Extract necessary information from a SYS_DATAFILES row */
7874  err_msg = dict_process_sys_datafiles(
7875  heap, rec, &space, &path);
7876 
7877  mtr_commit(&mtr);
7878  mutex_exit(&dict_sys->mutex);
7879 
7880  if (!err_msg) {
7881  i_s_dict_fill_sys_datafiles(
7882  thd, space, path, tables->table);
7883  } else {
7884  push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
7885  ER_CANT_FIND_SYSTEM_REC, "%s",
7886  err_msg);
7887  }
7888 
7889  mem_heap_empty(heap);
7890 
7891  /* Get the next record */
7892  mutex_enter(&dict_sys->mutex);
7893  mtr_start(&mtr);
7894  rec = dict_getnext_system(&pcur, &mtr);
7895  }
7896 
7897  mtr_commit(&mtr);
7898  mutex_exit(&dict_sys->mutex);
7899  mem_heap_free(heap);
7900 
7901  DBUG_RETURN(0);
7902 }
7903 /*******************************************************************/
7906 static
7907 int
7908 innodb_sys_datafiles_init(
7909 /*======================*/
7910  void* p)
7911 {
7912  ST_SCHEMA_TABLE* schema;
7913 
7914  DBUG_ENTER("innodb_sys_datafiles_init");
7915 
7916  schema = (ST_SCHEMA_TABLE*) p;
7917 
7918  schema->fields_info = innodb_sys_datafiles_fields_info;
7919  schema->fill_table = i_s_sys_datafiles_fill_table;
7920 
7921  DBUG_RETURN(0);
7922 }
7923 
7924 UNIV_INTERN struct st_mysql_plugin i_s_innodb_sys_datafiles =
7925 {
7926  /* the plugin type (a MYSQL_XXX_PLUGIN value) */
7927  /* int */
7928  STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
7929 
7930  /* pointer to type-specific plugin descriptor */
7931  /* void* */
7932  STRUCT_FLD(info, &i_s_info),
7933 
7934  /* plugin name */
7935  /* const char* */
7936  STRUCT_FLD(name, "INNODB_SYS_DATAFILES"),
7937 
7938  /* plugin author (for SHOW PLUGINS) */
7939  /* const char* */
7940  STRUCT_FLD(author, plugin_author),
7941 
7942  /* general descriptive text (for SHOW PLUGINS) */
7943  /* const char* */
7944  STRUCT_FLD(descr, "InnoDB SYS_DATAFILES"),
7945 
7946  /* the plugin license (PLUGIN_LICENSE_XXX) */
7947  /* int */
7948  STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
7949 
7950  /* the function to invoke when plugin is loaded */
7951  /* int (*)(void*); */
7952  STRUCT_FLD(init, innodb_sys_datafiles_init),
7953 
7954  /* the function to invoke when plugin is unloaded */
7955  /* int (*)(void*); */
7956  STRUCT_FLD(deinit, i_s_common_deinit),
7957 
7958  /* plugin version (for SHOW PLUGINS) */
7959  /* unsigned int */
7960  STRUCT_FLD(version, INNODB_VERSION_SHORT),
7961 
7962  /* struct st_mysql_show_var* */
7963  STRUCT_FLD(status_vars, NULL),
7964 
7965  /* struct st_mysql_sys_var** */
7966  STRUCT_FLD(system_vars, NULL),
7967 
7968  /* reserved for dependency checking */
7969  /* void* */
7970  STRUCT_FLD(__reserved1, NULL),
7971 
7972  /* Plugin flags */
7973  /* unsigned long */
7974  STRUCT_FLD(flags, 0UL),
7975 };