summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
Diffstat (limited to 'sql')
-rw-r--r--sql/sql_parse.cc31
-rw-r--r--sql/wsrep_trans_observer.h10
2 files changed, 29 insertions, 12 deletions
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index e03b98177d0..209caa9460e 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -1164,6 +1164,14 @@ static bool wsrep_tables_accessible_when_detached(const TABLE_LIST *tables)
}
return true;
}
+
+static bool wsrep_command_no_result(char command)
+{
+ return (command == COM_STMT_PREPARE ||
+ command == COM_STMT_FETCH ||
+ command == COM_STMT_SEND_LONG_DATA ||
+ command == COM_STMT_CLOSE);
+}
#endif /* WITH_WSREP */
#ifndef EMBEDDED_LIBRARY
@@ -1287,12 +1295,20 @@ bool do_command(THD *thd)
#ifdef WITH_WSREP
DEBUG_SYNC(thd, "wsrep_before_before_command");
/*
- Aborted by background rollbacker thread.
- Handle error here and jump straight to out
+ If this command does not return a result, then we
+ instruct wsrep_before_command() to skip result handling.
+ This causes BF aborted transaction to roll back but keep
+ the error state until next command which is able to return
+ a result to the client.
*/
- if (wsrep_before_command(thd))
+ if (wsrep_before_command(thd, wsrep_command_no_result(command)))
{
- thd->store_globals();
+ /*
+ Aborted by background rollbacker thread.
+ Handle error here and jump straight to out.
+ Notice that thd->store_globals() is called
+ in wsrep_before_command().
+ */
WSREP_LOG_THD(thd, "enter found BF aborted");
DBUG_ASSERT(!thd->mdl_context.has_locks());
DBUG_ASSERT(!thd->get_stmt_da()->is_set());
@@ -2384,12 +2400,7 @@ dispatch_end:
WSREP_DEBUG("THD is killed at dispatch_end");
}
wsrep_after_command_before_result(thd);
- if (wsrep_current_error(thd) &&
- !(command == COM_STMT_PREPARE ||
- command == COM_STMT_FETCH ||
- command == COM_STMT_SEND_LONG_DATA ||
- command == COM_STMT_CLOSE
- ))
+ if (wsrep_current_error(thd) && !wsrep_command_no_result(command))
{
/* todo: Pass wsrep client state current error to override */
wsrep_override_error(thd, wsrep_current_error(thd),
diff --git a/sql/wsrep_trans_observer.h b/sql/wsrep_trans_observer.h
index 05970e8b12f..dbe710a0256 100644
--- a/sql/wsrep_trans_observer.h
+++ b/sql/wsrep_trans_observer.h
@@ -442,11 +442,17 @@ wsrep_wait_rollback_complete_and_acquire_ownership(THD *thd)
DBUG_VOID_RETURN;
}
-static inline int wsrep_before_command(THD* thd)
+static inline int wsrep_before_command(THD* thd, bool keep_command_error)
{
return (thd->wsrep_cs().state() != wsrep::client_state::s_none ?
- thd->wsrep_cs().before_command() : 0);
+ thd->wsrep_cs().before_command(keep_command_error) : 0);
+}
+
+static inline int wsrep_before_command(THD* thd)
+{
+ return wsrep_before_command(thd, false);
}
+
/*
Called after each command.