summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorSujatha Sivakumar <sujatha.sivakumar@oracle.com>2017-02-28 10:00:51 +0530
committerSujatha Sivakumar <sujatha.sivakumar@oracle.com>2017-02-28 10:00:51 +0530
commite619295e1b480a24ee9740641ce69b8a412e1fc9 (patch)
treee86823a435cc6d889968fb4dd2510155af812f89 /sql
parent9181a561a68d9b18331cc4c0a9b9fdc704edb300 (diff)
downloadmariadb-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.cc3
-rw-r--r--sql/rpl_rli.cc50
-rw-r--r--sql/rpl_rli.h11
-rw-r--r--sql/slave.cc4
-rw-r--r--sql/sql_repl.cc3
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)) &&