1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-01 03:47:19 +03:00

BUG#50364: FLUSH LOGS crashes the server (rpl.rpl_heartbeat_basic

fails in PB sporadically)
      
The IO thread can concurrently access the relay log IO_CACHE
while another thread is performing an FLUSH LOGS procedure.
      
FLUSH LOGS closes and reopens the relay log and while doing so it
(re)initializes its IO_CACHE. During this procedure the IO_CACHE
mutex is also reinitialized, which can cause problems if some
other thread (namely the IO THREAD) is concurrently accessing it
at the time .
      
This patch fixes the problem by extending the interface of the
flush_master_info function to also include a second paramater, 
"need_relay_log_lock", stating whether the thread should grab the 
relay log lock or not before actually flushing the relay log. 
Also, IO thread now calls flush_master_info with this flag set 
when it flushes master info with in the event read_event loop.

Finally, we also increase loop time in rpl_heartbeat_basic test 
case, so that the number of calls to flush logs doubles, stressing
this part of the code a little more.
This commit is contained in:
Luis Soares
2010-02-03 16:56:17 +00:00
parent da88c90aa2
commit d0ffa8e51b
7 changed files with 25 additions and 10 deletions

View File

@ -387,7 +387,7 @@ file '%s')", fname);
mi->rli.is_relay_log_recovery= FALSE;
// now change cache READ -> WRITE - must do this before flush_master_info
reinit_io_cache(&mi->file, WRITE_CACHE, 0L, 0, 1);
if ((error=test(flush_master_info(mi, 1))))
if ((error=test(flush_master_info(mi, TRUE, TRUE))))
sql_print_error("Failed to flush master info file");
pthread_mutex_unlock(&mi->data_lock);
DBUG_RETURN(error);
@ -413,7 +413,9 @@ err:
1 - flush master info failed
0 - all ok
*/
int flush_master_info(Master_info* mi, bool flush_relay_log_cache)
int flush_master_info(Master_info* mi,
bool flush_relay_log_cache,
bool need_lock_relay_log)
{
IO_CACHE* file = &mi->file;
char lbuf[22];
@ -436,8 +438,19 @@ int flush_master_info(Master_info* mi, bool flush_relay_log_cache)
*/
if (flush_relay_log_cache)
{
pthread_mutex_t *log_lock= mi->rli.relay_log.get_log_lock();
IO_CACHE *log_file= mi->rli.relay_log.get_log_file();
if (flush_io_cache(log_file))
if (need_lock_relay_log)
pthread_mutex_lock(log_lock);
safe_mutex_assert_owner(log_lock);
err= flush_io_cache(log_file);
if (need_lock_relay_log)
pthread_mutex_unlock(log_lock);
if (err)
DBUG_RETURN(2);
}