1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-08 11:22:35 +03:00

galera fix: Donor in non-Primary causes assertion in wsrep-lib

Constructed a test which makes donor to go into non-Primary configuration
before `sst_sent()` is called, causing an assertion in wsrep-lib
if the bug is present.

Updated wsrep-lib to version which contains the fix.

Signed-off-by: Julius Goryavsky <julius.goryavsky@mariadb.com>
This commit is contained in:
Teemu Ollakka
2023-02-26 12:44:49 +02:00
committed by Julius Goryavsky
parent dd5dc92a19
commit 1b146e8220
5 changed files with 106 additions and 0 deletions

View File

@@ -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_address='127.0.0.1:@mysqld.1.#galera_port'
wsrep_node_incoming_address=127.0.0.1:@mysqld.1.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_sst_receive_address='127.0.0.1:@mysqld.1.#sst_port'
wsrep_node_name=node1
[mysqld.2] [mysqld.2]
wsrep-on=1 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_address='127.0.0.1:@mysqld.2.#galera_port'
wsrep_node_incoming_address=127.0.0.1:@mysqld.2.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_sst_receive_address='127.0.0.1:@mysqld.2.#sst_port'
wsrep_node_name=node2
[mysqld.3] [mysqld.3]
wsrep-on=1 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_address='127.0.0.1:@mysqld.3.#galera_port'
wsrep_node_incoming_address=127.0.0.1:@mysqld.3.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_sst_receive_address='127.0.0.1:@mysqld.3.#sst_port'
wsrep_node_name=node3
[sst] [sst]
sst-log-archive-dir=@ENV.MYSQLTEST_VARDIR/log sst-log-archive-dir=@ENV.MYSQLTEST_VARDIR/log

View File

@@ -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");

View File

@@ -0,0 +1,4 @@
!include ../galera_3nodes.cnf
[mysqld.2]
wsrep_sst_donor=node1

View File

@@ -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");

View File

@@ -1874,6 +1874,15 @@ wait_signal:
wsrep::seqno(err ? wsrep::seqno::undefined() : wsrep::seqno(err ? wsrep::seqno::undefined() :
wsrep::seqno(ret_seqno))); 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); Wsrep_server_state::instance().sst_sent(gtid, err);
proc.wait(); proc.wait();