summaryrefslogtreecommitdiff
path: root/sql/slave.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/slave.cc')
-rw-r--r--sql/slave.cc55
1 files changed, 40 insertions, 15 deletions
diff --git a/sql/slave.cc b/sql/slave.cc
index d6510b26271..21337e0476e 100644
--- a/sql/slave.cc
+++ b/sql/slave.cc
@@ -584,19 +584,26 @@ int start_slave_threads(bool need_slave_mutex, bool wait_for_start,
lock_cond_sql = &mi->rli.run_lock;
}
- if (thread_mask & SLAVE_IO)
- error=start_slave_thread(handle_slave_io,lock_io,lock_cond_io,
- cond_io,
- &mi->slave_running, &mi->slave_run_id,
- mi);
- if (!error && (thread_mask & SLAVE_SQL))
- {
+ /*
+ We must first start the SQL thread, becasue for lock_slave_threads() to work
+ we must first unlock mi->rli.run_lock and then mi->run_lock
+ If we don't do this, we will get a deadlock if two threads calls START SLAVE
+ at the same time.
+ */
+
+ if (thread_mask & SLAVE_SQL)
error=start_slave_thread(handle_slave_sql,lock_sql,lock_cond_sql,
cond_sql,
&mi->rli.slave_running, &mi->rli.slave_run_id,
mi);
+ if (!error && (thread_mask & SLAVE_IO))
+ {
+ error=start_slave_thread(handle_slave_io,lock_io,lock_cond_io,
+ cond_io,
+ &mi->slave_running, &mi->slave_run_id,
+ mi);
if (error)
- terminate_slave_threads(mi, thread_mask & SLAVE_IO, 0);
+ terminate_slave_threads(mi, thread_mask & SLAVE_SQL, 0);
}
DBUG_RETURN(error);
}
@@ -1431,7 +1438,7 @@ Failed to open the existing relay log info file '%s' (errno %d)",
before flush_relay_log_info
*/
reinit_io_cache(&rli->info_file, WRITE_CACHE,0L,0,1);
- if ((error= flush_relay_log_info(rli)))
+ if ((error= flush_relay_log_info(rli, 0)))
sql_print_error("Failed to flush relay log info file");
if (count_relay_log_space(rli))
{
@@ -1650,9 +1657,9 @@ file '%s')", fname);
mi->master_log_name,
(ulong) mi->master_log_pos));
+ mi->rli.mi = mi;
if (init_relay_log_info(&mi->rli, slave_info_fname))
goto err;
- mi->rli.mi = mi;
mi->inited = 1;
// now change cache READ -> WRITE - must do this before flush_master_info
@@ -2279,7 +2286,7 @@ static int exec_relay_log_event(THD* thd, RELAY_LOG_INFO* rli)
rli->inc_pos(ev->get_event_len(),
type_code != STOP_EVENT ? ev->log_pos : LL(0),
1/* skip lock*/);
- flush_relay_log_info(rli);
+ flush_relay_log_info(rli, 0);
/*
Protect against common user error of setting the counter to 1
@@ -3239,6 +3246,7 @@ static int safe_reconnect(THD* thd, MYSQL* mysql, MASTER_INFO* mi,
SYNOPSIS
flush_relay_log_info()
rli Relay log information
+ flush_cur_log Flush the current log if it's a hot log.
NOTES
- As this is only called by the slave thread, we don't need to
@@ -3251,6 +3259,8 @@ static int safe_reconnect(THD* thd, MYSQL* mysql, MASTER_INFO* mi,
If this would not be the case, we would have to ensure that we
don't delete the relay log file where the transaction started when
we switch to a new relay log file.
+ - The reason for flushing current log is to ensure that we have saved on
+ disk the last query the SQL thread read
TODO
- Change the log file information to a binary format to avoid calling
@@ -3261,7 +3271,7 @@ static int safe_reconnect(THD* thd, MYSQL* mysql, MASTER_INFO* mi,
1 write error
*/
-bool flush_relay_log_info(RELAY_LOG_INFO* rli)
+bool flush_relay_log_info(RELAY_LOG_INFO* rli, bool flush_cur_log)
{
bool error=0;
IO_CACHE *file = &rli->info_file;
@@ -3284,8 +3294,23 @@ bool flush_relay_log_info(RELAY_LOG_INFO* rli)
error=1;
if (flush_io_cache(file))
error=1;
- if (flush_io_cache(rli->cur_log)) // QQ Why this call ?
- error=1;
+
+ /*
+ We want to flush the io log here if this is a hot cache to ensure
+ that we have the execute SQL statement on disk.
+ */
+ if (flush_cur_log)
+ {
+ /*
+ The following mutex is to protect us against log changes in middle of
+ the flush_io_cache() call
+ */
+ pthread_mutex_lock(&rli->mi->data_lock);
+ /* Only flush hot logs */
+ if (rli->cur_log != &rli->cache_buf && flush_io_cache(rli->cur_log))
+ error=1;
+ pthread_mutex_unlock(&rli->mi->data_lock);
+ }
return error;
}
@@ -3506,7 +3531,7 @@ rli->relay_log_pos=%s rli->pending=%lu",
rli->pending=0;
strmake(rli->relay_log_name,rli->linfo.log_file_name,
sizeof(rli->relay_log_name)-1);
- flush_relay_log_info(rli);
+ flush_relay_log_info(rli, 0);
}
/*