summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMonty <monty@mariadb.org>2021-08-24 00:38:30 +0300
committerMonty <monty@mariadb.org>2021-09-14 13:43:50 +0300
commit4ebaa80f0b26de814e8de27b8ea2188038b7d0f2 (patch)
tree9d5ed6903bdb6e1f8f67ef20af81eec2d3566e23
parent0629711db43ec489a360d8f689b72fac66a2470b (diff)
downloadmariadb-git-4ebaa80f0b26de814e8de27b8ea2188038b7d0f2.tar.gz
Failed change master could leave around old relay log files
The reason was that there where no cleanup after a failed 'change master'. Fixed by doing a cleanup of created relay log files in remove_master_info()
-rw-r--r--mysql-test/suite/multi_source/change_master.result8
-rw-r--r--mysql-test/suite/multi_source/change_master.test13
-rw-r--r--sql/rpl_mi.cc23
-rw-r--r--sql/rpl_mi.h2
-rw-r--r--sql/sql_parse.cc2
-rw-r--r--sql/sql_reload.cc2
6 files changed, 46 insertions, 4 deletions
diff --git a/mysql-test/suite/multi_source/change_master.result b/mysql-test/suite/multi_source/change_master.result
new file mode 100644
index 00000000000..9fd84e51364
--- /dev/null
+++ b/mysql-test/suite/multi_source/change_master.result
@@ -0,0 +1,8 @@
+RESET MASTER;
+connect slave,127.0.0.1,root,,,$SERVER_MYPORT_3;
+change master 'abc1' to relay_log_file='';
+ERROR HY000: Failed initializing relay log position: Could not find target log during relay log initialization
+change master 'abc1' to relay_log_file='';
+ERROR HY000: Failed initializing relay log position: Could not find target log during relay log initialization
+disconnect slave;
+connection default;
diff --git a/mysql-test/suite/multi_source/change_master.test b/mysql-test/suite/multi_source/change_master.test
new file mode 100644
index 00000000000..08e6909694f
--- /dev/null
+++ b/mysql-test/suite/multi_source/change_master.test
@@ -0,0 +1,13 @@
+--source include/not_embedded.inc
+
+RESET MASTER;
+
+--connect (slave,127.0.0.1,root,,,$SERVER_MYPORT_3)
+
+--error ER_RELAY_LOG_INIT
+change master 'abc1' to relay_log_file='';
+--error ER_RELAY_LOG_INIT
+change master 'abc1' to relay_log_file='';
+--disconnect slave
+--connection default
+
diff --git a/sql/rpl_mi.cc b/sql/rpl_mi.cc
index 84c3109c136..da192df7aa7 100644
--- a/sql/rpl_mi.cc
+++ b/sql/rpl_mi.cc
@@ -1453,11 +1453,32 @@ bool Master_info_index::add_master_info(Master_info *mi, bool write_to_file)
atomic
*/
-bool Master_info_index::remove_master_info(Master_info *mi)
+bool Master_info_index::remove_master_info(Master_info *mi, bool clear_log_files)
{
+ char tmp_name[FN_REFLEN];
DBUG_ENTER("remove_master_info");
mysql_mutex_assert_owner(&LOCK_active_mi);
+ if (clear_log_files)
+ {
+ /* This code is only executed when change_master() failes to create a new master info */
+
+ // Delete any temporary relay log files that could have been created by change_master()
+ mi->rli.relay_log.reset_logs(current_thd, 0, (rpl_gtid*) 0, 0, 0);
+ /* Delete master-'connection'.info */
+ create_logfile_name_with_suffix(tmp_name,
+ sizeof(tmp_name),
+ master_info_file, 0,
+ &mi->cmp_connection_name);
+ my_delete(tmp_name, MYF(0));
+ /* Delete relay-log-'connection'.info */
+ create_logfile_name_with_suffix(tmp_name,
+ sizeof(tmp_name),
+ relay_log_info_file, 0,
+ &mi->cmp_connection_name);
+ my_delete(tmp_name, MYF(0));
+ }
+
// Delete Master_info and rewrite others to file
if (!my_hash_delete(&master_info_hash, (uchar*) mi))
{
diff --git a/sql/rpl_mi.h b/sql/rpl_mi.h
index 0d6e959838f..d2232ac2664 100644
--- a/sql/rpl_mi.h
+++ b/sql/rpl_mi.h
@@ -385,7 +385,7 @@ public:
bool check_duplicate_master_info(LEX_CSTRING *connection_name,
const char *host, uint port);
bool add_master_info(Master_info *mi, bool write_to_file);
- bool remove_master_info(Master_info *mi);
+ bool remove_master_info(Master_info *mi, bool clear_log_files);
Master_info *get_master_info(const LEX_CSTRING *connection_name,
Sql_condition::enum_warning_level warning);
bool start_all_slaves(THD *thd);
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index d5d061b1242..b42868e7255 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -4137,7 +4137,7 @@ mysql_execute_command(THD *thd, bool is_called_from_prepared_stmt)
If new master was not added, we still need to free mi.
*/
if (master_info_added)
- master_info_index->remove_master_info(mi);
+ master_info_index->remove_master_info(mi, 1);
else
delete mi;
}
diff --git a/sql/sql_reload.cc b/sql/sql_reload.cc
index ddada6ad892..1dfa238de50 100644
--- a/sql/sql_reload.cc
+++ b/sql/sql_reload.cc
@@ -403,7 +403,7 @@ bool reload_acl_and_cache(THD *thd, unsigned long long options,
/* If not default connection and 'all' is used */
mi->release();
mysql_mutex_lock(&LOCK_active_mi);
- if (master_info_index->remove_master_info(mi))
+ if (master_info_index->remove_master_info(mi, 0))
result= 1;
mysql_mutex_unlock(&LOCK_active_mi);
}