Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions mysql-test/suite/rpl/r/rpl_change_master_long_channel_name.result
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
include/master-slave.inc
[connection master]
connection slave;
CHANGE MASTER TO MASTER_DELAY=1 FOR CHANNEL '################################################';
ERROR HY000: Can't open file: 'slave-relay-bin-@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@0023@002' (errno: 36 "File name too long")
connection master;
CREATE TABLE t1 (a INT);
INSERT INTO t1 VALUES (1);
connection slave;
connection slave;
include/diff_tables.inc [master:t1, slave:t1]
CHANGE MASTER 'new_channel' TO MASTER_HOST='127.0.0.1', MASTER_PORT=1, MASTER_USER='root';
RESET SLAVE 'new_channel' ALL;
connection master;
DROP TABLE t1;
connection slave;
include/rpl_end.inc
41 changes: 41 additions & 0 deletions mysql-test/suite/rpl/t/rpl_change_master_long_channel_name.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#
# CHANGE MASTER ... FOR CHANNEL with a name that overflows the relay
# log file name once escaped should return an error, not crash.
#
# STEPS:
# 1. Issue CHANGE MASTER ... FOR CHANNEL with a channel name that is
# within MAX_CONNECTION_NAME, but expands past the file name
# limit once escaped into the relay log file name.
# 2. Verify the statement fails with a clean error, not a crash.
# 3. Verify the server is still usable: a normal CHANGE MASTER for a
# new, short-named channel succeeds.
#
--source include/master-slave.inc

--connection slave
--let $channel= `SELECT REPEAT('#', 48)`
--error ER_CANT_OPEN_FILE
eval CHANGE MASTER TO MASTER_DELAY=1 FOR CHANNEL '$channel';

--connection master
CREATE TABLE t1 (a INT);
INSERT INTO t1 VALUES (1);
--sync_slave_with_master

--connection slave
--let $diff_tables= master:t1, slave:t1
--source include/diff_tables.inc

CHANGE MASTER 'new_channel' TO MASTER_HOST='127.0.0.1', MASTER_PORT=1, MASTER_USER='root';
RESET SLAVE 'new_channel' ALL;

--disable_query_log
call mtr.add_suppression("Failed when trying to open logs");
call mtr.add_suppression("Failed to locate old binlog or relay log files");
--enable_query_log

--connection master
DROP TABLE t1;
--sync_slave_with_master

--source include/rpl_end.inc
17 changes: 12 additions & 5 deletions sql/log.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3871,15 +3871,15 @@ bool MYSQL_BIN_LOG::open_index_file(const char *index_file_name_arg,
Create an index file that will hold all file names uses for logging.
Add new entries to the end of it.
*/
myf opt= MY_UNPACK_FILENAME;
myf opt= MY_UNPACK_FILENAME | MY_SAFE_PATH;
if (!index_file_name_arg)
{
index_file_name_arg= log_name; // Use same basename for index file
opt= MY_UNPACK_FILENAME | MY_REPLACE_EXT;
opt= MY_UNPACK_FILENAME | MY_REPLACE_EXT | MY_SAFE_PATH;
}
fn_format(index_file_name, index_file_name_arg, mysql_data_home,
".index", opt);
if ((index_file_nr= mysql_file_open(m_key_file_log_index,
if (!fn_format(index_file_name, index_file_name_arg, mysql_data_home,
".index", opt) ||
(index_file_nr= mysql_file_open(m_key_file_log_index,
index_file_name,
O_RDWR | O_CREAT | O_BINARY | O_CLOEXEC,
MYF(MY_WME))) < 0 ||
Expand Down Expand Up @@ -4475,6 +4475,13 @@ int MYSQL_BIN_LOG::find_log_pos(LOG_INFO *linfo, const char *log_name,
DBUG_PRINT("enter", ("log_name: %s, full_log_name: %s",
log_name ? log_name : "NULL", full_log_name));

/* index_file is not open if the log/index file failed to be created */
if (!my_b_inited(&index_file))
{
error= LOG_INFO_EOF;
goto end;
}

/* As the file is flushed, we can't get an error here */
(void) reinit_io_cache(&index_file, READ_CACHE, (my_off_t) 0, 0, 0);

Expand Down
1 change: 1 addition & 0 deletions sql/rpl_rli.cc
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,7 @@ a file name for --relay-log-index option", opt_relaylog_index_name);
{
mysql_mutex_unlock(log_lock);
mysql_mutex_unlock(&data_lock);
my_error(ER_CANT_OPEN_FILE, MYF(0), ln, my_errno);
sql_print_error("Failed when trying to open logs for '%s' in Relay_log_info::init(). Error: %M", ln, my_errno);
DBUG_RETURN(1);
}
Expand Down
13 changes: 9 additions & 4 deletions sql/sql_repl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3487,7 +3487,9 @@ int start_slave(THD* thd , Master_info* mi, bool net_report)

if (slave_errno)
{
if (net_report)
/* A more specific error may already have been raised (e.g. by
Relay_log_info::init() when it fails to open the relay log). */
if (net_report && !thd->is_error())
my_error(slave_errno, MYF(0),
(int) mi->connection_name.length,
mi->connection_name.str);
Expand Down Expand Up @@ -3921,9 +3923,12 @@ bool change_master(THD* thd, Master_info* mi, bool *master_info_added)
if (init_master_info(mi, master_info_file_tmp, relay_log_info_file_tmp, 0,
thread_mask))
{
my_error(ER_MASTER_INFO, MYF(0),
(int) lex_mi->connection_name.length,
lex_mi->connection_name.str);
/* A more specific error may already have been raised (e.g. by
Relay_log_info::init() when it fails to open the relay log). */
if (!thd->is_error())
my_error(ER_MASTER_INFO, MYF(0),
(int) lex_mi->connection_name.length,
lex_mi->connection_name.str);
ret= TRUE;
goto err;
}
Expand Down