diff options
Diffstat (limited to 'sql/slave.cc')
-rw-r--r-- | sql/slave.cc | 55 |
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); } /* |