1- /* Copyright (c) 2009, 2015 , Oracle and/or its affiliates. All rights reserved.
1+ /* Copyright (c) 2009, 2016 , Oracle and/or its affiliates. All rights reserved.
22
33 This program is free software; you can redistribute it and/or modify
44 it under the terms of the GNU General Public License as published by
@@ -5067,9 +5067,6 @@ int MYSQL_BIN_LOG::new_file_impl(bool need_lock_log, Format_description_log_even
50675067 @note The caller must hold LOCK_log before invoking this function.
50685068
50695069 @param mi Master_info for the IO thread.
5070- @param need_data_lock If true, mi->data_lock will be acquired if a
5071- rotation is needed. Otherwise, mi->data_lock must be held by the
5072- caller.
50735070
50745071 @retval false success
50755072 @retval true error
@@ -5081,7 +5078,6 @@ bool MYSQL_BIN_LOG::after_append_to_relay_log(Master_info *mi)
50815078
50825079 // Check pre-conditions
50835080 mysql_mutex_assert_owner (&LOCK_log);
5084- mysql_mutex_assert_owner (&mi->data_lock );
50855081 DBUG_ASSERT (is_relay_log);
50865082 DBUG_ASSERT (current_thd->system_thread == SYSTEM_THREAD_SLAVE_IO);
50875083
@@ -5095,13 +5091,28 @@ bool MYSQL_BIN_LOG::after_append_to_relay_log(Master_info *mi)
50955091 if ((uint) my_b_append_tell (&log_file) >
50965092 DBUG_EVALUATE_IF (" rotate_slave_debug_group" , 500 , max_size))
50975093 {
5094+ /*
5095+ If rotation is required we must acquire data_lock to protect
5096+ description_event from clients executing FLUSH LOGS in parallel.
5097+ In order do that we must release the existing LOCK_log so that we
5098+ get it once again in proper locking order to avoid dead locks.
5099+ i.e data_lock , LOCK_log.
5100+ */
5101+ mysql_mutex_unlock (&LOCK_log);
5102+ mysql_mutex_lock (&mi->data_lock );
5103+ mysql_mutex_lock (&LOCK_log);
50985104 error= new_file_without_locking (mi->get_mi_description_event ());
50995105 DBUG_EXECUTE_IF (" set_max_size_zero" ,
51005106 {
51015107 max_size=1073741824 ;
51025108 DBUG_SET (" -d,set_max_size_zero" );
51035109 DBUG_SET (" -d,flush_after_reading_gtid_event" );
51045110 });
5111+ /*
5112+ After rotation release data_lock, we need the LOCK_log till we signal
5113+ the updation.
5114+ */
5115+ mysql_mutex_unlock (&mi->data_lock );
51055116 }
51065117 }
51075118
@@ -5113,14 +5124,21 @@ bool MYSQL_BIN_LOG::after_append_to_relay_log(Master_info *mi)
51135124
51145125bool MYSQL_BIN_LOG::append_event (Log_event* ev, Master_info *mi)
51155126{
5116- DBUG_ENTER (" MYSQL_BIN_LOG::append " );
5127+ DBUG_ENTER (" MYSQL_BIN_LOG::append_event " );
51175128
5129+ mysql_mutex_assert_owner (&mi->data_lock );
5130+ mysql_mutex_lock (&LOCK_log);
51185131 // check preconditions
51195132 DBUG_ASSERT (log_file.type == SEQ_READ_APPEND);
51205133 DBUG_ASSERT (is_relay_log);
51215134
5122- // acquire locks
5123- mysql_mutex_lock (&LOCK_log);
5135+ /*
5136+ Release data_lock by holding LOCK_log, while writing into the relay log.
5137+ If slave IO thread waits here for free space, we don't want
5138+ SHOW SLAVE STATUS to hang on mi->data_lock. Note LOCK_log mutex is
5139+ sufficient to block SQL thread when IO thread is updating relay log here.
5140+ */
5141+ mysql_mutex_unlock (&mi->data_lock );
51245142
51255143 // write data
51265144 bool error = false ;
@@ -5133,6 +5151,7 @@ bool MYSQL_BIN_LOG::append_event(Log_event* ev, Master_info *mi)
51335151 error= true ;
51345152
51355153 mysql_mutex_unlock (&LOCK_log);
5154+ mysql_mutex_lock (&mi->data_lock );
51365155 DBUG_RETURN (error);
51375156}
51385157
@@ -5141,11 +5160,18 @@ bool MYSQL_BIN_LOG::append_buffer(const char* buf, uint len, Master_info *mi)
51415160{
51425161 DBUG_ENTER (" MYSQL_BIN_LOG::append_buffer" );
51435162
5163+ mysql_mutex_assert_owner (&mi->data_lock );
5164+ mysql_mutex_lock (&LOCK_log);
51445165 // check preconditions
51455166 DBUG_ASSERT (log_file.type == SEQ_READ_APPEND);
51465167 DBUG_ASSERT (is_relay_log);
5147- mysql_mutex_assert_owner (&LOCK_log);
5148-
5168+ /*
5169+ Release data_lock by holding LOCK_log, while writing into the relay log.
5170+ If slave IO thread waits here for free space, we don't want
5171+ SHOW SLAVE STATUS to hang on mi->data_lock. Note LOCK_log mutex is
5172+ sufficient to block SQL thread when IO thread is updating relay log here.
5173+ */
5174+ mysql_mutex_unlock (&mi->data_lock );
51495175 // write data
51505176 bool error= false ;
51515177 if (my_b_append (&log_file,(uchar*) buf,len) == 0 )
@@ -5156,6 +5182,8 @@ bool MYSQL_BIN_LOG::append_buffer(const char* buf, uint len, Master_info *mi)
51565182 else
51575183 error= true ;
51585184
5185+ mysql_mutex_unlock (&LOCK_log);
5186+ mysql_mutex_lock (&mi->data_lock );
51595187 DBUG_RETURN (error);
51605188}
51615189#endif // ifdef HAVE_REPLICATION
0 commit comments