1
0
mirror of https://github.com/MariaDB/server.git synced 2026-10-23 18:49:29 +03:00

MDEV-41264: binlog-in-engine dump thread not stopping at server shutdown

The binlog-in-engine code for binlog dump thread didn't check
should_stop(info, true) to stop on KILL_SERVER when it reaches the end of
the current binlog. This caused the dump threads to hang indefinitely during
SHUTDOWN WAIT FOR ALL SLAVES, and thus the shutdown to hang as well.

Signed-off-by: Kristian Nielsen <knielsen@knielsen-hq.org>
This commit is contained in:
Kristian Nielsen
2026-09-29 14:50:07 +02:00
parent ae55324a2c
commit 5f8c344ba2
6 changed files with 116 additions and 1 deletions

View File

@@ -0,0 +1,13 @@
include/master-slave.inc
[connection master]
### MDEV-41264: binlog-in-engine dump thread not stopping at server shutdown
CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB;
INSERT INTO t1 VALUES (1);
SHUTDOWN WAIT FOR ALL SLAVES;
include/rpl_reconnect.inc
connection master;
INSERT INTO t1 VALUES (2);
connection slave;
connection master;
DROP TABLE t1;
include/rpl_end.inc

View File

@@ -0,0 +1,31 @@
--source include/have_binlog_format_mixed.inc
--source include/master-slave.inc
--source include/have_innodb_binlog.inc
--echo ### MDEV-41264: binlog-in-engine dump thread not stopping at server shutdown
CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB;
INSERT INTO t1 VALUES (1);
--write_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
wait-rpl_master_stop.test
EOF
# The bug was that this shutdown would hang.
SHUTDOWN WAIT FOR ALL SLAVES;
--source include/wait_until_disconnected.inc
--append_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
restart
EOF
--let $rpl_server_number= 1
--source include/rpl_reconnect.inc
--connection master
INSERT INTO t1 VALUES (2);
--sync_slave_with_master
# Cleanup.
--connection master
DROP TABLE t1;
--source include/rpl_end.inc

View File

@@ -0,0 +1,24 @@
!include my.cnf
[mysqld.1]
log_warnings=3
[mysqld.2]
[mysqld.3]
innodb
binlog-storage-engine=innodb
max_binlog_size=8M
innodb-binlog-state-interval=128k
[mysqld.4]
innodb
binlog-storage-engine=innodb
max_binlog_size=8M
innodb-binlog-state-interval=128k
[ENV]
SERVER_MYPORT_3= @mysqld.3.port
SERVER_MYSOCK_3= @mysqld.3.socket
SERVER_MYPORT_4= @mysqld.4.port
SERVER_MYSOCK_4= @mysqld.4.socket

View File

@@ -0,0 +1,29 @@
include/rpl_init.inc [topology=1->2, 1->3, 1->4]
connection server_1;
CREATE TABLE t1 (a INT) ENGINE=innodb;
connection server_2;
connection server_3;
connection server_4;
include/stop_slave.inc
connection server_1;
connection server_1;
SET @@GLOBAL.debug_dbug="+d,simulate_delay_at_shutdown";
connection server_4;
include/start_slave.inc
connection server_1;
SHUTDOWN WAIT FOR ALL SLAVES;
connection server_4;
connection server_3;
connection server_2;
connection server_1;
connection default;
connection server_1;
connection server_1;
DROP TABLE t1;
connection server_2;
include/start_slave.inc
connection server_3;
include/start_slave.inc
connection server_4;
include/start_slave.inc
include/rpl_end.inc

View File

@@ -0,0 +1,9 @@
--source include/have_debug.inc
--source include/have_binlog_format_mixed.inc
--let $rpl_topology=1->2, 1->3, 1->4
--source include/rpl_init.inc
--source include/have_innodb_binlog.inc
--source suite/rpl/include/rpl_shutdown_wait_slaves.inc
--source include/rpl_end.inc

View File

@@ -3592,7 +3592,8 @@ static int send_engine_events(binlog_send_info *info, LOG_INFO* linfo)
return 1; return 1;
} }
while (!should_stop(info, true) && !reader->data_available()) bool stop;
while (!(stop= should_stop(info, true)) && !reader->data_available())
{ {
struct timespec ts; struct timespec ts;
struct timespec *ts_ptr= nullptr; struct timespec *ts_ptr= nullptr;
@@ -3613,6 +3614,14 @@ static int send_engine_events(binlog_send_info *info, LOG_INFO* linfo)
info->heartbeat_period= get_heartbeat_period(info->thd); info->heartbeat_period= get_heartbeat_period(info->thd);
} }
} }
/*
Stop the dump thread during SHUTDOWN WAIT FOR ALL SLAVES (as indicated
by stop= should_stop(info, true)) only when we're at EOF and have no
more data available in the binlog.
*/
if (unlikely(stop) && !reader->data_available())
return 1;
continue; continue;
} }