mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 03:52:35 +01:00
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: Jan Lindström <jan.lindstrom@mariadb.com>
This commit is contained in:
parent
57fdd016ce
commit
2f5ae0da71
3 changed files with 23 additions and 8 deletions
|
@ -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) {
|
||||
|
|
Loading…
Reference in a new issue