summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sql/sql_class.cc1
-rw-r--r--sql/sql_class.h4
-rw-r--r--sql/sql_parse.cc19
-rw-r--r--sql/sql_prepare.cc8
4 files changed, 30 insertions, 2 deletions
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index f3353135ac8..c9e55fd413e 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -666,6 +666,7 @@ THD::THD(my_thread_id id, bool is_wsrep_applier)
wsrep_replicate_GTID(false),
wsrep_ignore_table(false),
wsrep_aborter(0),
+ wsrep_delayed_BF_abort(false),
/* wsrep-lib */
m_wsrep_next_trx_id(WSREP_UNDEFINED_TRX_ID),
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 2afda6e63b7..76deee68a71 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -4897,6 +4897,10 @@ public:
/* thread who has started kill for this THD protected by LOCK_thd_data*/
my_thread_id wsrep_aborter;
+ /* true if BF abort is observed in do_command() right after reading
+ client's packet, and if the client has sent PS execute command. */
+ bool wsrep_delayed_BF_abort;
+
/*
Transaction id:
* m_wsrep_next_trx_id is assigned on the first query after
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index a3d44423a69..bd685add60e 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -1313,7 +1313,13 @@ bool do_command(THD *thd)
DBUG_ASSERT(!thd->mdl_context.has_locks());
DBUG_ASSERT(!thd->get_stmt_da()->is_set());
/* We let COM_QUIT and COM_STMT_CLOSE to execute even if wsrep aborted. */
- if (command != COM_STMT_CLOSE &&
+ if (command == COM_STMT_EXECUTE)
+ {
+ WSREP_DEBUG("PS BF aborted at do_command");
+ thd->wsrep_delayed_BF_abort= true;
+ }
+ if (command != COM_STMT_CLOSE &&
+ command != COM_STMT_EXECUTE &&
command != COM_QUIT)
{
my_error(ER_LOCK_DEADLOCK, MYF(0));
@@ -1385,6 +1391,17 @@ out:
/* there was a command to process, and before_command() has been called */
wsrep_after_command_after_result(thd);
}
+
+ if (thd->wsrep_delayed_BF_abort)
+ {
+ my_error(ER_LOCK_DEADLOCK, MYF(0));
+ WSREP_DEBUG("Deadlock error for PS query: %s", thd->query());
+ thd->reset_killed();
+ thd->mysys_var->abort = 0;
+ thd->wsrep_retry_counter = 0;
+
+ thd->wsrep_delayed_BF_abort= false;
+ }
#endif /* WITH_WSREP */
DBUG_RETURN(return_value);
}
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index 49b342d660d..c674cc78719 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -4461,7 +4461,13 @@ Prepared_statement::execute_loop(String *expanded_query,
if (set_parameters(expanded_query, packet, packet_end))
return TRUE;
-
+#ifdef WITH_WSREP
+ if (thd->wsrep_delayed_BF_abort)
+ {
+ WSREP_DEBUG("delayed BF abort, quitting execute_loop, stmt: %d", id);
+ return TRUE;
+ }
+#endif /* WITH_WSREP */
reexecute:
// Make sure that reprepare() did not create any new Items.
DBUG_ASSERT(thd->free_list == NULL);