diff options
Diffstat (limited to 'sql')
-rw-r--r-- | sql/sql_class.h | 8 | ||||
-rw-r--r-- | sql/sql_parse.cc | 41 | ||||
-rw-r--r-- | sql/sys_vars.cc | 10 | ||||
-rw-r--r-- | sql/wsrep_mysqld.h | 7 | ||||
-rw-r--r-- | sql/wsrep_var.cc | 25 | ||||
-rw-r--r-- | sql/wsrep_var.h | 1 |
6 files changed, 83 insertions, 9 deletions
diff --git a/sql/sql_class.h b/sql/sql_class.h index 91030145022..b42b6ece9d4 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -5475,6 +5475,14 @@ public: sent by the user (ie: stored procedure). */ #define CF_SKIP_QUESTIONS (1U << 1) +#ifdef WITH_WSREP +/** + Do not check that wsrep snapshot is ready before allowing this command +*/ +#define CF_SKIP_WSREP_CHECK (1U << 2) +#else +#define CF_SKIP_WSREP_CHECK 0 +#endif /* WITH_WSREP */ /** Do not check that wsrep snapshot is ready before allowing this command diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 97d743d9a42..6a10f50813b 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1,5 +1,5 @@ /* Copyright (c) 2000, 2017, Oracle and/or its affiliates. - Copyright (c) 2008, 2017, MariaDB + Copyright (c) 2008, 2018, MariaDB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -284,6 +284,8 @@ void init_update_queries(void) server_command_flags[COM_QUERY]= CF_SKIP_WSREP_CHECK; server_command_flags[COM_SET_OPTION]= CF_SKIP_WSREP_CHECK; server_command_flags[COM_STMT_PREPARE]= CF_SKIP_QUESTIONS | CF_SKIP_WSREP_CHECK; + server_command_flags[COM_STMT_EXECUTE]= CF_SKIP_WSREP_CHECK; + server_command_flags[COM_STMT_FETCH]= CF_SKIP_WSREP_CHECK; server_command_flags[COM_STMT_CLOSE]= CF_SKIP_QUESTIONS | CF_SKIP_WSREP_CHECK; server_command_flags[COM_STMT_RESET]= CF_SKIP_QUESTIONS | CF_SKIP_WSREP_CHECK; server_command_flags[COM_STMT_EXECUTE]= CF_SKIP_WSREP_CHECK; @@ -887,6 +889,25 @@ void cleanup_items(Item *item) } +#ifdef WITH_WSREP +static bool wsrep_tables_accessible_when_detached(const TABLE_LIST *tables) +{ + for (const TABLE_LIST *table= tables; table; table= table->next_global) + { + TABLE_CATEGORY c; + LEX_STRING db, tn; + lex_string_set(&db, table->db); + lex_string_set(&tn, table->table_name); + c= get_table_category(&db, &tn); + if (c != TABLE_CATEGORY_INFORMATION && + c != TABLE_CATEGORY_PERFORMANCE) + { + return false; + } + } + return true; +} +#endif /* WITH_WSREP */ #ifndef EMBEDDED_LIBRARY #ifdef WITH_WSREP @@ -2659,14 +2680,18 @@ mysql_execute_command(THD *thd) We additionally allow all other commands that do not change data in case wsrep_dirty_reads is enabled. */ - if (lex->sql_command != SQLCOM_SET_OPTION && - !wsrep_is_show_query(lex->sql_command) && - !(thd->variables.wsrep_dirty_reads && - !is_update_query(lex->sql_command)) && - !(lex->sql_command == SQLCOM_SELECT && - !all_tables) && - !wsrep_node_is_ready(thd)) + if (thd->variables.wsrep_on && !thd->wsrep_applier && + !(wsrep_ready || + (thd->variables.wsrep_dirty_reads && + (sql_command_flags[lex->sql_command] & CF_CHANGES_DATA) == 0) || + wsrep_tables_accessible_when_detached(all_tables)) && + lex->sql_command != SQLCOM_SET_OPTION && + !wsrep_is_show_query(lex->sql_command)) + { + my_message(ER_UNKNOWN_COM_ERROR, + "WSREP has not yet prepared node for application use", MYF(0)); goto error; + } } #endif /* WITH_WSREP */ status_var_increment(thd->status_var.com_stat[lex->sql_command]); diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index 303633939c3..2ec886f0528 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -1,5 +1,5 @@ /* Copyright (c) 2002, 2015, Oracle and/or its affiliates. - Copyright (c) 2012, 2015, MariaDB + Copyright (c) 2012, 2018, MariaDB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -4967,6 +4967,14 @@ static Sys_var_mybool Sys_wsrep_desync ( ON_CHECK(wsrep_desync_check), ON_UPDATE(wsrep_desync_update)); +static const char *wsrep_reject_queries_names[]= { "NONE", "ALL", "ALL_KILL", NullS }; +static Sys_var_enum Sys_wsrep_reject_queries( + "wsrep_reject_queries", "Variable to set to reject queries", + GLOBAL_VAR(wsrep_reject_queries), CMD_LINE(OPT_ARG), + wsrep_reject_queries_names, DEFAULT(WSREP_REJECT_NONE), + NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0), + ON_UPDATE(wsrep_reject_queries_update)); + static const char *wsrep_binlog_format_names[]= {"MIXED", "STATEMENT", "ROW", "NONE", NullS}; static Sys_var_enum Sys_wsrep_forced_binlog_format( diff --git a/sql/wsrep_mysqld.h b/sql/wsrep_mysqld.h index fd68fab991c..33af697a19b 100644 --- a/sql/wsrep_mysqld.h +++ b/sql/wsrep_mysqld.h @@ -80,6 +80,7 @@ extern const char* wsrep_notify_cmd; extern long wsrep_max_protocol_version; extern ulong wsrep_forced_binlog_format; extern my_bool wsrep_desync; +extern ulong wsrep_reject_queries; extern my_bool wsrep_replicate_myisam; extern ulong wsrep_mysql_replication_bundle; extern my_bool wsrep_restart_slave; @@ -92,6 +93,12 @@ extern bool wsrep_gtid_mode; extern uint32 wsrep_gtid_domain_id; extern bool wsrep_dirty_reads; +enum enum_wsrep_reject_types { + WSREP_REJECT_NONE, /* nothing rejected */ + WSREP_REJECT_ALL, /* reject all queries, with UNKNOWN_COMMAND error */ + WSREP_REJECT_ALL_KILL /* kill existing connections and reject all queries*/ +}; + enum enum_wsrep_OSU_method { WSREP_OSU_TOI, WSREP_OSU_RSU, diff --git a/sql/wsrep_var.cc b/sql/wsrep_var.cc index ad1f4ec0eac..da53c0981af 100644 --- a/sql/wsrep_var.cc +++ b/sql/wsrep_var.cc @@ -34,6 +34,7 @@ const char* wsrep_node_name = 0; const char* wsrep_node_address = 0; const char* wsrep_node_incoming_address = 0; const char* wsrep_start_position = 0; +ulong wsrep_reject_queries; static long wsrep_prev_slave_threads = wsrep_slave_threads; @@ -384,6 +385,30 @@ void wsrep_provider_options_init(const char* value) wsrep_provider_options = (value) ? my_strdup(value, MYF(0)) : NULL; } +bool wsrep_reject_queries_update(sys_var *self, THD* thd, enum_var_type type) +{ + switch (wsrep_reject_queries) { + case WSREP_REJECT_NONE: + wsrep_ready_set(TRUE); + WSREP_INFO("Allowing client queries due to manual setting"); + break; + case WSREP_REJECT_ALL: + wsrep_ready_set(FALSE); + WSREP_INFO("Rejecting client queries due to manual setting"); + break; + case WSREP_REJECT_ALL_KILL: + wsrep_ready_set(FALSE); + wsrep_close_client_connections(FALSE); + WSREP_INFO("Rejecting client queries and killing connections due to manual setting"); + break; + default: + WSREP_INFO("Unknown value for wsrep_reject_queries: %lu", + wsrep_reject_queries); + return true; + } + return false; +} + static int wsrep_cluster_address_verify (const char* cluster_address_str) { /* There is no predefined address format, it depends on provider. */ diff --git a/sql/wsrep_var.h b/sql/wsrep_var.h index 55eb2fbc501..53952173c83 100644 --- a/sql/wsrep_var.h +++ b/sql/wsrep_var.h @@ -93,6 +93,7 @@ extern bool wsrep_desync_update UPDATE_ARGS; extern bool wsrep_max_ws_size_check CHECK_ARGS; extern bool wsrep_max_ws_size_update UPDATE_ARGS; +extern bool wsrep_reject_queries_update UPDATE_ARGS; #else /* WITH_WSREP */ |