diff options
author | Alfranio Correia <alfranio.correia@oracle.com> | 2010-09-06 18:18:44 +0100 |
---|---|---|
committer | Alfranio Correia <alfranio.correia@oracle.com> | 2010-09-06 18:18:44 +0100 |
commit | eab1def49ad1785ad65c9388de3704a5d658a0f6 (patch) | |
tree | 5a565d2cb4494feb616399f54d66ff3fdcb1e74a /sql/sql_repl.cc | |
parent | 744c1013a2b429557fec07246e812fcc40ec00a8 (diff) | |
parent | e297990d5b17cf888f6ac6d0c069551c317a53ef (diff) | |
download | mariadb-git-eab1def49ad1785ad65c9388de3704a5d658a0f6.tar.gz |
BUG#55415 wait_for_update_bin_log enters a condition but does not leave
In sql/log.c, member function wait_for_update_bin_log, a condition is entered with
THD::enter_cond but is not exited. This might leave dangling references to the
mutex/condition in the per-thread information area.
To fix the problem, we call exit_cond to properly remove references to the mutex,
LOCK_log.
Diffstat (limited to 'sql/sql_repl.cc')
-rw-r--r-- | sql/sql_repl.cc | 16 |
1 files changed, 13 insertions, 3 deletions
diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index ab6c6e738b2..7bca41f1265 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -448,6 +448,8 @@ void mysql_binlog_send(THD* thd, char* log_ident, my_off_t pos, const char *errmsg = "Unknown error"; NET* net = &thd->net; mysql_mutex_t *log_lock; + mysql_cond_t *log_cond; + bool binlog_can_be_corrupted= FALSE; #ifndef DBUG_OFF int left_events = max_binlog_dump_events; @@ -591,7 +593,8 @@ impossible position"; mysql_bin_log, and it's already inited, and it will be destroyed only at shutdown). */ - log_lock = mysql_bin_log.get_log_lock(); + log_lock= mysql_bin_log.get_log_lock(); + log_cond= mysql_bin_log.get_log_cond(); if (pos > BIN_LOG_HEADER_SIZE) { /* reset transmit packet for the event read from binary log @@ -826,6 +829,7 @@ impossible position"; #ifndef DBUG_OFF ulong hb_info_counter= 0; #endif + const char* old_msg= thd->proc_info; signal_cnt= mysql_bin_log.signal_cnt; do { @@ -834,6 +838,9 @@ impossible position"; DBUG_ASSERT(heartbeat_ts && heartbeat_period != 0); set_timespec_nsec(*heartbeat_ts, heartbeat_period); } + thd->enter_cond(log_cond, log_lock, + "Master has sent all binlog to slave; " + "waiting for binlog to be updated"); ret= mysql_bin_log.wait_for_update_bin_log(thd, heartbeat_ts); DBUG_ASSERT(ret == 0 || (heartbeat_period != 0 && coord != NULL)); if (ret == ETIMEDOUT || ret == ETIME) @@ -849,12 +856,15 @@ impossible position"; #endif /* reset transmit packet for the heartbeat event */ if (reset_transmit_packet(thd, flags, &ev_offset, &errmsg)) + { + thd->exit_cond(old_msg); goto err; + } if (send_heartbeat_event(net, packet, coord)) { errmsg = "Failed on my_net_write()"; my_errno= ER_UNKNOWN_ERROR; - mysql_mutex_unlock(log_lock); + thd->exit_cond(old_msg); goto err; } } @@ -863,7 +873,7 @@ impossible position"; DBUG_PRINT("wait",("binary log received update or a broadcast signal caught")); } } while (signal_cnt == mysql_bin_log.signal_cnt && !thd->killed); - mysql_mutex_unlock(log_lock); + thd->exit_cond(old_msg); } break; |