summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
Diffstat (limited to 'sql')
-rw-r--r--sql/sql_class.h8
-rw-r--r--sql/sql_parse.cc41
-rw-r--r--sql/sys_vars.cc10
-rw-r--r--sql/wsrep_mysqld.h7
-rw-r--r--sql/wsrep_var.cc25
-rw-r--r--sql/wsrep_var.h1
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 */