diff options
author | unknown <knielsen@knielsen-hq.org> | 2014-02-09 00:56:18 +0100 |
---|---|---|
committer | unknown <knielsen@knielsen-hq.org> | 2014-02-09 00:56:18 +0100 |
commit | 07eaf6ea76900a724fc6b89e1c4ccd0713c6a174 (patch) | |
tree | b78fd6293a8aac3026e2b47436e1fe9e08e78c7f /sql/log.h | |
parent | 76e929a92e6fb06b649ed9f199484b64946b6152 (diff) | |
download | mariadb-git-07eaf6ea76900a724fc6b89e1c4ccd0713c6a174.tar.gz |
MDEV-5636: Deadlock in RESET MASTER
The problem is a deadlock between MYSQL_BIN_LOG::reset_logs() and
MYSQL_BIN_LOG::mark_xid_done(). The former takes LOCK_log and waits for the
latter to complete. But the latter also tries to take LOCK_log; this can lead
to a deadlock.
There was already code that tries to deal with this, with the flag
reset_master_pending. However, there was still a small opportunity for
deadlock, when an previous mark_xid_done() is still running when reset_logs()
is called and is at the precise point where it first releases LOCK_xid_list
and then re-aquires both LOCK_log and LOCK_xid_list.
Solve by setting reset_master_pending in reset_logs() before taking
LOCK_log. And also count how many invocations of LOCK_xid_list are in the
progress of releasing and re-aquiring locks, and in reset_logs() wait for that
number to drop to zero after setting reset_master_pending and before taking
LOCK_log.
Diffstat (limited to 'sql/log.h')
-rw-r--r-- | sql/log.h | 1 |
1 files changed, 1 insertions, 0 deletions
diff --git a/sql/log.h b/sql/log.h index 45381152d97..4249246277f 100644 --- a/sql/log.h +++ b/sql/log.h @@ -471,6 +471,7 @@ class MYSQL_BIN_LOG: public TC_LOG, private MYSQL_LOG checkpoint arrives - when all have arrived, RESET MASTER will complete. */ bool reset_master_pending; + ulong mark_xid_done_waiting; /* LOCK_log and LOCK_index are inited by init_pthread_objects() */ mysql_mutex_t LOCK_index; |