1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-27 18:02:13 +03:00

MW-388 Fix conflict handling of SPs with DECLARE ... HANDLER

It is possible for a stored procedure that has an error handler
that catches SQLEXCEPTION to call thd->clear_error() on a thd
that failed certification. And because the error is cleared,
wsrep patch proceeds with the normal path and may try to commit
statements that should actually abort.
This patch catches the situation where wsrep_conflict_state is
still set, but the thd's error has been cleared, and rolls back
the statement in such cases.
This commit is contained in:
Daniele Sciascia
2017-07-11 12:55:03 +02:00
committed by Jan Lindström
parent 3cecb1bab3
commit 76f1195f5b
3 changed files with 107 additions and 0 deletions

View File

@ -5620,6 +5620,26 @@ finish:
}
if (thd->is_error() || (thd->variables.option_bits & OPTION_MASTER_SQL_ERROR))
trans_rollback_stmt(thd);
#ifdef WITH_WSREP
else if (thd->sp_runtime_ctx &&
!thd->is_error() &&
!thd->in_multi_stmt_transaction_mode() &&
(thd->wsrep_conflict_state == MUST_ABORT ||
thd->wsrep_conflict_state == CERT_FAILURE))
{
/*
The error was cleared, but THD was aborted by wsrep and
wsrep_conflict_state is still set accordingly. This
situation is expected if we are running a stored procedure
that declares a handler that catches ER_LOCK_DEADLOCK error.
In which case the error may have been cleared in method
sp_rcontext::handle_sql_condition().
*/
trans_rollback_stmt(thd);
thd->wsrep_conflict_state= NO_CONFLICT;
thd->killed= THD::NOT_KILLED;
}
#endif /* WITH_WSREP */
else
{
/* If commit fails, we should be able to reset the OK status. */