1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-30 16:24:05 +03:00

MDEV-24255 MTR test galera_bf_abort fails with --ps-protocol

Under ps-protocol, commandsl like COM_STMT_FETCH, COM_STMT_CLOSE and
COM_STMT_SEND_LONG_DATA are not supposed to return errors. Therefore,
if a transaction is BF aborted and the client is processing one of
those commands, then we should not return a deadlock error
immediately. Instead wait for the a subsequent client interaction
which permits errors to be returned. To handle this,
wsrep_before_command() now accepts parameter keep_command_error. If
set true, keep_command_error will cause wsrep-lib side to skip result
handling, and to keep the current error for the next interaction with
the client.

Reviewed-by: Jan Lindström <jan.lindstrom@mariadb.com>
This commit is contained in:
Teemu Ollakka
2020-10-29 16:30:52 +02:00
committed by Jan Lindström
parent a64cb6d265
commit 4601e6e565
10 changed files with 166 additions and 15 deletions

View File

@ -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),