@@ -3157,7 +3157,8 @@ void MYSQL_BIN_LOG::cleanup()
3157
3157
if (inited)
3158
3158
{
3159
3159
inited= 0 ;
3160
- close (LOG_CLOSE_INDEX|LOG_CLOSE_STOP_EVENT);
3160
+ close (LOG_CLOSE_INDEX|LOG_CLOSE_STOP_EVENT, true /* need_lock_log=true*/ ,
3161
+ true /* need_lock_index=true*/ );
3161
3162
mysql_mutex_destroy (&LOCK_log);
3162
3163
mysql_mutex_destroy (&LOCK_index);
3163
3164
mysql_mutex_destroy (&LOCK_commit);
@@ -3503,15 +3504,23 @@ bool MYSQL_BIN_LOG::open(
3503
3504
bool MYSQL_BIN_LOG::open_index_file (const char *index_file_name_arg,
3504
3505
const char *log_name, bool need_lock_index)
3505
3506
{
3507
+ bool error= false ;
3506
3508
File index_file_nr= -1 ;
3507
- DBUG_ASSERT (!my_b_inited (&index_file));
3509
+ if (need_lock_index)
3510
+ mysql_mutex_lock (&LOCK_index);
3511
+ else
3512
+ mysql_mutex_assert_owner (&LOCK_index);
3508
3513
3509
3514
/*
3510
3515
First open of this class instance
3511
3516
Create an index file that will hold all file names uses for logging.
3512
3517
Add new entries to the end of it.
3513
3518
*/
3514
3519
myf opt= MY_UNPACK_FILENAME;
3520
+
3521
+ if (my_b_inited (&index_file))
3522
+ goto end;
3523
+
3515
3524
if (!index_file_name_arg)
3516
3525
{
3517
3526
index_file_name_arg= log_name; // Use same basename for index file
@@ -3523,7 +3532,8 @@ bool MYSQL_BIN_LOG::open_index_file(const char *index_file_name_arg,
3523
3532
if (set_crash_safe_index_file_name (index_file_name_arg))
3524
3533
{
3525
3534
sql_print_error (" MYSQL_BIN_LOG::set_crash_safe_index_file_name failed." );
3526
- return TRUE ;
3535
+ error= true ;
3536
+ goto end;
3527
3537
}
3528
3538
3529
3539
/*
@@ -3537,7 +3547,8 @@ bool MYSQL_BIN_LOG::open_index_file(const char *index_file_name_arg,
3537
3547
{
3538
3548
sql_print_error (" MYSQL_BIN_LOG::open_index_file failed to "
3539
3549
" move crash_safe_index_file to index file." );
3540
- return TRUE ;
3550
+ error= true ;
3551
+ goto end;
3541
3552
}
3542
3553
3543
3554
if ((index_file_nr= mysql_file_open (m_key_file_log_index,
@@ -3560,7 +3571,8 @@ bool MYSQL_BIN_LOG::open_index_file(const char *index_file_name_arg,
3560
3571
*/
3561
3572
if (index_file_nr >= 0 )
3562
3573
mysql_file_close (index_file_nr, MYF (0 ));
3563
- return TRUE ;
3574
+ error= true ;
3575
+ goto end;
3564
3576
}
3565
3577
3566
3578
#ifdef HAVE_REPLICATION
@@ -3574,17 +3586,21 @@ bool MYSQL_BIN_LOG::open_index_file(const char *index_file_name_arg,
3574
3586
3575
3587
if (set_purge_index_file_name (index_file_name_arg) ||
3576
3588
open_purge_index_file (FALSE ) ||
3577
- purge_index_entry (NULL , NULL , need_lock_index ) ||
3589
+ purge_index_entry (NULL , NULL , false ) ||
3578
3590
close_purge_index_file () ||
3579
3591
DBUG_EVALUATE_IF (" fault_injection_recovering_index" , 1 , 0 ))
3580
3592
{
3581
3593
sql_print_error (" MYSQL_BIN_LOG::open_index_file failed to sync the index "
3582
3594
" file." );
3583
- return TRUE ;
3595
+ error= true ;
3596
+ goto end;
3584
3597
}
3585
3598
#endif
3586
3599
3587
- return FALSE ;
3600
+ end:
3601
+ if (need_lock_index)
3602
+ mysql_mutex_unlock (&LOCK_index);
3603
+ return error;
3588
3604
}
3589
3605
3590
3606
/* *
@@ -4939,22 +4955,21 @@ bool MYSQL_BIN_LOG::open_binlog(const char *log_name,
4939
4955
purge_index_entry (NULL , NULL , need_lock_index);
4940
4956
close_purge_index_file ();
4941
4957
#endif
4942
- end_io_cache (&log_file);
4943
- end_io_cache (&index_file);
4944
- my_free (name);
4945
- name= NULL ;
4946
- log_state.atomic_set (LOG_CLOSED);
4947
4958
if (binlog_error_action == ABORT_SERVER)
4948
4959
{
4949
4960
exec_binlog_error_action_abort (" Either disk is full or file system is read "
4950
4961
" only while opening the binlog. Aborting the"
4951
4962
" server." );
4952
4963
}
4953
4964
else
4965
+ {
4954
4966
sql_print_error (" Could not use %s for logging (error %d). "
4955
4967
" Turning logging off for the whole duration of the MySQL "
4956
4968
" server process. To turn it on again: fix the cause, "
4957
- " shutdown the MySQL server and restart it." , name, errno);
4969
+ " shutdown the MySQL server and restart it." ,
4970
+ (new_name) ? new_name : name, errno);
4971
+ close (LOG_CLOSE_INDEX, false , need_lock_index);
4972
+ }
4958
4973
DBUG_RETURN (1 );
4959
4974
}
4960
4975
@@ -5239,6 +5254,12 @@ int MYSQL_BIN_LOG::find_log_pos(LOG_INFO *linfo, const char *log_name,
5239
5254
else
5240
5255
mysql_mutex_assert_owner (&LOCK_index);
5241
5256
5257
+ if (!my_b_inited (&index_file))
5258
+ {
5259
+ error= LOG_INFO_IO;
5260
+ goto end;
5261
+ }
5262
+
5242
5263
// extend relative paths for log_name to be searched
5243
5264
if (log_name)
5244
5265
{
@@ -5330,6 +5351,11 @@ int MYSQL_BIN_LOG::find_next_log(LOG_INFO* linfo, bool need_lock_index)
5330
5351
else
5331
5352
mysql_mutex_assert_owner (&LOCK_index);
5332
5353
5354
+ if (!my_b_inited (&index_file))
5355
+ {
5356
+ error= LOG_INFO_IO;
5357
+ goto err;
5358
+ }
5333
5359
/* As the file is flushed, we can't get an error here */
5334
5360
my_b_seek (&index_file, linfo->index_file_offset );
5335
5361
@@ -5436,7 +5462,8 @@ bool MYSQL_BIN_LOG::reset_logs(THD* thd, bool delete_only)
5436
5462
/* Save variables so that we can reopen the log */
5437
5463
save_name=name;
5438
5464
name=0 ; // Protect against free
5439
- close (LOG_CLOSE_TO_BE_OPENED);
5465
+ close (LOG_CLOSE_TO_BE_OPENED, false /* need_lock_log=false*/ ,
5466
+ false /* need_lock_index=false*/ );
5440
5467
5441
5468
/*
5442
5469
First delete all old log files and then update the index file.
@@ -5489,7 +5516,9 @@ bool MYSQL_BIN_LOG::reset_logs(THD* thd, bool delete_only)
5489
5516
}
5490
5517
5491
5518
/* Start logging with a new file */
5492
- close (LOG_CLOSE_INDEX | LOG_CLOSE_TO_BE_OPENED);
5519
+ close (LOG_CLOSE_INDEX | LOG_CLOSE_TO_BE_OPENED,
5520
+ false /* need_lock_log=false*/ ,
5521
+ false /* need_lock_index=false*/ );
5493
5522
if ((error= my_delete_allow_opened (index_file_name, MYF (0 )))) // Reset (open will update)
5494
5523
{
5495
5524
if (my_errno () == ENOENT)
@@ -6643,7 +6672,9 @@ int MYSQL_BIN_LOG::new_file_impl(bool need_lock_log, Format_description_log_even
6643
6672
6644
6673
old_name=name;
6645
6674
name=0 ; // Don't free name
6646
- close (LOG_CLOSE_TO_BE_OPENED | LOG_CLOSE_INDEX);
6675
+ close (LOG_CLOSE_TO_BE_OPENED | LOG_CLOSE_INDEX,
6676
+ false /* need_lock_log=false*/ ,
6677
+ false /* need_lock_index=false*/ );
6647
6678
6648
6679
if (checksum_alg_reset != binary_log::BINLOG_CHECKSUM_ALG_UNDEF)
6649
6680
{
@@ -6706,7 +6737,6 @@ int MYSQL_BIN_LOG::new_file_impl(bool need_lock_log, Format_description_log_even
6706
6737
- switch server to protected/readonly mode
6707
6738
- ...
6708
6739
*/
6709
- close (LOG_CLOSE_INDEX);
6710
6740
if (binlog_error_action == ABORT_SERVER)
6711
6741
{
6712
6742
exec_binlog_error_action_abort (" Either disk is full or file system is"
@@ -6720,12 +6750,14 @@ int MYSQL_BIN_LOG::new_file_impl(bool need_lock_log, Format_description_log_even
6720
6750
" again: fix the cause, shutdown the MySQL "
6721
6751
" server and restart it." ,
6722
6752
new_name_ptr, errno);
6753
+ close (LOG_CLOSE_INDEX, false /* need_lock_log=false*/ ,
6754
+ false /* need_lock_index=false*/ );
6723
6755
}
6724
6756
6725
6757
mysql_mutex_unlock (&LOCK_index);
6726
6758
if (need_lock_log)
6727
6759
mysql_mutex_unlock (&LOCK_log);
6728
-
6760
+ DEBUG_SYNC (current_thd, " after_disable_binlog " );
6729
6761
DBUG_RETURN (error);
6730
6762
}
6731
6763
@@ -7699,10 +7731,16 @@ int MYSQL_BIN_LOG::wait_for_update_bin_log(THD* thd,
7699
7731
The internal structures are not freed until cleanup() is called
7700
7732
*/
7701
7733
7702
- void MYSQL_BIN_LOG::close (uint exiting)
7734
+ void MYSQL_BIN_LOG::close (uint exiting, bool need_lock_log,
7735
+ bool need_lock_index)
7703
7736
{ // One can't set log_type here!
7704
7737
DBUG_ENTER (" MYSQL_BIN_LOG::close" );
7705
7738
DBUG_PRINT (" enter" ,(" exiting: %d" , (int ) exiting));
7739
+ if (need_lock_log)
7740
+ mysql_mutex_lock (&LOCK_log);
7741
+ else
7742
+ mysql_mutex_assert_owner (&LOCK_log);
7743
+
7706
7744
if (log_state.atomic_get () == LOG_OPENED)
7707
7745
{
7708
7746
#ifdef HAVE_REPLICATION
@@ -7774,6 +7812,11 @@ void MYSQL_BIN_LOG::close(uint exiting)
7774
7812
called a not complete close earlier and the index file is still open.
7775
7813
*/
7776
7814
7815
+ if (need_lock_index)
7816
+ mysql_mutex_lock (&LOCK_index);
7817
+ else
7818
+ mysql_mutex_assert_owner (&LOCK_index);
7819
+
7777
7820
if ((exiting & LOG_CLOSE_INDEX) && my_b_inited (&index_file))
7778
7821
{
7779
7822
end_io_cache (&index_file);
@@ -7785,9 +7828,17 @@ void MYSQL_BIN_LOG::close(uint exiting)
7785
7828
errno, my_strerror (errbuf, sizeof (errbuf), errno));
7786
7829
}
7787
7830
}
7831
+
7832
+ if (need_lock_index)
7833
+ mysql_mutex_unlock (&LOCK_index);
7834
+
7788
7835
log_state.atomic_set ((exiting & LOG_CLOSE_TO_BE_OPENED) ? LOG_TO_BE_OPENED : LOG_CLOSED);
7789
7836
my_free (name);
7790
7837
name= NULL ;
7838
+
7839
+ if (need_lock_log)
7840
+ mysql_mutex_unlock (&LOCK_log);
7841
+
7791
7842
DBUG_VOID_RETURN;
7792
7843
}
7793
7844
@@ -8844,7 +8895,8 @@ void MYSQL_BIN_LOG::handle_binlog_flush_or_sync_error(THD *thd,
8844
8895
" the cause, shutdown the MySQL server and restart it." ,
8845
8896
errmsg);
8846
8897
}
8847
- close (LOG_CLOSE_INDEX|LOG_CLOSE_STOP_EVENT);
8898
+ close (LOG_CLOSE_INDEX|LOG_CLOSE_STOP_EVENT, false /* need_lock_log=false*/ ,
8899
+ true /* need_lock_index=true*/ );
8848
8900
if (need_lock_log)
8849
8901
mysql_mutex_unlock (&LOCK_log);
8850
8902
DEBUG_SYNC (thd, " after_binlog_closed_due_to_error" );
0 commit comments