Commit f3c65ce9 authored by Monty's avatar Monty Committed by Sergei Golubchik

Add protection to not access is_open() without LOCK_log mutex

Protection added to reopen_file() and new_file_impl().

Without this we could get an assert in fn_format() as name == 0,
because the file was closed and name reset, atthe same time
new_file_impl() was called.
parent b624b41a
......@@ -2702,16 +2702,16 @@ int MYSQL_LOG::generate_new_name(char *new_name, const char *log_name)
void MYSQL_QUERY_LOG::reopen_file()
{
char *save_name;
DBUG_ENTER("MYSQL_LOG::reopen_file");
mysql_mutex_lock(&LOCK_log);
if (!is_open())
{
DBUG_PRINT("info",("log is closed"));
mysql_mutex_unlock(&LOCK_log);
DBUG_VOID_RETURN;
}
mysql_mutex_lock(&LOCK_log);
save_name= name;
name= 0; // Don't free name
close(LOG_CLOSE_TO_BE_OPENED);
......@@ -2870,13 +2870,6 @@ bool MYSQL_QUERY_LOG::write(THD *thd, time_t current_time,
DBUG_ENTER("MYSQL_QUERY_LOG::write");
mysql_mutex_lock(&LOCK_log);
if (!is_open())
{
mysql_mutex_unlock(&LOCK_log);
DBUG_RETURN(0);
}
if (is_open())
{ // Safety agains reopen
int tmp_errno= 0;
......@@ -3100,7 +3093,9 @@ void MYSQL_BIN_LOG::cleanup()
}
inited= 0;
mysql_mutex_lock(&LOCK_log);
close(LOG_CLOSE_INDEX|LOG_CLOSE_STOP_EVENT);
mysql_mutex_unlock(&LOCK_log);
delete description_event_for_queue;
delete description_event_for_exec;
......@@ -3257,10 +3252,11 @@ bool MYSQL_BIN_LOG::open(const char *log_name,
{
File file= -1;
xid_count_per_binlog *new_xid_list_entry= NULL, *b;
DBUG_ENTER("MYSQL_BIN_LOG::open");
DBUG_PRINT("enter",("log_type: %d",(int) log_type_arg));
mysql_mutex_assert_owner(&LOCK_log);
if (!is_relay_log)
{
if (!binlog_state_recover_done)
......@@ -4842,21 +4838,21 @@ int MYSQL_BIN_LOG::new_file_impl(bool need_lock)
bool delay_close= false;
File old_file;
LINT_INIT(old_file);
DBUG_ENTER("MYSQL_BIN_LOG::new_file_impl");
if (need_lock)
mysql_mutex_lock(&LOCK_log);
mysql_mutex_assert_owner(&LOCK_log);
if (!is_open())
{
DBUG_PRINT("info",("log is closed"));
mysql_mutex_unlock(&LOCK_log);
DBUG_RETURN(error);
}
if (need_lock)
mysql_mutex_lock(&LOCK_log);
mysql_mutex_lock(&LOCK_index);
mysql_mutex_assert_owner(&LOCK_log);
mysql_mutex_assert_owner(&LOCK_index);
/* Reuse old name if not binlog and not update log */
new_name_ptr= name;
......@@ -4989,9 +4985,9 @@ int MYSQL_BIN_LOG::new_file_impl(bool need_lock)
new_name_ptr, errno);
}
mysql_mutex_unlock(&LOCK_index);
if (need_lock)
mysql_mutex_unlock(&LOCK_log);
mysql_mutex_unlock(&LOCK_index);
DBUG_RETURN(error);
}
......@@ -7775,9 +7771,11 @@ int MYSQL_BIN_LOG::wait_for_update_bin_log(THD* thd,
void MYSQL_BIN_LOG::close(uint exiting)
{ // One can't set log_type here!
bool failed_to_save_state= false;
DBUG_ENTER("MYSQL_BIN_LOG::close");
DBUG_PRINT("enter",("exiting: %d", (int) exiting));
mysql_mutex_assert_owner(&LOCK_log);
if (log_state == LOG_OPENED)
{
#ifdef HAVE_REPLICATION
......
......@@ -4928,9 +4928,17 @@ static int init_server_components()
unireg_abort(1);
}
if (opt_bin_log && mysql_bin_log.open(opt_bin_logname, LOG_BIN, 0,
WRITE_CACHE, max_binlog_size, 0, TRUE))
unireg_abort(1);
if (opt_bin_log)
{
int error;
mysql_mutex_t *log_lock= mysql_bin_log.get_log_lock();
mysql_mutex_lock(log_lock);
error= mysql_bin_log.open(opt_bin_logname, LOG_BIN, 0,
WRITE_CACHE, max_binlog_size, 0, TRUE);
mysql_mutex_unlock(log_lock);
if (error)
unireg_abort(1);
}
#ifdef HAVE_REPLICATION
if (opt_bin_log && expire_logs_days)
......
......@@ -208,6 +208,7 @@ a file name for --relay-log-index option", opt_relaylog_index_name);
Master_info* mi= rli->mi;
char buf_relay_logname[FN_REFLEN], buf_relaylog_index_name_buff[FN_REFLEN];
char *buf_relaylog_index_name= opt_relaylog_index_name;
mysql_mutex_t *log_lock;
create_logfile_name_with_suffix(buf_relay_logname,
sizeof(buf_relay_logname),
......@@ -227,14 +228,18 @@ a file name for --relay-log-index option", opt_relaylog_index_name);
note, that if open() fails, we'll still have index file open
but a destructor will take care of that
*/
log_lock= rli->relay_log.get_log_lock();
mysql_mutex_lock(log_lock);
if (rli->relay_log.open_index_file(buf_relaylog_index_name, ln, TRUE) ||
rli->relay_log.open(ln, LOG_BIN, 0, SEQ_READ_APPEND,
mi->rli.max_relay_log_size, 1, TRUE))
{
mysql_mutex_unlock(log_lock);
mysql_mutex_unlock(&rli->data_lock);
sql_print_error("Failed when trying to open logs for '%s' in init_relay_log_info(). Error: %M", ln, my_errno);
DBUG_RETURN(1);
}
mysql_mutex_unlock(log_lock);
}
/* if file does not exist */
......
......@@ -5990,6 +5990,7 @@ static int queue_event(Master_info* mi,const char* buf, ulong event_len)
void end_relay_log_info(Relay_log_info* rli)
{
mysql_mutex_t *log_lock;
DBUG_ENTER("end_relay_log_info");
if (!rli->inited)
......@@ -6007,8 +6008,11 @@ void end_relay_log_info(Relay_log_info* rli)
rli->cur_log_fd = -1;
}
rli->inited = 0;
log_lock= rli->relay_log.get_log_lock();
mysql_mutex_lock(log_lock);
rli->relay_log.close(LOG_CLOSE_INDEX | LOG_CLOSE_STOP_EVENT);
rli->relay_log.harvest_bytes_written(&rli->log_space_total);
mysql_mutex_unlock(log_lock);
/*
Delete the slave's temporary tables from memory.
In the future there will be other actions than this, to ensure persistance
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment