1 /*****************************************************************************
2
3 Copyright (c) 2007, 2012, Oracle and/or its affiliates. All Rights Reserved.
4 Copyright (c) 2010-2012, Percona Inc. All Rights Reserved.
5
6 This program is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free Software
8 Foundation; version 2 of the License.
9
10 This program is distributed in the hope that it will be useful, but WITHOUT
11 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License along with
15 this program; if not, write to the Free Software Foundation, Inc.,
16 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
17
18 *****************************************************************************/
19
20 #include <mysqld_error.h>
21 #include <sql_acl.h> // PROCESS_ACL
22
23 #include <m_ctype.h>
24 #include <hash.h>
25 #include <myisampack.h>
26 #include <mysys_err.h>
27 #include <my_sys.h>
28 #include "i_s.h"
29 #include <sql_plugin.h>
30 #include <mysql/innodb_priv.h>
31
32 #include <read0i_s.h>
33 #include <trx0i_s.h>
34 #include "srv0start.h" /* for srv_was_started */
35 #include <btr0pcur.h> /* btr_pcur_t */
36 #include <btr0sea.h> /* btr_search_sys */
37 #include <log0recv.h> /* recv_sys */
38 #include <fil0fil.h>
39 #include <dict0crea.h> /* for ZIP_DICT_MAX_* constants */
40
41 /* for XTRADB_RSEG table */
42 #include "trx0trx.h" /* for TRX_QUE_STATE_STR_MAX_LEN */
43 #include "trx0rseg.h" /* for trx_rseg_struct */
44 #include "trx0sys.h" /* for trx_sys */
45
46 #define PLUGIN_AUTHOR "Percona Inc."
47
48 #define OK(expr) \
49 if ((expr) != 0) { \
50 DBUG_RETURN(1); \
51 }
52
53 #if !defined __STRICT_ANSI__ && defined __GNUC__ && (__GNUC__) > 2 && \
54 !defined __INTEL_COMPILER && !defined __clang__
55 #define STRUCT_FLD(name, value) name: value
56 #else
57 #define STRUCT_FLD(name, value) value
58 #endif
59
60 #define END_OF_ST_FIELD_INFO \
61 {STRUCT_FLD(field_name, NULL), \
62 STRUCT_FLD(field_length, 0), \
63 STRUCT_FLD(field_type, MYSQL_TYPE_NULL), \
64 STRUCT_FLD(value, 0), \
65 STRUCT_FLD(field_flags, 0), \
66 STRUCT_FLD(old_name, ""), \
67 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}
68
69
70 /*******************************************************************//**
71 Auxiliary function to store ulint value in MYSQL_TYPE_LONGLONG field.
72 If the value is ULINT_UNDEFINED then the field it set to NULL.
73 @return 0 on success */
74 static
75 int
field_store_ulint(Field * field,ulint n)76 field_store_ulint(
77 /*==============*/
78 Field* field, /*!< in/out: target field for storage */
79 ulint n) /*!< in: value to store */
80 {
81 int ret;
82
83 if (n != ULINT_UNDEFINED) {
84
85 ret = field->store(n);
86 field->set_notnull();
87 } else {
88
89 ret = 0; /* success */
90 field->set_null();
91 }
92
93 return(ret);
94 }
95
96 /*******************************************************************//**
97 Auxiliary function to store char* value in MYSQL_TYPE_STRING field.
98 @return 0 on success */
99 static
100 int
field_store_string(Field * field,const char * str)101 field_store_string(
102 /*===============*/
103 Field* field, /*!< in/out: target field for storage */
104 const char* str) /*!< in: NUL-terminated utf-8 string,
105 or NULL */
106 {
107 int ret;
108
109 if (str != NULL) {
110
111 ret = field->store(str, strlen(str),
112 system_charset_info);
113 field->set_notnull();
114 } else {
115
116 ret = 0; /* success */
117 field->set_null();
118 }
119
120 return(ret);
121 }
122 /** Auxiliary function to store (char*, len) value in MYSQL_TYPE_BLOB
123 field.
124 @return 0 on success */
125 static
126 int
field_store_blob(Field * field,const char * data,uint data_len)127 field_store_blob(
128 Field* field, /*!< in/out: target field for storage */
129 const char* data, /*!< in: pointer to data, or NULL */
130 uint data_len) /*!< in: data length */
131 {
132 int ret;
133
134 if (data != NULL) {
135 ret = field->store(data, data_len, system_charset_info);
136 field->set_notnull();
137 } else {
138 ret = 0; /* success */
139 field->set_null();
140 }
141
142 return(ret);
143 }
144
145 static
146 int
i_s_common_deinit(void * p)147 i_s_common_deinit(
148 /*==============*/
149 void* p) /*!< in/out: table schema object */
150 {
151 DBUG_ENTER("i_s_common_deinit");
152
153 /* Do nothing */
154
155 DBUG_RETURN(0);
156 }
157
158 static ST_FIELD_INFO xtradb_read_view_fields_info[] =
159 {
160 #define READ_VIEW_LOW_LIMIT_NUMBER 0
161 {STRUCT_FLD(field_name, "READ_VIEW_LOW_LIMIT_TRX_NUMBER"),
162 STRUCT_FLD(field_length, TRX_ID_MAX_LEN + 1),
163 STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
164 STRUCT_FLD(value, 0),
165 STRUCT_FLD(field_flags, 0),
166 STRUCT_FLD(old_name, ""),
167 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
168
169 #define READ_VIEW_UPPER_LIMIT_ID 1
170 {STRUCT_FLD(field_name, "READ_VIEW_UPPER_LIMIT_TRX_ID"),
171 STRUCT_FLD(field_length, TRX_ID_MAX_LEN + 1),
172 STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
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 #define READ_VIEW_LOW_LIMIT_ID 2
179 {STRUCT_FLD(field_name, "READ_VIEW_LOW_LIMIT_TRX_ID"),
180
181 STRUCT_FLD(field_length, TRX_ID_MAX_LEN + 1),
182 STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
183 STRUCT_FLD(value, 0),
184 STRUCT_FLD(field_flags, 0),
185 STRUCT_FLD(old_name, ""),
186 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
187
188 END_OF_ST_FIELD_INFO
189 };
190
xtradb_read_view_fill_table(THD * thd,TABLE_LIST * tables,Item *)191 static int xtradb_read_view_fill_table(THD* thd, TABLE_LIST* tables, Item*)
192 {
193 Field** fields;
194 TABLE* table;
195 char trx_id[TRX_ID_MAX_LEN + 1];
196
197
198 DBUG_ENTER("xtradb_read_view_fill_table");
199
200 /* deny access to non-superusers */
201 if (check_global_access(thd, PROCESS_ACL)) {
202
203 DBUG_RETURN(0);
204 }
205
206 table = tables->table;
207 fields = table->field;
208
209 i_s_xtradb_read_view_t read_view;
210
211 if (read_fill_i_s_xtradb_read_view(&read_view) == NULL)
212 DBUG_RETURN(0);
213
214 ut_snprintf(trx_id, sizeof(trx_id), TRX_ID_FMT, read_view.low_limit_no);
215 OK(field_store_string(fields[READ_VIEW_LOW_LIMIT_NUMBER], trx_id));
216
217 ut_snprintf(trx_id, sizeof(trx_id), TRX_ID_FMT, read_view.up_limit_id);
218 OK(field_store_string(fields[READ_VIEW_UPPER_LIMIT_ID], trx_id));
219
220 ut_snprintf(trx_id, sizeof(trx_id), TRX_ID_FMT, read_view.low_limit_id);
221 OK(field_store_string(fields[READ_VIEW_LOW_LIMIT_ID], trx_id));
222
223 OK(schema_table_store_record(thd, table));
224
225 DBUG_RETURN(0);
226 }
227
228
xtradb_read_view_init(void * p)229 static int xtradb_read_view_init(void* p)
230 {
231 ST_SCHEMA_TABLE* schema;
232
233 DBUG_ENTER("xtradb_read_view_init");
234
235 schema = (ST_SCHEMA_TABLE*) p;
236
237 schema->fields_info = xtradb_read_view_fields_info;
238 schema->fill_table = xtradb_read_view_fill_table;
239
240 DBUG_RETURN(0);
241 }
242
243 static struct st_mysql_information_schema i_s_info =
244 {
245 MYSQL_INFORMATION_SCHEMA_INTERFACE_VERSION
246 };
247
248 struct st_mysql_plugin i_s_xtradb_read_view =
249 {
250 STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
251 STRUCT_FLD(info, &i_s_info),
252 STRUCT_FLD(name, "XTRADB_READ_VIEW"),
253 STRUCT_FLD(author, PLUGIN_AUTHOR),
254 STRUCT_FLD(descr, "InnoDB Read View information"),
255 STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
256 STRUCT_FLD(init, xtradb_read_view_init),
257 STRUCT_FLD(deinit, i_s_common_deinit),
258 STRUCT_FLD(version, INNODB_VERSION_SHORT),
259 STRUCT_FLD(status_vars, NULL),
260 STRUCT_FLD(system_vars, NULL),
261 STRUCT_FLD(__reserved1, NULL),
262 STRUCT_FLD(flags, 0UL),
263 };
264
265 static ST_FIELD_INFO xtradb_internal_hash_tables_fields_info[] =
266 {
267 #define INT_HASH_TABLES_NAME 0
268 {STRUCT_FLD(field_name, "INTERNAL_HASH_TABLE_NAME"),
269 STRUCT_FLD(field_length, 100),
270 STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
271 STRUCT_FLD(value, 0),
272 STRUCT_FLD(field_flags, 0),
273 STRUCT_FLD(old_name, ""),
274 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
275
276 #define INT_HASH_TABLES_TOTAL 1
277 {STRUCT_FLD(field_name, "TOTAL_MEMORY"),
278 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
279 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
280 STRUCT_FLD(value, 0),
281 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
282 STRUCT_FLD(old_name, ""),
283 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
284
285 #define INT_HASH_TABLES_CONSTANT 2
286 {STRUCT_FLD(field_name, "CONSTANT_MEMORY"),
287 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
288 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
289 STRUCT_FLD(value, 0),
290 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
291 STRUCT_FLD(old_name, ""),
292 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
293
294 #define INT_HASH_TABLES_VARIABLE 3
295 {STRUCT_FLD(field_name, "VARIABLE_MEMORY"),
296 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
297 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
298 STRUCT_FLD(value, 0),
299 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
300 STRUCT_FLD(old_name, ""),
301 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
302
303 END_OF_ST_FIELD_INFO
304 };
305
xtradb_internal_hash_tables_fill_table(THD * thd,TABLE_LIST * tables,Item *)306 static int xtradb_internal_hash_tables_fill_table(THD* thd, TABLE_LIST* tables, Item*)
307 {
308 Field** fields;
309 TABLE* table;
310
311 DBUG_ENTER("xtradb_internal_hash_tables_fill_table");
312
313 /* deny access to non-superusers */
314 if (check_global_access(thd, PROCESS_ACL)) {
315
316 DBUG_RETURN(0);
317 }
318
319 table = tables->table;
320 fields = table->field;
321
322 /* Calculate AHI constant and variable memory allocations */
323
324 ulong btr_search_sys_constant = btr_search_sys_constant_mem;
325 os_rmb;
326 ulong btr_search_sys_variable = btr_search_sys_variable_mem;
327 size_t dict_sys_hash_size = dict_sys->hash_size;
328 ulong dict_sys_size = dict_sys->size;
329
330 OK(field_store_string(fields[INT_HASH_TABLES_NAME],
331 "Adaptive hash index"));
332 OK(field_store_ulint(fields[INT_HASH_TABLES_TOTAL],
333 btr_search_sys_variable + btr_search_sys_constant));
334 OK(field_store_ulint(fields[INT_HASH_TABLES_CONSTANT],
335 btr_search_sys_constant));
336 OK(field_store_ulint(fields[INT_HASH_TABLES_VARIABLE],
337 btr_search_sys_variable));
338 OK(schema_table_store_record(thd, table));
339
340 {
341 OK(field_store_string(fields[INT_HASH_TABLES_NAME],
342 "Page hash (buffer pool 0 only)"));
343 OK(field_store_ulint(fields[INT_HASH_TABLES_TOTAL],
344 (ulong) (buf_pool_from_array(0)->page_hash->n_cells * sizeof(hash_cell_t))));
345 OK(field_store_ulint(fields[INT_HASH_TABLES_CONSTANT],
346 (ulong) (buf_pool_from_array(0)->page_hash->n_cells * sizeof(hash_cell_t))));
347 OK(field_store_ulint(fields[INT_HASH_TABLES_VARIABLE], 0));
348 OK(schema_table_store_record(thd, table));
349
350 }
351
352 OK(field_store_string(fields[INT_HASH_TABLES_NAME],
353 "Dictionary Cache"));
354 OK(field_store_ulint(fields[INT_HASH_TABLES_TOTAL],
355 dict_sys_hash_size + dict_sys_size));
356 OK(field_store_ulint(fields[INT_HASH_TABLES_CONSTANT],
357 dict_sys_hash_size));
358 OK(field_store_ulint(fields[INT_HASH_TABLES_VARIABLE],
359 dict_sys_size));
360 OK(schema_table_store_record(thd, table));
361
362 {
363 OK(field_store_string(fields[INT_HASH_TABLES_NAME],
364 "File system"));
365 OK(field_store_ulint(fields[INT_HASH_TABLES_TOTAL],
366 (ulong) (fil_system_hash_cells()
367 * sizeof(hash_cell_t)
368 + fil_system_hash_nodes())));
369 OK(field_store_ulint(fields[INT_HASH_TABLES_CONSTANT],
370 (ulong) (fil_system_hash_cells() * sizeof(hash_cell_t))));
371 OK(field_store_ulint(fields[INT_HASH_TABLES_VARIABLE],
372 (ulong) fil_system_hash_nodes()));
373 OK(schema_table_store_record(thd, table));
374
375 }
376
377 {
378 ulint lock_sys_constant, lock_sys_variable;
379
380 trx_i_s_get_lock_sys_memory_usage(&lock_sys_constant,
381 &lock_sys_variable);
382
383 OK(field_store_string(fields[INT_HASH_TABLES_NAME], "Lock System"));
384 OK(field_store_ulint(fields[INT_HASH_TABLES_TOTAL],
385 lock_sys_constant + lock_sys_variable));
386 OK(field_store_ulint(fields[INT_HASH_TABLES_CONSTANT],
387 lock_sys_constant));
388 OK(field_store_ulint(fields[INT_HASH_TABLES_VARIABLE],
389 lock_sys_variable));
390 OK(schema_table_store_record(thd, table));
391 }
392
393 if (recv_sys)
394 {
395 ulint recv_sys_subtotal = ((recv_sys && recv_sys->addr_hash)
396 ? mem_heap_get_size(recv_sys->heap) : 0);
397
398 OK(field_store_string(fields[INT_HASH_TABLES_NAME], "Recovery System"));
399 OK(field_store_ulint(fields[INT_HASH_TABLES_TOTAL],
400 ((recv_sys->addr_hash) ? (recv_sys->addr_hash->n_cells * sizeof(hash_cell_t)) : 0) + recv_sys_subtotal));
401 OK(field_store_ulint(fields[INT_HASH_TABLES_CONSTANT],
402 ((recv_sys->addr_hash) ? (recv_sys->addr_hash->n_cells * sizeof(hash_cell_t)) : 0)));
403 OK(field_store_ulint(fields[INT_HASH_TABLES_VARIABLE],
404 recv_sys_subtotal));
405 OK(schema_table_store_record(thd, table));
406 }
407
408 DBUG_RETURN(0);
409 }
410
xtradb_internal_hash_tables_init(void * p)411 static int xtradb_internal_hash_tables_init(void* p)
412 {
413 ST_SCHEMA_TABLE* schema;
414
415 DBUG_ENTER("xtradb_internal_hash_tables_init");
416
417 schema = (ST_SCHEMA_TABLE*) p;
418
419 schema->fields_info = xtradb_internal_hash_tables_fields_info;
420 schema->fill_table = xtradb_internal_hash_tables_fill_table;
421
422 DBUG_RETURN(0);
423 }
424
425 struct st_mysql_plugin i_s_xtradb_internal_hash_tables =
426 {
427 STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
428 STRUCT_FLD(info, &i_s_info),
429 STRUCT_FLD(name, "XTRADB_INTERNAL_HASH_TABLES"),
430 STRUCT_FLD(author, PLUGIN_AUTHOR),
431 STRUCT_FLD(descr, "InnoDB internal hash tables information"),
432 STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
433 STRUCT_FLD(init, xtradb_internal_hash_tables_init),
434 STRUCT_FLD(deinit, i_s_common_deinit),
435 STRUCT_FLD(version, INNODB_VERSION_SHORT),
436 STRUCT_FLD(status_vars, NULL),
437 STRUCT_FLD(system_vars, NULL),
438 STRUCT_FLD(__reserved1, NULL),
439 STRUCT_FLD(flags, 0UL),
440 };
441
442
443 /***********************************************************************
444 */
445 static ST_FIELD_INFO i_s_xtradb_rseg_fields_info[] =
446 {
447 {STRUCT_FLD(field_name, "rseg_id"),
448 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
449 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
450 STRUCT_FLD(value, 0),
451 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
452 STRUCT_FLD(old_name, ""),
453 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
454
455 {STRUCT_FLD(field_name, "space_id"),
456 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
457 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
458 STRUCT_FLD(value, 0),
459 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
460 STRUCT_FLD(old_name, ""),
461 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
462
463 {STRUCT_FLD(field_name, "physical_page_size"),
464 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
465 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
466 STRUCT_FLD(value, 0),
467 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
468 STRUCT_FLD(old_name, ""),
469 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
470
471 {STRUCT_FLD(field_name, "logical_page_size"),
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 {STRUCT_FLD(field_name, "is_compressed"),
480 STRUCT_FLD(field_length, 1),
481 STRUCT_FLD(field_type, MYSQL_TYPE_TINY),
482 STRUCT_FLD(value, 0),
483 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
484 STRUCT_FLD(old_name, ""),
485 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
486
487 {STRUCT_FLD(field_name, "page_no"),
488 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
489 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
490 STRUCT_FLD(value, 0),
491 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
492 STRUCT_FLD(old_name, ""),
493 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
494
495 {STRUCT_FLD(field_name, "max_size"),
496 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
497 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
498 STRUCT_FLD(value, 0),
499 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
500 STRUCT_FLD(old_name, ""),
501 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
502
503 {STRUCT_FLD(field_name, "curr_size"),
504 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
505 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
506 STRUCT_FLD(value, 0),
507 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
508 STRUCT_FLD(old_name, ""),
509 STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
510
511 END_OF_ST_FIELD_INFO
512 };
513
514 static
515 int
i_s_xtradb_rseg_fill(THD * thd,TABLE_LIST * tables,Item *)516 i_s_xtradb_rseg_fill(
517 /*=================*/
518 THD* thd, /* in: thread */
519 TABLE_LIST* tables, /* in/out: tables to fill */
520 Item* ) /* in: condition (ignored) */
521 {
522 TABLE* table = (TABLE *) tables->table;
523 int status = 0;
524 trx_rseg_t* rseg;
525
526 DBUG_ENTER("i_s_xtradb_rseg_fill");
527
528 /* deny access to non-superusers */
529 if (check_global_access(thd, PROCESS_ACL)) {
530
531 DBUG_RETURN(0);
532 }
533
534 for(int i=0; i < TRX_SYS_N_RSEGS; i++)
535 {
536 rseg = trx_sys->rseg_array[i];
537 if (!rseg)
538 continue;
539
540 table->field[0]->store(rseg->id);
541 table->field[1]->store(rseg->space);
542 table->field[2]->store(rseg->page_size.physical());
543 table->field[3]->store(rseg->page_size.logical());
544 table->field[4]->store(rseg->page_size.is_compressed());
545 table->field[5]->store(rseg->page_no);
546 table->field[6]->store(rseg->max_size);
547 table->field[7]->store(rseg->curr_size);
548
549 if (schema_table_store_record(thd, table)) {
550 status = 1;
551 break;
552 }
553 }
554
555 DBUG_RETURN(status);
556 }
557
558 static
559 int
i_s_xtradb_rseg_init(void * p)560 i_s_xtradb_rseg_init(
561 /*=================*/
562 /* out: 0 on success */
563 void* p) /* in/out: table schema object */
564 {
565 DBUG_ENTER("i_s_xtradb_rseg_init");
566 ST_SCHEMA_TABLE* schema = (ST_SCHEMA_TABLE*) p;
567
568 schema->fields_info = i_s_xtradb_rseg_fields_info;
569 schema->fill_table = i_s_xtradb_rseg_fill;
570
571 DBUG_RETURN(0);
572 }
573
574 struct st_mysql_plugin i_s_xtradb_rseg =
575 {
576 STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
577 STRUCT_FLD(info, &i_s_info),
578 STRUCT_FLD(name, "XTRADB_RSEG"),
579 STRUCT_FLD(author, PLUGIN_AUTHOR),
580 STRUCT_FLD(descr, "InnoDB rollback segment information"),
581 STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
582 STRUCT_FLD(init, i_s_xtradb_rseg_init),
583 STRUCT_FLD(deinit, i_s_common_deinit),
584 STRUCT_FLD(version, INNODB_VERSION_SHORT),
585 STRUCT_FLD(status_vars, NULL),
586 STRUCT_FLD(system_vars, NULL),
587 STRUCT_FLD(__reserved1, NULL),
588 STRUCT_FLD(flags, 0UL),
589 };
590
591
592 /************************************************************************/
593 enum zip_dict_field_type
594 {
595 zip_dict_field_id,
596 zip_dict_field_name,
597 zip_dict_field_zip_dict
598 };
599
600 static ST_FIELD_INFO xtradb_sys_zip_dict_fields_info[] =
601 {
602 { STRUCT_FLD(field_name, "id"),
603 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
604 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
605 STRUCT_FLD(value, 0),
606 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
607 STRUCT_FLD(old_name, ""),
608 STRUCT_FLD(open_method, SKIP_OPEN_TABLE) },
609
610 { STRUCT_FLD(field_name, "name"),
611 STRUCT_FLD(field_length, ZIP_DICT_MAX_NAME_LENGTH),
612 STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
613 STRUCT_FLD(value, 0),
614 STRUCT_FLD(field_flags, 0),
615 STRUCT_FLD(old_name, ""),
616 STRUCT_FLD(open_method, SKIP_OPEN_TABLE) },
617
618 { STRUCT_FLD(field_name, "zip_dict"),
619 STRUCT_FLD(field_length, ZIP_DICT_MAX_DATA_LENGTH),
620 STRUCT_FLD(field_type, MYSQL_TYPE_BLOB),
621 STRUCT_FLD(value, 0),
622 STRUCT_FLD(field_flags, 0),
623 STRUCT_FLD(old_name, ""),
624 STRUCT_FLD(open_method, SKIP_OPEN_TABLE) },
625
626 END_OF_ST_FIELD_INFO
627 };
628
629 /** Function to fill INFORMATION_SCHEMA.XTRADB_ZIP_DICT with information
630 collected by scanning SYS_ZIP_DICT table.
631 @return 0 on success */
632 static
633 int
xtradb_i_s_dict_fill_sys_zip_dict(THD * thd,ulint id,const char * name,const char * data,ulint data_len,TABLE * table_to_fill)634 xtradb_i_s_dict_fill_sys_zip_dict(
635 THD* thd, /*!< in: thread */
636 ulint id, /*!< in: dict ID */
637 const char* name, /*!< in: dict name */
638 const char* data, /*!< in: dict data */
639 ulint data_len, /*!< in: dict data length */
640 TABLE* table_to_fill) /*!< in/out: fill this table */
641 {
642 DBUG_ENTER("xtradb_i_s_dict_fill_sys_zip_dict");
643
644 Field** fields = table_to_fill->field;
645
646 OK(field_store_ulint(fields[zip_dict_field_id], id));
647 OK(field_store_string(fields[zip_dict_field_name], name));
648 OK(field_store_blob(fields[zip_dict_field_zip_dict], data,
649 data_len));
650
651 OK(schema_table_store_record(thd, table_to_fill));
652
653 DBUG_RETURN(0);
654 }
655
656 /** Function to populate INFORMATION_SCHEMA.XTRADB_ZIP_DICT table.
657 Loop through each record in SYS_ZIP_DICT, and extract the column
658 information and fill the INFORMATION_SCHEMA.XTRADB_ZIP_DICT table.
659 @return 0 on success */
660 static
661 int
xtradb_i_s_sys_zip_dict_fill_table(THD * thd,TABLE_LIST * tables,Item *)662 xtradb_i_s_sys_zip_dict_fill_table(
663 THD* thd, /*!< in: thread */
664 TABLE_LIST* tables, /*!< in/out: tables to fill */
665 Item* ) /*!< in: condition (not used) */
666 {
667 btr_pcur_t pcur;
668 const rec_t* rec;
669 mem_heap_t* heap;
670 mtr_t mtr;
671
672 DBUG_ENTER("xtradb_i_s_sys_zip_dict_fill_table");
673
674 /* deny access to user without SUPER_ACL privilege */
675 if (check_global_access(thd, SUPER_ACL)) {
676 DBUG_RETURN(0);
677 }
678
679 heap = mem_heap_create(1000);
680 mutex_enter(&dict_sys->mutex);
681 mtr_start(&mtr);
682
683 rec = dict_startscan_system(&pcur, &mtr, SYS_ZIP_DICT);
684 page_size_t page_size = dict_table_page_size(
685 pcur.btr_cur.index->table);
686
687 while (rec) {
688 const char* err_msg;
689 ulint id;
690 const char* name;
691 const char* data;
692 ulint data_len;
693
694 /* Extract necessary information from a SYS_ZIP_DICT row */
695 err_msg = dict_process_sys_zip_dict(
696 heap, page_size, rec, &id, &name, &data, &data_len);
697
698 mtr_commit(&mtr);
699 mutex_exit(&dict_sys->mutex);
700
701 if (!err_msg) {
702 xtradb_i_s_dict_fill_sys_zip_dict(
703 thd, id, name, data, data_len,
704 tables->table);
705 } else {
706 push_warning_printf(thd,
707 Sql_condition::SL_WARNING,
708 ER_CANT_FIND_SYSTEM_REC, "%s", err_msg);
709 }
710
711 mem_heap_empty(heap);
712
713 /* Get the next record */
714 mutex_enter(&dict_sys->mutex);
715 mtr_start(&mtr);
716 rec = dict_getnext_system(&pcur, &mtr);
717 }
718
719 mtr_commit(&mtr);
720 mutex_exit(&dict_sys->mutex);
721 mem_heap_free(heap);
722
723 DBUG_RETURN(0);
724 }
725
i_s_xtradb_zip_dict_init(void * p)726 static int i_s_xtradb_zip_dict_init(void* p)
727 {
728 DBUG_ENTER("i_s_xtradb_zip_dict_init");
729
730 ST_SCHEMA_TABLE* schema = static_cast<ST_SCHEMA_TABLE*>(p);
731
732 schema->fields_info = xtradb_sys_zip_dict_fields_info;
733 schema->fill_table = xtradb_i_s_sys_zip_dict_fill_table;
734
735 DBUG_RETURN(0);
736 }
737
738 struct st_mysql_plugin i_s_xtradb_zip_dict =
739 {
740 STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
741 STRUCT_FLD(info, &i_s_info),
742 STRUCT_FLD(name, "XTRADB_ZIP_DICT"),
743 STRUCT_FLD(author, PLUGIN_AUTHOR),
744 STRUCT_FLD(descr, "InnoDB compression dictionaries information"),
745 STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
746 STRUCT_FLD(init, i_s_xtradb_zip_dict_init),
747 STRUCT_FLD(deinit, i_s_common_deinit),
748 STRUCT_FLD(version, INNODB_VERSION_SHORT),
749 STRUCT_FLD(status_vars, NULL),
750 STRUCT_FLD(system_vars, NULL),
751 STRUCT_FLD(__reserved1, NULL),
752 STRUCT_FLD(flags, 0UL),
753 };
754
755 enum zip_dict_cols_field_type
756 {
757 zip_dict_cols_field_table_id,
758 zip_dict_cols_field_column_pos,
759 zip_dict_cols_field_dict_id
760 };
761
762 static ST_FIELD_INFO xtradb_sys_zip_dict_cols_fields_info[] =
763 {
764 { STRUCT_FLD(field_name, "table_id"),
765 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
766 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
767 STRUCT_FLD(value, 0),
768 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
769 STRUCT_FLD(old_name, ""),
770 STRUCT_FLD(open_method, SKIP_OPEN_TABLE) },
771
772 { STRUCT_FLD(field_name, "column_pos"),
773 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
774 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
775 STRUCT_FLD(value, 0),
776 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
777 STRUCT_FLD(old_name, ""),
778 STRUCT_FLD(open_method, SKIP_OPEN_TABLE) },
779
780 { STRUCT_FLD(field_name, "dict_id"),
781 STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
782 STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
783 STRUCT_FLD(value, 0),
784 STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
785 STRUCT_FLD(old_name, ""),
786 STRUCT_FLD(open_method, SKIP_OPEN_TABLE) },
787
788 END_OF_ST_FIELD_INFO
789 };
790
791 /** Function to fill INFORMATION_SCHEMA.XTRADB_ZIP_DICT_COLS with information
792 collected by scanning SYS_ZIP_DICT_COLS table.
793 @return 0 on success */
794 static
795 int
xtradb_i_s_dict_fill_sys_zip_dict_cols(THD * thd,table_id_t table_id,ulint column_pos,ulint dict_id,TABLE * table_to_fill)796 xtradb_i_s_dict_fill_sys_zip_dict_cols(
797 THD* thd, /*!< in: thread */
798 table_id_t table_id, /*!< in: table ID */
799 ulint column_pos, /*!< in: column position */
800 ulint dict_id, /*!< in: dict ID */
801 TABLE* table_to_fill) /*!< in/out: fill this table */
802 {
803 DBUG_ENTER("xtradb_i_s_dict_fill_sys_zip_dict_cols");
804
805 Field** fields = table_to_fill->field;
806
807 OK(field_store_ulint(fields[zip_dict_cols_field_table_id],
808 table_id));
809 OK(field_store_ulint(fields[zip_dict_cols_field_column_pos],
810 column_pos));
811 OK(field_store_ulint(fields[zip_dict_cols_field_dict_id],
812 dict_id));
813
814 OK(schema_table_store_record(thd, table_to_fill));
815
816 DBUG_RETURN(0);
817 }
818
819 /** Function to populate INFORMATION_SCHEMA.XTRADB_ZIP_DICT_COLS table.
820 Loop through each record in SYS_ZIP_DICT_COLS, and extract the column
821 information and fill the INFORMATION_SCHEMA.XTRADB_ZIP_DICT_COLS table.
822 @return 0 on success */
823 static
824 int
xtradb_i_s_sys_zip_dict_cols_fill_table(THD * thd,TABLE_LIST * tables,Item *)825 xtradb_i_s_sys_zip_dict_cols_fill_table(
826 THD* thd, /*!< in: thread */
827 TABLE_LIST* tables, /*!< in/out: tables to fill */
828 Item* ) /*!< in: condition (not used) */
829 {
830 btr_pcur_t pcur;
831 const rec_t* rec;
832 mem_heap_t* heap;
833 mtr_t mtr;
834
835 DBUG_ENTER("xtradb_i_s_sys_zip_dict_cols_fill_table");
836
837 /* deny access to user without SUPER_ACL privilege */
838 if (check_global_access(thd, SUPER_ACL)) {
839 DBUG_RETURN(0);
840 }
841
842 heap = mem_heap_create(1000);
843 mutex_enter(&dict_sys->mutex);
844 mtr_start(&mtr);
845
846 rec = dict_startscan_system(&pcur, &mtr, SYS_ZIP_DICT_COLS);
847
848 while (rec) {
849 const char* err_msg;
850 table_id_t table_id;
851 ulint column_pos;
852 ulint dict_id;
853
854 /* Extract necessary information from a SYS_ZIP_DICT_COLS
855 row */
856 err_msg = dict_process_sys_zip_dict_cols(
857 heap, rec, &table_id, &column_pos, &dict_id);
858
859 mtr_commit(&mtr);
860 mutex_exit(&dict_sys->mutex);
861
862 if (!err_msg) {
863 xtradb_i_s_dict_fill_sys_zip_dict_cols(
864 thd, table_id, column_pos, dict_id,
865 tables->table);
866 } else {
867 push_warning_printf(thd,
868 Sql_condition::SL_WARNING,
869 ER_CANT_FIND_SYSTEM_REC, "%s", err_msg);
870 }
871
872 mem_heap_empty(heap);
873
874 /* Get the next record */
875 mutex_enter(&dict_sys->mutex);
876 mtr_start(&mtr);
877 rec = dict_getnext_system(&pcur, &mtr);
878 }
879
880 mtr_commit(&mtr);
881 mutex_exit(&dict_sys->mutex);
882 mem_heap_free(heap);
883
884 DBUG_RETURN(0);
885 }
886
i_s_xtradb_zip_dict_cols_init(void * p)887 static int i_s_xtradb_zip_dict_cols_init(void* p)
888 {
889 DBUG_ENTER("i_s_xtradb_zip_dict_cols_init");
890
891 ST_SCHEMA_TABLE* schema = static_cast<ST_SCHEMA_TABLE*>(p);
892
893 schema->fields_info = xtradb_sys_zip_dict_cols_fields_info;
894 schema->fill_table = xtradb_i_s_sys_zip_dict_cols_fill_table;
895
896 DBUG_RETURN(0);
897 }
898
899 struct st_mysql_plugin i_s_xtradb_zip_dict_cols =
900 {
901 STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
902 STRUCT_FLD(info, &i_s_info),
903 STRUCT_FLD(name, "XTRADB_ZIP_DICT_COLS"),
904 STRUCT_FLD(author, PLUGIN_AUTHOR),
905 STRUCT_FLD(descr, "InnoDB compressed columns information"),
906 STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
907 STRUCT_FLD(init, i_s_xtradb_zip_dict_cols_init),
908 STRUCT_FLD(deinit, i_s_common_deinit),
909 STRUCT_FLD(version, INNODB_VERSION_SHORT),
910 STRUCT_FLD(status_vars, NULL),
911 STRUCT_FLD(system_vars, NULL),
912 STRUCT_FLD(__reserved1, NULL),
913 STRUCT_FLD(flags, 0UL),
914 };
915