diff --git a/mysql-test/suite/rpl/r/rpl_mysql_manager_race_condition.result b/mysql-test/suite/rpl/r/rpl_mysql_manager_race_condition.result index 1172d8e39a9..740d1ddfcfa 100644 --- a/mysql-test/suite/rpl/r/rpl_mysql_manager_race_condition.result +++ b/mysql-test/suite/rpl/r/rpl_mysql_manager_race_condition.result @@ -17,6 +17,36 @@ include/sync_with_master_gtid.inc include/rpl_restart_server.inc [server_number=2 parameters: --debug_dbug="+d,delay_start_handle_manager"] include/start_slave.inc # +# MDEV-33799 +# Ensure that when the binary log is used for recovery (as tc log), that +# the recovery process cannot start the binlog background thread before +# the mysql handle manager has started. +connection slave; +# Add test suppresssions so crash recovery messages don't fail the test +set session sql_log_bin=0; +call mtr.add_suppression("mariadbd: Got error '145.*"); +call mtr.add_suppression("Checking table:.*"); +call mtr.add_suppression("mysql.gtid_slave_pos:.*hasn't closed the table properly"); +call mtr.add_suppression("Can't init tc log"); +call mtr.add_suppression("Aborting"); +set session sql_log_bin=1; +# Create slave-side only table +create table t2 (a int) engine=innodb; +# Crash mariadbd when binlogging transaction to corrupt database state +connection slave1; +set @@session.debug_dbug="+d,crash_before_writing_xid"; +insert into t2 values (1); +connection slave; +connection slave1; +Got one of the listed errors +# Restart mariadbd in recovery mode. Note --tc-heuristic-recover +# forces mysqld to exit with error, so we run mariadbd via CLI +# MYSQLD_LAST_CMD --debug_dbug="+d,delay_start_handle_manager" --tc-heuristic-recover=COMMIT +connection server_2; +connection slave1; +connection slave; +include/start_slave.inc +# # Cleanup # connection master; @@ -24,4 +54,5 @@ drop table t1; include/save_master_gtid.inc connection slave; include/sync_with_master_gtid.inc +drop table t2; include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_mysql_manager_race_condition.test b/mysql-test/suite/rpl/t/rpl_mysql_manager_race_condition.test index 751da3158b7..dd4a0fbbc99 100644 --- a/mysql-test/suite/rpl/t/rpl_mysql_manager_race_condition.test +++ b/mysql-test/suite/rpl/t/rpl_mysql_manager_race_condition.test @@ -18,8 +18,14 @@ # associated with this test should enforce that the binlog background thread is # not created before the handle manager is initialized. # +# Addendum 1) This test is extended for MDEV-33799, as the original fix +# left out the possibility that the binlog background thread can be +# started during recovery if the binary log is used as the transaction +# coordinator. This resulted in similar segfaults as seen by MDEV-26473. +# # References: # MDEV-26473 mysqld got exception 0xc0000005 (rpl_slave_state/rpl_load_gtid_slave_state) +# MDEV-33799 mysql_manager_submit Segfault at Startup Still Possible During Recovery # --source include/have_debug.inc @@ -53,6 +59,63 @@ create table t1 (a int); --source include/start_slave.inc +--echo # +--echo # MDEV-33799 +--echo # Ensure that when the binary log is used for recovery (as tc log), that +--echo # the recovery process cannot start the binlog background thread before +--echo # the mysql handle manager has started. +--connection slave + +--echo # Add test suppresssions so crash recovery messages don't fail the test +set session sql_log_bin=0; +call mtr.add_suppression("mariadbd: Got error '145.*"); +call mtr.add_suppression("Checking table:.*"); +call mtr.add_suppression("mysql.gtid_slave_pos:.*hasn't closed the table properly"); +call mtr.add_suppression("Can't init tc log"); +call mtr.add_suppression("Aborting"); +set session sql_log_bin=1; + +--echo # Create slave-side only table +create table t2 (a int) engine=innodb; + +--write_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect +wait +EOF + +--echo # Crash mariadbd when binlogging transaction to corrupt database state +--connection slave1 +set @@session.debug_dbug="+d,crash_before_writing_xid"; +--send insert into t2 values (1) + +--connection slave +--source include/wait_until_disconnected.inc + +--connection slave1 +--error 2013,ER_CONNECTION_KILLED +--reap + +--echo # Restart mariadbd in recovery mode. Note --tc-heuristic-recover +--echo # forces mysqld to exit with error, so we run mariadbd via CLI +--echo # MYSQLD_LAST_CMD --debug_dbug="+d,delay_start_handle_manager" --tc-heuristic-recover=COMMIT +--error 1 +--exec $MYSQLD_LAST_CMD --debug_dbug="+d,delay_start_handle_manager" --tc-heuristic-recover=COMMIT + +--append_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect +restart +EOF + +--connection server_2 +--enable_reconnect +--source include/wait_until_connected_again.inc +--connection slave1 +--enable_reconnect +--source include/wait_until_connected_again.inc +--connection slave +--enable_reconnect +--source include/wait_until_connected_again.inc +--source include/start_slave.inc + + --echo # --echo # Cleanup --echo # @@ -63,5 +126,6 @@ drop table t1; --connection slave --source include/sync_with_master_gtid.inc +drop table t2; --source include/rpl_end.inc diff --git a/sql/mysqld.cc b/sql/mysqld.cc index c29bfc2ed50..d10c342a6dc 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -5383,6 +5383,10 @@ static int init_server_components() if (ddl_log_initialize()) unireg_abort(1); +#ifndef EMBEDDED_LIBRARY + start_handle_manager(); +#endif + tc_log= get_tc_log_implementation(); if (tc_log->open(opt_bin_log ? opt_bin_logname : opt_tc_log_file)) @@ -5394,9 +5398,6 @@ static int init_server_components() if (ha_recover(0)) unireg_abort(1); -#ifndef EMBEDDED_LIBRARY - start_handle_manager(); -#endif if (opt_bin_log) { int error;