Skip to content

Commit 9b577ed

Browse files
author
Jan Lindström
committed
MDEV-8577: With enforce-storage-engine mysql_upgrade corrupts the schema:
ALTER TABLE should either bypass enforce-storage-engine, or mysql_upgrade should refuse to run Allow user to alter contents of existing table without enforcing storage engine. However, enforce storage engine on ALTER TABLE x ENGINE=y;
1 parent 1e9ab68 commit 9b577ed

File tree

5 files changed

+144
-2
lines changed

5 files changed

+144
-2
lines changed

mysql-test/r/enforce_storage_engine.result

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,3 +122,33 @@ DROP TABLE t1;
122122
set global sql_mode=default;
123123
SET SESSION enforce_storage_engine=NULL;
124124
SET GLOBAL enforce_storage_engine=NULL;
125+
CREATE TABLE t3 (c1 INT PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=MyISAM;
126+
INSERT INTO t3 values (NULL, 'test');
127+
SET SESSION enforce_storage_engine=Memory;
128+
ALTER TABLE t3 ENGINE=MyISAM;
129+
Warnings:
130+
Note 1266 Using storage engine MEMORY for table 't3'
131+
SHOW CREATE TABLE t3;
132+
Table Create Table
133+
t3 CREATE TABLE `t3` (
134+
`c1` int(11) NOT NULL AUTO_INCREMENT,
135+
`c2` varchar(10) DEFAULT NULL,
136+
PRIMARY KEY (`c1`)
137+
) ENGINE=MEMORY AUTO_INCREMENT=2 DEFAULT CHARSET=latin1
138+
DROP TABLE t3;
139+
SET SESSION enforce_storage_engine=NULL;
140+
CREATE TABLE t3 (c1 INT PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=MyISAM;
141+
INSERT INTO t3 values (NULL, 'test');
142+
SET SESSION enforce_storage_engine=Memory;
143+
ALTER TABLE t3 ADD COLUMN c3 INT;
144+
SHOW CREATE TABLE t3;
145+
Table Create Table
146+
t3 CREATE TABLE `t3` (
147+
`c1` int(11) NOT NULL AUTO_INCREMENT,
148+
`c2` varchar(10) DEFAULT NULL,
149+
`c3` int(11) DEFAULT NULL,
150+
PRIMARY KEY (`c1`)
151+
) ENGINE=MyISAM AUTO_INCREMENT=2 DEFAULT CHARSET=latin1
152+
DROP TABLE t3;
153+
SET SESSION enforce_storage_engine=NULL;
154+
SET GLOBAL enforce_storage_engine=NULL;

mysql-test/r/mysql_upgrade.result

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -459,4 +459,64 @@ even_longer_user_name_number_3_to_test_the_grantor_and_definer_field_length@loca
459459
DROP USER very_long_user_name_number_1, very_long_user_name_number_2, even_longer_user_name_number_3_to_test_the_grantor_and_definer_field_length@localhost;
460460
DROP PROCEDURE test.pr;
461461
set sql_mode=default;
462+
# Droping the previously created mysql_upgrade_info file..
463+
create table test.t1(a int) engine=MyISAM;
464+
# Trying to enforce InnoDB for all tables
465+
SET GLOBAL enforce_storage_engine=InnoDB;
466+
Phase 1/6: Checking and upgrading mysql database
467+
Processing databases
468+
mysql
469+
mysql.column_stats OK
470+
mysql.columns_priv OK
471+
mysql.db OK
472+
mysql.event OK
473+
mysql.func OK
474+
mysql.gtid_slave_pos OK
475+
mysql.help_category OK
476+
mysql.help_keyword OK
477+
mysql.help_relation OK
478+
mysql.help_topic OK
479+
mysql.host OK
480+
mysql.index_stats OK
481+
mysql.innodb_index_stats OK
482+
mysql.innodb_table_stats OK
483+
mysql.plugin OK
484+
mysql.proc OK
485+
mysql.procs_priv OK
486+
mysql.proxies_priv OK
487+
mysql.roles_mapping OK
488+
mysql.servers OK
489+
mysql.table_stats OK
490+
mysql.tables_priv OK
491+
mysql.time_zone OK
492+
mysql.time_zone_leap_second OK
493+
mysql.time_zone_name OK
494+
mysql.time_zone_transition OK
495+
mysql.time_zone_transition_type OK
496+
mysql.user OK
497+
Phase 2/6: Fixing views
498+
Phase 3/6: Running 'mysql_fix_privilege_tables'
499+
Phase 4/6: Fixing table and database names
500+
Phase 5/6: Checking and upgrading tables
501+
Processing databases
502+
information_schema
503+
mtr
504+
mtr.global_suppressions OK
505+
mtr.test_suppressions OK
506+
performance_schema
507+
test
508+
test.t1 OK
509+
Phase 6/6: Running 'FLUSH PRIVILEGES'
510+
OK
511+
# Should return 2
512+
SELECT count(*) FROM information_schema.tables where ENGINE="InnoDB";
513+
count(*)
514+
2
515+
SHOW CREATE TABLE test.t1;
516+
Table Create Table
517+
t1 CREATE TABLE `t1` (
518+
`a` int(11) DEFAULT NULL
519+
) ENGINE=MyISAM DEFAULT CHARSET=latin1
520+
DROP TABLE test.t1;
521+
SET GLOBAL enforce_storage_engine=NULL;
462522
End of tests

mysql-test/t/enforce_storage_engine.test

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,3 +87,25 @@ disconnect con1;
8787
set global sql_mode=default;
8888
SET SESSION enforce_storage_engine=NULL;
8989
SET GLOBAL enforce_storage_engine=NULL;
90+
91+
#
92+
# MDEV-8577: With enforce-storage-engine mysql_upgrade corrupts the schema:
93+
# ALTER TABLE should either bypass enforce-storage-engine, or mysql_upgrade
94+
# should refuse to run
95+
#
96+
CREATE TABLE t3 (c1 INT PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=MyISAM;
97+
INSERT INTO t3 values (NULL, 'test');
98+
SET SESSION enforce_storage_engine=Memory;
99+
ALTER TABLE t3 ENGINE=MyISAM;
100+
SHOW CREATE TABLE t3;
101+
DROP TABLE t3;
102+
SET SESSION enforce_storage_engine=NULL;
103+
CREATE TABLE t3 (c1 INT PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=MyISAM;
104+
INSERT INTO t3 values (NULL, 'test');
105+
SET SESSION enforce_storage_engine=Memory;
106+
ALTER TABLE t3 ADD COLUMN c3 INT;
107+
SHOW CREATE TABLE t3;
108+
DROP TABLE t3;
109+
110+
SET SESSION enforce_storage_engine=NULL;
111+
SET GLOBAL enforce_storage_engine=NULL;

mysql-test/t/mysql_upgrade.test

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,4 +161,27 @@ DROP USER very_long_user_name_number_1, very_long_user_name_number_2, even_longe
161161
DROP PROCEDURE test.pr;
162162

163163
set sql_mode=default;
164+
165+
#
166+
# Enforce storage engine option should not effect mysql_upgrade
167+
#
168+
--echo # Droping the previously created mysql_upgrade_info file..
169+
--remove_file $MYSQLD_DATADIR/mysql_upgrade_info
170+
171+
create table test.t1(a int) engine=MyISAM;
172+
--echo # Trying to enforce InnoDB for all tables
173+
SET GLOBAL enforce_storage_engine=InnoDB;
174+
175+
--replace_result $MYSQLTEST_VARDIR var
176+
--exec $MYSQL_UPGRADE --force 2>&1
177+
178+
--echo # Should return 2
179+
SELECT count(*) FROM information_schema.tables where ENGINE="InnoDB";
180+
SHOW CREATE TABLE test.t1;
181+
DROP TABLE test.t1;
182+
# mysql_upgrade must have created mysql_upgrade_info file,
183+
# so the following command should never fail.
184+
--remove_file $MYSQLD_DATADIR/mysql_upgrade_info
185+
SET GLOBAL enforce_storage_engine=NULL;
186+
164187
--echo End of tests

sql/sql_table.cc

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9818,14 +9818,21 @@ static bool check_engine(THD *thd, const char *db_name,
98189818
DBUG_ENTER("check_engine");
98199819
handlerton **new_engine= &create_info->db_type;
98209820
handlerton *req_engine= *new_engine;
9821-
handlerton *enf_engine= thd->variables.enforced_table_plugin ?
9822-
plugin_hton(thd->variables.enforced_table_plugin) : NULL;
9821+
handlerton *enf_engine= NULL;
98239822
bool no_substitution= thd->variables.sql_mode & MODE_NO_ENGINE_SUBSTITUTION;
98249823
*new_engine= ha_checktype(thd, req_engine, no_substitution);
98259824
DBUG_ASSERT(*new_engine);
98269825
if (!*new_engine)
98279826
DBUG_RETURN(true);
98289827

9828+
/* Enforced storage engine should not be used in
9829+
ALTER TABLE that does not use explicit ENGINE = x to
9830+
avoid unwanted unrelated changes.*/
9831+
if (!(thd->lex->sql_command == SQLCOM_ALTER_TABLE &&
9832+
!(create_info->used_fields & HA_CREATE_USED_ENGINE)))
9833+
enf_engine= thd->variables.enforced_table_plugin ?
9834+
plugin_hton(thd->variables.enforced_table_plugin) : NULL;
9835+
98299836
if (enf_engine && enf_engine != *new_engine)
98309837
{
98319838
if (no_substitution)

0 commit comments

Comments
 (0)