mirror of
https://github.com/MariaDB/server.git
synced 2025-05-02 19:25:03 +03:00
Mutex order violation when wsrep bf thread kills a conflicting trx, the stack is wsrep_thd_LOCK() wsrep_kill_victim() lock_rec_other_has_conflicting() lock_clust_rec_read_check_and_lock() row_search_mvcc() ha_innobase::index_read() ha_innobase::rnd_pos() handler::ha_rnd_pos() handler::rnd_pos_by_record() handler::ha_rnd_pos_by_record() Rows_log_event::find_row() Update_rows_log_event::do_exec_row() Rows_log_event::do_apply_event() Log_event::apply_event() wsrep_apply_events() and mutexes are taken in the order lock_sys->mutex -> victim_trx->mutex -> victim_thread->LOCK_thd_data When a normal KILL statement is executed, the stack is innobase_kill_query() kill_handlerton() plugin_foreach_with_mask() ha_kill_query() THD::awake() kill_one_thread() and mutexes are victim_thread->LOCK_thd_data -> lock_sys->mutex -> victim_trx->mutex This patch is the plan D variant for fixing potetial mutex locking order exercised by BF aborting and KILL command execution. In this approach, KILL command is replicated as TOI operation. This guarantees total isolation for the KILL command execution in the first node: there is no concurrent replication applying and no concurrent DDL executing. Therefore there is no risk of BF aborting to happen in parallel with KILL command execution either. Potential mutex deadlocks between the different mutex access paths with KILL command execution and BF aborting cannot therefore happen. TOI replication is used, in this approach, purely as means to provide isolated KILL command execution in the first node. KILL command should not (and must not) be applied in secondary nodes. In this patch, we make this sure by skipping KILL execution in secondary nodes, in applying phase, where we bail out if applier thread is trying to execute KILL command. This is effective, but skipping the applying of KILL command could happen much earlier as well. This also fixed unprotected calls to wsrep_thd_abort that will use wsrep_abort_transaction. This is fixed by holding THD::LOCK_thd_data while we abort transaction. Reviewed-by: Jan Lindström <jan.lindstrom@mariadb.com>
152 lines
4.9 KiB
Plaintext
152 lines
4.9 KiB
Plaintext
--source include/have_wsrep.inc
|
|
--source include/force_restart.inc
|
|
--source include/have_innodb.inc
|
|
|
|
call mtr.add_suppression("WSREP: Initial position was provided by configuration or SST, avoiding override");
|
|
|
|
SET @wsrep_provider_options_saved= @@global.wsrep_provider_options;
|
|
SET @wsrep_cluster_address_saved= @@global.wsrep_cluster_address;
|
|
|
|
--echo
|
|
--echo # MDEV#5534: mysql_tzinfo_to_sql generates wrong query
|
|
--echo #
|
|
--echo # Testing wsrep_replicate_myisam variable.
|
|
|
|
--error ER_INCORRECT_GLOBAL_LOCAL_VAR
|
|
SELECT @@session.wsrep_replicate_myisam;
|
|
SELECT @@global.wsrep_replicate_myisam;
|
|
|
|
--error ER_GLOBAL_VARIABLE
|
|
SET SESSION wsrep_replicate_myisam= ON;
|
|
SET GLOBAL wsrep_replicate_myisam= ON;
|
|
|
|
# Reset it back.
|
|
SET GLOBAL wsrep_replicate_myisam= OFF;
|
|
#SET GLOBAL wsrep_provider=none;
|
|
|
|
--echo #
|
|
--echo # MDEV#5790: SHOW GLOBAL STATUS LIKE does not show the correct list of
|
|
--echo # variables when using "_"
|
|
--echo #
|
|
|
|
CALL mtr.add_suppression("WSREP: Could not open saved state file for reading.*");
|
|
|
|
#evalp SET GLOBAL wsrep_provider= '$WSREP_PROVIDER';
|
|
--let $galera_version=25.3.24
|
|
source include/check_galera_version.inc;
|
|
|
|
--replace_column 2 #
|
|
SHOW GLOBAL STATUS LIKE 'wsrep_local_state_comment';
|
|
|
|
--echo # Should show nothing.
|
|
SHOW STATUS LIKE 'x';
|
|
|
|
# Reset it back.
|
|
#SET GLOBAL wsrep_provider=none;
|
|
|
|
#evalp SET GLOBAL wsrep_provider= '$WSREP_PROVIDER';
|
|
|
|
# The following 2 variables are used by mariabackup
|
|
# SST.
|
|
--echo
|
|
--replace_column 2 #
|
|
SHOW STATUS LIKE 'wsrep_local_state_uuid';
|
|
--echo
|
|
--replace_column 2 #
|
|
SHOW STATUS LIKE 'wsrep_last_committed';
|
|
|
|
# Reset it back.
|
|
#SET GLOBAL wsrep_provider=none;
|
|
|
|
--echo
|
|
--echo #
|
|
--echo # MDEV#6206: wsrep_slave_threads subtracts from max_connections
|
|
--echo #
|
|
call mtr.add_suppression("WSREP: Failed to get provider options");
|
|
|
|
#evalp SET GLOBAL wsrep_provider= '$WSREP_PROVIDER';
|
|
|
|
--replace_regex /.*libgalera.*/libgalera_smm.so/
|
|
SELECT @@global.wsrep_provider;
|
|
SELECT @@global.wsrep_slave_threads;
|
|
SELECT @@global.wsrep_cluster_address;
|
|
SELECT @@global.wsrep_on;
|
|
SHOW STATUS LIKE 'threads_connected';
|
|
SHOW STATUS LIKE 'wsrep_thread_count';
|
|
--echo
|
|
|
|
#evalp SET GLOBAL wsrep_provider= '$WSREP_PROVIDER';
|
|
|
|
--replace_regex /.*libgalera.*/libgalera_smm.so/
|
|
SELECT @@global.wsrep_provider;
|
|
SELECT @@global.wsrep_cluster_address;
|
|
SELECT @@global.wsrep_on;
|
|
SHOW STATUS LIKE 'threads_connected';
|
|
SHOW STATUS LIKE 'wsrep_thread_count';
|
|
--echo
|
|
|
|
--echo # Setting wsrep_cluster_address triggers the creation of
|
|
--echo # applier/rollbacker threads.
|
|
#SET GLOBAL wsrep_cluster_address= 'gcomm://';
|
|
|
|
--echo # Wait for applier thread to get created 1.
|
|
--let $wait_condition = SELECT VARIABLE_VALUE = 1 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_applier_thread_count';
|
|
--source include/wait_condition.inc
|
|
--echo # Wait for applier thread to get created 2.
|
|
--let $wait_condition = SELECT VARIABLE_VALUE = 1 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_rollbacker_thread_count';
|
|
--source include/wait_condition.inc
|
|
|
|
SELECT VARIABLE_VALUE AS EXPECT_1 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_applier_thread_count';
|
|
SELECT VARIABLE_VALUE AS EXPECT_1 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_rollbacker_thread_count';
|
|
SELECT VARIABLE_VALUE AS EXPECT_2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_thread_count';
|
|
|
|
--replace_regex /.*libgalera.*/libgalera_smm.so/
|
|
SELECT @@global.wsrep_provider;
|
|
SELECT @@global.wsrep_cluster_address;
|
|
SELECT @@global.wsrep_on;
|
|
SHOW STATUS LIKE 'threads_connected';
|
|
SHOW STATUS LIKE 'wsrep_thread_count';
|
|
--echo
|
|
|
|
SET @wsrep_slave_threads_saved= @@global.wsrep_slave_threads;
|
|
SET GLOBAL wsrep_slave_threads= 10;
|
|
|
|
--echo # Wait for 9 applier threads to get created.
|
|
--let $wait_condition = SELECT VARIABLE_VALUE = 10 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_applier_thread_count';
|
|
--source include/wait_condition.inc
|
|
|
|
SELECT VARIABLE_VALUE AS EXPECT_10 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_applier_thread_count';
|
|
SELECT VARIABLE_VALUE AS EXPECT_1 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_rollbacker_thread_count';
|
|
SELECT VARIABLE_VALUE AS EXPECT_11 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_thread_count';
|
|
|
|
SHOW STATUS LIKE 'threads_connected';
|
|
|
|
#
|
|
# privileges for wsrep_on
|
|
#
|
|
set wsrep_on=0;
|
|
set wsrep_on=1;
|
|
--source include/wait_until_connected_again.inc
|
|
create user test@localhost;
|
|
connect con1,localhost,test;
|
|
set auto_increment_increment=10;
|
|
--error ER_SPECIFIC_ACCESS_DENIED_ERROR
|
|
set wsrep_on=0;
|
|
disconnect con1;
|
|
connection default;
|
|
drop user test@localhost;
|
|
|
|
--echo #
|
|
--echo # MDEV#6411: Setting set @@global.wsrep_sst_auth=NULL causes crash
|
|
--echo #
|
|
SET @wsrep_sst_auth_saved= @@global.wsrep_sst_auth;
|
|
SET @@global.wsrep_sst_auth= 'user:pass';
|
|
SET @@global.wsrep_sst_auth= '';
|
|
SET @@global.wsrep_sst_auth= NULL;
|
|
SET @@global.wsrep_sst_auth= @wsrep_sst_auth_saved;
|
|
|
|
--source include/galera_wait_ready.inc
|
|
|
|
--echo # End of test.
|
|
|