mirror of
https://github.com/MariaDB/server.git
synced 2026-01-06 05:22:24 +03:00
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.
This commit is contained in:
@@ -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));
|
||||
|
||||
Reference in New Issue
Block a user