# # MDEV-25717 Assertion `owning_thread_id_ == wsrep::this_thread::get_id()' # # This test exposes a race condition between rollbacker thread and rollback # fragment processing. # --source include/galera_cluster.inc --source include/have_debug_sync.inc --connection node_1 CREATE TABLE t1 (f1 INTEGER PRIMARY KEY) Engine=InnoDB; INSERT INTO t1 VALUES (1), (2), (3); # # On node_2 we start a SR transaction, it going to # be BF aborted later on # --connection node_2 SET SESSION wsrep_trx_fragment_size = 1; START TRANSACTION; INSERT INTO t1 VALUES (4); --connection node_1 SELECT COUNT(*) FROM t1; # Sync wait # # Issue a conflicting TRUNCATE statement on node_1: # - on node_2, block it before it is going to apply # - on node_1, block before the before it BF aborts the INSERT # --connect node_2a, 127.0.0.1, root, , test, $NODE_MYPORT_2 --connection node_2a SET GLOBAL DEBUG_DBUG = "d,sync.wsrep_apply_toi"; --connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1 --connection node_1a SET GLOBAL DEBUG_DBUG = "d,sync.wsrep_bf_abort"; --connection node_1 --send TRUNCATE TABLE t1 --connection node_1a SET DEBUG_SYNC = "now WAIT_FOR sync.wsrep_bf_abort_reached"; --connection node_2a SET DEBUG_SYNC = "now WAIT_FOR sync.wsrep_apply_toi_reached"; # # Generate one more fragment on the SR transaction. # This is going to fail certification and results # in a rollback fragment. # --connection node_2 --let $expected_cert_failures = `SELECT VARIABLE_VALUE + 1 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_cert_failures'` --send INSERT INTO t1 VALUES (5) # # Wait until after certify and observe the certification # failure. Let both continue and we are done on node_2. # --connection node_2a SET SESSION wsrep_sync_wait = 0; --let $wait_condition = SELECT VARIABLE_VALUE = $expected_cert_failures FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_cert_failures' --source include/wait_condition.inc SET SESSION wsrep_sync_wait = DEFAULT; SET GLOBAL DEBUG_DBUG = ""; SET DEBUG_SYNC = "now SIGNAL signal.wsrep_apply_toi"; --connection node_2 --error ER_LOCK_DEADLOCK --reap # # On node_1 we expect the following things: # - the TRUNCATE should successfully bf abort the transaction # - A rollback fragment should be delivered as a result of # certification failure. We expect the rollback fragment to # be delivered after TRUNCATE has bf aborted, therefore rollback # fragment logs a dummy writeset. # --connection node_1a SET SESSION wsrep_sync_wait=0; SET GLOBAL DEBUG_DBUG = "+d,sync.wsrep_log_dummy_write_set"; # Signal the TRUNCATE to continue and observe the BF abort --let $expected_bf_aborts = `SELECT VARIABLE_VALUE + 1 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_bf_aborts'` SET DEBUG_SYNC = "now SIGNAL signal.wsrep_bf_abort"; # Expect a timeout if bug is present --let $wait_condition = SELECT VARIABLE_VALUE = $expected_bf_aborts FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_bf_aborts' --source include/wait_condition.inc # Observe logging of dummy writeset SET DEBUG_SYNC = "now WAIT_FOR sync.wsrep_log_dummy_write_set_reached"; # TRUNCATE succeeds --connection node_1 --reap # # Cleanup # --connection node_2 SET GLOBAL DEBUG_DBUG = ""; SET DEBUG_SYNC = "RESET"; --connection node_1 SET GLOBAL DEBUG_DBUG = ""; SET DEBUG_SYNC = "RESET"; DROP TABLE t1;