summaryrefslogtreecommitdiff
path: root/sql/sp_head.cc
diff options
context:
space:
mode:
authorTeemu Ollakka <teemu.ollakka@galeracluster.com>2019-04-06 12:33:51 +0300
committerJan Lindström <jan.lindstrom@mariadb.com>2019-04-06 12:33:51 +0300
commiteb872ceb2710034eb507bfb7f5133022d814c59f (patch)
tree26af870c685195ed480498bebccf2603272c9fc0 /sql/sp_head.cc
parentfe62ff6e1c8d6931935a0f9a10613abf93e3668f (diff)
downloadmariadb-git-eb872ceb2710034eb507bfb7f5133022d814c59f.tar.gz
Fixed wsrep replaying for stored procedures (#1256)mariadb-10.4.4
- Changed replaying to always allocate a separate THD object for applying log events. This is to avoid tampering original THD state during replay process. - Return success from sp_instr_stmt::exec_core() if replaying succeeds. - Do not push warnings/errors into diagnostics area if the transaction must be replayed. This is to avoid reporting transient errors to the client. Added two tests galera_sp_bf_abort, galera_sp_insert_parallel. Wsrep-lib position updated.
Diffstat (limited to 'sql/sp_head.cc')
-rw-r--r--sql/sp_head.cc61
1 files changed, 37 insertions, 24 deletions
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index bd4d74c58a8..e98e5fbc27e 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -3605,32 +3605,45 @@ sp_instr_stmt::exec_core(THD *thd, uint *nextp)
3);
int res= mysql_execute_command(thd);
#ifdef WITH_WSREP
- if ((thd->is_fatal_error || thd->killed_errno()) &&
- (thd->wsrep_trx().state() == wsrep::transaction::s_executing))
+ if (WSREP(thd))
{
- /*
- SP was killed, and it is not due to a wsrep conflict.
- We skip after_statement hook at this point because
- otherwise it clears the error, and cleans up the
- whole transaction. For now we just return and finish
- our handling once we are back to mysql_parse.
- */
- WSREP_DEBUG("Skipping after_command hook for killed SP");
- }
- else
- {
- (void) wsrep_after_statement(thd);
- /*
- Final wsrep error status for statement is known only after
- wsrep_after_statement() call. If the error is set, override
- error in thd diagnostics area and reset wsrep client_state error
- so that the error does not get propagated via client-server protocol.
- */
- if (wsrep_current_error(thd))
+ if ((thd->is_fatal_error || thd->killed_errno()) &&
+ (thd->wsrep_trx().state() == wsrep::transaction::s_executing))
+ {
+ /*
+ SP was killed, and it is not due to a wsrep conflict.
+ We skip after_statement hook at this point because
+ otherwise it clears the error, and cleans up the
+ whole transaction. For now we just return and finish
+ our handling once we are back to mysql_parse.
+ */
+ WSREP_DEBUG("Skipping after_command hook for killed SP");
+ }
+ else
{
- wsrep_override_error(thd, wsrep_current_error(thd),
- wsrep_current_error_status(thd));
- thd->wsrep_cs().reset_error();
+ const bool must_replay= wsrep_must_replay(thd);
+ (void) wsrep_after_statement(thd);
+ /*
+ Reset the return code to zero if the transaction was
+ replayed succesfully.
+ */
+ if (res && must_replay && !wsrep_current_error(thd))
+ res= 0;
+ /*
+ Final wsrep error status for statement is known only after
+ wsrep_after_statement() call. If the error is set, override
+ error in thd diagnostics area and reset wsrep client_state error
+ so that the error does not get propagated via client-server protocol.
+ */
+ if (wsrep_current_error(thd))
+ {
+ wsrep_override_error(thd, wsrep_current_error(thd),
+ wsrep_current_error_status(thd));
+ thd->wsrep_cs().reset_error();
+ /* Reset also thd->killed if it has been set during BF abort. */
+ if (thd->killed == KILL_QUERY)
+ thd->reset_killed();
+ }
}
}
#endif /* WITH_WSREP */