summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2021-11-09 07:59:36 +0200
committerMarko Mäkelä <marko.makela@mariadb.com>2021-11-09 07:59:36 +0200
commitf7054ff5dfea7b84afdde11c14898cff7154521e (patch)
tree97d33d01294e148cf245d16bdab42f7d3cd2a4c6 /sql
parente026eddc7dc3b17e7120adfded1d53da0e7ec9f0 (diff)
parenta2f147af35480e27bd599462db59b9b95f71acd9 (diff)
downloadmariadb-git-f7054ff5dfea7b84afdde11c14898cff7154521e.tar.gz
Merge mariadb-10.3.32 into 10.3
Diffstat (limited to 'sql')
-rw-r--r--sql/handler.cc2
-rw-r--r--sql/handler.h12
-rw-r--r--sql/log.cc37
-rw-r--r--sql/sp_head.cc8
-rw-r--r--sql/sql_class.cc27
-rw-r--r--sql/sql_class.h3
-rw-r--r--sql/sql_parse.cc36
-rw-r--r--sql/threadpool_generic.cc4
-rw-r--r--sql/wsrep_mysqld.cc61
-rw-r--r--sql/wsrep_thd.cc11
10 files changed, 143 insertions, 58 deletions
diff --git a/sql/handler.cc b/sql/handler.cc
index 47f78283897..11a387fb4e3 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -835,11 +835,9 @@ static my_bool kill_handlerton(THD *thd, plugin_ref plugin,
{
handlerton *hton= plugin_hton(plugin);
- mysql_mutex_lock(&thd->LOCK_thd_data);
if (hton->state == SHOW_OPTION_YES && hton->kill_query &&
thd_get_ha_data(thd, hton))
hton->kill_query(hton, thd, *(enum thd_kill_levels *) level);
- mysql_mutex_unlock(&thd->LOCK_thd_data);
return FALSE;
}
diff --git a/sql/handler.h b/sql/handler.h
index e56ac9fab6e..91225982e9e 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -1730,9 +1730,13 @@ struct THD_TRANS
/*
Define the type of statements which cannot be rolled back safely.
Each type occupies one bit in m_unsafe_rollback_flags.
+ MODIFIED_NON_TRANS_TABLE is limited to mark only the temporary
+ non-transactional table *when* it's cached along with the transactional
+ events; the regular table is covered by the "namesake" bool var.
*/
enum unsafe_statement_types
{
+ MODIFIED_NON_TRANS_TABLE= 1,
CREATED_TEMP_TABLE= 2,
DROPPED_TEMP_TABLE= 4,
DID_WAIT= 8,
@@ -1740,6 +1744,14 @@ struct THD_TRANS
EXECUTED_TABLE_ADMIN_CMD= 0x20
};
+ void mark_modified_non_trans_temp_table()
+ {
+ m_unsafe_rollback_flags|= MODIFIED_NON_TRANS_TABLE;
+ }
+ bool has_modified_non_trans_temp_table() const
+ {
+ return (m_unsafe_rollback_flags & MODIFIED_NON_TRANS_TABLE) != 0;
+ }
void mark_executed_table_admin_cmd()
{
DBUG_PRINT("debug", ("mark_executed_table_admin_cmd"));
diff --git a/sql/log.cc b/sql/log.cc
index 95cb60ea829..1e4b9d9f1f4 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -263,7 +263,7 @@ class binlog_cache_data
public:
binlog_cache_data(): m_pending(0), status(0),
before_stmt_pos(MY_OFF_T_UNDEF),
- incident(FALSE), changes_to_non_trans_temp_table_flag(FALSE),
+ incident(FALSE),
saved_max_binlog_cache_size(0), ptr_binlog_cache_use(0),
ptr_binlog_cache_disk_use(0)
{ }
@@ -312,16 +312,6 @@ public:
return(incident);
}
- void set_changes_to_non_trans_temp_table()
- {
- changes_to_non_trans_temp_table_flag= TRUE;
- }
-
- bool changes_to_non_trans_temp_table()
- {
- return (changes_to_non_trans_temp_table_flag);
- }
-
void reset()
{
bool cache_was_empty= empty();
@@ -333,7 +323,6 @@ public:
if (truncate_file)
my_chsize(cache_log.file, 0, 0, MYF(MY_WME));
- changes_to_non_trans_temp_table_flag= FALSE;
status= 0;
incident= FALSE;
before_stmt_pos= MY_OFF_T_UNDEF;
@@ -432,12 +421,6 @@ private:
*/
bool incident;
- /*
- This flag indicates if the cache has changes to temporary tables.
- @TODO This a temporary fix and should be removed after BUG#54562.
- */
- bool changes_to_non_trans_temp_table_flag;
-
/**
This function computes binlog cache and disk usage.
*/
@@ -1977,13 +1960,12 @@ static int binlog_prepare(handlerton *hton, THD *thd, bool all)
*/
static bool trans_cannot_safely_rollback(THD *thd, bool all)
{
- binlog_cache_mngr *const cache_mngr=
- (binlog_cache_mngr*) thd_get_ha_data(thd, binlog_hton);
+ DBUG_ASSERT(ending_trans(thd, all));
return ((thd->variables.option_bits & OPTION_KEEP_LOG) ||
(trans_has_updated_non_trans_table(thd) &&
thd->wsrep_binlog_format() == BINLOG_FORMAT_STMT) ||
- (cache_mngr->trx_cache.changes_to_non_trans_temp_table() &&
+ (thd->transaction.all.has_modified_non_trans_temp_table() &&
thd->wsrep_binlog_format() == BINLOG_FORMAT_MIXED) ||
(trans_has_updated_non_trans_table(thd) &&
ending_single_stmt_trans(thd,all) &&
@@ -2134,17 +2116,19 @@ static int binlog_rollback(handlerton *hton, THD *thd, bool all)
/*
Truncate the cache if:
. aborting a single or multi-statement transaction or;
- . the OPTION_KEEP_LOG is not active and;
+ . the current statement created or dropped a temporary table
+ while having actual STATEMENT format;
. the format is not STMT or no non-trans table was
updated and;
. the format is not MIXED or no temporary non-trans table
was updated.
*/
else if (ending_trans(thd, all) ||
- (!(thd->variables.option_bits & OPTION_KEEP_LOG) &&
+ (!(thd->transaction.stmt.has_created_dropped_temp_table() &&
+ !thd->is_current_stmt_binlog_format_row()) &&
(!stmt_has_updated_non_trans_table(thd) ||
thd->wsrep_binlog_format() != BINLOG_FORMAT_STMT) &&
- (!cache_mngr->trx_cache.changes_to_non_trans_temp_table() ||
+ (!thd->transaction.stmt.has_modified_non_trans_temp_table() ||
thd->wsrep_binlog_format() != BINLOG_FORMAT_MIXED)))
error= binlog_truncate_trx_cache(thd, cache_mngr, all);
}
@@ -6340,9 +6324,8 @@ bool MYSQL_BIN_LOG::write(Log_event *event_info, my_bool *with_annotate)
cache_data= cache_mngr->get_binlog_cache_data(is_trans_cache);
file= &cache_data->cache_log;
- if (thd->lex->stmt_accessed_non_trans_temp_table())
- cache_data->set_changes_to_non_trans_temp_table();
-
+ if (thd->lex->stmt_accessed_non_trans_temp_table() && is_trans_cache)
+ thd->transaction.stmt.mark_modified_non_trans_temp_table();
thd->binlog_start_trans_and_stmt();
}
DBUG_PRINT("info",("event type: %d",event_info->get_type_code()));
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index 525d836b8c3..57ab31d9edf 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -3379,8 +3379,13 @@ sp_lex_keeper::reset_lex_and_exec_core(THD *thd, uint *nextp,
It's reset further in the common code part.
It's merged with the saved parent's value at the exit of this func.
*/
- bool parent_modified_non_trans_table= thd->transaction.stmt.modified_non_trans_table;
+ bool parent_modified_non_trans_table=
+ thd->transaction.stmt.modified_non_trans_table;
+ unsigned int parent_unsafe_rollback_flags=
+ thd->transaction.stmt.m_unsafe_rollback_flags;
thd->transaction.stmt.modified_non_trans_table= FALSE;
+ thd->transaction.stmt.m_unsafe_rollback_flags= 0;
+
DBUG_ASSERT(!thd->derived_tables);
DBUG_ASSERT(thd->Item_change_list::is_empty());
/*
@@ -3496,6 +3501,7 @@ sp_lex_keeper::reset_lex_and_exec_core(THD *thd, uint *nextp,
what is needed from the substatement gained
*/
thd->transaction.stmt.modified_non_trans_table |= parent_modified_non_trans_table;
+ thd->transaction.stmt.m_unsafe_rollback_flags |= parent_unsafe_rollback_flags;
TRANSACT_TRACKER(add_trx_state_from_thd(thd));
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index d3c090c3308..fbfb742d9ee 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -1977,7 +1977,9 @@ bool THD::notify_shared_lock(MDL_context_owner *ctx_in_use,
if (needs_thr_lock_abort)
{
+ bool mutex_released= false;
mysql_mutex_lock(&in_use->LOCK_thd_data);
+ mysql_mutex_lock(&in_use->LOCK_thd_kill);
/* If not already dying */
if (in_use->killed != KILL_CONNECTION_HARD)
{
@@ -1993,18 +1995,25 @@ bool THD::notify_shared_lock(MDL_context_owner *ctx_in_use,
thread can see those instances (e.g. see partitioning code).
*/
if (!thd_table->needs_reopen())
- {
signalled|= mysql_lock_abort_for_thread(this, thd_table);
- if (WSREP(this) && wsrep_thd_is_BF(this, FALSE))
- {
- WSREP_DEBUG("remove_table_from_cache: %llu",
- (unsigned long long) this->real_id);
- wsrep_abort_thd((void *)this, (void *)in_use, FALSE);
- }
- }
}
+#ifdef WITH_WSREP
+ if (WSREP(this) && wsrep_thd_is_BF(this, false))
+ {
+ WSREP_DEBUG("notify_shared_lock: BF thread %llu query %s"
+ " victim %llu query %s",
+ this->real_id, wsrep_thd_query(this),
+ in_use->real_id, wsrep_thd_query(in_use));
+ wsrep_abort_thd((void *)this, (void *)in_use, false);
+ mutex_released= true;
+ }
+#endif /* WITH_WSREP */
+ }
+ if (!mutex_released)
+ {
+ mysql_mutex_unlock(&in_use->LOCK_thd_kill);
+ mysql_mutex_unlock(&in_use->LOCK_thd_data);
}
- mysql_mutex_unlock(&in_use->LOCK_thd_data);
}
DBUG_RETURN(signalled);
}
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 1df9a9dc718..4dcb0a0d5a5 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -4816,7 +4816,8 @@ public:
transaction.all.modified_non_trans_table= TRUE;
transaction.all.m_unsafe_rollback_flags|=
(transaction.stmt.m_unsafe_rollback_flags &
- (THD_TRANS::DID_WAIT | THD_TRANS::CREATED_TEMP_TABLE |
+ (THD_TRANS::MODIFIED_NON_TRANS_TABLE |
+ THD_TRANS::DID_WAIT | THD_TRANS::CREATED_TEMP_TABLE |
THD_TRANS::DROPPED_TEMP_TABLE | THD_TRANS::DID_DDL |
THD_TRANS::EXECUTED_TABLE_ADMIN_CMD));
}
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 95c04321b4d..4ff1776e244 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -9157,6 +9157,18 @@ static
void sql_kill(THD *thd, longlong id, killed_state state, killed_type type)
{
uint error;
+#ifdef WITH_WSREP
+ if (WSREP(thd))
+ {
+ WSREP_DEBUG("sql_kill called");
+ if (thd->wsrep_applier)
+ {
+ WSREP_DEBUG("KILL in applying, bailing out here");
+ return;
+ }
+ WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL)
+ }
+#endif /* WITH_WSREP */
if (likely(!(error= kill_one_thread(thd, id, state, type))))
{
if (!thd->killed)
@@ -9166,6 +9178,13 @@ void sql_kill(THD *thd, longlong id, killed_state state, killed_type type)
}
else
my_error(error, MYF(0), id);
+#ifdef WITH_WSREP
+ return;
+ wsrep_error_label:
+ error= (type == KILL_TYPE_QUERY ? ER_KILL_QUERY_DENIED_ERROR :
+ ER_KILL_DENIED_ERROR);
+ my_error(error, MYF(0), id);
+#endif /* WITH_WSREP */
}
@@ -9174,6 +9193,18 @@ void sql_kill_user(THD *thd, LEX_USER *user, killed_state state)
{
uint error;
ha_rows rows;
+#ifdef WITH_WSREP
+ if (WSREP(thd))
+ {
+ WSREP_DEBUG("sql_kill_user called");
+ if (thd->wsrep_applier)
+ {
+ WSREP_DEBUG("KILL in applying, bailing out here");
+ return;
+ }
+ WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL)
+ }
+#endif /* WITH_WSREP */
if (likely(!(error= kill_threads_for_user(thd, user, state, &rows))))
my_ok(thd, rows);
else
@@ -9184,6 +9215,11 @@ void sql_kill_user(THD *thd, LEX_USER *user, killed_state state)
*/
my_error(error, MYF(0), user->host.str, user->user.str);
}
+#ifdef WITH_WSREP
+ return;
+ wsrep_error_label:
+ my_error(ER_CANNOT_USER, MYF(0), user ? user->user.str : "NULL");
+#endif /* WITH_WSREP */
}
diff --git a/sql/threadpool_generic.cc b/sql/threadpool_generic.cc
index 8b424591ba6..74b1a778647 100644
--- a/sql/threadpool_generic.cc
+++ b/sql/threadpool_generic.cc
@@ -1787,9 +1787,9 @@ static void print_pool_blocked_message(bool max_threads_reached)
if (now > pool_block_start + BLOCK_MSG_DELAY && !msg_written)
{
if (max_threads_reached)
- sql_print_error(MAX_THREADS_REACHED_MSG);
+ sql_print_warning(MAX_THREADS_REACHED_MSG);
else
- sql_print_error(CREATE_THREAD_ERROR_MSG, my_errno);
+ sql_print_warning(CREATE_THREAD_ERROR_MSG, my_errno);
sql_print_information("Threadpool has been blocked for %u seconds\n",
(uint)((now- pool_block_start)/1000000));
diff --git a/sql/wsrep_mysqld.cc b/sql/wsrep_mysqld.cc
index ce798a918e3..fcb7de9ca58 100644
--- a/sql/wsrep_mysqld.cc
+++ b/sql/wsrep_mysqld.cc
@@ -1,4 +1,4 @@
-/* Copyright 2008-2015 Codership Oy <http://www.codership.com>
+/* Copyright 2008-2021 Codership Oy <http://www.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
@@ -833,13 +833,25 @@ void wsrep_thr_init()
DBUG_VOID_RETURN;
}
+/* This is wrapper for wsrep_break_lock in thr_lock.c */
+static int wsrep_thr_abort_thd(void *bf_thd_ptr, void *victim_thd_ptr, my_bool signal)
+{
+ THD* victim_thd= (THD *) victim_thd_ptr;
+ /* We need to lock THD::LOCK_thd_data to protect victim
+ from concurrent usage or disconnect or delete. */
+ wsrep_thd_LOCK(victim_thd);
+ int res= wsrep_abort_thd(bf_thd_ptr, victim_thd_ptr, signal);
+ return res;
+}
+
+
void wsrep_init_startup (bool first)
{
if (wsrep_init()) unireg_abort(1);
wsrep_thr_lock_init(
(wsrep_thd_is_brute_force_fun)wsrep_thd_is_BF,
- (wsrep_abort_thd_fun)wsrep_abort_thd,
+ (wsrep_abort_thd_fun)wsrep_thr_abort_thd,
wsrep_debug, wsrep_convert_LOCK_to_trx,
(wsrep_on_fun)wsrep_on);
@@ -1685,6 +1697,11 @@ static int wsrep_TOI_begin(THD *thd, const char *db_, const char *table_,
case SQLCOM_DROP_TABLE:
buf_err= wsrep_drop_table_query(thd, &buf, &buf_len);
break;
+ case SQLCOM_KILL:
+ WSREP_DEBUG("KILL as TOI: %s", thd->query());
+ buf_err= wsrep_to_buf_helper(thd, thd->query(), thd->query_length(),
+ &buf, &buf_len);
+ break;
case SQLCOM_CREATE_ROLE:
if (sp_process_definer(thd))
{
@@ -2005,14 +2022,14 @@ bool wsrep_grant_mdl_exception(MDL_context *requestor_ctx,
request_thd, granted_thd);
ticket->wsrep_report(wsrep_debug);
- mysql_mutex_lock(&granted_thd->LOCK_thd_data);
+ wsrep_thd_LOCK(granted_thd);
if (granted_thd->wsrep_exec_mode == TOTAL_ORDER ||
granted_thd->wsrep_exec_mode == REPL_RECV)
{
WSREP_MDL_LOG(INFO, "MDL BF-BF conflict", schema, schema_len,
request_thd, granted_thd);
ticket->wsrep_report(true);
- mysql_mutex_unlock(&granted_thd->LOCK_thd_data);
+ wsrep_thd_UNLOCK(granted_thd);
ret= true;
}
else if (granted_thd->lex->sql_command == SQLCOM_FLUSH ||
@@ -2020,7 +2037,7 @@ bool wsrep_grant_mdl_exception(MDL_context *requestor_ctx,
{
WSREP_DEBUG("BF thread waiting for FLUSH");
ticket->wsrep_report(wsrep_debug);
- mysql_mutex_unlock(&granted_thd->LOCK_thd_data);
+ wsrep_thd_UNLOCK(granted_thd);
ret= false;
}
else
@@ -2045,8 +2062,10 @@ bool wsrep_grant_mdl_exception(MDL_context *requestor_ctx,
ticket->wsrep_report(true);
}
- mysql_mutex_unlock(&granted_thd->LOCK_thd_data);
- wsrep_abort_thd((void *) request_thd, (void *) granted_thd, 1);
+ /* This will call wsrep_abort_transaction so we should hold
+ THD::LOCK_thd_data to protect victim from concurrent usage
+ or disconnect or delete. */
+ wsrep_abort_thd((void *) request_thd, (void *) granted_thd, true);
ret= false;
}
}
@@ -2221,6 +2240,7 @@ error:
static bool abort_replicated(THD *thd)
{
bool ret_code= false;
+ wsrep_thd_LOCK(thd);
if (thd->wsrep_query_state== QUERY_COMMITTING)
{
WSREP_DEBUG("aborting replicated trx: %llu", (ulonglong)(thd->real_id));
@@ -2228,6 +2248,8 @@ static bool abort_replicated(THD *thd)
(void)wsrep_abort_thd(thd, thd, TRUE);
ret_code= true;
}
+ else
+ wsrep_thd_UNLOCK(thd);
return ret_code;
}
@@ -2274,6 +2296,8 @@ static bool have_client_connections()
(longlong) tmp->thread_id));
if (is_client_connection(tmp) && tmp->killed == KILL_CONNECTION)
{
+ WSREP_DEBUG("Informing thread %lld that it's time to die",
+ (longlong)tmp->thread_id);
(void)abort_replicated(tmp);
return true;
}
@@ -2358,6 +2382,8 @@ void wsrep_close_client_connections(my_bool wait_to_end, THD *except_caller_thd)
{
DBUG_PRINT("quit",("Informing thread %lld that it's time to die",
(longlong) tmp->thread_id));
+ WSREP_DEBUG("Informing thread %lld that it's time to die",
+ (longlong)tmp->thread_id);
/* We skip slave threads & scheduler on this first loop through. */
if (!is_client_connection(tmp))
continue;
@@ -2374,15 +2400,18 @@ void wsrep_close_client_connections(my_bool wait_to_end, THD *except_caller_thd)
continue;
}
- /* replicated transactions must be skipped */
+ /* replicated transactions must be skipped and aborted
+ with wsrep_abort_thd. */
if (abort_replicated(tmp))
continue;
WSREP_DEBUG("closing connection %lld", (longlong) tmp->thread_id);
/*
- instead of wsrep_close_thread() we do now soft kill by THD::awake
- */
+ instead of wsrep_close_thread() we do now soft kill by
+ THD::awake(). Here also victim needs to be protected from
+ concurrent usage or disconnect or delete.
+ */
tmp->awake(KILL_CONNECTION);
}
mysql_mutex_unlock(&LOCK_thread_count);
@@ -2398,7 +2427,6 @@ void wsrep_close_client_connections(my_bool wait_to_end, THD *except_caller_thd)
I_List_iterator<THD> it2(threads);
while ((tmp=it2++))
{
-#ifndef __bsdi__ // Bug in BSDI kernel
if (is_client_connection(tmp) &&
!abort_replicated(tmp) &&
!is_replaying_connection(tmp) &&
@@ -2407,7 +2435,6 @@ void wsrep_close_client_connections(my_bool wait_to_end, THD *except_caller_thd)
WSREP_INFO("killing local connection: %lld", (longlong) tmp->thread_id);
close_connection(tmp,0);
}
-#endif
}
DBUG_PRINT("quit",("Waiting for threads to die (count=%u)",thread_count));
@@ -2594,7 +2621,8 @@ extern "C" void wsrep_thd_set_query_state(
void wsrep_thd_set_conflict_state(THD *thd, enum wsrep_conflict_state state)
{
- if (WSREP(thd)) thd->wsrep_conflict_state= state;
+ mysql_mutex_assert_owner(&thd->LOCK_thd_data);
+ thd->wsrep_conflict_state= state;
}
@@ -2662,11 +2690,13 @@ wsrep_ws_handle_t* wsrep_thd_ws_handle(THD *thd)
void wsrep_thd_LOCK(THD *thd)
{
mysql_mutex_lock(&thd->LOCK_thd_data);
+ mysql_mutex_lock(&thd->LOCK_thd_kill);
}
void wsrep_thd_UNLOCK(THD *thd)
{
+ mysql_mutex_unlock(&thd->LOCK_thd_kill);
mysql_mutex_unlock(&thd->LOCK_thd_data);
}
@@ -2747,6 +2777,11 @@ extern "C" void wsrep_thd_awake(THD *thd, my_bool signal)
{
if (signal)
{
+ /* Here we should hold THD::LOCK_thd_data to
+ protect from concurrent usage and
+ THD::LOCK_thd_kill from disconnect or delete */
+ mysql_mutex_assert_owner(&thd->LOCK_thd_data);
+ mysql_mutex_assert_owner(&thd->LOCK_thd_kill);
thd->awake_no_mutex(KILL_QUERY);
}
else
diff --git a/sql/wsrep_thd.cc b/sql/wsrep_thd.cc
index 6fd57edc692..f8eaa14d176 100644
--- a/sql/wsrep_thd.cc
+++ b/sql/wsrep_thd.cc
@@ -1,4 +1,4 @@
-/* Copyright (C) 2013 Codership Oy <info@codership.com>
+/* Copyright (C) 2013-2021 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
@@ -803,10 +803,13 @@ my_bool wsrep_thd_is_local(void *thd_ptr, my_bool sync)
int wsrep_abort_thd(void *bf_thd_ptr, void *victim_thd_ptr, my_bool signal)
{
- THD *victim_thd = (THD *) victim_thd_ptr;
- THD *bf_thd = (THD *) bf_thd_ptr;
+ THD *victim_thd= (THD *) victim_thd_ptr;
+ THD *bf_thd= (THD *) bf_thd_ptr;
DBUG_ENTER("wsrep_abort_thd");
+ mysql_mutex_assert_owner(&victim_thd->LOCK_thd_data);
+ mysql_mutex_assert_owner(&victim_thd->LOCK_thd_kill);
+
if ( (WSREP(bf_thd) ||
( (WSREP_ON || bf_thd->variables.wsrep_OSU_method == WSREP_OSU_RSU) &&
bf_thd->wsrep_exec_mode == TOTAL_ORDER) ) &&
@@ -820,6 +823,7 @@ int wsrep_abort_thd(void *bf_thd_ptr, void *victim_thd_ptr, my_bool signal)
"aborted. Ignoring.",
(bf_thd) ? (long long)bf_thd->real_id : 0,
(long long)victim_thd->real_id);
+ wsrep_thd_UNLOCK(victim_thd);
DBUG_RETURN(1);
}
@@ -830,6 +834,7 @@ int wsrep_abort_thd(void *bf_thd_ptr, void *victim_thd_ptr, my_bool signal)
else
{
WSREP_DEBUG("wsrep_abort_thd not effective: %p %p", bf_thd, victim_thd);
+ wsrep_thd_UNLOCK(victim_thd);
}
DBUG_RETURN(1);