mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
MDEV-23328 Server hang due to Galera lock conflict resolution
Cherry-pick the sql_kill and sql_user_kill from ef2dbb8dbc
Changed ER_CANNOT_USER to ER_KILL_DENIED_ERROR to match
other kill denied user messages.
Cherry-pick by Daniel Black.
Reviewed-by: Jan Lindström <jan.lindstrom@mariadb.com>
This commit is contained in:
@ -9203,6 +9203,7 @@ THD *find_thread_by_id(longlong id, bool query_id)
|
|||||||
return arg.thd;
|
return arg.thd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
kill one thread.
|
kill one thread.
|
||||||
|
|
||||||
@ -9246,7 +9247,8 @@ kill_one_thread(THD *thd, longlong id, killed_state kill_signal, killed_type typ
|
|||||||
faster and do a harder kill than KILL_SYSTEM_THREAD;
|
faster and do a harder kill than KILL_SYSTEM_THREAD;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
mysql_mutex_lock(&tmp->LOCK_thd_data); // for various wsrep* checks below
|
mysql_mutex_lock(&tmp->LOCK_thd_data); // Lock from concurrent usage
|
||||||
|
|
||||||
#ifdef WITH_WSREP
|
#ifdef WITH_WSREP
|
||||||
if (((thd->security_ctx->master_access & PRIV_KILL_OTHER_USER_PROCESS) ||
|
if (((thd->security_ctx->master_access & PRIV_KILL_OTHER_USER_PROCESS) ||
|
||||||
thd->security_ctx->user_matches(tmp->security_ctx)) &&
|
thd->security_ctx->user_matches(tmp->security_ctx)) &&
|
||||||
@ -9261,23 +9263,23 @@ kill_one_thread(THD *thd, longlong id, killed_state kill_signal, killed_type typ
|
|||||||
if (tmp->wsrep_aborter && tmp->wsrep_aborter != thd->thread_id)
|
if (tmp->wsrep_aborter && tmp->wsrep_aborter != thd->thread_id)
|
||||||
{
|
{
|
||||||
/* victim is in hit list already, bail out */
|
/* victim is in hit list already, bail out */
|
||||||
WSREP_DEBUG("victim has wsrep aborter: %lu, skipping awake()",
|
WSREP_DEBUG("victim %lld has wsrep aborter: %lu, skipping awake()",
|
||||||
tmp->wsrep_aborter);
|
id, tmp->wsrep_aborter);
|
||||||
error= 0;
|
error= 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif /* WITH_WSREP */
|
#endif /* WITH_WSREP */
|
||||||
{
|
{
|
||||||
WSREP_DEBUG("kill_one_thread %llu, victim: %llu wsrep_aborter %llu by signal %d",
|
WSREP_DEBUG("kill_one_thread victim: %lld wsrep_aborter %lu by signal %d",
|
||||||
thd->thread_id, id, tmp->wsrep_aborter, kill_signal);
|
id, tmp->wsrep_aborter, kill_signal);
|
||||||
tmp->awake_no_mutex(kill_signal);
|
tmp->awake_no_mutex(kill_signal);
|
||||||
WSREP_DEBUG("victim: %llu taken care of", id);
|
|
||||||
error= 0;
|
error= 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
error= (type == KILL_TYPE_QUERY ? ER_KILL_QUERY_DENIED_ERROR :
|
error= (type == KILL_TYPE_QUERY ? ER_KILL_QUERY_DENIED_ERROR :
|
||||||
ER_KILL_DENIED_ERROR);
|
ER_KILL_DENIED_ERROR);
|
||||||
|
|
||||||
mysql_mutex_unlock(&tmp->LOCK_thd_data);
|
mysql_mutex_unlock(&tmp->LOCK_thd_data);
|
||||||
}
|
}
|
||||||
mysql_mutex_unlock(&tmp->LOCK_thd_kill);
|
mysql_mutex_unlock(&tmp->LOCK_thd_kill);
|
||||||
@ -9392,6 +9394,18 @@ static
|
|||||||
void sql_kill(THD *thd, longlong id, killed_state state, killed_type type)
|
void sql_kill(THD *thd, longlong id, killed_state state, killed_type type)
|
||||||
{
|
{
|
||||||
uint error;
|
uint error;
|
||||||
|
#ifdef WITH_WSREP
|
||||||
|
if (WSREP(thd))
|
||||||
|
{
|
||||||
|
WSREP_DEBUG("sql_kill called");
|
||||||
|
if (thd->wsrep_applier)
|
||||||
|
{
|
||||||
|
WSREP_DEBUG("KILL in applying, bailing out here");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL)
|
||||||
|
}
|
||||||
|
#endif /* WITH_WSREP */
|
||||||
if (likely(!(error= kill_one_thread(thd, id, state, type))))
|
if (likely(!(error= kill_one_thread(thd, id, state, type))))
|
||||||
{
|
{
|
||||||
if (!thd->killed)
|
if (!thd->killed)
|
||||||
@ -9401,6 +9415,11 @@ void sql_kill(THD *thd, longlong id, killed_state state, killed_type type)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
my_error(error, MYF(0), id);
|
my_error(error, MYF(0), id);
|
||||||
|
#ifdef WITH_WSREP
|
||||||
|
return;
|
||||||
|
wsrep_error_label:
|
||||||
|
my_error(ER_KILL_DENIED_ERROR, MYF(0), (long long) thd->thread_id);
|
||||||
|
#endif /* WITH_WSREP */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -9409,6 +9428,18 @@ sql_kill_user(THD *thd, LEX_USER *user, killed_state state)
|
|||||||
{
|
{
|
||||||
uint error;
|
uint error;
|
||||||
ha_rows rows;
|
ha_rows rows;
|
||||||
|
#ifdef WITH_WSREP
|
||||||
|
if (WSREP(thd))
|
||||||
|
{
|
||||||
|
WSREP_DEBUG("sql_kill_user called");
|
||||||
|
if (thd->wsrep_applier)
|
||||||
|
{
|
||||||
|
WSREP_DEBUG("KILL in applying, bailing out here");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL)
|
||||||
|
}
|
||||||
|
#endif /* WITH_WSREP */
|
||||||
switch (error= kill_threads_for_user(thd, user, state, &rows))
|
switch (error= kill_threads_for_user(thd, user, state, &rows))
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
@ -9421,6 +9452,11 @@ sql_kill_user(THD *thd, LEX_USER *user, killed_state state)
|
|||||||
default:
|
default:
|
||||||
my_error(error, MYF(0));
|
my_error(error, MYF(0));
|
||||||
}
|
}
|
||||||
|
#ifdef WITH_WSREP
|
||||||
|
return;
|
||||||
|
wsrep_error_label:
|
||||||
|
my_error(ER_KILL_DENIED_ERROR, MYF(0), (long long) thd->thread_id);
|
||||||
|
#endif /* WITH_WSREP */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user