Commit e7e20585 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 c0a43775
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) ...@@ -2970,6 +2970,8 @@ void handler::print_error(int error, myf errflag)
break; break;
case HA_ERR_LOCK_DEADLOCK: case HA_ERR_LOCK_DEADLOCK:
textno=ER_LOCK_DEADLOCK; textno=ER_LOCK_DEADLOCK;
/* cannot continue. the statement was already aborted in the engine */
SET_FATAL_ERROR;
break; break;
case HA_ERR_READ_ONLY_TRANSACTION: case HA_ERR_READ_ONLY_TRANSACTION:
textno=ER_READ_ONLY_TRANSACTION; textno=ER_READ_ONLY_TRANSACTION;
......
...@@ -1145,6 +1145,7 @@ MDL_wait::timed_wait(THD *thd, struct timespec *abs_timeout, ...@@ -1145,6 +1145,7 @@ MDL_wait::timed_wait(THD *thd, struct timespec *abs_timeout,
const char *old_msg; const char *old_msg;
enum_wait_status result; enum_wait_status result;
int wait_result= 0; int wait_result= 0;
DBUG_ENTER("MDL_wait::timed_wait");
mysql_mutex_lock(&m_LOCK_wait_status); mysql_mutex_lock(&m_LOCK_wait_status);
...@@ -1183,7 +1184,7 @@ MDL_wait::timed_wait(THD *thd, struct timespec *abs_timeout, ...@@ -1183,7 +1184,7 @@ MDL_wait::timed_wait(THD *thd, struct timespec *abs_timeout,
thd_exit_cond(thd, old_msg); 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) ...@@ -1937,11 +1938,13 @@ MDL_context::acquire_lock(MDL_request *mdl_request, ulong lock_wait_timeout)
MDL_ticket *ticket; MDL_ticket *ticket;
struct timespec abs_timeout; struct timespec abs_timeout;
MDL_wait::enum_wait_status wait_status; MDL_wait::enum_wait_status wait_status;
DBUG_ENTER("MDL_context::acquire_lock");
/* Do some work outside the critical section. */ /* Do some work outside the critical section. */
set_timespec(abs_timeout, lock_wait_timeout); set_timespec(abs_timeout, lock_wait_timeout);
if (try_acquire_lock_impl(mdl_request, &ticket)) if (try_acquire_lock_impl(mdl_request, &ticket))
return TRUE; DBUG_RETURN(TRUE);
if (mdl_request->ticket) if (mdl_request->ticket)
{ {
...@@ -1950,7 +1953,7 @@ MDL_context::acquire_lock(MDL_request *mdl_request, ulong lock_wait_timeout) ...@@ -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 MDL_lock, MDL_context and MDL_request were updated
accordingly, so we can simply return success. 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) ...@@ -2031,7 +2034,7 @@ MDL_context::acquire_lock(MDL_request *mdl_request, ulong lock_wait_timeout)
DBUG_ASSERT(0); DBUG_ASSERT(0);
break; break;
} }
return TRUE; DBUG_RETURN(TRUE);
} }
/* /*
...@@ -2046,7 +2049,7 @@ MDL_context::acquire_lock(MDL_request *mdl_request, ulong lock_wait_timeout) ...@@ -2046,7 +2049,7 @@ MDL_context::acquire_lock(MDL_request *mdl_request, ulong lock_wait_timeout)
mdl_request->ticket= ticket; mdl_request->ticket= ticket;
return FALSE; DBUG_RETURN(FALSE);
} }
...@@ -2085,15 +2088,16 @@ bool MDL_context::acquire_locks(MDL_request_list *mdl_requests, ...@@ -2085,15 +2088,16 @@ bool MDL_context::acquire_locks(MDL_request_list *mdl_requests,
MDL_request **sort_buf, **p_req; MDL_request **sort_buf, **p_req;
MDL_savepoint mdl_svp= mdl_savepoint(); MDL_savepoint mdl_svp= mdl_savepoint();
ssize_t req_count= static_cast<ssize_t>(mdl_requests->elements()); ssize_t req_count= static_cast<ssize_t>(mdl_requests->elements());
DBUG_ENTER("MDL_context::acquire_locks");
if (req_count == 0) if (req_count == 0)
return FALSE; DBUG_RETURN(FALSE);
/* Sort requests according to MDL_key. */ /* Sort requests according to MDL_key. */
if (! (sort_buf= (MDL_request **)my_malloc(req_count * if (! (sort_buf= (MDL_request **)my_malloc(req_count *
sizeof(MDL_request*), sizeof(MDL_request*),
MYF(MY_WME)))) MYF(MY_WME))))
return TRUE; DBUG_RETURN(TRUE);
for (p_req= sort_buf; p_req < sort_buf + req_count; p_req++) for (p_req= sort_buf; p_req < sort_buf + req_count; p_req++)
*p_req= it++; *p_req= it++;
...@@ -2107,7 +2111,7 @@ bool MDL_context::acquire_locks(MDL_request_list *mdl_requests, ...@@ -2107,7 +2111,7 @@ bool MDL_context::acquire_locks(MDL_request_list *mdl_requests,
goto err; goto err;
} }
my_free(sort_buf); my_free(sort_buf);
return FALSE; DBUG_RETURN(FALSE);
err: err:
/* /*
...@@ -2123,7 +2127,7 @@ err: ...@@ -2123,7 +2127,7 @@ err:
(*p_req)->ticket= NULL; (*p_req)->ticket= NULL;
} }
my_free(sort_buf); my_free(sort_buf);
return TRUE; DBUG_RETURN(TRUE);
} }
......
...@@ -4678,6 +4678,7 @@ lock_table_names(THD *thd, ...@@ -4678,6 +4678,7 @@ lock_table_names(THD *thd,
TABLE_LIST *table; TABLE_LIST *table;
MDL_request global_request; MDL_request global_request;
Hash_set<TABLE_LIST, schema_set_get_key> schema_set; Hash_set<TABLE_LIST, schema_set_get_key> schema_set;
DBUG_ENTER("lock_table_names");
DBUG_ASSERT(!thd->locked_tables_mode); DBUG_ASSERT(!thd->locked_tables_mode);
...@@ -4693,7 +4694,7 @@ lock_table_names(THD *thd, ...@@ -4693,7 +4694,7 @@ lock_table_names(THD *thd,
{ {
if (! (flags & MYSQL_OPEN_SKIP_SCOPED_MDL_LOCK) && if (! (flags & MYSQL_OPEN_SKIP_SCOPED_MDL_LOCK) &&
schema_set.insert(table)) schema_set.insert(table))
return TRUE; DBUG_RETURN(TRUE);
mdl_requests.push_front(&table->mdl_request); mdl_requests.push_front(&table->mdl_request);
} }
} }
...@@ -4710,7 +4711,7 @@ lock_table_names(THD *thd, ...@@ -4710,7 +4711,7 @@ lock_table_names(THD *thd,
{ {
MDL_request *schema_request= new (thd->mem_root) MDL_request; MDL_request *schema_request= new (thd->mem_root) MDL_request;
if (schema_request == NULL) if (schema_request == NULL)
return TRUE; DBUG_RETURN(TRUE);
schema_request->init(MDL_key::SCHEMA, table->db, "", schema_request->init(MDL_key::SCHEMA, table->db, "",
MDL_INTENTION_EXCLUSIVE, MDL_INTENTION_EXCLUSIVE,
MDL_TRANSACTION); MDL_TRANSACTION);
...@@ -4723,16 +4724,16 @@ lock_table_names(THD *thd, ...@@ -4723,16 +4724,16 @@ lock_table_names(THD *thd,
duration. duration.
*/ */
if (thd->global_read_lock.can_acquire_protection()) if (thd->global_read_lock.can_acquire_protection())
return TRUE; DBUG_RETURN(TRUE);
global_request.init(MDL_key::GLOBAL, "", "", MDL_INTENTION_EXCLUSIVE, global_request.init(MDL_key::GLOBAL, "", "", MDL_INTENTION_EXCLUSIVE,
MDL_STATEMENT); MDL_STATEMENT);
mdl_requests.push_front(&global_request); mdl_requests.push_front(&global_request);
} }
if (thd->mdl_context.acquire_locks(&mdl_requests, lock_wait_timeout)) 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