00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include <config.h>
00020
00021 #include "data_dictionary.h"
00022
00023 #include <drizzled/current_session.h>
00024
00025 #include "trx0i_s.h"
00026 #include "trx0trx.h"
00027 #include "buf0buddy.h"
00028 #include "buf0buf.h"
00029 #include "ha_prototypes.h"
00030 #include "srv0start.h"
00031 #include "btr0pcur.h"
00032 #include "btr0types.h"
00033 #include "dict0load.h"
00034 #include "dict0mem.h"
00035 #include "dict0types.h"
00036 #include "handler0vars.h"
00037
00038 using namespace drizzled;
00039
00040 InnodbSysTablesTool::InnodbSysTablesTool() :
00041 plugin::TableFunction("DATA_DICTIONARY", "INNODB_SYS_TABLES")
00042 {
00043 add_field("TABLE_ID", plugin::TableFunction::NUMBER, 0, false);
00044 add_field("NAME", plugin::TableFunction::STRING, NAME_LEN + 1, false);
00045 add_field("FLAG", plugin::TableFunction::NUMBER, 0, false);
00046 add_field("N_COLS", plugin::TableFunction::NUMBER, 0, false);
00047 add_field("SPACE", plugin::TableFunction::NUMBER, 0, false);
00048 }
00049
00050 InnodbSysTablesTool::Generator::Generator(Field **arg) :
00051 plugin::TableFunction::Generator(arg)
00052 {
00053 heap= NULL;
00054 }
00055
00056 bool InnodbSysTablesTool::Generator::populate()
00057 {
00058 if (heap == NULL)
00059 {
00060 heap = mem_heap_create(1000);
00061 mutex_enter(&(dict_sys->mutex));
00062 mtr_start(&mtr);
00063
00064 rec = dict_startscan_system(&pcur, &mtr, SYS_TABLES);
00065 }
00066 else
00067 {
00068
00069 mutex_enter(&dict_sys->mutex);
00070 mtr_start(&mtr);
00071 rec = dict_getnext_system(&pcur, &mtr);
00072 }
00073
00074 if (! rec)
00075 {
00076 mtr_commit(&mtr);
00077 mutex_exit(&dict_sys->mutex);
00078 mem_heap_free(heap);
00079 return false;
00080 }
00081
00082 const char* err_msg;
00083 dict_table_t* table_rec;
00084
00085
00086
00087 err_msg = dict_process_sys_tables_rec(heap, rec, &table_rec,
00088 DICT_TABLE_LOAD_FROM_RECORD);
00089
00090 mtr_commit(&mtr);
00091 mutex_exit(&dict_sys->mutex);
00092
00093 if (!err_msg) {
00094 push(table_rec->id);
00095 push(table_rec->name);
00096 push(static_cast<uint64_t>(table_rec->flags));
00097 push(static_cast<uint64_t>(table_rec->n_cols));
00098 push(static_cast<uint64_t>(table_rec->space));
00099 } else {
00100
00101
00102
00103 }
00104
00105
00106
00107
00108 if (table_rec) {
00109 dict_mem_table_free(table_rec);
00110 }
00111
00112 mem_heap_empty(heap);
00113
00114 return true;
00115 }
00116
00117 InnodbSysTableStatsTool::InnodbSysTableStatsTool() :
00118 plugin::TableFunction("DATA_DICTIONARY", "INNODB_SYS_TABLESTATS")
00119 {
00120 add_field("TABLE_ID", plugin::TableFunction::NUMBER, 0, false);
00121 add_field("NAME", plugin::TableFunction::STRING, NAME_LEN + 1, false);
00122 add_field("STATS_INITIALIZED", plugin::TableFunction::STRING, NAME_LEN + 1, false);
00123 add_field("NUM_ROWS", plugin::TableFunction::NUMBER, 0, false);
00124 add_field("CLUST_INDEX_SIZE", plugin::TableFunction::NUMBER, 0, false);
00125 add_field("OTHER_INDEX_SIZE", plugin::TableFunction::NUMBER, 0, false);
00126 add_field("MODIFIED_COUNTER", plugin::TableFunction::NUMBER, 0, false);
00127 add_field("AUTOINC", plugin::TableFunction::NUMBER, 0, false);
00128 add_field("HANDLES_OPENED", plugin::TableFunction::NUMBER, 0, false);
00129 }
00130
00131 InnodbSysTableStatsTool::Generator::Generator(Field **arg) :
00132 plugin::TableFunction::Generator(arg)
00133 {
00134 heap= NULL;
00135 }
00136
00137 bool InnodbSysTableStatsTool::Generator::populate()
00138 {
00139 if (heap == NULL)
00140 {
00141 heap = mem_heap_create(1000);
00142 mutex_enter(&dict_sys->mutex);
00143 mtr_start(&mtr);
00144 rec = dict_startscan_system(&pcur, &mtr, SYS_TABLES);
00145 }
00146 else
00147 {
00148
00149 mutex_enter(&dict_sys->mutex);
00150 mtr_start(&mtr);
00151 rec = dict_getnext_system(&pcur, &mtr);
00152 }
00153
00154 if (!rec)
00155 {
00156 mtr_commit(&mtr);
00157 mutex_exit(&dict_sys->mutex);
00158 mem_heap_free(heap);
00159 return false;
00160 }
00161
00162 const char* err_msg;
00163 dict_table_t* table_rec;
00164
00165
00166
00167 err_msg = dict_process_sys_tables_rec(heap, rec, &table_rec,
00168 DICT_TABLE_LOAD_FROM_CACHE);
00169
00170 mtr_commit(&mtr);
00171 mutex_exit(&dict_sys->mutex);
00172
00173 if (!err_msg) {
00174 push(table_rec->id);
00175 push(table_rec->name);
00176 if (table_rec->stat_initialized)
00177 push("Initialized");
00178 else
00179 push("Uninitialized");
00180 push(table_rec->stat_n_rows);
00181 push(static_cast<uint64_t>(table_rec->stat_clustered_index_size));
00182 push(static_cast<uint64_t>(table_rec->stat_sum_of_other_index_sizes));
00183 push(static_cast<uint64_t>(table_rec->stat_modified_counter));
00184 push(table_rec->autoinc);
00185 push(static_cast<uint64_t>(table_rec->n_mysql_handles_opened));
00186 } else {
00187
00188
00189
00190 }
00191
00192 mem_heap_empty(heap);
00193
00194 return true;
00195 }
00196
00197 InnodbSysIndexesTool::InnodbSysIndexesTool() :
00198 plugin::TableFunction("DATA_DICTIONARY", "INNODB_SYS_INDEXES")
00199 {
00200 add_field("INDEX_ID", plugin::TableFunction::NUMBER, 0, false);
00201 add_field("NAME", plugin::TableFunction::STRING, NAME_LEN + 1, false);
00202 add_field("TABLE_ID", plugin::TableFunction::NUMBER, 0, false);
00203 add_field("TYPE", plugin::TableFunction::NUMBER, 0, false);
00204 add_field("N_FIELDS", plugin::TableFunction::NUMBER, 0, false);
00205 add_field("PAGE_NO", plugin::TableFunction::NUMBER, 0, false);
00206 add_field("SPACE", plugin::TableFunction::NUMBER, 0, false);
00207 }
00208
00209 InnodbSysIndexesTool::Generator::Generator(Field **arg) :
00210 plugin::TableFunction::Generator(arg)
00211 {
00212 heap= NULL;
00213 }
00214
00215 bool InnodbSysIndexesTool::Generator::populate()
00216 {
00217 if (heap == NULL)
00218 {
00219 heap = mem_heap_create(1000);
00220 mutex_enter(&dict_sys->mutex);
00221 mtr_start(&mtr);
00222
00223
00224 rec = dict_startscan_system(&pcur, &mtr, SYS_INDEXES);
00225 }
00226 else
00227 {
00228
00229 mutex_enter(&dict_sys->mutex);
00230 mtr_start(&mtr);
00231 rec = dict_getnext_system(&pcur, &mtr);
00232 }
00233
00234 if (! rec)
00235 {
00236 mtr_commit(&mtr);
00237 mutex_exit(&dict_sys->mutex);
00238 mem_heap_free(heap);
00239 return false;
00240 }
00241
00242 const char* err_msg;;
00243 table_id_t table_id;
00244 dict_index_t index_rec;
00245
00246
00247
00248 err_msg = dict_process_sys_indexes_rec(heap, rec, &index_rec,
00249 &table_id);
00250
00251 mtr_commit(&mtr);
00252 mutex_exit(&dict_sys->mutex);
00253 if (!err_msg) {
00254 push(index_rec.id);
00255 push(index_rec.name);
00256 push(static_cast<uint64_t>(table_id));
00257 push(static_cast<uint64_t>(index_rec.type));
00258 push(static_cast<uint64_t>(index_rec.n_fields));
00259 push(static_cast<uint64_t>(index_rec.page));
00260 push(static_cast<uint64_t>(index_rec.space));
00261 } else {
00262
00263
00264
00265 }
00266
00267 mem_heap_empty(heap);
00268
00269 if (!rec)
00270 {
00271 mtr_commit(&mtr);
00272 mutex_exit(&dict_sys->mutex);
00273 mem_heap_free(heap);
00274 return false;
00275 }
00276
00277 return true;
00278 }
00279
00280 InnodbSysColumnsTool::InnodbSysColumnsTool() :
00281 plugin::TableFunction("DATA_DICTIONARY", "INNODB_SYS_COLUMNS")
00282 {
00283 add_field("TABLE_ID", plugin::TableFunction::NUMBER, 0, false);
00284 add_field("NAME", plugin::TableFunction::STRING, NAME_LEN + 1, false);
00285 add_field("POS", plugin::TableFunction::NUMBER, 0, false);
00286 add_field("MTYPE", plugin::TableFunction::NUMBER, 0, false);
00287 add_field("PRTYPE", plugin::TableFunction::NUMBER, 0, false);
00288 add_field("LEN", plugin::TableFunction::NUMBER, 0, false);
00289 }
00290
00291 InnodbSysColumnsTool::Generator::Generator(Field **arg) :
00292 plugin::TableFunction::Generator(arg)
00293 {
00294 heap= NULL;
00295 }
00296
00297 bool InnodbSysColumnsTool::Generator::populate()
00298 {
00299 if (heap == NULL)
00300 {
00301 heap = mem_heap_create(1000);
00302 mutex_enter(&dict_sys->mutex);
00303 mtr_start(&mtr);
00304 rec = dict_startscan_system(&pcur, &mtr, SYS_COLUMNS);
00305 }
00306 else
00307 {
00308
00309 mutex_enter(&dict_sys->mutex);
00310 mtr_start(&mtr);
00311 rec = dict_getnext_system(&pcur, &mtr);
00312 }
00313
00314 if (! rec)
00315 {
00316 mtr_commit(&mtr);
00317 mutex_exit(&dict_sys->mutex);
00318 mem_heap_free(heap);
00319 return false;
00320 }
00321
00322 const char* err_msg;
00323 dict_col_t column_rec;
00324 table_id_t table_id;
00325 const char* col_name;
00326
00327
00328
00329 err_msg = dict_process_sys_columns_rec(heap, rec, &column_rec,
00330 &table_id, &col_name);
00331
00332 mtr_commit(&mtr);
00333 mutex_exit(&dict_sys->mutex);
00334
00335 if (!err_msg) {
00336 push(table_id);
00337 push(col_name);
00338 push(static_cast<uint64_t>(column_rec.ind));
00339 push(static_cast<uint64_t>(column_rec.mtype));
00340 push(static_cast<uint64_t>(column_rec.prtype));
00341 push(static_cast<uint64_t>(column_rec.len));
00342 } else {
00343
00344
00345
00346 }
00347
00348 mem_heap_empty(heap);
00349
00350 return true;
00351 }
00352
00353 InnodbSysFieldsTool::InnodbSysFieldsTool() :
00354 plugin::TableFunction("DATA_DICTIONARY", "INNODB_SYS_FIELDS")
00355 {
00356 add_field("INDEX_ID", plugin::TableFunction::NUMBER, 0, false);
00357 add_field("NAME", plugin::TableFunction::STRING, NAME_LEN + 1, false);
00358 add_field("POS", plugin::TableFunction::NUMBER, 0, false);
00359 }
00360
00361 InnodbSysFieldsTool::Generator::Generator(Field **arg) :
00362 plugin::TableFunction::Generator(arg)
00363 {
00364 heap= NULL;
00365 }
00366
00367 bool InnodbSysFieldsTool::Generator::populate()
00368 {
00369 if (heap == NULL)
00370 {
00371 heap = mem_heap_create(1000);
00372 mutex_enter(&dict_sys->mutex);
00373 mtr_start(&mtr);
00374
00375
00376
00377 last_id = 0;
00378
00379 rec = dict_startscan_system(&pcur, &mtr, SYS_FIELDS);
00380 }
00381 else
00382 {
00383
00384 mutex_enter(&dict_sys->mutex);
00385 mtr_start(&mtr);
00386 rec = dict_getnext_system(&pcur, &mtr);
00387 }
00388
00389 if (! rec)
00390 {
00391 mtr_commit(&mtr);
00392 mutex_exit(&dict_sys->mutex);
00393 mem_heap_free(heap);
00394
00395 return false;
00396 }
00397
00398 ulint pos;
00399 const char* err_msg;
00400 index_id_t index_id;
00401 dict_field_t field_rec;
00402
00403
00404
00405 err_msg = dict_process_sys_fields_rec(heap, rec, &field_rec,
00406 &pos, &index_id, last_id);
00407
00408 mtr_commit(&mtr);
00409 mutex_exit(&dict_sys->mutex);
00410
00411 if (!err_msg) {
00412 push(index_id);
00413 push(field_rec.name);
00414 push(static_cast<uint64_t>(pos));
00415
00416 last_id = index_id;
00417 } else {
00418
00419
00420
00421 }
00422
00423 mem_heap_empty(heap);
00424
00425 return true;
00426 }
00427
00428 InnodbSysForeignTool::InnodbSysForeignTool() :
00429 plugin::TableFunction("DATA_DICTIONARY", "INNODB_SYS_FOREIGN")
00430 {
00431 add_field("ID", plugin::TableFunction::STRING, NAME_LEN + 1, false);
00432 add_field("FOR_NAME", plugin::TableFunction::STRING, NAME_LEN + 1, false);
00433 add_field("REF_NAME", plugin::TableFunction::STRING, NAME_LEN + 1, false);
00434 add_field("N_COLS", plugin::TableFunction::NUMBER, 0, false);
00435 add_field("TYPE", plugin::TableFunction::NUMBER, 0, false);
00436 }
00437
00438 InnodbSysForeignTool::Generator::Generator(Field **arg) :
00439 plugin::TableFunction::Generator(arg)
00440 {
00441 heap= NULL;
00442 }
00443
00444 bool InnodbSysForeignTool::Generator::populate()
00445 {
00446 if (heap == NULL)
00447 {
00448 heap = mem_heap_create(1000);
00449 mutex_enter(&dict_sys->mutex);
00450 mtr_start(&mtr);
00451
00452 rec = dict_startscan_system(&pcur, &mtr, SYS_FOREIGN);
00453 }
00454 else
00455 {
00456
00457 mtr_start(&mtr);
00458 mutex_enter(&dict_sys->mutex);
00459 rec = dict_getnext_system(&pcur, &mtr);
00460 }
00461
00462 if (! rec)
00463 {
00464 mtr_commit(&mtr);
00465 mutex_exit(&dict_sys->mutex);
00466 mem_heap_free(heap);
00467 return false;
00468 }
00469
00470 const char* err_msg;
00471 dict_foreign_t foreign_rec;
00472
00473
00474
00475 err_msg = dict_process_sys_foreign_rec(heap, rec, &foreign_rec);
00476
00477 mtr_commit(&mtr);
00478 mutex_exit(&dict_sys->mutex);
00479
00480 if (!err_msg) {
00481 push(foreign_rec.id);
00482 push(foreign_rec.foreign_table_name);
00483 push(foreign_rec.referenced_table_name);
00484 push(static_cast<uint64_t>(foreign_rec.n_fields));
00485 push(static_cast<uint64_t>(foreign_rec.type));
00486 } else {
00487
00488
00489
00490 }
00491
00492 mem_heap_empty(heap);
00493
00494 return true;
00495 }
00496
00497 InnodbSysForeignColsTool::InnodbSysForeignColsTool() :
00498 plugin::TableFunction("DATA_DICTIONARY", "INNODB_SYS_FOREIGN_COLS")
00499 {
00500 add_field("ID", plugin::TableFunction::STRING, NAME_LEN + 1, false);
00501 add_field("FOR_COL_NAME", plugin::TableFunction::STRING, NAME_LEN + 1, false);
00502 add_field("REF_COL_NAME", plugin::TableFunction::STRING, NAME_LEN + 1, false);
00503 add_field("POS", plugin::TableFunction::NUMBER, 0, false);
00504 }
00505
00506 InnodbSysForeignColsTool::Generator::Generator(Field **arg) :
00507 plugin::TableFunction::Generator(arg)
00508 {
00509 heap= NULL;
00510 }
00511
00512 bool InnodbSysForeignColsTool::Generator::populate()
00513 {
00514 if (heap == NULL)
00515 {
00516 heap = mem_heap_create(1000);
00517 mutex_enter(&dict_sys->mutex);
00518 mtr_start(&mtr);
00519
00520 rec = dict_startscan_system(&pcur, &mtr, SYS_FOREIGN_COLS);
00521 }
00522 else
00523 {
00524
00525 mutex_enter(&dict_sys->mutex);
00526 mtr_start(&mtr);
00527 rec = dict_getnext_system(&pcur, &mtr);
00528 }
00529
00530 if (! rec)
00531 {
00532 mtr_commit(&mtr);
00533 mutex_exit(&dict_sys->mutex);
00534 mem_heap_free(heap);
00535
00536 return false;
00537 }
00538
00539 const char* err_msg;
00540 const char* name;
00541 const char* for_col_name;
00542 const char* ref_col_name;
00543 ulint pos;
00544
00545
00546 err_msg = dict_process_sys_foreign_col_rec(heap, rec, &name, &for_col_name,
00547 &ref_col_name, &pos);
00548
00549 mtr_commit(&mtr);
00550 mutex_exit(&dict_sys->mutex);
00551
00552 if (!err_msg) {
00553 push(name);
00554 push(for_col_name);
00555 push(ref_col_name);
00556 push(static_cast<uint64_t>(pos));
00557 } else {
00558
00559
00560
00561
00562 }
00563
00564 mem_heap_empty(heap);
00565
00566 return true;
00567 }
00568
00569
00570
00571
00572
00573 CmpTool::CmpTool(bool in_reset) :
00574 plugin::TableFunction("DATA_DICTIONARY", in_reset ? "INNODB_CMP_RESET" : "INNODB_CMP"),
00575 outer_reset(in_reset)
00576 {
00577 add_field("PAGE_SIZE", plugin::TableFunction::NUMBER, 0, false);
00578 add_field("COMPRESS_OPS", plugin::TableFunction::NUMBER, 0, false);
00579 add_field("COMPRESS_OPS_OK", plugin::TableFunction::NUMBER, 0, false);
00580 add_field("COMPRESS_TIME", plugin::TableFunction::NUMBER, 0, false);
00581 add_field("UNCOMPRESS_OPS", plugin::TableFunction::NUMBER, 0, false);
00582 add_field("UNCOMPRESS_TIME", plugin::TableFunction::NUMBER, 0, false);
00583 }
00584
00585 CmpTool::Generator::Generator(Field **arg, bool in_reset) :
00586 plugin::TableFunction::Generator(arg),
00587 record_number(0),
00588 inner_reset(in_reset)
00589 {
00590 }
00591
00592 bool CmpTool::Generator::populate()
00593 {
00594 if (record_number == (PAGE_ZIP_NUM_SSIZE - 1))
00595 {
00596 return false;
00597 }
00598
00599 page_zip_stat_t* zip_stat = &page_zip_stat[record_number];
00600
00601 push(static_cast<uint64_t>(PAGE_ZIP_MIN_SIZE << record_number));
00602
00603
00604
00605
00606
00607
00608
00609 push(static_cast<uint64_t>(zip_stat->compressed));
00610 push(static_cast<uint64_t>(zip_stat->compressed_ok));
00611 push(zip_stat->compressed_usec / 1000000);
00612 push(static_cast<uint64_t>(zip_stat->decompressed));
00613 push(zip_stat->decompressed_usec / 1000000);
00614
00615 if (inner_reset)
00616 {
00617 memset(zip_stat, 0, sizeof *zip_stat);
00618 }
00619
00620 record_number++;
00621
00622 return true;
00623 }
00624
00625
00626
00627
00628
00629 CmpmemTool::CmpmemTool(bool in_reset) :
00630 plugin::TableFunction("DATA_DICTIONARY", in_reset ? "INNODB_CMPMEM_RESET" : "INNODB_CMPMEM"),
00631 outer_reset(in_reset)
00632 {
00633 add_field("BUF_POOL", plugin::TableFunction::NUMBER, 0, false);
00634 add_field("PAGE_SIZE", plugin::TableFunction::NUMBER, 0, false);
00635 add_field("PAGES_USED", plugin::TableFunction::NUMBER, 0, false);
00636 add_field("PAGES_FREE", plugin::TableFunction::NUMBER, 0, false);
00637 add_field("RELOCATION_OPS", plugin::TableFunction::NUMBER, 0, false);
00638 add_field("RELOCATION_TIME", plugin::TableFunction::NUMBER, 0, false);
00639 }
00640
00641 CmpmemTool::Generator::Generator(Field **arg, bool in_reset) :
00642 plugin::TableFunction::Generator(arg),
00643 record_number(0),
00644 inner_reset(in_reset)
00645 {
00646 }
00647
00648 CmpmemTool::Generator::~Generator()
00649 {
00650 }
00651
00652 bool CmpmemTool::Generator::populate()
00653 {
00654 if (record_number >= (BUF_BUDDY_SIZES+1)*srv_buf_pool_instances)
00655 {
00656 return false;
00657 }
00658
00659 uint32_t buddy_nr= record_number % (BUF_BUDDY_SIZES+1);
00660 uint32_t buf_pool_nr= (record_number/(BUF_BUDDY_SIZES+1));
00661
00662 buf_pool_t *buf_pool= buf_pool_from_array(buf_pool_nr);
00663
00664 buf_pool_mutex_enter(buf_pool);
00665
00666 buf_buddy_stat_t* buddy_stat = &buf_pool->buddy_stat[buddy_nr];
00667
00668
00669 push(static_cast<uint64_t>(buf_pool_nr));
00670 push(static_cast<uint64_t>(BUF_BUDDY_LOW << buddy_nr));
00671 push(static_cast<uint64_t>(buddy_stat->used));
00672
00673
00674 uint64_t pages_free= (UNIV_LIKELY(buddy_nr < BUF_BUDDY_SIZES) ? UT_LIST_GET_LEN(buf_pool->zip_free[buddy_nr]) : 0);
00675 push(pages_free);
00676
00677 push(buddy_stat->relocated);
00678 push(buddy_stat->relocated_usec / 1000000);
00679
00680
00681 if (inner_reset)
00682 {
00683 buddy_stat->relocated = 0;
00684 buddy_stat->relocated_usec = 0;
00685 }
00686
00687 buf_pool_mutex_exit(buf_pool);
00688 record_number++;
00689
00690 return true;
00691 }
00692
00693
00694
00695
00696
00697 InnodbTrxTool::InnodbTrxTool(const char* in_table_name) :
00698 plugin::TableFunction("DATA_DICTIONARY", in_table_name),
00699 table_name(in_table_name)
00700 {
00701 if (innobase_strcasecmp(table_name, "INNODB_TRX") == 0)
00702 {
00703 add_field("TRX_ID");
00704 add_field("TRX_STATE");
00705 add_field("TRX_STARTED", plugin::TableFunction::NUMBER, 0, false);
00706 add_field("TRX_REQUESTED_LOCK_ID");
00707 add_field("TRX_WAIT_STARTED", plugin::TableFunction::NUMBER, 0, false);
00708 add_field("TRX_WEIGHT", plugin::TableFunction::NUMBER, 0, false);
00709 add_field("TRX_DRIZZLE_THREAD_ID", plugin::TableFunction::NUMBER, 0, false);
00710 add_field("TRX_QUERY", plugin::TableFunction::STRING, TRX_I_S_TRX_QUERY_MAX_LEN, true);
00711 add_field("TRX_OPERATION_STATE", plugin::TableFunction::STRING, TRX_I_S_TRX_OP_STATE_MAX_LEN, true);
00712
00713 add_field("TRX_TABLES_LOCKED", plugin::TableFunction::NUMBER, 0, false);
00714 add_field("TRX_LOCK_STRUCTS", plugin::TableFunction::NUMBER, 0, false);
00715 add_field("TRX_LOCK_MEMORY_BYTES", plugin::TableFunction::NUMBER, 0, false);
00716 add_field("TRX_ROWS_LOCKED", plugin::TableFunction::NUMBER, 0, false);
00717 add_field("TRX_ROWS_MODIFIED", plugin::TableFunction::NUMBER, 0, false);
00718 add_field("TRX_CONCURRENCY_TICKETS", plugin::TableFunction::NUMBER, 0, false);
00719 add_field("TRX_ISOLATION_LEVEL", plugin::TableFunction::STRING, TRX_I_S_TRX_ISOLATION_LEVEL_MAX_LEN, false);
00720 add_field("TRX_UNIQUE_CHECKS", plugin::TableFunction::NUMBER, 0, false);
00721 add_field("TRX_FOREIGN_KEY_CHECKS", plugin::TableFunction::NUMBER, 0, false);
00722 add_field("TRX_LAST_FOREIGN_KEY_ERROR", plugin::TableFunction::STRING,
00723 TRX_I_S_TRX_FK_ERROR_MAX_LEN, true);
00724 add_field("TRX_ADAPTIVE_HASH_LATCHED", plugin::TableFunction::NUMBER, 0, false);
00725 add_field("TRX_ADAPTIVE_HASH_TIMEOUT", plugin::TableFunction::NUMBER, 0, false);
00726 }
00727 else if (innobase_strcasecmp(table_name, "INNODB_LOCKS") == 0)
00728 {
00729 add_field("LOCK_ID");
00730 add_field("LOCK_TRX_ID");
00731 add_field("LOCK_MODE");
00732 add_field("LOCK_TYPE");
00733 add_field("LOCK_TABLE");
00734 add_field("LOCK_INDEX");
00735 add_field("LOCK_SPACE", plugin::TableFunction::NUMBER, 0, false);
00736 add_field("LOCK_PAGE", plugin::TableFunction::NUMBER, 0, false);
00737 add_field("LOCK_REC", plugin::TableFunction::NUMBER, 0, false);
00738 add_field("LOCK_DATA");
00739 }
00740 else if (innobase_strcasecmp(table_name, "INNODB_LOCK_WAITS") == 0)
00741 {
00742 add_field("REQUESTING_TRX_ID");
00743 add_field("REQUESTED_LOCK_ID");
00744 add_field("BLOCKING_TRX_ID");
00745 add_field("BLOCKING_LOCK_ID");
00746 }
00747 }
00748
00749 InnodbTrxTool::Generator::Generator(Field **arg, const char* in_table_name) :
00750 plugin::TableFunction::Generator(arg),
00751 table_name(in_table_name)
00752 {
00753
00754 trx_i_s_cache_start_write(trx_i_s_cache);
00755 trx_i_s_possibly_fetch_data_into_cache(trx_i_s_cache);
00756 trx_i_s_cache_end_write(trx_i_s_cache);
00757
00758 if (trx_i_s_cache_is_truncated(trx_i_s_cache))
00759 {
00760 errmsg_printf(error::ERROR, _("Warning: data in %s truncated due to memory limit of %d bytes\n"),
00761 table_name, TRX_I_S_MEM_LIMIT);
00762 }
00763
00764 trx_i_s_cache_start_read(trx_i_s_cache);
00765
00766 if (innobase_strcasecmp(table_name, "INNODB_TRX") == 0)
00767 number_rows= trx_i_s_cache_get_rows_used(trx_i_s_cache, I_S_INNODB_TRX);
00768 else if (innobase_strcasecmp(table_name, "INNODB_LOCKS") == 0)
00769 number_rows= trx_i_s_cache_get_rows_used(trx_i_s_cache, I_S_INNODB_LOCKS);
00770 else if (innobase_strcasecmp(table_name, "INNODB_LOCK_WAITS") == 0)
00771 number_rows= trx_i_s_cache_get_rows_used(trx_i_s_cache, I_S_INNODB_LOCK_WAITS);
00772
00773 record_number= 0;
00774 }
00775
00776 InnodbTrxTool::Generator::~Generator()
00777 {
00778 trx_i_s_cache_end_read(trx_i_s_cache);
00779 }
00780
00781 bool InnodbTrxTool::Generator::populate()
00782 {
00783 if (record_number == number_rows)
00784 {
00785 return false;
00786 }
00787
00788 if (innobase_strcasecmp(table_name, "INNODB_TRX") == 0)
00789 {
00790 populate_innodb_trx();
00791 }
00792 else if (innobase_strcasecmp(table_name, "INNODB_LOCKS") == 0)
00793 {
00794 populate_innodb_locks();
00795 }
00796 else if (innobase_strcasecmp(table_name, "INNODB_LOCK_WAITS") == 0)
00797 {
00798 populate_innodb_lock_waits();
00799 }
00800 else
00801 {
00802 return false;
00803 }
00804 record_number++;
00805
00806 return true;
00807 }
00808
00809 void InnodbTrxTool::Generator::populate_innodb_locks()
00810 {
00811
00812 char lock_id[TRX_I_S_LOCK_ID_MAX_LEN + 1];
00813 i_s_locks_row_t* row;
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824
00825 char buf[2 * NAME_LEN + 14];
00826 const char* bufend;
00827
00828 char lock_trx_id[TRX_ID_MAX_LEN + 1];
00829
00830 row = (i_s_locks_row_t*)
00831 trx_i_s_cache_get_nth_row(
00832 trx_i_s_cache, I_S_INNODB_LOCKS, record_number);
00833
00834
00835 trx_i_s_create_lock_id(row, lock_id, sizeof(lock_id));
00836 push(lock_id);
00837
00838 ut_snprintf(lock_trx_id, sizeof(lock_trx_id),
00839 TRX_ID_FMT, row->lock_trx_id);
00840 push(lock_trx_id);
00841
00842 push(row->lock_mode);
00843 push(row->lock_type);
00844
00845 bufend = innobase_convert_name(buf, sizeof(buf),
00846 row->lock_table,
00847 strlen(row->lock_table),
00848 &getSession(), TRUE);
00849 push(bufend);
00850
00851 if (row->lock_index != NULL)
00852 {
00853 bufend = innobase_convert_name(buf, sizeof(buf),
00854 row->lock_index,
00855 strlen(row->lock_index),
00856 &getSession(), FALSE);
00857 push(bufend);
00858 }
00859 else
00860 {
00861 push("");
00862 }
00863
00864 push(static_cast<uint64_t>(row->lock_space));
00865 push(static_cast<uint64_t>(row->lock_page));
00866 push(static_cast<uint64_t>(row->lock_rec));
00867 push(row->lock_data);
00868 }
00869
00870 void InnodbTrxTool::Generator::populate_innodb_trx()
00871 {
00872 char lock_id[TRX_I_S_LOCK_ID_MAX_LEN + 1];
00873 i_s_trx_row_t* row;
00874 char trx_id[TRX_ID_MAX_LEN + 1];
00875 row = (i_s_trx_row_t*) trx_i_s_cache_get_nth_row(trx_i_s_cache, I_S_INNODB_TRX, record_number);
00876
00877
00878 ut_snprintf(trx_id, sizeof(trx_id), TRX_ID_FMT, row->trx_id);
00879
00880 push(trx_id);
00881 push(row->trx_state);
00882 push(static_cast<uint64_t>(row->trx_started));
00883
00884 if (row->trx_wait_started != 0)
00885 {
00886 push(trx_i_s_create_lock_id(row->requested_lock_row, lock_id, sizeof(lock_id)));
00887 push(static_cast<uint64_t>(row->trx_wait_started));
00888 }
00889 else
00890 {
00891 push(static_cast<uint64_t>(0));
00892 push(static_cast<uint64_t>(0));
00893 }
00894
00895 push(static_cast<int64_t>(row->trx_weight));
00896 push(static_cast<uint64_t>(row->trx_mysql_thread_id));
00897 if (row->trx_query)
00898 push(row->trx_query);
00899 else
00900 push();
00901
00902 if (row->trx_operation_state)
00903 push(row->trx_operation_state);
00904 else
00905 push();
00906
00907
00908 push(static_cast<uint64_t>(row->trx_tables_locked));
00909 push(static_cast<uint64_t>(row->trx_lock_structs));
00910 push(static_cast<uint64_t>(row->trx_lock_memory_bytes));
00911 push(static_cast<uint64_t>(row->trx_rows_locked));
00912 push(static_cast<uint64_t>(row->trx_rows_modified));
00913 push(static_cast<uint64_t>(row->trx_concurrency_tickets));
00914 push(row->trx_isolation_level);
00915 push(static_cast<uint64_t>(row->trx_unique_checks));
00916 push(static_cast<uint64_t>(row->trx_foreign_key_checks));
00917 if (row->trx_foreign_key_error)
00918 push(row->trx_foreign_key_error);
00919 else
00920 push();
00921
00922 push(static_cast<uint64_t>(row->trx_has_search_latch));
00923 push(static_cast<uint64_t>(row->trx_search_latch_timeout));
00924 }
00925
00926 void InnodbTrxTool::Generator::populate_innodb_lock_waits()
00927 {
00928 char requested_lock_id[TRX_I_S_LOCK_ID_MAX_LEN + 1];
00929 char blocking_lock_id[TRX_I_S_LOCK_ID_MAX_LEN + 1];
00930
00931 i_s_lock_waits_row_t* row;
00932
00933 char requesting_trx_id[TRX_ID_MAX_LEN + 1];
00934 char blocking_trx_id[TRX_ID_MAX_LEN + 1];
00935
00936 row = (i_s_lock_waits_row_t*)
00937 trx_i_s_cache_get_nth_row(
00938 trx_i_s_cache, I_S_INNODB_LOCK_WAITS, record_number);
00939
00940 ut_snprintf(requesting_trx_id, sizeof(requesting_trx_id),
00941 TRX_ID_FMT, row->requested_lock_row->lock_trx_id);
00942 push(requesting_trx_id);
00943
00944 push(trx_i_s_create_lock_id(row->requested_lock_row, requested_lock_id,
00945 sizeof(requested_lock_id)));
00946
00947 ut_snprintf(blocking_trx_id, sizeof(blocking_trx_id),
00948 TRX_ID_FMT, row->blocking_lock_row->lock_trx_id);
00949 push(blocking_trx_id);
00950
00951 push(trx_i_s_create_lock_id(row->blocking_lock_row, blocking_lock_id,
00952 sizeof(blocking_lock_id)));
00953 }