Commit e2ac8c07 authored by Andrei Elkin's avatar Andrei Elkin

Bug #38240 Crash in safe_mutex_lock () thr_mutex.c line 97 on rotate_relay_log

            
The reason for the crash was rotate_relay_log (mi=0x0) did not verify
the passed value of active_mi.  There are more cases where active_mi
is supposed to be non-zero e.g change_master(), stop_slave(), and it's
reasonable to protect from a similar crash all of them with common
fixes.
            
Fixed with spliting end_slave() in slave threads release and slave
data clean-up parts (a new close_active_mi()). The new function is
invoked at the very end of close_connections() so that all users of
active_mi are proven to have left.

sql/mysqld.cc:
  added the 2nd part (data) of the slave's clean up.
sql/slave.cc:
  end_slave() is split in two part to release the slave threads and the remained
  resources separately.
  The new close_active_mi() should be called after all possible users ofactive_mi
  has left, i.e at the very end of close_connections().
sql/slave.h:
  interface to the new end_active_mi() function is added.
parent f3bdd56f
......@@ -983,6 +983,7 @@ static void close_connections(void)
}
(void) pthread_mutex_unlock(&LOCK_thread_count);
close_active_mi();
DBUG_PRINT("quit",("close_connections thread"));
DBUG_VOID_RETURN;
}
......
......@@ -668,7 +668,7 @@ static int end_slave_on_walk(Master_info* mi, uchar* /*unused*/)
/*
Free all resources used by slave
Release slave threads at time of executing shutdown.
SYNOPSIS
end_slave()
......@@ -694,15 +694,32 @@ void end_slave()
once multi-master code is ready.
*/
terminate_slave_threads(active_mi,SLAVE_FORCE_ALL);
}
pthread_mutex_unlock(&LOCK_active_mi);
DBUG_VOID_RETURN;
}
/**
Free all resources used by slave threads at time of executing shutdown.
The routine must be called after all possible users of @c active_mi
have left.
SYNOPSIS
close_active_mi()
*/
void close_active_mi()
{
pthread_mutex_lock(&LOCK_active_mi);
if (active_mi)
{
end_master_info(active_mi);
delete active_mi;
active_mi= 0;
}
pthread_mutex_unlock(&LOCK_active_mi);
DBUG_VOID_RETURN;
}
static bool io_slave_killed(THD* thd, Master_info* mi)
{
DBUG_ENTER("io_slave_killed");
......
......@@ -174,7 +174,8 @@ const char *print_slave_db_safe(const char *db);
int check_expected_error(THD* thd, Relay_log_info const *rli, int error_code);
void skip_load_data_infile(NET* net);
void end_slave(); /* clean up */
void end_slave(); /* release slave threads */
void close_active_mi(); /* clean up slave threads data */
void clear_until_condition(Relay_log_info* rli);
void clear_slave_error(Relay_log_info* rli);
void end_relay_log_info(Relay_log_info* rli);
......
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