@@ -3354,7 +3354,8 @@ void MYSQL_BIN_LOG::cleanup()
3354
3354
if (inited)
3355
3355
{
3356
3356
inited= 0 ;
3357
- close (LOG_CLOSE_INDEX|LOG_CLOSE_STOP_EVENT);
3357
+ close (LOG_CLOSE_INDEX|LOG_CLOSE_STOP_EVENT, true /* need_lock_log=true*/ ,
3358
+ true /* need_lock_index=true*/ );
3358
3359
mysql_mutex_destroy (&LOCK_log);
3359
3360
mysql_mutex_destroy (&LOCK_index);
3360
3361
mysql_mutex_destroy (&LOCK_commit);
@@ -3711,15 +3712,23 @@ bool MYSQL_BIN_LOG::open(
3711
3712
bool MYSQL_BIN_LOG::open_index_file (const char *index_file_name_arg,
3712
3713
const char *log_name, bool need_lock_index)
3713
3714
{
3715
+ bool error= false ;
3714
3716
File index_file_nr= -1 ;
3715
- DBUG_ASSERT (!my_b_inited (&index_file));
3717
+ if (need_lock_index)
3718
+ mysql_mutex_lock (&LOCK_index);
3719
+ else
3720
+ mysql_mutex_assert_owner (&LOCK_index);
3716
3721
3717
3722
/*
3718
3723
First open of this class instance
3719
3724
Create an index file that will hold all file names uses for logging.
3720
3725
Add new entries to the end of it.
3721
3726
*/
3722
3727
myf opt= MY_UNPACK_FILENAME;
3728
+
3729
+ if (my_b_inited (&index_file))
3730
+ goto end;
3731
+
3723
3732
if (!index_file_name_arg)
3724
3733
{
3725
3734
index_file_name_arg= log_name; // Use same basename for index file
@@ -3731,7 +3740,8 @@ bool MYSQL_BIN_LOG::open_index_file(const char *index_file_name_arg,
3731
3740
if (set_crash_safe_index_file_name (index_file_name_arg))
3732
3741
{
3733
3742
sql_print_error (" MYSQL_BIN_LOG::set_crash_safe_index_file_name failed." );
3734
- return TRUE ;
3743
+ error= true ;
3744
+ goto end;
3735
3745
}
3736
3746
3737
3747
/*
@@ -3745,7 +3755,8 @@ bool MYSQL_BIN_LOG::open_index_file(const char *index_file_name_arg,
3745
3755
{
3746
3756
sql_print_error (" MYSQL_BIN_LOG::open_index_file failed to "
3747
3757
" move crash_safe_index_file to index file." );
3748
- return TRUE ;
3758
+ error= true ;
3759
+ goto end;
3749
3760
}
3750
3761
3751
3762
if ((index_file_nr= mysql_file_open (m_key_file_log_index,
@@ -3768,7 +3779,8 @@ bool MYSQL_BIN_LOG::open_index_file(const char *index_file_name_arg,
3768
3779
*/
3769
3780
if (index_file_nr >= 0 )
3770
3781
mysql_file_close (index_file_nr, MYF (0 ));
3771
- return TRUE ;
3782
+ error= true ;
3783
+ goto end;
3772
3784
}
3773
3785
3774
3786
/*
@@ -3781,16 +3793,20 @@ bool MYSQL_BIN_LOG::open_index_file(const char *index_file_name_arg,
3781
3793
3782
3794
if (set_purge_index_file_name (index_file_name_arg) ||
3783
3795
open_purge_index_file (FALSE ) ||
3784
- purge_index_entry (NULL , NULL , need_lock_index ) ||
3796
+ purge_index_entry (NULL , NULL , false ) ||
3785
3797
close_purge_index_file () ||
3786
3798
DBUG_EVALUATE_IF (" fault_injection_recovering_index" , 1 , 0 ))
3787
3799
{
3788
3800
sql_print_error (" MYSQL_BIN_LOG::open_index_file failed to sync the index "
3789
3801
" file." );
3790
- return TRUE ;
3802
+ error= true ;
3803
+ goto end;
3791
3804
}
3792
3805
3793
- return FALSE ;
3806
+ end:
3807
+ if (need_lock_index)
3808
+ mysql_mutex_unlock (&LOCK_index);
3809
+ return error;
3794
3810
}
3795
3811
3796
3812
/* *
@@ -5133,22 +5149,21 @@ bool MYSQL_BIN_LOG::open_binlog(const char *log_name,
5133
5149
if (is_inited_purge_index_file ())
5134
5150
purge_index_entry (NULL , NULL , need_lock_index);
5135
5151
close_purge_index_file ();
5136
- end_io_cache (&log_file);
5137
- end_io_cache (&index_file);
5138
- my_free (name);
5139
- name= NULL ;
5140
- atomic_log_state = LOG_CLOSED;
5141
5152
if (binlog_error_action == ABORT_SERVER)
5142
5153
{
5143
5154
exec_binlog_error_action_abort (" Either disk is full or file system is read "
5144
5155
" only while opening the binlog. Aborting the"
5145
5156
" server." );
5146
5157
}
5147
5158
else
5159
+ {
5148
5160
sql_print_error (" Could not use %s for logging (error %d). "
5149
5161
" Turning logging off for the whole duration of the MySQL "
5150
5162
" server process. To turn it on again: fix the cause, "
5151
- " shutdown the MySQL server and restart it." , name, errno);
5163
+ " shutdown the MySQL server and restart it." ,
5164
+ (new_name) ? new_name : name, errno);
5165
+ close (LOG_CLOSE_INDEX, false , need_lock_index);
5166
+ }
5152
5167
DBUG_RETURN (1 );
5153
5168
}
5154
5169
@@ -5433,6 +5448,12 @@ int MYSQL_BIN_LOG::find_log_pos(LOG_INFO *linfo, const char *log_name,
5433
5448
else
5434
5449
mysql_mutex_assert_owner (&LOCK_index);
5435
5450
5451
+ if (!my_b_inited (&index_file))
5452
+ {
5453
+ error= LOG_INFO_IO;
5454
+ goto end;
5455
+ }
5456
+
5436
5457
// extend relative paths for log_name to be searched
5437
5458
if (log_name)
5438
5459
{
@@ -5524,6 +5545,11 @@ int MYSQL_BIN_LOG::find_next_log(LOG_INFO* linfo, bool need_lock_index)
5524
5545
else
5525
5546
mysql_mutex_assert_owner (&LOCK_index);
5526
5547
5548
+ if (!my_b_inited (&index_file))
5549
+ {
5550
+ error= LOG_INFO_IO;
5551
+ goto err;
5552
+ }
5527
5553
/* As the file is flushed, we can't get an error here */
5528
5554
my_b_seek (&index_file, linfo->index_file_offset );
5529
5555
@@ -5632,7 +5658,8 @@ bool MYSQL_BIN_LOG::reset_logs(THD* thd, bool delete_only)
5632
5658
/* Save variables so that we can reopen the log */
5633
5659
save_name=name;
5634
5660
name=0 ; // Protect against free
5635
- close (LOG_CLOSE_TO_BE_OPENED);
5661
+ close (LOG_CLOSE_TO_BE_OPENED, false /* need_lock_log=false*/ ,
5662
+ false /* need_lock_index=false*/ );
5636
5663
5637
5664
/*
5638
5665
First delete all old log files and then update the index file.
@@ -5686,7 +5713,9 @@ bool MYSQL_BIN_LOG::reset_logs(THD* thd, bool delete_only)
5686
5713
}
5687
5714
5688
5715
/* Start logging with a new file */
5689
- close (LOG_CLOSE_INDEX | LOG_CLOSE_TO_BE_OPENED);
5716
+ close (LOG_CLOSE_INDEX | LOG_CLOSE_TO_BE_OPENED,
5717
+ false /* need_lock_log=false*/ ,
5718
+ false /* need_lock_index=false*/ );
5690
5719
if ((error= my_delete_allow_opened (index_file_name, MYF (0 )))) // Reset (open will update)
5691
5720
{
5692
5721
if (my_errno () == ENOENT)
@@ -6843,7 +6872,9 @@ int MYSQL_BIN_LOG::new_file_impl(bool need_lock_log, Format_description_log_even
6843
6872
6844
6873
old_name=name;
6845
6874
name=0 ; // Don't free name
6846
- close (LOG_CLOSE_TO_BE_OPENED | LOG_CLOSE_INDEX);
6875
+ close (LOG_CLOSE_TO_BE_OPENED | LOG_CLOSE_INDEX,
6876
+ false /* need_lock_log=false*/ ,
6877
+ false /* need_lock_index=false*/ );
6847
6878
6848
6879
if (checksum_alg_reset != binary_log::BINLOG_CHECKSUM_ALG_UNDEF)
6849
6880
{
@@ -6907,7 +6938,6 @@ int MYSQL_BIN_LOG::new_file_impl(bool need_lock_log, Format_description_log_even
6907
6938
- switch server to protected/readonly mode
6908
6939
- ...
6909
6940
*/
6910
- close (LOG_CLOSE_INDEX);
6911
6941
if (binlog_error_action == ABORT_SERVER)
6912
6942
{
6913
6943
exec_binlog_error_action_abort (" Either disk is full or file system is"
@@ -6921,12 +6951,15 @@ int MYSQL_BIN_LOG::new_file_impl(bool need_lock_log, Format_description_log_even
6921
6951
" again: fix the cause, shutdown the MySQL "
6922
6952
" server and restart it." ,
6923
6953
new_name_ptr, errno);
6954
+ close (LOG_CLOSE_INDEX, false /* need_lock_log=false*/ ,
6955
+ false /* need_lock_index=false*/ );
6924
6956
}
6925
6957
6926
6958
mysql_mutex_unlock (&LOCK_index);
6927
6959
if (need_lock_log)
6928
6960
mysql_mutex_unlock (&LOCK_log);
6929
6961
6962
+ DEBUG_SYNC (current_thd, " after_disable_binlog" );
6930
6963
DBUG_RETURN (error);
6931
6964
}
6932
6965
@@ -7891,10 +7924,16 @@ int MYSQL_BIN_LOG::wait_for_update_bin_log(const struct timespec *timeout)
7891
7924
The internal structures are not freed until cleanup() is called
7892
7925
*/
7893
7926
7894
- void MYSQL_BIN_LOG::close (uint exiting)
7927
+ void MYSQL_BIN_LOG::close (uint exiting, bool need_lock_log,
7928
+ bool need_lock_index)
7895
7929
{ // One can't set log_type here!
7896
7930
DBUG_ENTER (" MYSQL_BIN_LOG::close" );
7897
7931
DBUG_PRINT (" enter" ,(" exiting: %d" , (int ) exiting));
7932
+ if (need_lock_log)
7933
+ mysql_mutex_lock (&LOCK_log);
7934
+ else
7935
+ mysql_mutex_assert_owner (&LOCK_log);
7936
+
7898
7937
if (atomic_log_state == LOG_OPENED)
7899
7938
{
7900
7939
if ((exiting & LOG_CLOSE_STOP_EVENT) != 0 )
@@ -7965,6 +8004,11 @@ void MYSQL_BIN_LOG::close(uint exiting)
7965
8004
called a not complete close earlier and the index file is still open.
7966
8005
*/
7967
8006
8007
+ if (need_lock_index)
8008
+ mysql_mutex_lock (&LOCK_index);
8009
+ else
8010
+ mysql_mutex_assert_owner (&LOCK_index);
8011
+
7968
8012
if ((exiting & LOG_CLOSE_INDEX) && my_b_inited (&index_file))
7969
8013
{
7970
8014
end_io_cache (&index_file);
@@ -7976,10 +8020,18 @@ void MYSQL_BIN_LOG::close(uint exiting)
7976
8020
errno, my_strerror (errbuf, sizeof (errbuf), errno));
7977
8021
}
7978
8022
}
8023
+
8024
+ if (need_lock_index)
8025
+ mysql_mutex_unlock (&LOCK_index);
8026
+
7979
8027
atomic_log_state =
7980
8028
(exiting & LOG_CLOSE_TO_BE_OPENED) ? LOG_TO_BE_OPENED : LOG_CLOSED;
7981
8029
my_free (name);
7982
8030
name= NULL ;
8031
+
8032
+ if (need_lock_log)
8033
+ mysql_mutex_unlock (&LOCK_log);
8034
+
7983
8035
DBUG_VOID_RETURN;
7984
8036
}
7985
8037
@@ -9033,7 +9085,8 @@ void MYSQL_BIN_LOG::handle_binlog_flush_or_sync_error(THD *thd,
9033
9085
" the cause, shutdown the MySQL server and restart it." ,
9034
9086
errmsg);
9035
9087
}
9036
- close (LOG_CLOSE_INDEX|LOG_CLOSE_STOP_EVENT);
9088
+ close (LOG_CLOSE_INDEX|LOG_CLOSE_STOP_EVENT, false /* need_lock_log=false*/ ,
9089
+ true /* need_lock_index=true*/ );
9037
9090
if (need_lock_log)
9038
9091
mysql_mutex_unlock (&LOCK_log);
9039
9092
DEBUG_SYNC (thd, " after_binlog_closed_due_to_error" );
0 commit comments