diff options
author | Jan Lindström <jan.lindstrom@mariadb.com> | 2015-03-10 08:28:51 +0200 |
---|---|---|
committer | Jan Lindström <jan.lindstrom@mariadb.com> | 2015-03-12 12:17:14 +0200 |
commit | 8249dcaaebf8cd1944bd4ab7ccaa8b199e76d6f9 (patch) | |
tree | 66a9b1c65f0f220e305681fa41811886fa05d908 | |
parent | ba3573cae8f0d269452cc6213f1a8243e455830e (diff) | |
download | mariadb-git-8249dcaaebf8cd1944bd4ab7ccaa8b199e76d6f9.tar.gz |
MDEV-6858: enforce_storage_engine option
Merge from Percona Server enforced use of a specific storage engine
authored by Stewart Smith.
Modified to be session variable and modifiable only by SUPER. Use
similar implementation as default_storage_engine.
-rw-r--r-- | mysql-test/r/enforce_storage_engine.result | 102 | ||||
-rw-r--r-- | mysql-test/r/mysqld--help.result | 3 | ||||
-rw-r--r-- | mysql-test/suite/sys_vars/r/all_vars.result | 1 | ||||
-rw-r--r-- | mysql-test/suite/sys_vars/r/enforce_storage_engine_basic.result | 39 | ||||
-rw-r--r-- | mysql-test/suite/sys_vars/r/innodb_instrument_semaphores_basic.result | 45 | ||||
-rw-r--r-- | mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result | 14 | ||||
-rw-r--r-- | mysql-test/suite/sys_vars/t/enforce_storage_engine_basic.test | 40 | ||||
-rw-r--r-- | mysql-test/suite/sys_vars/t/innodb_instrument_semaphores_basic.test (renamed from mysql-test/suite/sys_vars/t/innodb_instrument_semaphores.test) | 0 | ||||
-rw-r--r-- | mysql-test/t/enforce_storage_engine.test | 73 | ||||
-rw-r--r-- | sql/handler.cc | 1 | ||||
-rw-r--r-- | sql/mysqld.cc | 7 | ||||
-rw-r--r-- | sql/mysqld.h | 1 | ||||
-rw-r--r-- | sql/sql_class.h | 1 | ||||
-rw-r--r-- | sql/sql_plugin.cc | 8 | ||||
-rw-r--r-- | sql/sql_table.cc | 12 | ||||
-rw-r--r-- | sql/sys_vars.cc | 6 |
16 files changed, 351 insertions, 2 deletions
diff --git a/mysql-test/r/enforce_storage_engine.result b/mysql-test/r/enforce_storage_engine.result new file mode 100644 index 00000000000..3b29d5ecb09 --- /dev/null +++ b/mysql-test/r/enforce_storage_engine.result @@ -0,0 +1,102 @@ +drop table if exists t1; +SET SESSION enforce_storage_engine=MyISAM; +select @@session.enforce_storage_engine; +@@session.enforce_storage_engine +MyISAM +CREATE TABLE t1 (c1 INT PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=Memory; +Warnings: +Note 1266 Using storage engine MyISAM for table 't1' +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c1` int(11) NOT NULL AUTO_INCREMENT, + `c2` varchar(10) DEFAULT NULL, + PRIMARY KEY (`c1`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +DROP TABLE t1; +CREATE TABLE t1 (c1 INT PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=MyISAM; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c1` int(11) NOT NULL AUTO_INCREMENT, + `c2` varchar(10) DEFAULT NULL, + PRIMARY KEY (`c1`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +DROP TABLE t1; +CREATE TABLE t1 (c1 INT PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c1` int(11) NOT NULL AUTO_INCREMENT, + `c2` varchar(10) DEFAULT NULL, + PRIMARY KEY (`c1`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +DROP TABLE t1; +SET SESSION sql_mode='NO_ENGINE_SUBSTITUTION'; +CREATE TABLE t1 (c1 INT PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=MyISAM; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c1` int(11) NOT NULL AUTO_INCREMENT, + `c2` varchar(10) DEFAULT NULL, + PRIMARY KEY (`c1`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +INSERT INTO t1 values (1,'abba'); +CREATE TABLE t2 (c1 INT PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=Memory; +ERROR 42000: Unknown storage engine 'MEMORY' +SET SESSION sql_mode=''; +SET SESSION enforce_storage_engine=MyISAM; +select @@session.enforce_storage_engine; +@@session.enforce_storage_engine +MyISAM +select * from t1; +c1 c2 +1 abba +drop table t1; +CREATE TABLE t1 (c1 INT PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c1` int(11) NOT NULL AUTO_INCREMENT, + `c2` varchar(10) DEFAULT NULL, + PRIMARY KEY (`c1`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +DROP TABLE t1; +SET SESSION enforce_storage_engine=FooBar; +ERROR 42000: Unknown storage engine 'FooBar' +select @@session.enforce_storage_engine; +@@session.enforce_storage_engine +MyISAM +SET SESSION enforce_storage_engine=MyISAM; +ERROR 42000: Access denied; you need (at least one of) the SUPER privilege(s) for this operation +SET SESSION enforce_storage_engine=NULL; +SET SESSION sql_mode='NO_ENGINE_SUBSTITUTION'; +CREATE TABLE t1 (c1 INT PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=Memory; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c1` int(11) NOT NULL AUTO_INCREMENT, + `c2` varchar(10) DEFAULT NULL, + PRIMARY KEY (`c1`) +) ENGINE=MEMORY DEFAULT CHARSET=latin1 +DROP TABLE t1; +CREATE TABLE t1 (c1 INT PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=MyISAM; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c1` int(11) NOT NULL AUTO_INCREMENT, + `c2` varchar(10) DEFAULT NULL, + PRIMARY KEY (`c1`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +DROP TABLE t1; +CREATE TABLE t1 (c1 INT PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c1` int(11) NOT NULL AUTO_INCREMENT, + `c2` varchar(10) DEFAULT NULL, + PRIMARY KEY (`c1`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +DROP TABLE t1; +SET GLOBAL enforce_storage_engine=NULL; +ERROR HY000: Variable 'enforce_storage_engine' is a SESSION variable and can't be used with SET GLOBAL diff --git a/mysql-test/r/mysqld--help.result b/mysql-test/r/mysqld--help.result index 3036700be6f..7d59ecd1dc2 100644 --- a/mysql-test/r/mysqld--help.result +++ b/mysql-test/r/mysqld--help.result @@ -169,6 +169,8 @@ The following options may be given as the first argument: Which encryption algorithm to use for table encryption. aes_cbc is the recommended one.. One of: none, aes_ecb, aes_cbc, aes_ctr + --enforce-storage-engine=name + Force the use of a storage engine for new tables --event-scheduler[=name] Enable the event scheduler. Possible values are ON, OFF, and DISABLED (keep the event scheduler completely @@ -1150,6 +1152,7 @@ delayed-queue-size 1000 div-precision-increment 4 encrypt-tmp-disk-tables FALSE encryption-algorithm none +enforce-storage-engine (No default value) event-scheduler OFF expensive-subquery-limit 100 expire-logs-days 0 diff --git a/mysql-test/suite/sys_vars/r/all_vars.result b/mysql-test/suite/sys_vars/r/all_vars.result index 0ace47d1378..840da8405c3 100644 --- a/mysql-test/suite/sys_vars/r/all_vars.result +++ b/mysql-test/suite/sys_vars/r/all_vars.result @@ -10,7 +10,6 @@ there should be *no* long test name listed below: select distinct variable_name as `there should be *no* variables listed below:` from t2 left join t1 on variable_name=test_name where test_name is null; there should be *no* variables listed below: -innodb_instrument_semaphores strict_password_validation drop table t1; drop table t2; diff --git a/mysql-test/suite/sys_vars/r/enforce_storage_engine_basic.result b/mysql-test/suite/sys_vars/r/enforce_storage_engine_basic.result new file mode 100644 index 00000000000..cb5b199b271 --- /dev/null +++ b/mysql-test/suite/sys_vars/r/enforce_storage_engine_basic.result @@ -0,0 +1,39 @@ +SET @start_session_value = @@session.enforce_storage_engine; +SET @@session.enforce_storage_engine = INNODB; +SET @@session.enforce_storage_engine = DEFAULT; +SELECT @@session.enforce_storage_engine; +@@session.enforce_storage_engine +NULL +SET @@session.enforce_storage_engine = MYISAM; +SELECT @@session.enforce_storage_engine; +@@session.enforce_storage_engine +MyISAM +SET @@session.enforce_storage_engine = MERGE; +SELECT @@session.enforce_storage_engine; +@@session.enforce_storage_engine +MRG_MyISAM +SET @@session.enforce_storage_engine = MEMORY; +SELECT @@session.enforce_storage_engine; +@@session.enforce_storage_engine +MEMORY +SET @@session.enforce_storage_engine = INNODB; +SELECT @@session.enforce_storage_engine; +@@session.enforce_storage_engine +InnoDB +SET @@session.enforce_storage_engine = 8199; +ERROR 42000: Incorrect argument type to variable 'enforce_storage_engine' +SET @@session.enforce_storage_engine = 65530.34; +ERROR 42000: Incorrect argument type to variable 'enforce_storage_engine' +SET @@session.enforce_storage_engine = RECORD; +ERROR 42000: Unknown storage engine 'RECORD' +SELECT @@session.enforce_storage_engine = +VARIABLE_VALUE FROM INFORMATION_SCHEMA.SESSION_VARIABLES +WHERE VARIABLE_NAME='enforce_storage_engine'; +@@session.enforce_storage_engine = +VARIABLE_VALUE +1 +SET @@session.enforce_storage_engine = TRUE; +ERROR 42000: Incorrect argument type to variable 'enforce_storage_engine' +SET @@session.enforce_storage_engine = FALSE; +ERROR 42000: Incorrect argument type to variable 'enforce_storage_engine' +SET @@session.enforce_storage_engine = @start_session_value; diff --git a/mysql-test/suite/sys_vars/r/innodb_instrument_semaphores_basic.result b/mysql-test/suite/sys_vars/r/innodb_instrument_semaphores_basic.result new file mode 100644 index 00000000000..dc8fba41e0b --- /dev/null +++ b/mysql-test/suite/sys_vars/r/innodb_instrument_semaphores_basic.result @@ -0,0 +1,45 @@ +# +# innodb_instrument_semaphores +# +# save the initial value +SET @innodb_instrument_semaphores_global_saved = @@global.innodb_instrument_semaphores; +# default +SELECT @@global.innodb_instrument_semaphores; +@@global.innodb_instrument_semaphores +0 + +# scope +SELECT @@session.innodb_instrument_semaphores; +ERROR HY000: Variable 'innodb_instrument_semaphores' is a GLOBAL variable +SET @@global.innodb_instrument_semaphores=OFF; +SELECT @@global.innodb_instrument_semaphores; +@@global.innodb_instrument_semaphores +0 +SET @@global.innodb_instrument_semaphores=ON; +SELECT @@global.innodb_instrument_semaphores; +@@global.innodb_instrument_semaphores +1 + +# valid values +SET @@global.innodb_instrument_semaphores='OFF'; +SELECT @@global.innodb_instrument_semaphores; +@@global.innodb_instrument_semaphores +0 +SET @@global.innodb_instrument_semaphores=ON; +SELECT @@global.innodb_instrument_semaphores; +@@global.innodb_instrument_semaphores +1 +SET @@global.innodb_instrument_semaphores=default; +SELECT @@global.innodb_instrument_semaphores; +@@global.innodb_instrument_semaphores +0 + +# invalid values +SET @@global.innodb_instrument_semaphores=NULL; +ERROR 42000: Variable 'innodb_instrument_semaphores' can't be set to the value of 'NULL' +SET @@global.innodb_instrument_semaphores='junk'; +ERROR 42000: Variable 'innodb_instrument_semaphores' can't be set to the value of 'junk' + +# restore the initial value +SET @@global.innodb_instrument_semaphores = @innodb_instrument_semaphores_global_saved; +# End of test diff --git a/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result b/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result index 83c0196f789..bf8f8687133 100644 --- a/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result +++ b/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result @@ -721,6 +721,20 @@ NUMERIC_BLOCK_SIZE NULL ENUM_VALUE_LIST OFF,ON READ_ONLY NO COMMAND_LINE_ARGUMENT OPTIONAL +VARIABLE_NAME ENFORCE_STORAGE_ENGINE +SESSION_VALUE +GLOBAL_VALUE NULL +GLOBAL_VALUE_ORIGIN COMPILE-TIME +DEFAULT_VALUE NULL +VARIABLE_SCOPE SESSION ONLY +VARIABLE_TYPE VARCHAR +VARIABLE_COMMENT Force the use of a storage engine for new tables +NUMERIC_MIN_VALUE NULL +NUMERIC_MAX_VALUE NULL +NUMERIC_BLOCK_SIZE NULL +ENUM_VALUE_LIST NULL +READ_ONLY NO +COMMAND_LINE_ARGUMENT NULL VARIABLE_NAME ERROR_COUNT SESSION_VALUE 0 GLOBAL_VALUE NULL diff --git a/mysql-test/suite/sys_vars/t/enforce_storage_engine_basic.test b/mysql-test/suite/sys_vars/t/enforce_storage_engine_basic.test new file mode 100644 index 00000000000..62627a1e5ca --- /dev/null +++ b/mysql-test/suite/sys_vars/t/enforce_storage_engine_basic.test @@ -0,0 +1,40 @@ +--source include/not_embedded.inc +--source include/have_innodb.inc +--source include/load_sysvars.inc + +SET @start_session_value = @@session.enforce_storage_engine; + +SET @@session.enforce_storage_engine = INNODB; +SET @@session.enforce_storage_engine = DEFAULT; + +SELECT @@session.enforce_storage_engine; + +SET @@session.enforce_storage_engine = MYISAM; +SELECT @@session.enforce_storage_engine; +SET @@session.enforce_storage_engine = MERGE; +SELECT @@session.enforce_storage_engine; +SET @@session.enforce_storage_engine = MEMORY; +SELECT @@session.enforce_storage_engine; +SET @@session.enforce_storage_engine = INNODB; +SELECT @@session.enforce_storage_engine; + +--Error ER_WRONG_TYPE_FOR_VAR +SET @@session.enforce_storage_engine = 8199; + +--Error ER_WRONG_TYPE_FOR_VAR +SET @@session.enforce_storage_engine = 65530.34; + +--Error ER_UNKNOWN_STORAGE_ENGINE +SET @@session.enforce_storage_engine = RECORD; + +SELECT @@session.enforce_storage_engine = + VARIABLE_VALUE FROM INFORMATION_SCHEMA.SESSION_VARIABLES + WHERE VARIABLE_NAME='enforce_storage_engine'; + +--Error ER_WRONG_TYPE_FOR_VAR +SET @@session.enforce_storage_engine = TRUE; + +--Error ER_WRONG_TYPE_FOR_VAR +SET @@session.enforce_storage_engine = FALSE; + +SET @@session.enforce_storage_engine = @start_session_value; diff --git a/mysql-test/suite/sys_vars/t/innodb_instrument_semaphores.test b/mysql-test/suite/sys_vars/t/innodb_instrument_semaphores_basic.test index 9b302be79b5..9b302be79b5 100644 --- a/mysql-test/suite/sys_vars/t/innodb_instrument_semaphores.test +++ b/mysql-test/suite/sys_vars/t/innodb_instrument_semaphores_basic.test diff --git a/mysql-test/t/enforce_storage_engine.test b/mysql-test/t/enforce_storage_engine.test new file mode 100644 index 00000000000..83deac07fe0 --- /dev/null +++ b/mysql-test/t/enforce_storage_engine.test @@ -0,0 +1,73 @@ +-- source include/not_embedded.inc + +--disable_warnings +drop table if exists t1; +--enable_warnings + +SET SESSION enforce_storage_engine=MyISAM; +select @@session.enforce_storage_engine; +CREATE TABLE t1 (c1 INT PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=Memory; +SHOW CREATE TABLE t1; +DROP TABLE t1; + +CREATE TABLE t1 (c1 INT PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=MyISAM; +SHOW CREATE TABLE t1; +DROP TABLE t1; + +CREATE TABLE t1 (c1 INT PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)); +SHOW CREATE TABLE t1; +DROP TABLE t1; + +SET SESSION sql_mode='NO_ENGINE_SUBSTITUTION'; +CREATE TABLE t1 (c1 INT PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=MyISAM; +SHOW CREATE TABLE t1; +INSERT INTO t1 values (1,'abba'); + +--error 1286 +CREATE TABLE t2 (c1 INT PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=Memory; + +SET SESSION sql_mode=''; + +SET SESSION enforce_storage_engine=MyISAM; +select @@session.enforce_storage_engine; +select * from t1; +drop table t1; + +CREATE TABLE t1 (c1 INT PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)); +SHOW CREATE TABLE t1; +DROP TABLE t1; + +--error 1286 +SET SESSION enforce_storage_engine=FooBar; + +select @@session.enforce_storage_engine; + +--source include/add_anonymous_users.inc + +connect (con1,localhost,user_1,,); +connection con1; +--error 1227 +SET SESSION enforce_storage_engine=MyISAM; +disconnect con1; + +connection default; + +--source include/delete_anonymous_users.inc + +SET SESSION enforce_storage_engine=NULL; + +SET SESSION sql_mode='NO_ENGINE_SUBSTITUTION'; +CREATE TABLE t1 (c1 INT PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=Memory; +SHOW CREATE TABLE t1; +DROP TABLE t1; + +CREATE TABLE t1 (c1 INT PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=MyISAM; +SHOW CREATE TABLE t1; +DROP TABLE t1; + +CREATE TABLE t1 (c1 INT PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)); +SHOW CREATE TABLE t1; +DROP TABLE t1; + +--error 1228 +SET GLOBAL enforce_storage_engine=NULL; diff --git a/sql/handler.cc b/sql/handler.cc index 12d7ffb2f5e..d64c14689bd 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -117,6 +117,7 @@ static plugin_ref ha_default_tmp_plugin(THD *thd) return ha_default_plugin(thd); } + /** @brief Return the default storage engine handlerton for thread diff --git a/sql/mysqld.cc b/sql/mysqld.cc index b97742d01ee..aa85a023228 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -369,6 +369,7 @@ static char *lc_time_names_name; char *my_bind_addr_str; static char *default_collation_name; char *default_storage_engine, *default_tmp_storage_engine; +char *enforced_storage_engine=NULL; static char compiled_default_collation_name[]= MYSQL_DEFAULT_COLLATION_NAME; static I_List<THD> thread_cache; static bool binlog_format_used= false; @@ -5144,6 +5145,9 @@ a file name for --log-bin-index option", opt_binlog_index_name); if (init_default_storage_engine(default_tmp_storage_engine, tmp_table_plugin)) unireg_abort(1); + if (init_default_storage_engine(enforced_storage_engine, enforced_table_plugin)) + unireg_abort(1); + #ifdef USE_ARIA_FOR_TMP_TABLES if (!ha_storage_engine_is_enabled(maria_hton) && !opt_bootstrap) { @@ -7156,6 +7160,9 @@ struct my_option my_long_options[]= {"stack-trace", 0 , "Print a symbolic stack trace on failure", &opt_stack_trace, &opt_stack_trace, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, #endif /* HAVE_STACKTRACE */ + {"enforce-storage-engine", 0, "Force the use of a storage engine for new tables", + &enforced_storage_engine, 0, 0, GET_STR, REQUIRED_ARG, + 0, 0, 0, 0, 0, 0 }, {"external-locking", 0, "Use system (external) locking (disabled by " "default). With this option enabled you can run myisamchk to test " "(not repair) tables while the MySQL server is running. Disable with " diff --git a/sql/mysqld.h b/sql/mysqld.h index bfce719a280..b0b31856e52 100644 --- a/sql/mysqld.h +++ b/sql/mysqld.h @@ -138,6 +138,7 @@ extern ulong opt_replicate_events_marked_for_skip; extern char *default_tz_name; extern Time_zone *default_tz; extern char *default_storage_engine, *default_tmp_storage_engine; +extern char *enforced_storage_engine; extern bool opt_endinfo, using_udf_functions; extern my_bool locked_in_memory; extern bool opt_using_transactions; diff --git a/sql/sql_class.h b/sql/sql_class.h index dd5b623a8d2..a39ba782662 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -618,6 +618,7 @@ typedef struct system_variables plugin_ref table_plugin; plugin_ref tmp_table_plugin; + plugin_ref enforced_table_plugin; /* Only charset part of these variables is sensible */ CHARSET_INFO *character_set_filesystem; diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index 2fe22ea5d43..fe020d36f93 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -3089,11 +3089,13 @@ void plugin_thdvar_init(THD *thd) { plugin_ref old_table_plugin= thd->variables.table_plugin; plugin_ref old_tmp_table_plugin= thd->variables.tmp_table_plugin; + plugin_ref old_enforced_table_plugin= thd->variables.enforced_table_plugin; DBUG_ENTER("plugin_thdvar_init"); // This function may be called many times per THD (e.g. on COM_CHANGE_USER) thd->variables.table_plugin= NULL; thd->variables.tmp_table_plugin= NULL; + thd->variables.enforced_table_plugin= NULL; cleanup_variables(&thd->variables); thd->variables= global_system_variables; @@ -3113,12 +3115,14 @@ void plugin_thdvar_init(THD *thd) intern_plugin_lock(NULL, global_system_variables.tmp_table_plugin); intern_plugin_unlock(NULL, old_table_plugin); intern_plugin_unlock(NULL, old_tmp_table_plugin); + intern_plugin_unlock(NULL, old_enforced_table_plugin); mysql_mutex_unlock(&LOCK_plugin); } else { thd->variables.table_plugin= NULL; thd->variables.tmp_table_plugin= NULL; + thd->variables.enforced_table_plugin= NULL; } DBUG_VOID_RETURN; @@ -3132,7 +3136,8 @@ static void unlock_variables(THD *thd, struct system_variables *vars) { intern_plugin_unlock(NULL, vars->table_plugin); intern_plugin_unlock(NULL, vars->tmp_table_plugin); - vars->table_plugin= vars->tmp_table_plugin= NULL; + intern_plugin_unlock(NULL, vars->enforced_table_plugin); + vars->table_plugin= vars->tmp_table_plugin= vars->enforced_table_plugin= NULL; } @@ -3170,6 +3175,7 @@ static void cleanup_variables(struct system_variables *vars) DBUG_ASSERT(vars->table_plugin == NULL); DBUG_ASSERT(vars->tmp_table_plugin == NULL); + DBUG_ASSERT(vars->enforced_table_plugin == NULL); my_free(vars->dynamic_variables_ptr); vars->dynamic_variables_ptr= NULL; diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 4eace56eb13..898f70448ea 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -9745,12 +9745,24 @@ static bool check_engine(THD *thd, const char *db_name, DBUG_ENTER("check_engine"); handlerton **new_engine= &create_info->db_type; handlerton *req_engine= *new_engine; + handlerton *enf_engine= thd->variables.enforced_table_plugin ? plugin_hton(thd->variables.enforced_table_plugin) : NULL; bool no_substitution= thd->variables.sql_mode & MODE_NO_ENGINE_SUBSTITUTION; *new_engine= ha_checktype(thd, req_engine, no_substitution); DBUG_ASSERT(*new_engine); if (!*new_engine) DBUG_RETURN(true); + if (enf_engine && enf_engine != *new_engine) + { + if (no_substitution) + { + const char *engine_name= ha_resolve_storage_engine_name(req_engine); + my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0), engine_name, engine_name); + DBUG_RETURN(TRUE); + } + *new_engine= enf_engine; + } + if (req_engine && req_engine != *new_engine) { push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE, diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index a65e9ba3f1b..07875be91aa 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -3439,6 +3439,12 @@ static Sys_var_plugin Sys_default_tmp_storage_engine( SESSION_VAR(tmp_table_plugin), NO_CMD_LINE, MYSQL_STORAGE_ENGINE_PLUGIN, DEFAULT(&default_tmp_storage_engine)); +static Sys_var_plugin Sys_enforce_storage_engine( + "enforce_storage_engine", "Force the use of a storage engine for new tables", + SESSION_ONLY(enforced_table_plugin), + NO_CMD_LINE, MYSQL_STORAGE_ENGINE_PLUGIN, + DEFAULT(&enforced_storage_engine), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_has_super)); + #if defined(ENABLED_DEBUG_SYNC) /* Variable can be set for the session only. |