#At file:///home/anders/work/bzrwork/bug45516/mysql-5.1-bugteam/ based on revid:kristofer.pettersson@stripped
3191 Li-Bing.Song@stripped 2009-11-10
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-11-10 14:06:10 +0000
@@ -0,0 +1,19 @@
+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;
+CREATE TABLE t2(c1 int);
+DROP TABLE t2;
+STOP SLAVE;
+CHANGE MASTER TO master_host='127.0.0.1', master_log_file='master-bin.000001';
+START SLAVE IO_THREAD;
+Last_IO_Error
+echo 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.000002';
+START SLAVE;
=== 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-11-10 14:06:10 +0000
@@ -0,0 +1,54 @@
+###############################################################################
+# 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
+#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:");
+let $MASTER_DATADIR= `SELECT @@DATADIR`;
+CREATE TABLE t1(c1 int);
+DROP TABLE t1;
+
+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;
+#This operation will result in error EE_FILENOTFOUND which happens when slave IO thread is connecting to master.
+move_file $MASTER_DATADIR/master-bin.000001 $MASTER_DATADIR/master-bin.bak;
+
+connection slave;
+CHANGE MASTER TO master_host='127.0.0.1', master_log_file='master-bin.000001';
+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 master;
+#This operation will result in error EE_FILENOTFOUND which happens when slave IO thread is connecting to master.
+move_file $MASTER_DATADIR/master-bin.bak $MASTER_DATADIR/master-bin.000001;
+
+connection slave;
+CHANGE MASTER TO master_host='127.0.0.1', master_log_file='master-bin.000002';
+START SLAVE;
+source include/wait_for_slave_to_start.inc;
+
+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-11-10 14:06:10 +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-20091110140610-wi19y4dzm6zp7quz.bundle