List:Commits« Previous MessageNext Message »
From:Li-Bing.Song Date:December 17 2010 9:58am
Subject:bzr commit into mysql-trunk-bugfixing branch (Li-Bing.Song:3444) Bug#21437
View as plain text  
#At file:///home/anders/Work/bzrwork/wt1/mysql-trunk-bugfixing/ based on revid:tor.didriksen@stripped

 3444 Li-Bing.Song@stripped	2010-12-17
      Bug#21437 server_errno=29 error message flood mysqld error log
                  
      If an error happens while dumping a binary log from the master,
      the master sends one of the specific set of error messages and
      the slave I/O thread stops immediately.
                  
      However, when a slave requests a binlog file which does not exist
      on master, the master sends 'EE_FILENOTFOUND' error (i.e. error code 29)
      to the slave. the 'EE_FILENOTFOUND' is a low level error and slave
      I/O thread will still retry to request the binlog file, thus is flooding
      the mysqld error log.
                
      This happens because the master just sends the first error message set in 
      the diagnostic area and as such the I/O thread does not stop. To fix the
      the problem, we use a temporary diagnostic area to store the low level errors.
      MASTER_FATAL_ERROR_READING_BINLOG is always set into dump thread's real
      diagnostic area and sent to slave I/O thread.

    modified:
      mysql-test/suite/rpl/r/rpl_manual_change_index_file.result
      mysql-test/suite/rpl/t/rpl_manual_change_index_file.test
      sql/rpl_master.cc
=== modified file 'mysql-test/suite/rpl/r/rpl_manual_change_index_file.result'
--- a/mysql-test/suite/rpl/r/rpl_manual_change_index_file.result	2010-01-08 05:42:23 +0000
+++ b/mysql-test/suite/rpl/r/rpl_manual_change_index_file.result	2010-12-17 09:58:47 +0000
@@ -23,3 +23,49 @@ t2
 t3
 t4
 DROP TABLE t1, t2, t3, t4;
+
+# BUG#21437 server_errno=29 error message flood mysqld error log
+# --------------------------------------------------------------------------
+# This test verifies if the ER_MASTER_FATAL_ERROR_READING_BINLOG which
+# insteads of EE_FILENOTFOUND error is sent to slave, so that the slave
+# I/O thread stops immediately.
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+[ on master ]
+call mtr.add_suppression("Got fatal error 1236 from master when reading data from binary log:");
+CREATE TABLE t1(c1 int);
+DROP TABLE t1;
+FLUSH LOGS;
+FLUSH LOGS;
+CREATE TABLE t2(c1 int);
+DROP TABLE t2;
+[ on slave ]
+include/stop_slave.inc
+[ on master ]
+# Remove master-bin.000001 and master-bin.000002 from index file.
+PURGE MASTER LOGS TO 'master-bin.000003';
+# Re-insert master-bin.000002 into index file manually.
+# PURGE is used to update IO_CACHE of index file.  After this statement,
+# master knows that master-bin.000002 is in index file.
+PURGE MASTER LOGS TO 'master-bin.000002';
+[ on slave ]
+CHANGE MASTER TO master_host='127.0.0.1', master_log_file='master-bin.000002';
+START SLAVE IO_THREAD;
+# Instead of EE_FILENOTFOUND, ER_MASTER_FATAL_ERROR_READING_BINLOG and the
+# specific information are sent to slave.
+Last_IO_Error = Got fatal error 1236 from master when reading data from binary log: 'Could not open log file'
+CHANGE MASTER TO master_host='127.0.0.1', master_log_file='master-bin.000003';
+include/start_slave.inc
+[ on master ]
+# Restore the correct index file.
+FLUSH LOGS;
+PURGE MASTER LOGS TO 'master-bin.000004';
+CREATE TABLE t1(c1 INT);
+[ on slave ]
+SELECT * FROM t1;
+c1
+DROP TABLE t1;

=== 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-04-21 17:22:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_manual_change_index_file.test	2010-12-17 09:58:47 +0000
@@ -104,4 +104,101 @@ SHOW TABLES;
 
 connection master;
 DROP TABLE t1, t2, t3, t4;
-source include/master-slave-end.inc;
+sync_slave_with_master;
+
+--echo
+--echo # BUG#21437 server_errno=29 error message flood mysqld error log
+--echo # --------------------------------------------------------------------------
+--echo # This test verifies if the ER_MASTER_FATAL_ERROR_READING_BINLOG which
+--echo # insteads of EE_FILENOTFOUND error is sent to slave, so that the slave
+--echo # I/O thread stops immediately.
+
+source include/master-slave-reset.inc;
+--echo [ on master ]
+connection master;
+
+let $MASTER_DATADIR= `SELECT @@DATADIR`;
+
+call mtr.add_suppression("Got fatal error 1236 from master when reading data from binary log:");
+CREATE TABLE t1(c1 int);
+DROP TABLE t1;
+
+FLUSH LOGS;
+FLUSH LOGS;
+
+CREATE TABLE t2(c1 int);
+DROP TABLE t2;
+sync_slave_with_master;
+
+--echo [ on slave ]
+source include/stop_slave.inc;
+
+--echo [ on master ]
+connection master;
+--echo # Remove master-bin.000001 and master-bin.000002 from index file.
+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
+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';
+
+--echo [ on slave ]
+connection slave;
+CHANGE MASTER TO master_host='127.0.0.1', master_log_file='master-bin.000002';
+START SLAVE IO_THREAD;
+
+--echo # Instead of EE_FILENOTFOUND, ER_MASTER_FATAL_ERROR_READING_BINLOG and the
+--echo # specific information are sent to slave.
+let $slave_io_errno= 1236;
+let $show_slave_io_error= 1;
+source include/wait_for_slave_io_error.inc;
+
+CHANGE MASTER TO master_host='127.0.0.1', master_log_file='master-bin.000003';
+source include/start_slave.inc;
+
+
+--echo [ on master ]
+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
+EOF
+sleep 0.00000001;
+}
+FLUSH LOGS;
+PURGE MASTER LOGS TO 'master-bin.000004';
+
+CREATE TABLE t1(c1 INT);
+sync_slave_with_master;
+--echo [ on slave ]
+SELECT * FROM t1;
+
+connection master;
+DROP TABLE t1;
+source include/master-slave-end.inc;
\ No newline at end of file

=== modified file 'sql/rpl_master.cc'
--- a/sql/rpl_master.cc	2010-12-10 16:55:50 +0000
+++ b/sql/rpl_master.cc	2010-12-17 09:58:47 +0000
@@ -642,6 +642,19 @@ void mysql_binlog_send(THD* thd, char* l
   int left_events = max_binlog_dump_events;
 #endif
   int old_max_allowed_packet= thd->variables.max_allowed_packet;
+  /*
+    Dump thread sends ER_MASTER_FATAL_ERROR_READING_BINLOG instead of the real
+    errors happend on master to slave when erorr is encountered.
+    So set a temporary Diagnostics_area to thd. The low level error is always
+    set into the temporary Diagnostics_area and be ingored. The original
+    Diagnostics_area will be restored at the end of this function.
+    ER_MASTER_FATAL_ERROR_READING_BINLOG will be set to the original
+    Diagnostics_area.
+  */
+  Diagnostics_area temp_da;
+  Diagnostics_area *saved_da= thd->stmt_da;
+  thd->stmt_da= &temp_da;
+
   DBUG_ENTER("mysql_binlog_send");
   DBUG_PRINT("enter",("log_ident: '%s'  pos: %ld", log_ident, (long) pos));
 
@@ -1209,6 +1222,7 @@ impossible position";
   }
 
 end:
+  thd->stmt_da= saved_da;
   end_io_cache(&log);
   mysql_file_close(file, MYF(MY_WME));
 
@@ -1239,6 +1253,7 @@ err:
     mysql_file_close(file, MYF(MY_WME));
   thd->variables.max_allowed_packet= old_max_allowed_packet;
 
+  thd->stmt_da= saved_da;
   my_message(my_errno, errmsg, MYF(0));
   DBUG_VOID_RETURN;
 }


Attachment: [text/bzr-bundle] bzr/li-bing.song@sun.com-20101217095847-kl1jq6ae8drxzcev.bundle
Thread
bzr commit into mysql-trunk-bugfixing branch (Li-Bing.Song:3444) Bug#21437Li-Bing.Song17 Dec