summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Lindström <jan.lindstrom@mariadb.com>2015-03-10 08:28:51 +0200
committerJan Lindström <jan.lindstrom@mariadb.com>2015-03-12 12:17:14 +0200
commit8249dcaaebf8cd1944bd4ab7ccaa8b199e76d6f9 (patch)
tree66a9b1c65f0f220e305681fa41811886fa05d908
parentba3573cae8f0d269452cc6213f1a8243e455830e (diff)
downloadmariadb-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.result102
-rw-r--r--mysql-test/r/mysqld--help.result3
-rw-r--r--mysql-test/suite/sys_vars/r/all_vars.result1
-rw-r--r--mysql-test/suite/sys_vars/r/enforce_storage_engine_basic.result39
-rw-r--r--mysql-test/suite/sys_vars/r/innodb_instrument_semaphores_basic.result45
-rw-r--r--mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result14
-rw-r--r--mysql-test/suite/sys_vars/t/enforce_storage_engine_basic.test40
-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.test73
-rw-r--r--sql/handler.cc1
-rw-r--r--sql/mysqld.cc7
-rw-r--r--sql/mysqld.h1
-rw-r--r--sql/sql_class.h1
-rw-r--r--sql/sql_plugin.cc8
-rw-r--r--sql/sql_table.cc12
-rw-r--r--sql/sys_vars.cc6
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.