From bd65e80c84f668202060706e7705ffefafea985d Mon Sep 17 00:00:00 2001 From: Jimmy Yang Date: Wed, 12 May 2010 08:39:45 -0700 Subject: [PATCH] Check in patch for bug #53336, Improved InnoDB Transaction Reporting. rb://335, Approved by Sunny Bains --- .../innodb/r/innodb_information_schema.result | 43 +++ .../innodb/t/innodb_information_schema.test | 103 ++++++ storage/innobase/handler/i_s.cc | 308 ++++++++++++++++++ storage/innobase/include/lock0lock.h | 2 +- storage/innobase/include/trx0i_s.h | 87 ++++- storage/innobase/lock/lock0lock.c | 2 +- storage/innobase/trx/trx0i_s.c | 91 ++++-- 7 files changed, 600 insertions(+), 36 deletions(-) diff --git a/mysql-test/suite/innodb/r/innodb_information_schema.result b/mysql-test/suite/innodb/r/innodb_information_schema.result index 396cae579ce..ad8729804df 100644 --- a/mysql-test/suite/innodb/r/innodb_information_schema.result +++ b/mysql-test/suite/innodb/r/innodb_information_schema.result @@ -21,3 +21,46 @@ lock_table COUNT(*) "test"."t_max" 2 "test"."t_min" 2 "test"."`t'\""_str" 10 +Field Type Null Key Default Extra +trx_id varchar(18) NO +trx_state varchar(13) NO +trx_started datetime NO 0000-00-00 00:00:00 +trx_requested_lock_id varchar(81) YES NULL +trx_wait_started datetime YES NULL +trx_weight bigint(21) unsigned NO 0 +trx_mysql_thread_id bigint(21) unsigned NO 0 +trx_query varchar(1024) YES NULL +trx_operation_state varchar(64) YES NULL +trx_tables_in_use bigint(21) unsigned NO 0 +trx_tables_locked bigint(21) unsigned NO 0 +trx_lock_structs bigint(21) unsigned NO 0 +trx_lock_memory_bytes bigint(21) unsigned NO 0 +trx_rows_locked bigint(21) unsigned NO 0 +trx_rows_modified bigint(21) unsigned NO 0 +trx_concurrency_tickets bigint(21) unsigned NO 0 +trx_isolation_level varchar(16) NO +trx_unique_checks int(1) NO 0 +trx_foreign_key_checks int(1) NO 0 +trx_last_foreign_key_error varchar(256) YES NULL +trx_apative_hash_latched int(1) NO 0 +trx_adaptive_hash_timeout bigint(21) unsigned NO 0 +trx_operation_state varchar(64) YES NULL +trx_tables_in_use bigint(21) unsigned NO 0 +trx_tables_locked bigint(21) unsigned NO 0 +trx_lock_structs bigint(21) unsigned NO 0 +trx_lock_memory_bytes bigint(21) unsigned NO 0 +trx_rows_locked bigint(21) unsigned NO 0 +trx_rows_modified bigint(21) unsigned NO 0 +trx_concurrency_tickets bigint(21) unsigned NO 0 +trx_isolation_level varchar(16) NO +trx_unique_checks int(1) NO 0 +trx_foreign_key_checks int(1) NO 0 +trx_last_foreign_key_error varchar(256) YES NULL +trx_apative_hash_latched int(1) NO 0 +trx_adaptive_hash_timeout bigint(21) unsigned NO 0 +trx_state trx_weight trx_tables_in_use trx_tables_locked trx_rows_locked trx_rows_modified trx_concurrency_tickets trx_isolation_level trx_unique_checks trx_foreign_key_checks +RUNNING 4 0 0 7 1 0 REPEATABLE READ 1 1 +trx_isolation_level trx_unique_checks trx_foreign_key_checks +SERIALIZABLE 0 0 +trx_state trx_isolation_level trx_last_foreign_key_error +RUNNING SERIALIZABLE `test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`c02`) REFERENCES `t1` (`c01`) diff --git a/mysql-test/suite/innodb/t/innodb_information_schema.test b/mysql-test/suite/innodb/t/innodb_information_schema.test index fc1d38d8d14..3dc2a8a40d4 100644 --- a/mysql-test/suite/innodb/t/innodb_information_schema.test +++ b/mysql-test/suite/innodb/t/innodb_information_schema.test @@ -64,6 +64,8 @@ INSERT INTO ```t'\"_str` VALUES INSERT INTO ```t'\"_str` VALUES ('4', 'abc', 0x00616263, 0x61626300, 0x61006263, 0x6100626300, 0x610062630000); +--source include/count_sessions.inc + -- connect (con_lock,localhost,root,,) -- connect (con_min_trylock,localhost,root,,) -- connect (con_max_trylock,localhost,root,,) @@ -147,3 +149,104 @@ SET @@sql_mode=@save_sql_mode; -- disconnect con_verify_innodb_locks DROP TABLE t_min, t_max, ```t'\"_str`; + +--source include/wait_until_count_sessions.inc + +# +# Test that transaction data is correctly "visualized" in +# INFORMATION_SCHEMA.INNODB_TRX +# + +-- enable_result_log +DESCRIBE INFORMATION_SCHEMA.INNODB_TRX; +-- disable_result_log + +-- disable_warnings +DROP TABLE IF EXISTS t1; +-- enable_warnings + +CREATE TABLE t1 ( + c01 INT, + c02 INT, + PRIMARY KEY (c01) +) ENGINE = InnoDB; + +INSERT INTO t1 VALUES +(1,2),(2,4),(3,6),(4,8); + +CREATE TABLE t2 ( + c01 INT, + c02 INT, + PRIMARY KEY (c01), + FOREIGN KEY fk1 (c02) REFERENCES t1 (c01) +) ENGINE = InnoDB; + +INSERT INTO t2 VALUES +(1,1),(2,2),(3,3); + +-- connect (con_trx,localhost,root,,) +-- connect (con_verify_innodb_trx,localhost,root,,) + +-- connection con_trx +SET autocommit=0; +INSERT INTO t1 VALUES (5,10); +SELECT * FROM t1 FOR UPDATE; + +let $wait_condition= + SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.INNODB_TRX; +--source include/wait_condition.inc +-- disable_query_log + +-- connection con_verify_innodb_trx +-- enable_result_log +SELECT trx_state, trx_weight, trx_tables_in_use, trx_tables_locked, +trx_rows_locked, trx_rows_modified, trx_concurrency_tickets, +trx_isolation_level, trx_unique_checks, trx_foreign_key_checks +FROM INFORMATION_SCHEMA.INNODB_TRX; + +-- connection con_trx +-- disable_result_log +ROLLBACK; +SET FOREIGN_KEY_CHECKS = 0; +SET UNIQUE_CHECKS = 0; +SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; +BEGIN; +INSERT INTO t1 VALUES (6,12); + +let $wait_condition= + SELECT trx_unique_checks = 0 FROM INFORMATION_SCHEMA.INNODB_TRX; +--source include/wait_condition.inc +-- disable_query_log + +-- connection con_verify_innodb_trx +-- enable_result_log +SELECT trx_isolation_level, trx_unique_checks, trx_foreign_key_checks +FROM INFORMATION_SCHEMA.INNODB_TRX; + +-- disable_result_log +-- connection con_trx +ROLLBACK; +SET FOREIGN_KEY_CHECKS = 1; +SET UNIQUE_CHECKS = 1; +BEGIN; +-- error 1452 +INSERT INTO t2 VALUES (4,10); + +let $wait_condition= + SELECT trx_unique_checks = 1 FROM INFORMATION_SCHEMA.INNODB_TRX; +--source include/wait_condition.inc +-- disable_query_log + +-- enable_result_log +-- connection con_verify_innodb_trx +SELECT trx_state, trx_isolation_level, trx_last_foreign_key_error +FROM INFORMATION_SCHEMA.INNODB_TRX; +-- disable_result_log + +-- connection default + +-- disconnect con_trx +-- disconnect con_verify_innodb_trx + +DROP TABLE t2; +DROP TABLE t1; diff --git a/storage/innobase/handler/i_s.cc b/storage/innobase/handler/i_s.cc index 7a457e6a990..f8b3b71c804 100644 --- a/storage/innobase/handler/i_s.cc +++ b/storage/innobase/handler/i_s.cc @@ -288,6 +288,258 @@ static ST_FIELD_INFO innodb_trx_fields_info[] = STRUCT_FLD(old_name, ""), STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, +#define IDX_TRX_OPERATION_STATE 8 + {STRUCT_FLD(field_name, "trx_operation_state"), + STRUCT_FLD(field_length, TRX_I_S_TRX_OP_STATE_MAX_LEN), + STRUCT_FLD(field_type, MYSQL_TYPE_STRING), + STRUCT_FLD(value, 0), + STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL), + STRUCT_FLD(old_name, ""), + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, + +#define IDX_TRX_TABLES_IN_USE 9 + {STRUCT_FLD(field_name, "trx_tables_in_use"), + STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), + STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), + STRUCT_FLD(value, 0), + STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), + STRUCT_FLD(old_name, ""), + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, + +#define IDX_TRX_TABLES_LOCKED 10 + {STRUCT_FLD(field_name, "trx_tables_locked"), + STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), + STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), + STRUCT_FLD(value, 0), + STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), + STRUCT_FLD(old_name, ""), + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, + +#define IDX_TRX_LOCK_STRUCTS 11 + {STRUCT_FLD(field_name, "trx_lock_structs"), + STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), + STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), + STRUCT_FLD(value, 0), + STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), + STRUCT_FLD(old_name, ""), + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, + +#define IDX_TRX_LOCK_MEMORY_BYTES 12 + {STRUCT_FLD(field_name, "trx_lock_memory_bytes"), + STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), + STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), + STRUCT_FLD(value, 0), + STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), + STRUCT_FLD(old_name, ""), + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, + +#define IDX_TRX_ROWS_LOCKED 13 + {STRUCT_FLD(field_name, "trx_rows_locked"), + STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), + STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), + STRUCT_FLD(value, 0), + STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), + STRUCT_FLD(old_name, ""), + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, + +#define IDX_TRX_ROWS_MODIFIED 14 + {STRUCT_FLD(field_name, "trx_rows_modified"), + STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), + STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), + STRUCT_FLD(value, 0), + STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), + STRUCT_FLD(old_name, ""), + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, + +#define IDX_TRX_CONNCURRENCY_TICKETS 15 + {STRUCT_FLD(field_name, "trx_concurrency_tickets"), + STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), + STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), + STRUCT_FLD(value, 0), + STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), + STRUCT_FLD(old_name, ""), + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, + +#define IDX_TRX_ISOLATION_LEVEL 16 + {STRUCT_FLD(field_name, "trx_isolation_level"), + STRUCT_FLD(field_length, TRX_I_S_TRX_ISOLATION_LEVEL_MAX_LEN), + STRUCT_FLD(field_type, MYSQL_TYPE_STRING), + STRUCT_FLD(value, 0), + STRUCT_FLD(field_flags, 0), + STRUCT_FLD(old_name, ""), + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, + +#define IDX_TRX_UNIQUE_CHECKS 17 + {STRUCT_FLD(field_name, "trx_unique_checks"), + STRUCT_FLD(field_length, 1), + STRUCT_FLD(field_type, MYSQL_TYPE_LONG), + STRUCT_FLD(value, 1), + STRUCT_FLD(field_flags, 0), + STRUCT_FLD(old_name, ""), + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, + +#define IDX_TRX_FOREIGN_KEY_CHECKS 18 + {STRUCT_FLD(field_name, "trx_foreign_key_checks"), + STRUCT_FLD(field_length, 1), + STRUCT_FLD(field_type, MYSQL_TYPE_LONG), + STRUCT_FLD(value, 1), + STRUCT_FLD(field_flags, 0), + STRUCT_FLD(old_name, ""), + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, + +#define IDX_TRX_LAST_FOREIGN_KEY_ERROR 19 + {STRUCT_FLD(field_name, "trx_last_foreign_key_error"), + STRUCT_FLD(field_length, TRX_I_S_TRX_FK_ERROR_MAX_LEN), + STRUCT_FLD(field_type, MYSQL_TYPE_STRING), + STRUCT_FLD(value, 0), + STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL), + STRUCT_FLD(old_name, ""), + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, + +#define IDX_TRX_ADAPTIVE_HASH_LATCHED 20 + {STRUCT_FLD(field_name, "trx_apative_hash_latched"), + STRUCT_FLD(field_length, 1), + STRUCT_FLD(field_type, MYSQL_TYPE_LONG), + STRUCT_FLD(value, 0), + STRUCT_FLD(field_flags, 0), + STRUCT_FLD(old_name, ""), + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, + +#define IDX_TRX_ADAPTIVE_HASH_TIMEOUT 21 + {STRUCT_FLD(field_name, "trx_adaptive_hash_timeout"), + STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), + STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), + STRUCT_FLD(value, 0), + STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), + STRUCT_FLD(old_name, ""), + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, + +#define IDX_TRX_OPERATION_STATE 8 + {STRUCT_FLD(field_name, "trx_operation_state"), + STRUCT_FLD(field_length, TRX_I_S_TRX_OP_STATE_MAX_LEN), + STRUCT_FLD(field_type, MYSQL_TYPE_STRING), + STRUCT_FLD(value, 0), + STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL), + STRUCT_FLD(old_name, ""), + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, + +#define IDX_TRX_TABLES_IN_USE 9 + {STRUCT_FLD(field_name, "trx_tables_in_use"), + STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), + STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), + STRUCT_FLD(value, 0), + STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), + STRUCT_FLD(old_name, ""), + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, + +#define IDX_TRX_TABLES_LOCKED 10 + {STRUCT_FLD(field_name, "trx_tables_locked"), + STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), + STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), + STRUCT_FLD(value, 0), + STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), + STRUCT_FLD(old_name, ""), + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, + +#define IDX_TRX_LOCK_STRUCTS 11 + {STRUCT_FLD(field_name, "trx_lock_structs"), + STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), + STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), + STRUCT_FLD(value, 0), + STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), + STRUCT_FLD(old_name, ""), + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, + +#define IDX_TRX_LOCK_MEMORY_BYTES 12 + {STRUCT_FLD(field_name, "trx_lock_memory_bytes"), + STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), + STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), + STRUCT_FLD(value, 0), + STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), + STRUCT_FLD(old_name, ""), + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, + +#define IDX_TRX_ROWS_LOCKED 13 + {STRUCT_FLD(field_name, "trx_rows_locked"), + STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), + STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), + STRUCT_FLD(value, 0), + STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), + STRUCT_FLD(old_name, ""), + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, + +#define IDX_TRX_ROWS_MODIFIED 14 + {STRUCT_FLD(field_name, "trx_rows_modified"), + STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), + STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), + STRUCT_FLD(value, 0), + STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), + STRUCT_FLD(old_name, ""), + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, + +#define IDX_TRX_CONNCURRENCY_TICKETS 15 + {STRUCT_FLD(field_name, "trx_concurrency_tickets"), + STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), + STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), + STRUCT_FLD(value, 0), + STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), + STRUCT_FLD(old_name, ""), + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, + +#define IDX_TRX_ISOLATION_LEVEL 16 + {STRUCT_FLD(field_name, "trx_isolation_level"), + STRUCT_FLD(field_length, TRX_I_S_TRX_ISOLATION_LEVEL_MAX_LEN), + STRUCT_FLD(field_type, MYSQL_TYPE_STRING), + STRUCT_FLD(value, 0), + STRUCT_FLD(field_flags, 0), + STRUCT_FLD(old_name, ""), + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, + +#define IDX_TRX_UNIQUE_CHECKS 17 + {STRUCT_FLD(field_name, "trx_unique_checks"), + STRUCT_FLD(field_length, 1), + STRUCT_FLD(field_type, MYSQL_TYPE_LONG), + STRUCT_FLD(value, 1), + STRUCT_FLD(field_flags, 0), + STRUCT_FLD(old_name, ""), + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, + +#define IDX_TRX_FOREIGN_KEY_CHECKS 18 + {STRUCT_FLD(field_name, "trx_foreign_key_checks"), + STRUCT_FLD(field_length, 1), + STRUCT_FLD(field_type, MYSQL_TYPE_LONG), + STRUCT_FLD(value, 1), + STRUCT_FLD(field_flags, 0), + STRUCT_FLD(old_name, ""), + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, + +#define IDX_TRX_LAST_FOREIGN_KEY_ERROR 19 + {STRUCT_FLD(field_name, "trx_last_foreign_key_error"), + STRUCT_FLD(field_length, TRX_I_S_TRX_FK_ERROR_MAX_LEN), + STRUCT_FLD(field_type, MYSQL_TYPE_STRING), + STRUCT_FLD(value, 0), + STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL), + STRUCT_FLD(old_name, ""), + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, + +#define IDX_TRX_ADAPTIVE_HASH_LATCHED 20 + {STRUCT_FLD(field_name, "trx_apative_hash_latched"), + STRUCT_FLD(field_length, 1), + STRUCT_FLD(field_type, MYSQL_TYPE_LONG), + STRUCT_FLD(value, 0), + STRUCT_FLD(field_flags, 0), + STRUCT_FLD(old_name, ""), + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, + +#define IDX_TRX_ADAPTIVE_HASH_TIMEOUT 21 + {STRUCT_FLD(field_name, "trx_adaptive_hash_timeout"), + STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), + STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), + STRUCT_FLD(value, 0), + STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), + STRUCT_FLD(old_name, ""), + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, + END_OF_ST_FIELD_INFO }; @@ -370,6 +622,62 @@ fill_innodb_trx_from_cache( OK(field_store_string(fields[IDX_TRX_QUERY], row->trx_query)); + /* trx_operation_state */ + OK(field_store_string(fields[IDX_TRX_OPERATION_STATE], + row->trx_operation_state)); + + /* trx_tables_in_use */ + OK(fields[IDX_TRX_TABLES_IN_USE]->store( + (longlong) row->trx_tables_in_use, true)); + + /* trx_tables_locked */ + OK(fields[IDX_TRX_TABLES_LOCKED]->store( + (longlong) row->trx_tables_locked, true)); + + /* trx_lock_structs */ + OK(fields[IDX_TRX_LOCK_STRUCTS]->store( + (longlong) row->trx_lock_structs, true)); + + /* trx_lock_memory_bytes */ + OK(fields[IDX_TRX_LOCK_MEMORY_BYTES]->store( + (longlong) row->trx_lock_memory_bytes, true)); + + /* trx_rows_locked */ + OK(fields[IDX_TRX_ROWS_LOCKED]->store( + (longlong) row->trx_rows_locked, true)); + + /* trx_rows_modified */ + OK(fields[IDX_TRX_ROWS_MODIFIED]->store( + (longlong) row->trx_rows_modified, true)); + + /* trx_concurrency_tickets */ + OK(fields[IDX_TRX_CONNCURRENCY_TICKETS]->store( + (longlong) row->trx_concurrency_tickets, true)); + + /* trx_isolation_level */ + OK(field_store_string(fields[IDX_TRX_ISOLATION_LEVEL], + row->trx_isolation_level)); + + /* trx_unique_checks */ + OK(fields[IDX_TRX_UNIQUE_CHECKS]->store( + row->trx_unique_checks)); + + /* trx_foreign_key_checks */ + OK(fields[IDX_TRX_FOREIGN_KEY_CHECKS]->store( + row->trx_foreign_key_checks)); + + /* trx_last_foreign_key_error */ + OK(field_store_string(fields[IDX_TRX_LAST_FOREIGN_KEY_ERROR], + row->trx_foreign_key_error)); + + /* trx_apative_hash_latched */ + OK(fields[IDX_TRX_ADAPTIVE_HASH_LATCHED]->store( + row->trx_has_search_latch)); + + /* trx_adaptive_hash_timeout */ + OK(fields[IDX_TRX_ADAPTIVE_HASH_TIMEOUT]->store( + (longlong) row->trx_search_latch_timeout, true)); + OK(schema_table_store_record(thd, table)); } diff --git a/storage/innobase/include/lock0lock.h b/storage/innobase/include/lock0lock.h index ad271a95654..bdc11282dac 100644 --- a/storage/innobase/include/lock0lock.h +++ b/storage/innobase/include/lock0lock.h @@ -637,7 +637,7 @@ UNIV_INTERN ulint lock_number_of_rows_locked( /*=======================*/ - trx_t* trx); /*!< in: transaction */ + const trx_t* trx); /*!< in: transaction */ /*******************************************************************//** Check if a transaction holds any autoinc locks. @return TRUE if the transaction holds any AUTOINC locks. */ diff --git a/storage/innobase/include/trx0i_s.h b/storage/innobase/include/trx0i_s.h index 7bd4e1b88c8..c610782c229 100644 --- a/storage/innobase/include/trx0i_s.h +++ b/storage/innobase/include/trx0i_s.h @@ -44,6 +44,37 @@ i_s_locks_row_t::lock_data */ i_s_trx_row_t::trx_query */ #define TRX_I_S_TRX_QUERY_MAX_LEN 1024 +/** The maximum length of a string that can be stored in +i_s_trx_row_t::trx_operation_state */ +#define TRX_I_S_TRX_OP_STATE_MAX_LEN 64 + +/** The maximum length of a string that can be stored in +i_s_trx_row_t::trx_foreign_key_error */ +#define TRX_I_S_TRX_FK_ERROR_MAX_LEN 256 + +/** The maximum length of a string that can be stored in +i_s_trx_row_t::trx_isolation_level */ +#define TRX_I_S_TRX_ISOLATION_LEVEL_MAX_LEN 16 + +/** Safely copy strings in to the INNODB_TRX table's +string based columns */ +#define TRX_I_S_STRING_COPY(data, field, constraint, tcache) \ +do { \ + if (strlen(data) > constraint) { \ + char buff[constraint + 1]; \ + strncpy(buff, data, constraint); \ + buff[constraint] = '\0'; \ + \ + field = ha_storage_put_memlim( \ + (tcache)->storage, buff, constraint + 1,\ + MAX_ALLOWED_FOR_STORAGE(tcache)); \ + } else { \ + field = ha_storage_put_str_memlim( \ + (tcache)->storage, data, \ + MAX_ALLOWED_FOR_STORAGE(tcache)); \ + } \ +} while (0) + /** A row of INFORMATION_SCHEMA.innodb_locks */ typedef struct i_s_locks_row_struct i_s_locks_row_t; /** A row of INFORMATION_SCHEMA.innodb_trx */ @@ -95,21 +126,49 @@ struct i_s_locks_row_struct { /** This structure represents INFORMATION_SCHEMA.innodb_trx row */ struct i_s_trx_row_struct { - ullint trx_id; /*!< transaction identifier */ - const char* trx_state; /*!< transaction state from - trx_get_que_state_str() */ - ib_time_t trx_started; /*!< trx_struct::start_time */ + ullint trx_id; /*!< transaction identifier */ + const char* trx_state; /*!< transaction state from + trx_get_que_state_str() */ + ib_time_t trx_started; /*!< trx_struct::start_time */ const i_s_locks_row_t* requested_lock_row; - /*!< pointer to a row - in innodb_locks if trx - is waiting, or NULL */ - ib_time_t trx_wait_started; - /*!< trx_struct::wait_started */ - ullint trx_weight; /*!< TRX_WEIGHT() */ - ulint trx_mysql_thread_id; - /*!< thd_get_thread_id() */ - const char* trx_query; /*!< MySQL statement being - executed in the transaction */ + /*!< pointer to a row + in innodb_locks if trx + is waiting, or NULL */ + ib_time_t trx_wait_started; /*!< trx_struct::wait_started */ + ullint trx_weight; /*!< TRX_WEIGHT() */ + ulint trx_mysql_thread_id; /*!< thd_get_thread_id() */ + const char* trx_query; /*!< MySQL statement being + executed in the transaction */ + const char* trx_operation_state; /*!< trx_struct::op_info */ + ulint trx_tables_in_use;/*!< n_mysql_tables_in_use in + trx_struct */ + ulint trx_tables_locked; + /*!< mysql_n_tables_locked in + trx_struct */ + ulint trx_lock_structs;/*!< list len of trx_locks in + trx_struct */ + ulint trx_lock_memory_bytes; + /*!< mem_heap_get_size( + trx->lock_heap) */ + ulint trx_rows_locked;/*!< lock_number_of_rows_locked() */ + ullint trx_rows_modified;/*!< trx_struct::undo_no */ + ulint trx_concurrency_tickets; + /*!< n_tickets_to_enter_innodb in + trx_struct */ + const char* trx_isolation_level; + /*!< isolation_level in trx_struct*/ + ibool trx_unique_checks; + /*!< check_unique_secondary in + trx_struct*/ + ibool trx_foreign_key_checks; + /*!< check_foreigns in trx_struct */ + const char* trx_foreign_key_error; + /*!< detailed_error in trx_struct */ + ibool trx_has_search_latch; + /*!< has_search_latch in trx_struct */ + ulint trx_search_latch_timeout; + /*!< search_latch_timeout in + trx_struct */ }; /** This structure represents INFORMATION_SCHEMA.innodb_lock_waits row */ diff --git a/storage/innobase/lock/lock0lock.c b/storage/innobase/lock/lock0lock.c index 04e5fe1a65a..8f29948dec7 100644 --- a/storage/innobase/lock/lock0lock.c +++ b/storage/innobase/lock/lock0lock.c @@ -1624,7 +1624,7 @@ UNIV_INTERN ulint lock_number_of_rows_locked( /*=======================*/ - trx_t* trx) /*!< in: transaction */ + const trx_t* trx) /*!< in: transaction */ { lock_t* lock; ulint n_records = 0; diff --git a/storage/innobase/trx/trx0i_s.c b/storage/innobase/trx/trx0i_s.c index ba8f998affd..937ce1b31f2 100644 --- a/storage/innobase/trx/trx0i_s.c +++ b/storage/innobase/trx/trx0i_s.c @@ -427,7 +427,7 @@ fill_trx_row( /*=========*/ i_s_trx_row_t* row, /*!< out: result object that's filled */ - const trx_t* trx, /*!< in: transaction to + const trx_t* trx, /*!< in: transaction to get data from */ const i_s_locks_row_t* requested_lock_row,/*!< in: pointer to the corresponding row in @@ -470,25 +470,8 @@ fill_trx_row( if (trx->mysql_query_str != NULL && *trx->mysql_query_str != NULL) { - if (strlen(*trx->mysql_query_str) - > TRX_I_S_TRX_QUERY_MAX_LEN) { - - char query[TRX_I_S_TRX_QUERY_MAX_LEN + 1]; - - memcpy(query, *trx->mysql_query_str, - TRX_I_S_TRX_QUERY_MAX_LEN); - query[TRX_I_S_TRX_QUERY_MAX_LEN] = '\0'; - - row->trx_query = ha_storage_put_memlim( - cache->storage, query, - TRX_I_S_TRX_QUERY_MAX_LEN + 1, - MAX_ALLOWED_FOR_STORAGE(cache)); - } else { - - row->trx_query = ha_storage_put_str_memlim( - cache->storage, *trx->mysql_query_str, - MAX_ALLOWED_FOR_STORAGE(cache)); - } + TRX_I_S_STRING_COPY(*trx->mysql_query_str, row->trx_query, + TRX_I_S_TRX_QUERY_MAX_LEN, cache); if (row->trx_query == NULL) { @@ -499,6 +482,74 @@ fill_trx_row( row->trx_query = NULL; } + if (trx->op_info != NULL && trx->op_info[0] != '\0') { + + TRX_I_S_STRING_COPY(trx->op_info, row->trx_operation_state, + TRX_I_S_TRX_OP_STATE_MAX_LEN, cache); + + if (row->trx_operation_state == NULL) { + + return(FALSE); + } + } else { + + row->trx_operation_state = NULL; + } + + row->trx_tables_in_use = trx->n_mysql_tables_in_use; + + row->trx_tables_locked = trx->mysql_n_tables_locked; + + row->trx_lock_structs = UT_LIST_GET_LEN(trx->trx_locks); + + row->trx_lock_memory_bytes = mem_heap_get_size(trx->lock_heap); + + row->trx_rows_locked = lock_number_of_rows_locked(trx); + + row->trx_rows_modified = ut_conv_dulint_to_longlong(trx->undo_no); + + row->trx_concurrency_tickets = trx->n_tickets_to_enter_innodb; + + switch (trx->isolation_level) { + case TRX_ISO_READ_UNCOMMITTED: + row->trx_isolation_level = "READ UNCOMMITTED"; + break; + case TRX_ISO_READ_COMMITTED: + row->trx_isolation_level = "READ COMMITTED"; + break; + case TRX_ISO_REPEATABLE_READ: + row->trx_isolation_level = "REPEATABLE READ"; + break; + case TRX_ISO_SERIALIZABLE: + row->trx_isolation_level = "SERIALIZABLE"; + break; + /* Should not happen as TRX_ISO_READ_COMMITTED is default */ + default: + row->trx_isolation_level = "UNKNOWN"; + } + + row->trx_unique_checks = (ibool) trx->check_unique_secondary; + + row->trx_foreign_key_checks = (ibool) trx->check_foreigns; + + if (trx->detailed_error != NULL && trx->detailed_error[0] != '\0') { + + TRX_I_S_STRING_COPY(trx->detailed_error, + row->trx_foreign_key_error, + TRX_I_S_TRX_FK_ERROR_MAX_LEN, cache); + + if (row->trx_foreign_key_error == NULL) { + + return(FALSE); + } + } else { + row->trx_foreign_key_error = NULL; + } + + row->trx_has_search_latch = (ibool) trx->has_search_latch; + + row->trx_search_latch_timeout = trx->search_latch_timeout; + return(TRUE); }