diff options
author | Sujatha Sivakumar <sujatha.sivakumar@oracle.com> | 2017-02-28 10:00:51 +0530 |
---|---|---|
committer | Sujatha Sivakumar <sujatha.sivakumar@oracle.com> | 2017-02-28 10:00:51 +0530 |
commit | e619295e1b480a24ee9740641ce69b8a412e1fc9 (patch) | |
tree | e86823a435cc6d889968fb4dd2510155af812f89 /sql | |
parent | 9181a561a68d9b18331cc4c0a9b9fdc704edb300 (diff) | |
download | mariadb-git-e619295e1b480a24ee9740641ce69b8a412e1fc9.tar.gz |
Bug#24901077: RESET SLAVE ALL DOES NOT ALWAYS RESET SLAVE
Description:
============
If you have a relay log index file that has ended up with
some relay log files that do not exists, then RESET SLAVE
ALL is not enough to get back to a clean state.
Analysis:
=========
In the bug scenario slave server is in stopped state and
some of the relay logs got deleted but the relay log index
file is not updated.
During slave server restart replication initialization fails
as some of the required relay logs are missing. User
executes RESET SLAVE/RESET SLAVE ALL command to start a
clean slave. As per the documentation RESET SLAVE command
clears the master info and relay log info repositories,
deletes all the relay log files, and starts a new relay log
file. But in a scenario where the slave server's
Relay_log_info object is not initialized slave will not
purge the existing relay logs. Hence the index file still
remains in a bad state. Users will not be able to start
the slave unless these files are cleared.
Fix:
===
RESET SLAVE/RESET SLAVE ALL commands should do the cleanup
even in a scenario where Relay_log_info object
initialization failed.
Backported a flag named 'error_on_rli_init_info' which is
required to identify slave's Relay_log_info object
initialization failure. This flag exists in MySQL-5.6
onwards as part of BUG#14021292 fix.
During RESET SLAVE/RESET SLAVE ALL execution this flag
indicates the Relay_log_info initialization failure.
In such a case open the relay log index/relay log files
and do the required clean up.
Diffstat (limited to 'sql')
-rw-r--r-- | sql/rpl_mi.cc | 3 | ||||
-rw-r--r-- | sql/rpl_rli.cc | 50 | ||||
-rw-r--r-- | sql/rpl_rli.h | 11 | ||||
-rw-r--r-- | sql/slave.cc | 4 | ||||
-rw-r--r-- | sql/sql_repl.cc | 3 |
5 files changed, 56 insertions, 15 deletions
diff --git a/sql/rpl_mi.cc b/sql/rpl_mi.cc index ee5caced11a..a78b31cbaed 100644 --- a/sql/rpl_mi.cc +++ b/sql/rpl_mi.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2006, 2012, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2006, 2017, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -551,7 +551,6 @@ void end_master_info(Master_info* mi) if (!mi->inited) DBUG_VOID_RETURN; - end_relay_log_info(&mi->rli); if (mi->fd >= 0) { end_io_cache(&mi->file); diff --git a/sql/rpl_rli.cc b/sql/rpl_rli.cc index e4f2e4fd382..65ab264e1f3 100644 --- a/sql/rpl_rli.cc +++ b/sql/rpl_rli.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2006, 2017, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -41,7 +41,8 @@ Relay_log_info::Relay_log_info(bool is_slave_recovery) no_storage(FALSE), replicate_same_server_id(::replicate_same_server_id), info_fd(-1), cur_log_fd(-1), relay_log(&sync_relaylog_period), sync_counter(0), is_relay_log_recovery(is_slave_recovery), - save_temporary_tables(0), cur_log_old_open_count(0), group_relay_log_pos(0), + save_temporary_tables(0), cur_log_old_open_count(0), + error_on_rli_init_info(false), group_relay_log_pos(0), event_relay_log_pos(0), #if HAVE_purify is_fake(FALSE), @@ -108,7 +109,7 @@ int init_relay_log_info(Relay_log_info* rli, const char* info_fname) { char fname[FN_REFLEN+128]; - int info_fd; + int info_fd= -1; const char* msg = 0; int error = 0; DBUG_ENTER("init_relay_log_info"); @@ -118,6 +119,8 @@ int init_relay_log_info(Relay_log_info* rli, DBUG_RETURN(0); fn_format(fname, info_fname, mysql_data_home, "", 4+32); mysql_mutex_lock(&rli->data_lock); + if (rli->error_on_rli_init_info) + goto err; info_fd = rli->info_fd; rli->cur_log_fd = -1; rli->slave_skip_counter=0; @@ -351,11 +354,14 @@ Failed to open the existing relay log info file '%s' (errno %d)", goto err; } rli->inited= 1; + rli->error_on_rli_init_info= false; mysql_mutex_unlock(&rli->data_lock); DBUG_RETURN(error); err: - sql_print_error("%s", msg); + rli->error_on_rli_init_info= true; + if (msg) + sql_print_error("%s", msg); end_io_cache(&rli->info_file); if (info_fd >= 0) mysql_file_close(info_fd, MYF(0)); @@ -942,6 +948,8 @@ int purge_relay_logs(Relay_log_info* rli, THD *thd, bool just_reset, const char** errmsg) { int error=0; + const char *ln; + char name_buf[FN_REFLEN]; DBUG_ENTER("purge_relay_logs"); /* @@ -968,12 +976,34 @@ int purge_relay_logs(Relay_log_info* rli, THD *thd, bool just_reset, if (!rli->inited) { DBUG_PRINT("info", ("rli->inited == 0")); - DBUG_RETURN(0); - } - - DBUG_ASSERT(rli->slave_running == 0); - DBUG_ASSERT(rli->mi->slave_running == 0); + if (rli->error_on_rli_init_info) + { + ln= rli->relay_log.generate_name(opt_relay_logname, "-relay-bin", + 1, name_buf); + if (rli->relay_log.open_index_file(opt_relaylog_index_name, ln, TRUE)) + { + sql_print_error("Unable to purge relay log files. Failed to open relay " + "log index file:%s.", rli->relay_log.get_index_fname()); + DBUG_RETURN(1); + } + if (rli->relay_log.open(ln, LOG_BIN, 0, SEQ_READ_APPEND, 0, + (max_relay_log_size ? max_relay_log_size : + max_binlog_size), 1, TRUE)) + { + sql_print_error("Unable to purge relay log files. Failed to open relay " + "log file:%s.", rli->relay_log.get_log_fname()); + DBUG_RETURN(1); + } + } + else + DBUG_RETURN(0); + } + else + { + DBUG_ASSERT(rli->slave_running == 0); + DBUG_ASSERT(rli->mi->slave_running == 0); + } rli->slave_skip_counter=0; mysql_mutex_lock(&rli->data_lock); @@ -1013,6 +1043,8 @@ int purge_relay_logs(Relay_log_info* rli, THD *thd, bool just_reset, rli->group_relay_log_pos, 0 /* do not need data lock */, errmsg, 0); + if (!rli->inited && rli->error_on_rli_init_info) + rli->relay_log.close(LOG_CLOSE_INDEX | LOG_CLOSE_STOP_EVENT); err: #ifndef DBUG_OFF char buf[22]; diff --git a/sql/rpl_rli.h b/sql/rpl_rli.h index dceeec9e777..89865a9f55c 100644 --- a/sql/rpl_rli.h +++ b/sql/rpl_rli.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -153,7 +153,14 @@ public: a different log under our feet */ uint32 cur_log_old_open_count; - + + /* + If on init_info() call error_on_rli_init_info is true that means + that previous call to init_info() terminated with an error, RESET + SLAVE must be executed and the problem fixed manually. + */ + bool error_on_rli_init_info; + /* Let's call a group (of events) : - a transaction diff --git a/sql/slave.cc b/sql/slave.cc index acf68e231f3..1e641ac6d7e 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -881,6 +881,7 @@ void close_active_mi() if (active_mi) { end_master_info(active_mi); + end_relay_log_info(&active_mi->rli); delete active_mi; active_mi= 0; } @@ -4165,6 +4166,7 @@ void end_relay_log_info(Relay_log_info* rli) { DBUG_ENTER("end_relay_log_info"); + rli->error_on_rli_init_info= false; if (!rli->inited) DBUG_VOID_RETURN; if (rli->info_fd >= 0) diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index 8bbb8c52d95..ecbeff87a61 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -1313,6 +1313,7 @@ int reset_slave(THD *thd, Master_info* mi) // close master_info_file, relay_log_info_file, set mi->inited=rli->inited=0 end_master_info(mi); + end_relay_log_info(&mi->rli); // and delete these two files fn_format(fname, master_info_file, mysql_data_home, "", 4+32); if (mysql_file_stat(key_file_master_info, fname, &stat_area, MYF(0)) && |