summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormkaruza <mario.karuza@galeracluster.com>2021-09-17 14:20:02 +0200
committerJan Lindström <jan.lindstrom@mariadb.com>2021-09-30 12:25:26 +0300
commit2f5ae0da71d097fa5619ece6aa5dac075282d519 (patch)
treecabd978613eda4ace29465beeaa481814ffdce7e
parent57fdd016ce6167c15ba9cd41048b8a42ba582447 (diff)
downloadmariadb-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.cc11
-rw-r--r--storage/innobase/handler/ha_innodb.cc12
-rw-r--r--storage/innobase/srv/srv0conc.cc8
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) {