summaryrefslogtreecommitdiff
path: root/plugin
diff options
context:
space:
mode:
authorLuis Soares <luis.soares@oracle.com>2013-10-17 17:48:26 +0100
committerLuis Soares <luis.soares@oracle.com>2013-10-17 17:48:26 +0100
commit863d67e3acbc31951c9cf52cd49be1eb8e1e28b8 (patch)
tree0de914f8d373663d4be9cc7543f329d6cf8aa9d6 /plugin
parent54a36531ec3e29c2a7770af895b4d06195cf09dd (diff)
downloadmariadb-git-863d67e3acbc31951c9cf52cd49be1eb8e1e28b8.tar.gz
BUG#17460821: ASSERTION ERROR WHEN STOPPING SLAVE AFTER SEMI-SYNC ON MASTER IS DISABLED
The assertion happens when: (i) the master and slave are configured to use the semisync plugin; (ii) the DBA disables semisync on the master; (iii) and he also unsets the option to wait for slaves ACK even if the semisync slave count reaches 0 during the waiting period. This combination of factors makes the server run into an assertion as soon as the last semisync slave disconnects and its dump thread exits. The root of the problem is the fact that when the dump thread disconnects and calls the observer hook transmit_stop, which ends up calling ReplSemiSyncMaster::remove_slave, there is no check whether the master has already disabled semisync or not. If it has, the then a second call to the switch_off member function must be avoided. The quick fix is to avoid calling switch_off if the DBA has disabled the semisync plugin interactively on the master. Also, the switch_off member function should only be called if the plugin has not been switched off already. This is basically the pattern throughout the rest of the semisync plugin and no other calls seem vulnerable to similar crashes/assertions. (This a backport of the patch to 5.5, which is also vulnerable.)
Diffstat (limited to 'plugin')
-rw-r--r--plugin/semisync/semisync_master.cc18
1 files changed, 11 insertions, 7 deletions
diff --git a/plugin/semisync/semisync_master.cc b/plugin/semisync/semisync_master.cc
index 6b8bb915445..2e40fc8b5c5 100644
--- a/plugin/semisync/semisync_master.cc
+++ b/plugin/semisync/semisync_master.cc
@@ -482,13 +482,17 @@ void ReplSemiSyncMaster::remove_slave()
lock();
rpl_semi_sync_master_clients--;
- /* If user has chosen not to wait if no semi-sync slave available
- and the last semi-sync slave exits, turn off semi-sync on master
- immediately.
- */
- if (!rpl_semi_sync_master_wait_no_slave &&
- rpl_semi_sync_master_clients == 0)
- switch_off();
+ /* Only switch off if semi-sync is enabled and is on */
+ if (getMasterEnabled() && is_on())
+ {
+ /* If user has chosen not to wait if no semi-sync slave available
+ and the last semi-sync slave exits, turn off semi-sync on master
+ immediately.
+ */
+ if (!rpl_semi_sync_master_wait_no_slave &&
+ rpl_semi_sync_master_clients == 0)
+ switch_off();
+ }
unlock();
}