diff options
author | mkaruza <mario.karuza@galeracluster.com> | 2020-06-02 09:18:59 +0200 |
---|---|---|
committer | Jan Lindström <jan.lindstrom@mariadb.com> | 2020-07-24 12:05:39 +0300 |
commit | 4b4372af6a6e2e3c37220487bdb671054357698e (patch) | |
tree | a26bf55738600e42175af1d9de08593885b7f2bc | |
parent | 6b8b7b1e8cd876f798df10015c9853da8adb00f8 (diff) | |
download | mariadb-git-4b4372af6a6e2e3c37220487bdb671054357698e.tar.gz |
MDEV-22458: Server with WSREP hangs after INSERT, wrong usage of mutex 'LOCK_thd_data' and 'share->intern_lock' / 'lock->mutex'
Add `find_thread_by_id_with_thd_data_lock` which will be used only when killing thread.
This version needs to take `thd->LOCK_thd_data` lock.
-rw-r--r-- | mysql-test/suite/galera/r/MDEV-22458.result | 10 | ||||
-rw-r--r-- | mysql-test/suite/galera/t/MDEV-22458.test | 21 | ||||
-rw-r--r-- | sql/sql_parse.cc | 28 |
3 files changed, 57 insertions, 2 deletions
diff --git a/mysql-test/suite/galera/r/MDEV-22458.result b/mysql-test/suite/galera/r/MDEV-22458.result new file mode 100644 index 00000000000..d1f9d94bd1c --- /dev/null +++ b/mysql-test/suite/galera/r/MDEV-22458.result @@ -0,0 +1,10 @@ +connection node_2; +connection node_1; +CREATE TABLE t1 (a INT); +connect con1,localhost,root,,test; +INSERT INTO t1 VALUES (1),(2),(3),(4); +SHOW EXPLAIN FOR $con1; +ERROR HY000: Target is not running an EXPLAINable command +connection con1; +INSERT INTO t1 VALUES (5),(6),(7),(8); +DROP TABLE t1; diff --git a/mysql-test/suite/galera/t/MDEV-22458.test b/mysql-test/suite/galera/t/MDEV-22458.test new file mode 100644 index 00000000000..8f9ba1bb107 --- /dev/null +++ b/mysql-test/suite/galera/t/MDEV-22458.test @@ -0,0 +1,21 @@ +# MDEV-22458 +# +# When running SHOW command, thread lock `LOCK_thd_data` should not be taken. +# Lock will be taken only when we are killing thread +# + +--source include/galera_cluster.inc +CREATE TABLE t1 (a INT); + +--connect (con1,localhost,root,,test) +--let $con1 = `SELECT CONNECTION_ID()` + +INSERT INTO t1 VALUES (1),(2),(3),(4); + +--error ER_TARGET_NOT_EXPLAINABLE +EVALP SHOW EXPLAIN FOR $con1; + +--connection con1 +INSERT INTO t1 VALUES (5),(6),(7),(8); + +DROP TABLE t1; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 3c5c52e2aa1..4596915b096 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -9019,7 +9019,6 @@ my_bool find_thread_callback(THD *thd, find_thread_callback_arg *arg) if (thd->get_command() != COM_DAEMON && arg->id == (arg->query_id ? thd->query_id : (longlong) thd->thread_id)) { - if (WSREP(thd)) mysql_mutex_lock(&thd->LOCK_thd_data); mysql_mutex_lock(&thd->LOCK_thd_kill); // Lock from delete arg->thd= thd; return 1; @@ -9035,6 +9034,26 @@ THD *find_thread_by_id(longlong id, bool query_id) return arg.thd; } +#ifdef WITH_WSREP +my_bool find_thread_with_thd_data_lock_callback(THD *thd, find_thread_callback_arg *arg) +{ + if (thd->get_command() != COM_DAEMON && + arg->id == (arg->query_id ? thd->query_id : (longlong) thd->thread_id)) + { + if (WSREP(thd)) mysql_mutex_lock(&thd->LOCK_thd_data); + mysql_mutex_lock(&thd->LOCK_thd_kill); // Lock from delete + arg->thd= thd; + return 1; + } + return 0; +} +THD *find_thread_by_id_with_thd_data_lock(longlong id, bool query_id) +{ + find_thread_callback_arg arg(id, query_id); + server_threads.iterate(find_thread_with_thd_data_lock_callback, &arg); + return arg.thd; +} +#endif /** kill one thread. @@ -9052,7 +9071,11 @@ kill_one_thread(THD *thd, longlong id, killed_state kill_signal, killed_type typ uint error= (type == KILL_TYPE_QUERY ? ER_NO_SUCH_QUERY : ER_NO_SUCH_THREAD); DBUG_ENTER("kill_one_thread"); DBUG_PRINT("enter", ("id: %lld signal: %u", id, (uint) kill_signal)); +#ifdef WITH_WSREP + if (id && (tmp= find_thread_by_id_with_thd_data_lock(id, type == KILL_TYPE_QUERY))) +#else if (id && (tmp= find_thread_by_id(id, type == KILL_TYPE_QUERY))) +#endif { /* If we're SUPER, we can KILL anything, including system-threads. @@ -9106,8 +9129,9 @@ kill_one_thread(THD *thd, longlong id, killed_state kill_signal, killed_type typ else error= (type == KILL_TYPE_QUERY ? ER_KILL_QUERY_DENIED_ERROR : ER_KILL_DENIED_ERROR); - +#ifdef WITH_WSREP if (WSREP(tmp)) mysql_mutex_unlock(&tmp->LOCK_thd_data); +#endif mysql_mutex_unlock(&tmp->LOCK_thd_kill); } DBUG_PRINT("exit", ("%d", error)); |