diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2020-06-06 18:50:25 +0300 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2020-06-06 18:50:25 +0300 |
commit | b3e395a13ee7e9df323cb654d18dc81ff2f3fd1e (patch) | |
tree | 6078ccc55d5298796c3f626fb4886a131b833e37 /sql/sp_head.cc | |
parent | e14ffd85d09a62d098d3db9597fd34bf3d4c4fe3 (diff) | |
parent | 187b9c924ebaff8f02fb4e2139a01fd1512e3dc9 (diff) | |
download | mariadb-git-b3e395a13ee7e9df323cb654d18dc81ff2f3fd1e.tar.gz |
Merge 10.2 into 10.3
Diffstat (limited to 'sql/sp_head.cc')
-rw-r--r-- | sql/sp_head.cc | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/sql/sp_head.cc b/sql/sp_head.cc index f36650bafe9..59a304deb99 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -44,6 +44,9 @@ #include "transaction.h" // trans_commit_stmt #include "sql_audit.h" #include "debug_sync.h" +#ifdef WITH_WSREP +#include "wsrep_thd.h" +#endif /* WITH_WSREP */ /* Sufficient max length of printed destinations and frame offsets (all uints). @@ -1171,6 +1174,7 @@ sp_head::execute(THD *thd, bool merge_da_on_success) backup_arena; query_id_t old_query_id; TABLE *old_derived_tables; + TABLE *old_rec_tables; LEX *old_lex; Item_change_list old_change_list; String old_packet; @@ -1249,6 +1253,8 @@ sp_head::execute(THD *thd, bool merge_da_on_success) old_query_id= thd->query_id; old_derived_tables= thd->derived_tables; thd->derived_tables= 0; + old_rec_tables= thd->rec_tables; + thd->rec_tables= 0; save_sql_mode= thd->variables.sql_mode; thd->variables.sql_mode= m_sql_mode; save_abort_on_warning= thd->abort_on_warning; @@ -1369,7 +1375,93 @@ sp_head::execute(THD *thd, bool merge_da_on_success) thd->m_digest= NULL; err_status= i->execute(thd, &ip); +#ifdef WITH_WSREP + if (m_handler->type() == TYPE_ENUM_PROCEDURE) + { + mysql_mutex_lock(&thd->LOCK_thd_data); + if (thd->wsrep_conflict_state == MUST_REPLAY) + { + wsrep_replay_sp_transaction(thd); + err_status= thd->get_stmt_da()->is_set(); + thd->wsrep_conflict_state= NO_CONFLICT; + } + else if (thd->wsrep_conflict_state == ABORTED || + thd->wsrep_conflict_state == CERT_FAILURE) + { + /* + If the statement execution was BF aborted or was aborted + due to certification failure, clean up transaction here + and reset conflict state to NO_CONFLICT and thd->killed + to THD::NOT_KILLED. Error handling is done based on err_status + below. Error must have been raised by wsrep hton code before + entering here. + */ + DBUG_ASSERT(err_status); + DBUG_ASSERT(thd->get_stmt_da()->is_error()); + thd->wsrep_conflict_state= NO_CONFLICT; + thd->killed= NOT_KILLED; + } + mysql_mutex_unlock(&thd->LOCK_thd_data); + } +#endif /* WITH_WSREP */ +#ifdef WITH_WSREP_NO + if (WSREP(thd)) + { + if (((thd->wsrep_trx().state() == wsrep::transaction::s_executing) && + (thd->is_fatal_error || thd->killed))) + { + WSREP_DEBUG("SP abort err status %d in sub %d trx state %d", + err_status, thd->in_sub_stmt, thd->wsrep_trx().state()); + err_status= 1; + thd->is_fatal_error= 1; + /* + SP was killed, and it is not due to a wsrep conflict. + We skip after_command 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 + { + const bool must_replay= wsrep_must_replay(thd); + if (must_replay) + { + WSREP_DEBUG("MUST_REPLAY set after SP, err_status %d trx state: %d", + err_status, thd->wsrep_trx().state()); + } + (void) wsrep_after_statement(thd); + /* + Reset the return code to zero if the transaction was + replayed succesfully. + */ + if (must_replay && !wsrep_current_error(thd)) + { + err_status= 0; + thd->get_stmt_da()->reset_diagnostics_area(); + } + /* + 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->killed= NOT_KILLED; + /* if failed transaction was not replayed, must return with error from here */ + if (!must_replay) err_status = 1; + } + } + } +#endif /* WITH_WSREP */ thd->m_digest= parent_digest; if (i->free_list) @@ -1437,6 +1529,7 @@ sp_head::execute(THD *thd, bool merge_da_on_success) thd->set_query_id(old_query_id); DBUG_ASSERT(!thd->derived_tables); thd->derived_tables= old_derived_tables; + thd->rec_tables= old_rec_tables; thd->variables.sql_mode= save_sql_mode; thd->abort_on_warning= save_abort_on_warning; thd->m_reprepare_observer= save_reprepare_observer; |