# name : innodb_deadlock_count.patch # introduced : 11 or before # maintainer : Yasufumi # #!!! notice !!! # Any small change to this file in the main branch # should be done or reviewed by the maintainer! --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -691,6 +691,8 @@ (char*) &export_vars.innodb_dblwr_pages_written, SHOW_LONG}, {"dblwr_writes", (char*) &export_vars.innodb_dblwr_writes, SHOW_LONG}, + {"deadlocks", + (char*) &export_vars.innodb_deadlocks, SHOW_LONG}, {"dict_tables", (char*) &export_vars.innodb_dict_tables, SHOW_LONG}, {"have_atomic_builtins", --- a/storage/innobase/include/lock0lock.h +++ b/storage/innobase/include/lock0lock.h @@ -43,6 +43,7 @@ #endif /* UNIV_DEBUG */ /* Buffer for storing information about the most recent deadlock error */ extern FILE* lock_latest_err_file; +extern ulint srv_n_lock_deadlock_count; /*********************************************************************//** Gets the size of a lock struct. --- a/storage/innobase/include/srv0srv.h +++ b/storage/innobase/include/srv0srv.h @@ -770,6 +770,7 @@ ulint innodb_buffer_pool_read_ahead_evicted;/*!< srv_read_ahead evicted*/ ulint innodb_dblwr_pages_written; /*!< srv_dblwr_pages_written */ ulint innodb_dblwr_writes; /*!< srv_dblwr_writes */ + ulint innodb_deadlocks; ibool innodb_have_atomic_builtins; /*!< HAVE_ATOMIC_BUILTINS */ ulint innodb_log_waits; /*!< srv_log_waits */ ulint innodb_log_write_requests; /*!< srv_log_write_requests */ --- a/storage/innobase/lock/lock0lock.c +++ b/storage/innobase/lock/lock0lock.c @@ -3330,6 +3330,7 @@ break; case LOCK_VICTIM_IS_START: + srv_n_lock_deadlock_count++; fputs("*** WE ROLL BACK TRANSACTION (2)\n", lock_latest_err_file); break; --- a/storage/innobase/srv/srv0srv.c +++ b/storage/innobase/srv/srv0srv.c @@ -477,6 +477,7 @@ static ulint srv_n_rows_deleted_old = 0; static ulint srv_n_rows_read_old = 0; +UNIV_INTERN ulint srv_n_lock_deadlock_count = 0; UNIV_INTERN ulint srv_n_lock_wait_count = 0; UNIV_INTERN ulint srv_n_lock_wait_current_count = 0; UNIV_INTERN ib_int64_t srv_n_lock_wait_time = 0; @@ -2293,6 +2294,7 @@ export_vars.innodb_buffer_pool_pages_data = LRU_len; export_vars.innodb_buffer_pool_pages_dirty = flush_list_len; export_vars.innodb_buffer_pool_pages_free = free_len; + export_vars.innodb_deadlocks = srv_n_lock_deadlock_count; #ifdef UNIV_DEBUG export_vars.innodb_buffer_pool_pages_latched = buf_get_latched_pages_number(); --- /dev/null +++ b/mysql-test/r/percona_innodb_deadlock_count.result @@ -0,0 +1,28 @@ +# Establish connection con1 (user=root) +# Establish connection con2 (user=root) +# Establish connection con3 (user=root) +# Drop test table +drop table if exists t; +# Create test table +create table t(a INT PRIMARY KEY, b INT) engine=InnoDB; +# Insert two rows to test table +insert into t values(2,1); +insert into t values(1,2); +# Switch to connection con1 +BEGIN; +SELECT b FROM t WHERE a=1 FOR UPDATE; +# Switch to connection con2 +BEGIN; +SELECT b FROM t WHERE a=2 FOR UPDATE; +# Switch to connection con1 +SELECT b FROM t WHERE a=2 FOR UPDATE; +# Switch to connection con2 +SELECT b FROM t WHERE a=1 FOR UPDATE; +# Switch to connection con1 +ROLLBACK; +# Switch to connection con2 +ROLLBACK; +# Switch to connection con3 +Deadlocks: 1 +# Drop test table +drop table t; --- /dev/null +++ b/mysql-test/t/percona_innodb_deadlock_count.test @@ -0,0 +1,61 @@ +--source include/have_innodb.inc +--echo # Establish connection con1 (user=root) +connect (con1,localhost,root,,); +--echo # Establish connection con2 (user=root) +connect (con2,localhost,root,,); +--echo # Establish connection con3 (user=root) +connect (con3,localhost,root,,); +--echo # Drop test table +--disable_warnings +drop table if exists t; +--enable_warnings + +--echo # Create test table +create table t(a INT PRIMARY KEY, b INT) engine=InnoDB; +--echo # Insert two rows to test table +insert into t values(2,1); +insert into t values(1,2); + +#--echo # Save current deadlock count +let $current = `SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'Innodb_deadlocks'`; + +--disable_result_log + +--echo # Switch to connection con1 +connection con1; +BEGIN; SELECT b FROM t WHERE a=1 FOR UPDATE; + +--echo # Switch to connection con2 +connection con2; +BEGIN; SELECT b FROM t WHERE a=2 FOR UPDATE; + +--echo # Switch to connection con1 +connection con1; +SEND SELECT b FROM t WHERE a=2 FOR UPDATE; + +--echo # Switch to connection con2 +connection con2; +SEND SELECT b FROM t WHERE a=1 FOR UPDATE; + +--echo # Switch to connection con1 +connection con1; +--error 0, ER_LOCK_DEADLOCK +reap; +ROLLBACK; + +--echo # Switch to connection con2 +connection con2; +--error 0, ER_LOCK_DEADLOCK +reap; +ROLLBACK; + +--echo # Switch to connection con3 +connection con3; +let $result = `SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'Innodb_deadlocks'`; + +--enable_result_log + +let $diff = `SELECT $result - $current`; +echo Deadlocks: $diff; +--echo # Drop test table +drop table t;