summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/suite/galera/r/galera_can_run_toi.result6
-rw-r--r--mysql-test/suite/galera/r/galera_strict_require_innodb.result92
-rw-r--r--mysql-test/suite/galera/r/galera_strict_require_primary_key.result86
-rw-r--r--mysql-test/suite/galera/t/galera_can_run_toi.test4
-rw-r--r--mysql-test/suite/galera/t/galera_strict_require_innodb.test95
-rw-r--r--mysql-test/suite/galera/t/galera_strict_require_primary_key.test90
-rw-r--r--sql/sql_base.cc37
-rw-r--r--sql/wsrep_mysqld.cc267
-rw-r--r--sql/wsrep_mysqld.h5
9 files changed, 638 insertions, 44 deletions
diff --git a/mysql-test/suite/galera/r/galera_can_run_toi.result b/mysql-test/suite/galera/r/galera_can_run_toi.result
index 6a7078b93a5..fb2fa6675ff 100644
--- a/mysql-test/suite/galera/r/galera_can_run_toi.result
+++ b/mysql-test/suite/galera/r/galera_can_run_toi.result
@@ -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
diff --git a/mysql-test/suite/galera/r/galera_strict_require_innodb.result b/mysql-test/suite/galera/r/galera_strict_require_innodb.result
new file mode 100644
index 00000000000..0367a9e0cf7
--- /dev/null
+++ b/mysql-test/suite/galera/r/galera_strict_require_innodb.result
@@ -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]
diff --git a/mysql-test/suite/galera/r/galera_strict_require_primary_key.result b/mysql-test/suite/galera/r/galera_strict_require_primary_key.result
new file mode 100644
index 00000000000..bc644851b3e
--- /dev/null
+++ b/mysql-test/suite/galera/r/galera_strict_require_primary_key.result
@@ -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]
diff --git a/mysql-test/suite/galera/t/galera_can_run_toi.test b/mysql-test/suite/galera/t/galera_can_run_toi.test
index a0087be4304..060ea887692 100644
--- a/mysql-test/suite/galera/t/galera_can_run_toi.test
+++ b/mysql-test/suite/galera/t/galera_can_run_toi.test
@@ -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
diff --git a/mysql-test/suite/galera/t/galera_strict_require_innodb.test b/mysql-test/suite/galera/t/galera_strict_require_innodb.test
new file mode 100644
index 00000000000..b4fe74d3406
--- /dev/null
+++ b/mysql-test/suite/galera/t/galera_strict_require_innodb.test
@@ -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
+
diff --git a/mysql-test/suite/galera/t/galera_strict_require_primary_key.test b/mysql-test/suite/galera/t/galera_strict_require_primary_key.test
new file mode 100644
index 00000000000..3a94c408fb6
--- /dev/null
+++ b/mysql-test/suite/galera/t/galera_strict_require_primary_key.test
@@ -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
+
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 623c0eff5b9..bfbf688c932 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -4431,13 +4431,16 @@ restart:
tbl->reginfo.lock_type= tables->lock_type;
}
#ifdef WITH_WSREP
- /*
+ /*
At this point we have SE associated with table so we can check wsrep_mode
rules at this point.
*/
- if (WSREP(thd) &&
+ 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);
diff --git a/sql/wsrep_mysqld.cc b/sql/wsrep_mysqld.cc
index 9353aa82540..b1eb68d52fd 100644
--- a/sql/wsrep_mysqld.cc
+++ b/sql/wsrep_mysqld.cc
@@ -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,15 +1170,273 @@ 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)
-{
+{
bool ret= true;
- if (wsrep_check_mode(WSREP_MODE_BINLOG_ROW_FORMAT_ONLY) &&
+ if (wsrep_check_mode(WSREP_MODE_BINLOG_ROW_FORMAT_ONLY) &&
!thd->is_current_stmt_binlog_format_row() && is_update_query(thd->lex->sql_command))
{
my_error(ER_GALERA_REPLICATION_NOT_SUPPORTED, MYF(0));
@@ -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;
diff --git a/sql/wsrep_mysqld.h b/sql/wsrep_mysqld.h
index 87991ce33f5..1aad684bd0a 100644
--- a/sql/wsrep_mysqld.h
+++ b/sql/wsrep_mysqld.h
@@ -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);