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.
This commit is contained in:
parent
f3bdd56fe6
commit
e2ac8c07bd
@ -983,6 +983,7 @@ static void close_connections(void)
|
|||||||
}
|
}
|
||||||
(void) pthread_mutex_unlock(&LOCK_thread_count);
|
(void) pthread_mutex_unlock(&LOCK_thread_count);
|
||||||
|
|
||||||
|
close_active_mi();
|
||||||
DBUG_PRINT("quit",("close_connections thread"));
|
DBUG_PRINT("quit",("close_connections thread"));
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
|
25
sql/slave.cc
25
sql/slave.cc
@ -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
|
SYNOPSIS
|
||||||
end_slave()
|
end_slave()
|
||||||
@ -694,14 +694,31 @@ void end_slave()
|
|||||||
once multi-master code is ready.
|
once multi-master code is ready.
|
||||||
*/
|
*/
|
||||||
terminate_slave_threads(active_mi,SLAVE_FORCE_ALL);
|
terminate_slave_threads(active_mi,SLAVE_FORCE_ALL);
|
||||||
end_master_info(active_mi);
|
|
||||||
delete active_mi;
|
|
||||||
active_mi= 0;
|
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(&LOCK_active_mi);
|
pthread_mutex_unlock(&LOCK_active_mi);
|
||||||
DBUG_VOID_RETURN;
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
static bool io_slave_killed(THD* thd, Master_info* mi)
|
static bool io_slave_killed(THD* thd, Master_info* mi)
|
||||||
{
|
{
|
||||||
|
@ -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);
|
int check_expected_error(THD* thd, Relay_log_info const *rli, int error_code);
|
||||||
void skip_load_data_infile(NET* net);
|
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_until_condition(Relay_log_info* rli);
|
||||||
void clear_slave_error(Relay_log_info* rli);
|
void clear_slave_error(Relay_log_info* rli);
|
||||||
void end_relay_log_info(Relay_log_info* rli);
|
void end_relay_log_info(Relay_log_info* rli);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user