1
/*****************************************************************************
3
Copyright (c) 2007, 2009, Innobase Oy. All Rights Reserved.
5
This program is free software; you can redistribute it and/or modify it under
6
the terms of the GNU General Public License as published by the Free Software
7
Foundation; version 2 of the License.
9
This program is distributed in the hope that it will be useful, but WITHOUT
10
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
13
You should have received a copy of the GNU General Public License along with
14
this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
15
St, Fifth Floor, Boston, MA 02110-1301 USA
17
*****************************************************************************/
21
#include "data_dictionary.h"
23
#include "drizzled/current_session.h"
27
#include "trx0trx.h" /* for TRX_QUE_STATE_STR_MAX_LEN */
28
#include "buf0buddy.h" /* for i_s_cmpmem */
29
#include "buf0buf.h" /* for buf_pool and PAGE_ZIP_MIN_SIZE */
30
#include "ha_prototypes.h" /* for innobase_convert_name() */
31
#include "srv0start.h" /* for srv_was_started */
32
#include "btr0pcur.h" /* for file sys_tables related info. */
33
#include "btr0types.h"
34
#include "dict0load.h" /* for file sys_tables related info. */
36
#include "dict0types.h"
38
#include "handler0vars.h"
40
using namespace drizzled;
42
InnodbSysTablesTool::InnodbSysTablesTool() :
43
plugin::TableFunction("DATA_DICTIONARY", "INNODB_SYS_TABLES")
45
add_field("TABLE_ID", plugin::TableFunction::NUMBER, 0, false);
46
add_field("NAME", plugin::TableFunction::STRING, NAME_LEN + 1, false);
47
add_field("FLAG", plugin::TableFunction::NUMBER, 0, false);
48
add_field("N_COLS", plugin::TableFunction::NUMBER, 0, false);
49
add_field("SPACE", plugin::TableFunction::NUMBER, 0, false);
52
InnodbSysTablesTool::Generator::Generator(Field **arg) :
53
plugin::TableFunction::Generator(arg)
58
bool InnodbSysTablesTool::Generator::populate()
62
heap = mem_heap_create(1000);
63
mutex_enter(&(dict_sys->mutex));
66
rec = dict_startscan_system(&pcur, &mtr, SYS_TABLES);
70
/* Get the next record */
71
mutex_enter(&dict_sys->mutex);
73
rec = dict_getnext_system(&pcur, &mtr);
79
mutex_exit(&dict_sys->mutex);
85
dict_table_t* table_rec;
87
/* Create and populate a dict_table_t structure with
88
information from SYS_TABLES row */
89
err_msg = dict_process_sys_tables_rec(heap, rec, &table_rec,
90
DICT_TABLE_LOAD_FROM_RECORD);
93
mutex_exit(&dict_sys->mutex);
97
push(table_rec->name);
98
push(static_cast<uint64_t>(table_rec->flags));
99
push(static_cast<uint64_t>(table_rec->n_cols));
100
push(static_cast<uint64_t>(table_rec->space));
102
/* push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
103
ER_CANT_FIND_SYSTEM_REC,
107
/* Since dict_process_sys_tables_rec() is called with
108
DICT_TABLE_LOAD_FROM_RECORD, the table_rec is created in
109
dict_process_sys_tables_rec(), we will need to free it */
111
dict_mem_table_free(table_rec);
114
mem_heap_empty(heap);
119
InnodbSysTableStatsTool::InnodbSysTableStatsTool() :
120
plugin::TableFunction("DATA_DICTIONARY", "INNODB_SYS_TABLESTATS")
122
add_field("TABLE_ID", plugin::TableFunction::NUMBER, 0, false);
123
add_field("NAME", plugin::TableFunction::STRING, NAME_LEN + 1, false);
124
add_field("STATS_INITIALIZED", plugin::TableFunction::STRING, NAME_LEN + 1, false);
125
add_field("NUM_ROWS", plugin::TableFunction::NUMBER, 0, false);
126
add_field("CLUST_INDEX_SIZE", plugin::TableFunction::NUMBER, 0, false);
127
add_field("OTHER_INDEX_SIZE", plugin::TableFunction::NUMBER, 0, false);
128
add_field("MODIFIED_COUNTER", plugin::TableFunction::NUMBER, 0, false);
129
add_field("AUTOINC", plugin::TableFunction::NUMBER, 0, false);
130
add_field("HANDLES_OPENED", plugin::TableFunction::NUMBER, 0, false);
133
InnodbSysTableStatsTool::Generator::Generator(Field **arg) :
134
plugin::TableFunction::Generator(arg)
139
bool InnodbSysTableStatsTool::Generator::populate()
143
heap = mem_heap_create(1000);
144
mutex_enter(&dict_sys->mutex);
146
rec = dict_startscan_system(&pcur, &mtr, SYS_TABLES);
150
/* Get the next record */
151
mutex_enter(&dict_sys->mutex);
153
rec = dict_getnext_system(&pcur, &mtr);
159
mutex_exit(&dict_sys->mutex);
165
dict_table_t* table_rec;
167
/* Fetch the dict_table_t structure corresponding to
168
this SYS_TABLES record */
169
err_msg = dict_process_sys_tables_rec(heap, rec, &table_rec,
170
DICT_TABLE_LOAD_FROM_CACHE);
173
mutex_exit(&dict_sys->mutex);
177
push(table_rec->name);
178
if (table_rec->stat_initialized)
181
push("Uninitialized");
182
push(table_rec->stat_n_rows);
183
push(static_cast<uint64_t>(table_rec->stat_clustered_index_size));
184
push(static_cast<uint64_t>(table_rec->stat_sum_of_other_index_sizes));
185
push(static_cast<uint64_t>(table_rec->stat_modified_counter));
186
push(table_rec->autoinc);
187
push(static_cast<uint64_t>(table_rec->n_mysql_handles_opened));
189
/* push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
190
ER_CANT_FIND_SYSTEM_REC,
194
mem_heap_empty(heap);
199
InnodbSysIndexesTool::InnodbSysIndexesTool() :
200
plugin::TableFunction("DATA_DICTIONARY", "INNODB_SYS_INDEXES")
202
add_field("INDEX_ID", plugin::TableFunction::NUMBER, 0, false);
203
add_field("NAME", plugin::TableFunction::STRING, NAME_LEN + 1, false);
204
add_field("TABLE_ID", plugin::TableFunction::NUMBER, 0, false);
205
add_field("TYPE", plugin::TableFunction::NUMBER, 0, false);
206
add_field("N_FIELDS", plugin::TableFunction::NUMBER, 0, false);
207
add_field("PAGE_NO", plugin::TableFunction::NUMBER, 0, false);
208
add_field("SPACE", plugin::TableFunction::NUMBER, 0, false);
211
InnodbSysIndexesTool::Generator::Generator(Field **arg) :
212
plugin::TableFunction::Generator(arg)
217
bool InnodbSysIndexesTool::Generator::populate()
221
heap = mem_heap_create(1000);
222
mutex_enter(&dict_sys->mutex);
225
/* Start scan the SYS_INDEXES table */
226
rec = dict_startscan_system(&pcur, &mtr, SYS_INDEXES);
230
/* Get the next record */
231
mutex_enter(&dict_sys->mutex);
233
rec = dict_getnext_system(&pcur, &mtr);
239
mutex_exit(&dict_sys->mutex);
244
const char* err_msg;;
246
dict_index_t index_rec;
248
/* Populate a dict_index_t structure with information from
250
err_msg = dict_process_sys_indexes_rec(heap, rec, &index_rec,
254
mutex_exit(&dict_sys->mutex);
257
push(index_rec.name);
258
push(static_cast<uint64_t>(table_id));
259
push(static_cast<uint64_t>(index_rec.type));
260
push(static_cast<uint64_t>(index_rec.n_fields));
261
push(static_cast<uint64_t>(index_rec.page));
262
push(static_cast<uint64_t>(index_rec.space));
264
/* push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
265
ER_CANT_FIND_SYSTEM_REC,
269
mem_heap_empty(heap);
274
mutex_exit(&dict_sys->mutex);
282
InnodbSysColumnsTool::InnodbSysColumnsTool() :
283
plugin::TableFunction("DATA_DICTIONARY", "INNODB_SYS_COLUMNS")
285
add_field("TABLE_ID", plugin::TableFunction::NUMBER, 0, false);
286
add_field("NAME", plugin::TableFunction::STRING, NAME_LEN + 1, false);
287
add_field("POS", plugin::TableFunction::NUMBER, 0, false);
288
add_field("MTYPE", plugin::TableFunction::NUMBER, 0, false);
289
add_field("PRTYPE", plugin::TableFunction::NUMBER, 0, false);
290
add_field("LEN", plugin::TableFunction::NUMBER, 0, false);
293
InnodbSysColumnsTool::Generator::Generator(Field **arg) :
294
plugin::TableFunction::Generator(arg)
299
bool InnodbSysColumnsTool::Generator::populate()
303
heap = mem_heap_create(1000);
304
mutex_enter(&dict_sys->mutex);
306
rec = dict_startscan_system(&pcur, &mtr, SYS_COLUMNS);
310
/* Get the next record */
311
mutex_enter(&dict_sys->mutex);
313
rec = dict_getnext_system(&pcur, &mtr);
319
mutex_exit(&dict_sys->mutex);
325
dict_col_t column_rec;
327
const char* col_name;
329
/* populate a dict_col_t structure with information from
331
err_msg = dict_process_sys_columns_rec(heap, rec, &column_rec,
332
&table_id, &col_name);
335
mutex_exit(&dict_sys->mutex);
340
push(static_cast<uint64_t>(column_rec.ind));
341
push(static_cast<uint64_t>(column_rec.mtype));
342
push(static_cast<uint64_t>(column_rec.prtype));
343
push(static_cast<uint64_t>(column_rec.len));
345
/* push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
346
ER_CANT_FIND_SYSTEM_REC,
350
mem_heap_empty(heap);
355
InnodbSysFieldsTool::InnodbSysFieldsTool() :
356
plugin::TableFunction("DATA_DICTIONARY", "INNODB_SYS_FIELDS")
358
add_field("INDEX_ID", plugin::TableFunction::NUMBER, 0, false);
359
add_field("NAME", plugin::TableFunction::STRING, NAME_LEN + 1, false);
360
add_field("POS", plugin::TableFunction::NUMBER, 0, false);
363
InnodbSysFieldsTool::Generator::Generator(Field **arg) :
364
plugin::TableFunction::Generator(arg)
369
bool InnodbSysFieldsTool::Generator::populate()
373
heap = mem_heap_create(1000);
374
mutex_enter(&dict_sys->mutex);
377
/* will save last index id so that we know whether we move to
378
the next index. This is used to calculate prefix length */
381
rec = dict_startscan_system(&pcur, &mtr, SYS_FIELDS);
385
/* Get the next record */
386
mutex_enter(&dict_sys->mutex);
388
rec = dict_getnext_system(&pcur, &mtr);
394
mutex_exit(&dict_sys->mutex);
403
dict_field_t field_rec;
405
/* Populate a dict_field_t structure with information from
407
err_msg = dict_process_sys_fields_rec(heap, rec, &field_rec,
408
&pos, &index_id, last_id);
411
mutex_exit(&dict_sys->mutex);
415
push(field_rec.name);
416
push(static_cast<uint64_t>(pos));
420
/* push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
421
ER_CANT_FIND_SYSTEM_REC,
425
mem_heap_empty(heap);
430
InnodbSysForeignTool::InnodbSysForeignTool() :
431
plugin::TableFunction("DATA_DICTIONARY", "INNODB_SYS_FOREIGN")
433
add_field("ID", plugin::TableFunction::STRING, NAME_LEN + 1, false);
434
add_field("FOR_NAME", plugin::TableFunction::STRING, NAME_LEN + 1, false);
435
add_field("REF_NAME", plugin::TableFunction::STRING, NAME_LEN + 1, false);
436
add_field("N_COLS", plugin::TableFunction::NUMBER, 0, false);
437
add_field("TYPE", plugin::TableFunction::NUMBER, 0, false);
440
InnodbSysForeignTool::Generator::Generator(Field **arg) :
441
plugin::TableFunction::Generator(arg)
446
bool InnodbSysForeignTool::Generator::populate()
450
heap = mem_heap_create(1000);
451
mutex_enter(&dict_sys->mutex);
454
rec = dict_startscan_system(&pcur, &mtr, SYS_FOREIGN);
458
/* Get the next record */
460
mutex_enter(&dict_sys->mutex);
461
rec = dict_getnext_system(&pcur, &mtr);
467
mutex_exit(&dict_sys->mutex);
473
dict_foreign_t foreign_rec;
475
/* Populate a dict_foreign_t structure with information from
477
err_msg = dict_process_sys_foreign_rec(heap, rec, &foreign_rec);
480
mutex_exit(&dict_sys->mutex);
483
push(foreign_rec.id);
484
push(foreign_rec.foreign_table_name);
485
push(foreign_rec.referenced_table_name);
486
push(static_cast<uint64_t>(foreign_rec.n_fields));
487
push(static_cast<uint64_t>(foreign_rec.type));
489
/* push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
490
ER_CANT_FIND_SYSTEM_REC,
494
mem_heap_empty(heap);
499
InnodbSysForeignColsTool::InnodbSysForeignColsTool() :
500
plugin::TableFunction("DATA_DICTIONARY", "INNODB_SYS_FOREIGN_COLS")
502
add_field("ID", plugin::TableFunction::STRING, NAME_LEN + 1, false);
503
add_field("FOR_COL_NAME", plugin::TableFunction::STRING, NAME_LEN + 1, false);
504
add_field("REF_COL_NAME", plugin::TableFunction::STRING, NAME_LEN + 1, false);
505
add_field("POS", plugin::TableFunction::NUMBER, 0, false);
508
InnodbSysForeignColsTool::Generator::Generator(Field **arg) :
509
plugin::TableFunction::Generator(arg)
514
bool InnodbSysForeignColsTool::Generator::populate()
518
heap = mem_heap_create(1000);
519
mutex_enter(&dict_sys->mutex);
522
rec = dict_startscan_system(&pcur, &mtr, SYS_FOREIGN_COLS);
526
/* Get the next record */
527
mutex_enter(&dict_sys->mutex);
529
rec = dict_getnext_system(&pcur, &mtr);
535
mutex_exit(&dict_sys->mutex);
543
const char* for_col_name;
544
const char* ref_col_name;
547
/* Extract necessary information from a SYS_FOREIGN_COLS row */
548
err_msg = dict_process_sys_foreign_col_rec(heap, rec, &name, &for_col_name,
549
&ref_col_name, &pos);
552
mutex_exit(&dict_sys->mutex);
558
push(static_cast<uint64_t>(pos));
560
/* push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
561
ER_CANT_FIND_SYSTEM_REC,
566
mem_heap_empty(heap);
572
* Fill the dynamic table data_dictionary.INNODB_CMP and INNODB_CMP_RESET
575
CmpTool::CmpTool(bool in_reset) :
576
plugin::TableFunction("DATA_DICTIONARY", in_reset ? "INNODB_CMP_RESET" : "INNODB_CMP"),
577
outer_reset(in_reset)
579
add_field("PAGE_SIZE", plugin::TableFunction::NUMBER, 0, false);
580
add_field("COMPRESS_OPS", plugin::TableFunction::NUMBER, 0, false);
581
add_field("COMPRESS_OPS_OK", plugin::TableFunction::NUMBER, 0, false);
582
add_field("COMPRESS_TIME", plugin::TableFunction::NUMBER, 0, false);
583
add_field("UNCOMPRESS_OPS", plugin::TableFunction::NUMBER, 0, false);
584
add_field("UNCOMPRESS_TIME", plugin::TableFunction::NUMBER, 0, false);
587
CmpTool::Generator::Generator(Field **arg, bool in_reset) :
588
plugin::TableFunction::Generator(arg),
590
inner_reset(in_reset)
594
bool CmpTool::Generator::populate()
596
if (record_number == (PAGE_ZIP_NUM_SSIZE - 1))
601
page_zip_stat_t* zip_stat = &page_zip_stat[record_number];
603
push(static_cast<uint64_t>(PAGE_ZIP_MIN_SIZE << record_number));
605
/* The cumulated counts are not protected by any
606
mutex. Thus, some operation in page0zip.c could
607
increment a counter between the time we read it and
608
clear it. We could introduce mutex protection, but it
609
could cause a measureable performance hit in
611
push(static_cast<uint64_t>(zip_stat->compressed));
612
push(static_cast<uint64_t>(zip_stat->compressed_ok));
613
push(zip_stat->compressed_usec / 1000000);
614
push(static_cast<uint64_t>(zip_stat->decompressed));
615
push(zip_stat->decompressed_usec / 1000000);
619
memset(zip_stat, 0, sizeof *zip_stat);
628
* Fill the dynamic table data_dictionary.INNODB_CMPMEM and INNODB_CMPMEM_RESET
631
CmpmemTool::CmpmemTool(bool in_reset) :
632
plugin::TableFunction("DATA_DICTIONARY", in_reset ? "INNODB_CMPMEM_RESET" : "INNODB_CMPMEM"),
633
outer_reset(in_reset)
635
add_field("BUF_POOL", plugin::TableFunction::NUMBER, 0, false);
636
add_field("PAGE_SIZE", plugin::TableFunction::NUMBER, 0, false);
637
add_field("PAGES_USED", plugin::TableFunction::NUMBER, 0, false);
638
add_field("PAGES_FREE", plugin::TableFunction::NUMBER, 0, false);
639
add_field("RELOCATION_OPS", plugin::TableFunction::NUMBER, 0, false);
640
add_field("RELOCATION_TIME", plugin::TableFunction::NUMBER, 0, false);
643
CmpmemTool::Generator::Generator(Field **arg, bool in_reset) :
644
plugin::TableFunction::Generator(arg),
646
inner_reset(in_reset)
650
CmpmemTool::Generator::~Generator()
654
bool CmpmemTool::Generator::populate()
656
if (record_number >= (BUF_BUDDY_SIZES+1)*srv_buf_pool_instances)
661
uint32_t buddy_nr= record_number % (BUF_BUDDY_SIZES+1);
662
uint32_t buf_pool_nr= (record_number/(BUF_BUDDY_SIZES+1));
664
buf_pool_t *buf_pool= buf_pool_from_array(buf_pool_nr);
666
buf_pool_mutex_enter(buf_pool);
668
buf_buddy_stat_t* buddy_stat = &buf_pool->buddy_stat[buddy_nr];
671
push(static_cast<uint64_t>(buf_pool_nr));
672
push(static_cast<uint64_t>(BUF_BUDDY_LOW << buddy_nr));
673
push(static_cast<uint64_t>(buddy_stat->used));
676
uint64_t pages_free= (UNIV_LIKELY(buddy_nr < BUF_BUDDY_SIZES) ? UT_LIST_GET_LEN(buf_pool->zip_free[buddy_nr]) : 0);
679
push(buddy_stat->relocated);
680
push(buddy_stat->relocated_usec / 1000000);
685
buddy_stat->relocated = 0;
686
buddy_stat->relocated_usec = 0;
689
buf_pool_mutex_exit(buf_pool);
696
* Fill the dynamic table data_dictionary.INNODB_TRX INNODB_LOCKS INNODB_LOCK_WAITS
699
InnodbTrxTool::InnodbTrxTool(const char* in_table_name) :
700
plugin::TableFunction("DATA_DICTIONARY", in_table_name),
701
table_name(in_table_name)
703
if (innobase_strcasecmp(table_name, "INNODB_TRX") == 0)
706
add_field("TRX_STATE");
707
add_field("TRX_STARTED", plugin::TableFunction::NUMBER, 0, false);
708
add_field("TRX_REQUESTED_LOCK_ID");
709
add_field("TRX_WAIT_STARTED", plugin::TableFunction::NUMBER, 0, false);
710
add_field("TRX_WEIGHT", plugin::TableFunction::NUMBER, 0, false);
711
add_field("TRX_DRIZZLE_THREAD_ID", plugin::TableFunction::NUMBER, 0, false);
712
add_field("TRX_QUERY", plugin::TableFunction::STRING, TRX_I_S_TRX_QUERY_MAX_LEN, true);
713
add_field("TRX_OPERATION_STATE", plugin::TableFunction::STRING, TRX_I_S_TRX_OP_STATE_MAX_LEN, true);
714
// add_field("TRX_TABLES_IN_USE", plugin::TableFunction::NUMBER, 0, false);
715
add_field("TRX_TABLES_LOCKED", plugin::TableFunction::NUMBER, 0, false);
716
add_field("TRX_LOCK_STRUCTS", plugin::TableFunction::NUMBER, 0, false);
717
add_field("TRX_LOCK_MEMORY_BYTES", plugin::TableFunction::NUMBER, 0, false);
718
add_field("TRX_ROWS_LOCKED", plugin::TableFunction::NUMBER, 0, false);
719
add_field("TRX_ROWS_MODIFIED", plugin::TableFunction::NUMBER, 0, false);
720
add_field("TRX_CONCURRENCY_TICKETS", plugin::TableFunction::NUMBER, 0, false);
721
add_field("TRX_ISOLATION_LEVEL", plugin::TableFunction::STRING, TRX_I_S_TRX_ISOLATION_LEVEL_MAX_LEN, false);
722
add_field("TRX_UNIQUE_CHECKS", plugin::TableFunction::NUMBER, 0, false);
723
add_field("TRX_FOREIGN_KEY_CHECKS", plugin::TableFunction::NUMBER, 0, false);
724
add_field("TRX_LAST_FOREIGN_KEY_ERROR", plugin::TableFunction::STRING,
725
TRX_I_S_TRX_FK_ERROR_MAX_LEN, true);
726
add_field("TRX_ADAPTIVE_HASH_LATCHED", plugin::TableFunction::NUMBER, 0, false);
727
add_field("TRX_ADAPTIVE_HASH_TIMEOUT", plugin::TableFunction::NUMBER, 0, false);
729
else if (innobase_strcasecmp(table_name, "INNODB_LOCKS") == 0)
731
add_field("LOCK_ID");
732
add_field("LOCK_TRX_ID");
733
add_field("LOCK_MODE");
734
add_field("LOCK_TYPE");
735
add_field("LOCK_TABLE");
736
add_field("LOCK_INDEX");
737
add_field("LOCK_SPACE", plugin::TableFunction::NUMBER, 0, false);
738
add_field("LOCK_PAGE", plugin::TableFunction::NUMBER, 0, false);
739
add_field("LOCK_REC", plugin::TableFunction::NUMBER, 0, false);
740
add_field("LOCK_DATA");
742
else if (innobase_strcasecmp(table_name, "INNODB_LOCK_WAITS") == 0)
744
add_field("REQUESTING_TRX_ID");
745
add_field("REQUESTED_LOCK_ID");
746
add_field("BLOCKING_TRX_ID");
747
add_field("BLOCKING_LOCK_ID");
751
InnodbTrxTool::Generator::Generator(Field **arg, const char* in_table_name) :
752
plugin::TableFunction::Generator(arg),
753
table_name(in_table_name)
755
/* update the cache */
756
trx_i_s_cache_start_write(trx_i_s_cache);
757
trx_i_s_possibly_fetch_data_into_cache(trx_i_s_cache);
758
trx_i_s_cache_end_write(trx_i_s_cache);
760
if (trx_i_s_cache_is_truncated(trx_i_s_cache))
762
errmsg_printf(ERRMSG_LVL_ERROR, _("Warning: data in %s truncated due to memory limit of %d bytes\n"),
763
table_name, TRX_I_S_MEM_LIMIT);
766
trx_i_s_cache_start_read(trx_i_s_cache);
768
if (innobase_strcasecmp(table_name, "INNODB_TRX") == 0)
769
number_rows= trx_i_s_cache_get_rows_used(trx_i_s_cache, I_S_INNODB_TRX);
770
else if (innobase_strcasecmp(table_name, "INNODB_LOCKS") == 0)
771
number_rows= trx_i_s_cache_get_rows_used(trx_i_s_cache, I_S_INNODB_LOCKS);
772
else if (innobase_strcasecmp(table_name, "INNODB_LOCK_WAITS") == 0)
773
number_rows= trx_i_s_cache_get_rows_used(trx_i_s_cache, I_S_INNODB_LOCK_WAITS);
778
InnodbTrxTool::Generator::~Generator()
780
trx_i_s_cache_end_read(trx_i_s_cache);
783
bool InnodbTrxTool::Generator::populate()
785
if (record_number == number_rows)
790
if (innobase_strcasecmp(table_name, "INNODB_TRX") == 0)
792
populate_innodb_trx();
794
else if (innobase_strcasecmp(table_name, "INNODB_LOCKS") == 0)
796
populate_innodb_locks();
798
else if (innobase_strcasecmp(table_name, "INNODB_LOCK_WAITS") == 0)
800
populate_innodb_lock_waits();
811
void InnodbTrxTool::Generator::populate_innodb_locks()
814
char lock_id[TRX_I_S_LOCK_ID_MAX_LEN + 1];
815
i_s_locks_row_t* row;
817
/* note that the decoded database or table name is
818
never expected to be longer than NAME_LEN;
819
NAME_LEN for database name
820
2 for surrounding quotes around database name
821
NAME_LEN for table name
822
2 for surrounding quotes around table name
823
1 for the separating dot (.)
824
9 for the #mysql50# prefix
827
char buf[2 * NAME_LEN + 14];
830
char lock_trx_id[TRX_ID_MAX_LEN + 1];
832
row = (i_s_locks_row_t*)
833
trx_i_s_cache_get_nth_row(
834
trx_i_s_cache, I_S_INNODB_LOCKS, record_number);
837
trx_i_s_create_lock_id(row, lock_id, sizeof(lock_id));
840
ut_snprintf(lock_trx_id, sizeof(lock_trx_id),
841
TRX_ID_FMT, row->lock_trx_id);
844
push(row->lock_mode);
845
push(row->lock_type);
847
bufend = innobase_convert_name(buf, sizeof(buf),
849
strlen(row->lock_table),
850
current_session, TRUE);
853
if (row->lock_index != NULL)
855
bufend = innobase_convert_name(buf, sizeof(buf),
857
strlen(row->lock_index),
858
current_session, FALSE);
866
push(static_cast<uint64_t>(row->lock_space));
867
push(static_cast<uint64_t>(row->lock_page));
868
push(static_cast<uint64_t>(row->lock_rec));
869
push(row->lock_data);
872
void InnodbTrxTool::Generator::populate_innodb_trx()
874
char lock_id[TRX_I_S_LOCK_ID_MAX_LEN + 1];
876
char trx_id[TRX_ID_MAX_LEN + 1];
877
row = (i_s_trx_row_t*) trx_i_s_cache_get_nth_row(trx_i_s_cache, I_S_INNODB_TRX, record_number);
880
ut_snprintf(trx_id, sizeof(trx_id), TRX_ID_FMT, row->trx_id);
883
push(row->trx_state);
884
push(static_cast<uint64_t>(row->trx_started));
886
if (row->trx_wait_started != 0)
888
push(trx_i_s_create_lock_id(row->requested_lock_row, lock_id, sizeof(lock_id)));
889
push(static_cast<uint64_t>(row->trx_wait_started));
893
push(static_cast<uint64_t>(0));
894
push(static_cast<uint64_t>(0));
897
push(static_cast<int64_t>(row->trx_weight));
898
push(static_cast<uint64_t>(row->trx_mysql_thread_id));
900
push(row->trx_query);
904
if (row->trx_operation_state)
905
push(row->trx_operation_state);
909
// push(row->trx_tables_in_use);
910
push(static_cast<uint64_t>(row->trx_tables_locked));
911
push(static_cast<uint64_t>(row->trx_lock_structs));
912
push(static_cast<uint64_t>(row->trx_lock_memory_bytes));
913
push(static_cast<uint64_t>(row->trx_rows_locked));
914
push(static_cast<uint64_t>(row->trx_rows_modified));
915
push(static_cast<uint64_t>(row->trx_concurrency_tickets));
916
push(row->trx_isolation_level);
917
push(static_cast<uint64_t>(row->trx_unique_checks));
918
push(static_cast<uint64_t>(row->trx_foreign_key_checks));
919
if (row->trx_foreign_key_error)
920
push(row->trx_foreign_key_error);
924
push(static_cast<uint64_t>(row->trx_has_search_latch));
925
push(static_cast<uint64_t>(row->trx_search_latch_timeout));
928
void InnodbTrxTool::Generator::populate_innodb_lock_waits()
930
char requested_lock_id[TRX_I_S_LOCK_ID_MAX_LEN + 1];
931
char blocking_lock_id[TRX_I_S_LOCK_ID_MAX_LEN + 1];
933
i_s_lock_waits_row_t* row;
935
char requesting_trx_id[TRX_ID_MAX_LEN + 1];
936
char blocking_trx_id[TRX_ID_MAX_LEN + 1];
938
row = (i_s_lock_waits_row_t*)
939
trx_i_s_cache_get_nth_row(
940
trx_i_s_cache, I_S_INNODB_LOCK_WAITS, record_number);
942
ut_snprintf(requesting_trx_id, sizeof(requesting_trx_id),
943
TRX_ID_FMT, row->requested_lock_row->lock_trx_id);
944
push(requesting_trx_id);
946
push(trx_i_s_create_lock_id(row->requested_lock_row, requested_lock_id,
947
sizeof(requested_lock_id)));
949
ut_snprintf(blocking_trx_id, sizeof(blocking_trx_id),
950
TRX_ID_FMT, row->blocking_lock_row->lock_trx_id);
951
push(blocking_trx_id);
953
push(trx_i_s_create_lock_id(row->blocking_lock_row, blocking_lock_id,
954
sizeof(blocking_lock_id)));