Skip to content

Commit ac52536

Browse files
author
Sujatha Sivakumar
committed
Merge branch 'mysql-5.6' into mysql-5.7
2 parents f19e19e + 970e96b commit ac52536

File tree

4 files changed

+118
-29
lines changed

4 files changed

+118
-29
lines changed

sql/binlog.cc

Lines changed: 73 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3157,7 +3157,8 @@ void MYSQL_BIN_LOG::cleanup()
31573157
if (inited)
31583158
{
31593159
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*/);
31613162
mysql_mutex_destroy(&LOCK_log);
31623163
mysql_mutex_destroy(&LOCK_index);
31633164
mysql_mutex_destroy(&LOCK_commit);
@@ -3503,15 +3504,23 @@ bool MYSQL_BIN_LOG::open(
35033504
bool MYSQL_BIN_LOG::open_index_file(const char *index_file_name_arg,
35043505
const char *log_name, bool need_lock_index)
35053506
{
3507+
bool error= false;
35063508
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);
35083513

35093514
/*
35103515
First open of this class instance
35113516
Create an index file that will hold all file names uses for logging.
35123517
Add new entries to the end of it.
35133518
*/
35143519
myf opt= MY_UNPACK_FILENAME;
3520+
3521+
if (my_b_inited(&index_file))
3522+
goto end;
3523+
35153524
if (!index_file_name_arg)
35163525
{
35173526
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,
35233532
if (set_crash_safe_index_file_name(index_file_name_arg))
35243533
{
35253534
sql_print_error("MYSQL_BIN_LOG::set_crash_safe_index_file_name failed.");
3526-
return TRUE;
3535+
error= true;
3536+
goto end;
35273537
}
35283538

35293539
/*
@@ -3537,7 +3547,8 @@ bool MYSQL_BIN_LOG::open_index_file(const char *index_file_name_arg,
35373547
{
35383548
sql_print_error("MYSQL_BIN_LOG::open_index_file failed to "
35393549
"move crash_safe_index_file to index file.");
3540-
return TRUE;
3550+
error= true;
3551+
goto end;
35413552
}
35423553

35433554
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,
35603571
*/
35613572
if (index_file_nr >= 0)
35623573
mysql_file_close(index_file_nr, MYF(0));
3563-
return TRUE;
3574+
error= true;
3575+
goto end;
35643576
}
35653577

35663578
#ifdef HAVE_REPLICATION
@@ -3574,17 +3586,21 @@ bool MYSQL_BIN_LOG::open_index_file(const char *index_file_name_arg,
35743586

35753587
if (set_purge_index_file_name(index_file_name_arg) ||
35763588
open_purge_index_file(FALSE) ||
3577-
purge_index_entry(NULL, NULL, need_lock_index) ||
3589+
purge_index_entry(NULL, NULL, false) ||
35783590
close_purge_index_file() ||
35793591
DBUG_EVALUATE_IF("fault_injection_recovering_index", 1, 0))
35803592
{
35813593
sql_print_error("MYSQL_BIN_LOG::open_index_file failed to sync the index "
35823594
"file.");
3583-
return TRUE;
3595+
error= true;
3596+
goto end;
35843597
}
35853598
#endif
35863599

3587-
return FALSE;
3600+
end:
3601+
if (need_lock_index)
3602+
mysql_mutex_unlock(&LOCK_index);
3603+
return error;
35883604
}
35893605

35903606
/**
@@ -4939,22 +4955,21 @@ bool MYSQL_BIN_LOG::open_binlog(const char *log_name,
49394955
purge_index_entry(NULL, NULL, need_lock_index);
49404956
close_purge_index_file();
49414957
#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);
49474958
if (binlog_error_action == ABORT_SERVER)
49484959
{
49494960
exec_binlog_error_action_abort("Either disk is full or file system is read "
49504961
"only while opening the binlog. Aborting the"
49514962
" server.");
49524963
}
49534964
else
4965+
{
49544966
sql_print_error("Could not use %s for logging (error %d). "
49554967
"Turning logging off for the whole duration of the MySQL "
49564968
"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+
}
49584973
DBUG_RETURN(1);
49594974
}
49604975

@@ -5239,6 +5254,12 @@ int MYSQL_BIN_LOG::find_log_pos(LOG_INFO *linfo, const char *log_name,
52395254
else
52405255
mysql_mutex_assert_owner(&LOCK_index);
52415256

5257+
if (!my_b_inited(&index_file))
5258+
{
5259+
error= LOG_INFO_IO;
5260+
goto end;
5261+
}
5262+
52425263
// extend relative paths for log_name to be searched
52435264
if (log_name)
52445265
{
@@ -5330,6 +5351,11 @@ int MYSQL_BIN_LOG::find_next_log(LOG_INFO* linfo, bool need_lock_index)
53305351
else
53315352
mysql_mutex_assert_owner(&LOCK_index);
53325353

5354+
if (!my_b_inited(&index_file))
5355+
{
5356+
error= LOG_INFO_IO;
5357+
goto err;
5358+
}
53335359
/* As the file is flushed, we can't get an error here */
53345360
my_b_seek(&index_file, linfo->index_file_offset);
53355361

@@ -5436,7 +5462,8 @@ bool MYSQL_BIN_LOG::reset_logs(THD* thd, bool delete_only)
54365462
/* Save variables so that we can reopen the log */
54375463
save_name=name;
54385464
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*/);
54405467

54415468
/*
54425469
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)
54895516
}
54905517

54915518
/* 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*/);
54935522
if ((error= my_delete_allow_opened(index_file_name, MYF(0)))) // Reset (open will update)
54945523
{
54955524
if (my_errno() == ENOENT)
@@ -6643,7 +6672,9 @@ int MYSQL_BIN_LOG::new_file_impl(bool need_lock_log, Format_description_log_even
66436672

66446673
old_name=name;
66456674
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*/);
66476678

66486679
if (checksum_alg_reset != binary_log::BINLOG_CHECKSUM_ALG_UNDEF)
66496680
{
@@ -6706,7 +6737,6 @@ int MYSQL_BIN_LOG::new_file_impl(bool need_lock_log, Format_description_log_even
67066737
- switch server to protected/readonly mode
67076738
- ...
67086739
*/
6709-
close(LOG_CLOSE_INDEX);
67106740
if (binlog_error_action == ABORT_SERVER)
67116741
{
67126742
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
67206750
"again: fix the cause, shutdown the MySQL "
67216751
"server and restart it.",
67226752
new_name_ptr, errno);
6753+
close(LOG_CLOSE_INDEX, false /*need_lock_log=false*/,
6754+
false/*need_lock_index=false*/);
67236755
}
67246756

67256757
mysql_mutex_unlock(&LOCK_index);
67266758
if (need_lock_log)
67276759
mysql_mutex_unlock(&LOCK_log);
6728-
6760+
DEBUG_SYNC(current_thd, "after_disable_binlog");
67296761
DBUG_RETURN(error);
67306762
}
67316763

@@ -7699,10 +7731,16 @@ int MYSQL_BIN_LOG::wait_for_update_bin_log(THD* thd,
76997731
The internal structures are not freed until cleanup() is called
77007732
*/
77017733

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)
77037736
{ // One can't set log_type here!
77047737
DBUG_ENTER("MYSQL_BIN_LOG::close");
77057738
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+
77067744
if (log_state.atomic_get() == LOG_OPENED)
77077745
{
77087746
#ifdef HAVE_REPLICATION
@@ -7774,6 +7812,11 @@ void MYSQL_BIN_LOG::close(uint exiting)
77747812
called a not complete close earlier and the index file is still open.
77757813
*/
77767814

7815+
if (need_lock_index)
7816+
mysql_mutex_lock(&LOCK_index);
7817+
else
7818+
mysql_mutex_assert_owner(&LOCK_index);
7819+
77777820
if ((exiting & LOG_CLOSE_INDEX) && my_b_inited(&index_file))
77787821
{
77797822
end_io_cache(&index_file);
@@ -7785,9 +7828,17 @@ void MYSQL_BIN_LOG::close(uint exiting)
77857828
errno, my_strerror(errbuf, sizeof(errbuf), errno));
77867829
}
77877830
}
7831+
7832+
if (need_lock_index)
7833+
mysql_mutex_unlock(&LOCK_index);
7834+
77887835
log_state.atomic_set((exiting & LOG_CLOSE_TO_BE_OPENED) ? LOG_TO_BE_OPENED : LOG_CLOSED);
77897836
my_free(name);
77907837
name= NULL;
7838+
7839+
if (need_lock_log)
7840+
mysql_mutex_unlock(&LOCK_log);
7841+
77917842
DBUG_VOID_RETURN;
77927843
}
77937844

@@ -8844,7 +8895,8 @@ void MYSQL_BIN_LOG::handle_binlog_flush_or_sync_error(THD *thd,
88448895
"the cause, shutdown the MySQL server and restart it.",
88458896
errmsg);
88468897
}
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*/);
88488900
if (need_lock_log)
88498901
mysql_mutex_unlock(&LOCK_log);
88508902
DEBUG_SYNC(thd, "after_binlog_closed_due_to_error");

sql/binlog.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#ifndef BINLOG_H_INCLUDED
2-
/* Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved.
2+
/* Copyright (c) 2010, 2017, Oracle and/or its affiliates. All rights reserved.
33
44
This program is free software; you can redistribute it and/or modify
55
it under the terms of the GNU General Public License as published by
@@ -899,7 +899,7 @@ class MYSQL_BIN_LOG: public TC_LOG
899899
int purge_index_entry(THD *thd, ulonglong *decrease_log_space,
900900
bool need_lock_index);
901901
bool reset_logs(THD* thd, bool delete_only= false);
902-
void close(uint exiting);
902+
void close(uint exiting, bool need_lock_log, bool need_lock_index);
903903

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

sql/rpl_binlog_sender.cc

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
1+
/* Copyright (c) 2013, 2017, 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
@@ -196,7 +196,7 @@ void Binlog_sender::run()
196196
IO_CACHE log_cache;
197197
my_off_t start_pos= m_start_pos;
198198
const char *log_file= m_linfo.log_file_name;
199-
199+
bool is_index_file_reopened_on_binlog_disable= false;
200200
init();
201201

202202
while (!has_error() && !m_thd->killed)
@@ -230,9 +230,40 @@ void Binlog_sender::run()
230230

231231
THD_STAGE_INFO(m_thd,
232232
stage_finished_reading_one_binlog_switching_to_next_binlog);
233-
int error= mysql_bin_log.find_next_log(&m_linfo, 1);
233+
DBUG_EXECUTE_IF("waiting_for_disable_binlog",
234+
{
235+
const char act[]= "now "
236+
"signal dump_thread_reached_wait_point "
237+
"wait_for continue_dump_thread no_clear_event";
238+
DBUG_ASSERT(!debug_sync_set_action(current_thd,
239+
STRING_WITH_LEN(act)));
240+
};);
241+
mysql_bin_log.lock_index();
242+
if (!mysql_bin_log.is_open())
243+
{
244+
if (mysql_bin_log.open_index_file(mysql_bin_log.get_index_fname(),
245+
log_file, FALSE))
246+
{
247+
set_fatal_error("Binary log is not open and failed to open index file "
248+
"to retrieve next file.");
249+
mysql_bin_log.unlock_index();
250+
break;
251+
}
252+
is_index_file_reopened_on_binlog_disable= true;
253+
}
254+
int error= mysql_bin_log.find_next_log(&m_linfo, 0);
255+
mysql_bin_log.unlock_index();
234256
if (unlikely(error))
235257
{
258+
DBUG_EXECUTE_IF("waiting_for_disable_binlog",
259+
{
260+
const char act[]= "now signal consumed_binlog";
261+
DBUG_ASSERT(!debug_sync_set_action(current_thd,
262+
STRING_WITH_LEN(act)));
263+
};);
264+
if (is_index_file_reopened_on_binlog_disable)
265+
mysql_bin_log.close(LOG_CLOSE_INDEX, true/*need_lock_log=true*/,
266+
true/*need_lock_index=true*/);
236267
set_fatal_error("could not find next log");
237268
break;
238269
}

sql/rpl_rli.cc

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1346,7 +1346,9 @@ int Relay_log_info::purge_relay_logs(THD *thd, bool just_reset,
13461346
group_relay_log_pos,
13471347
false/*need_data_lock=false*/, errmsg, 0);
13481348
if (!inited && error_on_rli_init_info)
1349-
relay_log.close(LOG_CLOSE_INDEX | LOG_CLOSE_STOP_EVENT);
1349+
relay_log.close(LOG_CLOSE_INDEX | LOG_CLOSE_STOP_EVENT,
1350+
true/*need_lock_log=true*/,
1351+
true/*need_lock_index=true*/);
13501352
err:
13511353
#ifndef DBUG_OFF
13521354
char buf[22];
@@ -2355,7 +2357,9 @@ a file name for --relay-log-index option.", opt_relaylog_index_name);
23552357
error_on_rli_init_info= true;
23562358
if (msg)
23572359
sql_print_error("%s.", msg);
2358-
relay_log.close(LOG_CLOSE_INDEX | LOG_CLOSE_STOP_EVENT);
2360+
relay_log.close(LOG_CLOSE_INDEX | LOG_CLOSE_STOP_EVENT,
2361+
true/*need_lock_log=true*/,
2362+
true/*need_lock_index=true*/);
23592363
DBUG_RETURN(error);
23602364
}
23612365

@@ -2376,7 +2380,9 @@ void Relay_log_info::end_info()
23762380
cur_log_fd= -1;
23772381
}
23782382
inited = 0;
2379-
relay_log.close(LOG_CLOSE_INDEX | LOG_CLOSE_STOP_EVENT);
2383+
relay_log.close(LOG_CLOSE_INDEX | LOG_CLOSE_STOP_EVENT,
2384+
true/*need_lock_log=true*/,
2385+
true/*need_lock_index=true*/);
23802386
relay_log.harvest_bytes_written(&log_space_total);
23812387
/*
23822388
Delete the slave's temporary tables from memory.

0 commit comments

Comments
 (0)