List:Commits« Previous MessageNext Message »
From:Li-Bing.Song Date:December 14 2009 5:34am
Subject:bzr commit into mysql-5.1-bugteam branch (Li-Bing.Song:3236) Bug#21437
View as plain text  
#At file:///home/anders/work/bzrwork/bug45516/mysql-5.1-bugteam/ based on revid:gshchepa@stripped

 3236 Li-Bing.Song@stripped	2009-12-14
      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 reset the disagnostic area before setting the 
      ER_MASTER_FATAL_ERROR_READING_BINLOG in order to notify and stop the slave
      I/O thread immediately.

    added:
      mysql-test/suite/rpl/r/rpl_master_fatal_error.result
      mysql-test/suite/rpl/t/rpl_master_fatal_error.test
    modified:
      sql/sql_repl.cc
=== added file 'mysql-test/suite/rpl/r/rpl_master_fatal_error.result'
--- a/mysql-test/suite/rpl/r/rpl_master_fatal_error.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/r/rpl_master_fatal_error.result	2009-12-14 05:34:54 +0000
@@ -0,0 +1,24 @@
+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;
+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;
+STOP SLAVE;
+PURGE MASTER LOGS TO 'master-bin.000003';
+PURGE MASTER LOGS TO 'master-bin.000002';
+CHANGE MASTER TO master_host='127.0.0.1', master_log_file='master-bin.000002';
+START SLAVE IO_THREAD;
+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';
+START SLAVE;
+FLUSH LOGS;
+PURGE MASTER LOGS TO 'master-bin.000004';

=== added file 'mysql-test/suite/rpl/t/rpl_master_fatal_error.test'
--- a/mysql-test/suite/rpl/t/rpl_master_fatal_error.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_master_fatal_error.test	2009-12-14 05:34:54 +0000
@@ -0,0 +1,69 @@
+###############################################################################
+# Bug #21437 server_errno=29 error message flood mysqld error log
+# 
+# This test verify 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.
+################################################################################
+--disable_warnings
+source include/master-slave.inc;
+--enable_warnings
+let $MASTER_DATADIR= `SELECT @@DATADIR`;
+
+#Add supression for the expected error in slave error log
+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;
+
+STOP SLAVE;
+source include/wait_for_slave_to_stop.inc;
+
+connection master;
+PURGE MASTER LOGS TO 'master-bin.000003';
+# Now, master-bin.000001 and master-bin.000002 are removed from index file.
+#
+# Re-insert master-bin.000002 into index file.
+append_file $MASTER_DATADIR/master-bin.index;
+./master-bin.000002
+EOF
+# 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';
+
+connection slave;
+CHANGE MASTER TO master_host='127.0.0.1', master_log_file='master-bin.000002';
+START SLAVE IO_THREAD;
+source include/wait_for_slave_io_to_stop.inc;
+
+# Instead of EE_FILENOTFOUND, ER_MASTER_FATAL_ERROR_READING_BINLOG and the
+# specific information are sent to slave.
+let $field= Last_IO_Errno;
+let $show_statement= SHOW SLAVE STATUS;
+let $connection= = '1236';
+source include/wait_show_condition.inc;
+let $last_io_error= query_get_value(SHOW SLAVE STATUS, Last_IO_Error, 1);
+echo Last_IO_Error;
+echo $last_io_error;
+
+connection slave;
+CHANGE MASTER TO master_host='127.0.0.1', master_log_file='master-bin.000003';
+START SLAVE;
+source include/wait_for_slave_to_start.inc;
+
+#restore the correct index file.
+connection master;
+remove_file $MASTER_DATADIR/master-bin.index;
+write_file $MASTER_DATADIR/master-bin.index;
+./master-bin.000003
+EOF
+FLUSH LOGS;
+PURGE MASTER LOGS TO 'master-bin.000004';
+
+source include/master-slave-end.inc;

=== modified file 'sql/sql_repl.cc'
--- a/sql/sql_repl.cc	2009-09-18 08:20:29 +0000
+++ b/sql/sql_repl.cc	2009-12-14 05:34:54 +0000
@@ -777,6 +777,14 @@ err:
   if (file >= 0)
     (void) my_close(file, MYF(MY_WME));
 
+  /*
+     thd->main_da will not accept other errors after an error has been assigned
+     to it. A low level error(eg. EEEE_FILENOTFOUND) has sometimes been set into
+     thd->main_da before a high level error is set. thd->main_da should be
+     cleaned before the high level error is set into main_da and then is sent to
+     slave.
+   */
+  thd->main_da.reset_diagnostics_area();
   my_message(my_errno, errmsg, MYF(0));
   DBUG_VOID_RETURN;
 }


Attachment: [text/bzr-bundle] bzr/li-bing.song@sun.com-20091214053454-p95qrxendzdpkylh.bundle
Thread
bzr commit into mysql-5.1-bugteam branch (Li-Bing.Song:3236) Bug#21437Li-Bing.Song14 Dec