diff options
author | mkaruza <mario.karuza@galeracluster.com> | 2021-09-17 14:20:02 +0200 |
---|---|---|
committer | Jan Lindström <jan.lindstrom@mariadb.com> | 2021-09-30 12:25:26 +0300 |
commit | 2f5ae0da71d097fa5619ece6aa5dac075282d519 (patch) | |
tree | cabd978613eda4ace29465beeaa481814ffdce7e | |
parent | 57fdd016ce6167c15ba9cd41048b8a42ba582447 (diff) | |
download | mariadb-git-bb-10.4-MDEV-25883-galera.tar.gz |
MDEV-25883 Galera Cluster hangs while "DELETE FROM mysql.wsrep_cluster"bb-10.4-MDEV-25883-galera
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>
-rw-r--r-- | sql/service_wsrep.cc | 11 | ||||
-rw-r--r-- | storage/innobase/handler/ha_innodb.cc | 12 | ||||
-rw-r--r-- | storage/innobase/srv/srv0conc.cc | 8 |
3 files changed, 23 insertions, 8 deletions
diff --git a/sql/service_wsrep.cc b/sql/service_wsrep.cc index 14f136ca480..4f8e3402610 100644 --- a/sql/service_wsrep.cc +++ b/sql/service_wsrep.cc @@ -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; } diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 2afe3af9eaf..81952f73058 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -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. */ diff --git a/storage/innobase/srv/srv0conc.cc b/storage/innobase/srv/srv0conc.cc index 6167c8daeba..ba264ba7d6b 100644 --- a/storage/innobase/srv/srv0conc.cc +++ b/storage/innobase/srv/srv0conc.cc @@ -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) { |