mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
MDEV-24830 : Write a warning to error log if Galera replicates InnoDB table with no primary key
Two new features for Galera * Write a warning to error log if Galera replicates table with storage engine not supported by Galera (at the moment only InnoDB is supported ** Warning is pushed to client also ** MyISAM is allowed if wsrep_replicate_myisam=ON * Write a warning to error log if Galera replicates table with no primary key ** Warning is pushed to client also ** MyISAM is allowed if wsrep_relicate_myisam=ON * In both cases apply flood control if > 10 same warning is writen to error log (requires log_warnings > 1), flood control will suppress warnings for 300 seconds
This commit is contained in:
@ -26,9 +26,7 @@ SELECT @@default_storage_engine;
|
||||
@@default_storage_engine
|
||||
MyISAM
|
||||
SET GLOBAL wsrep_replicate_myisam=OFF;
|
||||
SET GLOBAL wsrep_strict_ddl=ON;
|
||||
Warnings:
|
||||
Warning 1287 '@@wsrep_strict_ddl' is deprecated and will be removed in a future release. Please use '@@wsrep_mode=STRICT_REPLICATION' instead
|
||||
SET GLOBAL wsrep_mode=STRICT_REPLICATION;
|
||||
CREATE TABLE t3 (c1 VARCHAR(10)) ENGINE=InnoDB;
|
||||
ALTER TABLE t3 ENGINE=NonExistentEngine;
|
||||
ERROR HY000: Galera replication not supported
|
||||
@ -38,5 +36,3 @@ t3 CREATE TABLE `t3` (
|
||||
`c1` varchar(10) DEFAULT NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1
|
||||
DROP TABLE t3;
|
||||
Warnings:
|
||||
Warning 1287 '@@wsrep_strict_ddl' is deprecated and will be removed in a future release. Please use '@@wsrep_mode=STRICT_REPLICATION' instead
|
||||
|
@ -0,0 +1,92 @@
|
||||
connection node_2;
|
||||
connection node_1;
|
||||
call mtr.add_suppression("WSREP: wsrep_mode = STRICT_REPLICATION enabled. Storage engine .*");
|
||||
CREATE TABLE t1(a int NOT NULL PRIMARY KEY, b varchar(50)) ENGINE=INNODB;
|
||||
CREATE TABLE t2(a int NOT NULL PRIMARY KEY, b varchar(50)) ENGINE=MYISAM;
|
||||
CREATE TABLE t3(a int NOT NULL PRIMARY KEY, b varchar(50)) ENGINE=ARIA;
|
||||
CREATE TABLE t4(a int NOT NULL PRIMARY KEY, b varchar(50)) ENGINE=MEMORY;
|
||||
SET GLOBAL wsrep_replicate_myisam=ON;
|
||||
SET GLOBAL log_warnings=2;
|
||||
SET GLOBAL wsrep_mode= STRICT_REPLICATION;
|
||||
INSERT INTO t1 values (1,'innodb1');
|
||||
INSERT INTO t2 values (1,'myisam1');
|
||||
INSERT INTO t3 values (1,'aria1');
|
||||
Warnings:
|
||||
Warning 1290 WSREP: wsrep_mode = STRICT_REPLICATION enabled. Storage engine Aria for table 'test'.'t3' is not supported in Galera
|
||||
INSERT INTO t4 values (1,'memory1');
|
||||
Warnings:
|
||||
Warning 1290 WSREP: wsrep_mode = STRICT_REPLICATION enabled. Storage engine MEMORY for table 'test'.'t4' is not supported in Galera
|
||||
SET GLOBAL wsrep_replicate_myisam=OFF;
|
||||
INSERT INTO t2 values (2,'myisam2');
|
||||
Warnings:
|
||||
Warning 1290 WSREP: wsrep_mode = STRICT_REPLICATION enabled. Storage engine MyISAM for table 'test'.'t2' is not supported in Galera
|
||||
SET GLOBAL log_warnings=1;
|
||||
INSERT INTO t1 values (2,'innodb2');
|
||||
INSERT INTO t2 values (3,'myisam3');
|
||||
Warnings:
|
||||
Warning 1290 WSREP: wsrep_mode = STRICT_REPLICATION enabled. Storage engine MyISAM for table 'test'.'t2' is not supported in Galera
|
||||
INSERT INTO t3 values (2,'aria2');
|
||||
Warnings:
|
||||
Warning 1290 WSREP: wsrep_mode = STRICT_REPLICATION enabled. Storage engine Aria for table 'test'.'t3' is not supported in Galera
|
||||
INSERT INTO t4 values (2,'memory2');
|
||||
Warnings:
|
||||
Warning 1290 WSREP: wsrep_mode = STRICT_REPLICATION enabled. Storage engine MEMORY for table 'test'.'t4' is not supported in Galera
|
||||
include/assert_grep.inc [WSREP: wsrep_mode = STRICT_REPLICATION enabled.]
|
||||
SET GLOBAL log_warnings=2;
|
||||
INSERT INTO t2 values (4,'myisam3');
|
||||
Warnings:
|
||||
Warning 1290 WSREP: wsrep_mode = STRICT_REPLICATION enabled. Storage engine MyISAM for table 'test'.'t2' is not supported in Galera
|
||||
INSERT INTO t3 values (4,'aria2');
|
||||
Warnings:
|
||||
Warning 1290 WSREP: wsrep_mode = STRICT_REPLICATION enabled. Storage engine Aria for table 'test'.'t3' is not supported in Galera
|
||||
INSERT INTO t4 values (4,'memory2');
|
||||
Warnings:
|
||||
Warning 1290 WSREP: wsrep_mode = STRICT_REPLICATION enabled. Storage engine MEMORY for table 'test'.'t4' is not supported in Galera
|
||||
INSERT INTO t2 values (5,'myisam3');
|
||||
Warnings:
|
||||
Warning 1290 WSREP: wsrep_mode = STRICT_REPLICATION enabled. Storage engine MyISAM for table 'test'.'t2' is not supported in Galera
|
||||
INSERT INTO t3 values (5,'aria2');
|
||||
Warnings:
|
||||
Warning 1290 WSREP: wsrep_mode = STRICT_REPLICATION enabled. Storage engine Aria for table 'test'.'t3' is not supported in Galera
|
||||
INSERT INTO t4 values (5,'memory2');
|
||||
Warnings:
|
||||
Warning 1290 WSREP: wsrep_mode = STRICT_REPLICATION enabled. Storage engine MEMORY for table 'test'.'t4' is not supported in Galera
|
||||
INSERT INTO t2 values (6,'myisam3');
|
||||
Warnings:
|
||||
Warning 1290 WSREP: wsrep_mode = STRICT_REPLICATION enabled. Storage engine MyISAM for table 'test'.'t2' is not supported in Galera
|
||||
INSERT INTO t3 values (6,'aria2');
|
||||
Warnings:
|
||||
Warning 1290 WSREP: wsrep_mode = STRICT_REPLICATION enabled. Storage engine Aria for table 'test'.'t3' is not supported in Galera
|
||||
INSERT INTO t4 values (6,'memory2');
|
||||
Warnings:
|
||||
Warning 1290 WSREP: wsrep_mode = STRICT_REPLICATION enabled. Storage engine MEMORY for table 'test'.'t4' is not supported in Galera
|
||||
SELECT COUNT(*) AS EXPECT_2 FROM t1;
|
||||
EXPECT_2
|
||||
2
|
||||
SELECT COUNT(*) AS EXPECT_6 FROM t2;
|
||||
EXPECT_6
|
||||
6
|
||||
SELECT COUNT(*) AS EXPECT_5 FROM t3;
|
||||
EXPECT_5
|
||||
5
|
||||
SELECT COUNT(*) AS EXPECT_5 FROM t4;
|
||||
EXPECT_5
|
||||
5
|
||||
connection node_2;
|
||||
SELECT COUNT(*) AS EXPECT_2 FROM t1;
|
||||
EXPECT_2
|
||||
2
|
||||
SELECT COUNT(*) AS EXPECT_1 FROM t2;
|
||||
EXPECT_1
|
||||
1
|
||||
SELECT COUNT(*) AS EXPECT_0 FROM t3;
|
||||
EXPECT_0
|
||||
0
|
||||
SELECT COUNT(*) AS EXPECT_0 FROM t4;
|
||||
EXPECT_0
|
||||
0
|
||||
connection node_1;
|
||||
SET GLOBAL wsrep_mode= DEFAULT;
|
||||
DROP TABLE t1,t2,t3,t4;
|
||||
include/assert_grep.inc [WSREP: wsrep_mode = STRICT_REPLICATION enabled.]
|
||||
include/assert_grep.inc [WSREP: Suppressing warnings of type 'WSREP_REQUIRE_INNODB' for up to 300 seconds because of flooding]
|
@ -0,0 +1,86 @@
|
||||
connection node_2;
|
||||
connection node_1;
|
||||
call mtr.add_suppression("WSREP: wsrep_mode = REQUIRED_PRIMARY_KEY enabled. Table .*");
|
||||
CREATE TABLE t1(a int, b varchar(50)) ENGINE=INNODB;
|
||||
CREATE TABLE t2(a int, b varchar(50)) ENGINE=MYISAM;
|
||||
CREATE TABLE t3(a int, b varchar(50)) ENGINE=MEMORY;
|
||||
SET GLOBAL wsrep_replicate_myisam=ON;
|
||||
SET GLOBAL log_warnings=2;
|
||||
SET GLOBAL wsrep_mode= REQUIRED_PRIMARY_KEY;
|
||||
INSERT INTO t1 values (1,'test1');
|
||||
Warnings:
|
||||
Warning 1290 WSREP: wsrep_mode = REQUIRED_PRIMARY_KEY enabled. Table 'test'.'t1' should have PRIMARY KEY defined.
|
||||
INSERT INTO t2 values (1,'myisam1');
|
||||
Warnings:
|
||||
Warning 1290 WSREP: wsrep_mode = REQUIRED_PRIMARY_KEY enabled. Table 'test'.'t2' should have PRIMARY KEY defined.
|
||||
INSERT INTO t3 values (1,'memory');
|
||||
SET GLOBAL wsrep_replicate_myisam=OFF;
|
||||
INSERT INTO t2 values (2,'mysam2');
|
||||
INSERT INTO t1 values (2,'test2');
|
||||
Warnings:
|
||||
Warning 1290 WSREP: wsrep_mode = REQUIRED_PRIMARY_KEY enabled. Table 'test'.'t1' should have PRIMARY KEY defined.
|
||||
INSERT INTO t1 values (3,'test3');
|
||||
Warnings:
|
||||
Warning 1290 WSREP: wsrep_mode = REQUIRED_PRIMARY_KEY enabled. Table 'test'.'t1' should have PRIMARY KEY defined.
|
||||
INSERT INTO t1 values (4,'test4');
|
||||
Warnings:
|
||||
Warning 1290 WSREP: wsrep_mode = REQUIRED_PRIMARY_KEY enabled. Table 'test'.'t1' should have PRIMARY KEY defined.
|
||||
INSERT INTO t1 values (5,'test5');
|
||||
Warnings:
|
||||
Warning 1290 WSREP: wsrep_mode = REQUIRED_PRIMARY_KEY enabled. Table 'test'.'t1' should have PRIMARY KEY defined.
|
||||
SET GLOBAL log_warnings=1;
|
||||
INSERT INTO t1 values (21,'not1');
|
||||
Warnings:
|
||||
Warning 1290 WSREP: wsrep_mode = REQUIRED_PRIMARY_KEY enabled. Table 'test'.'t1' should have PRIMARY KEY defined.
|
||||
INSERT INTO t1 values (22,'not2');
|
||||
Warnings:
|
||||
Warning 1290 WSREP: wsrep_mode = REQUIRED_PRIMARY_KEY enabled. Table 'test'.'t1' should have PRIMARY KEY defined.
|
||||
include/assert_grep.inc [WSREP: wsrep_mode = REQUIRED_PRIMARY_KEY enabled.]
|
||||
SET GLOBAL log_warnings=2;
|
||||
INSERT INTO t1 values (6,'test6');
|
||||
Warnings:
|
||||
Warning 1290 WSREP: wsrep_mode = REQUIRED_PRIMARY_KEY enabled. Table 'test'.'t1' should have PRIMARY KEY defined.
|
||||
INSERT INTO t1 values (7,'test7');
|
||||
Warnings:
|
||||
Warning 1290 WSREP: wsrep_mode = REQUIRED_PRIMARY_KEY enabled. Table 'test'.'t1' should have PRIMARY KEY defined.
|
||||
INSERT INTO t1 values (8,'test8');
|
||||
Warnings:
|
||||
Warning 1290 WSREP: wsrep_mode = REQUIRED_PRIMARY_KEY enabled. Table 'test'.'t1' should have PRIMARY KEY defined.
|
||||
INSERT INTO t1 values (9,'test9');
|
||||
Warnings:
|
||||
Warning 1290 WSREP: wsrep_mode = REQUIRED_PRIMARY_KEY enabled. Table 'test'.'t1' should have PRIMARY KEY defined.
|
||||
INSERT INTO t1 values (10,'test10');
|
||||
Warnings:
|
||||
Warning 1290 WSREP: wsrep_mode = REQUIRED_PRIMARY_KEY enabled. Table 'test'.'t1' should have PRIMARY KEY defined.
|
||||
INSERT INTO t1 values (11,'test11');
|
||||
Warnings:
|
||||
Warning 1290 WSREP: wsrep_mode = REQUIRED_PRIMARY_KEY enabled. Table 'test'.'t1' should have PRIMARY KEY defined.
|
||||
INSERT INTO t1 values (12,'test12');
|
||||
Warnings:
|
||||
Warning 1290 WSREP: wsrep_mode = REQUIRED_PRIMARY_KEY enabled. Table 'test'.'t1' should have PRIMARY KEY defined.
|
||||
INSERT INTO t1 values (13,'test13');
|
||||
Warnings:
|
||||
Warning 1290 WSREP: wsrep_mode = REQUIRED_PRIMARY_KEY enabled. Table 'test'.'t1' should have PRIMARY KEY defined.
|
||||
SELECT COUNT(*) AS EXPECT_15 FROM t1;
|
||||
EXPECT_15
|
||||
15
|
||||
SELECT COUNT(*) AS EXPECT_2 FROM t2;
|
||||
EXPECT_2
|
||||
2
|
||||
SELECT COUNT(*) AS EXPECT_1 FROM t3;
|
||||
EXPECT_1
|
||||
1
|
||||
connection node_2;
|
||||
SELECT COUNT(*) AS EXPECT_15 FROM t1;
|
||||
EXPECT_15
|
||||
15
|
||||
SELECT COUNT(*) AS EXPECT_1 FROM t2;
|
||||
EXPECT_1
|
||||
1
|
||||
SELECT COUNT(*) AS EXPECT_0 FROM t3;
|
||||
EXPECT_0
|
||||
0
|
||||
connection node_1;
|
||||
DROP TABLE t1,t2,t3;
|
||||
include/assert_grep.inc [WSREP: wsrep_mode = REQUIRED_PRIMARY_KEY enabled.]
|
||||
include/assert_grep.inc [WSREP: Suppressing warnings of type 'WSREP_REQUIRE_PRIMARY_KEY' for up to 300 seconds because of flooding]
|
@ -19,7 +19,7 @@ SET sql_mode='';
|
||||
SET SESSION default_storage_engine=MyISAM;
|
||||
SELECT @@default_storage_engine;
|
||||
SET GLOBAL wsrep_replicate_myisam=OFF;
|
||||
SET GLOBAL wsrep_strict_ddl=ON;
|
||||
SET GLOBAL wsrep_mode=STRICT_REPLICATION;
|
||||
CREATE TABLE t3 (c1 VARCHAR(10)) ENGINE=InnoDB;
|
||||
--error ER_GALERA_REPLICATION_NOT_SUPPORTED
|
||||
ALTER TABLE t3 ENGINE=NonExistentEngine;
|
||||
@ -30,5 +30,5 @@ DROP TABLE t3;
|
||||
SET GLOBAL sql_mode=default;
|
||||
SET GLOBAL default_storage_engine=default;
|
||||
SET GLOBAL wsrep_replicate_myisam=default;
|
||||
SET GLOBAL wsrep_strict_ddl=default;
|
||||
SET GLOBAL wsrep_mode=default;
|
||||
--enable_query_log
|
||||
|
95
mysql-test/suite/galera/t/galera_strict_require_innodb.test
Normal file
95
mysql-test/suite/galera/t/galera_strict_require_innodb.test
Normal file
@ -0,0 +1,95 @@
|
||||
#
|
||||
# Write a warning to error log if Galera replicates table with storage engine
|
||||
# not supported by Galera
|
||||
#
|
||||
# For MyISAM
|
||||
# * push warning to client if wsrep_mode == STRICT_REPLICATION and wsrep_replicate_myisam=off
|
||||
# * push warning to error log if log_warnings > 1
|
||||
# For Memory
|
||||
# * push warning to client if wsrep_mode == STRICT_REPLICATION
|
||||
# * push warning to error log if log_warnings > 1
|
||||
# ( Note here Aria and case wsrep_replicate_aria=ON)
|
||||
#
|
||||
# In both cases apply flood control if > 10 same warning
|
||||
#
|
||||
--source include/galera_cluster.inc
|
||||
--source include/have_aria.inc
|
||||
|
||||
call mtr.add_suppression("WSREP: wsrep_mode = STRICT_REPLICATION enabled. Storage engine .*");
|
||||
|
||||
CREATE TABLE t1(a int NOT NULL PRIMARY KEY, b varchar(50)) ENGINE=INNODB;
|
||||
CREATE TABLE t2(a int NOT NULL PRIMARY KEY, b varchar(50)) ENGINE=MYISAM;
|
||||
CREATE TABLE t3(a int NOT NULL PRIMARY KEY, b varchar(50)) ENGINE=ARIA;
|
||||
CREATE TABLE t4(a int NOT NULL PRIMARY KEY, b varchar(50)) ENGINE=MEMORY;
|
||||
|
||||
SET GLOBAL wsrep_replicate_myisam=ON;
|
||||
SET GLOBAL log_warnings=2;
|
||||
SET GLOBAL wsrep_mode= STRICT_REPLICATION;
|
||||
|
||||
INSERT INTO t1 values (1,'innodb1');
|
||||
INSERT INTO t2 values (1,'myisam1');
|
||||
INSERT INTO t3 values (1,'aria1');
|
||||
INSERT INTO t4 values (1,'memory1');
|
||||
|
||||
SET GLOBAL wsrep_replicate_myisam=OFF;
|
||||
INSERT INTO t2 values (2,'myisam2');
|
||||
|
||||
SET GLOBAL log_warnings=1;
|
||||
INSERT INTO t1 values (2,'innodb2');
|
||||
INSERT INTO t2 values (3,'myisam3');
|
||||
INSERT INTO t3 values (2,'aria2');
|
||||
INSERT INTO t4 values (2,'memory2');
|
||||
|
||||
# test flood control
|
||||
--let $assert_count = 3
|
||||
--let $assert_file = $MYSQLTEST_VARDIR/log/mysqld.1.err
|
||||
--let $assert_text = WSREP: wsrep_mode = STRICT_REPLICATION enabled.
|
||||
--let $assert_select = WSREP: wsrep_mode = STRICT_REPLICATION enabled.
|
||||
--source include/assert_grep.inc
|
||||
|
||||
SET GLOBAL log_warnings=2;
|
||||
INSERT INTO t2 values (4,'myisam3');
|
||||
INSERT INTO t3 values (4,'aria2');
|
||||
INSERT INTO t4 values (4,'memory2');
|
||||
INSERT INTO t2 values (5,'myisam3');
|
||||
INSERT INTO t3 values (5,'aria2');
|
||||
INSERT INTO t4 values (5,'memory2');
|
||||
INSERT INTO t2 values (6,'myisam3');
|
||||
INSERT INTO t3 values (6,'aria2');
|
||||
INSERT INTO t4 values (6,'memory2');
|
||||
|
||||
SELECT COUNT(*) AS EXPECT_2 FROM t1;
|
||||
SELECT COUNT(*) AS EXPECT_6 FROM t2;
|
||||
SELECT COUNT(*) AS EXPECT_5 FROM t3;
|
||||
SELECT COUNT(*) AS EXPECT_5 FROM t4;
|
||||
|
||||
--connection node_2
|
||||
SELECT COUNT(*) AS EXPECT_2 FROM t1;
|
||||
SELECT COUNT(*) AS EXPECT_1 FROM t2;
|
||||
SELECT COUNT(*) AS EXPECT_0 FROM t3;
|
||||
SELECT COUNT(*) AS EXPECT_0 FROM t4;
|
||||
|
||||
--connection node_1
|
||||
SET GLOBAL wsrep_mode= DEFAULT;
|
||||
DROP TABLE t1,t2,t3,t4;
|
||||
|
||||
#
|
||||
# Verify no flood
|
||||
#
|
||||
--let $assert_count = 10
|
||||
--let $assert_file = $MYSQLTEST_VARDIR/log/mysqld.1.err
|
||||
--let $assert_text = WSREP: wsrep_mode = STRICT_REPLICATION enabled.
|
||||
--let $assert_select = WSREP: wsrep_mode = STRICT_REPLICATION enabled.
|
||||
--source include/assert_grep.inc
|
||||
--let $assert_count = 1
|
||||
--let $assert_text = WSREP: Suppressing warnings of type 'WSREP_REQUIRE_INNODB' for up to 300 seconds because of flooding
|
||||
--let $assert_select = WSREP: Suppressing warnings of type 'WSREP_REQUIRE_INNODB' for up to 300 seconds because of flooding
|
||||
--source include/assert_grep.inc
|
||||
|
||||
# reset env
|
||||
--disable_query_log
|
||||
SET GLOBAL wsrep_replicate_myisam=DEFAULT;
|
||||
SET GLOBAL log_warnings=DEFAULT;
|
||||
SET GLOBAL wsrep_mode=DEFAULT;
|
||||
--disable_query_log
|
||||
|
@ -0,0 +1,90 @@
|
||||
#
|
||||
# Write a warning to error log if Galera replicates table with no primary key
|
||||
#
|
||||
# For InnoDB
|
||||
# * push warning to client if wsrep_mode == REQUIRED_PRIMARY_KEY
|
||||
# * push warning to error log if log_warnings > 1
|
||||
# For MyIsam
|
||||
# * push warning if wsrep_replicate_myisam=ON
|
||||
#
|
||||
# In both cases apply flood control if > 10 same warning
|
||||
#
|
||||
--source include/galera_cluster.inc
|
||||
|
||||
call mtr.add_suppression("WSREP: wsrep_mode = REQUIRED_PRIMARY_KEY enabled. Table .*");
|
||||
|
||||
CREATE TABLE t1(a int, b varchar(50)) ENGINE=INNODB;
|
||||
CREATE TABLE t2(a int, b varchar(50)) ENGINE=MYISAM;
|
||||
CREATE TABLE t3(a int, b varchar(50)) ENGINE=MEMORY;
|
||||
|
||||
SET GLOBAL wsrep_replicate_myisam=ON;
|
||||
SET GLOBAL log_warnings=2;
|
||||
SET GLOBAL wsrep_mode= REQUIRED_PRIMARY_KEY;
|
||||
|
||||
INSERT INTO t1 values (1,'test1');
|
||||
INSERT INTO t2 values (1,'myisam1');
|
||||
INSERT INTO t3 values (1,'memory');
|
||||
|
||||
SET GLOBAL wsrep_replicate_myisam=OFF;
|
||||
INSERT INTO t2 values (2,'mysam2');
|
||||
|
||||
# test flood control
|
||||
INSERT INTO t1 values (2,'test2');
|
||||
INSERT INTO t1 values (3,'test3');
|
||||
INSERT INTO t1 values (4,'test4');
|
||||
INSERT INTO t1 values (5,'test5');
|
||||
|
||||
# these should not write warning to error log
|
||||
SET GLOBAL log_warnings=1;
|
||||
INSERT INTO t1 values (21,'not1');
|
||||
INSERT INTO t1 values (22,'not2');
|
||||
|
||||
--let $assert_count = 6
|
||||
--let $assert_file = $MYSQLTEST_VARDIR/log/mysqld.1.err
|
||||
--let $assert_text = WSREP: wsrep_mode = REQUIRED_PRIMARY_KEY enabled.
|
||||
--let $assert_select = WSREP: wsrep_mode = REQUIRED_PRIMARY_KEY enabled.
|
||||
--source include/assert_grep.inc
|
||||
|
||||
# force flood
|
||||
SET GLOBAL log_warnings=2;
|
||||
INSERT INTO t1 values (6,'test6');
|
||||
INSERT INTO t1 values (7,'test7');
|
||||
INSERT INTO t1 values (8,'test8');
|
||||
INSERT INTO t1 values (9,'test9');
|
||||
INSERT INTO t1 values (10,'test10');
|
||||
INSERT INTO t1 values (11,'test11');
|
||||
INSERT INTO t1 values (12,'test12');
|
||||
INSERT INTO t1 values (13,'test13');
|
||||
|
||||
SELECT COUNT(*) AS EXPECT_15 FROM t1;
|
||||
SELECT COUNT(*) AS EXPECT_2 FROM t2;
|
||||
SELECT COUNT(*) AS EXPECT_1 FROM t3;
|
||||
|
||||
--connection node_2
|
||||
SELECT COUNT(*) AS EXPECT_15 FROM t1;
|
||||
SELECT COUNT(*) AS EXPECT_1 FROM t2;
|
||||
SELECT COUNT(*) AS EXPECT_0 FROM t3;
|
||||
|
||||
--connection node_1
|
||||
DROP TABLE t1,t2,t3;
|
||||
|
||||
#
|
||||
# Verify warning is on error log and check that no flood
|
||||
#
|
||||
--let $assert_count = 9
|
||||
--let $assert_file = $MYSQLTEST_VARDIR/log/mysqld.1.err
|
||||
--let $assert_text = WSREP: wsrep_mode = REQUIRED_PRIMARY_KEY enabled.
|
||||
--let $assert_select = WSREP: wsrep_mode = REQUIRED_PRIMARY_KEY enabled.
|
||||
--source include/assert_grep.inc
|
||||
--let $assert_count = 1
|
||||
--let $assert_text = WSREP: Suppressing warnings of type 'WSREP_REQUIRE_PRIMARY_KEY' for up to 300 seconds because of flooding
|
||||
--let $assert_select = WSREP: Suppressing warnings of type 'WSREP_REQUIRE_PRIMARY_KEY' for up to 300 seconds because of flooding
|
||||
--source include/assert_grep.inc
|
||||
|
||||
# reset env
|
||||
--disable_query_log
|
||||
SET GLOBAL wsrep_replicate_myisam=DEFAULT;
|
||||
SET GLOBAL log_warnings=DEFAULT;
|
||||
SET GLOBAL wsrep_mode=DEFAULT;
|
||||
--disable_query_log
|
||||
|
@ -4437,7 +4437,10 @@ restart:
|
||||
*/
|
||||
if (WSREP(thd) &&
|
||||
wsrep_thd_is_local(thd) &&
|
||||
!wsrep_check_mode_after_open_table(thd, tbl->file->ht->db_type))
|
||||
tbl &&
|
||||
tables == *start &&
|
||||
!wsrep_check_mode_after_open_table(thd,
|
||||
tbl->file->ht, tables))
|
||||
{
|
||||
error= TRUE;
|
||||
goto error;
|
||||
@ -4445,35 +4448,7 @@ restart:
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
if (WSREP(thd) &&
|
||||
wsrep_replicate_myisam &&
|
||||
(*start) &&
|
||||
(*start)->table &&
|
||||
(*start)->table->file->ht == myisam_hton &&
|
||||
wsrep_thd_is_local(thd) &&
|
||||
!is_stat_table(&(*start)->db, &(*start)->alias) &&
|
||||
thd->get_command() != COM_STMT_PREPARE &&
|
||||
((thd->lex->sql_command == SQLCOM_INSERT ||
|
||||
thd->lex->sql_command == SQLCOM_INSERT_SELECT ||
|
||||
thd->lex->sql_command == SQLCOM_REPLACE ||
|
||||
thd->lex->sql_command == SQLCOM_REPLACE_SELECT ||
|
||||
thd->lex->sql_command == SQLCOM_UPDATE ||
|
||||
thd->lex->sql_command == SQLCOM_UPDATE_MULTI ||
|
||||
thd->lex->sql_command == SQLCOM_LOAD ||
|
||||
thd->lex->sql_command == SQLCOM_DELETE)))
|
||||
{
|
||||
wsrep_before_rollback(thd, true);
|
||||
wsrep_after_rollback(thd, true);
|
||||
wsrep_after_statement(thd);
|
||||
WSREP_TO_ISOLATION_BEGIN(NULL, NULL, (*start));
|
||||
}
|
||||
#endif /* WITH_WSREP */
|
||||
|
||||
error:
|
||||
#ifdef WITH_WSREP
|
||||
wsrep_error_label:
|
||||
#endif
|
||||
THD_STAGE_INFO(thd, stage_after_opening_tables);
|
||||
thd_proc_info(thd, 0);
|
||||
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include <sql_class.h>
|
||||
#include <sql_parse.h>
|
||||
#include <sql_base.h> /* find_temporary_table() */
|
||||
#include <sql_statistics.h> /* is_stat_table() */
|
||||
#include "slave.h"
|
||||
#include "rpl_mi.h"
|
||||
#include "sql_repl.h"
|
||||
@ -1169,9 +1170,267 @@ bool wsrep_check_mode (enum_wsrep_mode mask)
|
||||
return wsrep_mode & mask;
|
||||
}
|
||||
|
||||
bool wsrep_check_mode_after_open_table (THD *thd, legacy_db_type db_type)
|
||||
//seconds after which the limit warnings suppression will be activated
|
||||
#define WSREP_WARNING_ACTIVATION_TIMEOUT 5*60
|
||||
//number of limit warnings after which the suppression will be activated
|
||||
#define WSREP_WARNING_ACTIVATION_THRESHOLD 10
|
||||
|
||||
enum wsrep_warning_type {
|
||||
WSREP_DISABLED = 0,
|
||||
WSREP_REQUIRE_PRIMARY_KEY= 1,
|
||||
WSREP_REQUIRE_INNODB= 2,
|
||||
WSREP_REQUIRE_MAX=3,
|
||||
};
|
||||
|
||||
static ulonglong wsrep_warning_start_time=0;
|
||||
static bool wsrep_warning_active[WSREP_REQUIRE_MAX+1];
|
||||
static ulonglong wsrep_warning_count[WSREP_REQUIRE_MAX+1];
|
||||
static ulonglong wsrep_total_warnings_count=0;
|
||||
|
||||
/**
|
||||
Auxiliary function to reset the limit of wsrep warnings.
|
||||
This is done without mutex protection, but this should be good
|
||||
enough as it doesn't matter if we loose a couple of suppressed
|
||||
messages or if this is called multiple times.
|
||||
*/
|
||||
|
||||
static void wsrep_reset_warnings(ulonglong now)
|
||||
{
|
||||
uint i;
|
||||
|
||||
wsrep_warning_start_time= now;
|
||||
wsrep_total_warnings_count= 0;
|
||||
|
||||
for (i= 0 ; i < WSREP_REQUIRE_MAX ; i++)
|
||||
{
|
||||
wsrep_warning_active[i]= false;
|
||||
wsrep_warning_count[i]= 0;
|
||||
}
|
||||
}
|
||||
|
||||
static const char* wsrep_warning_name(const enum wsrep_warning_type type)
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case WSREP_REQUIRE_PRIMARY_KEY:
|
||||
return "WSREP_REQUIRE_PRIMARY_KEY"; break;
|
||||
case WSREP_REQUIRE_INNODB:
|
||||
return "WSREP_REQUIRE_INNODB"; break;
|
||||
default: assert(0);
|
||||
}
|
||||
}
|
||||
/**
|
||||
Auxiliary function to check if the warning statements should be
|
||||
thrown or suppressed.
|
||||
|
||||
Logic is:
|
||||
- If we get more than WSREP_WARNING_ACTIVATION_THRESHOLD errors
|
||||
of one type, that type of errors will be suppressed for
|
||||
WSREP_WARNING_ACTIVATION_TIMEOUT.
|
||||
- When the time limit has been reached, all suppressions are reset.
|
||||
|
||||
This means that if one gets many different types of errors, some of them
|
||||
may be reset less than WSREP_WARNING_ACTIVATION_TIMEOUT. However at
|
||||
least one error is disabled for this time.
|
||||
|
||||
SYNOPSIS:
|
||||
@params
|
||||
warning_type - The type of warning.
|
||||
|
||||
RETURN:
|
||||
0 0k to log
|
||||
1 Message suppressed
|
||||
*/
|
||||
|
||||
static bool wsrep_protect_against_warning_flood(
|
||||
enum wsrep_warning_type warning_type)
|
||||
{
|
||||
ulonglong count;
|
||||
ulonglong now= my_interval_timer()/1000000000ULL;
|
||||
|
||||
count= ++wsrep_warning_count[warning_type];
|
||||
wsrep_total_warnings_count++;
|
||||
|
||||
/*
|
||||
INITIALIZING:
|
||||
If this is the first time this function is called with log warning
|
||||
enabled, the monitoring the warnings should start.
|
||||
*/
|
||||
if (wsrep_warning_start_time == 0)
|
||||
{
|
||||
wsrep_reset_warnings(now);
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
The following is true if we got too many errors or if the error was
|
||||
already suppressed
|
||||
*/
|
||||
if (count >= WSREP_WARNING_ACTIVATION_THRESHOLD)
|
||||
{
|
||||
ulonglong diff_time= (now - wsrep_warning_start_time);
|
||||
|
||||
if (!wsrep_warning_active[warning_type])
|
||||
{
|
||||
/*
|
||||
ACTIVATION:
|
||||
We got WSREP_WARNING_ACTIVATION_THRESHOLD warnings in
|
||||
less than WSREP_WARNING_ACTIVATION_TIMEOUT we activate the
|
||||
suppression.
|
||||
*/
|
||||
if (diff_time <= WSREP_WARNING_ACTIVATION_TIMEOUT)
|
||||
{
|
||||
wsrep_warning_active[warning_type]= true;
|
||||
WSREP_INFO("Suppressing warnings of type '%s' for up to %d seconds because of flooding",
|
||||
wsrep_warning_name(warning_type),
|
||||
WSREP_WARNING_ACTIVATION_TIMEOUT);
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
There is no flooding till now, therefore we restart the monitoring
|
||||
*/
|
||||
wsrep_reset_warnings(now);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* This type of warnings was suppressed */
|
||||
if (diff_time > WSREP_WARNING_ACTIVATION_TIMEOUT)
|
||||
{
|
||||
ulonglong save_count= wsrep_total_warnings_count;
|
||||
/* Print a suppression note and remove the suppression */
|
||||
wsrep_reset_warnings(now);
|
||||
WSREP_INFO("Suppressed %lu unsafe warnings during "
|
||||
"the last %d seconds",
|
||||
save_count, (int) diff_time);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return wsrep_warning_active[warning_type];
|
||||
}
|
||||
|
||||
/**
|
||||
Auxiliary function to push warning to client and to the error log
|
||||
*/
|
||||
static void wsrep_push_warning(THD *thd,
|
||||
enum wsrep_warning_type type,
|
||||
const handlerton *hton,
|
||||
const TABLE_LIST *tables)
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case WSREP_REQUIRE_PRIMARY_KEY:
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_OPTION_PREVENTS_STATEMENT,
|
||||
"WSREP: wsrep_mode = REQUIRED_PRIMARY_KEY enabled. "
|
||||
"Table '%s'.'%s' should have PRIMARY KEY defined.",
|
||||
tables->db.str, tables->table_name.str);
|
||||
if (global_system_variables.log_warnings > 1 &&
|
||||
!wsrep_protect_against_warning_flood(type))
|
||||
WSREP_WARN("wsrep_mode = REQUIRED_PRIMARY_KEY enabled. "
|
||||
"Table '%s'.'%s' should have PRIMARY KEY defined",
|
||||
tables->db.str, tables->table_name.str);
|
||||
break;
|
||||
case WSREP_REQUIRE_INNODB:
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_OPTION_PREVENTS_STATEMENT,
|
||||
"WSREP: wsrep_mode = STRICT_REPLICATION enabled. "
|
||||
"Storage engine %s for table '%s'.'%s' is "
|
||||
"not supported in Galera",
|
||||
ha_resolve_storage_engine_name(hton),
|
||||
tables->db.str, tables->table_name.str);
|
||||
if (global_system_variables.log_warnings > 1 &&
|
||||
!wsrep_protect_against_warning_flood(type))
|
||||
WSREP_WARN("wsrep_mode = STRICT_REPLICATION enabled. "
|
||||
"Storage engine %s for table '%s'.'%s' is "
|
||||
"not supported in Galera",
|
||||
ha_resolve_storage_engine_name(hton),
|
||||
tables->db.str, tables->table_name.str);
|
||||
break;
|
||||
|
||||
default: assert(0); break;
|
||||
}
|
||||
}
|
||||
|
||||
bool wsrep_check_mode_after_open_table (THD *thd,
|
||||
const handlerton *hton,
|
||||
TABLE_LIST *tables)
|
||||
{
|
||||
enum_sql_command sql_command= thd->lex->sql_command;
|
||||
bool is_dml_stmt= thd->get_command() != COM_STMT_PREPARE &&
|
||||
(sql_command == SQLCOM_INSERT ||
|
||||
sql_command == SQLCOM_INSERT_SELECT ||
|
||||
sql_command == SQLCOM_REPLACE ||
|
||||
sql_command == SQLCOM_REPLACE_SELECT ||
|
||||
sql_command == SQLCOM_UPDATE ||
|
||||
sql_command == SQLCOM_UPDATE_MULTI ||
|
||||
sql_command == SQLCOM_LOAD ||
|
||||
sql_command == SQLCOM_DELETE);
|
||||
|
||||
if (!is_dml_stmt)
|
||||
return true;
|
||||
|
||||
const legacy_db_type db_type= hton->db_type;
|
||||
bool replicate= (wsrep_replicate_myisam && db_type == DB_TYPE_MYISAM);
|
||||
TABLE *tbl= tables->table;
|
||||
|
||||
if (replicate)
|
||||
{
|
||||
/* It is not recommended to replicate MyISAM as it lacks rollback feature
|
||||
but if user demands then actions are replicated using TOI.
|
||||
Following code will kick-start the TOI but this has to be done only once
|
||||
per statement.
|
||||
Note: kick-start will take-care of creating isolation key for all tables
|
||||
involved in the list (provided all of them are MYISAM tables). */
|
||||
if (!is_stat_table(&tables->db, &tables->alias))
|
||||
{
|
||||
if (tbl->s->primary_key == MAX_KEY &&
|
||||
wsrep_check_mode(WSREP_MODE_REQUIRED_PRIMARY_KEY))
|
||||
{
|
||||
/* Other replicated table doesn't have explicit primary-key defined. */
|
||||
wsrep_push_warning(thd, WSREP_REQUIRE_PRIMARY_KEY, hton, tables);
|
||||
}
|
||||
|
||||
wsrep_before_rollback(thd, true);
|
||||
wsrep_after_rollback(thd, true);
|
||||
wsrep_after_statement(thd);
|
||||
WSREP_TO_ISOLATION_BEGIN(NULL, NULL, (tables));
|
||||
}
|
||||
} else if (db_type != DB_TYPE_UNKNOWN &&
|
||||
db_type != DB_TYPE_PERFORMANCE_SCHEMA)
|
||||
{
|
||||
bool is_system_db= (tbl &&
|
||||
((strcmp(tbl->s->db.str, "mysql") == 0) ||
|
||||
(strcmp(tbl->s->db.str, "information_schema") == 0)));
|
||||
|
||||
if (!is_system_db &&
|
||||
!is_temporary_table(tables))
|
||||
{
|
||||
|
||||
if (db_type != DB_TYPE_INNODB &&
|
||||
wsrep_check_mode(WSREP_MODE_STRICT_REPLICATION))
|
||||
{
|
||||
/* Table is not an InnoDB table and strict replication is requested*/
|
||||
wsrep_push_warning(thd, WSREP_REQUIRE_INNODB, hton, tables);
|
||||
}
|
||||
|
||||
if (tbl->s->primary_key == MAX_KEY &&
|
||||
db_type == DB_TYPE_INNODB &&
|
||||
wsrep_check_mode(WSREP_MODE_REQUIRED_PRIMARY_KEY))
|
||||
{
|
||||
/* InnoDB table doesn't have explicit primary-key defined. */
|
||||
wsrep_push_warning(thd, WSREP_REQUIRE_PRIMARY_KEY, hton, tables);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
|
||||
wsrep_error_label:
|
||||
return false;
|
||||
}
|
||||
|
||||
bool wsrep_check_mode_before_cmd_execute (THD *thd)
|
||||
@ -1186,7 +1445,7 @@ bool wsrep_check_mode_before_cmd_execute (THD *thd)
|
||||
"WSREP: wsrep_mode = BINLOG_ROW_FORMAT_ONLY enabled. Only ROW binlog format is supported.");
|
||||
ret= false;
|
||||
}
|
||||
if (wsrep_check_mode(WSREP_MODE_REQURIED_PRIMARY_KEY) &&
|
||||
if (wsrep_check_mode(WSREP_MODE_REQUIRED_PRIMARY_KEY) &&
|
||||
thd->lex->sql_command == SQLCOM_CREATE_TABLE)
|
||||
{
|
||||
Key *key;
|
||||
|
@ -137,7 +137,7 @@ enum enum_wsrep_ignore_apply_error {
|
||||
enum enum_wsrep_mode {
|
||||
WSREP_MODE_STRICT_REPLICATION= (1ULL << 0),
|
||||
WSREP_MODE_BINLOG_ROW_FORMAT_ONLY= (1ULL << 1),
|
||||
WSREP_MODE_REQURIED_PRIMARY_KEY= (1ULL << 2)
|
||||
WSREP_MODE_REQUIRED_PRIMARY_KEY= (1ULL << 2)
|
||||
};
|
||||
|
||||
// Streaming Replication
|
||||
@ -217,7 +217,8 @@ extern void wsrep_stop_replication(THD *thd);
|
||||
extern bool wsrep_start_replication(const char *wsrep_cluster_address);
|
||||
extern void wsrep_shutdown_replication();
|
||||
extern bool wsrep_check_mode (enum_wsrep_mode mask);
|
||||
extern bool wsrep_check_mode_after_open_table (THD *thd, legacy_db_type db_type);
|
||||
extern bool wsrep_check_mode_after_open_table (THD *thd, const handlerton *hton,
|
||||
TABLE_LIST *tables);
|
||||
extern bool wsrep_check_mode_before_cmd_execute (THD *thd);
|
||||
extern bool wsrep_must_sync_wait (THD* thd, uint mask= WSREP_SYNC_WAIT_BEFORE_READ);
|
||||
extern bool wsrep_sync_wait (THD* thd, uint mask= WSREP_SYNC_WAIT_BEFORE_READ);
|
||||
|
Reference in New Issue
Block a user