diff options
author | Jan Lindström <jan.lindstrom@mariadb.com> | 2019-08-27 17:04:59 +0300 |
---|---|---|
committer | Jan Lindström <jan.lindstrom@mariadb.com> | 2019-08-27 17:04:59 +0300 |
commit | 0a221992dd6383ef2a7ebc87e79370c984c05701 (patch) | |
tree | 91713626d72907c4af2f64e63e5c687177a28935 | |
parent | 53ee9c6cf9ecc7064222a24746cb5e6da3fc1402 (diff) | |
parent | 85774e7f339ed464c1c2360561e5a58407242b07 (diff) | |
download | mariadb-git-bb-10.5-voting.tar.gz |
Merge branch 'codership-vote-10.5' into 10.5bb-10.5-voting
66 files changed, 2432 insertions, 346 deletions
diff --git a/include/mysql/service_wsrep.h b/include/mysql/service_wsrep.h index e7ac5e159cf..9a81ebb7e92 100644 --- a/include/mysql/service_wsrep.h +++ b/include/mysql/service_wsrep.h @@ -84,6 +84,8 @@ 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); + 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; #define MYSQL_SERVICE_WSREP_INCLUDED @@ -124,6 +126,8 @@ 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_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 @@ -217,5 +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" 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 */ diff --git a/mysql-test/include/galera_cluster.inc b/mysql-test/include/galera_cluster.inc index 7f76ea59c7f..48b5bc631db 100644 --- a/mysql-test/include/galera_cluster.inc +++ b/mysql-test/include/galera_cluster.inc @@ -3,16 +3,29 @@ # # Description # ----------- -# Configure galera cluster with 2 nodes. +# Configure galera cluster with $galera_cluster_size (default: 2) nodes. # ---let $galera_cluster_size = 2 +if (!$galera_cluster_size) +{ +# --die ERROR IN TEST: $galera_cluster_size variable must be set + --let $galera_cluster_size = 2 +} + --source include/galera_init.inc --source include/have_innodb.inc --source include/galera_wait_ready.inc ---connection node_2 ---source include/galera_wait_ready.inc ---source include/have_innodb.inc + +--let $_galera_node= $galera_cluster_size + +while ($_galera_node != 1) +{ + --connection node_$_galera_node + --source include/galera_wait_ready.inc + --source include/have_innodb.inc + + --dec $_galera_node +} --connection node_1 diff --git a/mysql-test/include/wsrep_wait_condition.inc b/mysql-test/include/wsrep_wait_condition.inc new file mode 100644 index 00000000000..89b310475eb --- /dev/null +++ b/mysql-test/include/wsrep_wait_condition.inc @@ -0,0 +1,23 @@ +# Helper script to allow to wait for condition on a node that may become +# non-primary. It attempts to preserve wsrep_sync_wait and wsrep_on session +# variables. +# +# We are forced to restore a global value for the session wsrep_sync_wait +# here because we can not always issue a SELECT query to obtain the original +# value and then restore it + +disable_query_log; +SET SESSION wsrep_sync_wait = 8; +let $restore_wsrep_sync_wait = `SELECT @@GLOBAL.wsrep_sync_wait`; +let $restore_wsrep_on = `SELECT @@wsrep_on`; +SET SESSION wsrep_on = OFF; + +--source include/wait_condition.inc + +if ($restore_wsrep_on == 1) +{ + --eval SET SESSION wsrep_on = ON +} +--eval SET SESSION wsrep_sync_wait = $restore_wsrep_sync_wait + +enable_query_log; diff --git a/mysql-test/include/wsrep_wait_disconnect.inc b/mysql-test/include/wsrep_wait_disconnect.inc index 740fc0d9426..504e8069cba 100644 --- a/mysql-test/include/wsrep_wait_disconnect.inc +++ b/mysql-test/include/wsrep_wait_disconnect.inc @@ -1,20 +1,2 @@ let $wait_condition = SELECT 1 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_ready' AND VARIABLE_VALUE = 'OFF'; -# since this is called until AFTER provider disconnects,we need to allow -# queries in non-prim -# -# We are also forced to use a hard-coded value for wsrep_sync_wait here because -# we can not issue a SELECT query to obtain the original value and then restore -# it -disable_query_log; -SET SESSION wsrep_sync_wait = 7; ---let $restore_wsrep_on = `SHOW VARIABLES WHERE Variable_name = 'wsrep_on' AND Value = 'ON'` -SET SESSION wsrep_on = OFF; - ---source include/wait_condition.inc - -if ($restore_wsrep_on != "") -{ - --eval SET SESSION wsrep_on = ON -} -SET SESSION wsrep_sync_wait = 15; -enable_query_log; +--source include/wsrep_wait_condition.inc diff --git a/mysql-test/include/wsrep_wait_membership.inc b/mysql-test/include/wsrep_wait_membership.inc new file mode 100644 index 00000000000..8bc1920ddfb --- /dev/null +++ b/mysql-test/include/wsrep_wait_membership.inc @@ -0,0 +1,10 @@ +# Waits for N members in the cluster +# +# Usage: +# --let $members=1 +# --source wsrep_wait_membership.inc +# + +let $wait_condition = SELECT VARIABLE_VALUE = $members FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; + +--source include/wsrep_wait_condition.inc diff --git a/mysql-test/suite/galera/include/kill_galera.inc b/mysql-test/suite/galera/include/kill_galera.inc index d7f665df6c7..98ebf4ff35d 100644 --- a/mysql-test/suite/galera/include/kill_galera.inc +++ b/mysql-test/suite/galera/include/kill_galera.inc @@ -1,5 +1,10 @@ --echo Killing server ... +if (!$kill_signal) +{ +--let $kill_signal = 9 +} + # Write file to make mysql-test-run.pl expect the crash, but don't start it --let $_server_id= `SELECT @@server_id` --let $_expect_file_name= $MYSQLTEST_VARDIR/tmp/mysqld.$_server_id.expect @@ -7,13 +12,15 @@ # Kill the connected server --disable_reconnect +--let KILL_SIGNAL_VALUE = $kill_signal --let KILL_NODE_PIDFILE = `SELECT @@pid_file` --perl + my $kill_sig = $ENV{'KILL_SIGNAL_VALUE'}; my $pid_filename = $ENV{'KILL_NODE_PIDFILE'}; my $mysqld_pid = `cat $pid_filename`; chomp($mysqld_pid); - system("kill -9 $mysqld_pid"); + system("kill -s $kill_sig $mysqld_pid"); exit(0); EOF diff --git a/mysql-test/suite/galera/r/GCF-360.result b/mysql-test/suite/galera/r/GCF-360.result new file mode 100644 index 00000000000..8c1ba193c1f --- /dev/null +++ b/mysql-test/suite/galera/r/GCF-360.result @@ -0,0 +1,24 @@ +connection node_2; +connection node_1; +connect node_3, 127.0.0.1, root, , test, $NODE_MYPORT_3; +connect node_4, 127.0.0.1, root, , test, $NODE_MYPORT_4; +connection node_1; +SELECT VARIABLE_VALUE AS expect_4 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; +expect_4 +4 +CALL mtr.add_suppression("Slave SQL: Error 'Unknown table"); +connection node_2; +SELECT VARIABLE_VALUE AS expect_4 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; +expect_4 +4 +CALL mtr.add_suppression("Slave SQL: Error 'Unknown table"); +connection node_3; +SELECT VARIABLE_VALUE AS expect_4 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; +expect_4 +4 +CALL mtr.add_suppression("Slave SQL: Error 'Unknown table"); +connection node_4; +SELECT VARIABLE_VALUE AS expect_4 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; +expect_4 +4 +CALL mtr.add_suppression("Slave SQL: Error 'Unknown table"); diff --git a/mysql-test/suite/galera/r/galera-features#117.result b/mysql-test/suite/galera/r/galera-features#117.result new file mode 100644 index 00000000000..583f3c74a8b --- /dev/null +++ b/mysql-test/suite/galera/r/galera-features#117.result @@ -0,0 +1,37 @@ +connection node_2; +connection node_1; +connection node_2; +SET SESSION wsrep_on=OFF; +CREATE TABLE test.t1 (f2 INTEGER); +SET SESSION wsrep_on=ON; +CREATE TABLE test.t1 (f1 INTEGER); +ERROR 42S01: Table 't1' already exists +connection node_1; +SHOW CREATE TABLE test.t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `f1` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +SHOW STATUS LIKE 'wsrep_cluster_status'; +Variable_name Value +wsrep_cluster_status Primary +DROP TABLE test.t1; +connection node_2; +SET SESSION wsrep_sync_wait=0; +SHOW CREATE TABLE test.t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `f2` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +SHOW STATUS LIKE 'wsrep_cluster_status'; +Variable_name Value +wsrep_cluster_status Disconnected +CREATE TABLE test.t2 (f1 INTEGER); +ERROR 08S01: WSREP has not yet prepared node for application use +SHOW TABLES IN test; +Tables_in_test +t1 +Killing server ... +CALL mtr.add_suppression("Inconsistent by consensus."); +CALL mtr.add_suppression("WSREP: Failed to execute TOI action"); +CALL mtr.add_suppression("WSREP: TO isolation end failed"); diff --git a/mysql-test/suite/galera/r/galera_gra_log.result b/mysql-test/suite/galera/r/galera_gra_log.result index 33853188965..3b133b2732e 100644 --- a/mysql-test/suite/galera/r/galera_gra_log.result +++ b/mysql-test/suite/galera/r/galera_gra_log.result @@ -1,15 +1,12 @@ connection node_2; connection node_1; connection node_2; +SET GLOBAL wsrep_ignore_apply_errors=0; SET SESSION wsrep_on=OFF; CREATE TABLE t1 (f1 INTEGER); connection node_1; CREATE TABLE t1 (f1 INTEGER); connection node_2; -SET SESSION wsrep_on=ON; -SELECT COUNT(*) = 0 FROM t1; -COUNT(*) = 0 -1 /*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; @@ -33,5 +30,7 @@ DELIMITER ; ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; /*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/; -CALL mtr.add_suppression("Slave SQL: Error 'Table 't1' already exists' on query"); +Killing server ... +SET GLOBAL wsrep_ignore_apply_errors = 7; DROP TABLE t1; +CALL mtr.add_suppression("WSREP: Inconsistency detected: Inconsistent by consensus on"); diff --git a/mysql-test/suite/galera/r/galera_var_ignore_apply_errors.result b/mysql-test/suite/galera/r/galera_var_ignore_apply_errors.result index 48c845a4c2b..3173369386d 100644 --- a/mysql-test/suite/galera/r/galera_var_ignore_apply_errors.result +++ b/mysql-test/suite/galera/r/galera_var_ignore_apply_errors.result @@ -7,27 +7,60 @@ SET GLOBAL wsrep_on = OFF; CREATE TABLE t1 (f1 INTEGER); SET GLOBAL wsrep_on = ON; DROP TABLE t1; +connection node_2; +SHOW TABLES; +Tables_in_test +connection node_1; SET GLOBAL wsrep_on = OFF; CREATE SCHEMA s1; SET GLOBAL wsrep_on = ON; DROP SCHEMA s1; +connection node_2; +SHOW SCHEMAS; +Database +information_schema +mtr +mysql +performance_schema +test +connection node_1; CREATE TABLE t1 (f1 INTEGER); SET GLOBAL wsrep_on = OFF; CREATE INDEX idx1 ON t1 (f1); SET GLOBAL wsrep_on = ON; DROP INDEX idx1 ON t1; +connection node_2; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `f1` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 DROP TABLE t1; +connection node_1; CREATE TABLE t1 (f1 INTEGER); SET GLOBAL wsrep_on = OFF; CREATE INDEX idx1 ON t1 (f1); SET GLOBAL wsrep_on = ON; ALTER TABLE t1 DROP INDEX idx1; +connection node_2; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `f1` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 DROP TABLE t1; +connection node_1; CREATE TABLE t1 (f1 INTEGER); SET GLOBAL wsrep_on = OFF; ALTER TABLE t1 ADD COLUMN f2 INTEGER; SET GLOBAL wsrep_on = ON; ALTER TABLE t1 DROP COLUMN f2; +connection node_2; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `f1` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 DROP TABLE t1; connection node_2; SET GLOBAL wsrep_ignore_apply_errors = 2; @@ -37,14 +70,13 @@ SET GLOBAL wsrep_on = OFF; INSERT INTO t1 VALUES (1); SET GLOBAL wsrep_on = ON; DELETE FROM t1 WHERE f1 = 1; -connection node_1; -SELECT COUNT(*) = 0 FROM t1; -COUNT(*) = 0 -1 +SELECT COUNT(*) AS expect_0 FROM t1; +expect_0 +0 connection node_2; -SELECT COUNT(*) = 0 FROM t1; -COUNT(*) = 0 -1 +SELECT COUNT(*) AS expect_0 FROM t1; +expect_0 +0 DROP TABLE t1; connection node_1; CREATE TABLE t1 (f1 INTEGER); @@ -57,13 +89,12 @@ INSERT INTO t1 VALUES (3); DELETE FROM t1 WHERE f1 = 1; DELETE FROM t1 WHERE f1 = 2; COMMIT; -connection node_1; -SELECT COUNT(*) = 1 FROM t1; -COUNT(*) = 1 +SELECT COUNT(*) AS expect_1 FROM t1; +expect_1 1 connection node_2; -SELECT COUNT(*) = 1 FROM t1; -COUNT(*) = 1 +SELECT COUNT(*) AS expect_1 FROM t1; +expect_1 1 DROP TABLE t1; connection node_1; @@ -75,16 +106,16 @@ DELETE FROM t1 WHERE f1 = 3; SET SESSION wsrep_on = ON; connection node_1; DELETE FROM t1; -SELECT COUNT(*) = 0 FROM t1; -COUNT(*) = 0 -1 -connection node_2; -SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; -VARIABLE_VALUE = 'Primary' -1 -SELECT COUNT(*) = 0 FROM t1; -COUNT(*) = 0 -1 +SELECT COUNT(*) AS expect_0 FROM t1; +expect_0 +0 +connection node_2; +SELECT VARIABLE_VALUE expect_Primary FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; +expect_Primary +Primary +SELECT COUNT(*) AS expect_0 FROM t1; +expect_0 +0 DROP TABLE t1; connection node_1; CREATE TABLE t1 (f1 INTEGER PRIMARY KEY) ENGINE=InnoDB; @@ -103,16 +134,16 @@ DELETE FROM t1 WHERE f1 = 4; DELETE FROM t1 WHERE f1 = 5; COMMIT; SET AUTOCOMMIT=ON; -SELECT COUNT(*) = 0 FROM t1; -COUNT(*) = 0 -1 -connection node_2; -SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; -VARIABLE_VALUE = 'Primary' -1 -SELECT COUNT(*) = 0 FROM t1; -COUNT(*) = 0 -1 +SELECT COUNT(*) AS expect_0 FROM t1; +expect_0 +0 +connection node_2; +SELECT VARIABLE_VALUE expect_Primary FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; +expect_Primary +Primary +SELECT COUNT(*) AS expect_0 FROM t1; +expect_0 +0 DROP TABLE t1; connection node_1; CREATE TABLE t1 (f1 INTEGER PRIMARY KEY) ENGINE=InnoDB; @@ -126,16 +157,16 @@ DELETE FROM t1 WHERE f1 = 3; SET SESSION wsrep_on = ON; connection node_1; DELETE t1, t2 FROM t1 JOIN t2 WHERE t1.f1 = t2.f1; -SELECT COUNT(*) = 0 FROM t1; -COUNT(*) = 0 -1 +SELECT COUNT(*) expect_0 FROM t1; +expect_0 +0 connection node_2; SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; VARIABLE_VALUE = 'Primary' 1 -SELECT COUNT(*) = 0 FROM t1; -COUNT(*) = 0 -1 +SELECT COUNT(*) expect_0 FROM t1; +expect_0 +0 DROP TABLE t1,t2; connection node_1; CREATE TABLE parent (id INT NOT NULL, PRIMARY KEY (id)) ENGINE=INNODB; @@ -148,22 +179,22 @@ DELETE FROM child WHERE parent_id = 2; SET SESSION wsrep_on = ON; connection node_1; DELETE FROM parent; -SELECT COUNT(*) = 0 FROM parent; -COUNT(*) = 0 -1 -SELECT COUNT(*) = 0 FROM child; -COUNT(*) = 0 -1 +SELECT COUNT(*) AS expect_0 FROM parent; +expect_0 +0 +SELECT COUNT(*) AS expect_0 FROM child; +expect_0 +0 connection node_2; SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; VARIABLE_VALUE = 'Primary' 1 -SELECT COUNT(*) = 0 FROM parent; -COUNT(*) = 0 -1 -SELECT COUNT(*) = 0 FROM child; -COUNT(*) = 0 -1 +SELECT COUNT(*) AS expect_0 FROM parent; +expect_0 +0 +SELECT COUNT(*) AS expect_0 FROM child; +expect_0 +0 DROP TABLE child, parent; connection node_2; SET GLOBAL wsrep_ignore_apply_errors = 4; @@ -175,6 +206,8 @@ connection node_1; CREATE TABLE t1 (f1 INTEGER, f2 INTEGER); DROP TABLE t1; connection node_2; +SELECT * FROM t1; +ERROR 42S02: Table 'test.t1' doesn't exist SET GLOBAL wsrep_ignore_apply_errors = 7; CALL mtr.add_suppression("Can't find record in 't.*'"); CALL mtr.add_suppression("Slave SQL: Could not execute Delete_rows event"); diff --git a/mysql-test/suite/galera/r/galera_vote_rejoin_ddl.result b/mysql-test/suite/galera/r/galera_vote_rejoin_ddl.result new file mode 100644 index 00000000000..fe98d403e13 --- /dev/null +++ b/mysql-test/suite/galera/r/galera_vote_rejoin_ddl.result @@ -0,0 +1,60 @@ +connection node_2; +connection node_1; +connect node_3, 127.0.0.1, root, , test, $NODE_MYPORT_3; +connection node_3; +SET GLOBAL wsrep_provider_options = 'gmcast.isolate = 1'; +connection node_1; +connect node_4, 127.0.0.1, root, , test, $NODE_MYPORT_4; +connection node_4; +SET SESSION wsrep_on=OFF; +CREATE TABLE t1 (f1 INTEGER); +SET SESSION wsrep_on=ON; +DROP TABLE t1; +connection node_1; +CREATE TABLE t2 (f1 INTEGER); +connection node_3; +SET GLOBAL wsrep_provider_options = 'gmcast.isolate = 0'; +connection node_1; +connection node_3; +SELECT COUNT(*) AS expect_0 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't1'; +expect_0 +0 +SELECT COUNT(*) AS expect_1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't2'; +expect_1 +1 +connection node_4; +SET SESSION wsrep_on=OFF; +Killing server ... +Starting mysqld +connection node_1; +SELECT COUNT(*) AS expect_0 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't1'; +expect_0 +0 +SELECT COUNT(*) AS expect_1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't2'; +expect_1 +1 +CALL mtr.add_suppression("Slave SQL: Error 'Unknown table"); +connection node_2; +SELECT COUNT(*) AS expect_0 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't1'; +expect_0 +0 +SELECT COUNT(*) AS expect_1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't2'; +expect_1 +1 +CALL mtr.add_suppression("Slave SQL: Error 'Unknown table"); +connection node_3; +SELECT COUNT(*) AS expect_0 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't1'; +expect_0 +0 +SELECT COUNT(*) AS expect_1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't2'; +expect_1 +1 +connection node_4; +SELECT COUNT(*) AS expect_0 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't1'; +expect_0 +0 +SELECT COUNT(*) AS expect_1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't2'; +expect_1 +1 +CALL mtr.add_suppression("WSREP: Vote 0 \\(success\\) on .* is inconsistent with group. Leaving cluster."); +DROP TABLE t2; diff --git a/mysql-test/suite/galera/r/galera_vote_rejoin_dml.result b/mysql-test/suite/galera/r/galera_vote_rejoin_dml.result new file mode 100644 index 00000000000..f451555e000 --- /dev/null +++ b/mysql-test/suite/galera/r/galera_vote_rejoin_dml.result @@ -0,0 +1,73 @@ +connection node_4; +connection node_3; +connection node_2; +connection node_1; +connection node_1; +connection node_2; +connection node_3; +connection node_4; +connection node_3; +SET GLOBAL wsrep_provider_options = 'gmcast.isolate = 1'; +connection node_1; +connection node_1; +CREATE TABLE t1 (f1 INTEGER PRIMARY KEY, f2 CHAR(10)) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1, 'A'); +connection node_4; +SET SESSION wsrep_on=OFF; +INSERT INTO t1 VALUES (2, 'B'); +SET SESSION wsrep_on=ON; +DELETE FROM t1 WHERE f1 = 2; +connection node_1; +connection node_3; +SET SESSION wsrep_on = ON; +SET SESSION wsrep_sync_wait = 15; +SET GLOBAL wsrep_provider_options = 'gmcast.isolate = 0'; +connection node_1; +connection node_3; +SELECT COUNT(*) = 1 FROM t1 WHERE f2 = 'A'; +COUNT(*) = 1 +1 +SELECT COUNT(*) = 0 FROM t1 WHERE f2 = 'B'; +COUNT(*) = 0 +1 +connection node_4; +SET SESSION wsrep_on=OFF; +Killing server ... +Starting mysqld +connection node_1; +connection node_1; +SELECT COUNT(*) = 1 FROM t1 WHERE f2 = 'A'; +COUNT(*) = 1 +1 +SELECT COUNT(*) = 0 FROM t1 WHERE f2 = 'B'; +COUNT(*) = 0 +1 +CALL mtr.add_suppression("mysqld: Can't find record in 't1'"); +CALL mtr.add_suppression("Slave SQL: Could not execute Delete_rows"); +CALL mtr.add_suppression("WSREP: Event 3 Delete_rows_v1 apply failed: 120, seqno [0-9]*"); +connection node_2; +SELECT COUNT(*) = 1 FROM t1 WHERE f2 = 'A'; +COUNT(*) = 1 +1 +SELECT COUNT(*) = 0 FROM t1 WHERE f2 = 'B'; +COUNT(*) = 0 +1 +CALL mtr.add_suppression("mysqld: Can't find record in 't1'"); +CALL mtr.add_suppression("Slave SQL: Could not execute Delete_rows"); +CALL mtr.add_suppression("WSREP: Event 3 Delete_rows_v1 apply failed: 120, seqno [0-9]*"); +connection node_3; +SELECT COUNT(*) = 1 FROM t1 WHERE f2 = 'A'; +COUNT(*) = 1 +1 +SELECT COUNT(*) = 0 FROM t1 WHERE f2 = 'B'; +COUNT(*) = 0 +1 +connection node_4; +SELECT COUNT(*) = 1 FROM t1 WHERE f2 = 'A'; +COUNT(*) = 1 +1 +SELECT COUNT(*) = 0 FROM t1 WHERE f2 = 'B'; +COUNT(*) = 0 +1 +CALL mtr.add_suppression("inconsistent with group"); +DROP TABLE t1; diff --git a/mysql-test/suite/galera/t/GCF-360.cnf b/mysql-test/suite/galera/t/GCF-360.cnf new file mode 100644 index 00000000000..28e51f87e8e --- /dev/null +++ b/mysql-test/suite/galera/t/GCF-360.cnf @@ -0,0 +1,17 @@ +!include ../galera_4nodes.cnf + +[mysqld.1] +wsrep_provider_options='base_port=@mysqld.1.#galera_port' +wsrep_ignore_apply_errors=0 + +[mysqld.2] +wsrep_provider_options='base_port=@mysqld.2.#galera_port' +wsrep_ignore_apply_errors=0 + +[mysqld.3] +wsrep_provider_options='base_port=@mysqld.3.#galera_port' +wsrep_ignore_apply_errors=0 + +[mysqld.4] +wsrep_provider_options='base_port=@mysqld.4.#galera_port' +wsrep_ignore_apply_errors=0 diff --git a/mysql-test/suite/galera/t/GCF-360.test b/mysql-test/suite/galera/t/GCF-360.test new file mode 100644 index 00000000000..f1a511177f6 --- /dev/null +++ b/mysql-test/suite/galera/t/GCF-360.test @@ -0,0 +1,65 @@ +# +# GCF-360 Inconsistency voting: node goes non-prim on DDL that fails everywhere +# +# We issue 400 DDLs in total to make this test more stressful# +# + +--source include/galera_cluster.inc + +--let $count = 100 + +--connect node_3, 127.0.0.1, root, , test, $NODE_MYPORT_3 +--connect node_4, 127.0.0.1, root, , test, $NODE_MYPORT_4 + +--disable_query_log +--disable_result_log +while ($count) +{ + --connection node_1 + --send DROP TABLE nonexisting_table; + + --connection node_2 + --send DROP TABLE nonexisting_table; + + --connection node_3 + --send DROP TABLE nonexisting_table; + + --connection node_4 + --send DROP TABLE nonexisting_table; + + --connection node_1 + --error ER_BAD_TABLE_ERROR + --reap + + --connection node_2 + --error ER_BAD_TABLE_ERROR + --reap + + --connection node_3 + --error ER_BAD_TABLE_ERROR + --reap + + --connection node_4 + --error ER_BAD_TABLE_ERROR + --reap + + --dec $count +} +--enable_result_log +--enable_query_log + +--connection node_1 +SELECT VARIABLE_VALUE AS expect_4 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; +CALL mtr.add_suppression("Slave SQL: Error 'Unknown table"); + +--connection node_2 +SELECT VARIABLE_VALUE AS expect_4 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; +CALL mtr.add_suppression("Slave SQL: Error 'Unknown table"); + +--connection node_3 +SELECT VARIABLE_VALUE AS expect_4 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; +CALL mtr.add_suppression("Slave SQL: Error 'Unknown table"); + +--connection node_4 +SELECT VARIABLE_VALUE AS expect_4 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; +CALL mtr.add_suppression("Slave SQL: Error 'Unknown table"); diff --git a/mysql-test/suite/galera/t/galera-features#117.cnf b/mysql-test/suite/galera/t/galera-features#117.cnf new file mode 100644 index 00000000000..8eaed546ad8 --- /dev/null +++ b/mysql-test/suite/galera/t/galera-features#117.cnf @@ -0,0 +1,5 @@ +!include ../galera_2nodes.cnf + +[mysqld] +wsrep-ignore-apply-errors=0 +wsrep-sync-wait=0 diff --git a/mysql-test/suite/galera/t/galera-features#117.test b/mysql-test/suite/galera/t/galera-features#117.test new file mode 100644 index 00000000000..0436b201a09 --- /dev/null +++ b/mysql-test/suite/galera/t/galera-features#117.test @@ -0,0 +1,38 @@ +# +# This test tests voting for DDLs (TOI events) +# +--source include/galera_cluster.inc +--source include/have_innodb.inc + +--connection node_2 +SET SESSION wsrep_on=OFF; +CREATE TABLE test.t1 (f2 INTEGER); +SET SESSION wsrep_on=ON; + +--error ER_TABLE_EXISTS_ERROR +CREATE TABLE test.t1 (f1 INTEGER); + +--connection node_1 +--let $wait_condition = SELECT VARIABLE_VALUE = 1 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; +--source include/wait_condition.inc +SHOW CREATE TABLE test.t1; +SHOW STATUS LIKE 'wsrep_cluster_status'; +DROP TABLE test.t1; + +--connection node_2 +SET SESSION wsrep_sync_wait=0; +--let $wait_condition = SELECT VARIABLE_VALUE = 0 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; +--source include/wait_condition.inc +SHOW CREATE TABLE test.t1; +SHOW STATUS LIKE 'wsrep_cluster_status'; +--error ER_UNKNOWN_COM_ERROR +CREATE TABLE test.t2 (f1 INTEGER); +SHOW TABLES IN test; + +--source include/kill_galera.inc +--source include/wait_until_disconnected.inc +--source include/start_mysqld.inc + +CALL mtr.add_suppression("Inconsistent by consensus."); +CALL mtr.add_suppression("WSREP: Failed to execute TOI action"); +CALL mtr.add_suppression("WSREP: TO isolation end failed"); diff --git a/mysql-test/suite/galera/t/galera_gra_log.test b/mysql-test/suite/galera/t/galera_gra_log.test index 8b5aaaae5bd..aeadafad969 100644 --- a/mysql-test/suite/galera/t/galera_gra_log.test +++ b/mysql-test/suite/galera/t/galera_gra_log.test @@ -7,24 +7,35 @@ --connection node_2 --exec rm -rf $MYSQLTEST_VARDIR/mysqld.2/data/GRA_*.log +let $restore_wsrep_ignore_apply_errors = `SELECT @@GLOBAL.wsrep_ignore_apply_errors`; +SET GLOBAL wsrep_ignore_apply_errors=0; # Create applier failure - SET SESSION wsrep_on=OFF; CREATE TABLE t1 (f1 INTEGER); --connection node_1 CREATE TABLE t1 (f1 INTEGER); +# node 2 should detect an error and leave the cluster +--let $wait_condition = SELECT VARIABLE_VALUE = 1 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; +--source include/wait_condition.inc + --connection node_2 -SET SESSION wsrep_on=ON; -SELECT COUNT(*) = 0 FROM t1; +--let $wait_condition = SELECT VARIABLE_VALUE = 0 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; +--source include/wait_condition.inc # Make sure the GRA file produced is readable and contains the failure --replace_regex /SET TIMESTAMP=[0-9]+/SET TIMESTAMP=<TIMESTAMP>/ /pseudo_thread_id=[0-9]+/pseudo_thread_id=<PSEUDO_THREAD_ID>/ --exec $MYSQL_BINLOG --short-form $MYSQLTEST_VARDIR/mysqld.2/data/GRA_*.log -CALL mtr.add_suppression("Slave SQL: Error 'Table 't1' already exists' on query"); +# restart and reconnect node_2 +--source include/kill_galera.inc +--source include/wait_until_disconnected.inc +--source include/start_mysqld.inc +--eval SET GLOBAL wsrep_ignore_apply_errors = $restore_wsrep_ignore_apply_errors DROP TABLE t1; + +CALL mtr.add_suppression("WSREP: Inconsistency detected: Inconsistent by consensus on"); diff --git a/mysql-test/suite/galera/t/galera_var_ignore_apply_errors.test b/mysql-test/suite/galera/t/galera_var_ignore_apply_errors.test index ddf561c8784..c6928cddb0f 100644 --- a/mysql-test/suite/galera/t/galera_var_ignore_apply_errors.test +++ b/mysql-test/suite/galera/t/galera_var_ignore_apply_errors.test @@ -5,7 +5,6 @@ --source include/galera_cluster.inc --source include/have_innodb.inc - # # Ignore reconciling DDL errors on node_2 # @@ -20,34 +19,53 @@ CREATE TABLE t1 (f1 INTEGER); SET GLOBAL wsrep_on = ON; DROP TABLE t1; +--connection node_2 +SHOW TABLES; + # Drop schema that does not exist +--connection node_1 SET GLOBAL wsrep_on = OFF; CREATE SCHEMA s1; SET GLOBAL wsrep_on = ON; DROP SCHEMA s1; +--connection node_2 +SHOW SCHEMAS; + # Drop index that does not exist using DROP INDEX +--connection node_1 CREATE TABLE t1 (f1 INTEGER); SET GLOBAL wsrep_on = OFF; CREATE INDEX idx1 ON t1 (f1); SET GLOBAL wsrep_on = ON; DROP INDEX idx1 ON t1; + +--connection node_2 +SHOW CREATE TABLE t1; DROP TABLE t1; # Drop index that does not exist using ALTER TABLE +--connection node_1 CREATE TABLE t1 (f1 INTEGER); SET GLOBAL wsrep_on = OFF; CREATE INDEX idx1 ON t1 (f1); SET GLOBAL wsrep_on = ON; ALTER TABLE t1 DROP INDEX idx1; + +--connection node_2 +SHOW CREATE TABLE t1; DROP TABLE t1; # Drop column that does not exist +--connection node_1 CREATE TABLE t1 (f1 INTEGER); SET GLOBAL wsrep_on = OFF; ALTER TABLE t1 ADD COLUMN f2 INTEGER; SET GLOBAL wsrep_on = ON; ALTER TABLE t1 DROP COLUMN f2; + +--connection node_2 +SHOW CREATE TABLE t1; DROP TABLE t1; @@ -65,12 +83,10 @@ SET GLOBAL wsrep_on = OFF; INSERT INTO t1 VALUES (1); SET GLOBAL wsrep_on = ON; DELETE FROM t1 WHERE f1 = 1; +SELECT COUNT(*) AS expect_0 FROM t1; ---connection node_1 -SELECT COUNT(*) = 0 FROM t1; --connection node_2 -SELECT COUNT(*) = 0 FROM t1; - +SELECT COUNT(*) AS expect_0 FROM t1; DROP TABLE t1; # Delete row that does not exist in a multi statement transaction @@ -85,12 +101,10 @@ INSERT INTO t1 VALUES (3); DELETE FROM t1 WHERE f1 = 1; DELETE FROM t1 WHERE f1 = 2; COMMIT; +SELECT COUNT(*) AS expect_1 FROM t1; ---connection node_1 -SELECT COUNT(*) = 1 FROM t1; --connection node_2 -SELECT COUNT(*) = 1 FROM t1; - +SELECT COUNT(*) AS expect_1 FROM t1; DROP TABLE t1; # @@ -107,13 +121,16 @@ INSERT INTO t1 VALUES (1),(2),(3),(4),(5); SET SESSION wsrep_on = OFF; DELETE FROM t1 WHERE f1 = 3; SET SESSION wsrep_on = ON; + --connection node_1 DELETE FROM t1; +SELECT COUNT(*) AS expect_0 FROM t1; -SELECT COUNT(*) = 0 FROM t1; --connection node_2 -SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; -SELECT COUNT(*) = 0 FROM t1; +--let $wait_condition = SELECT COUNT(*) = 0 FROM t1; +--source include/wait_condition.inc +SELECT VARIABLE_VALUE expect_Primary FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; +SELECT COUNT(*) AS expect_0 FROM t1; DROP TABLE t1; # @@ -130,8 +147,8 @@ INSERT INTO t1 VALUES (1),(2),(3),(4),(5); SET SESSION wsrep_on = OFF; DELETE FROM t1 WHERE f1 = 3; SET SESSION wsrep_on = ON; ---connection node_1 +--connection node_1 SET AUTOCOMMIT=OFF; START TRANSACTION; DELETE FROM t1 WHERE f1 = 1; @@ -141,11 +158,13 @@ DELETE FROM t1 WHERE f1 = 4; DELETE FROM t1 WHERE f1 = 5; COMMIT; SET AUTOCOMMIT=ON; +SELECT COUNT(*) AS expect_0 FROM t1; -SELECT COUNT(*) = 0 FROM t1; --connection node_2 -SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; -SELECT COUNT(*) = 0 FROM t1; +--let $wait_condition = SELECT COUNT(*) = 0 FROM t1; +--source include/wait_condition.inc +SELECT VARIABLE_VALUE expect_Primary FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; +SELECT COUNT(*) AS expect_0 FROM t1; DROP TABLE t1; # @@ -169,11 +188,13 @@ SET SESSION wsrep_on = ON; --connection node_1 DELETE t1, t2 FROM t1 JOIN t2 WHERE t1.f1 = t2.f1; -SELECT COUNT(*) = 0 FROM t1; +SELECT COUNT(*) expect_0 FROM t1; --connection node_2 +--let $wait_condition = SELECT COUNT(*) = 0 FROM t1; +--source include/wait_condition.inc SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; -SELECT COUNT(*) = 0 FROM t1; +SELECT COUNT(*) expect_0 FROM t1; DROP TABLE t1,t2; # @@ -196,13 +217,15 @@ SET SESSION wsrep_on = ON; --connection node_1 DELETE FROM parent; -SELECT COUNT(*) = 0 FROM parent; -SELECT COUNT(*) = 0 FROM child; +SELECT COUNT(*) AS expect_0 FROM parent; +SELECT COUNT(*) AS expect_0 FROM child; --connection node_2 +--let $wait_condition = SELECT COUNT(*) = 0 FROM child; +--source include/wait_condition.inc SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; -SELECT COUNT(*) = 0 FROM parent; -SELECT COUNT(*) = 0 FROM child; +SELECT COUNT(*) AS expect_0 FROM parent; +SELECT COUNT(*) AS expect_0 FROM child; DROP TABLE child, parent; # @@ -217,12 +240,14 @@ SET GLOBAL wsrep_ignore_apply_errors = 4; SET GLOBAL wsrep_on = OFF; CREATE TABLE t1 (f1 INTEGER); SET GLOBAL wsrep_on = ON; + --connection node_1 CREATE TABLE t1 (f1 INTEGER, f2 INTEGER); DROP TABLE t1; - --connection node_2 +--error ER_NO_SUCH_TABLE +SELECT * FROM t1; SET GLOBAL wsrep_ignore_apply_errors = 7; CALL mtr.add_suppression("Can't find record in 't.*'"); diff --git a/mysql-test/suite/galera/t/galera_vote_rejoin_ddl.cnf b/mysql-test/suite/galera/t/galera_vote_rejoin_ddl.cnf new file mode 100644 index 00000000000..b2cba42c0bd --- /dev/null +++ b/mysql-test/suite/galera/t/galera_vote_rejoin_ddl.cnf @@ -0,0 +1,4 @@ +!include ../galera_4nodes.cnf + +[mysqld] +wsrep-ignore-apply-errors=0 diff --git a/mysql-test/suite/galera/t/galera_vote_rejoin_ddl.test b/mysql-test/suite/galera/t/galera_vote_rejoin_ddl.test new file mode 100644 index 00000000000..ce87c728b8c --- /dev/null +++ b/mysql-test/suite/galera/t/galera_vote_rejoin_ddl.test @@ -0,0 +1,83 @@ +# +# Test the case where a node that dropped prior to an inconsistency vote is +# able to rejoin via IST after the vote is complete +# + +--source include/galera_cluster.inc +--source include/big_test.inc + +# Isolate node #3 +--connect node_3, 127.0.0.1, root, , test, $NODE_MYPORT_3 +--connection node_3 +SET GLOBAL wsrep_provider_options = 'gmcast.isolate = 1'; + +# Wait for node #3 to leave cluster +--connection node_1 +--let $wait_condition = SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; +--source include/wait_condition.inc + +# Introduce inconsistency on node #4 +--connect node_4, 127.0.0.1, root, , test, $NODE_MYPORT_4 +--connection node_4 +SET SESSION wsrep_on=OFF; +CREATE TABLE t1 (f1 INTEGER); +SET SESSION wsrep_on=ON; +DROP TABLE t1; + +# Wait for node #4 to be voted out +--connection node_1 +--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; +--source include/wait_condition.inc +# Do some more stuff on the cluster to add to the IST stream +CREATE TABLE t2 (f1 INTEGER); + +# Rejoin node #3 +--connection node_3 +SET GLOBAL wsrep_provider_options = 'gmcast.isolate = 0'; +--source include/galera_wait_ready.inc + +--let $wait_condition = SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; +--source include/wait_condition.inc + +--connection node_1 +--let $wait_condition = SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; +--source include/wait_condition.inc + +# Confirm that all is good +--connection node_3 +SELECT COUNT(*) AS expect_0 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't1'; +SELECT COUNT(*) AS expect_1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't2'; + +# Rejoin node #4 +--connection node_4 +SET SESSION wsrep_on=OFF; +--source include/kill_galera.inc +--sleep 1 +--echo Starting mysqld +--source include/start_mysqld.inc + +--connection node_1 +# Confirm node #4 has rejoined +--let $wait_condition = SELECT VARIABLE_VALUE = 4 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; +--source include/wait_condition.inc + +# Confirm that all is good and all nodes have identical data +SELECT COUNT(*) AS expect_0 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't1'; +SELECT COUNT(*) AS expect_1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't2'; +CALL mtr.add_suppression("Slave SQL: Error 'Unknown table"); + +--connection node_2 +SELECT COUNT(*) AS expect_0 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't1'; +SELECT COUNT(*) AS expect_1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't2'; +CALL mtr.add_suppression("Slave SQL: Error 'Unknown table"); + +--connection node_3 +SELECT COUNT(*) AS expect_0 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't1'; +SELECT COUNT(*) AS expect_1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't2'; + +--connection node_4 +SELECT COUNT(*) AS expect_0 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't1'; +SELECT COUNT(*) AS expect_1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't2'; +CALL mtr.add_suppression("WSREP: Vote 0 \\(success\\) on .* is inconsistent with group. Leaving cluster."); + +DROP TABLE t2; diff --git a/mysql-test/suite/galera/t/galera_vote_rejoin_dml.cnf b/mysql-test/suite/galera/t/galera_vote_rejoin_dml.cnf new file mode 100644 index 00000000000..af445b25372 --- /dev/null +++ b/mysql-test/suite/galera/t/galera_vote_rejoin_dml.cnf @@ -0,0 +1,7 @@ +!include ../galera_4nodes.cnf + +[mysqld] +wsrep-ignore-apply-errors=0 + +[ENV] +galera_cluster_size=4 diff --git a/mysql-test/suite/galera/t/galera_vote_rejoin_dml.test b/mysql-test/suite/galera/t/galera_vote_rejoin_dml.test new file mode 100644 index 00000000000..e65c067304e --- /dev/null +++ b/mysql-test/suite/galera/t/galera_vote_rejoin_dml.test @@ -0,0 +1,99 @@ +# +# Test the case where a node that dropped prior to an inconsistency vote is +# able to rejoin via IST after the vote is complete +# + +--source include/galera_cluster.inc +--source include/big_test.inc + +--let $node_1=node_1 +--let $node_2=node_2 +--let $node_3=node_3 +--let $node_4=node_4 +--source include/auto_increment_offset_save.inc + +# Isolate node #3 +--connection node_3 +SET GLOBAL wsrep_provider_options = 'gmcast.isolate = 1'; + +# Wait for node #3 to leave cluster +--connection node_1 +--let $wait_condition = SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; +--source include/wait_condition.inc + +--connection node_1 +CREATE TABLE t1 (f1 INTEGER PRIMARY KEY, f2 CHAR(10)) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1, 'A'); + +# Introduce inconsistency on node #4 +--connection node_4 +SET SESSION wsrep_on=OFF; +INSERT INTO t1 VALUES (2, 'B'); +SET SESSION wsrep_on=ON; +DELETE FROM t1 WHERE f1 = 2; + +# Wait for node #4 to be voted out +--connection node_1 +--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; +--source include/wait_condition.inc + +# Rejoin node #3 +--connection node_3 +--source include/wsrep_wait_disconnect.inc +SET GLOBAL wsrep_provider_options = 'gmcast.isolate = 0'; +--source include/galera_wait_ready.inc + +--let $wait_condition = SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; +--source include/wait_condition.inc + +--connection node_1 +--let $wait_condition = SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; +--source include/wait_condition.inc + +# Confirm that all is good +--connection node_3 +SELECT COUNT(*) = 1 FROM t1 WHERE f2 = 'A'; +SELECT COUNT(*) = 0 FROM t1 WHERE f2 = 'B'; + +# Rejoin node #4 +--connection node_4 +SET SESSION wsrep_on=OFF; +--source include/kill_galera.inc +--sleep 1 +--echo Starting mysqld +--source include/start_mysqld.inc + +# Confirm node #4 has rejoined +--connection node_1 +--let $wait_condition = SELECT VARIABLE_VALUE = 4 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; +--source include/wait_condition.inc + +# Confirm that all is good and all nodes have identical data + +--connection node_1 +SELECT COUNT(*) = 1 FROM t1 WHERE f2 = 'A'; +SELECT COUNT(*) = 0 FROM t1 WHERE f2 = 'B'; +CALL mtr.add_suppression("mysqld: Can't find record in 't1'"); +CALL mtr.add_suppression("Slave SQL: Could not execute Delete_rows"); +CALL mtr.add_suppression("WSREP: Event 3 Delete_rows_v1 apply failed: 120, seqno [0-9]*"); + +--connection node_2 +SELECT COUNT(*) = 1 FROM t1 WHERE f2 = 'A'; +SELECT COUNT(*) = 0 FROM t1 WHERE f2 = 'B'; +CALL mtr.add_suppression("mysqld: Can't find record in 't1'"); +CALL mtr.add_suppression("Slave SQL: Could not execute Delete_rows"); +CALL mtr.add_suppression("WSREP: Event 3 Delete_rows_v1 apply failed: 120, seqno [0-9]*"); + +--connection node_3 +SELECT COUNT(*) = 1 FROM t1 WHERE f2 = 'A'; +SELECT COUNT(*) = 0 FROM t1 WHERE f2 = 'B'; + +--connection node_4 +--source include/galera_wait_ready.inc +SELECT COUNT(*) = 1 FROM t1 WHERE f2 = 'A'; +SELECT COUNT(*) = 0 FROM t1 WHERE f2 = 'B'; +CALL mtr.add_suppression("inconsistent with group"); + +DROP TABLE t1; + +--source include/auto_increment_offset_restore.inc diff --git a/mysql-test/suite/galera_3nodes/r/GCF-354.result b/mysql-test/suite/galera_3nodes/r/GCF-354.result new file mode 100644 index 00000000000..b7ab3014ff5 --- /dev/null +++ b/mysql-test/suite/galera_3nodes/r/GCF-354.result @@ -0,0 +1,52 @@ +connection node_2; +connection node_1; +connection node_2; +SET wsrep_on=OFF; +DROP SCHEMA test; +connect node_3, 127.0.0.1, root, , test, $NODE_MYPORT_3; +connection node_3; +SET wsrep_on=OFF; +CREATE TABLE test.t1 (f1 INTEGER); +connection node_1; +CREATE TABLE test.t1 (f1 INTEGER); +SHOW STATUS LIKE 'wsrep_cluster_status'; +Variable_name Value +wsrep_cluster_status Primary +DROP TABLE test.t1; +connection node_2; +SET SESSION wsrep_sync_wait=0; +SHOW STATUS LIKE 'wsrep_cluster_status'; +Variable_name Value +wsrep_cluster_status Disconnected +disconnect node_2; +connect node_2, 127.0.0.1, root, , mysql, $NODE_MYPORT_2; +Killing server ... +connection node_2; +Starting node_2 +# restart +connection node_3; +SET SESSION wsrep_sync_wait=0; +SHOW STATUS LIKE 'wsrep_cluster_status'; +Variable_name Value +wsrep_cluster_status Disconnected +disconnect node_3; +connect node_3, 127.0.0.1, root, , test, $NODE_MYPORT_3; +Killing server ... +connection node_3; +Starting node_3 +# restart +connection node_1; +Nodes 2 and 3 started +connection node_2; +USE test; +Node 2 synced +CALL mtr.add_suppression("Slave SQL: Error 'Unknown database 'test'' on query. Default database: 'test'. Query: 'CREATE TABLE test.t1 \\\(f1 INTEGER\\\)', Error_code: 1049"); +CALL mtr.add_suppression("Query apply failed"); +CALL mtr.add_suppression("WSREP: Inconsistency detected: Inconsistent by consensus on .*"); +CALL mtr.add_suppression("Plugin 'InnoDB' will be forced to shutdown"); +connection node_3; +Node 3 synced +CALL mtr.add_suppression("Slave SQL: Error 'Table 't1' already exists' on query. Default database: 'test'. Query: 'CREATE TABLE test.t1 \\\(f1 INTEGER\\\)', Error_code: 1050"); +CALL mtr.add_suppression("Query apply failed"); +CALL mtr.add_suppression("WSREP: Inconsistency detected: Inconsistent by consensus on .*"); +CALL mtr.add_suppression("Plugin 'InnoDB' will be forced to shutdown"); diff --git a/mysql-test/suite/galera_3nodes/r/GCF-363.result b/mysql-test/suite/galera_3nodes/r/GCF-363.result new file mode 100644 index 00000000000..afab5012ee5 --- /dev/null +++ b/mysql-test/suite/galera_3nodes/r/GCF-363.result @@ -0,0 +1,46 @@ +connection node_2; +connection node_1; +CREATE TABLE t1 (f1 INTEGER PRIMARY KEY, f2 CHAR(1)) ENGINE=InnoDB; +connection node_1; +SET GLOBAL wsrep_on=OFF; +INSERT INTO t1 VALUES (1, 'a'); +SET GLOBAL wsrep_on=ON; +connection node_2; +SET GLOBAL wsrep_on=OFF; +INSERT INTO t1 VALUES (1, 'a'); +SET GLOBAL wsrep_on=ON; +connect node_3, 127.0.0.1, root, , test, $NODE_MYPORT_3; +connection node_3; +INSERT INTO t1 VALUES (1, 'b'); +SET SESSION wsrep_sync_wait = 0; +SHOW STATUS LIKE 'wsrep_cluster_status'; +Variable_name Value +wsrep_cluster_status Disconnected +connection node_1; +connection node_3; +SET SESSION wsrep_on=OFF; +# restart +SET SESSION wsrep_on=ON; +connection node_1; +SELECT * FROM t1; +f1 f2 +1 a +connection node_2; +SELECT * FROM t1; +f1 f2 +1 a +connection node_3; +SELECT * FROM t1; +f1 f2 +1 a +DROP TABLE t1; +connection node_1; +CALL mtr.add_suppression("Slave SQL: Could not execute Write_rows event on table test.t1; Duplicate entry '1' for key 'PRIMARY', Error_code: 1062; handler error HA_ERR_FOUND_DUPP_KEY; the event's master log FIRST, end_log_pos 155, Error_code: 1062"); +CALL mtr.add_suppression("WSREP: Event 3 Write_rows_v1 apply failed: 121, seqno "); +connection node_2; +CALL mtr.add_suppression("Slave SQL: Could not execute Write_rows event on table test.t1; Duplicate entry '1' for key 'PRIMARY', Error_code: 1062; handler error HA_ERR_FOUND_DUPP_KEY; the event's master log FIRST, end_log_pos 155, Error_code: 1062"); +CALL mtr.add_suppression("WSREP: Event 3 Write_rows_v1 apply failed: 121, seqno "); +connection node_3; +CALL mtr.add_suppression("WSREP: Vote 0 \\\(success\\\) on (.*) is inconsistent with group. Leaving cluster."); +CALL mtr.add_suppression("WSREP: Inconsistency detected: Inconsistent by consensus on "); +CALL mtr.add_suppression("Plugin 'InnoDB' will be forced to shutdown"); diff --git a/mysql-test/suite/galera_3nodes/r/GCF-376.result b/mysql-test/suite/galera_3nodes/r/GCF-376.result new file mode 100644 index 00000000000..a852d1f2385 --- /dev/null +++ b/mysql-test/suite/galera_3nodes/r/GCF-376.result @@ -0,0 +1,71 @@ +connection node_2; +connection node_1; +connect node_3, 127.0.0.1, root, , test, $NODE_MYPORT_3; +connection node_1; +connection node_1; +connection node_2; +connection node_3; +CREATE TABLE test.t1 (f1 INTEGER PRIMARY KEY, f2 CHAR(1)) ENGINE=InnoDB; +connection node_2; +SET GLOBAL wsrep_on=OFF; +INSERT INTO t1 VALUES (1, 'a'); +SET GLOBAL wsrep_on=ON; +LOCK TABLE t1 WRITE; +connection node_1; +INSERT INTO t1 VALUES (1, 'b'); +SET GLOBAL wsrep_provider_options = 'gmcast.isolate=1'; +SET SESSION wsrep_sync_wait=0; +connection node_3; +connection node_2; +UNLOCK TABLES; +SET SESSION wsrep_on = ON; +SET SESSION wsrep_sync_wait = 15; +connection node_1; +SHOW STATUS LIKE 'wsrep_cluster_status'; +Variable_name Value +wsrep_cluster_status non-Primary +connection node_2; +SET SESSION wsrep_sync_wait=0; +SHOW STATUS LIKE 'wsrep_cluster_status'; +Variable_name Value +wsrep_cluster_status Disconnected +SHOW STATUS LIKE 'wsrep_cluster_size'; +Variable_name Value +wsrep_cluster_size 0 +SET GLOBAL wsrep_on=OFF; +SELECT * FROM t1; +f1 f2 +1 a +connection node_3; +SET SESSION wsrep_sync_wait=0; +SHOW STATUS LIKE 'wsrep_cluster_status'; +Variable_name Value +wsrep_cluster_status Primary +SHOW STATUS LIKE 'wsrep_cluster_size'; +Variable_name Value +wsrep_cluster_size 1 +SELECT * FROM t1; +f1 f2 +1 b +connection node_1; +SET GLOBAL wsrep_provider_options = 'gmcast.isolate=0'; +connection node_2; +# restart +connection node_1; +SELECT * FROM t1; +f1 f2 +1 b +connection node_2; +SELECT * FROM t1; +f1 f2 +1 b +connection node_3; +SELECT * FROM t1; +f1 f2 +1 b +DROP TABLE t1; +connection node_2; +CALL mtr.add_suppression("Slave SQL: Could not execute Write_rows event on table test.t1; Duplicate entry '1' for key 'PRIMARY', Error_code: 1062; handler error HA_ERR_FOUND_DUPP_KEY; the event's master log FIRST, end_log_pos (.*), Error_code: 1062"); +CALL mtr.add_suppression("WSREP: Event (.*) Write_rows_v1 apply failed: 121, seqno "); +CALL mtr.add_suppression("WSREP: Inconsistency detected: Inconsistent by consensus on (.*)"); +CALL mtr.add_suppression("Plugin 'InnoDB' will be forced to shutdown"); diff --git a/mysql-test/suite/galera_3nodes/r/galera-features#119.result b/mysql-test/suite/galera_3nodes/r/galera-features#119.result new file mode 100644 index 00000000000..7796064d563 --- /dev/null +++ b/mysql-test/suite/galera_3nodes/r/galera-features#119.result @@ -0,0 +1,33 @@ +connection node_2; +connection node_1; +connection node_1; +connection node_2; +connection node_3; +CREATE TABLE test.t1 (f1 INTEGER PRIMARY KEY) ENGINE=InnoDB; +connection node_2; +SET wsrep_on=OFF; +INSERT INTO t1 VALUES (1); +LOCK TABLE t1 WRITE; +SET GLOBAL wsrep_sync_wait=0; +connection node_1; +INSERT INTO t1 VALUES (1); +SET GLOBAL wsrep_sync_wait=0; +SET GLOBAL wsrep_provider_options = 'gmcast.isolate=1'; +connection node_3; +connection node_2; +UNLOCK TABLES; +connection node_3; +connection node_1; +SET GLOBAL wsrep_provider_options = 'gmcast.isolate=0'; +SET GLOBAL wsrep_sync_wait=15; +DROP TABLE test.t1; +connection node_2; +Killing server ... +# restart +connection node_2; +CALL mtr.add_suppression("Inconsistent by consensus."); +CALL mtr.add_suppression("Slave SQL: Could not execute Write_rows event on table test.t1; Duplicate entry '1' for key 'PRIMARY', Error_code: 1062; handler error HA_ERR_FOUND_DUPP_KEY; the event's master log FIRST"); +CALL mtr.add_suppression("WSREP: Event 3 Write_rows_v1 apply failed: 121, seqno"); +CALL mtr.add_suppression("WSREP: Failed to apply trx: source: "); +CALL mtr.add_suppression("WSREP: Failed to apply app buffer: seqno:"); +CALL mtr.add_suppression("WSREP: Node consistency compromized, leaving cluster..."); diff --git a/mysql-test/suite/galera_3nodes/r/galera_evs_suspect_timeout.result b/mysql-test/suite/galera_3nodes/r/galera_evs_suspect_timeout.result index b1332a5f87c..1910106c646 100644 --- a/mysql-test/suite/galera_3nodes/r/galera_evs_suspect_timeout.result +++ b/mysql-test/suite/galera_3nodes/r/galera_evs_suspect_timeout.result @@ -8,6 +8,7 @@ SET GLOBAL wsrep_provider_options = 'evs.inactive_timeout=PT100M; evs.suspect_ti connection node_2; SET GLOBAL wsrep_provider_options = 'evs.inactive_timeout=PT100M; evs.suspect_timeout=PT1S'; connection node_3; +connection node_3; Suspending node ... connection node_1; SET SESSION wsrep_sync_wait=0; diff --git a/mysql-test/suite/galera_3nodes/r/galera_pc_weight.result b/mysql-test/suite/galera_3nodes/r/galera_pc_weight.result index 3ae983f9550..858f2297f91 100644 --- a/mysql-test/suite/galera_3nodes/r/galera_pc_weight.result +++ b/mysql-test/suite/galera_3nodes/r/galera_pc_weight.result @@ -5,9 +5,9 @@ SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_N VARIABLE_VALUE = 3 1 SET GLOBAL wsrep_provider_options = 'pc.weight=3'; -SELECT VARIABLE_VALUE = 5 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_weight'; -VARIABLE_VALUE = 5 -1 +SELECT VARIABLE_VALUE AS expect_5 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_weight'; +expect_5 +5 SET GLOBAL wsrep_provider_options = 'gmcast.isolate=1'; connection node_2; SET SESSION wsrep_sync_wait=0; @@ -60,106 +60,104 @@ SHOW STATUS LIKE 'wsrep_local_state_comment'; Variable_name Value wsrep_local_state_comment Initialized connection node_1; -SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_weight'; -VARIABLE_VALUE = 3 -1 -SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; -VARIABLE_VALUE = 'Primary' -1 -SELECT VARIABLE_VALUE = 'ON' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_connected'; -VARIABLE_VALUE = 'ON' -1 -SELECT VARIABLE_VALUE = 'ON' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_ready'; -VARIABLE_VALUE = 'ON' -1 -SELECT VARIABLE_VALUE = 4 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_state'; -VARIABLE_VALUE = 4 -1 -SELECT VARIABLE_VALUE = 'Synced' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_state_comment'; -VARIABLE_VALUE = 'Synced' -1 +SELECT VARIABLE_VALUE AS expect_3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_weight'; +expect_3 +3 +SELECT VARIABLE_VALUE AS expect_Primary FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; +expect_Primary +Primary +SELECT VARIABLE_VALUE AS expect_ON FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_connected'; +expect_ON +ON +SELECT VARIABLE_VALUE AS expect_ON FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_ready'; +expect_ON +ON +SELECT VARIABLE_VALUE AS expect_4 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_state'; +expect_4 +4 +SELECT VARIABLE_VALUE AS expect_Synced FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_state_comment'; +expect_Synced +Synced SET GLOBAL wsrep_provider_options = 'pc.weight=1'; -SELECT VARIABLE_VALUE = 1 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_weight'; -VARIABLE_VALUE = 1 +SELECT VARIABLE_VALUE AS expect_1 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_weight'; +expect_1 1 connection node_1; SET GLOBAL wsrep_provider_options = 'gmcast.isolate=0'; connection node_2; connection node_3; -connection node_1; -SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; -VARIABLE_VALUE = 3 -1 -SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_weight'; -VARIABLE_VALUE = 3 -1 -SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; -VARIABLE_VALUE = 'Primary' -1 -SELECT VARIABLE_VALUE = 'ON' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_connected'; -VARIABLE_VALUE = 'ON' -1 -SELECT VARIABLE_VALUE = 'ON' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_ready'; -VARIABLE_VALUE = 'ON' -1 -SELECT VARIABLE_VALUE = 4 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_state'; -VARIABLE_VALUE = 4 -1 -SELECT VARIABLE_VALUE = 'Synced' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_state_comment'; -VARIABLE_VALUE = 'Synced' -1 +SELECT VARIABLE_VALUE AS expect_3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; +expect_3 +3 +SELECT VARIABLE_VALUE AS expect_3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_weight'; +expect_3 +3 +SELECT VARIABLE_VALUE AS expect_Primary FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; +expect_Primary +Primary +SELECT VARIABLE_VALUE AS expect_ON FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_connected'; +expect_ON +ON +SELECT VARIABLE_VALUE AS expect_ON FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_ready'; +expect_ON +ON +SELECT VARIABLE_VALUE AS expect_4 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_state'; +expect_4 +4 +SELECT VARIABLE_VALUE AS expect_Synced FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_state_comment'; +expect_Synced +Synced connection node_2; -SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; -VARIABLE_VALUE = 3 -1 -SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_weight'; -VARIABLE_VALUE = 3 -1 -SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; -VARIABLE_VALUE = 'Primary' -1 -SELECT VARIABLE_VALUE = 'ON' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_connected'; -VARIABLE_VALUE = 'ON' -1 -SELECT VARIABLE_VALUE = 'ON' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_ready'; -VARIABLE_VALUE = 'ON' -1 -SELECT VARIABLE_VALUE = 4 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_state'; -VARIABLE_VALUE = 4 -1 -SELECT VARIABLE_VALUE = 'Synced' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_state_comment'; -VARIABLE_VALUE = 'Synced' -1 -connection node_3; -SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; -VARIABLE_VALUE = 3 -1 -SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_weight'; -VARIABLE_VALUE = 3 -1 -SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; -VARIABLE_VALUE = 'Primary' -1 -SELECT VARIABLE_VALUE = 'ON' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_connected'; -VARIABLE_VALUE = 'ON' -1 -SELECT VARIABLE_VALUE = 'ON' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_ready'; -VARIABLE_VALUE = 'ON' -1 -SELECT VARIABLE_VALUE = 4 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_state'; -VARIABLE_VALUE = 4 -1 -SELECT VARIABLE_VALUE = 'Synced' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_state_comment'; -VARIABLE_VALUE = 'Synced' -1 +SELECT VARIABLE_VALUE AS expect_3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; +expect_3 +3 +SELECT VARIABLE_VALUE AS expect_3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_weight'; +expect_3 +3 +SELECT VARIABLE_VALUE AS expect_Primary FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; +expect_Primary +Primary +SELECT VARIABLE_VALUE AS expect_ON FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_connected'; +expect_ON +ON +SELECT VARIABLE_VALUE AS expect_ON FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_ready'; +expect_ON +ON +SELECT VARIABLE_VALUE AS expect_4 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_state'; +expect_4 +4 +SELECT VARIABLE_VALUE AS expect_Synced FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_state_comment'; +expect_Synced +Synced connection node_1; +SELECT VARIABLE_VALUE AS expect_3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; +expect_3 +3 +SELECT VARIABLE_VALUE AS expect_3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_weight'; +expect_3 +3 +SELECT VARIABLE_VALUE AS expect_Primary FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; +expect_Primary +Primary +SELECT VARIABLE_VALUE AS expect_ON FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_connected'; +expect_ON +ON +SELECT VARIABLE_VALUE AS expect_ON FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_ready'; +expect_ON +ON +SELECT VARIABLE_VALUE AS expect_4 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_state'; +expect_4 +4 +SELECT VARIABLE_VALUE AS expect_Synced FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_state_comment'; +expect_Synced +Synced SET GLOBAL wsrep_provider_options = 'pc.weight=1'; CALL mtr.add_suppression('WSREP: gcs_caused\\(\\) returned -1'); connection node_2; -CALL mtr.add_suppression('overriding reported weight for'); CALL mtr.add_suppression('SYNC message from member'); CALL mtr.add_suppression('user message in state LEAVING'); CALL mtr.add_suppression('sending install message failed: (Transport endpoint is not connected|Socket is not connected)'); +CALL mtr.add_suppression('overriding reported weight for'); connection node_3; CALL mtr.add_suppression('WSREP: user message in state LEAVING'); CALL mtr.add_suppression('sending install message failed: (Transport endpoint is not connected|Socket is not connected)'); diff --git a/mysql-test/suite/galera_3nodes/r/galera_toi_vote.result b/mysql-test/suite/galera_3nodes/r/galera_toi_vote.result new file mode 100644 index 00000000000..13caead79d3 --- /dev/null +++ b/mysql-test/suite/galera_3nodes/r/galera_toi_vote.result @@ -0,0 +1,22 @@ +connection node_2; +connection node_1; +connection node_1; +connection node_2; +connection node_3; +connection node_3; +SET SESSION wsrep_on=OFF; +DROP SCHEMA test; +connection node_1; +CREATE SCHEMA test; +ERROR HY000: Can't create database 'test'; database exists +connection node_1; +SET SESSION wsrep_sync_wait=0; +connection node_2; +SET SESSION wsrep_sync_wait=0; +connection node_3; +SET SESSION wsrep_sync_wait=0; +disconnect node_3; +connect node_3, 127.0.0.1, root, , test, $NODE_MYPORT_3; +Killing server ... +# restart +CALL mtr.add_suppression("WSREP: Vote 0 \\\(success\\\) on (.*) is inconsistent with group. Leaving cluster."); diff --git a/mysql-test/suite/galera_3nodes/r/galera_vote_rejoin_mysqldump.result b/mysql-test/suite/galera_3nodes/r/galera_vote_rejoin_mysqldump.result new file mode 100644 index 00000000000..d43f31d4c87 --- /dev/null +++ b/mysql-test/suite/galera_3nodes/r/galera_vote_rejoin_mysqldump.result @@ -0,0 +1,83 @@ +connection node_2; +connection node_1; +Setting SST method to mysqldump ... +call mtr.add_suppression("WSREP: wsrep_sst_method is set to 'mysqldump' yet mysqld bind_address is set to '127.0.0.1'"); +call mtr.add_suppression("Failed to load slave replication state from table mysql.gtid_slave_pos"); +connection node_1; +CREATE USER 'sst'; +GRANT ALL PRIVILEGES ON *.* TO 'sst'; +SET GLOBAL wsrep_sst_auth = 'sst:'; +connection node_2; +SET GLOBAL wsrep_sst_method = 'mysqldump'; +connect node_3, 127.0.0.1, root, , test, $NODE_MYPORT_3; +connection node_1; +connection node_2; +connection node_3; +connection node_1; +CREATE TABLE t1 (f1 INTEGER) ENGINE=InnoDB; +connection node_2; +SET SESSION wsrep_on=OFF; +ALTER TABLE t1 ADD PRIMARY KEY (f1); +SET SESSION wsrep_on=ON; +connection node_1; +ALTER TABLE t1 LOCK=SHARED, DROP PRIMARY KEY; +ERROR 42000: Can't DROP INDEX `PRIMARY`; check that it exists +connection node_1; +SELECT VARIABLE_VALUE AS expect_Primary FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; +expect_Primary +Primary +connection node_3; +SELECT VARIABLE_VALUE AS expect_2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; +expect_2 +2 +SELECT VARIABLE_VALUE AS expect_Primary FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; +expect_Primary +Primary +connection node_2; +SET SESSION wsrep_on=OFF; +SELECT VARIABLE_VALUE AS expect_Disconnected FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; +expect_Disconnected +Disconnected +SET SESSION wsrep_on=ON; +SELECT VARIABLE_VALUE AS expect_Primary FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; +expect_Primary +Primary +connection node_1; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `f1` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +connection node_2; +SET SESSION wsrep_on=OFF; +SET SESSION wsrep_on=ON; +# restart +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `f1` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +SELECT COUNT(*) AS expect_0 FROM t1; +expect_0 +0 +CALL mtr.add_suppression("is inconsistent with group"); +connection node_3; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `f1` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +DROP TABLE t1; +CALL mtr.add_suppression("Slave SQL: Error 'Can't DROP 'PRIMARY'; check that column/key exists'"); +connection node_1; +connection node_1; +CALL mtr.add_suppression("Slave SQL: Error 'The MySQL server is running with the --skip-grant-tables option so it cannot execute this statement' on query"); +DROP USER sst; +connection node_2; +CALL mtr.add_suppression("Slave SQL: Error 'The MySQL server is running with the --skip-grant-tables option so it cannot execute this statement' on query"); +CALL mtr.add_suppression("InnoDB: Error: Table \"mysql\"\\.\"innodb_index_stats\" not found"); +CALL mtr.add_suppression("Can't open and lock time zone table"); +CALL mtr.add_suppression("Can't open and lock privilege tables"); +CALL mtr.add_suppression("Info table is not ready to be used"); +CALL mtr.add_suppression("Native table .* has the wrong structure"); +CALL mtr.add_suppression("Table \'mysql.gtid_slave_pos\' doesn\'t exist"); diff --git a/mysql-test/suite/galera_3nodes/r/inconsistency_shutdown.result b/mysql-test/suite/galera_3nodes/r/inconsistency_shutdown.result new file mode 100644 index 00000000000..4b668d89d91 --- /dev/null +++ b/mysql-test/suite/galera_3nodes/r/inconsistency_shutdown.result @@ -0,0 +1,140 @@ +connection node_3; +connection node_2; +connection node_1; +connection node_1; +connection node_2; +connection node_3; +connection node_2; +SELECT @@wsrep_slave_threads = 8; +@@wsrep_slave_threads = 8 +1 +connection node_1; +CREATE TABLE t1 (f1 INTEGER PRIMARY KEY, f2 INT); +INSERT INTO t1 VALUES (1, 0),(2, 0),(3, 0),(4, 0),(5, 0),(6, 0),(7, 0),(8, 0); +connection node_2; +SET GLOBAL wsrep_provider_options='gcs.fc_limit=1K'; +SET wsrep_on=OFF; +DELETE FROM t1 WHERE f1 = 2; +DELETE FROM t1 WHERE f1 = 4; +SET wsrep_on=ON; +LOCK TABLES t1 WRITE; +connection node_1; +UPDATE t1 SET f2 = 1 WHERE f1 = 1; +UPDATE t1 SET f2 = 1 WHERE f1 = 2; +UPDATE t1 SET f2 = 1 WHERE f1 = 3; +UPDATE t1 SET f2 = 1 WHERE f1 = 4; +UPDATE t1 SET f2 = 2 WHERE f1 = 4; +/* dependent applier */ +UPDATE t1 SET f2 = 3 WHERE f1 = 4; +/* dependent applier */ +UPDATE t1 SET f2 = 1 WHERE f1 = 5; +UPDATE t1 SET f2 = 1 WHERE f1 = 6; +UPDATE t1 SET f2 = 1 WHERE f1 = 7; +UPDATE t1 SET f2 = 1 WHERE f1 = 8; +connection node_2; +SET wsrep_on=OFF; +SET wsrep_on=ON; +UNLOCK TABLES; +SET SESSION wsrep_on = ON; +SET SESSION wsrep_sync_wait = 15; +SET SESSION wsrep_on = ON; +SET SESSION wsrep_sync_wait = 15; +connection node_1; +SET SESSION wsrep_on = ON; +SET SESSION wsrep_sync_wait = 15; +SHOW STATUS LIKE 'wsrep_cluster_size'; +Variable_name Value +wsrep_cluster_size 2 +SELECT * FROM t1; +f1 f2 +1 1 +2 1 +3 1 +4 3 +5 1 +6 1 +7 1 +8 1 +connection node_2; +SET GLOBAL wsrep_on=OFF; +# restart +DROP TABLE t1; +connection node_1; +CREATE TABLE t1 (f1 INTEGER PRIMARY KEY, f2 INT); +START TRANSACTION; +INSERT INTO t1 VALUES (1, 0); +INSERT INTO t1 VALUES (2, 0); +INSERT INTO t1 VALUES (3, 0); +INSERT INTO t1 VALUES (4, 0); +INSERT INTO t1 VALUES (5, 0); +INSERT INTO t1 VALUES (6, 0); +INSERT INTO t1 VALUES (7, 0); +INSERT INTO t1 VALUES (8, 0); +COMMIT; +CREATE TABLE t2 (f1 INTEGER PRIMARY KEY, f2 INT); +connection node_2; +SET GLOBAL wsrep_provider_options='gcs.fc_limit=1K'; +SET wsrep_on=OFF; +DROP TABLE t2; +SET wsrep_on=ON; +SET GLOBAL wsrep_provider_options = 'dbug=d,after_replicate_sync'; +LOCK TABLES t1 READ; +connection node_1; +UPDATE t1 SET f2 = 1 WHERE f1 = 1; +UPDATE t1 SET f2 = 1 WHERE f1 = 2; +UPDATE t1 SET f2 = 1 WHERE f1 = 3; +UPDATE t1 SET f2 = 1 WHERE f1 = 4; +UPDATE t1 SET f2 = 2 WHERE f1 = 4; +/* dependent applier */; +connect node_2a, 127.0.0.1, root, , test, $NODE_MYPORT_2; +connection node_2a; +DROP TABLE t2;; +connection node_2; +SET wsrep_on=OFF; +"Wait for DROP TABLE to replicate" +SET SESSION wsrep_on = 0; +SET SESSION wsrep_on = 0; +SET GLOBAL wsrep_provider_options = 'signal=after_replicate_sync'; +SET GLOBAL wsrep_provider_options = 'dbug='; +"DROP TABLE replicated" +SET wsrep_on=ON; +connection node_1; +UPDATE t1 SET f2 = 3 WHERE f1 = 4; +/* dependent applier */ +UPDATE t1 SET f2 = 1 WHERE f1 = 5; +UPDATE t1 SET f2 = 1 WHERE f1 = 6; +UPDATE t1 SET f2 = 1 WHERE f1 = 7; +UPDATE t1 SET f2 = 1 WHERE f1 = 8; +connection node_2; +SET wsrep_on=OFF; +SET wsrep_on=ON; +UNLOCK TABLES; +connection node_2a; +ERROR 42S02: Unknown table 'test.t2' +connection node_1; +SET SESSION wsrep_on = ON; +SET SESSION wsrep_sync_wait = 15; +SHOW STATUS LIKE 'wsrep_cluster_size'; +Variable_name Value +wsrep_cluster_size 2 +SELECT * FROM t1; +f1 f2 +1 1 +2 1 +3 1 +4 3 +5 1 +6 1 +7 1 +8 1 +connection node_2; +SET SESSION wsrep_on = ON; +SET SESSION wsrep_sync_wait = 15; +SET SESSION wsrep_on = ON; +SET SESSION wsrep_sync_wait = 15; +SET GLOBAL wsrep_on=OFF; +# restart +DROP TABLE t1; +CALL mtr.add_suppression('mysqld: Can\'t find record in \'t1\''); +CALL mtr.add_suppression('Update_rows_v1 apply failed'); +CALL mtr.add_suppression('Inconsistency detected: Inconsistent by consensus on'); diff --git a/mysql-test/suite/galera_3nodes/t/GCF-354.cnf b/mysql-test/suite/galera_3nodes/t/GCF-354.cnf new file mode 100644 index 00000000000..252b4b613c7 --- /dev/null +++ b/mysql-test/suite/galera_3nodes/t/GCF-354.cnf @@ -0,0 +1,5 @@ +!include ../galera_3nodes.cnf + +[mysqld] +wsrep-ignore-apply-errors=0 +wsrep_sync_wait=0
\ No newline at end of file diff --git a/mysql-test/suite/galera_3nodes/t/GCF-354.test b/mysql-test/suite/galera_3nodes/t/GCF-354.test new file mode 100644 index 00000000000..f48d9fbc72a --- /dev/null +++ b/mysql-test/suite/galera_3nodes/t/GCF-354.test @@ -0,0 +1,92 @@ +--source include/galera_cluster.inc +--source include/have_innodb.inc +# +# 1. Create different inconsistencies on nodes 2 and 3 +# +--connection node_2 +SET wsrep_on=OFF; +DROP SCHEMA test; + +--connect node_3, 127.0.0.1, root, , test, $NODE_MYPORT_3 +--connection node_3 +SET wsrep_on=OFF; +CREATE TABLE test.t1 (f1 INTEGER); +# +# 2. The following should generate different errors on nodes 2 and 3 and +# trigger voting with 3 different votes. node_1 should remain alone +# in the cluster. +# +--connection node_1 +CREATE TABLE test.t1 (f1 INTEGER); + +--let $wait_condition = SELECT VARIABLE_VALUE = 1 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size' +--source include/wait_condition.inc +--let $wait_condition = SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status' +--source include/wait_condition.inc +SHOW STATUS LIKE 'wsrep_cluster_status'; + +# Test cleanup +DROP TABLE test.t1; +# +# 3. Wait for nodes 2 and 3 to drop out of the cluster and restart them to +# recover the initial configuration. +# +--connection node_2 +SET SESSION wsrep_sync_wait=0; +--let $wait_condition = SELECT VARIABLE_VALUE = 'OFF' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_ready' +--source include/wait_condition.inc +SHOW STATUS LIKE 'wsrep_cluster_status'; + +# need to reinitialize connection due to a "Bad handshake" bug +--disconnect node_2 +--connect node_2, 127.0.0.1, root, , mysql, $NODE_MYPORT_2 + +--source include/kill_galera.inc + +--connection node_2 +--source include/wait_until_disconnected.inc +--echo Starting node_2 +--source include/start_mysqld.inc + +--connection node_3 +SET SESSION wsrep_sync_wait=0; +--let $wait_condition = SELECT VARIABLE_VALUE = 'OFF' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_ready' +--source include/wait_condition.inc +SHOW STATUS LIKE 'wsrep_cluster_status'; + +# need to reinitialize connection due to a "Bad handshake" bug +--disconnect node_3 +--connect node_3, 127.0.0.1, root, , test, $NODE_MYPORT_3 + +--source include/kill_galera.inc + +--connection node_3 +--source include/wait_until_disconnected.inc +--echo Starting node_3 +--source include/start_mysqld.inc + +--connection node_1 +--let $wait_condition = SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size' +--source include/wait_condition.inc +--echo Nodes 2 and 3 started + +--connection node_2 +# fix the default schema +USE test; +--let $wait_condition = SELECT VARIABLE_VALUE = 'ON' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_ready' +--source include/wait_condition.inc +--echo Node 2 synced +CALL mtr.add_suppression("Slave SQL: Error 'Unknown database 'test'' on query. Default database: 'test'. Query: 'CREATE TABLE test.t1 \\\(f1 INTEGER\\\)', Error_code: 1049"); +CALL mtr.add_suppression("Query apply failed"); +CALL mtr.add_suppression("WSREP: Inconsistency detected: Inconsistent by consensus on .*"); +CALL mtr.add_suppression("Plugin 'InnoDB' will be forced to shutdown"); + +--connection node_3 +--let $wait_condition = SELECT VARIABLE_VALUE = 'ON' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_ready' +--source include/wait_condition.inc +--echo Node 3 synced +CALL mtr.add_suppression("Slave SQL: Error 'Table 't1' already exists' on query. Default database: 'test'. Query: 'CREATE TABLE test.t1 \\\(f1 INTEGER\\\)', Error_code: 1050"); +CALL mtr.add_suppression("Query apply failed"); +CALL mtr.add_suppression("WSREP: Inconsistency detected: Inconsistent by consensus on .*"); +CALL mtr.add_suppression("Plugin 'InnoDB' will be forced to shutdown"); + diff --git a/mysql-test/suite/galera_3nodes/t/GCF-363.cnf b/mysql-test/suite/galera_3nodes/t/GCF-363.cnf new file mode 100644 index 00000000000..7b7770e3ad1 --- /dev/null +++ b/mysql-test/suite/galera_3nodes/t/GCF-363.cnf @@ -0,0 +1,8 @@ +!include ../galera_3nodes.cnf + +[mysqld] +wsrep-ignore-apply-errors=0 + +# [mysqld.3] +# wsrep-sst-method=mysqldump +# wsrep_sst_receive_address=127.0.0.2:@mysqld.3.port diff --git a/mysql-test/suite/galera_3nodes/t/GCF-363.test b/mysql-test/suite/galera_3nodes/t/GCF-363.test new file mode 100644 index 00000000000..c8ddea435a7 --- /dev/null +++ b/mysql-test/suite/galera_3nodes/t/GCF-363.test @@ -0,0 +1,63 @@ +# +# GCF-363 Inconsistency voting: If in a 3-node cluster the nodes with applier +# error survive, the other node can not join properly +# +--source include/galera_cluster.inc +--source include/have_innodb.inc + +CREATE TABLE t1 (f1 INTEGER PRIMARY KEY, f2 CHAR(1)) ENGINE=InnoDB; + +--connection node_1 +SET GLOBAL wsrep_on=OFF; +INSERT INTO t1 VALUES (1, 'a'); +SET GLOBAL wsrep_on=ON; + +--connection node_2 +SET GLOBAL wsrep_on=OFF; +INSERT INTO t1 VALUES (1, 'a'); +SET GLOBAL wsrep_on=ON; + +--connect node_3, 127.0.0.1, root, , test, $NODE_MYPORT_3 +--connection node_3 +INSERT INTO t1 VALUES (1, 'b'); +SET SESSION wsrep_sync_wait = 0; +--let $wait_condition = SELECT VARIABLE_VALUE = 'OFF' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_ready' +--source include/wait_condition.inc +SHOW STATUS LIKE 'wsrep_cluster_status'; + +--connection node_1 +# Wait until node #3 leaves the cluster +--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size' +--source include/wait_condition.inc + +--connection node_3 +SET SESSION wsrep_on=OFF; +--source include/restart_mysqld.inc +--source include/wait_until_connected_again.inc +SET SESSION wsrep_on=ON; + +--connection node_1 +SELECT * FROM t1; + +--connection node_2 +SELECT * FROM t1; + +--connection node_3 +SELECT * FROM t1; + +DROP TABLE t1; + +--connection node_1 +CALL mtr.add_suppression("Slave SQL: Could not execute Write_rows event on table test.t1; Duplicate entry '1' for key 'PRIMARY', Error_code: 1062; handler error HA_ERR_FOUND_DUPP_KEY; the event's master log FIRST, end_log_pos 155, Error_code: 1062"); +CALL mtr.add_suppression("WSREP: Event 3 Write_rows_v1 apply failed: 121, seqno "); + +--connection node_2 +CALL mtr.add_suppression("Slave SQL: Could not execute Write_rows event on table test.t1; Duplicate entry '1' for key 'PRIMARY', Error_code: 1062; handler error HA_ERR_FOUND_DUPP_KEY; the event's master log FIRST, end_log_pos 155, Error_code: 1062"); +CALL mtr.add_suppression("WSREP: Event 3 Write_rows_v1 apply failed: 121, seqno "); + +--connection node_3 +CALL mtr.add_suppression("WSREP: Vote 0 \\\(success\\\) on (.*) is inconsistent with group. Leaving cluster."); +CALL mtr.add_suppression("WSREP: Inconsistency detected: Inconsistent by consensus on "); +CALL mtr.add_suppression("Plugin 'InnoDB' will be forced to shutdown"); + + diff --git a/mysql-test/suite/galera_3nodes/t/GCF-376.cnf b/mysql-test/suite/galera_3nodes/t/GCF-376.cnf new file mode 100644 index 00000000000..e255e1d527e --- /dev/null +++ b/mysql-test/suite/galera_3nodes/t/GCF-376.cnf @@ -0,0 +1,4 @@ +!include ../galera_3nodes.cnf + +[mysqld] +wsrep-ignore-apply-errors=0 diff --git a/mysql-test/suite/galera_3nodes/t/GCF-376.test b/mysql-test/suite/galera_3nodes/t/GCF-376.test new file mode 100644 index 00000000000..7a5c5251910 --- /dev/null +++ b/mysql-test/suite/galera_3nodes/t/GCF-376.test @@ -0,0 +1,94 @@ +# +# GCF-376: slaves become inconsistent if master goes non-prim during +# inconsistency voting +# +--source include/galera_cluster.inc +--source include/have_innodb.inc + +--connect node_3, 127.0.0.1, root, , test, $NODE_MYPORT_3 +--connection node_1 + +# Save original auto_increment_offset values. +--let $node_1=node_1 +--let $node_2=node_2 +--let $node_3=node_3 +--source ../galera/include/auto_increment_offset_save.inc + +CREATE TABLE test.t1 (f1 INTEGER PRIMARY KEY, f2 CHAR(1)) ENGINE=InnoDB; + +--connection node_2 +SET GLOBAL wsrep_on=OFF; +INSERT INTO t1 VALUES (1, 'a'); +SET GLOBAL wsrep_on=ON; + +LOCK TABLE t1 WRITE; + +--connection node_1 +INSERT INTO t1 VALUES (1, 'b'); + +SET GLOBAL wsrep_provider_options = 'gmcast.isolate=1'; +SET SESSION wsrep_sync_wait=0; + +# Wait until node #1 leaves the cluster +--connection node_3 +--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size' +--source include/wait_condition.inc + +--connection node_2 +UNLOCK TABLES; + +# Wait until node #2 leaves the cluster +--source include/wsrep_wait_disconnect.inc + +--connection node_1 +SHOW STATUS LIKE 'wsrep_cluster_status'; + +--connection node_2 +SET SESSION wsrep_sync_wait=0; +SHOW STATUS LIKE 'wsrep_cluster_status'; +SHOW STATUS LIKE 'wsrep_cluster_size'; +SET GLOBAL wsrep_on=OFF; +SELECT * FROM t1; + +--connection node_3 +SET SESSION wsrep_sync_wait=0; +--let $wait_condition = SELECT VARIABLE_VALUE = 1 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size' +--source include/wait_condition.inc +SHOW STATUS LIKE 'wsrep_cluster_status'; +SHOW STATUS LIKE 'wsrep_cluster_size'; +SELECT * FROM t1; + +# reconnect node #1 +--connection node_1 +SET GLOBAL wsrep_provider_options = 'gmcast.isolate=0'; + +# reconnect node #2 +--connection node_2 +--source include/restart_mysqld.inc +--source include/wait_until_connected_again.inc + +--connection node_1 +--let $wait_condition = SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size' +--source include/wait_condition.inc +SELECT * FROM t1; + +--connection node_2 +--let $wait_condition = SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size' +--source include/wait_condition.inc +SELECT * FROM t1; + +--connection node_3 +--let $wait_condition = SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size' +--source include/wait_condition.inc +SELECT * FROM t1; + +DROP TABLE t1; + +# Restore original auto_increment_offset values. +--source ../galera/include/auto_increment_offset_restore.inc + +--connection node_2 +CALL mtr.add_suppression("Slave SQL: Could not execute Write_rows event on table test.t1; Duplicate entry '1' for key 'PRIMARY', Error_code: 1062; handler error HA_ERR_FOUND_DUPP_KEY; the event's master log FIRST, end_log_pos (.*), Error_code: 1062"); +CALL mtr.add_suppression("WSREP: Event (.*) Write_rows_v1 apply failed: 121, seqno "); +CALL mtr.add_suppression("WSREP: Inconsistency detected: Inconsistent by consensus on (.*)"); +CALL mtr.add_suppression("Plugin 'InnoDB' will be forced to shutdown"); diff --git a/mysql-test/suite/galera_3nodes/t/galera-features#119.test b/mysql-test/suite/galera_3nodes/t/galera-features#119.test new file mode 100644 index 00000000000..95dfec23932 --- /dev/null +++ b/mysql-test/suite/galera_3nodes/t/galera-features#119.test @@ -0,0 +1,72 @@ +# +# This test tests voting (successful slave wins) in the absence of the master +# for trasaction. +# +--source include/galera_cluster.inc +--source include/have_innodb.inc + +--let $galera_connection_name = node_3 +--let $galera_server_number = 3 +--source include/galera_connect.inc + +# Save original auto_increment_offset values. +--let $node_1=node_1 +--let $node_2=node_2 +--let $node_3=node_3 +--source ../galera/include/auto_increment_offset_save.inc + +CREATE TABLE test.t1 (f1 INTEGER PRIMARY KEY) ENGINE=InnoDB; + +--connection node_2 +--let $wsrep_provider_orig = `SELECT @@wsrep_provider` +--let $wsrep_cluster_address_orig = `SELECT @@wsrep_cluster_address` +SET wsrep_on=OFF; +INSERT INTO t1 VALUES (1); +LOCK TABLE t1 WRITE; +SET GLOBAL wsrep_sync_wait=0; + +--connection node_1 +INSERT INTO t1 VALUES (1); +SET GLOBAL wsrep_sync_wait=0; +SET GLOBAL wsrep_provider_options = 'gmcast.isolate=1'; + +--connection node_3 +# wait for node_1 to disappear +--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; +--source include/wait_condition.inc + +--connection node_2 +UNLOCK TABLES; +# wait to go non-Primary due to inconsistency voting +#--let $wait_condition = SELECT VARIABLE_VALUE = 'non-Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; +#--source include/wait_condition.inc +# Somehow the above times out so we use connectin to node 3 + +--connection node_3 +# wait for node_1 to disappear +--let $wait_condition = SELECT VARIABLE_VALUE = 1 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; +--source include/wait_condition.inc + +--connection node_1 +SET GLOBAL wsrep_provider_options = 'gmcast.isolate=0'; +--source include/galera_wait_ready.inc +SET GLOBAL wsrep_sync_wait=15; +DROP TABLE test.t1; + +# reconnect node 2, since it is now inconsistent +--connection node_2 +--source include/kill_galera.inc +--source include/wait_until_disconnected.inc +--source include/start_mysqld.inc + +--connection node_2 +CALL mtr.add_suppression("Inconsistent by consensus."); +CALL mtr.add_suppression("Slave SQL: Could not execute Write_rows event on table test.t1; Duplicate entry '1' for key 'PRIMARY', Error_code: 1062; handler error HA_ERR_FOUND_DUPP_KEY; the event's master log FIRST"); +CALL mtr.add_suppression("WSREP: Event 3 Write_rows_v1 apply failed: 121, seqno"); +CALL mtr.add_suppression("WSREP: Failed to apply trx: source: "); +CALL mtr.add_suppression("WSREP: Failed to apply app buffer: seqno:"); +CALL mtr.add_suppression("WSREP: Node consistency compromized, leaving cluster..."); + +# Restore original auto_increment_offset values. +--source ../galera/include/auto_increment_offset_restore.inc + diff --git a/mysql-test/suite/galera_3nodes/t/galera_evs_suspect_timeout.test b/mysql-test/suite/galera_3nodes/t/galera_evs_suspect_timeout.test index 3f1140b175d..ee75aa085e6 100644 --- a/mysql-test/suite/galera_3nodes/t/galera_evs_suspect_timeout.test +++ b/mysql-test/suite/galera_3nodes/t/galera_evs_suspect_timeout.test @@ -26,8 +26,11 @@ SET GLOBAL wsrep_provider_options = 'evs.inactive_timeout=PT100M; evs.suspect_ti --let $wsrep_provider_options_node2 = `SELECT @@wsrep_provider_options` SET GLOBAL wsrep_provider_options = 'evs.inactive_timeout=PT100M; evs.suspect_timeout=PT1S'; -# Suspend node #3 +--connection node_3 +--source include/wait_until_connected_again.inc +--let $wsrep_cluster_address_node3 = `SELECT @@wsrep_cluster_address` +# Suspend node #3 --connection node_3 --source include/galera_suspend.inc --sleep 5 diff --git a/mysql-test/suite/galera_3nodes/t/galera_pc_weight.test b/mysql-test/suite/galera_3nodes/t/galera_pc_weight.test index 729f14a731f..0097d335e36 100644 --- a/mysql-test/suite/galera_3nodes/t/galera_pc_weight.test +++ b/mysql-test/suite/galera_3nodes/t/galera_pc_weight.test @@ -10,7 +10,7 @@ --connection node_1 SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_weight'; SET GLOBAL wsrep_provider_options = 'pc.weight=3'; -SELECT VARIABLE_VALUE = 5 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_weight'; +SELECT VARIABLE_VALUE AS expect_5 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_weight'; # Isolate node_1 from the cluster. SET GLOBAL wsrep_provider_options = 'gmcast.isolate=1'; @@ -62,15 +62,15 @@ SHOW STATUS LIKE 'wsrep_local_state_comment'; --let $wait_condition = SELECT VARIABLE_VALUE = 1 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size' --source include/wait_condition.inc -SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_weight'; -SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; -SELECT VARIABLE_VALUE = 'ON' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_connected'; -SELECT VARIABLE_VALUE = 'ON' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_ready'; -SELECT VARIABLE_VALUE = 4 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_state'; -SELECT VARIABLE_VALUE = 'Synced' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_state_comment'; +SELECT VARIABLE_VALUE AS expect_3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_weight'; +SELECT VARIABLE_VALUE AS expect_Primary FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; +SELECT VARIABLE_VALUE AS expect_ON FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_connected'; +SELECT VARIABLE_VALUE AS expect_ON FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_ready'; +SELECT VARIABLE_VALUE AS expect_4 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_state'; +SELECT VARIABLE_VALUE AS expect_Synced FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_state_comment'; SET GLOBAL wsrep_provider_options = 'pc.weight=1'; -SELECT VARIABLE_VALUE = 1 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_weight'; +SELECT VARIABLE_VALUE AS expect_1 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_weight'; # Resume cluster connectivity on node_1 --connection node_1 @@ -78,44 +78,42 @@ SET GLOBAL wsrep_provider_options = 'gmcast.isolate=0'; --let $wait_condition = SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size' --source include/wait_condition.inc +--source include/galera_wait_ready.inc --connection node_2 --source include/wait_condition.inc +--source include/galera_wait_ready.inc --connection node_3 --source include/wait_condition.inc - ---connection node_1 ---source include/wait_condition.inc +--source include/galera_wait_ready.inc # On all nodes, we now expect a Primary component of size 3, weight 3, Synced and ready -SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; -SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_weight'; -SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; -SELECT VARIABLE_VALUE = 'ON' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_connected'; -SELECT VARIABLE_VALUE = 'ON' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_ready'; -SELECT VARIABLE_VALUE = 4 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_state'; -SELECT VARIABLE_VALUE = 'Synced' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_state_comment'; +SELECT VARIABLE_VALUE AS expect_3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; +SELECT VARIABLE_VALUE AS expect_3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_weight'; +SELECT VARIABLE_VALUE AS expect_Primary FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; +SELECT VARIABLE_VALUE AS expect_ON FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_connected'; +SELECT VARIABLE_VALUE AS expect_ON FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_ready'; +SELECT VARIABLE_VALUE AS expect_4 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_state'; +SELECT VARIABLE_VALUE AS expect_Synced FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_state_comment'; --connection node_2 -SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; -SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_weight'; -SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; -SELECT VARIABLE_VALUE = 'ON' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_connected'; -SELECT VARIABLE_VALUE = 'ON' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_ready'; -SELECT VARIABLE_VALUE = 4 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_state'; -SELECT VARIABLE_VALUE = 'Synced' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_state_comment'; - ---connection node_3 -SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; -SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_weight'; -SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; -SELECT VARIABLE_VALUE = 'ON' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_connected'; -SELECT VARIABLE_VALUE = 'ON' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_ready'; -SELECT VARIABLE_VALUE = 4 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_state'; -SELECT VARIABLE_VALUE = 'Synced' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_state_comment'; +SELECT VARIABLE_VALUE AS expect_3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; +SELECT VARIABLE_VALUE AS expect_3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_weight'; +SELECT VARIABLE_VALUE AS expect_Primary FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; +SELECT VARIABLE_VALUE AS expect_ON FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_connected'; +SELECT VARIABLE_VALUE AS expect_ON FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_ready'; +SELECT VARIABLE_VALUE AS expect_4 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_state'; +SELECT VARIABLE_VALUE AS expect_Synced FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_state_comment'; --connection node_1 +SELECT VARIABLE_VALUE AS expect_3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; +SELECT VARIABLE_VALUE AS expect_3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_weight'; +SELECT VARIABLE_VALUE AS expect_Primary FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; +SELECT VARIABLE_VALUE AS expect_ON FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_connected'; +SELECT VARIABLE_VALUE AS expect_ON FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_ready'; +SELECT VARIABLE_VALUE AS expect_4 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_state'; +SELECT VARIABLE_VALUE AS expect_Synced FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_state_comment'; SET GLOBAL wsrep_provider_options = 'pc.weight=1'; --let $wait_condition = SELECT @@wsrep_provider_options LIKE '%pc.weight = 1%' @@ -124,10 +122,10 @@ SET GLOBAL wsrep_provider_options = 'pc.weight=1'; CALL mtr.add_suppression('WSREP: gcs_caused\\(\\) returned -1'); --connection node_2 -CALL mtr.add_suppression('overriding reported weight for'); CALL mtr.add_suppression('SYNC message from member'); CALL mtr.add_suppression('user message in state LEAVING'); CALL mtr.add_suppression('sending install message failed: (Transport endpoint is not connected|Socket is not connected)'); +CALL mtr.add_suppression('overriding reported weight for'); --connection node_3 CALL mtr.add_suppression('WSREP: user message in state LEAVING'); diff --git a/mysql-test/suite/galera_3nodes/t/galera_toi_vote.cnf b/mysql-test/suite/galera_3nodes/t/galera_toi_vote.cnf new file mode 100644 index 00000000000..4c5e4854606 --- /dev/null +++ b/mysql-test/suite/galera_3nodes/t/galera_toi_vote.cnf @@ -0,0 +1,5 @@ +!include ../galera_3nodes.cnf + +[mysqld] +wsrep-ignore-apply-errors=0 +wsrep_sync_wait=0 diff --git a/mysql-test/suite/galera_3nodes/t/galera_toi_vote.test b/mysql-test/suite/galera_3nodes/t/galera_toi_vote.test new file mode 100644 index 00000000000..7b5682ed030 --- /dev/null +++ b/mysql-test/suite/galera_3nodes/t/galera_toi_vote.test @@ -0,0 +1,67 @@ +# +# This test tests that TOI failure on 2 nodes (master and slave) for the +# same reason, wins over success on a third slave. +# In particular this tests that master and slave TOI cast the same vote for +# the same error +# +--source include/galera_cluster.inc +--source include/have_innodb.inc + +--let $galera_connection_name = node_3 +--let $galera_server_number = 3 +--source include/galera_connect.inc + +# Save original auto_increment_offset values. +--let $node_1=node_1 +--let $node_2=node_2 +--let $node_3=node_3 +--source ../galera/include/auto_increment_offset_save.inc + +# create inconsistency on node 3 +--connection node_3 +SET SESSION wsrep_on=OFF; +DROP SCHEMA test; + +# This should fail on nodes 1 and 2 and succeed on node 3 +--connection node_1 +--error ER_DB_CREATE_EXISTS +CREATE SCHEMA test; + +--connection node_1 +SET SESSION wsrep_sync_wait=0; +# wait for node 3 to drop from the cluster +--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; +--source include/wait_condition.inc +--let $wait_condition = SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; +--source include/wait_condition.inc + +--connection node_2 +SET SESSION wsrep_sync_wait=0; +# wait for node 3 to drop from the cluster +--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; +--source include/wait_condition.inc +--let $wait_condition = SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; +--source include/wait_condition.inc + +--connection node_3 +SET SESSION wsrep_sync_wait=0; +--let $wait_condition = SELECT VARIABLE_VALUE = 'Disconnected' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; +--source include/wait_condition.inc + +# need to reinitialize connection due to a "Bad handshake" bug +--disconnect node_3 +--connect node_3, 127.0.0.1, root, , test, $NODE_MYPORT_3 + +# reconnect node 3, since it failed +--source include/kill_galera.inc +--source include/wait_until_disconnected.inc +--source include/start_mysqld.inc +--let $wait_condition = SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; +--source include/wait_condition.inc +--let $wait_condition = SELECT VARIABLE_VALUE = 'ON' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_ready' +--source include/wait_condition.inc + +CALL mtr.add_suppression("WSREP: Vote 0 \\\(success\\\) on (.*) is inconsistent with group. Leaving cluster."); + +# Restore original auto_increment_offset values. +--source ../galera/include/auto_increment_offset_restore.inc diff --git a/mysql-test/suite/galera_3nodes/t/galera_vote_rejoin_mysqldump.cnf b/mysql-test/suite/galera_3nodes/t/galera_vote_rejoin_mysqldump.cnf new file mode 100644 index 00000000000..e255e1d527e --- /dev/null +++ b/mysql-test/suite/galera_3nodes/t/galera_vote_rejoin_mysqldump.cnf @@ -0,0 +1,4 @@ +!include ../galera_3nodes.cnf + +[mysqld] +wsrep-ignore-apply-errors=0 diff --git a/mysql-test/suite/galera_3nodes/t/galera_vote_rejoin_mysqldump.test b/mysql-test/suite/galera_3nodes/t/galera_vote_rejoin_mysqldump.test new file mode 100644 index 00000000000..70d58cb25f4 --- /dev/null +++ b/mysql-test/suite/galera_3nodes/t/galera_vote_rejoin_mysqldump.test @@ -0,0 +1,93 @@ +# +# Test that mysqldump SST is possible after a vote without a cluster restart +# + +--source include/galera_cluster.inc +--source suite/galera/include/galera_sst_set_mysqldump.inc + +--connect node_3, 127.0.0.1, root, , test, $NODE_MYPORT_3 + +# Save original auto_increment_offset values. +--let $node_1=node_1 +--let $node_2=node_2 +--let $node_3=node_3 +--source ../galera/include/auto_increment_offset_save.inc + +--connection node_1 +CREATE TABLE t1 (f1 INTEGER) ENGINE=InnoDB; + +# Introduce inconsistency on node #2 + +--connection node_2 +--let $wsrep_cluster_address_node2 = `SELECT @@wsrep_cluster_address` +SET SESSION wsrep_on=OFF; +ALTER TABLE t1 ADD PRIMARY KEY (f1); +SET SESSION wsrep_on=ON; + +# Run DDL that will fail on nodes #1 and #3 but succeed on node #2 + +--connection node_1 +--error ER_CANT_DROP_FIELD_OR_KEY +ALTER TABLE t1 LOCK=SHARED, DROP PRIMARY KEY; + +# Nodes #1 and #3 remain in the cluster + +--connection node_1 +--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; +--source include/wait_condition.inc + +SELECT VARIABLE_VALUE AS expect_Primary FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; + +--connection node_3 +SELECT VARIABLE_VALUE AS expect_2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; +SELECT VARIABLE_VALUE AS expect_Primary FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; + +# Node #2 is kicked out + +--connection node_2 +SET SESSION wsrep_on=OFF; +SELECT VARIABLE_VALUE AS expect_Disconnected FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; +SET SESSION wsrep_on=ON; + +# Restore cluster + +--disable_query_log +--eval SET GLOBAL wsrep_cluster_address = '$wsrep_cluster_address_node2' +--enable_query_log +--enable_reconnect + +--let $wait_condition = SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; +--source include/wait_condition.inc + +SELECT VARIABLE_VALUE AS expect_Primary FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; + +# Confirm that the table is now identical throughout + +--connection node_1 +SHOW CREATE TABLE t1; + +--connection node_2 +SET SESSION wsrep_on=OFF; +--let $wait_condition = SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; +--source include/wait_condition.inc +--source include/galera_wait_ready.inc +SET SESSION wsrep_on=ON; + +# restart node so we don't fail on WSREP_START_POSITION internal check +--source include/restart_mysqld.inc +--source include/wait_until_connected_again.inc + +SHOW CREATE TABLE t1; +SELECT COUNT(*) AS expect_0 FROM t1; +CALL mtr.add_suppression("is inconsistent with group"); + +--connection node_3 +SHOW CREATE TABLE t1; +DROP TABLE t1; +CALL mtr.add_suppression("Slave SQL: Error 'Can't DROP 'PRIMARY'; check that column/key exists'"); + +--connection node_1 +--source suite/galera/include/galera_sst_restore.inc + +# Restore original auto_increment_offset values. +--source ../galera/include/auto_increment_offset_restore.inc diff --git a/mysql-test/suite/galera_3nodes/t/inconsistency_shutdown.cnf b/mysql-test/suite/galera_3nodes/t/inconsistency_shutdown.cnf new file mode 100644 index 00000000000..ae2cf8068f5 --- /dev/null +++ b/mysql-test/suite/galera_3nodes/t/inconsistency_shutdown.cnf @@ -0,0 +1,9 @@ +!include ../galera_3nodes.cnf + +[mysqld] +wsrep-slave-threads=8 +wsrep-ignore-apply-errors=0 + +[ENV] +galera_cluster_size = 3 + diff --git a/mysql-test/suite/galera_3nodes/t/inconsistency_shutdown.test b/mysql-test/suite/galera_3nodes/t/inconsistency_shutdown.test new file mode 100644 index 00000000000..ac47ea5ea09 --- /dev/null +++ b/mysql-test/suite/galera_3nodes/t/inconsistency_shutdown.test @@ -0,0 +1,179 @@ +# +# Check that the node can cleanly shutdown in case of inconsistency +# (no locked up threads) +# + +--source include/galera_cluster.inc +--source include/have_innodb.inc + +# Save original auto_increment_offset values. +--let $node_1=node_1 +--let $node_2=node_2 +--let $node_3=node_3 +--source ../galera/include/auto_increment_offset_save.inc + +--connection node_2 +SELECT @@wsrep_slave_threads = 8; + +# +# 1. Inconsistency on slave +# +--connection node_1 +CREATE TABLE t1 (f1 INTEGER PRIMARY KEY, f2 INT); +INSERT INTO t1 VALUES (1, 0),(2, 0),(3, 0),(4, 0),(5, 0),(6, 0),(7, 0),(8, 0); + +--connection node_2 +# Allow 1K slave queue woithout flow control +SET GLOBAL wsrep_provider_options='gcs.fc_limit=1K'; +# Introduce 2 inconsistencies +SET wsrep_on=OFF; +DELETE FROM t1 WHERE f1 = 2; +DELETE FROM t1 WHERE f1 = 4; +SET wsrep_on=ON; + +# Build up slave queue: +# - first 8 events will be picked by slave threads +# - one moreevent will be waiting in slave queue +LOCK TABLES t1 WRITE; +--connection node_1 +UPDATE t1 SET f2 = 1 WHERE f1 = 1; +UPDATE t1 SET f2 = 1 WHERE f1 = 2; +UPDATE t1 SET f2 = 1 WHERE f1 = 3; +UPDATE t1 SET f2 = 1 WHERE f1 = 4; +UPDATE t1 SET f2 = 2 WHERE f1 = 4; /* dependent applier */ +UPDATE t1 SET f2 = 3 WHERE f1 = 4; /* dependent applier */ +UPDATE t1 SET f2 = 1 WHERE f1 = 5; +UPDATE t1 SET f2 = 1 WHERE f1 = 6; +UPDATE t1 SET f2 = 1 WHERE f1 = 7; +UPDATE t1 SET f2 = 1 WHERE f1 = 8; + +--connection node_2 +# make sure all events landed to slave queue +SET wsrep_on=OFF; +--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_recv_queue'; +--source include/wait_condition.inc +SET wsrep_on=ON; +UNLOCK TABLES; +--source include/wsrep_wait_disconnect.inc +# Wait for the node to shutdown replication +--let $members=0 +--source include/wsrep_wait_membership.inc + +--connection node_1 +--let $members=2 +--source include/wsrep_wait_membership.inc +--source include/wait_until_ready.inc +SHOW STATUS LIKE 'wsrep_cluster_size'; +SELECT * FROM t1; + +--connection node_2 +#Gracefully restart the node +SET GLOBAL wsrep_on=OFF; +--source include/shutdown_mysqld.inc +--source include/start_mysqld.inc +--source include/galera_wait_ready.inc + +DROP TABLE t1; + +# +# 2. Inconsistency on master +# +--connection node_1 +CREATE TABLE t1 (f1 INTEGER PRIMARY KEY, f2 INT); +START TRANSACTION; +INSERT INTO t1 VALUES (1, 0); +INSERT INTO t1 VALUES (2, 0); +INSERT INTO t1 VALUES (3, 0); +INSERT INTO t1 VALUES (4, 0); +INSERT INTO t1 VALUES (5, 0); +INSERT INTO t1 VALUES (6, 0); +INSERT INTO t1 VALUES (7, 0); +INSERT INTO t1 VALUES (8, 0); +COMMIT; +CREATE TABLE t2 (f1 INTEGER PRIMARY KEY, f2 INT); + +--connection node_2 +# Allow 1K slave queue without flow control +SET GLOBAL wsrep_provider_options='gcs.fc_limit=1K'; +# Introduce inconsistency +SET wsrep_on=OFF; +DROP TABLE t2; +SET wsrep_on=ON; + +# set up sync point to ensure DROP TABLE replication order below +--let galera_sync_point = after_replicate_sync +--source include/galera_set_sync_point.inc + +# Build up slave queue: +# - first 8 events will be picked by slave threads +# - one more event will be waiting in slave queue +LOCK TABLES t1 READ; + +--connection node_1 +UPDATE t1 SET f2 = 1 WHERE f1 = 1; +UPDATE t1 SET f2 = 1 WHERE f1 = 2; +UPDATE t1 SET f2 = 1 WHERE f1 = 3; +UPDATE t1 SET f2 = 1 WHERE f1 = 4; +UPDATE t1 SET f2 = 2 WHERE f1 = 4; /* dependent applier */; + +# interleave a failing statement +--connect node_2a, 127.0.0.1, root, , test, $NODE_MYPORT_2 +--connection node_2a +--send DROP TABLE t2; + +# make sure DROP TABLE from above has replicated +--connection node_2 +SET wsrep_on=OFF; +--echo "Wait for DROP TABLE to replicate" +--source include/galera_wait_sync_point.inc +--source include/galera_signal_sync_point.inc +--source include/galera_clear_sync_point.inc +--echo "DROP TABLE replicated" +SET wsrep_on=ON; + +--connection node_1 +UPDATE t1 SET f2 = 3 WHERE f1 = 4; /* dependent applier */ +UPDATE t1 SET f2 = 1 WHERE f1 = 5; +UPDATE t1 SET f2 = 1 WHERE f1 = 6; +UPDATE t1 SET f2 = 1 WHERE f1 = 7; +UPDATE t1 SET f2 = 1 WHERE f1 = 8; + +--connection node_2 +# make sure all events landed to slave queue +SET wsrep_on=OFF; +--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_recv_queue'; +--source include/wait_condition.inc +SET wsrep_on=ON; +UNLOCK TABLES; + +--connection node_2a +--error ER_BAD_TABLE_ERROR +--reap + +--connection node_1 +--let $members=2 +--source include/wsrep_wait_membership.inc +--source include/wait_until_ready.inc +SHOW STATUS LIKE 'wsrep_cluster_size'; +SELECT * FROM t1; + +--connection node_2 +--source include/wsrep_wait_disconnect.inc +# Wait for the node to shutdown replication +--let $members=0 +--source include/wsrep_wait_membership.inc +# Gracefully restart the node +SET GLOBAL wsrep_on=OFF; +--source include/shutdown_mysqld.inc +--source include/start_mysqld.inc +--source include/galera_wait_ready.inc + +DROP TABLE t1; + +CALL mtr.add_suppression('mysqld: Can\'t find record in \'t1\''); +CALL mtr.add_suppression('Update_rows_v1 apply failed'); +CALL mtr.add_suppression('Inconsistency detected: Inconsistent by consensus on'); +CALL mtr.add_suppression('last left .* greater than drain seqno'); + +# Restore original auto_increment_offset values. +--source ../galera/include/auto_increment_offset_restore.inc diff --git a/mysql-test/suite/galera_3nodes_sr/r/galera_vote_sr.result b/mysql-test/suite/galera_3nodes_sr/r/galera_vote_sr.result new file mode 100644 index 00000000000..55a0757897a --- /dev/null +++ b/mysql-test/suite/galera_3nodes_sr/r/galera_vote_sr.result @@ -0,0 +1,195 @@ +connection node_2; +connection node_1; +connect node_3, 127.0.0.1, root, , test, $NODE_MYPORT_3; +connection node_1; +connection node_2; +connection node_3; +Inconsistency on the first fragment +connection node_1; +CREATE TABLE t1 (f1 INTEGER PRIMARY KEY, f2 BLOB) ENGINE=InnoDB; +connection node_2; +SET SESSION wsrep_on=OFF; +INSERT INTO t1 VALUES (1, 'X'); +SET SESSION wsrep_on=ON; +DELETE FROM t1 WHERE f1 = 2; +connection node_1; +SET AUTOCOMMIT=OFF; +SET SESSION wsrep_trx_fragment_size = 131070; +START TRANSACTION; +INSERT INTO t1 VALUES (1, REPEAT('A', 65535)); +INSERT INTO t1 VALUES (2, REPEAT('A', 65535)); +INSERT INTO t1 VALUES (3, REPEAT('A', 65535)); +INSERT INTO t1 VALUES (4, REPEAT('A', 65535)); +INSERT INTO t1 VALUES (5, REPEAT('A', 65535)); +COMMIT; +SELECT COUNT(*) AS expect_0 FROM mysql.wsrep_streaming_log; +expect_0 +0 +START TRANSACTION; +INSERT INTO t1 VALUES (11, REPEAT('A', 65535)); +INSERT INTO t1 VALUES (12, REPEAT('A', 65535)); +INSERT INTO t1 VALUES (13, REPEAT('A', 65535)); +INSERT INTO t1 VALUES (14, REPEAT('A', 65535)); +INSERT INTO t1 VALUES (15, REPEAT('A', 65535)); +connection node_2; +SET SESSION wsrep_on=OFF; +Starting mysqld +# restart +connection node_1; +connection node_2; +SELECT COUNT(*) > 0 FROM mysql.wsrep_streaming_log; +COUNT(*) > 0 +1 +connection node_1; +COMMIT; +connection node_1; +SELECT COUNT(*) AS expect_0 FROM mysql.wsrep_streaming_log; +expect_0 +0 +SELECT COUNT(*) AS expect_10 FROM t1; +expect_10 +10 +connection node_2; +SELECT COUNT(*) AS expect_0 FROM mysql.wsrep_streaming_log; +expect_0 +0 +SELECT COUNT(*) AS expect_10 FROM t1; +expect_10 +10 +connection node_3; +SELECT COUNT(*) AS expect_0 FROM mysql.wsrep_streaming_log; +expect_0 +0 +SELECT COUNT(*) AS expect_10 FROM t1; +expect_10 +10 +connection node_1; +DROP TABLE t1; +Inconsistency on a middle fragment +connection node_1; +CREATE TABLE t1 (f1 INTEGER PRIMARY KEY, f2 BLOB) ENGINE=InnoDB; +connection node_2; +SET SESSION wsrep_on=OFF; +INSERT INTO t1 VALUES (3, 'X'); +SET SESSION wsrep_on=ON; +DELETE FROM t1 WHERE f1 = 2; +connection node_1; +SET AUTOCOMMIT=OFF; +SET SESSION wsrep_trx_fragment_size = 131070; +START TRANSACTION; +INSERT INTO t1 VALUES (1, REPEAT('A', 65535)); +INSERT INTO t1 VALUES (2, REPEAT('A', 65535)); +INSERT INTO t1 VALUES (3, REPEAT('A', 65535)); +INSERT INTO t1 VALUES (4, REPEAT('A', 65535)); +INSERT INTO t1 VALUES (5, REPEAT('A', 65535)); +COMMIT; +SELECT COUNT(*) AS expect_0 FROM mysql.wsrep_streaming_log; +expect_0 +0 +START TRANSACTION; +INSERT INTO t1 VALUES (11, REPEAT('A', 65535)); +INSERT INTO t1 VALUES (12, REPEAT('A', 65535)); +INSERT INTO t1 VALUES (13, REPEAT('A', 65535)); +INSERT INTO t1 VALUES (14, REPEAT('A', 65535)); +INSERT INTO t1 VALUES (15, REPEAT('A', 65535)); +connection node_2; +SET SESSION wsrep_on=OFF; +Starting mysqld +# restart +connection node_1; +connection node_2; +SELECT COUNT(*) > 0 FROM mysql.wsrep_streaming_log; +COUNT(*) > 0 +1 +connection node_1; +COMMIT; +connection node_1; +SELECT COUNT(*) AS expect_0 FROM mysql.wsrep_streaming_log; +expect_0 +0 +SELECT COUNT(*) AS expect_10 FROM t1; +expect_10 +10 +connection node_2; +SELECT COUNT(*) AS expect_0 FROM mysql.wsrep_streaming_log; +expect_0 +0 +SELECT COUNT(*) AS expect_10 FROM t1; +expect_10 +10 +connection node_3; +SELECT COUNT(*) AS expect_0 FROM mysql.wsrep_streaming_log; +expect_0 +0 +SELECT COUNT(*) AS expect_10 FROM t1; +expect_10 +10 +connection node_1; +DROP TABLE t1; +Inconsistency on the commit fragment +connection node_1; +CREATE TABLE t1 (f1 INTEGER PRIMARY KEY, f2 BLOB) ENGINE=InnoDB; +connection node_2; +SET SESSION wsrep_on=OFF; +INSERT INTO t1 VALUES (5, 'X'); +SET SESSION wsrep_on=ON; +DELETE FROM t1 WHERE f1 = 2; +connection node_1; +SET AUTOCOMMIT=OFF; +SET SESSION wsrep_trx_fragment_size = 131070; +START TRANSACTION; +INSERT INTO t1 VALUES (1, REPEAT('A', 65535)); +INSERT INTO t1 VALUES (2, REPEAT('A', 65535)); +INSERT INTO t1 VALUES (3, REPEAT('A', 65535)); +INSERT INTO t1 VALUES (4, REPEAT('A', 65535)); +INSERT INTO t1 VALUES (5, REPEAT('A', 65535)); +COMMIT; +SELECT COUNT(*) AS expect_0 FROM mysql.wsrep_streaming_log; +expect_0 +0 +START TRANSACTION; +INSERT INTO t1 VALUES (11, REPEAT('A', 65535)); +INSERT INTO t1 VALUES (12, REPEAT('A', 65535)); +INSERT INTO t1 VALUES (13, REPEAT('A', 65535)); +INSERT INTO t1 VALUES (14, REPEAT('A', 65535)); +INSERT INTO t1 VALUES (15, REPEAT('A', 65535)); +connection node_2; +SET SESSION wsrep_on=OFF; +Starting mysqld +# restart +connection node_1; +connection node_2; +SELECT COUNT(*) > 0 FROM mysql.wsrep_streaming_log; +COUNT(*) > 0 +1 +connection node_1; +COMMIT; +connection node_1; +SELECT COUNT(*) AS expect_0 FROM mysql.wsrep_streaming_log; +expect_0 +0 +SELECT COUNT(*) AS expect_10 FROM t1; +expect_10 +10 +connection node_2; +SELECT COUNT(*) AS expect_0 FROM mysql.wsrep_streaming_log; +expect_0 +0 +SELECT COUNT(*) AS expect_10 FROM t1; +expect_10 +10 +connection node_3; +SELECT COUNT(*) AS expect_0 FROM mysql.wsrep_streaming_log; +expect_0 +0 +SELECT COUNT(*) AS expect_10 FROM t1; +expect_10 +10 +connection node_1; +DROP TABLE t1; +connection node_2; +CALL mtr.add_suppression("Slave SQL: Could not execute Write_rows event on table test.t1; Duplicate entry '1' for key 'PRIMARY'"); +CALL mtr.add_suppression("Slave SQL: Could not execute Write_rows event on table test.t1; Duplicate entry '3' for key 'PRIMARY'"); +CALL mtr.add_suppression("Slave SQL: Could not execute Write_rows event on table test.t1; Duplicate entry '5' for key 'PRIMARY'"); +CALL mtr.add_suppression("Write_rows_v1 apply failed"); +CALL mtr.add_suppression("Inconsistent by consensus"); diff --git a/mysql-test/suite/galera_3nodes_sr/t/galera_vote_sr-master.opt b/mysql-test/suite/galera_3nodes_sr/t/galera_vote_sr-master.opt new file mode 100644 index 00000000000..196498bb9fa --- /dev/null +++ b/mysql-test/suite/galera_3nodes_sr/t/galera_vote_sr-master.opt @@ -0,0 +1,2 @@ +--wsrep-ignore-apply-errors=0 + diff --git a/mysql-test/suite/galera_3nodes_sr/t/galera_vote_sr.inc b/mysql-test/suite/galera_3nodes_sr/t/galera_vote_sr.inc new file mode 100644 index 00000000000..db6ba458379 --- /dev/null +++ b/mysql-test/suite/galera_3nodes_sr/t/galera_vote_sr.inc @@ -0,0 +1,79 @@ +# +# set $inconsistent_fragment to determine at which fragment inconsistency +# happens +# + +--connection node_1 +CREATE TABLE t1 (f1 INTEGER PRIMARY KEY, f2 BLOB) ENGINE=InnoDB; + +# Introduce inconsistency +--connection node_2 +SET SESSION wsrep_on=OFF; +--eval INSERT INTO t1 VALUES ($inconsistent_fragment, 'X') +SET SESSION wsrep_on=ON; +DELETE FROM t1 WHERE f1 = 2; + +# Perform an SR transaction that will hit the inconsistency +--connection node_1 +SET AUTOCOMMIT=OFF; +SET SESSION wsrep_trx_fragment_size = 131070; +START TRANSACTION; +INSERT INTO t1 VALUES (1, REPEAT('A', 65535)); +INSERT INTO t1 VALUES (2, REPEAT('A', 65535)); +INSERT INTO t1 VALUES (3, REPEAT('A', 65535)); +INSERT INTO t1 VALUES (4, REPEAT('A', 65535)); +INSERT INTO t1 VALUES (5, REPEAT('A', 65535)); +COMMIT; +SELECT COUNT(*) AS expect_0 FROM mysql.wsrep_streaming_log; + +# Perform another SR transaction in order to have stuff in the +# wsrep_streaming_log table +START TRANSACTION; +INSERT INTO t1 VALUES (11, REPEAT('A', 65535)); +INSERT INTO t1 VALUES (12, REPEAT('A', 65535)); +INSERT INTO t1 VALUES (13, REPEAT('A', 65535)); +INSERT INTO t1 VALUES (14, REPEAT('A', 65535)); +INSERT INTO t1 VALUES (15, REPEAT('A', 65535)); + +# Node #2 has dropped from the cluster due to voting +--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; +--source include/wait_condition.inc + +# Bring node #2 back via SST +--connection node_2 +SET SESSION wsrep_on=OFF; +--source include/shutdown_mysqld.inc +--source include/wait_until_disconnected.inc +--echo Starting mysqld +--source include/start_mysqld.inc + +--connection node_1 +--let $wait_condition = SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; +--source include/wait_condition.inc + +--connection node_2 +--let $wait_condition = SELECT VARIABLE_VALUE = 'ON' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_ready'; +--source include/wait_condition.inc + +# Node #2 should have some entries in its SR table post-restart +SELECT COUNT(*) > 0 FROM mysql.wsrep_streaming_log; + +# Commit second SR transaction +--connection node_1 +COMMIT; + +# Confirm that all nodes are identical +--connection node_1 +SELECT COUNT(*) AS expect_0 FROM mysql.wsrep_streaming_log; +SELECT COUNT(*) AS expect_10 FROM t1; + +--connection node_2 +SELECT COUNT(*) AS expect_0 FROM mysql.wsrep_streaming_log; +SELECT COUNT(*) AS expect_10 FROM t1; + +--connection node_3 +SELECT COUNT(*) AS expect_0 FROM mysql.wsrep_streaming_log; +SELECT COUNT(*) AS expect_10 FROM t1; + +--connection node_1 +DROP TABLE t1; diff --git a/mysql-test/suite/galera_3nodes_sr/t/galera_vote_sr.test b/mysql-test/suite/galera_3nodes_sr/t/galera_vote_sr.test new file mode 100644 index 00000000000..de2fe2c019d --- /dev/null +++ b/mysql-test/suite/galera_3nodes_sr/t/galera_vote_sr.test @@ -0,0 +1,37 @@ +# +# Test voting while an SR transaction is in progress +# + +--source include/galera_cluster.inc +--source include/big_test.inc + +--connect node_3, 127.0.0.1, root, , test, $NODE_MYPORT_3 + +# Save original auto_increment_offset values. +--let $node_1=node_1 +--let $node_2=node_2 +--let $node_3=node_3 +--source ../galera/include/auto_increment_offset_save.inc + +--echo Inconsistency on the first fragment +--let $inconsistent_fragment=1 +--source galera_vote_sr.inc + +--echo Inconsistency on a middle fragment +--let $inconsistent_fragment=3 +--source galera_vote_sr.inc + +--echo Inconsistency on the commit fragment +--let $inconsistent_fragment=5 +--source galera_vote_sr.inc + +--connection node_2 +CALL mtr.add_suppression("Slave SQL: Could not execute Write_rows event on table test.t1; Duplicate entry '1' for key 'PRIMARY'"); +CALL mtr.add_suppression("Slave SQL: Could not execute Write_rows event on table test.t1; Duplicate entry '3' for key 'PRIMARY'"); +CALL mtr.add_suppression("Slave SQL: Could not execute Write_rows event on table test.t1; Duplicate entry '5' for key 'PRIMARY'"); +CALL mtr.add_suppression("Write_rows_v1 apply failed"); +CALL mtr.add_suppression("Inconsistent by consensus"); +#CALL mtr.add_suppression("no THD for trx"); + +# Restore original auto_increment_offset values. +--source ../galera/include/auto_increment_offset_restore.inc diff --git a/mysql-test/suite/galera_sr/r/galera_sr_mysqldump_sst.result b/mysql-test/suite/galera_sr/r/galera_sr_mysqldump_sst.result index df454772346..6789990f18e 100644 --- a/mysql-test/suite/galera_sr/r/galera_sr_mysqldump_sst.result +++ b/mysql-test/suite/galera_sr/r/galera_sr_mysqldump_sst.result @@ -10,6 +10,8 @@ SET GLOBAL wsrep_sst_auth = 'sst:'; connection node_2; SET GLOBAL wsrep_sst_method = 'mysqldump'; connection node_1; +connection node_2; +connection node_1; CREATE TABLE ten (f1 INTEGER); INSERT INTO ten VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10); CREATE TABLE t1 (f1 INTEGER PRIMARY KEY AUTO_INCREMENT, f2 CHAR(255)) ENGINE=InnoDB; diff --git a/mysql-test/suite/galera_sr/t/galera_sr_mysqldump_sst.test b/mysql-test/suite/galera_sr/t/galera_sr_mysqldump_sst.test index 5a3f48e02a3..9df4392375a 100644 --- a/mysql-test/suite/galera_sr/t/galera_sr_mysqldump_sst.test +++ b/mysql-test/suite/galera_sr/t/galera_sr_mysqldump_sst.test @@ -7,6 +7,11 @@ --source suite/galera/include/galera_sst_set_mysqldump.inc +# Save original auto_increment_offset values. +--let $node_1=node_1 +--let $node_2=node_2 +--source ../../galera/include/auto_increment_offset_save.inc + --connection node_1 CREATE TABLE ten (f1 INTEGER); INSERT INTO ten VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10); @@ -77,3 +82,6 @@ DROP TABLE ten; # with SR, need to disable SR before that. SET SESSION wsrep_trx_fragment_size=0; --source suite/galera/include/galera_sst_restore.inc + +# Restore original auto_increment_offset values. +--source ../galera/include/auto_increment_offset_restore.inc diff --git a/sql/handler.cc b/sql/handler.cc index 94cffd69b75..5f2a1a573ba 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -1537,8 +1537,9 @@ int ha_commit_trans(THD *thd, bool all) #endif /* WITH_WSREP */ error= ha_commit_one_phase(thd, all); #ifdef WITH_WSREP - if (run_wsrep_hooks) - error= error || wsrep_after_commit(thd, all); + // Here in case of error we must return 2 for inconsistency + if (run_wsrep_hooks && !error) + error= wsrep_after_commit(thd, all) ? 2 : 0; #endif /* WITH_WSREP */ goto done; } @@ -1607,8 +1608,10 @@ int ha_commit_trans(THD *thd, bool all) error= commit_one_phase_2(thd, all, trans, is_real_trans) ? 2 : 0; #ifdef WITH_WSREP - if (run_wsrep_hooks && (error || (error = wsrep_after_commit(thd, all)))) + if (run_wsrep_hooks && + (error || (error = wsrep_after_commit(thd, all)))) { + error = 2; mysql_mutex_lock(&thd->LOCK_thd_data); if (wsrep_must_abort(thd)) { diff --git a/sql/log.cc b/sql/log.cc index d5d879a3409..4f51a9a9c17 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -7735,7 +7735,7 @@ MYSQL_BIN_LOG::write_transaction_to_binlog_events(group_commit_entry *entry) Release commit order and if leader, wait for prior commit to complete. This establishes total order for group leaders. */ - if (wsrep_ordered_commit(entry->thd, entry->all, wsrep_apply_error())) + if (wsrep_ordered_commit(entry->thd, entry->all)) { entry->thd->wakeup_subsequent_commits(1); return 1; diff --git a/sql/service_wsrep.cc b/sql/service_wsrep.cc index 8583897e064..c47ba9d9d37 100644 --- a/sql/service_wsrep.cc +++ b/sql/service_wsrep.cc @@ -270,3 +270,13 @@ extern "C" void wsrep_commit_ordered(THD *thd) thd->wsrep_cs().ordered_commit(); } } + +extern "C" my_bool wsrep_thd_has_ignored_error(const THD *thd) +{ + return thd->wsrep_has_ignored_error; +} + +extern "C" void wsrep_thd_set_ignored_error(THD *thd, my_bool val) +{ + thd->wsrep_has_ignored_error= val; +} diff --git a/sql/sql_plugin_services.ic b/sql/sql_plugin_services.ic index c7ecfcd482e..c3b0088c9bd 100644 --- a/sql/sql_plugin_services.ic +++ b/sql/sql_plugin_services.ic @@ -173,7 +173,9 @@ static struct wsrep_service_st wsrep_handler = { wsrep_get_sr_table_name, wsrep_get_debug, wsrep_commit_ordered, - wsrep_thd_is_applying + wsrep_thd_is_applying, + wsrep_thd_has_ignored_error, + wsrep_thd_set_ignored_error }; static struct thd_specifics_service_st thd_specifics_handler= diff --git a/sql/wsrep_applier.cc b/sql/wsrep_applier.cc index fd51dbf9439..1ab65df1ca3 100644 --- a/sql/wsrep_applier.cc +++ b/sql/wsrep_applier.cc @@ -1,4 +1,4 @@ -/* Copyright (C) 2013-2015 Codership Oy <info@codership.com> +/* Copyright (C) 2013-2019 Codership Oy <info@codership.com> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -24,7 +24,6 @@ #include "wsrep_trans_observer.h" #include "slave.h" // opt_log_slave_updates -#include "log_event.h" // class THD, EVENT_LEN_OFFSET, etc. #include "debug_sync.h" /* @@ -60,7 +59,6 @@ static Log_event* wsrep_read_log_event( } #include "transaction.h" // trans_commit(), trans_rollback() -#include "rpl_rli.h" // class Relay_log_info; void wsrep_set_apply_format(THD* thd, Format_description_log_event* ev) { @@ -84,7 +82,7 @@ wsrep_get_apply_format(THD* thd) return thd->wsrep_rgi->rli->relay_log.description_event_for_exec; } -void wsrep_apply_error::store(const THD* const thd) +void wsrep_store_error(const THD* const thd, wsrep::mutable_buffer& dst) { Diagnostics_area::Sql_condition_iterator it= thd->get_stmt_da()->sql_conditions(); @@ -92,27 +90,10 @@ void wsrep_apply_error::store(const THD* const thd) static size_t const max_len= 2*MAX_SLAVE_ERRMSG; // 2x so that we have enough - if (NULL == str_) - { - // this must be freeable by standard free() - str_= static_cast<char*>(malloc(max_len)); - if (NULL == str_) - { - WSREP_ERROR("Failed to allocate %zu bytes for error buffer.", max_len); - len_= 0; - return; - } - } - else - { - /* This is possible when we invoke rollback after failed applying. - * In this situation DA should not be reset yet and should contain - * all previous errors from applying and new ones from rollbacking, - * so we just overwrite is from scratch */ - } + dst.resize(max_len); - char* slider= str_; - const char* const buf_end= str_ + max_len - 1; // -1: leave space for \0 + char* slider= dst.data(); + const char* const buf_end= slider + max_len - 1; // -1: leave space for \0 for (cond= it++; cond && slider < buf_end; cond= it++) { @@ -123,12 +104,17 @@ void wsrep_apply_error::store(const THD* const thd) err_str, err_code); } - *slider= '\0'; - len_= slider - str_ + 1; // +1: add \0 + if (slider != dst.data()) + { + *slider= '\0'; + slider++; + } + + dst.resize(slider - dst.data()); - WSREP_DEBUG("Error buffer for thd %llu seqno %lld, %zu bytes: %s", + WSREP_DEBUG("Error buffer for thd %llu seqno %lld, %zu bytes: '%s'", thd->thread_id, (long long)wsrep_thd_trx_seqno(thd), - len_, str_ ? str_ : "(null)"); + dst.size(), dst.size() ? dst.data() : "(null)"); } int wsrep_apply_events(THD* thd, diff --git a/sql/wsrep_applier.h b/sql/wsrep_applier.h index 70361987cc7..fefca306a70 100644 --- a/sql/wsrep_applier.h +++ b/sql/wsrep_applier.h @@ -1,4 +1,4 @@ -/* Copyright 2013-2015 Codership Oy <http://www.codership.com> +/* Copyright 2013-2019 Codership Oy <http://www.codership.com> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -16,16 +16,15 @@ #ifndef WSREP_APPLIER_H #define WSREP_APPLIER_H -#include <my_config.h> - #include "sql_class.h" // THD class +#include "rpl_rli.h" // Relay_log_info +#include "log_event.h" // Format_description_log_event int wsrep_apply_events(THD* thd, Relay_log_info* rli, const void* events_buf, size_t buf_len); - /* Applier error codes, when nothing better is available. */ #define WSREP_RET_SUCCESS 0 // Success #define WSREP_ERR_GENERIC 1 // When in doubt (MySQL default error code) @@ -36,38 +35,10 @@ int wsrep_apply_events(THD* thd, #define WSREP_ERR_FAILED 6 // Operation failed for some internal reason #define WSREP_ERR_ABORTED 7 // Operation was aborted externally -class wsrep_apply_error -{ -public: - wsrep_apply_error() : str_(NULL), len_(0) {}; - ~wsrep_apply_error() { ::free(str_); } - /* stores the current THD error info from the diagnostic area. Works only - * once, subsequent invocations are ignored in order to preserve the original - * condition. */ - void store(const THD* thd); - const char* c_str() const { return str_; } - size_t length() const { return len_; } - bool is_null() const { return (c_str() == NULL && length() == 0); } - wsrep_buf_t get_buf() const - { - wsrep_buf_t ret= { c_str(), length() }; - return ret; - } -private: - char* str_; - size_t len_; -}; +void wsrep_store_error(const THD* thd, wsrep::mutable_buffer& buf); class Format_description_log_event; void wsrep_set_apply_format(THD*, Format_description_log_event*); Format_description_log_event* wsrep_get_apply_format(THD* thd); -int wsrep_apply(void* ctx, - uint32_t flags, - const wsrep_buf_t* buf, - const wsrep_trx_meta_t* meta, - wsrep_apply_error& err); - -wsrep_cb_status_t wsrep_unordered_cb(void* ctx, - const wsrep_buf_t* data); #endif /* WSREP_APPLIER_H */ diff --git a/sql/wsrep_binlog.cc b/sql/wsrep_binlog.cc index ecab4664d7b..cfa709b1055 100644 --- a/sql/wsrep_binlog.cc +++ b/sql/wsrep_binlog.cc @@ -417,7 +417,9 @@ void wsrep_register_for_group_commit(THD *thd) void wsrep_unregister_from_group_commit(THD *thd) { - DBUG_ASSERT(thd->wsrep_trx().state() == wsrep::transaction::s_ordered_commit); + DBUG_ASSERT(thd->wsrep_trx().state() == wsrep::transaction::s_ordered_commit|| + // ordered_commit() failure results in s_aborting state + thd->wsrep_trx().state() == wsrep::transaction::s_aborting); wait_for_commit *wfc= thd->wait_for_commit_ptr; if (wfc) diff --git a/sql/wsrep_client_service.cc b/sql/wsrep_client_service.cc index b182691c593..0fa10c1c9ea 100644 --- a/sql/wsrep_client_service.cc +++ b/sql/wsrep_client_service.cc @@ -15,7 +15,6 @@ #include "wsrep_client_service.h" #include "wsrep_high_priority_service.h" -#include "wsrep_applier.h" /* wsrep_apply_events() */ #include "wsrep_binlog.h" /* wsrep_dump_rbr_buf() */ #include "wsrep_schema.h" /* remove_fragments() */ #include "wsrep_thd.h" diff --git a/sql/wsrep_dummy.cc b/sql/wsrep_dummy.cc index 75ee9b04cdf..2ea434c092b 100644 --- a/sql/wsrep_dummy.cc +++ b/sql/wsrep_dummy.cc @@ -138,3 +138,9 @@ void wsrep_commit_ordered(THD* ) my_bool wsrep_thd_is_applying(const THD*) { return 0;} + +my_bool wsrep_thd_has_ignored_error(const THD*) +{ return 0;} + +void wsrep_thd_set_ignored_error(THD*, my_bool) +{ } diff --git a/sql/wsrep_high_priority_service.cc b/sql/wsrep_high_priority_service.cc index 68cf0d1877b..581ecfc8d34 100644 --- a/sql/wsrep_high_priority_service.cc +++ b/sql/wsrep_high_priority_service.cc @@ -119,6 +119,23 @@ static void wsrep_setup_uk_and_fk_checks(THD* thd) thd->variables.option_bits&= ~OPTION_NO_FOREIGN_KEY_CHECKS; } +static int apply_events(THD* thd, + Relay_log_info* rli, + const wsrep::const_buffer& data, + wsrep::mutable_buffer& err) +{ + int const ret= wsrep_apply_events(thd, rli, data.data(), data.size()); + if (ret || wsrep_thd_has_ignored_error(thd)) + { + if (ret) + { + wsrep_store_error(thd, err); + } + wsrep_dump_rbr_buf_with_header(thd, data.data(), data.size()); + } + return ret; +} + /**************************************************************************** High priority service *****************************************************************************/ @@ -247,8 +264,8 @@ int Wsrep_high_priority_service::append_fragment_and_commit( common utility function to deal with commit. */ const bool do_binlog_commit= (opt_log_slave_updates && - wsrep_gtid_mode && - m_thd->variables.gtid_seq_no); + wsrep_gtid_mode && + m_thd->variables.gtid_seq_no); /* Write skip event into binlog if gtid_mode is on. This is to maintain gtid continuity. @@ -265,8 +282,7 @@ int Wsrep_high_priority_service::append_fragment_and_commit( } ret= ret || trans_commit(m_thd); - - m_thd->wsrep_cs().after_applying(); + ret= ret || (m_thd->wsrep_cs().after_applying(), 0); m_thd->mdl_context.release_transactional_locks(); thd_proc_info(m_thd, "wsrep applier committed"); @@ -335,7 +351,15 @@ int Wsrep_high_priority_service::rollback(const wsrep::ws_handle& ws_handle, const wsrep::ws_meta& ws_meta) { DBUG_ENTER("Wsrep_high_priority_service::rollback"); - m_thd->wsrep_cs().prepare_for_ordering(ws_handle, ws_meta, false); + if (ws_meta.ordered()) + { + m_thd->wsrep_cs().prepare_for_ordering(ws_handle, ws_meta, false); + } + else + { + assert(ws_meta == wsrep::ws_meta()); + assert(ws_handle == wsrep::ws_handle()); + } int ret= (trans_rollback_stmt(m_thd) || trans_rollback(m_thd)); m_thd->mdl_context.release_transactional_locks(); m_thd->mdl_context.release_explicit_locks(); @@ -344,7 +368,7 @@ int Wsrep_high_priority_service::rollback(const wsrep::ws_handle& ws_handle, int Wsrep_high_priority_service::apply_toi(const wsrep::ws_meta& ws_meta, const wsrep::const_buffer& data, - wsrep::mutable_buffer&) + wsrep::mutable_buffer& err) { DBUG_ENTER("Wsrep_high_priority_service::apply_toi"); THD* thd= m_thd; @@ -358,13 +382,8 @@ int Wsrep_high_priority_service::apply_toi(const wsrep::ws_meta& ws_meta, WSREP_DEBUG("Wsrep_high_priority_service::apply_toi: %lld", client_state.toi_meta().seqno().get()); - int ret= wsrep_apply_events(thd, m_rli, data.data(), data.size()); - if (ret != 0 || thd->wsrep_has_ignored_error) - { - wsrep_dump_rbr_buf_with_header(thd, data.data(), data.size()); - thd->wsrep_has_ignored_error= false; - /* todo: error voting */ - } + int ret= apply_events(thd, m_rli, data, err); + wsrep_thd_set_ignored_error(thd, false); trans_commit(thd); thd->close_temporary_tables(); @@ -435,6 +454,11 @@ int Wsrep_high_priority_service::log_dummy_write_set(const wsrep::ws_handle& ws_ DBUG_RETURN(ret); } +void Wsrep_high_priority_service::adopt_apply_error(wsrep::mutable_buffer& err) +{ + m_thd->wsrep_cs().adopt_apply_error(err); +} + void Wsrep_high_priority_service::debug_crash(const char* crash_point) { DBUG_ASSERT(m_thd == current_thd); @@ -466,7 +490,7 @@ Wsrep_applier_service::~Wsrep_applier_service() int Wsrep_applier_service::apply_write_set(const wsrep::ws_meta& ws_meta, const wsrep::const_buffer& data, - wsrep::mutable_buffer&) + wsrep::mutable_buffer& err) { DBUG_ENTER("Wsrep_applier_service::apply_write_set"); THD* thd= m_thd; @@ -492,13 +516,7 @@ int Wsrep_applier_service::apply_write_set(const wsrep::ws_meta& ws_meta, };); wsrep_setup_uk_and_fk_checks(thd); - - int ret= wsrep_apply_events(thd, m_rli, data.data(), data.size()); - - if (ret || thd->wsrep_has_ignored_error) - { - wsrep_dump_rbr_buf_with_header(thd, data.data(), data.size()); - } + int ret= apply_events(thd, m_rli, data, err); thd->close_temporary_tables(); if (!ret && !(ws_meta.flags() & wsrep::provider::flag::commit)) @@ -621,7 +639,7 @@ Wsrep_replayer_service::~Wsrep_replayer_service() int Wsrep_replayer_service::apply_write_set(const wsrep::ws_meta& ws_meta, const wsrep::const_buffer& data, - wsrep::mutable_buffer&) + wsrep::mutable_buffer& err) { DBUG_ENTER("Wsrep_replayer_service::apply_write_set"); THD* thd= m_thd; @@ -640,14 +658,7 @@ int Wsrep_replayer_service::apply_write_set(const wsrep::ws_meta& ws_meta, ws_meta, thd->wsrep_sr().fragments()); } - - ret= ret || wsrep_apply_events(thd, m_rli, data.data(), data.size()); - - if (ret || thd->wsrep_has_ignored_error) - { - wsrep_dump_rbr_buf_with_header(thd, data.data(), data.size()); - } - + ret= ret || apply_events(thd, m_rli, data, err); thd->close_temporary_tables(); if (!ret && !(ws_meta.flags() & wsrep::provider::flag::commit)) { diff --git a/sql/wsrep_high_priority_service.h b/sql/wsrep_high_priority_service.h index c8c5eb87f44..5657a2e82fc 100644 --- a/sql/wsrep_high_priority_service.h +++ b/sql/wsrep_high_priority_service.h @@ -17,7 +17,6 @@ #define WSREP_HIGH_PRIORITY_SERVICE_H #include "wsrep/high_priority_service.hpp" -#include "wsrep/client_state.hpp" #include "my_global.h" #include "sql_error.h" /* Diagnostics area */ #include "sql_class.h" /* rpl_group_info */ @@ -53,7 +52,7 @@ public: int log_dummy_write_set(const wsrep::ws_handle&, const wsrep::ws_meta&, wsrep::mutable_buffer&); - void adopt_apply_error(wsrep::mutable_buffer& err) {} + void adopt_apply_error(wsrep::mutable_buffer&); virtual bool check_exit_status() const = 0; void debug_crash(const char*); @@ -74,7 +73,7 @@ protected: my_hrtime_t user_time; longlong row_count_func; bool wsrep_applier; -} m_shadow; + } m_shadow; }; class Wsrep_applier_service : public Wsrep_high_priority_service diff --git a/sql/wsrep_mysqld.cc b/sql/wsrep_mysqld.cc index 6b64915ada2..ad4203490f2 100644 --- a/sql/wsrep_mysqld.cc +++ b/sql/wsrep_mysqld.cc @@ -281,7 +281,7 @@ static void wsrep_log_cb(wsrep::log::level level, const char *msg) sql_print_warning("WSREP: %s", msg); break; case wsrep::log::error: - sql_print_error("WSREP: %s", msg); + sql_print_error("WSREP: %s", msg); break; case wsrep::log::debug: if (wsrep_debug) sql_print_information ("[Debug] WSREP: %s", msg); @@ -1800,13 +1800,16 @@ static void wsrep_TOI_begin_failed(THD* thd, const wsrep_buf_t* /* const err */) if (wsrep_emulate_bin_log) wsrep_thd_binlog_trx_reset(thd); if (wsrep_write_dummy_event(thd, "TOI begin failed")) { goto fail; } wsrep::client_state& cs(thd->wsrep_cs()); - int const ret= cs.leave_toi_local(wsrep::mutable_buffer()); + std::string const err(wsrep::to_c_string(cs.current_error())); + wsrep::mutable_buffer err_buf; + err_buf.push_back(err); + int const ret= cs.leave_toi_local(err_buf); if (ret) { WSREP_ERROR("Leaving critical section for failed TOI failed: thd: %lld, " "schema: %s, SQL: %s, rcode: %d wsrep_error: %s", (long long)thd->real_id, thd->db.str, - thd->query(), ret, wsrep::to_c_string(cs.current_error())); + thd->query(), ret, err.c_str()); goto fail; } } @@ -1927,7 +1930,12 @@ static void wsrep_TOI_end(THD *thd) { if (wsrep_thd_is_local_toi(thd)) { wsrep_set_SE_checkpoint(client_state.toi_meta().gtid()); - int ret= client_state.leave_toi_local(wsrep::mutable_buffer()); + wsrep::mutable_buffer err; + if (thd->is_error() && !wsrep_must_ignore_error(thd)) + { + wsrep_store_error(thd, err); + } + int const ret= client_state.leave_toi_local(err); if (!ret) { WSREP_DEBUG("TO END: %lld", client_state.toi_meta().seqno().get()); @@ -2418,7 +2426,7 @@ int wsrep_must_ignore_error(THD* thd) const uint flags= sql_command_flags[thd->lex->sql_command]; DBUG_ASSERT(error); - DBUG_ASSERT(wsrep_thd_is_toi(thd) || wsrep_thd_is_applying(thd)); + DBUG_ASSERT(wsrep_thd_is_toi(thd)); if ((wsrep_ignore_apply_errors & WSREP_IGNORE_ERRORS_ON_DDL)) goto ignore_error; diff --git a/sql/wsrep_schema.cc b/sql/wsrep_schema.cc index 0fb0adca2bb..ee0fc8f12cc 100644 --- a/sql/wsrep_schema.cc +++ b/sql/wsrep_schema.cc @@ -1289,7 +1289,7 @@ int Wsrep_schema::recover_sr_transactions(THD *orig_thd) goto out; } - while (true) + while (0 == error) { if ((error= Wsrep_schema_impl::next_record(frag_table)) == 0) { @@ -1344,19 +1344,23 @@ int Wsrep_schema::recover_sr_transactions(THD *orig_thd) } applier->store_globals(); wsrep::mutable_buffer unused; - applier->apply_write_set(ws_meta, data, unused); - applier->after_apply(); + if ((ret= applier->apply_write_set(ws_meta, data, unused)) != 0) + { + WSREP_ERROR("SR trx recovery applying returned %d", ret); + } + else + { + applier->after_apply(); + } storage_service.store_globals(); } else if (error == HA_ERR_END_OF_FILE) { ret= 0; - break; } else { WSREP_ERROR("SR table scan returned error %d", error); - break; } } Wsrep_schema_impl::end_scan(frag_table); diff --git a/sql/wsrep_trans_observer.h b/sql/wsrep_trans_observer.h index 69756786dd2..118525bb908 100644 --- a/sql/wsrep_trans_observer.h +++ b/sql/wsrep_trans_observer.h @@ -292,9 +292,7 @@ static inline int wsrep_before_commit(THD* thd, bool all) Return zero on succes, non-zero on failure. */ -static inline int wsrep_ordered_commit(THD* thd, - bool all, - const wsrep_apply_error&) +static inline int wsrep_ordered_commit(THD* thd, bool all) { DBUG_ENTER("wsrep_ordered_commit"); WSREP_DEBUG("wsrep_ordered_commit: %d", wsrep_is_real(thd, all)); |