Commit e76d96c4 authored by He Zhenxing's avatar He Zhenxing

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
parent aa388252
......@@ -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)
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
}
if (!(flags & RP_LOCK_LOG_IS_ALREADY_LOCKED))
pthread_mutex_unlock(&LOCK_log);
}
uint MYSQL_BIN_LOG::next_file_id()
......
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