#At file:///media/sdb2/hezx/work/mysql/bzr/b12133/trunk/ based on revid:mattias.jonsson@stripped
3481 He Zhenxing 2011-01-26
BUG#12133 master.index file keeps mysqld from starting if bin log has been moved
Absolute path or relative path to the data directory was recorded
in the binlog or relay log index files, which caused the server
unable to locate the log files and failed to start when user moved
the binlog or relay log files to another directory and restart the
server with binlog or relay log option set to the new path.
Fixed the problem by only record the basename in the binlog or relay
log index files, and use the directory of the binlog or relay log
option to calculate the path to access the log files.
When reading an index file that was generated by a server before
the fix, the directory part will be stripped before calculating
the path.
@ mysql-test/include/begin_include_file.inc
Add $keep_silent to suppress the output of the include line.
@ mysql-test/include/setup_fake_relay_log.inc
After fix of BUG#12133, there is no need to prepend ./ or .\ for
filenames in the binlog or relay log index file.
@ mysql-test/suite/rpl/t/rpl_manual_change_index_file.test
After fix of BUG#12133, there is no need to prepend ./ or .\ for
filenames in the binlog or relay log index file.
added:
mysql-test/suite/rpl/r/rpl_binlog_index.result
mysql-test/suite/rpl/t/rpl_binlog_index.test
modified:
mysql-test/include/begin_include_file.inc
mysql-test/include/setup_fake_relay_log.inc
mysql-test/suite/rpl/t/rpl_manual_change_index_file.test
sql/binlog.cc
sql/binlog.h
sql/rpl_master.cc
sql/rpl_rli.cc
sql/rpl_slave.cc
=== modified file 'mysql-test/include/begin_include_file.inc'
--- a/mysql-test/include/begin_include_file.inc 2010-12-19 17:15:12 +0000
+++ b/mysql-test/include/begin_include_file.inc 2011-01-26 07:55:10 +0000
@@ -48,6 +48,9 @@
# must be provided both for begin_include_file.inc and
# end_include_file.inc.
#
+# $keep_silent
+# Keep silent, do not print the include line;
+#
# $rpl_debug
# If set, this script will print the following text:
# ==== BEGIN include/$include_filename.inc ====
@@ -59,8 +62,11 @@
# recursively.
if (!$_include_file_depth)
{
- --echo include/$include_filename
- --let $_include_file_depth= 0
+ if (!$keep_silent)
+ {
+ --echo include/$include_filename
+ }
+ --let $_include_file_depth= 0
}
--inc $_include_file_depth
if ($rpl_debug)
=== modified file 'mysql-test/include/setup_fake_relay_log.inc'
--- a/mysql-test/include/setup_fake_relay_log.inc 2010-12-19 17:22:30 +0000
+++ b/mysql-test/include/setup_fake_relay_log.inc 2011-01-26 07:55:10 +0000
@@ -80,19 +80,7 @@ RESET SLAVE;
# Create relay log index.
-# After patch for BUG#12190, the filename used in CHANGE MASTER
-# RELAY_LOG_FILE will be automatically added the directory of the
-# relay log before comparison, thus we need to added the directory
-# part (./ on unix .\ on windows) when faking the relay-log-bin.index.
-
-# mysqltest currently parses backslash escapes wrong, so any sequence
-# of N backslashes is collapsed to just one backslash. So we use the
-# SQL function CHAR() to generate a backslash character instead. Since
-# the string is interpreted in SQL context, we to escape it, so we use
-# two backslashes.
-
---let $_fake_dir= `select IF(convert(@@version_compile_os using latin1) IN ("Win32","Win64","Windows"), CONCAT('.', CHAR(92), CHAR(92)), './')`
---let $write_var= $_fake_dir$_fake_filename-fake.000001\n
+--let $write_var= $_fake_filename-fake.000001\n
--let $write_to_file= $_fake_relay_index
--source include/write_var_to_file.inc
=== added file 'mysql-test/suite/rpl/r/rpl_binlog_index.result'
--- a/mysql-test/suite/rpl/r/rpl_binlog_index.result 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/r/rpl_binlog_index.result 2011-01-26 07:55:10 +0000
@@ -0,0 +1,24 @@
+include/master-slave.inc
+[connection master]
+CREATE TABLE t1 (a INT);
+FLUSH BINARY LOGS;
+INSERT INTO t1 VALUES (1);
+# Shutdown master
+include/rpl_stop_server.inc [server_number=1]
+# Move the master binlog files and the index file to a new place
+# Restart master with log-bin option set to the new path
+# Master has restarted successfully
+# Create the master-bin.index file with the old format
+# Shutdown master
+include/rpl_stop_server.inc [server_number=1]
+# Move back the master binlog files
+# Remove the unneeded master-bin.index file
+# Restart master with log-bin option set to default
+# Master has restarted successfully
+# Move the slave binlog and relay log files and index to the new place
+# Shutdown slave
+include/rpl_stop_server.inc [server_number=2]
+# Restart slave with options log-bin, relay-log set to the new paths
+# Slave has restarted successfully
+INSERT INTO t1 VALUES (2);
+DROP TABLE t1;
=== added file 'mysql-test/suite/rpl/t/rpl_binlog_index.test'
--- a/mysql-test/suite/rpl/t/rpl_binlog_index.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_binlog_index.test 2011-01-26 07:55:10 +0000
@@ -0,0 +1,146 @@
+# ==== Purpose ====
+#
+# Test that server can work fine after moving binlog or relay log
+# files to another directory and setting binlog or relay log paths to
+# the new path.
+#
+# ==== Method ====
+#
+# Start replication, and then shutdown the master, move the binary
+# logs and the log index file to a another directory and then restart
+# the server with option to set the new binlog directory. After master
+# restarted successfully, do the similar on slave to check the relay
+# log of slave.
+#
+# ==== Reference ====
+#
+# BUG#12133 master.index file keeps mysqld from starting if bin log has been moved
+# BUG#42576 Relay logs in relay-log.info&localhost-relay-bin.index not processed after move
+
+source include/master-slave.inc;
+# There is no need to run this test case on all binlog format
+source include/have_binlog_format_row.inc;
+
+connection master;
+--let $master_datadir= `select @@datadir`
+connection slave;
+--let $slave_datadir= `select @@datadir`
+connection master;
+--let $tmpdir= $MYSQLTEST_VARDIR/tmp/rpl_binlog_index
+--mkdir $tmpdir
+
+CREATE TABLE t1 (a INT);
+# flush to generate one more binlog file.
+FLUSH BINARY LOGS;
+INSERT INTO t1 VALUES (1);
+
+sync_slave_with_master;
+
+# Tell include/rpl_start_server.inc not show the include line, which
+# may include pathnames that can vary.
+--let $keep_silent=1
+
+#
+# Test on master
+#
+connection master;
+--echo # Shutdown master
+--let $rpl_server_number=1
+source include/rpl_stop_server.inc;
+
+--echo # Move the master binlog files and the index file to a new place
+--move_file $master_datadir/master-bin.000001 $tmpdir/master-bin.000001
+--move_file $master_datadir/master-bin.000002 $tmpdir/master-bin.000002
+--move_file $master_datadir/master-bin.index $tmpdir/master-bin.index
+
+--echo # Restart master with log-bin option set to the new path
+--let $rpl_server_parameters=--log-bin=$tmpdir/master-bin
+source include/rpl_start_server.inc;
+
+--echo # Master has restarted successfully
+
+#
+# Test master can handle old format with directory path in index file
+#
+--let $is_windows= `select convert(@@version_compile_os using latin1) in ('Win32', 'Win64', 'Windows')`
+
+# write_var_to_file.inc will call SELECT INTO DUMPFIE, which has to be
+# done before shutdown the server
+--echo # Create the master-bin.index file with the old format
+--let $write_to_file= $master_datadir/master-bin.index
+if ($is_windows)
+{
+ --let $write_var= .\\master-bin.000001\n.\\master-bin.000002\n
+}
+if (!$is_windows)
+{
+ --let $write_var= ./master-bin.000001\n./master-bin.000002\n
+}
+--disable_query_log
+source include/write_var_to_file.inc;
+--enable_query_log
+
+--echo # Shutdown master
+--let $rpl_server_number=1
+source include/rpl_stop_server.inc;
+
+--echo # Move back the master binlog files
+--move_file $tmpdir/master-bin.000001 $master_datadir/master-bin.000001
+--move_file $tmpdir/master-bin.000002 $master_datadir/master-bin.000002
+
+--echo # Remove the unneeded master-bin.index file
+--remove_file $tmpdir/master-bin.index
+
+--echo # Restart master with log-bin option set to default
+--let $rpl_server_parameters=--log-bin=$master_datadir/master-bin
+source include/rpl_start_server.inc;
+
+--echo # Master has restarted successfully
+
+connection slave;
+source include/stop_slave.inc;
+
+--disable_query_log
+# slave-relay-bin.* files can vary, so read the slave-relay-bin.index
+# to figure out the slave-relay-bin.* files
+CREATE TEMPORARY TABLE tmp (id INT AUTO_INCREMENT PRIMARY KEY, filename VARCHAR(1024));
+# chmod to allow the following LOAD DATA
+--chmod 0666 $slave_datadir/slave-relay-bin.index
+--eval LOAD DATA INFILE '$slave_datadir/slave-relay-bin.index' INTO TABLE tmp (filename)
+--let $count= `SELECT count(*) FROM tmp`
+--echo # Move the slave binlog and relay log files and index to the new place
+--move_file $slave_datadir/slave-bin.index $tmpdir/slave-bin.index
+--move_file $slave_datadir/slave-bin.000001 $tmpdir/slave-bin.000001
+--move_file $slave_datadir/slave-relay-bin.index $tmpdir/slave-relay-bin.index
+while ($count)
+{
+ --let $filename= `select filename from tmp where id=$count`
+ --move_file $slave_datadir/$filename $tmpdir/$filename
+ --dec $count
+}
+DROP TEMPORARY TABLE tmp;
+--enable_query_log
+
+--echo # Shutdown slave
+--let $rpl_server_number=2
+source include/rpl_stop_server.inc;
+
+--echo # Restart slave with options log-bin, relay-log set to the new paths
+--let $rpl_server_parameters=--log-bin=$tmpdir/slave-bin --relay-log=$tmpdir/slave-relay-bin
+source include/rpl_start_server.inc;
+
+--echo # Slave has restarted successfully
+source include/start_slave.inc;
+
+connection master;
+
+INSERT INTO t1 VALUES (2);
+sync_slave_with_master;
+--let $diff_tables= master:t1,slave:t1
+source include/diff_tables.inc;
+
+connection master;
+DROP TABLE t1;
+sync_slave_with_master;
+--remove_files_wildcard $tmpdir *
+--rmdir $tmpdir
=== modified file 'mysql-test/suite/rpl/t/rpl_manual_change_index_file.test'
--- a/mysql-test/suite/rpl/t/rpl_manual_change_index_file.test 2010-12-19 17:22:30 +0000
+++ b/mysql-test/suite/rpl/t/rpl_manual_change_index_file.test 2011-01-26 07:55:10 +0000
@@ -11,8 +11,8 @@ source include/master-slave.inc;
FLUSH LOGS;
# Now, 2 entries in index file.
-# ./master-bin.000001
-# ./master-bin.000002
+# master-bin.000001
+# master-bin.000002
CREATE TABLE t1(c1 INT);
# Now, the current dump file(master-bin.000002) is the second line of index
@@ -23,34 +23,23 @@ sync_slave_with_master;
# events.
connection master;
-# Delete './master-bin.000001' from index file.
+# Delete 'master-bin.000001' from index file.
let $MYSQLD_DATADIR= `SELECT @@DATADIR`;
let $file= $MYSQLD_DATADIR/master-bin.index;
source include/truncate_file.inc;
-if (`SELECT CONVERT(@@VERSION_COMPILE_OS USING latin1) NOT IN ('Win32', 'Win64', 'Windows')`)
-{
append_file $MYSQLD_DATADIR/master-bin.index;
-./master-bin.000002
+master-bin.000002
EOF
sleep 0.00000001;
-}
-
-if (`SELECT CONVERT(@@VERSION_COMPILE_OS USING latin1) IN ('Win32', 'Win64', 'Windows')`)
-{
-append_file $MYSQLD_DATADIR/master-bin.index;
-.\master-bin.000002
-EOF
-sleep 0.00000001;
-}
# Now, only 1 entry in index file. ./master-bin.000002
# Generate master-bin.000003, but it is in the second line.
FLUSH LOGS;
# Now, 2 entries in index file.
-# ./master-bin.000002
-# ./master-bin.000003
+# master-bin.000002
+# master-bin.000003
# Now, master know that new binlog file(master-bin.000003) has been generated.
# It expects that the new binlog file is in third line of index file, but
@@ -67,25 +56,12 @@ connection master;
source include/truncate_file.inc;
-if (`SELECT CONVERT(@@VERSION_COMPILE_OS USING latin1) NOT IN ('Win32', 'Win64', 'Windows')`)
-{
append_file $MYSQLD_DATADIR/master-bin.index;
-./master-bin.000001
-./master-bin.000002
-./master-bin.000003
+master-bin.000001
+master-bin.000002
+master-bin.000003
EOF
sleep 0.00000001;
-}
-
-if (`SELECT CONVERT(@@VERSION_COMPILE_OS USING latin1) IN ('Win32', 'Win64', 'Windows')`)
-{
-append_file $MYSQLD_DATADIR/master-bin.index;
-.\master-bin.000001
-.\master-bin.000002
-.\master-bin.000003
-EOF
-sleep 0.00000001;
-}
CREATE TABLE t2(c1 INT);
FLUSH LOGS;
@@ -138,20 +114,11 @@ connection master;
PURGE MASTER LOGS TO 'master-bin.000003';
--echo # Re-insert master-bin.000002 into index file manually.
-if (`SELECT CONVERT(@@VERSION_COMPILE_OS USING latin1) NOT IN ('Win32', 'Win64', 'Windows')`)
-{
append_file $MASTER_DATADIR/master-bin.index;
-./master-bin.000002
+master-bin.000002
EOF
sleep 0.00000001;
-}
-if (`SELECT CONVERT(@@VERSION_COMPILE_OS USING latin1) IN ('Win32', 'Win64', 'Windows')`)
-{
-append_file $MASTER_DATADIR/master-bin.index;
-.\master-bin.000002
-EOF
-sleep 0.00000001;
-}
+
--echo # PURGE is used to update IO_CACHE of index file. After this statement,
--echo # master knows that master-bin.000002 is in index file.
PURGE MASTER LOGS TO 'master-bin.000002';
@@ -176,20 +143,12 @@ connection master;
--echo # Restore the correct index file.
let $file= $MASTER_DATADIR/master-bin.index;
source include/truncate_file.inc;
-if (`SELECT CONVERT(@@VERSION_COMPILE_OS USING latin1) NOT IN ('Win32', 'Win64', 'Windows')`)
-{
-append_file $MASTER_DATADIR/master-bin.index;
-./master-bin.000003
-EOF
-sleep 0.00000001;
-}
-if (`SELECT CONVERT(@@VERSION_COMPILE_OS USING latin1) IN ('Win32', 'Win64', 'Windows')`)
-{
+
append_file $MASTER_DATADIR/master-bin.index;
-.\master-bin.000003
+master-bin.000003
EOF
sleep 0.00000001;
-}
+
FLUSH LOGS;
PURGE MASTER LOGS TO 'master-bin.000004';
=== modified file 'sql/binlog.cc'
--- a/sql/binlog.cc 2010-12-17 02:01:32 +0000
+++ b/sql/binlog.cc 2011-01-26 07:55:10 +0000
@@ -42,6 +42,13 @@ static int binlog_commit(handlerton *hto
static int binlog_rollback(handlerton *hton, THD *thd, bool all);
static int binlog_prepare(handlerton *hton, THD *thd, bool all);
+static inline bool same_log_name(const char* log_name1, const char* log_name2)
+{
+ uint dir_len1= dirname_length(log_name1);
+ uint dir_len2= dirname_length(log_name2);
+ return !strcmp(log_name1 + dir_len1, log_name2 + dir_len2);
+}
+
/*
Helper class to hold a mutex for the duration of the
block.
@@ -1201,17 +1208,14 @@ bool stmt_has_updated_non_trans_table(co
*/
bool purge_master_logs(THD* thd, const char* to_log)
{
- char search_file_name[FN_REFLEN];
if (!mysql_bin_log.is_open())
{
my_ok(thd);
return FALSE;
}
- mysql_bin_log.make_log_name(search_file_name, to_log);
return purge_error_message(thd,
- mysql_bin_log.purge_logs(search_file_name, 0, 1,
- 1, NULL));
+ mysql_bin_log.purge_logs(to_log, 0, 1, 1, NULL));
}
@@ -1397,7 +1401,6 @@ bool show_binlog_events(THD *thd, MYSQL_
SELECT_LEX_UNIT *unit= &thd->lex->unit;
ha_rows event_count, limit_start, limit_end;
my_off_t pos = max(BIN_LOG_HEADER_SIZE, lex_mi->pos); // user-friendly
- char search_file_name[FN_REFLEN], *name;
const char *log_file_name = lex_mi->log_file_name;
mysql_mutex_t *log_lock = binary_log->get_log_lock();
LOG_INFO linfo;
@@ -1407,15 +1410,9 @@ bool show_binlog_events(THD *thd, MYSQL_
limit_start= unit->offset_limit_cnt;
limit_end= unit->select_limit_cnt;
- name= search_file_name;
- if (log_file_name)
- binary_log->make_log_name(search_file_name, log_file_name);
- else
- name=0; // Find first log
-
linfo.index_file_offset = 0;
- if (binary_log->find_log_pos(&linfo, name, 1))
+ if (binary_log->find_log_pos(&linfo, log_file_name, 1))
{
errmsg = "Could not find target log";
goto err;
@@ -1425,7 +1422,9 @@ bool show_binlog_events(THD *thd, MYSQL_
thd->current_linfo = &linfo;
mysql_mutex_unlock(&LOCK_thread_count);
- if ((file=open_binlog(&log, linfo.log_file_name, &errmsg)) < 0)
+ char log_path[FN_REFLEN];
+ binary_log->make_log_name(log_path, linfo.log_file_name);
+ if ((file=open_binlog(&log, log_path, &errmsg)) < 0)
goto err;
/*
@@ -1473,7 +1472,7 @@ bool show_binlog_events(THD *thd, MYSQL_
description_event->checksum_alg= ev->checksum_alg;
if (event_count >= limit_start &&
- ev->net_send(protocol, linfo.log_file_name, pos))
+ ev->net_send(protocol, log_path, pos))
{
errmsg = "Net error";
delete ev;
@@ -1868,9 +1867,10 @@ bool MYSQL_BIN_LOG::open(const char *log
As this is a new log file, we write the file name to the index
file. As every time we write to the index file, we sync it.
*/
+ char *log_basename= log_file_name + dirname_length(log_file_name);
if (DBUG_EVALUATE_IF("fault_injection_updating_index", 1, 0) ||
- my_b_write(&index_file, (uchar*) log_file_name,
- strlen(log_file_name)) ||
+ my_b_write(&index_file, (uchar*) log_basename,
+ strlen(log_basename)) ||
my_b_write(&index_file, (uchar*) "\n", 1) ||
flush_io_cache(&index_file) ||
mysql_file_sync(index_file.file, MYF(MY_WME)))
@@ -1980,7 +1980,7 @@ void MYSQL_BIN_LOG::set_write_error(THD
@param linfo Store here the found log file name and position to
the NEXT log file name in the index file.
- @param log_name Filename to find in the index file.
+ @param log_name Filename to find in the index file.
Is a null pointer if we want to read the first entry
@param need_lock Set this to 1 if the parent doesn't already have a
lock on LOCK_index
@@ -2002,9 +2002,10 @@ int MYSQL_BIN_LOG::find_log_pos(LOG_INFO
{
int error= 0;
char *fname= linfo->log_file_name;
- uint log_name_len= log_name ? (uint) strlen(log_name) : 0;
+ uint log_name_len= log_name ? strlen(log_name) : 0;
DBUG_ENTER("find_log_pos");
DBUG_PRINT("enter",("log_name: %s", log_name ? log_name : "NULL"));
+ DBUG_ASSERT(log_name == NULL || dirname_length(log_name) == 0);
/*
Mutex needed because we need to make sure the file pointer does not
@@ -2032,6 +2033,12 @@ int MYSQL_BIN_LOG::find_log_pos(LOG_INFO
break;
}
+ /* Entries generated by server before fix of bug#12133 may include
+ the dir part, skip the dir part when compare */
+ uint dir_len= dirname_length(fname);
+ fname += dir_len;
+ length -= dir_len;
+
// if the log entry matches, null string matching anything
if (!log_name ||
(log_name_len == length-1 && fname[log_name_len] == '\n' &&
@@ -2172,7 +2179,9 @@ bool MYSQL_BIN_LOG::reset_logs(THD* thd)
for (;;)
{
- if ((error= my_delete_allow_opened(linfo.log_file_name, MYF(0))) != 0)
+ char log_name[FN_REFLEN];
+ make_log_name(log_name, linfo.log_file_name);
+ if ((error= my_delete_allow_opened(log_name, MYF(0))) != 0)
{
if (my_errno == ENOENT)
{
@@ -2296,7 +2305,7 @@ int MYSQL_BIN_LOG::purge_first_log(Relay
DBUG_ASSERT(is_open());
DBUG_ASSERT(rli->slave_running == 1);
- DBUG_ASSERT(!strcmp(rli->linfo.log_file_name,rli->get_event_relay_log_name()));
+ DBUG_ASSERT(same_log_name(rli->linfo.log_file_name,rli->get_event_relay_log_name()));
mysql_mutex_assert_owner(&rli->data_lock);
@@ -2453,7 +2462,7 @@ int MYSQL_BIN_LOG::purge_logs(const char
*/
if ((error=find_log_pos(&log_info, NullS, 0 /*no mutex*/)))
goto err;
- while ((strcmp(to_log,log_info.log_file_name) || (exit_loop=included)) &&
+ while ((!same_log_name(to_log,log_info.log_file_name) || (exit_loop=included)) &&
!is_active(log_info.log_file_name) &&
!log_in_use(log_info.log_file_name))
{
@@ -2682,7 +2691,9 @@ int MYSQL_BIN_LOG::purge_index_entry(THD
}
else
{
- if ((error= find_log_pos(&check_log_info, log_info.log_file_name, need_mutex)))
+ if ((error= find_log_pos(&check_log_info,
+ log_info.log_file_name + dirname_length(log_info.log_file_name),
+ need_mutex)))
{
if (error != LOG_INFO_EOF)
{
@@ -2806,12 +2817,13 @@ int MYSQL_BIN_LOG::purge_logs_before_dat
if ((error=find_log_pos(&log_info, NullS, 0 /*no mutex*/)))
goto err;
- while (strcmp(log_file_name, log_info.log_file_name) &&
+ while (!same_log_name(log_file_name, log_info.log_file_name) &&
!is_active(log_info.log_file_name) &&
!log_in_use(log_info.log_file_name))
{
- if (!mysql_file_stat(key_file_binlog,
- log_info.log_file_name, &stat_area, MYF(0)))
+ char log_path[FN_REFLEN];
+ make_log_name(log_path, log_info.log_file_name);
+ if (!mysql_file_stat(key_file_binlog, log_path, &stat_area, MYF(0)))
{
if (my_errno == ENOENT)
{
@@ -2870,6 +2882,7 @@ err:
Create a new log file name.
@param buf buf of at least FN_REFLEN where new name is stored
+ @return buf
@note
If file name will be longer then FN_REFLEN it will be truncated
@@ -2877,11 +2890,12 @@ err:
void MYSQL_BIN_LOG::make_log_name(char* buf, const char* log_ident)
{
+ const char* log_name= log_ident + dirname_length(log_ident);
uint dir_len = dirname_length(log_file_name);
if (dir_len >= FN_REFLEN)
dir_len=FN_REFLEN-1;
strnmov(buf, log_file_name, dir_len);
- strmake(buf+dir_len, log_ident, FN_REFLEN - dir_len -1);
+ strmake(buf+dir_len, log_name, FN_REFLEN - dir_len -1);
}
@@ -2891,7 +2905,7 @@ void MYSQL_BIN_LOG::make_log_name(char*
bool MYSQL_BIN_LOG::is_active(const char *log_file_name_arg)
{
- return !strcmp(log_file_name, log_file_name_arg);
+ return same_log_name(log_file_name, log_file_name_arg);
}
@@ -4173,7 +4187,7 @@ int MYSQL_BIN_LOG::open(const char *opt_
do
{
- strmake(log_name, log_info.log_file_name, sizeof(log_name)-1);
+ make_log_name(log_name, log_info.log_file_name);
} while (!(error= find_next_log(&log_info, 1)));
if (error != LOG_INFO_EOF)
@@ -4182,6 +4196,14 @@ int MYSQL_BIN_LOG::open(const char *opt_
goto err;
}
+ if (!dirname_length(log_name))
+ {
+ int dir_len= dirname_length(opt_name);
+ if (dir_len >= FN_REFLEN)
+ dir_len=FN_REFLEN-1;
+ strmake(log_name+dir_len, log_name, FN_REFLEN - dir_len -1);
+ strnmov(log_name, opt_name, dir_len);
+ }
if ((file= open_binlog(&log, log_name, &errmsg)) < 0)
{
sql_print_error("%s", errmsg);
=== modified file 'sql/binlog.h'
--- a/sql/binlog.h 2010-12-10 16:55:50 +0000
+++ b/sql/binlog.h 2011-01-26 07:55:10 +0000
@@ -262,6 +262,7 @@ public:
uint next_file_id();
inline char* get_index_fname() { return index_file_name;}
inline char* get_log_fname() { return log_file_name; }
+ inline char* get_log_fbasename() { return log_file_name + dirname_length(log_file_name); }
inline char* get_name() { return name; }
inline mysql_mutex_t* get_log_lock() { return &LOCK_log; }
inline mysql_cond_t* get_log_cond() { return &update_cond; }
=== modified file 'sql/rpl_master.cc'
--- a/sql/rpl_master.cc 2010-12-17 10:07:30 +0000
+++ b/sql/rpl_master.cc 2011-01-26 07:55:10 +0000
@@ -622,8 +622,7 @@ void mysql_binlog_send(THD* thd, char* l
ushort flags)
{
LOG_INFO linfo;
- char *log_file_name = linfo.log_file_name;
- char search_file_name[FN_REFLEN], *name;
+ char log_file_name[FN_REFLEN], *name;
ulong ev_offset;
@@ -672,7 +671,7 @@ void mysql_binlog_send(THD* thd, char* l
heartbeat_ts= &heartbeat_buf;
set_timespec_nsec(*heartbeat_ts, 0);
coord= &coord_buf;
- coord->file_name= log_file_name; // initialization basing on what slave remembers
+ coord->file_name= linfo.log_file_name; // points to the current binary log file name
coord->pos= pos;
}
sql_print_information("Start binlog_dump to slave_server(%d), pos(%s, %lu)",
@@ -706,9 +705,8 @@ void mysql_binlog_send(THD* thd, char* l
goto err;
}
- name=search_file_name;
if (log_ident[0])
- mysql_bin_log.make_log_name(search_file_name, log_ident);
+ name= log_ident;
else
name=0; // Find first log
@@ -725,6 +723,8 @@ void mysql_binlog_send(THD* thd, char* l
thd->current_linfo = &linfo;
mysql_mutex_unlock(&LOCK_thread_count);
+ mysql_bin_log.make_log_name(log_file_name, linfo.log_file_name);
+
if ((file=open_binlog(&log, log_file_name, &errmsg)) < 0)
{
my_errno= ER_MASTER_FATAL_ERROR_READING_BINLOG;
@@ -1001,7 +1001,7 @@ impossible position";
goto err;
if (!(flags & BINLOG_DUMP_NON_BLOCK) &&
- mysql_bin_log.is_active(log_file_name))
+ mysql_bin_log.is_active(linfo.log_file_name))
{
/*
Block until there is more data in the log
@@ -1178,7 +1178,7 @@ impossible position";
case 0:
break;
case LOG_INFO_EOF:
- if (mysql_bin_log.is_active(log_file_name))
+ if (mysql_bin_log.is_active(linfo.log_file_name))
{
loop_breaker = (flags & BINLOG_DUMP_NON_BLOCK);
break;
@@ -1199,6 +1199,7 @@ impossible position";
if (reset_transmit_packet(thd, flags, &ev_offset, &errmsg))
goto err;
+ mysql_bin_log.make_log_name(log_file_name, linfo.log_file_name);
/*
Call fake_rotate_event() in case the previous log (the one which
we have just finished reading) did not contain a Rotate event
@@ -1215,9 +1216,7 @@ impossible position";
my_errno= ER_MASTER_FATAL_ERROR_READING_BINLOG;
goto err;
}
-
- if (coord)
- coord->file_name= log_file_name; // reset to the next
+ DBUG_ASSERT(!coord || (coord->file_name == linfo.log_file_name));
}
}
=== modified file 'sql/rpl_rli.cc'
--- a/sql/rpl_rli.cc 2010-12-21 09:33:41 +0000
+++ b/sql/rpl_rli.cc 2011-01-26 07:55:10 +0000
@@ -104,11 +104,13 @@ static inline int add_relay_log(Relay_lo
{
MY_STAT s;
DBUG_ENTER("add_relay_log");
- if (!mysql_file_stat(key_file_binlog,
- linfo->log_file_name, &s, MYF(0)))
+ char log_name[FN_REFLEN];
+
+ rli->relay_log.make_log_name(log_name, linfo->log_file_name);
+ if (!mysql_file_stat(key_file_binlog, log_name, &s, MYF(0)))
{
sql_print_error("log %s listed in the index, but failed to stat",
- linfo->log_file_name);
+ log_name);
DBUG_RETURN(1);
}
rli->log_space_total += s.st_size;
@@ -263,11 +265,12 @@ int Relay_log_info::init_relay_log_pos(c
}
else
{
+ char log_name[FN_REFLEN];
+ relay_log.make_log_name(log_name, linfo.log_file_name);
/*
Open the relay log and set cur_log to point at this one
*/
- if ((cur_log_fd=open_binlog(&cache_buf,
- linfo.log_file_name,errmsg)) < 0)
+ if ((cur_log_fd=open_binlog(&cache_buf, log_name, errmsg)) < 0)
goto err;
cur_log = &cache_buf;
}
@@ -721,9 +724,9 @@ int Relay_log_info::purge_relay_logs(THD
goto err;
}
/* Save name of used relay log file */
- strmake(group_relay_log_name, relay_log.get_log_fname(),
+ strmake(group_relay_log_name, relay_log.get_log_fbasename(),
sizeof(group_relay_log_name)-1);
- strmake(event_relay_log_name, relay_log.get_log_fname(),
+ strmake(event_relay_log_name, relay_log.get_log_fbasename(),
sizeof(event_relay_log_name)-1);
group_relay_log_pos= event_relay_log_pos= BIN_LOG_HEADER_SIZE;
if (count_relay_log_space())
@@ -1457,6 +1460,15 @@ bool Relay_log_info::read_info(Rpl_info_
else
DBUG_PRINT("info", ("relay_log_info file is in old format."));
+ /* Remove the directory part */
+ int dirlen= dirname_length(group_relay_log_name);
+ if (dirlen)
+ {
+ int len= strlen(group_relay_log_name);
+ memmove(group_relay_log_name, group_relay_log_name + dirlen, len - dirlen);
+ group_relay_log_name[len-dirlen]= '\0';
+ }
+
if (from->get_info((ulong *) &temp_group_relay_log_pos,
(ulong) BIN_LOG_HEADER_SIZE) ||
from->get_info(group_master_log_name,
@@ -1487,6 +1499,7 @@ bool Relay_log_info::write_info(Rpl_info
Relay_log_info::read_info() for details. /Sven
*/
//DBUG_ASSERT(!belongs_to_client());
+ DBUG_ASSERT(dirname_length(group_relay_log_name) == 0);
if (to->prepare_info_for_write() ||
to->set_info((int) LINES_IN_RELAY_LOG_INFO_WITH_DELAY) ||
=== modified file 'sql/rpl_slave.cc'
--- a/sql/rpl_slave.cc 2010-12-10 16:55:50 +0000
+++ b/sql/rpl_slave.cc 2011-01-26 07:55:10 +0000
@@ -374,8 +374,8 @@ int init_recovery(Master_info* mi, const
sql_print_warning("Recovery from master pos %ld and file %s.",
(ulong) mi->get_master_log_pos(), mi->get_master_log_name());
- rli->set_group_relay_log_name(rli->relay_log.get_log_fname());
- rli->set_event_relay_log_name(rli->relay_log.get_log_fname());
+ rli->set_group_relay_log_name(rli->relay_log.get_log_fbasename());
+ rli->set_event_relay_log_name(rli->relay_log.get_log_fbasename());
rli->set_group_relay_log_pos(BIN_LOG_HEADER_SIZE);
rli->set_event_relay_log_pos(BIN_LOG_HEADER_SIZE);
}
@@ -4943,9 +4943,11 @@ static IO_CACHE *reopen_relay_log(Relay_
DBUG_ASSERT(rli->cur_log != &rli->cache_buf);
DBUG_ASSERT(rli->cur_log_fd == -1);
+ char relay_log_name[FN_REFLEN];
+ rli->relay_log.make_log_name(relay_log_name, rli->get_event_relay_log_name());
+
IO_CACHE *cur_log = rli->cur_log=&rli->cache_buf;
- if ((rli->cur_log_fd=open_binlog(cur_log,rli->get_event_relay_log_name(),
- errmsg)) <0)
+ if ((rli->cur_log_fd=open_binlog(cur_log, relay_log_name, errmsg)) <0)
DBUG_RETURN(0);
/*
We want to start exactly where we was before:
@@ -5363,9 +5365,10 @@ static Log_event* next_event(Relay_log_i
sql_print_information("next log '%s' is not active",
rli->linfo.log_file_name);
#endif
+ char log_name[FN_REFLEN];
+ rli->relay_log.make_log_name(log_name, rli->linfo.log_file_name);
// open_binlog() will check the magic header
- if ((rli->cur_log_fd=open_binlog(cur_log,rli->linfo.log_file_name,
- &errmsg)) <0)
+ if ((rli->cur_log_fd=open_binlog(cur_log, log_name, &errmsg)) <0)
goto err;
}
else
@@ -5996,11 +5999,8 @@ bool change_master(THD* thd, Master_info
if (lex_mi->relay_log_name)
{
need_relay_log_purge= 0;
- char relay_log_name[FN_REFLEN];
-
- mi->rli->relay_log.make_log_name(relay_log_name, lex_mi->relay_log_name);
- mi->rli->set_group_relay_log_name(relay_log_name);
- mi->rli->set_event_relay_log_name(relay_log_name);
+ mi->rli->set_group_relay_log_name(lex_mi->relay_log_name);
+ mi->rli->set_event_relay_log_name(lex_mi->relay_log_name);
}
if (lex_mi->relay_log_pos)
Attachment: [text/bzr-bundle] bzr/hezx@greatopensource.com-20110126075510-f23ditvfxcvu3xx9.bundle