1 | /***************************************************************************** |
2 | |
3 | Copyright (c) 2007, 2016, Oracle and/or its affiliates. All Rights Reserved. |
4 | Copyright (c) 2014, 2018, MariaDB Corporation. |
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 | /**************************************************//** |
21 | @file handler/i_s.cc |
22 | InnoDB INFORMATION SCHEMA tables interface to MySQL. |
23 | |
24 | Created July 18, 2007 Vasil Dimov |
25 | Modified Dec 29, 2014 Jan Lindström (Added sys_semaphore_waits) |
26 | *******************************************************/ |
27 | |
28 | #include "ha_prototypes.h" |
29 | #include <mysql_version.h> |
30 | #include <field.h> |
31 | #include "univ.i" |
32 | |
33 | #include <sql_acl.h> |
34 | #include <sql_show.h> |
35 | #include <sql_time.h> |
36 | |
37 | #include "i_s.h" |
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 "srv0start.h" |
48 | #include "trx0i_s.h" |
49 | #include "trx0trx.h" |
50 | #include "srv0mon.h" |
51 | #include "fut0fut.h" |
52 | #include "pars0pars.h" |
53 | #include "fts0types.h" |
54 | #include "fts0opt.h" |
55 | #include "fts0priv.h" |
56 | #include "btr0btr.h" |
57 | #include "page0zip.h" |
58 | #include "sync0arr.h" |
59 | #include "fil0fil.h" |
60 | #include "fil0crypt.h" |
61 | #include "fsp0sysspace.h" |
62 | #include "ut0new.h" |
63 | #include "dict0crea.h" |
64 | |
65 | /** structure associates a name string with a file page type and/or buffer |
66 | page state. */ |
67 | struct buf_page_desc_t{ |
68 | const char* type_str; /*!< String explain the page |
69 | type/state */ |
70 | ulint type_value; /*!< Page type or page state */ |
71 | }; |
72 | |
73 | /** We also define I_S_PAGE_TYPE_INDEX as the Index Page's position |
74 | in i_s_page_type[] array */ |
75 | #define I_S_PAGE_TYPE_INDEX 1 |
76 | |
77 | /** Any unassigned FIL_PAGE_TYPE will be treated as unknown. */ |
78 | #define I_S_PAGE_TYPE_UNKNOWN FIL_PAGE_TYPE_UNKNOWN |
79 | |
80 | /** R-tree index page */ |
81 | #define I_S_PAGE_TYPE_RTREE (FIL_PAGE_TYPE_LAST + 1) |
82 | |
83 | /** Change buffer B-tree page */ |
84 | #define I_S_PAGE_TYPE_IBUF (FIL_PAGE_TYPE_LAST + 2) |
85 | |
86 | #define I_S_PAGE_TYPE_LAST I_S_PAGE_TYPE_IBUF |
87 | |
88 | #define I_S_PAGE_TYPE_BITS 4 |
89 | |
90 | /** Name string for File Page Types */ |
91 | static buf_page_desc_t i_s_page_type[] = { |
92 | {"ALLOCATED" , FIL_PAGE_TYPE_ALLOCATED}, |
93 | {"INDEX" , FIL_PAGE_INDEX}, |
94 | {"UNDO_LOG" , FIL_PAGE_UNDO_LOG}, |
95 | {"INODE" , FIL_PAGE_INODE}, |
96 | {"IBUF_FREE_LIST" , FIL_PAGE_IBUF_FREE_LIST}, |
97 | {"IBUF_BITMAP" , FIL_PAGE_IBUF_BITMAP}, |
98 | {"SYSTEM" , FIL_PAGE_TYPE_SYS}, |
99 | {"TRX_SYSTEM" , FIL_PAGE_TYPE_TRX_SYS}, |
100 | {"FILE_SPACE_HEADER" , FIL_PAGE_TYPE_FSP_HDR}, |
101 | {"EXTENT_DESCRIPTOR" , FIL_PAGE_TYPE_XDES}, |
102 | {"BLOB" , FIL_PAGE_TYPE_BLOB}, |
103 | {"COMPRESSED_BLOB" , FIL_PAGE_TYPE_ZBLOB}, |
104 | {"COMPRESSED_BLOB2" , FIL_PAGE_TYPE_ZBLOB2}, |
105 | {"UNKNOWN" , I_S_PAGE_TYPE_UNKNOWN}, |
106 | {"RTREE_INDEX" , I_S_PAGE_TYPE_RTREE}, |
107 | {"IBUF_INDEX" , I_S_PAGE_TYPE_IBUF}, |
108 | {"PAGE COMPRESSED" , FIL_PAGE_PAGE_COMPRESSED}, |
109 | {"PAGE COMPRESSED AND ENCRYPTED" , FIL_PAGE_PAGE_COMPRESSED_ENCRYPTED}, |
110 | }; |
111 | |
112 | /** This structure defines information we will fetch from pages |
113 | currently cached in the buffer pool. It will be used to populate |
114 | table INFORMATION_SCHEMA.INNODB_BUFFER_PAGE */ |
115 | struct buf_page_info_t{ |
116 | ulint block_id; /*!< Buffer Pool block ID */ |
117 | unsigned space_id:32; /*!< Tablespace ID */ |
118 | unsigned page_num:32; /*!< Page number/offset */ |
119 | unsigned access_time:32; /*!< Time of first access */ |
120 | unsigned pool_id:MAX_BUFFER_POOLS_BITS; |
121 | /*!< Buffer Pool ID. Must be less than |
122 | MAX_BUFFER_POOLS */ |
123 | unsigned flush_type:2; /*!< Flush type */ |
124 | unsigned io_fix:2; /*!< type of pending I/O operation */ |
125 | unsigned fix_count:19; /*!< Count of how manyfold this block |
126 | is bufferfixed */ |
127 | #ifdef BTR_CUR_HASH_ADAPT |
128 | unsigned hashed:1; /*!< Whether hash index has been |
129 | built on this page */ |
130 | #endif /* BTR_CUR_HASH_ADAPT */ |
131 | unsigned is_old:1; /*!< TRUE if the block is in the old |
132 | blocks in buf_pool->LRU_old */ |
133 | unsigned freed_page_clock:31; /*!< the value of |
134 | buf_pool->freed_page_clock */ |
135 | unsigned zip_ssize:PAGE_ZIP_SSIZE_BITS; |
136 | /*!< Compressed page size */ |
137 | unsigned page_state:BUF_PAGE_STATE_BITS; /*!< Page state */ |
138 | unsigned page_type:I_S_PAGE_TYPE_BITS; /*!< Page type */ |
139 | unsigned num_recs:UNIV_PAGE_SIZE_SHIFT_MAX-2; |
140 | /*!< Number of records on Page */ |
141 | unsigned data_size:UNIV_PAGE_SIZE_SHIFT_MAX; |
142 | /*!< Sum of the sizes of the records */ |
143 | lsn_t newest_mod; /*!< Log sequence number of |
144 | the youngest modification */ |
145 | lsn_t oldest_mod; /*!< Log sequence number of |
146 | the oldest modification */ |
147 | index_id_t index_id; /*!< Index ID if a index page */ |
148 | }; |
149 | |
150 | /* |
151 | Use the following types mapping: |
152 | |
153 | C type ST_FIELD_INFO::field_type |
154 | --------------------------------- |
155 | long MYSQL_TYPE_LONGLONG |
156 | (field_length=MY_INT64_NUM_DECIMAL_DIGITS) |
157 | |
158 | long unsigned MYSQL_TYPE_LONGLONG |
159 | (field_length=MY_INT64_NUM_DECIMAL_DIGITS, field_flags=MY_I_S_UNSIGNED) |
160 | |
161 | char* MYSQL_TYPE_STRING |
162 | (field_length=n) |
163 | |
164 | float MYSQL_TYPE_FLOAT |
165 | (field_length=0 is ignored) |
166 | |
167 | void* MYSQL_TYPE_LONGLONG |
168 | (field_length=MY_INT64_NUM_DECIMAL_DIGITS, field_flags=MY_I_S_UNSIGNED) |
169 | |
170 | boolean (if else) MYSQL_TYPE_LONG |
171 | (field_length=1) |
172 | |
173 | time_t MYSQL_TYPE_DATETIME |
174 | (field_length=0 ignored) |
175 | --------------------------------- |
176 | */ |
177 | |
178 | /** Implemented on sync0arr.cc */ |
179 | /*******************************************************************//** |
180 | Function to populate INFORMATION_SCHEMA.INNODB_SYS_SEMAPHORE_WAITS table. |
181 | Loop through each item on sync array, and extract the column |
182 | information and fill the INFORMATION_SCHEMA.INNODB_SYS_SEMAPHORE_WAITS table. |
183 | @return 0 on success */ |
184 | UNIV_INTERN |
185 | int |
186 | sync_arr_fill_sys_semphore_waits_table( |
187 | /*===================================*/ |
188 | THD* thd, /*!< in: thread */ |
189 | TABLE_LIST* tables, /*!< in/out: tables to fill */ |
190 | Item* ); /*!< in: condition (not used) */ |
191 | |
192 | /*******************************************************************//** |
193 | Common function to fill any of the dynamic tables: |
194 | INFORMATION_SCHEMA.innodb_trx |
195 | INFORMATION_SCHEMA.innodb_locks |
196 | INFORMATION_SCHEMA.innodb_lock_waits |
197 | @return 0 on success */ |
198 | static |
199 | int |
200 | trx_i_s_common_fill_table( |
201 | /*======================*/ |
202 | THD* thd, /*!< in: thread */ |
203 | TABLE_LIST* tables, /*!< in/out: tables to fill */ |
204 | Item* ); /*!< in: condition (not used) */ |
205 | |
206 | /*******************************************************************//** |
207 | Unbind a dynamic INFORMATION_SCHEMA table. |
208 | @return 0 on success */ |
209 | static |
210 | int |
211 | i_s_common_deinit( |
212 | /*==============*/ |
213 | void* p); /*!< in/out: table schema object */ |
214 | /*******************************************************************//** |
215 | Auxiliary function to store time_t value in MYSQL_TYPE_DATETIME |
216 | field. |
217 | @return 0 on success */ |
218 | static |
219 | int |
220 | field_store_time_t( |
221 | /*===============*/ |
222 | Field* field, /*!< in/out: target field for storage */ |
223 | time_t time) /*!< in: value to store */ |
224 | { |
225 | MYSQL_TIME my_time; |
226 | struct tm tm_time; |
227 | |
228 | if (time) { |
229 | #if 0 |
230 | /* use this if you are sure that `variables' and `time_zone' |
231 | are always initialized */ |
232 | thd->variables.time_zone->gmt_sec_to_TIME( |
233 | &my_time, (my_time_t) time); |
234 | #else |
235 | localtime_r(&time, &tm_time); |
236 | localtime_to_TIME(&my_time, &tm_time); |
237 | my_time.time_type = MYSQL_TIMESTAMP_DATETIME; |
238 | #endif |
239 | } else { |
240 | memset(&my_time, 0, sizeof(my_time)); |
241 | } |
242 | |
243 | /* JAN: TODO: MySQL 5.7 |
244 | return(field->store_time(&my_time, MYSQL_TIMESTAMP_DATETIME)); |
245 | */ |
246 | return(field->store_time(&my_time)); |
247 | } |
248 | |
249 | /*******************************************************************//** |
250 | Auxiliary function to store char* value in MYSQL_TYPE_STRING field. |
251 | @return 0 on success */ |
252 | int |
253 | field_store_string( |
254 | /*===============*/ |
255 | Field* field, /*!< in/out: target field for storage */ |
256 | const char* str) /*!< in: NUL-terminated utf-8 string, |
257 | or NULL */ |
258 | { |
259 | int ret; |
260 | |
261 | if (str != NULL) { |
262 | |
263 | ret = field->store(str, static_cast<uint>(strlen(str)), |
264 | system_charset_info); |
265 | field->set_notnull(); |
266 | } else { |
267 | |
268 | ret = 0; /* success */ |
269 | field->set_null(); |
270 | } |
271 | |
272 | return(ret); |
273 | } |
274 | |
275 | /*******************************************************************//** |
276 | Store the name of an index in a MYSQL_TYPE_VARCHAR field. |
277 | Handles the names of incomplete secondary indexes. |
278 | @return 0 on success */ |
279 | static |
280 | int |
281 | field_store_index_name( |
282 | /*===================*/ |
283 | Field* field, /*!< in/out: target field for |
284 | storage */ |
285 | const char* index_name) /*!< in: NUL-terminated utf-8 |
286 | index name, possibly starting with |
287 | TEMP_INDEX_PREFIX */ |
288 | { |
289 | int ret; |
290 | |
291 | ut_ad(index_name != NULL); |
292 | ut_ad(field->real_type() == MYSQL_TYPE_VARCHAR || |
293 | field->real_type() == MYSQL_TYPE_NULL); |
294 | |
295 | /* Since TEMP_INDEX_PREFIX is not a valid UTF8, we need to convert |
296 | it to something else. */ |
297 | if (*index_name == *TEMP_INDEX_PREFIX_STR) { |
298 | char buf[NAME_LEN + 1]; |
299 | buf[0] = '?'; |
300 | memcpy(buf + 1, index_name + 1, strlen(index_name)); |
301 | ret = field->store( |
302 | buf, static_cast<uint>(strlen(buf)), |
303 | system_charset_info); |
304 | } else { |
305 | ret = field->store( |
306 | index_name, static_cast<uint>(strlen(index_name)), |
307 | system_charset_info); |
308 | } |
309 | |
310 | field->set_notnull(); |
311 | |
312 | return(ret); |
313 | } |
314 | |
315 | /*******************************************************************//** |
316 | Auxiliary function to store ulint value in MYSQL_TYPE_LONGLONG field. |
317 | If the value is ULINT_UNDEFINED then the field is set to NULL. |
318 | @return 0 on success */ |
319 | int |
320 | field_store_ulint( |
321 | /*==============*/ |
322 | Field* field, /*!< in/out: target field for storage */ |
323 | ulint n) /*!< in: value to store */ |
324 | { |
325 | int ret; |
326 | |
327 | if (n != ULINT_UNDEFINED) { |
328 | |
329 | ret = field->store(longlong(n), true); |
330 | field->set_notnull(); |
331 | } else { |
332 | |
333 | ret = 0; /* success */ |
334 | field->set_null(); |
335 | } |
336 | |
337 | return(ret); |
338 | } |
339 | |
340 | #ifdef BTR_CUR_HASH_ADAPT |
341 | # define I_S_AHI 1 /* Include the IS_HASHED column */ |
342 | #else |
343 | # define I_S_AHI 0 /* Omit the IS_HASHED column */ |
344 | #endif |
345 | |
346 | /* Fields of the dynamic table INFORMATION_SCHEMA.innodb_trx */ |
347 | static ST_FIELD_INFO innodb_trx_fields_info[] = |
348 | { |
349 | #define IDX_TRX_ID 0 |
350 | {STRUCT_FLD(field_name, "trx_id" ), |
351 | STRUCT_FLD(field_length, TRX_ID_MAX_LEN + 1), |
352 | STRUCT_FLD(field_type, MYSQL_TYPE_STRING), |
353 | STRUCT_FLD(value, 0), |
354 | STRUCT_FLD(field_flags, 0), |
355 | STRUCT_FLD(old_name, "" ), |
356 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
357 | |
358 | #define IDX_TRX_STATE 1 |
359 | {STRUCT_FLD(field_name, "trx_state" ), |
360 | STRUCT_FLD(field_length, TRX_QUE_STATE_STR_MAX_LEN + 1), |
361 | STRUCT_FLD(field_type, MYSQL_TYPE_STRING), |
362 | STRUCT_FLD(value, 0), |
363 | STRUCT_FLD(field_flags, 0), |
364 | STRUCT_FLD(old_name, "" ), |
365 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
366 | |
367 | #define IDX_TRX_STARTED 2 |
368 | {STRUCT_FLD(field_name, "trx_started" ), |
369 | STRUCT_FLD(field_length, 0), |
370 | STRUCT_FLD(field_type, MYSQL_TYPE_DATETIME), |
371 | STRUCT_FLD(value, 0), |
372 | STRUCT_FLD(field_flags, 0), |
373 | STRUCT_FLD(old_name, "" ), |
374 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
375 | |
376 | #define IDX_TRX_REQUESTED_LOCK_ID 3 |
377 | {STRUCT_FLD(field_name, "trx_requested_lock_id" ), |
378 | STRUCT_FLD(field_length, TRX_I_S_LOCK_ID_MAX_LEN + 1), |
379 | STRUCT_FLD(field_type, MYSQL_TYPE_STRING), |
380 | STRUCT_FLD(value, 0), |
381 | STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL), |
382 | STRUCT_FLD(old_name, "" ), |
383 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
384 | |
385 | #define IDX_TRX_WAIT_STARTED 4 |
386 | {STRUCT_FLD(field_name, "trx_wait_started" ), |
387 | STRUCT_FLD(field_length, 0), |
388 | STRUCT_FLD(field_type, MYSQL_TYPE_DATETIME), |
389 | STRUCT_FLD(value, 0), |
390 | STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL), |
391 | STRUCT_FLD(old_name, "" ), |
392 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
393 | |
394 | #define IDX_TRX_WEIGHT 5 |
395 | {STRUCT_FLD(field_name, "trx_weight" ), |
396 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
397 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
398 | STRUCT_FLD(value, 0), |
399 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
400 | STRUCT_FLD(old_name, "" ), |
401 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
402 | |
403 | #define IDX_TRX_MYSQL_THREAD_ID 6 |
404 | {STRUCT_FLD(field_name, "trx_mysql_thread_id" ), |
405 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
406 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
407 | STRUCT_FLD(value, 0), |
408 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
409 | STRUCT_FLD(old_name, "" ), |
410 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
411 | |
412 | #define IDX_TRX_QUERY 7 |
413 | {STRUCT_FLD(field_name, "trx_query" ), |
414 | STRUCT_FLD(field_length, TRX_I_S_TRX_QUERY_MAX_LEN), |
415 | STRUCT_FLD(field_type, MYSQL_TYPE_STRING), |
416 | STRUCT_FLD(value, 0), |
417 | STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL), |
418 | STRUCT_FLD(old_name, "" ), |
419 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
420 | |
421 | #define IDX_TRX_OPERATION_STATE 8 |
422 | {STRUCT_FLD(field_name, "trx_operation_state" ), |
423 | STRUCT_FLD(field_length, TRX_I_S_TRX_OP_STATE_MAX_LEN), |
424 | STRUCT_FLD(field_type, MYSQL_TYPE_STRING), |
425 | STRUCT_FLD(value, 0), |
426 | STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL), |
427 | STRUCT_FLD(old_name, "" ), |
428 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
429 | |
430 | #define IDX_TRX_TABLES_IN_USE 9 |
431 | {STRUCT_FLD(field_name, "trx_tables_in_use" ), |
432 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
433 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
434 | STRUCT_FLD(value, 0), |
435 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
436 | STRUCT_FLD(old_name, "" ), |
437 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
438 | |
439 | #define IDX_TRX_TABLES_LOCKED 10 |
440 | {STRUCT_FLD(field_name, "trx_tables_locked" ), |
441 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
442 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
443 | STRUCT_FLD(value, 0), |
444 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
445 | STRUCT_FLD(old_name, "" ), |
446 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
447 | |
448 | #define IDX_TRX_LOCK_STRUCTS 11 |
449 | {STRUCT_FLD(field_name, "trx_lock_structs" ), |
450 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
451 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
452 | STRUCT_FLD(value, 0), |
453 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
454 | STRUCT_FLD(old_name, "" ), |
455 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
456 | |
457 | #define IDX_TRX_LOCK_MEMORY_BYTES 12 |
458 | {STRUCT_FLD(field_name, "trx_lock_memory_bytes" ), |
459 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
460 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
461 | STRUCT_FLD(value, 0), |
462 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
463 | STRUCT_FLD(old_name, "" ), |
464 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
465 | |
466 | #define IDX_TRX_ROWS_LOCKED 13 |
467 | {STRUCT_FLD(field_name, "trx_rows_locked" ), |
468 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
469 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
470 | STRUCT_FLD(value, 0), |
471 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
472 | STRUCT_FLD(old_name, "" ), |
473 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
474 | |
475 | #define IDX_TRX_ROWS_MODIFIED 14 |
476 | {STRUCT_FLD(field_name, "trx_rows_modified" ), |
477 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
478 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
479 | STRUCT_FLD(value, 0), |
480 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
481 | STRUCT_FLD(old_name, "" ), |
482 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
483 | |
484 | #define IDX_TRX_CONNCURRENCY_TICKETS 15 |
485 | {STRUCT_FLD(field_name, "trx_concurrency_tickets" ), |
486 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
487 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
488 | STRUCT_FLD(value, 0), |
489 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
490 | STRUCT_FLD(old_name, "" ), |
491 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
492 | |
493 | #define IDX_TRX_ISOLATION_LEVEL 16 |
494 | {STRUCT_FLD(field_name, "trx_isolation_level" ), |
495 | STRUCT_FLD(field_length, TRX_I_S_TRX_ISOLATION_LEVEL_MAX_LEN), |
496 | STRUCT_FLD(field_type, MYSQL_TYPE_STRING), |
497 | STRUCT_FLD(value, 0), |
498 | STRUCT_FLD(field_flags, 0), |
499 | STRUCT_FLD(old_name, "" ), |
500 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
501 | |
502 | #define IDX_TRX_UNIQUE_CHECKS 17 |
503 | {STRUCT_FLD(field_name, "trx_unique_checks" ), |
504 | STRUCT_FLD(field_length, 1), |
505 | STRUCT_FLD(field_type, MYSQL_TYPE_LONG), |
506 | STRUCT_FLD(value, 1), |
507 | STRUCT_FLD(field_flags, 0), |
508 | STRUCT_FLD(old_name, "" ), |
509 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
510 | |
511 | #define IDX_TRX_FOREIGN_KEY_CHECKS 18 |
512 | {STRUCT_FLD(field_name, "trx_foreign_key_checks" ), |
513 | STRUCT_FLD(field_length, 1), |
514 | STRUCT_FLD(field_type, MYSQL_TYPE_LONG), |
515 | STRUCT_FLD(value, 1), |
516 | STRUCT_FLD(field_flags, 0), |
517 | STRUCT_FLD(old_name, "" ), |
518 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
519 | |
520 | #define IDX_TRX_LAST_FOREIGN_KEY_ERROR 19 |
521 | {STRUCT_FLD(field_name, "trx_last_foreign_key_error" ), |
522 | STRUCT_FLD(field_length, TRX_I_S_TRX_FK_ERROR_MAX_LEN), |
523 | STRUCT_FLD(field_type, MYSQL_TYPE_STRING), |
524 | STRUCT_FLD(value, 0), |
525 | STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL), |
526 | STRUCT_FLD(old_name, "" ), |
527 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
528 | |
529 | #define IDX_TRX_READ_ONLY 20 |
530 | {STRUCT_FLD(field_name, "trx_is_read_only" ), |
531 | STRUCT_FLD(field_length, 1), |
532 | STRUCT_FLD(field_type, MYSQL_TYPE_LONG), |
533 | STRUCT_FLD(value, 0), |
534 | STRUCT_FLD(field_flags, 0), |
535 | STRUCT_FLD(old_name, "" ), |
536 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
537 | |
538 | #define IDX_TRX_AUTOCOMMIT_NON_LOCKING 21 |
539 | {STRUCT_FLD(field_name, "trx_autocommit_non_locking" ), |
540 | STRUCT_FLD(field_length, 1), |
541 | STRUCT_FLD(field_type, MYSQL_TYPE_LONG), |
542 | STRUCT_FLD(value, 0), |
543 | STRUCT_FLD(field_flags, 0), |
544 | STRUCT_FLD(old_name, "" ), |
545 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
546 | |
547 | END_OF_ST_FIELD_INFO |
548 | }; |
549 | |
550 | /*******************************************************************//** |
551 | Read data from cache buffer and fill the INFORMATION_SCHEMA.innodb_trx |
552 | table with it. |
553 | @return 0 on success */ |
554 | static |
555 | int |
556 | fill_innodb_trx_from_cache( |
557 | /*=======================*/ |
558 | trx_i_s_cache_t* cache, /*!< in: cache to read from */ |
559 | THD* thd, /*!< in: used to call |
560 | schema_table_store_record() */ |
561 | TABLE* table) /*!< in/out: fill this table */ |
562 | { |
563 | Field** fields; |
564 | ulint rows_num; |
565 | char lock_id[TRX_I_S_LOCK_ID_MAX_LEN + 1]; |
566 | ulint i; |
567 | |
568 | DBUG_ENTER("fill_innodb_trx_from_cache" ); |
569 | |
570 | fields = table->field; |
571 | |
572 | rows_num = trx_i_s_cache_get_rows_used(cache, |
573 | I_S_INNODB_TRX); |
574 | |
575 | for (i = 0; i < rows_num; i++) { |
576 | |
577 | i_s_trx_row_t* row; |
578 | char trx_id[TRX_ID_MAX_LEN + 1]; |
579 | |
580 | row = (i_s_trx_row_t*) |
581 | trx_i_s_cache_get_nth_row( |
582 | cache, I_S_INNODB_TRX, i); |
583 | |
584 | /* trx_id */ |
585 | snprintf(trx_id, sizeof(trx_id), TRX_ID_FMT, row->trx_id); |
586 | OK(field_store_string(fields[IDX_TRX_ID], trx_id)); |
587 | |
588 | /* trx_state */ |
589 | OK(field_store_string(fields[IDX_TRX_STATE], |
590 | row->trx_state)); |
591 | |
592 | /* trx_started */ |
593 | OK(field_store_time_t(fields[IDX_TRX_STARTED], |
594 | (time_t) row->trx_started)); |
595 | |
596 | /* trx_requested_lock_id */ |
597 | /* trx_wait_started */ |
598 | if (row->trx_wait_started != 0) { |
599 | |
600 | OK(field_store_string( |
601 | fields[IDX_TRX_REQUESTED_LOCK_ID], |
602 | trx_i_s_create_lock_id( |
603 | row->requested_lock_row, |
604 | lock_id, sizeof(lock_id)))); |
605 | /* field_store_string() sets it no notnull */ |
606 | |
607 | OK(field_store_time_t( |
608 | fields[IDX_TRX_WAIT_STARTED], |
609 | (time_t) row->trx_wait_started)); |
610 | fields[IDX_TRX_WAIT_STARTED]->set_notnull(); |
611 | } else { |
612 | |
613 | fields[IDX_TRX_REQUESTED_LOCK_ID]->set_null(); |
614 | fields[IDX_TRX_WAIT_STARTED]->set_null(); |
615 | } |
616 | |
617 | /* trx_weight */ |
618 | OK(fields[IDX_TRX_WEIGHT]->store(row->trx_weight, true)); |
619 | |
620 | /* trx_mysql_thread_id */ |
621 | OK(fields[IDX_TRX_MYSQL_THREAD_ID]->store( |
622 | row->trx_mysql_thread_id, true)); |
623 | |
624 | /* trx_query */ |
625 | if (row->trx_query) { |
626 | /* store will do appropriate character set |
627 | conversion check */ |
628 | fields[IDX_TRX_QUERY]->store( |
629 | row->trx_query, |
630 | static_cast<uint>(strlen(row->trx_query)), |
631 | row->trx_query_cs); |
632 | fields[IDX_TRX_QUERY]->set_notnull(); |
633 | } else { |
634 | fields[IDX_TRX_QUERY]->set_null(); |
635 | } |
636 | |
637 | /* trx_operation_state */ |
638 | OK(field_store_string(fields[IDX_TRX_OPERATION_STATE], |
639 | row->trx_operation_state)); |
640 | |
641 | /* trx_tables_in_use */ |
642 | OK(fields[IDX_TRX_TABLES_IN_USE]->store( |
643 | row->trx_tables_in_use, true)); |
644 | |
645 | /* trx_tables_locked */ |
646 | OK(fields[IDX_TRX_TABLES_LOCKED]->store( |
647 | row->trx_tables_locked, true)); |
648 | |
649 | /* trx_lock_structs */ |
650 | OK(fields[IDX_TRX_LOCK_STRUCTS]->store( |
651 | row->trx_lock_structs, true)); |
652 | |
653 | /* trx_lock_memory_bytes */ |
654 | OK(fields[IDX_TRX_LOCK_MEMORY_BYTES]->store( |
655 | row->trx_lock_memory_bytes, true)); |
656 | |
657 | /* trx_rows_locked */ |
658 | OK(fields[IDX_TRX_ROWS_LOCKED]->store( |
659 | row->trx_rows_locked, true)); |
660 | |
661 | /* trx_rows_modified */ |
662 | OK(fields[IDX_TRX_ROWS_MODIFIED]->store( |
663 | row->trx_rows_modified, true)); |
664 | |
665 | /* trx_concurrency_tickets */ |
666 | OK(fields[IDX_TRX_CONNCURRENCY_TICKETS]->store( |
667 | row->trx_concurrency_tickets, true)); |
668 | |
669 | /* trx_isolation_level */ |
670 | OK(field_store_string(fields[IDX_TRX_ISOLATION_LEVEL], |
671 | row->trx_isolation_level)); |
672 | |
673 | /* trx_unique_checks */ |
674 | OK(fields[IDX_TRX_UNIQUE_CHECKS]->store( |
675 | row->trx_unique_checks, true)); |
676 | |
677 | /* trx_foreign_key_checks */ |
678 | OK(fields[IDX_TRX_FOREIGN_KEY_CHECKS]->store( |
679 | row->trx_foreign_key_checks, true)); |
680 | |
681 | /* trx_last_foreign_key_error */ |
682 | OK(field_store_string(fields[IDX_TRX_LAST_FOREIGN_KEY_ERROR], |
683 | row->trx_foreign_key_error)); |
684 | |
685 | /* trx_is_read_only*/ |
686 | OK(fields[IDX_TRX_READ_ONLY]->store( |
687 | row->trx_is_read_only, true)); |
688 | |
689 | /* trx_is_autocommit_non_locking */ |
690 | OK(fields[IDX_TRX_AUTOCOMMIT_NON_LOCKING]->store( |
691 | (longlong) row->trx_is_autocommit_non_locking, |
692 | true)); |
693 | |
694 | OK(schema_table_store_record(thd, table)); |
695 | } |
696 | |
697 | DBUG_RETURN(0); |
698 | } |
699 | |
700 | /*******************************************************************//** |
701 | Bind the dynamic table INFORMATION_SCHEMA.innodb_trx |
702 | @return 0 on success */ |
703 | static |
704 | int |
705 | innodb_trx_init( |
706 | /*============*/ |
707 | void* p) /*!< in/out: table schema object */ |
708 | { |
709 | ST_SCHEMA_TABLE* schema; |
710 | |
711 | DBUG_ENTER("innodb_trx_init" ); |
712 | |
713 | schema = (ST_SCHEMA_TABLE*) p; |
714 | |
715 | schema->fields_info = innodb_trx_fields_info; |
716 | schema->fill_table = trx_i_s_common_fill_table; |
717 | |
718 | DBUG_RETURN(0); |
719 | } |
720 | |
721 | static struct st_mysql_information_schema i_s_info = |
722 | { |
723 | MYSQL_INFORMATION_SCHEMA_INTERFACE_VERSION |
724 | }; |
725 | |
726 | UNIV_INTERN struct st_maria_plugin i_s_innodb_trx = |
727 | { |
728 | /* the plugin type (a MYSQL_XXX_PLUGIN value) */ |
729 | /* int */ |
730 | STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN), |
731 | |
732 | /* pointer to type-specific plugin descriptor */ |
733 | /* void* */ |
734 | STRUCT_FLD(info, &i_s_info), |
735 | |
736 | /* plugin name */ |
737 | /* const char* */ |
738 | STRUCT_FLD(name, "INNODB_TRX" ), |
739 | |
740 | /* plugin author (for SHOW PLUGINS) */ |
741 | /* const char* */ |
742 | STRUCT_FLD(author, plugin_author), |
743 | |
744 | /* general descriptive text (for SHOW PLUGINS) */ |
745 | /* const char* */ |
746 | STRUCT_FLD(descr, "InnoDB transactions" ), |
747 | |
748 | /* the plugin license (PLUGIN_LICENSE_XXX) */ |
749 | /* int */ |
750 | STRUCT_FLD(license, PLUGIN_LICENSE_GPL), |
751 | |
752 | /* the function to invoke when plugin is loaded */ |
753 | /* int (*)(void*); */ |
754 | STRUCT_FLD(init, innodb_trx_init), |
755 | |
756 | /* the function to invoke when plugin is unloaded */ |
757 | /* int (*)(void*); */ |
758 | STRUCT_FLD(deinit, i_s_common_deinit), |
759 | |
760 | /* plugin version (for SHOW PLUGINS) */ |
761 | /* unsigned int */ |
762 | STRUCT_FLD(version, INNODB_VERSION_SHORT), |
763 | |
764 | /* struct st_mysql_show_var* */ |
765 | STRUCT_FLD(status_vars, NULL), |
766 | |
767 | /* struct st_mysql_sys_var** */ |
768 | STRUCT_FLD(system_vars, NULL), |
769 | |
770 | /* Maria extension */ |
771 | STRUCT_FLD(version_info, INNODB_VERSION_STR), |
772 | STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE), |
773 | }; |
774 | |
775 | /* Fields of the dynamic table INFORMATION_SCHEMA.innodb_locks */ |
776 | static ST_FIELD_INFO innodb_locks_fields_info[] = |
777 | { |
778 | #define IDX_LOCK_ID 0 |
779 | {STRUCT_FLD(field_name, "lock_id" ), |
780 | STRUCT_FLD(field_length, TRX_I_S_LOCK_ID_MAX_LEN + 1), |
781 | STRUCT_FLD(field_type, MYSQL_TYPE_STRING), |
782 | STRUCT_FLD(value, 0), |
783 | STRUCT_FLD(field_flags, 0), |
784 | STRUCT_FLD(old_name, "" ), |
785 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
786 | |
787 | #define IDX_LOCK_TRX_ID 1 |
788 | {STRUCT_FLD(field_name, "lock_trx_id" ), |
789 | STRUCT_FLD(field_length, TRX_ID_MAX_LEN + 1), |
790 | STRUCT_FLD(field_type, MYSQL_TYPE_STRING), |
791 | STRUCT_FLD(value, 0), |
792 | STRUCT_FLD(field_flags, 0), |
793 | STRUCT_FLD(old_name, "" ), |
794 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
795 | |
796 | #define IDX_LOCK_MODE 2 |
797 | {STRUCT_FLD(field_name, "lock_mode" ), |
798 | /* S[,GAP] X[,GAP] IS[,GAP] IX[,GAP] AUTO_INC UNKNOWN */ |
799 | STRUCT_FLD(field_length, 32), |
800 | STRUCT_FLD(field_type, MYSQL_TYPE_STRING), |
801 | STRUCT_FLD(value, 0), |
802 | STRUCT_FLD(field_flags, 0), |
803 | STRUCT_FLD(old_name, "" ), |
804 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
805 | |
806 | #define IDX_LOCK_TYPE 3 |
807 | {STRUCT_FLD(field_name, "lock_type" ), |
808 | STRUCT_FLD(field_length, 32 /* RECORD|TABLE|UNKNOWN */), |
809 | STRUCT_FLD(field_type, MYSQL_TYPE_STRING), |
810 | STRUCT_FLD(value, 0), |
811 | STRUCT_FLD(field_flags, 0), |
812 | STRUCT_FLD(old_name, "" ), |
813 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
814 | |
815 | #define IDX_LOCK_TABLE 4 |
816 | {STRUCT_FLD(field_name, "lock_table" ), |
817 | STRUCT_FLD(field_length, 1024), |
818 | STRUCT_FLD(field_type, MYSQL_TYPE_STRING), |
819 | STRUCT_FLD(value, 0), |
820 | STRUCT_FLD(field_flags, 0), |
821 | STRUCT_FLD(old_name, "" ), |
822 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
823 | |
824 | #define IDX_LOCK_INDEX 5 |
825 | {STRUCT_FLD(field_name, "lock_index" ), |
826 | STRUCT_FLD(field_length, 1024), |
827 | STRUCT_FLD(field_type, MYSQL_TYPE_STRING), |
828 | STRUCT_FLD(value, 0), |
829 | STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL), |
830 | STRUCT_FLD(old_name, "" ), |
831 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
832 | |
833 | #define IDX_LOCK_SPACE 6 |
834 | {STRUCT_FLD(field_name, "lock_space" ), |
835 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
836 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
837 | STRUCT_FLD(value, 0), |
838 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED | MY_I_S_MAYBE_NULL), |
839 | STRUCT_FLD(old_name, "" ), |
840 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
841 | |
842 | #define IDX_LOCK_PAGE 7 |
843 | {STRUCT_FLD(field_name, "lock_page" ), |
844 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
845 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
846 | STRUCT_FLD(value, 0), |
847 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED | MY_I_S_MAYBE_NULL), |
848 | STRUCT_FLD(old_name, "" ), |
849 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
850 | |
851 | #define IDX_LOCK_REC 8 |
852 | {STRUCT_FLD(field_name, "lock_rec" ), |
853 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
854 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
855 | STRUCT_FLD(value, 0), |
856 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED | MY_I_S_MAYBE_NULL), |
857 | STRUCT_FLD(old_name, "" ), |
858 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
859 | |
860 | #define IDX_LOCK_DATA 9 |
861 | {STRUCT_FLD(field_name, "lock_data" ), |
862 | STRUCT_FLD(field_length, TRX_I_S_LOCK_DATA_MAX_LEN), |
863 | STRUCT_FLD(field_type, MYSQL_TYPE_STRING), |
864 | STRUCT_FLD(value, 0), |
865 | STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL), |
866 | STRUCT_FLD(old_name, "" ), |
867 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
868 | |
869 | END_OF_ST_FIELD_INFO |
870 | }; |
871 | |
872 | /*******************************************************************//** |
873 | Read data from cache buffer and fill the INFORMATION_SCHEMA.innodb_locks |
874 | table with it. |
875 | @return 0 on success */ |
876 | static |
877 | int |
878 | fill_innodb_locks_from_cache( |
879 | /*=========================*/ |
880 | trx_i_s_cache_t* cache, /*!< in: cache to read from */ |
881 | THD* thd, /*!< in: MySQL client connection */ |
882 | TABLE* table) /*!< in/out: fill this table */ |
883 | { |
884 | Field** fields; |
885 | ulint rows_num; |
886 | char lock_id[TRX_I_S_LOCK_ID_MAX_LEN + 1]; |
887 | ulint i; |
888 | |
889 | DBUG_ENTER("fill_innodb_locks_from_cache" ); |
890 | |
891 | fields = table->field; |
892 | |
893 | rows_num = trx_i_s_cache_get_rows_used(cache, |
894 | I_S_INNODB_LOCKS); |
895 | |
896 | for (i = 0; i < rows_num; i++) { |
897 | |
898 | i_s_locks_row_t* row; |
899 | char buf[MAX_FULL_NAME_LEN + 1]; |
900 | const char* bufend; |
901 | |
902 | char lock_trx_id[TRX_ID_MAX_LEN + 1]; |
903 | |
904 | row = (i_s_locks_row_t*) |
905 | trx_i_s_cache_get_nth_row( |
906 | cache, I_S_INNODB_LOCKS, i); |
907 | |
908 | /* lock_id */ |
909 | trx_i_s_create_lock_id(row, lock_id, sizeof(lock_id)); |
910 | OK(field_store_string(fields[IDX_LOCK_ID], |
911 | lock_id)); |
912 | |
913 | /* lock_trx_id */ |
914 | snprintf(lock_trx_id, sizeof(lock_trx_id), |
915 | TRX_ID_FMT, row->lock_trx_id); |
916 | OK(field_store_string(fields[IDX_LOCK_TRX_ID], lock_trx_id)); |
917 | |
918 | /* lock_mode */ |
919 | OK(field_store_string(fields[IDX_LOCK_MODE], |
920 | row->lock_mode)); |
921 | |
922 | /* lock_type */ |
923 | OK(field_store_string(fields[IDX_LOCK_TYPE], |
924 | row->lock_type)); |
925 | |
926 | /* lock_table */ |
927 | bufend = innobase_convert_name(buf, sizeof(buf), |
928 | row->lock_table, |
929 | strlen(row->lock_table), |
930 | thd); |
931 | OK(fields[IDX_LOCK_TABLE]->store( |
932 | buf, uint(bufend - buf), system_charset_info)); |
933 | |
934 | /* lock_index */ |
935 | if (row->lock_index != NULL) { |
936 | OK(field_store_index_name(fields[IDX_LOCK_INDEX], |
937 | row->lock_index)); |
938 | } else { |
939 | fields[IDX_LOCK_INDEX]->set_null(); |
940 | } |
941 | |
942 | /* lock_space */ |
943 | OK(field_store_ulint(fields[IDX_LOCK_SPACE], |
944 | row->lock_space)); |
945 | |
946 | /* lock_page */ |
947 | OK(field_store_ulint(fields[IDX_LOCK_PAGE], |
948 | row->lock_page)); |
949 | |
950 | /* lock_rec */ |
951 | OK(field_store_ulint(fields[IDX_LOCK_REC], |
952 | row->lock_rec)); |
953 | |
954 | /* lock_data */ |
955 | OK(field_store_string(fields[IDX_LOCK_DATA], |
956 | row->lock_data)); |
957 | |
958 | OK(schema_table_store_record(thd, table)); |
959 | } |
960 | |
961 | DBUG_RETURN(0); |
962 | } |
963 | |
964 | /*******************************************************************//** |
965 | Bind the dynamic table INFORMATION_SCHEMA.innodb_locks |
966 | @return 0 on success */ |
967 | static |
968 | int |
969 | innodb_locks_init( |
970 | /*==============*/ |
971 | void* p) /*!< in/out: table schema object */ |
972 | { |
973 | ST_SCHEMA_TABLE* schema; |
974 | |
975 | DBUG_ENTER("innodb_locks_init" ); |
976 | |
977 | schema = (ST_SCHEMA_TABLE*) p; |
978 | |
979 | schema->fields_info = innodb_locks_fields_info; |
980 | schema->fill_table = trx_i_s_common_fill_table; |
981 | |
982 | DBUG_RETURN(0); |
983 | } |
984 | |
985 | UNIV_INTERN struct st_maria_plugin i_s_innodb_locks = |
986 | { |
987 | /* the plugin type (a MYSQL_XXX_PLUGIN value) */ |
988 | /* int */ |
989 | STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN), |
990 | |
991 | /* pointer to type-specific plugin descriptor */ |
992 | /* void* */ |
993 | STRUCT_FLD(info, &i_s_info), |
994 | |
995 | /* plugin name */ |
996 | /* const char* */ |
997 | STRUCT_FLD(name, "INNODB_LOCKS" ), |
998 | |
999 | /* plugin author (for SHOW PLUGINS) */ |
1000 | /* const char* */ |
1001 | STRUCT_FLD(author, plugin_author), |
1002 | |
1003 | /* general descriptive text (for SHOW PLUGINS) */ |
1004 | /* const char* */ |
1005 | STRUCT_FLD(descr, "InnoDB conflicting locks" ), |
1006 | |
1007 | /* the plugin license (PLUGIN_LICENSE_XXX) */ |
1008 | /* int */ |
1009 | STRUCT_FLD(license, PLUGIN_LICENSE_GPL), |
1010 | |
1011 | /* the function to invoke when plugin is loaded */ |
1012 | /* int (*)(void*); */ |
1013 | STRUCT_FLD(init, innodb_locks_init), |
1014 | |
1015 | /* the function to invoke when plugin is unloaded */ |
1016 | /* int (*)(void*); */ |
1017 | STRUCT_FLD(deinit, i_s_common_deinit), |
1018 | |
1019 | /* plugin version (for SHOW PLUGINS) */ |
1020 | /* unsigned int */ |
1021 | STRUCT_FLD(version, INNODB_VERSION_SHORT), |
1022 | |
1023 | /* struct st_mysql_show_var* */ |
1024 | STRUCT_FLD(status_vars, NULL), |
1025 | |
1026 | /* struct st_mysql_sys_var** */ |
1027 | STRUCT_FLD(system_vars, NULL), |
1028 | |
1029 | /* Maria extension */ |
1030 | STRUCT_FLD(version_info, INNODB_VERSION_STR), |
1031 | STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE), |
1032 | }; |
1033 | |
1034 | /* Fields of the dynamic table INFORMATION_SCHEMA.innodb_lock_waits */ |
1035 | static ST_FIELD_INFO innodb_lock_waits_fields_info[] = |
1036 | { |
1037 | #define IDX_REQUESTING_TRX_ID 0 |
1038 | {STRUCT_FLD(field_name, "requesting_trx_id" ), |
1039 | STRUCT_FLD(field_length, TRX_ID_MAX_LEN + 1), |
1040 | STRUCT_FLD(field_type, MYSQL_TYPE_STRING), |
1041 | STRUCT_FLD(value, 0), |
1042 | STRUCT_FLD(field_flags, 0), |
1043 | STRUCT_FLD(old_name, "" ), |
1044 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
1045 | |
1046 | #define IDX_REQUESTED_LOCK_ID 1 |
1047 | {STRUCT_FLD(field_name, "requested_lock_id" ), |
1048 | STRUCT_FLD(field_length, TRX_I_S_LOCK_ID_MAX_LEN + 1), |
1049 | STRUCT_FLD(field_type, MYSQL_TYPE_STRING), |
1050 | STRUCT_FLD(value, 0), |
1051 | STRUCT_FLD(field_flags, 0), |
1052 | STRUCT_FLD(old_name, "" ), |
1053 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
1054 | |
1055 | #define IDX_BLOCKING_TRX_ID 2 |
1056 | {STRUCT_FLD(field_name, "blocking_trx_id" ), |
1057 | STRUCT_FLD(field_length, TRX_ID_MAX_LEN + 1), |
1058 | STRUCT_FLD(field_type, MYSQL_TYPE_STRING), |
1059 | STRUCT_FLD(value, 0), |
1060 | STRUCT_FLD(field_flags, 0), |
1061 | STRUCT_FLD(old_name, "" ), |
1062 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
1063 | |
1064 | #define IDX_BLOCKING_LOCK_ID 3 |
1065 | {STRUCT_FLD(field_name, "blocking_lock_id" ), |
1066 | STRUCT_FLD(field_length, TRX_I_S_LOCK_ID_MAX_LEN + 1), |
1067 | STRUCT_FLD(field_type, MYSQL_TYPE_STRING), |
1068 | STRUCT_FLD(value, 0), |
1069 | STRUCT_FLD(field_flags, 0), |
1070 | STRUCT_FLD(old_name, "" ), |
1071 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
1072 | |
1073 | END_OF_ST_FIELD_INFO |
1074 | }; |
1075 | |
1076 | /*******************************************************************//** |
1077 | Read data from cache buffer and fill the |
1078 | INFORMATION_SCHEMA.innodb_lock_waits table with it. |
1079 | @return 0 on success */ |
1080 | static |
1081 | int |
1082 | fill_innodb_lock_waits_from_cache( |
1083 | /*==============================*/ |
1084 | trx_i_s_cache_t* cache, /*!< in: cache to read from */ |
1085 | THD* thd, /*!< in: used to call |
1086 | schema_table_store_record() */ |
1087 | TABLE* table) /*!< in/out: fill this table */ |
1088 | { |
1089 | Field** fields; |
1090 | ulint rows_num; |
1091 | char requested_lock_id[TRX_I_S_LOCK_ID_MAX_LEN + 1]; |
1092 | char blocking_lock_id[TRX_I_S_LOCK_ID_MAX_LEN + 1]; |
1093 | ulint i; |
1094 | |
1095 | DBUG_ENTER("fill_innodb_lock_waits_from_cache" ); |
1096 | |
1097 | fields = table->field; |
1098 | |
1099 | rows_num = trx_i_s_cache_get_rows_used(cache, |
1100 | I_S_INNODB_LOCK_WAITS); |
1101 | |
1102 | for (i = 0; i < rows_num; i++) { |
1103 | |
1104 | i_s_lock_waits_row_t* row; |
1105 | |
1106 | char requesting_trx_id[TRX_ID_MAX_LEN + 1]; |
1107 | char blocking_trx_id[TRX_ID_MAX_LEN + 1]; |
1108 | |
1109 | row = (i_s_lock_waits_row_t*) |
1110 | trx_i_s_cache_get_nth_row( |
1111 | cache, I_S_INNODB_LOCK_WAITS, i); |
1112 | |
1113 | /* requesting_trx_id */ |
1114 | snprintf(requesting_trx_id, sizeof(requesting_trx_id), |
1115 | TRX_ID_FMT, row->requested_lock_row->lock_trx_id); |
1116 | OK(field_store_string(fields[IDX_REQUESTING_TRX_ID], |
1117 | requesting_trx_id)); |
1118 | |
1119 | /* requested_lock_id */ |
1120 | OK(field_store_string( |
1121 | fields[IDX_REQUESTED_LOCK_ID], |
1122 | trx_i_s_create_lock_id( |
1123 | row->requested_lock_row, |
1124 | requested_lock_id, |
1125 | sizeof(requested_lock_id)))); |
1126 | |
1127 | /* blocking_trx_id */ |
1128 | snprintf(blocking_trx_id, sizeof(blocking_trx_id), |
1129 | TRX_ID_FMT, row->blocking_lock_row->lock_trx_id); |
1130 | OK(field_store_string(fields[IDX_BLOCKING_TRX_ID], |
1131 | blocking_trx_id)); |
1132 | |
1133 | /* blocking_lock_id */ |
1134 | OK(field_store_string( |
1135 | fields[IDX_BLOCKING_LOCK_ID], |
1136 | trx_i_s_create_lock_id( |
1137 | row->blocking_lock_row, |
1138 | blocking_lock_id, |
1139 | sizeof(blocking_lock_id)))); |
1140 | |
1141 | OK(schema_table_store_record(thd, table)); |
1142 | } |
1143 | |
1144 | DBUG_RETURN(0); |
1145 | } |
1146 | |
1147 | /*******************************************************************//** |
1148 | Bind the dynamic table INFORMATION_SCHEMA.innodb_lock_waits |
1149 | @return 0 on success */ |
1150 | static |
1151 | int |
1152 | innodb_lock_waits_init( |
1153 | /*===================*/ |
1154 | void* p) /*!< in/out: table schema object */ |
1155 | { |
1156 | ST_SCHEMA_TABLE* schema; |
1157 | |
1158 | DBUG_ENTER("innodb_lock_waits_init" ); |
1159 | |
1160 | schema = (ST_SCHEMA_TABLE*) p; |
1161 | |
1162 | schema->fields_info = innodb_lock_waits_fields_info; |
1163 | schema->fill_table = trx_i_s_common_fill_table; |
1164 | |
1165 | DBUG_RETURN(0); |
1166 | } |
1167 | |
1168 | UNIV_INTERN struct st_maria_plugin i_s_innodb_lock_waits = |
1169 | { |
1170 | /* the plugin type (a MYSQL_XXX_PLUGIN value) */ |
1171 | /* int */ |
1172 | STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN), |
1173 | |
1174 | /* pointer to type-specific plugin descriptor */ |
1175 | /* void* */ |
1176 | STRUCT_FLD(info, &i_s_info), |
1177 | |
1178 | /* plugin name */ |
1179 | /* const char* */ |
1180 | STRUCT_FLD(name, "INNODB_LOCK_WAITS" ), |
1181 | |
1182 | /* plugin author (for SHOW PLUGINS) */ |
1183 | /* const char* */ |
1184 | STRUCT_FLD(author, plugin_author), |
1185 | |
1186 | /* general descriptive text (for SHOW PLUGINS) */ |
1187 | /* const char* */ |
1188 | STRUCT_FLD(descr, "InnoDB which lock is blocking which" ), |
1189 | |
1190 | /* the plugin license (PLUGIN_LICENSE_XXX) */ |
1191 | /* int */ |
1192 | STRUCT_FLD(license, PLUGIN_LICENSE_GPL), |
1193 | |
1194 | /* the function to invoke when plugin is loaded */ |
1195 | /* int (*)(void*); */ |
1196 | STRUCT_FLD(init, innodb_lock_waits_init), |
1197 | |
1198 | /* the function to invoke when plugin is unloaded */ |
1199 | /* int (*)(void*); */ |
1200 | STRUCT_FLD(deinit, i_s_common_deinit), |
1201 | |
1202 | /* plugin version (for SHOW PLUGINS) */ |
1203 | /* unsigned int */ |
1204 | STRUCT_FLD(version, INNODB_VERSION_SHORT), |
1205 | |
1206 | /* struct st_mysql_show_var* */ |
1207 | STRUCT_FLD(status_vars, NULL), |
1208 | |
1209 | /* struct st_mysql_sys_var** */ |
1210 | STRUCT_FLD(system_vars, NULL), |
1211 | |
1212 | /* Maria extension */ |
1213 | STRUCT_FLD(version_info, INNODB_VERSION_STR), |
1214 | STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE), |
1215 | }; |
1216 | |
1217 | /*******************************************************************//** |
1218 | Common function to fill any of the dynamic tables: |
1219 | INFORMATION_SCHEMA.innodb_trx |
1220 | INFORMATION_SCHEMA.innodb_locks |
1221 | INFORMATION_SCHEMA.innodb_lock_waits |
1222 | @return 0 on success */ |
1223 | static |
1224 | int |
1225 | trx_i_s_common_fill_table( |
1226 | /*======================*/ |
1227 | THD* thd, /*!< in: thread */ |
1228 | TABLE_LIST* tables, /*!< in/out: tables to fill */ |
1229 | Item* ) /*!< in: condition (not used) */ |
1230 | { |
1231 | LEX_CSTRING table_name; |
1232 | int ret; |
1233 | trx_i_s_cache_t* cache; |
1234 | |
1235 | DBUG_ENTER("trx_i_s_common_fill_table" ); |
1236 | |
1237 | /* deny access to non-superusers */ |
1238 | if (check_global_access(thd, PROCESS_ACL)) { |
1239 | |
1240 | DBUG_RETURN(0); |
1241 | } |
1242 | |
1243 | /* minimize the number of places where global variables are |
1244 | referenced */ |
1245 | cache = trx_i_s_cache; |
1246 | |
1247 | /* which table we have to fill? */ |
1248 | table_name = tables->schema_table_name; |
1249 | /* or table_name = tables->schema_table->table_name; */ |
1250 | |
1251 | RETURN_IF_INNODB_NOT_STARTED(table_name.str); |
1252 | |
1253 | /* update the cache */ |
1254 | trx_i_s_cache_start_write(cache); |
1255 | trx_i_s_possibly_fetch_data_into_cache(cache); |
1256 | trx_i_s_cache_end_write(cache); |
1257 | |
1258 | if (trx_i_s_cache_is_truncated(cache)) { |
1259 | |
1260 | ib::warn() << "Data in " << table_name.str << " truncated due to" |
1261 | " memory limit of " << TRX_I_S_MEM_LIMIT << " bytes" ; |
1262 | } |
1263 | |
1264 | ret = 0; |
1265 | |
1266 | trx_i_s_cache_start_read(cache); |
1267 | |
1268 | if (innobase_strcasecmp(table_name.str, "innodb_trx" ) == 0) { |
1269 | |
1270 | if (fill_innodb_trx_from_cache( |
1271 | cache, thd, tables->table) != 0) { |
1272 | |
1273 | ret = 1; |
1274 | } |
1275 | |
1276 | } else if (innobase_strcasecmp(table_name.str, "innodb_locks" ) == 0) { |
1277 | |
1278 | if (fill_innodb_locks_from_cache( |
1279 | cache, thd, tables->table) != 0) { |
1280 | |
1281 | ret = 1; |
1282 | } |
1283 | |
1284 | } else if (innobase_strcasecmp(table_name.str, "innodb_lock_waits" ) == 0) { |
1285 | |
1286 | if (fill_innodb_lock_waits_from_cache( |
1287 | cache, thd, tables->table) != 0) { |
1288 | |
1289 | ret = 1; |
1290 | } |
1291 | |
1292 | } else { |
1293 | ib::error() << "trx_i_s_common_fill_table() was" |
1294 | " called to fill unknown table: " << table_name.str << "." |
1295 | " This function only knows how to fill" |
1296 | " innodb_trx, innodb_locks and" |
1297 | " innodb_lock_waits tables." ; |
1298 | |
1299 | ret = 1; |
1300 | } |
1301 | |
1302 | trx_i_s_cache_end_read(cache); |
1303 | |
1304 | #if 0 |
1305 | DBUG_RETURN(ret); |
1306 | #else |
1307 | /* if this function returns something else than 0 then a |
1308 | deadlock occurs between the mysqld server and mysql client, |
1309 | see http://bugs.mysql.com/29900 ; when that bug is resolved |
1310 | we can enable the DBUG_RETURN(ret) above */ |
1311 | ret++; // silence a gcc46 warning |
1312 | DBUG_RETURN(0); |
1313 | #endif |
1314 | } |
1315 | |
1316 | /* Fields of the dynamic table information_schema.innodb_cmp. */ |
1317 | static ST_FIELD_INFO i_s_cmp_fields_info[] = |
1318 | { |
1319 | {STRUCT_FLD(field_name, "page_size" ), |
1320 | STRUCT_FLD(field_length, 5), |
1321 | STRUCT_FLD(field_type, MYSQL_TYPE_LONG), |
1322 | STRUCT_FLD(value, 0), |
1323 | STRUCT_FLD(field_flags, 0), |
1324 | STRUCT_FLD(old_name, "Compressed Page Size" ), |
1325 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
1326 | |
1327 | {STRUCT_FLD(field_name, "compress_ops" ), |
1328 | STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS), |
1329 | STRUCT_FLD(field_type, MYSQL_TYPE_LONG), |
1330 | STRUCT_FLD(value, 0), |
1331 | STRUCT_FLD(field_flags, 0), |
1332 | STRUCT_FLD(old_name, "Total Number of Compressions" ), |
1333 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
1334 | |
1335 | {STRUCT_FLD(field_name, "compress_ops_ok" ), |
1336 | STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS), |
1337 | STRUCT_FLD(field_type, MYSQL_TYPE_LONG), |
1338 | STRUCT_FLD(value, 0), |
1339 | STRUCT_FLD(field_flags, 0), |
1340 | STRUCT_FLD(old_name, "Total Number of" |
1341 | " Successful Compressions" ), |
1342 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
1343 | |
1344 | {STRUCT_FLD(field_name, "compress_time" ), |
1345 | STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS), |
1346 | STRUCT_FLD(field_type, MYSQL_TYPE_LONG), |
1347 | STRUCT_FLD(value, 0), |
1348 | STRUCT_FLD(field_flags, 0), |
1349 | STRUCT_FLD(old_name, "Total Duration of Compressions," |
1350 | " in Seconds" ), |
1351 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
1352 | |
1353 | {STRUCT_FLD(field_name, "uncompress_ops" ), |
1354 | STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS), |
1355 | STRUCT_FLD(field_type, MYSQL_TYPE_LONG), |
1356 | STRUCT_FLD(value, 0), |
1357 | STRUCT_FLD(field_flags, 0), |
1358 | STRUCT_FLD(old_name, "Total Number of Decompressions" ), |
1359 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
1360 | |
1361 | {STRUCT_FLD(field_name, "uncompress_time" ), |
1362 | STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS), |
1363 | STRUCT_FLD(field_type, MYSQL_TYPE_LONG), |
1364 | STRUCT_FLD(value, 0), |
1365 | STRUCT_FLD(field_flags, 0), |
1366 | STRUCT_FLD(old_name, "Total Duration of Decompressions," |
1367 | " in Seconds" ), |
1368 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
1369 | |
1370 | END_OF_ST_FIELD_INFO |
1371 | }; |
1372 | |
1373 | |
1374 | /*******************************************************************//** |
1375 | Fill the dynamic table information_schema.innodb_cmp or |
1376 | innodb_cmp_reset. |
1377 | @return 0 on success, 1 on failure */ |
1378 | static |
1379 | int |
1380 | i_s_cmp_fill_low( |
1381 | /*=============*/ |
1382 | THD* thd, /*!< in: thread */ |
1383 | TABLE_LIST* tables, /*!< in/out: tables to fill */ |
1384 | Item* , /*!< in: condition (ignored) */ |
1385 | ibool reset) /*!< in: TRUE=reset cumulated counts */ |
1386 | { |
1387 | TABLE* table = (TABLE*) tables->table; |
1388 | int status = 0; |
1389 | |
1390 | DBUG_ENTER("i_s_cmp_fill_low" ); |
1391 | |
1392 | /* deny access to non-superusers */ |
1393 | if (check_global_access(thd, PROCESS_ACL)) { |
1394 | |
1395 | DBUG_RETURN(0); |
1396 | } |
1397 | |
1398 | RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name.str); |
1399 | |
1400 | for (uint i = 0; i < PAGE_ZIP_SSIZE_MAX; i++) { |
1401 | page_zip_stat_t* zip_stat = &page_zip_stat[i]; |
1402 | |
1403 | table->field[0]->store(UNIV_ZIP_SIZE_MIN << i); |
1404 | |
1405 | /* The cumulated counts are not protected by any |
1406 | mutex. Thus, some operation in page0zip.cc could |
1407 | increment a counter between the time we read it and |
1408 | clear it. We could introduce mutex protection, but it |
1409 | could cause a measureable performance hit in |
1410 | page0zip.cc. */ |
1411 | table->field[1]->store(zip_stat->compressed, true); |
1412 | table->field[2]->store(zip_stat->compressed_ok, true); |
1413 | table->field[3]->store(zip_stat->compressed_usec / 1000000, true); |
1414 | table->field[4]->store(zip_stat->decompressed, true); |
1415 | table->field[5]->store(zip_stat->decompressed_usec / 1000000, true); |
1416 | |
1417 | if (reset) { |
1418 | memset(zip_stat, 0, sizeof *zip_stat); |
1419 | } |
1420 | |
1421 | if (schema_table_store_record(thd, table)) { |
1422 | status = 1; |
1423 | break; |
1424 | } |
1425 | } |
1426 | |
1427 | DBUG_RETURN(status); |
1428 | } |
1429 | |
1430 | /*******************************************************************//** |
1431 | Fill the dynamic table information_schema.innodb_cmp. |
1432 | @return 0 on success, 1 on failure */ |
1433 | static |
1434 | int |
1435 | i_s_cmp_fill( |
1436 | /*=========*/ |
1437 | THD* thd, /*!< in: thread */ |
1438 | TABLE_LIST* tables, /*!< in/out: tables to fill */ |
1439 | Item* cond) /*!< in: condition (ignored) */ |
1440 | { |
1441 | return(i_s_cmp_fill_low(thd, tables, cond, FALSE)); |
1442 | } |
1443 | |
1444 | /*******************************************************************//** |
1445 | Fill the dynamic table information_schema.innodb_cmp_reset. |
1446 | @return 0 on success, 1 on failure */ |
1447 | static |
1448 | int |
1449 | i_s_cmp_reset_fill( |
1450 | /*===============*/ |
1451 | THD* thd, /*!< in: thread */ |
1452 | TABLE_LIST* tables, /*!< in/out: tables to fill */ |
1453 | Item* cond) /*!< in: condition (ignored) */ |
1454 | { |
1455 | return(i_s_cmp_fill_low(thd, tables, cond, TRUE)); |
1456 | } |
1457 | |
1458 | /*******************************************************************//** |
1459 | Bind the dynamic table information_schema.innodb_cmp. |
1460 | @return 0 on success */ |
1461 | static |
1462 | int |
1463 | i_s_cmp_init( |
1464 | /*=========*/ |
1465 | void* p) /*!< in/out: table schema object */ |
1466 | { |
1467 | DBUG_ENTER("i_s_cmp_init" ); |
1468 | ST_SCHEMA_TABLE* schema = (ST_SCHEMA_TABLE*) p; |
1469 | |
1470 | schema->fields_info = i_s_cmp_fields_info; |
1471 | schema->fill_table = i_s_cmp_fill; |
1472 | |
1473 | DBUG_RETURN(0); |
1474 | } |
1475 | |
1476 | /*******************************************************************//** |
1477 | Bind the dynamic table information_schema.innodb_cmp_reset. |
1478 | @return 0 on success */ |
1479 | static |
1480 | int |
1481 | i_s_cmp_reset_init( |
1482 | /*===============*/ |
1483 | void* p) /*!< in/out: table schema object */ |
1484 | { |
1485 | DBUG_ENTER("i_s_cmp_reset_init" ); |
1486 | ST_SCHEMA_TABLE* schema = (ST_SCHEMA_TABLE*) p; |
1487 | |
1488 | schema->fields_info = i_s_cmp_fields_info; |
1489 | schema->fill_table = i_s_cmp_reset_fill; |
1490 | |
1491 | DBUG_RETURN(0); |
1492 | } |
1493 | |
1494 | UNIV_INTERN struct st_maria_plugin i_s_innodb_cmp = |
1495 | { |
1496 | /* the plugin type (a MYSQL_XXX_PLUGIN value) */ |
1497 | /* int */ |
1498 | STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN), |
1499 | |
1500 | /* pointer to type-specific plugin descriptor */ |
1501 | /* void* */ |
1502 | STRUCT_FLD(info, &i_s_info), |
1503 | |
1504 | /* plugin name */ |
1505 | /* const char* */ |
1506 | STRUCT_FLD(name, "INNODB_CMP" ), |
1507 | |
1508 | /* plugin author (for SHOW PLUGINS) */ |
1509 | /* const char* */ |
1510 | STRUCT_FLD(author, plugin_author), |
1511 | |
1512 | /* general descriptive text (for SHOW PLUGINS) */ |
1513 | /* const char* */ |
1514 | STRUCT_FLD(descr, "Statistics for the InnoDB compression" ), |
1515 | |
1516 | /* the plugin license (PLUGIN_LICENSE_XXX) */ |
1517 | /* int */ |
1518 | STRUCT_FLD(license, PLUGIN_LICENSE_GPL), |
1519 | |
1520 | /* the function to invoke when plugin is loaded */ |
1521 | /* int (*)(void*); */ |
1522 | STRUCT_FLD(init, i_s_cmp_init), |
1523 | |
1524 | /* the function to invoke when plugin is unloaded */ |
1525 | /* int (*)(void*); */ |
1526 | STRUCT_FLD(deinit, i_s_common_deinit), |
1527 | |
1528 | /* plugin version (for SHOW PLUGINS) */ |
1529 | /* unsigned int */ |
1530 | STRUCT_FLD(version, INNODB_VERSION_SHORT), |
1531 | |
1532 | /* struct st_mysql_show_var* */ |
1533 | STRUCT_FLD(status_vars, NULL), |
1534 | |
1535 | /* struct st_mysql_sys_var** */ |
1536 | STRUCT_FLD(system_vars, NULL), |
1537 | |
1538 | /* Maria extension */ |
1539 | STRUCT_FLD(version_info, INNODB_VERSION_STR), |
1540 | STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE), |
1541 | }; |
1542 | |
1543 | UNIV_INTERN struct st_maria_plugin i_s_innodb_cmp_reset = |
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_RESET" ), |
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 | " reset cumulated counts" ), |
1565 | |
1566 | /* the plugin license (PLUGIN_LICENSE_XXX) */ |
1567 | /* int */ |
1568 | STRUCT_FLD(license, PLUGIN_LICENSE_GPL), |
1569 | |
1570 | /* the function to invoke when plugin is loaded */ |
1571 | /* int (*)(void*); */ |
1572 | STRUCT_FLD(init, i_s_cmp_reset_init), |
1573 | |
1574 | /* the function to invoke when plugin is unloaded */ |
1575 | /* int (*)(void*); */ |
1576 | STRUCT_FLD(deinit, i_s_common_deinit), |
1577 | |
1578 | /* plugin version (for SHOW PLUGINS) */ |
1579 | /* unsigned int */ |
1580 | STRUCT_FLD(version, INNODB_VERSION_SHORT), |
1581 | |
1582 | /* struct st_mysql_show_var* */ |
1583 | STRUCT_FLD(status_vars, NULL), |
1584 | |
1585 | /* struct st_mysql_sys_var** */ |
1586 | STRUCT_FLD(system_vars, NULL), |
1587 | |
1588 | /* Maria extension */ |
1589 | STRUCT_FLD(version_info, INNODB_VERSION_STR), |
1590 | STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE), |
1591 | }; |
1592 | |
1593 | /* Fields of the dynamic tables |
1594 | information_schema.innodb_cmp_per_index and |
1595 | information_schema.innodb_cmp_per_index_reset. */ |
1596 | static ST_FIELD_INFO i_s_cmp_per_index_fields_info[] = |
1597 | { |
1598 | #define IDX_DATABASE_NAME 0 |
1599 | {STRUCT_FLD(field_name, "database_name" ), |
1600 | STRUCT_FLD(field_length, 192), |
1601 | STRUCT_FLD(field_type, MYSQL_TYPE_STRING), |
1602 | STRUCT_FLD(value, 0), |
1603 | STRUCT_FLD(field_flags, 0), |
1604 | STRUCT_FLD(old_name, "" ), |
1605 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
1606 | |
1607 | #define IDX_TABLE_NAME 1 |
1608 | {STRUCT_FLD(field_name, "table_name" ), |
1609 | STRUCT_FLD(field_length, 192), |
1610 | STRUCT_FLD(field_type, MYSQL_TYPE_STRING), |
1611 | STRUCT_FLD(value, 0), |
1612 | STRUCT_FLD(field_flags, 0), |
1613 | STRUCT_FLD(old_name, "" ), |
1614 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
1615 | |
1616 | #define IDX_INDEX_NAME 2 |
1617 | {STRUCT_FLD(field_name, "index_name" ), |
1618 | STRUCT_FLD(field_length, 192), |
1619 | STRUCT_FLD(field_type, MYSQL_TYPE_STRING), |
1620 | STRUCT_FLD(value, 0), |
1621 | STRUCT_FLD(field_flags, 0), |
1622 | STRUCT_FLD(old_name, "" ), |
1623 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
1624 | |
1625 | #define IDX_COMPRESS_OPS 3 |
1626 | {STRUCT_FLD(field_name, "compress_ops" ), |
1627 | STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS), |
1628 | STRUCT_FLD(field_type, MYSQL_TYPE_LONG), |
1629 | STRUCT_FLD(value, 0), |
1630 | STRUCT_FLD(field_flags, 0), |
1631 | STRUCT_FLD(old_name, "" ), |
1632 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
1633 | |
1634 | #define IDX_COMPRESS_OPS_OK 4 |
1635 | {STRUCT_FLD(field_name, "compress_ops_ok" ), |
1636 | STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS), |
1637 | STRUCT_FLD(field_type, MYSQL_TYPE_LONG), |
1638 | STRUCT_FLD(value, 0), |
1639 | STRUCT_FLD(field_flags, 0), |
1640 | STRUCT_FLD(old_name, "" ), |
1641 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
1642 | |
1643 | #define IDX_COMPRESS_TIME 5 |
1644 | {STRUCT_FLD(field_name, "compress_time" ), |
1645 | STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS), |
1646 | STRUCT_FLD(field_type, MYSQL_TYPE_LONG), |
1647 | STRUCT_FLD(value, 0), |
1648 | STRUCT_FLD(field_flags, 0), |
1649 | STRUCT_FLD(old_name, "" ), |
1650 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
1651 | |
1652 | #define IDX_UNCOMPRESS_OPS 6 |
1653 | {STRUCT_FLD(field_name, "uncompress_ops" ), |
1654 | STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS), |
1655 | STRUCT_FLD(field_type, MYSQL_TYPE_LONG), |
1656 | STRUCT_FLD(value, 0), |
1657 | STRUCT_FLD(field_flags, 0), |
1658 | STRUCT_FLD(old_name, "" ), |
1659 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
1660 | |
1661 | #define IDX_UNCOMPRESS_TIME 7 |
1662 | {STRUCT_FLD(field_name, "uncompress_time" ), |
1663 | STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS), |
1664 | STRUCT_FLD(field_type, MYSQL_TYPE_LONG), |
1665 | STRUCT_FLD(value, 0), |
1666 | STRUCT_FLD(field_flags, 0), |
1667 | STRUCT_FLD(old_name, "" ), |
1668 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
1669 | |
1670 | END_OF_ST_FIELD_INFO |
1671 | }; |
1672 | |
1673 | /*******************************************************************//** |
1674 | Fill the dynamic table |
1675 | information_schema.innodb_cmp_per_index or |
1676 | information_schema.innodb_cmp_per_index_reset. |
1677 | @return 0 on success, 1 on failure */ |
1678 | static |
1679 | int |
1680 | i_s_cmp_per_index_fill_low( |
1681 | /*=======================*/ |
1682 | THD* thd, /*!< in: thread */ |
1683 | TABLE_LIST* tables, /*!< in/out: tables to fill */ |
1684 | Item* , /*!< in: condition (ignored) */ |
1685 | ibool reset) /*!< in: TRUE=reset cumulated counts */ |
1686 | { |
1687 | TABLE* table = tables->table; |
1688 | Field** fields = table->field; |
1689 | int status = 0; |
1690 | |
1691 | DBUG_ENTER("i_s_cmp_per_index_fill_low" ); |
1692 | |
1693 | /* deny access to non-superusers */ |
1694 | if (check_global_access(thd, PROCESS_ACL)) { |
1695 | |
1696 | DBUG_RETURN(0); |
1697 | } |
1698 | |
1699 | RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name.str); |
1700 | |
1701 | /* Create a snapshot of the stats so we do not bump into lock |
1702 | order violations with dict_sys->mutex below. */ |
1703 | mutex_enter(&page_zip_stat_per_index_mutex); |
1704 | page_zip_stat_per_index_t snap (page_zip_stat_per_index); |
1705 | mutex_exit(&page_zip_stat_per_index_mutex); |
1706 | |
1707 | mutex_enter(&dict_sys->mutex); |
1708 | |
1709 | page_zip_stat_per_index_t::iterator iter; |
1710 | ulint i; |
1711 | |
1712 | for (iter = snap.begin(), i = 0; iter != snap.end(); iter++, i++) { |
1713 | |
1714 | char name[192]; |
1715 | dict_index_t* index = dict_index_find_on_id_low(iter->first); |
1716 | |
1717 | if (index != NULL) { |
1718 | char db_utf8[MAX_DB_UTF8_LEN]; |
1719 | char table_utf8[MAX_TABLE_UTF8_LEN]; |
1720 | |
1721 | dict_fs2utf8(index->table->name.m_name, |
1722 | db_utf8, sizeof(db_utf8), |
1723 | table_utf8, sizeof(table_utf8)); |
1724 | |
1725 | field_store_string(fields[IDX_DATABASE_NAME], db_utf8); |
1726 | field_store_string(fields[IDX_TABLE_NAME], table_utf8); |
1727 | field_store_index_name(fields[IDX_INDEX_NAME], |
1728 | index->name); |
1729 | } else { |
1730 | /* index not found */ |
1731 | snprintf(name, sizeof(name), |
1732 | "index_id:" IB_ID_FMT, iter->first); |
1733 | field_store_string(fields[IDX_DATABASE_NAME], |
1734 | "unknown" ); |
1735 | field_store_string(fields[IDX_TABLE_NAME], |
1736 | "unknown" ); |
1737 | field_store_string(fields[IDX_INDEX_NAME], |
1738 | name); |
1739 | } |
1740 | |
1741 | fields[IDX_COMPRESS_OPS]->store( |
1742 | iter->second.compressed, true); |
1743 | |
1744 | fields[IDX_COMPRESS_OPS_OK]->store( |
1745 | iter->second.compressed_ok, true); |
1746 | |
1747 | fields[IDX_COMPRESS_TIME]->store( |
1748 | iter->second.compressed_usec / 1000000, true); |
1749 | |
1750 | fields[IDX_UNCOMPRESS_OPS]->store( |
1751 | iter->second.decompressed, true); |
1752 | |
1753 | fields[IDX_UNCOMPRESS_TIME]->store( |
1754 | iter->second.decompressed_usec / 1000000, true); |
1755 | |
1756 | if (schema_table_store_record(thd, table)) { |
1757 | status = 1; |
1758 | break; |
1759 | } |
1760 | /* Release and reacquire the dict mutex to allow other |
1761 | threads to proceed. This could eventually result in the |
1762 | contents of INFORMATION_SCHEMA.innodb_cmp_per_index being |
1763 | inconsistent, but it is an acceptable compromise. */ |
1764 | if (i % 1000 == 0) { |
1765 | mutex_exit(&dict_sys->mutex); |
1766 | mutex_enter(&dict_sys->mutex); |
1767 | } |
1768 | } |
1769 | |
1770 | mutex_exit(&dict_sys->mutex); |
1771 | |
1772 | if (reset) { |
1773 | page_zip_reset_stat_per_index(); |
1774 | } |
1775 | |
1776 | DBUG_RETURN(status); |
1777 | } |
1778 | |
1779 | /*******************************************************************//** |
1780 | Fill the dynamic table information_schema.innodb_cmp_per_index. |
1781 | @return 0 on success, 1 on failure */ |
1782 | static |
1783 | int |
1784 | i_s_cmp_per_index_fill( |
1785 | /*===================*/ |
1786 | THD* thd, /*!< in: thread */ |
1787 | TABLE_LIST* tables, /*!< in/out: tables to fill */ |
1788 | Item* cond) /*!< in: condition (ignored) */ |
1789 | { |
1790 | return(i_s_cmp_per_index_fill_low(thd, tables, cond, FALSE)); |
1791 | } |
1792 | |
1793 | /*******************************************************************//** |
1794 | Fill the dynamic table information_schema.innodb_cmp_per_index_reset. |
1795 | @return 0 on success, 1 on failure */ |
1796 | static |
1797 | int |
1798 | i_s_cmp_per_index_reset_fill( |
1799 | /*=========================*/ |
1800 | THD* thd, /*!< in: thread */ |
1801 | TABLE_LIST* tables, /*!< in/out: tables to fill */ |
1802 | Item* cond) /*!< in: condition (ignored) */ |
1803 | { |
1804 | return(i_s_cmp_per_index_fill_low(thd, tables, cond, TRUE)); |
1805 | } |
1806 | |
1807 | /*******************************************************************//** |
1808 | Bind the dynamic table information_schema.innodb_cmp_per_index. |
1809 | @return 0 on success */ |
1810 | static |
1811 | int |
1812 | i_s_cmp_per_index_init( |
1813 | /*===================*/ |
1814 | void* p) /*!< in/out: table schema object */ |
1815 | { |
1816 | DBUG_ENTER("i_s_cmp_init" ); |
1817 | ST_SCHEMA_TABLE* schema = (ST_SCHEMA_TABLE*) p; |
1818 | |
1819 | schema->fields_info = i_s_cmp_per_index_fields_info; |
1820 | schema->fill_table = i_s_cmp_per_index_fill; |
1821 | |
1822 | DBUG_RETURN(0); |
1823 | } |
1824 | |
1825 | /*******************************************************************//** |
1826 | Bind the dynamic table information_schema.innodb_cmp_per_index_reset. |
1827 | @return 0 on success */ |
1828 | static |
1829 | int |
1830 | i_s_cmp_per_index_reset_init( |
1831 | /*=========================*/ |
1832 | void* p) /*!< in/out: table schema object */ |
1833 | { |
1834 | DBUG_ENTER("i_s_cmp_reset_init" ); |
1835 | ST_SCHEMA_TABLE* schema = (ST_SCHEMA_TABLE*) p; |
1836 | |
1837 | schema->fields_info = i_s_cmp_per_index_fields_info; |
1838 | schema->fill_table = i_s_cmp_per_index_reset_fill; |
1839 | |
1840 | DBUG_RETURN(0); |
1841 | } |
1842 | |
1843 | UNIV_INTERN struct st_maria_plugin i_s_innodb_cmp_per_index = |
1844 | { |
1845 | /* the plugin type (a MYSQL_XXX_PLUGIN value) */ |
1846 | /* int */ |
1847 | STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN), |
1848 | |
1849 | /* pointer to type-specific plugin descriptor */ |
1850 | /* void* */ |
1851 | STRUCT_FLD(info, &i_s_info), |
1852 | |
1853 | /* plugin name */ |
1854 | /* const char* */ |
1855 | STRUCT_FLD(name, "INNODB_CMP_PER_INDEX" ), |
1856 | |
1857 | /* plugin author (for SHOW PLUGINS) */ |
1858 | /* const char* */ |
1859 | STRUCT_FLD(author, plugin_author), |
1860 | |
1861 | /* general descriptive text (for SHOW PLUGINS) */ |
1862 | /* const char* */ |
1863 | STRUCT_FLD(descr, "Statistics for the InnoDB compression (per index)" ), |
1864 | |
1865 | /* the plugin license (PLUGIN_LICENSE_XXX) */ |
1866 | /* int */ |
1867 | STRUCT_FLD(license, PLUGIN_LICENSE_GPL), |
1868 | |
1869 | /* the function to invoke when plugin is loaded */ |
1870 | /* int (*)(void*); */ |
1871 | STRUCT_FLD(init, i_s_cmp_per_index_init), |
1872 | |
1873 | /* the function to invoke when plugin is unloaded */ |
1874 | /* int (*)(void*); */ |
1875 | STRUCT_FLD(deinit, i_s_common_deinit), |
1876 | |
1877 | /* plugin version (for SHOW PLUGINS) */ |
1878 | /* unsigned int */ |
1879 | STRUCT_FLD(version, INNODB_VERSION_SHORT), |
1880 | |
1881 | /* struct st_mysql_show_var* */ |
1882 | STRUCT_FLD(status_vars, NULL), |
1883 | |
1884 | /* struct st_mysql_sys_var** */ |
1885 | STRUCT_FLD(system_vars, NULL), |
1886 | |
1887 | /* Maria extension */ |
1888 | STRUCT_FLD(version_info, INNODB_VERSION_STR), |
1889 | STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE), |
1890 | }; |
1891 | |
1892 | UNIV_INTERN struct st_maria_plugin i_s_innodb_cmp_per_index_reset = |
1893 | { |
1894 | /* the plugin type (a MYSQL_XXX_PLUGIN value) */ |
1895 | /* int */ |
1896 | STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN), |
1897 | |
1898 | /* pointer to type-specific plugin descriptor */ |
1899 | /* void* */ |
1900 | STRUCT_FLD(info, &i_s_info), |
1901 | |
1902 | /* plugin name */ |
1903 | /* const char* */ |
1904 | STRUCT_FLD(name, "INNODB_CMP_PER_INDEX_RESET" ), |
1905 | |
1906 | /* plugin author (for SHOW PLUGINS) */ |
1907 | /* const char* */ |
1908 | STRUCT_FLD(author, plugin_author), |
1909 | |
1910 | /* general descriptive text (for SHOW PLUGINS) */ |
1911 | /* const char* */ |
1912 | STRUCT_FLD(descr, "Statistics for the InnoDB compression (per index);" |
1913 | " reset cumulated counts" ), |
1914 | |
1915 | /* the plugin license (PLUGIN_LICENSE_XXX) */ |
1916 | /* int */ |
1917 | STRUCT_FLD(license, PLUGIN_LICENSE_GPL), |
1918 | |
1919 | /* the function to invoke when plugin is loaded */ |
1920 | /* int (*)(void*); */ |
1921 | STRUCT_FLD(init, i_s_cmp_per_index_reset_init), |
1922 | |
1923 | /* the function to invoke when plugin is unloaded */ |
1924 | /* int (*)(void*); */ |
1925 | STRUCT_FLD(deinit, i_s_common_deinit), |
1926 | |
1927 | /* plugin version (for SHOW PLUGINS) */ |
1928 | /* unsigned int */ |
1929 | STRUCT_FLD(version, INNODB_VERSION_SHORT), |
1930 | |
1931 | /* struct st_mysql_show_var* */ |
1932 | STRUCT_FLD(status_vars, NULL), |
1933 | |
1934 | /* struct st_mysql_sys_var** */ |
1935 | STRUCT_FLD(system_vars, NULL), |
1936 | |
1937 | /* Maria extension */ |
1938 | STRUCT_FLD(version_info, INNODB_VERSION_STR), |
1939 | STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE), |
1940 | }; |
1941 | |
1942 | /* Fields of the dynamic table information_schema.innodb_cmpmem. */ |
1943 | static ST_FIELD_INFO i_s_cmpmem_fields_info[] = |
1944 | { |
1945 | {STRUCT_FLD(field_name, "page_size" ), |
1946 | STRUCT_FLD(field_length, 5), |
1947 | STRUCT_FLD(field_type, MYSQL_TYPE_LONG), |
1948 | STRUCT_FLD(value, 0), |
1949 | STRUCT_FLD(field_flags, 0), |
1950 | STRUCT_FLD(old_name, "Buddy Block Size" ), |
1951 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
1952 | |
1953 | {STRUCT_FLD(field_name, "buffer_pool_instance" ), |
1954 | STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS), |
1955 | STRUCT_FLD(field_type, MYSQL_TYPE_LONG), |
1956 | STRUCT_FLD(value, 0), |
1957 | STRUCT_FLD(field_flags, 0), |
1958 | STRUCT_FLD(old_name, "Buffer Pool Id" ), |
1959 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
1960 | |
1961 | {STRUCT_FLD(field_name, "pages_used" ), |
1962 | STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS), |
1963 | STRUCT_FLD(field_type, MYSQL_TYPE_LONG), |
1964 | STRUCT_FLD(value, 0), |
1965 | STRUCT_FLD(field_flags, 0), |
1966 | STRUCT_FLD(old_name, "Currently in Use" ), |
1967 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
1968 | |
1969 | {STRUCT_FLD(field_name, "pages_free" ), |
1970 | STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS), |
1971 | STRUCT_FLD(field_type, MYSQL_TYPE_LONG), |
1972 | STRUCT_FLD(value, 0), |
1973 | STRUCT_FLD(field_flags, 0), |
1974 | STRUCT_FLD(old_name, "Currently Available" ), |
1975 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
1976 | |
1977 | {STRUCT_FLD(field_name, "relocation_ops" ), |
1978 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
1979 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
1980 | STRUCT_FLD(value, 0), |
1981 | STRUCT_FLD(field_flags, 0), |
1982 | STRUCT_FLD(old_name, "Total Number of Relocations" ), |
1983 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
1984 | |
1985 | {STRUCT_FLD(field_name, "relocation_time" ), |
1986 | STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS), |
1987 | STRUCT_FLD(field_type, MYSQL_TYPE_LONG), |
1988 | STRUCT_FLD(value, 0), |
1989 | STRUCT_FLD(field_flags, 0), |
1990 | STRUCT_FLD(old_name, "Total Duration of Relocations," |
1991 | " in Seconds" ), |
1992 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
1993 | |
1994 | END_OF_ST_FIELD_INFO |
1995 | }; |
1996 | |
1997 | /*******************************************************************//** |
1998 | Fill the dynamic table information_schema.innodb_cmpmem or |
1999 | innodb_cmpmem_reset. |
2000 | @return 0 on success, 1 on failure */ |
2001 | static |
2002 | int |
2003 | i_s_cmpmem_fill_low( |
2004 | /*================*/ |
2005 | THD* thd, /*!< in: thread */ |
2006 | TABLE_LIST* tables, /*!< in/out: tables to fill */ |
2007 | Item* , /*!< in: condition (ignored) */ |
2008 | ibool reset) /*!< in: TRUE=reset cumulated counts */ |
2009 | { |
2010 | int status = 0; |
2011 | TABLE* table = (TABLE*) tables->table; |
2012 | |
2013 | DBUG_ENTER("i_s_cmpmem_fill_low" ); |
2014 | |
2015 | /* deny access to non-superusers */ |
2016 | if (check_global_access(thd, PROCESS_ACL)) { |
2017 | |
2018 | DBUG_RETURN(0); |
2019 | } |
2020 | |
2021 | RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name.str); |
2022 | |
2023 | for (ulint i = 0; i < srv_buf_pool_instances; i++) { |
2024 | buf_pool_t* buf_pool; |
2025 | ulint zip_free_len_local[BUF_BUDDY_SIZES_MAX + 1]; |
2026 | buf_buddy_stat_t buddy_stat_local[BUF_BUDDY_SIZES_MAX + 1]; |
2027 | |
2028 | status = 0; |
2029 | |
2030 | buf_pool = buf_pool_from_array(i); |
2031 | |
2032 | /* Save buddy stats for buffer pool in local variables. */ |
2033 | buf_pool_mutex_enter(buf_pool); |
2034 | for (uint x = 0; x <= BUF_BUDDY_SIZES; x++) { |
2035 | |
2036 | zip_free_len_local[x] = (x < BUF_BUDDY_SIZES) ? |
2037 | UT_LIST_GET_LEN(buf_pool->zip_free[x]) : 0; |
2038 | |
2039 | buddy_stat_local[x] = buf_pool->buddy_stat[x]; |
2040 | |
2041 | if (reset) { |
2042 | /* This is protected by buf_pool->mutex. */ |
2043 | buf_pool->buddy_stat[x].relocated = 0; |
2044 | buf_pool->buddy_stat[x].relocated_usec = 0; |
2045 | } |
2046 | } |
2047 | buf_pool_mutex_exit(buf_pool); |
2048 | |
2049 | for (uint x = 0; x <= BUF_BUDDY_SIZES; x++) { |
2050 | buf_buddy_stat_t* buddy_stat; |
2051 | |
2052 | buddy_stat = &buddy_stat_local[x]; |
2053 | |
2054 | table->field[0]->store(BUF_BUDDY_LOW << x); |
2055 | table->field[1]->store(i, true); |
2056 | table->field[2]->store(buddy_stat->used, true); |
2057 | table->field[3]->store(zip_free_len_local[x], true); |
2058 | table->field[4]->store(buddy_stat->relocated, true); |
2059 | table->field[5]->store( |
2060 | buddy_stat->relocated_usec / 1000000, true); |
2061 | |
2062 | if (schema_table_store_record(thd, table)) { |
2063 | status = 1; |
2064 | break; |
2065 | } |
2066 | } |
2067 | |
2068 | if (status) { |
2069 | break; |
2070 | } |
2071 | } |
2072 | |
2073 | DBUG_RETURN(status); |
2074 | } |
2075 | |
2076 | /*******************************************************************//** |
2077 | Fill the dynamic table information_schema.innodb_cmpmem. |
2078 | @return 0 on success, 1 on failure */ |
2079 | static |
2080 | int |
2081 | i_s_cmpmem_fill( |
2082 | /*============*/ |
2083 | THD* thd, /*!< in: thread */ |
2084 | TABLE_LIST* tables, /*!< in/out: tables to fill */ |
2085 | Item* cond) /*!< in: condition (ignored) */ |
2086 | { |
2087 | return(i_s_cmpmem_fill_low(thd, tables, cond, FALSE)); |
2088 | } |
2089 | |
2090 | /*******************************************************************//** |
2091 | Fill the dynamic table information_schema.innodb_cmpmem_reset. |
2092 | @return 0 on success, 1 on failure */ |
2093 | static |
2094 | int |
2095 | i_s_cmpmem_reset_fill( |
2096 | /*==================*/ |
2097 | THD* thd, /*!< in: thread */ |
2098 | TABLE_LIST* tables, /*!< in/out: tables to fill */ |
2099 | Item* cond) /*!< in: condition (ignored) */ |
2100 | { |
2101 | return(i_s_cmpmem_fill_low(thd, tables, cond, TRUE)); |
2102 | } |
2103 | |
2104 | /*******************************************************************//** |
2105 | Bind the dynamic table information_schema.innodb_cmpmem. |
2106 | @return 0 on success */ |
2107 | static |
2108 | int |
2109 | i_s_cmpmem_init( |
2110 | /*============*/ |
2111 | void* p) /*!< in/out: table schema object */ |
2112 | { |
2113 | DBUG_ENTER("i_s_cmpmem_init" ); |
2114 | ST_SCHEMA_TABLE* schema = (ST_SCHEMA_TABLE*) p; |
2115 | |
2116 | schema->fields_info = i_s_cmpmem_fields_info; |
2117 | schema->fill_table = i_s_cmpmem_fill; |
2118 | |
2119 | DBUG_RETURN(0); |
2120 | } |
2121 | |
2122 | /*******************************************************************//** |
2123 | Bind the dynamic table information_schema.innodb_cmpmem_reset. |
2124 | @return 0 on success */ |
2125 | static |
2126 | int |
2127 | i_s_cmpmem_reset_init( |
2128 | /*==================*/ |
2129 | void* p) /*!< in/out: table schema object */ |
2130 | { |
2131 | DBUG_ENTER("i_s_cmpmem_reset_init" ); |
2132 | ST_SCHEMA_TABLE* schema = (ST_SCHEMA_TABLE*) p; |
2133 | |
2134 | schema->fields_info = i_s_cmpmem_fields_info; |
2135 | schema->fill_table = i_s_cmpmem_reset_fill; |
2136 | |
2137 | DBUG_RETURN(0); |
2138 | } |
2139 | |
2140 | UNIV_INTERN struct st_maria_plugin i_s_innodb_cmpmem = |
2141 | { |
2142 | /* the plugin type (a MYSQL_XXX_PLUGIN value) */ |
2143 | /* int */ |
2144 | STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN), |
2145 | |
2146 | /* pointer to type-specific plugin descriptor */ |
2147 | /* void* */ |
2148 | STRUCT_FLD(info, &i_s_info), |
2149 | |
2150 | /* plugin name */ |
2151 | /* const char* */ |
2152 | STRUCT_FLD(name, "INNODB_CMPMEM" ), |
2153 | |
2154 | /* plugin author (for SHOW PLUGINS) */ |
2155 | /* const char* */ |
2156 | STRUCT_FLD(author, plugin_author), |
2157 | |
2158 | /* general descriptive text (for SHOW PLUGINS) */ |
2159 | /* const char* */ |
2160 | STRUCT_FLD(descr, "Statistics for the InnoDB compressed buffer pool" ), |
2161 | |
2162 | /* the plugin license (PLUGIN_LICENSE_XXX) */ |
2163 | /* int */ |
2164 | STRUCT_FLD(license, PLUGIN_LICENSE_GPL), |
2165 | |
2166 | /* the function to invoke when plugin is loaded */ |
2167 | /* int (*)(void*); */ |
2168 | STRUCT_FLD(init, i_s_cmpmem_init), |
2169 | |
2170 | /* the function to invoke when plugin is unloaded */ |
2171 | /* int (*)(void*); */ |
2172 | STRUCT_FLD(deinit, i_s_common_deinit), |
2173 | |
2174 | /* plugin version (for SHOW PLUGINS) */ |
2175 | /* unsigned int */ |
2176 | STRUCT_FLD(version, INNODB_VERSION_SHORT), |
2177 | |
2178 | /* struct st_mysql_show_var* */ |
2179 | STRUCT_FLD(status_vars, NULL), |
2180 | |
2181 | /* struct st_mysql_sys_var** */ |
2182 | STRUCT_FLD(system_vars, NULL), |
2183 | |
2184 | /* Maria extension */ |
2185 | STRUCT_FLD(version_info, INNODB_VERSION_STR), |
2186 | STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE), |
2187 | }; |
2188 | |
2189 | UNIV_INTERN struct st_maria_plugin i_s_innodb_cmpmem_reset = |
2190 | { |
2191 | /* the plugin type (a MYSQL_XXX_PLUGIN value) */ |
2192 | /* int */ |
2193 | STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN), |
2194 | |
2195 | /* pointer to type-specific plugin descriptor */ |
2196 | /* void* */ |
2197 | STRUCT_FLD(info, &i_s_info), |
2198 | |
2199 | /* plugin name */ |
2200 | /* const char* */ |
2201 | STRUCT_FLD(name, "INNODB_CMPMEM_RESET" ), |
2202 | |
2203 | /* plugin author (for SHOW PLUGINS) */ |
2204 | /* const char* */ |
2205 | STRUCT_FLD(author, plugin_author), |
2206 | |
2207 | /* general descriptive text (for SHOW PLUGINS) */ |
2208 | /* const char* */ |
2209 | STRUCT_FLD(descr, "Statistics for the InnoDB compressed buffer pool;" |
2210 | " reset cumulated counts" ), |
2211 | |
2212 | /* the plugin license (PLUGIN_LICENSE_XXX) */ |
2213 | /* int */ |
2214 | STRUCT_FLD(license, PLUGIN_LICENSE_GPL), |
2215 | |
2216 | /* the function to invoke when plugin is loaded */ |
2217 | /* int (*)(void*); */ |
2218 | STRUCT_FLD(init, i_s_cmpmem_reset_init), |
2219 | |
2220 | /* the function to invoke when plugin is unloaded */ |
2221 | /* int (*)(void*); */ |
2222 | STRUCT_FLD(deinit, i_s_common_deinit), |
2223 | |
2224 | /* plugin version (for SHOW PLUGINS) */ |
2225 | /* unsigned int */ |
2226 | STRUCT_FLD(version, INNODB_VERSION_SHORT), |
2227 | |
2228 | /* struct st_mysql_show_var* */ |
2229 | STRUCT_FLD(status_vars, NULL), |
2230 | |
2231 | /* struct st_mysql_sys_var** */ |
2232 | STRUCT_FLD(system_vars, NULL), |
2233 | |
2234 | /* Maria extension */ |
2235 | STRUCT_FLD(version_info, INNODB_VERSION_STR), |
2236 | STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE), |
2237 | }; |
2238 | |
2239 | /* Fields of the dynamic table INFORMATION_SCHEMA.innodb_metrics */ |
2240 | static ST_FIELD_INFO innodb_metrics_fields_info[] = |
2241 | { |
2242 | #define METRIC_NAME 0 |
2243 | {STRUCT_FLD(field_name, "NAME" ), |
2244 | STRUCT_FLD(field_length, NAME_LEN + 1), |
2245 | STRUCT_FLD(field_type, MYSQL_TYPE_STRING), |
2246 | STRUCT_FLD(value, 0), |
2247 | STRUCT_FLD(field_flags, 0), |
2248 | STRUCT_FLD(old_name, "" ), |
2249 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
2250 | |
2251 | #define METRIC_SUBSYS 1 |
2252 | {STRUCT_FLD(field_name, "SUBSYSTEM" ), |
2253 | STRUCT_FLD(field_length, NAME_LEN + 1), |
2254 | STRUCT_FLD(field_type, MYSQL_TYPE_STRING), |
2255 | STRUCT_FLD(value, 0), |
2256 | STRUCT_FLD(field_flags, 0), |
2257 | STRUCT_FLD(old_name, "" ), |
2258 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
2259 | |
2260 | #define METRIC_VALUE_START 2 |
2261 | {STRUCT_FLD(field_name, "COUNT" ), |
2262 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
2263 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
2264 | STRUCT_FLD(value, 0), |
2265 | STRUCT_FLD(field_flags, 0), |
2266 | STRUCT_FLD(old_name, "" ), |
2267 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
2268 | |
2269 | #define METRIC_MAX_VALUE_START 3 |
2270 | {STRUCT_FLD(field_name, "MAX_COUNT" ), |
2271 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
2272 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
2273 | STRUCT_FLD(value, 0), |
2274 | STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL), |
2275 | STRUCT_FLD(old_name, "" ), |
2276 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
2277 | |
2278 | #define METRIC_MIN_VALUE_START 4 |
2279 | {STRUCT_FLD(field_name, "MIN_COUNT" ), |
2280 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
2281 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
2282 | STRUCT_FLD(value, 0), |
2283 | STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL), |
2284 | STRUCT_FLD(old_name, "" ), |
2285 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
2286 | |
2287 | #define METRIC_AVG_VALUE_START 5 |
2288 | {STRUCT_FLD(field_name, "AVG_COUNT" ), |
2289 | STRUCT_FLD(field_length, MAX_FLOAT_STR_LENGTH), |
2290 | STRUCT_FLD(field_type, MYSQL_TYPE_FLOAT), |
2291 | STRUCT_FLD(value, 0), |
2292 | STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL), |
2293 | STRUCT_FLD(old_name, "" ), |
2294 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
2295 | |
2296 | #define METRIC_VALUE_RESET 6 |
2297 | {STRUCT_FLD(field_name, "COUNT_RESET" ), |
2298 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
2299 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
2300 | STRUCT_FLD(value, 0), |
2301 | STRUCT_FLD(field_flags, 0), |
2302 | STRUCT_FLD(old_name, "" ), |
2303 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
2304 | |
2305 | #define METRIC_MAX_VALUE_RESET 7 |
2306 | {STRUCT_FLD(field_name, "MAX_COUNT_RESET" ), |
2307 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
2308 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
2309 | STRUCT_FLD(value, 0), |
2310 | STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL), |
2311 | STRUCT_FLD(old_name, "" ), |
2312 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
2313 | |
2314 | #define METRIC_MIN_VALUE_RESET 8 |
2315 | {STRUCT_FLD(field_name, "MIN_COUNT_RESET" ), |
2316 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
2317 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
2318 | STRUCT_FLD(value, 0), |
2319 | STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL), |
2320 | STRUCT_FLD(old_name, "" ), |
2321 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
2322 | |
2323 | #define METRIC_AVG_VALUE_RESET 9 |
2324 | {STRUCT_FLD(field_name, "AVG_COUNT_RESET" ), |
2325 | STRUCT_FLD(field_length, MAX_FLOAT_STR_LENGTH), |
2326 | STRUCT_FLD(field_type, MYSQL_TYPE_FLOAT), |
2327 | STRUCT_FLD(value, 0), |
2328 | STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL), |
2329 | STRUCT_FLD(old_name, "" ), |
2330 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
2331 | |
2332 | #define METRIC_START_TIME 10 |
2333 | {STRUCT_FLD(field_name, "TIME_ENABLED" ), |
2334 | STRUCT_FLD(field_length, 0), |
2335 | STRUCT_FLD(field_type, MYSQL_TYPE_DATETIME), |
2336 | STRUCT_FLD(value, 0), |
2337 | STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL), |
2338 | STRUCT_FLD(old_name, "" ), |
2339 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
2340 | |
2341 | #define METRIC_STOP_TIME 11 |
2342 | {STRUCT_FLD(field_name, "TIME_DISABLED" ), |
2343 | STRUCT_FLD(field_length, 0), |
2344 | STRUCT_FLD(field_type, MYSQL_TYPE_DATETIME), |
2345 | STRUCT_FLD(value, 0), |
2346 | STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL), |
2347 | STRUCT_FLD(old_name, "" ), |
2348 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
2349 | |
2350 | #define METRIC_TIME_ELAPSED 12 |
2351 | {STRUCT_FLD(field_name, "TIME_ELAPSED" ), |
2352 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
2353 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
2354 | STRUCT_FLD(value, 0), |
2355 | STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL), |
2356 | STRUCT_FLD(old_name, "" ), |
2357 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
2358 | |
2359 | #define METRIC_RESET_TIME 13 |
2360 | {STRUCT_FLD(field_name, "TIME_RESET" ), |
2361 | STRUCT_FLD(field_length, 0), |
2362 | STRUCT_FLD(field_type, MYSQL_TYPE_DATETIME), |
2363 | STRUCT_FLD(value, 0), |
2364 | STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL), |
2365 | STRUCT_FLD(old_name, "" ), |
2366 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
2367 | |
2368 | #define METRIC_STATUS 14 |
2369 | {STRUCT_FLD(field_name, "STATUS" ), |
2370 | STRUCT_FLD(field_length, NAME_LEN + 1), |
2371 | STRUCT_FLD(field_type, MYSQL_TYPE_STRING), |
2372 | STRUCT_FLD(value, 0), |
2373 | STRUCT_FLD(field_flags, 0), |
2374 | STRUCT_FLD(old_name, "" ), |
2375 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
2376 | |
2377 | #define METRIC_TYPE 15 |
2378 | {STRUCT_FLD(field_name, "TYPE" ), |
2379 | STRUCT_FLD(field_length, NAME_LEN + 1), |
2380 | STRUCT_FLD(field_type, MYSQL_TYPE_STRING), |
2381 | STRUCT_FLD(value, 0), |
2382 | STRUCT_FLD(field_flags, 0), |
2383 | STRUCT_FLD(old_name, "" ), |
2384 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
2385 | |
2386 | #define METRIC_DESC 16 |
2387 | {STRUCT_FLD(field_name, "COMMENT" ), |
2388 | STRUCT_FLD(field_length, NAME_LEN + 1), |
2389 | STRUCT_FLD(field_type, MYSQL_TYPE_STRING), |
2390 | STRUCT_FLD(value, 0), |
2391 | STRUCT_FLD(field_flags, 0), |
2392 | STRUCT_FLD(old_name, "" ), |
2393 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
2394 | |
2395 | END_OF_ST_FIELD_INFO |
2396 | }; |
2397 | |
2398 | /**********************************************************************//** |
2399 | Fill the information schema metrics table. |
2400 | @return 0 on success */ |
2401 | static |
2402 | int |
2403 | i_s_metrics_fill( |
2404 | /*=============*/ |
2405 | THD* thd, /*!< in: thread */ |
2406 | TABLE* table_to_fill) /*!< in/out: fill this table */ |
2407 | { |
2408 | int count; |
2409 | Field** fields; |
2410 | double time_diff = 0; |
2411 | monitor_info_t* monitor_info; |
2412 | mon_type_t min_val; |
2413 | mon_type_t max_val; |
2414 | |
2415 | DBUG_ENTER("i_s_metrics_fill" ); |
2416 | fields = table_to_fill->field; |
2417 | |
2418 | for (count = 0; count < NUM_MONITOR; count++) { |
2419 | monitor_info = srv_mon_get_info((monitor_id_t) count); |
2420 | |
2421 | /* A good place to sanity check the Monitor ID */ |
2422 | ut_a(count == monitor_info->monitor_id); |
2423 | |
2424 | /* If the item refers to a Module, nothing to fill, |
2425 | continue. */ |
2426 | if ((monitor_info->monitor_type & MONITOR_MODULE) |
2427 | || (monitor_info->monitor_type & MONITOR_HIDDEN)) { |
2428 | continue; |
2429 | } |
2430 | |
2431 | /* If this is an existing "status variable", and |
2432 | its corresponding counter is still on, we need |
2433 | to calculate the result from its corresponding |
2434 | counter. */ |
2435 | if (monitor_info->monitor_type & MONITOR_EXISTING |
2436 | && MONITOR_IS_ON(count)) { |
2437 | srv_mon_process_existing_counter((monitor_id_t) count, |
2438 | MONITOR_GET_VALUE); |
2439 | } |
2440 | |
2441 | /* Fill in counter's basic information */ |
2442 | OK(field_store_string(fields[METRIC_NAME], |
2443 | monitor_info->monitor_name)); |
2444 | |
2445 | OK(field_store_string(fields[METRIC_SUBSYS], |
2446 | monitor_info->monitor_module)); |
2447 | |
2448 | OK(field_store_string(fields[METRIC_DESC], |
2449 | monitor_info->monitor_desc)); |
2450 | |
2451 | /* Fill in counter values */ |
2452 | OK(fields[METRIC_VALUE_RESET]->store( |
2453 | MONITOR_VALUE(count), FALSE)); |
2454 | |
2455 | OK(fields[METRIC_VALUE_START]->store( |
2456 | MONITOR_VALUE_SINCE_START(count), FALSE)); |
2457 | |
2458 | /* If the max value is MAX_RESERVED, counter max |
2459 | value has not been updated. Set the column value |
2460 | to NULL. */ |
2461 | if (MONITOR_MAX_VALUE(count) == MAX_RESERVED |
2462 | || MONITOR_MAX_MIN_NOT_INIT(count)) { |
2463 | fields[METRIC_MAX_VALUE_RESET]->set_null(); |
2464 | } else { |
2465 | OK(fields[METRIC_MAX_VALUE_RESET]->store( |
2466 | MONITOR_MAX_VALUE(count), FALSE)); |
2467 | fields[METRIC_MAX_VALUE_RESET]->set_notnull(); |
2468 | } |
2469 | |
2470 | /* If the min value is MAX_RESERVED, counter min |
2471 | value has not been updated. Set the column value |
2472 | to NULL. */ |
2473 | if (MONITOR_MIN_VALUE(count) == MIN_RESERVED |
2474 | || MONITOR_MAX_MIN_NOT_INIT(count)) { |
2475 | fields[METRIC_MIN_VALUE_RESET]->set_null(); |
2476 | } else { |
2477 | OK(fields[METRIC_MIN_VALUE_RESET]->store( |
2478 | MONITOR_MIN_VALUE(count), FALSE)); |
2479 | fields[METRIC_MIN_VALUE_RESET]->set_notnull(); |
2480 | } |
2481 | |
2482 | /* Calculate the max value since counter started */ |
2483 | max_val = srv_mon_calc_max_since_start((monitor_id_t) count); |
2484 | |
2485 | if (max_val == MAX_RESERVED |
2486 | || MONITOR_MAX_MIN_NOT_INIT(count)) { |
2487 | fields[METRIC_MAX_VALUE_START]->set_null(); |
2488 | } else { |
2489 | OK(fields[METRIC_MAX_VALUE_START]->store( |
2490 | max_val, FALSE)); |
2491 | fields[METRIC_MAX_VALUE_START]->set_notnull(); |
2492 | } |
2493 | |
2494 | /* Calculate the min value since counter started */ |
2495 | min_val = srv_mon_calc_min_since_start((monitor_id_t) count); |
2496 | |
2497 | if (min_val == MIN_RESERVED |
2498 | || MONITOR_MAX_MIN_NOT_INIT(count)) { |
2499 | fields[METRIC_MIN_VALUE_START]->set_null(); |
2500 | } else { |
2501 | OK(fields[METRIC_MIN_VALUE_START]->store( |
2502 | min_val, FALSE)); |
2503 | |
2504 | fields[METRIC_MIN_VALUE_START]->set_notnull(); |
2505 | } |
2506 | |
2507 | /* If monitor has been enabled (no matter it is disabled |
2508 | or not now), fill METRIC_START_TIME and METRIC_TIME_ELAPSED |
2509 | field */ |
2510 | if (MONITOR_FIELD(count, mon_start_time)) { |
2511 | OK(field_store_time_t(fields[METRIC_START_TIME], |
2512 | (time_t)MONITOR_FIELD(count, mon_start_time))); |
2513 | fields[METRIC_START_TIME]->set_notnull(); |
2514 | |
2515 | /* If monitor is enabled, the TIME_ELAPSED is the |
2516 | time difference between current and time when monitor |
2517 | is enabled. Otherwise, it is the time difference |
2518 | between time when monitor is enabled and time |
2519 | when it is disabled */ |
2520 | if (MONITOR_IS_ON(count)) { |
2521 | time_diff = difftime(time(NULL), |
2522 | MONITOR_FIELD(count, mon_start_time)); |
2523 | } else { |
2524 | time_diff = difftime( |
2525 | MONITOR_FIELD(count, mon_stop_time), |
2526 | MONITOR_FIELD(count, mon_start_time)); |
2527 | } |
2528 | |
2529 | OK(fields[METRIC_TIME_ELAPSED]->store( |
2530 | time_diff)); |
2531 | fields[METRIC_TIME_ELAPSED]->set_notnull(); |
2532 | } else { |
2533 | fields[METRIC_START_TIME]->set_null(); |
2534 | fields[METRIC_TIME_ELAPSED]->set_null(); |
2535 | time_diff = 0; |
2536 | } |
2537 | |
2538 | /* Unless MONITOR__NO_AVERAGE is marked, we will need |
2539 | to calculate the average value. If this is a monitor set |
2540 | owner marked by MONITOR_SET_OWNER, divide |
2541 | the value by another counter (number of calls) designated |
2542 | by monitor_info->monitor_related_id. |
2543 | Otherwise average the counter value by the time between the |
2544 | time that the counter is enabled and time it is disabled |
2545 | or time it is sampled. */ |
2546 | if (!(monitor_info->monitor_type & MONITOR_NO_AVERAGE) |
2547 | && (monitor_info->monitor_type & MONITOR_SET_OWNER) |
2548 | && monitor_info->monitor_related_id) { |
2549 | mon_type_t value_start |
2550 | = MONITOR_VALUE_SINCE_START( |
2551 | monitor_info->monitor_related_id); |
2552 | |
2553 | if (value_start) { |
2554 | OK(fields[METRIC_AVG_VALUE_START]->store( |
2555 | MONITOR_VALUE_SINCE_START(count) |
2556 | / value_start, FALSE)); |
2557 | |
2558 | fields[METRIC_AVG_VALUE_START]->set_notnull(); |
2559 | } else { |
2560 | fields[METRIC_AVG_VALUE_START]->set_null(); |
2561 | } |
2562 | |
2563 | if (MONITOR_VALUE(monitor_info->monitor_related_id)) { |
2564 | OK(fields[METRIC_AVG_VALUE_RESET]->store( |
2565 | MONITOR_VALUE(count) |
2566 | / MONITOR_VALUE( |
2567 | monitor_info->monitor_related_id), |
2568 | FALSE)); |
2569 | } else { |
2570 | fields[METRIC_AVG_VALUE_RESET]->set_null(); |
2571 | } |
2572 | } else if (!(monitor_info->monitor_type & MONITOR_NO_AVERAGE) |
2573 | && !(monitor_info->monitor_type |
2574 | & MONITOR_DISPLAY_CURRENT)) { |
2575 | if (time_diff != 0) { |
2576 | OK(fields[METRIC_AVG_VALUE_START]->store( |
2577 | (double) MONITOR_VALUE_SINCE_START( |
2578 | count) / time_diff)); |
2579 | fields[METRIC_AVG_VALUE_START]->set_notnull(); |
2580 | } else { |
2581 | fields[METRIC_AVG_VALUE_START]->set_null(); |
2582 | } |
2583 | |
2584 | if (MONITOR_FIELD(count, mon_reset_time)) { |
2585 | /* calculate the time difference since last |
2586 | reset */ |
2587 | if (MONITOR_IS_ON(count)) { |
2588 | time_diff = difftime( |
2589 | time(NULL), MONITOR_FIELD( |
2590 | count, mon_reset_time)); |
2591 | } else { |
2592 | time_diff = difftime( |
2593 | MONITOR_FIELD(count, mon_stop_time), |
2594 | MONITOR_FIELD(count, mon_reset_time)); |
2595 | } |
2596 | } else { |
2597 | time_diff = 0; |
2598 | } |
2599 | |
2600 | if (time_diff != 0) { |
2601 | OK(fields[METRIC_AVG_VALUE_RESET]->store( |
2602 | static_cast<double>( |
2603 | MONITOR_VALUE(count) / time_diff))); |
2604 | fields[METRIC_AVG_VALUE_RESET]->set_notnull(); |
2605 | } else { |
2606 | fields[METRIC_AVG_VALUE_RESET]->set_null(); |
2607 | } |
2608 | } else { |
2609 | fields[METRIC_AVG_VALUE_START]->set_null(); |
2610 | fields[METRIC_AVG_VALUE_RESET]->set_null(); |
2611 | } |
2612 | |
2613 | |
2614 | if (MONITOR_IS_ON(count)) { |
2615 | /* If monitor is on, the stop time will set to NULL */ |
2616 | fields[METRIC_STOP_TIME]->set_null(); |
2617 | |
2618 | /* Display latest Monitor Reset Time only if Monitor |
2619 | counter is on. */ |
2620 | if (MONITOR_FIELD(count, mon_reset_time)) { |
2621 | OK(field_store_time_t( |
2622 | fields[METRIC_RESET_TIME], |
2623 | (time_t)MONITOR_FIELD( |
2624 | count, mon_reset_time))); |
2625 | fields[METRIC_RESET_TIME]->set_notnull(); |
2626 | } else { |
2627 | fields[METRIC_RESET_TIME]->set_null(); |
2628 | } |
2629 | |
2630 | /* Display the monitor status as "enabled" */ |
2631 | OK(field_store_string(fields[METRIC_STATUS], |
2632 | "enabled" )); |
2633 | } else { |
2634 | if (MONITOR_FIELD(count, mon_stop_time)) { |
2635 | OK(field_store_time_t(fields[METRIC_STOP_TIME], |
2636 | (time_t)MONITOR_FIELD(count, mon_stop_time))); |
2637 | fields[METRIC_STOP_TIME]->set_notnull(); |
2638 | } else { |
2639 | fields[METRIC_STOP_TIME]->set_null(); |
2640 | } |
2641 | |
2642 | fields[METRIC_RESET_TIME]->set_null(); |
2643 | |
2644 | OK(field_store_string(fields[METRIC_STATUS], |
2645 | "disabled" )); |
2646 | } |
2647 | |
2648 | if (monitor_info->monitor_type & MONITOR_DISPLAY_CURRENT) { |
2649 | OK(field_store_string(fields[METRIC_TYPE], |
2650 | "value" )); |
2651 | } else if (monitor_info->monitor_type & MONITOR_EXISTING) { |
2652 | OK(field_store_string(fields[METRIC_TYPE], |
2653 | "status_counter" )); |
2654 | } else if (monitor_info->monitor_type & MONITOR_SET_OWNER) { |
2655 | OK(field_store_string(fields[METRIC_TYPE], |
2656 | "set_owner" )); |
2657 | } else if ( monitor_info->monitor_type & MONITOR_SET_MEMBER) { |
2658 | OK(field_store_string(fields[METRIC_TYPE], |
2659 | "set_member" )); |
2660 | } else { |
2661 | OK(field_store_string(fields[METRIC_TYPE], |
2662 | "counter" )); |
2663 | } |
2664 | |
2665 | OK(schema_table_store_record(thd, table_to_fill)); |
2666 | } |
2667 | |
2668 | DBUG_RETURN(0); |
2669 | } |
2670 | |
2671 | /*******************************************************************//** |
2672 | Function to fill information schema metrics tables. |
2673 | @return 0 on success */ |
2674 | static |
2675 | int |
2676 | i_s_metrics_fill_table( |
2677 | /*===================*/ |
2678 | THD* thd, /*!< in: thread */ |
2679 | TABLE_LIST* tables, /*!< in/out: tables to fill */ |
2680 | Item* ) /*!< in: condition (not used) */ |
2681 | { |
2682 | DBUG_ENTER("i_s_metrics_fill_table" ); |
2683 | |
2684 | /* deny access to non-superusers */ |
2685 | if (check_global_access(thd, PROCESS_ACL)) { |
2686 | DBUG_RETURN(0); |
2687 | } |
2688 | |
2689 | i_s_metrics_fill(thd, tables->table); |
2690 | |
2691 | DBUG_RETURN(0); |
2692 | } |
2693 | /*******************************************************************//** |
2694 | Bind the dynamic table INFORMATION_SCHEMA.innodb_metrics |
2695 | @return 0 on success */ |
2696 | static |
2697 | int |
2698 | innodb_metrics_init( |
2699 | /*================*/ |
2700 | void* p) /*!< in/out: table schema object */ |
2701 | { |
2702 | ST_SCHEMA_TABLE* schema; |
2703 | |
2704 | DBUG_ENTER("innodb_metrics_init" ); |
2705 | |
2706 | schema = (ST_SCHEMA_TABLE*) p; |
2707 | |
2708 | schema->fields_info = innodb_metrics_fields_info; |
2709 | schema->fill_table = i_s_metrics_fill_table; |
2710 | |
2711 | DBUG_RETURN(0); |
2712 | } |
2713 | |
2714 | UNIV_INTERN struct st_maria_plugin i_s_innodb_metrics = |
2715 | { |
2716 | /* the plugin type (a MYSQL_XXX_PLUGIN value) */ |
2717 | /* int */ |
2718 | STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN), |
2719 | |
2720 | /* pointer to type-specific plugin descriptor */ |
2721 | /* void* */ |
2722 | STRUCT_FLD(info, &i_s_info), |
2723 | |
2724 | /* plugin name */ |
2725 | /* const char* */ |
2726 | STRUCT_FLD(name, "INNODB_METRICS" ), |
2727 | |
2728 | /* plugin author (for SHOW PLUGINS) */ |
2729 | /* const char* */ |
2730 | STRUCT_FLD(author, plugin_author), |
2731 | |
2732 | /* general descriptive text (for SHOW PLUGINS) */ |
2733 | /* const char* */ |
2734 | STRUCT_FLD(descr, "InnoDB Metrics Info" ), |
2735 | |
2736 | /* the plugin license (PLUGIN_LICENSE_XXX) */ |
2737 | /* int */ |
2738 | STRUCT_FLD(license, PLUGIN_LICENSE_GPL), |
2739 | |
2740 | /* the function to invoke when plugin is loaded */ |
2741 | /* int (*)(void*); */ |
2742 | STRUCT_FLD(init, innodb_metrics_init), |
2743 | |
2744 | /* the function to invoke when plugin is unloaded */ |
2745 | /* int (*)(void*); */ |
2746 | STRUCT_FLD(deinit, i_s_common_deinit), |
2747 | |
2748 | /* plugin version (for SHOW PLUGINS) */ |
2749 | /* unsigned int */ |
2750 | STRUCT_FLD(version, INNODB_VERSION_SHORT), |
2751 | |
2752 | /* struct st_mysql_show_var* */ |
2753 | STRUCT_FLD(status_vars, NULL), |
2754 | |
2755 | /* struct st_mysql_sys_var** */ |
2756 | STRUCT_FLD(system_vars, NULL), |
2757 | |
2758 | /* Maria extension */ |
2759 | STRUCT_FLD(version_info, INNODB_VERSION_STR), |
2760 | STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE), |
2761 | }; |
2762 | /* Fields of the dynamic table INFORMATION_SCHEMA.innodb_ft_default_stopword */ |
2763 | static ST_FIELD_INFO i_s_stopword_fields_info[] = |
2764 | { |
2765 | #define STOPWORD_VALUE 0 |
2766 | {STRUCT_FLD(field_name, "value" ), |
2767 | STRUCT_FLD(field_length, TRX_ID_MAX_LEN + 1), |
2768 | STRUCT_FLD(field_type, MYSQL_TYPE_STRING), |
2769 | STRUCT_FLD(value, 0), |
2770 | STRUCT_FLD(field_flags, 0), |
2771 | STRUCT_FLD(old_name, "" ), |
2772 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
2773 | |
2774 | END_OF_ST_FIELD_INFO |
2775 | }; |
2776 | |
2777 | /*******************************************************************//** |
2778 | Fill the dynamic table information_schema.innodb_ft_default_stopword. |
2779 | @return 0 on success, 1 on failure */ |
2780 | static |
2781 | int |
2782 | i_s_stopword_fill( |
2783 | /*==============*/ |
2784 | THD* thd, /*!< in: thread */ |
2785 | TABLE_LIST* tables, /*!< in/out: tables to fill */ |
2786 | Item* ) /*!< in: condition (not used) */ |
2787 | { |
2788 | Field** fields; |
2789 | ulint i = 0; |
2790 | TABLE* table = (TABLE*) tables->table; |
2791 | |
2792 | DBUG_ENTER("i_s_stopword_fill" ); |
2793 | |
2794 | fields = table->field; |
2795 | |
2796 | /* Fill with server default stopword list in array |
2797 | fts_default_stopword */ |
2798 | while (fts_default_stopword[i]) { |
2799 | OK(field_store_string(fields[STOPWORD_VALUE], |
2800 | fts_default_stopword[i])); |
2801 | |
2802 | OK(schema_table_store_record(thd, table)); |
2803 | i++; |
2804 | } |
2805 | |
2806 | DBUG_RETURN(0); |
2807 | } |
2808 | |
2809 | /*******************************************************************//** |
2810 | Bind the dynamic table information_schema.innodb_ft_default_stopword. |
2811 | @return 0 on success */ |
2812 | static |
2813 | int |
2814 | i_s_stopword_init( |
2815 | /*==============*/ |
2816 | void* p) /*!< in/out: table schema object */ |
2817 | { |
2818 | DBUG_ENTER("i_s_stopword_init" ); |
2819 | ST_SCHEMA_TABLE* schema = (ST_SCHEMA_TABLE*) p; |
2820 | |
2821 | schema->fields_info = i_s_stopword_fields_info; |
2822 | schema->fill_table = i_s_stopword_fill; |
2823 | |
2824 | DBUG_RETURN(0); |
2825 | } |
2826 | |
2827 | UNIV_INTERN struct st_maria_plugin i_s_innodb_ft_default_stopword = |
2828 | { |
2829 | /* the plugin type (a MYSQL_XXX_PLUGIN value) */ |
2830 | /* int */ |
2831 | STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN), |
2832 | |
2833 | /* pointer to type-specific plugin descriptor */ |
2834 | /* void* */ |
2835 | STRUCT_FLD(info, &i_s_info), |
2836 | |
2837 | /* plugin name */ |
2838 | /* const char* */ |
2839 | STRUCT_FLD(name, "INNODB_FT_DEFAULT_STOPWORD" ), |
2840 | |
2841 | /* plugin author (for SHOW PLUGINS) */ |
2842 | /* const char* */ |
2843 | STRUCT_FLD(author, plugin_author), |
2844 | |
2845 | /* general descriptive text (for SHOW PLUGINS) */ |
2846 | /* const char* */ |
2847 | STRUCT_FLD(descr, "Default stopword list for InnoDB Full Text Search" ), |
2848 | |
2849 | /* the plugin license (PLUGIN_LICENSE_XXX) */ |
2850 | /* int */ |
2851 | STRUCT_FLD(license, PLUGIN_LICENSE_GPL), |
2852 | |
2853 | /* the function to invoke when plugin is loaded */ |
2854 | /* int (*)(void*); */ |
2855 | STRUCT_FLD(init, i_s_stopword_init), |
2856 | |
2857 | /* the function to invoke when plugin is unloaded */ |
2858 | /* int (*)(void*); */ |
2859 | STRUCT_FLD(deinit, i_s_common_deinit), |
2860 | |
2861 | /* plugin version (for SHOW PLUGINS) */ |
2862 | /* unsigned int */ |
2863 | STRUCT_FLD(version, INNODB_VERSION_SHORT), |
2864 | |
2865 | /* struct st_mysql_show_var* */ |
2866 | STRUCT_FLD(status_vars, NULL), |
2867 | |
2868 | /* struct st_mysql_sys_var** */ |
2869 | STRUCT_FLD(system_vars, NULL), |
2870 | |
2871 | /* Maria extension */ |
2872 | STRUCT_FLD(version_info, INNODB_VERSION_STR), |
2873 | STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE), |
2874 | }; |
2875 | |
2876 | /* Fields of the dynamic table INFORMATION_SCHEMA.INNODB_FT_DELETED |
2877 | INFORMATION_SCHEMA.INNODB_FT_BEING_DELETED */ |
2878 | static ST_FIELD_INFO i_s_fts_doc_fields_info[] = |
2879 | { |
2880 | #define I_S_FTS_DOC_ID 0 |
2881 | {STRUCT_FLD(field_name, "DOC_ID" ), |
2882 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
2883 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
2884 | STRUCT_FLD(value, 0), |
2885 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
2886 | STRUCT_FLD(old_name, "" ), |
2887 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
2888 | |
2889 | END_OF_ST_FIELD_INFO |
2890 | }; |
2891 | |
2892 | /*******************************************************************//** |
2893 | Fill the dynamic table INFORMATION_SCHEMA.INNODB_FT_DELETED or |
2894 | INFORMATION_SCHEMA.INNODB_FT_BEING_DELETED |
2895 | @return 0 on success, 1 on failure */ |
2896 | static |
2897 | int |
2898 | i_s_fts_deleted_generic_fill( |
2899 | /*=========================*/ |
2900 | THD* thd, /*!< in: thread */ |
2901 | TABLE_LIST* tables, /*!< in/out: tables to fill */ |
2902 | ibool being_deleted) /*!< in: BEING_DELTED table */ |
2903 | { |
2904 | Field** fields; |
2905 | TABLE* table = (TABLE*) tables->table; |
2906 | trx_t* trx; |
2907 | fts_table_t fts_table; |
2908 | fts_doc_ids_t* deleted; |
2909 | dict_table_t* user_table; |
2910 | |
2911 | DBUG_ENTER("i_s_fts_deleted_generic_fill" ); |
2912 | |
2913 | /* deny access to non-superusers */ |
2914 | if (check_global_access(thd, PROCESS_ACL)) { |
2915 | DBUG_RETURN(0); |
2916 | } |
2917 | |
2918 | if (!fts_internal_tbl_name) { |
2919 | DBUG_RETURN(0); |
2920 | } |
2921 | |
2922 | /* Prevent DDL to drop fts aux tables. */ |
2923 | rw_lock_s_lock(dict_operation_lock); |
2924 | |
2925 | user_table = dict_table_open_on_name( |
2926 | fts_internal_tbl_name, FALSE, FALSE, DICT_ERR_IGNORE_NONE); |
2927 | |
2928 | if (!user_table) { |
2929 | rw_lock_s_unlock(dict_operation_lock); |
2930 | |
2931 | DBUG_RETURN(0); |
2932 | } else if (!dict_table_has_fts_index(user_table)) { |
2933 | dict_table_close(user_table, FALSE, FALSE); |
2934 | |
2935 | rw_lock_s_unlock(dict_operation_lock); |
2936 | |
2937 | DBUG_RETURN(0); |
2938 | } |
2939 | |
2940 | deleted = fts_doc_ids_create(); |
2941 | |
2942 | trx = trx_create(); |
2943 | trx->op_info = "Select for FTS DELETE TABLE" ; |
2944 | |
2945 | FTS_INIT_FTS_TABLE(&fts_table, |
2946 | (being_deleted) ? "BEING_DELETED" : "DELETED" , |
2947 | FTS_COMMON_TABLE, user_table); |
2948 | |
2949 | fts_table_fetch_doc_ids(trx, &fts_table, deleted); |
2950 | |
2951 | fields = table->field; |
2952 | |
2953 | int ret = 0; |
2954 | |
2955 | for (ulint j = 0; j < ib_vector_size(deleted->doc_ids); ++j) { |
2956 | doc_id_t doc_id; |
2957 | |
2958 | doc_id = *(doc_id_t*) ib_vector_get_const(deleted->doc_ids, j); |
2959 | |
2960 | BREAK_IF(ret = fields[I_S_FTS_DOC_ID]->store(doc_id, true)); |
2961 | |
2962 | BREAK_IF(ret = schema_table_store_record(thd, table)); |
2963 | } |
2964 | |
2965 | trx_free(trx); |
2966 | |
2967 | fts_doc_ids_free(deleted); |
2968 | |
2969 | dict_table_close(user_table, FALSE, FALSE); |
2970 | |
2971 | rw_lock_s_unlock(dict_operation_lock); |
2972 | |
2973 | DBUG_RETURN(ret); |
2974 | } |
2975 | |
2976 | /*******************************************************************//** |
2977 | Fill the dynamic table INFORMATION_SCHEMA.INNODB_FT_DELETED |
2978 | @return 0 on success, 1 on failure */ |
2979 | static |
2980 | int |
2981 | i_s_fts_deleted_fill( |
2982 | /*=================*/ |
2983 | THD* thd, /*!< in: thread */ |
2984 | TABLE_LIST* tables, /*!< in/out: tables to fill */ |
2985 | Item* ) /*!< in: condition (ignored) */ |
2986 | { |
2987 | DBUG_ENTER("i_s_fts_deleted_fill" ); |
2988 | |
2989 | DBUG_RETURN(i_s_fts_deleted_generic_fill(thd, tables, FALSE)); |
2990 | } |
2991 | |
2992 | /*******************************************************************//** |
2993 | Bind the dynamic table INFORMATION_SCHEMA.INNODB_FT_DELETED |
2994 | @return 0 on success */ |
2995 | static |
2996 | int |
2997 | i_s_fts_deleted_init( |
2998 | /*=================*/ |
2999 | void* p) /*!< in/out: table schema object */ |
3000 | { |
3001 | DBUG_ENTER("i_s_fts_deleted_init" ); |
3002 | ST_SCHEMA_TABLE* schema = (ST_SCHEMA_TABLE*) p; |
3003 | |
3004 | schema->fields_info = i_s_fts_doc_fields_info; |
3005 | schema->fill_table = i_s_fts_deleted_fill; |
3006 | |
3007 | DBUG_RETURN(0); |
3008 | } |
3009 | |
3010 | UNIV_INTERN struct st_maria_plugin i_s_innodb_ft_deleted = |
3011 | { |
3012 | /* the plugin type (a MYSQL_XXX_PLUGIN value) */ |
3013 | /* int */ |
3014 | STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN), |
3015 | |
3016 | /* pointer to type-specific plugin descriptor */ |
3017 | /* void* */ |
3018 | STRUCT_FLD(info, &i_s_info), |
3019 | |
3020 | /* plugin name */ |
3021 | /* const char* */ |
3022 | STRUCT_FLD(name, "INNODB_FT_DELETED" ), |
3023 | |
3024 | /* plugin author (for SHOW PLUGINS) */ |
3025 | /* const char* */ |
3026 | STRUCT_FLD(author, plugin_author), |
3027 | |
3028 | /* general descriptive text (for SHOW PLUGINS) */ |
3029 | /* const char* */ |
3030 | STRUCT_FLD(descr, "INNODB AUXILIARY FTS DELETED TABLE" ), |
3031 | |
3032 | /* the plugin license (PLUGIN_LICENSE_XXX) */ |
3033 | /* int */ |
3034 | STRUCT_FLD(license, PLUGIN_LICENSE_GPL), |
3035 | |
3036 | /* the function to invoke when plugin is loaded */ |
3037 | /* int (*)(void*); */ |
3038 | STRUCT_FLD(init, i_s_fts_deleted_init), |
3039 | |
3040 | /* the function to invoke when plugin is unloaded */ |
3041 | /* int (*)(void*); */ |
3042 | STRUCT_FLD(deinit, i_s_common_deinit), |
3043 | |
3044 | /* plugin version (for SHOW PLUGINS) */ |
3045 | /* unsigned int */ |
3046 | STRUCT_FLD(version, INNODB_VERSION_SHORT), |
3047 | |
3048 | /* struct st_mysql_show_var* */ |
3049 | STRUCT_FLD(status_vars, NULL), |
3050 | |
3051 | /* struct st_mysql_sys_var** */ |
3052 | STRUCT_FLD(system_vars, NULL), |
3053 | |
3054 | /* Maria extension */ |
3055 | STRUCT_FLD(version_info, INNODB_VERSION_STR), |
3056 | STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE), |
3057 | }; |
3058 | |
3059 | /*******************************************************************//** |
3060 | Fill the dynamic table INFORMATION_SCHEMA.INNODB_FT_BEING_DELETED |
3061 | @return 0 on success, 1 on failure */ |
3062 | static |
3063 | int |
3064 | i_s_fts_being_deleted_fill( |
3065 | /*=======================*/ |
3066 | THD* thd, /*!< in: thread */ |
3067 | TABLE_LIST* tables, /*!< in/out: tables to fill */ |
3068 | Item* ) /*!< in: condition (ignored) */ |
3069 | { |
3070 | DBUG_ENTER("i_s_fts_being_deleted_fill" ); |
3071 | |
3072 | DBUG_RETURN(i_s_fts_deleted_generic_fill(thd, tables, TRUE)); |
3073 | } |
3074 | |
3075 | /*******************************************************************//** |
3076 | Bind the dynamic table INFORMATION_SCHEMA.INNODB_FT_BEING_DELETED |
3077 | @return 0 on success */ |
3078 | static |
3079 | int |
3080 | i_s_fts_being_deleted_init( |
3081 | /*=======================*/ |
3082 | void* p) /*!< in/out: table schema object */ |
3083 | { |
3084 | DBUG_ENTER("i_s_fts_deleted_init" ); |
3085 | ST_SCHEMA_TABLE* schema = (ST_SCHEMA_TABLE*) p; |
3086 | |
3087 | schema->fields_info = i_s_fts_doc_fields_info; |
3088 | schema->fill_table = i_s_fts_being_deleted_fill; |
3089 | |
3090 | DBUG_RETURN(0); |
3091 | } |
3092 | |
3093 | UNIV_INTERN struct st_maria_plugin i_s_innodb_ft_being_deleted = |
3094 | { |
3095 | /* the plugin type (a MYSQL_XXX_PLUGIN value) */ |
3096 | /* int */ |
3097 | STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN), |
3098 | |
3099 | /* pointer to type-specific plugin descriptor */ |
3100 | /* void* */ |
3101 | STRUCT_FLD(info, &i_s_info), |
3102 | |
3103 | /* plugin name */ |
3104 | /* const char* */ |
3105 | STRUCT_FLD(name, "INNODB_FT_BEING_DELETED" ), |
3106 | |
3107 | /* plugin author (for SHOW PLUGINS) */ |
3108 | /* const char* */ |
3109 | STRUCT_FLD(author, plugin_author), |
3110 | |
3111 | /* general descriptive text (for SHOW PLUGINS) */ |
3112 | /* const char* */ |
3113 | STRUCT_FLD(descr, "INNODB AUXILIARY FTS BEING DELETED TABLE" ), |
3114 | |
3115 | /* the plugin license (PLUGIN_LICENSE_XXX) */ |
3116 | /* int */ |
3117 | STRUCT_FLD(license, PLUGIN_LICENSE_GPL), |
3118 | |
3119 | /* the function to invoke when plugin is loaded */ |
3120 | /* int (*)(void*); */ |
3121 | STRUCT_FLD(init, i_s_fts_being_deleted_init), |
3122 | |
3123 | /* the function to invoke when plugin is unloaded */ |
3124 | /* int (*)(void*); */ |
3125 | STRUCT_FLD(deinit, i_s_common_deinit), |
3126 | |
3127 | /* plugin version (for SHOW PLUGINS) */ |
3128 | /* unsigned int */ |
3129 | STRUCT_FLD(version, INNODB_VERSION_SHORT), |
3130 | |
3131 | /* struct st_mysql_show_var* */ |
3132 | STRUCT_FLD(status_vars, NULL), |
3133 | |
3134 | /* struct st_mysql_sys_var** */ |
3135 | STRUCT_FLD(system_vars, NULL), |
3136 | |
3137 | /* Maria extension */ |
3138 | STRUCT_FLD(version_info, INNODB_VERSION_STR), |
3139 | STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE), |
3140 | }; |
3141 | |
3142 | /* Fields of the dynamic table INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHED and |
3143 | INFORMATION_SCHEMA.INNODB_FT_INDEX_TABLE */ |
3144 | static ST_FIELD_INFO i_s_fts_index_fields_info[] = |
3145 | { |
3146 | #define I_S_FTS_WORD 0 |
3147 | {STRUCT_FLD(field_name, "WORD" ), |
3148 | STRUCT_FLD(field_length, FTS_MAX_WORD_LEN + 1), |
3149 | STRUCT_FLD(field_type, MYSQL_TYPE_STRING), |
3150 | STRUCT_FLD(value, 0), |
3151 | STRUCT_FLD(field_flags, 0), |
3152 | STRUCT_FLD(old_name, "" ), |
3153 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
3154 | |
3155 | #define I_S_FTS_FIRST_DOC_ID 1 |
3156 | {STRUCT_FLD(field_name, "FIRST_DOC_ID" ), |
3157 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
3158 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
3159 | STRUCT_FLD(value, 0), |
3160 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
3161 | STRUCT_FLD(old_name, "" ), |
3162 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
3163 | |
3164 | #define I_S_FTS_LAST_DOC_ID 2 |
3165 | {STRUCT_FLD(field_name, "LAST_DOC_ID" ), |
3166 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
3167 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
3168 | STRUCT_FLD(value, 0), |
3169 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
3170 | STRUCT_FLD(old_name, "" ), |
3171 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
3172 | |
3173 | #define I_S_FTS_DOC_COUNT 3 |
3174 | {STRUCT_FLD(field_name, "DOC_COUNT" ), |
3175 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
3176 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
3177 | STRUCT_FLD(value, 0), |
3178 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
3179 | STRUCT_FLD(old_name, "" ), |
3180 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
3181 | |
3182 | #define I_S_FTS_ILIST_DOC_ID 4 |
3183 | {STRUCT_FLD(field_name, "DOC_ID" ), |
3184 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
3185 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
3186 | STRUCT_FLD(value, 0), |
3187 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
3188 | STRUCT_FLD(old_name, "" ), |
3189 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
3190 | |
3191 | #define I_S_FTS_ILIST_DOC_POS 5 |
3192 | {STRUCT_FLD(field_name, "POSITION" ), |
3193 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
3194 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
3195 | STRUCT_FLD(value, 0), |
3196 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
3197 | STRUCT_FLD(old_name, "" ), |
3198 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
3199 | |
3200 | END_OF_ST_FIELD_INFO |
3201 | }; |
3202 | |
3203 | /*******************************************************************//** |
3204 | Go through the Doc Node and its ilist, fill the dynamic table |
3205 | INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHED for one FTS index on the table. |
3206 | @return 0 on success, 1 on failure */ |
3207 | static |
3208 | int |
3209 | i_s_fts_index_cache_fill_one_index( |
3210 | /*===============================*/ |
3211 | fts_index_cache_t* index_cache, /*!< in: FTS index cache */ |
3212 | THD* thd, /*!< in: thread */ |
3213 | fts_string_t* conv_str, /*!< in/out: buffer */ |
3214 | TABLE_LIST* tables) /*!< in/out: tables to fill */ |
3215 | { |
3216 | TABLE* table = (TABLE*) tables->table; |
3217 | Field** fields; |
3218 | CHARSET_INFO* index_charset; |
3219 | const ib_rbt_node_t* rbt_node; |
3220 | uint dummy_errors; |
3221 | char* word_str; |
3222 | |
3223 | DBUG_ENTER("i_s_fts_index_cache_fill_one_index" ); |
3224 | |
3225 | fields = table->field; |
3226 | |
3227 | index_charset = index_cache->charset; |
3228 | conv_str->f_n_char = 0; |
3229 | |
3230 | int ret = 0; |
3231 | |
3232 | /* Go through each word in the index cache */ |
3233 | for (rbt_node = rbt_first(index_cache->words); |
3234 | rbt_node; |
3235 | rbt_node = rbt_next(index_cache->words, rbt_node)) { |
3236 | fts_tokenizer_word_t* word; |
3237 | |
3238 | word = rbt_value(fts_tokenizer_word_t, rbt_node); |
3239 | |
3240 | /* Convert word from index charset to system_charset_info */ |
3241 | if (index_charset->cset != system_charset_info->cset) { |
3242 | conv_str->f_n_char = my_convert( |
3243 | reinterpret_cast<char*>(conv_str->f_str), |
3244 | static_cast<uint32>(conv_str->f_len), |
3245 | system_charset_info, |
3246 | reinterpret_cast<char*>(word->text.f_str), |
3247 | static_cast<uint32>(word->text.f_len), |
3248 | index_charset, &dummy_errors); |
3249 | ut_ad(conv_str->f_n_char <= conv_str->f_len); |
3250 | conv_str->f_str[conv_str->f_n_char] = 0; |
3251 | word_str = reinterpret_cast<char*>(conv_str->f_str); |
3252 | } else { |
3253 | word_str = reinterpret_cast<char*>(word->text.f_str); |
3254 | } |
3255 | |
3256 | /* Decrypt the ilist, and display Dod ID and word position */ |
3257 | for (ulint i = 0; i < ib_vector_size(word->nodes); i++) { |
3258 | fts_node_t* node; |
3259 | byte* ptr; |
3260 | ulint decoded = 0; |
3261 | doc_id_t doc_id = 0; |
3262 | |
3263 | node = static_cast<fts_node_t*> (ib_vector_get( |
3264 | word->nodes, i)); |
3265 | |
3266 | ptr = node->ilist; |
3267 | |
3268 | while (decoded < node->ilist_size) { |
3269 | ulint pos = fts_decode_vlc(&ptr); |
3270 | |
3271 | doc_id += pos; |
3272 | |
3273 | /* Get position info */ |
3274 | while (*ptr) { |
3275 | pos = fts_decode_vlc(&ptr); |
3276 | |
3277 | OK(field_store_string( |
3278 | fields[I_S_FTS_WORD], |
3279 | word_str)); |
3280 | |
3281 | OK(fields[I_S_FTS_FIRST_DOC_ID]->store( |
3282 | node->first_doc_id, |
3283 | true)); |
3284 | |
3285 | OK(fields[I_S_FTS_LAST_DOC_ID]->store( |
3286 | node->last_doc_id, |
3287 | true)); |
3288 | |
3289 | OK(fields[I_S_FTS_DOC_COUNT]->store( |
3290 | node->doc_count, true)); |
3291 | |
3292 | OK(fields[I_S_FTS_ILIST_DOC_ID]->store( |
3293 | doc_id, true)); |
3294 | |
3295 | OK(fields[I_S_FTS_ILIST_DOC_POS]->store( |
3296 | pos, true)); |
3297 | |
3298 | OK(schema_table_store_record( |
3299 | thd, table)); |
3300 | } |
3301 | |
3302 | ++ptr; |
3303 | |
3304 | decoded = ptr - (byte*) node->ilist; |
3305 | } |
3306 | } |
3307 | } |
3308 | |
3309 | DBUG_RETURN(ret); |
3310 | } |
3311 | /*******************************************************************//** |
3312 | Fill the dynamic table INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHED |
3313 | @return 0 on success, 1 on failure */ |
3314 | static |
3315 | int |
3316 | i_s_fts_index_cache_fill( |
3317 | /*=====================*/ |
3318 | THD* thd, /*!< in: thread */ |
3319 | TABLE_LIST* tables, /*!< in/out: tables to fill */ |
3320 | Item* ) /*!< in: condition (ignored) */ |
3321 | { |
3322 | dict_table_t* user_table; |
3323 | fts_cache_t* cache; |
3324 | |
3325 | DBUG_ENTER("i_s_fts_index_cache_fill" ); |
3326 | |
3327 | /* deny access to non-superusers */ |
3328 | if (check_global_access(thd, PROCESS_ACL)) { |
3329 | DBUG_RETURN(0); |
3330 | } |
3331 | |
3332 | if (!fts_internal_tbl_name) { |
3333 | DBUG_RETURN(0); |
3334 | } |
3335 | |
3336 | user_table = dict_table_open_on_name( |
3337 | fts_internal_tbl_name, FALSE, FALSE, DICT_ERR_IGNORE_NONE); |
3338 | |
3339 | if (!user_table) { |
3340 | DBUG_RETURN(0); |
3341 | } |
3342 | |
3343 | if (user_table->fts == NULL || user_table->fts->cache == NULL) { |
3344 | dict_table_close(user_table, FALSE, FALSE); |
3345 | |
3346 | DBUG_RETURN(0); |
3347 | } |
3348 | |
3349 | cache = user_table->fts->cache; |
3350 | |
3351 | ut_a(cache); |
3352 | |
3353 | int ret = 0; |
3354 | fts_string_t conv_str; |
3355 | conv_str.f_len = system_charset_info->mbmaxlen |
3356 | * FTS_MAX_WORD_LEN_IN_CHAR; |
3357 | conv_str.f_str = static_cast<byte*>(ut_malloc_nokey(conv_str.f_len)); |
3358 | |
3359 | for (ulint i = 0; i < ib_vector_size(cache->indexes); i++) { |
3360 | fts_index_cache_t* index_cache; |
3361 | |
3362 | index_cache = static_cast<fts_index_cache_t*> ( |
3363 | ib_vector_get(cache->indexes, i)); |
3364 | |
3365 | BREAK_IF(ret = i_s_fts_index_cache_fill_one_index( |
3366 | index_cache, thd, &conv_str, tables)); |
3367 | } |
3368 | |
3369 | ut_free(conv_str.f_str); |
3370 | |
3371 | dict_table_close(user_table, FALSE, FALSE); |
3372 | |
3373 | DBUG_RETURN(ret); |
3374 | } |
3375 | |
3376 | /*******************************************************************//** |
3377 | Bind the dynamic table INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHE |
3378 | @return 0 on success */ |
3379 | static |
3380 | int |
3381 | i_s_fts_index_cache_init( |
3382 | /*=====================*/ |
3383 | void* p) /*!< in/out: table schema object */ |
3384 | { |
3385 | DBUG_ENTER("i_s_fts_index_cache_init" ); |
3386 | ST_SCHEMA_TABLE* schema = (ST_SCHEMA_TABLE*) p; |
3387 | |
3388 | schema->fields_info = i_s_fts_index_fields_info; |
3389 | schema->fill_table = i_s_fts_index_cache_fill; |
3390 | |
3391 | DBUG_RETURN(0); |
3392 | } |
3393 | |
3394 | UNIV_INTERN struct st_maria_plugin i_s_innodb_ft_index_cache = |
3395 | { |
3396 | /* the plugin type (a MYSQL_XXX_PLUGIN value) */ |
3397 | /* int */ |
3398 | STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN), |
3399 | |
3400 | /* pointer to type-specific plugin descriptor */ |
3401 | /* void* */ |
3402 | STRUCT_FLD(info, &i_s_info), |
3403 | |
3404 | /* plugin name */ |
3405 | /* const char* */ |
3406 | STRUCT_FLD(name, "INNODB_FT_INDEX_CACHE" ), |
3407 | |
3408 | /* plugin author (for SHOW PLUGINS) */ |
3409 | /* const char* */ |
3410 | STRUCT_FLD(author, plugin_author), |
3411 | |
3412 | /* general descriptive text (for SHOW PLUGINS) */ |
3413 | /* const char* */ |
3414 | STRUCT_FLD(descr, "INNODB AUXILIARY FTS INDEX CACHED" ), |
3415 | |
3416 | /* the plugin license (PLUGIN_LICENSE_XXX) */ |
3417 | /* int */ |
3418 | STRUCT_FLD(license, PLUGIN_LICENSE_GPL), |
3419 | |
3420 | /* the function to invoke when plugin is loaded */ |
3421 | /* int (*)(void*); */ |
3422 | STRUCT_FLD(init, i_s_fts_index_cache_init), |
3423 | |
3424 | /* the function to invoke when plugin is unloaded */ |
3425 | /* int (*)(void*); */ |
3426 | STRUCT_FLD(deinit, i_s_common_deinit), |
3427 | |
3428 | /* plugin version (for SHOW PLUGINS) */ |
3429 | /* unsigned int */ |
3430 | STRUCT_FLD(version, INNODB_VERSION_SHORT), |
3431 | |
3432 | /* struct st_mysql_show_var* */ |
3433 | STRUCT_FLD(status_vars, NULL), |
3434 | |
3435 | /* struct st_mysql_sys_var** */ |
3436 | STRUCT_FLD(system_vars, NULL), |
3437 | |
3438 | /* Maria extension */ |
3439 | STRUCT_FLD(version_info, INNODB_VERSION_STR), |
3440 | STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE), |
3441 | }; |
3442 | |
3443 | /*******************************************************************//** |
3444 | Go through a FTS index auxiliary table, fetch its rows and fill |
3445 | FTS word cache structure. |
3446 | @return DB_SUCCESS on success, otherwise error code */ |
3447 | static |
3448 | dberr_t |
3449 | i_s_fts_index_table_fill_selected( |
3450 | /*==============================*/ |
3451 | dict_index_t* index, /*!< in: FTS index */ |
3452 | ib_vector_t* words, /*!< in/out: vector to hold |
3453 | fetched words */ |
3454 | ulint selected, /*!< in: selected FTS index */ |
3455 | fts_string_t* word) /*!< in: word to select */ |
3456 | { |
3457 | pars_info_t* info; |
3458 | fts_table_t fts_table; |
3459 | trx_t* trx; |
3460 | que_t* graph; |
3461 | dberr_t error; |
3462 | fts_fetch_t fetch; |
3463 | char table_name[MAX_FULL_NAME_LEN]; |
3464 | |
3465 | info = pars_info_create(); |
3466 | |
3467 | fetch.read_arg = words; |
3468 | fetch.read_record = fts_optimize_index_fetch_node; |
3469 | fetch.total_memory = 0; |
3470 | |
3471 | DBUG_EXECUTE_IF("fts_instrument_result_cache_limit" , |
3472 | fts_result_cache_limit = 8192; |
3473 | ); |
3474 | |
3475 | trx = trx_create(); |
3476 | |
3477 | trx->op_info = "fetching FTS index nodes" ; |
3478 | |
3479 | pars_info_bind_function(info, "my_func" , fetch.read_record, &fetch); |
3480 | pars_info_bind_varchar_literal(info, "word" , word->f_str, word->f_len); |
3481 | |
3482 | FTS_INIT_INDEX_TABLE(&fts_table, fts_get_suffix(selected), |
3483 | FTS_INDEX_TABLE, index); |
3484 | fts_get_table_name(&fts_table, table_name); |
3485 | pars_info_bind_id(info, true, "table_name" , table_name); |
3486 | |
3487 | graph = fts_parse_sql( |
3488 | &fts_table, info, |
3489 | "DECLARE FUNCTION my_func;\n" |
3490 | "DECLARE CURSOR c IS" |
3491 | " SELECT word, doc_count, first_doc_id, last_doc_id," |
3492 | " ilist\n" |
3493 | " FROM $table_name WHERE word >= :word;\n" |
3494 | "BEGIN\n" |
3495 | "\n" |
3496 | "OPEN c;\n" |
3497 | "WHILE 1 = 1 LOOP\n" |
3498 | " FETCH c INTO my_func();\n" |
3499 | " IF c % NOTFOUND THEN\n" |
3500 | " EXIT;\n" |
3501 | " END IF;\n" |
3502 | "END LOOP;\n" |
3503 | "CLOSE c;" ); |
3504 | |
3505 | for (;;) { |
3506 | error = fts_eval_sql(trx, graph); |
3507 | |
3508 | if (error == DB_SUCCESS) { |
3509 | fts_sql_commit(trx); |
3510 | |
3511 | break; |
3512 | } else { |
3513 | fts_sql_rollback(trx); |
3514 | |
3515 | if (error == DB_LOCK_WAIT_TIMEOUT) { |
3516 | ib::warn() << "Lock wait timeout reading" |
3517 | " FTS index. Retrying!" ; |
3518 | |
3519 | trx->error_state = DB_SUCCESS; |
3520 | } else { |
3521 | ib::error() << "Error occurred while reading" |
3522 | " FTS index: " << ut_strerr(error); |
3523 | break; |
3524 | } |
3525 | } |
3526 | } |
3527 | |
3528 | mutex_enter(&dict_sys->mutex); |
3529 | que_graph_free(graph); |
3530 | mutex_exit(&dict_sys->mutex); |
3531 | |
3532 | trx_free(trx); |
3533 | |
3534 | if (fetch.total_memory >= fts_result_cache_limit) { |
3535 | error = DB_FTS_EXCEED_RESULT_CACHE_LIMIT; |
3536 | } |
3537 | |
3538 | return(error); |
3539 | } |
3540 | |
3541 | /*******************************************************************//** |
3542 | Free words. */ |
3543 | static |
3544 | void |
3545 | i_s_fts_index_table_free_one_fetch( |
3546 | /*===============================*/ |
3547 | ib_vector_t* words) /*!< in: words fetched */ |
3548 | { |
3549 | for (ulint i = 0; i < ib_vector_size(words); i++) { |
3550 | fts_word_t* word; |
3551 | |
3552 | word = static_cast<fts_word_t*>(ib_vector_get(words, i)); |
3553 | |
3554 | for (ulint j = 0; j < ib_vector_size(word->nodes); j++) { |
3555 | fts_node_t* node; |
3556 | |
3557 | node = static_cast<fts_node_t*> (ib_vector_get( |
3558 | word->nodes, j)); |
3559 | ut_free(node->ilist); |
3560 | } |
3561 | |
3562 | fts_word_free(word); |
3563 | } |
3564 | |
3565 | ib_vector_reset(words); |
3566 | } |
3567 | |
3568 | /*******************************************************************//** |
3569 | Go through words, fill INFORMATION_SCHEMA.INNODB_FT_INDEX_TABLE. |
3570 | @return 0 on success, 1 on failure */ |
3571 | static |
3572 | int |
3573 | i_s_fts_index_table_fill_one_fetch( |
3574 | /*===============================*/ |
3575 | CHARSET_INFO* index_charset, /*!< in: FTS index charset */ |
3576 | THD* thd, /*!< in: thread */ |
3577 | TABLE_LIST* tables, /*!< in/out: tables to fill */ |
3578 | ib_vector_t* words, /*!< in: words fetched */ |
3579 | fts_string_t* conv_str, /*!< in: string for conversion*/ |
3580 | bool has_more) /*!< in: has more to fetch */ |
3581 | { |
3582 | TABLE* table = (TABLE*) tables->table; |
3583 | Field** fields; |
3584 | uint dummy_errors; |
3585 | char* word_str; |
3586 | ulint words_size; |
3587 | int ret = 0; |
3588 | |
3589 | DBUG_ENTER("i_s_fts_index_table_fill_one_fetch" ); |
3590 | |
3591 | fields = table->field; |
3592 | |
3593 | words_size = ib_vector_size(words); |
3594 | if (has_more) { |
3595 | /* the last word is not fetched completely. */ |
3596 | ut_ad(words_size > 1); |
3597 | words_size -= 1; |
3598 | } |
3599 | |
3600 | /* Go through each word in the index cache */ |
3601 | for (ulint i = 0; i < words_size; i++) { |
3602 | fts_word_t* word; |
3603 | |
3604 | word = static_cast<fts_word_t*>(ib_vector_get(words, i)); |
3605 | |
3606 | word->text.f_str[word->text.f_len] = 0; |
3607 | |
3608 | /* Convert word from index charset to system_charset_info */ |
3609 | if (index_charset->cset != system_charset_info->cset) { |
3610 | conv_str->f_n_char = my_convert( |
3611 | reinterpret_cast<char*>(conv_str->f_str), |
3612 | static_cast<uint32>(conv_str->f_len), |
3613 | system_charset_info, |
3614 | reinterpret_cast<char*>(word->text.f_str), |
3615 | static_cast<uint32>(word->text.f_len), |
3616 | index_charset, &dummy_errors); |
3617 | ut_ad(conv_str->f_n_char <= conv_str->f_len); |
3618 | conv_str->f_str[conv_str->f_n_char] = 0; |
3619 | word_str = reinterpret_cast<char*>(conv_str->f_str); |
3620 | } else { |
3621 | word_str = reinterpret_cast<char*>(word->text.f_str); |
3622 | } |
3623 | |
3624 | /* Decrypt the ilist, and display Dod ID and word position */ |
3625 | for (ulint i = 0; i < ib_vector_size(word->nodes); i++) { |
3626 | fts_node_t* node; |
3627 | byte* ptr; |
3628 | ulint decoded = 0; |
3629 | doc_id_t doc_id = 0; |
3630 | |
3631 | node = static_cast<fts_node_t*> (ib_vector_get( |
3632 | word->nodes, i)); |
3633 | |
3634 | ptr = node->ilist; |
3635 | |
3636 | while (decoded < node->ilist_size) { |
3637 | ulint pos = fts_decode_vlc(&ptr); |
3638 | |
3639 | doc_id += pos; |
3640 | |
3641 | /* Get position info */ |
3642 | while (*ptr) { |
3643 | pos = fts_decode_vlc(&ptr); |
3644 | |
3645 | OK(field_store_string( |
3646 | fields[I_S_FTS_WORD], |
3647 | word_str)); |
3648 | |
3649 | OK(fields[I_S_FTS_FIRST_DOC_ID]->store( |
3650 | longlong(node->first_doc_id), true)); |
3651 | |
3652 | OK(fields[I_S_FTS_LAST_DOC_ID]->store( |
3653 | longlong(node->last_doc_id), true)); |
3654 | |
3655 | OK(fields[I_S_FTS_DOC_COUNT]->store( |
3656 | node->doc_count, true)); |
3657 | |
3658 | OK(fields[I_S_FTS_ILIST_DOC_ID]->store( |
3659 | longlong(doc_id), true)); |
3660 | |
3661 | OK(fields[I_S_FTS_ILIST_DOC_POS]->store( |
3662 | pos, true)); |
3663 | |
3664 | OK(schema_table_store_record( |
3665 | thd, table)); |
3666 | } |
3667 | |
3668 | ++ptr; |
3669 | |
3670 | decoded = ptr - (byte*) node->ilist; |
3671 | } |
3672 | } |
3673 | } |
3674 | |
3675 | DBUG_RETURN(ret); |
3676 | } |
3677 | |
3678 | /*******************************************************************//** |
3679 | Go through a FTS index and its auxiliary tables, fetch rows in each table |
3680 | and fill INFORMATION_SCHEMA.INNODB_FT_INDEX_TABLE. |
3681 | @return 0 on success, 1 on failure */ |
3682 | static |
3683 | int |
3684 | i_s_fts_index_table_fill_one_index( |
3685 | /*===============================*/ |
3686 | dict_index_t* index, /*!< in: FTS index */ |
3687 | THD* thd, /*!< in: thread */ |
3688 | fts_string_t* conv_str, /*!< in/out: buffer */ |
3689 | TABLE_LIST* tables) /*!< in/out: tables to fill */ |
3690 | { |
3691 | ib_vector_t* words; |
3692 | mem_heap_t* heap; |
3693 | CHARSET_INFO* index_charset; |
3694 | dberr_t error; |
3695 | int ret = 0; |
3696 | |
3697 | DBUG_ENTER("i_s_fts_index_table_fill_one_index" ); |
3698 | DBUG_ASSERT(!dict_index_is_online_ddl(index)); |
3699 | |
3700 | heap = mem_heap_create(1024); |
3701 | |
3702 | words = ib_vector_create(ib_heap_allocator_create(heap), |
3703 | sizeof(fts_word_t), 256); |
3704 | |
3705 | index_charset = fts_index_get_charset(index); |
3706 | |
3707 | /* Iterate through each auxiliary table as described in |
3708 | fts_index_selector */ |
3709 | for (ulint selected = 0; selected < FTS_NUM_AUX_INDEX; selected++) { |
3710 | fts_string_t word; |
3711 | bool has_more = false; |
3712 | |
3713 | word.f_str = NULL; |
3714 | word.f_len = 0; |
3715 | word.f_n_char = 0; |
3716 | |
3717 | do { |
3718 | /* Fetch from index */ |
3719 | error = i_s_fts_index_table_fill_selected( |
3720 | index, words, selected, &word); |
3721 | |
3722 | if (error == DB_SUCCESS) { |
3723 | has_more = false; |
3724 | } else if (error == DB_FTS_EXCEED_RESULT_CACHE_LIMIT) { |
3725 | has_more = true; |
3726 | } else { |
3727 | i_s_fts_index_table_free_one_fetch(words); |
3728 | ret = 1; |
3729 | goto func_exit; |
3730 | } |
3731 | |
3732 | if (has_more) { |
3733 | fts_word_t* last_word; |
3734 | |
3735 | /* Prepare start point for next fetch */ |
3736 | last_word = static_cast<fts_word_t*>(ib_vector_last(words)); |
3737 | ut_ad(last_word != NULL); |
3738 | fts_string_dup(&word, &last_word->text, heap); |
3739 | } |
3740 | |
3741 | /* Fill into tables */ |
3742 | ret = i_s_fts_index_table_fill_one_fetch( |
3743 | index_charset, thd, tables, words, conv_str, |
3744 | has_more); |
3745 | i_s_fts_index_table_free_one_fetch(words); |
3746 | |
3747 | if (ret != 0) { |
3748 | goto func_exit; |
3749 | } |
3750 | } while (has_more); |
3751 | } |
3752 | |
3753 | func_exit: |
3754 | mem_heap_free(heap); |
3755 | |
3756 | DBUG_RETURN(ret); |
3757 | } |
3758 | /*******************************************************************//** |
3759 | Fill the dynamic table INFORMATION_SCHEMA.INNODB_FT_INDEX_TABLE |
3760 | @return 0 on success, 1 on failure */ |
3761 | static |
3762 | int |
3763 | i_s_fts_index_table_fill( |
3764 | /*=====================*/ |
3765 | THD* thd, /*!< in: thread */ |
3766 | TABLE_LIST* tables, /*!< in/out: tables to fill */ |
3767 | Item* ) /*!< in: condition (ignored) */ |
3768 | { |
3769 | dict_table_t* user_table; |
3770 | dict_index_t* index; |
3771 | |
3772 | DBUG_ENTER("i_s_fts_index_table_fill" ); |
3773 | |
3774 | /* deny access to non-superusers */ |
3775 | if (check_global_access(thd, PROCESS_ACL)) { |
3776 | DBUG_RETURN(0); |
3777 | } |
3778 | |
3779 | if (!fts_internal_tbl_name) { |
3780 | DBUG_RETURN(0); |
3781 | } |
3782 | |
3783 | /* Prevent DDL to drop fts aux tables. */ |
3784 | rw_lock_s_lock(dict_operation_lock); |
3785 | |
3786 | user_table = dict_table_open_on_name( |
3787 | fts_internal_tbl_name, FALSE, FALSE, DICT_ERR_IGNORE_NONE); |
3788 | |
3789 | if (!user_table) { |
3790 | rw_lock_s_unlock(dict_operation_lock); |
3791 | |
3792 | DBUG_RETURN(0); |
3793 | } |
3794 | |
3795 | int ret = 0; |
3796 | fts_string_t conv_str; |
3797 | conv_str.f_len = system_charset_info->mbmaxlen |
3798 | * FTS_MAX_WORD_LEN_IN_CHAR; |
3799 | conv_str.f_str = static_cast<byte*>(ut_malloc_nokey(conv_str.f_len)); |
3800 | |
3801 | for (index = dict_table_get_first_index(user_table); |
3802 | index; index = dict_table_get_next_index(index)) { |
3803 | if (index->type & DICT_FTS) { |
3804 | BREAK_IF(ret = i_s_fts_index_table_fill_one_index( |
3805 | index, thd, &conv_str, tables)); |
3806 | } |
3807 | } |
3808 | |
3809 | dict_table_close(user_table, FALSE, FALSE); |
3810 | |
3811 | rw_lock_s_unlock(dict_operation_lock); |
3812 | |
3813 | ut_free(conv_str.f_str); |
3814 | |
3815 | DBUG_RETURN(ret); |
3816 | } |
3817 | |
3818 | /*******************************************************************//** |
3819 | Bind the dynamic table INFORMATION_SCHEMA.INNODB_FT_INDEX_TABLE |
3820 | @return 0 on success */ |
3821 | static |
3822 | int |
3823 | i_s_fts_index_table_init( |
3824 | /*=====================*/ |
3825 | void* p) /*!< in/out: table schema object */ |
3826 | { |
3827 | DBUG_ENTER("i_s_fts_index_table_init" ); |
3828 | ST_SCHEMA_TABLE* schema = (ST_SCHEMA_TABLE*) p; |
3829 | |
3830 | schema->fields_info = i_s_fts_index_fields_info; |
3831 | schema->fill_table = i_s_fts_index_table_fill; |
3832 | |
3833 | DBUG_RETURN(0); |
3834 | } |
3835 | |
3836 | UNIV_INTERN struct st_maria_plugin i_s_innodb_ft_index_table = |
3837 | { |
3838 | /* the plugin type (a MYSQL_XXX_PLUGIN value) */ |
3839 | /* int */ |
3840 | STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN), |
3841 | |
3842 | /* pointer to type-specific plugin descriptor */ |
3843 | /* void* */ |
3844 | STRUCT_FLD(info, &i_s_info), |
3845 | |
3846 | /* plugin name */ |
3847 | /* const char* */ |
3848 | STRUCT_FLD(name, "INNODB_FT_INDEX_TABLE" ), |
3849 | |
3850 | /* plugin author (for SHOW PLUGINS) */ |
3851 | /* const char* */ |
3852 | STRUCT_FLD(author, plugin_author), |
3853 | |
3854 | /* general descriptive text (for SHOW PLUGINS) */ |
3855 | /* const char* */ |
3856 | STRUCT_FLD(descr, "INNODB AUXILIARY FTS INDEX TABLE" ), |
3857 | |
3858 | /* the plugin license (PLUGIN_LICENSE_XXX) */ |
3859 | /* int */ |
3860 | STRUCT_FLD(license, PLUGIN_LICENSE_GPL), |
3861 | |
3862 | /* the function to invoke when plugin is loaded */ |
3863 | /* int (*)(void*); */ |
3864 | STRUCT_FLD(init, i_s_fts_index_table_init), |
3865 | |
3866 | /* the function to invoke when plugin is unloaded */ |
3867 | /* int (*)(void*); */ |
3868 | STRUCT_FLD(deinit, i_s_common_deinit), |
3869 | |
3870 | /* plugin version (for SHOW PLUGINS) */ |
3871 | /* unsigned int */ |
3872 | STRUCT_FLD(version, INNODB_VERSION_SHORT), |
3873 | |
3874 | /* struct st_mysql_show_var* */ |
3875 | STRUCT_FLD(status_vars, NULL), |
3876 | |
3877 | /* struct st_mysql_sys_var** */ |
3878 | STRUCT_FLD(system_vars, NULL), |
3879 | |
3880 | /* Maria extension */ |
3881 | STRUCT_FLD(version_info, INNODB_VERSION_STR), |
3882 | STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE), |
3883 | }; |
3884 | |
3885 | /* Fields of the dynamic table INFORMATION_SCHEMA.INNODB_FT_CONFIG */ |
3886 | static ST_FIELD_INFO i_s_fts_config_fields_info[] = |
3887 | { |
3888 | #define FTS_CONFIG_KEY 0 |
3889 | {STRUCT_FLD(field_name, "KEY" ), |
3890 | STRUCT_FLD(field_length, NAME_LEN + 1), |
3891 | STRUCT_FLD(field_type, MYSQL_TYPE_STRING), |
3892 | STRUCT_FLD(value, 0), |
3893 | STRUCT_FLD(field_flags, 0), |
3894 | STRUCT_FLD(old_name, "" ), |
3895 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
3896 | |
3897 | #define FTS_CONFIG_VALUE 1 |
3898 | {STRUCT_FLD(field_name, "VALUE" ), |
3899 | STRUCT_FLD(field_length, NAME_LEN + 1), |
3900 | STRUCT_FLD(field_type, MYSQL_TYPE_STRING), |
3901 | STRUCT_FLD(value, 0), |
3902 | STRUCT_FLD(field_flags, 0), |
3903 | STRUCT_FLD(old_name, "" ), |
3904 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
3905 | |
3906 | END_OF_ST_FIELD_INFO |
3907 | }; |
3908 | |
3909 | static const char* fts_config_key[] = { |
3910 | FTS_OPTIMIZE_LIMIT_IN_SECS, |
3911 | FTS_SYNCED_DOC_ID, |
3912 | FTS_STOPWORD_TABLE_NAME, |
3913 | FTS_USE_STOPWORD, |
3914 | NULL |
3915 | }; |
3916 | |
3917 | /*******************************************************************//** |
3918 | Fill the dynamic table INFORMATION_SCHEMA.INNODB_FT_CONFIG |
3919 | @return 0 on success, 1 on failure */ |
3920 | static |
3921 | int |
3922 | i_s_fts_config_fill( |
3923 | /*================*/ |
3924 | THD* thd, /*!< in: thread */ |
3925 | TABLE_LIST* tables, /*!< in/out: tables to fill */ |
3926 | Item* ) /*!< in: condition (ignored) */ |
3927 | { |
3928 | Field** fields; |
3929 | TABLE* table = (TABLE*) tables->table; |
3930 | trx_t* trx; |
3931 | fts_table_t fts_table; |
3932 | dict_table_t* user_table; |
3933 | ulint i = 0; |
3934 | dict_index_t* index = NULL; |
3935 | unsigned char str[FTS_MAX_CONFIG_VALUE_LEN + 1]; |
3936 | |
3937 | DBUG_ENTER("i_s_fts_config_fill" ); |
3938 | |
3939 | /* deny access to non-superusers */ |
3940 | if (check_global_access(thd, PROCESS_ACL)) { |
3941 | DBUG_RETURN(0); |
3942 | } |
3943 | |
3944 | if (!fts_internal_tbl_name) { |
3945 | DBUG_RETURN(0); |
3946 | } |
3947 | |
3948 | DEBUG_SYNC_C("i_s_fts_config_fille_check" ); |
3949 | |
3950 | fields = table->field; |
3951 | |
3952 | /* Prevent DDL to drop fts aux tables. */ |
3953 | rw_lock_s_lock(dict_operation_lock); |
3954 | |
3955 | user_table = dict_table_open_on_name( |
3956 | fts_internal_tbl_name, FALSE, FALSE, DICT_ERR_IGNORE_NONE); |
3957 | |
3958 | if (!user_table) { |
3959 | rw_lock_s_unlock(dict_operation_lock); |
3960 | |
3961 | DBUG_RETURN(0); |
3962 | } else if (!dict_table_has_fts_index(user_table)) { |
3963 | dict_table_close(user_table, FALSE, FALSE); |
3964 | |
3965 | rw_lock_s_unlock(dict_operation_lock); |
3966 | |
3967 | DBUG_RETURN(0); |
3968 | } |
3969 | |
3970 | trx = trx_create(); |
3971 | trx->op_info = "Select for FTS CONFIG TABLE" ; |
3972 | |
3973 | FTS_INIT_FTS_TABLE(&fts_table, "CONFIG" , FTS_COMMON_TABLE, user_table); |
3974 | |
3975 | if (!ib_vector_is_empty(user_table->fts->indexes)) { |
3976 | index = (dict_index_t*) ib_vector_getp_const( |
3977 | user_table->fts->indexes, 0); |
3978 | DBUG_ASSERT(!dict_index_is_online_ddl(index)); |
3979 | } |
3980 | |
3981 | int ret = 0; |
3982 | |
3983 | while (fts_config_key[i]) { |
3984 | fts_string_t value; |
3985 | char* key_name; |
3986 | ulint allocated = FALSE; |
3987 | |
3988 | value.f_len = FTS_MAX_CONFIG_VALUE_LEN; |
3989 | |
3990 | value.f_str = str; |
3991 | |
3992 | if (index |
3993 | && strcmp(fts_config_key[i], FTS_TOTAL_WORD_COUNT) == 0) { |
3994 | key_name = fts_config_create_index_param_name( |
3995 | fts_config_key[i], index); |
3996 | allocated = TRUE; |
3997 | } else { |
3998 | key_name = (char*) fts_config_key[i]; |
3999 | } |
4000 | |
4001 | fts_config_get_value(trx, &fts_table, key_name, &value); |
4002 | |
4003 | if (allocated) { |
4004 | ut_free(key_name); |
4005 | } |
4006 | |
4007 | BREAK_IF(ret = field_store_string( |
4008 | fields[FTS_CONFIG_KEY], fts_config_key[i])); |
4009 | |
4010 | BREAK_IF(ret = field_store_string( |
4011 | fields[FTS_CONFIG_VALUE], |
4012 | reinterpret_cast<const char*>(value.f_str))); |
4013 | |
4014 | BREAK_IF(ret = schema_table_store_record(thd, table)); |
4015 | |
4016 | i++; |
4017 | } |
4018 | |
4019 | fts_sql_commit(trx); |
4020 | |
4021 | trx_free(trx); |
4022 | |
4023 | dict_table_close(user_table, FALSE, FALSE); |
4024 | |
4025 | rw_lock_s_unlock(dict_operation_lock); |
4026 | |
4027 | DBUG_RETURN(ret); |
4028 | } |
4029 | |
4030 | /*******************************************************************//** |
4031 | Bind the dynamic table INFORMATION_SCHEMA.INNODB_FT_CONFIG |
4032 | @return 0 on success */ |
4033 | static |
4034 | int |
4035 | i_s_fts_config_init( |
4036 | /*=================*/ |
4037 | void* p) /*!< in/out: table schema object */ |
4038 | { |
4039 | DBUG_ENTER("i_s_fts_config_init" ); |
4040 | ST_SCHEMA_TABLE* schema = (ST_SCHEMA_TABLE*) p; |
4041 | |
4042 | schema->fields_info = i_s_fts_config_fields_info; |
4043 | schema->fill_table = i_s_fts_config_fill; |
4044 | |
4045 | DBUG_RETURN(0); |
4046 | } |
4047 | |
4048 | UNIV_INTERN struct st_maria_plugin i_s_innodb_ft_config = |
4049 | { |
4050 | /* the plugin type (a MYSQL_XXX_PLUGIN value) */ |
4051 | /* int */ |
4052 | STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN), |
4053 | |
4054 | /* pointer to type-specific plugin descriptor */ |
4055 | /* void* */ |
4056 | STRUCT_FLD(info, &i_s_info), |
4057 | |
4058 | /* plugin name */ |
4059 | /* const char* */ |
4060 | STRUCT_FLD(name, "INNODB_FT_CONFIG" ), |
4061 | |
4062 | /* plugin author (for SHOW PLUGINS) */ |
4063 | /* const char* */ |
4064 | STRUCT_FLD(author, plugin_author), |
4065 | |
4066 | /* general descriptive text (for SHOW PLUGINS) */ |
4067 | /* const char* */ |
4068 | STRUCT_FLD(descr, "INNODB AUXILIARY FTS CONFIG TABLE" ), |
4069 | |
4070 | /* the plugin license (PLUGIN_LICENSE_XXX) */ |
4071 | /* int */ |
4072 | STRUCT_FLD(license, PLUGIN_LICENSE_GPL), |
4073 | |
4074 | /* the function to invoke when plugin is loaded */ |
4075 | /* int (*)(void*); */ |
4076 | STRUCT_FLD(init, i_s_fts_config_init), |
4077 | |
4078 | /* the function to invoke when plugin is unloaded */ |
4079 | /* int (*)(void*); */ |
4080 | STRUCT_FLD(deinit, i_s_common_deinit), |
4081 | |
4082 | /* plugin version (for SHOW PLUGINS) */ |
4083 | /* unsigned int */ |
4084 | STRUCT_FLD(version, INNODB_VERSION_SHORT), |
4085 | |
4086 | /* struct st_mysql_show_var* */ |
4087 | STRUCT_FLD(status_vars, NULL), |
4088 | |
4089 | /* struct st_mysql_sys_var** */ |
4090 | STRUCT_FLD(system_vars, NULL), |
4091 | |
4092 | /* Maria extension */ |
4093 | STRUCT_FLD(version_info, INNODB_VERSION_STR), |
4094 | STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE), |
4095 | }; |
4096 | |
4097 | /* Fields of the dynamic table INNODB_BUFFER_POOL_STATS. */ |
4098 | static ST_FIELD_INFO i_s_innodb_buffer_stats_fields_info[] = |
4099 | { |
4100 | #define IDX_BUF_STATS_POOL_ID 0 |
4101 | {STRUCT_FLD(field_name, "POOL_ID" ), |
4102 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
4103 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
4104 | STRUCT_FLD(value, 0), |
4105 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
4106 | STRUCT_FLD(old_name, "" ), |
4107 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
4108 | |
4109 | #define IDX_BUF_STATS_POOL_SIZE 1 |
4110 | {STRUCT_FLD(field_name, "POOL_SIZE" ), |
4111 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
4112 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
4113 | STRUCT_FLD(value, 0), |
4114 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
4115 | STRUCT_FLD(old_name, "" ), |
4116 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
4117 | |
4118 | #define IDX_BUF_STATS_FREE_BUFFERS 2 |
4119 | {STRUCT_FLD(field_name, "FREE_BUFFERS" ), |
4120 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
4121 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
4122 | STRUCT_FLD(value, 0), |
4123 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
4124 | STRUCT_FLD(old_name, "" ), |
4125 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
4126 | |
4127 | #define IDX_BUF_STATS_LRU_LEN 3 |
4128 | {STRUCT_FLD(field_name, "DATABASE_PAGES" ), |
4129 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
4130 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
4131 | STRUCT_FLD(value, 0), |
4132 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
4133 | STRUCT_FLD(old_name, "" ), |
4134 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
4135 | |
4136 | #define IDX_BUF_STATS_OLD_LRU_LEN 4 |
4137 | {STRUCT_FLD(field_name, "OLD_DATABASE_PAGES" ), |
4138 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
4139 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
4140 | STRUCT_FLD(value, 0), |
4141 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
4142 | STRUCT_FLD(old_name, "" ), |
4143 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
4144 | |
4145 | #define IDX_BUF_STATS_FLUSH_LIST_LEN 5 |
4146 | {STRUCT_FLD(field_name, "MODIFIED_DATABASE_PAGES" ), |
4147 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
4148 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
4149 | STRUCT_FLD(value, 0), |
4150 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
4151 | STRUCT_FLD(old_name, "" ), |
4152 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
4153 | |
4154 | #define IDX_BUF_STATS_PENDING_ZIP 6 |
4155 | {STRUCT_FLD(field_name, "PENDING_DECOMPRESS" ), |
4156 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
4157 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
4158 | STRUCT_FLD(value, 0), |
4159 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
4160 | STRUCT_FLD(old_name, "" ), |
4161 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
4162 | |
4163 | #define IDX_BUF_STATS_PENDING_READ 7 |
4164 | {STRUCT_FLD(field_name, "PENDING_READS" ), |
4165 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
4166 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
4167 | STRUCT_FLD(value, 0), |
4168 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
4169 | STRUCT_FLD(old_name, "" ), |
4170 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
4171 | |
4172 | #define IDX_BUF_STATS_FLUSH_LRU 8 |
4173 | {STRUCT_FLD(field_name, "PENDING_FLUSH_LRU" ), |
4174 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
4175 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
4176 | STRUCT_FLD(value, 0), |
4177 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
4178 | STRUCT_FLD(old_name, "" ), |
4179 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
4180 | |
4181 | #define IDX_BUF_STATS_FLUSH_LIST 9 |
4182 | {STRUCT_FLD(field_name, "PENDING_FLUSH_LIST" ), |
4183 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
4184 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
4185 | STRUCT_FLD(value, 0), |
4186 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
4187 | STRUCT_FLD(old_name, "" ), |
4188 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
4189 | |
4190 | #define IDX_BUF_STATS_PAGE_YOUNG 10 |
4191 | {STRUCT_FLD(field_name, "PAGES_MADE_YOUNG" ), |
4192 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
4193 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
4194 | STRUCT_FLD(value, 0), |
4195 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
4196 | STRUCT_FLD(old_name, "" ), |
4197 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
4198 | |
4199 | #define IDX_BUF_STATS_PAGE_NOT_YOUNG 11 |
4200 | {STRUCT_FLD(field_name, "PAGES_NOT_MADE_YOUNG" ), |
4201 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
4202 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
4203 | STRUCT_FLD(value, 0), |
4204 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
4205 | STRUCT_FLD(old_name, "" ), |
4206 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
4207 | |
4208 | #define IDX_BUF_STATS_PAGE_YOUNG_RATE 12 |
4209 | {STRUCT_FLD(field_name, "PAGES_MADE_YOUNG_RATE" ), |
4210 | STRUCT_FLD(field_length, MAX_FLOAT_STR_LENGTH), |
4211 | STRUCT_FLD(field_type, MYSQL_TYPE_FLOAT), |
4212 | STRUCT_FLD(value, 0), |
4213 | STRUCT_FLD(field_flags, 0), |
4214 | STRUCT_FLD(old_name, "" ), |
4215 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
4216 | |
4217 | #define IDX_BUF_STATS_PAGE_NOT_YOUNG_RATE 13 |
4218 | {STRUCT_FLD(field_name, "PAGES_MADE_NOT_YOUNG_RATE" ), |
4219 | STRUCT_FLD(field_length, MAX_FLOAT_STR_LENGTH), |
4220 | STRUCT_FLD(field_type, MYSQL_TYPE_FLOAT), |
4221 | STRUCT_FLD(value, 0), |
4222 | STRUCT_FLD(field_flags, 0), |
4223 | STRUCT_FLD(old_name, "" ), |
4224 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
4225 | |
4226 | #define IDX_BUF_STATS_PAGE_READ 14 |
4227 | {STRUCT_FLD(field_name, "NUMBER_PAGES_READ" ), |
4228 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
4229 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
4230 | STRUCT_FLD(value, 0), |
4231 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
4232 | STRUCT_FLD(old_name, "" ), |
4233 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
4234 | |
4235 | #define IDX_BUF_STATS_PAGE_CREATED 15 |
4236 | {STRUCT_FLD(field_name, "NUMBER_PAGES_CREATED" ), |
4237 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
4238 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
4239 | STRUCT_FLD(value, 0), |
4240 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
4241 | STRUCT_FLD(old_name, "" ), |
4242 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
4243 | |
4244 | #define IDX_BUF_STATS_PAGE_WRITTEN 16 |
4245 | {STRUCT_FLD(field_name, "NUMBER_PAGES_WRITTEN" ), |
4246 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
4247 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
4248 | STRUCT_FLD(value, 0), |
4249 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
4250 | STRUCT_FLD(old_name, "" ), |
4251 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
4252 | |
4253 | #define IDX_BUF_STATS_PAGE_READ_RATE 17 |
4254 | {STRUCT_FLD(field_name, "PAGES_READ_RATE" ), |
4255 | STRUCT_FLD(field_length, MAX_FLOAT_STR_LENGTH), |
4256 | STRUCT_FLD(field_type, MYSQL_TYPE_FLOAT), |
4257 | STRUCT_FLD(value, 0), |
4258 | STRUCT_FLD(field_flags, 0), |
4259 | STRUCT_FLD(old_name, "" ), |
4260 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
4261 | |
4262 | #define IDX_BUF_STATS_PAGE_CREATE_RATE 18 |
4263 | {STRUCT_FLD(field_name, "PAGES_CREATE_RATE" ), |
4264 | STRUCT_FLD(field_length, MAX_FLOAT_STR_LENGTH), |
4265 | STRUCT_FLD(field_type, MYSQL_TYPE_FLOAT), |
4266 | STRUCT_FLD(value, 0), |
4267 | STRUCT_FLD(field_flags, 0), |
4268 | STRUCT_FLD(old_name, "" ), |
4269 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
4270 | |
4271 | #define IDX_BUF_STATS_PAGE_WRITTEN_RATE 19 |
4272 | {STRUCT_FLD(field_name, "PAGES_WRITTEN_RATE" ), |
4273 | STRUCT_FLD(field_length, MAX_FLOAT_STR_LENGTH), |
4274 | STRUCT_FLD(field_type, MYSQL_TYPE_FLOAT), |
4275 | STRUCT_FLD(value, 0), |
4276 | STRUCT_FLD(field_flags, 0), |
4277 | STRUCT_FLD(old_name, "" ), |
4278 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
4279 | |
4280 | #define IDX_BUF_STATS_GET 20 |
4281 | {STRUCT_FLD(field_name, "NUMBER_PAGES_GET" ), |
4282 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
4283 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
4284 | STRUCT_FLD(value, 0), |
4285 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
4286 | STRUCT_FLD(old_name, "" ), |
4287 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
4288 | |
4289 | #define IDX_BUF_STATS_HIT_RATE 21 |
4290 | {STRUCT_FLD(field_name, "HIT_RATE" ), |
4291 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
4292 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
4293 | STRUCT_FLD(value, 0), |
4294 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
4295 | STRUCT_FLD(old_name, "" ), |
4296 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
4297 | |
4298 | #define IDX_BUF_STATS_MADE_YOUNG_PCT 22 |
4299 | {STRUCT_FLD(field_name, "YOUNG_MAKE_PER_THOUSAND_GETS" ), |
4300 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
4301 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
4302 | STRUCT_FLD(value, 0), |
4303 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
4304 | STRUCT_FLD(old_name, "" ), |
4305 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
4306 | |
4307 | #define IDX_BUF_STATS_NOT_MADE_YOUNG_PCT 23 |
4308 | {STRUCT_FLD(field_name, "NOT_YOUNG_MAKE_PER_THOUSAND_GETS" ), |
4309 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
4310 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
4311 | STRUCT_FLD(value, 0), |
4312 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
4313 | STRUCT_FLD(old_name, "" ), |
4314 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
4315 | |
4316 | #define IDX_BUF_STATS_READ_AHREAD 24 |
4317 | {STRUCT_FLD(field_name, "NUMBER_PAGES_READ_AHEAD" ), |
4318 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
4319 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
4320 | STRUCT_FLD(value, 0), |
4321 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
4322 | STRUCT_FLD(old_name, "" ), |
4323 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
4324 | |
4325 | #define IDX_BUF_STATS_READ_AHEAD_EVICTED 25 |
4326 | {STRUCT_FLD(field_name, "NUMBER_READ_AHEAD_EVICTED" ), |
4327 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
4328 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
4329 | STRUCT_FLD(value, 0), |
4330 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
4331 | STRUCT_FLD(old_name, "" ), |
4332 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
4333 | |
4334 | #define IDX_BUF_STATS_READ_AHEAD_RATE 26 |
4335 | {STRUCT_FLD(field_name, "READ_AHEAD_RATE" ), |
4336 | STRUCT_FLD(field_length, MAX_FLOAT_STR_LENGTH), |
4337 | STRUCT_FLD(field_type, MYSQL_TYPE_FLOAT), |
4338 | STRUCT_FLD(value, 0), |
4339 | STRUCT_FLD(field_flags, 0), |
4340 | STRUCT_FLD(old_name, "" ), |
4341 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
4342 | |
4343 | #define IDX_BUF_STATS_READ_AHEAD_EVICT_RATE 27 |
4344 | {STRUCT_FLD(field_name, "READ_AHEAD_EVICTED_RATE" ), |
4345 | STRUCT_FLD(field_length, MAX_FLOAT_STR_LENGTH), |
4346 | STRUCT_FLD(field_type, MYSQL_TYPE_FLOAT), |
4347 | STRUCT_FLD(value, 0), |
4348 | STRUCT_FLD(field_flags, 0), |
4349 | STRUCT_FLD(old_name, "" ), |
4350 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
4351 | |
4352 | #define IDX_BUF_STATS_LRU_IO_SUM 28 |
4353 | {STRUCT_FLD(field_name, "LRU_IO_TOTAL" ), |
4354 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
4355 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
4356 | STRUCT_FLD(value, 0), |
4357 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
4358 | STRUCT_FLD(old_name, "" ), |
4359 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
4360 | |
4361 | #define IDX_BUF_STATS_LRU_IO_CUR 29 |
4362 | {STRUCT_FLD(field_name, "LRU_IO_CURRENT" ), |
4363 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
4364 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
4365 | STRUCT_FLD(value, 0), |
4366 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
4367 | STRUCT_FLD(old_name, "" ), |
4368 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
4369 | |
4370 | #define IDX_BUF_STATS_UNZIP_SUM 30 |
4371 | {STRUCT_FLD(field_name, "UNCOMPRESS_TOTAL" ), |
4372 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
4373 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
4374 | STRUCT_FLD(value, 0), |
4375 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
4376 | STRUCT_FLD(old_name, "" ), |
4377 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
4378 | |
4379 | #define IDX_BUF_STATS_UNZIP_CUR 31 |
4380 | {STRUCT_FLD(field_name, "UNCOMPRESS_CURRENT" ), |
4381 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
4382 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
4383 | STRUCT_FLD(value, 0), |
4384 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
4385 | STRUCT_FLD(old_name, "" ), |
4386 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
4387 | |
4388 | END_OF_ST_FIELD_INFO |
4389 | }; |
4390 | |
4391 | /*******************************************************************//** |
4392 | Fill Information Schema table INNODB_BUFFER_POOL_STATS for a particular |
4393 | buffer pool |
4394 | @return 0 on success, 1 on failure */ |
4395 | static |
4396 | int |
4397 | i_s_innodb_stats_fill( |
4398 | /*==================*/ |
4399 | THD* thd, /*!< in: thread */ |
4400 | TABLE_LIST* tables, /*!< in/out: tables to fill */ |
4401 | const buf_pool_info_t* info) /*!< in: buffer pool |
4402 | information */ |
4403 | { |
4404 | TABLE* table; |
4405 | Field** fields; |
4406 | |
4407 | DBUG_ENTER("i_s_innodb_stats_fill" ); |
4408 | |
4409 | table = tables->table; |
4410 | |
4411 | fields = table->field; |
4412 | |
4413 | OK(fields[IDX_BUF_STATS_POOL_ID]->store( |
4414 | info->pool_unique_id, true)); |
4415 | |
4416 | OK(fields[IDX_BUF_STATS_POOL_SIZE]->store( |
4417 | info->pool_size, true)); |
4418 | |
4419 | OK(fields[IDX_BUF_STATS_LRU_LEN]->store( |
4420 | info->lru_len, true)); |
4421 | |
4422 | OK(fields[IDX_BUF_STATS_OLD_LRU_LEN]->store( |
4423 | info->old_lru_len, true)); |
4424 | |
4425 | OK(fields[IDX_BUF_STATS_FREE_BUFFERS]->store( |
4426 | info->free_list_len, true)); |
4427 | |
4428 | OK(fields[IDX_BUF_STATS_FLUSH_LIST_LEN]->store( |
4429 | info->flush_list_len, true)); |
4430 | |
4431 | OK(fields[IDX_BUF_STATS_PENDING_ZIP]->store( |
4432 | info->n_pend_unzip, true)); |
4433 | |
4434 | OK(fields[IDX_BUF_STATS_PENDING_READ]->store( |
4435 | info->n_pend_reads, true)); |
4436 | |
4437 | OK(fields[IDX_BUF_STATS_FLUSH_LRU]->store( |
4438 | info->n_pending_flush_lru, true)); |
4439 | |
4440 | OK(fields[IDX_BUF_STATS_FLUSH_LIST]->store( |
4441 | info->n_pending_flush_list, true)); |
4442 | |
4443 | OK(fields[IDX_BUF_STATS_PAGE_YOUNG]->store( |
4444 | info->n_pages_made_young, true)); |
4445 | |
4446 | OK(fields[IDX_BUF_STATS_PAGE_NOT_YOUNG]->store( |
4447 | info->n_pages_not_made_young, true)); |
4448 | |
4449 | OK(fields[IDX_BUF_STATS_PAGE_YOUNG_RATE]->store( |
4450 | info->page_made_young_rate)); |
4451 | |
4452 | OK(fields[IDX_BUF_STATS_PAGE_NOT_YOUNG_RATE]->store( |
4453 | info->page_not_made_young_rate)); |
4454 | |
4455 | OK(fields[IDX_BUF_STATS_PAGE_READ]->store( |
4456 | info->n_pages_read, true)); |
4457 | |
4458 | OK(fields[IDX_BUF_STATS_PAGE_CREATED]->store( |
4459 | info->n_pages_created, true)); |
4460 | |
4461 | OK(fields[IDX_BUF_STATS_PAGE_WRITTEN]->store( |
4462 | info->n_pages_written, true)); |
4463 | |
4464 | OK(fields[IDX_BUF_STATS_GET]->store( |
4465 | info->n_page_gets, true)); |
4466 | |
4467 | OK(fields[IDX_BUF_STATS_PAGE_READ_RATE]->store( |
4468 | info->pages_read_rate)); |
4469 | |
4470 | OK(fields[IDX_BUF_STATS_PAGE_CREATE_RATE]->store( |
4471 | info->pages_created_rate)); |
4472 | |
4473 | OK(fields[IDX_BUF_STATS_PAGE_WRITTEN_RATE]->store( |
4474 | info->pages_written_rate)); |
4475 | |
4476 | if (info->n_page_get_delta) { |
4477 | if (info->page_read_delta <= info->n_page_get_delta) { |
4478 | OK(fields[IDX_BUF_STATS_HIT_RATE]->store( |
4479 | static_cast<double>( |
4480 | 1000 - (1000 * info->page_read_delta |
4481 | / info->n_page_get_delta)))); |
4482 | } else { |
4483 | OK(fields[IDX_BUF_STATS_HIT_RATE]->store(0)); |
4484 | } |
4485 | |
4486 | OK(fields[IDX_BUF_STATS_MADE_YOUNG_PCT]->store( |
4487 | 1000 * info->young_making_delta |
4488 | / info->n_page_get_delta, true)); |
4489 | |
4490 | OK(fields[IDX_BUF_STATS_NOT_MADE_YOUNG_PCT]->store( |
4491 | 1000 * info->not_young_making_delta |
4492 | / info->n_page_get_delta, true)); |
4493 | } else { |
4494 | OK(fields[IDX_BUF_STATS_HIT_RATE]->store(0, true)); |
4495 | OK(fields[IDX_BUF_STATS_MADE_YOUNG_PCT]->store(0, true)); |
4496 | OK(fields[IDX_BUF_STATS_NOT_MADE_YOUNG_PCT]->store(0, true)); |
4497 | } |
4498 | |
4499 | OK(fields[IDX_BUF_STATS_READ_AHREAD]->store( |
4500 | info->n_ra_pages_read, true)); |
4501 | |
4502 | OK(fields[IDX_BUF_STATS_READ_AHEAD_EVICTED]->store( |
4503 | info->n_ra_pages_evicted, true)); |
4504 | |
4505 | OK(fields[IDX_BUF_STATS_READ_AHEAD_RATE]->store( |
4506 | info->pages_readahead_rate)); |
4507 | |
4508 | OK(fields[IDX_BUF_STATS_READ_AHEAD_EVICT_RATE]->store( |
4509 | info->pages_evicted_rate)); |
4510 | |
4511 | OK(fields[IDX_BUF_STATS_LRU_IO_SUM]->store( |
4512 | info->io_sum, true)); |
4513 | |
4514 | OK(fields[IDX_BUF_STATS_LRU_IO_CUR]->store( |
4515 | info->io_cur, true)); |
4516 | |
4517 | OK(fields[IDX_BUF_STATS_UNZIP_SUM]->store( |
4518 | info->unzip_sum, true)); |
4519 | |
4520 | OK(fields[IDX_BUF_STATS_UNZIP_CUR]->store( |
4521 | info->unzip_cur, true)); |
4522 | |
4523 | DBUG_RETURN(schema_table_store_record(thd, table)); |
4524 | } |
4525 | |
4526 | /*******************************************************************//** |
4527 | This is the function that loops through each buffer pool and fetch buffer |
4528 | pool stats to information schema table: I_S_INNODB_BUFFER_POOL_STATS |
4529 | @return 0 on success, 1 on failure */ |
4530 | static |
4531 | int |
4532 | i_s_innodb_buffer_stats_fill_table( |
4533 | /*===============================*/ |
4534 | THD* thd, /*!< in: thread */ |
4535 | TABLE_LIST* tables, /*!< in/out: tables to fill */ |
4536 | Item* ) /*!< in: condition (ignored) */ |
4537 | { |
4538 | int status = 0; |
4539 | buf_pool_info_t* pool_info; |
4540 | |
4541 | DBUG_ENTER("i_s_innodb_buffer_fill_general" ); |
4542 | RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name.str); |
4543 | |
4544 | /* Only allow the PROCESS privilege holder to access the stats */ |
4545 | if (check_global_access(thd, PROCESS_ACL)) { |
4546 | DBUG_RETURN(0); |
4547 | } |
4548 | |
4549 | pool_info = (buf_pool_info_t*) ut_zalloc_nokey( |
4550 | srv_buf_pool_instances * sizeof *pool_info); |
4551 | |
4552 | /* Walk through each buffer pool */ |
4553 | for (ulint i = 0; i < srv_buf_pool_instances; i++) { |
4554 | buf_pool_t* buf_pool; |
4555 | |
4556 | buf_pool = buf_pool_from_array(i); |
4557 | |
4558 | /* Fetch individual buffer pool info */ |
4559 | buf_stats_get_pool_info(buf_pool, i, pool_info); |
4560 | |
4561 | status = i_s_innodb_stats_fill(thd, tables, &pool_info[i]); |
4562 | |
4563 | /* If something goes wrong, break and return */ |
4564 | if (status) { |
4565 | break; |
4566 | } |
4567 | } |
4568 | |
4569 | ut_free(pool_info); |
4570 | |
4571 | DBUG_RETURN(status); |
4572 | } |
4573 | |
4574 | /*******************************************************************//** |
4575 | Bind the dynamic table INFORMATION_SCHEMA.INNODB_BUFFER_POOL_STATS. |
4576 | @return 0 on success, 1 on failure */ |
4577 | static |
4578 | int |
4579 | i_s_innodb_buffer_pool_stats_init( |
4580 | /*==============================*/ |
4581 | void* p) /*!< in/out: table schema object */ |
4582 | { |
4583 | ST_SCHEMA_TABLE* schema; |
4584 | |
4585 | DBUG_ENTER("i_s_innodb_buffer_pool_stats_init" ); |
4586 | |
4587 | schema = reinterpret_cast<ST_SCHEMA_TABLE*>(p); |
4588 | |
4589 | schema->fields_info = i_s_innodb_buffer_stats_fields_info; |
4590 | schema->fill_table = i_s_innodb_buffer_stats_fill_table; |
4591 | |
4592 | DBUG_RETURN(0); |
4593 | } |
4594 | |
4595 | UNIV_INTERN struct st_maria_plugin i_s_innodb_buffer_stats = |
4596 | { |
4597 | /* the plugin type (a MYSQL_XXX_PLUGIN value) */ |
4598 | /* int */ |
4599 | STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN), |
4600 | |
4601 | /* pointer to type-specific plugin descriptor */ |
4602 | /* void* */ |
4603 | STRUCT_FLD(info, &i_s_info), |
4604 | |
4605 | /* plugin name */ |
4606 | /* const char* */ |
4607 | STRUCT_FLD(name, "INNODB_BUFFER_POOL_STATS" ), |
4608 | |
4609 | /* plugin author (for SHOW PLUGINS) */ |
4610 | /* const char* */ |
4611 | STRUCT_FLD(author, plugin_author), |
4612 | |
4613 | /* general descriptive text (for SHOW PLUGINS) */ |
4614 | /* const char* */ |
4615 | STRUCT_FLD(descr, "InnoDB Buffer Pool Statistics Information " ), |
4616 | |
4617 | /* the plugin license (PLUGIN_LICENSE_XXX) */ |
4618 | /* int */ |
4619 | STRUCT_FLD(license, PLUGIN_LICENSE_GPL), |
4620 | |
4621 | /* the function to invoke when plugin is loaded */ |
4622 | /* int (*)(void*); */ |
4623 | STRUCT_FLD(init, i_s_innodb_buffer_pool_stats_init), |
4624 | |
4625 | /* the function to invoke when plugin is unloaded */ |
4626 | /* int (*)(void*); */ |
4627 | STRUCT_FLD(deinit, i_s_common_deinit), |
4628 | |
4629 | /* plugin version (for SHOW PLUGINS) */ |
4630 | /* unsigned int */ |
4631 | STRUCT_FLD(version, INNODB_VERSION_SHORT), |
4632 | |
4633 | /* struct st_mysql_show_var* */ |
4634 | STRUCT_FLD(status_vars, NULL), |
4635 | |
4636 | /* struct st_mysql_sys_var** */ |
4637 | STRUCT_FLD(system_vars, NULL), |
4638 | |
4639 | /* Maria extension */ |
4640 | STRUCT_FLD(version_info, INNODB_VERSION_STR), |
4641 | STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE), |
4642 | }; |
4643 | |
4644 | /* Fields of the dynamic table INNODB_BUFFER_POOL_PAGE. */ |
4645 | static ST_FIELD_INFO i_s_innodb_buffer_page_fields_info[] = |
4646 | { |
4647 | #define IDX_BUFFER_POOL_ID 0 |
4648 | {STRUCT_FLD(field_name, "POOL_ID" ), |
4649 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
4650 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
4651 | STRUCT_FLD(value, 0), |
4652 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
4653 | STRUCT_FLD(old_name, "" ), |
4654 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
4655 | |
4656 | #define IDX_BUFFER_BLOCK_ID 1 |
4657 | {STRUCT_FLD(field_name, "BLOCK_ID" ), |
4658 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
4659 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
4660 | STRUCT_FLD(value, 0), |
4661 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
4662 | STRUCT_FLD(old_name, "" ), |
4663 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
4664 | |
4665 | #define IDX_BUFFER_PAGE_SPACE 2 |
4666 | {STRUCT_FLD(field_name, "SPACE" ), |
4667 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
4668 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
4669 | STRUCT_FLD(value, 0), |
4670 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
4671 | STRUCT_FLD(old_name, "" ), |
4672 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
4673 | |
4674 | #define IDX_BUFFER_PAGE_NUM 3 |
4675 | {STRUCT_FLD(field_name, "PAGE_NUMBER" ), |
4676 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
4677 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
4678 | STRUCT_FLD(value, 0), |
4679 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
4680 | STRUCT_FLD(old_name, "" ), |
4681 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
4682 | |
4683 | #define IDX_BUFFER_PAGE_TYPE 4 |
4684 | {STRUCT_FLD(field_name, "PAGE_TYPE" ), |
4685 | STRUCT_FLD(field_length, 64), |
4686 | STRUCT_FLD(field_type, MYSQL_TYPE_STRING), |
4687 | STRUCT_FLD(value, 0), |
4688 | STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL), |
4689 | STRUCT_FLD(old_name, "" ), |
4690 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
4691 | |
4692 | #define IDX_BUFFER_PAGE_FLUSH_TYPE 5 |
4693 | {STRUCT_FLD(field_name, "FLUSH_TYPE" ), |
4694 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
4695 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
4696 | STRUCT_FLD(value, 0), |
4697 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
4698 | STRUCT_FLD(old_name, "" ), |
4699 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
4700 | |
4701 | #define IDX_BUFFER_PAGE_FIX_COUNT 6 |
4702 | {STRUCT_FLD(field_name, "FIX_COUNT" ), |
4703 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
4704 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
4705 | STRUCT_FLD(value, 0), |
4706 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
4707 | STRUCT_FLD(old_name, "" ), |
4708 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
4709 | |
4710 | #ifdef BTR_CUR_HASH_ADAPT |
4711 | #define IDX_BUFFER_PAGE_HASHED 7 |
4712 | {STRUCT_FLD(field_name, "IS_HASHED" ), |
4713 | STRUCT_FLD(field_length, 3), |
4714 | STRUCT_FLD(field_type, MYSQL_TYPE_STRING), |
4715 | STRUCT_FLD(value, 0), |
4716 | STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL), |
4717 | STRUCT_FLD(old_name, "" ), |
4718 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
4719 | #endif /* BTR_CUR_HASH_ADAPT */ |
4720 | |
4721 | #define IDX_BUFFER_PAGE_NEWEST_MOD 7 + I_S_AHI |
4722 | {STRUCT_FLD(field_name, "NEWEST_MODIFICATION" ), |
4723 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
4724 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
4725 | STRUCT_FLD(value, 0), |
4726 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
4727 | STRUCT_FLD(old_name, "" ), |
4728 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
4729 | |
4730 | #define IDX_BUFFER_PAGE_OLDEST_MOD 8 + I_S_AHI |
4731 | {STRUCT_FLD(field_name, "OLDEST_MODIFICATION" ), |
4732 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
4733 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
4734 | STRUCT_FLD(value, 0), |
4735 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
4736 | STRUCT_FLD(old_name, "" ), |
4737 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
4738 | |
4739 | #define IDX_BUFFER_PAGE_ACCESS_TIME 9 + I_S_AHI |
4740 | {STRUCT_FLD(field_name, "ACCESS_TIME" ), |
4741 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
4742 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
4743 | STRUCT_FLD(value, 0), |
4744 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
4745 | STRUCT_FLD(old_name, "" ), |
4746 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
4747 | |
4748 | #define IDX_BUFFER_PAGE_TABLE_NAME 10 + I_S_AHI |
4749 | {STRUCT_FLD(field_name, "TABLE_NAME" ), |
4750 | STRUCT_FLD(field_length, 1024), |
4751 | STRUCT_FLD(field_type, MYSQL_TYPE_STRING), |
4752 | STRUCT_FLD(value, 0), |
4753 | STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL), |
4754 | STRUCT_FLD(old_name, "" ), |
4755 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
4756 | |
4757 | #define IDX_BUFFER_PAGE_INDEX_NAME 11 + I_S_AHI |
4758 | {STRUCT_FLD(field_name, "INDEX_NAME" ), |
4759 | STRUCT_FLD(field_length, 1024), |
4760 | STRUCT_FLD(field_type, MYSQL_TYPE_STRING), |
4761 | STRUCT_FLD(value, 0), |
4762 | STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL), |
4763 | STRUCT_FLD(old_name, "" ), |
4764 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
4765 | |
4766 | #define IDX_BUFFER_PAGE_NUM_RECS 12 + I_S_AHI |
4767 | {STRUCT_FLD(field_name, "NUMBER_RECORDS" ), |
4768 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
4769 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
4770 | STRUCT_FLD(value, 0), |
4771 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
4772 | STRUCT_FLD(old_name, "" ), |
4773 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
4774 | |
4775 | #define IDX_BUFFER_PAGE_DATA_SIZE 13 + I_S_AHI |
4776 | {STRUCT_FLD(field_name, "DATA_SIZE" ), |
4777 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
4778 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
4779 | STRUCT_FLD(value, 0), |
4780 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
4781 | STRUCT_FLD(old_name, "" ), |
4782 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
4783 | |
4784 | #define IDX_BUFFER_PAGE_ZIP_SIZE 14 + I_S_AHI |
4785 | {STRUCT_FLD(field_name, "COMPRESSED_SIZE" ), |
4786 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
4787 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
4788 | STRUCT_FLD(value, 0), |
4789 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
4790 | STRUCT_FLD(old_name, "" ), |
4791 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
4792 | |
4793 | #define IDX_BUFFER_PAGE_STATE 15 + I_S_AHI |
4794 | {STRUCT_FLD(field_name, "PAGE_STATE" ), |
4795 | STRUCT_FLD(field_length, 64), |
4796 | STRUCT_FLD(field_type, MYSQL_TYPE_STRING), |
4797 | STRUCT_FLD(value, 0), |
4798 | STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL), |
4799 | STRUCT_FLD(old_name, "" ), |
4800 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
4801 | |
4802 | #define IDX_BUFFER_PAGE_IO_FIX 16 + I_S_AHI |
4803 | {STRUCT_FLD(field_name, "IO_FIX" ), |
4804 | STRUCT_FLD(field_length, 64), |
4805 | STRUCT_FLD(field_type, MYSQL_TYPE_STRING), |
4806 | STRUCT_FLD(value, 0), |
4807 | STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL), |
4808 | STRUCT_FLD(old_name, "" ), |
4809 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
4810 | |
4811 | #define IDX_BUFFER_PAGE_IS_OLD 17 + I_S_AHI |
4812 | {STRUCT_FLD(field_name, "IS_OLD" ), |
4813 | STRUCT_FLD(field_length, 3), |
4814 | STRUCT_FLD(field_type, MYSQL_TYPE_STRING), |
4815 | STRUCT_FLD(value, 0), |
4816 | STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL), |
4817 | STRUCT_FLD(old_name, "" ), |
4818 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
4819 | |
4820 | #define IDX_BUFFER_PAGE_FREE_CLOCK 18 + I_S_AHI |
4821 | {STRUCT_FLD(field_name, "FREE_PAGE_CLOCK" ), |
4822 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
4823 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
4824 | STRUCT_FLD(value, 0), |
4825 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
4826 | STRUCT_FLD(old_name, "" ), |
4827 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
4828 | |
4829 | END_OF_ST_FIELD_INFO |
4830 | }; |
4831 | |
4832 | /*******************************************************************//** |
4833 | Fill Information Schema table INNODB_BUFFER_PAGE with information |
4834 | cached in the buf_page_info_t array |
4835 | @return 0 on success, 1 on failure */ |
4836 | static |
4837 | int |
4838 | i_s_innodb_buffer_page_fill( |
4839 | /*========================*/ |
4840 | THD* thd, /*!< in: thread */ |
4841 | TABLE_LIST* tables, /*!< in/out: tables to fill */ |
4842 | const buf_page_info_t* info_array, /*!< in: array cached page |
4843 | info */ |
4844 | ulint num_page) /*!< in: number of page info |
4845 | cached */ |
4846 | { |
4847 | TABLE* table; |
4848 | Field** fields; |
4849 | |
4850 | compile_time_assert(I_S_PAGE_TYPE_LAST < 1 << I_S_PAGE_TYPE_BITS); |
4851 | |
4852 | DBUG_ENTER("i_s_innodb_buffer_page_fill" ); |
4853 | |
4854 | table = tables->table; |
4855 | |
4856 | fields = table->field; |
4857 | |
4858 | /* Iterate through the cached array and fill the I_S table rows */ |
4859 | for (ulint i = 0; i < num_page; i++) { |
4860 | const buf_page_info_t* page_info; |
4861 | char table_name[MAX_FULL_NAME_LEN + 1]; |
4862 | const char* table_name_end = NULL; |
4863 | const char* state_str; |
4864 | enum buf_page_state state; |
4865 | |
4866 | page_info = info_array + i; |
4867 | |
4868 | state_str = NULL; |
4869 | |
4870 | OK(fields[IDX_BUFFER_POOL_ID]->store( |
4871 | page_info->pool_id, true)); |
4872 | |
4873 | OK(fields[IDX_BUFFER_BLOCK_ID]->store( |
4874 | page_info->block_id, true)); |
4875 | |
4876 | OK(fields[IDX_BUFFER_PAGE_SPACE]->store( |
4877 | page_info->space_id, true)); |
4878 | |
4879 | OK(fields[IDX_BUFFER_PAGE_NUM]->store( |
4880 | page_info->page_num, true)); |
4881 | |
4882 | OK(field_store_string( |
4883 | fields[IDX_BUFFER_PAGE_TYPE], |
4884 | i_s_page_type[page_info->page_type].type_str)); |
4885 | |
4886 | OK(fields[IDX_BUFFER_PAGE_FLUSH_TYPE]->store( |
4887 | page_info->flush_type, true)); |
4888 | |
4889 | OK(fields[IDX_BUFFER_PAGE_FIX_COUNT]->store( |
4890 | page_info->fix_count, true)); |
4891 | |
4892 | #ifdef BTR_CUR_HASH_ADAPT |
4893 | OK(field_store_string(fields[IDX_BUFFER_PAGE_HASHED], |
4894 | page_info->hashed ? "YES" : "NO" )); |
4895 | #endif /* BTR_CUR_HASH_ADAPT */ |
4896 | |
4897 | OK(fields[IDX_BUFFER_PAGE_NEWEST_MOD]->store( |
4898 | page_info->newest_mod, true)); |
4899 | |
4900 | OK(fields[IDX_BUFFER_PAGE_OLDEST_MOD]->store( |
4901 | page_info->oldest_mod, true)); |
4902 | |
4903 | OK(fields[IDX_BUFFER_PAGE_ACCESS_TIME]->store( |
4904 | page_info->access_time, true)); |
4905 | |
4906 | fields[IDX_BUFFER_PAGE_TABLE_NAME]->set_null(); |
4907 | |
4908 | fields[IDX_BUFFER_PAGE_INDEX_NAME]->set_null(); |
4909 | |
4910 | /* If this is an index page, fetch the index name |
4911 | and table name */ |
4912 | if (page_info->page_type == I_S_PAGE_TYPE_INDEX) { |
4913 | bool ret = false; |
4914 | |
4915 | mutex_enter(&dict_sys->mutex); |
4916 | |
4917 | if (const dict_index_t* index = |
4918 | dict_index_get_if_in_cache_low( |
4919 | page_info->index_id)) { |
4920 | table_name_end = innobase_convert_name( |
4921 | table_name, sizeof(table_name), |
4922 | index->table->name.m_name, |
4923 | strlen(index->table->name.m_name), |
4924 | thd); |
4925 | |
4926 | ret = fields[IDX_BUFFER_PAGE_TABLE_NAME] |
4927 | ->store(table_name, |
4928 | static_cast<uint>( |
4929 | table_name_end |
4930 | - table_name), |
4931 | system_charset_info) |
4932 | || field_store_index_name( |
4933 | fields |
4934 | [IDX_BUFFER_PAGE_INDEX_NAME], |
4935 | index->name); |
4936 | } |
4937 | |
4938 | mutex_exit(&dict_sys->mutex); |
4939 | |
4940 | OK(ret); |
4941 | |
4942 | fields[IDX_BUFFER_PAGE_TABLE_NAME]->set_notnull(); |
4943 | } |
4944 | |
4945 | OK(fields[IDX_BUFFER_PAGE_NUM_RECS]->store( |
4946 | page_info->num_recs, true)); |
4947 | |
4948 | OK(fields[IDX_BUFFER_PAGE_DATA_SIZE]->store( |
4949 | page_info->data_size, true)); |
4950 | |
4951 | OK(fields[IDX_BUFFER_PAGE_ZIP_SIZE]->store( |
4952 | page_info->zip_ssize |
4953 | ? (UNIV_ZIP_SIZE_MIN >> 1) << page_info->zip_ssize |
4954 | : 0, true)); |
4955 | compile_time_assert(BUF_PAGE_STATE_BITS == 3); |
4956 | state = static_cast<enum buf_page_state>(page_info->page_state); |
4957 | |
4958 | switch (state) { |
4959 | /* First three states are for compression pages and |
4960 | are not states we would get as we scan pages through |
4961 | buffer blocks */ |
4962 | case BUF_BLOCK_POOL_WATCH: |
4963 | case BUF_BLOCK_ZIP_PAGE: |
4964 | case BUF_BLOCK_ZIP_DIRTY: |
4965 | state_str = NULL; |
4966 | break; |
4967 | case BUF_BLOCK_NOT_USED: |
4968 | state_str = "NOT_USED" ; |
4969 | break; |
4970 | case BUF_BLOCK_READY_FOR_USE: |
4971 | state_str = "READY_FOR_USE" ; |
4972 | break; |
4973 | case BUF_BLOCK_FILE_PAGE: |
4974 | state_str = "FILE_PAGE" ; |
4975 | break; |
4976 | case BUF_BLOCK_MEMORY: |
4977 | state_str = "MEMORY" ; |
4978 | break; |
4979 | case BUF_BLOCK_REMOVE_HASH: |
4980 | state_str = "REMOVE_HASH" ; |
4981 | break; |
4982 | }; |
4983 | |
4984 | OK(field_store_string(fields[IDX_BUFFER_PAGE_STATE], |
4985 | state_str)); |
4986 | |
4987 | switch (page_info->io_fix) { |
4988 | case BUF_IO_NONE: |
4989 | state_str = "IO_NONE" ; |
4990 | break; |
4991 | case BUF_IO_READ: |
4992 | state_str = "IO_READ" ; |
4993 | break; |
4994 | case BUF_IO_WRITE: |
4995 | state_str = "IO_WRITE" ; |
4996 | break; |
4997 | case BUF_IO_PIN: |
4998 | state_str = "IO_PIN" ; |
4999 | break; |
5000 | } |
5001 | |
5002 | OK(field_store_string(fields[IDX_BUFFER_PAGE_IO_FIX], |
5003 | state_str)); |
5004 | |
5005 | OK(field_store_string(fields[IDX_BUFFER_PAGE_IS_OLD], |
5006 | (page_info->is_old) ? "YES" : "NO" )); |
5007 | |
5008 | OK(fields[IDX_BUFFER_PAGE_FREE_CLOCK]->store( |
5009 | page_info->freed_page_clock, true)); |
5010 | |
5011 | OK(schema_table_store_record(thd, table)); |
5012 | } |
5013 | |
5014 | DBUG_RETURN(0); |
5015 | } |
5016 | |
5017 | /*******************************************************************//** |
5018 | Set appropriate page type to a buf_page_info_t structure */ |
5019 | static |
5020 | void |
5021 | i_s_innodb_set_page_type( |
5022 | /*=====================*/ |
5023 | buf_page_info_t*page_info, /*!< in/out: structure to fill with |
5024 | scanned info */ |
5025 | ulint page_type, /*!< in: page type */ |
5026 | const byte* frame) /*!< in: buffer frame */ |
5027 | { |
5028 | if (fil_page_type_is_index(page_type)) { |
5029 | const page_t* page = (const page_t*) frame; |
5030 | |
5031 | page_info->index_id = btr_page_get_index_id(page); |
5032 | |
5033 | /* FIL_PAGE_INDEX and FIL_PAGE_RTREE are a bit special, |
5034 | their values are defined as 17855 and 17854, so we cannot |
5035 | use them to index into i_s_page_type[] array, its array index |
5036 | in the i_s_page_type[] array is I_S_PAGE_TYPE_INDEX |
5037 | (1) for index pages or I_S_PAGE_TYPE_IBUF for |
5038 | change buffer index pages */ |
5039 | if (page_type == FIL_PAGE_RTREE) { |
5040 | page_info->page_type = I_S_PAGE_TYPE_RTREE; |
5041 | } else if (page_info->index_id |
5042 | == static_cast<index_id_t>(DICT_IBUF_ID_MIN |
5043 | + IBUF_SPACE_ID)) { |
5044 | page_info->page_type = I_S_PAGE_TYPE_IBUF; |
5045 | } else { |
5046 | ut_ad(page_type == FIL_PAGE_INDEX |
5047 | || page_type == FIL_PAGE_TYPE_INSTANT); |
5048 | page_info->page_type = I_S_PAGE_TYPE_INDEX; |
5049 | } |
5050 | |
5051 | page_info->data_size = unsigned(page_header_get_field( |
5052 | page, PAGE_HEAP_TOP) - (page_is_comp(page) |
5053 | ? PAGE_NEW_SUPREMUM_END |
5054 | : PAGE_OLD_SUPREMUM_END) |
5055 | - page_header_get_field(page, PAGE_GARBAGE)); |
5056 | |
5057 | page_info->num_recs = page_get_n_recs(page); |
5058 | } else if (page_type > FIL_PAGE_TYPE_LAST) { |
5059 | /* Encountered an unknown page type */ |
5060 | page_info->page_type = I_S_PAGE_TYPE_UNKNOWN; |
5061 | } else { |
5062 | /* Make sure we get the right index into the |
5063 | i_s_page_type[] array */ |
5064 | ut_a(page_type == i_s_page_type[page_type].type_value); |
5065 | |
5066 | page_info->page_type = page_type; |
5067 | } |
5068 | |
5069 | if (page_info->page_type == FIL_PAGE_TYPE_ZBLOB |
5070 | || page_info->page_type == FIL_PAGE_TYPE_ZBLOB2) { |
5071 | page_info->page_num = mach_read_from_4( |
5072 | frame + FIL_PAGE_OFFSET); |
5073 | page_info->space_id = mach_read_from_4( |
5074 | frame + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID); |
5075 | } |
5076 | } |
5077 | /*******************************************************************//** |
5078 | Scans pages in the buffer cache, and collect their general information |
5079 | into the buf_page_info_t array which is zero-filled. So any fields |
5080 | that are not initialized in the function will default to 0 */ |
5081 | static |
5082 | void |
5083 | i_s_innodb_buffer_page_get_info( |
5084 | /*============================*/ |
5085 | const buf_page_t*bpage, /*!< in: buffer pool page to scan */ |
5086 | ulint pool_id, /*!< in: buffer pool id */ |
5087 | ulint pos, /*!< in: buffer block position in |
5088 | buffer pool or in the LRU list */ |
5089 | buf_page_info_t*page_info) /*!< in: zero filled info structure; |
5090 | out: structure filled with scanned |
5091 | info */ |
5092 | { |
5093 | ut_ad(pool_id < MAX_BUFFER_POOLS); |
5094 | |
5095 | page_info->pool_id = pool_id; |
5096 | |
5097 | page_info->block_id = pos; |
5098 | |
5099 | page_info->page_state = buf_page_get_state(bpage); |
5100 | |
5101 | /* Only fetch information for buffers that map to a tablespace, |
5102 | that is, buffer page with state BUF_BLOCK_ZIP_PAGE, |
5103 | BUF_BLOCK_ZIP_DIRTY or BUF_BLOCK_FILE_PAGE */ |
5104 | if (buf_page_in_file(bpage)) { |
5105 | const byte* frame; |
5106 | ulint page_type; |
5107 | |
5108 | page_info->space_id = bpage->id.space(); |
5109 | |
5110 | page_info->page_num = bpage->id.page_no(); |
5111 | |
5112 | page_info->flush_type = bpage->flush_type; |
5113 | |
5114 | page_info->fix_count = bpage->buf_fix_count; |
5115 | |
5116 | page_info->newest_mod = bpage->newest_modification; |
5117 | |
5118 | page_info->oldest_mod = bpage->oldest_modification; |
5119 | |
5120 | page_info->access_time = bpage->access_time; |
5121 | |
5122 | page_info->zip_ssize = bpage->zip.ssize; |
5123 | |
5124 | page_info->io_fix = bpage->io_fix; |
5125 | |
5126 | page_info->is_old = bpage->old; |
5127 | |
5128 | page_info->freed_page_clock = bpage->freed_page_clock; |
5129 | |
5130 | switch (buf_page_get_io_fix(bpage)) { |
5131 | case BUF_IO_NONE: |
5132 | case BUF_IO_WRITE: |
5133 | case BUF_IO_PIN: |
5134 | break; |
5135 | case BUF_IO_READ: |
5136 | page_info->page_type = I_S_PAGE_TYPE_UNKNOWN; |
5137 | return; |
5138 | } |
5139 | |
5140 | if (page_info->page_state == BUF_BLOCK_FILE_PAGE) { |
5141 | const buf_block_t*block; |
5142 | |
5143 | block = reinterpret_cast<const buf_block_t*>(bpage); |
5144 | frame = block->frame; |
5145 | #ifdef BTR_CUR_HASH_ADAPT |
5146 | /* Note: this may be a false positive, that |
5147 | is, block->index will not always be set to |
5148 | NULL when the last adaptive hash index |
5149 | reference is dropped. */ |
5150 | page_info->hashed = (block->index != NULL); |
5151 | #endif /* BTR_CUR_HASH_ADAPT */ |
5152 | } else { |
5153 | ut_ad(page_info->zip_ssize); |
5154 | frame = bpage->zip.data; |
5155 | } |
5156 | |
5157 | page_type = fil_page_get_type(frame); |
5158 | |
5159 | i_s_innodb_set_page_type(page_info, page_type, frame); |
5160 | } else { |
5161 | page_info->page_type = I_S_PAGE_TYPE_UNKNOWN; |
5162 | } |
5163 | } |
5164 | |
5165 | /*******************************************************************//** |
5166 | This is the function that goes through each block of the buffer pool |
5167 | and fetch information to information schema tables: INNODB_BUFFER_PAGE. |
5168 | @return 0 on success, 1 on failure */ |
5169 | static |
5170 | int |
5171 | i_s_innodb_fill_buffer_pool( |
5172 | /*========================*/ |
5173 | THD* thd, /*!< in: thread */ |
5174 | TABLE_LIST* tables, /*!< in/out: tables to fill */ |
5175 | buf_pool_t* buf_pool, /*!< in: buffer pool to scan */ |
5176 | const ulint pool_id) /*!< in: buffer pool id */ |
5177 | { |
5178 | int status = 0; |
5179 | mem_heap_t* heap; |
5180 | |
5181 | DBUG_ENTER("i_s_innodb_fill_buffer_pool" ); |
5182 | |
5183 | heap = mem_heap_create(10000); |
5184 | |
5185 | /* Go through each chunk of buffer pool. Currently, we only |
5186 | have one single chunk for each buffer pool */ |
5187 | for (ulint n = 0; |
5188 | n < ut_min(buf_pool->n_chunks, buf_pool->n_chunks_new); n++) { |
5189 | const buf_block_t* block; |
5190 | ulint n_blocks; |
5191 | buf_page_info_t* info_buffer; |
5192 | ulint num_page; |
5193 | ulint mem_size; |
5194 | ulint chunk_size; |
5195 | ulint num_to_process = 0; |
5196 | ulint block_id = 0; |
5197 | |
5198 | /* Get buffer block of the nth chunk */ |
5199 | block = buf_get_nth_chunk_block(buf_pool, n, &chunk_size); |
5200 | num_page = 0; |
5201 | |
5202 | while (chunk_size > 0) { |
5203 | /* we cache maximum MAX_BUF_INFO_CACHED number of |
5204 | buffer page info */ |
5205 | num_to_process = ut_min(chunk_size, |
5206 | (ulint)MAX_BUF_INFO_CACHED); |
5207 | |
5208 | mem_size = num_to_process * sizeof(buf_page_info_t); |
5209 | |
5210 | /* For each chunk, we'll pre-allocate information |
5211 | structures to cache the page information read from |
5212 | the buffer pool. Doing so before obtain any mutex */ |
5213 | info_buffer = (buf_page_info_t*) mem_heap_zalloc( |
5214 | heap, mem_size); |
5215 | |
5216 | /* Obtain appropriate mutexes. Since this is diagnostic |
5217 | buffer pool info printout, we are not required to |
5218 | preserve the overall consistency, so we can |
5219 | release mutex periodically */ |
5220 | buf_pool_mutex_enter(buf_pool); |
5221 | |
5222 | /* GO through each block in the chunk */ |
5223 | for (n_blocks = num_to_process; n_blocks--; block++) { |
5224 | i_s_innodb_buffer_page_get_info( |
5225 | &block->page, pool_id, block_id, |
5226 | info_buffer + num_page); |
5227 | block_id++; |
5228 | num_page++; |
5229 | } |
5230 | |
5231 | buf_pool_mutex_exit(buf_pool); |
5232 | |
5233 | /* Fill in information schema table with information |
5234 | just collected from the buffer chunk scan */ |
5235 | status = i_s_innodb_buffer_page_fill( |
5236 | thd, tables, info_buffer, |
5237 | num_page); |
5238 | |
5239 | /* If something goes wrong, break and return */ |
5240 | if (status) { |
5241 | break; |
5242 | } |
5243 | |
5244 | mem_heap_empty(heap); |
5245 | chunk_size -= num_to_process; |
5246 | num_page = 0; |
5247 | } |
5248 | } |
5249 | |
5250 | mem_heap_free(heap); |
5251 | |
5252 | DBUG_RETURN(status); |
5253 | } |
5254 | |
5255 | /*******************************************************************//** |
5256 | Fill page information for pages in InnoDB buffer pool to the |
5257 | dynamic table INFORMATION_SCHEMA.INNODB_BUFFER_PAGE |
5258 | @return 0 on success, 1 on failure */ |
5259 | static |
5260 | int |
5261 | i_s_innodb_buffer_page_fill_table( |
5262 | /*==============================*/ |
5263 | THD* thd, /*!< in: thread */ |
5264 | TABLE_LIST* tables, /*!< in/out: tables to fill */ |
5265 | Item* ) /*!< in: condition (ignored) */ |
5266 | { |
5267 | int status = 0; |
5268 | |
5269 | DBUG_ENTER("i_s_innodb_buffer_page_fill_table" ); |
5270 | |
5271 | RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name.str); |
5272 | |
5273 | /* deny access to user without PROCESS privilege */ |
5274 | if (check_global_access(thd, PROCESS_ACL)) { |
5275 | DBUG_RETURN(0); |
5276 | } |
5277 | |
5278 | /* Walk through each buffer pool */ |
5279 | for (ulint i = 0; i < srv_buf_pool_instances; i++) { |
5280 | buf_pool_t* buf_pool; |
5281 | |
5282 | buf_pool = buf_pool_from_array(i); |
5283 | |
5284 | /* Fetch information from pages in this buffer pool, |
5285 | and fill the corresponding I_S table */ |
5286 | status = i_s_innodb_fill_buffer_pool(thd, tables, buf_pool, i); |
5287 | |
5288 | /* If something wrong, break and return */ |
5289 | if (status) { |
5290 | break; |
5291 | } |
5292 | } |
5293 | |
5294 | DBUG_RETURN(status); |
5295 | } |
5296 | |
5297 | /*******************************************************************//** |
5298 | Bind the dynamic table INFORMATION_SCHEMA.INNODB_BUFFER_PAGE. |
5299 | @return 0 on success, 1 on failure */ |
5300 | static |
5301 | int |
5302 | i_s_innodb_buffer_page_init( |
5303 | /*========================*/ |
5304 | void* p) /*!< in/out: table schema object */ |
5305 | { |
5306 | ST_SCHEMA_TABLE* schema; |
5307 | |
5308 | DBUG_ENTER("i_s_innodb_buffer_page_init" ); |
5309 | |
5310 | schema = reinterpret_cast<ST_SCHEMA_TABLE*>(p); |
5311 | |
5312 | schema->fields_info = i_s_innodb_buffer_page_fields_info; |
5313 | schema->fill_table = i_s_innodb_buffer_page_fill_table; |
5314 | |
5315 | DBUG_RETURN(0); |
5316 | } |
5317 | |
5318 | UNIV_INTERN struct st_maria_plugin i_s_innodb_buffer_page = |
5319 | { |
5320 | /* the plugin type (a MYSQL_XXX_PLUGIN value) */ |
5321 | /* int */ |
5322 | STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN), |
5323 | |
5324 | /* pointer to type-specific plugin descriptor */ |
5325 | /* void* */ |
5326 | STRUCT_FLD(info, &i_s_info), |
5327 | |
5328 | /* plugin name */ |
5329 | /* const char* */ |
5330 | STRUCT_FLD(name, "INNODB_BUFFER_PAGE" ), |
5331 | |
5332 | /* plugin author (for SHOW PLUGINS) */ |
5333 | /* const char* */ |
5334 | STRUCT_FLD(author, plugin_author), |
5335 | |
5336 | /* general descriptive text (for SHOW PLUGINS) */ |
5337 | /* const char* */ |
5338 | STRUCT_FLD(descr, "InnoDB Buffer Page Information" ), |
5339 | |
5340 | /* the plugin license (PLUGIN_LICENSE_XXX) */ |
5341 | /* int */ |
5342 | STRUCT_FLD(license, PLUGIN_LICENSE_GPL), |
5343 | |
5344 | /* the function to invoke when plugin is loaded */ |
5345 | /* int (*)(void*); */ |
5346 | STRUCT_FLD(init, i_s_innodb_buffer_page_init), |
5347 | |
5348 | /* the function to invoke when plugin is unloaded */ |
5349 | /* int (*)(void*); */ |
5350 | STRUCT_FLD(deinit, i_s_common_deinit), |
5351 | |
5352 | /* plugin version (for SHOW PLUGINS) */ |
5353 | /* unsigned int */ |
5354 | STRUCT_FLD(version, INNODB_VERSION_SHORT), |
5355 | |
5356 | /* struct st_mysql_show_var* */ |
5357 | STRUCT_FLD(status_vars, NULL), |
5358 | |
5359 | /* struct st_mysql_sys_var** */ |
5360 | STRUCT_FLD(system_vars, NULL), |
5361 | |
5362 | /* Maria extension */ |
5363 | STRUCT_FLD(version_info, INNODB_VERSION_STR), |
5364 | STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE), |
5365 | }; |
5366 | |
5367 | static ST_FIELD_INFO i_s_innodb_buf_page_lru_fields_info[] = |
5368 | { |
5369 | #define IDX_BUF_LRU_POOL_ID 0 |
5370 | {STRUCT_FLD(field_name, "POOL_ID" ), |
5371 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
5372 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
5373 | STRUCT_FLD(value, 0), |
5374 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
5375 | STRUCT_FLD(old_name, "" ), |
5376 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
5377 | |
5378 | #define IDX_BUF_LRU_POS 1 |
5379 | {STRUCT_FLD(field_name, "LRU_POSITION" ), |
5380 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
5381 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
5382 | STRUCT_FLD(value, 0), |
5383 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
5384 | STRUCT_FLD(old_name, "" ), |
5385 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
5386 | |
5387 | #define IDX_BUF_LRU_PAGE_SPACE 2 |
5388 | {STRUCT_FLD(field_name, "SPACE" ), |
5389 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
5390 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
5391 | STRUCT_FLD(value, 0), |
5392 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
5393 | STRUCT_FLD(old_name, "" ), |
5394 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
5395 | |
5396 | #define IDX_BUF_LRU_PAGE_NUM 3 |
5397 | {STRUCT_FLD(field_name, "PAGE_NUMBER" ), |
5398 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
5399 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
5400 | STRUCT_FLD(value, 0), |
5401 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
5402 | STRUCT_FLD(old_name, "" ), |
5403 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
5404 | |
5405 | #define IDX_BUF_LRU_PAGE_TYPE 4 |
5406 | {STRUCT_FLD(field_name, "PAGE_TYPE" ), |
5407 | STRUCT_FLD(field_length, 64), |
5408 | STRUCT_FLD(field_type, MYSQL_TYPE_STRING), |
5409 | STRUCT_FLD(value, 0), |
5410 | STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL), |
5411 | STRUCT_FLD(old_name, "" ), |
5412 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
5413 | |
5414 | #define IDX_BUF_LRU_PAGE_FLUSH_TYPE 5 |
5415 | {STRUCT_FLD(field_name, "FLUSH_TYPE" ), |
5416 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
5417 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
5418 | STRUCT_FLD(value, 0), |
5419 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
5420 | STRUCT_FLD(old_name, "" ), |
5421 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
5422 | |
5423 | #define IDX_BUF_LRU_PAGE_FIX_COUNT 6 |
5424 | {STRUCT_FLD(field_name, "FIX_COUNT" ), |
5425 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
5426 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
5427 | STRUCT_FLD(value, 0), |
5428 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
5429 | STRUCT_FLD(old_name, "" ), |
5430 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
5431 | |
5432 | #ifdef BTR_CUR_HASH_ADAPT |
5433 | #define IDX_BUF_LRU_PAGE_HASHED 7 |
5434 | {STRUCT_FLD(field_name, "IS_HASHED" ), |
5435 | STRUCT_FLD(field_length, 3), |
5436 | STRUCT_FLD(field_type, MYSQL_TYPE_STRING), |
5437 | STRUCT_FLD(value, 0), |
5438 | STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL), |
5439 | STRUCT_FLD(old_name, "" ), |
5440 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
5441 | #endif /* BTR_CUR_HASH_ADAPT */ |
5442 | |
5443 | #define IDX_BUF_LRU_PAGE_NEWEST_MOD 7 + I_S_AHI |
5444 | {STRUCT_FLD(field_name, "NEWEST_MODIFICATION" ), |
5445 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
5446 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
5447 | STRUCT_FLD(value, 0), |
5448 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
5449 | STRUCT_FLD(old_name, "" ), |
5450 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
5451 | |
5452 | #define IDX_BUF_LRU_PAGE_OLDEST_MOD 8 + I_S_AHI |
5453 | {STRUCT_FLD(field_name, "OLDEST_MODIFICATION" ), |
5454 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
5455 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
5456 | STRUCT_FLD(value, 0), |
5457 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
5458 | STRUCT_FLD(old_name, "" ), |
5459 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
5460 | |
5461 | #define IDX_BUF_LRU_PAGE_ACCESS_TIME 9 + I_S_AHI |
5462 | {STRUCT_FLD(field_name, "ACCESS_TIME" ), |
5463 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
5464 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
5465 | STRUCT_FLD(value, 0), |
5466 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
5467 | STRUCT_FLD(old_name, "" ), |
5468 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
5469 | |
5470 | #define IDX_BUF_LRU_PAGE_TABLE_NAME 10 + I_S_AHI |
5471 | {STRUCT_FLD(field_name, "TABLE_NAME" ), |
5472 | STRUCT_FLD(field_length, 1024), |
5473 | STRUCT_FLD(field_type, MYSQL_TYPE_STRING), |
5474 | STRUCT_FLD(value, 0), |
5475 | STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL), |
5476 | STRUCT_FLD(old_name, "" ), |
5477 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
5478 | |
5479 | #define IDX_BUF_LRU_PAGE_INDEX_NAME 11 + I_S_AHI |
5480 | {STRUCT_FLD(field_name, "INDEX_NAME" ), |
5481 | STRUCT_FLD(field_length, 1024), |
5482 | STRUCT_FLD(field_type, MYSQL_TYPE_STRING), |
5483 | STRUCT_FLD(value, 0), |
5484 | STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL), |
5485 | STRUCT_FLD(old_name, "" ), |
5486 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
5487 | |
5488 | #define IDX_BUF_LRU_PAGE_NUM_RECS 12 + I_S_AHI |
5489 | {STRUCT_FLD(field_name, "NUMBER_RECORDS" ), |
5490 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
5491 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
5492 | STRUCT_FLD(value, 0), |
5493 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
5494 | STRUCT_FLD(old_name, "" ), |
5495 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
5496 | |
5497 | #define IDX_BUF_LRU_PAGE_DATA_SIZE 13 + I_S_AHI |
5498 | {STRUCT_FLD(field_name, "DATA_SIZE" ), |
5499 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
5500 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
5501 | STRUCT_FLD(value, 0), |
5502 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
5503 | STRUCT_FLD(old_name, "" ), |
5504 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
5505 | |
5506 | #define IDX_BUF_LRU_PAGE_ZIP_SIZE 14 + I_S_AHI |
5507 | {STRUCT_FLD(field_name, "COMPRESSED_SIZE" ), |
5508 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
5509 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
5510 | STRUCT_FLD(value, 0), |
5511 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
5512 | STRUCT_FLD(old_name, "" ), |
5513 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
5514 | |
5515 | #define IDX_BUF_LRU_PAGE_STATE 15 + I_S_AHI |
5516 | {STRUCT_FLD(field_name, "COMPRESSED" ), |
5517 | STRUCT_FLD(field_length, 3), |
5518 | STRUCT_FLD(field_type, MYSQL_TYPE_STRING), |
5519 | STRUCT_FLD(value, 0), |
5520 | STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL), |
5521 | STRUCT_FLD(old_name, "" ), |
5522 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
5523 | |
5524 | #define IDX_BUF_LRU_PAGE_IO_FIX 16 + I_S_AHI |
5525 | {STRUCT_FLD(field_name, "IO_FIX" ), |
5526 | STRUCT_FLD(field_length, 64), |
5527 | STRUCT_FLD(field_type, MYSQL_TYPE_STRING), |
5528 | STRUCT_FLD(value, 0), |
5529 | STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL), |
5530 | STRUCT_FLD(old_name, "" ), |
5531 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
5532 | |
5533 | #define IDX_BUF_LRU_PAGE_IS_OLD 17 + I_S_AHI |
5534 | {STRUCT_FLD(field_name, "IS_OLD" ), |
5535 | STRUCT_FLD(field_length, 3), |
5536 | STRUCT_FLD(field_type, MYSQL_TYPE_STRING), |
5537 | STRUCT_FLD(value, 0), |
5538 | STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL), |
5539 | STRUCT_FLD(old_name, "" ), |
5540 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
5541 | |
5542 | #define IDX_BUF_LRU_PAGE_FREE_CLOCK 18 + I_S_AHI |
5543 | {STRUCT_FLD(field_name, "FREE_PAGE_CLOCK" ), |
5544 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
5545 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
5546 | STRUCT_FLD(value, 0), |
5547 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
5548 | STRUCT_FLD(old_name, "" ), |
5549 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
5550 | |
5551 | END_OF_ST_FIELD_INFO |
5552 | }; |
5553 | |
5554 | /*******************************************************************//** |
5555 | Fill Information Schema table INNODB_BUFFER_PAGE_LRU with information |
5556 | cached in the buf_page_info_t array |
5557 | @return 0 on success, 1 on failure */ |
5558 | static |
5559 | int |
5560 | i_s_innodb_buf_page_lru_fill( |
5561 | /*=========================*/ |
5562 | THD* thd, /*!< in: thread */ |
5563 | TABLE_LIST* tables, /*!< in/out: tables to fill */ |
5564 | const buf_page_info_t* info_array, /*!< in: array cached page |
5565 | info */ |
5566 | ulint num_page) /*!< in: number of page info |
5567 | cached */ |
5568 | { |
5569 | DBUG_ENTER("i_s_innodb_buf_page_lru_fill" ); |
5570 | |
5571 | TABLE* table = tables->table; |
5572 | Field** fields = table->field; |
5573 | |
5574 | /* Iterate through the cached array and fill the I_S table rows */ |
5575 | for (ulint i = 0; i < num_page; i++) { |
5576 | const buf_page_info_t* page_info; |
5577 | char table_name[MAX_FULL_NAME_LEN + 1]; |
5578 | const char* table_name_end = NULL; |
5579 | const char* state_str; |
5580 | enum buf_page_state state; |
5581 | |
5582 | state_str = NULL; |
5583 | |
5584 | page_info = info_array + i; |
5585 | |
5586 | OK(fields[IDX_BUF_LRU_POOL_ID]->store( |
5587 | page_info->pool_id, true)); |
5588 | |
5589 | OK(fields[IDX_BUF_LRU_POS]->store( |
5590 | page_info->block_id, true)); |
5591 | |
5592 | OK(fields[IDX_BUF_LRU_PAGE_SPACE]->store( |
5593 | page_info->space_id, true)); |
5594 | |
5595 | OK(fields[IDX_BUF_LRU_PAGE_NUM]->store( |
5596 | page_info->page_num, true)); |
5597 | |
5598 | OK(field_store_string( |
5599 | fields[IDX_BUF_LRU_PAGE_TYPE], |
5600 | i_s_page_type[page_info->page_type].type_str)); |
5601 | |
5602 | OK(fields[IDX_BUF_LRU_PAGE_FLUSH_TYPE]->store( |
5603 | page_info->flush_type, true)); |
5604 | |
5605 | OK(fields[IDX_BUF_LRU_PAGE_FIX_COUNT]->store( |
5606 | page_info->fix_count, true)); |
5607 | |
5608 | #ifdef BTR_CUR_HASH_ADAPT |
5609 | OK(field_store_string(fields[IDX_BUF_LRU_PAGE_HASHED], |
5610 | page_info->hashed ? "YES" : "NO" )); |
5611 | #endif /* BTR_CUR_HASH_ADAPT */ |
5612 | |
5613 | OK(fields[IDX_BUF_LRU_PAGE_NEWEST_MOD]->store( |
5614 | page_info->newest_mod, true)); |
5615 | |
5616 | OK(fields[IDX_BUF_LRU_PAGE_OLDEST_MOD]->store( |
5617 | page_info->oldest_mod, true)); |
5618 | |
5619 | OK(fields[IDX_BUF_LRU_PAGE_ACCESS_TIME]->store( |
5620 | page_info->access_time, true)); |
5621 | |
5622 | fields[IDX_BUF_LRU_PAGE_TABLE_NAME]->set_null(); |
5623 | |
5624 | fields[IDX_BUF_LRU_PAGE_INDEX_NAME]->set_null(); |
5625 | |
5626 | /* If this is an index page, fetch the index name |
5627 | and table name */ |
5628 | if (page_info->page_type == I_S_PAGE_TYPE_INDEX) { |
5629 | bool ret = false; |
5630 | |
5631 | mutex_enter(&dict_sys->mutex); |
5632 | |
5633 | if (const dict_index_t* index = |
5634 | dict_index_get_if_in_cache_low( |
5635 | page_info->index_id)) { |
5636 | table_name_end = innobase_convert_name( |
5637 | table_name, sizeof(table_name), |
5638 | index->table->name.m_name, |
5639 | strlen(index->table->name.m_name), |
5640 | thd); |
5641 | |
5642 | ret = fields[IDX_BUF_LRU_PAGE_TABLE_NAME] |
5643 | ->store(table_name, |
5644 | static_cast<uint>( |
5645 | table_name_end |
5646 | - table_name), |
5647 | system_charset_info) |
5648 | || field_store_index_name( |
5649 | fields |
5650 | [IDX_BUF_LRU_PAGE_INDEX_NAME], |
5651 | index->name); |
5652 | } |
5653 | |
5654 | mutex_exit(&dict_sys->mutex); |
5655 | |
5656 | OK(ret); |
5657 | |
5658 | fields[IDX_BUF_LRU_PAGE_TABLE_NAME]->set_notnull(); |
5659 | } |
5660 | |
5661 | OK(fields[IDX_BUF_LRU_PAGE_NUM_RECS]->store( |
5662 | page_info->num_recs, true)); |
5663 | |
5664 | OK(fields[IDX_BUF_LRU_PAGE_DATA_SIZE]->store( |
5665 | page_info->data_size, true)); |
5666 | |
5667 | OK(fields[IDX_BUF_LRU_PAGE_ZIP_SIZE]->store( |
5668 | page_info->zip_ssize |
5669 | ? 512 << page_info->zip_ssize : 0, true)); |
5670 | |
5671 | state = static_cast<enum buf_page_state>(page_info->page_state); |
5672 | |
5673 | switch (state) { |
5674 | /* Compressed page */ |
5675 | case BUF_BLOCK_ZIP_PAGE: |
5676 | case BUF_BLOCK_ZIP_DIRTY: |
5677 | state_str = "YES" ; |
5678 | break; |
5679 | /* Uncompressed page */ |
5680 | case BUF_BLOCK_FILE_PAGE: |
5681 | state_str = "NO" ; |
5682 | break; |
5683 | /* We should not see following states */ |
5684 | case BUF_BLOCK_POOL_WATCH: |
5685 | case BUF_BLOCK_READY_FOR_USE: |
5686 | case BUF_BLOCK_NOT_USED: |
5687 | case BUF_BLOCK_MEMORY: |
5688 | case BUF_BLOCK_REMOVE_HASH: |
5689 | state_str = NULL; |
5690 | break; |
5691 | }; |
5692 | |
5693 | OK(field_store_string(fields[IDX_BUF_LRU_PAGE_STATE], |
5694 | state_str)); |
5695 | |
5696 | switch (page_info->io_fix) { |
5697 | case BUF_IO_NONE: |
5698 | state_str = "IO_NONE" ; |
5699 | break; |
5700 | case BUF_IO_READ: |
5701 | state_str = "IO_READ" ; |
5702 | break; |
5703 | case BUF_IO_WRITE: |
5704 | state_str = "IO_WRITE" ; |
5705 | break; |
5706 | case BUF_IO_PIN: |
5707 | state_str = "IO_PIN" ; |
5708 | break; |
5709 | } |
5710 | |
5711 | OK(field_store_string(fields[IDX_BUF_LRU_PAGE_IO_FIX], |
5712 | state_str)); |
5713 | |
5714 | OK(field_store_string(fields[IDX_BUF_LRU_PAGE_IS_OLD], |
5715 | page_info->is_old ? "YES" : "NO" )); |
5716 | |
5717 | OK(fields[IDX_BUF_LRU_PAGE_FREE_CLOCK]->store( |
5718 | page_info->freed_page_clock, true)); |
5719 | |
5720 | OK(schema_table_store_record(thd, table)); |
5721 | } |
5722 | |
5723 | DBUG_RETURN(0); |
5724 | } |
5725 | |
5726 | /*******************************************************************//** |
5727 | This is the function that goes through buffer pool's LRU list |
5728 | and fetch information to INFORMATION_SCHEMA.INNODB_BUFFER_PAGE_LRU. |
5729 | @return 0 on success, 1 on failure */ |
5730 | static |
5731 | int |
5732 | i_s_innodb_fill_buffer_lru( |
5733 | /*=======================*/ |
5734 | THD* thd, /*!< in: thread */ |
5735 | TABLE_LIST* tables, /*!< in/out: tables to fill */ |
5736 | buf_pool_t* buf_pool, /*!< in: buffer pool to scan */ |
5737 | const ulint pool_id) /*!< in: buffer pool id */ |
5738 | { |
5739 | int status = 0; |
5740 | buf_page_info_t* info_buffer; |
5741 | ulint lru_pos = 0; |
5742 | const buf_page_t* bpage; |
5743 | ulint lru_len; |
5744 | |
5745 | DBUG_ENTER("i_s_innodb_fill_buffer_lru" ); |
5746 | |
5747 | /* Obtain buf_pool mutex before allocate info_buffer, since |
5748 | UT_LIST_GET_LEN(buf_pool->LRU) could change */ |
5749 | buf_pool_mutex_enter(buf_pool); |
5750 | |
5751 | lru_len = UT_LIST_GET_LEN(buf_pool->LRU); |
5752 | |
5753 | /* Print error message if malloc fail */ |
5754 | info_buffer = (buf_page_info_t*) my_malloc( |
5755 | lru_len * sizeof *info_buffer, MYF(MY_WME)); |
5756 | /* JAN: TODO: MySQL 5.7 PSI |
5757 | info_buffer = (buf_page_info_t*) my_malloc(PSI_INSTRUMENT_ME, |
5758 | lru_len * sizeof *info_buffer, MYF(MY_WME)); |
5759 | */ |
5760 | |
5761 | if (!info_buffer) { |
5762 | status = 1; |
5763 | goto exit; |
5764 | } |
5765 | |
5766 | memset(info_buffer, 0, lru_len * sizeof *info_buffer); |
5767 | |
5768 | /* Walk through Pool's LRU list and print the buffer page |
5769 | information */ |
5770 | bpage = UT_LIST_GET_LAST(buf_pool->LRU); |
5771 | |
5772 | while (bpage != NULL) { |
5773 | /* Use the same function that collect buffer info for |
5774 | INNODB_BUFFER_PAGE to get buffer page info */ |
5775 | i_s_innodb_buffer_page_get_info(bpage, pool_id, lru_pos, |
5776 | (info_buffer + lru_pos)); |
5777 | |
5778 | bpage = UT_LIST_GET_PREV(LRU, bpage); |
5779 | |
5780 | lru_pos++; |
5781 | } |
5782 | |
5783 | ut_ad(lru_pos == lru_len); |
5784 | ut_ad(lru_pos == UT_LIST_GET_LEN(buf_pool->LRU)); |
5785 | |
5786 | exit: |
5787 | buf_pool_mutex_exit(buf_pool); |
5788 | |
5789 | if (info_buffer) { |
5790 | status = i_s_innodb_buf_page_lru_fill( |
5791 | thd, tables, info_buffer, lru_len); |
5792 | |
5793 | my_free(info_buffer); |
5794 | } |
5795 | |
5796 | DBUG_RETURN(status); |
5797 | } |
5798 | |
5799 | /*******************************************************************//** |
5800 | Fill page information for pages in InnoDB buffer pool to the |
5801 | dynamic table INFORMATION_SCHEMA.INNODB_BUFFER_PAGE_LRU |
5802 | @return 0 on success, 1 on failure */ |
5803 | static |
5804 | int |
5805 | i_s_innodb_buf_page_lru_fill_table( |
5806 | /*===============================*/ |
5807 | THD* thd, /*!< in: thread */ |
5808 | TABLE_LIST* tables, /*!< in/out: tables to fill */ |
5809 | Item* ) /*!< in: condition (ignored) */ |
5810 | { |
5811 | int status = 0; |
5812 | |
5813 | DBUG_ENTER("i_s_innodb_buf_page_lru_fill_table" ); |
5814 | |
5815 | RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name.str); |
5816 | |
5817 | /* deny access to any users that do not hold PROCESS_ACL */ |
5818 | if (check_global_access(thd, PROCESS_ACL)) { |
5819 | DBUG_RETURN(0); |
5820 | } |
5821 | |
5822 | /* Walk through each buffer pool */ |
5823 | for (ulint i = 0; i < srv_buf_pool_instances; i++) { |
5824 | buf_pool_t* buf_pool; |
5825 | |
5826 | buf_pool = buf_pool_from_array(i); |
5827 | |
5828 | /* Fetch information from pages in this buffer pool's LRU list, |
5829 | and fill the corresponding I_S table */ |
5830 | status = i_s_innodb_fill_buffer_lru(thd, tables, buf_pool, i); |
5831 | |
5832 | /* If something wrong, break and return */ |
5833 | if (status) { |
5834 | break; |
5835 | } |
5836 | } |
5837 | |
5838 | DBUG_RETURN(status); |
5839 | } |
5840 | |
5841 | /*******************************************************************//** |
5842 | Bind the dynamic table INFORMATION_SCHEMA.INNODB_BUFFER_PAGE_LRU. |
5843 | @return 0 on success, 1 on failure */ |
5844 | static |
5845 | int |
5846 | i_s_innodb_buffer_page_lru_init( |
5847 | /*============================*/ |
5848 | void* p) /*!< in/out: table schema object */ |
5849 | { |
5850 | ST_SCHEMA_TABLE* schema; |
5851 | |
5852 | DBUG_ENTER("i_s_innodb_buffer_page_lru_init" ); |
5853 | |
5854 | schema = reinterpret_cast<ST_SCHEMA_TABLE*>(p); |
5855 | |
5856 | schema->fields_info = i_s_innodb_buf_page_lru_fields_info; |
5857 | schema->fill_table = i_s_innodb_buf_page_lru_fill_table; |
5858 | |
5859 | DBUG_RETURN(0); |
5860 | } |
5861 | |
5862 | UNIV_INTERN struct st_maria_plugin i_s_innodb_buffer_page_lru = |
5863 | { |
5864 | /* the plugin type (a MYSQL_XXX_PLUGIN value) */ |
5865 | /* int */ |
5866 | STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN), |
5867 | |
5868 | /* pointer to type-specific plugin descriptor */ |
5869 | /* void* */ |
5870 | STRUCT_FLD(info, &i_s_info), |
5871 | |
5872 | /* plugin name */ |
5873 | /* const char* */ |
5874 | STRUCT_FLD(name, "INNODB_BUFFER_PAGE_LRU" ), |
5875 | |
5876 | /* plugin author (for SHOW PLUGINS) */ |
5877 | /* const char* */ |
5878 | STRUCT_FLD(author, plugin_author), |
5879 | |
5880 | /* general descriptive text (for SHOW PLUGINS) */ |
5881 | /* const char* */ |
5882 | STRUCT_FLD(descr, "InnoDB Buffer Page in LRU" ), |
5883 | |
5884 | /* the plugin license (PLUGIN_LICENSE_XXX) */ |
5885 | /* int */ |
5886 | STRUCT_FLD(license, PLUGIN_LICENSE_GPL), |
5887 | |
5888 | /* the function to invoke when plugin is loaded */ |
5889 | /* int (*)(void*); */ |
5890 | STRUCT_FLD(init, i_s_innodb_buffer_page_lru_init), |
5891 | |
5892 | /* the function to invoke when plugin is unloaded */ |
5893 | /* int (*)(void*); */ |
5894 | STRUCT_FLD(deinit, i_s_common_deinit), |
5895 | |
5896 | /* plugin version (for SHOW PLUGINS) */ |
5897 | /* unsigned int */ |
5898 | STRUCT_FLD(version, INNODB_VERSION_SHORT), |
5899 | |
5900 | /* struct st_mysql_show_var* */ |
5901 | STRUCT_FLD(status_vars, NULL), |
5902 | |
5903 | /* struct st_mysql_sys_var** */ |
5904 | STRUCT_FLD(system_vars, NULL), |
5905 | |
5906 | /* Maria extension */ |
5907 | STRUCT_FLD(version_info, INNODB_VERSION_STR), |
5908 | STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE), |
5909 | }; |
5910 | |
5911 | /*******************************************************************//** |
5912 | Unbind a dynamic INFORMATION_SCHEMA table. |
5913 | @return 0 */ |
5914 | static int i_s_common_deinit(void*) |
5915 | { |
5916 | DBUG_ENTER("i_s_common_deinit" ); |
5917 | |
5918 | /* Do nothing */ |
5919 | |
5920 | DBUG_RETURN(0); |
5921 | } |
5922 | |
5923 | /** SYS_TABLES ***************************************************/ |
5924 | /* Fields of the dynamic table INFORMATION_SCHEMA.SYS_TABLES */ |
5925 | static ST_FIELD_INFO innodb_sys_tables_fields_info[] = |
5926 | { |
5927 | #define SYS_TABLES_ID 0 |
5928 | {STRUCT_FLD(field_name, "TABLE_ID" ), |
5929 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
5930 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
5931 | STRUCT_FLD(value, 0), |
5932 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
5933 | STRUCT_FLD(old_name, "" ), |
5934 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
5935 | |
5936 | #define SYS_TABLES_NAME 1 |
5937 | {STRUCT_FLD(field_name, "NAME" ), |
5938 | STRUCT_FLD(field_length, MAX_FULL_NAME_LEN + 1), |
5939 | STRUCT_FLD(field_type, MYSQL_TYPE_STRING), |
5940 | STRUCT_FLD(value, 0), |
5941 | STRUCT_FLD(field_flags, 0), |
5942 | STRUCT_FLD(old_name, "" ), |
5943 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
5944 | |
5945 | #define SYS_TABLES_FLAG 2 |
5946 | {STRUCT_FLD(field_name, "FLAG" ), |
5947 | STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS), |
5948 | STRUCT_FLD(field_type, MYSQL_TYPE_LONG), |
5949 | STRUCT_FLD(value, 0), |
5950 | STRUCT_FLD(field_flags, 0), |
5951 | STRUCT_FLD(old_name, "" ), |
5952 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
5953 | |
5954 | #define SYS_TABLES_NUM_COLUMN 3 |
5955 | {STRUCT_FLD(field_name, "N_COLS" ), |
5956 | STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS), |
5957 | STRUCT_FLD(field_type, MYSQL_TYPE_LONG), |
5958 | STRUCT_FLD(value, 0), |
5959 | STRUCT_FLD(field_flags, 0), |
5960 | STRUCT_FLD(old_name, "" ), |
5961 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
5962 | |
5963 | #define SYS_TABLES_SPACE 4 |
5964 | {STRUCT_FLD(field_name, "SPACE" ), |
5965 | STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS), |
5966 | STRUCT_FLD(field_type, MYSQL_TYPE_LONG), |
5967 | STRUCT_FLD(value, 0), |
5968 | STRUCT_FLD(field_flags, 0), |
5969 | STRUCT_FLD(old_name, "" ), |
5970 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
5971 | |
5972 | #define SYS_TABLES_ROW_FORMAT 5 |
5973 | {STRUCT_FLD(field_name, "ROW_FORMAT" ), |
5974 | STRUCT_FLD(field_length, 12), |
5975 | STRUCT_FLD(field_type, MYSQL_TYPE_STRING), |
5976 | STRUCT_FLD(value, 0), |
5977 | STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL), |
5978 | STRUCT_FLD(old_name, "" ), |
5979 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
5980 | |
5981 | #define SYS_TABLES_ZIP_PAGE_SIZE 6 |
5982 | {STRUCT_FLD(field_name, "ZIP_PAGE_SIZE" ), |
5983 | STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS), |
5984 | STRUCT_FLD(field_type, MYSQL_TYPE_LONG), |
5985 | STRUCT_FLD(value, 0), |
5986 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
5987 | STRUCT_FLD(old_name, "" ), |
5988 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
5989 | |
5990 | #define SYS_TABLES_SPACE_TYPE 7 |
5991 | {STRUCT_FLD(field_name, "SPACE_TYPE" ), |
5992 | STRUCT_FLD(field_length, 10), |
5993 | STRUCT_FLD(field_type, MYSQL_TYPE_STRING), |
5994 | STRUCT_FLD(value, 0), |
5995 | STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL), |
5996 | STRUCT_FLD(old_name, "" ), |
5997 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
5998 | |
5999 | END_OF_ST_FIELD_INFO |
6000 | }; |
6001 | |
6002 | /**********************************************************************//** |
6003 | Populate information_schema.innodb_sys_tables table with information |
6004 | from SYS_TABLES. |
6005 | @return 0 on success */ |
6006 | static |
6007 | int |
6008 | i_s_dict_fill_sys_tables( |
6009 | /*=====================*/ |
6010 | THD* thd, /*!< in: thread */ |
6011 | dict_table_t* table, /*!< in: table */ |
6012 | TABLE* table_to_fill) /*!< in/out: fill this table */ |
6013 | { |
6014 | Field** fields; |
6015 | ulint compact = DICT_TF_GET_COMPACT(table->flags); |
6016 | ulint atomic_blobs = DICT_TF_HAS_ATOMIC_BLOBS( |
6017 | table->flags); |
6018 | const page_size_t& page_size = dict_tf_get_page_size(table->flags); |
6019 | const char* row_format; |
6020 | |
6021 | if (!compact) { |
6022 | row_format = "Redundant" ; |
6023 | } else if (!atomic_blobs) { |
6024 | row_format = "Compact" ; |
6025 | } else if (DICT_TF_GET_ZIP_SSIZE(table->flags)) { |
6026 | row_format = "Compressed" ; |
6027 | } else { |
6028 | row_format = "Dynamic" ; |
6029 | } |
6030 | |
6031 | DBUG_ENTER("i_s_dict_fill_sys_tables" ); |
6032 | |
6033 | fields = table_to_fill->field; |
6034 | |
6035 | OK(fields[SYS_TABLES_ID]->store(longlong(table->id), TRUE)); |
6036 | |
6037 | OK(field_store_string(fields[SYS_TABLES_NAME], table->name.m_name)); |
6038 | |
6039 | OK(fields[SYS_TABLES_FLAG]->store(table->flags)); |
6040 | |
6041 | OK(fields[SYS_TABLES_NUM_COLUMN]->store(table->n_cols)); |
6042 | |
6043 | OK(fields[SYS_TABLES_SPACE]->store(table->space_id, true)); |
6044 | |
6045 | OK(field_store_string(fields[SYS_TABLES_ROW_FORMAT], row_format)); |
6046 | |
6047 | OK(fields[SYS_TABLES_ZIP_PAGE_SIZE]->store( |
6048 | page_size.is_compressed() |
6049 | ? page_size.physical() |
6050 | : 0, true)); |
6051 | |
6052 | OK(field_store_string(fields[SYS_TABLES_SPACE_TYPE], |
6053 | table->space_id ? "Single" : "System" )); |
6054 | |
6055 | OK(schema_table_store_record(thd, table_to_fill)); |
6056 | |
6057 | DBUG_RETURN(0); |
6058 | } |
6059 | /*******************************************************************//** |
6060 | Function to go through each record in SYS_TABLES table, and fill the |
6061 | information_schema.innodb_sys_tables table with related table information |
6062 | @return 0 on success */ |
6063 | static |
6064 | int |
6065 | i_s_sys_tables_fill_table( |
6066 | /*======================*/ |
6067 | THD* thd, /*!< in: thread */ |
6068 | TABLE_LIST* tables, /*!< in/out: tables to fill */ |
6069 | Item* ) /*!< in: condition (not used) */ |
6070 | { |
6071 | btr_pcur_t pcur; |
6072 | const rec_t* rec; |
6073 | mem_heap_t* heap; |
6074 | mtr_t mtr; |
6075 | |
6076 | DBUG_ENTER("i_s_sys_tables_fill_table" ); |
6077 | RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name.str); |
6078 | |
6079 | /* deny access to user without PROCESS_ACL privilege */ |
6080 | if (check_global_access(thd, PROCESS_ACL)) { |
6081 | DBUG_RETURN(0); |
6082 | } |
6083 | |
6084 | heap = mem_heap_create(1000); |
6085 | mutex_enter(&dict_sys->mutex); |
6086 | mtr_start(&mtr); |
6087 | |
6088 | rec = dict_startscan_system(&pcur, &mtr, SYS_TABLES); |
6089 | |
6090 | while (rec) { |
6091 | const char* err_msg; |
6092 | dict_table_t* table_rec; |
6093 | |
6094 | /* Create and populate a dict_table_t structure with |
6095 | information from SYS_TABLES row */ |
6096 | err_msg = dict_process_sys_tables_rec_and_mtr_commit( |
6097 | heap, rec, &table_rec, false, &mtr); |
6098 | |
6099 | mutex_exit(&dict_sys->mutex); |
6100 | |
6101 | if (!err_msg) { |
6102 | i_s_dict_fill_sys_tables(thd, table_rec, |
6103 | tables->table); |
6104 | } else { |
6105 | push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, |
6106 | ER_CANT_FIND_SYSTEM_REC, "%s" , |
6107 | err_msg); |
6108 | } |
6109 | |
6110 | if (table_rec) { |
6111 | dict_mem_table_free(table_rec); |
6112 | } |
6113 | |
6114 | mem_heap_empty(heap); |
6115 | |
6116 | /* Get the next record */ |
6117 | mutex_enter(&dict_sys->mutex); |
6118 | mtr_start(&mtr); |
6119 | rec = dict_getnext_system(&pcur, &mtr); |
6120 | } |
6121 | |
6122 | mtr_commit(&mtr); |
6123 | mutex_exit(&dict_sys->mutex); |
6124 | mem_heap_free(heap); |
6125 | |
6126 | DBUG_RETURN(0); |
6127 | } |
6128 | |
6129 | /*******************************************************************//** |
6130 | Bind the dynamic table INFORMATION_SCHEMA.innodb_sys_tables |
6131 | @return 0 on success */ |
6132 | static |
6133 | int |
6134 | innodb_sys_tables_init( |
6135 | /*===================*/ |
6136 | void* p) /*!< in/out: table schema object */ |
6137 | { |
6138 | ST_SCHEMA_TABLE* schema; |
6139 | |
6140 | DBUG_ENTER("innodb_sys_tables_init" ); |
6141 | |
6142 | schema = (ST_SCHEMA_TABLE*) p; |
6143 | |
6144 | schema->fields_info = innodb_sys_tables_fields_info; |
6145 | schema->fill_table = i_s_sys_tables_fill_table; |
6146 | |
6147 | DBUG_RETURN(0); |
6148 | } |
6149 | |
6150 | UNIV_INTERN struct st_maria_plugin i_s_innodb_sys_tables = |
6151 | { |
6152 | /* the plugin type (a MYSQL_XXX_PLUGIN value) */ |
6153 | /* int */ |
6154 | STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN), |
6155 | |
6156 | /* pointer to type-specific plugin descriptor */ |
6157 | /* void* */ |
6158 | STRUCT_FLD(info, &i_s_info), |
6159 | |
6160 | /* plugin name */ |
6161 | /* const char* */ |
6162 | STRUCT_FLD(name, "INNODB_SYS_TABLES" ), |
6163 | |
6164 | /* plugin author (for SHOW PLUGINS) */ |
6165 | /* const char* */ |
6166 | STRUCT_FLD(author, plugin_author), |
6167 | |
6168 | /* general descriptive text (for SHOW PLUGINS) */ |
6169 | /* const char* */ |
6170 | STRUCT_FLD(descr, "InnoDB SYS_TABLES" ), |
6171 | |
6172 | /* the plugin license (PLUGIN_LICENSE_XXX) */ |
6173 | /* int */ |
6174 | STRUCT_FLD(license, PLUGIN_LICENSE_GPL), |
6175 | |
6176 | /* the function to invoke when plugin is loaded */ |
6177 | /* int (*)(void*); */ |
6178 | STRUCT_FLD(init, innodb_sys_tables_init), |
6179 | |
6180 | /* the function to invoke when plugin is unloaded */ |
6181 | /* int (*)(void*); */ |
6182 | STRUCT_FLD(deinit, i_s_common_deinit), |
6183 | |
6184 | /* plugin version (for SHOW PLUGINS) */ |
6185 | /* unsigned int */ |
6186 | STRUCT_FLD(version, INNODB_VERSION_SHORT), |
6187 | |
6188 | /* struct st_mysql_show_var* */ |
6189 | STRUCT_FLD(status_vars, NULL), |
6190 | |
6191 | /* struct st_mysql_sys_var** */ |
6192 | STRUCT_FLD(system_vars, NULL), |
6193 | |
6194 | /* Maria extension */ |
6195 | STRUCT_FLD(version_info, INNODB_VERSION_STR), |
6196 | STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE), |
6197 | }; |
6198 | |
6199 | /** SYS_TABLESTATS ***********************************************/ |
6200 | /* Fields of the dynamic table INFORMATION_SCHEMA.SYS_TABLESTATS */ |
6201 | static ST_FIELD_INFO innodb_sys_tablestats_fields_info[] = |
6202 | { |
6203 | #define SYS_TABLESTATS_ID 0 |
6204 | {STRUCT_FLD(field_name, "TABLE_ID" ), |
6205 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
6206 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
6207 | STRUCT_FLD(value, 0), |
6208 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
6209 | STRUCT_FLD(old_name, "" ), |
6210 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
6211 | |
6212 | #define SYS_TABLESTATS_NAME 1 |
6213 | {STRUCT_FLD(field_name, "NAME" ), |
6214 | STRUCT_FLD(field_length, NAME_LEN + 1), |
6215 | STRUCT_FLD(field_type, MYSQL_TYPE_STRING), |
6216 | STRUCT_FLD(value, 0), |
6217 | STRUCT_FLD(field_flags, 0), |
6218 | STRUCT_FLD(old_name, "" ), |
6219 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
6220 | |
6221 | #define SYS_TABLESTATS_INIT 2 |
6222 | {STRUCT_FLD(field_name, "STATS_INITIALIZED" ), |
6223 | STRUCT_FLD(field_length, NAME_LEN + 1), |
6224 | STRUCT_FLD(field_type, MYSQL_TYPE_STRING), |
6225 | STRUCT_FLD(value, 0), |
6226 | STRUCT_FLD(field_flags, 0), |
6227 | STRUCT_FLD(old_name, "" ), |
6228 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
6229 | |
6230 | #define SYS_TABLESTATS_NROW 3 |
6231 | {STRUCT_FLD(field_name, "NUM_ROWS" ), |
6232 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
6233 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
6234 | STRUCT_FLD(value, 0), |
6235 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
6236 | STRUCT_FLD(old_name, "" ), |
6237 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
6238 | |
6239 | #define SYS_TABLESTATS_CLUST_SIZE 4 |
6240 | {STRUCT_FLD(field_name, "CLUST_INDEX_SIZE" ), |
6241 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
6242 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
6243 | STRUCT_FLD(value, 0), |
6244 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
6245 | STRUCT_FLD(old_name, "" ), |
6246 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
6247 | |
6248 | #define SYS_TABLESTATS_INDEX_SIZE 5 |
6249 | {STRUCT_FLD(field_name, "OTHER_INDEX_SIZE" ), |
6250 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
6251 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
6252 | STRUCT_FLD(value, 0), |
6253 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
6254 | STRUCT_FLD(old_name, "" ), |
6255 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
6256 | |
6257 | #define SYS_TABLESTATS_MODIFIED 6 |
6258 | {STRUCT_FLD(field_name, "MODIFIED_COUNTER" ), |
6259 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
6260 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
6261 | STRUCT_FLD(value, 0), |
6262 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
6263 | STRUCT_FLD(old_name, "" ), |
6264 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
6265 | |
6266 | #define SYS_TABLESTATS_AUTONINC 7 |
6267 | {STRUCT_FLD(field_name, "AUTOINC" ), |
6268 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
6269 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
6270 | STRUCT_FLD(value, 0), |
6271 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
6272 | STRUCT_FLD(old_name, "" ), |
6273 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
6274 | |
6275 | #define SYS_TABLESTATS_TABLE_REF_COUNT 8 |
6276 | {STRUCT_FLD(field_name, "REF_COUNT" ), |
6277 | STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS), |
6278 | STRUCT_FLD(field_type, MYSQL_TYPE_LONG), |
6279 | STRUCT_FLD(value, 0), |
6280 | STRUCT_FLD(field_flags, 0), |
6281 | STRUCT_FLD(old_name, "" ), |
6282 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
6283 | |
6284 | END_OF_ST_FIELD_INFO |
6285 | }; |
6286 | |
6287 | /** Populate information_schema.innodb_sys_tablestats table with information |
6288 | from SYS_TABLES. |
6289 | @param[in] thd thread ID |
6290 | @param[in,out] table table |
6291 | @param[in] ref_count table reference count |
6292 | @param[in,out] table_to_fill fill this table |
6293 | @return 0 on success */ |
6294 | static |
6295 | int |
6296 | i_s_dict_fill_sys_tablestats( |
6297 | THD* thd, |
6298 | dict_table_t* table, |
6299 | ulint ref_count, |
6300 | TABLE* table_to_fill) |
6301 | { |
6302 | Field** fields; |
6303 | |
6304 | DBUG_ENTER("i_s_dict_fill_sys_tablestats" ); |
6305 | |
6306 | fields = table_to_fill->field; |
6307 | |
6308 | OK(fields[SYS_TABLESTATS_ID]->store(longlong(table->id), TRUE)); |
6309 | |
6310 | OK(field_store_string(fields[SYS_TABLESTATS_NAME], |
6311 | table->name.m_name)); |
6312 | |
6313 | dict_table_stats_lock(table, RW_S_LATCH); |
6314 | |
6315 | if (table->stat_initialized) { |
6316 | OK(field_store_string(fields[SYS_TABLESTATS_INIT], |
6317 | "Initialized" )); |
6318 | |
6319 | OK(fields[SYS_TABLESTATS_NROW]->store(table->stat_n_rows, |
6320 | true)); |
6321 | |
6322 | OK(fields[SYS_TABLESTATS_CLUST_SIZE]->store( |
6323 | table->stat_clustered_index_size, true)); |
6324 | |
6325 | OK(fields[SYS_TABLESTATS_INDEX_SIZE]->store( |
6326 | table->stat_sum_of_other_index_sizes, true)); |
6327 | |
6328 | OK(fields[SYS_TABLESTATS_MODIFIED]->store( |
6329 | table->stat_modified_counter, true)); |
6330 | } else { |
6331 | OK(field_store_string(fields[SYS_TABLESTATS_INIT], |
6332 | "Uninitialized" )); |
6333 | |
6334 | OK(fields[SYS_TABLESTATS_NROW]->store(0, true)); |
6335 | |
6336 | OK(fields[SYS_TABLESTATS_CLUST_SIZE]->store(0, true)); |
6337 | |
6338 | OK(fields[SYS_TABLESTATS_INDEX_SIZE]->store(0, true)); |
6339 | |
6340 | OK(fields[SYS_TABLESTATS_MODIFIED]->store(0, true)); |
6341 | } |
6342 | |
6343 | dict_table_stats_unlock(table, RW_S_LATCH); |
6344 | |
6345 | OK(fields[SYS_TABLESTATS_AUTONINC]->store(table->autoinc, true)); |
6346 | |
6347 | OK(fields[SYS_TABLESTATS_TABLE_REF_COUNT]->store(ref_count, true)); |
6348 | |
6349 | OK(schema_table_store_record(thd, table_to_fill)); |
6350 | |
6351 | DBUG_RETURN(0); |
6352 | } |
6353 | |
6354 | /*******************************************************************//** |
6355 | Function to go through each record in SYS_TABLES table, and fill the |
6356 | information_schema.innodb_sys_tablestats table with table statistics |
6357 | related information |
6358 | @return 0 on success */ |
6359 | static |
6360 | int |
6361 | i_s_sys_tables_fill_table_stats( |
6362 | /*============================*/ |
6363 | THD* thd, /*!< in: thread */ |
6364 | TABLE_LIST* tables, /*!< in/out: tables to fill */ |
6365 | Item* ) /*!< in: condition (not used) */ |
6366 | { |
6367 | btr_pcur_t pcur; |
6368 | const rec_t* rec; |
6369 | mem_heap_t* heap; |
6370 | mtr_t mtr; |
6371 | |
6372 | DBUG_ENTER("i_s_sys_tables_fill_table_stats" ); |
6373 | RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name.str); |
6374 | |
6375 | /* deny access to user without PROCESS_ACL privilege */ |
6376 | if (check_global_access(thd, PROCESS_ACL)) { |
6377 | DBUG_RETURN(0); |
6378 | } |
6379 | |
6380 | heap = mem_heap_create(1000); |
6381 | rw_lock_s_lock(dict_operation_lock); |
6382 | mutex_enter(&dict_sys->mutex); |
6383 | mtr_start(&mtr); |
6384 | |
6385 | rec = dict_startscan_system(&pcur, &mtr, SYS_TABLES); |
6386 | |
6387 | while (rec) { |
6388 | const char* err_msg; |
6389 | dict_table_t* table_rec; |
6390 | |
6391 | /* Fetch the dict_table_t structure corresponding to |
6392 | this SYS_TABLES record */ |
6393 | err_msg = dict_process_sys_tables_rec_and_mtr_commit( |
6394 | heap, rec, &table_rec, true, &mtr); |
6395 | |
6396 | ulint ref_count = table_rec ? table_rec->get_ref_count() : 0; |
6397 | mutex_exit(&dict_sys->mutex); |
6398 | |
6399 | DBUG_EXECUTE_IF("test_sys_tablestats" , { |
6400 | if (strcmp("test/t1" , table_rec->name.m_name) == 0 ) { |
6401 | DEBUG_SYNC_C("dict_table_not_protected" ); |
6402 | }}); |
6403 | |
6404 | if (table_rec != NULL) { |
6405 | ut_ad(err_msg == NULL); |
6406 | i_s_dict_fill_sys_tablestats(thd, table_rec, ref_count, |
6407 | tables->table); |
6408 | } else { |
6409 | ut_ad(err_msg != NULL); |
6410 | push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, |
6411 | ER_CANT_FIND_SYSTEM_REC, "%s" , |
6412 | err_msg); |
6413 | } |
6414 | |
6415 | rw_lock_s_unlock(dict_operation_lock); |
6416 | mem_heap_empty(heap); |
6417 | |
6418 | /* Get the next record */ |
6419 | rw_lock_s_lock(dict_operation_lock); |
6420 | mutex_enter(&dict_sys->mutex); |
6421 | |
6422 | mtr_start(&mtr); |
6423 | rec = dict_getnext_system(&pcur, &mtr); |
6424 | } |
6425 | |
6426 | mtr_commit(&mtr); |
6427 | mutex_exit(&dict_sys->mutex); |
6428 | rw_lock_s_unlock(dict_operation_lock); |
6429 | mem_heap_free(heap); |
6430 | |
6431 | DBUG_RETURN(0); |
6432 | } |
6433 | |
6434 | /*******************************************************************//** |
6435 | Bind the dynamic table INFORMATION_SCHEMA.innodb_sys_tablestats |
6436 | @return 0 on success */ |
6437 | static |
6438 | int |
6439 | innodb_sys_tablestats_init( |
6440 | /*=======================*/ |
6441 | void* p) /*!< in/out: table schema object */ |
6442 | { |
6443 | ST_SCHEMA_TABLE* schema; |
6444 | |
6445 | DBUG_ENTER("innodb_sys_tablestats_init" ); |
6446 | |
6447 | schema = (ST_SCHEMA_TABLE*) p; |
6448 | |
6449 | schema->fields_info = innodb_sys_tablestats_fields_info; |
6450 | schema->fill_table = i_s_sys_tables_fill_table_stats; |
6451 | |
6452 | DBUG_RETURN(0); |
6453 | } |
6454 | |
6455 | UNIV_INTERN struct st_maria_plugin i_s_innodb_sys_tablestats = |
6456 | { |
6457 | /* the plugin type (a MYSQL_XXX_PLUGIN value) */ |
6458 | /* int */ |
6459 | STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN), |
6460 | |
6461 | /* pointer to type-specific plugin descriptor */ |
6462 | /* void* */ |
6463 | STRUCT_FLD(info, &i_s_info), |
6464 | |
6465 | /* plugin name */ |
6466 | /* const char* */ |
6467 | STRUCT_FLD(name, "INNODB_SYS_TABLESTATS" ), |
6468 | |
6469 | /* plugin author (for SHOW PLUGINS) */ |
6470 | /* const char* */ |
6471 | STRUCT_FLD(author, plugin_author), |
6472 | |
6473 | /* general descriptive text (for SHOW PLUGINS) */ |
6474 | /* const char* */ |
6475 | STRUCT_FLD(descr, "InnoDB SYS_TABLESTATS" ), |
6476 | |
6477 | /* the plugin license (PLUGIN_LICENSE_XXX) */ |
6478 | /* int */ |
6479 | STRUCT_FLD(license, PLUGIN_LICENSE_GPL), |
6480 | |
6481 | /* the function to invoke when plugin is loaded */ |
6482 | /* int (*)(void*); */ |
6483 | STRUCT_FLD(init, innodb_sys_tablestats_init), |
6484 | |
6485 | /* the function to invoke when plugin is unloaded */ |
6486 | /* int (*)(void*); */ |
6487 | STRUCT_FLD(deinit, i_s_common_deinit), |
6488 | |
6489 | /* plugin version (for SHOW PLUGINS) */ |
6490 | /* unsigned int */ |
6491 | STRUCT_FLD(version, INNODB_VERSION_SHORT), |
6492 | |
6493 | /* struct st_mysql_show_var* */ |
6494 | STRUCT_FLD(status_vars, NULL), |
6495 | |
6496 | /* struct st_mysql_sys_var** */ |
6497 | STRUCT_FLD(system_vars, NULL), |
6498 | |
6499 | /* Maria extension */ |
6500 | STRUCT_FLD(version_info, INNODB_VERSION_STR), |
6501 | STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE), |
6502 | }; |
6503 | |
6504 | /** SYS_INDEXES **************************************************/ |
6505 | /* Fields of the dynamic table INFORMATION_SCHEMA.SYS_INDEXES */ |
6506 | static ST_FIELD_INFO innodb_sysindex_fields_info[] = |
6507 | { |
6508 | #define SYS_INDEX_ID 0 |
6509 | {STRUCT_FLD(field_name, "INDEX_ID" ), |
6510 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
6511 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
6512 | STRUCT_FLD(value, 0), |
6513 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
6514 | STRUCT_FLD(old_name, "" ), |
6515 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
6516 | |
6517 | #define SYS_INDEX_NAME 1 |
6518 | {STRUCT_FLD(field_name, "NAME" ), |
6519 | STRUCT_FLD(field_length, NAME_LEN + 1), |
6520 | STRUCT_FLD(field_type, MYSQL_TYPE_STRING), |
6521 | STRUCT_FLD(value, 0), |
6522 | STRUCT_FLD(field_flags, 0), |
6523 | STRUCT_FLD(old_name, "" ), |
6524 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
6525 | |
6526 | #define SYS_INDEX_TABLE_ID 2 |
6527 | {STRUCT_FLD(field_name, "TABLE_ID" ), |
6528 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
6529 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
6530 | STRUCT_FLD(value, 0), |
6531 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
6532 | STRUCT_FLD(old_name, "" ), |
6533 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
6534 | |
6535 | #define SYS_INDEX_TYPE 3 |
6536 | {STRUCT_FLD(field_name, "TYPE" ), |
6537 | STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS), |
6538 | STRUCT_FLD(field_type, MYSQL_TYPE_LONG), |
6539 | STRUCT_FLD(value, 0), |
6540 | STRUCT_FLD(field_flags, 0), |
6541 | STRUCT_FLD(old_name, "" ), |
6542 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
6543 | |
6544 | #define SYS_INDEX_NUM_FIELDS 4 |
6545 | {STRUCT_FLD(field_name, "N_FIELDS" ), |
6546 | STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS), |
6547 | STRUCT_FLD(field_type, MYSQL_TYPE_LONG), |
6548 | STRUCT_FLD(value, 0), |
6549 | STRUCT_FLD(field_flags, 0), |
6550 | STRUCT_FLD(old_name, "" ), |
6551 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
6552 | |
6553 | #define SYS_INDEX_PAGE_NO 5 |
6554 | {STRUCT_FLD(field_name, "PAGE_NO" ), |
6555 | STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS), |
6556 | STRUCT_FLD(field_type, MYSQL_TYPE_LONG), |
6557 | STRUCT_FLD(value, 0), |
6558 | STRUCT_FLD(field_flags, 0), |
6559 | STRUCT_FLD(old_name, "" ), |
6560 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
6561 | |
6562 | #define SYS_INDEX_SPACE 6 |
6563 | {STRUCT_FLD(field_name, "SPACE" ), |
6564 | STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS), |
6565 | STRUCT_FLD(field_type, MYSQL_TYPE_LONG), |
6566 | STRUCT_FLD(value, 0), |
6567 | STRUCT_FLD(field_flags, 0), |
6568 | STRUCT_FLD(old_name, "" ), |
6569 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
6570 | |
6571 | #define SYS_INDEX_MERGE_THRESHOLD 7 |
6572 | {STRUCT_FLD(field_name, "MERGE_THRESHOLD" ), |
6573 | STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS), |
6574 | STRUCT_FLD(field_type, MYSQL_TYPE_LONG), |
6575 | STRUCT_FLD(value, 0), |
6576 | STRUCT_FLD(field_flags, 0), |
6577 | STRUCT_FLD(old_name, "" ), |
6578 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
6579 | |
6580 | END_OF_ST_FIELD_INFO |
6581 | }; |
6582 | |
6583 | /**********************************************************************//** |
6584 | Function to populate the information_schema.innodb_sys_indexes table with |
6585 | collected index information |
6586 | @return 0 on success */ |
6587 | static |
6588 | int |
6589 | i_s_dict_fill_sys_indexes( |
6590 | /*======================*/ |
6591 | THD* thd, /*!< in: thread */ |
6592 | table_id_t table_id, /*!< in: table id */ |
6593 | ulint space_id, /*!< in: tablespace id */ |
6594 | dict_index_t* index, /*!< in: populated dict_index_t |
6595 | struct with index info */ |
6596 | TABLE* table_to_fill) /*!< in/out: fill this table */ |
6597 | { |
6598 | Field** fields; |
6599 | |
6600 | DBUG_ENTER("i_s_dict_fill_sys_indexes" ); |
6601 | |
6602 | fields = table_to_fill->field; |
6603 | |
6604 | OK(field_store_index_name(fields[SYS_INDEX_NAME], index->name)); |
6605 | |
6606 | OK(fields[SYS_INDEX_ID]->store(longlong(index->id), true)); |
6607 | |
6608 | OK(fields[SYS_INDEX_TABLE_ID]->store(longlong(table_id), true)); |
6609 | |
6610 | OK(fields[SYS_INDEX_TYPE]->store(index->type, true)); |
6611 | |
6612 | OK(fields[SYS_INDEX_NUM_FIELDS]->store(index->n_fields)); |
6613 | |
6614 | /* FIL_NULL is ULINT32_UNDEFINED */ |
6615 | if (index->page == FIL_NULL) { |
6616 | fields[SYS_INDEX_PAGE_NO]->set_null(); |
6617 | } else { |
6618 | OK(fields[SYS_INDEX_PAGE_NO]->store(index->page, true)); |
6619 | } |
6620 | |
6621 | if (space_id == ULINT_UNDEFINED) { |
6622 | fields[SYS_INDEX_SPACE]->set_null(); |
6623 | } else { |
6624 | OK(fields[SYS_INDEX_SPACE]->store(space_id, true)); |
6625 | } |
6626 | |
6627 | OK(fields[SYS_INDEX_MERGE_THRESHOLD]->store(index->merge_threshold, |
6628 | true)); |
6629 | |
6630 | OK(schema_table_store_record(thd, table_to_fill)); |
6631 | |
6632 | DBUG_RETURN(0); |
6633 | } |
6634 | /*******************************************************************//** |
6635 | Function to go through each record in SYS_INDEXES table, and fill the |
6636 | information_schema.innodb_sys_indexes table with related index information |
6637 | @return 0 on success */ |
6638 | static |
6639 | int |
6640 | i_s_sys_indexes_fill_table( |
6641 | /*=======================*/ |
6642 | THD* thd, /*!< in: thread */ |
6643 | TABLE_LIST* tables, /*!< in/out: tables to fill */ |
6644 | Item* ) /*!< in: condition (not used) */ |
6645 | { |
6646 | btr_pcur_t pcur; |
6647 | const rec_t* rec; |
6648 | mem_heap_t* heap; |
6649 | mtr_t mtr; |
6650 | |
6651 | DBUG_ENTER("i_s_sys_indexes_fill_table" ); |
6652 | RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name.str); |
6653 | |
6654 | /* deny access to user without PROCESS_ACL privilege */ |
6655 | if (check_global_access(thd, PROCESS_ACL)) { |
6656 | DBUG_RETURN(0); |
6657 | } |
6658 | |
6659 | heap = mem_heap_create(1000); |
6660 | mutex_enter(&dict_sys->mutex); |
6661 | mtr_start(&mtr); |
6662 | |
6663 | /* Start scan the SYS_INDEXES table */ |
6664 | rec = dict_startscan_system(&pcur, &mtr, SYS_INDEXES); |
6665 | |
6666 | /* Process each record in the table */ |
6667 | while (rec) { |
6668 | const char* err_msg; |
6669 | table_id_t table_id; |
6670 | ulint space_id; |
6671 | dict_index_t index_rec; |
6672 | |
6673 | /* Populate a dict_index_t structure with information from |
6674 | a SYS_INDEXES row */ |
6675 | err_msg = dict_process_sys_indexes_rec(heap, rec, &index_rec, |
6676 | &table_id); |
6677 | const byte* field = rec_get_nth_field_old( |
6678 | rec, DICT_FLD__SYS_INDEXES__SPACE, &space_id); |
6679 | space_id = space_id == 4 ? mach_read_from_4(field) |
6680 | : ULINT_UNDEFINED; |
6681 | mtr_commit(&mtr); |
6682 | mutex_exit(&dict_sys->mutex); |
6683 | |
6684 | if (!err_msg) { |
6685 | if (int err = i_s_dict_fill_sys_indexes( |
6686 | thd, table_id, space_id, &index_rec, |
6687 | tables->table)) { |
6688 | mem_heap_free(heap); |
6689 | DBUG_RETURN(err); |
6690 | } |
6691 | } else { |
6692 | push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, |
6693 | ER_CANT_FIND_SYSTEM_REC, "%s" , |
6694 | err_msg); |
6695 | } |
6696 | |
6697 | mem_heap_empty(heap); |
6698 | |
6699 | /* Get the next record */ |
6700 | mutex_enter(&dict_sys->mutex); |
6701 | mtr_start(&mtr); |
6702 | rec = dict_getnext_system(&pcur, &mtr); |
6703 | } |
6704 | |
6705 | mtr_commit(&mtr); |
6706 | mutex_exit(&dict_sys->mutex); |
6707 | mem_heap_free(heap); |
6708 | |
6709 | DBUG_RETURN(0); |
6710 | } |
6711 | /*******************************************************************//** |
6712 | Bind the dynamic table INFORMATION_SCHEMA.innodb_sys_indexes |
6713 | @return 0 on success */ |
6714 | static |
6715 | int |
6716 | innodb_sys_indexes_init( |
6717 | /*====================*/ |
6718 | void* p) /*!< in/out: table schema object */ |
6719 | { |
6720 | ST_SCHEMA_TABLE* schema; |
6721 | |
6722 | DBUG_ENTER("innodb_sys_indexes_init" ); |
6723 | |
6724 | schema = (ST_SCHEMA_TABLE*) p; |
6725 | |
6726 | schema->fields_info = innodb_sysindex_fields_info; |
6727 | schema->fill_table = i_s_sys_indexes_fill_table; |
6728 | |
6729 | DBUG_RETURN(0); |
6730 | } |
6731 | |
6732 | UNIV_INTERN struct st_maria_plugin i_s_innodb_sys_indexes = |
6733 | { |
6734 | /* the plugin type (a MYSQL_XXX_PLUGIN value) */ |
6735 | /* int */ |
6736 | STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN), |
6737 | |
6738 | /* pointer to type-specific plugin descriptor */ |
6739 | /* void* */ |
6740 | STRUCT_FLD(info, &i_s_info), |
6741 | |
6742 | /* plugin name */ |
6743 | /* const char* */ |
6744 | STRUCT_FLD(name, "INNODB_SYS_INDEXES" ), |
6745 | |
6746 | /* plugin author (for SHOW PLUGINS) */ |
6747 | /* const char* */ |
6748 | STRUCT_FLD(author, plugin_author), |
6749 | |
6750 | /* general descriptive text (for SHOW PLUGINS) */ |
6751 | /* const char* */ |
6752 | STRUCT_FLD(descr, "InnoDB SYS_INDEXES" ), |
6753 | |
6754 | /* the plugin license (PLUGIN_LICENSE_XXX) */ |
6755 | /* int */ |
6756 | STRUCT_FLD(license, PLUGIN_LICENSE_GPL), |
6757 | |
6758 | /* the function to invoke when plugin is loaded */ |
6759 | /* int (*)(void*); */ |
6760 | STRUCT_FLD(init, innodb_sys_indexes_init), |
6761 | |
6762 | /* the function to invoke when plugin is unloaded */ |
6763 | /* int (*)(void*); */ |
6764 | STRUCT_FLD(deinit, i_s_common_deinit), |
6765 | |
6766 | /* plugin version (for SHOW PLUGINS) */ |
6767 | /* unsigned int */ |
6768 | STRUCT_FLD(version, INNODB_VERSION_SHORT), |
6769 | |
6770 | /* struct st_mysql_show_var* */ |
6771 | STRUCT_FLD(status_vars, NULL), |
6772 | |
6773 | /* struct st_mysql_sys_var** */ |
6774 | STRUCT_FLD(system_vars, NULL), |
6775 | |
6776 | /* Maria extension */ |
6777 | STRUCT_FLD(version_info, INNODB_VERSION_STR), |
6778 | STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE), |
6779 | }; |
6780 | |
6781 | /** SYS_COLUMNS **************************************************/ |
6782 | /* Fields of the dynamic table INFORMATION_SCHEMA.INNODB_SYS_COLUMNS */ |
6783 | static ST_FIELD_INFO innodb_sys_columns_fields_info[] = |
6784 | { |
6785 | #define SYS_COLUMN_TABLE_ID 0 |
6786 | {STRUCT_FLD(field_name, "TABLE_ID" ), |
6787 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
6788 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
6789 | STRUCT_FLD(value, 0), |
6790 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
6791 | STRUCT_FLD(old_name, "" ), |
6792 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
6793 | |
6794 | #define SYS_COLUMN_NAME 1 |
6795 | {STRUCT_FLD(field_name, "NAME" ), |
6796 | STRUCT_FLD(field_length, NAME_LEN + 1), |
6797 | STRUCT_FLD(field_type, MYSQL_TYPE_STRING), |
6798 | STRUCT_FLD(value, 0), |
6799 | STRUCT_FLD(field_flags, 0), |
6800 | STRUCT_FLD(old_name, "" ), |
6801 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
6802 | |
6803 | #define SYS_COLUMN_POSITION 2 |
6804 | {STRUCT_FLD(field_name, "POS" ), |
6805 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
6806 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
6807 | STRUCT_FLD(value, 0), |
6808 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
6809 | STRUCT_FLD(old_name, "" ), |
6810 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
6811 | |
6812 | #define SYS_COLUMN_MTYPE 3 |
6813 | {STRUCT_FLD(field_name, "MTYPE" ), |
6814 | STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS), |
6815 | STRUCT_FLD(field_type, MYSQL_TYPE_LONG), |
6816 | STRUCT_FLD(value, 0), |
6817 | STRUCT_FLD(field_flags, 0), |
6818 | STRUCT_FLD(old_name, "" ), |
6819 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
6820 | |
6821 | #define SYS_COLUMN__PRTYPE 4 |
6822 | {STRUCT_FLD(field_name, "PRTYPE" ), |
6823 | STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS), |
6824 | STRUCT_FLD(field_type, MYSQL_TYPE_LONG), |
6825 | STRUCT_FLD(value, 0), |
6826 | STRUCT_FLD(field_flags, 0), |
6827 | STRUCT_FLD(old_name, "" ), |
6828 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
6829 | |
6830 | #define SYS_COLUMN_COLUMN_LEN 5 |
6831 | {STRUCT_FLD(field_name, "LEN" ), |
6832 | STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS), |
6833 | STRUCT_FLD(field_type, MYSQL_TYPE_LONG), |
6834 | STRUCT_FLD(value, 0), |
6835 | STRUCT_FLD(field_flags, 0), |
6836 | STRUCT_FLD(old_name, "" ), |
6837 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
6838 | |
6839 | END_OF_ST_FIELD_INFO |
6840 | }; |
6841 | |
6842 | /**********************************************************************//** |
6843 | Function to populate the information_schema.innodb_sys_columns with |
6844 | related column information |
6845 | @return 0 on success */ |
6846 | static |
6847 | int |
6848 | i_s_dict_fill_sys_columns( |
6849 | /*======================*/ |
6850 | THD* thd, /*!< in: thread */ |
6851 | table_id_t table_id, /*!< in: table ID */ |
6852 | const char* col_name, /*!< in: column name */ |
6853 | dict_col_t* column, /*!< in: dict_col_t struct holding |
6854 | more column information */ |
6855 | ulint nth_v_col, /*!< in: virtual column, its |
6856 | sequence number (nth virtual col) */ |
6857 | TABLE* table_to_fill) /*!< in/out: fill this table */ |
6858 | { |
6859 | Field** fields; |
6860 | |
6861 | DBUG_ENTER("i_s_dict_fill_sys_columns" ); |
6862 | |
6863 | fields = table_to_fill->field; |
6864 | |
6865 | OK(fields[SYS_COLUMN_TABLE_ID]->store((longlong) table_id, TRUE)); |
6866 | |
6867 | OK(field_store_string(fields[SYS_COLUMN_NAME], col_name)); |
6868 | |
6869 | if (column->is_virtual()) { |
6870 | ulint pos = dict_create_v_col_pos(nth_v_col, column->ind); |
6871 | OK(fields[SYS_COLUMN_POSITION]->store(pos, true)); |
6872 | } else { |
6873 | OK(fields[SYS_COLUMN_POSITION]->store(column->ind, true)); |
6874 | } |
6875 | |
6876 | OK(fields[SYS_COLUMN_MTYPE]->store(column->mtype)); |
6877 | |
6878 | OK(fields[SYS_COLUMN__PRTYPE]->store(column->prtype)); |
6879 | |
6880 | OK(fields[SYS_COLUMN_COLUMN_LEN]->store(column->len)); |
6881 | |
6882 | OK(schema_table_store_record(thd, table_to_fill)); |
6883 | |
6884 | DBUG_RETURN(0); |
6885 | } |
6886 | /*******************************************************************//** |
6887 | Function to fill information_schema.innodb_sys_columns with information |
6888 | collected by scanning SYS_COLUMNS table. |
6889 | @return 0 on success */ |
6890 | static |
6891 | int |
6892 | i_s_sys_columns_fill_table( |
6893 | /*=======================*/ |
6894 | THD* thd, /*!< in: thread */ |
6895 | TABLE_LIST* tables, /*!< in/out: tables to fill */ |
6896 | Item* ) /*!< in: condition (not used) */ |
6897 | { |
6898 | btr_pcur_t pcur; |
6899 | const rec_t* rec; |
6900 | const char* col_name; |
6901 | mem_heap_t* heap; |
6902 | mtr_t mtr; |
6903 | |
6904 | DBUG_ENTER("i_s_sys_columns_fill_table" ); |
6905 | RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name.str); |
6906 | |
6907 | /* deny access to user without PROCESS_ACL privilege */ |
6908 | if (check_global_access(thd, PROCESS_ACL)) { |
6909 | DBUG_RETURN(0); |
6910 | } |
6911 | |
6912 | heap = mem_heap_create(1000); |
6913 | mutex_enter(&dict_sys->mutex); |
6914 | mtr_start(&mtr); |
6915 | |
6916 | rec = dict_startscan_system(&pcur, &mtr, SYS_COLUMNS); |
6917 | |
6918 | while (rec) { |
6919 | const char* err_msg; |
6920 | dict_col_t column_rec; |
6921 | table_id_t table_id; |
6922 | ulint nth_v_col; |
6923 | |
6924 | /* populate a dict_col_t structure with information from |
6925 | a SYS_COLUMNS row */ |
6926 | err_msg = dict_process_sys_columns_rec(heap, rec, &column_rec, |
6927 | &table_id, &col_name, |
6928 | &nth_v_col); |
6929 | |
6930 | mtr_commit(&mtr); |
6931 | mutex_exit(&dict_sys->mutex); |
6932 | |
6933 | if (!err_msg) { |
6934 | i_s_dict_fill_sys_columns(thd, table_id, col_name, |
6935 | &column_rec, nth_v_col, |
6936 | tables->table); |
6937 | } else { |
6938 | push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, |
6939 | ER_CANT_FIND_SYSTEM_REC, "%s" , |
6940 | err_msg); |
6941 | } |
6942 | |
6943 | mem_heap_empty(heap); |
6944 | |
6945 | /* Get the next record */ |
6946 | mutex_enter(&dict_sys->mutex); |
6947 | mtr_start(&mtr); |
6948 | rec = dict_getnext_system(&pcur, &mtr); |
6949 | } |
6950 | |
6951 | mtr_commit(&mtr); |
6952 | mutex_exit(&dict_sys->mutex); |
6953 | mem_heap_free(heap); |
6954 | |
6955 | DBUG_RETURN(0); |
6956 | } |
6957 | /*******************************************************************//** |
6958 | Bind the dynamic table INFORMATION_SCHEMA.innodb_sys_columns |
6959 | @return 0 on success */ |
6960 | static |
6961 | int |
6962 | innodb_sys_columns_init( |
6963 | /*====================*/ |
6964 | void* p) /*!< in/out: table schema object */ |
6965 | { |
6966 | ST_SCHEMA_TABLE* schema; |
6967 | |
6968 | DBUG_ENTER("innodb_sys_columns_init" ); |
6969 | |
6970 | schema = (ST_SCHEMA_TABLE*) p; |
6971 | |
6972 | schema->fields_info = innodb_sys_columns_fields_info; |
6973 | schema->fill_table = i_s_sys_columns_fill_table; |
6974 | |
6975 | DBUG_RETURN(0); |
6976 | } |
6977 | |
6978 | UNIV_INTERN struct st_maria_plugin i_s_innodb_sys_columns = |
6979 | { |
6980 | /* the plugin type (a MYSQL_XXX_PLUGIN value) */ |
6981 | /* int */ |
6982 | STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN), |
6983 | |
6984 | /* pointer to type-specific plugin descriptor */ |
6985 | /* void* */ |
6986 | STRUCT_FLD(info, &i_s_info), |
6987 | |
6988 | /* plugin name */ |
6989 | /* const char* */ |
6990 | STRUCT_FLD(name, "INNODB_SYS_COLUMNS" ), |
6991 | |
6992 | /* plugin author (for SHOW PLUGINS) */ |
6993 | /* const char* */ |
6994 | STRUCT_FLD(author, plugin_author), |
6995 | |
6996 | /* general descriptive text (for SHOW PLUGINS) */ |
6997 | /* const char* */ |
6998 | STRUCT_FLD(descr, "InnoDB SYS_COLUMNS" ), |
6999 | |
7000 | /* the plugin license (PLUGIN_LICENSE_XXX) */ |
7001 | /* int */ |
7002 | STRUCT_FLD(license, PLUGIN_LICENSE_GPL), |
7003 | |
7004 | /* the function to invoke when plugin is loaded */ |
7005 | /* int (*)(void*); */ |
7006 | STRUCT_FLD(init, innodb_sys_columns_init), |
7007 | |
7008 | /* the function to invoke when plugin is unloaded */ |
7009 | /* int (*)(void*); */ |
7010 | STRUCT_FLD(deinit, i_s_common_deinit), |
7011 | |
7012 | /* plugin version (for SHOW PLUGINS) */ |
7013 | /* unsigned int */ |
7014 | STRUCT_FLD(version, INNODB_VERSION_SHORT), |
7015 | |
7016 | /* struct st_mysql_show_var* */ |
7017 | STRUCT_FLD(status_vars, NULL), |
7018 | |
7019 | /* struct st_mysql_sys_var** */ |
7020 | STRUCT_FLD(system_vars, NULL), |
7021 | |
7022 | /* Maria extension */ |
7023 | STRUCT_FLD(version_info, INNODB_VERSION_STR), |
7024 | STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE), |
7025 | }; |
7026 | |
7027 | /** SYS_VIRTUAL **************************************************/ |
7028 | /** Fields of the dynamic table INFORMATION_SCHEMA.INNODB_SYS_VIRTUAL */ |
7029 | static ST_FIELD_INFO innodb_sys_virtual_fields_info[] = |
7030 | { |
7031 | #define SYS_VIRTUAL_TABLE_ID 0 |
7032 | {STRUCT_FLD(field_name, "TABLE_ID" ), |
7033 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
7034 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
7035 | STRUCT_FLD(value, 0), |
7036 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
7037 | STRUCT_FLD(old_name, "" ), |
7038 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
7039 | |
7040 | #define SYS_VIRTUAL_POS 1 |
7041 | {STRUCT_FLD(field_name, "POS" ), |
7042 | STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS), |
7043 | STRUCT_FLD(field_type, MYSQL_TYPE_LONG), |
7044 | STRUCT_FLD(value, 0), |
7045 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
7046 | STRUCT_FLD(old_name, "" ), |
7047 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
7048 | |
7049 | #define SYS_VIRTUAL_BASE_POS 2 |
7050 | {STRUCT_FLD(field_name, "BASE_POS" ), |
7051 | STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS), |
7052 | STRUCT_FLD(field_type, MYSQL_TYPE_LONG), |
7053 | STRUCT_FLD(value, 0), |
7054 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
7055 | STRUCT_FLD(old_name, "" ), |
7056 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
7057 | |
7058 | END_OF_ST_FIELD_INFO |
7059 | }; |
7060 | |
7061 | /** Function to populate the information_schema.innodb_sys_virtual with |
7062 | related information |
7063 | param[in] thd thread |
7064 | param[in] table_id table ID |
7065 | param[in] pos virtual column position |
7066 | param[in] base_pos base column position |
7067 | param[in,out] table_to_fill fill this table |
7068 | @return 0 on success */ |
7069 | static |
7070 | int |
7071 | i_s_dict_fill_sys_virtual( |
7072 | THD* thd, |
7073 | table_id_t table_id, |
7074 | ulint pos, |
7075 | ulint base_pos, |
7076 | TABLE* table_to_fill) |
7077 | { |
7078 | Field** fields; |
7079 | |
7080 | DBUG_ENTER("i_s_dict_fill_sys_virtual" ); |
7081 | |
7082 | fields = table_to_fill->field; |
7083 | |
7084 | OK(fields[SYS_VIRTUAL_TABLE_ID]->store(table_id, true)); |
7085 | |
7086 | OK(fields[SYS_VIRTUAL_POS]->store(pos, true)); |
7087 | |
7088 | OK(fields[SYS_VIRTUAL_BASE_POS]->store(base_pos, true)); |
7089 | |
7090 | OK(schema_table_store_record(thd, table_to_fill)); |
7091 | |
7092 | DBUG_RETURN(0); |
7093 | } |
7094 | |
7095 | /** Function to fill information_schema.innodb_sys_virtual with information |
7096 | collected by scanning SYS_VIRTUAL table. |
7097 | param[in] thd thread |
7098 | param[in,out] tables tables to fill |
7099 | param[in] item condition (not used) |
7100 | @return 0 on success */ |
7101 | static |
7102 | int |
7103 | i_s_sys_virtual_fill_table( |
7104 | THD* thd, |
7105 | TABLE_LIST* tables, |
7106 | Item* ) |
7107 | { |
7108 | btr_pcur_t pcur; |
7109 | const rec_t* rec; |
7110 | ulint pos; |
7111 | ulint base_pos; |
7112 | mtr_t mtr; |
7113 | |
7114 | DBUG_ENTER("i_s_sys_virtual_fill_table" ); |
7115 | RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name.str); |
7116 | |
7117 | /* deny access to user without PROCESS_ACL privilege */ |
7118 | if (check_global_access(thd, PROCESS_ACL)) { |
7119 | DBUG_RETURN(0); |
7120 | } |
7121 | |
7122 | mutex_enter(&dict_sys->mutex); |
7123 | mtr_start(&mtr); |
7124 | |
7125 | rec = dict_startscan_system(&pcur, &mtr, SYS_VIRTUAL); |
7126 | |
7127 | while (rec) { |
7128 | const char* err_msg; |
7129 | table_id_t table_id; |
7130 | |
7131 | /* populate a dict_col_t structure with information from |
7132 | a SYS_VIRTUAL row */ |
7133 | err_msg = dict_process_sys_virtual_rec(rec, |
7134 | &table_id, &pos, |
7135 | &base_pos); |
7136 | |
7137 | mtr_commit(&mtr); |
7138 | mutex_exit(&dict_sys->mutex); |
7139 | |
7140 | if (!err_msg) { |
7141 | i_s_dict_fill_sys_virtual(thd, table_id, pos, base_pos, |
7142 | tables->table); |
7143 | } else { |
7144 | push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, |
7145 | ER_CANT_FIND_SYSTEM_REC, "%s" , |
7146 | err_msg); |
7147 | } |
7148 | |
7149 | /* Get the next record */ |
7150 | mutex_enter(&dict_sys->mutex); |
7151 | mtr_start(&mtr); |
7152 | rec = dict_getnext_system(&pcur, &mtr); |
7153 | } |
7154 | |
7155 | mtr_commit(&mtr); |
7156 | mutex_exit(&dict_sys->mutex); |
7157 | |
7158 | DBUG_RETURN(0); |
7159 | } |
7160 | |
7161 | /** Bind the dynamic table INFORMATION_SCHEMA.innodb_sys_virtual |
7162 | param[in,out] p table schema object |
7163 | @return 0 on success */ |
7164 | static |
7165 | int |
7166 | innodb_sys_virtual_init( |
7167 | void* p) |
7168 | { |
7169 | ST_SCHEMA_TABLE* schema; |
7170 | |
7171 | DBUG_ENTER("innodb_sys_virtual_init" ); |
7172 | |
7173 | schema = (ST_SCHEMA_TABLE*) p; |
7174 | |
7175 | schema->fields_info = innodb_sys_virtual_fields_info; |
7176 | schema->fill_table = i_s_sys_virtual_fill_table; |
7177 | |
7178 | DBUG_RETURN(0); |
7179 | } |
7180 | |
7181 | struct st_maria_plugin i_s_innodb_sys_virtual = |
7182 | { |
7183 | /* the plugin type (a MYSQL_XXX_PLUGIN value) */ |
7184 | /* int */ |
7185 | STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN), |
7186 | |
7187 | /* pointer to type-specific plugin descriptor */ |
7188 | /* void* */ |
7189 | STRUCT_FLD(info, &i_s_info), |
7190 | |
7191 | /* plugin name */ |
7192 | /* const char* */ |
7193 | STRUCT_FLD(name, "INNODB_SYS_VIRTUAL" ), |
7194 | |
7195 | /* plugin author (for SHOW PLUGINS) */ |
7196 | /* const char* */ |
7197 | STRUCT_FLD(author, plugin_author), |
7198 | |
7199 | /* general descriptive text (for SHOW PLUGINS) */ |
7200 | /* const char* */ |
7201 | STRUCT_FLD(descr, "InnoDB SYS_VIRTUAL" ), |
7202 | |
7203 | /* the plugin license (PLUGIN_LICENSE_XXX) */ |
7204 | /* int */ |
7205 | STRUCT_FLD(license, PLUGIN_LICENSE_GPL), |
7206 | |
7207 | /* the function to invoke when plugin is loaded */ |
7208 | /* int (*)(void*); */ |
7209 | STRUCT_FLD(init, innodb_sys_virtual_init), |
7210 | |
7211 | /* the function to invoke when plugin is unloaded */ |
7212 | /* int (*)(void*); */ |
7213 | STRUCT_FLD(deinit, i_s_common_deinit), |
7214 | |
7215 | /* plugin version (for SHOW PLUGINS) */ |
7216 | /* unsigned int */ |
7217 | STRUCT_FLD(version, INNODB_VERSION_SHORT), |
7218 | |
7219 | /* struct st_mysql_show_var* */ |
7220 | STRUCT_FLD(status_vars, NULL), |
7221 | |
7222 | /* struct st_mysql_sys_var** */ |
7223 | STRUCT_FLD(system_vars, NULL), |
7224 | |
7225 | /* Maria extension */ |
7226 | STRUCT_FLD(version_info, INNODB_VERSION_STR), |
7227 | STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_BETA), |
7228 | }; |
7229 | /** SYS_FIELDS ***************************************************/ |
7230 | /* Fields of the dynamic table INFORMATION_SCHEMA.INNODB_SYS_FIELDS */ |
7231 | static ST_FIELD_INFO innodb_sys_fields_fields_info[] = |
7232 | { |
7233 | #define SYS_FIELD_INDEX_ID 0 |
7234 | {STRUCT_FLD(field_name, "INDEX_ID" ), |
7235 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
7236 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
7237 | STRUCT_FLD(value, 0), |
7238 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
7239 | STRUCT_FLD(old_name, "" ), |
7240 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
7241 | |
7242 | #define SYS_FIELD_NAME 1 |
7243 | {STRUCT_FLD(field_name, "NAME" ), |
7244 | STRUCT_FLD(field_length, NAME_LEN + 1), |
7245 | STRUCT_FLD(field_type, MYSQL_TYPE_STRING), |
7246 | STRUCT_FLD(value, 0), |
7247 | STRUCT_FLD(field_flags, 0), |
7248 | STRUCT_FLD(old_name, "" ), |
7249 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
7250 | |
7251 | #define SYS_FIELD_POS 2 |
7252 | {STRUCT_FLD(field_name, "POS" ), |
7253 | STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS), |
7254 | STRUCT_FLD(field_type, MYSQL_TYPE_LONG), |
7255 | STRUCT_FLD(value, 0), |
7256 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
7257 | STRUCT_FLD(old_name, "" ), |
7258 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
7259 | |
7260 | END_OF_ST_FIELD_INFO |
7261 | }; |
7262 | |
7263 | /**********************************************************************//** |
7264 | Function to fill information_schema.innodb_sys_fields with information |
7265 | collected by scanning SYS_FIELDS table. |
7266 | @return 0 on success */ |
7267 | static |
7268 | int |
7269 | i_s_dict_fill_sys_fields( |
7270 | /*=====================*/ |
7271 | THD* thd, /*!< in: thread */ |
7272 | index_id_t index_id, /*!< in: index id for the field */ |
7273 | dict_field_t* field, /*!< in: table */ |
7274 | ulint pos, /*!< in: Field position */ |
7275 | TABLE* table_to_fill) /*!< in/out: fill this table */ |
7276 | { |
7277 | Field** fields; |
7278 | |
7279 | DBUG_ENTER("i_s_dict_fill_sys_fields" ); |
7280 | |
7281 | fields = table_to_fill->field; |
7282 | |
7283 | OK(fields[SYS_FIELD_INDEX_ID]->store(index_id, true)); |
7284 | |
7285 | OK(field_store_string(fields[SYS_FIELD_NAME], field->name)); |
7286 | |
7287 | OK(fields[SYS_FIELD_POS]->store(pos, true)); |
7288 | |
7289 | OK(schema_table_store_record(thd, table_to_fill)); |
7290 | |
7291 | DBUG_RETURN(0); |
7292 | } |
7293 | /*******************************************************************//** |
7294 | Function to go through each record in SYS_FIELDS table, and fill the |
7295 | information_schema.innodb_sys_fields table with related index field |
7296 | information |
7297 | @return 0 on success */ |
7298 | static |
7299 | int |
7300 | i_s_sys_fields_fill_table( |
7301 | /*======================*/ |
7302 | THD* thd, /*!< in: thread */ |
7303 | TABLE_LIST* tables, /*!< in/out: tables to fill */ |
7304 | Item* ) /*!< in: condition (not used) */ |
7305 | { |
7306 | btr_pcur_t pcur; |
7307 | const rec_t* rec; |
7308 | mem_heap_t* heap; |
7309 | index_id_t last_id; |
7310 | mtr_t mtr; |
7311 | |
7312 | DBUG_ENTER("i_s_sys_fields_fill_table" ); |
7313 | RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name.str); |
7314 | |
7315 | /* deny access to user without PROCESS_ACL privilege */ |
7316 | if (check_global_access(thd, PROCESS_ACL)) { |
7317 | |
7318 | DBUG_RETURN(0); |
7319 | } |
7320 | |
7321 | heap = mem_heap_create(1000); |
7322 | mutex_enter(&dict_sys->mutex); |
7323 | mtr_start(&mtr); |
7324 | |
7325 | /* will save last index id so that we know whether we move to |
7326 | the next index. This is used to calculate prefix length */ |
7327 | last_id = 0; |
7328 | |
7329 | rec = dict_startscan_system(&pcur, &mtr, SYS_FIELDS); |
7330 | |
7331 | while (rec) { |
7332 | ulint pos; |
7333 | const char* err_msg; |
7334 | index_id_t index_id; |
7335 | dict_field_t field_rec; |
7336 | |
7337 | /* Populate a dict_field_t structure with information from |
7338 | a SYS_FIELDS row */ |
7339 | err_msg = dict_process_sys_fields_rec(heap, rec, &field_rec, |
7340 | &pos, &index_id, last_id); |
7341 | |
7342 | mtr_commit(&mtr); |
7343 | mutex_exit(&dict_sys->mutex); |
7344 | |
7345 | if (!err_msg) { |
7346 | i_s_dict_fill_sys_fields(thd, index_id, &field_rec, |
7347 | pos, tables->table); |
7348 | last_id = index_id; |
7349 | } else { |
7350 | push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, |
7351 | ER_CANT_FIND_SYSTEM_REC, "%s" , |
7352 | err_msg); |
7353 | } |
7354 | |
7355 | mem_heap_empty(heap); |
7356 | |
7357 | /* Get the next record */ |
7358 | mutex_enter(&dict_sys->mutex); |
7359 | mtr_start(&mtr); |
7360 | rec = dict_getnext_system(&pcur, &mtr); |
7361 | } |
7362 | |
7363 | mtr_commit(&mtr); |
7364 | mutex_exit(&dict_sys->mutex); |
7365 | mem_heap_free(heap); |
7366 | |
7367 | DBUG_RETURN(0); |
7368 | } |
7369 | /*******************************************************************//** |
7370 | Bind the dynamic table INFORMATION_SCHEMA.innodb_sys_fields |
7371 | @return 0 on success */ |
7372 | static |
7373 | int |
7374 | innodb_sys_fields_init( |
7375 | /*===================*/ |
7376 | void* p) /*!< in/out: table schema object */ |
7377 | { |
7378 | ST_SCHEMA_TABLE* schema; |
7379 | |
7380 | DBUG_ENTER("innodb_sys_field_init" ); |
7381 | |
7382 | schema = (ST_SCHEMA_TABLE*) p; |
7383 | |
7384 | schema->fields_info = innodb_sys_fields_fields_info; |
7385 | schema->fill_table = i_s_sys_fields_fill_table; |
7386 | |
7387 | DBUG_RETURN(0); |
7388 | } |
7389 | |
7390 | UNIV_INTERN struct st_maria_plugin i_s_innodb_sys_fields = |
7391 | { |
7392 | /* the plugin type (a MYSQL_XXX_PLUGIN value) */ |
7393 | /* int */ |
7394 | STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN), |
7395 | |
7396 | /* pointer to type-specific plugin descriptor */ |
7397 | /* void* */ |
7398 | STRUCT_FLD(info, &i_s_info), |
7399 | |
7400 | /* plugin name */ |
7401 | /* const char* */ |
7402 | STRUCT_FLD(name, "INNODB_SYS_FIELDS" ), |
7403 | |
7404 | /* plugin author (for SHOW PLUGINS) */ |
7405 | /* const char* */ |
7406 | STRUCT_FLD(author, plugin_author), |
7407 | |
7408 | /* general descriptive text (for SHOW PLUGINS) */ |
7409 | /* const char* */ |
7410 | STRUCT_FLD(descr, "InnoDB SYS_FIELDS" ), |
7411 | |
7412 | /* the plugin license (PLUGIN_LICENSE_XXX) */ |
7413 | /* int */ |
7414 | STRUCT_FLD(license, PLUGIN_LICENSE_GPL), |
7415 | |
7416 | /* the function to invoke when plugin is loaded */ |
7417 | /* int (*)(void*); */ |
7418 | STRUCT_FLD(init, innodb_sys_fields_init), |
7419 | |
7420 | /* the function to invoke when plugin is unloaded */ |
7421 | /* int (*)(void*); */ |
7422 | STRUCT_FLD(deinit, i_s_common_deinit), |
7423 | |
7424 | /* plugin version (for SHOW PLUGINS) */ |
7425 | /* unsigned int */ |
7426 | STRUCT_FLD(version, INNODB_VERSION_SHORT), |
7427 | |
7428 | /* struct st_mysql_show_var* */ |
7429 | STRUCT_FLD(status_vars, NULL), |
7430 | |
7431 | /* struct st_mysql_sys_var** */ |
7432 | STRUCT_FLD(system_vars, NULL), |
7433 | |
7434 | /* Maria extension */ |
7435 | STRUCT_FLD(version_info, INNODB_VERSION_STR), |
7436 | STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE), |
7437 | }; |
7438 | |
7439 | /** SYS_FOREIGN ********************************************/ |
7440 | /* Fields of the dynamic table INFORMATION_SCHEMA.INNODB_SYS_FOREIGN */ |
7441 | static ST_FIELD_INFO innodb_sys_foreign_fields_info[] = |
7442 | { |
7443 | #define SYS_FOREIGN_ID 0 |
7444 | {STRUCT_FLD(field_name, "ID" ), |
7445 | STRUCT_FLD(field_length, NAME_LEN + 1), |
7446 | STRUCT_FLD(field_type, MYSQL_TYPE_STRING), |
7447 | STRUCT_FLD(value, 0), |
7448 | STRUCT_FLD(field_flags, 0), |
7449 | STRUCT_FLD(old_name, "" ), |
7450 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
7451 | |
7452 | #define SYS_FOREIGN_FOR_NAME 1 |
7453 | {STRUCT_FLD(field_name, "FOR_NAME" ), |
7454 | STRUCT_FLD(field_length, NAME_LEN + 1), |
7455 | STRUCT_FLD(field_type, MYSQL_TYPE_STRING), |
7456 | STRUCT_FLD(value, 0), |
7457 | STRUCT_FLD(field_flags, 0), |
7458 | STRUCT_FLD(old_name, "" ), |
7459 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
7460 | |
7461 | #define SYS_FOREIGN_REF_NAME 2 |
7462 | {STRUCT_FLD(field_name, "REF_NAME" ), |
7463 | STRUCT_FLD(field_length, NAME_LEN + 1), |
7464 | STRUCT_FLD(field_type, MYSQL_TYPE_STRING), |
7465 | STRUCT_FLD(value, 0), |
7466 | STRUCT_FLD(field_flags, 0), |
7467 | STRUCT_FLD(old_name, "" ), |
7468 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
7469 | |
7470 | #define SYS_FOREIGN_NUM_COL 3 |
7471 | {STRUCT_FLD(field_name, "N_COLS" ), |
7472 | STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS), |
7473 | STRUCT_FLD(field_type, MYSQL_TYPE_LONG), |
7474 | STRUCT_FLD(value, 0), |
7475 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
7476 | STRUCT_FLD(old_name, "" ), |
7477 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
7478 | |
7479 | #define SYS_FOREIGN_TYPE 4 |
7480 | {STRUCT_FLD(field_name, "TYPE" ), |
7481 | STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS), |
7482 | STRUCT_FLD(field_type, MYSQL_TYPE_LONG), |
7483 | STRUCT_FLD(value, 0), |
7484 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
7485 | STRUCT_FLD(old_name, "" ), |
7486 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
7487 | |
7488 | END_OF_ST_FIELD_INFO |
7489 | }; |
7490 | |
7491 | /**********************************************************************//** |
7492 | Function to fill information_schema.innodb_sys_foreign with information |
7493 | collected by scanning SYS_FOREIGN table. |
7494 | @return 0 on success */ |
7495 | static |
7496 | int |
7497 | i_s_dict_fill_sys_foreign( |
7498 | /*======================*/ |
7499 | THD* thd, /*!< in: thread */ |
7500 | dict_foreign_t* foreign, /*!< in: table */ |
7501 | TABLE* table_to_fill) /*!< in/out: fill this table */ |
7502 | { |
7503 | Field** fields; |
7504 | |
7505 | DBUG_ENTER("i_s_dict_fill_sys_foreign" ); |
7506 | |
7507 | fields = table_to_fill->field; |
7508 | |
7509 | OK(field_store_string(fields[SYS_FOREIGN_ID], foreign->id)); |
7510 | |
7511 | OK(field_store_string(fields[SYS_FOREIGN_FOR_NAME], |
7512 | foreign->foreign_table_name)); |
7513 | |
7514 | OK(field_store_string(fields[SYS_FOREIGN_REF_NAME], |
7515 | foreign->referenced_table_name)); |
7516 | |
7517 | OK(fields[SYS_FOREIGN_NUM_COL]->store(foreign->n_fields)); |
7518 | |
7519 | OK(fields[SYS_FOREIGN_TYPE]->store(foreign->type)); |
7520 | |
7521 | OK(schema_table_store_record(thd, table_to_fill)); |
7522 | |
7523 | DBUG_RETURN(0); |
7524 | } |
7525 | |
7526 | /*******************************************************************//** |
7527 | Function to populate INFORMATION_SCHEMA.innodb_sys_foreign table. Loop |
7528 | through each record in SYS_FOREIGN, and extract the foreign key |
7529 | information. |
7530 | @return 0 on success */ |
7531 | static |
7532 | int |
7533 | i_s_sys_foreign_fill_table( |
7534 | /*=======================*/ |
7535 | THD* thd, /*!< in: thread */ |
7536 | TABLE_LIST* tables, /*!< in/out: tables to fill */ |
7537 | Item* ) /*!< in: condition (not used) */ |
7538 | { |
7539 | btr_pcur_t pcur; |
7540 | const rec_t* rec; |
7541 | mem_heap_t* heap; |
7542 | mtr_t mtr; |
7543 | |
7544 | DBUG_ENTER("i_s_sys_foreign_fill_table" ); |
7545 | RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name.str); |
7546 | |
7547 | /* deny access to user without PROCESS_ACL privilege */ |
7548 | if (check_global_access(thd, PROCESS_ACL)) { |
7549 | |
7550 | DBUG_RETURN(0); |
7551 | } |
7552 | |
7553 | heap = mem_heap_create(1000); |
7554 | mutex_enter(&dict_sys->mutex); |
7555 | mtr_start(&mtr); |
7556 | |
7557 | rec = dict_startscan_system(&pcur, &mtr, SYS_FOREIGN); |
7558 | |
7559 | while (rec) { |
7560 | const char* err_msg; |
7561 | dict_foreign_t foreign_rec; |
7562 | |
7563 | /* Populate a dict_foreign_t structure with information from |
7564 | a SYS_FOREIGN row */ |
7565 | err_msg = dict_process_sys_foreign_rec(heap, rec, &foreign_rec); |
7566 | |
7567 | mtr_commit(&mtr); |
7568 | mutex_exit(&dict_sys->mutex); |
7569 | |
7570 | if (!err_msg) { |
7571 | i_s_dict_fill_sys_foreign(thd, &foreign_rec, |
7572 | tables->table); |
7573 | } else { |
7574 | push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, |
7575 | ER_CANT_FIND_SYSTEM_REC, "%s" , |
7576 | err_msg); |
7577 | } |
7578 | |
7579 | mem_heap_empty(heap); |
7580 | |
7581 | /* Get the next record */ |
7582 | mtr_start(&mtr); |
7583 | mutex_enter(&dict_sys->mutex); |
7584 | rec = dict_getnext_system(&pcur, &mtr); |
7585 | } |
7586 | |
7587 | mtr_commit(&mtr); |
7588 | mutex_exit(&dict_sys->mutex); |
7589 | mem_heap_free(heap); |
7590 | |
7591 | DBUG_RETURN(0); |
7592 | } |
7593 | |
7594 | /*******************************************************************//** |
7595 | Bind the dynamic table INFORMATION_SCHEMA.innodb_sys_foreign |
7596 | @return 0 on success */ |
7597 | static |
7598 | int |
7599 | innodb_sys_foreign_init( |
7600 | /*====================*/ |
7601 | void* p) /*!< in/out: table schema object */ |
7602 | { |
7603 | ST_SCHEMA_TABLE* schema; |
7604 | |
7605 | DBUG_ENTER("innodb_sys_foreign_init" ); |
7606 | |
7607 | schema = (ST_SCHEMA_TABLE*) p; |
7608 | |
7609 | schema->fields_info = innodb_sys_foreign_fields_info; |
7610 | schema->fill_table = i_s_sys_foreign_fill_table; |
7611 | |
7612 | DBUG_RETURN(0); |
7613 | } |
7614 | |
7615 | UNIV_INTERN struct st_maria_plugin i_s_innodb_sys_foreign = |
7616 | { |
7617 | /* the plugin type (a MYSQL_XXX_PLUGIN value) */ |
7618 | /* int */ |
7619 | STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN), |
7620 | |
7621 | /* pointer to type-specific plugin descriptor */ |
7622 | /* void* */ |
7623 | STRUCT_FLD(info, &i_s_info), |
7624 | |
7625 | /* plugin name */ |
7626 | /* const char* */ |
7627 | STRUCT_FLD(name, "INNODB_SYS_FOREIGN" ), |
7628 | |
7629 | /* plugin author (for SHOW PLUGINS) */ |
7630 | /* const char* */ |
7631 | STRUCT_FLD(author, plugin_author), |
7632 | |
7633 | /* general descriptive text (for SHOW PLUGINS) */ |
7634 | /* const char* */ |
7635 | STRUCT_FLD(descr, "InnoDB SYS_FOREIGN" ), |
7636 | |
7637 | /* the plugin license (PLUGIN_LICENSE_XXX) */ |
7638 | /* int */ |
7639 | STRUCT_FLD(license, PLUGIN_LICENSE_GPL), |
7640 | |
7641 | /* the function to invoke when plugin is loaded */ |
7642 | /* int (*)(void*); */ |
7643 | STRUCT_FLD(init, innodb_sys_foreign_init), |
7644 | |
7645 | /* the function to invoke when plugin is unloaded */ |
7646 | /* int (*)(void*); */ |
7647 | STRUCT_FLD(deinit, i_s_common_deinit), |
7648 | |
7649 | /* plugin version (for SHOW PLUGINS) */ |
7650 | /* unsigned int */ |
7651 | STRUCT_FLD(version, INNODB_VERSION_SHORT), |
7652 | |
7653 | /* struct st_mysql_show_var* */ |
7654 | STRUCT_FLD(status_vars, NULL), |
7655 | |
7656 | /* struct st_mysql_sys_var** */ |
7657 | STRUCT_FLD(system_vars, NULL), |
7658 | |
7659 | /* Maria extension */ |
7660 | STRUCT_FLD(version_info, INNODB_VERSION_STR), |
7661 | STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE), |
7662 | }; |
7663 | |
7664 | /** SYS_FOREIGN_COLS ********************************************/ |
7665 | /* Fields of the dynamic table INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS */ |
7666 | static ST_FIELD_INFO innodb_sys_foreign_cols_fields_info[] = |
7667 | { |
7668 | #define SYS_FOREIGN_COL_ID 0 |
7669 | {STRUCT_FLD(field_name, "ID" ), |
7670 | STRUCT_FLD(field_length, NAME_LEN + 1), |
7671 | STRUCT_FLD(field_type, MYSQL_TYPE_STRING), |
7672 | STRUCT_FLD(value, 0), |
7673 | STRUCT_FLD(field_flags, 0), |
7674 | STRUCT_FLD(old_name, "" ), |
7675 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
7676 | |
7677 | #define SYS_FOREIGN_COL_FOR_NAME 1 |
7678 | {STRUCT_FLD(field_name, "FOR_COL_NAME" ), |
7679 | STRUCT_FLD(field_length, NAME_LEN + 1), |
7680 | STRUCT_FLD(field_type, MYSQL_TYPE_STRING), |
7681 | STRUCT_FLD(value, 0), |
7682 | STRUCT_FLD(field_flags, 0), |
7683 | STRUCT_FLD(old_name, "" ), |
7684 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
7685 | |
7686 | #define SYS_FOREIGN_COL_REF_NAME 2 |
7687 | {STRUCT_FLD(field_name, "REF_COL_NAME" ), |
7688 | STRUCT_FLD(field_length, NAME_LEN + 1), |
7689 | STRUCT_FLD(field_type, MYSQL_TYPE_STRING), |
7690 | STRUCT_FLD(value, 0), |
7691 | STRUCT_FLD(field_flags, 0), |
7692 | STRUCT_FLD(old_name, "" ), |
7693 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
7694 | |
7695 | #define SYS_FOREIGN_COL_POS 3 |
7696 | {STRUCT_FLD(field_name, "POS" ), |
7697 | STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS), |
7698 | STRUCT_FLD(field_type, MYSQL_TYPE_LONG), |
7699 | STRUCT_FLD(value, 0), |
7700 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
7701 | STRUCT_FLD(old_name, "" ), |
7702 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
7703 | |
7704 | END_OF_ST_FIELD_INFO |
7705 | }; |
7706 | |
7707 | /**********************************************************************//** |
7708 | Function to fill information_schema.innodb_sys_foreign_cols with information |
7709 | collected by scanning SYS_FOREIGN_COLS table. |
7710 | @return 0 on success */ |
7711 | static |
7712 | int |
7713 | i_s_dict_fill_sys_foreign_cols( |
7714 | /*==========================*/ |
7715 | THD* thd, /*!< in: thread */ |
7716 | const char* name, /*!< in: foreign key constraint name */ |
7717 | const char* for_col_name, /*!< in: referencing column name*/ |
7718 | const char* ref_col_name, /*!< in: referenced column |
7719 | name */ |
7720 | ulint pos, /*!< in: column position */ |
7721 | TABLE* table_to_fill) /*!< in/out: fill this table */ |
7722 | { |
7723 | Field** fields; |
7724 | |
7725 | DBUG_ENTER("i_s_dict_fill_sys_foreign_cols" ); |
7726 | |
7727 | fields = table_to_fill->field; |
7728 | |
7729 | OK(field_store_string(fields[SYS_FOREIGN_COL_ID], name)); |
7730 | |
7731 | OK(field_store_string(fields[SYS_FOREIGN_COL_FOR_NAME], for_col_name)); |
7732 | |
7733 | OK(field_store_string(fields[SYS_FOREIGN_COL_REF_NAME], ref_col_name)); |
7734 | |
7735 | OK(fields[SYS_FOREIGN_COL_POS]->store(pos, true)); |
7736 | |
7737 | OK(schema_table_store_record(thd, table_to_fill)); |
7738 | |
7739 | DBUG_RETURN(0); |
7740 | } |
7741 | /*******************************************************************//** |
7742 | Function to populate INFORMATION_SCHEMA.innodb_sys_foreign_cols table. Loop |
7743 | through each record in SYS_FOREIGN_COLS, and extract the foreign key column |
7744 | information and fill the INFORMATION_SCHEMA.innodb_sys_foreign_cols table. |
7745 | @return 0 on success */ |
7746 | static |
7747 | int |
7748 | i_s_sys_foreign_cols_fill_table( |
7749 | /*============================*/ |
7750 | THD* thd, /*!< in: thread */ |
7751 | TABLE_LIST* tables, /*!< in/out: tables to fill */ |
7752 | Item* ) /*!< in: condition (not used) */ |
7753 | { |
7754 | btr_pcur_t pcur; |
7755 | const rec_t* rec; |
7756 | mem_heap_t* heap; |
7757 | mtr_t mtr; |
7758 | |
7759 | DBUG_ENTER("i_s_sys_foreign_cols_fill_table" ); |
7760 | RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name.str); |
7761 | |
7762 | /* deny access to user without PROCESS_ACL privilege */ |
7763 | if (check_global_access(thd, PROCESS_ACL)) { |
7764 | DBUG_RETURN(0); |
7765 | } |
7766 | |
7767 | heap = mem_heap_create(1000); |
7768 | mutex_enter(&dict_sys->mutex); |
7769 | mtr_start(&mtr); |
7770 | |
7771 | rec = dict_startscan_system(&pcur, &mtr, SYS_FOREIGN_COLS); |
7772 | |
7773 | while (rec) { |
7774 | const char* err_msg; |
7775 | const char* name; |
7776 | const char* for_col_name; |
7777 | const char* ref_col_name; |
7778 | ulint pos; |
7779 | |
7780 | /* Extract necessary information from a SYS_FOREIGN_COLS row */ |
7781 | err_msg = dict_process_sys_foreign_col_rec( |
7782 | heap, rec, &name, &for_col_name, &ref_col_name, &pos); |
7783 | |
7784 | mtr_commit(&mtr); |
7785 | mutex_exit(&dict_sys->mutex); |
7786 | |
7787 | if (!err_msg) { |
7788 | i_s_dict_fill_sys_foreign_cols( |
7789 | thd, name, for_col_name, ref_col_name, pos, |
7790 | tables->table); |
7791 | } else { |
7792 | push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, |
7793 | ER_CANT_FIND_SYSTEM_REC, "%s" , |
7794 | err_msg); |
7795 | } |
7796 | |
7797 | mem_heap_empty(heap); |
7798 | |
7799 | /* Get the next record */ |
7800 | mutex_enter(&dict_sys->mutex); |
7801 | mtr_start(&mtr); |
7802 | rec = dict_getnext_system(&pcur, &mtr); |
7803 | } |
7804 | |
7805 | mtr_commit(&mtr); |
7806 | mutex_exit(&dict_sys->mutex); |
7807 | mem_heap_free(heap); |
7808 | |
7809 | DBUG_RETURN(0); |
7810 | } |
7811 | /*******************************************************************//** |
7812 | Bind the dynamic table INFORMATION_SCHEMA.innodb_sys_foreign_cols |
7813 | @return 0 on success */ |
7814 | static |
7815 | int |
7816 | innodb_sys_foreign_cols_init( |
7817 | /*========================*/ |
7818 | void* p) /*!< in/out: table schema object */ |
7819 | { |
7820 | ST_SCHEMA_TABLE* schema; |
7821 | |
7822 | DBUG_ENTER("innodb_sys_foreign_cols_init" ); |
7823 | |
7824 | schema = (ST_SCHEMA_TABLE*) p; |
7825 | |
7826 | schema->fields_info = innodb_sys_foreign_cols_fields_info; |
7827 | schema->fill_table = i_s_sys_foreign_cols_fill_table; |
7828 | |
7829 | DBUG_RETURN(0); |
7830 | } |
7831 | |
7832 | UNIV_INTERN struct st_maria_plugin i_s_innodb_sys_foreign_cols = |
7833 | { |
7834 | /* the plugin type (a MYSQL_XXX_PLUGIN value) */ |
7835 | /* int */ |
7836 | STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN), |
7837 | |
7838 | /* pointer to type-specific plugin descriptor */ |
7839 | /* void* */ |
7840 | STRUCT_FLD(info, &i_s_info), |
7841 | |
7842 | /* plugin name */ |
7843 | /* const char* */ |
7844 | STRUCT_FLD(name, "INNODB_SYS_FOREIGN_COLS" ), |
7845 | |
7846 | /* plugin author (for SHOW PLUGINS) */ |
7847 | /* const char* */ |
7848 | STRUCT_FLD(author, plugin_author), |
7849 | |
7850 | /* general descriptive text (for SHOW PLUGINS) */ |
7851 | /* const char* */ |
7852 | STRUCT_FLD(descr, "InnoDB SYS_FOREIGN_COLS" ), |
7853 | |
7854 | /* the plugin license (PLUGIN_LICENSE_XXX) */ |
7855 | /* int */ |
7856 | STRUCT_FLD(license, PLUGIN_LICENSE_GPL), |
7857 | |
7858 | /* the function to invoke when plugin is loaded */ |
7859 | /* int (*)(void*); */ |
7860 | STRUCT_FLD(init, innodb_sys_foreign_cols_init), |
7861 | |
7862 | /* the function to invoke when plugin is unloaded */ |
7863 | /* int (*)(void*); */ |
7864 | STRUCT_FLD(deinit, i_s_common_deinit), |
7865 | |
7866 | /* plugin version (for SHOW PLUGINS) */ |
7867 | /* unsigned int */ |
7868 | STRUCT_FLD(version, INNODB_VERSION_SHORT), |
7869 | |
7870 | /* struct st_mysql_show_var* */ |
7871 | STRUCT_FLD(status_vars, NULL), |
7872 | |
7873 | /* struct st_mysql_sys_var** */ |
7874 | STRUCT_FLD(system_vars, NULL), |
7875 | |
7876 | /* Maria extension */ |
7877 | STRUCT_FLD(version_info, INNODB_VERSION_STR), |
7878 | STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE), |
7879 | }; |
7880 | |
7881 | /** SYS_TABLESPACES ********************************************/ |
7882 | /* Fields of the dynamic table INFORMATION_SCHEMA.INNODB_SYS_TABLESPACES */ |
7883 | static ST_FIELD_INFO innodb_sys_tablespaces_fields_info[] = |
7884 | { |
7885 | #define SYS_TABLESPACES_SPACE 0 |
7886 | {STRUCT_FLD(field_name, "SPACE" ), |
7887 | STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS), |
7888 | STRUCT_FLD(field_type, MYSQL_TYPE_LONG), |
7889 | STRUCT_FLD(value, 0), |
7890 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
7891 | STRUCT_FLD(old_name, "" ), |
7892 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
7893 | |
7894 | #define SYS_TABLESPACES_NAME 1 |
7895 | {STRUCT_FLD(field_name, "NAME" ), |
7896 | STRUCT_FLD(field_length, MAX_FULL_NAME_LEN + 1), |
7897 | STRUCT_FLD(field_type, MYSQL_TYPE_STRING), |
7898 | STRUCT_FLD(value, 0), |
7899 | STRUCT_FLD(field_flags, 0), |
7900 | STRUCT_FLD(old_name, "" ), |
7901 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
7902 | |
7903 | #define SYS_TABLESPACES_FLAGS 2 |
7904 | {STRUCT_FLD(field_name, "FLAG" ), |
7905 | STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS), |
7906 | STRUCT_FLD(field_type, MYSQL_TYPE_LONG), |
7907 | STRUCT_FLD(value, 0), |
7908 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
7909 | STRUCT_FLD(old_name, "" ), |
7910 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
7911 | |
7912 | #define SYS_TABLESPACES_ROW_FORMAT 3 |
7913 | {STRUCT_FLD(field_name, "ROW_FORMAT" ), |
7914 | STRUCT_FLD(field_length, 22), |
7915 | STRUCT_FLD(field_type, MYSQL_TYPE_STRING), |
7916 | STRUCT_FLD(value, 0), |
7917 | STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL), |
7918 | STRUCT_FLD(old_name, "" ), |
7919 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
7920 | |
7921 | #define SYS_TABLESPACES_PAGE_SIZE 4 |
7922 | {STRUCT_FLD(field_name, "PAGE_SIZE" ), |
7923 | STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS), |
7924 | STRUCT_FLD(field_type, MYSQL_TYPE_LONG), |
7925 | STRUCT_FLD(value, 0), |
7926 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
7927 | STRUCT_FLD(old_name, "" ), |
7928 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
7929 | |
7930 | #define SYS_TABLESPACES_ZIP_PAGE_SIZE 5 |
7931 | {STRUCT_FLD(field_name, "ZIP_PAGE_SIZE" ), |
7932 | STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS), |
7933 | STRUCT_FLD(field_type, MYSQL_TYPE_LONG), |
7934 | STRUCT_FLD(value, 0), |
7935 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
7936 | STRUCT_FLD(old_name, "" ), |
7937 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
7938 | |
7939 | #define SYS_TABLESPACES_SPACE_TYPE 6 |
7940 | {STRUCT_FLD(field_name, "SPACE_TYPE" ), |
7941 | STRUCT_FLD(field_length, 10), |
7942 | STRUCT_FLD(field_type, MYSQL_TYPE_STRING), |
7943 | STRUCT_FLD(value, 0), |
7944 | STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL), |
7945 | STRUCT_FLD(old_name, "" ), |
7946 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
7947 | |
7948 | #define SYS_TABLESPACES_FS_BLOCK_SIZE 7 |
7949 | {STRUCT_FLD(field_name, "FS_BLOCK_SIZE" ), |
7950 | STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS), |
7951 | STRUCT_FLD(field_type, MYSQL_TYPE_LONG), |
7952 | STRUCT_FLD(value, 0), |
7953 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
7954 | STRUCT_FLD(old_name, "" ), |
7955 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
7956 | |
7957 | #define SYS_TABLESPACES_FILE_SIZE 8 |
7958 | {STRUCT_FLD(field_name, "FILE_SIZE" ), |
7959 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
7960 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
7961 | STRUCT_FLD(value, 0), |
7962 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
7963 | STRUCT_FLD(old_name, "" ), |
7964 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
7965 | |
7966 | #define SYS_TABLESPACES_ALLOC_SIZE 9 |
7967 | {STRUCT_FLD(field_name, "ALLOCATED_SIZE" ), |
7968 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
7969 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
7970 | STRUCT_FLD(value, 0), |
7971 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
7972 | STRUCT_FLD(old_name, "" ), |
7973 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
7974 | |
7975 | END_OF_ST_FIELD_INFO |
7976 | |
7977 | }; |
7978 | |
7979 | /**********************************************************************//** |
7980 | Function to fill INFORMATION_SCHEMA.INNODB_SYS_TABLESPACES with information |
7981 | collected by scanning SYS_TABLESPACESS table. |
7982 | @return 0 on success */ |
7983 | static |
7984 | int |
7985 | i_s_dict_fill_sys_tablespaces( |
7986 | /*==========================*/ |
7987 | THD* thd, /*!< in: thread */ |
7988 | ulint space, /*!< in: space ID */ |
7989 | const char* name, /*!< in: tablespace name */ |
7990 | ulint flags, /*!< in: tablespace flags */ |
7991 | TABLE* table_to_fill) /*!< in/out: fill this table */ |
7992 | { |
7993 | Field** fields; |
7994 | ulint atomic_blobs = FSP_FLAGS_HAS_ATOMIC_BLOBS(flags); |
7995 | const char* row_format; |
7996 | |
7997 | DBUG_ENTER("i_s_dict_fill_sys_tablespaces" ); |
7998 | |
7999 | if (is_system_tablespace(space)) { |
8000 | row_format = "Compact, Redundant or Dynamic" ; |
8001 | } else if (FSP_FLAGS_GET_ZIP_SSIZE(flags)) { |
8002 | row_format = "Compressed" ; |
8003 | } else if (atomic_blobs) { |
8004 | row_format = "Dynamic" ; |
8005 | } else { |
8006 | row_format = "Compact or Redundant" ; |
8007 | } |
8008 | |
8009 | fields = table_to_fill->field; |
8010 | |
8011 | OK(fields[SYS_TABLESPACES_SPACE]->store(space, true)); |
8012 | |
8013 | OK(field_store_string(fields[SYS_TABLESPACES_NAME], name)); |
8014 | |
8015 | OK(fields[SYS_TABLESPACES_FLAGS]->store(flags, true)); |
8016 | |
8017 | OK(field_store_string(fields[SYS_TABLESPACES_ROW_FORMAT], row_format)); |
8018 | |
8019 | OK(field_store_string(fields[SYS_TABLESPACES_SPACE_TYPE], |
8020 | is_system_tablespace(space) |
8021 | ? "System" : "Single" )); |
8022 | |
8023 | ulint cflags = fsp_flags_is_valid(flags, space) |
8024 | ? flags : fsp_flags_convert_from_101(flags); |
8025 | if (cflags == ULINT_UNDEFINED) { |
8026 | fields[SYS_TABLESPACES_PAGE_SIZE]->set_null(); |
8027 | fields[SYS_TABLESPACES_ZIP_PAGE_SIZE]->set_null(); |
8028 | fields[SYS_TABLESPACES_FS_BLOCK_SIZE]->set_null(); |
8029 | fields[SYS_TABLESPACES_FILE_SIZE]->set_null(); |
8030 | fields[SYS_TABLESPACES_ALLOC_SIZE]->set_null(); |
8031 | OK(schema_table_store_record(thd, table_to_fill)); |
8032 | DBUG_RETURN(0); |
8033 | } |
8034 | |
8035 | const page_size_t page_size(cflags); |
8036 | |
8037 | OK(fields[SYS_TABLESPACES_PAGE_SIZE]->store( |
8038 | page_size.logical(), true)); |
8039 | |
8040 | OK(fields[SYS_TABLESPACES_ZIP_PAGE_SIZE]->store( |
8041 | page_size.physical(), true)); |
8042 | |
8043 | char* filepath = NULL; |
8044 | if (FSP_FLAGS_HAS_DATA_DIR(cflags)) { |
8045 | mutex_enter(&dict_sys->mutex); |
8046 | filepath = dict_get_first_path(space); |
8047 | mutex_exit(&dict_sys->mutex); |
8048 | } |
8049 | |
8050 | if (filepath == NULL) { |
8051 | filepath = fil_make_filepath(NULL, name, IBD, false); |
8052 | } |
8053 | |
8054 | os_file_stat_t stat; |
8055 | os_file_size_t file; |
8056 | |
8057 | memset(&file, 0xff, sizeof(file)); |
8058 | memset(&stat, 0x0, sizeof(stat)); |
8059 | |
8060 | if (filepath != NULL) { |
8061 | |
8062 | file = os_file_get_size(filepath); |
8063 | |
8064 | /* Get the file system (or Volume) block size. */ |
8065 | dberr_t err = os_file_get_status(filepath, &stat, false, false); |
8066 | |
8067 | switch(err) { |
8068 | case DB_FAIL: |
8069 | ib::warn() |
8070 | << "File '" << filepath << "', failed to get " |
8071 | << "stats" ; |
8072 | break; |
8073 | |
8074 | case DB_SUCCESS: |
8075 | case DB_NOT_FOUND: |
8076 | break; |
8077 | |
8078 | default: |
8079 | ib::error() |
8080 | << "File '" << filepath << "' " |
8081 | << ut_strerr(err); |
8082 | break; |
8083 | } |
8084 | |
8085 | ut_free(filepath); |
8086 | } |
8087 | |
8088 | if (file.m_total_size == static_cast<os_offset_t>(~0)) { |
8089 | stat.block_size = 0; |
8090 | file.m_total_size = 0; |
8091 | file.m_alloc_size = 0; |
8092 | } |
8093 | |
8094 | OK(fields[SYS_TABLESPACES_FS_BLOCK_SIZE]->store(stat.block_size, true)); |
8095 | |
8096 | OK(fields[SYS_TABLESPACES_FILE_SIZE]->store(file.m_total_size, true)); |
8097 | |
8098 | OK(fields[SYS_TABLESPACES_ALLOC_SIZE]->store(file.m_alloc_size, true)); |
8099 | |
8100 | OK(schema_table_store_record(thd, table_to_fill)); |
8101 | |
8102 | DBUG_RETURN(0); |
8103 | } |
8104 | |
8105 | /*******************************************************************//** |
8106 | Function to populate INFORMATION_SCHEMA.INNODB_SYS_TABLESPACES table. |
8107 | Loop through each record in SYS_TABLESPACES, and extract the column |
8108 | information and fill the INFORMATION_SCHEMA.INNODB_SYS_TABLESPACES table. |
8109 | @return 0 on success */ |
8110 | static |
8111 | int |
8112 | i_s_sys_tablespaces_fill_table( |
8113 | /*===========================*/ |
8114 | THD* thd, /*!< in: thread */ |
8115 | TABLE_LIST* tables, /*!< in/out: tables to fill */ |
8116 | Item* ) /*!< in: condition (not used) */ |
8117 | { |
8118 | btr_pcur_t pcur; |
8119 | const rec_t* rec; |
8120 | mem_heap_t* heap; |
8121 | mtr_t mtr; |
8122 | |
8123 | DBUG_ENTER("i_s_sys_tablespaces_fill_table" ); |
8124 | RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name.str); |
8125 | |
8126 | /* deny access to user without PROCESS_ACL privilege */ |
8127 | if (check_global_access(thd, PROCESS_ACL)) { |
8128 | DBUG_RETURN(0); |
8129 | } |
8130 | |
8131 | heap = mem_heap_create(1000); |
8132 | mutex_enter(&dict_sys->mutex); |
8133 | mtr_start(&mtr); |
8134 | |
8135 | for (rec = dict_startscan_system(&pcur, &mtr, SYS_TABLESPACES); |
8136 | rec != NULL; |
8137 | rec = dict_getnext_system(&pcur, &mtr)) { |
8138 | |
8139 | const char* err_msg; |
8140 | ulint space; |
8141 | const char* name; |
8142 | ulint flags; |
8143 | |
8144 | /* Extract necessary information from a SYS_TABLESPACES row */ |
8145 | err_msg = dict_process_sys_tablespaces( |
8146 | heap, rec, &space, &name, &flags); |
8147 | |
8148 | mtr_commit(&mtr); |
8149 | mutex_exit(&dict_sys->mutex); |
8150 | |
8151 | if (!err_msg) { |
8152 | i_s_dict_fill_sys_tablespaces( |
8153 | thd, space, name, flags, |
8154 | tables->table); |
8155 | } else { |
8156 | push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, |
8157 | ER_CANT_FIND_SYSTEM_REC, "%s" , |
8158 | err_msg); |
8159 | } |
8160 | |
8161 | mem_heap_empty(heap); |
8162 | |
8163 | /* Get the next record */ |
8164 | mutex_enter(&dict_sys->mutex); |
8165 | mtr_start(&mtr); |
8166 | } |
8167 | |
8168 | mtr_commit(&mtr); |
8169 | mutex_exit(&dict_sys->mutex); |
8170 | mem_heap_free(heap); |
8171 | |
8172 | DBUG_RETURN(0); |
8173 | } |
8174 | /*******************************************************************//** |
8175 | Bind the dynamic table INFORMATION_SCHEMA.INNODB_SYS_TABLESPACES |
8176 | @return 0 on success */ |
8177 | static |
8178 | int |
8179 | innodb_sys_tablespaces_init( |
8180 | /*========================*/ |
8181 | void* p) /*!< in/out: table schema object */ |
8182 | { |
8183 | ST_SCHEMA_TABLE* schema; |
8184 | |
8185 | DBUG_ENTER("innodb_sys_tablespaces_init" ); |
8186 | |
8187 | schema = (ST_SCHEMA_TABLE*) p; |
8188 | |
8189 | schema->fields_info = innodb_sys_tablespaces_fields_info; |
8190 | schema->fill_table = i_s_sys_tablespaces_fill_table; |
8191 | |
8192 | DBUG_RETURN(0); |
8193 | } |
8194 | |
8195 | UNIV_INTERN struct st_maria_plugin i_s_innodb_sys_tablespaces = |
8196 | { |
8197 | /* the plugin type (a MYSQL_XXX_PLUGIN value) */ |
8198 | /* int */ |
8199 | STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN), |
8200 | |
8201 | /* pointer to type-specific plugin descriptor */ |
8202 | /* void* */ |
8203 | STRUCT_FLD(info, &i_s_info), |
8204 | |
8205 | /* plugin name */ |
8206 | /* const char* */ |
8207 | STRUCT_FLD(name, "INNODB_SYS_TABLESPACES" ), |
8208 | |
8209 | /* plugin author (for SHOW PLUGINS) */ |
8210 | /* const char* */ |
8211 | STRUCT_FLD(author, plugin_author), |
8212 | |
8213 | /* general descriptive text (for SHOW PLUGINS) */ |
8214 | /* const char* */ |
8215 | STRUCT_FLD(descr, "InnoDB SYS_TABLESPACES" ), |
8216 | |
8217 | /* the plugin license (PLUGIN_LICENSE_XXX) */ |
8218 | /* int */ |
8219 | STRUCT_FLD(license, PLUGIN_LICENSE_GPL), |
8220 | |
8221 | /* the function to invoke when plugin is loaded */ |
8222 | /* int (*)(void*); */ |
8223 | STRUCT_FLD(init, innodb_sys_tablespaces_init), |
8224 | |
8225 | /* the function to invoke when plugin is unloaded */ |
8226 | /* int (*)(void*); */ |
8227 | STRUCT_FLD(deinit, i_s_common_deinit), |
8228 | |
8229 | /* plugin version (for SHOW PLUGINS) */ |
8230 | /* unsigned int */ |
8231 | STRUCT_FLD(version, INNODB_VERSION_SHORT), |
8232 | |
8233 | /* struct st_mysql_show_var* */ |
8234 | STRUCT_FLD(status_vars, NULL), |
8235 | |
8236 | /* struct st_mysql_sys_var** */ |
8237 | STRUCT_FLD(system_vars, NULL), |
8238 | |
8239 | /* Maria extension */ |
8240 | STRUCT_FLD(version_info, INNODB_VERSION_STR), |
8241 | STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE), |
8242 | }; |
8243 | |
8244 | /** SYS_DATAFILES ************************************************/ |
8245 | /* Fields of the dynamic table INFORMATION_SCHEMA.INNODB_SYS_DATAFILES */ |
8246 | static ST_FIELD_INFO innodb_sys_datafiles_fields_info[] = |
8247 | { |
8248 | #define SYS_DATAFILES_SPACE 0 |
8249 | {STRUCT_FLD(field_name, "SPACE" ), |
8250 | STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS), |
8251 | STRUCT_FLD(field_type, MYSQL_TYPE_LONG), |
8252 | STRUCT_FLD(value, 0), |
8253 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
8254 | STRUCT_FLD(old_name, "" ), |
8255 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
8256 | |
8257 | #define SYS_DATAFILES_PATH 1 |
8258 | {STRUCT_FLD(field_name, "PATH" ), |
8259 | STRUCT_FLD(field_length, OS_FILE_MAX_PATH), |
8260 | STRUCT_FLD(field_type, MYSQL_TYPE_STRING), |
8261 | STRUCT_FLD(value, 0), |
8262 | STRUCT_FLD(field_flags, 0), |
8263 | STRUCT_FLD(old_name, "" ), |
8264 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
8265 | |
8266 | END_OF_ST_FIELD_INFO |
8267 | }; |
8268 | |
8269 | /**********************************************************************//** |
8270 | Function to fill INFORMATION_SCHEMA.INNODB_SYS_DATAFILES with information |
8271 | collected by scanning SYS_DATAFILESS table. |
8272 | @return 0 on success */ |
8273 | static |
8274 | int |
8275 | i_s_dict_fill_sys_datafiles( |
8276 | /*========================*/ |
8277 | THD* thd, /*!< in: thread */ |
8278 | ulint space, /*!< in: space ID */ |
8279 | const char* path, /*!< in: absolute path */ |
8280 | TABLE* table_to_fill) /*!< in/out: fill this table */ |
8281 | { |
8282 | Field** fields; |
8283 | |
8284 | DBUG_ENTER("i_s_dict_fill_sys_datafiles" ); |
8285 | |
8286 | fields = table_to_fill->field; |
8287 | |
8288 | OK(field_store_ulint(fields[SYS_DATAFILES_SPACE], space)); |
8289 | |
8290 | OK(field_store_string(fields[SYS_DATAFILES_PATH], path)); |
8291 | |
8292 | OK(schema_table_store_record(thd, table_to_fill)); |
8293 | |
8294 | DBUG_RETURN(0); |
8295 | } |
8296 | /*******************************************************************//** |
8297 | Function to populate INFORMATION_SCHEMA.INNODB_SYS_DATAFILES table. |
8298 | Loop through each record in SYS_DATAFILES, and extract the column |
8299 | information and fill the INFORMATION_SCHEMA.INNODB_SYS_DATAFILES table. |
8300 | @return 0 on success */ |
8301 | static |
8302 | int |
8303 | i_s_sys_datafiles_fill_table( |
8304 | /*=========================*/ |
8305 | THD* thd, /*!< in: thread */ |
8306 | TABLE_LIST* tables, /*!< in/out: tables to fill */ |
8307 | Item* ) /*!< in: condition (not used) */ |
8308 | { |
8309 | btr_pcur_t pcur; |
8310 | const rec_t* rec; |
8311 | mem_heap_t* heap; |
8312 | mtr_t mtr; |
8313 | |
8314 | DBUG_ENTER("i_s_sys_datafiles_fill_table" ); |
8315 | RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name.str); |
8316 | |
8317 | /* deny access to user without PROCESS_ACL privilege */ |
8318 | if (check_global_access(thd, PROCESS_ACL)) { |
8319 | DBUG_RETURN(0); |
8320 | } |
8321 | |
8322 | heap = mem_heap_create(1000); |
8323 | mutex_enter(&dict_sys->mutex); |
8324 | mtr_start(&mtr); |
8325 | |
8326 | rec = dict_startscan_system(&pcur, &mtr, SYS_DATAFILES); |
8327 | |
8328 | while (rec) { |
8329 | const char* err_msg; |
8330 | ulint space; |
8331 | const char* path; |
8332 | |
8333 | /* Extract necessary information from a SYS_DATAFILES row */ |
8334 | err_msg = dict_process_sys_datafiles( |
8335 | heap, rec, &space, &path); |
8336 | |
8337 | mtr_commit(&mtr); |
8338 | mutex_exit(&dict_sys->mutex); |
8339 | |
8340 | if (!err_msg) { |
8341 | i_s_dict_fill_sys_datafiles( |
8342 | thd, space, path, tables->table); |
8343 | } else { |
8344 | push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, |
8345 | ER_CANT_FIND_SYSTEM_REC, "%s" , |
8346 | err_msg); |
8347 | } |
8348 | |
8349 | mem_heap_empty(heap); |
8350 | |
8351 | /* Get the next record */ |
8352 | mutex_enter(&dict_sys->mutex); |
8353 | mtr_start(&mtr); |
8354 | rec = dict_getnext_system(&pcur, &mtr); |
8355 | } |
8356 | |
8357 | mtr_commit(&mtr); |
8358 | mutex_exit(&dict_sys->mutex); |
8359 | mem_heap_free(heap); |
8360 | |
8361 | DBUG_RETURN(0); |
8362 | } |
8363 | /*******************************************************************//** |
8364 | Bind the dynamic table INFORMATION_SCHEMA.INNODB_SYS_DATAFILES |
8365 | @return 0 on success */ |
8366 | static |
8367 | int |
8368 | innodb_sys_datafiles_init( |
8369 | /*======================*/ |
8370 | void* p) /*!< in/out: table schema object */ |
8371 | { |
8372 | ST_SCHEMA_TABLE* schema; |
8373 | |
8374 | DBUG_ENTER("innodb_sys_datafiles_init" ); |
8375 | |
8376 | schema = (ST_SCHEMA_TABLE*) p; |
8377 | |
8378 | schema->fields_info = innodb_sys_datafiles_fields_info; |
8379 | schema->fill_table = i_s_sys_datafiles_fill_table; |
8380 | |
8381 | DBUG_RETURN(0); |
8382 | } |
8383 | |
8384 | UNIV_INTERN struct st_maria_plugin i_s_innodb_sys_datafiles = |
8385 | { |
8386 | /* the plugin type (a MYSQL_XXX_PLUGIN value) */ |
8387 | /* int */ |
8388 | STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN), |
8389 | |
8390 | /* pointer to type-specific plugin descriptor */ |
8391 | /* void* */ |
8392 | STRUCT_FLD(info, &i_s_info), |
8393 | |
8394 | /* plugin name */ |
8395 | /* const char* */ |
8396 | STRUCT_FLD(name, "INNODB_SYS_DATAFILES" ), |
8397 | |
8398 | /* plugin author (for SHOW PLUGINS) */ |
8399 | /* const char* */ |
8400 | STRUCT_FLD(author, plugin_author), |
8401 | |
8402 | /* general descriptive text (for SHOW PLUGINS) */ |
8403 | /* const char* */ |
8404 | STRUCT_FLD(descr, "InnoDB SYS_DATAFILES" ), |
8405 | |
8406 | /* the plugin license (PLUGIN_LICENSE_XXX) */ |
8407 | /* int */ |
8408 | STRUCT_FLD(license, PLUGIN_LICENSE_GPL), |
8409 | |
8410 | /* the function to invoke when plugin is loaded */ |
8411 | /* int (*)(void*); */ |
8412 | STRUCT_FLD(init, innodb_sys_datafiles_init), |
8413 | |
8414 | /* the function to invoke when plugin is unloaded */ |
8415 | /* int (*)(void*); */ |
8416 | STRUCT_FLD(deinit, i_s_common_deinit), |
8417 | |
8418 | /* plugin version (for SHOW PLUGINS) */ |
8419 | /* unsigned int */ |
8420 | STRUCT_FLD(version, INNODB_VERSION_SHORT), |
8421 | |
8422 | /* struct st_mysql_show_var* */ |
8423 | STRUCT_FLD(status_vars, NULL), |
8424 | |
8425 | /* struct st_mysql_sys_var** */ |
8426 | STRUCT_FLD(system_vars, NULL), |
8427 | |
8428 | /* Maria extension */ |
8429 | STRUCT_FLD(version_info, INNODB_VERSION_STR), |
8430 | STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE), |
8431 | }; |
8432 | |
8433 | /** TABLESPACES_ENCRYPTION ********************************************/ |
8434 | /* Fields of the table INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION */ |
8435 | static ST_FIELD_INFO innodb_tablespaces_encryption_fields_info[] = |
8436 | { |
8437 | #define TABLESPACES_ENCRYPTION_SPACE 0 |
8438 | {STRUCT_FLD(field_name, "SPACE" ), |
8439 | STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS), |
8440 | STRUCT_FLD(field_type, MYSQL_TYPE_LONG), |
8441 | STRUCT_FLD(value, 0), |
8442 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
8443 | STRUCT_FLD(old_name, "" ), |
8444 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
8445 | |
8446 | #define TABLESPACES_ENCRYPTION_NAME 1 |
8447 | {STRUCT_FLD(field_name, "NAME" ), |
8448 | STRUCT_FLD(field_length, MAX_FULL_NAME_LEN + 1), |
8449 | STRUCT_FLD(field_type, MYSQL_TYPE_STRING), |
8450 | STRUCT_FLD(value, 0), |
8451 | STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL), |
8452 | STRUCT_FLD(old_name, "" ), |
8453 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
8454 | |
8455 | #define TABLESPACES_ENCRYPTION_ENCRYPTION_SCHEME 2 |
8456 | {STRUCT_FLD(field_name, "ENCRYPTION_SCHEME" ), |
8457 | STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS), |
8458 | STRUCT_FLD(field_type, MYSQL_TYPE_LONG), |
8459 | STRUCT_FLD(value, 0), |
8460 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
8461 | STRUCT_FLD(old_name, "" ), |
8462 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
8463 | |
8464 | #define TABLESPACES_ENCRYPTION_KEYSERVER_REQUESTS 3 |
8465 | {STRUCT_FLD(field_name, "KEYSERVER_REQUESTS" ), |
8466 | STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS), |
8467 | STRUCT_FLD(field_type, MYSQL_TYPE_LONG), |
8468 | STRUCT_FLD(value, 0), |
8469 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
8470 | STRUCT_FLD(old_name, "" ), |
8471 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
8472 | |
8473 | #define TABLESPACES_ENCRYPTION_MIN_KEY_VERSION 4 |
8474 | {STRUCT_FLD(field_name, "MIN_KEY_VERSION" ), |
8475 | STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS), |
8476 | STRUCT_FLD(field_type, MYSQL_TYPE_LONG), |
8477 | STRUCT_FLD(value, 0), |
8478 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
8479 | STRUCT_FLD(old_name, "" ), |
8480 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
8481 | |
8482 | #define TABLESPACES_ENCRYPTION_CURRENT_KEY_VERSION 5 |
8483 | {STRUCT_FLD(field_name, "CURRENT_KEY_VERSION" ), |
8484 | STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS), |
8485 | STRUCT_FLD(field_type, MYSQL_TYPE_LONG), |
8486 | STRUCT_FLD(value, 0), |
8487 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
8488 | STRUCT_FLD(old_name, "" ), |
8489 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
8490 | |
8491 | #define TABLESPACES_ENCRYPTION_KEY_ROTATION_PAGE_NUMBER 6 |
8492 | {STRUCT_FLD(field_name, "KEY_ROTATION_PAGE_NUMBER" ), |
8493 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
8494 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
8495 | STRUCT_FLD(value, 0), |
8496 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED | MY_I_S_MAYBE_NULL), |
8497 | STRUCT_FLD(old_name, "" ), |
8498 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
8499 | |
8500 | #define TABLESPACES_ENCRYPTION_KEY_ROTATION_MAX_PAGE_NUMBER 7 |
8501 | {STRUCT_FLD(field_name, "KEY_ROTATION_MAX_PAGE_NUMBER" ), |
8502 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
8503 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
8504 | STRUCT_FLD(value, 0), |
8505 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED | MY_I_S_MAYBE_NULL), |
8506 | STRUCT_FLD(old_name, "" ), |
8507 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
8508 | |
8509 | #define TABLESPACES_ENCRYPTION_CURRENT_KEY_ID 8 |
8510 | {STRUCT_FLD(field_name, "CURRENT_KEY_ID" ), |
8511 | STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS), |
8512 | STRUCT_FLD(field_type, MYSQL_TYPE_LONG), |
8513 | STRUCT_FLD(value, 0), |
8514 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
8515 | STRUCT_FLD(old_name, "" ), |
8516 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
8517 | |
8518 | #define TABLESPACES_ENCRYPTION_ROTATING_OR_FLUSHING 9 |
8519 | {STRUCT_FLD(field_name, "ROTATING_OR_FLUSHING" ), |
8520 | STRUCT_FLD(field_length, 1), |
8521 | STRUCT_FLD(field_type, MYSQL_TYPE_LONG), |
8522 | STRUCT_FLD(value, 0), |
8523 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
8524 | STRUCT_FLD(old_name, "" ), |
8525 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
8526 | |
8527 | END_OF_ST_FIELD_INFO |
8528 | }; |
8529 | |
8530 | /**********************************************************************//** |
8531 | Function to fill INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION |
8532 | with information collected by scanning SYS_TABLESPACES table. |
8533 | @param[in] thd thread handle |
8534 | @param[in] space Tablespace |
8535 | @param[in] table_to_fill I_S table to fill |
8536 | @return 0 on success */ |
8537 | static |
8538 | int |
8539 | i_s_dict_fill_tablespaces_encryption( |
8540 | THD* thd, |
8541 | fil_space_t* space, |
8542 | TABLE* table_to_fill) |
8543 | { |
8544 | Field** fields; |
8545 | struct fil_space_crypt_status_t status; |
8546 | |
8547 | DBUG_ENTER("i_s_dict_fill_tablespaces_encryption" ); |
8548 | |
8549 | fields = table_to_fill->field; |
8550 | |
8551 | fil_space_crypt_get_status(space, &status); |
8552 | |
8553 | /* If tablespace id does not match, we did not find |
8554 | encryption information for this tablespace. */ |
8555 | if (!space->crypt_data || space->id != status.space) { |
8556 | goto skip; |
8557 | } |
8558 | |
8559 | OK(fields[TABLESPACES_ENCRYPTION_SPACE]->store(space->id, true)); |
8560 | |
8561 | OK(field_store_string(fields[TABLESPACES_ENCRYPTION_NAME], |
8562 | space->name)); |
8563 | |
8564 | OK(fields[TABLESPACES_ENCRYPTION_ENCRYPTION_SCHEME]->store( |
8565 | status.scheme, true)); |
8566 | OK(fields[TABLESPACES_ENCRYPTION_KEYSERVER_REQUESTS]->store( |
8567 | status.keyserver_requests, true)); |
8568 | OK(fields[TABLESPACES_ENCRYPTION_MIN_KEY_VERSION]->store( |
8569 | status.min_key_version, true)); |
8570 | OK(fields[TABLESPACES_ENCRYPTION_CURRENT_KEY_VERSION]->store( |
8571 | status.current_key_version, true)); |
8572 | OK(fields[TABLESPACES_ENCRYPTION_CURRENT_KEY_ID]->store( |
8573 | status.key_id, true)); |
8574 | OK(fields[TABLESPACES_ENCRYPTION_ROTATING_OR_FLUSHING]->store( |
8575 | status.rotating || status.flushing, true)); |
8576 | |
8577 | if (status.rotating) { |
8578 | fields[TABLESPACES_ENCRYPTION_KEY_ROTATION_PAGE_NUMBER]->set_notnull(); |
8579 | OK(fields[TABLESPACES_ENCRYPTION_KEY_ROTATION_PAGE_NUMBER]->store( |
8580 | status.rotate_next_page_number, true)); |
8581 | fields[TABLESPACES_ENCRYPTION_KEY_ROTATION_MAX_PAGE_NUMBER]->set_notnull(); |
8582 | OK(fields[TABLESPACES_ENCRYPTION_KEY_ROTATION_MAX_PAGE_NUMBER]->store( |
8583 | status.rotate_max_page_number, true)); |
8584 | } else { |
8585 | fields[TABLESPACES_ENCRYPTION_KEY_ROTATION_PAGE_NUMBER] |
8586 | ->set_null(); |
8587 | fields[TABLESPACES_ENCRYPTION_KEY_ROTATION_MAX_PAGE_NUMBER] |
8588 | ->set_null(); |
8589 | } |
8590 | |
8591 | OK(schema_table_store_record(thd, table_to_fill)); |
8592 | |
8593 | skip: |
8594 | DBUG_RETURN(0); |
8595 | } |
8596 | /*******************************************************************//** |
8597 | Function to populate INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION table. |
8598 | Loop through each record in TABLESPACES_ENCRYPTION, and extract the column |
8599 | information and fill the INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION table. |
8600 | @return 0 on success */ |
8601 | static |
8602 | int |
8603 | i_s_tablespaces_encryption_fill_table( |
8604 | /*===========================*/ |
8605 | THD* thd, /*!< in: thread */ |
8606 | TABLE_LIST* tables, /*!< in/out: tables to fill */ |
8607 | Item* ) /*!< in: condition (not used) */ |
8608 | { |
8609 | DBUG_ENTER("i_s_tablespaces_encryption_fill_table" ); |
8610 | RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name.str); |
8611 | |
8612 | /* deny access to user without PROCESS_ACL privilege */ |
8613 | if (check_global_access(thd, SUPER_ACL)) { |
8614 | DBUG_RETURN(0); |
8615 | } |
8616 | |
8617 | mutex_enter(&fil_system.mutex); |
8618 | |
8619 | for (fil_space_t* space = UT_LIST_GET_FIRST(fil_system.space_list); |
8620 | space; space = UT_LIST_GET_NEXT(space_list, space)) { |
8621 | if (space->purpose == FIL_TYPE_TABLESPACE |
8622 | && !space->is_stopping()) { |
8623 | space->acquire(); |
8624 | mutex_exit(&fil_system.mutex); |
8625 | if (int err = i_s_dict_fill_tablespaces_encryption( |
8626 | thd, space, tables->table)) { |
8627 | space->release(); |
8628 | DBUG_RETURN(err); |
8629 | } |
8630 | mutex_enter(&fil_system.mutex); |
8631 | space->release(); |
8632 | } |
8633 | } |
8634 | |
8635 | mutex_exit(&fil_system.mutex); |
8636 | DBUG_RETURN(0); |
8637 | } |
8638 | /*******************************************************************//** |
8639 | Bind the dynamic table INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION |
8640 | @return 0 on success */ |
8641 | static |
8642 | int |
8643 | innodb_tablespaces_encryption_init( |
8644 | /*========================*/ |
8645 | void* p) /*!< in/out: table schema object */ |
8646 | { |
8647 | ST_SCHEMA_TABLE* schema; |
8648 | |
8649 | DBUG_ENTER("innodb_tablespaces_encryption_init" ); |
8650 | |
8651 | schema = (ST_SCHEMA_TABLE*) p; |
8652 | |
8653 | schema->fields_info = innodb_tablespaces_encryption_fields_info; |
8654 | schema->fill_table = i_s_tablespaces_encryption_fill_table; |
8655 | |
8656 | DBUG_RETURN(0); |
8657 | } |
8658 | |
8659 | UNIV_INTERN struct st_maria_plugin i_s_innodb_tablespaces_encryption = |
8660 | { |
8661 | /* the plugin type (a MYSQL_XXX_PLUGIN value) */ |
8662 | /* int */ |
8663 | STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN), |
8664 | |
8665 | /* pointer to type-specific plugin descriptor */ |
8666 | /* void* */ |
8667 | STRUCT_FLD(info, &i_s_info), |
8668 | |
8669 | /* plugin name */ |
8670 | /* const char* */ |
8671 | STRUCT_FLD(name, "INNODB_TABLESPACES_ENCRYPTION" ), |
8672 | |
8673 | /* plugin author (for SHOW PLUGINS) */ |
8674 | /* const char* */ |
8675 | STRUCT_FLD(author, "Google Inc" ), |
8676 | |
8677 | /* general descriptive text (for SHOW PLUGINS) */ |
8678 | /* const char* */ |
8679 | STRUCT_FLD(descr, "InnoDB TABLESPACES_ENCRYPTION" ), |
8680 | |
8681 | /* the plugin license (PLUGIN_LICENSE_XXX) */ |
8682 | /* int */ |
8683 | STRUCT_FLD(license, PLUGIN_LICENSE_BSD), |
8684 | |
8685 | /* the function to invoke when plugin is loaded */ |
8686 | /* int (*)(void*); */ |
8687 | STRUCT_FLD(init, innodb_tablespaces_encryption_init), |
8688 | |
8689 | /* the function to invoke when plugin is unloaded */ |
8690 | /* int (*)(void*); */ |
8691 | STRUCT_FLD(deinit, i_s_common_deinit), |
8692 | |
8693 | /* plugin version (for SHOW PLUGINS) */ |
8694 | /* unsigned int */ |
8695 | STRUCT_FLD(version, INNODB_VERSION_SHORT), |
8696 | |
8697 | /* struct st_mysql_show_var* */ |
8698 | STRUCT_FLD(status_vars, NULL), |
8699 | |
8700 | /* struct st_mysql_sys_var** */ |
8701 | STRUCT_FLD(system_vars, NULL), |
8702 | |
8703 | /* Maria extension */ |
8704 | STRUCT_FLD(version_info, INNODB_VERSION_STR), |
8705 | STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE) |
8706 | }; |
8707 | |
8708 | /** TABLESPACES_SCRUBBING ********************************************/ |
8709 | /* Fields of the table INFORMATION_SCHEMA.INNODB_TABLESPACES_SCRUBBING */ |
8710 | static ST_FIELD_INFO innodb_tablespaces_scrubbing_fields_info[] = |
8711 | { |
8712 | #define TABLESPACES_SCRUBBING_SPACE 0 |
8713 | {STRUCT_FLD(field_name, "SPACE" ), |
8714 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
8715 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
8716 | STRUCT_FLD(value, 0), |
8717 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
8718 | STRUCT_FLD(old_name, "" ), |
8719 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
8720 | |
8721 | #define TABLESPACES_SCRUBBING_NAME 1 |
8722 | {STRUCT_FLD(field_name, "NAME" ), |
8723 | STRUCT_FLD(field_length, MAX_FULL_NAME_LEN + 1), |
8724 | STRUCT_FLD(field_type, MYSQL_TYPE_STRING), |
8725 | STRUCT_FLD(value, 0), |
8726 | STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL), |
8727 | STRUCT_FLD(old_name, "" ), |
8728 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
8729 | |
8730 | #define TABLESPACES_SCRUBBING_COMPRESSED 2 |
8731 | {STRUCT_FLD(field_name, "COMPRESSED" ), |
8732 | STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS), |
8733 | STRUCT_FLD(field_type, MYSQL_TYPE_LONG), |
8734 | STRUCT_FLD(value, 0), |
8735 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
8736 | STRUCT_FLD(old_name, "" ), |
8737 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
8738 | |
8739 | #define TABLESPACES_SCRUBBING_LAST_SCRUB_COMPLETED 3 |
8740 | {STRUCT_FLD(field_name, "LAST_SCRUB_COMPLETED" ), |
8741 | STRUCT_FLD(field_length, 0), |
8742 | STRUCT_FLD(field_type, MYSQL_TYPE_DATETIME), |
8743 | STRUCT_FLD(value, 0), |
8744 | STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL), |
8745 | STRUCT_FLD(old_name, "" ), |
8746 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
8747 | |
8748 | #define TABLESPACES_SCRUBBING_CURRENT_SCRUB_STARTED 4 |
8749 | {STRUCT_FLD(field_name, "CURRENT_SCRUB_STARTED" ), |
8750 | STRUCT_FLD(field_length, 0), |
8751 | STRUCT_FLD(field_type, MYSQL_TYPE_DATETIME), |
8752 | STRUCT_FLD(value, 0), |
8753 | STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL), |
8754 | STRUCT_FLD(old_name, "" ), |
8755 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
8756 | |
8757 | #define TABLESPACES_SCRUBBING_CURRENT_SCRUB_ACTIVE_THREADS 5 |
8758 | {STRUCT_FLD(field_name, "CURRENT_SCRUB_ACTIVE_THREADS" ), |
8759 | STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS), |
8760 | STRUCT_FLD(field_type, MYSQL_TYPE_LONG), |
8761 | STRUCT_FLD(value, 0), |
8762 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED | MY_I_S_MAYBE_NULL), |
8763 | STRUCT_FLD(old_name, "" ), |
8764 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
8765 | |
8766 | #define TABLESPACES_SCRUBBING_CURRENT_SCRUB_PAGE_NUMBER 6 |
8767 | {STRUCT_FLD(field_name, "CURRENT_SCRUB_PAGE_NUMBER" ), |
8768 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
8769 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
8770 | STRUCT_FLD(value, 0), |
8771 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
8772 | STRUCT_FLD(old_name, "" ), |
8773 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
8774 | |
8775 | #define TABLESPACES_SCRUBBING_CURRENT_SCRUB_MAX_PAGE_NUMBER 7 |
8776 | {STRUCT_FLD(field_name, "CURRENT_SCRUB_MAX_PAGE_NUMBER" ), |
8777 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
8778 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
8779 | STRUCT_FLD(value, 0), |
8780 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
8781 | STRUCT_FLD(old_name, "" ), |
8782 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
8783 | |
8784 | #define TABLESPACES_ENCRYPTION_ROTATING_OR_FLUSHING 9 |
8785 | {STRUCT_FLD(field_name, "ROTATING_OR_FLUSHING" ), |
8786 | STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS), |
8787 | STRUCT_FLD(field_type, MYSQL_TYPE_LONG), |
8788 | STRUCT_FLD(value, 0), |
8789 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
8790 | STRUCT_FLD(old_name, "" ), |
8791 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
8792 | |
8793 | END_OF_ST_FIELD_INFO |
8794 | }; |
8795 | |
8796 | /**********************************************************************//** |
8797 | Function to fill INFORMATION_SCHEMA.INNODB_TABLESPACES_SCRUBBING |
8798 | with information collected by scanning SYS_TABLESPACES table and |
8799 | fil_space. |
8800 | @param[in] thd Thread handle |
8801 | @param[in] space Tablespace |
8802 | @param[in] table_to_fill I_S table |
8803 | @return 0 on success */ |
8804 | static |
8805 | int |
8806 | i_s_dict_fill_tablespaces_scrubbing( |
8807 | THD* thd, |
8808 | fil_space_t* space, |
8809 | TABLE* table_to_fill) |
8810 | { |
8811 | Field** fields; |
8812 | struct fil_space_scrub_status_t status; |
8813 | |
8814 | DBUG_ENTER("i_s_dict_fill_tablespaces_scrubbing" ); |
8815 | |
8816 | fields = table_to_fill->field; |
8817 | |
8818 | fil_space_get_scrub_status(space, &status); |
8819 | |
8820 | OK(fields[TABLESPACES_SCRUBBING_SPACE]->store(space->id, true)); |
8821 | |
8822 | OK(field_store_string(fields[TABLESPACES_SCRUBBING_NAME], |
8823 | space->name)); |
8824 | |
8825 | OK(fields[TABLESPACES_SCRUBBING_COMPRESSED]->store( |
8826 | status.compressed ? 1 : 0, true)); |
8827 | |
8828 | if (status.last_scrub_completed == 0) { |
8829 | fields[TABLESPACES_SCRUBBING_LAST_SCRUB_COMPLETED]->set_null(); |
8830 | } else { |
8831 | fields[TABLESPACES_SCRUBBING_LAST_SCRUB_COMPLETED] |
8832 | ->set_notnull(); |
8833 | OK(field_store_time_t( |
8834 | fields[TABLESPACES_SCRUBBING_LAST_SCRUB_COMPLETED], |
8835 | status.last_scrub_completed)); |
8836 | } |
8837 | |
8838 | int field_numbers[] = { |
8839 | TABLESPACES_SCRUBBING_CURRENT_SCRUB_STARTED, |
8840 | TABLESPACES_SCRUBBING_CURRENT_SCRUB_ACTIVE_THREADS, |
8841 | TABLESPACES_SCRUBBING_CURRENT_SCRUB_PAGE_NUMBER, |
8842 | TABLESPACES_SCRUBBING_CURRENT_SCRUB_MAX_PAGE_NUMBER }; |
8843 | |
8844 | if (status.scrubbing) { |
8845 | for (uint i = 0; i < array_elements(field_numbers); i++) { |
8846 | fields[field_numbers[i]]->set_notnull(); |
8847 | } |
8848 | |
8849 | OK(field_store_time_t( |
8850 | fields[TABLESPACES_SCRUBBING_CURRENT_SCRUB_STARTED], |
8851 | status.current_scrub_started)); |
8852 | OK(fields[TABLESPACES_SCRUBBING_CURRENT_SCRUB_ACTIVE_THREADS] |
8853 | ->store(status.current_scrub_active_threads, true)); |
8854 | OK(fields[TABLESPACES_SCRUBBING_CURRENT_SCRUB_PAGE_NUMBER] |
8855 | ->store(status.current_scrub_page_number, true)); |
8856 | OK(fields[TABLESPACES_SCRUBBING_CURRENT_SCRUB_MAX_PAGE_NUMBER] |
8857 | ->store(status.current_scrub_max_page_number, true)); |
8858 | } else { |
8859 | for (uint i = 0; i < array_elements(field_numbers); i++) { |
8860 | fields[field_numbers[i]]->set_null(); |
8861 | } |
8862 | } |
8863 | |
8864 | OK(schema_table_store_record(thd, table_to_fill)); |
8865 | |
8866 | DBUG_RETURN(0); |
8867 | } |
8868 | /*******************************************************************//** |
8869 | Function to populate INFORMATION_SCHEMA.INNODB_TABLESPACES_SCRUBBING table. |
8870 | Loop through each record in TABLESPACES_SCRUBBING, and extract the column |
8871 | information and fill the INFORMATION_SCHEMA.INNODB_TABLESPACES_SCRUBBING table. |
8872 | @return 0 on success */ |
8873 | static |
8874 | int |
8875 | i_s_tablespaces_scrubbing_fill_table( |
8876 | /*===========================*/ |
8877 | THD* thd, /*!< in: thread */ |
8878 | TABLE_LIST* tables, /*!< in/out: tables to fill */ |
8879 | Item* ) /*!< in: condition (not used) */ |
8880 | { |
8881 | DBUG_ENTER("i_s_tablespaces_scrubbing_fill_table" ); |
8882 | RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name.str); |
8883 | |
8884 | /* deny access to user without SUPER_ACL privilege */ |
8885 | if (check_global_access(thd, SUPER_ACL)) { |
8886 | DBUG_RETURN(0); |
8887 | } |
8888 | |
8889 | mutex_enter(&fil_system.mutex); |
8890 | |
8891 | for (fil_space_t* space = UT_LIST_GET_FIRST(fil_system.space_list); |
8892 | space; space = UT_LIST_GET_NEXT(space_list, space)) { |
8893 | if (space->purpose == FIL_TYPE_TABLESPACE |
8894 | && !space->is_stopping()) { |
8895 | space->acquire(); |
8896 | mutex_exit(&fil_system.mutex); |
8897 | if (int err = i_s_dict_fill_tablespaces_scrubbing( |
8898 | thd, space, tables->table)) { |
8899 | space->release(); |
8900 | DBUG_RETURN(err); |
8901 | } |
8902 | mutex_enter(&fil_system.mutex); |
8903 | space->release(); |
8904 | } |
8905 | } |
8906 | |
8907 | mutex_exit(&fil_system.mutex); |
8908 | DBUG_RETURN(0); |
8909 | } |
8910 | /*******************************************************************//** |
8911 | Bind the dynamic table INFORMATION_SCHEMA.INNODB_TABLESPACES_SCRUBBING |
8912 | @return 0 on success */ |
8913 | static |
8914 | int |
8915 | innodb_tablespaces_scrubbing_init( |
8916 | /*========================*/ |
8917 | void* p) /*!< in/out: table schema object */ |
8918 | { |
8919 | ST_SCHEMA_TABLE* schema; |
8920 | |
8921 | DBUG_ENTER("innodb_tablespaces_scrubbing_init" ); |
8922 | |
8923 | schema = (ST_SCHEMA_TABLE*) p; |
8924 | |
8925 | schema->fields_info = innodb_tablespaces_scrubbing_fields_info; |
8926 | schema->fill_table = i_s_tablespaces_scrubbing_fill_table; |
8927 | |
8928 | DBUG_RETURN(0); |
8929 | } |
8930 | |
8931 | UNIV_INTERN struct st_maria_plugin i_s_innodb_tablespaces_scrubbing = |
8932 | { |
8933 | /* the plugin type (a MYSQL_XXX_PLUGIN value) */ |
8934 | /* int */ |
8935 | STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN), |
8936 | |
8937 | /* pointer to type-specific plugin descriptor */ |
8938 | /* void* */ |
8939 | STRUCT_FLD(info, &i_s_info), |
8940 | |
8941 | /* plugin name */ |
8942 | /* const char* */ |
8943 | STRUCT_FLD(name, "INNODB_TABLESPACES_SCRUBBING" ), |
8944 | |
8945 | /* plugin author (for SHOW PLUGINS) */ |
8946 | /* const char* */ |
8947 | STRUCT_FLD(author, "Google Inc" ), |
8948 | |
8949 | /* general descriptive text (for SHOW PLUGINS) */ |
8950 | /* const char* */ |
8951 | STRUCT_FLD(descr, "InnoDB TABLESPACES_SCRUBBING" ), |
8952 | |
8953 | /* the plugin license (PLUGIN_LICENSE_XXX) */ |
8954 | /* int */ |
8955 | STRUCT_FLD(license, PLUGIN_LICENSE_BSD), |
8956 | |
8957 | /* the function to invoke when plugin is loaded */ |
8958 | /* int (*)(void*); */ |
8959 | STRUCT_FLD(init, innodb_tablespaces_scrubbing_init), |
8960 | |
8961 | /* the function to invoke when plugin is unloaded */ |
8962 | /* int (*)(void*); */ |
8963 | STRUCT_FLD(deinit, i_s_common_deinit), |
8964 | |
8965 | /* plugin version (for SHOW PLUGINS) */ |
8966 | /* unsigned int */ |
8967 | STRUCT_FLD(version, INNODB_VERSION_SHORT), |
8968 | |
8969 | /* struct st_mysql_show_var* */ |
8970 | STRUCT_FLD(status_vars, NULL), |
8971 | |
8972 | /* struct st_mysql_sys_var** */ |
8973 | STRUCT_FLD(system_vars, NULL), |
8974 | |
8975 | /* Maria extension */ |
8976 | STRUCT_FLD(version_info, INNODB_VERSION_STR), |
8977 | STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE) |
8978 | }; |
8979 | |
8980 | /** INNODB_MUTEXES *********************************************/ |
8981 | /* Fields of the dynamic table INFORMATION_SCHEMA.INNODB_MUTEXES */ |
8982 | static ST_FIELD_INFO innodb_mutexes_fields_info[] = |
8983 | { |
8984 | #define MUTEXES_NAME 0 |
8985 | {STRUCT_FLD(field_name, "NAME" ), |
8986 | STRUCT_FLD(field_length, OS_FILE_MAX_PATH), |
8987 | STRUCT_FLD(field_type, MYSQL_TYPE_STRING), |
8988 | STRUCT_FLD(value, 0), |
8989 | STRUCT_FLD(field_flags, 0), |
8990 | STRUCT_FLD(old_name, "" ), |
8991 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
8992 | #define MUTEXES_CREATE_FILE 1 |
8993 | {STRUCT_FLD(field_name, "CREATE_FILE" ), |
8994 | STRUCT_FLD(field_length, OS_FILE_MAX_PATH), |
8995 | STRUCT_FLD(field_type, MYSQL_TYPE_STRING), |
8996 | STRUCT_FLD(value, 0), |
8997 | STRUCT_FLD(field_flags, 0), |
8998 | STRUCT_FLD(old_name, "" ), |
8999 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
9000 | #define MUTEXES_CREATE_LINE 2 |
9001 | {STRUCT_FLD(field_name, "CREATE_LINE" ), |
9002 | STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS), |
9003 | STRUCT_FLD(field_type, MYSQL_TYPE_LONG), |
9004 | STRUCT_FLD(value, 0), |
9005 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
9006 | STRUCT_FLD(old_name, "" ), |
9007 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
9008 | #define MUTEXES_OS_WAITS 3 |
9009 | {STRUCT_FLD(field_name, "OS_WAITS" ), |
9010 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
9011 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
9012 | STRUCT_FLD(value, 0), |
9013 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
9014 | STRUCT_FLD(old_name, "" ), |
9015 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
9016 | |
9017 | END_OF_ST_FIELD_INFO |
9018 | }; |
9019 | |
9020 | /*******************************************************************//** |
9021 | Function to populate INFORMATION_SCHEMA.INNODB_MUTEXES table. |
9022 | Loop through each record in mutex and rw_lock lists, and extract the column |
9023 | information and fill the INFORMATION_SCHEMA.INNODB_MUTEXES table. |
9024 | @return 0 on success */ |
9025 | static |
9026 | int |
9027 | i_s_innodb_mutexes_fill_table( |
9028 | /*==========================*/ |
9029 | THD* thd, /*!< in: thread */ |
9030 | TABLE_LIST* tables, /*!< in/out: tables to fill */ |
9031 | Item* ) /*!< in: condition (not used) */ |
9032 | { |
9033 | rw_lock_t* lock; |
9034 | ulint block_lock_oswait_count = 0; |
9035 | rw_lock_t* block_lock = NULL; |
9036 | Field** fields = tables->table->field; |
9037 | |
9038 | DBUG_ENTER("i_s_innodb_mutexes_fill_table" ); |
9039 | RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name.str); |
9040 | |
9041 | /* deny access to user without PROCESS_ACL privilege */ |
9042 | if (check_global_access(thd, PROCESS_ACL)) { |
9043 | DBUG_RETURN(0); |
9044 | } |
9045 | |
9046 | // mutex_enter(&mutex_list_mutex); |
9047 | |
9048 | #ifdef JAN_TODO_FIXME |
9049 | ib_mutex_t* mutex; |
9050 | ulint block_mutex_oswait_count = 0; |
9051 | ib_mutex_t* block_mutex = NULL; |
9052 | for (mutex = UT_LIST_GET_FIRST(os_mutex_list); mutex != NULL; |
9053 | mutex = UT_LIST_GET_NEXT(list, mutex)) { |
9054 | if (mutex->count_os_wait == 0) { |
9055 | continue; |
9056 | } |
9057 | |
9058 | if (buf_pool_is_block_mutex(mutex)) { |
9059 | block_mutex = mutex; |
9060 | block_mutex_oswait_count += mutex->count_os_wait; |
9061 | continue; |
9062 | } |
9063 | |
9064 | OK(field_store_string(fields[MUTEXES_NAME], mutex->cmutex_name)); |
9065 | OK(field_store_string(fields[MUTEXES_CREATE_FILE], innobase_basename(mutex->cfile_name))); |
9066 | OK(fields[MUTEXES_CREATE_LINE]->store(mutex->cline, true)); |
9067 | fields[MUTEXES_CREATE_LINE]->set_notnull(); |
9068 | OK(field_store_ulint(fields[MUTEXES_OS_WAITS], (longlong)mutex->count_os_wait)); |
9069 | OK(schema_table_store_record(thd, tables->table)); |
9070 | } |
9071 | |
9072 | if (block_mutex) { |
9073 | char buf1[IO_SIZE]; |
9074 | |
9075 | snprintf(buf1, sizeof buf1, "combined %s" , |
9076 | innobase_basename(block_mutex->cfile_name)); |
9077 | |
9078 | OK(field_store_string(fields[MUTEXES_NAME], block_mutex->cmutex_name)); |
9079 | OK(field_store_string(fields[MUTEXES_CREATE_FILE], buf1)); |
9080 | OK(fields[MUTEXES_CREATE_LINE]->store(block_mutex->cline, true)); |
9081 | fields[MUTEXES_CREATE_LINE]->set_notnull(); |
9082 | OK(field_store_ulint(fields[MUTEXES_OS_WAITS], (longlong)block_mutex_oswait_count)); |
9083 | OK(schema_table_store_record(thd, tables->table)); |
9084 | } |
9085 | |
9086 | mutex_exit(&mutex_list_mutex); |
9087 | #endif /* JAN_TODO_FIXME */ |
9088 | |
9089 | mutex_enter(&rw_lock_list_mutex); |
9090 | |
9091 | for (lock = UT_LIST_GET_FIRST(rw_lock_list); lock != NULL; |
9092 | lock = UT_LIST_GET_NEXT(list, lock)) { |
9093 | if (lock->count_os_wait == 0) { |
9094 | continue; |
9095 | } |
9096 | |
9097 | if (buf_pool_is_block_lock(lock)) { |
9098 | block_lock = lock; |
9099 | block_lock_oswait_count += lock->count_os_wait; |
9100 | continue; |
9101 | } |
9102 | |
9103 | //OK(field_store_string(fields[MUTEXES_NAME], lock->lock_name)); |
9104 | OK(field_store_string(fields[MUTEXES_CREATE_FILE], innobase_basename(lock->cfile_name))); |
9105 | OK(fields[MUTEXES_CREATE_LINE]->store(lock->cline, true)); |
9106 | fields[MUTEXES_CREATE_LINE]->set_notnull(); |
9107 | OK(field_store_ulint(fields[MUTEXES_OS_WAITS], (longlong)lock->count_os_wait)); |
9108 | OK(schema_table_store_record(thd, tables->table)); |
9109 | } |
9110 | |
9111 | if (block_lock) { |
9112 | char buf1[IO_SIZE]; |
9113 | |
9114 | snprintf(buf1, sizeof buf1, "combined %s" , |
9115 | innobase_basename(block_lock->cfile_name)); |
9116 | |
9117 | //OK(field_store_string(fields[MUTEXES_NAME], block_lock->lock_name)); |
9118 | OK(field_store_string(fields[MUTEXES_CREATE_FILE], buf1)); |
9119 | OK(fields[MUTEXES_CREATE_LINE]->store(block_lock->cline, true)); |
9120 | fields[MUTEXES_CREATE_LINE]->set_notnull(); |
9121 | OK(field_store_ulint(fields[MUTEXES_OS_WAITS], (longlong)block_lock_oswait_count)); |
9122 | OK(schema_table_store_record(thd, tables->table)); |
9123 | } |
9124 | |
9125 | mutex_exit(&rw_lock_list_mutex); |
9126 | |
9127 | DBUG_RETURN(0); |
9128 | } |
9129 | |
9130 | /*******************************************************************//** |
9131 | Bind the dynamic table INFORMATION_SCHEMA.INNODB_MUTEXES |
9132 | @return 0 on success */ |
9133 | static |
9134 | int |
9135 | innodb_mutexes_init( |
9136 | /*================*/ |
9137 | void* p) /*!< in/out: table schema object */ |
9138 | { |
9139 | ST_SCHEMA_TABLE* schema; |
9140 | |
9141 | DBUG_ENTER("innodb_mutexes_init" ); |
9142 | |
9143 | schema = (ST_SCHEMA_TABLE*) p; |
9144 | |
9145 | schema->fields_info = innodb_mutexes_fields_info; |
9146 | schema->fill_table = i_s_innodb_mutexes_fill_table; |
9147 | |
9148 | DBUG_RETURN(0); |
9149 | } |
9150 | |
9151 | UNIV_INTERN struct st_maria_plugin i_s_innodb_mutexes = |
9152 | { |
9153 | /* the plugin type (a MYSQL_XXX_PLUGIN value) */ |
9154 | /* int */ |
9155 | STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN), |
9156 | |
9157 | /* pointer to type-specific plugin descriptor */ |
9158 | /* void* */ |
9159 | STRUCT_FLD(info, &i_s_info), |
9160 | |
9161 | /* plugin name */ |
9162 | /* const char* */ |
9163 | STRUCT_FLD(name, "INNODB_MUTEXES" ), |
9164 | |
9165 | /* plugin author (for SHOW PLUGINS) */ |
9166 | /* const char* */ |
9167 | STRUCT_FLD(author, plugin_author), |
9168 | |
9169 | /* general descriptive text (for SHOW PLUGINS) */ |
9170 | /* const char* */ |
9171 | STRUCT_FLD(descr, "InnoDB SYS_DATAFILES" ), |
9172 | |
9173 | /* the plugin license (PLUGIN_LICENSE_XXX) */ |
9174 | /* int */ |
9175 | STRUCT_FLD(license, PLUGIN_LICENSE_GPL), |
9176 | |
9177 | /* the function to invoke when plugin is loaded */ |
9178 | /* int (*)(void*); */ |
9179 | STRUCT_FLD(init, innodb_mutexes_init), |
9180 | |
9181 | /* the function to invoke when plugin is unloaded */ |
9182 | /* int (*)(void*); */ |
9183 | STRUCT_FLD(deinit, i_s_common_deinit), |
9184 | |
9185 | /* plugin version (for SHOW PLUGINS) */ |
9186 | /* unsigned int */ |
9187 | STRUCT_FLD(version, INNODB_VERSION_SHORT), |
9188 | |
9189 | /* struct st_mysql_show_var* */ |
9190 | STRUCT_FLD(status_vars, NULL), |
9191 | |
9192 | /* struct st_mysql_sys_var** */ |
9193 | STRUCT_FLD(system_vars, NULL), |
9194 | |
9195 | /* Maria extension */ |
9196 | STRUCT_FLD(version_info, INNODB_VERSION_STR), |
9197 | STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE), |
9198 | }; |
9199 | |
9200 | /** SYS_SEMAPHORE_WAITS ************************************************/ |
9201 | /* Fields of the dynamic table INFORMATION_SCHEMA.INNODB_SYS_SEMAPHORE_WAITS */ |
9202 | static ST_FIELD_INFO innodb_sys_semaphore_waits_fields_info[] = |
9203 | { |
9204 | // SYS_SEMAPHORE_WAITS_THREAD_ID 0 |
9205 | {STRUCT_FLD(field_name, "THREAD_ID" ), |
9206 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
9207 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
9208 | STRUCT_FLD(value, 0), |
9209 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
9210 | STRUCT_FLD(old_name, "" ), |
9211 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
9212 | |
9213 | // SYS_SEMAPHORE_WAITS_OBJECT_NAME 1 |
9214 | {STRUCT_FLD(field_name, "OBJECT_NAME" ), |
9215 | STRUCT_FLD(field_length, OS_FILE_MAX_PATH), |
9216 | STRUCT_FLD(field_type, MYSQL_TYPE_STRING), |
9217 | STRUCT_FLD(value, 0), |
9218 | STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL), |
9219 | STRUCT_FLD(old_name, "" ), |
9220 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
9221 | |
9222 | // SYS_SEMAPHORE_WAITS_FILE 2 |
9223 | {STRUCT_FLD(field_name, "FILE" ), |
9224 | STRUCT_FLD(field_length, OS_FILE_MAX_PATH), |
9225 | STRUCT_FLD(field_type, MYSQL_TYPE_STRING), |
9226 | STRUCT_FLD(value, 0), |
9227 | STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL), |
9228 | STRUCT_FLD(old_name, "" ), |
9229 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
9230 | |
9231 | // SYS_SEMAPHORE_WAITS_LINE 3 |
9232 | {STRUCT_FLD(field_name, "LINE" ), |
9233 | STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS), |
9234 | STRUCT_FLD(field_type, MYSQL_TYPE_LONG), |
9235 | STRUCT_FLD(value, 0), |
9236 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
9237 | STRUCT_FLD(old_name, "" ), |
9238 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
9239 | |
9240 | // SYS_SEMAPHORE_WAITS_WAIT_TIME 4 |
9241 | {STRUCT_FLD(field_name, "WAIT_TIME" ), |
9242 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
9243 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
9244 | STRUCT_FLD(value, 0), |
9245 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
9246 | STRUCT_FLD(old_name, "" ), |
9247 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
9248 | |
9249 | // SYS_SEMAPHORE_WAITS_WAIT_OBJECT 5 |
9250 | {STRUCT_FLD(field_name, "WAIT_OBJECT" ), |
9251 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
9252 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
9253 | STRUCT_FLD(value, 0), |
9254 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
9255 | STRUCT_FLD(old_name, "" ), |
9256 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
9257 | |
9258 | // SYS_SEMAPHORE_WAITS_WAIT_TYPE 6 |
9259 | {STRUCT_FLD(field_name, "WAIT_TYPE" ), |
9260 | STRUCT_FLD(field_length, 16), |
9261 | STRUCT_FLD(field_type, MYSQL_TYPE_STRING), |
9262 | STRUCT_FLD(value, 0), |
9263 | STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL), |
9264 | STRUCT_FLD(old_name, "" ), |
9265 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
9266 | |
9267 | // SYS_SEMAPHORE_WAITS_HOLDER_THREAD_ID 7 |
9268 | {STRUCT_FLD(field_name, "HOLDER_THREAD_ID" ), |
9269 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
9270 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
9271 | STRUCT_FLD(value, 0), |
9272 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
9273 | STRUCT_FLD(old_name, "" ), |
9274 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
9275 | |
9276 | // SYS_SEMAPHORE_WAITS_HOLDER_FILE 8 |
9277 | {STRUCT_FLD(field_name, "HOLDER_FILE" ), |
9278 | STRUCT_FLD(field_length, OS_FILE_MAX_PATH), |
9279 | STRUCT_FLD(field_type, MYSQL_TYPE_STRING), |
9280 | STRUCT_FLD(value, 0), |
9281 | STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL), |
9282 | STRUCT_FLD(old_name, "" ), |
9283 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
9284 | |
9285 | // SYS_SEMAPHORE_WAITS_HOLDER_LINE 9 |
9286 | {STRUCT_FLD(field_name, "HOLDER_LINE" ), |
9287 | STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS), |
9288 | STRUCT_FLD(field_type, MYSQL_TYPE_LONG), |
9289 | STRUCT_FLD(value, 0), |
9290 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
9291 | STRUCT_FLD(old_name, "" ), |
9292 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
9293 | |
9294 | // SYS_SEMAPHORE_WAITS_CREATED_FILE 10 |
9295 | {STRUCT_FLD(field_name, "CREATED_FILE" ), |
9296 | STRUCT_FLD(field_length, OS_FILE_MAX_PATH), |
9297 | STRUCT_FLD(field_type, MYSQL_TYPE_STRING), |
9298 | STRUCT_FLD(value, 0), |
9299 | STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL), |
9300 | STRUCT_FLD(old_name, "" ), |
9301 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
9302 | |
9303 | // SYS_SEMAPHORE_WAITS_CREATED_LINE 11 |
9304 | {STRUCT_FLD(field_name, "CREATED_LINE" ), |
9305 | STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS), |
9306 | STRUCT_FLD(field_type, MYSQL_TYPE_LONG), |
9307 | STRUCT_FLD(value, 0), |
9308 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
9309 | STRUCT_FLD(old_name, "" ), |
9310 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
9311 | |
9312 | // SYS_SEMAPHORE_WAITS_WRITER_THREAD 12 |
9313 | {STRUCT_FLD(field_name, "WRITER_THREAD" ), |
9314 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
9315 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
9316 | STRUCT_FLD(value, 0), |
9317 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
9318 | STRUCT_FLD(old_name, "" ), |
9319 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
9320 | |
9321 | // SYS_SEMAPHORE_WAITS_RESERVATION_MODE 13 |
9322 | {STRUCT_FLD(field_name, "RESERVATION_MODE" ), |
9323 | STRUCT_FLD(field_length, 16), |
9324 | STRUCT_FLD(field_type, MYSQL_TYPE_STRING), |
9325 | STRUCT_FLD(value, 0), |
9326 | STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL), |
9327 | STRUCT_FLD(old_name, "" ), |
9328 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
9329 | |
9330 | // SYS_SEMAPHORE_WAITS_READERS 14 |
9331 | {STRUCT_FLD(field_name, "READERS" ), |
9332 | STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS), |
9333 | STRUCT_FLD(field_type, MYSQL_TYPE_LONG), |
9334 | STRUCT_FLD(value, 0), |
9335 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
9336 | STRUCT_FLD(old_name, "" ), |
9337 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
9338 | |
9339 | // SYS_SEMAPHORE_WAITS_WAITERS_FLAG 15 |
9340 | {STRUCT_FLD(field_name, "WAITERS_FLAG" ), |
9341 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
9342 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
9343 | STRUCT_FLD(value, 0), |
9344 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
9345 | STRUCT_FLD(old_name, "" ), |
9346 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
9347 | |
9348 | // SYS_SEMAPHORE_WAITS_LOCK_WORD 16 |
9349 | {STRUCT_FLD(field_name, "LOCK_WORD" ), |
9350 | STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), |
9351 | STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), |
9352 | STRUCT_FLD(value, 0), |
9353 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
9354 | STRUCT_FLD(old_name, "" ), |
9355 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
9356 | |
9357 | // SYS_SEMAPHORE_WAITS_LAST_WRITER_FILE 17 |
9358 | {STRUCT_FLD(field_name, "LAST_WRITER_FILE" ), |
9359 | STRUCT_FLD(field_length, OS_FILE_MAX_PATH), |
9360 | STRUCT_FLD(field_type, MYSQL_TYPE_STRING), |
9361 | STRUCT_FLD(value, 0), |
9362 | STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL), |
9363 | STRUCT_FLD(old_name, "" ), |
9364 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
9365 | |
9366 | // SYS_SEMAPHORE_WAITS_LAST_WRITER_LINE 18 |
9367 | {STRUCT_FLD(field_name, "LAST_WRITER_LINE" ), |
9368 | STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS), |
9369 | STRUCT_FLD(field_type, MYSQL_TYPE_LONG), |
9370 | STRUCT_FLD(value, 0), |
9371 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
9372 | STRUCT_FLD(old_name, "" ), |
9373 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
9374 | |
9375 | // SYS_SEMAPHORE_WAITS_OS_WAIT_COUNT 19 |
9376 | {STRUCT_FLD(field_name, "OS_WAIT_COUNT" ), |
9377 | STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS), |
9378 | STRUCT_FLD(field_type, MYSQL_TYPE_LONG), |
9379 | STRUCT_FLD(value, 0), |
9380 | STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), |
9381 | STRUCT_FLD(old_name, "" ), |
9382 | STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, |
9383 | |
9384 | END_OF_ST_FIELD_INFO |
9385 | }; |
9386 | |
9387 | |
9388 | |
9389 | /*******************************************************************//** |
9390 | Bind the dynamic table INFORMATION_SCHEMA.INNODB_SYS_SEMAPHORE_WAITS |
9391 | @return 0 on success */ |
9392 | static |
9393 | int |
9394 | innodb_sys_semaphore_waits_init( |
9395 | /*============================*/ |
9396 | void* p) /*!< in/out: table schema object */ |
9397 | { |
9398 | ST_SCHEMA_TABLE* schema; |
9399 | |
9400 | DBUG_ENTER("innodb_sys_semaphore_waits_init" ); |
9401 | |
9402 | schema = (ST_SCHEMA_TABLE*) p; |
9403 | |
9404 | schema->fields_info = innodb_sys_semaphore_waits_fields_info; |
9405 | schema->fill_table = sync_arr_fill_sys_semphore_waits_table; |
9406 | |
9407 | DBUG_RETURN(0); |
9408 | } |
9409 | |
9410 | UNIV_INTERN struct st_maria_plugin i_s_innodb_sys_semaphore_waits = |
9411 | { |
9412 | /* the plugin type (a MYSQL_XXX_PLUGIN value) */ |
9413 | /* int */ |
9414 | STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN), |
9415 | |
9416 | /* pointer to type-specific plugin descriptor */ |
9417 | /* void* */ |
9418 | STRUCT_FLD(info, &i_s_info), |
9419 | |
9420 | /* plugin name */ |
9421 | /* const char* */ |
9422 | STRUCT_FLD(name, "INNODB_SYS_SEMAPHORE_WAITS" ), |
9423 | |
9424 | /* plugin author (for SHOW PLUGINS) */ |
9425 | /* const char* */ |
9426 | STRUCT_FLD(author, maria_plugin_author), |
9427 | |
9428 | /* general descriptive text (for SHOW PLUGINS) */ |
9429 | /* const char* */ |
9430 | STRUCT_FLD(descr, "InnoDB SYS_SEMAPHORE_WAITS" ), |
9431 | |
9432 | /* the plugin license (PLUGIN_LICENSE_XXX) */ |
9433 | /* int */ |
9434 | STRUCT_FLD(license, PLUGIN_LICENSE_GPL), |
9435 | |
9436 | /* the function to invoke when plugin is loaded */ |
9437 | /* int (*)(void*); */ |
9438 | STRUCT_FLD(init, innodb_sys_semaphore_waits_init), |
9439 | |
9440 | /* the function to invoke when plugin is unloaded */ |
9441 | /* int (*)(void*); */ |
9442 | STRUCT_FLD(deinit, i_s_common_deinit), |
9443 | |
9444 | /* plugin version (for SHOW PLUGINS) */ |
9445 | /* unsigned int */ |
9446 | STRUCT_FLD(version, INNODB_VERSION_SHORT), |
9447 | |
9448 | /* struct st_mysql_show_var* */ |
9449 | STRUCT_FLD(status_vars, NULL), |
9450 | |
9451 | /* struct st_mysql_sys_var** */ |
9452 | STRUCT_FLD(system_vars, NULL), |
9453 | |
9454 | /* Maria extension */ |
9455 | STRUCT_FLD(version_info, INNODB_VERSION_STR), |
9456 | STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE), |
9457 | }; |
9458 | |