diff options
-rw-r--r-- | mysql-test/suite/innodb/r/mdev-117.result | 12 | ||||
-rw-r--r-- | mysql-test/suite/innodb/t/mdev-117.test | 30 | ||||
-rw-r--r-- | sql/handler.cc | 2 | ||||
-rw-r--r-- | sql/mdl.cc | 22 | ||||
-rw-r--r-- | sql/sql_base.cc | 11 |
5 files changed, 63 insertions, 14 deletions
diff --git a/mysql-test/suite/innodb/r/mdev-117.result b/mysql-test/suite/innodb/r/mdev-117.result new file mode 100644 index 00000000000..40c63b5ae38 --- /dev/null +++ b/mysql-test/suite/innodb/r/mdev-117.result @@ -0,0 +1,12 @@ +SET GLOBAL innodb_lock_wait_timeout=3; +CREATE TABLE t1 (col_int_key INT, KEY (col_int_key)) ENGINE=InnoDB; +INSERT INTO t1 VALUES (6); +SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE; +SET AUTOCOMMIT=OFF; +SELECT col_int_key FROM t1; +col_int_key +6 +DELETE IGNORE FROM t1;; +DELETE FROM t1 WHERE col_int_key IN (1, 40000000); +drop table t1; +SET GLOBAL innodb_lock_wait_timeout=default; diff --git a/mysql-test/suite/innodb/t/mdev-117.test b/mysql-test/suite/innodb/t/mdev-117.test new file mode 100644 index 00000000000..ae7fbc021f6 --- /dev/null +++ b/mysql-test/suite/innodb/t/mdev-117.test @@ -0,0 +1,30 @@ +# +# verify that DELETE IGNORE does not ignore deadlocks +# + +--source include/have_innodb.inc + +SET GLOBAL innodb_lock_wait_timeout=3; + +CREATE TABLE t1 (col_int_key INT, KEY (col_int_key)) ENGINE=InnoDB; +INSERT INTO t1 VALUES (6); + +--connect (con1,localhost,root,,test) +SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE; +SET AUTOCOMMIT=OFF; +SELECT col_int_key FROM t1; + +--connection default +--send DELETE IGNORE FROM t1; + +--connection con1 +--error 0,1213 +DELETE FROM t1 WHERE col_int_key IN (1, 40000000); + +--connection default +--error 0,1213 +--reap + +--disconnect con1 +drop table t1; +SET GLOBAL innodb_lock_wait_timeout=default; diff --git a/sql/handler.cc b/sql/handler.cc index 50db743a8ff..516f61c8700 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -2970,6 +2970,8 @@ void handler::print_error(int error, myf errflag) break; case HA_ERR_LOCK_DEADLOCK: textno=ER_LOCK_DEADLOCK; + /* cannot continue. the statement was already aborted in the engine */ + SET_FATAL_ERROR; break; case HA_ERR_READ_ONLY_TRANSACTION: textno=ER_READ_ONLY_TRANSACTION; diff --git a/sql/mdl.cc b/sql/mdl.cc index 9b846f4e657..ca552a540b9 100644 --- a/sql/mdl.cc +++ b/sql/mdl.cc @@ -1145,6 +1145,7 @@ MDL_wait::timed_wait(THD *thd, struct timespec *abs_timeout, const char *old_msg; enum_wait_status result; int wait_result= 0; + DBUG_ENTER("MDL_wait::timed_wait"); mysql_mutex_lock(&m_LOCK_wait_status); @@ -1183,7 +1184,7 @@ MDL_wait::timed_wait(THD *thd, struct timespec *abs_timeout, thd_exit_cond(thd, old_msg); - return result; + DBUG_RETURN(result); } @@ -1937,11 +1938,13 @@ MDL_context::acquire_lock(MDL_request *mdl_request, ulong lock_wait_timeout) MDL_ticket *ticket; struct timespec abs_timeout; MDL_wait::enum_wait_status wait_status; + DBUG_ENTER("MDL_context::acquire_lock"); + /* Do some work outside the critical section. */ set_timespec(abs_timeout, lock_wait_timeout); if (try_acquire_lock_impl(mdl_request, &ticket)) - return TRUE; + DBUG_RETURN(TRUE); if (mdl_request->ticket) { @@ -1950,7 +1953,7 @@ MDL_context::acquire_lock(MDL_request *mdl_request, ulong lock_wait_timeout) MDL_lock, MDL_context and MDL_request were updated accordingly, so we can simply return success. */ - return FALSE; + DBUG_RETURN(FALSE); } /* @@ -2031,7 +2034,7 @@ MDL_context::acquire_lock(MDL_request *mdl_request, ulong lock_wait_timeout) DBUG_ASSERT(0); break; } - return TRUE; + DBUG_RETURN(TRUE); } /* @@ -2046,7 +2049,7 @@ MDL_context::acquire_lock(MDL_request *mdl_request, ulong lock_wait_timeout) mdl_request->ticket= ticket; - return FALSE; + DBUG_RETURN(FALSE); } @@ -2085,15 +2088,16 @@ bool MDL_context::acquire_locks(MDL_request_list *mdl_requests, MDL_request **sort_buf, **p_req; MDL_savepoint mdl_svp= mdl_savepoint(); ssize_t req_count= static_cast<ssize_t>(mdl_requests->elements()); + DBUG_ENTER("MDL_context::acquire_locks"); if (req_count == 0) - return FALSE; + DBUG_RETURN(FALSE); /* Sort requests according to MDL_key. */ if (! (sort_buf= (MDL_request **)my_malloc(req_count * sizeof(MDL_request*), MYF(MY_WME)))) - return TRUE; + DBUG_RETURN(TRUE); for (p_req= sort_buf; p_req < sort_buf + req_count; p_req++) *p_req= it++; @@ -2107,7 +2111,7 @@ bool MDL_context::acquire_locks(MDL_request_list *mdl_requests, goto err; } my_free(sort_buf); - return FALSE; + DBUG_RETURN(FALSE); err: /* @@ -2123,7 +2127,7 @@ err: (*p_req)->ticket= NULL; } my_free(sort_buf); - return TRUE; + DBUG_RETURN(TRUE); } diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 3167cb7363d..9d758829111 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -4678,6 +4678,7 @@ lock_table_names(THD *thd, TABLE_LIST *table; MDL_request global_request; Hash_set<TABLE_LIST, schema_set_get_key> schema_set; + DBUG_ENTER("lock_table_names"); DBUG_ASSERT(!thd->locked_tables_mode); @@ -4693,7 +4694,7 @@ lock_table_names(THD *thd, { if (! (flags & MYSQL_OPEN_SKIP_SCOPED_MDL_LOCK) && schema_set.insert(table)) - return TRUE; + DBUG_RETURN(TRUE); mdl_requests.push_front(&table->mdl_request); } } @@ -4710,7 +4711,7 @@ lock_table_names(THD *thd, { MDL_request *schema_request= new (thd->mem_root) MDL_request; if (schema_request == NULL) - return TRUE; + DBUG_RETURN(TRUE); schema_request->init(MDL_key::SCHEMA, table->db, "", MDL_INTENTION_EXCLUSIVE, MDL_TRANSACTION); @@ -4723,16 +4724,16 @@ lock_table_names(THD *thd, duration. */ if (thd->global_read_lock.can_acquire_protection()) - return TRUE; + DBUG_RETURN(TRUE); global_request.init(MDL_key::GLOBAL, "", "", MDL_INTENTION_EXCLUSIVE, MDL_STATEMENT); mdl_requests.push_front(&global_request); } if (thd->mdl_context.acquire_locks(&mdl_requests, lock_wait_timeout)) - return TRUE; + DBUG_RETURN(TRUE); - return FALSE; + DBUG_RETURN(FALSE); } |