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
This commit is contained in:
parent
c75eec8e0d
commit
73ebabd2ee
@ -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 @@ public:
|
||||
|
||||
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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user