diff options
author | Teemu Ollakka <teemu.ollakka@galeracluster.com> | 2019-04-06 12:33:51 +0300 |
---|---|---|
committer | Jan Lindström <jan.lindstrom@mariadb.com> | 2019-04-06 12:33:51 +0300 |
commit | eb872ceb2710034eb507bfb7f5133022d814c59f (patch) | |
tree | 26af870c685195ed480498bebccf2603272c9fc0 /sql/sp_head.cc | |
parent | fe62ff6e1c8d6931935a0f9a10613abf93e3668f (diff) | |
download | mariadb-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.cc | 61 |
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 */ |