Commit 987e04d2 authored by Sergei Golubchik's avatar Sergei Golubchik

MDEV-117 Assertion: prebuilt->sql_stat_start || trx->conc_state == 1 failed at row0sel.c:3933

DELETE IGNORE should not ignore deadlocks

sql/mdl.cc:
  more DBUG_ENTER/DBUG_RETURN
sql/sql_base.cc:
  more DBUG_ENTER/DBUG_RETURN
parent f8a54c4a
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;
#
# 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;
......@@ -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;
......
......@@ -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 @@ bool MDL_context::acquire_locks(MDL_request_list *mdl_requests,
(*p_req)->ticket= NULL;
}
my_free(sort_buf);
return TRUE;
DBUG_RETURN(TRUE);
}
......
......@@ -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);
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment