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.
This commit is contained in:
parent
41541a7c48
commit
e6a50e41da
@ -84,6 +84,7 @@ extern struct wsrep_service_st {
|
||||
my_bool (*wsrep_get_debug_func)();
|
||||
void (*wsrep_commit_ordered_func)(MYSQL_THD thd);
|
||||
my_bool (*wsrep_thd_is_applying_func)(const MYSQL_THD thd);
|
||||
ulong (*wsrep_OSU_method_get_func)(const MYSQL_THD thd);
|
||||
my_bool (*wsrep_thd_has_ignored_error_func)(const MYSQL_THD thd);
|
||||
void (*wsrep_thd_set_ignored_error_func)(MYSQL_THD thd, my_bool val);
|
||||
} *wsrep_service;
|
||||
@ -126,9 +127,9 @@ extern struct wsrep_service_st {
|
||||
#define wsrep_get_debug() wsrep_service->wsrep_get_debug_func()
|
||||
#define wsrep_commit_ordered(T) wsrep_service->wsrep_commit_ordered_func(T)
|
||||
#define wsrep_thd_is_applying(T) wsrep_service->wsrep_thd_is_applying_func(T)
|
||||
#define wsrep_OSU_method_get(T) wsrep_service->wsrep_OSU_method_get_func(T)
|
||||
#define wsrep_thd_has_ignored_error(T) wsrep_service->wsrep_thd_has_ignored_error_func(T)
|
||||
#define wsrep_thd_set_ignored_error(T,V) wsrep_service->wsrep_thd_set_ignored_error_func(T,V)
|
||||
|
||||
#else
|
||||
|
||||
#define MYSQL_SERVICE_WSREP_STATIC_INCLUDED
|
||||
@ -220,9 +221,8 @@ extern "C" my_bool wsrep_get_debug();
|
||||
|
||||
extern "C" void wsrep_commit_ordered(MYSQL_THD thd);
|
||||
extern "C" my_bool wsrep_thd_is_applying(const MYSQL_THD thd);
|
||||
|
||||
extern "C" ulong wsrep_OSU_method_get(const MYSQL_THD thd);
|
||||
extern "C" my_bool wsrep_thd_has_ignored_error(const MYSQL_THD thd);
|
||||
extern "C" void wsrep_thd_set_ignored_error(MYSQL_THD thd, my_bool val);
|
||||
|
||||
#endif
|
||||
#endif /* MYSQL_SERVICE_WSREP_INCLUDED */
|
||||
|
@ -19,18 +19,27 @@
|
||||
#include <my_config.h>
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
|
||||
#define IF_WSREP(A,B) A
|
||||
|
||||
#define DBUG_ASSERT_IF_WSREP(A) DBUG_ASSERT(A)
|
||||
|
||||
#define WSREP_MYSQL_DB (char *)"mysql"
|
||||
|
||||
#define WSREP_TO_ISOLATION_BEGIN(db_, table_, table_list_) \
|
||||
if (WSREP_ON && WSREP(thd) && wsrep_to_isolation_begin(thd, db_, table_, table_list_)) \
|
||||
if (WSREP(thd) && wsrep_to_isolation_begin(thd, db_, table_, table_list_)) \
|
||||
goto wsrep_error_label;
|
||||
|
||||
#define WSREP_TO_ISOLATION_BEGIN_ALTER(db_, table_, table_list_, alter_info_) \
|
||||
#define WSREP_TO_ISOLATION_BEGIN_CREATE(db_, table_, table_list_, create_info_) \
|
||||
if (WSREP(thd) && \
|
||||
wsrep_to_isolation_begin(thd, db_, table_, \
|
||||
table_list_, NULL, create_info_)) \
|
||||
goto wsrep_error_label;
|
||||
|
||||
#define WSREP_TO_ISOLATION_BEGIN_ALTER(db_, table_, table_list_, alter_info_, create_info_) \
|
||||
if (WSREP(thd) && wsrep_thd_is_local(thd) && \
|
||||
wsrep_to_isolation_begin(thd, db_, table_, \
|
||||
table_list_, alter_info_)) \
|
||||
table_list_, alter_info_, create_info_)) \
|
||||
goto wsrep_error_label;
|
||||
|
||||
#define WSREP_TO_ISOLATION_END \
|
||||
@ -56,14 +65,12 @@
|
||||
* (e.g. embedded) */
|
||||
|
||||
#define IF_WSREP(A,B) B
|
||||
//#define DBUG_ASSERT_IF_WSREP(A)
|
||||
#define WSREP_DEBUG(...)
|
||||
//#define WSREP_INFO(...)
|
||||
//#define WSREP_WARN(...)
|
||||
#define WSREP_ERROR(...)
|
||||
#define WSREP_TO_ISOLATION_BEGIN(db_, table_, table_list_) do { } while(0)
|
||||
#define WSREP_TO_ISOLATION_BEGIN_ALTER(db_, table_, table_list_, alter_info_)
|
||||
#define WSREP_TO_ISOLATION_BEGIN_ALTER(db_, table_, table_list_, alter_info_, create_info_)
|
||||
#define WSREP_TO_ISOLATION_END
|
||||
#define WSREP_TO_ISOLATION_BEGIN_CREATE(db_, table_, table_list_, create_info_)
|
||||
#define WSREP_TO_ISOLATION_BEGIN_WRTCHK(db_, table_, table_list_)
|
||||
#define WSREP_SYNC_WAIT(thd_, before_)
|
||||
#endif /* WITH_WSREP */
|
||||
|
194
mysql-test/suite/galera/r/wsrep_strict_ddl.result
Normal file
194
mysql-test/suite/galera/r/wsrep_strict_ddl.result
Normal file
@ -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;
|
133
mysql-test/suite/galera/t/wsrep_strict_ddl.test
Normal file
133
mysql-test/suite/galera/t/wsrep_strict_ddl.test
Normal file
@ -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;
|
@ -706,6 +706,21 @@ ENUM_VALUE_LIST NULL
|
||||
READ_ONLY NO
|
||||
COMMAND_LINE_ARGUMENT REQUIRED
|
||||
GLOBAL_VALUE_PATH NULL
|
||||
VARIABLE_NAME WSREP_STRICT_DDL
|
||||
SESSION_VALUE NULL
|
||||
GLOBAL_VALUE OFF
|
||||
GLOBAL_VALUE_ORIGIN COMPILE-TIME
|
||||
DEFAULT_VALUE OFF
|
||||
VARIABLE_SCOPE GLOBAL
|
||||
VARIABLE_TYPE BOOLEAN
|
||||
VARIABLE_COMMENT Reject DDL on effected tables not supporting Galera replication
|
||||
NUMERIC_MIN_VALUE NULL
|
||||
NUMERIC_MAX_VALUE NULL
|
||||
NUMERIC_BLOCK_SIZE NULL
|
||||
ENUM_VALUE_LIST OFF,ON
|
||||
READ_ONLY NO
|
||||
COMMAND_LINE_ARGUMENT OPTIONAL
|
||||
GLOBAL_VALUE_PATH NULL
|
||||
VARIABLE_NAME WSREP_SYNC_WAIT
|
||||
SESSION_VALUE 0
|
||||
GLOBAL_VALUE 0
|
||||
|
45
mysql-test/suite/sys_vars/r/wsrep_strict_ddl_basic.result
Normal file
45
mysql-test/suite/sys_vars/r/wsrep_strict_ddl_basic.result
Normal file
@ -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
|
42
mysql-test/suite/sys_vars/t/wsrep_strict_ddl_basic.test
Normal file
42
mysql-test/suite/sys_vars/t/wsrep_strict_ddl_basic.test
Normal file
@ -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
|
@ -52,13 +52,14 @@ extern "C" const char* wsrep_thd_transaction_state_str(const THD *thd)
|
||||
return wsrep::to_c_string(thd->wsrep_cs().transaction().state());
|
||||
}
|
||||
|
||||
|
||||
extern "C" const char *wsrep_thd_query(const THD *thd)
|
||||
{
|
||||
if (thd)
|
||||
if (!thd)
|
||||
return "NULL";
|
||||
|
||||
switch(thd->lex->sql_command)
|
||||
{
|
||||
switch(thd->lex->sql_command)
|
||||
{
|
||||
// Mask away some security related details from error log
|
||||
case SQLCOM_CREATE_USER:
|
||||
return "CREATE USER";
|
||||
case SQLCOM_GRANT:
|
||||
@ -67,12 +68,10 @@ extern "C" const char *wsrep_thd_query(const THD *thd)
|
||||
return "REVOKE";
|
||||
case SQLCOM_SET_OPTION:
|
||||
if (thd->lex->definer)
|
||||
return "SET PASSWORD";
|
||||
return "SET PASSWORD";
|
||||
/* fallthrough */
|
||||
default:
|
||||
if (thd->query())
|
||||
return thd->query();
|
||||
}
|
||||
return (thd->query() ? thd->query() : "NULL");
|
||||
}
|
||||
return "NULL";
|
||||
}
|
||||
@ -321,3 +320,11 @@ extern "C" void wsrep_thd_set_ignored_error(THD *thd, my_bool val)
|
||||
{
|
||||
thd->wsrep_has_ignored_error= val;
|
||||
}
|
||||
|
||||
extern "C" ulong wsrep_OSU_method_get(const MYSQL_THD thd)
|
||||
{
|
||||
if (thd)
|
||||
return(thd->variables.wsrep_OSU_method);
|
||||
else
|
||||
return(global_system_variables.wsrep_OSU_method);
|
||||
}
|
||||
|
@ -7943,3 +7943,5 @@ ER_WARN_HISTORY_ROW_START_TIME
|
||||
eng "Table `%s.%s` history row start '%s' is later than row end '%s'"
|
||||
ER_PART_STARTS_BEYOND_INTERVAL
|
||||
eng "%`s: STARTS is later than query time, first history partition may exceed INTERVAL value"
|
||||
ER_GALERA_REPLICATION_NOT_SUPPORTED
|
||||
eng "DDL-statement is forbidden as table storage engine does not support Galera replication"
|
@ -505,9 +505,9 @@ bool Sql_cmd_alter_table::execute(THD *thd)
|
||||
(!thd->is_current_stmt_binlog_format_row() ||
|
||||
!thd->find_temporary_table(first_table)))
|
||||
{
|
||||
WSREP_TO_ISOLATION_BEGIN_ALTER((lex->name.str ? select_lex->db.str : NULL),
|
||||
(lex->name.str ? lex->name.str : NULL),
|
||||
first_table, &alter_info);
|
||||
WSREP_TO_ISOLATION_BEGIN_ALTER((lex->name.str ? select_lex->db.str : first_table->db.str),
|
||||
(lex->name.str ? lex->name.str : first_table->table_name.str),
|
||||
first_table, &alter_info, used_engine ? &create_info : NULL);
|
||||
|
||||
thd->variables.auto_increment_offset = 1;
|
||||
thd->variables.auto_increment_increment = 1;
|
||||
|
@ -3079,6 +3079,7 @@ mysql_create_routine(THD *thd, LEX *lex)
|
||||
return true;
|
||||
|
||||
WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL);
|
||||
|
||||
if (!lex->sphead->m_handler->sp_create_routine(thd, lex->sphead))
|
||||
{
|
||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||
@ -4147,7 +4148,6 @@ mysql_execute_command(THD *thd)
|
||||
DBUG_ASSERT(first_table == all_tables && first_table != 0);
|
||||
if (check_one_table_access(thd, INDEX_ACL, all_tables))
|
||||
goto error; /* purecov: inspected */
|
||||
WSREP_TO_ISOLATION_BEGIN(first_table->db.str, first_table->table_name.str, NULL);
|
||||
|
||||
bzero((char*) &create_info, sizeof(create_info));
|
||||
create_info.db_type= 0;
|
||||
@ -4155,6 +4155,8 @@ mysql_execute_command(THD *thd)
|
||||
create_info.default_table_charset= thd->variables.collation_database;
|
||||
create_info.alter_info= &alter_info;
|
||||
|
||||
WSREP_TO_ISOLATION_BEGIN(first_table->db.str, first_table->table_name.str, NULL);
|
||||
|
||||
res= mysql_alter_table(thd, &first_table->db, &first_table->table_name,
|
||||
&create_info, first_table, &alter_info,
|
||||
0, (ORDER*) 0, 0);
|
||||
@ -4857,6 +4859,7 @@ mysql_execute_command(THD *thd)
|
||||
slave_ddl_exec_mode_options == SLAVE_EXEC_MODE_IDEMPOTENT)
|
||||
lex->create_info.set(DDL_options_st::OPT_IF_EXISTS);
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
if (WSREP(thd))
|
||||
{
|
||||
for (TABLE_LIST *table= all_tables; table; table= table->next_global)
|
||||
@ -4870,7 +4873,8 @@ mysql_execute_command(THD *thd)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* WITH_WSREP */
|
||||
|
||||
/* DDL and binlog write order are protected by metadata locks. */
|
||||
res= mysql_rm_table(thd, first_table, lex->if_exists(), lex->tmp_table(),
|
||||
lex->table_type == TABLE_TYPE_SEQUENCE);
|
||||
@ -5070,7 +5074,9 @@ mysql_execute_command(THD *thd)
|
||||
(CREATE_ACL | DROP_ACL) : CREATE_ACL,
|
||||
&lex->name))
|
||||
break;
|
||||
|
||||
WSREP_TO_ISOLATION_BEGIN(lex->name.str, NULL, NULL);
|
||||
|
||||
res= mysql_create_db(thd, &lex->name,
|
||||
lex->create_info, &lex->create_info);
|
||||
break;
|
||||
@ -5079,7 +5085,9 @@ mysql_execute_command(THD *thd)
|
||||
{
|
||||
if (prepare_db_action(thd, DROP_ACL, &lex->name))
|
||||
break;
|
||||
|
||||
WSREP_TO_ISOLATION_BEGIN(lex->name.str, NULL, NULL);
|
||||
|
||||
res= mysql_rm_db(thd, &lex->name, lex->if_exists());
|
||||
break;
|
||||
}
|
||||
@ -5111,7 +5119,9 @@ mysql_execute_command(THD *thd)
|
||||
res= 1;
|
||||
break;
|
||||
}
|
||||
|
||||
WSREP_TO_ISOLATION_BEGIN(db->str, NULL, NULL);
|
||||
|
||||
res= mysql_upgrade_db(thd, db);
|
||||
if (!res)
|
||||
my_ok(thd);
|
||||
@ -5122,7 +5132,9 @@ mysql_execute_command(THD *thd)
|
||||
LEX_CSTRING *db= &lex->name;
|
||||
if (prepare_db_action(thd, ALTER_ACL, db))
|
||||
break;
|
||||
|
||||
WSREP_TO_ISOLATION_BEGIN(db->str, NULL, NULL);
|
||||
|
||||
res= mysql_alter_db(thd, db, &lex->create_info);
|
||||
break;
|
||||
}
|
||||
@ -5196,6 +5208,7 @@ mysql_execute_command(THD *thd)
|
||||
break;
|
||||
#ifdef HAVE_DLOPEN
|
||||
WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL);
|
||||
|
||||
if (!(res = mysql_create_function(thd, &lex->udf)))
|
||||
my_ok(thd);
|
||||
#else
|
||||
@ -5213,7 +5226,9 @@ mysql_execute_command(THD *thd)
|
||||
"mysql", NULL, NULL, 1, 1) &&
|
||||
check_global_access(thd,CREATE_USER_ACL))
|
||||
break;
|
||||
|
||||
WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL);
|
||||
|
||||
/* Conditionally writes to binlog */
|
||||
if (!(res= mysql_create_user(thd, lex->users_list,
|
||||
lex->sql_command == SQLCOM_CREATE_ROLE)))
|
||||
@ -5226,8 +5241,10 @@ mysql_execute_command(THD *thd)
|
||||
if (check_access(thd, DELETE_ACL, "mysql", NULL, NULL, 1, 1) &&
|
||||
check_global_access(thd,CREATE_USER_ACL))
|
||||
break;
|
||||
/* Conditionally writes to binlog */
|
||||
|
||||
WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL);
|
||||
|
||||
/* Conditionally writes to binlog */
|
||||
if (!(res= mysql_drop_user(thd, lex->users_list,
|
||||
lex->sql_command == SQLCOM_DROP_ROLE)))
|
||||
my_ok(thd);
|
||||
@ -5239,8 +5256,10 @@ mysql_execute_command(THD *thd)
|
||||
if (check_access(thd, UPDATE_ACL, "mysql", NULL, NULL, 1, 1) &&
|
||||
check_global_access(thd,CREATE_USER_ACL))
|
||||
break;
|
||||
/* Conditionally writes to binlog */
|
||||
|
||||
WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL);
|
||||
|
||||
/* Conditionally writes to binlog */
|
||||
if (lex->sql_command == SQLCOM_ALTER_USER)
|
||||
res= mysql_alter_user(thd, lex->users_list);
|
||||
else
|
||||
@ -5255,16 +5274,19 @@ mysql_execute_command(THD *thd)
|
||||
check_global_access(thd,CREATE_USER_ACL))
|
||||
break;
|
||||
|
||||
/* Conditionally writes to binlog */
|
||||
WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL);
|
||||
|
||||
/* Conditionally writes to binlog */
|
||||
if (!(res = mysql_revoke_all(thd, lex->users_list)))
|
||||
my_ok(thd);
|
||||
break;
|
||||
}
|
||||
|
||||
case SQLCOM_REVOKE_ROLE:
|
||||
case SQLCOM_GRANT_ROLE:
|
||||
{
|
||||
WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL);
|
||||
|
||||
if (!(res= mysql_grant_role(thd, lex->users_list,
|
||||
lex->sql_command != SQLCOM_GRANT_ROLE)))
|
||||
my_ok(thd);
|
||||
@ -5611,6 +5633,7 @@ mysql_execute_command(THD *thd)
|
||||
case SQLCOM_DROP_PACKAGE:
|
||||
case SQLCOM_DROP_PACKAGE_BODY:
|
||||
if (drop_routine(thd, lex))
|
||||
|
||||
goto error;
|
||||
break;
|
||||
case SQLCOM_SHOW_CREATE_PROC:
|
||||
@ -5676,8 +5699,10 @@ mysql_execute_command(THD *thd)
|
||||
{
|
||||
if (check_table_access(thd, DROP_ACL, all_tables, FALSE, UINT_MAX, FALSE))
|
||||
goto error;
|
||||
/* Conditionally writes to binlog. */
|
||||
|
||||
WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL);
|
||||
|
||||
/* Conditionally writes to binlog. */
|
||||
res= mysql_drop_view(thd, first_table, thd->lex->drop_mode);
|
||||
break;
|
||||
}
|
||||
@ -5983,7 +6008,7 @@ finish:
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
thd->wsrep_consistency_check= NO_CONSISTENCY_CHECK;
|
||||
|
||||
|
||||
WSREP_TO_ISOLATION_END;
|
||||
/*
|
||||
Force release of transactional locks if not in active MST and wsrep is on.
|
||||
|
@ -175,6 +175,7 @@ static struct wsrep_service_st wsrep_handler = {
|
||||
wsrep_get_debug,
|
||||
wsrep_commit_ordered,
|
||||
wsrep_thd_is_applying,
|
||||
wsrep_OSU_method_get,
|
||||
wsrep_thd_has_ignored_error,
|
||||
wsrep_thd_set_ignored_error
|
||||
};
|
||||
|
@ -286,6 +286,13 @@ do_rename(THD *thd, TABLE_LIST *ren_table, const LEX_CSTRING *new_db,
|
||||
if (ha_table_exists(thd, &ren_table->db, &old_alias, &hton) && hton)
|
||||
{
|
||||
DBUG_ASSERT(!thd->locked_tables_mode);
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
if (WSREP(thd) && hton &&
|
||||
!wsrep_should_replicate_ddl(thd, hton->db_type))
|
||||
DBUG_RETURN(1);
|
||||
#endif
|
||||
|
||||
tdc_remove_table(thd, TDC_RT_REMOVE_ALL,
|
||||
ren_table->db.str, ren_table->table_name.str);
|
||||
|
||||
|
@ -2443,6 +2443,16 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists,
|
||||
{
|
||||
char *end;
|
||||
int frm_delete_error= 0;
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
if (WSREP(thd) &&
|
||||
!wsrep_should_replicate_ddl(thd, table_type->db_type))
|
||||
{
|
||||
error= 1;
|
||||
goto err;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
It could happen that table's share in the table definition cache
|
||||
is the only thing that keeps the engine plugin loaded
|
||||
@ -9461,6 +9471,17 @@ bool mysql_alter_table(THD *thd, const LEX_CSTRING *new_db,
|
||||
&alter_prelocking_strategy);
|
||||
thd->open_options&= ~HA_OPEN_FOR_ALTER;
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
if (WSREP(thd) &&
|
||||
(thd->lex->sql_command == SQLCOM_ALTER_TABLE ||
|
||||
thd->lex->sql_command == SQLCOM_CREATE_INDEX ||
|
||||
thd->lex->sql_command == SQLCOM_DROP_INDEX) &&
|
||||
!wsrep_should_replicate_ddl(thd, table_list->table->s->db_type()->db_type))
|
||||
DBUG_RETURN(true);
|
||||
#endif
|
||||
|
||||
DEBUG_SYNC(thd, "alter_table_after_open_tables");
|
||||
|
||||
TABLE *table= table_list->table;
|
||||
bool versioned= table && table->versioned();
|
||||
|
||||
@ -11503,7 +11524,8 @@ bool Sql_cmd_create_table_like::execute(THD *thd)
|
||||
(!thd->is_current_stmt_binlog_format_row() ||
|
||||
!create_info.tmp_table()))
|
||||
{
|
||||
WSREP_TO_ISOLATION_BEGIN(create_table->db.str, create_table->table_name.str, NULL);
|
||||
WSREP_TO_ISOLATION_BEGIN_CREATE(create_table->db.str, create_table->table_name.str,
|
||||
create_table, &create_info);
|
||||
}
|
||||
/* Regular CREATE TABLE */
|
||||
res= mysql_create_table(thd, create_table, &create_info, &alter_info);
|
||||
|
@ -507,9 +507,7 @@ bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create)
|
||||
goto end;
|
||||
}
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, tables);
|
||||
#endif
|
||||
|
||||
/* We should have only one table in table list. */
|
||||
DBUG_ASSERT(tables->next_global == 0);
|
||||
@ -550,6 +548,12 @@ bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create)
|
||||
}
|
||||
table= tables->table;
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
if (WSREP(thd) &&
|
||||
!wsrep_should_replicate_ddl(thd, table->s->db_type()->db_type))
|
||||
goto wsrep_error_label;
|
||||
#endif
|
||||
|
||||
/* Later on we will need it to downgrade the lock */
|
||||
mdl_ticket= table->mdl_ticket;
|
||||
|
||||
|
@ -303,6 +303,12 @@ bool Sql_cmd_truncate_table::lock_table(THD *thd, TABLE_LIST *table_ref,
|
||||
|
||||
versioned= table->versioned();
|
||||
hton= table->file->ht;
|
||||
#ifdef WITH_WSREP
|
||||
if (WSREP(thd) &&
|
||||
!wsrep_should_replicate_ddl(thd, hton->db_type))
|
||||
DBUG_RETURN(TRUE);
|
||||
#endif
|
||||
|
||||
table_ref->mdl_request.ticket= table->mdl_ticket;
|
||||
}
|
||||
else
|
||||
@ -320,6 +326,15 @@ bool Sql_cmd_truncate_table::lock_table(THD *thd, TABLE_LIST *table_ref,
|
||||
versioned= share->versioned;
|
||||
sequence= share->table_type == TABLE_TYPE_SEQUENCE;
|
||||
hton= share->db_type();
|
||||
#ifdef WITH_WSREP
|
||||
if (WSREP(thd) &&
|
||||
hton != view_pseudo_hton &&
|
||||
!wsrep_should_replicate_ddl(thd, hton->db_type))
|
||||
{
|
||||
tdc_release_share(share);
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
#endif
|
||||
|
||||
tdc_release_share(share);
|
||||
|
||||
@ -417,9 +432,10 @@ bool Sql_cmd_truncate_table::truncate_table(THD *thd, TABLE_LIST *table_ref)
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
if (WSREP(thd) &&
|
||||
wsrep_to_isolation_begin(thd, table_ref->db.str, table_ref->table_name.str, 0))
|
||||
DBUG_RETURN(TRUE);
|
||||
wsrep_to_isolation_begin(thd, table_ref->db.str, table_ref->table_name.str, NULL))
|
||||
DBUG_RETURN(TRUE);
|
||||
#endif /* WITH_WSREP */
|
||||
|
||||
if (lock_table(thd, table_ref, &hton_can_recreate))
|
||||
DBUG_RETURN(TRUE);
|
||||
|
||||
|
@ -37,6 +37,7 @@
|
||||
#include "sql_derived.h"
|
||||
#include "sql_cte.h" // check_dependencies_in_with_clauses()
|
||||
#include "opt_trace.h"
|
||||
#include "wsrep_mysqld.h"
|
||||
|
||||
#define MD5_BUFF_LENGTH 33
|
||||
|
||||
@ -454,6 +455,14 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views,
|
||||
goto err;
|
||||
}
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
if(!wsrep_should_replicate_ddl_iterate(thd, static_cast<const TABLE_LIST *>(tables)))
|
||||
{
|
||||
res= TRUE;
|
||||
goto err;
|
||||
}
|
||||
#endif
|
||||
|
||||
view= lex->unlink_first_table(&link_to_local);
|
||||
|
||||
if (check_db_dir_existence(view->db.str))
|
||||
|
@ -5685,12 +5685,20 @@ static Sys_var_enum Sys_wsrep_OSU_method(
|
||||
static PolyLock_mutex PLock_wsrep_desync(&LOCK_wsrep_desync);
|
||||
static Sys_var_mybool Sys_wsrep_desync (
|
||||
"wsrep_desync", "To desynchronize the node from the cluster",
|
||||
GLOBAL_VAR(wsrep_desync),
|
||||
GLOBAL_VAR(wsrep_desync),
|
||||
CMD_LINE(OPT_ARG), DEFAULT(FALSE),
|
||||
&PLock_wsrep_desync, NOT_IN_BINLOG,
|
||||
ON_CHECK(wsrep_desync_check),
|
||||
ON_UPDATE(wsrep_desync_update));
|
||||
|
||||
static Sys_var_mybool Sys_wsrep_strict_ddl (
|
||||
"wsrep_strict_ddl", "Reject DDL on effected tables not supporting Galera replication",
|
||||
GLOBAL_VAR(wsrep_strict_ddl),
|
||||
CMD_LINE(OPT_ARG), DEFAULT(FALSE),
|
||||
NO_MUTEX_GUARD, NOT_IN_BINLOG,
|
||||
ON_CHECK(0),
|
||||
ON_UPDATE(0));
|
||||
|
||||
static const char *wsrep_reject_queries_names[]= { "NONE", "ALL", "ALL_KILL", NullS };
|
||||
static Sys_var_enum Sys_wsrep_reject_queries(
|
||||
"wsrep_reject_queries", "Variable to set to reject queries",
|
||||
|
@ -144,3 +144,5 @@ my_bool wsrep_thd_has_ignored_error(const THD*)
|
||||
|
||||
void wsrep_thd_set_ignored_error(THD*, my_bool)
|
||||
{ }
|
||||
ulong wsrep_OSU_method_get(const THD*)
|
||||
{ return 0;}
|
@ -96,6 +96,9 @@ my_bool wsrep_restart_slave; // Should mysql slave thread be
|
||||
// restarted, when node joins back?
|
||||
my_bool wsrep_desync; // De(re)synchronize the node from the
|
||||
// cluster
|
||||
my_bool wsrep_strict_ddl; // Reject DDL to
|
||||
// effected tables not
|
||||
// supporting Galera replication
|
||||
long wsrep_slave_threads; // No. of slave appliers threads
|
||||
ulong wsrep_retry_autocommit; // Retry aborted autocommit trx
|
||||
ulong wsrep_max_ws_size; // Max allowed ws (RBR buffer) size
|
||||
@ -1296,11 +1299,11 @@ static bool wsrep_prepare_key_for_isolation(const char* db,
|
||||
}
|
||||
|
||||
static bool wsrep_prepare_keys_for_alter_add_fk(const char* child_table_db,
|
||||
Alter_info* alter_info,
|
||||
const Alter_info* alter_info,
|
||||
wsrep_key_arr_t* ka)
|
||||
{
|
||||
Key *key;
|
||||
List_iterator<Key> key_iterator(alter_info->key_list);
|
||||
List_iterator<Key> key_iterator(const_cast<Alter_info*>(alter_info)->key_list);
|
||||
while ((key= key_iterator++))
|
||||
{
|
||||
if (key->type == Key::FOREIGN_KEY)
|
||||
@ -1436,12 +1439,12 @@ wsrep::key wsrep_prepare_key_for_toi(const char* db, const char* table,
|
||||
|
||||
wsrep::key_array
|
||||
wsrep_prepare_keys_for_alter_add_fk(const char* child_table_db,
|
||||
Alter_info* alter_info)
|
||||
const Alter_info* alter_info)
|
||||
|
||||
{
|
||||
wsrep::key_array ret;
|
||||
Key *key;
|
||||
List_iterator<Key> key_iterator(alter_info->key_list);
|
||||
List_iterator<Key> key_iterator(const_cast<Alter_info*>(alter_info)->key_list);
|
||||
while ((key= key_iterator++))
|
||||
{
|
||||
if (key->type == Key::FOREIGN_KEY)
|
||||
@ -1463,7 +1466,7 @@ wsrep_prepare_keys_for_alter_add_fk(const char* child_table_db,
|
||||
wsrep::key_array wsrep_prepare_keys_for_toi(const char* db,
|
||||
const char* table,
|
||||
const TABLE_LIST* table_list,
|
||||
Alter_info* alter_info)
|
||||
const Alter_info* alter_info)
|
||||
{
|
||||
wsrep::key_array ret;
|
||||
if (db || table)
|
||||
@ -1735,6 +1738,51 @@ static int wsrep_drop_table_query(THD* thd, uchar** buf, size_t* buf_len)
|
||||
/* Forward declarations. */
|
||||
int wsrep_create_trigger_query(THD *thd, uchar** buf, size_t* buf_len);
|
||||
|
||||
bool wsrep_should_replicate_ddl_iterate(THD* thd, const TABLE_LIST* table_list)
|
||||
{
|
||||
if (WSREP(thd))
|
||||
{
|
||||
for (const TABLE_LIST* it= table_list; it; it= it->next_global)
|
||||
{
|
||||
if (!wsrep_should_replicate_ddl(thd, it->table->s->db_type()->db_type))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool wsrep_should_replicate_ddl(THD* thd,
|
||||
const enum legacy_db_type db_type)
|
||||
{
|
||||
if (!wsrep_strict_ddl)
|
||||
return true;
|
||||
|
||||
switch (db_type)
|
||||
{
|
||||
case DB_TYPE_INNODB:
|
||||
return true;
|
||||
break;
|
||||
case DB_TYPE_MYISAM:
|
||||
if (wsrep_replicate_myisam)
|
||||
return true;
|
||||
else
|
||||
WSREP_DEBUG("wsrep OSU failed for %s", wsrep_thd_query(thd));
|
||||
break;
|
||||
case DB_TYPE_ARIA:
|
||||
/* if (wsrep_replicate_aria) */
|
||||
/* fallthrough */
|
||||
default:
|
||||
WSREP_DEBUG("wsrep OSU failed for %s", wsrep_thd_query(thd));
|
||||
break;
|
||||
}
|
||||
|
||||
/* STRICT, treat as error */
|
||||
my_error(ER_GALERA_REPLICATION_NOT_SUPPORTED, MYF(0));
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_ILLEGAL_HA,
|
||||
"WSREP: wsrep_strict_ddl=true and storage engine does not support Galera replication.");
|
||||
return false;
|
||||
}
|
||||
/*
|
||||
Decide if statement should run in TOI.
|
||||
|
||||
@ -1745,24 +1793,28 @@ int wsrep_create_trigger_query(THD *thd, uchar** buf, size_t* buf_len);
|
||||
should be rewritten at later time for replication to contain only
|
||||
non-temporary tables.
|
||||
*/
|
||||
static bool wsrep_can_run_in_toi(THD *thd, const char *db, const char *table,
|
||||
const TABLE_LIST *table_list)
|
||||
bool wsrep_can_run_in_toi(THD *thd, const char *db, const char *table,
|
||||
const TABLE_LIST *table_list,
|
||||
const HA_CREATE_INFO* create_info)
|
||||
{
|
||||
DBUG_ASSERT(!table || db);
|
||||
DBUG_ASSERT(table_list || db);
|
||||
|
||||
LEX* lex= thd->lex;
|
||||
SELECT_LEX* select_lex= lex->first_select_lex();
|
||||
TABLE_LIST* first_table= select_lex->table_list.first;
|
||||
const TABLE_LIST* first_table= select_lex->table_list.first;
|
||||
|
||||
switch (lex->sql_command)
|
||||
{
|
||||
case SQLCOM_CREATE_TABLE:
|
||||
DBUG_ASSERT(!table_list);
|
||||
if (thd->lex->create_info.options & HA_LEX_CREATE_TMP_TABLE)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!wsrep_should_replicate_ddl(thd, create_info->db_type->db_type))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
/*
|
||||
If mariadb master has replicated a CTAS, we should not replicate the create table
|
||||
part separately as TOI, but to replicate both create table and following inserts
|
||||
@ -1771,7 +1823,8 @@ static bool wsrep_can_run_in_toi(THD *thd, const char *db, const char *table,
|
||||
as TOI. We have to do relay log event lookup to see if row events follow the
|
||||
create table event.
|
||||
*/
|
||||
if (thd->slave_thread && !(thd->rgi_slave->gtid_ev_flags2 & Gtid_log_event::FL_STANDALONE))
|
||||
if (thd->slave_thread &&
|
||||
!(thd->rgi_slave->gtid_ev_flags2 & Gtid_log_event::FL_STANDALONE))
|
||||
{
|
||||
/* this is CTAS, either empty or populated table */
|
||||
ulonglong event_size = 0;
|
||||
@ -1797,7 +1850,7 @@ static bool wsrep_can_run_in_toi(THD *thd, const char *db, const char *table,
|
||||
}
|
||||
/* no next async replication event */
|
||||
return true;
|
||||
|
||||
break;
|
||||
case SQLCOM_CREATE_VIEW:
|
||||
|
||||
DBUG_ASSERT(!table_list);
|
||||
@ -1806,7 +1859,7 @@ static bool wsrep_can_run_in_toi(THD *thd, const char *db, const char *table,
|
||||
If any of the remaining tables refer to temporary table error
|
||||
is returned to client, so TOI can be skipped
|
||||
*/
|
||||
for (TABLE_LIST* it= first_table->next_global; it; it= it->next_global)
|
||||
for (const TABLE_LIST* it= first_table->next_global; it; it= it->next_global)
|
||||
{
|
||||
if (thd->find_temporary_table(it))
|
||||
{
|
||||
@ -1814,7 +1867,7 @@ static bool wsrep_can_run_in_toi(THD *thd, const char *db, const char *table,
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
||||
break;
|
||||
case SQLCOM_CREATE_TRIGGER:
|
||||
|
||||
DBUG_ASSERT(first_table);
|
||||
@ -1824,15 +1877,12 @@ static bool wsrep_can_run_in_toi(THD *thd, const char *db, const char *table,
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
case SQLCOM_DROP_TRIGGER:
|
||||
DBUG_ASSERT(table_list);
|
||||
if (thd->find_temporary_table(table_list))
|
||||
{
|
||||
break;
|
||||
case SQLCOM_ALTER_TABLE:
|
||||
if (create_info &&
|
||||
!wsrep_should_replicate_ddl(thd, create_info->db_type->db_type))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
/* fallthrough */
|
||||
default:
|
||||
if (table && !thd->find_temporary_table(db, table))
|
||||
{
|
||||
@ -1841,7 +1891,7 @@ static bool wsrep_can_run_in_toi(THD *thd, const char *db, const char *table,
|
||||
|
||||
if (table_list)
|
||||
{
|
||||
for (TABLE_LIST* table= first_table; table; table= table->next_global)
|
||||
for (const TABLE_LIST* table= first_table; table; table= table->next_global)
|
||||
{
|
||||
if (!thd->find_temporary_table(table->db.str, table->table_name.str))
|
||||
{
|
||||
@ -1849,11 +1899,12 @@ static bool wsrep_can_run_in_toi(THD *thd, const char *db, const char *table,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return !(table || table_list);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int wsrep_create_sp(THD *thd, uchar** buf, size_t* buf_len)
|
||||
{
|
||||
String log_query;
|
||||
@ -1962,14 +2013,16 @@ fail:
|
||||
*/
|
||||
static int wsrep_TOI_begin(THD *thd, const char *db, const char *table,
|
||||
const TABLE_LIST* table_list,
|
||||
Alter_info* alter_info)
|
||||
const Alter_info* alter_info,
|
||||
const HA_CREATE_INFO* create_info)
|
||||
{
|
||||
DBUG_ASSERT(thd->variables.wsrep_OSU_method == WSREP_OSU_TOI);
|
||||
DBUG_ASSERT(wsrep_OSU_method_get(thd) == WSREP_OSU_TOI);
|
||||
|
||||
WSREP_DEBUG("TOI Begin");
|
||||
if (wsrep_can_run_in_toi(thd, db, table, table_list) == false)
|
||||
WSREP_DEBUG("TOI Begin: %s", wsrep_thd_query(thd));
|
||||
|
||||
if (wsrep_can_run_in_toi(thd, db, table, table_list, create_info) == false)
|
||||
{
|
||||
WSREP_DEBUG("No TOI for %s", WSREP_QUERY(thd));
|
||||
WSREP_DEBUG("No TOI for %s", wsrep_thd_query(thd));
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -1979,6 +2032,7 @@ static int wsrep_TOI_begin(THD *thd, const char *db, const char *table,
|
||||
int rc;
|
||||
|
||||
buf_err= wsrep_TOI_event_buf(thd, &buf, &buf_len);
|
||||
|
||||
if (buf_err) {
|
||||
WSREP_ERROR("Failed to create TOI event buf: %d", buf_err);
|
||||
my_message(ER_UNKNOWN_ERROR,
|
||||
@ -1987,6 +2041,7 @@ static int wsrep_TOI_begin(THD *thd, const char *db, const char *table,
|
||||
MYF(0));
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct wsrep_buf buff= { buf, buf_len };
|
||||
|
||||
wsrep::key_array key_array=
|
||||
@ -1997,7 +2052,7 @@ static int wsrep_TOI_begin(THD *thd, const char *db, const char *table,
|
||||
/* non replicated DDL, affecting temporary tables only */
|
||||
WSREP_DEBUG("TO isolation skipped, sql: %s."
|
||||
"Only temporary tables affected.",
|
||||
WSREP_QUERY(thd));
|
||||
wsrep_thd_query(thd));
|
||||
if (buf) my_free(buf);
|
||||
return -1;
|
||||
}
|
||||
@ -2005,6 +2060,7 @@ static int wsrep_TOI_begin(THD *thd, const char *db, const char *table,
|
||||
thd_proc_info(thd, "acquiring total order isolation");
|
||||
|
||||
wsrep::client_state& cs(thd->wsrep_cs());
|
||||
|
||||
int ret= cs.enter_toi_local(key_array,
|
||||
wsrep::const_buffer(buff.ptr, buff.len));
|
||||
|
||||
@ -2012,7 +2068,7 @@ static int wsrep_TOI_begin(THD *thd, const char *db, const char *table,
|
||||
{
|
||||
DBUG_ASSERT(cs.current_error());
|
||||
WSREP_DEBUG("to_execute_start() failed for %llu: %s, seqno: %lld",
|
||||
thd->thread_id, WSREP_QUERY(thd),
|
||||
thd->thread_id, wsrep_thd_query(thd),
|
||||
(long long)wsrep_thd_trx_seqno(thd));
|
||||
|
||||
/* jump to error handler in mysql_execute_command() */
|
||||
@ -2023,7 +2079,7 @@ static int wsrep_TOI_begin(THD *thd, const char *db, const char *table,
|
||||
"Maximum size exceeded.",
|
||||
ret,
|
||||
(thd->db.str ? thd->db.str : "(null)"),
|
||||
WSREP_QUERY(thd));
|
||||
wsrep_thd_query(thd));
|
||||
my_error(ER_ERROR_DURING_COMMIT, MYF(0), WSREP_SIZE_EXCEEDED);
|
||||
break;
|
||||
default:
|
||||
@ -2031,7 +2087,7 @@ static int wsrep_TOI_begin(THD *thd, const char *db, const char *table,
|
||||
"Check wsrep connection state and retry the query.",
|
||||
ret,
|
||||
(thd->db.str ? thd->db.str : "(null)"),
|
||||
WSREP_QUERY(thd));
|
||||
wsrep_thd_query(thd));
|
||||
if (!thd->is_error())
|
||||
{
|
||||
my_error(ER_LOCK_DEADLOCK, MYF(0), "WSREP replication failed. Check "
|
||||
@ -2079,7 +2135,7 @@ static void wsrep_TOI_end(THD *thd) {
|
||||
wsrep::client_state& client_state(thd->wsrep_cs());
|
||||
DBUG_ASSERT(wsrep_thd_is_local_toi(thd));
|
||||
WSREP_DEBUG("TO END: %lld: %s", client_state.toi_meta().seqno().get(),
|
||||
WSREP_QUERY(thd));
|
||||
wsrep_thd_query(thd));
|
||||
|
||||
wsrep_gtid_server.signal_waiters(thd->wsrep_current_gtid_seqno, false);
|
||||
|
||||
@ -2104,7 +2160,7 @@ static void wsrep_TOI_end(THD *thd) {
|
||||
else
|
||||
{
|
||||
WSREP_WARN("TO isolation end failed for: %d, schema: %s, sql: %s",
|
||||
ret, (thd->db.str ? thd->db.str : "(null)"), WSREP_QUERY(thd));
|
||||
ret, (thd->db.str ? thd->db.str : "(null)"), wsrep_thd_query(thd));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2112,7 +2168,7 @@ static void wsrep_TOI_end(THD *thd) {
|
||||
static int wsrep_RSU_begin(THD *thd, const char *db_, const char *table_)
|
||||
{
|
||||
WSREP_DEBUG("RSU BEGIN: %lld, : %s", wsrep_thd_trx_seqno(thd),
|
||||
WSREP_QUERY(thd));
|
||||
wsrep_thd_query(thd));
|
||||
if (thd->wsrep_cs().begin_rsu(5000))
|
||||
{
|
||||
WSREP_WARN("RSU begin failed");
|
||||
@ -2127,7 +2183,7 @@ static int wsrep_RSU_begin(THD *thd, const char *db_, const char *table_)
|
||||
static void wsrep_RSU_end(THD *thd)
|
||||
{
|
||||
WSREP_DEBUG("RSU END: %lld : %s", wsrep_thd_trx_seqno(thd),
|
||||
WSREP_QUERY(thd));
|
||||
wsrep_thd_query(thd));
|
||||
if (thd->wsrep_cs().end_rsu())
|
||||
{
|
||||
WSREP_WARN("Failed to end RSU, server may need to be restarted");
|
||||
@ -2137,7 +2193,8 @@ static void wsrep_RSU_end(THD *thd)
|
||||
|
||||
int wsrep_to_isolation_begin(THD *thd, const char *db_, const char *table_,
|
||||
const TABLE_LIST* table_list,
|
||||
Alter_info* alter_info)
|
||||
const Alter_info* alter_info,
|
||||
const HA_CREATE_INFO* create_info)
|
||||
{
|
||||
/*
|
||||
No isolation for applier or replaying threads.
|
||||
@ -2162,14 +2219,14 @@ int wsrep_to_isolation_begin(THD *thd, const char *db_, const char *table_,
|
||||
if (thd->global_read_lock.is_acquired())
|
||||
{
|
||||
WSREP_DEBUG("Aborting TOI: Global Read-Lock (FTWRL) in place: %s %llu",
|
||||
WSREP_QUERY(thd), thd->thread_id);
|
||||
wsrep_thd_query(thd), thd->thread_id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (wsrep_debug && thd->mdl_context.has_locks())
|
||||
{
|
||||
WSREP_DEBUG("thread holds MDL locks at TI begin: %s %llu",
|
||||
WSREP_QUERY(thd), thd->thread_id);
|
||||
wsrep_thd_query(thd), thd->thread_id);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2187,24 +2244,24 @@ int wsrep_to_isolation_begin(THD *thd, const char *db_, const char *table_,
|
||||
|
||||
if (thd->variables.wsrep_on && wsrep_thd_is_local(thd))
|
||||
{
|
||||
switch (thd->variables.wsrep_OSU_method) {
|
||||
switch (wsrep_OSU_method_get(thd)) {
|
||||
case WSREP_OSU_TOI:
|
||||
ret= wsrep_TOI_begin(thd, db_, table_, table_list, alter_info);
|
||||
ret= wsrep_TOI_begin(thd, db_, table_, table_list, alter_info, create_info);
|
||||
break;
|
||||
case WSREP_OSU_RSU:
|
||||
ret= wsrep_RSU_begin(thd, db_, table_);
|
||||
break;
|
||||
default:
|
||||
WSREP_ERROR("Unsupported OSU method: %lu",
|
||||
thd->variables.wsrep_OSU_method);
|
||||
wsrep_OSU_method_get(thd));
|
||||
ret= -1;
|
||||
break;
|
||||
}
|
||||
switch (ret) {
|
||||
case 0: /* wsrep_TOI_begin sould set toi mode */ break;
|
||||
case 0: /* wsrep_TOI_begin should set toi mode */ break;
|
||||
case 1:
|
||||
/* TOI replication skipped, treat as success */
|
||||
ret= 0;
|
||||
/* TOI replication skipped, treat as success */
|
||||
ret= 0;
|
||||
break;
|
||||
case -1:
|
||||
/* TOI replication failed, treat as error */
|
||||
@ -2221,12 +2278,12 @@ void wsrep_to_isolation_end(THD *thd)
|
||||
wsrep_thd_is_in_rsu(thd));
|
||||
if (wsrep_thd_is_local_toi(thd))
|
||||
{
|
||||
DBUG_ASSERT(thd->variables.wsrep_OSU_method == WSREP_OSU_TOI);
|
||||
DBUG_ASSERT(wsrep_OSU_method_get(thd) == WSREP_OSU_TOI);
|
||||
wsrep_TOI_end(thd);
|
||||
}
|
||||
else if (wsrep_thd_is_in_rsu(thd))
|
||||
{
|
||||
DBUG_ASSERT(thd->variables.wsrep_OSU_method == WSREP_OSU_RSU);
|
||||
DBUG_ASSERT(wsrep_OSU_method_get(thd) == WSREP_OSU_RSU);
|
||||
wsrep_RSU_end(thd);
|
||||
}
|
||||
else
|
||||
@ -2678,17 +2735,17 @@ bool wsrep_create_like_table(THD* thd, TABLE_LIST* table,
|
||||
if (create_info->tmp_table())
|
||||
{
|
||||
/* CREATE TEMPORARY TABLE LIKE must be skipped from replication */
|
||||
WSREP_DEBUG("CREATE TEMPORARY TABLE LIKE... skipped replication\n %s",
|
||||
WSREP_DEBUG("CREATE TEMPORARY TABLE LIKE... skipped replication\n %s",
|
||||
thd->query());
|
||||
}
|
||||
else if (!(thd->find_temporary_table(src_table)))
|
||||
{
|
||||
/* this is straight CREATE TABLE LIKE... with no tmp tables */
|
||||
WSREP_TO_ISOLATION_BEGIN(table->db.str, table->table_name.str, NULL);
|
||||
WSREP_TO_ISOLATION_BEGIN_CREATE(table->db.str, table->table_name.str, table, create_info);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* here we have CREATE TABLE LIKE <temporary table>
|
||||
/* here we have CREATE TABLE LIKE <temporary table>
|
||||
the temporary table definition will be needed in slaves to
|
||||
enable the create to succeed
|
||||
*/
|
||||
@ -2707,7 +2764,7 @@ bool wsrep_create_like_table(THD* thd, TABLE_LIST* table,
|
||||
thd->wsrep_TOI_pre_query= query.ptr();
|
||||
thd->wsrep_TOI_pre_query_len= query.length();
|
||||
|
||||
WSREP_TO_ISOLATION_BEGIN(table->db.str, table->table_name.str, NULL);
|
||||
WSREP_TO_ISOLATION_BEGIN_CREATE(table->db.str, table->table_name.str, table, create_info);
|
||||
|
||||
thd->wsrep_TOI_pre_query= NULL;
|
||||
thd->wsrep_TOI_pre_query_len= 0;
|
||||
|
@ -98,6 +98,7 @@ extern ulong wsrep_running_applier_threads;
|
||||
extern ulong wsrep_running_rollbacker_threads;
|
||||
extern bool wsrep_new_cluster;
|
||||
extern bool wsrep_gtid_mode;
|
||||
extern my_bool wsrep_strict_ddl;
|
||||
|
||||
enum enum_wsrep_reject_types {
|
||||
WSREP_REJECT_NONE, /* nothing rejected */
|
||||
@ -108,7 +109,7 @@ enum enum_wsrep_reject_types {
|
||||
enum enum_wsrep_OSU_method {
|
||||
WSREP_OSU_TOI,
|
||||
WSREP_OSU_RSU,
|
||||
WSREP_OSU_NONE,
|
||||
WSREP_OSU_NONE
|
||||
};
|
||||
|
||||
enum enum_wsrep_sync_wait {
|
||||
@ -360,9 +361,15 @@ extern PSI_thread_key key_wsrep_sst_donor_monitor;
|
||||
|
||||
struct TABLE_LIST;
|
||||
class Alter_info;
|
||||
struct HA_CREATE_INFO;
|
||||
|
||||
int wsrep_to_isolation_begin(THD *thd, const char *db_, const char *table_,
|
||||
const TABLE_LIST* table_list,
|
||||
Alter_info* alter_info= NULL);
|
||||
const Alter_info* alter_info= NULL,
|
||||
const HA_CREATE_INFO* create_info= NULL);
|
||||
|
||||
bool wsrep_should_replicate_ddl(THD* thd, const enum legacy_db_type db_type);
|
||||
bool wsrep_should_replicate_ddl_iterate(THD* thd, const TABLE_LIST* table_list);
|
||||
|
||||
void wsrep_to_isolation_end(THD *thd);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user