List:Commits« Previous MessageNext Message »
From:He Zhenxing Date:January 25 2011 10:22am
Subject:bzr commit into mysql-trunk branch (hezx:3481) Bug#12133
View as plain text  
#At file:///media/sdb2/hezx/work/mysql/bzr/b12133/trunk/ based on revid:mattias.jonsson@stripped

 3481 He Zhenxing	2011-01-25
      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/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/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-25 10:22:43 +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-25 10:22:43 +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-25 10:22:43 +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-25 10:22:43 +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-25 10:22:43 +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-25 10:22:43 +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
@@ -1997,15 +1997,23 @@ void MYSQL_BIN_LOG::set_write_error(THD 
     LOG_INFO_IO		Got IO error while reading file
 */
 
-int MYSQL_BIN_LOG::find_log_pos(LOG_INFO *linfo, const char *log_name,
+int MYSQL_BIN_LOG::find_log_pos(LOG_INFO *linfo, const char *log_name_arg,
 			    bool need_lock)
 {
   int error= 0;
   char *fname= linfo->log_file_name;
-  uint log_name_len= log_name ? (uint) strlen(log_name) : 0;
+  const char* log_name= log_name_arg;
+  uint log_name_len= 0;
   DBUG_ENTER("find_log_pos");
   DBUG_PRINT("enter",("log_name: %s", log_name ? log_name : "NULL"));
 
+  if (log_name)
+  {
+    /* remove the dir path */
+    log_name= log_name + dirname_length(log_name);
+    log_name_len= (uint) strlen(log_name);
+  }
+
   /*
     Mutex needed because we need to make sure the file pointer does not
     move from under our feet
@@ -2032,6 +2040,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 +2186,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 +2312,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 +2469,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))
   {
@@ -2806,12 +2822,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 +2887,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 +2895,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 +2910,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 +4192,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 +4201,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/rpl_master.cc'
--- a/sql/rpl_master.cc	2010-12-17 10:07:30 +0000
+++ b/sql/rpl_master.cc	2011-01-25 10:22:43 +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-25 10:22:43 +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;
   }

=== 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-25 10:22:43 +0000
@@ -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


Attachment: [text/bzr-bundle] bzr/hezx@greatopensource.com-20110125102243-blbwmzn39nfb4enz.bundle
Thread
bzr commit into mysql-trunk branch (hezx:3481) Bug#12133He Zhenxing25 Jan