diff options
Diffstat (limited to 'sql')
-rw-r--r-- | sql/share/errmsg-utf8.txt | 2 | ||||
-rw-r--r-- | sql/sql_base.cc | 13 | ||||
-rw-r--r-- | sql/sql_parse.cc | 5 | ||||
-rw-r--r-- | sql/sql_rename.cc | 2 | ||||
-rw-r--r-- | sql/sql_table.cc | 4 | ||||
-rw-r--r-- | sql/sql_trigger.cc | 2 | ||||
-rw-r--r-- | sql/sql_truncate.cc | 4 | ||||
-rw-r--r-- | sql/sys_vars.cc | 22 | ||||
-rw-r--r-- | sql/wsrep_mysqld.cc | 72 | ||||
-rw-r--r-- | sql/wsrep_mysqld.h | 14 | ||||
-rw-r--r-- | sql/wsrep_var.cc | 16 | ||||
-rw-r--r-- | sql/wsrep_var.h | 3 |
12 files changed, 137 insertions, 22 deletions
diff --git a/sql/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt index 2785a178e6e..add46a4cc75 100644 --- a/sql/share/errmsg-utf8.txt +++ b/sql/share/errmsg-utf8.txt @@ -7948,7 +7948,7 @@ ER_WARN_HISTORY_ROW_START_TIME ER_PART_STARTS_BEYOND_INTERVAL eng "%`s: STARTS is later than query time, first history partition may exceed INTERVAL value" ER_GALERA_REPLICATION_NOT_SUPPORTED - eng "DDL-statement is forbidden as table storage engine does not support Galera replication" + eng "Galera replication not supported" ER_LOAD_INFILE_CAPABILITY_DISABLED eng "The used command is not allowed because the MariaDB server or client has disabled the local infile capability" rum "Comanda folosită nu este permisă deoarece clientul sau serverul MariaDB a dezactivat această capabilitate" diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 87970ee11b4..623c0eff5b9 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -4430,6 +4430,19 @@ restart: else tbl->reginfo.lock_type= tables->lock_type; } +#ifdef WITH_WSREP + /* + At this point we have SE associated with table so we can check wsrep_mode + rules at this point. + */ + if (WSREP(thd) && + wsrep_thd_is_local(thd) && + !wsrep_check_mode_after_open_table(thd, tbl->file->ht->db_type)) + { + error= TRUE; + goto error; + } +#endif } #ifdef WITH_WSREP diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index d976e75843a..97b7dd427a5 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -3707,6 +3707,11 @@ mysql_execute_command(THD *thd) thd->set_query_timer(); #ifdef WITH_WSREP + /* Check wsrep_mode rules before command execution. */ + if (WSREP(thd) && + wsrep_thd_is_local(thd) && !wsrep_check_mode_before_cmd_execute(thd)) + goto error; + /* Always start a new transaction for a wsrep THD unless the current command is DDL or explicit BEGIN. This will guarantee that diff --git a/sql/sql_rename.cc b/sql/sql_rename.cc index 77a1e46a75a..b7aed97a8a2 100644 --- a/sql/sql_rename.cc +++ b/sql/sql_rename.cc @@ -325,7 +325,7 @@ do_rename(THD *thd, TABLE_LIST *ren_table, const LEX_CSTRING *new_db, #ifdef WITH_WSREP if (WSREP(thd) && hton && hton != view_pseudo_hton && - !wsrep_should_replicate_ddl(thd, hton->db_type)) + !wsrep_should_replicate_ddl(thd, hton)) DBUG_RETURN(1); #endif diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 5321ffd11bb..a3e0801cfb0 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -2474,7 +2474,7 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, } else { - if (WSREP(thd) && hton && !wsrep_should_replicate_ddl(thd, hton->db_type)) + if (WSREP(thd) && hton && !wsrep_should_replicate_ddl(thd, hton)) { error= 1; goto err; @@ -10001,7 +10001,7 @@ bool mysql_alter_table(THD *thd, const LEX_CSTRING *new_db, (thd->lex->sql_command == SQLCOM_ALTER_TABLE || thd->lex->sql_command == SQLCOM_CREATE_INDEX || thd->lex->sql_command == SQLCOM_DROP_INDEX) && - !wsrep_should_replicate_ddl(thd, table_list->table->s->db_type()->db_type)) + !wsrep_should_replicate_ddl(thd, table_list->table->s->db_type())) DBUG_RETURN(true); #endif diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc index 9417ec667ff..f93fe196728 100644 --- a/sql/sql_trigger.cc +++ b/sql/sql_trigger.cc @@ -551,7 +551,7 @@ bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create) #ifdef WITH_WSREP if (WSREP(thd) && - !wsrep_should_replicate_ddl(thd, table->s->db_type()->db_type)) + !wsrep_should_replicate_ddl(thd, table->s->db_type())) goto wsrep_error_label; #endif diff --git a/sql/sql_truncate.cc b/sql/sql_truncate.cc index 5e89c4d19ee..68b3570db9e 100644 --- a/sql/sql_truncate.cc +++ b/sql/sql_truncate.cc @@ -305,7 +305,7 @@ bool Sql_cmd_truncate_table::lock_table(THD *thd, TABLE_LIST *table_ref, hton= table->file->ht; #ifdef WITH_WSREP if (WSREP(thd) && - !wsrep_should_replicate_ddl(thd, hton->db_type)) + !wsrep_should_replicate_ddl(thd, hton)) DBUG_RETURN(TRUE); #endif @@ -329,7 +329,7 @@ bool Sql_cmd_truncate_table::lock_table(THD *thd, TABLE_LIST *table_ref, #ifdef WITH_WSREP if (WSREP(thd) && hton != view_pseudo_hton && - !wsrep_should_replicate_ddl(thd, hton->db_type)) + !wsrep_should_replicate_ddl(thd, hton)) { tdc_release_share(share); DBUG_RETURN(TRUE); diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index 12b6ea96182..a120e6963ec 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -5927,6 +5927,22 @@ static Sys_var_uint Sys_wsrep_sync_wait( NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0), ON_UPDATE(wsrep_sync_wait_update)); +static const char *wsrep_mode_names[]= +{ + "STRICT_REPLICATION", + "BINLOG_ROW_FORMAT_ONLY", + "REQUIRED_PRIMARY_KEY", + NullS +}; +static Sys_var_set Sys_wsrep_mode( + "wsrep_mode", + "Set of WSREP features that are enabled.", + GLOBAL_VAR(wsrep_mode), CMD_LINE(REQUIRED_ARG), + wsrep_mode_names, + DEFAULT(0), + NO_MUTEX_GUARD, NOT_IN_BINLOG, + ON_CHECK(wsrep_mode_check)); + static const char *wsrep_OSU_method_names[]= { "TOI", "RSU", NullS }; static Sys_var_enum Sys_wsrep_OSU_method( "wsrep_OSU_method", "Method for Online Schema Upgrade", @@ -5943,12 +5959,14 @@ static Sys_var_mybool Sys_wsrep_desync ( ON_UPDATE(wsrep_desync_update)); static Sys_var_mybool Sys_wsrep_strict_ddl ( - "wsrep_strict_ddl", "If set, reject DDL on affected tables not supporting Galera replication", + "wsrep_strict_ddl", + "If set, reject DDL on affected tables not supporting Galera replication", GLOBAL_VAR(wsrep_strict_ddl), CMD_LINE(OPT_ARG), DEFAULT(FALSE), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0), - ON_UPDATE(0)); + ON_UPDATE(wsrep_strict_ddl_update), + DEPRECATED("'@@wsrep_mode=STRICT_REPLICATION'")); // since 10.6.0 static const char *wsrep_reject_queries_names[]= { "NONE", "ALL", "ALL_KILL", NullS }; static Sys_var_enum Sys_wsrep_reject_queries( diff --git a/sql/wsrep_mysqld.cc b/sql/wsrep_mysqld.cc index 8118822d595..53150bfa7e7 100644 --- a/sql/wsrep_mysqld.cc +++ b/sql/wsrep_mysqld.cc @@ -97,7 +97,8 @@ my_bool wsrep_restart_slave; // Should mysql slave thread be // restarted, when node joins back? my_bool wsrep_desync; // De(re)synchronize the node from the // cluster -my_bool wsrep_strict_ddl; // Reject DDL to +ulonglong wsrep_mode; +my_bool wsrep_strict_ddl; // Deprecated: Reject DDL to // effected tables not // supporting Galera replication bool wsrep_service_started; // If Galera was initialized @@ -1167,6 +1168,54 @@ bool wsrep_start_replication() return true; } +bool wsrep_check_mode (enum_wsrep_mode mask) +{ + return wsrep_mode & mask; +} + +bool wsrep_check_mode_after_open_table (THD *thd, legacy_db_type db_type) +{ + return true; +} + +bool wsrep_check_mode_before_cmd_execute (THD *thd) +{ + bool ret= true; + if (wsrep_check_mode(WSREP_MODE_BINLOG_ROW_FORMAT_ONLY) && + !thd->is_current_stmt_binlog_format_row() && is_update_query(thd->lex->sql_command)) + { + my_error(ER_GALERA_REPLICATION_NOT_SUPPORTED, MYF(0)); + push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, + ER_OPTION_PREVENTS_STATEMENT, + "WSREP: wsrep_mode = BINLOG_ROW_FORMAT_ONLY enabled. Only ROW binlog format is supported."); + ret= false; + } + if (wsrep_check_mode(WSREP_MODE_REQURIED_PRIMARY_KEY) && + thd->lex->sql_command == SQLCOM_CREATE_TABLE) + { + Key *key; + List_iterator<Key> key_iterator(thd->lex->alter_info.key_list); + bool primary_key_found= false; + while ((key= key_iterator++)) + { + if (key->type == Key::PRIMARY) + { + primary_key_found= true; + break; + } + } + if (!primary_key_found) + { + my_error(ER_GALERA_REPLICATION_NOT_SUPPORTED, MYF(0)); + push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, + ER_OPTION_PREVENTS_STATEMENT, + "WSREP: wsrep_mode = REQUIRED_PRIMARY_KEY enabled. Table should have PRIMARY KEY defined."); + ret= false; + } + } + return ret; +} + bool wsrep_must_sync_wait (THD* thd, uint mask) { bool ret= 0; @@ -1848,20 +1897,19 @@ bool wsrep_should_replicate_ddl_iterate(THD* thd, const TABLE_LIST* table_list) for (const TABLE_LIST* it= table_list; it; it= it->next_global) { if (it->table && - !wsrep_should_replicate_ddl(thd, it->table->s->db_type()->db_type)) + !wsrep_should_replicate_ddl(thd, it->table->s->db_type())) return false; } } return true; } -bool wsrep_should_replicate_ddl(THD* thd, - const enum legacy_db_type db_type) +bool wsrep_should_replicate_ddl(THD* thd, const handlerton *hton) { - if (!wsrep_strict_ddl) + if (!wsrep_check_mode(WSREP_MODE_STRICT_REPLICATION)) return true; - switch (db_type) + switch (hton->db_type) { case DB_TYPE_INNODB: return true; @@ -1880,11 +1928,13 @@ bool wsrep_should_replicate_ddl(THD* thd, break; } - /* STRICT, treat as error */ + /* wsrep_mode = STRICT_REPLICATION, treat as error */ my_error(ER_GALERA_REPLICATION_NOT_SUPPORTED, MYF(0)); push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, - ER_ILLEGAL_HA, - "WSREP: wsrep_strict_ddl=true and storage engine does not support Galera replication."); + ER_ILLEGAL_HA, + "WSREP: wsrep_mode = STRICT_REPLICATION enabled. " + "Storage engine %s not supported.", + ha_resolve_storage_engine_name(hton)); return false; } /* @@ -1915,7 +1965,7 @@ bool wsrep_can_run_in_toi(THD *thd, const char *db, const char *table, { return false; } - if (!wsrep_should_replicate_ddl(thd, create_info->db_type->db_type)) + if (!wsrep_should_replicate_ddl(thd, create_info->db_type)) { return false; } @@ -1992,7 +2042,7 @@ bool wsrep_can_run_in_toi(THD *thd, const char *db, const char *table, break; case SQLCOM_ALTER_TABLE: if (create_info && - !wsrep_should_replicate_ddl(thd, create_info->db_type->db_type)) + !wsrep_should_replicate_ddl(thd, create_info->db_type)) return false; /* fallthrough */ default: diff --git a/sql/wsrep_mysqld.h b/sql/wsrep_mysqld.h index adfd3cec626..ff157fc4981 100644 --- a/sql/wsrep_mysqld.h +++ b/sql/wsrep_mysqld.h @@ -100,8 +100,9 @@ extern ulong wsrep_running_applier_threads; extern ulong wsrep_running_rollbacker_threads; extern bool wsrep_new_cluster; extern bool wsrep_gtid_mode; -extern my_bool wsrep_strict_ddl; extern uint wsrep_gtid_domain_id; +extern ulonglong wsrep_mode; +extern my_bool wsrep_strict_ddl; enum enum_wsrep_reject_types { WSREP_REJECT_NONE, /* nothing rejected */ @@ -133,6 +134,12 @@ enum enum_wsrep_ignore_apply_error { WSREP_IGNORE_ERRORS_MAX= 0x7 }; +enum enum_wsrep_mode { + WSREP_MODE_STRICT_REPLICATION= (1ULL << 0), + WSREP_MODE_BINLOG_ROW_FORMAT_ONLY= (1ULL << 1), + WSREP_MODE_REQURIED_PRIMARY_KEY= (1ULL << 2) +}; + // Streaming Replication #define WSREP_FRAG_BYTES 0 #define WSREP_FRAG_ROWS 1 @@ -209,6 +216,9 @@ extern void wsrep_close_applier_threads(int count); extern void wsrep_stop_replication(THD *thd); extern bool wsrep_start_replication(); extern void wsrep_shutdown_replication(); +extern bool wsrep_check_mode (enum_wsrep_mode mask); +extern bool wsrep_check_mode_after_open_table (THD *thd, legacy_db_type db_type); +extern bool wsrep_check_mode_before_cmd_execute (THD *thd); extern bool wsrep_must_sync_wait (THD* thd, uint mask= WSREP_SYNC_WAIT_BEFORE_READ); extern bool wsrep_sync_wait (THD* thd, uint mask= WSREP_SYNC_WAIT_BEFORE_READ); extern enum wsrep::provider::status @@ -369,7 +379,7 @@ int wsrep_to_isolation_begin(THD *thd, const char *db_, const char *table_, const wsrep::key_array *fk_tables= nullptr, const HA_CREATE_INFO* create_info= nullptr); -bool wsrep_should_replicate_ddl(THD* thd, const enum legacy_db_type db_type); +bool wsrep_should_replicate_ddl(THD* thd, const handlerton *db_type); bool wsrep_should_replicate_ddl_iterate(THD* thd, const TABLE_LIST* table_list); void wsrep_to_isolation_end(THD *thd); diff --git a/sql/wsrep_var.cc b/sql/wsrep_var.cc index c5a75739190..7dbe1d5aa60 100644 --- a/sql/wsrep_var.cc +++ b/sql/wsrep_var.cc @@ -891,6 +891,11 @@ bool wsrep_max_ws_size_update(sys_var *self, THD *thd, enum_var_type) return refresh_provider_options(); } +bool wsrep_mode_check(sys_var *self, THD* thd, set_var* var) +{ + return false; +} + #if UNUSED /* eaec266eb16c (Sergei Golubchik 2014-09-28) */ static SHOW_VAR wsrep_status_vars[]= { @@ -1019,3 +1024,14 @@ bool wsrep_gtid_domain_id_update(sys_var* self, THD *thd, enum_var_type) wsrep_gtid_server.domain_id= wsrep_gtid_domain_id; return false; } + +bool wsrep_strict_ddl_update(sys_var *self, THD* thd, enum_var_type var_type) +{ + // In case user still sets wsrep_strict_ddl we set new + // option to wsrep_mode + if (wsrep_strict_ddl) + wsrep_mode|= WSREP_MODE_STRICT_REPLICATION; + else + wsrep_mode&= (~WSREP_MODE_STRICT_REPLICATION); + return false; +} diff --git a/sql/wsrep_var.h b/sql/wsrep_var.h index fb23182dbf2..ae4f39a4034 100644 --- a/sql/wsrep_var.h +++ b/sql/wsrep_var.h @@ -106,6 +106,9 @@ extern bool wsrep_debug_update UPDATE_ARGS; extern bool wsrep_gtid_seq_no_check CHECK_ARGS; extern bool wsrep_gtid_domain_id_update UPDATE_ARGS; + +extern bool wsrep_mode_check CHECK_ARGS; +extern bool wsrep_strict_ddl_update UPDATE_ARGS; #else /* WITH_WSREP */ #define wsrep_provider_init(X) |