List:Commits« Previous MessageNext Message »
From:Daogang Qu Date:December 16 2010 8:55am
Subject:Re: bzr commit into mysql-trunk branch (Dao-Gang.Qu:3208) WL#5493
View as plain text  
Hi Alfranio,
Thanks for your comment. See reply in-line.
Please review:
http://lists.mysql.com/commits/127027

Best Regards,

Daogang

2010-12-11 05:05, Alfranio Correia wrote:
> Hi Daogang,
>
>
> Great work,
>
>
> STATUS
> ------
>
> Conditionally approved.
>
> REQUEST
> ------
>
> 1 - We are not writing directly to the index_file so I think
> we can replace the init_io_cache by a simple seek.
We are using init_io_cache for efficiently reading from index file  
instead of writing.
>
> 2 - Rename rpl_crashed_master.test to rpl_crash_safe_master.test
Updated.
>
> 3 - Rename rpl_*_crash_safe.test to rpl_*_crash_safe_slave.test
Updated.
>
> 4 - Create a version with checksum and without checksum, maybe
>     rpl_crash_safe_master_checksum.test and rpl_crash_safe_master.test
>     respectively.
Updated.
>
> 5. I still don't understand what fdle->flags&= 
> ~LOG_EVENT_BINLOG_IN_USE_F is for. Please, add comments to the code
I have checked out that it is obsolete code. So I will remove it in the 
patch.
>
> int MYSQL_BIN_LOG::recover(IO_CACHE *log, Format_description_log_event 
> *fdle,
>                              my_off_t *valid_pos)
> {
>
>    fdle->flags&= ~LOG_EVENT_BINLOG_IN_USE_F; // abort on the first error
>
> 6 - See more comments in-line
>
> Cheers.
>
>
> On 12/02/2010 02:56 AM, Dao-Gang.Qu@stripped wrote:
>> #At file:///home/daogang/bzrwork/wl5493/mysql-trunk/ based on 
>> revid:alexander.nozdrin@stripped
>>
>>   3208 Dao-Gang.Qu@stripped    2010-12-02
>>        WL#5493 Binlog crash-safe when master crashed
>>
>>        Trim the crashed binlog file to last valid transaction or event
>>        (non-transaction) base on binlog size(valid_pos) when MYSQL 
>> server
>>        crashed in the middle of binlog. And add a temp file to guarantee
>>        the binlog index file to be crash safe.
>
>
>>
>>        WL#5440 Test binlog and replication when master crashed
>>
>>        Test whether the transaction is binlogged partly and the 
>> replication
>>        works fine or not when the master crashed.
>>       @ mysql-test/r/crash_commit_before.result
>>          Removed the result file. Because its test file is removed.
>>       @ mysql-test/suite/binlog/r/binlog_index.result
>>          Test result for WL#5493
>>       @ mysql-test/suite/binlog/t/binlog_delete_and_flush_index.test
>>          Updated for WL#5493.
>>       @ mysql-test/suite/binlog/t/binlog_index.test
>>          Added Test cases to verify that the index file will be crash 
>> safe.
>>       @ mysql-test/suite/rpl/r/rpl_crashed_master.result
>>          Test result for WL#5493 and WL#5440
>>       @ mysql-test/suite/rpl/t/rpl_crashed_master.test
>>          Added test to verify if the crashed binlog file is trimmed to
>>          last valid transaction or event(non-transaction) correctly.
>>          And if the binlog index is crash safe.
>>       @ mysql-test/t/crash_commit_before-master.opt
>>          Removed the opt file. Because its test file is removed.
>>       @ mysql-test/t/crash_commit_before.test
>>          Removed the test file. Because the test case is tested
>>          in rpl_crashed_master.test file.
>>       @ mysys/my_rename.c
>>          Cleared obsolete code. Because all non-windows platforms 
>> will support
>>          the "rename()" POSIX interface.
>>       @ sql/binlog.cc
>>          Added code to trim the crashed binlog file to last valid 
>> transaction
>>          or event(non-transaction) base on valid_pos, make binlog 
>> index to be
>>          crash safe.
>>       @ sql/binlog.h
>>          Added code to define these functions for binlog index crash 
>> safe.
>>       @ sql/log_event.cc
>>          Updated code to remove sql_print_error() line, because its
>>          direct caller will invoke sql_print_error() to print error.
>
>
>
>>
>>      removed:
>>        mysql-test/r/crash_commit_before.result
>>        mysql-test/t/crash_commit_before-master.opt
>>        mysql-test/t/crash_commit_before.test
>>      added:
>>        mysql-test/suite/rpl/r/rpl_crashed_master.result
>>        mysql-test/suite/rpl/t/rpl_crashed_master-master.opt
>>        mysql-test/suite/rpl/t/rpl_crashed_master.test
>>      modified:
>>        mysql-test/suite/binlog/r/binlog_index.result
>>        mysql-test/suite/binlog/t/binlog_delete_and_flush_index.test
>>        mysql-test/suite/binlog/t/binlog_index.test
>>        mysys/my_rename.c
>>        sql/binlog.cc
>>        sql/binlog.h
>>        sql/log_event.cc
>
>
>> === removed file 'mysql-test/r/crash_commit_before.result'
>> --- a/mysql-test/r/crash_commit_before.result    2007-04-03 09:36:33 
>> +0000
>> +++ b/mysql-test/r/crash_commit_before.result    1970-01-01 00:00:00 
>> +0000
>> @@ -1,14 +0,0 @@
>> -CREATE TABLE t1(a int) engine=innodb;
>> -START TRANSACTION;
>> -insert into t1 values(9);
>> -SET SESSION debug="d,crash_commit_before";
>> -COMMIT;
>> -ERROR HY000: Lost connection to MySQL server during query
>> -SHOW CREATE TABLE t1;
>> -Table    Create Table
>> -t1    CREATE TABLE `t1` (
>> -  `a` int(11) DEFAULT NULL
>> -) ENGINE=InnoDB DEFAULT CHARSET=latin1
>> -SELECT * FROM t1;
>> -a
>> -DROP TABLE t1;
>
>
> ok.
>
>>
>> === modified file 'mysql-test/suite/binlog/r/binlog_index.result'
>> --- a/mysql-test/suite/binlog/r/binlog_index.result    2009-12-17 
>> 17:10:18 +0000
>> +++ b/mysql-test/suite/binlog/r/binlog_index.result    2010-12-02 
>> 02:56:34 +0000
>> @@ -147,5 +147,180 @@ master-bin.000011
>>   master-bin.000012
>>   master-bin.000013
>>
>> +# Test case6: Set DEBUG POINT before rename index file to make the 
>> master
>> +#             crash when appending a binlog file name to index file.
>> +show binary logs;
>> +Log_name    File_size
>> +master-bin.000006    #
>> +master-bin.000007    #
>> +master-bin.000008    #
>> +master-bin.000009    #
>> +master-bin.000010    #
>> +master-bin.000011    #
>> +master-bin.000012    #
>> +master-bin.000013    #
>> +SET SESSION debug="+d,crash_create_before_rename_index_file";
>> +flush logs;
>> +ERROR HY000: Lost connection to MySQL server during query
>> +# Restart the master server
>> +# Test the index file is complete and binlog file name is added.
>> +show binary logs;
>> +Log_name    File_size
>> +master-bin.000006    #
>> +master-bin.000007    #
>> +master-bin.000008    #
>> +master-bin.000009    #
>> +master-bin.000010    #
>> +master-bin.000011    #
>> +master-bin.000012    #
>> +master-bin.000013    #
>> +master-bin.000014    #
>> +master-bin.000015    #
>> +# Test case7: Set DEBUG POINT after rename index file to make the 
>> master
>> +#             crash when appending a binlog file name to index file.
>> +SET SESSION debug="+d,crash_create_after_rename_index_file";
>> +flush logs;
>> +ERROR HY000: Lost connection to MySQL server during query
>> +# Restart the master server
>> +# Test the index file is complete and binlog file name is added.
>> +show binary logs;
>> +Log_name    File_size
>> +master-bin.000006    #
>> +master-bin.000007    #
>> +master-bin.000008    #
>> +master-bin.000009    #
>> +master-bin.000010    #
>> +master-bin.000011    #
>> +master-bin.000012    #
>> +master-bin.000013    #
>> +master-bin.000014    #
>> +master-bin.000015    #
>> +master-bin.000016    #
>> +master-bin.000017    #
>> +show binary logs;
>> +Log_name    File_size
>> +master-bin.000006    #
>> +master-bin.000007    #
>> +master-bin.000008    #
>> +master-bin.000009    #
>> +master-bin.000010    #
>> +master-bin.000011    #
>> +master-bin.000012    #
>> +master-bin.000013    #
>> +master-bin.000014    #
>> +master-bin.000015    #
>> +master-bin.000016    #
>> +master-bin.000017    #
>> +SET SESSION debug="+d,crash_create_after_rename_index_file";
>> +purge binary logs TO 'master-bin.000008';
>> +ERROR HY000: Lost connection to MySQL server during query
>> +# Restart the master server
>> +# Test the index file is complete and is purged successfully
>> +show binary logs;
>> +Log_name    File_size
>> +master-bin.000008    #
>> +master-bin.000009    #
>> +master-bin.000010    #
>> +master-bin.000011    #
>> +master-bin.000012    #
>> +master-bin.000013    #
>> +master-bin.000014    #
>> +master-bin.000015    #
>> +master-bin.000016    #
>> +master-bin.000017    #
>> +master-bin.000018    #
>> +# Test case8: Set DEBUG POINT after rename index file to make the 
>> master
>> +#             crash when purging the index file.
>> +show binary logs;
>> +Log_name    File_size
>> +master-bin.000008    #
>> +master-bin.000009    #
>> +master-bin.000010    #
>> +master-bin.000011    #
>> +master-bin.000012    #
>> +master-bin.000013    #
>> +master-bin.000014    #
>> +master-bin.000015    #
>> +master-bin.000016    #
>> +master-bin.000017    #
>> +master-bin.000018    #
>> +SET SESSION debug="+d,crash_create_after_rename_index_file";
>> +purge binary logs TO 'master-bin.000010';
>> +ERROR HY000: Lost connection to MySQL server during query
>> +# Restart the master server
>> +# Test the index file is complete, and is purged successfully.
>> +show binary logs;
>> +Log_name    File_size
>> +master-bin.000010    #
>> +master-bin.000011    #
>> +master-bin.000012    #
>> +master-bin.000013    #
>> +master-bin.000014    #
>> +master-bin.000015    #
>> +master-bin.000016    #
>> +master-bin.000017    #
>> +master-bin.000018    #
>> +master-bin.000019    #
>> +# Test case9: Set DEBUG POINT befor rename index file to make the 
>> master
>> +#             crash when purging the index file.
>> +show binary logs;
>> +Log_name    File_size
>> +master-bin.000010    #
>> +master-bin.000011    #
>> +master-bin.000012    #
>> +master-bin.000013    #
>> +master-bin.000014    #
>> +master-bin.000015    #
>> +master-bin.000016    #
>> +master-bin.000017    #
>> +master-bin.000018    #
>> +master-bin.000019    #
>> +SET SESSION debug="+d,crash_create_before_rename_index_file";
>> +purge binary logs TO 'master-bin.000012';
>> +ERROR HY000: Lost connection to MySQL server during query
>> +# Restart the master server
>> +# Test the index file is complete, and is purged successfully.
>> +show binary logs;
>> +Log_name    File_size
>> +master-bin.000012    #
>> +master-bin.000013    #
>> +master-bin.000014    #
>> +master-bin.000015    #
>> +master-bin.000016    #
>> +master-bin.000017    #
>> +master-bin.000018    #
>> +master-bin.000019    #
>> +master-bin.000020    #
>> +# Test case10: Inject a fault to copy part content to the temp file
>> +#             and abort the server after the temp file is closed
>> +#             when purging the index file.
>> +show binary logs;
>> +Log_name    File_size
>> +master-bin.000012    #
>> +master-bin.000013    #
>> +master-bin.000014    #
>> +master-bin.000015    #
>> +master-bin.000016    #
>> +master-bin.000017    #
>> +master-bin.000018    #
>> +master-bin.000019    #
>> +master-bin.000020    #
>> +SET SESSION debug="+d,fault_injection_copy_part_file";
>> +purge binary logs TO 'master-bin.000014';
>> +ERROR HY000: Lost connection to MySQL server during query
>> +# Restart the master server
>> +# Test the index file is complete, although is not purged successfully.
>> +show binary logs;
>> +Log_name    File_size
>> +master-bin.000012    #
>> +master-bin.000013    #
>> +master-bin.000014    #
>> +master-bin.000015    #
>> +master-bin.000016    #
>> +master-bin.000017    #
>> +master-bin.000018    #
>> +master-bin.000019    #
>> +master-bin.000020    #
>> +master-bin.000021    #
>>   SET SESSION debug="";
>>   End of tests
>
>
> ok.
>
>>
>> === modified file 
>> 'mysql-test/suite/binlog/t/binlog_delete_and_flush_index.test'
>> --- a/mysql-test/suite/binlog/t/binlog_delete_and_flush_index.test    
>> 2009-10-20 08:39:40 +0000
>> +++ b/mysql-test/suite/binlog/t/binlog_delete_and_flush_index.test    
>> 2010-12-02 02:56:34 +0000
>> @@ -77,6 +77,7 @@ FLUSH LOGS;
>>   -- remove_file $datadir/master-bin.000001
>>
>>   -- echo ### assertion: index file contains renamed binlog and the 
>> new one
>> +-- chmod 0644 $index
>>   -- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
>>   -- eval SET @index=LOAD_FILE('$index')
>>   -- replace_regex /\.[\\\/]master/master/
>> @@ -106,6 +107,7 @@ DROP TABLE t1;
>>   -- file_exists $datadir/$current_binlog
>>
>>   -- echo ### assertion: show index file contents and these should 
>> match show binary logs issued above
>> +-- chmod 0644 $index
>>   -- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
>>   -- eval SET @index=LOAD_FILE('$index')
>>   -- replace_regex /\.[\\\/]master/master/
>>
>
> Can you explain in the commit message why you need this chmod?
Sure.
>
>
>> === modified file 'mysql-test/suite/binlog/t/binlog_index.test'
>> --- a/mysql-test/suite/binlog/t/binlog_index.test    2009-12-08 
>> 16:03:19 +0000
>> +++ b/mysql-test/suite/binlog/t/binlog_index.test    2010-12-02 
>> 02:56:34 +0000
>> @@ -230,6 +230,185 @@ flush logs;
>>   -- replace_regex /\.[\\\/]master/master/
>>   SELECT @index;
>>
>> +#
>> +# WL#5493
>> +# Test case6 verifies if the index file is complete and the binlog
>> +# file name is added after the master restarts when setting
>> +# DEBUG POINT before rename index file and appending binlog file name
>> +# to index file to cause the master crash.
>
> I would change this as follows
>
> Test case6 verifies if the index file has the correct data, i.e. if 
> binlog file name is added after the master restarts when setting
> DEBUG POINT before renaming index file.
Updated.
>
>> +#
>> +# Test case7 verifies if the index file is complete and the binlog
>> +# file name is added after the master restarts when setting
>> +# DEBUG POINT after rename index file and appending binlog file name
>> +# to index file to cause the master crash.
>
> See above.
Updated.
>
>> +#
>> +# Test case8 verifies if the index file is complete and is purged
>> +# successfully after the master restarts when setting DEBUG POINT
>> +# after rename index file and purging the index file to cause the
>> +# master crash.
>
> See above.
Updated.
>
>> +#
>> +# Test case9 verifies if the index file is complete and is purged
>> +# successfully after the master restarts when setting DEBUG POINT
>> +# before rename index file and purging the index file to cause the
>> +# master crash.
>
> See above.
Updated.
>
>> +#
>> +# Test case10 verifies if the index file is complete, although is
>> +# not purged successfully after the master restarts when injecting
>> +# a fault to the temp file and aborting the server after the temp
>> +# file is closed in the process of purging the index file
>> +#
>
> See above.
Updated.
>
>> +
>> +-- echo # Test case6: Set DEBUG POINT before rename index file to 
>> make the master
>> +-- echo #             crash when appending a binlog file name to 
>> index file.
>
> Set DEBUG POINT before renaming index file to when appending a binlog 
> file name to index file.
Updated.
>
>
>> +-- source include/show_binary_logs.inc
>> +file_exists $MYSQLD_DATADIR/master-bin.000013;
>> +--error 1
>> +file_exists $MYSQLD_DATADIR/master-bin.000014;
>> +
>> +# Write file to make mysql-test-run.pl expect crash and restart
>> +SET SESSION debug="+d,crash_create_before_rename_index_file";
>> +-- exec echo "restart">  $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
>> +
>> +--error 2013
>> +flush logs;
>> +
>> +-- source include/wait_until_disconnected.inc
>> +-- enable_reconnect
>> +-- echo # Restart the master server
>> +-- exec echo "restart">  $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
>> +-- source include/wait_until_connected_again.inc
>> +-- disable_reconnect
>> +
>> +-- echo # Test the index file is complete and binlog file name is 
>> added.
>
> Test if the index file has the correct data, i.e. binlog file name is
> added.
Updated.
>
>> +-- source include/show_binary_logs.inc
>> +file_exists $MYSQLD_DATADIR/master-bin.000014;
>> +file_exists $MYSQLD_DATADIR/master-bin.000015;
>> +--error 1
>> +file_exists $MYSQLD_DATADIR/master-bin.000016;
>> +
>> +-- echo # Test case7: Set DEBUG POINT after rename index file to 
>> make the master
>> +-- echo #             crash when appending a binlog file name to 
>> index file.
>
> See above.
Updated.
>
>> +# Write file to make mysql-test-run.pl expect crash and restart
>> +SET SESSION debug="+d,crash_create_after_rename_index_file";
>> +-- exec echo "restart">  $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
>> +
>> +-- error 2013
>> +flush logs;
>> +
>> +-- source include/wait_until_disconnected.inc
>> +-- enable_reconnect
>> +-- echo # Restart the master server
>> +-- exec echo "restart">  $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
>> +-- source include/wait_until_connected_again.inc
>> +-- disable_reconnect
>> +
>> +-- echo # Test the index file is complete and binlog file name is 
>> added.
>> +-- source include/show_binary_logs.inc
>
> See above... There are other case in what follows.
Updated.
>
>> +file_exists $MYSQLD_DATADIR/master-bin.000016;
>> +file_exists $MYSQLD_DATADIR/master-bin.000017;
>> +--error 1
>> +file_exists $MYSQLD_DATADIR/master-bin.000018;
>> +
>> +-- source include/show_binary_logs.inc

The following case is redundant.
>> +# Write file to make mysql-test-run.pl expect crash and restart
>> +SET SESSION debug="+d,crash_create_after_rename_index_file";
>> +-- exec echo "restart">  $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
>> +
>> +-- error 2013
>> +purge binary logs TO 'master-bin.000008';
>> +
>> +-- source include/wait_until_disconnected.inc
>> +-- enable_reconnect
>> +-- echo # Restart the master server
>> +-- exec echo "restart">  $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
>> +-- source include/wait_until_connected_again.inc
>> +-- disable_reconnect
>> +
>> +-- echo # Test the index file is complete and is purged successfully
>> +-- source include/show_binary_logs.inc
>> +--error 1
>> +file_exists $MYSQLD_DATADIR/master-bin.000006;
>> +--error 1
>> +file_exists $MYSQLD_DATADIR/master-bin.000007;
>> +file_exists $MYSQLD_DATADIR/master-bin.000008;
Yes. The above case is removed.
>> +
>> +-- echo # Test case8: Set DEBUG POINT after rename index file to 
>> make the master
>> +-- echo #             crash when purging the index file.
>> +
>> +-- source include/show_binary_logs.inc
>> +# Write file to make mysql-test-run.pl expect crash and restart
>> +SET SESSION debug="+d,crash_create_after_rename_index_file";
>> +-- exec echo "restart">  $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
>> +
>> +-- error 2013
>> +purge binary logs TO 'master-bin.000010';
>> +
>> +-- source include/wait_until_disconnected.inc
>> +-- enable_reconnect
>> +-- echo # Restart the master server
>> +-- exec echo "restart">  $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
>> +-- source include/wait_until_connected_again.inc
>> +-- disable_reconnect
>> +
>> +-- echo # Test the index file is complete, and is purged successfully.
>> +-- source include/show_binary_logs.inc
>> +-- error 1
>> +file_exists $MYSQLD_DATADIR/master-bin.000008;
>> +-- error 1
>> +file_exists $MYSQLD_DATADIR/master-bin.000009;
>> +file_exists $MYSQLD_DATADIR/master-bin.000010;
>> +
>> +-- echo # Test case9: Set DEBUG POINT befor rename index file to 
>> make the master
>> +-- echo #             crash when purging the index file.
>> +
>> +-- source include/show_binary_logs.inc
>> +# Write file to make mysql-test-run.pl expect crash and restart
>> +SET SESSION debug="+d,crash_create_before_rename_index_file";
>> +-- exec echo "restart">  $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
>> +
>> +-- error 2013
>> +purge binary logs TO 'master-bin.000012';
>> +
>> +-- source include/wait_until_disconnected.inc
>> +-- enable_reconnect
>> +-- echo # Restart the master server
>> +-- exec echo "restart">  $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
>> +-- source include/wait_until_connected_again.inc
>> +-- disable_reconnect
>> +
>> +-- echo # Test the index file is complete, and is purged successfully.
>> +-- source include/show_binary_logs.inc
>> +-- error 1
>> +file_exists $MYSQLD_DATADIR/master-bin.000010;
>> +-- error 1
>> +file_exists $MYSQLD_DATADIR/master-bin.000011;
>> +file_exists $MYSQLD_DATADIR/master-bin.000012;
>> +
>> +-- echo # Test case10: Inject a fault to copy part content to the 
>> temp file
>> +-- echo #             and abort the server after the temp file is 
>> closed
>> +-- echo #             when purging the index file.
>> +
>> +-- source include/show_binary_logs.inc
>> +# Write file to make mysql-test-run.pl expect crash and restart
>> +SET SESSION debug="+d,fault_injection_copy_part_file";
>> +-- exec echo "restart">  $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
>> +
>> +-- error 2013
>> +purge binary logs TO 'master-bin.000014';
>> +
>> +-- source include/wait_until_disconnected.inc
>> +-- enable_reconnect
>> +-- echo # Restart the master server
>> +-- exec echo "restart">  $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
>> +-- source include/wait_until_connected_again.inc
>> +-- disable_reconnect
>> +
>> +-- echo # Test the index file is complete, although is not purged 
>> successfully.
>> +-- source include/show_binary_logs.inc
>> +file_exists $MYSQLD_DATADIR/master-bin.000012;
>> +file_exists $MYSQLD_DATADIR/master-bin.000013;
>> +file_exists $MYSQLD_DATADIR/master-bin.000014;
>> +
>>   eval SET SESSION debug="$old";
>>
>>   --echo End of tests
>>
>> === added file 'mysql-test/suite/rpl/r/rpl_crashed_master.result'
>> --- a/mysql-test/suite/rpl/r/rpl_crashed_master.result    1970-01-01 
>> 00:00:00 +0000
>> +++ b/mysql-test/suite/rpl/r/rpl_crashed_master.result    2010-12-02 
>> 02:56:34 +0000
>> @@ -0,0 +1,150 @@
>> +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;
>> +STOP SLAVE;
>> +RESET MASTER;
>> +START SLAVE;
>> +call mtr.add_suppression("Attempting backtrace");
>> +call mtr.add_suppression("allocated tablespace *., old maximum was 0");
>> +call mtr.add_suppression("Error in Log_event::read_log_event()");
>> +call mtr.add_suppression("Buffered warning: Performance schema 
>> disabled");
>> +CREATE TABLE t1(a LONGBLOB) ENGINE=INNODB;
>> +# Test case1: Set DEBUG POINT before binlog to make
>> +#             the master crash for transaction
>> +BEGIN;
>> +INSERT INTO t1 (a) VALUES (REPEAT('a',2));
>> +INSERT INTO t1 (a) VALUES (REPEAT('a',2));
>> +INSERT INTO t1 (a) VALUES (REPEAT('a',2));
>> +SET SESSION debug="d,crash_commit_after_prepare";
>> +COMMIT;
>> +ERROR HY000: Lost connection to MySQL server during query
>> +# Restart the master server
>> +# Test the transaction statements will not be binlogged
>> +show binlog events in 'master-bin.000001' from<binlog_start>;
>> +Log_name    Pos    Event_type    Server_id    End_log_pos    Info
>> +master-bin.000001    #    Query    #    #    use `test`; CREATE 
>> TABLE t1(a LONGBLOB) ENGINE=INNODB
>> +# On master, test the data will be rolled back after restart.
>> +SELECT COUNT(*) FROM t1;
>> +COUNT(*)
>> +0
>> +# On slave, test replication will work fine, and the data
>> +#           is not replicated
>> +SELECT COUNT(*) FROM t1;
>> +COUNT(*)
>> +0
>> +# Test case2: Set DEBUG POINT after binlog, and before the date
>> +#             is committed to make crash for transaction
>> +BEGIN;
>> +INSERT INTO t1 (a) VALUES (REPEAT('a',2));
>> +INSERT INTO t1 (a) VALUES (REPEAT('a',2));
>> +INSERT INTO t1 (a) VALUES (REPEAT('a',2));
>> +SET SESSION debug="d,crash_commit_after_log";
>> +COMMIT;
>> +ERROR HY000: Lost connection to MySQL server during query
>> +# Restart the master server
>> +# Test the transaction statements will be binlogged
>> +show binlog events in 'master-bin.000002' from<binlog_start>;
>> +Log_name    Pos    Event_type    Server_id    End_log_pos    Info
>> +master-bin.000002    #    Query    #    #    BEGIN
>> +master-bin.000002    #    Table_map    #    #    table_id: # (test.t1)
>> +master-bin.000002    #    Write_rows    #    #    table_id: # flags: 
>> STMT_END_F
>> +master-bin.000002    #    Table_map    #    #    table_id: # (test.t1)
>> +master-bin.000002    #    Write_rows    #    #    table_id: # flags: 
>> STMT_END_F
>> +master-bin.000002    #    Table_map    #    #    table_id: # (test.t1)
>> +master-bin.000002    #    Write_rows    #    #    table_id: # flags: 
>> STMT_END_F
>> +master-bin.000002    #    Xid    #    #    COMMIT /* XID */
>> +# On master, test the data will be recovered after the master restart
>> +SELECT COUNT(*) FROM t1;
>> +COUNT(*)
>> +3
>> +# On slave, test replication will work fine, and the data is replicated
>> +SELECT COUNT(*) FROM t1;
>> +COUNT(*)
>> +3
>> +DROP TABLE t1;
>> +include/stop_slave.inc
>> +CREATE TABLE t1(a LONGBLOB) ENGINE=INNODB;
>> +# Test case3: Set DEBUG POINT in the middle of binlog to
>> +#             make the master crash for transaction.
>> +SET SESSION debug="d,half_binlogged_transaction";
>> +BEGIN;
>> +INSERT INTO t1 (a) VALUES (REPEAT('a',6144));
>> +INSERT INTO t1 (a) VALUES (REPEAT('a',6144));
>> +INSERT INTO t1 (a) VALUES (REPEAT('a',6144));
>> +INSERT INTO t1 (a) VALUES (REPEAT('a',6144));
>> +INSERT INTO t1 (a) VALUES (REPEAT('a',6144));
>> +INSERT INTO t1 (a) VALUES (REPEAT('a',6144));
>> +INSERT INTO t1 (a) VALUES (REPEAT('a',6144));
>> +INSERT INTO t1 (a) VALUES (REPEAT('a',6144));
>> +INSERT INTO t1 (a) VALUES (REPEAT('a',6144));
>> +INSERT INTO t1 (a) VALUES (REPEAT('a',6144));
>> +INSERT INTO t1 (a) VALUES (REPEAT('a',6144));
>> +INSERT INTO t1 (a) VALUES (REPEAT('a',6144));
>> +INSERT INTO t1 (a) VALUES (REPEAT('a',6144));
>> +INSERT INTO t1 (a) VALUES (REPEAT('a',6144));
>> +INSERT INTO t1 (a) VALUES (REPEAT('a',6144));
>> +INSERT INTO t1 (a) VALUES (REPEAT('a',6144));
>> +INSERT INTO t1 (a) VALUES (REPEAT('a',6144));
>> +INSERT INTO t1 (a) VALUES (REPEAT('a',6144));
>> +INSERT INTO t1 (a) VALUES (REPEAT('a',6144));
>> +INSERT INTO t1 (a) VALUES (REPEAT('a',6144));
>> +INSERT INTO t1 (a) VALUES (REPEAT('a',6144));
>> +INSERT INTO t1 (a) VALUES (REPEAT('a',6144));
>> +INSERT INTO t1 (a) VALUES (REPEAT('a',6144));
>> +INSERT INTO t1 (a) VALUES (REPEAT('a',6144));
>> +COMMIT;
>> +ERROR HY000: Lost connection to MySQL server during query
>> +# Restart the master server
>> +# Test the halfly binlogged transaction will be trimmed
>> +# from the crashed binlog file
>> +show binlog events in 'master-bin.000003' from<binlog_start>;
>> +Log_name    Pos    Event_type    Server_id    End_log_pos    Info
>> +master-bin.000003    #    Query    #    #    use `test`; CREATE 
>> TABLE t1(a LONGBLOB) ENGINE=INNODB
>> +# Test the data will not be recovered successfully
>> +# after the master restart.
>> +SELECT COUNT(*) FROM t1;
>> +COUNT(*)
>> +0
>> +# Test case4: Set DEBUG POINT in the middle of binlog to
>> +#             make the master crash for non-transaction.
>> +SET SESSION debug="d,half_binlogged_transaction";
>> +CREATE TABLE t2(a LONGBLOB) ENGINE=MYISAM;
>> +INSERT INTO t2 (a) VALUES (REPEAT('a',16384));
>> +ERROR HY000: Lost connection to MySQL server during query
>> +# Restart the master server
>> +# Test the halfly binlogged non-transaction statement will be trimmed
>> +# from the crashed binlog file
>> +show binlog events in 'master-bin.000004' from<binlog_start>;
>> +Log_name    Pos    Event_type    Server_id    End_log_pos    Info
>> +master-bin.000004    #    Query    #    #    use `test`; CREATE 
>> TABLE t2(a LONGBLOB) ENGINE=MYISAM
>> +# Test the data will not be recovered successfully
>> +# after the master restart.
>> +SELECT COUNT(*) FROM t2;
>> +COUNT(*)
>> +0
>> +# Test case5: Inject wrong value of crc for a log event, and
>> +#             then set DBUG POINT to casue the master crash.
>> +INSERT INTO t2 (a) VALUES (REPEAT('a',1));
>> +BEGIN;
>> +INSERT INTO t1 (a) VALUES (REPEAT('a',1));
>> +SET SESSION debug="d,fault_injection_crc_value";
>> +INSERT INTO t1 (a) VALUES (REPEAT('a',2));
>> +COMMIT;
>> +BEGIN;
>> +INSERT INTO t1 (a) VALUES (REPEAT('a',3));
>> +SET SESSION debug="d,crash_commit_after_prepare";
>> +COMMIT;
>> +ERROR HY000: Lost connection to MySQL server during query
>> +# Restart the master server
>> +# Test the transaction with a log event injected a wrong crc value
>> +# will be trimmed from the crashed binlog file
>> +show binlog events in 'master-bin.000005' from<binlog_start>;
>> +Log_name    Pos    Event_type    Server_id    End_log_pos    Info
>> +master-bin.000005    #    Query    #    #    BEGIN
>> +master-bin.000005    #    Table_map    #    #    table_id: # (test.t2)
>> +master-bin.000005    #    Write_rows    #    #    table_id: # flags: 
>> STMT_END_F
>> +master-bin.000005    #    Query    #    #    COMMIT
>> +DROP TABLE t1, t2;
>>
>> === added file 'mysql-test/suite/rpl/t/rpl_crashed_master-master.opt'
>> --- a/mysql-test/suite/rpl/t/rpl_crashed_master-master.opt    
>> 1970-01-01 00:00:00 +0000
>> +++ b/mysql-test/suite/rpl/t/rpl_crashed_master-master.opt    
>> 2010-12-02 02:56:34 +0000
>> @@ -0,0 +1 @@
>> +--binlog-checksum=CRC32 --master-verify-checksum=1
>>
>> === added file 'mysql-test/suite/rpl/t/rpl_crashed_master.test'
>> --- a/mysql-test/suite/rpl/t/rpl_crashed_master.test    1970-01-01 
>> 00:00:00 +0000
>> +++ b/mysql-test/suite/rpl/t/rpl_crashed_master.test    2010-12-02 
>> 02:56:34 +0000
>> @@ -0,0 +1,237 @@
>> +#
>> +# WL#5493&  WL#5440
>> +# Test case1 verifies if the transaction statements will not be
>> +# binlogged and replication will work fine, but the data will
>> +# be rolled back on master after the master restarts when setting
>> +# DEBUG POINT before binlog to make the master crash.
>> +#
>> +# Test case2 verifies if the transaction statements will be
>> +# binlogged and replication will work fine, and the data will
>> +# be recovered after the master restarts when setting DEBUG
>> +# POINT after binlog, and before the date is committed to make
>> +# the master crash.
>> +#
>> +# Test case3 verifies if the halfly binlogged transaction
>> +# statements will be trimmed from the crashed binlog file
>> +# and the data will not be recovered successfully after
>> +# the master restarts when setting DEBUG POINT in the
>> +# middle of binlog to make the master crash
>> +#
>> +# Test case4 verifies if the halfly binlogged non-transaction
>> +# statement will be trimmed from the crashed binlog file
>> +# and the data will not be recovered successfully after
>> +# the master restarts when setting DEBUG POINT in the
>> +# middle of binlog to make the master crash.
>> +#
>> +# Test case5 verifies if a transaction with a wrong crc value
>> +# will be trimmed from the crashed binlog file after
>> +# master restarts when injecting a wrong crc value
>> +# for a statment of the transaction and then setting
>> +# DEBUG POINT to cause master crash.
>> +#
>> +
>> +# Don't test this under valgrind, memory leaks will occur
>> +-- source include/not_valgrind.inc
>> +-- source include/not_embedded.inc
>> +-- source include/master-slave.inc
>> +-- source include/have_debug.inc
>> +-- source include/have_innodb.inc
>> +-- source include/have_binlog_format_row.inc
>> +
>> +# Reset master
>> +connection slave;
>> +STOP SLAVE;
>> +--source include/wait_for_slave_to_stop.inc
>
> please, use --source include/stop_slave.inc
Updated.
>
>> +
>> +connection master;
>> +RESET MASTER;
>> +
>> +connection slave;
>> +START SLAVE;
>> +--source include/wait_for_slave_to_start.inc
>
> please, use --source include/start_slave.inc
Updated.
>
>> +
>> +connection master;
>> +call mtr.add_suppression("Attempting backtrace");
>> +call mtr.add_suppression("allocated tablespace *., old maximum was 0");
>> +call mtr.add_suppression("Error in Log_event::read_log_event()");
>> +call mtr.add_suppression("Buffered warning: Performance schema 
>> disabled");
>
> Please, move to this part of the code to beginning and call 
> syn_slave_with_master.
I had tried to do that. But the test is blocked.
And we don't need call syn_slave_with_master,
because the they will be synced by default.
in worse case, the slave will not cause these
error at all in the test.
>
>
>> +-- let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1)
>> +-- let $binlog_file= query_get_value(SHOW MASTER STATUS, File, 1)
>> +CREATE TABLE t1(a LONGBLOB) ENGINE=INNODB;
>> +
>> +-- echo # Test case1: Set DEBUG POINT before binlog to make
>> +-- echo #             the master crash for transaction
>> +#SET SESSION debug="d,crash_trans_commit_before_binlog";
>> +BEGIN;
>> +let $rows= 3;
>> +WHILE($rows)
>> +{
>> +  INSERT INTO t1 (a) VALUES (REPEAT('a',2));
>> +  dec $rows;
>> +}
>> +# Write file to make mysql-test-run.pl expect crash and restart
>> +-- exec echo "restart">  $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
>> +SET SESSION debug="d,crash_commit_after_prepare";
>> +# Run the crashing query
>> +-- error 2013
>> +COMMIT;
>
> Use the following pattern
>
> --exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
> # CRASH OR SHUTDOWN
> --source include/wait_until_disconnected.inc
> --enable_reconnect
> --exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
> --source include/wait_until_connected_again.inc
Sure. Updated.
>
>
>> +
>> +-- source include/wait_until_disconnected.inc
>> +-- enable_reconnect
>> +-- echo # Restart the master server
>> +-- exec echo "restart">  $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
>> +-- source include/wait_until_connected_again.inc
>> +-- disable_reconnect
>> +
>> +-- echo # Test the transaction statements will not be binlogged
>> +-- source include/show_binlog_events.inc
>> +
>> +-- echo # On master, test the data will be rolled back after restart.
>> +SELECT COUNT(*) FROM t1;
>> +
>> +sync_slave_with_master;
>> +-- echo # On slave, test replication will work fine, and the data
>> +-- echo #           is not replicated
>> +SELECT COUNT(*) FROM t1;
>> +
>> +connection master;
>> +-- let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1)
>> +-- let $binlog_file= query_get_value(SHOW MASTER STATUS, File, 1)
>> +-- echo # Test case2: Set DEBUG POINT after binlog, and before the date
>> +-- echo #             is committed to make crash for transaction
>> +#SET SESSION debug="d,crash_trans_commit_after_binlog";
>> +BEGIN;
>> +let $rows= 3;
>> +WHILE($rows)
>> +{
>> +  INSERT INTO t1 (a) VALUES (REPEAT('a',2));
>> +  dec $rows;
>> +}
>> +# Write file to make mysql-test-run.pl expect crash and restart
>> +-- exec echo "restart">  $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
>> +SET SESSION debug="d,crash_commit_after_log";
>> +# Run the crashing query
>> +-- error 2013
>> +COMMIT;
>> +
>> +-- source include/wait_until_disconnected.inc
>> +-- enable_reconnect
>> +-- echo # Restart the master server
>> +-- exec echo "restart">  $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
>> +-- source include/wait_until_connected_again.inc
>> +-- disable_reconnect
>> +
>> +-- echo # Test the transaction statements will be binlogged
>> +-- source include/show_binlog_events.inc
>> +
>> +-- echo # On master, test the data will be recovered after the 
>> master restart
>> +SELECT COUNT(*) FROM t1;
>> +
>> +sync_slave_with_master;
>> +-- echo # On slave, test replication will work fine, and the data is 
>> replicated
>> +SELECT COUNT(*) FROM t1;
>> +
>> +connection master;
>> +DROP TABLE t1;
>> +sync_slave_with_master;
>> +
>> +-- source include/stop_slave.inc
>> +
>> +connection master;
>> +-- let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1)
>> +-- let $binlog_file= query_get_value(SHOW MASTER STATUS, File, 1)
>> +# Test transaction with large data inserted
>> +CREATE TABLE t1(a LONGBLOB) ENGINE=INNODB;
>> +
>> +-- echo # Test case3: Set DEBUG POINT in the middle of binlog to
>> +-- echo #             make the master crash for transaction.
>> +SET SESSION debug="d,half_binlogged_transaction";
>> +BEGIN;
>> +let $rows= 24;
>> +WHILE($rows)
>> +{
>> +  INSERT INTO t1 (a) VALUES (REPEAT('a',6144));
>> +  dec $rows;
>> +}
>> +# Write file to make mysql-test-run.pl expect crash and restart
>> +-- exec echo "restart">  $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
>> +# Run the crashing query
>> +-- error 2013
>> +COMMIT;
>> +
>> +-- source include/wait_until_disconnected.inc
>> +-- enable_reconnect
>> +-- echo # Restart the master server
>> +-- exec echo "restart">  $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
>> +-- source include/wait_until_connected_again.inc
>> +-- disable_reconnect
>> +
>> +-- echo # Test the halfly binlogged transaction will be trimmed
>> +-- echo # from the crashed binlog file
>> +-- source include/show_binlog_events.inc
>> +
>> +-- echo # Test the data will not be recovered successfully
>> +-- echo # after the master restart.
>> +SELECT COUNT(*) FROM t1;
>> +
>> +-- echo # Test case4: Set DEBUG POINT in the middle of binlog to
>> +-- echo #             make the master crash for non-transaction.
>> +SET SESSION debug="d,half_binlogged_transaction";
>> +# Write file to make mysql-test-run.pl expect crash and restart
>> +-- exec echo "restart">  $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
>> +-- let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1)
>> +-- let $binlog_file= query_get_value(SHOW MASTER STATUS, File, 1)
>> +CREATE TABLE t2(a LONGBLOB) ENGINE=MYISAM;
>> +-- error 2013
>> +INSERT INTO t2 (a) VALUES (REPEAT('a',16384));
>> +
>> +-- source include/wait_until_disconnected.inc
>> +-- enable_reconnect
>> +-- echo # Restart the master server
>> +-- exec echo "restart">  $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
>> +-- source include/wait_until_connected_again.inc
>> +-- disable_reconnect
>> +
>> +-- echo # Test the halfly binlogged non-transaction statement will 
>> be trimmed
>> +-- echo # from the crashed binlog file
>> +-- source include/show_binlog_events.inc
>> +
>> +-- echo # Test the data will not be recovered successfully
>> +-- echo # after the master restart.
>> +SELECT COUNT(*) FROM t2;
>> +
>> +-- echo # Test case5: Inject wrong value of crc for a log event, and
>> +-- echo #             then set DBUG POINT to casue the master crash.
>> +# Write file to make mysql-test-run.pl expect crash and restart
>> +-- exec echo "restart">  $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
>> +-- let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1)
>> +-- let $binlog_file= query_get_value(SHOW MASTER STATUS, File, 1)
>> +INSERT INTO t2 (a) VALUES (REPEAT('a',1));
>> +
>> +BEGIN;
>> +INSERT INTO t1 (a) VALUES (REPEAT('a',1));
>> +SET SESSION debug="d,fault_injection_crc_value";
>> +INSERT INTO t1 (a) VALUES (REPEAT('a',2));
>> +COMMIT;
>> +
>> +BEGIN;
>> +INSERT INTO t1 (a) VALUES (REPEAT('a',3));
>> +SET SESSION debug="d,crash_commit_after_prepare";
>> +# Run the crashing query
>> +-- error 2013
>> +COMMIT;
>> +
>> +-- source include/wait_until_disconnected.inc
>> +-- enable_reconnect
>> +-- echo # Restart the master server
>> +-- exec echo "restart">  $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
>> +-- source include/wait_until_connected_again.inc
>> +-- disable_reconnect
>> +
>> +-- echo # Test the transaction with a log event injected a wrong crc 
>> value
>> +-- echo # will be trimmed from the crashed binlog file
>> +-- source include/show_binlog_events.inc
>> +
>> +DROP TABLE t1, t2;
>> +
>>
>> === removed file 'mysql-test/t/crash_commit_before-master.opt'
>> --- a/mysql-test/t/crash_commit_before-master.opt    2010-06-21 
>> 07:58:54 +0000
>> +++ b/mysql-test/t/crash_commit_before-master.opt    1970-01-01 
>> 00:00:00 +0000
>> @@ -1,3 +0,0 @@
>> ---skip-stack-trace --skip-core-file
>> ---default-storage-engine=MyISAM
>> ---innodb-file-per-table=0
>
> ok.
>
>>
>> === removed file 'mysql-test/t/crash_commit_before.test'
>> --- a/mysql-test/t/crash_commit_before.test    2007-12-12 17:19:24 +0000
>> +++ b/mysql-test/t/crash_commit_before.test    1970-01-01 00:00:00 +0000
>> @@ -1,35 +0,0 @@
>> --- source include/not_embedded.inc
>> -# Don't test this under valgrind, memory leaks will occur
>> ---source include/not_valgrind.inc
>> -
>> -# Binary must be compiled with debug for crash to occur
>> ---source include/have_debug.inc
>> -
>> ---source include/have_innodb.inc
>> -
>> -CREATE TABLE t1(a int) engine=innodb;
>> -START TRANSACTION;
>> -insert into t1 values(9);
>> -
>> -# Setup the mysqld to crash at certain point
>> -SET SESSION debug="d,crash_commit_before";
>> -
>> -# Write file to make mysql-test-run.pl expect crash and restart
>> ---exec echo "restart">  $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
>> -
>> -# Run the crashing query
>> ---error 2013
>> -COMMIT;
>> -
>> -# Turn on reconnect
>> ---enable_reconnect
>> -
>> -# Call script that will poll the server waiting for it to be back 
>> online again
>> ---source include/wait_until_connected_again.inc
>> -
>> -SHOW CREATE TABLE t1;
>> -
>> -SELECT * FROM t1;
>> -
>> -
>> -DROP TABLE t1;
>>
>
> ok.
>
>
>> === modified file 'mysys/my_rename.c'
>> --- a/mysys/my_rename.c    2010-07-15 11:41:37 +0000
>> +++ b/mysys/my_rename.c    2010-12-02 02:56:34 +0000
>> @@ -52,8 +52,6 @@ int my_rename(const char *from, const ch
>>   #else
>>   #if defined(HAVE_RENAME)
>>     if (rename(from,to))
>> -#else
>> -  if (link(from, to) || unlink(from))
>>   #endif
>>     {
>>       my_errno=errno;
>>
>
> Please, remove the #ifdef.
> Have you checked this with runtime?
Yes. Checked. Removed.
>
>> === modified file 'sql/binlog.cc'
>> --- a/sql/binlog.cc    2010-11-16 12:14:06 +0000
>> +++ b/sql/binlog.cc    2010-12-02 02:56:34 +0000
>> @@ -1138,58 +1138,51 @@ int query_error_code(THD *thd, bool not_
>>
>>
>>   /**
>> -  Move all data up in a file in an filename index file.
>> +  Copy content of 'from' file from offset to 'to' file.
>>
>> -    We do the copy outside of the IO_CACHE as the cache buffers 
>> would just
>> -    make things slower and more complicated.
>> -    In most cases the copy loop should only do one read.
>> +  - We do the copy outside of the IO_CACHE as the cache
>> +  buffers would just make things slower and more complicated.
>> +  In most cases the copy loop should only do one read.
>>
>> -  @param index_file            File to move
>> -  @param offset            Move everything from here to beginning
>> +  @param from          File to copy.
>> +  @param to            File to copy to.
>> +  @param offset        Offset in 'from' file.
>>
>> -  @note
>> -    File will be truncated to be 'offset' shorter or filled up with 
>> newlines
>>
>>     @retval
>> -    0    ok
>> +    0    ok
>> +  @retval
>> +    -1    error
>>   */
>> -
>> -#ifdef HAVE_REPLICATION
>> -
>> -static bool copy_up_file_and_fill(IO_CACHE *index_file, my_off_t 
>> offset)
>> +static bool copy_file(IO_CACHE *from, IO_CACHE *to, my_off_t offset)
>>   {
>>     int bytes_read;
>> -  my_off_t init_offset= offset;
>> -  File file= index_file->file;
>>     uchar io_buf[IO_SIZE*2];
>> -  DBUG_ENTER("copy_up_file_and_fill");
>> +  DBUG_ENTER("copy_file");
>>
>> -  for (;; offset+= bytes_read)
>> +  mysql_file_seek(from->file, offset, MY_SEEK_SET, MYF(0));
>> +  while(TRUE)
>>     {
>> -    mysql_file_seek(file, offset, MY_SEEK_SET, MYF(0));
>> -    if ((bytes_read= (int) mysql_file_read(file, io_buf, 
>> sizeof(io_buf),
>> +    if ((bytes_read= (int) mysql_file_read(from->file, io_buf, 
>> sizeof(io_buf),
>>                                              MYF(MY_WME)))
>> - <  0)
>> +<  0)
>>         goto err;
>> +    if (DBUG_EVALUATE_IF("fault_injection_copy_part_file", 1, 0))
>> +      bytes_read= bytes_read/2;
>>       if (!bytes_read)
>> -      break;                    // end of file
>> -    mysql_file_seek(file, offset-init_offset, MY_SEEK_SET, MYF(0));
>> -    if (mysql_file_write(file, io_buf, bytes_read, MYF(MY_WME | 
>> MY_NABP)))
>> +      break;                                    // end of file
>> +    if (mysql_file_write(to->file, io_buf, bytes_read, MYF(MY_WME | 
>> MY_NABP)))
>>         goto err;
>>     }
>> -  /* The following will either truncate the file or fill the end 
>> with \n' */
>> -  if (mysql_file_chsize(file, offset - init_offset, '\n', 
>> MYF(MY_WME)) ||
>> -      mysql_file_sync(file, MYF(MY_WME)))
>> -    goto err;
>>
>> -  /* Reset data in old index cache */
>> -  reinit_io_cache(index_file, READ_CACHE, (my_off_t) 0, 0, 1);
>>     DBUG_RETURN(0);
>>
>>   err:
>>     DBUG_RETURN(1);
>>   }
>>
>> +
>> +#ifdef HAVE_REPLICATION
>>   /**
>>      Load data's io cache specific hook to be executed
>>      before a chunk of data is being read into the cache's buffer
>> @@ -1443,6 +1436,7 @@ MYSQL_BIN_LOG::MYSQL_BIN_LOG(uint *sync_
>>     index_file_name[0] = 0;
>>     bzero((char*)&index_file, sizeof(index_file));
>>     bzero((char*)&purge_index_file, sizeof(purge_index_file));
>> +  bzero((char*)&crash_safe_index_file, sizeof(crash_safe_index_file));
>>   }
>>
>>   /* this is called only once */
>> @@ -1489,6 +1483,7 @@ bool MYSQL_BIN_LOG::open_index_file(cons
>>                                       const char *log_name, bool 
>> need_mutex)
>>   {
>>     File index_file_nr= -1;
>> +  bool need_rename= FALSE;
>>     DBUG_ASSERT(!my_b_inited(&index_file));
>>
>>     /*
>> @@ -1504,6 +1499,36 @@ bool MYSQL_BIN_LOG::open_index_file(cons
>>     }
>>     fn_format(index_file_name, index_file_name_arg, mysql_data_home,
>>               ".index", opt);
>> +
>> +  if (set_crash_safe_index_file_name(index_file_name_arg))
>> +  {
>> +    sql_print_error("MYSQL_BIN_LOG::set_crash_safe_index_file_name 
>> failed.");
>> +    return TRUE;
>> +  }
>> +
>> +  /*
>> +    We need move crash_safe_index_file to index_file if the index_file
>> +    does not exist and crash_safe_index_file exists when mysqld server
>> +    restarts.
>> +  */
>> +#ifdef __WIN__
>> +  if (my_access(index_file_name, F_OK)&&
>> +      !my_access(crash_safe_index_file_name, F_OK))
>> +    need_rename= TRUE;
>> +#else
>> +  if (access(index_file_name, F_OK)&&
>> +      !access(crash_safe_index_file_name, F_OK))
>> +    need_rename= TRUE;
>> +#endif
>
> We don't need this here. Notice that you have the following
> definition in include/my_sys.h:
>
> #ifdef _WIN32
> extern int      my_access(const char *path, int amode);
> #else
> #define my_access access
> #endif
Updated.
>
>
>> +
>> +  if (need_rename&&
>> +      my_rename(crash_safe_index_file_name, index_file_name, 
>> MYF(MY_WME)))
>> +  {
>> +    sql_print_error("MYSQL_BIN_LOG::open_index_file failed to "
>> +                    "move crash_safe_index_file to index file.");
>> +    return TRUE;
>> +  }
>> +
>>     if ((index_file_nr= mysql_file_open(key_file_binlog_index,
>>                                         index_file_name,
>>                                         O_RDWR | O_CREAT | O_BINARY,
>
> See comment above on init_io_cache.
Replied.
>
>> @@ -1711,18 +1736,15 @@ bool MYSQL_BIN_LOG::open(const char *log
>>   #endif
>>
>>         DBUG_ASSERT(my_b_inited(&index_file) != 0);
>> -      reinit_io_cache(&index_file, WRITE_CACHE,
>> -                      my_b_filelength(&index_file), 0, 0);
>> +
>>         /*
>> -        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.
>> +        The new log file name is appended into crash safe index file 
>> after
>> +        all the content of index file is copyed into the crash safe 
>> index
>> +        file. Then move the crash safe index file to index file.
>>         */
>>         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*) "\n", 1) ||
>> -          flush_io_cache(&index_file) ||
>> -          mysql_file_sync(index_file.file, MYF(MY_WME)))
>> +          add_log_to_index((uchar*) log_file_name, 
>> strlen(log_file_name),
>> +                           need_mutex))
>>           goto err;
>>
>>   #ifdef HAVE_REPLICATION
>
> ok.
>
>> @@ -1759,6 +1781,135 @@ shutdown the MySQL server and restart it
>>   }
>>
>>
>> +/**
>> +  Move crash safe index file to index file.
>> +
>> +  @param need_mutex    Set it to FALSE if its caller already has a
>> +                       lock on LOCK_index
>> +
>> +  @retval
>> +    0    ok
>> +  @retval
>> +    -1    error
>> +*/
>> +int MYSQL_BIN_LOG::move_crash_safe_index_file_to_index_file(bool 
>> need_mutex)
>> +{
>> +  int error= 0;
>> +  File fd= -1;
>> +  
>> DBUG_ENTER("MYSQL_BIN_LOG::move_crash_safe_index_file_to_index_file");
>> +
>> +  if (need_mutex)
>> +    mysql_mutex_lock(&LOCK_index);
>> +  mysql_mutex_assert_owner(&LOCK_index);
>> +
>> +  if (my_b_inited(&index_file))
>> +  {
>> +    end_io_cache(&index_file);
>> +    if (mysql_file_close(index_file.file, MYF(0))<  0)
>> +    {
>> +      error= -1;
>> +      
>> sql_print_error("MYSQL_BIN_LOG::move_crash_safe_index_file_to_index_file 
>> "
>> +                      "failed to close the index file.");
>> +      goto err;
>> +    }
>> +    mysql_file_delete(key_file_binlog_index, index_file_name, 
>> MYF(MY_WME));
>> +  }
>> +
>> +  DBUG_EXECUTE_IF("crash_create_before_rename_index_file", 
>> DBUG_SUICIDE(););
>> +  if (my_rename(crash_safe_index_file_name, index_file_name, 
>> MYF(MY_WME)))
>> +  {
>> +    error= -1;
>> +    
>> sql_print_error("MYSQL_BIN_LOG::move_crash_safe_index_file_to_index_file 
>> "
>> +                    "failed to move crash_safe_index_file to index 
>> file.");
>> +    goto err;
>> +  }
>> +  DBUG_EXECUTE_IF("crash_create_after_rename_index_file", 
>> DBUG_SUICIDE(););
>> +
>> +  if ((fd= mysql_file_open(key_file_binlog_index,
>> +                           index_file_name,
>> +                           O_RDWR | O_CREAT | O_BINARY,
>> +                           MYF(MY_WME)))<  0 ||
>> +           mysql_file_sync(fd, MYF(MY_WME)) ||
>> +           init_io_cache(&index_file, fd, IO_SIZE, READ_CACHE,
>> +                         mysql_file_seek(fd, 0L, MY_SEEK_END, MYF(0)),
>> +                                         0, MYF(MY_WME | 
>> MY_WAIT_IF_FULL)))
>
>
> See comment above on init_io_cache.
>
>> +  {
>> +    error= -1;
>> +    
>> sql_print_error("MYSQL_BIN_LOG::move_crash_safe_index_file_to_index_file 
>> "
>> +                      "failed to open the index file.");
>> +    goto err;
>> +  }
>> +
>> +err:
>> +  if (need_mutex)
>> +    mysql_mutex_unlock(&LOCK_index);
>> +  DBUG_RETURN(error);
>> +}
>> +
>> +
>> +/**
>> +  Append log file name to index file.
>> +
>> +  - To make crash safe, we copy all the content of index file
>> +  to crash safe index file firstly and then append the log
>> +  file name to the crash safe index file. Finally move the
>> +  crash safe index file to index file.
>> +
>> +  @retval
>> +    0   ok
>> +  @retval
>> +    -1   error
>> +*/
>> +int MYSQL_BIN_LOG::add_log_to_index(uchar* log_file_name,
>> +                                    int name_len, bool need_mutex)
>> +{
>> +  DBUG_ENTER("MYSQL_BIN_LOG::add_log_to_index");
>> +
>> +  if (open_crash_safe_index_file())
>> +  {
>> +    sql_print_error("MYSQL_BIN_LOG::add_log_to_index failed to "
>> +                    "open the crash safe index file.");
>> +    goto err;
>> +  }
>> +
>> +  if (copy_file(&index_file,&crash_safe_index_file, 0))
>> +  {
>> +    sql_print_error("MYSQL_BIN_LOG::add_log_to_index failed to "
>> +                    "copy index file to crash safe index file.");
>> +    goto err;
>> +  }
>> +
>> +  if (my_b_write(&crash_safe_index_file, log_file_name, name_len) ||
>> +      my_b_write(&crash_safe_index_file, (uchar*) "\n", 1) ||
>> +      flush_io_cache(&crash_safe_index_file) ||
>> +      mysql_file_sync(crash_safe_index_file.file, MYF(MY_WME)))
>> +  {
>> +    sql_print_error("MYSQL_BIN_LOG::add_log_to_index failed to "
>> +                    "append log file name: %s, to crash "
>> +                    "safe index file.", log_file_name);
>> +    goto err;
>> +  }
>> +
>> +  if (close_crash_safe_index_file())
>> +  {
>> +    sql_print_error("MYSQL_BIN_LOG::add_log_to_index failed to "
>> +                    "close the crash safe index file.");
>> +    goto err;
>> +  }
>> +
>> +  if (move_crash_safe_index_file_to_index_file(need_mutex))
>> +  {
>> +    sql_print_error("MYSQL_BIN_LOG::add_log_to_index failed to "
>> +                    "move crash safe index file to index file.");
>> +    goto err;
>> +  }
>> +
>> +  DBUG_RETURN(0);
>> +
>> +err:
>> +  DBUG_RETURN(-1);
>> +}
>> +
>>   int MYSQL_BIN_LOG::get_current_log(LOG_INFO* linfo)
>>   {
>>     mysql_mutex_lock(&LOCK_log);
>
> ok.
>
>> @@ -2082,6 +2233,92 @@ err:
>>
>>
>>   /**
>> +  Set the name of crash safe index file.
>> +
>> +  @retval
>> +    0   ok
>> +  @retval
>> +    1   error
>> +*/
>> +int MYSQL_BIN_LOG::set_crash_safe_index_file_name(const char 
>> *base_file_name)
>> +{
>> +  int error= 0;
>> +  DBUG_ENTER("MYSQL_BIN_LOG::set_crash_safe_index_file_name");
>> +  if (fn_format(crash_safe_index_file_name, base_file_name, 
>> mysql_data_home,
>> +                ".index_crash_safe", MYF(MY_UNPACK_FILENAME | 
>> MY_SAFE_PATH |
>> +                                         MY_REPLACE_EXT)) == NULL)
>> +  {
>> +    error= 1;
>> +    sql_print_error("MYSQL_BIN_LOG::set_crash_safe_index_file_name 
>> failed "
>> +                    "to set file name.");
>> +  }
>> +  DBUG_RETURN(error);
>> +}
>> +
>> +
>> +/**
>> +  Open a (new) crash safe index file.
>> +
>> +  @note
>> +    The crash safe index file is a special file
>> +    used for guaranteeing index file crash safe.
>> +  @retval
>> +    0   ok
>> +  @retval
>> +    1   error
>> +*/
>> +int MYSQL_BIN_LOG::open_crash_safe_index_file()
>> +{
>> +  int error= 0;
>> +  File file= -1;
>> +
>> +  DBUG_ENTER("MYSQL_BIN_LOG::open_crash_safe_index_file");
>> +
>> +  if (!my_b_inited(&crash_safe_index_file))
>> +  {
>> +    if ((file= my_open(crash_safe_index_file_name, O_RDWR | O_CREAT 
>> | O_BINARY,
>> +                       MYF(MY_WME | ME_WAITTANG)))<  0  ||
>> +        init_io_cache(&crash_safe_index_file, file, IO_SIZE, 
>> WRITE_CACHE,
>> +                      0, 0, MYF(MY_WME | MY_NABP | MY_WAIT_IF_FULL)))
>> +    {
>> +      error= 1;
>> +      sql_print_error("MYSQL_BIN_LOG::open_crash_safe_index_file 
>> failed "
>> +                      "to open temporary index file.");
>> +    }
>> +  }
>> +  DBUG_RETURN(error);
>> +}
>> +
>> +
>> +/**
>> +  Close the crash safe index file.
>> +
>> +  @note
>> +    The crash safe file is just closed, is not deleted.
>> +    Because it is moved to index file later on.
>> +  @retval
>> +    0   ok
>> +  @retval
>> +    1   error
>> +*/
>> +int MYSQL_BIN_LOG::close_crash_safe_index_file()
>> +{
>> +  int error= 0;
>> +
>> +  DBUG_ENTER("MYSQL_BIN_LOG::close_crash_safe_index_file");
>> +
>> +  if (my_b_inited(&crash_safe_index_file))
>> +  {
>> +    end_io_cache(&crash_safe_index_file);
>> +    error= my_close(crash_safe_index_file.file, MYF(0));
>> +  }
>> +  bzero((char*)&crash_safe_index_file, sizeof(crash_safe_index_file));
>> +
>> +  DBUG_RETURN(error);
>> +}
>> +
>> +
>> +/**
>>     Delete relay log files prior to rli->group_relay_log_name
>>     (i.e. all logs which are not involved in a non-finished group
>>     (transaction)), remove them from the index file and start on next
>
> ok.
>
>> @@ -2216,19 +2453,67 @@ err:
>>     DBUG_RETURN(error);
>>   }
>>
>> +
>>   /**
>> -  Update log index_file.
>> -*/
>> +  Remove logs from index file.
>> +
>> +  - To make crash safe, we copy the content of index file
>> +  from index_file_start_offset recored in log_info to
>> +  crash safe index file firstly and then move the crash
>> +  safe index file to index file.
>> +
>> +  @param linfo                  Store here the found log file name and
>> +                                position to the NEXT log file name in
>> +                                the index file.
>>
>> -int MYSQL_BIN_LOG::update_log_index(LOG_INFO* log_info, bool 
>> need_update_threads)
>> +  @param need_update_threads    If we want to update the log 
>> coordinates
>> +                                of all threads. False for relay logs,
>> +                                true otherwise.
>> +
>> +  @retval
>> +    0    ok
>> +  @retval
>> +    LOG_INFO_IO    Got IO error while reading/writing file
>> +*/
>
>
> ok.
>
>> +int MYSQL_BIN_LOG::remove_logs_from_index(LOG_INFO* log_info, bool 
>> need_update_threads)
>>   {
>> -  if (copy_up_file_and_fill(&index_file, 
>> log_info->index_file_start_offset))
>> -    return LOG_INFO_IO;
>> +  if (open_crash_safe_index_file())
>> +  {
>> +    sql_print_error("MYSQL_BIN_LOG::remove_logs_from_index failed to "
>> +                    "open the crash safe index file.");
>> +    goto err;
>> +  }
>> +
>> +  if (copy_file(&index_file,&crash_safe_index_file,
>> +                log_info->index_file_start_offset))
>> +  {
>> +    sql_print_error("MYSQL_BIN_LOG::remove_logs_from_index failed to "
>> +                    "copy index file to crash safe index file.");
>> +    goto err;
>> +  }
>> +
>> +  if (close_crash_safe_index_file())
>> +  {
>> +    sql_print_error("MYSQL_BIN_LOG::remove_logs_from_index failed to "
>> +                    "close the crash safe index file.");
>> +    goto err;
>> +  }
>> +  DBUG_EXECUTE_IF("fault_injection_copy_part_file", DBUG_SUICIDE(););
>> +
>> +  if (move_crash_safe_index_file_to_index_file(FALSE))
>> +  {
>> +    sql_print_error("MYSQL_BIN_LOG::remove_logs_from_index failed to "
>> +                    "move crash safe index file to index file.");
>> +    goto err;
>> +  }
>>
>>     // now update offsets in index file for running threads
>>     if (need_update_threads)
>>       adjust_linfo_offsets(log_info->index_file_start_offset);
>>     return 0;
>> +
>> +err:
>> +  return LOG_INFO_IO;
>>   }
>
>
> ok.
>
>>
>>   /**
>> @@ -2313,7 +2598,7 @@ int MYSQL_BIN_LOG::purge_logs(const char
>>     }
>>
>>     /* We know how many files to delete. Update index file. */
>> -  if ((error=update_log_index(&log_info, need_update_threads)))
>> +  if ((error=remove_logs_from_index(&log_info, need_update_threads)))
>>     {
>>       sql_print_error("MSYQL_BIN_LOG::purge_logs failed to update the 
>> index file");
>>       goto err;
>> @@ -3386,6 +3671,9 @@ int MYSQL_BIN_LOG::write_cache(IO_CACHE
>>     if (do_checksum)
>>       crc= crc_0= my_checksum(0L, NULL, 0);
>>
>> +  if (DBUG_EVALUATE_IF("fault_injection_crc_value", 1, 0))
>> +    crc= crc - 1;
>> +
>>     do
>>     {
>>       /*
>
> ok.
>
>> @@ -3655,9 +3943,9 @@ bool MYSQL_BIN_LOG::write(THD *thd, IO_C
>>           goto err;
>>
>>         bool synced= 0;
>> +      DBUG_EXECUTE_IF("half_binlogged_transaction", DBUG_SUICIDE(););
>>         if (flush_and_sync(&synced))
>>           goto err;
>> -      DBUG_EXECUTE_IF("half_binlogged_transaction", DBUG_SUICIDE(););
>>         if (cache->error)                // Error on read
>>         {
>>           sql_print_error(ER(ER_ERROR_ON_READ), cache->file_name, 
>> errno);
>
> ok.
>
>> @@ -3920,6 +4208,9 @@ int MYSQL_BIN_LOG::open(const char *opt_
>>       Log_event  *ev=0;
>>       Format_description_log_event fdle(BINLOG_VERSION);
>>       char        log_name[FN_REFLEN];
>> +    my_off_t    valid_pos= 0;
>> +    my_off_t    binlog_size;
>> +    MY_STAT     s;
>>
>>       if (! fdle.is_valid())
>>         goto err;
>
> ok.
>
>> @@ -3941,13 +4232,17 @@ int MYSQL_BIN_LOG::open(const char *opt_
>>         goto err;
>>       }
>>
>> +    my_stat(log_name,&s, MYF(0));
>> +    binlog_size= s.st_size;
>> +
>>       if ((ev= Log_event::read_log_event(&log, 0,&fdle,
>>                                          opt_master_verify_checksum))&&
>>           ev->get_type_code() == FORMAT_DESCRIPTION_EVENT&&
>>           ev->flags&  LOG_EVENT_BINLOG_IN_USE_F)
>>       {
>>         sql_print_information("Recovering after a crash using %s", 
>> opt_name);
>> -      error= recover(&log, (Format_description_log_event *)ev);
>> +      valid_pos= my_b_tell(&log);
>> +      error= recover(&log, (Format_description_log_event 
>> *)ev,&valid_pos);
>>       }
>>       else
>>         error=0;
>
> ok.
>
>> @@ -3958,6 +4253,51 @@ int MYSQL_BIN_LOG::open(const char *opt_
>>
>>       if (error)
>>         goto err;
>> +
>> +    /* Trim the crashed binlog file to last valid transaction
>> +      or event (non-transaction) base on valid_pos. */
>> +    if (valid_pos>  0)
>> +    {
>> +      if ((file= mysql_file_open(key_file_binlog, log_name,
>> +                                 O_RDWR | O_BINARY, MYF(MY_WME)))<  0)
>> +      {
>> +        sql_print_error("Failed to open the crashed binlog file "
>> +                        "when master server is recovering it.");
>> +        return -1;
>> +      }
>> +
>> +      /* Change binlog file size to valid_pos */
>> +      if (valid_pos<  binlog_size)
>> +      {
>> +        if (my_chsize(file, valid_pos, 0, MYF(MY_WME)))
>> +        {
>> +          sql_print_error("Failed to trim the crashed binlog file "
>> +                          "when master server is recovering it.");
>> +          mysql_file_close(file, MYF(MY_WME));
>> +          return -1;
>> +        }
>> +        else
>> +        {
>> +          sql_print_information("Crashed binlog file %s size is %llu, "
>> +                                "but recovered up to %llu. Binlog 
>> trimmed to %llu bytes.",
>> +                                log_name, binlog_size, valid_pos, 
>> valid_pos);
>> +        }
>> +      }
>> +
>> +      /* Clear LOG_EVENT_BINLOG_IN_USE_F */
>> +      my_off_t offset= BIN_LOG_HEADER_SIZE + FLAGS_OFFSET;
>> +      uchar flags= 0;
>> +      if (mysql_file_pwrite(file,&flags, 1, offset, MYF(0)) != 1)
>> +      {
>> +        sql_print_error("Failed to clear LOG_EVENT_BINLOG_IN_USE_F "
>> +                        "for the crashed binlog file when master "
>> +                        "server is recovering it.");
>> +        mysql_file_close(file, MYF(MY_WME));
>> +        return -1;
>> +      }
>> +
>> +      mysql_file_close(file, MYF(MY_WME));
>> +    } //end if
>>     }
>>
>>   err:
>
> ok.
>
>> @@ -4007,11 +4347,32 @@ void MYSQL_BIN_LOG::unlog(ulong cookie,
>>     rotate_and_purge(0);     // as ::write() did not rotate
>>   }
>>
>> -int MYSQL_BIN_LOG::recover(IO_CACHE *log, 
>> Format_description_log_event *fdle)
>> +
>> +/**
>> +  MYSQLD server recovers from last crashed binlog.
>> +
>> +  @param log           IO_CACHE of the crashed binlog.
>> +  @param fdle          Format_description_log_event of the crashed 
>> binlog.
>> +  @param valid_pos     The position of the last valid transaction or
>> +                       event(non-transaction) of the crashed binlog.
>> +
>> +  @retval
>> +    0                  ok
>> +  @retval
>> +    1                  error
>> +*/
>> +int MYSQL_BIN_LOG::recover(IO_CACHE *log, 
>> Format_description_log_event *fdle,
>> +                            my_off_t *valid_pos)
>>   {
>>     Log_event  *ev;
>>     HASH xids;
>>     MEM_ROOT mem_root;
>> +  my_off_t last_valid_pos= *valid_pos;
>> +  /*
>> +    The flag is used for handling the case that a transaction
>> +    is partially written to the binlog.
>> +  */
>> +  bool in_transaction= 0;
>>
>>     if (! fdle->is_valid() ||
>>         my_hash_init(&xids,&my_charset_bin, TC_LOG_PAGE_SIZE/3, 0,
>
> ok.
>
>> @@ -4026,8 +4387,27 @@ int MYSQL_BIN_LOG::recover(IO_CACHE *log
>>                                           opt_master_verify_checksum))
>> &&  ev->is_valid())
>>     {
>> +    /*
>> +      Recorded valid position for the crashed binlog file
>> +      which contains incorrect events.
>> +    */
>> +    if (ev->get_type_code() == QUERY_EVENT&&
>> +        !strcmp(((Query_log_event*)ev)->query, "BEGIN"))
>> +    {
>> +      in_transaction= TRUE;
>> +      *valid_pos= last_valid_pos;
>> +    }
>> +    last_valid_pos= my_b_tell(log);
>> +
>> +    sql_print_information("ev->get_type_code()== %d, 
>> last_valid_pos== %llu .", ev->get_type_code(), last_valid_pos);
>> +
>> +    if (ev->get_type_code() == QUERY_EVENT&&
>> +        !strcmp(((Query_log_event*)ev)->query, "COMMIT"))
>> +      in_transaction= FALSE;
>> +
>>       if (ev->get_type_code() == XID_EVENT)
>>       {
>> +      in_transaction= FALSE;
>>         Xid_log_event *xev=(Xid_log_event *)ev;
>>         uchar *x= (uchar *) memdup_root(&mem_root, (uchar*)&xev->xid,
>>                                         sizeof(xev->xid));
>
> ok.
>
>> @@ -4037,6 +4417,13 @@ int MYSQL_BIN_LOG::recover(IO_CACHE *log
>>       delete ev;
>>     }
>>
>> +  /*
>> +    Recorded valid position for the crashed binlog file
>> +    which did not contain incorrect events.
>> +  */
>> +  if (!log->error&&  !in_transaction)
>> +    *valid_pos= last_valid_pos;
>> +
>>     if (ha_recover(&xids))
>>       goto err2;
>>
>
> ok.
>
>>
>> === modified file 'sql/binlog.h'
>> --- a/sql/binlog.h    2010-10-25 19:02:24 +0000
>> +++ b/sql/binlog.h    2010-12-02 02:56:34 +0000
>> @@ -35,6 +35,12 @@ class MYSQL_BIN_LOG: public TC_LOG, priv
>>     IO_CACHE index_file;
>>     char index_file_name[FN_REFLEN];
>>     /*
>> +    crash_safe_index_file is temp file used for guaranteeing
>> +    index file crash safe when master server restarts.
>> +  */
>> +  IO_CACHE crash_safe_index_file;
>> +  char crash_safe_index_file_name[FN_REFLEN];
>> +  /*
>
> ok.
>
>>       purge_file is a temp file used in purge_logs so that the index 
>> file
>>       can be updated before deleting files from disk, yielding better 
>> crash
>>       recovery. It is created on demand the first time purge_logs is 
>> called
>> @@ -153,7 +159,8 @@ public:
>>     void close();
>>     int log_xid(THD *thd, my_xid xid);
>>     void unlog(ulong cookie, my_xid xid);
>> -  int recover(IO_CACHE *log, Format_description_log_event *fdle);
>> +  int recover(IO_CACHE *log, Format_description_log_event *fdle,
>> +              my_off_t *valid_pos);
>>   #if !defined(MYSQL_CLIENT)
>
> ok.
>
>>
>>     int flush_and_set_pending_rows_event(THD *thd, Rows_log_event* 
>> event,
>> @@ -218,7 +225,7 @@ public:
>>
>>     void make_log_name(char* buf, const char* log_ident);
>>     bool is_active(const char* log_file_name);
>> -  int update_log_index(LOG_INFO* linfo, bool need_update_threads);
>> +  int remove_logs_from_index(LOG_INFO* linfo, bool 
>> need_update_threads);
>>     void rotate_and_purge(uint flags);
>>     /**
>>        Flush binlog cache and synchronize to disk.
>
> ok.
>
>> @@ -240,6 +247,11 @@ public:
>>                    ulonglong *decrease_log_space);
>>     int purge_logs_before_date(time_t purge_time);
>>     int purge_first_log(Relay_log_info* rli, bool included);
>> +  int set_crash_safe_index_file_name(const char *base_file_name);
>> +  int open_crash_safe_index_file();
>> +  int close_crash_safe_index_file();
>> +  int add_log_to_index(uchar* log_file_name, int name_len, bool 
>> need_mutex);
>> +  int move_crash_safe_index_file_to_index_file(bool need_mutex);
>>     int set_purge_index_file_name(const char *base_file_name);
>>     int open_purge_index_file(bool destroy);
>>     bool is_inited_purge_index_file();
>>
>
> ok.
>
>> === modified file 'sql/log_event.cc'
>> --- a/sql/log_event.cc    2010-11-23 23:10:22 +0000
>> +++ b/sql/log_event.cc    2010-12-02 02:56:34 +0000
>> @@ -1306,6 +1306,8 @@ err:
>>         enough to stop the SQL thread now ; as we are skipping the 
>> current event,
>>         going on with reading and successfully executing other events 
>> can
>>         only corrupt the slave's databases. So stop.
>> +      The file->error is also checked to record the position of
>> +      the last valid event when master server recovers.
>>       */
>>       file->error= -1;
>>     }
>> @@ -1378,20 +1380,15 @@ Log_event* Log_event::read_log_event(con
>>     if (crc_check&&
>>         event_checksum_test((uchar *) buf, event_len, alg))
>>     {
>> -#ifdef MYSQL_CLIENT
>>       *error= "Event crc check failed! Most likely there is event 
>> corruption.";
>> +#ifdef MYSQL_CLIENT
>>       if (force_opt)
>>       {
>>         ev= new Unknown_log_event(buf, description_event);
>>         DBUG_RETURN(ev);
>>       }
>> -    else
>> -      DBUG_RETURN(NULL);
>> -#else
>> -    *error= ER(ER_BINLOG_READ_EVENT_CHECKSUM_FAILURE);
>> -    sql_print_error("%s", ER(ER_BINLOG_READ_EVENT_CHECKSUM_FAILURE));
>> -    DBUG_RETURN(NULL);
>>   #endif
>> +    DBUG_RETURN(NULL);
>>     }
>>
>>     if (event_type>  description_event->number_of_event_types&&
>>
>>
>
> Can you improve your comments here?
> I don't understan why these changes are necessary.

OK. I will make the decision after talking about it with Andrei.
In fact, the original code will cause segment error.
>
>
>>
>>
>

Thread
bzr commit into mysql-trunk branch (Dao-Gang.Qu:3208) WL#5493Dao-Gang.Qu2 Dec
  • Re: bzr commit into mysql-trunk branch (Dao-Gang.Qu:3208) WL#5493Alfranio Correia10 Dec
    • Re: bzr commit into mysql-trunk branch (Dao-Gang.Qu:3208) WL#5493Daogang Qu16 Dec
      • Re: bzr commit into mysql-trunk branch (Dao-Gang.Qu:3208) WL#5493Alfranio Correia16 Dec
        • Re: bzr commit into mysql-trunk branch (Dao-Gang.Qu:3208) WL#5493Daogang Qu16 Dec
          • Re: bzr commit into mysql-trunk branch (Dao-Gang.Qu:3208) WL#5493Alfranio Correia17 Dec
            • Re: bzr commit into mysql-trunk branch (Dao-Gang.Qu:3208) WL#5493Daogang Qu20 Dec
              • Re: bzr commit into mysql-trunk branch (Dao-Gang.Qu:3208) WL#5493Alfranio Correia20 Dec
                • Re: bzr commit into mysql-trunk branch (Dao-Gang.Qu:3208) WL#5493Daogang Qu21 Dec
    • Re: bzr commit into mysql-trunk branch (Dao-Gang.Qu:3208) WL#5493Daogang Qu16 Dec