Commit 36ed2c39 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 0df5e552
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,
set_timespec(start_ts, 0);
DEBUG_SYNC(current_thd, "rpl_semisync_master_commit_trx_before_lock");
/* Acquire the mutex. */
lock();
......@@ -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
must have been removed from ActiveTranx.
......@@ -747,6 +747,7 @@ int ReplSemiSyncMaster::commitTrx(const char* trx_wait_binlog_name,
!active_tranxs_->is_tranx_end_pos(trx_wait_binlog_name,
trx_wait_binlog_pos));
l_end:
/* Update the status counter. */
if (is_on())
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