Commit 0def671f authored by sjaakola's avatar sjaakola Committed by Jan Lindström

MDEV-26391 BF abortable mariabackup execution

This commit changes backup execution (namely the block ddl phase),
so that node is not paused from cluster. Instead, the following
backup execution is declared as vulnerable for possible cluster
level conflicts, especially with DDL statement applying.
With this, the mariabackup execution may be aborted, if DDL
statements happen during backup execution. This abortable
backup execution is optional feature and may be
enabled/disabled by wsrep_mode: BF_ABORT_MARIABACKUP.
Reviewed-by: default avatarJan Lindström <jan.lindstrom@mariadb.com>
parent 1e04cafc
...@@ -20,8 +20,8 @@ SET GLOBAL wsrep_mode='A'; ...@@ -20,8 +20,8 @@ SET GLOBAL wsrep_mode='A';
ERROR 42000: Variable 'wsrep_mode' can't be set to the value of 'A' ERROR 42000: Variable 'wsrep_mode' can't be set to the value of 'A'
SET GLOBAL wsrep_mode=NULL; SET GLOBAL wsrep_mode=NULL;
ERROR 42000: Variable 'wsrep_mode' can't be set to the value of 'NULL' ERROR 42000: Variable 'wsrep_mode' can't be set to the value of 'NULL'
SET GLOBAL wsrep_mode=64; SET GLOBAL wsrep_mode=128;
ERROR 42000: Variable 'wsrep_mode' can't be set to the value of '64' ERROR 42000: Variable 'wsrep_mode' can't be set to the value of '128'
SET GLOBAL wsrep_mode=REQUIRED_PRIMARY_KEY,REPLICATE_MYISAM; SET GLOBAL wsrep_mode=REQUIRED_PRIMARY_KEY,REPLICATE_MYISAM;
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '' at line 1 ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '' at line 1
SET GLOBAL wsrep_mode=1; SET GLOBAL wsrep_mode=1;
......
...@@ -22,7 +22,7 @@ SET GLOBAL wsrep_mode='A'; ...@@ -22,7 +22,7 @@ SET GLOBAL wsrep_mode='A';
--error ER_WRONG_VALUE_FOR_VAR --error ER_WRONG_VALUE_FOR_VAR
SET GLOBAL wsrep_mode=NULL; SET GLOBAL wsrep_mode=NULL;
--error ER_WRONG_VALUE_FOR_VAR --error ER_WRONG_VALUE_FOR_VAR
SET GLOBAL wsrep_mode=64; SET GLOBAL wsrep_mode=128;
--error ER_PARSE_ERROR --error ER_PARSE_ERROR
SET GLOBAL wsrep_mode=REQUIRED_PRIMARY_KEY,REPLICATE_MYISAM; SET GLOBAL wsrep_mode=REQUIRED_PRIMARY_KEY,REPLICATE_MYISAM;
# #
......
...@@ -36,6 +36,7 @@ ...@@ -36,6 +36,7 @@
#include <my_sys.h> #include <my_sys.h>
#include <strfunc.h> // strconvert() #include <strfunc.h> // strconvert()
#include "wsrep_mysqld.h" #include "wsrep_mysqld.h"
#include "debug_sync.h"
#ifdef WITH_WSREP #ifdef WITH_WSREP
#include "wsrep_server_state.h" #include "wsrep_server_state.h"
#endif /* WITH_WSREP */ #endif /* WITH_WSREP */
...@@ -295,7 +296,7 @@ static bool backup_block_ddl(THD *thd) ...@@ -295,7 +296,7 @@ static bool backup_block_ddl(THD *thd)
We desync the node for BACKUP STAGE because applier threads We desync the node for BACKUP STAGE because applier threads
bypass backup MDL locks (see MDL_lock::can_grant_lock) bypass backup MDL locks (see MDL_lock::can_grant_lock)
*/ */
if (WSREP_NNULL(thd)) if (WSREP_NNULL(thd) && !wsrep_check_mode(WSREP_MODE_BF_MARIABACKUP))
{ {
Wsrep_server_state &server_state= Wsrep_server_state::instance(); Wsrep_server_state &server_state= Wsrep_server_state::instance();
if (server_state.desync_and_pause().is_undefined()) { if (server_state.desync_and_pause().is_undefined()) {
...@@ -341,6 +342,18 @@ static bool backup_block_ddl(THD *thd) ...@@ -341,6 +342,18 @@ static bool backup_block_ddl(THD *thd)
/* There can't be anything more that needs to be logged to ddl log */ /* There can't be anything more that needs to be logged to ddl log */
THD_STAGE_INFO(thd, org_stage); THD_STAGE_INFO(thd, org_stage);
stop_ddl_logging(); stop_ddl_logging();
#ifdef WITH_WSREP
// Allow tests to block the applier thread using the DBUG facilities
DBUG_EXECUTE_IF("sync.wsrep_after_mdl_block_ddl",
{
const char act[]=
"now "
"signal signal.wsrep_apply_toi";
DBUG_ASSERT(!debug_sync_set_action(thd,
STRING_WITH_LEN(act)));
};);
#endif /* WITH_WSREP */
DBUG_RETURN(0); DBUG_RETURN(0);
err: err:
THD_STAGE_INFO(thd, org_stage); THD_STAGE_INFO(thd, org_stage);
...@@ -400,7 +413,8 @@ bool backup_end(THD *thd) ...@@ -400,7 +413,8 @@ bool backup_end(THD *thd)
thd->current_backup_stage= BACKUP_FINISHED; thd->current_backup_stage= BACKUP_FINISHED;
thd->mdl_context.release_lock(old_ticket); thd->mdl_context.release_lock(old_ticket);
#ifdef WITH_WSREP #ifdef WITH_WSREP
if (WSREP_NNULL(thd) && thd->wsrep_desynced_backup_stage) if (WSREP_NNULL(thd) && thd->wsrep_desynced_backup_stage &&
!wsrep_check_mode(WSREP_MODE_BF_MARIABACKUP))
{ {
Wsrep_server_state &server_state= Wsrep_server_state::instance(); Wsrep_server_state &server_state= Wsrep_server_state::instance();
THD_STAGE_INFO(thd, stage_waiting_flow); THD_STAGE_INFO(thd, stage_waiting_flow);
......
...@@ -1750,7 +1750,8 @@ MDL_lock::can_grant_lock(enum_mdl_type type_arg, ...@@ -1750,7 +1750,8 @@ MDL_lock::can_grant_lock(enum_mdl_type type_arg,
We should get rid of this code and forbid FTWRL/BACKUP statements We should get rid of this code and forbid FTWRL/BACKUP statements
when wsrep is active. when wsrep is active.
*/ */
if ((wsrep_thd_is_toi(requestor_ctx->get_thd()) || if (!wsrep_check_mode(WSREP_MODE_BF_MARIABACKUP) &&
(wsrep_thd_is_toi(requestor_ctx->get_thd()) ||
wsrep_thd_is_applying(requestor_ctx->get_thd())) && wsrep_thd_is_applying(requestor_ctx->get_thd())) &&
key.mdl_namespace() == MDL_key::BACKUP) key.mdl_namespace() == MDL_key::BACKUP)
{ {
......
...@@ -241,7 +241,7 @@ extern "C" my_bool wsrep_thd_bf_abort(THD *bf_thd, THD *victim_thd, ...@@ -241,7 +241,7 @@ extern "C" my_bool wsrep_thd_bf_abort(THD *bf_thd, THD *victim_thd,
victim_thd->awake_no_mutex(KILL_QUERY); victim_thd->awake_no_mutex(KILL_QUERY);
mysql_mutex_unlock(&victim_thd->LOCK_thd_data); mysql_mutex_unlock(&victim_thd->LOCK_thd_data);
} else { } else {
WSREP_DEBUG("wsrep_thd_bf_abort skipped awake"); WSREP_DEBUG("wsrep_thd_bf_abort skipped awake, signal %d", signal);
} }
return ret; return ret;
} }
...@@ -277,7 +277,6 @@ extern "C" my_bool wsrep_thd_is_aborting(const MYSQL_THD thd) ...@@ -277,7 +277,6 @@ extern "C" my_bool wsrep_thd_is_aborting(const MYSQL_THD thd)
return (cs.state() == wsrep::client_state::s_exec || return (cs.state() == wsrep::client_state::s_exec ||
cs.state() == wsrep::client_state::s_result); cs.state() == wsrep::client_state::s_result);
case wsrep::transaction::s_aborting: case wsrep::transaction::s_aborting:
case wsrep::transaction::s_aborted:
return true; return true;
default: default:
return false; return false;
......
...@@ -6028,6 +6028,7 @@ static const char *wsrep_mode_names[]= ...@@ -6028,6 +6028,7 @@ static const char *wsrep_mode_names[]=
"REPLICATE_MYISAM", "REPLICATE_MYISAM",
"REPLICATE_ARIA", "REPLICATE_ARIA",
"DISALLOW_LOCAL_GTID", "DISALLOW_LOCAL_GTID",
"BF_ABORT_MARIABACKUP",
NullS NullS
}; };
static Sys_var_set Sys_wsrep_mode( static Sys_var_set Sys_wsrep_mode(
......
...@@ -3078,6 +3078,11 @@ void wsrep_handle_mdl_conflict(MDL_context *requestor_ctx, ...@@ -3078,6 +3078,11 @@ void wsrep_handle_mdl_conflict(MDL_context *requestor_ctx,
THD_STAGE_INFO(request_thd, stage_waiting_ddl); THD_STAGE_INFO(request_thd, stage_waiting_ddl);
ticket->wsrep_report(wsrep_debug); ticket->wsrep_report(wsrep_debug);
mysql_mutex_unlock(&granted_thd->LOCK_thd_data); mysql_mutex_unlock(&granted_thd->LOCK_thd_data);
if (granted_thd->current_backup_stage != BACKUP_FINISHED &&
wsrep_check_mode(WSREP_MODE_BF_MARIABACKUP))
{
wsrep_abort_thd(request_thd, granted_thd, 1);
}
} }
else if (request_thd->lex->sql_command == SQLCOM_DROP_TABLE) else if (request_thd->lex->sql_command == SQLCOM_DROP_TABLE)
{ {
......
...@@ -128,7 +128,8 @@ enum enum_wsrep_mode { ...@@ -128,7 +128,8 @@ enum enum_wsrep_mode {
WSREP_MODE_REQUIRED_PRIMARY_KEY= (1ULL << 2), WSREP_MODE_REQUIRED_PRIMARY_KEY= (1ULL << 2),
WSREP_MODE_REPLICATE_MYISAM= (1ULL << 3), WSREP_MODE_REPLICATE_MYISAM= (1ULL << 3),
WSREP_MODE_REPLICATE_ARIA= (1ULL << 4), WSREP_MODE_REPLICATE_ARIA= (1ULL << 4),
WSREP_MODE_DISALLOW_LOCAL_GTID= (1ULL << 5) WSREP_MODE_DISALLOW_LOCAL_GTID= (1ULL << 5),
WSREP_MODE_BF_MARIABACKUP= (1ULL << 6)
}; };
// Streaming Replication // Streaming Replication
......
...@@ -375,6 +375,14 @@ bool wsrep_bf_abort(THD* bf_thd, THD* victim_thd) ...@@ -375,6 +375,14 @@ bool wsrep_bf_abort(THD* bf_thd, THD* victim_thd)
have acquired MDL locks (due to DDL execution), and this has caused BF conflict. have acquired MDL locks (due to DDL execution), and this has caused BF conflict.
such case does not require aborting in wsrep or replication provider state. such case does not require aborting in wsrep or replication provider state.
*/ */
if (victim_thd->current_backup_stage != BACKUP_FINISHED &&
wsrep_check_mode(WSREP_MODE_BF_MARIABACKUP))
{
WSREP_DEBUG("killing connection for non wsrep session");
mysql_mutex_lock(&victim_thd->LOCK_thd_data);
victim_thd->awake_no_mutex(KILL_CONNECTION);
mysql_mutex_unlock(&victim_thd->LOCK_thd_data);
}
return false; return false;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment