mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
MDEV-9573 'Stop slave' hangs on replication slave
The reason for this is that stop slave takes LOCK_active_mi over the whole operation while some slave operations will also need LOCK_active_mi which causes deadlocks. Fixed by introducing object counting for Master_info and not taking LOCK_active_mi over stop slave or even stop_all_slaves() Another benefit of this approach is that it allows: - Multiple threads can run SHOW SLAVE STATUS at the same time - START/STOP/RESET/SLAVE STATUS on a slave will not block other slaves - Simpler interface for handling get_master_info() - Added some missing unlock of 'log_lock' in error condtions - Moved rpl_parallel_inactivate_pool(&global_rpl_thread_pool) to end of stop_slave() to not have to use LOCK_active_mi inside terminate_slave_threads() - Changed argument for remove_master_info() to Master_info, as we always have this available - Fixed core dump when doing FLUSH TABLES WITH READ LOCK and parallel replication. Problem was that waiting for pause_for_ftwrl was not done when deleting rpt->current_owner after a force_abort.
This commit is contained in:
@ -174,24 +174,20 @@ bool reload_acl_and_cache(THD *thd, unsigned long long options,
|
||||
slave is not likely to have the same connection names.
|
||||
*/
|
||||
tmp_write_to_binlog= 0;
|
||||
mysql_mutex_lock(&LOCK_active_mi);
|
||||
if (master_info_index)
|
||||
|
||||
if (!(mi= (get_master_info(&connection_name,
|
||||
Sql_condition::WARN_LEVEL_ERROR))))
|
||||
{
|
||||
if (!(mi= (master_info_index->
|
||||
get_master_info(&connection_name,
|
||||
Sql_condition::WARN_LEVEL_ERROR))))
|
||||
{
|
||||
result= 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
mysql_mutex_lock(&mi->data_lock);
|
||||
if (rotate_relay_log(mi))
|
||||
*write_to_binlog= -1;
|
||||
mysql_mutex_unlock(&mi->data_lock);
|
||||
}
|
||||
result= 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
mysql_mutex_lock(&mi->data_lock);
|
||||
if (rotate_relay_log(mi))
|
||||
*write_to_binlog= -1;
|
||||
mysql_mutex_unlock(&mi->data_lock);
|
||||
mi->release();
|
||||
}
|
||||
mysql_mutex_unlock(&LOCK_active_mi);
|
||||
#endif
|
||||
}
|
||||
#ifdef HAVE_QUERY_CACHE
|
||||
@ -349,27 +345,33 @@ bool reload_acl_and_cache(THD *thd, unsigned long long options,
|
||||
LEX_MASTER_INFO* lex_mi= &thd->lex->mi;
|
||||
Master_info *mi;
|
||||
tmp_write_to_binlog= 0;
|
||||
mysql_mutex_lock(&LOCK_active_mi);
|
||||
if (master_info_index)
|
||||
|
||||
if (!(mi= get_master_info(&lex_mi->connection_name,
|
||||
Sql_condition::WARN_LEVEL_ERROR)))
|
||||
{
|
||||
if (!(mi= (master_info_index->
|
||||
get_master_info(&lex_mi->connection_name,
|
||||
Sql_condition::WARN_LEVEL_ERROR))))
|
||||
{
|
||||
result= 1;
|
||||
}
|
||||
else if (reset_slave(thd, mi))
|
||||
result= 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The following will fail if slave is running */
|
||||
if (reset_slave(thd, mi))
|
||||
{
|
||||
mi->release();
|
||||
/* NOTE: my_error() has been already called by reset_slave(). */
|
||||
result= 1;
|
||||
}
|
||||
else if (mi->connection_name.length && thd->lex->reset_slave_info.all)
|
||||
{
|
||||
/* If not default connection and 'all' is used */
|
||||
master_info_index->remove_master_info(&mi->connection_name);
|
||||
mi->release();
|
||||
mysql_mutex_lock(&LOCK_active_mi);
|
||||
if (master_info_index->remove_master_info(mi))
|
||||
result= 1;
|
||||
mysql_mutex_unlock(&LOCK_active_mi);
|
||||
}
|
||||
else
|
||||
mi->release();
|
||||
}
|
||||
mysql_mutex_unlock(&LOCK_active_mi);
|
||||
}
|
||||
#endif
|
||||
if (options & REFRESH_USER_RESOURCES)
|
||||
|
Reference in New Issue
Block a user