Commit 5e13093d authored by unknown's avatar unknown

MDEV-359: Server crash when SET GLOBAL rpl_semi_sync_master_enabled = OFF

The semisync code does a fast-but-unsafe check for enabled or not without lock,
followed by a slow-but-safe check under lock. However, if the slow check failed,
the code still referenced not valid data (in an assert() expression), causing a
crash.

Fixed by not running the incorrect assert when semisync is disabled.
parent 39005ea0
include/master-slave.inc
[connection master]
CREATE TABLE t1 (a INT) ENGINE=MyISAM;
INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
SET GLOBAL rpl_semi_sync_master_enabled = ON;
SET DEBUG_SYNC = "rpl_semisync_master_commit_trx_before_lock SIGNAL m1_ready WAIT_FOR m1_cont";
INSERT INTO t1 SELECT * FROM t1;
SET DEBUG_SYNC= "now WAIT_FOR m1_ready";
SET GLOBAL rpl_semi_sync_master_enabled = OFF;
SET DEBUG_SYNC= "now SIGNAL m1_cont";
DROP TABLE t1;
UNINSTALL PLUGIN rpl_semi_sync_master;
include/rpl_end.inc
--source include/have_semisync_plugin.inc
--source include/not_embedded.inc
--source include/have_binlog_format_mixed_or_statement.inc
--source include/master-slave.inc
--source include/have_debug_sync.inc
# MDEV-359: There was a server crash when the code first checks if semisync
# is enabled without lock, then if so takes the lock and tests again.
# If semisync was disabled in-between the first and the second test, an
# assert was incorrectly made that referenced a NULL pointer.
#
# This tests uses debug_sync to pause one thread at the critical point in
# the code, disable the semisync, and then continue the paused thread.
CREATE TABLE t1 (a INT) ENGINE=MyISAM;
INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
SET GLOBAL rpl_semi_sync_master_enabled = ON;
--connection master1
SET DEBUG_SYNC = "rpl_semisync_master_commit_trx_before_lock SIGNAL m1_ready WAIT_FOR m1_cont";
--send
INSERT INTO t1 SELECT * FROM t1;
--connection master
SET DEBUG_SYNC= "now WAIT_FOR m1_ready";
SET GLOBAL rpl_semi_sync_master_enabled = OFF;
SET DEBUG_SYNC= "now SIGNAL m1_cont";
--connection master1
--reap
connection master;
DROP TABLE t1;
disable_warnings;
UNINSTALL PLUGIN rpl_semi_sync_master;
enable_warnings;
--source include/rpl_end.inc
...@@ -608,6 +608,7 @@ int ReplSemiSyncMaster::commitTrx(const char* trx_wait_binlog_name, ...@@ -608,6 +608,7 @@ int ReplSemiSyncMaster::commitTrx(const char* trx_wait_binlog_name,
set_timespec(start_ts, 0); set_timespec(start_ts, 0);
DEBUG_SYNC(current_thd, "rpl_semisync_master_commit_trx_before_lock");
/* Acquire the mutex. */ /* Acquire the mutex. */
lock(); lock();
...@@ -738,7 +739,6 @@ int ReplSemiSyncMaster::commitTrx(const char* trx_wait_binlog_name, ...@@ -738,7 +739,6 @@ int ReplSemiSyncMaster::commitTrx(const char* trx_wait_binlog_name,
} }
} }
l_end:
/* /*
At this point, the binlog file and position of this transaction At this point, the binlog file and position of this transaction
must have been removed from ActiveTranx. must have been removed from ActiveTranx.
...@@ -747,6 +747,7 @@ int ReplSemiSyncMaster::commitTrx(const char* trx_wait_binlog_name, ...@@ -747,6 +747,7 @@ int ReplSemiSyncMaster::commitTrx(const char* trx_wait_binlog_name,
!active_tranxs_->is_tranx_end_pos(trx_wait_binlog_name, !active_tranxs_->is_tranx_end_pos(trx_wait_binlog_name,
trx_wait_binlog_pos)); trx_wait_binlog_pos));
l_end:
/* Update the status counter. */ /* Update the status counter. */
if (is_on()) if (is_on())
rpl_semi_sync_master_yes_transactions++; rpl_semi_sync_master_yes_transactions++;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment