List:Commits« Previous MessageNext Message »
From:Luís Soares Date:January 5 2010 3:24pm
Subject:Re: bzr commit into mysql-5.1-bugteam branch (Li-Bing.Song:3303)
Bug#28421
View as plain text  
Hi Libing,

  Nice Work. Please find my review comments below.

STATUS
------
 Approved (pending clarification about documentation purpose).

REQUIRED CHANGES
----------------
  RC1. Please check my questions in thread for previous patch.

REQUESTS
--------
 n/a

SUGGESTIONS
-----------
 n/a

DETAILS 
-------
 n/a

Zai Jian,
Luís

On Tue, 2010-01-05 at 10:22 +0000, Li-Bing.Song@stripped wrote:
> #At file:///home/anders/work/bzrwork/worktree2/mysql-5.1-bugteam/ based on
> revid:dao-gang.qu@stripped
> 
>  3303 Li-Bing.Song@stripped	2010-01-05
>       BUG #28421 Infinite loop on slave relay logs
>       
>       Manually deleteing one or more entries from 'master-bin.index', will
>       cause master infinitely loop to send one binlog file. 
>       
>       When starting a dump session, master opens index file and search the binlog
> file
>       which is being requested by the slave. The position of the binlog file in the
>       index file is recorded. it will be used to find the next binlog file when
> current
>       binlog file has dumped completely. As only the position is used, it may
>       not get the correct file if some entries has been removed manually from the
> index file.
>       the master will reopen the current binlog file which has been dump completely
>       and redump it if it can not get the next binlog file's name from index file.
>       It obviously is a logical error.
>       
>       
>       Even though it is allowed to manually change index file,
>       but it is not recommended. so after this patch, master
>       sends a fatal error to slave and close the dump session if a new binlog file
>       has been generated and master can not get it from the index file.

Thanks.

>     added:
>       mysql-test/include/truncate_file.inc
>       mysql-test/suite/rpl/r/rpl_manual_change_index_file.result
>       mysql-test/suite/rpl/t/rpl_manual_change_index_file.test
>     modified:
>       sql/sql_repl.cc
> === added file 'mysql-test/include/truncate_file.inc'
> --- a/mysql-test/include/truncate_file.inc	1970-01-01 00:00:00 +0000
> +++ b/mysql-test/include/truncate_file.inc	2010-01-05 10:22:11 +0000
> @@ -0,0 +1,16 @@
> +# truncate a giving file, all contents of the file are be cleared
> +
> +if (`SELECT 'x$file' = 'x'`)
> +{
> +  --echo Please assign a file name to $file!!
> +  exit;
> +}
> +
> +let TRUNCATE_FILE= $file;
> +
> +perl;
> +use Env;
> +Env::import('TRUNCATE_FILE');
> +open FILE, '>', $TRUNCATE_FILE || die "Can not open file $file";
> +close FILE;
> +EOF

Great!

> === added file 'mysql-test/suite/rpl/r/rpl_manual_change_index_file.result'
> --- a/mysql-test/suite/rpl/r/rpl_manual_change_index_file.result	1970-01-01 00:00:00
> +0000
> +++ b/mysql-test/suite/rpl/r/rpl_manual_change_index_file.result	2010-01-05 10:22:11
> +0000
> @@ -0,0 +1,25 @@
> +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;
> +FLUSH LOGS;
> +CREATE TABLE t1(c1 INT);
> +FLUSH LOGS;
> +call mtr.add_suppression('Got fatal error 1236 from master when reading data from
> binary log: .*could not find next log');
> +Last_IO_Error
> +Got fatal error 1236 from master when reading data from binary log: 'could not find
> next log'
> +CREATE TABLE t2(c1 INT);
> +FLUSH LOGS;
> +CREATE TABLE t3(c1 INT);
> +FLUSH LOGS;
> +CREATE TABLE t4(c1 INT);
> +START SLAVE IO_THREAD;
> +SHOW TABLES;
> +Tables_in_test
> +t1
> +t2
> +t3
> +t4
> +DROP TABLE t1, t2, t3, t4;
> 
> === added file 'mysql-test/suite/rpl/t/rpl_manual_change_index_file.test'
> --- a/mysql-test/suite/rpl/t/rpl_manual_change_index_file.test	1970-01-01 00:00:00
> +0000
> +++ b/mysql-test/suite/rpl/t/rpl_manual_change_index_file.test	2010-01-05 10:22:11
> +0000
> @@ -0,0 +1,85 @@
> +source include/master-slave.inc;
> +
> +#
> +# BUG#28421 Infinite loop on slave relay logs
> +# 
> +# That, manually deleteing one or more entries from 'master-bin.index', will
> +# cause master infinitely loop to send one binlog file.
> +# 
> +# Manually changing index file is a illegal action, so when this happen, we
> +# send a fatal error to slave and close the dump session.
> +
> +FLUSH LOGS;
> +# Now, 2 entries in index file.
> +# ./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
> +# file
> +sync_slave_with_master;
> +# Now, all events has been replicate to slave. As current dump file
> +# (master-bin.000002) is the last binlog file, so master is waiting for new
> +# events.
> +
> +connection master;
> +# Delete './master-bin.000001' from index file.
> +let $MYSQLD_DATADIR= `SELECT @@DATADIR`;
> +#remove_file $MYSQLD_DATADIR/master-bin.index;
> +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
> +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
> +
> +# 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
> +# there is no third line in index file. It is so strange that master sends an
> +# error to slave. 
> +call mtr.add_suppression('Got fatal error 1236 from master when reading data from
> binary log: .*could not find next log');
> +connection slave;
> +source include/wait_for_slave_io_to_stop.inc;
> +let $last_error= query_get_value(SHOW SLAVE STATUS, Last_IO_Error, 1);
> +echo Last_IO_Error;
> +echo $last_error;
> +
> +connection master;
> +CREATE TABLE t2(c1 INT);
> +FLUSH LOGS;
> +CREATE TABLE t3(c1 INT);
> +FLUSH LOGS;
> +CREATE TABLE t4(c1 INT);
> +
> +connection slave;
> +START SLAVE IO_THREAD;
> +source include/wait_for_slave_io_to_start.inc;
> +
> +connection master;
> +sync_slave_with_master;
> +SHOW TABLES;
> +
> +connection master;
> +DROP TABLE t1, t2, t3, t4;
> +source include/master-slave-end.inc;

Thanks for addressing the other comments.

> === modified file 'sql/sql_repl.cc'
> --- a/sql/sql_repl.cc	2009-09-18 08:20:29 +0000
> +++ b/sql/sql_repl.cc	2010-01-05 10:22:11 +0000
> @@ -711,11 +711,14 @@ impossible position";
>  
>        thd_proc_info(thd, "Finished reading one binlog; switching to next binlog");
>        switch (mysql_bin_log.find_next_log(&linfo, 1)) {
> -      case LOG_INFO_EOF:
> -	loop_breaker = (flags & BINLOG_DUMP_NON_BLOCK);
> -	break;
>        case 0:
>  	break;
> +      case LOG_INFO_EOF:
> +        if (mysql_bin_log.is_active(log_file_name))
> +        {
> +          loop_breaker = (flags & BINLOG_DUMP_NON_BLOCK);
> +          break;
> +        }
>        default:
>  	errmsg = "could not find next log";
>  	my_errno= ER_MASTER_FATAL_ERROR_READING_BINLOG;
> 
OK.

Thread
bzr commit into mysql-5.1-bugteam branch (Li-Bing.Song:3303) Bug#28421Li-Bing.Song5 Jan
  • Re: bzr commit into mysql-5.1-bugteam branch (Li-Bing.Song:3303)Bug#28421Luís Soares5 Jan