# # MGL-326: four connections of an asynchronous replication master update the # same rows while a cluster node updates them as well. The replica node # applies the events with four parallel workers. In debug builds the replica # node crashes with # handler.cc: ha_rollback_trans: Assertion # `!(thd->rgi_slave && !thd->rgi_slave->worker_error && # thd->rgi_slave->did_mark_start_commit) || ...' failed. # A crash with `!_current_thd()->wait_for_commit_ptr' in # Wsrep_provider_raft::release() is possible as well, when a worker reaches it # first. # # Node 3 is a native MariaDB server and the async master. Node 2 is a cluster # node and the replica. # --source include/have_innodb.inc --source include/have_debug.inc --source include/log_bin.inc --source include/force_restart.inc --connect node_2a, 127.0.0.1, root, , test, $NODE_MYPORT_2 --connection node_2a --source include/galera_cluster.inc ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; --connect node_3, 127.0.0.1, root, , test, $NODE_MYPORT_3 --connection node_3 RESET MASTER; --connection node_2a --disable_query_log --eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_USER='root', MASTER_SSL_VERIFY_SERVER_CERT=0, MASTER_PORT=$NODE_MYPORT_3; --enable_query_log START SLAVE; --connection node_3 CREATE TABLE t1 (f1 INTEGER PRIMARY KEY, f2 INTEGER) ENGINE=InnoDB; INSERT INTO t1 VALUES (1, 0), (2, 0), (3, 0), (4, 0); --connection node_2a --let $wait_condition = SELECT COUNT(*) = 4 FROM test.t1; --source include/wait_condition.inc # # Four connections of the async master update the same rows in opposite # order, and node 1 updates them as well. # --connect master_1, 127.0.0.1, root, , test, $NODE_MYPORT_3 --connect master_2, 127.0.0.1, root, , test, $NODE_MYPORT_3 --connect master_3, 127.0.0.1, root, , test, $NODE_MYPORT_3 --connect master_4, 127.0.0.1, root, , test, $NODE_MYPORT_3 --connection node_3 DELIMITER |; CREATE PROCEDURE load_a (n INT) BEGIN DECLARE i INT DEFAULT 0; DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN END; WHILE i < n DO START TRANSACTION; UPDATE t1 SET f2 = f2 + 1 WHERE f1 = 1; UPDATE t1 SET f2 = f2 + 1 WHERE f1 = 2; COMMIT; SET i = i + 1; END WHILE; END| CREATE PROCEDURE load_b (n INT) BEGIN DECLARE i INT DEFAULT 0; DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN END; WHILE i < n DO START TRANSACTION; UPDATE t1 SET f2 = f2 + 1 WHERE f1 = 2; UPDATE t1 SET f2 = f2 + 1 WHERE f1 = 1; COMMIT; SET i = i + 1; END WHILE; END| DELIMITER ;| --connection node_1 DELIMITER |; CREATE PROCEDURE load_c (n INT) BEGIN DECLARE i INT DEFAULT 0; DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN END; WHILE i < n DO UPDATE t1 SET f2 = f2 + 1 WHERE f1 = 1; UPDATE t1 SET f2 = f2 + 1 WHERE f1 = 2; SET i = i + 1; END WHILE; END| DELIMITER ;| --connection master_1 --send CALL test.load_a(200) --connection master_2 --send CALL test.load_b(200) --connection master_3 --send CALL test.load_a(200) --connection master_4 --send CALL test.load_b(200) --connection node_1 --send CALL test.load_c(200) --connection master_1 --reap --connection master_2 --reap --connection master_3 --reap --connection master_4 --reap --connection node_1 --reap --connection node_3 --source include/save_master_gtid.inc --connection node_2a --source include/sync_with_master_gtid.inc --connection node_1 SET SESSION wsrep_sync_wait = 15; SELECT COUNT(*) = 4 FROM t1; --connection node_2a STOP SLAVE; RESET SLAVE; SET GLOBAL gtid_slave_pos = ""; --connection node_1 DROP PROCEDURE load_c; DROP TABLE t1; --connection node_3 DROP PROCEDURE load_a; DROP PROCEDURE load_b; --source include/kill_binlog_dump_threads.inc --source include/reset_master.inc --connection node_1 --disconnect node_2a --disconnect node_3 --disconnect master_1 --disconnect master_2 --disconnect master_3 --disconnect master_4