don't take mutexes conditionally

This commit is contained in:
Sergei Golubchik 2021-02-05 14:59:27 +01:00
parent 259a1902a0
commit 9703cffa8c
8 changed files with 16 additions and 40 deletions

View File

@ -9049,16 +9049,14 @@ int Xid_log_event::do_apply_event(rpl_group_info *rgi)
res= trans_commit(thd); /* Automatically rolls back on error. */
thd->release_transactional_locks();
mysql_mutex_lock(&thd->LOCK_thd_data);
#ifdef WITH_WSREP
if (WSREP(thd)) mysql_mutex_lock(&thd->LOCK_thd_data);
if ((!res || (WSREP(thd) && thd->wsrep_trx().state() == wsrep::transaction::s_must_replay )) && sub_id)
if (sub_id && (!res || (WSREP(thd) && thd->wsrep_trx().state() == wsrep::transaction::s_must_replay)))
#else
if (likely(!res) && sub_id)
if (sub_id && !res)
#endif /* WITH_WSREP */
rpl_global_gtid_slave_state->update_state_hash(sub_id, &gtid, hton, rgi);
#ifdef WITH_WSREP
if (WSREP(thd)) mysql_mutex_unlock(&thd->LOCK_thd_data);
#endif /* WITH_WSREP */
mysql_mutex_unlock(&thd->LOCK_thd_data);
/*
Increment the global status commit count variable
*/

View File

@ -1521,11 +1521,9 @@ static void end_ssl();
/* common callee of two shutdown phases */
static void kill_thread(THD *thd)
{
if (WSREP(thd)) mysql_mutex_lock(&thd->LOCK_thd_data);
mysql_mutex_lock(&thd->LOCK_thd_kill);
thd->abort_current_cond_wait(true);
mysql_mutex_unlock(&thd->LOCK_thd_kill);
if (WSREP(thd)) mysql_mutex_unlock(&thd->LOCK_thd_data);
}

View File

@ -1069,11 +1069,7 @@ terminate_slave_thread(THD *thd,
int error __attribute__((unused));
DBUG_PRINT("loop", ("killing slave thread"));
#ifdef WITH_WSREP
/* awake_no_mutex() requires LOCK_thd_data to be locked if wsrep
is enabled */
if (WSREP(thd)) mysql_mutex_lock(&thd->LOCK_thd_data);
#endif /* WITH_WSREP */
mysql_mutex_lock(&thd->LOCK_thd_data);
mysql_mutex_lock(&thd->LOCK_thd_kill);
#ifndef DONT_USE_THR_ALARM
/*
@ -1087,9 +1083,7 @@ terminate_slave_thread(THD *thd,
thd->awake_no_mutex(NOT_KILLED);
mysql_mutex_unlock(&thd->LOCK_thd_kill);
#ifdef WITH_WSREP
if (WSREP(thd)) mysql_mutex_unlock(&thd->LOCK_thd_data);
#endif /* WITH_WSREP */
mysql_mutex_unlock(&thd->LOCK_thd_data);
/*
There is a small chance that slave thread might miss the first

View File

@ -1868,7 +1868,7 @@ void THD::awake_no_mutex(killed_state state_to_set)
DBUG_PRINT("enter", ("this: %p current_thd: %p state: %d",
this, current_thd, (int) state_to_set));
THD_CHECK_SENTRY(this);
if (WSREP_NNULL(this)) mysql_mutex_assert_owner(&LOCK_thd_data);
mysql_mutex_assert_owner(&LOCK_thd_data);
mysql_mutex_assert_owner(&LOCK_thd_kill);
print_aborted_warning(3, "KILLED");

View File

@ -3309,18 +3309,11 @@ public:
void awake_no_mutex(killed_state state_to_set);
void awake(killed_state state_to_set)
{
bool wsrep_on_local= variables.wsrep_on;
/*
mutex locking order (LOCK_thd_data - LOCK_thd_kill)) requires
to grab LOCK_thd_data here
*/
if (wsrep_on_local)
mysql_mutex_lock(&LOCK_thd_data);
mysql_mutex_lock(&LOCK_thd_data);
mysql_mutex_lock(&LOCK_thd_kill);
awake_no_mutex(state_to_set);
mysql_mutex_unlock(&LOCK_thd_kill);
if (wsrep_on_local)
mysql_mutex_unlock(&LOCK_thd_data);
mysql_mutex_unlock(&LOCK_thd_data);
}
void abort_current_cond_wait(bool force);

View File

@ -9098,12 +9098,11 @@ THD *find_thread_by_id(longlong id, bool query_id)
return arg.thd;
}
#ifdef WITH_WSREP
static my_bool find_thread_with_thd_data_lock_callback(THD *thd, find_thread_callback_arg *arg)
{
if (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_data);
mysql_mutex_lock(&thd->LOCK_thd_kill); // Lock from delete
arg->thd= thd;
return 1;
@ -9116,7 +9115,6 @@ THD *find_thread_by_id_with_thd_data_lock(longlong id, bool query_id)
server_threads.iterate(find_thread_with_thd_data_lock_callback, &arg);
return arg.thd;
}
#endif
/**
kill one thread.
@ -9134,11 +9132,7 @@ 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
tmp= find_thread_by_id_with_thd_data_lock(id, type == KILL_TYPE_QUERY);
#else
tmp= find_thread_by_id(id, type == KILL_TYPE_QUERY);
#endif
if (!tmp)
DBUG_RETURN(error);
@ -9197,10 +9191,8 @@ kill_one_thread(THD *thd, longlong id, killed_state kill_signal, killed_type typ
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);
mysql_mutex_unlock(&tmp->LOCK_thd_data);
DBUG_PRINT("exit", ("%d", error));
DBUG_RETURN(error);
}
@ -9246,7 +9238,7 @@ static my_bool kill_threads_callback(THD *thd, kill_threads_callback_arg *arg)
return 1;
if (!arg->threads_to_kill.push_back(thd, arg->thd->mem_root))
{
if (WSREP(thd)) mysql_mutex_lock(&thd->LOCK_thd_data);
mysql_mutex_lock(&thd->LOCK_thd_data);
mysql_mutex_lock(&thd->LOCK_thd_kill); // Lock from delete
}
}
@ -9290,7 +9282,7 @@ static uint kill_threads_for_user(THD *thd, LEX_USER *user,
*/
next_ptr= it2++;
mysql_mutex_unlock(&ptr->LOCK_thd_kill);
if (WSREP(ptr)) mysql_mutex_unlock(&ptr->LOCK_thd_data);
mysql_mutex_unlock(&ptr->LOCK_thd_data);
(*rows)++;
} while ((ptr= next_ptr));
}

View File

@ -3474,7 +3474,7 @@ static my_bool kill_callback(THD *thd, kill_callback_arg *arg)
thd->variables.server_id == arg->slave_server_id)
{
arg->thd= thd;
if (WSREP(thd)) mysql_mutex_lock(&thd->LOCK_thd_data);
mysql_mutex_lock(&thd->LOCK_thd_data);
mysql_mutex_lock(&thd->LOCK_thd_kill); // Lock from delete
return 1;
}
@ -3496,7 +3496,7 @@ void kill_zombie_dump_threads(uint32 slave_server_id)
*/
arg.thd->awake_no_mutex(KILL_SLAVE_SAME_ID);
mysql_mutex_unlock(&arg.thd->LOCK_thd_kill);
if (WSREP(arg.thd)) mysql_mutex_unlock(&arg.thd->LOCK_thd_data);
mysql_mutex_unlock(&arg.thd->LOCK_thd_data);
}
}

View File

@ -144,6 +144,7 @@ const char* get_one_variable(THD *thd, const SHOW_VAR *variable,
/* These functions were under INNODB_COMPATIBILITY_HOOKS */
int get_quote_char_for_identifier(THD *thd, const char *name, size_t length);
THD *find_thread_by_id(longlong id, bool query_id= false);
THD *find_thread_by_id_with_thd_data_lock(longlong id, bool query_id= false);
class select_result_explain_buffer;
/*