mirror of
https://github.com/MariaDB/server.git
synced 2025-05-11 13:21:44 +03:00
MDEV-26473 fixed a segmentation fault at startup between the handle manager thread and the binlog background thread, such that the binlog background thread could be started and submit a job to the handle manager, before it had initialized. Where MDEV-26473 made it so the handle manager would initialize before the main thread started the normal binary logs, it did not account for the recovery case. That is, there is still a possibility of a segmentation fault when a server is recovering using the binary logs such that it can open the binary logs, start the binlog background thread, and submit a job to the handle manager before it is initialized. This patch fixes this by moving the initialization of the mysql handler manager to happen prior to recovery. Reviewed By: ============ Andrei Elkin <andrei.elkin@mariadb.com>
132 lines
4.7 KiB
Plaintext
132 lines
4.7 KiB
Plaintext
#
|
|
# Purpose:
|
|
# This test ensures that, during mysqld initialization, the mysql handle
|
|
# manager starts before the binlog background thread. This is because the
|
|
# binlog background thread uses the mysql handle manager, and if the background
|
|
# thread tries to submit a job to the handle manager before it is
|
|
# initialized/started, mysqld can crash (the actual behavior is undefined).
|
|
# This race condition lead to the problem described in MDEV-26473.
|
|
#
|
|
# Methodology:
|
|
# This test ensures that the binlog background thread cannot be started
|
|
# before the mysql manager is started. Specifically, it forces a path in
|
|
# the binlog background thread to call mysql_manager_submit() by reducing
|
|
# --gtid-cleanup-batch-size to be 1 (which submits a job to delete unused rows
|
|
# from the mysql.gtid_slave_pos* tables). With this path forced, the main
|
|
# mysqld thread is suspended just before its handle manager initialization to
|
|
# allow time for the binlog thread to call mysql_manager_submit. The fix
|
|
# 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
|
|
--source include/master-slave.inc
|
|
|
|
# The race condition discovered from MDEV-26473 is binlog format independent.
|
|
# We use ROW format though because it was used by the reporter.
|
|
--source include/have_binlog_format_row.inc
|
|
|
|
--connection master
|
|
|
|
--echo # Create a GTID event so the binlog background thread will submit a
|
|
--echo # mysql handler job the next time mysqld is restarted.
|
|
create table t1 (a int);
|
|
--source include/save_master_gtid.inc
|
|
|
|
--connection slave
|
|
--source include/sync_with_master_gtid.inc
|
|
|
|
--echo # Set a debug point that forces the main mysqld thread to sleep before
|
|
--echo # anything is initialized for the mysql handle manager
|
|
--let $rpl_server_parameters=--debug_dbug="+d,delay_start_handle_manager"
|
|
|
|
|
|
--echo # Restart the slave mysqld instance so it re-initializes with the
|
|
--echo # binlog background thread submitting a mysql handler job and the
|
|
--echo # mysql handler initialization suspending for a second. Without the fix
|
|
--echo # associated with this test/patch, the following restart will error
|
|
--echo # with a failed assertion.
|
|
--source include/rpl_restart_server.inc
|
|
--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 #
|
|
|
|
--connection master
|
|
drop table t1;
|
|
--source include/save_master_gtid.inc
|
|
|
|
--connection slave
|
|
--source include/sync_with_master_gtid.inc
|
|
drop table t2;
|
|
|
|
--source include/rpl_end.inc
|