Browse Source
MDEV-20051: Add new mode to wsrep_OSU_method in which Galera checks storage engine of the effected table
MDEV-20051: Add new mode to wsrep_OSU_method in which Galera checks storage engine of the effected table
Introduced a new wsrep_strict_ddl configuration variable in which
Galera checks storage engine of the effected table. If table is not
InnoDB (only storage engine currently fully supporting Galera
replication) DDL-statement will return error code:
ER_GALERA_REPLICATION_NOT_SUPPORTED
eng "DDL-statement is forbidden as table storage engine does not support Galera replication"
However, when wsrep_replicate_myisam=ON we allow DDL-statements to
MyISAM tables. If effected table is allowed storage engine Galera
will run normal TOI.
This new setting should be for now set globally on all
nodes in a cluster. When this setting is set following DDL-clauses
accessing tables not supporting Galera replication are refused:
* CREATE TABLE (e.g. CREATE TABLE t1(a int) engine=Aria
* ALTER TABLE
* TRUNCATE TABLE
* CREATE VIEW
* CREATE TRIGGER
* CREATE INDEX
* DROP INDEX
* RENAME TABLE
* DROP TABLE
Statements on PROCEDURE, EVENT, FUNCTION are allowed as effected
tables are known only at execution. Furthermore, USER, ROLE, SERVER,
DATABASE statements are also allowed as they do not really have
effected table.
pull/1445/head
21 changed files with 690 additions and 87 deletions
-
6include/mysql/service_wsrep.h
-
21include/wsrep.h
-
194mysql-test/suite/galera/r/wsrep_strict_ddl.result
-
133mysql-test/suite/galera/t/wsrep_strict_ddl.test
-
15mysql-test/suite/sys_vars/r/sysvars_wsrep.result
-
45mysql-test/suite/sys_vars/r/wsrep_strict_ddl_basic.result
-
42mysql-test/suite/sys_vars/t/wsrep_strict_ddl_basic.test
-
23sql/service_wsrep.cc
-
2sql/share/errmsg-utf8.txt
-
6sql/sql_alter.cc
-
39sql/sql_parse.cc
-
1sql/sql_plugin_services.ic
-
7sql/sql_rename.cc
-
24sql/sql_table.cc
-
8sql/sql_trigger.cc
-
20sql/sql_truncate.cc
-
9sql/sql_view.cc
-
10sql/sys_vars.cc
-
2sql/wsrep_dummy.cc
-
159sql/wsrep_mysqld.cc
-
11sql/wsrep_mysqld.h
@ -0,0 +1,194 @@ |
|||
connection node_2; |
|||
connection node_1; |
|||
call mtr.add_suppression("WSREP: ALTER TABLE isolation failure"); |
|||
connection node_1; |
|||
SET GLOBAL binlog_format='ROW'; |
|||
create table before_t1(a int, count int, b int, key(b)) engine=Aria; |
|||
INSERT INTO before_t1 values (1,1,1); |
|||
set @@global.wsrep_strict_ddl=ON; |
|||
select @@global.wsrep_strict_ddl; |
|||
@@global.wsrep_strict_ddl |
|||
1 |
|||
connection node_2; |
|||
set @@global.wsrep_strict_ddl=ON; |
|||
select @@global.wsrep_strict_ddl; |
|||
@@global.wsrep_strict_ddl |
|||
1 |
|||
connection node_1; |
|||
CREATE TABLE t1(a int) engine=Aria; |
|||
ERROR HY000: DDL-statement is forbidden as table storage engine does not support Galera replication |
|||
SHOW WARNINGS; |
|||
Level Code Message |
|||
Error 4165 DDL-statement is forbidden as table storage engine does not support Galera replication |
|||
Warning 1031 WSREP: wsrep_strict_ddl=true and storage engine does not support Galera replication. |
|||
connection node_2; |
|||
SHOW CREATE TABLE t1; |
|||
ERROR 42S02: Table 'test.t1' doesn't exist |
|||
connection node_1; |
|||
CREATE TABLE t2(a int not null primary key) engine=InnoDB; |
|||
ALTER TABLE t2 engine=MyISAM; |
|||
ERROR HY000: DDL-statement is forbidden as table storage engine does not support Galera replication |
|||
SHOW WARNINGS; |
|||
Level Code Message |
|||
Error 4165 DDL-statement is forbidden as table storage engine does not support Galera replication |
|||
Warning 1031 WSREP: wsrep_strict_ddl=true and storage engine does not support Galera replication. |
|||
SHOW CREATE TABLE t2; |
|||
Table Create Table |
|||
t2 CREATE TABLE `t2` ( |
|||
`a` int(11) NOT NULL, |
|||
PRIMARY KEY (`a`) |
|||
) ENGINE=InnoDB DEFAULT CHARSET=latin1 |
|||
connection node_2; |
|||
SHOW CREATE TABLE t2; |
|||
Table Create Table |
|||
t2 CREATE TABLE `t2` ( |
|||
`a` int(11) NOT NULL, |
|||
PRIMARY KEY (`a`) |
|||
) ENGINE=InnoDB DEFAULT CHARSET=latin1 |
|||
connection node_1; |
|||
TRUNCATE TABLE before_t1; |
|||
ERROR HY000: DDL-statement is forbidden as table storage engine does not support Galera replication |
|||
SELECT * FROM before_t1; |
|||
a count b |
|||
1 1 1 |
|||
connection node_2; |
|||
SET SESSION wsrep_sync_wait=15; |
|||
SELECT @@wsrep_sync_wait; |
|||
@@wsrep_sync_wait |
|||
15 |
|||
SELECT * FROM before_t1; |
|||
a count b |
|||
connection node_1; |
|||
CREATE VIEW x1 AS SELECT * FROM before_t1; |
|||
ERROR HY000: DDL-statement is forbidden as table storage engine does not support Galera replication |
|||
SHOW CREATE VIEW x1; |
|||
ERROR 42S02: Table 'test.x1' doesn't exist |
|||
connection node_2; |
|||
SHOW CREATE VIEW x1; |
|||
ERROR 42S02: Table 'test.x1' doesn't exist |
|||
connection node_1; |
|||
CREATE DEFINER=`root`@`localhost` TRIGGER increment_before_t1 |
|||
AFTER INSERT ON before_t1 FOR EACH ROW |
|||
UPDATE before_t1 SET before_t1.count = before_t1.count+1; |
|||
ERROR HY000: DDL-statement is forbidden as table storage engine does not support Galera replication |
|||
SHOW CREATE TRIGGER increment_before_t1; |
|||
ERROR HY000: Trigger does not exist |
|||
connection node_2; |
|||
SHOW CREATE TRIGGER increment_before_t1; |
|||
ERROR HY000: Trigger does not exist |
|||
connection node_1; |
|||
CREATE INDEX xx2 ON before_t1(a); |
|||
ERROR HY000: DDL-statement is forbidden as table storage engine does not support Galera replication |
|||
SHOW CREATE TABLE before_t1; |
|||
Table Create Table |
|||
before_t1 CREATE TABLE `before_t1` ( |
|||
`a` int(11) DEFAULT NULL, |
|||
`count` int(11) DEFAULT NULL, |
|||
`b` int(11) DEFAULT NULL, |
|||
KEY `b` (`b`) |
|||
) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 |
|||
connection node_2; |
|||
SHOW CREATE TABLE before_t1; |
|||
Table Create Table |
|||
before_t1 CREATE TABLE `before_t1` ( |
|||
`a` int(11) DEFAULT NULL, |
|||
`count` int(11) DEFAULT NULL, |
|||
`b` int(11) DEFAULT NULL, |
|||
KEY `b` (`b`) |
|||
) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 |
|||
connection node_1; |
|||
DROP INDEX b ON before_t1; |
|||
ERROR HY000: DDL-statement is forbidden as table storage engine does not support Galera replication |
|||
SHOW CREATE TABLE before_t1; |
|||
Table Create Table |
|||
before_t1 CREATE TABLE `before_t1` ( |
|||
`a` int(11) DEFAULT NULL, |
|||
`count` int(11) DEFAULT NULL, |
|||
`b` int(11) DEFAULT NULL, |
|||
KEY `b` (`b`) |
|||
) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 |
|||
connection node_2; |
|||
SHOW CREATE TABLE before_t1; |
|||
Table Create Table |
|||
before_t1 CREATE TABLE `before_t1` ( |
|||
`a` int(11) DEFAULT NULL, |
|||
`count` int(11) DEFAULT NULL, |
|||
`b` int(11) DEFAULT NULL, |
|||
KEY `b` (`b`) |
|||
) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 |
|||
connection node_1; |
|||
ALTER TABLE before_t1 ADD COLUMN f int; |
|||
ERROR HY000: DDL-statement is forbidden as table storage engine does not support Galera replication |
|||
SHOW CREATE TABLE before_t1; |
|||
Table Create Table |
|||
before_t1 CREATE TABLE `before_t1` ( |
|||
`a` int(11) DEFAULT NULL, |
|||
`count` int(11) DEFAULT NULL, |
|||
`b` int(11) DEFAULT NULL, |
|||
KEY `b` (`b`) |
|||
) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 |
|||
connection node_2; |
|||
SHOW CREATE TABLE before_t1; |
|||
Table Create Table |
|||
before_t1 CREATE TABLE `before_t1` ( |
|||
`a` int(11) DEFAULT NULL, |
|||
`count` int(11) DEFAULT NULL, |
|||
`b` int(11) DEFAULT NULL, |
|||
KEY `b` (`b`) |
|||
) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 |
|||
connection node_1; |
|||
RENAME TABLE before_t1 to after_t1; |
|||
ERROR HY000: DDL-statement is forbidden as table storage engine does not support Galera replication |
|||
SHOW CREATE TABLE before_t1; |
|||
Table Create Table |
|||
before_t1 CREATE TABLE `before_t1` ( |
|||
`a` int(11) DEFAULT NULL, |
|||
`count` int(11) DEFAULT NULL, |
|||
`b` int(11) DEFAULT NULL, |
|||
KEY `b` (`b`) |
|||
) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 |
|||
SHOW CREATE TABLE after_t1; |
|||
ERROR 42S02: Table 'test.after_t1' doesn't exist |
|||
connection node_2; |
|||
SHOW CREATE TABLE before_t1; |
|||
Table Create Table |
|||
before_t1 CREATE TABLE `before_t1` ( |
|||
`a` int(11) DEFAULT NULL, |
|||
`count` int(11) DEFAULT NULL, |
|||
`b` int(11) DEFAULT NULL, |
|||
KEY `b` (`b`) |
|||
) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 |
|||
SHOW CREATE TABLE after_t1; |
|||
ERROR 42S02: Table 'test.after_t1' doesn't exist |
|||
connection node_1; |
|||
DROP TABLE before_t1; |
|||
ERROR HY000: DDL-statement is forbidden as table storage engine does not support Galera replication |
|||
SHOW CREATE TABLE before_t1; |
|||
Table Create Table |
|||
before_t1 CREATE TABLE `before_t1` ( |
|||
`a` int(11) DEFAULT NULL, |
|||
`count` int(11) DEFAULT NULL, |
|||
`b` int(11) DEFAULT NULL, |
|||
KEY `b` (`b`) |
|||
) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 |
|||
connection node_2; |
|||
SHOW CREATE TABLE before_t1; |
|||
Table Create Table |
|||
before_t1 CREATE TABLE `before_t1` ( |
|||
`a` int(11) DEFAULT NULL, |
|||
`count` int(11) DEFAULT NULL, |
|||
`b` int(11) DEFAULT NULL, |
|||
KEY `b` (`b`) |
|||
) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 |
|||
connection node_1; |
|||
set @@global.wsrep_strict_ddl=OFF; |
|||
select @@global.wsrep_strict_ddl; |
|||
@@global.wsrep_strict_ddl |
|||
0 |
|||
connection node_2; |
|||
set @@global.wsrep_strict_ddl=OFF; |
|||
select @@global.wsrep_strict_ddl; |
|||
@@global.wsrep_strict_ddl |
|||
0 |
|||
DROP TABLE t2; |
|||
DROP TABLE before_t1; |
|||
@ -0,0 +1,133 @@ |
|||
--source include/galera_cluster.inc |
|||
|
|||
call mtr.add_suppression("WSREP: ALTER TABLE isolation failure"); |
|||
|
|||
--connection node_1 |
|||
SET GLOBAL binlog_format='ROW'; |
|||
create table before_t1(a int, count int, b int, key(b)) engine=Aria; |
|||
INSERT INTO before_t1 values (1,1,1); |
|||
|
|||
set @@global.wsrep_strict_ddl=ON; |
|||
select @@global.wsrep_strict_ddl; |
|||
|
|||
--connection node_2 |
|||
set @@global.wsrep_strict_ddl=ON; |
|||
select @@global.wsrep_strict_ddl; |
|||
|
|||
--connection node_1 |
|||
--error ER_GALERA_REPLICATION_NOT_SUPPORTED |
|||
CREATE TABLE t1(a int) engine=Aria; |
|||
SHOW WARNINGS; |
|||
|
|||
--connection node_2 |
|||
--error ER_NO_SUCH_TABLE |
|||
SHOW CREATE TABLE t1; |
|||
|
|||
--connection node_1 |
|||
CREATE TABLE t2(a int not null primary key) engine=InnoDB; |
|||
|
|||
--error ER_GALERA_REPLICATION_NOT_SUPPORTED |
|||
ALTER TABLE t2 engine=MyISAM; |
|||
SHOW WARNINGS; |
|||
SHOW CREATE TABLE t2; |
|||
|
|||
--connection node_2 |
|||
SHOW CREATE TABLE t2; |
|||
|
|||
--connection node_1 |
|||
--error ER_GALERA_REPLICATION_NOT_SUPPORTED |
|||
TRUNCATE TABLE before_t1; |
|||
SELECT * FROM before_t1; |
|||
|
|||
--connection node_2 |
|||
SET SESSION wsrep_sync_wait=15; |
|||
SELECT @@wsrep_sync_wait; |
|||
SELECT * FROM before_t1; |
|||
|
|||
--connection node_1 |
|||
--error ER_GALERA_REPLICATION_NOT_SUPPORTED |
|||
CREATE VIEW x1 AS SELECT * FROM before_t1; |
|||
--error ER_NO_SUCH_TABLE |
|||
SHOW CREATE VIEW x1; |
|||
|
|||
--connection node_2 |
|||
--error ER_NO_SUCH_TABLE |
|||
SHOW CREATE VIEW x1; |
|||
|
|||
--connection node_1 |
|||
--error ER_GALERA_REPLICATION_NOT_SUPPORTED |
|||
CREATE DEFINER=`root`@`localhost` TRIGGER increment_before_t1 |
|||
AFTER INSERT ON before_t1 FOR EACH ROW |
|||
UPDATE before_t1 SET before_t1.count = before_t1.count+1; |
|||
|
|||
--error ER_TRG_DOES_NOT_EXIST |
|||
SHOW CREATE TRIGGER increment_before_t1; |
|||
|
|||
--connection node_2 |
|||
|
|||
--error ER_TRG_DOES_NOT_EXIST |
|||
SHOW CREATE TRIGGER increment_before_t1; |
|||
|
|||
--connection node_1 |
|||
--error ER_GALERA_REPLICATION_NOT_SUPPORTED |
|||
CREATE INDEX xx2 ON before_t1(a); |
|||
SHOW CREATE TABLE before_t1; |
|||
|
|||
--connection node_2 |
|||
SHOW CREATE TABLE before_t1; |
|||
|
|||
--connection node_1 |
|||
--error ER_GALERA_REPLICATION_NOT_SUPPORTED |
|||
DROP INDEX b ON before_t1; |
|||
SHOW CREATE TABLE before_t1; |
|||
|
|||
--connection node_2 |
|||
SHOW CREATE TABLE before_t1; |
|||
|
|||
--connection node_1 |
|||
--error ER_GALERA_REPLICATION_NOT_SUPPORTED |
|||
ALTER TABLE before_t1 ADD COLUMN f int; |
|||
SHOW CREATE TABLE before_t1; |
|||
|
|||
--connection node_2 |
|||
SHOW CREATE TABLE before_t1; |
|||
|
|||
--connection node_1 |
|||
--error ER_GALERA_REPLICATION_NOT_SUPPORTED |
|||
RENAME TABLE before_t1 to after_t1; |
|||
SHOW CREATE TABLE before_t1; |
|||
--error ER_NO_SUCH_TABLE |
|||
SHOW CREATE TABLE after_t1; |
|||
|
|||
--connection node_2 |
|||
SHOW CREATE TABLE before_t1; |
|||
--error ER_NO_SUCH_TABLE |
|||
SHOW CREATE TABLE after_t1; |
|||
|
|||
--connection node_1 |
|||
--error ER_GALERA_REPLICATION_NOT_SUPPORTED |
|||
DROP TABLE before_t1; |
|||
|
|||
SHOW CREATE TABLE before_t1; |
|||
|
|||
--connection node_2 |
|||
SHOW CREATE TABLE before_t1; |
|||
|
|||
# |
|||
# PROCEDURE, EVENT, FUNCTION |
|||
# Unfortunately accessed tables are opened only |
|||
# in SP execution so no hope at CREATE |
|||
|
|||
# |
|||
# USER, ROLE, SERVER, DATABASE not really storage engine objects |
|||
# |
|||
|
|||
--connection node_1 |
|||
set @@global.wsrep_strict_ddl=OFF; |
|||
select @@global.wsrep_strict_ddl; |
|||
|
|||
--connectIon node_2 |
|||
set @@global.wsrep_strict_ddl=OFF; |
|||
select @@global.wsrep_strict_ddl; |
|||
DROP TABLE t2; |
|||
DROP TABLE before_t1; |
|||
@ -0,0 +1,45 @@ |
|||
# |
|||
# wsrep_strict_ddl |
|||
# |
|||
# save the initial value |
|||
SET @wsrep_strict_ddl_global_saved = @@global.wsrep_strict_ddl; |
|||
# default |
|||
SELECT @@global.wsrep_strict_ddl; |
|||
@@global.wsrep_strict_ddl |
|||
0 |
|||
|
|||
# scope |
|||
SELECT @@session.wsrep_strict_ddl; |
|||
ERROR HY000: Variable 'wsrep_strict_ddl' is a GLOBAL variable |
|||
SET @@global.wsrep_strict_ddl=OFF; |
|||
SELECT @@global.wsrep_strict_ddl; |
|||
@@global.wsrep_strict_ddl |
|||
0 |
|||
SET @@global.wsrep_strict_ddl=ON; |
|||
SELECT @@global.wsrep_strict_ddl; |
|||
@@global.wsrep_strict_ddl |
|||
1 |
|||
|
|||
# valid values |
|||
SET @@global.wsrep_strict_ddl='OFF'; |
|||
SELECT @@global.wsrep_strict_ddl; |
|||
@@global.wsrep_strict_ddl |
|||
0 |
|||
SET @@global.wsrep_strict_ddl=ON; |
|||
SELECT @@global.wsrep_strict_ddl; |
|||
@@global.wsrep_strict_ddl |
|||
1 |
|||
SET @@global.wsrep_strict_ddl=default; |
|||
SELECT @@global.wsrep_strict_ddl; |
|||
@@global.wsrep_strict_ddl |
|||
0 |
|||
|
|||
# invalid values |
|||
SET @@global.wsrep_strict_ddl=NULL; |
|||
ERROR 42000: Variable 'wsrep_strict_ddl' can't be set to the value of 'NULL' |
|||
SET @@global.wsrep_strict_ddl='junk'; |
|||
ERROR 42000: Variable 'wsrep_strict_ddl' can't be set to the value of 'junk' |
|||
|
|||
# restore the initial value |
|||
SET @@global.wsrep_strict_ddl = @wsrep_strict_ddl_global_saved; |
|||
# End of test |
|||
@ -0,0 +1,42 @@ |
|||
--source include/have_wsrep.inc |
|||
|
|||
--echo # |
|||
--echo # wsrep_strict_ddl |
|||
--echo # |
|||
|
|||
--echo # save the initial value |
|||
SET @wsrep_strict_ddl_global_saved = @@global.wsrep_strict_ddl; |
|||
|
|||
--echo # default |
|||
SELECT @@global.wsrep_strict_ddl; |
|||
|
|||
--echo |
|||
--echo # scope |
|||
--error ER_INCORRECT_GLOBAL_LOCAL_VAR |
|||
SELECT @@session.wsrep_strict_ddl; |
|||
SET @@global.wsrep_strict_ddl=OFF; |
|||
SELECT @@global.wsrep_strict_ddl; |
|||
SET @@global.wsrep_strict_ddl=ON; |
|||
SELECT @@global.wsrep_strict_ddl; |
|||
|
|||
--echo |
|||
--echo # valid values |
|||
SET @@global.wsrep_strict_ddl='OFF'; |
|||
SELECT @@global.wsrep_strict_ddl; |
|||
SET @@global.wsrep_strict_ddl=ON; |
|||
SELECT @@global.wsrep_strict_ddl; |
|||
SET @@global.wsrep_strict_ddl=default; |
|||
SELECT @@global.wsrep_strict_ddl; |
|||
|
|||
--echo |
|||
--echo # invalid values |
|||
--error ER_WRONG_VALUE_FOR_VAR |
|||
SET @@global.wsrep_strict_ddl=NULL; |
|||
--error ER_WRONG_VALUE_FOR_VAR |
|||
SET @@global.wsrep_strict_ddl='junk'; |
|||
|
|||
--echo |
|||
--echo # restore the initial value |
|||
SET @@global.wsrep_strict_ddl = @wsrep_strict_ddl_global_saved; |
|||
|
|||
--echo # End of test |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue