Skip to content

Commit

Permalink
Failed change master could leave around old relay log files
Browse files Browse the repository at this point in the history
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()
  • Loading branch information
montywi committed Sep 14, 2021
1 parent 0629711 commit 4ebaa80
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 4 deletions.
8 changes: 8 additions & 0 deletions 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;
13 changes: 13 additions & 0 deletions 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

23 changes: 22 additions & 1 deletion sql/rpl_mi.cc
Expand Up @@ -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))
{
Expand Down
2 changes: 1 addition & 1 deletion sql/rpl_mi.h
Expand Up @@ -385,7 +385,7 @@ class Master_info_index
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);
Expand Down
2 changes: 1 addition & 1 deletion sql/sql_parse.cc
Expand Up @@ -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;
}
Expand Down
2 changes: 1 addition & 1 deletion sql/sql_reload.cc
Expand Up @@ -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);
}
Expand Down

0 comments on commit 4ebaa80

Please sign in to comment.