summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/suite/galera_3nodes/galera_3nodes.cnf3
-rw-r--r--mysql-test/suite/galera_3nodes/r/galera_sst_donor_non_prim.result26
-rw-r--r--mysql-test/suite/galera_3nodes/t/galera_sst_donor_non_prim.cnf4
-rw-r--r--mysql-test/suite/galera_3nodes/t/galera_sst_donor_non_prim.test64
-rw-r--r--sql/wsrep_sst.cc9
5 files changed, 106 insertions, 0 deletions
diff --git a/mysql-test/suite/galera_3nodes/galera_3nodes.cnf b/mysql-test/suite/galera_3nodes/galera_3nodes.cnf
index a7dd4d21bc7..bc85867ec8b 100644
--- a/mysql-test/suite/galera_3nodes/galera_3nodes.cnf
+++ b/mysql-test/suite/galera_3nodes/galera_3nodes.cnf
@@ -23,6 +23,7 @@ wsrep_provider_options='repl.causal_read_timeout=PT90S;base_port=@mysqld.1.#gale
wsrep_node_address='127.0.0.1:@mysqld.1.#galera_port'
wsrep_node_incoming_address=127.0.0.1:@mysqld.1.port
wsrep_sst_receive_address='127.0.0.1:@mysqld.1.#sst_port'
+wsrep_node_name=node1
[mysqld.2]
wsrep-on=1
@@ -34,6 +35,7 @@ wsrep_provider_options='repl.causal_read_timeout=PT90S;base_port=@mysqld.2.#gale
wsrep_node_address='127.0.0.1:@mysqld.2.#galera_port'
wsrep_node_incoming_address=127.0.0.1:@mysqld.2.port
wsrep_sst_receive_address='127.0.0.1:@mysqld.2.#sst_port'
+wsrep_node_name=node2
[mysqld.3]
wsrep-on=1
@@ -45,6 +47,7 @@ wsrep_provider_options='repl.causal_read_timeout=PT90S;base_port=@mysqld.3.#gale
wsrep_node_address='127.0.0.1:@mysqld.3.#galera_port'
wsrep_node_incoming_address=127.0.0.1:@mysqld.3.port
wsrep_sst_receive_address='127.0.0.1:@mysqld.3.#sst_port'
+wsrep_node_name=node3
[ENV]
NODE_MYPORT_1= @mysqld.1.port
diff --git a/mysql-test/suite/galera_3nodes/r/galera_sst_donor_non_prim.result b/mysql-test/suite/galera_3nodes/r/galera_sst_donor_non_prim.result
new file mode 100644
index 00000000000..6f372463b15
--- /dev/null
+++ b/mysql-test/suite/galera_3nodes/r/galera_sst_donor_non_prim.result
@@ -0,0 +1,26 @@
+connection node_2;
+connection node_1;
+connection node_1;
+connection node_2;
+connection node_3;
+connection node_2;
+connection node_1;
+SET GLOBAL debug_dbug = '+d,sync.wsrep_sst_donor_after_donation';
+connection node_2;
+# restart
+connection node_1;
+SET DEBUG_SYNC = 'now WAIT_FOR sync.wsrep_sst_donor_after_donation_reached';
+SET GLOBAL wsrep_provider_options = 'gmcast.isolate=1';
+SET SESSION wsrep_sync_wait=0;
+SET DEBUG_SYNC = 'now SIGNAL signal.wsrep_sst_donor_after_donation_continue';
+SET DEBUG_SYNC = 'RESET';
+SET GLOBAL debug_dbug = '';
+SET GLOBAL wsrep_provider_options = 'gmcast.isolate=0';
+SET SESSION wsrep_sync_wait=15;
+connection node_1;
+connection node_2;
+connection node_3;
+connection node_1;
+connection node_1;
+CALL mtr.add_suppression("WSREP: sst sent called when not SST donor, state CONNECTED");
+CALL mtr.add_suppression("WSREP: .* returned an error: Not connected to Primary Component");
diff --git a/mysql-test/suite/galera_3nodes/t/galera_sst_donor_non_prim.cnf b/mysql-test/suite/galera_3nodes/t/galera_sst_donor_non_prim.cnf
new file mode 100644
index 00000000000..ecb568672fe
--- /dev/null
+++ b/mysql-test/suite/galera_3nodes/t/galera_sst_donor_non_prim.cnf
@@ -0,0 +1,4 @@
+!include ../galera_3nodes.cnf
+
+[mysqld.2]
+wsrep_sst_donor=node1
diff --git a/mysql-test/suite/galera_3nodes/t/galera_sst_donor_non_prim.test b/mysql-test/suite/galera_3nodes/t/galera_sst_donor_non_prim.test
new file mode 100644
index 00000000000..22c4f75b601
--- /dev/null
+++ b/mysql-test/suite/galera_3nodes/t/galera_sst_donor_non_prim.test
@@ -0,0 +1,64 @@
+#
+# Construct a situation where Donor node partitions in the
+# middle of SST. The Donor should stay in non-Primary state instead of
+# crashing in assertion in wsrep-lib.
+#
+# In the test, node_2 is restarted and node_1 configured to be
+# the donor. Node_1 execution is stopped before sst_sent() is
+# called and node_1 is made to partition from the cluster.
+#
+
+--source include/galera_cluster.inc
+--source include/have_innodb.inc
+--source include/have_debug_sync.inc
+--source include/big_test.inc
+
+--let $galera_connection_name = node_3
+--let $galera_server_number = 3
+--source include/galera_connect.inc
+
+--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
+--source include/shutdown_mysqld.inc
+--remove_file $MYSQLTEST_VARDIR/mysqld.2/data/grastate.dat
+
+--connection node_1
+SET GLOBAL debug_dbug = '+d,sync.wsrep_sst_donor_after_donation';
+
+--connection node_2
+--source include/start_mysqld.inc
+
+--connection node_1
+SET DEBUG_SYNC = 'now WAIT_FOR sync.wsrep_sst_donor_after_donation_reached';
+SET GLOBAL wsrep_provider_options = 'gmcast.isolate=1';
+SET SESSION wsrep_sync_wait=0;
+--let $wait_condition = SELECT VARIABLE_VALUE = 'non-Primary' FROM information_schema.global_status WHERE VARIABLE_NAME = 'wsrep_cluster_status'
+--source include/wait_condition.inc
+
+SET DEBUG_SYNC = 'now SIGNAL signal.wsrep_sst_donor_after_donation_continue';
+SET DEBUG_SYNC = 'RESET';
+SET GLOBAL debug_dbug = '';
+
+SET GLOBAL wsrep_provider_options = 'gmcast.isolate=0';
+SET SESSION wsrep_sync_wait=15;
+
+--let $wait_condition = SELECT VARIABLE_VALUE = 3 FROM information_schema.global_status WHERE VARIABLE_NAME = 'wsrep_cluster_size'
+--connection node_1
+--source include/wait_condition.inc
+--connection node_2
+--source include/wait_condition.inc
+--connection node_3
+
+--connection node_1
+--let $wait_condition = SELECT VARIABLE_VALUE = 'ON' FROM information_schema.global_status WHERE VARIABLE_NAME = 'wsrep_ready'
+--source include/wait_condition.inc
+
+--source ../galera/include/auto_increment_offset_restore.inc
+
+--connection node_1
+CALL mtr.add_suppression("WSREP: sst sent called when not SST donor, state CONNECTED");
+CALL mtr.add_suppression("WSREP: .* returned an error: Not connected to Primary Component");
diff --git a/sql/wsrep_sst.cc b/sql/wsrep_sst.cc
index 1fb1d6890e2..46c6a4fd63d 100644
--- a/sql/wsrep_sst.cc
+++ b/sql/wsrep_sst.cc
@@ -1808,6 +1808,15 @@ wait_signal:
wsrep::seqno(err ? wsrep::seqno::undefined() :
wsrep::seqno(ret_seqno)));
+#ifdef ENABLED_DEBUG_SYNC
+ DBUG_EXECUTE_IF("sync.wsrep_sst_donor_after_donation", {
+ const char act[]= "now "
+ "SIGNAL sync.wsrep_sst_donor_after_donation_reached "
+ "WAIT_FOR signal.wsrep_sst_donor_after_donation_continue";
+ DBUG_ASSERT(!debug_sync_set_action(thd.ptr, STRING_WITH_LEN(act)));
+ });
+#endif /* ENABLED_DEBUG_SYNC */
+
Wsrep_server_state::instance().sst_sent(gtid, err);
proc.wait();