summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorSujatha Sivakumar <sujatha.sivakumar@oracle.com>2016-05-13 16:42:45 +0530
committerPrashant Tekriwal <prashant.tekriwal@oracle.com>2016-05-16 11:34:20 +0200
commitef3f09f0c9e62ea1bf86b33b5d97e954b3ae34fe (patch)
treee5e133ed139581968188e0800606ed0c9867f311 /sql
parent9d72fb4af0d87f6a69a3ccb9202b4029acf2bd56 (diff)
downloadmariadb-git-ef3f09f0c9e62ea1bf86b33b5d97e954b3ae34fe.tar.gz
Bug#23251517: SEMISYNC REPLICATION HANGINGmysql-5.5.50
Revert following bug fix: Bug#20685029: SLAVE IO THREAD SHOULD STOP WHEN DISK IS FULL Bug#21753696: MAKE SHOW SLAVE STATUS NON BLOCKING IF IO THREAD WAITS FOR DISK SPACE This fix results in a deadlock between slave IO thread and SQL thread. (cherry picked from commit e3fea6c6dbb36c6ab21c4ab777224560e9608b53)
Diffstat (limited to 'sql')
-rw-r--r--sql/log.cc75
-rw-r--r--sql/log.h5
-rw-r--r--sql/slave.cc38
-rw-r--r--sql/slave.h2
-rw-r--r--sql/sql_reload.cc2
5 files changed, 21 insertions, 101 deletions
diff --git a/sql/log.cc b/sql/log.cc
index a7f05905514..42937ec1682 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -37,7 +37,6 @@
#include "log_event.h" // Query_log_event
#include "rpl_filter.h"
#include "rpl_rli.h"
-#include "rpl_mi.h"
#include "sql_audit.h"
#include "sql_show.h"
@@ -4378,23 +4377,14 @@ end:
}
-#ifdef HAVE_REPLICATION
-bool MYSQL_BIN_LOG::append(Log_event* ev, Master_info *mi)
+bool MYSQL_BIN_LOG::append(Log_event* ev)
{
bool error = 0;
- mysql_mutex_assert_owner(&mi->data_lock);
mysql_mutex_lock(&LOCK_log);
DBUG_ENTER("MYSQL_BIN_LOG::append");
DBUG_ASSERT(log_file.type == SEQ_READ_APPEND);
/*
- Release data_lock by holding LOCK_log, while writing into the relay log.
- If slave IO thread waits here for free space, we don't want
- SHOW SLAVE STATUS to hang on mi->data_lock. Note LOCK_log mutex is
- sufficient to block SQL thread when IO thread is updating relay log here.
- */
- mysql_mutex_unlock(&mi->data_lock);
- /*
Log_event::write() is smart enough to use my_b_write() or
my_b_append() depending on the kind of cache we have.
*/
@@ -4408,58 +4398,24 @@ bool MYSQL_BIN_LOG::append(Log_event* ev, Master_info *mi)
if (flush_and_sync(0))
goto err;
if ((uint) my_b_append_tell(&log_file) > max_size)
- {
- /*
- If rotation is required we must acquire data_lock to protect
- description_event from clients executing FLUSH LOGS in parallel.
- In order do that we must release the existing LOCK_log so that we
- get it once again in proper locking order to avoid dead locks.
- i.e data_lock , LOCK_log.
- */
- mysql_mutex_unlock(&LOCK_log);
- mysql_mutex_lock(&mi->data_lock);
- mysql_mutex_lock(&LOCK_log);
error= new_file_without_locking();
- /*
- After rotation release data_lock, we need the LOCK_log till we signal
- the updation.
- */
- mysql_mutex_unlock(&mi->data_lock);
- }
err:
- signal_update(); // Safe as we don't call close
mysql_mutex_unlock(&LOCK_log);
- mysql_mutex_lock(&mi->data_lock);
+ signal_update(); // Safe as we don't call close
DBUG_RETURN(error);
}
-bool MYSQL_BIN_LOG::appendv(Master_info* mi, const char* buf, uint len,...)
+bool MYSQL_BIN_LOG::appendv(const char* buf, uint len,...)
{
bool error= 0;
DBUG_ENTER("MYSQL_BIN_LOG::appendv");
va_list(args);
va_start(args,len);
- mysql_mutex_assert_owner(&mi->data_lock);
- mysql_mutex_lock(&LOCK_log);
DBUG_ASSERT(log_file.type == SEQ_READ_APPEND);
- /*
- Release data_lock by holding LOCK_log, while writing into the relay log.
- If slave IO thread waits here for free space, we don't want
- SHOW SLAVE STATUS to hang on mi->data_lock. Note LOCK_log mutex is
- sufficient to block SQL thread when IO thread is updating relay log here.
- */
- mysql_mutex_unlock(&mi->data_lock);
- DBUG_EXECUTE_IF("simulate_io_thd_wait_for_disk_space",
- {
- const char act[]= "disk_full_reached SIGNAL parked";
- DBUG_ASSERT(opt_debug_sync_timeout > 0);
- DBUG_ASSERT(!debug_sync_set_action(current_thd,
- STRING_WITH_LEN(act)));
- };);
-
+ mysql_mutex_assert_owner(&LOCK_log);
do
{
if (my_b_append(&log_file,(uchar*) buf,len))
@@ -4472,34 +4428,13 @@ bool MYSQL_BIN_LOG::appendv(Master_info* mi, const char* buf, uint len,...)
DBUG_PRINT("info",("max_size: %lu",max_size));
if (flush_and_sync(0))
goto err;
- if ((uint) my_b_append_tell(&log_file) >
- DBUG_EVALUATE_IF("rotate_slave_debug_group", 500, max_size))
- {
- /*
- If rotation is required we must acquire data_lock to protect
- description_event from clients executing FLUSH LOGS in parallel.
- In order do that we must release the existing LOCK_log so that we
- get it once again in proper locking order to avoid dead locks.
- i.e data_lock , LOCK_log.
- */
- mysql_mutex_unlock(&LOCK_log);
- mysql_mutex_lock(&mi->data_lock);
- mysql_mutex_lock(&LOCK_log);
+ if ((uint) my_b_append_tell(&log_file) > max_size)
error= new_file_without_locking();
- /*
- After rotation release data_lock, we need the LOCK_log till we signal
- the updation.
- */
- mysql_mutex_unlock(&mi->data_lock);
- }
err:
if (!error)
signal_update();
- mysql_mutex_unlock(&LOCK_log);
- mysql_mutex_lock(&mi->data_lock);
DBUG_RETURN(error);
}
-#endif
bool MYSQL_BIN_LOG::flush_and_sync(bool *synced)
{
diff --git a/sql/log.h b/sql/log.h
index 7d1c3161ac2..4d13e4d0720 100644
--- a/sql/log.h
+++ b/sql/log.h
@@ -20,7 +20,6 @@
#include "handler.h" /* my_xid */
class Relay_log_info;
-class Master_info;
class Format_description_log_event;
@@ -455,8 +454,8 @@ public:
v stands for vector
invoked as appendv(buf1,len1,buf2,len2,...,bufn,lenn,0)
*/
- bool appendv(Master_info* mi, const char* buf,uint len,...);
- bool append(Log_event* ev, Master_info* mi);
+ bool appendv(const char* buf,uint len,...);
+ bool append(Log_event* ev);
void make_log_name(char* buf, const char* log_ident);
bool is_active(const char* log_file_name);
diff --git a/sql/slave.cc b/sql/slave.cc
index 31037c453d3..acf68e231f3 100644
--- a/sql/slave.cc
+++ b/sql/slave.cc
@@ -1660,7 +1660,7 @@ Waiting for the slave SQL thread to free enough relay log space");
#endif
if (rli->sql_force_rotate_relay)
{
- rotate_relay_log(rli->mi, true/*need_data_lock=true*/);
+ rotate_relay_log(rli->mi);
rli->sql_force_rotate_relay= false;
}
@@ -1705,7 +1705,7 @@ static void write_ignored_events_info_to_relay_log(THD *thd, Master_info *mi)
if (likely((bool)ev))
{
ev->server_id= 0; // don't be ignored by slave SQL thread
- if (unlikely(rli->relay_log.append(ev, mi)))
+ if (unlikely(rli->relay_log.append(ev)))
mi->report(ERROR_LEVEL, ER_SLAVE_RELAY_LOG_WRITE_FAILURE,
ER(ER_SLAVE_RELAY_LOG_WRITE_FAILURE),
"failed to write a Rotate event"
@@ -3605,7 +3605,7 @@ static int process_io_create_file(Master_info* mi, Create_file_log_event* cev)
break;
Execute_load_log_event xev(thd,0,0);
xev.log_pos = cev->log_pos;
- if (unlikely(mi->rli.relay_log.append(&xev, mi)))
+ if (unlikely(mi->rli.relay_log.append(&xev)))
{
mi->report(ERROR_LEVEL, ER_SLAVE_RELAY_LOG_WRITE_FAILURE,
ER(ER_SLAVE_RELAY_LOG_WRITE_FAILURE),
@@ -3619,7 +3619,7 @@ static int process_io_create_file(Master_info* mi, Create_file_log_event* cev)
{
cev->block = net->read_pos;
cev->block_len = num_bytes;
- if (unlikely(mi->rli.relay_log.append(cev, mi)))
+ if (unlikely(mi->rli.relay_log.append(cev)))
{
mi->report(ERROR_LEVEL, ER_SLAVE_RELAY_LOG_WRITE_FAILURE,
ER(ER_SLAVE_RELAY_LOG_WRITE_FAILURE),
@@ -3634,7 +3634,7 @@ static int process_io_create_file(Master_info* mi, Create_file_log_event* cev)
aev.block = net->read_pos;
aev.block_len = num_bytes;
aev.log_pos = cev->log_pos;
- if (unlikely(mi->rli.relay_log.append(&aev, mi)))
+ if (unlikely(mi->rli.relay_log.append(&aev)))
{
mi->report(ERROR_LEVEL, ER_SLAVE_RELAY_LOG_WRITE_FAILURE,
ER(ER_SLAVE_RELAY_LOG_WRITE_FAILURE),
@@ -3713,7 +3713,7 @@ static int process_io_rotate(Master_info *mi, Rotate_log_event *rev)
Rotate the relay log makes binlog format detection easier (at next slave
start or mysqlbinlog)
*/
- DBUG_RETURN(rotate_relay_log(mi, false/*need_data_lock=false*/));
+ DBUG_RETURN(rotate_relay_log(mi) /* will take the right mutexes */);
}
/*
@@ -3819,7 +3819,7 @@ static int queue_binlog_ver_1_event(Master_info *mi, const char *buf,
Log_event::Log_event(const char* buf...) in log_event.cc).
*/
ev->log_pos+= event_len; /* make log_pos be the pos of the end of the event */
- if (unlikely(rli->relay_log.append(ev, mi)))
+ if (unlikely(rli->relay_log.append(ev)))
{
delete ev;
mysql_mutex_unlock(&mi->data_lock);
@@ -3875,7 +3875,7 @@ static int queue_binlog_ver_3_event(Master_info *mi, const char *buf,
inc_pos= event_len;
break;
}
- if (unlikely(rli->relay_log.append(ev, mi)))
+ if (unlikely(rli->relay_log.append(ev)))
{
delete ev;
mysql_mutex_unlock(&mi->data_lock);
@@ -4083,6 +4083,7 @@ static int queue_event(Master_info* mi,const char* buf, ulong event_len)
direct master (an unsupported, useless setup!).
*/
+ mysql_mutex_lock(log_lock);
s_id= uint4korr(buf + SERVER_ID_OFFSET);
if ((s_id == ::server_id && !mi->rli.replicate_same_server_id) ||
/*
@@ -4115,7 +4116,6 @@ static int queue_event(Master_info* mi,const char* buf, ulong event_len)
IGNORE_SERVER_IDS it increments mi->master_log_pos
as well as rli->group_relay_log_pos.
*/
- mysql_mutex_lock(log_lock);
if (!(s_id == ::server_id && !mi->rli.replicate_same_server_id) ||
(buf[EVENT_TYPE_OFFSET] != FORMAT_DESCRIPTION_EVENT &&
buf[EVENT_TYPE_OFFSET] != ROTATE_EVENT &&
@@ -4127,14 +4127,13 @@ static int queue_event(Master_info* mi,const char* buf, ulong event_len)
rli->ign_master_log_pos_end= mi->master_log_pos;
}
rli->relay_log.signal_update(); // the slave SQL thread needs to re-check
- mysql_mutex_unlock(log_lock);
DBUG_PRINT("info", ("master_log_pos: %lu, event originating from %u server, ignored",
(ulong) mi->master_log_pos, uint4korr(buf + SERVER_ID_OFFSET)));
}
else
{
/* write the event to the relay log */
- if (likely(!(rli->relay_log.appendv(mi, buf,event_len,0))))
+ if (likely(!(rli->relay_log.appendv(buf,event_len,0))))
{
mi->master_log_pos+= inc_pos;
DBUG_PRINT("info", ("master_log_pos: %lu", (ulong) mi->master_log_pos));
@@ -4144,10 +4143,9 @@ static int queue_event(Master_info* mi,const char* buf, ulong event_len)
{
error= ER_SLAVE_RELAY_LOG_WRITE_FAILURE;
}
- mysql_mutex_lock(log_lock);
rli->ign_master_log_name_end[0]= 0; // last event is not ignored
- mysql_mutex_unlock(log_lock);
}
+ mysql_mutex_unlock(log_lock);
skip_relay_logging:
@@ -5007,21 +5005,11 @@ err:
locks; here we don't, so this function is mainly taking locks).
Returns nothing as we cannot catch any error (MYSQL_BIN_LOG::new_file()
is void).
-
- @param mi Master_info for the IO thread.
- @param need_data_lock If true, mi->data_lock will be acquired otherwise,
- mi->data_lock must be held by the caller.
*/
-int rotate_relay_log(Master_info* mi, bool need_data_lock)
+int rotate_relay_log(Master_info* mi)
{
DBUG_ENTER("rotate_relay_log");
- if (need_data_lock)
- mysql_mutex_lock(&mi->data_lock);
- else
- {
- mysql_mutex_assert_owner(&mi->data_lock);
- }
Relay_log_info* rli= &mi->rli;
int error= 0;
@@ -5056,8 +5044,6 @@ int rotate_relay_log(Master_info* mi, bool need_data_lock)
*/
rli->relay_log.harvest_bytes_written(&rli->log_space_total);
end:
- if (need_data_lock)
- mysql_mutex_unlock(&mi->data_lock);
DBUG_RETURN(error);
}
diff --git a/sql/slave.h b/sql/slave.h
index 0cf8adb0315..7bf136694cc 100644
--- a/sql/slave.h
+++ b/sql/slave.h
@@ -205,7 +205,7 @@ int purge_relay_logs(Relay_log_info* rli, THD *thd, bool just_reset,
const char** errmsg);
void set_slave_thread_options(THD* thd);
void set_slave_thread_default_charset(THD *thd, Relay_log_info const *rli);
-int rotate_relay_log(Master_info* mi, bool need_data_lock);
+int rotate_relay_log(Master_info* mi);
int apply_event_and_update_pos(Log_event* ev, THD* thd, Relay_log_info* rli);
pthread_handler_t handle_slave_io(void *arg);
diff --git a/sql/sql_reload.cc b/sql/sql_reload.cc
index f24f31b6399..b29cc9a9433 100644
--- a/sql/sql_reload.cc
+++ b/sql/sql_reload.cc
@@ -157,7 +157,7 @@ bool reload_acl_and_cache(THD *thd, unsigned long options,
{
#ifdef HAVE_REPLICATION
mysql_mutex_lock(&LOCK_active_mi);
- if (rotate_relay_log(active_mi, true/*need_data_lock=true*/))
+ if (rotate_relay_log(active_mi))
*write_to_binlog= -1;
mysql_mutex_unlock(&LOCK_active_mi);
#endif