Commit 73ebabd2 authored by Sergei Golubchik's avatar Sergei Golubchik

MDEV-7299 Assertion `m_status == DA_ERROR || m_status == DA_OK' fails on...

MDEV-7299 Assertion `m_status == DA_ERROR || m_status == DA_OK' fails on concurrent execution of DDL, queries from I_S, and KILL QUERY

Fix MDL to report an error when a wait was killed, but preserve
the old documented behavior of GET_LOCK() where killing it is not an error.

Also remove race conditions in main.create_or_replace test
parent c75eec8e
......@@ -436,7 +436,9 @@ CREATE OR REPLACE TEMPORARY TABLE tmp LIKE t1;
LOCK TABLE t1 WRITE;
CREATE OR REPLACE TABLE t1 LIKE tmp;
KILL QUERY con_id;
ERROR 70100: Query execution was interrupted
CREATE OR REPLACE TABLE t1 (a int);
KILL QUERY con_id;
ERROR 70100: Query execution was interrupted
drop table t1;
DROP TABLE t2;
......@@ -346,20 +346,26 @@ LOCK TABLE t1 WRITE;
--let $con_id = `SELECT CONNECTION_ID()`
--send CREATE OR REPLACE TABLE t1 LIKE tmp
--connection default
let $wait_condition= SELECT COUNT(*)=1 FROM information_schema.processlist
WHERE state= 'Waiting for table metadata lock';
--source include/wait_condition.inc
--replace_result $con_id con_id
--eval KILL QUERY $con_id
--connection con1
--error 0,ER_QUERY_INTERRUPTED
--error ER_QUERY_INTERRUPTED
--reap
--send CREATE OR REPLACE TABLE t1 (a int)
--connection default
let $wait_condition= SELECT COUNT(*)=1 FROM information_schema.processlist
WHERE state= 'Waiting for table metadata lock';
--source include/wait_condition.inc
--replace_result $con_id con_id
--eval KILL QUERY $con_id
--connection con1
--error 0,ER_QUERY_INTERRUPTED
--error ER_QUERY_INTERRUPTED
--reap
--disconnect con1
--connection default
......
......@@ -4179,9 +4179,10 @@ void mysql_ull_set_explicit_lock_duration(THD *thd)
When MDL detects a lock wait timeout, it pushes
an error into the statement diagnostics area.
For GET_LOCK(), lock wait timeout is not an error,
but a special return value (0). NULL is returned in
case of error.
Capture and suppress lock wait timeout.
but a special return value (0).
Similarly, killing get_lock wait is not an error either,
but a return value NULL.
Capture and suppress lock wait timeouts and kills.
*/
class Lock_wait_timeout_handler: public Internal_error_handler
......@@ -4200,7 +4201,7 @@ class Lock_wait_timeout_handler: public Internal_error_handler
bool
Lock_wait_timeout_handler::
handle_condition(THD * /* thd */, uint sql_errno,
handle_condition(THD *thd, uint sql_errno,
const char * /* sqlstate */,
Sql_condition::enum_warning_level /* level */,
const char *message,
......@@ -4211,6 +4212,9 @@ handle_condition(THD * /* thd */, uint sql_errno,
m_lock_wait_timeout= true;
return true; /* condition handled */
}
if (thd->is_killed())
return true;
return false;
}
......
......@@ -2413,6 +2413,7 @@ MDL_context::acquire_lock(MDL_request *mdl_request, ulong lock_wait_timeout)
my_error(ER_LOCK_WAIT_TIMEOUT, MYF(0));
break;
case MDL_wait::KILLED:
get_thd()->send_kill_message();
break;
default:
DBUG_ASSERT(0);
......
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