Commit 2f5ae0da authored by mkaruza's avatar mkaruza Committed by Jan Lindström

MDEV-25883 Galera Cluster hangs while "DELETE FROM mysql.wsrep_cluster"

Using `innodb_thread_concurrency` will call `wsrep_thd_is_aborting` to
check WSREP thread state. This call should be protected by taking
`LOCK_thd_data` before entering function.
Applier and TOI threads should no be affected with usage of
`innodb_thread_concurrency` variable so returning before any checks.
Reviewed-by: default avatarJan Lindström <jan.lindstrom@mariadb.com>
parent 57fdd016
......@@ -269,12 +269,11 @@ extern "C" my_bool wsrep_thd_order_before(const THD *left, const THD *right)
extern "C" my_bool wsrep_thd_is_aborting(const MYSQL_THD thd)
{
mysql_mutex_assert_owner(&thd->LOCK_thd_data);
if (thd != 0)
const wsrep::client_state& cs(thd->wsrep_cs());
const enum wsrep::transaction::state tx_state(cs.transaction().state());
switch (tx_state)
{
const wsrep::client_state& cs(thd->wsrep_cs());
const enum wsrep::transaction::state tx_state(cs.transaction().state());
switch (tx_state)
{
case wsrep::transaction::s_must_abort:
return (cs.state() == wsrep::client_state::s_exec ||
cs.state() == wsrep::client_state::s_result);
......@@ -283,8 +282,8 @@ extern "C" my_bool wsrep_thd_is_aborting(const MYSQL_THD thd)
return true;
default:
return false;
}
}
return false;
}
......
......@@ -1689,7 +1689,11 @@ static inline void innobase_srv_conc_enter_innodb(row_prebuilt_t *prebuilt)
trx_t* trx = prebuilt->trx;
#ifdef WITH_WSREP
if (trx->is_wsrep() && wsrep_thd_is_BF(trx->mysql_thd, FALSE)) return;
if (global_system_variables.wsrep_on &&
(wsrep_thd_is_applying(trx->mysql_thd)
|| wsrep_thd_is_toi(trx->mysql_thd))) {
return;
}
#endif /* WITH_WSREP */
if (srv_thread_concurrency) {
......@@ -1725,7 +1729,11 @@ static inline void innobase_srv_conc_exit_innodb(row_prebuilt_t *prebuilt)
trx_t* trx = prebuilt->trx;
#ifdef WITH_WSREP
if (trx->is_wsrep() && wsrep_thd_is_BF(trx->mysql_thd, FALSE)) return;
if (global_system_variables.wsrep_on &&
(wsrep_thd_is_applying(trx->mysql_thd)
|| wsrep_thd_is_toi(trx->mysql_thd))) {
return;
}
#endif /* WITH_WSREP */
/* This is to avoid making an unnecessary function call. */
......
......@@ -118,7 +118,12 @@ srv_conc_enter_innodb_with_atomics(
for (;;) {
ulint sleep_in_us;
#ifdef WITH_WSREP
/* We need to take `thd->LOCK_thd_data` to check WSREP thread state */
if (trx->is_wsrep()) {
wsrep_thd_LOCK(trx->mysql_thd);
}
if (trx->is_wsrep() && wsrep_thd_is_aborting(trx->mysql_thd)) {
wsrep_thd_UNLOCK(trx->mysql_thd);
if (UNIV_UNLIKELY(wsrep_debug)) {
ib::info() <<
"srv_conc_enter due to MUST_ABORT";
......@@ -126,6 +131,9 @@ srv_conc_enter_innodb_with_atomics(
srv_conc_force_enter_innodb(trx);
return;
}
if (trx->is_wsrep()) {
wsrep_thd_UNLOCK(trx->mysql_thd);
}
#endif /* WITH_WSREP */
if (srv_thread_concurrency == 0) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment