1
- /* Copyright (c) 2009, 2016 , Oracle and/or its affiliates. All rights reserved.
1
+ /* Copyright (c) 2009, 2017 , Oracle and/or its affiliates. All rights reserved.
2
2
3
3
This program is free software; you can redistribute it and/or modify
4
4
it under the terms of the GNU General Public License as published by
@@ -2481,7 +2481,8 @@ void MYSQL_BIN_LOG::cleanup()
2481
2481
if (inited)
2482
2482
{
2483
2483
inited= 0 ;
2484
- close (LOG_CLOSE_INDEX|LOG_CLOSE_STOP_EVENT);
2484
+ close (LOG_CLOSE_INDEX|LOG_CLOSE_STOP_EVENT, true /* need_lock_log=true*/ ,
2485
+ true /* need_lock_index=true*/ );
2485
2486
mysql_mutex_destroy (&LOCK_log);
2486
2487
mysql_mutex_destroy (&LOCK_index);
2487
2488
mysql_mutex_destroy (&LOCK_commit);
@@ -2519,15 +2520,24 @@ void MYSQL_BIN_LOG::init_pthread_objects()
2519
2520
bool MYSQL_BIN_LOG::open_index_file (const char *index_file_name_arg,
2520
2521
const char *log_name, bool need_lock_index)
2521
2522
{
2523
+ bool error= false ;
2522
2524
File index_file_nr= -1 ;
2523
- DBUG_ASSERT (!my_b_inited (&index_file));
2525
+
2526
+ if (need_lock_index)
2527
+ mysql_mutex_lock (&LOCK_index);
2528
+ else
2529
+ mysql_mutex_assert_owner (&LOCK_index);
2524
2530
2525
2531
/*
2526
2532
First open of this class instance
2527
2533
Create an index file that will hold all file names uses for logging.
2528
2534
Add new entries to the end of it.
2529
2535
*/
2530
2536
myf opt= MY_UNPACK_FILENAME;
2537
+
2538
+ if (my_b_inited (&index_file))
2539
+ goto end;
2540
+
2531
2541
if (!index_file_name_arg)
2532
2542
{
2533
2543
index_file_name_arg= log_name; // Use same basename for index file
@@ -2539,7 +2549,8 @@ bool MYSQL_BIN_LOG::open_index_file(const char *index_file_name_arg,
2539
2549
if (set_crash_safe_index_file_name (index_file_name_arg))
2540
2550
{
2541
2551
sql_print_error (" MYSQL_BIN_LOG::set_crash_safe_index_file_name failed." );
2542
- return TRUE ;
2552
+ error= true ;
2553
+ goto end;
2543
2554
}
2544
2555
2545
2556
/*
@@ -2553,7 +2564,8 @@ bool MYSQL_BIN_LOG::open_index_file(const char *index_file_name_arg,
2553
2564
{
2554
2565
sql_print_error (" MYSQL_BIN_LOG::open_index_file failed to "
2555
2566
" move crash_safe_index_file to index file." );
2556
- return TRUE ;
2567
+ error= true ;
2568
+ goto end;
2557
2569
}
2558
2570
2559
2571
if ((index_file_nr= mysql_file_open (m_key_file_log_index,
@@ -2575,7 +2587,8 @@ bool MYSQL_BIN_LOG::open_index_file(const char *index_file_name_arg,
2575
2587
*/
2576
2588
if (index_file_nr >= 0 )
2577
2589
mysql_file_close (index_file_nr, MYF (0 ));
2578
- return TRUE ;
2590
+ error= true ;
2591
+ goto end;
2579
2592
}
2580
2593
2581
2594
#ifdef HAVE_REPLICATION
@@ -2589,17 +2602,20 @@ bool MYSQL_BIN_LOG::open_index_file(const char *index_file_name_arg,
2589
2602
2590
2603
if (set_purge_index_file_name (index_file_name_arg) ||
2591
2604
open_purge_index_file (FALSE ) ||
2592
- purge_index_entry (NULL , NULL , need_lock_index ) ||
2605
+ purge_index_entry (NULL , NULL , false ) ||
2593
2606
close_purge_index_file () ||
2594
2607
DBUG_EVALUATE_IF (" fault_injection_recovering_index" , 1 , 0 ))
2595
2608
{
2596
2609
sql_print_error (" MYSQL_BIN_LOG::open_index_file failed to sync the index "
2597
2610
" file." );
2598
- return TRUE ;
2611
+ error= TRUE ;
2612
+ goto end;
2599
2613
}
2600
2614
#endif
2601
-
2602
- return FALSE ;
2615
+ end:
2616
+ if (need_lock_index)
2617
+ mysql_mutex_unlock (&LOCK_index);
2618
+ return error;
2603
2619
}
2604
2620
2605
2621
@@ -3161,11 +3177,11 @@ bool MYSQL_BIN_LOG::open_binlog(const char *log_name,
3161
3177
enum cache_type io_cache_type_arg,
3162
3178
ulong max_size_arg,
3163
3179
bool null_created_arg,
3180
+ bool need_lock_log,
3164
3181
bool need_lock_index,
3165
3182
bool need_sid_lock,
3166
3183
Format_description_log_event *extra_description_event)
3167
3184
{
3168
- File file= -1 ;
3169
3185
3170
3186
// lock_index must be acquired *before* sid_lock.
3171
3187
DBUG_ASSERT (need_sid_lock || !need_lock_index);
@@ -3377,24 +3393,22 @@ bool MYSQL_BIN_LOG::open_binlog(const char *log_name,
3377
3393
purge_index_entry (NULL , NULL , need_lock_index);
3378
3394
close_purge_index_file ();
3379
3395
#endif
3380
- if (file >= 0 )
3381
- mysql_file_close (file, MYF (0 ));
3382
- end_io_cache (&log_file);
3383
- end_io_cache (&index_file);
3384
- my_free (name);
3385
- name= NULL ;
3386
- log_state= LOG_CLOSED;
3396
+
3387
3397
if (binlog_error_action == ABORT_SERVER)
3388
3398
{
3389
3399
exec_binlog_error_action_abort (" Either disk is full or file system is read "
3390
3400
" only while opening the binlog. Aborting the"
3391
3401
" server." );
3392
3402
}
3393
3403
else
3404
+ {
3394
3405
sql_print_error (" Could not use %s for logging (error %d). "
3395
3406
" Turning logging off for the whole duration of the MySQL "
3396
3407
" server process. To turn it on again: fix the cause, "
3397
- " shutdown the MySQL server and restart it." , name, errno);
3408
+ " shutdown the MySQL server and restart it." ,
3409
+ (new_name) ? new_name : name, errno);
3410
+ close (LOG_CLOSE_INDEX, need_lock_log, need_lock_index);
3411
+ }
3398
3412
DBUG_RETURN (1 );
3399
3413
}
3400
3414
@@ -3678,6 +3692,12 @@ int MYSQL_BIN_LOG::find_log_pos(LOG_INFO *linfo, const char *log_name,
3678
3692
else
3679
3693
mysql_mutex_assert_owner (&LOCK_index);
3680
3694
3695
+ if (!my_b_inited (&index_file))
3696
+ {
3697
+ error= LOG_INFO_IO;
3698
+ goto end;
3699
+ }
3700
+
3681
3701
// extend relative paths for log_name to be searched
3682
3702
if (log_name)
3683
3703
{
@@ -3770,6 +3790,11 @@ int MYSQL_BIN_LOG::find_next_log(LOG_INFO* linfo, bool need_lock_index)
3770
3790
else
3771
3791
mysql_mutex_assert_owner (&LOCK_index);
3772
3792
3793
+ if (!my_b_inited (&index_file))
3794
+ {
3795
+ error= LOG_INFO_IO;
3796
+ goto err;
3797
+ }
3773
3798
/* As the file is flushed, we can't get an error here */
3774
3799
my_b_seek (&index_file, linfo->index_file_offset );
3775
3800
@@ -3854,7 +3879,8 @@ bool MYSQL_BIN_LOG::reset_logs(THD* thd)
3854
3879
/* Save variables so that we can reopen the log */
3855
3880
save_name=name;
3856
3881
name=0 ; // Protect against free
3857
- close (LOG_CLOSE_TO_BE_OPENED);
3882
+ close (LOG_CLOSE_TO_BE_OPENED, false /* need_lock_log=false*/ ,
3883
+ false /* need_lock_index=false*/ );
3858
3884
3859
3885
/*
3860
3886
First delete all old log files and then update the index file.
@@ -3907,7 +3933,9 @@ bool MYSQL_BIN_LOG::reset_logs(THD* thd)
3907
3933
}
3908
3934
3909
3935
/* Start logging with a new file */
3910
- close (LOG_CLOSE_INDEX | LOG_CLOSE_TO_BE_OPENED);
3936
+ close (LOG_CLOSE_INDEX | LOG_CLOSE_TO_BE_OPENED,
3937
+ false /* need_lock_log=false*/ ,
3938
+ false /* need_lock_index=false*/ );
3911
3939
if ((error= my_delete_allow_opened (index_file_name, MYF (0 )))) // Reset (open will update)
3912
3940
{
3913
3941
if (my_errno == ENOENT)
@@ -3953,6 +3981,7 @@ bool MYSQL_BIN_LOG::reset_logs(THD* thd)
3953
3981
if (!open_index_file (index_file_name, 0 , false /* need_lock_index=false*/ ))
3954
3982
if ((error= open_binlog (save_name, 0 , io_cache_type,
3955
3983
max_size, false ,
3984
+ false /* need_lock_log=false*/ ,
3956
3985
false /* need_lock_index=false*/ ,
3957
3986
false /* need_sid_lock=false*/ ,
3958
3987
NULL )))
@@ -5010,7 +5039,9 @@ int MYSQL_BIN_LOG::new_file_impl(bool need_lock_log, Format_description_log_even
5010
5039
5011
5040
old_name=name;
5012
5041
name=0 ; // Don't free name
5013
- close (LOG_CLOSE_TO_BE_OPENED | LOG_CLOSE_INDEX);
5042
+ close (LOG_CLOSE_TO_BE_OPENED | LOG_CLOSE_INDEX,
5043
+ false /* need_lock_log=false*/ ,
5044
+ false /* need_lock_index=false*/ );
5014
5045
5015
5046
if (checksum_alg_reset != BINLOG_CHECKSUM_ALG_UNDEF)
5016
5047
{
@@ -5041,6 +5072,7 @@ int MYSQL_BIN_LOG::new_file_impl(bool need_lock_log, Format_description_log_even
5041
5072
file_to_open= new_name_ptr;
5042
5073
error= open_binlog (old_name, new_name_ptr, io_cache_type,
5043
5074
max_size, true /* null_created_arg=true*/ ,
5075
+ false /* need_lock_log=false*/ ,
5044
5076
false /* need_lock_index=false*/ ,
5045
5077
true /* need_sid_lock=true*/ ,
5046
5078
extra_description_event);
@@ -5073,7 +5105,6 @@ int MYSQL_BIN_LOG::new_file_impl(bool need_lock_log, Format_description_log_even
5073
5105
- switch server to protected/readonly mode
5074
5106
- ...
5075
5107
*/
5076
- close (LOG_CLOSE_INDEX);
5077
5108
if (binlog_error_action == ABORT_SERVER)
5078
5109
{
5079
5110
exec_binlog_error_action_abort (" Either disk is full or file system is"
@@ -5087,12 +5118,15 @@ int MYSQL_BIN_LOG::new_file_impl(bool need_lock_log, Format_description_log_even
5087
5118
" again: fix the cause, shutdown the MySQL "
5088
5119
" server and restart it." ,
5089
5120
new_name_ptr, errno);
5121
+ close (LOG_CLOSE_INDEX, false /* need_lock_log=false*/ ,
5122
+ false /* need_lock_index=false*/ );
5090
5123
}
5091
5124
5092
5125
mysql_mutex_unlock (&LOCK_index);
5093
5126
if (need_lock_log)
5094
5127
mysql_mutex_unlock (&LOCK_log);
5095
5128
5129
+ DEBUG_SYNC (current_thd, " after_disable_binlog" );
5096
5130
DBUG_RETURN (error);
5097
5131
}
5098
5132
@@ -6113,10 +6147,17 @@ int MYSQL_BIN_LOG::wait_for_update_bin_log(THD* thd,
6113
6147
The internal structures are not freed until cleanup() is called
6114
6148
*/
6115
6149
6116
- void MYSQL_BIN_LOG::close (uint exiting)
6150
+ void MYSQL_BIN_LOG::close (uint exiting, bool need_lock_log,
6151
+ bool need_lock_index)
6117
6152
{ // One can't set log_type here!
6118
6153
DBUG_ENTER (" MYSQL_BIN_LOG::close" );
6119
6154
DBUG_PRINT (" enter" ,(" exiting: %d" , (int ) exiting));
6155
+
6156
+ if (need_lock_log)
6157
+ mysql_mutex_lock (&LOCK_log);
6158
+ else
6159
+ mysql_mutex_assert_owner (&LOCK_log);
6160
+
6120
6161
if (log_state == LOG_OPENED)
6121
6162
{
6122
6163
#ifdef HAVE_REPLICATION
@@ -6159,6 +6200,11 @@ void MYSQL_BIN_LOG::close(uint exiting)
6159
6200
called a not complete close earlier and the index file is still open.
6160
6201
*/
6161
6202
6203
+ if (need_lock_index)
6204
+ mysql_mutex_lock (&LOCK_index);
6205
+ else
6206
+ mysql_mutex_assert_owner (&LOCK_index);
6207
+
6162
6208
if ((exiting & LOG_CLOSE_INDEX) && my_b_inited (&index_file))
6163
6209
{
6164
6210
end_io_cache (&index_file);
@@ -6170,9 +6216,17 @@ void MYSQL_BIN_LOG::close(uint exiting)
6170
6216
errno, my_strerror (errbuf, sizeof (errbuf), errno));
6171
6217
}
6172
6218
}
6219
+
6220
+ if (need_lock_index)
6221
+ mysql_mutex_unlock (&LOCK_index);
6222
+
6173
6223
log_state= (exiting & LOG_CLOSE_TO_BE_OPENED) ? LOG_TO_BE_OPENED : LOG_CLOSED;
6174
6224
my_free (name);
6175
6225
name= NULL ;
6226
+
6227
+ if (need_lock_log)
6228
+ mysql_mutex_unlock (&LOCK_log);
6229
+
6176
6230
DBUG_VOID_RETURN;
6177
6231
}
6178
6232
@@ -6237,6 +6291,7 @@ int MYSQL_BIN_LOG::open_binlog(const char *opt_name)
6237
6291
{
6238
6292
/* generate a new binlog to mask a corrupted one */
6239
6293
open_binlog (opt_name, 0 , WRITE_CACHE, max_binlog_size, false ,
6294
+ true /* need_lock_log=true*/ ,
6240
6295
true /* need_lock_index=true*/ ,
6241
6296
true /* need_sid_lock=true*/ ,
6242
6297
NULL );
@@ -7036,7 +7091,8 @@ void MYSQL_BIN_LOG::handle_binlog_flush_or_sync_error(THD *thd,
7036
7091
" the cause, shutdown the MySQL server and restart it." ,
7037
7092
errmsg);
7038
7093
}
7039
- close (LOG_CLOSE_INDEX|LOG_CLOSE_STOP_EVENT);
7094
+ close (LOG_CLOSE_INDEX|LOG_CLOSE_STOP_EVENT, false /* need_lock_log=false*/ ,
7095
+ true /* need_lock_index=true*/ );
7040
7096
if (need_lock_log)
7041
7097
mysql_mutex_unlock (&LOCK_log);
7042
7098
DEBUG_SYNC (thd, " after_binlog_closed_due_to_error" );
0 commit comments