summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Lindström <jan.lindstrom@mariadb.com>2023-01-26 10:27:31 +0200
committerJan Lindström <jan.lindstrom@mariadb.com>2023-01-27 08:38:27 +0200
commit015fb54d45a27dc33191f513f896ab1ead5d2377 (patch)
treeb1e413832ae5ddfc3d5147f753c1c72f16cc962a
parent75bbf645a66db797be2abd3a348dce32eb753acc (diff)
downloadmariadb-git-015fb54d45a27dc33191f513f896ab1ead5d2377.tar.gz
MDEV-25037 : SIGSEGV in MDL_lock::hog_lock_types_bitmap
We should not call mdl_context.release_explicit_locks() in Wsrep_client_service::bf_rollback() if client is quiting because it will be done again in THD::cleanup(). Note that problem with GET_LOCK() / RELEASE_LOCK() will be fixed on MDEV-30473.
-rw-r--r--mysql-test/suite/galera/r/galera_backup_start.result6
-rw-r--r--mysql-test/suite/galera/t/galera_backup_start.test6
-rw-r--r--sql/wsrep_client_service.cc40
-rw-r--r--sql/wsrep_high_priority_service.cc10
4 files changed, 49 insertions, 13 deletions
diff --git a/mysql-test/suite/galera/r/galera_backup_start.result b/mysql-test/suite/galera/r/galera_backup_start.result
new file mode 100644
index 00000000000..253a0ce7416
--- /dev/null
+++ b/mysql-test/suite/galera/r/galera_backup_start.result
@@ -0,0 +1,6 @@
+connection node_2;
+connection node_1;
+BACKUP STAGE START;
+START TRANSACTION;
+COMMIT;
+BACKUP STAGE END;
diff --git a/mysql-test/suite/galera/t/galera_backup_start.test b/mysql-test/suite/galera/t/galera_backup_start.test
new file mode 100644
index 00000000000..4489e9ff582
--- /dev/null
+++ b/mysql-test/suite/galera/t/galera_backup_start.test
@@ -0,0 +1,6 @@
+--source include/galera_cluster.inc
+
+BACKUP STAGE START;
+START TRANSACTION;
+COMMIT;
+BACKUP STAGE END;
diff --git a/sql/wsrep_client_service.cc b/sql/wsrep_client_service.cc
index 5162f13458b..e77f307f028 100644
--- a/sql/wsrep_client_service.cc
+++ b/sql/wsrep_client_service.cc
@@ -1,4 +1,4 @@
-/* Copyright 2018-2022 Codership Oy <info@codership.com>
+/* Copyright 2018-2023 Codership Oy <info@codership.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -349,22 +349,36 @@ void Wsrep_client_service::debug_crash(const char* crash_point)
int Wsrep_client_service::bf_rollback()
{
DBUG_ASSERT(m_thd == current_thd);
- DBUG_ENTER("Wsrep_client_service::rollback");
+ DBUG_ENTER("Wsrep_client_service::bf_rollback");
int ret= (trans_rollback_stmt(m_thd) || trans_rollback(m_thd));
- if (m_thd->locked_tables_mode && m_thd->lock)
- {
- if (m_thd->locked_tables_list.unlock_locked_tables(m_thd))
- ret= 1;
- m_thd->variables.option_bits&= ~OPTION_TABLE_LOCK;
- }
- if (m_thd->global_read_lock.is_acquired())
+
+ WSREP_DEBUG("::bf_rollback() thread: %lu, client_state %s "
+ "client_mode %s trans_state %s killed %d",
+ thd_get_thread_id(m_thd),
+ wsrep_thd_client_state_str(m_thd),
+ wsrep_thd_client_mode_str(m_thd),
+ wsrep_thd_transaction_state_str(m_thd),
+ m_thd->killed);
+
+ /* If client is quiting all below will be done in THD::cleanup()
+ TODO: why we need this any other case? */
+ if (m_thd->wsrep_cs().state() != wsrep::client_state::s_quitting)
{
- m_thd->global_read_lock.unlock_global_read_lock(m_thd);
+ if (m_thd->locked_tables_mode && m_thd->lock)
+ {
+ if (m_thd->locked_tables_list.unlock_locked_tables(m_thd))
+ ret= 1;
+ m_thd->variables.option_bits&= ~OPTION_TABLE_LOCK;
+ }
+ if (m_thd->global_read_lock.is_acquired())
+ {
+ m_thd->global_read_lock.unlock_global_read_lock(m_thd);
+ }
+ m_thd->release_transactional_locks();
+ mysql_ull_cleanup(m_thd);
+ m_thd->mdl_context.release_explicit_locks();
}
- m_thd->release_transactional_locks();
- mysql_ull_cleanup(m_thd);
- m_thd->mdl_context.release_explicit_locks();
DBUG_RETURN(ret);
}
diff --git a/sql/wsrep_high_priority_service.cc b/sql/wsrep_high_priority_service.cc
index 93d4738212d..7d8296a75a1 100644
--- a/sql/wsrep_high_priority_service.cc
+++ b/sql/wsrep_high_priority_service.cc
@@ -292,6 +292,7 @@ int Wsrep_high_priority_service::append_fragment_and_commit(
ret= ret || trans_commit(m_thd);
ret= ret || (m_thd->wsrep_cs().after_applying(), 0);
+
m_thd->release_transactional_locks();
free_root(m_thd->mem_root, MYF(MY_KEEP_PREALLOC));
@@ -380,6 +381,15 @@ int Wsrep_high_priority_service::rollback(const wsrep::ws_handle& ws_handle,
assert(ws_handle == wsrep::ws_handle());
}
int ret= (trans_rollback_stmt(m_thd) || trans_rollback(m_thd));
+
+ WSREP_DEBUG("::rollback() thread: %lu, client_state %s "
+ "client_mode %s trans_state %s killed %d",
+ thd_get_thread_id(m_thd),
+ wsrep_thd_client_state_str(m_thd),
+ wsrep_thd_client_mode_str(m_thd),
+ wsrep_thd_transaction_state_str(m_thd),
+ m_thd->killed);
+
m_thd->release_transactional_locks();
mysql_ull_cleanup(m_thd);
m_thd->mdl_context.release_explicit_locks();