diff options
-rw-r--r-- | sql/sql_class.cc | 1 | ||||
-rw-r--r-- | sql/sql_class.h | 4 | ||||
-rw-r--r-- | sql/sql_parse.cc | 19 | ||||
-rw-r--r-- | sql/sql_prepare.cc | 8 |
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); |