Skip to content

Commit

Permalink
MDEV-6858: enforce_storage_engine option
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
Jan Lindström committed Mar 12, 2015
1 parent ba3573c commit 8249dca
Show file tree
Hide file tree
Showing 16 changed files with 351 additions and 2 deletions.
102 changes: 102 additions & 0 deletions mysql-test/r/enforce_storage_engine.result
Original file line number Diff line number Diff line change
@@ -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
3 changes: 3 additions & 0 deletions mysql-test/r/mysqld--help.result
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
1 change: 0 additions & 1 deletion mysql-test/suite/sys_vars/r/all_vars.result
Original file line number Diff line number Diff line change
Expand Up @@ -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;
39 changes: 39 additions & 0 deletions mysql-test/suite/sys_vars/r/enforce_storage_engine_basic.result
Original file line number Diff line number Diff line change
@@ -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;
Original file line number Diff line number Diff line change
@@ -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
14 changes: 14 additions & 0 deletions mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
40 changes: 40 additions & 0 deletions mysql-test/suite/sys_vars/t/enforce_storage_engine_basic.test
Original file line number Diff line number Diff line change
@@ -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;
73 changes: 73 additions & 0 deletions mysql-test/t/enforce_storage_engine.test
Original file line number Diff line number Diff line change
@@ -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;
1 change: 1 addition & 0 deletions sql/handler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
7 changes: 7 additions & 0 deletions sql/mysqld.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -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 "
Expand Down
1 change: 1 addition & 0 deletions sql/mysqld.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Loading

0 comments on commit 8249dca

Please sign in to comment.