Skip to content

Commit a93db4b

Browse files
author
Sujatha Sivakumar
committed
Merge branch 'mysql-5.7' into mysql-trunk
2 parents cbda6b6 + ac52536 commit a93db4b

File tree

4 files changed

+116
-25
lines changed

4 files changed

+116
-25
lines changed

sql/binlog.cc

Lines changed: 73 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3354,7 +3354,8 @@ void MYSQL_BIN_LOG::cleanup()
33543354
if (inited)
33553355
{
33563356
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*/);
33583359
mysql_mutex_destroy(&LOCK_log);
33593360
mysql_mutex_destroy(&LOCK_index);
33603361
mysql_mutex_destroy(&LOCK_commit);
@@ -3711,15 +3712,23 @@ bool MYSQL_BIN_LOG::open(
37113712
bool MYSQL_BIN_LOG::open_index_file(const char *index_file_name_arg,
37123713
const char *log_name, bool need_lock_index)
37133714
{
3715+
bool error= false;
37143716
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);
37163721

37173722
/*
37183723
First open of this class instance
37193724
Create an index file that will hold all file names uses for logging.
37203725
Add new entries to the end of it.
37213726
*/
37223727
myf opt= MY_UNPACK_FILENAME;
3728+
3729+
if (my_b_inited(&index_file))
3730+
goto end;
3731+
37233732
if (!index_file_name_arg)
37243733
{
37253734
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,
37313740
if (set_crash_safe_index_file_name(index_file_name_arg))
37323741
{
37333742
sql_print_error("MYSQL_BIN_LOG::set_crash_safe_index_file_name failed.");
3734-
return TRUE;
3743+
error= true;
3744+
goto end;
37353745
}
37363746

37373747
/*
@@ -3745,7 +3755,8 @@ bool MYSQL_BIN_LOG::open_index_file(const char *index_file_name_arg,
37453755
{
37463756
sql_print_error("MYSQL_BIN_LOG::open_index_file failed to "
37473757
"move crash_safe_index_file to index file.");
3748-
return TRUE;
3758+
error= true;
3759+
goto end;
37493760
}
37503761

37513762
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,
37683779
*/
37693780
if (index_file_nr >= 0)
37703781
mysql_file_close(index_file_nr, MYF(0));
3771-
return TRUE;
3782+
error= true;
3783+
goto end;
37723784
}
37733785

37743786
/*
@@ -3781,16 +3793,20 @@ bool MYSQL_BIN_LOG::open_index_file(const char *index_file_name_arg,
37813793

37823794
if (set_purge_index_file_name(index_file_name_arg) ||
37833795
open_purge_index_file(FALSE) ||
3784-
purge_index_entry(NULL, NULL, need_lock_index) ||
3796+
purge_index_entry(NULL, NULL, false) ||
37853797
close_purge_index_file() ||
37863798
DBUG_EVALUATE_IF("fault_injection_recovering_index", 1, 0))
37873799
{
37883800
sql_print_error("MYSQL_BIN_LOG::open_index_file failed to sync the index "
37893801
"file.");
3790-
return TRUE;
3802+
error= true;
3803+
goto end;
37913804
}
37923805

3793-
return FALSE;
3806+
end:
3807+
if (need_lock_index)
3808+
mysql_mutex_unlock(&LOCK_index);
3809+
return error;
37943810
}
37953811

37963812
/**
@@ -5133,22 +5149,21 @@ bool MYSQL_BIN_LOG::open_binlog(const char *log_name,
51335149
if (is_inited_purge_index_file())
51345150
purge_index_entry(NULL, NULL, need_lock_index);
51355151
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;
51415152
if (binlog_error_action == ABORT_SERVER)
51425153
{
51435154
exec_binlog_error_action_abort("Either disk is full or file system is read "
51445155
"only while opening the binlog. Aborting the"
51455156
" server.");
51465157
}
51475158
else
5159+
{
51485160
sql_print_error("Could not use %s for logging (error %d). "
51495161
"Turning logging off for the whole duration of the MySQL "
51505162
"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+
}
51525167
DBUG_RETURN(1);
51535168
}
51545169

@@ -5433,6 +5448,12 @@ int MYSQL_BIN_LOG::find_log_pos(LOG_INFO *linfo, const char *log_name,
54335448
else
54345449
mysql_mutex_assert_owner(&LOCK_index);
54355450

5451+
if (!my_b_inited(&index_file))
5452+
{
5453+
error= LOG_INFO_IO;
5454+
goto end;
5455+
}
5456+
54365457
// extend relative paths for log_name to be searched
54375458
if (log_name)
54385459
{
@@ -5524,6 +5545,11 @@ int MYSQL_BIN_LOG::find_next_log(LOG_INFO* linfo, bool need_lock_index)
55245545
else
55255546
mysql_mutex_assert_owner(&LOCK_index);
55265547

5548+
if (!my_b_inited(&index_file))
5549+
{
5550+
error= LOG_INFO_IO;
5551+
goto err;
5552+
}
55275553
/* As the file is flushed, we can't get an error here */
55285554
my_b_seek(&index_file, linfo->index_file_offset);
55295555

@@ -5632,7 +5658,8 @@ bool MYSQL_BIN_LOG::reset_logs(THD* thd, bool delete_only)
56325658
/* Save variables so that we can reopen the log */
56335659
save_name=name;
56345660
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*/);
56365663

56375664
/*
56385665
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)
56865713
}
56875714

56885715
/* 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*/);
56905719
if ((error= my_delete_allow_opened(index_file_name, MYF(0)))) // Reset (open will update)
56915720
{
56925721
if (my_errno() == ENOENT)
@@ -6843,7 +6872,9 @@ int MYSQL_BIN_LOG::new_file_impl(bool need_lock_log, Format_description_log_even
68436872

68446873
old_name=name;
68456874
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*/);
68476878

68486879
if (checksum_alg_reset != binary_log::BINLOG_CHECKSUM_ALG_UNDEF)
68496880
{
@@ -6907,7 +6938,6 @@ int MYSQL_BIN_LOG::new_file_impl(bool need_lock_log, Format_description_log_even
69076938
- switch server to protected/readonly mode
69086939
- ...
69096940
*/
6910-
close(LOG_CLOSE_INDEX);
69116941
if (binlog_error_action == ABORT_SERVER)
69126942
{
69136943
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
69216951
"again: fix the cause, shutdown the MySQL "
69226952
"server and restart it.",
69236953
new_name_ptr, errno);
6954+
close(LOG_CLOSE_INDEX, false /*need_lock_log=false*/,
6955+
false/*need_lock_index=false*/);
69246956
}
69256957

69266958
mysql_mutex_unlock(&LOCK_index);
69276959
if (need_lock_log)
69286960
mysql_mutex_unlock(&LOCK_log);
69296961

6962+
DEBUG_SYNC(current_thd, "after_disable_binlog");
69306963
DBUG_RETURN(error);
69316964
}
69326965

@@ -7891,10 +7924,16 @@ int MYSQL_BIN_LOG::wait_for_update_bin_log(const struct timespec *timeout)
78917924
The internal structures are not freed until cleanup() is called
78927925
*/
78937926

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)
78957929
{ // One can't set log_type here!
78967930
DBUG_ENTER("MYSQL_BIN_LOG::close");
78977931
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+
78987937
if (atomic_log_state == LOG_OPENED)
78997938
{
79007939
if ((exiting & LOG_CLOSE_STOP_EVENT) != 0)
@@ -7965,6 +8004,11 @@ void MYSQL_BIN_LOG::close(uint exiting)
79658004
called a not complete close earlier and the index file is still open.
79668005
*/
79678006

8007+
if (need_lock_index)
8008+
mysql_mutex_lock(&LOCK_index);
8009+
else
8010+
mysql_mutex_assert_owner(&LOCK_index);
8011+
79688012
if ((exiting & LOG_CLOSE_INDEX) && my_b_inited(&index_file))
79698013
{
79708014
end_io_cache(&index_file);
@@ -7976,10 +8020,18 @@ void MYSQL_BIN_LOG::close(uint exiting)
79768020
errno, my_strerror(errbuf, sizeof(errbuf), errno));
79778021
}
79788022
}
8023+
8024+
if (need_lock_index)
8025+
mysql_mutex_unlock(&LOCK_index);
8026+
79798027
atomic_log_state =
79808028
(exiting & LOG_CLOSE_TO_BE_OPENED) ? LOG_TO_BE_OPENED : LOG_CLOSED;
79818029
my_free(name);
79828030
name= NULL;
8031+
8032+
if (need_lock_log)
8033+
mysql_mutex_unlock(&LOCK_log);
8034+
79838035
DBUG_VOID_RETURN;
79848036
}
79858037

@@ -9033,7 +9085,8 @@ void MYSQL_BIN_LOG::handle_binlog_flush_or_sync_error(THD *thd,
90339085
"the cause, shutdown the MySQL server and restart it.",
90349086
errmsg);
90359087
}
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*/);
90379090
if (need_lock_log)
90389091
mysql_mutex_unlock(&LOCK_log);
90399092
DEBUG_SYNC(thd, "after_binlog_closed_due_to_error");

sql/binlog.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -938,7 +938,7 @@ class MYSQL_BIN_LOG: public TC_LOG
938938
int purge_index_entry(THD *thd, ulonglong *decrease_log_space,
939939
bool need_lock_index);
940940
bool reset_logs(THD* thd, bool delete_only= false);
941-
void close(uint exiting);
941+
void close(uint exiting, bool need_lock_log, bool need_lock_index);
942942

943943
// iterating through the log index file
944944
int find_log_pos(LOG_INFO* linfo, const char* log_name,

sql/rpl_binlog_sender.cc

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,7 @@ void Binlog_sender::run()
218218
IO_CACHE log_cache;
219219
my_off_t start_pos= m_start_pos;
220220
const char *log_file= m_linfo.log_file_name;
221+
bool is_index_file_reopened_on_binlog_disable= false;
221222

222223
init();
223224

@@ -252,9 +253,40 @@ void Binlog_sender::run()
252253

253254
THD_STAGE_INFO(m_thd,
254255
stage_finished_reading_one_binlog_switching_to_next_binlog);
255-
int error= mysql_bin_log.find_next_log(&m_linfo, 1);
256+
DBUG_EXECUTE_IF("waiting_for_disable_binlog",
257+
{
258+
const char act[]= "now "
259+
"signal dump_thread_reached_wait_point "
260+
"wait_for continue_dump_thread no_clear_event";
261+
DBUG_ASSERT(!debug_sync_set_action(m_thd,
262+
STRING_WITH_LEN(act)));
263+
};);
264+
mysql_bin_log.lock_index();
265+
if (!mysql_bin_log.is_open())
266+
{
267+
if (mysql_bin_log.open_index_file(mysql_bin_log.get_index_fname(),
268+
log_file, FALSE))
269+
{
270+
set_fatal_error("Binary log is not open and failed to open index file "
271+
"to retrieve next file.");
272+
mysql_bin_log.unlock_index();
273+
break;
274+
}
275+
is_index_file_reopened_on_binlog_disable= true;
276+
}
277+
int error= mysql_bin_log.find_next_log(&m_linfo, 0);
278+
mysql_bin_log.unlock_index();
256279
if (unlikely(error))
257280
{
281+
DBUG_EXECUTE_IF("waiting_for_disable_binlog",
282+
{
283+
const char act[]= "now signal consumed_binlog";
284+
DBUG_ASSERT(!debug_sync_set_action(m_thd,
285+
STRING_WITH_LEN(act)));
286+
};);
287+
if (is_index_file_reopened_on_binlog_disable)
288+
mysql_bin_log.close(LOG_CLOSE_INDEX, true/*need_lock_log=true*/,
289+
true/*need_lock_index=true*/);
258290
set_fatal_error("could not find next log");
259291
break;
260292
}

sql/rpl_rli.cc

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1356,7 +1356,9 @@ int Relay_log_info::purge_relay_logs(THD *thd, bool just_reset,
13561356
group_relay_log_pos,
13571357
false/*need_data_lock=false*/, errmsg, 0);
13581358
if (!inited && error_on_rli_init_info)
1359-
relay_log.close(LOG_CLOSE_INDEX | LOG_CLOSE_STOP_EVENT);
1359+
relay_log.close(LOG_CLOSE_INDEX | LOG_CLOSE_STOP_EVENT,
1360+
true/*need_lock_log=true*/,
1361+
true/*need_lock_index=true*/);
13601362
err:
13611363
#ifndef DBUG_OFF
13621364
char buf[22];
@@ -2106,7 +2108,9 @@ a file name for --relay-log-index option.", opt_relaylog_index_name);
21062108
error_on_rli_init_info= true;
21072109
if (msg)
21082110
sql_print_error("%s.", msg);
2109-
relay_log.close(LOG_CLOSE_INDEX | LOG_CLOSE_STOP_EVENT);
2111+
relay_log.close(LOG_CLOSE_INDEX | LOG_CLOSE_STOP_EVENT,
2112+
true/*need_lock_log=true*/,
2113+
true/*need_lock_index=true*/);
21102114
DBUG_RETURN(error);
21112115
}
21122116

@@ -2127,7 +2131,9 @@ void Relay_log_info::end_info()
21272131
cur_log_fd= -1;
21282132
}
21292133
inited = 0;
2130-
relay_log.close(LOG_CLOSE_INDEX | LOG_CLOSE_STOP_EVENT);
2134+
relay_log.close(LOG_CLOSE_INDEX | LOG_CLOSE_STOP_EVENT,
2135+
true/*need_lock_log=true*/,
2136+
true/*need_lock_index=true*/);
21312137
relay_log.harvest_bytes_written(&log_space_total);
21322138
/*
21332139
Delete the slave's temporary tables from memory.

0 commit comments

Comments
 (0)