bug#49536 - deadlock on rotate_and_purge when using expire_logs_days
Problem is that purge_logs implementation in ndb (ndbcluster_binlog_index_purge_file) calls mysql_parse (with (thd->options & OPTION_BIN_LOG) === 0)) but MYSQL_BIN_LOG first takes LOCK_log and then checks thd->options Solution in this patch, changes so that rotate_and_purge does not hold LOCK_log when calling purge_logs_before_date. I think this is safe as other "purge"-function(s) is called wo/ holding LOCK_log, e.g purge_master_logs
This commit is contained in:
parent
aa38825287
commit
e76d96c4ad
23
sql/log.cc
23
sql/log.cc
@ -4481,6 +4481,9 @@ bool general_log_write(THD *thd, enum enum_server_command command,
|
||||
|
||||
void MYSQL_BIN_LOG::rotate_and_purge(uint flags)
|
||||
{
|
||||
#ifdef HAVE_REPLICATION
|
||||
bool check_purge= false;
|
||||
#endif
|
||||
if (!(flags & RP_LOCK_LOG_IS_ALREADY_LOCKED))
|
||||
pthread_mutex_lock(&LOCK_log);
|
||||
if ((flags & RP_FORCE_ROTATE) ||
|
||||
@ -4488,16 +4491,24 @@ void MYSQL_BIN_LOG::rotate_and_purge(uint flags)
|
||||
{
|
||||
new_file_without_locking();
|
||||
#ifdef HAVE_REPLICATION
|
||||
if (expire_logs_days)
|
||||
{
|
||||
time_t purge_time= my_time(0) - expire_logs_days*24*60*60;
|
||||
if (purge_time >= 0)
|
||||
purge_logs_before_date(purge_time);
|
||||
}
|
||||
check_purge= true;
|
||||
#endif
|
||||
}
|
||||
if (!(flags & RP_LOCK_LOG_IS_ALREADY_LOCKED))
|
||||
pthread_mutex_unlock(&LOCK_log);
|
||||
|
||||
#ifdef HAVE_REPLICATION
|
||||
/*
|
||||
NOTE: Run purge_logs wo/ holding LOCK_log
|
||||
as it otherwise will deadlock in ndbcluster_binlog_index_purge_file
|
||||
*/
|
||||
if (check_purge && expire_logs_days)
|
||||
{
|
||||
time_t purge_time= my_time(0) - expire_logs_days*24*60*60;
|
||||
if (purge_time >= 0)
|
||||
purge_logs_before_date(purge_time);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
uint MYSQL_BIN_LOG::next_file_id()
|
||||
|
Loading…
x
Reference in New Issue
Block a user