Hi Luis,
Patch looks good, thank you!
STATUS
------
Approved after addressing following comments!
REQUESTS
--------
R1. In the following block, why adding the my_printf_error()?
if (find_uniq_filename(new_name))
{
+ my_printf_error(ER_NO_UNIQUE_LOGFILE, ER(ER_NO_UNIQUE_LOGFILE),
+ MYF(0), log_name);
sql_print_error(ER(ER_NO_UNIQUE_LOGFILE), log_name);
return 1;
}
R2. This is way too hard to read :(, please rewrite it.
if ((error= ((file_to_open= index_file_name) &&
(error= open_index_file(index_file_name, 0, FALSE))) ||
((file_to_open= new_name_ptr) &&
(error= open(old_name, log_type, new_name_ptr,
io_cache_type, no_auto_events,
max_size, 1, FALSE)))))
Luis Soares wrote:
> #At file:///home/lsoares/Workspace/bzr/work/bugfixing/46166/mysql-5.1-bugteam-commit/
> based on revid:martin.hansson@stripped
>
> 3503 Luis Soares 2010-09-10
> BUG#46166: MYSQL_BIN_LOG::new_file_impl is not propagating error
> when generating new name.
>
>
> If find_uniq_filename returns an error, then this error is not
> being propagated upwards, and execution does not report error
> to the user (although a entry in the error log is generated).
>
> Additionally, some more errors were ignored in new_file_impl:
> - when writing the rotate event
> - when reopening the index and binary log file
>
> This patch addresses this by propagating the error up in the
> execution stack. Furthermore, when rotation of the binary log
> fails, an incident event is written, because there may be a
> chance that some changes for a given statement, were not properly
> logged. For example, in SBR, LOAD DATA INFILE statement requires
> more than one event to be logged, should rotation fail while
> logging part of the LOAD DATA events, then the logged data would
> become inconsistent with the data in the storage engine.
> @ mysql-test/include/restart_mysqld.inc
> Refactored restart_mysqld so that it is not hardcoded for
> mysqld.1, but rather for the current server.
> @ mysql-test/suite/binlog/t/binlog_index.test
> The error on open of index and binary log on new_file_impl is now
> caught. Thence the user will get an error message. We need to
> accomodate this change in the test case for the failing FLUSH LOGS.
> @ mysql-test/suite/rpl/t/rpl_binlog_errors-master.opt
> Sets max_binlog_size to 4096.
> @ mysql-test/suite/rpl/t/rpl_binlog_errors.test
> Added some test cases for asserting that the error is found and
> reported.
> @ sql/handler.cc
> Catching error now returned by unlog (in ha_commit_trans) and
> returning it.
> @ sql/log.cc
> Propagating errors from new_file_impl upwards. The errors that
> new_file_impl catches now are:
> - error on generate_new_name
> - error on writing the rotate event
> - error when opening the index or the binary log file.
> @ sql/log.h
> Changing declaration of:
> - rotate_and_purge
> - new_file
> - new_file_without_locking
> - new_file_impl
> - unlog
> They now return int instead of void.
> @ sql/rpl_injector.cc
> Changes to catch the return from rotate_and_purge.
> @ sql/slave.cc
> Changes to catch the return values for new_file and rotate_relay_log.
> @ sql/slave.h
> Changes to rotate_relay_log declaration (now returns int
> instead of void).
> @ sql/sql_load.cc
> In SBR, some logging of LOAD DATA events goes through
> IO_CACHE_CALLBACK invocation at mf_iocache.c:_my_b_get. The
> IO_CACHE implementation is ignoring the return value for from
> these callbacks (pre_read and post_read), so we need to find
> out at the end of the execution if the error is set or not
> in THD.
> @ sql/sql_parse.cc
> Catching the rotate_relay_log and rotate_and_purge return values.
>
> added:
> mysql-test/include/io_thd_fault_injection.inc
> mysql-test/suite/rpl/r/rpl_binlog_errors.result
> mysql-test/suite/rpl/t/rpl_binlog_errors-master.opt
> mysql-test/suite/rpl/t/rpl_binlog_errors.test
> modified:
> mysql-test/include/restart_mysqld.inc
> mysql-test/suite/binlog/r/binlog_index.result
> mysql-test/suite/binlog/t/binlog_index.test
> sql/handler.cc
> sql/log.cc
> sql/log.h
> sql/rpl_injector.cc
> sql/slave.cc
> sql/slave.h
> sql/sql_load.cc
> sql/sql_parse.cc
> === added file 'mysql-test/include/io_thd_fault_injection.inc'
> --- a/mysql-test/include/io_thd_fault_injection.inc 1970-01-01 00:00:00 +0000
> +++ b/mysql-test/include/io_thd_fault_injection.inc 2010-09-10 10:21:38 +0000
> @@ -0,0 +1,21 @@
> +#
> +# Takes the flag as an argument:
> +# -- let $io_thd_injection_fault_flag=+d,fault_injection_new_file_rotate_event
> +# -- source include/io_thd_fault_injection.inc
> +#
> +
> +SET @old_debug=@@global.debug;
> +-- disable_warnings
> +-- source include/stop_slave.inc
> +-- enable_warnings
> +-- eval SET GLOBAL debug="+d,$io_thd_injection_fault_flag"
> +
> +START SLAVE io_thread;
> +-- source include/wait_for_slave_io_to_stop.inc
> +-- source include/wait_for_slave_io_error.inc
> +
> +-- eval SET GLOBAL debug="-d,$io_thd_injection_fault_flag"
> +SET GLOBAL debug=@old_debug;
> +
> +# restart because slave is in bad shape
> +-- source include/restart_mysqld.inc
>
> === modified file 'mysql-test/include/restart_mysqld.inc'
> --- a/mysql-test/include/restart_mysqld.inc 2008-12-25 09:53:24 +0000
> +++ b/mysql-test/include/restart_mysqld.inc 2010-09-10 10:21:38 +0000
> @@ -1,7 +1,11 @@
>
> # Write file to make mysql-test-run.pl expect the "crash", but don't start
> # it until it's told to
> ---write_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
> +
> +--let $_server_id= `SELECT @@server_id`
> +--let $_expect_file_name= $MYSQLTEST_VARDIR/tmp/mysqld.$_server_id.expect
> +
> +--write_file $_expect_file_name
> wait
> EOF
>
> @@ -10,7 +14,7 @@ EOF
> shutdown_server 10;
>
> # Write file to make mysql-test-run.pl start up the server again
> ---append_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
> +--append_file $_expect_file_name
> restart
> EOF
>
>
> === modified file 'mysql-test/suite/binlog/r/binlog_index.result'
> --- a/mysql-test/suite/binlog/r/binlog_index.result 2009-12-16 19:52:56 +0000
> +++ b/mysql-test/suite/binlog/r/binlog_index.result 2010-09-10 10:21:38 +0000
> @@ -2,7 +2,9 @@ call mtr.add_suppression('Attempting bac
> call mtr.add_suppression('MSYQL_BIN_LOG::purge_logs failed to process registered
> files that would be purged.');
> call mtr.add_suppression('MSYQL_BIN_LOG::open failed to sync the index file');
> call mtr.add_suppression('Turning logging off for the whole duration of the MySQL
> server process.');
> +call mtr.add_suppression('Could not open .*');
> call mtr.add_suppression('MSYQL_BIN_LOG::purge_logs failed to clean registers before
> purging logs.');
> +RESET MASTER;
> flush logs;
> flush logs;
> flush logs;
> @@ -116,11 +118,31 @@ master-bin.000011
> # This should put the server in unsafe state and stop
> # accepting any command. If we inject a fault at this
> # point and continue the execution the server crashes.
> -# Besides the flush command does not report an error.
> #
> +SET @index=LOAD_FILE('MYSQLTEST_VARDIR/mysqld.1/data//master-bin.index');
> +SELECT @index;
> +@index
> +master-bin.000006
> +master-bin.000007
> +master-bin.000008
> +master-bin.000009
> +master-bin.000010
> +master-bin.000011
> +
> # fault_injection_registering_index
> SET SESSION debug="+d,fault_injection_registering_index";
> flush logs;
> +ERROR HY000: Can't open file: './master-bin.000012' (errno: 1)
> +SET @index=LOAD_FILE('MYSQLTEST_VARDIR/mysqld.1/data//master-bin.index');
> +SELECT @index;
> +@index
> +master-bin.000006
> +master-bin.000007
> +master-bin.000008
> +master-bin.000009
> +master-bin.000010
> +master-bin.000011
> +
> SET @index=LOAD_FILE('MYSQLTEST_VARDIR/mysqld.1/data//master-bin.index');
> SELECT @index;
> @index
> @@ -135,6 +157,18 @@ master-bin.000012
> # fault_injection_updating_index
> SET SESSION debug="+d,fault_injection_updating_index";
> flush logs;
> +ERROR HY000: Can't open file: './master-bin.000013' (errno: 1)
> +SET @index=LOAD_FILE('MYSQLTEST_VARDIR/mysqld.1/data//master-bin.index');
> +SELECT @index;
> +@index
> +master-bin.000006
> +master-bin.000007
> +master-bin.000008
> +master-bin.000009
> +master-bin.000010
> +master-bin.000011
> +master-bin.000012
> +
> SET @index=LOAD_FILE('MYSQLTEST_VARDIR/mysqld.1/data//master-bin.index');
> SELECT @index;
> @index
>
> === 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-09-10 10:21:38 +0000
> @@ -10,9 +10,12 @@ call mtr.add_suppression('Attempting bac
> call mtr.add_suppression('MSYQL_BIN_LOG::purge_logs failed to process registered
> files that would be purged.');
> call mtr.add_suppression('MSYQL_BIN_LOG::open failed to sync the index file');
> call mtr.add_suppression('Turning logging off for the whole duration of the MySQL
> server process.');
> +call mtr.add_suppression('Could not open .*');
> call mtr.add_suppression('MSYQL_BIN_LOG::purge_logs failed to clean registers before
> purging logs.');
> let $old=`select @@debug`;
>
> +RESET MASTER;
> +
> let $MYSQLD_DATADIR= `select @@datadir`;
> let $INDEX=$MYSQLD_DATADIR/master-bin.index;
>
> @@ -205,12 +208,25 @@ SELECT @index;
> --echo # This should put the server in unsafe state and stop
> --echo # accepting any command. If we inject a fault at this
> --echo # point and continue the execution the server crashes.
> ---echo # Besides the flush command does not report an error.
> --echo #
>
> +--chmod 0644 $INDEX
> +-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
> +-- eval SET @index=LOAD_FILE('$index')
> +-- replace_regex /\.[\\\/]master/master/
> +SELECT @index;
> +
> --echo # fault_injection_registering_index
> SET SESSION debug="+d,fault_injection_registering_index";
> +-- error ER_CANT_OPEN_FILE
> flush logs;
> +
> +--chmod 0644 $INDEX
> +-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
> +-- eval SET @index=LOAD_FILE('$index')
> +-- replace_regex /\.[\\\/]master/master/
> +SELECT @index;
> +
> --source include/restart_mysqld.inc
>
> --chmod 0644 $INDEX
> @@ -221,7 +237,15 @@ SELECT @index;
>
> --echo # fault_injection_updating_index
> SET SESSION debug="+d,fault_injection_updating_index";
> +-- error ER_CANT_OPEN_FILE
> flush logs;
> +
> +--chmod 0644 $INDEX
> +-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
> +-- eval SET @index=LOAD_FILE('$index')
> +-- replace_regex /\.[\\\/]master/master/
> +SELECT @index;
> +
> --source include/restart_mysqld.inc
>
> --chmod 0644 $INDEX
>
> === added file 'mysql-test/suite/rpl/r/rpl_binlog_errors.result'
> --- a/mysql-test/suite/rpl/r/rpl_binlog_errors.result 1970-01-01 00:00:00 +0000
> +++ b/mysql-test/suite/rpl/r/rpl_binlog_errors.result 2010-09-10 10:21:38 +0000
> @@ -0,0 +1,274 @@
> +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;
> +#######################################################################
> +####################### PART 1: MASTER TESTS ##########################
> +#######################################################################
> +include/stop_slave.inc
> +call mtr.add_suppression("Can't generate a unique log-filename");
> +call mtr.add_suppression("Writing one row to the row-based binary log failed.*");
> +call mtr.add_suppression("Error writing file .*");
> +SET @old_debug= @@global.debug;
> +SELECT repeat('x',8192) INTO OUTFILE 'MYSQLTEST_VARDIR/tmp/bug_46166.data';
> +SELECT repeat('x',10) INTO OUTFILE 'MYSQLTEST_VARDIR/tmp/bug_46166-2.data';
> +RESET MASTER;
> +###################### TEST #1
> +FLUSH LOGS;
> +# assert: must show two binlogs
> +show binary logs;
> +Log_name File_size
> +master-bin.000001 #
> +master-bin.000002 #
> +###################### TEST #2
> +RESET MASTER;
> +SET GLOBAL debug="+d,error_unique_log_filename";
> +FLUSH LOGS;
> +ERROR HY000: Can't generate a unique log-filename master-bin.(1-999)
> +
> +# assert: must show one binlog
> +show binary logs;
> +Log_name File_size
> +master-bin.000001 #
> +SET GLOBAL debug="";
> +RESET MASTER;
> +###################### TEST #3
> +CREATE TABLE t1 (a int);
> +CREATE TABLE t2 (a TEXT) Engine=InnoDB;
> +CREATE TABLE t4 (a TEXT);
> +INSERT INTO t1 VALUES (1);
> +RESET MASTER;
> +LOAD DATA INFILE 'MYSQLTEST_VARDIR/tmp/bug_46166.data' INTO TABLE t2;
> +# assert: must show two binlog
> +show binary logs;
> +Log_name File_size
> +master-bin.000001 #
> +master-bin.000002 #
> +SET GLOBAL debug="-d,error_unique_log_filename";
> +DELETE FROM t2;
> +RESET MASTER;
> +###################### TEST #4
> +SET GLOBAL debug="+d,error_unique_log_filename";
> +LOAD DATA INFILE 'MYSQLTEST_VARDIR/tmp/bug_46166.data' INTO TABLE t2;
> +ERROR HY000: Can't generate a unique log-filename master-bin.(1-999)
> +
> +# assert: must show one entry
> +SELECT count(*) FROM t2;
> +count(*)
> +1
> +SET GLOBAL debug="-d,error_unique_log_filename";
> +DELETE FROM t2;
> +RESET MASTER;
> +###################### TEST #5
> +SET GLOBAL debug="+d,error_unique_log_filename";
> +LOAD DATA INFILE 'MYSQLTEST_VARDIR/tmp/bug_46166-2.data' INTO TABLE t2;
> +# assert: must show one entry
> +SELECT count(*) FROM t2;
> +count(*)
> +1
> +SET GLOBAL debug="-d,error_unique_log_filename";
> +DELETE FROM t2;
> +RESET MASTER;
> +###################### TEST #6
> +SET GLOBAL debug="+d,error_unique_log_filename";
> +SET AUTOCOMMIT=0;
> +INSERT INTO t2 VALUES ('muse');
> +LOAD DATA INFILE 'MYSQLTEST_VARDIR/tmp/bug_46166.data' INTO TABLE t2;
> +INSERT INTO t2 VALUES ('muse');
> +COMMIT;
> +ERROR HY000: Can't generate a unique log-filename master-bin.(1-999)
> +
> +# assert: must show three entries
> +SELECT count(*) FROM t2;
> +count(*)
> +3
> +SET AUTOCOMMIT= 1;
> +SET GLOBAL debug="-d,error_unique_log_filename";
> +DELETE FROM t2;
> +RESET MASTER;
> +###################### TEST #7
> +SET GLOBAL debug="+d,error_unique_log_filename";
> +SELECT count(*) FROM t4;
> +count(*)
> +0
> +LOAD DATA INFILE 'MYSQLTEST_VARDIR/tmp/bug_46166.data' INTO TABLE t4;
> +ERROR HY000: Can't generate a unique log-filename master-bin.(1-999)
> +
> +# assert: must show 1 entry
> +SELECT count(*) FROM t4;
> +count(*)
> +1
> +### check that the incident event is written to the current log
> +SET GLOBAL debug="-d,error_unique_log_filename";
> +FLUSH LOGS;
> +SHOW BINLOG EVENTS IN 'BINLOG_FILE' FROM <binlog_start> LIMIT 1;
> +Log_name Pos Event_type Server_id End_log_pos Info
> +BINLOG_FILE # Incident # # #1 (LOST_EVENTS)
> +DELETE FROM t4;
> +RESET MASTER;
> +###################### TEST #8
> +SET GLOBAL debug="+d,error_unique_log_filename";
> +# must show 0 entries
> +SELECT count(*) FROM t4;
> +count(*)
> +0
> +SELECT count(*) FROM t2;
> +count(*)
> +0
> +LOAD DATA INFILE 'MYSQLTEST_VARDIR/tmp/bug_46166.data' INTO TABLE t4;
> +ERROR HY000: Can't generate a unique log-filename master-bin.(1-999)
> +
> +LOAD DATA INFILE 'MYSQLTEST_VARDIR/tmp/bug_46166.data' INTO TABLE t2;
> +ERROR HY000: Can't generate a unique log-filename master-bin.(1-999)
> +
> +INSERT INTO t2 VALUES ('aaa'), ('bbb'), ('ccc');
> +ERROR HY000: Can't generate a unique log-filename master-bin.(1-999)
> +
> +# INFO: Count(*) Before Offending DELETEs
> +# assert: must show 1 entry
> +SELECT count(*) FROM t4;
> +count(*)
> +1
> +# assert: must show 4 entries
> +SELECT count(*) FROM t2;
> +count(*)
> +4
> +DELETE FROM t4;
> +ERROR HY000: Can't generate a unique log-filename master-bin.(1-999)
> +
> +DELETE FROM t2;
> +ERROR HY000: Can't generate a unique log-filename master-bin.(1-999)
> +
> +# INFO: Count(*) After Offending DELETEs
> +# assert: must show zero entries
> +SELECT count(*) FROM t4;
> +count(*)
> +0
> +SELECT count(*) FROM t2;
> +count(*)
> +0
> +SET GLOBAL debug="-d,error_unique_log_filename";
> +###################### TEST #9
> +SET GLOBAL debug="+d,error_unique_log_filename";
> +SET SQL_LOG_BIN=0;
> +INSERT INTO t2 VALUES ('aaa'), ('bbb'), ('ccc'), ('ddd');
> +INSERT INTO t4 VALUES ('eee'), ('fff'), ('ggg'), ('hhh');
> +# assert: must show four entries
> +SELECT count(*) FROM t2;
> +count(*)
> +4
> +SELECT count(*) FROM t4;
> +count(*)
> +4
> +DELETE FROM t2;
> +DELETE FROM t4;
> +# assert: must show zero entries
> +SELECT count(*) FROM t2;
> +count(*)
> +0
> +SELECT count(*) FROM t4;
> +count(*)
> +0
> +SET SQL_LOG_BIN=1;
> +SET GLOBAL debug="-d,error_unique_log_filename";
> +###################### TEST #10
> +call mtr.add_suppression("MSYQL_BIN_LOG::open failed to sync the index file.");
> +call mtr.add_suppression("Could not open .*");
> +RESET MASTER;
> +SHOW WARNINGS;
> +Level Code Message
> +SET GLOBAL debug="+d,fault_injection_registering_index";
> +FLUSH LOGS;
> +ERROR HY000: Can't open file: './master-bin.000002' (errno: 1)
> +SET GLOBAL debug="-d,fault_injection_registering_index";
> +SHOW BINARY LOGS;
> +ERROR HY000: You are not using binary logging
> +CREATE TABLE t5 (a INT);
> +INSERT INTO t4 VALUES ('bbbbb');
> +INSERT INTO t2 VALUES ('aaaaa');
> +DELETE FROM t4;
> +DELETE FROM t2;
> +DROP TABLE t5;
> +###################### TEST #11
> +SET GLOBAL debug="+d,fault_injection_openning_index";
> +FLUSH LOGS;
> +ERROR HY000: Can't open file: './master-bin.index' (errno: 1)
> +SET GLOBAL debug="-d,fault_injection_openning_index";
> +RESET MASTER;
> +ERROR HY000: Binlog closed, cannot RESET MASTER
> +CREATE TABLE t5 (a INT);
> +INSERT INTO t4 VALUES ('bbbbb');
> +INSERT INTO t2 VALUES ('aaaaa');
> +DELETE FROM t4;
> +DELETE FROM t2;
> +DROP TABLE t5;
> +###################### TEST #12
> +SET GLOBAL debug="+d,fault_injection_new_file_rotate_event";
> +FLUSH LOGS;
> +ERROR HY000: Can't open file: 'master-bin' (errno: 0)
> +SET GLOBAL debug="-d,fault_injection_new_file_rotate_event";
> +RESET MASTER;
> +ERROR HY000: Binlog closed, cannot RESET MASTER
> +CREATE TABLE t5 (a INT);
> +INSERT INTO t4 VALUES ('bbbbb');
> +INSERT INTO t2 VALUES ('aaaaa');
> +DELETE FROM t4;
> +DELETE FROM t2;
> +DROP TABLE t5;
> +SET GLOBAL debug= @old_debug;
> +DROP TABLE t1, t2, t4;
> +RESET MASTER;
> +include/start_slave.inc
> +#######################################################################
> +####################### PART 2: SLAVE TESTS ###########################
> +#######################################################################
> +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("Slave I/O: Relay log write failure: could not queue event
> from master.*");
> +call mtr.add_suppression("Error writing file .*");
> +call mtr.add_suppression("Could not open .*");
> +call mtr.add_suppression("MSYQL_BIN_LOG::open failed to sync the index file.");
> +call mtr.add_suppression("Can't generate a unique log-filename .*");
> +###################### TEST #13
> +SET @old_debug=@@global.debug;
> +include/stop_slave.inc
> +SET GLOBAL debug="+d,error_unique_log_filename";
> +START SLAVE io_thread;
> +Last_IO_Error = Relay log write failure: could not queue event from master
> +SET GLOBAL debug="-d,error_unique_log_filename";
> +SET GLOBAL debug=@old_debug;
> +###################### TEST #14
> +SET @old_debug=@@global.debug;
> +include/stop_slave.inc
> +SET GLOBAL debug="+d,fault_injection_new_file_rotate_event";
> +START SLAVE io_thread;
> +Last_IO_Error = Relay log write failure: could not queue event from master
> +SET GLOBAL debug="-d,fault_injection_new_file_rotate_event";
> +SET GLOBAL debug=@old_debug;
> +###################### TEST #15
> +SET @old_debug=@@global.debug;
> +include/stop_slave.inc
> +SET GLOBAL debug="+d,fault_injection_registering_index";
> +START SLAVE io_thread;
> +Last_IO_Error = Relay log write failure: could not queue event from master
> +SET GLOBAL debug="-d,fault_injection_registering_index";
> +SET GLOBAL debug=@old_debug;
> +###################### TEST #16
> +SET @old_debug=@@global.debug;
> +include/stop_slave.inc
> +SET GLOBAL debug="+d,fault_injection_openning_index";
> +START SLAVE io_thread;
> +Last_IO_Error = Relay log write failure: could not queue event from master
> +SET GLOBAL debug="-d,fault_injection_openning_index";
> +SET GLOBAL debug=@old_debug;
> +include/stop_slave.inc
> +SET GLOBAL debug=@old_debug;
> +RESET SLAVE;
> +RESET MASTER;
> +include/start_slave.inc
>
> === added file 'mysql-test/suite/rpl/t/rpl_binlog_errors-master.opt'
> --- a/mysql-test/suite/rpl/t/rpl_binlog_errors-master.opt 1970-01-01 00:00:00 +0000
> +++ b/mysql-test/suite/rpl/t/rpl_binlog_errors-master.opt 2010-09-10 10:21:38 +0000
> @@ -0,0 +1 @@
> +--max_binlog_size=4096
>
> === added file 'mysql-test/suite/rpl/t/rpl_binlog_errors.test'
> --- a/mysql-test/suite/rpl/t/rpl_binlog_errors.test 1970-01-01 00:00:00 +0000
> +++ b/mysql-test/suite/rpl/t/rpl_binlog_errors.test 2010-09-10 10:21:38 +0000
> @@ -0,0 +1,413 @@
> +# BUG#46166: MYSQL_BIN_LOG::new_file_impl is not propagating error
> +# when generating new name.
> +#
> +# WHY
> +# ===
> +#
> +# We want to check whether error is reported or not when
> +# new_file_impl fails (this may happen when rotation is not
> +# possible because there is some problem finding an
> +# unique filename).
> +#
> +# HOW
> +# ===
> +#
> +# Test cases are documented inline.
> +
> +-- source include/master-slave.inc
> +-- source include/have_innodb.inc
> +-- source include/have_debug.inc
> +
> +-- echo #######################################################################
> +-- echo ####################### PART 1: MASTER TESTS ##########################
> +-- echo #######################################################################
> +
> +
> +### ACTION: stopping slave as it is not needed for the first part of
> +### the test
> +
> +-- connection slave
> +-- source include/stop_slave.inc
> +-- connection master
> +
> +call mtr.add_suppression("Can't generate a unique log-filename");
> +call mtr.add_suppression("Writing one row to the row-based binary log failed.*");
> +call mtr.add_suppression("Error writing file .*");
> +
> +SET @old_debug= @@global.debug;
> +
> +### ACTION: create a large file (> 4096 bytes) that will be later used
> +### in LOAD DATA INFILE to check binlog errors in its vacinity
> +-- let $load_file= $MYSQLTEST_VARDIR/tmp/bug_46166.data
> +-- let $MYSQLD_DATADIR= `select @@datadir`
> +-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
> +-- eval SELECT repeat('x',8192) INTO OUTFILE '$load_file'
> +
> +### ACTION: create a small file (< 4096 bytes) that will be later used
> +### in LOAD DATA INFILE to check for absence of binlog errors
> +### when file loading this file does not force flushing and
> +### rotating the binary log
> +-- let $load_file2= $MYSQLTEST_VARDIR/tmp/bug_46166-2.data
> +-- let $MYSQLD_DATADIR= `select @@datadir`
> +-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
> +-- eval SELECT repeat('x',10) INTO OUTFILE '$load_file2'
> +
> +RESET MASTER;
> +
> +-- echo ###################### TEST #1
> +
> +### ASSERTION: no problem flushing logs (should show two binlogs)
> +FLUSH LOGS;
> +-- echo # assert: must show two binlogs
> +-- source include/show_binary_logs.inc
> +
> +-- echo ###################### TEST #2
> +
> +### ASSERTION: check that FLUSH LOGS actually fails and reports
> +### failure back to the user if find_uniq_filename fails
> +### (should show just one binlog)
> +
> +RESET MASTER;
> +SET GLOBAL debug="+d,error_unique_log_filename";
> +-- error ER_NO_UNIQUE_LOGFILE
> +FLUSH LOGS;
> +-- echo # assert: must show one binlog
> +-- source include/show_binary_logs.inc
> +
> +### ACTION: clean up and move to next test
> +SET GLOBAL debug="";
> +RESET MASTER;
> +
> +-- echo ###################### TEST #3
> +
> +### ACTION: create some tables (t1, t2, t4) and insert some values in
> +### table t1
> +CREATE TABLE t1 (a int);
> +CREATE TABLE t2 (a TEXT) Engine=InnoDB;
> +CREATE TABLE t4 (a TEXT);
> +INSERT INTO t1 VALUES (1);
> +RESET MASTER;
> +
> +### ASSERTION: we force rotation of the binary log because it exceeds
> +### the max_binlog_size option (should show two binary
> +### logs)
> +
> +-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
> +-- eval LOAD DATA INFILE '$load_file' INTO TABLE t2
> +
> +# shows two binary logs
> +-- echo # assert: must show two binlog
> +-- source include/show_binary_logs.inc
> +
> +# clean up the table and the binlog to be used in next part of test
> +SET GLOBAL debug="-d,error_unique_log_filename";
> +DELETE FROM t2;
> +RESET MASTER;
> +
> +-- echo ###################### TEST #4
> +
> +### ASSERTION: load the big file into a transactional table and check
> +### that it reports error. The table will contain the
> +### changes performed despite the fact that it reported an
> +### error.
> +
> +SET GLOBAL debug="+d,error_unique_log_filename";
> +-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
> +-- error ER_NO_UNIQUE_LOGFILE
> +-- eval LOAD DATA INFILE '$load_file' INTO TABLE t2
> +
> +# show table
> +-- echo # assert: must show one entry
> +SELECT count(*) FROM t2;
> +
> +# clean up the table and the binlog to be used in next part of test
> +SET GLOBAL debug="-d,error_unique_log_filename";
> +DELETE FROM t2;
> +RESET MASTER;
> +
> +-- echo ###################### TEST #5
> +
> +### ASSERTION: load the small file into a transactional table and
> +### check that it succeeds
> +
> +SET GLOBAL debug="+d,error_unique_log_filename";
> +-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
> +-- eval LOAD DATA INFILE '$load_file2' INTO TABLE t2
> +
> +# show table
> +-- echo # assert: must show one entry
> +SELECT count(*) FROM t2;
> +
> +# clean up the table and the binlog to be used in next part of test
> +SET GLOBAL debug="-d,error_unique_log_filename";
> +DELETE FROM t2;
> +RESET MASTER;
> +
> +-- echo ###################### TEST #6
> +
> +### ASSERTION: check that even if one is using a transactional table
> +### and explicit transactions (no autocommit) if rotation
> +### fails we get the error. Transaction is not rolledback
> +### because rotation happens after the commit.
> +
> +SET GLOBAL debug="+d,error_unique_log_filename";
> +SET AUTOCOMMIT=0;
> +INSERT INTO t2 VALUES ('muse');
> +-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
> +-- eval LOAD DATA INFILE '$load_file' INTO TABLE t2
> +INSERT INTO t2 VALUES ('muse');
> +-- error ER_NO_UNIQUE_LOGFILE
> +COMMIT;
> +
> +### ACTION: Show the contents of the table after the test
> +-- echo # assert: must show three entries
> +SELECT count(*) FROM t2;
> +
> +### ACTION: clean up and move to the next test
> +SET AUTOCOMMIT= 1;
> +SET GLOBAL debug="-d,error_unique_log_filename";
> +DELETE FROM t2;
> +RESET MASTER;
> +
> +-- echo ###################### TEST #7
> +
> +### ASSERTION: check that on a non-transactional table, if rotation
> +### fails then an error is reported and an incident event
> +### is written to the current binary log.
> +
> +SET GLOBAL debug="+d,error_unique_log_filename";
> +SELECT count(*) FROM t4;
> +-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
> +-- error ER_NO_UNIQUE_LOGFILE
> +-- eval LOAD DATA INFILE '$load_file' INTO TABLE t4
> +
> +-- echo # assert: must show 1 entry
> +SELECT count(*) FROM t4;
> +
> +-- echo ### check that the incident event is written to the current log
> +SET GLOBAL debug="-d,error_unique_log_filename";
> +-- let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1)
> +-- let $binlog_file= query_get_value(SHOW MASTER STATUS, File, 1)
> +
> +# 53 is the size of the incident event, so we start from 22 bytes before the
> +# current position
> +-- let $binlog_start = `SELECT $binlog_start - 53`
> +FLUSH LOGS;
> +-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR $binlog_start
> <binlog_start> $binlog_file BINLOG_FILE
> +-- replace_column 2 # 4 # 5 #
> +-- eval SHOW BINLOG EVENTS IN '$binlog_file' FROM $binlog_start LIMIT 1
> +
> +# clean up and move to next test
> +DELETE FROM t4;
> +RESET MASTER;
> +
> +-- echo ###################### TEST #8
> +
> +### ASSERTION: check that statements end up in error but they succeed
> +### on changing the data.
> +
> +SET GLOBAL debug="+d,error_unique_log_filename";
> +-- echo # must show 0 entries
> +SELECT count(*) FROM t4;
> +SELECT count(*) FROM t2;
> +
> +-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
> +-- error ER_NO_UNIQUE_LOGFILE
> +-- eval LOAD DATA INFILE '$load_file' INTO TABLE t4
> +-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
> +-- error ER_NO_UNIQUE_LOGFILE
> +-- eval LOAD DATA INFILE '$load_file' INTO TABLE t2
> +-- error ER_NO_UNIQUE_LOGFILE
> +INSERT INTO t2 VALUES ('aaa'), ('bbb'), ('ccc');
> +
> +-- echo # INFO: Count(*) Before Offending DELETEs
> +-- echo # assert: must show 1 entry
> +SELECT count(*) FROM t4;
> +-- echo # assert: must show 4 entries
> +SELECT count(*) FROM t2;
> +
> +-- error ER_NO_UNIQUE_LOGFILE
> +DELETE FROM t4;
> +-- error ER_NO_UNIQUE_LOGFILE
> +DELETE FROM t2;
> +
> +-- echo # INFO: Count(*) After Offending DELETEs
> +-- echo # assert: must show zero entries
> +SELECT count(*) FROM t4;
> +SELECT count(*) FROM t2;
> +
> +# remove fault injection
> +SET GLOBAL debug="-d,error_unique_log_filename";
> +
> +-- echo ###################### TEST #9
> +
> +### ASSERTION: check that if we disable binlogging, then statements
> +### succeed.
> +SET GLOBAL debug="+d,error_unique_log_filename";
> +SET SQL_LOG_BIN=0;
> +INSERT INTO t2 VALUES ('aaa'), ('bbb'), ('ccc'), ('ddd');
> +INSERT INTO t4 VALUES ('eee'), ('fff'), ('ggg'), ('hhh');
> +-- echo # assert: must show four entries
> +SELECT count(*) FROM t2;
> +SELECT count(*) FROM t4;
> +DELETE FROM t2;
> +DELETE FROM t4;
> +-- echo # assert: must show zero entries
> +SELECT count(*) FROM t2;
> +SELECT count(*) FROM t4;
> +SET SQL_LOG_BIN=1;
> +SET GLOBAL debug="-d,error_unique_log_filename";
> +
> +-- echo ###################### TEST #10
> +
> +### ASSERTION: check that error is reported if there is a failure
> +### while registering the index file and the binary log
> +### file or failure to write the rotate event.
> +
> +call mtr.add_suppression("MSYQL_BIN_LOG::open failed to sync the index file.");
> +call mtr.add_suppression("Could not open .*");
> +
> +RESET MASTER;
> +SHOW WARNINGS;
> +
> +# +d,fault_injection_registering_index => injects fault on MYSQL_BIN_LOG::open
> +SET GLOBAL debug="+d,fault_injection_registering_index";
> +-- error ER_CANT_OPEN_FILE
> +FLUSH LOGS;
> +SET GLOBAL debug="-d,fault_injection_registering_index";
> +
> +-- error ER_NO_BINARY_LOGGING
> +SHOW BINARY LOGS;
> +
> +# issue some statements and check that they don't fail
> +CREATE TABLE t5 (a INT);
> +INSERT INTO t4 VALUES ('bbbbb');
> +INSERT INTO t2 VALUES ('aaaaa');
> +DELETE FROM t4;
> +DELETE FROM t2;
> +DROP TABLE t5;
> +
> +-- echo ###################### TEST #11
> +
> +### ASSERTION: check that error is reported if there is a failure
> +### while opening the index file and the binary log file or
> +### failure to write the rotate event.
> +
> +# restart the server so that we have binlog again
> +--source include/restart_mysqld.inc
> +
> +# +d,fault_injection_openning_index => injects fault on
> MYSQL_BIN_LOG::open_index_file
> +SET GLOBAL debug="+d,fault_injection_openning_index";
> +-- error ER_CANT_OPEN_FILE
> +FLUSH LOGS;
> +SET GLOBAL debug="-d,fault_injection_openning_index";
> +
> +-- error ER_FLUSH_MASTER_BINLOG_CLOSED
> +RESET MASTER;
> +
> +# issue some statements and check that they don't fail
> +CREATE TABLE t5 (a INT);
> +INSERT INTO t4 VALUES ('bbbbb');
> +INSERT INTO t2 VALUES ('aaaaa');
> +DELETE FROM t4;
> +DELETE FROM t2;
> +DROP TABLE t5;
> +
> +# restart the server so that we have binlog again
> +-- source include/restart_mysqld.inc
> +
> +-- echo ###################### TEST #12
> +
> +### ASSERTION: check that error is reported if there is a failure
> +### while writing the rotate event when creating a new log
> +### file.
> +
> +# +d,fault_injection_new_file_rotate_event => injects fault on
> MYSQL_BIN_LOG::MYSQL_BIN_LOG::new_file_impl
> +SET GLOBAL debug="+d,fault_injection_new_file_rotate_event";
> +-- error ER_ERROR_ON_WRITE
> +FLUSH LOGS;
> +SET GLOBAL debug="-d,fault_injection_new_file_rotate_event";
> +
> +-- error ER_FLUSH_MASTER_BINLOG_CLOSED
> +RESET MASTER;
> +
> +# issue some statements and check that they don't fail
> +CREATE TABLE t5 (a INT);
> +INSERT INTO t4 VALUES ('bbbbb');
> +INSERT INTO t2 VALUES ('aaaaa');
> +DELETE FROM t4;
> +DELETE FROM t2;
> +DROP TABLE t5;
> +
> +# restart the server so that we have binlog again
> +-- source include/restart_mysqld.inc
> +
> +## clean up
> +SET GLOBAL debug= @old_debug;
> +DROP TABLE t1, t2, t4;
> +RESET MASTER;
> +
> +# restart slave again
> +-- connection slave
> +-- source include/start_slave.inc
> +-- connection master
> +
> +-- echo #######################################################################
> +-- echo ####################### PART 2: SLAVE TESTS ###########################
> +-- echo #######################################################################
> +
> +### setup
> +-- connection master
> +# master-slave-reset starts the slave automatically
> +-- source include/master-slave-reset.inc
> +-- connection slave
> +
> +# slave suppressions
> +
> +call mtr.add_suppression("Slave I/O: Relay log write failure: could not queue event
> from master.*");
> +call mtr.add_suppression("Error writing file .*");
> +call mtr.add_suppression("Could not open .*");
> +call mtr.add_suppression("MSYQL_BIN_LOG::open failed to sync the index file.");
> +call mtr.add_suppression("Can't generate a unique log-filename .*");
> +-- echo ###################### TEST #13
> +
> +#### ASSERTION: check against unique log filename error
> +-- let $io_thd_injection_fault_flag= error_unique_log_filename
> +-- let $slave_io_errno= 1595
> +-- let $show_slave_io_error= 1
> +-- source include/io_thd_fault_injection.inc
> +
> +-- echo ###################### TEST #14
> +
> +#### ASSERTION: check against rotate failing
> +-- let $io_thd_injection_fault_flag= fault_injection_new_file_rotate_event
> +-- let $slave_io_errno= 1595
> +-- let $show_slave_io_error= 1
> +-- source include/io_thd_fault_injection.inc
> +
> +-- echo ###################### TEST #15
> +
> +#### ASSERTION: check against relay log open failure
> +-- let $io_thd_injection_fault_flag= fault_injection_registering_index
> +-- let $slave_io_errno= 1595
> +-- let $show_slave_io_error= 1
> +-- source include/io_thd_fault_injection.inc
> +
> +-- echo ###################### TEST #16
> +
> +#### ASSERTION: check against relay log index open failure
> +-- let $io_thd_injection_fault_flag= fault_injection_openning_index
> +-- let $slave_io_errno= 1595
> +-- let $show_slave_io_error= 1
> +-- source include/io_thd_fault_injection.inc
> +
> +### clean up
> +-- disable_warnings
> +-- source include/stop_slave.inc
> +-- enable_warnings
> +SET GLOBAL debug=@old_debug;
> +RESET SLAVE;
> +RESET MASTER;
> +-- source include/start_slave.inc
> +-- connection master
> +-- source include/master-slave-end.inc
>
> === modified file 'sql/handler.cc'
> --- a/sql/handler.cc 2010-04-14 09:53:59 +0000
> +++ b/sql/handler.cc 2010-09-10 10:21:38 +0000
> @@ -1192,7 +1192,11 @@ int ha_commit_trans(THD *thd, bool all)
> error=ha_commit_one_phase(thd, all) ? (cookie ? 2 : 1) : 0;
> DBUG_EXECUTE_IF("crash_commit_before_unlog", abort(););
> if (cookie)
> - tc_log->unlog(cookie, xid);
> + if(tc_log->unlog(cookie, xid))
> + {
> + error= 2;
> + goto end;
> + }
> DBUG_EXECUTE_IF("crash_commit_after", abort(););
> end:
> if (rw_trans)
>
> === modified file 'sql/log.cc'
> --- a/sql/log.cc 2010-08-25 08:47:45 +0000
> +++ b/sql/log.cc 2010-09-10 10:21:38 +0000
> @@ -1867,10 +1867,11 @@ static int find_uniq_filename(char *name
> *end='.';
> length= (size_t) (end-start+1);
>
> - if (!(dir_info = my_dir(buff,MYF(MY_DONT_SORT))))
> + if ((DBUG_EVALUATE_IF("error_unique_log_filename", 1,
> + !(dir_info = my_dir(buff,MYF(MY_DONT_SORT))))))
> { // This shouldn't happen
> strmov(end,".1"); // use name+1
> - DBUG_RETURN(0);
> + DBUG_RETURN(1);
> }
> file_info= dir_info->dir_entry;
> for (i=dir_info->number_off_files ; i-- ; file_info++)
> @@ -1884,8 +1885,7 @@ static int find_uniq_filename(char *name
> my_dirend(dir_info);
>
> *end++='.';
> - sprintf(end,"%06ld",max_found+1);
> - DBUG_RETURN(0);
> + DBUG_RETURN((sprintf(end,"%06ld",max_found+1) < 0));
> }
>
>
> @@ -2097,6 +2097,8 @@ int MYSQL_LOG::generate_new_name(char *n
> {
> if (find_uniq_filename(new_name))
> {
> + my_printf_error(ER_NO_UNIQUE_LOGFILE, ER(ER_NO_UNIQUE_LOGFILE),
> + MYF(0), log_name);
> sql_print_error(ER(ER_NO_UNIQUE_LOGFILE), log_name);
> return 1;
> }
> @@ -3062,7 +3064,8 @@ bool MYSQL_BIN_LOG::reset_logs(THD* thd)
> if (!thd->slave_thread)
> need_start_event=1;
> if (!open_index_file(index_file_name, 0, FALSE))
> - open(save_name, log_type, 0, io_cache_type, no_auto_events, max_size, 0,
> FALSE);
> + if ((error= open(save_name, log_type, 0, io_cache_type, no_auto_events,
> max_size, 0, FALSE)))
> + goto err;
> my_free((uchar*) save_name, MYF(0));
>
> err:
> @@ -3724,17 +3727,23 @@ bool MYSQL_BIN_LOG::is_active(const char
> incapsulation 3) allows external access to the class without
> a lock (which is not possible with private new_file_without_locking
> method).
> +
> + @retval
> + nonzero - error
> */
>
> -void MYSQL_BIN_LOG::new_file()
> +int MYSQL_BIN_LOG::new_file()
> {
> - new_file_impl(1);
> + return new_file_impl(1);
> }
>
> -
> -void MYSQL_BIN_LOG::new_file_without_locking()
> +/*
> + @retval
> + nonzero - error
> + */
> +int MYSQL_BIN_LOG::new_file_without_locking()
> {
> - new_file_impl(0);
> + return new_file_impl(0);
> }
>
>
> @@ -3743,19 +3752,23 @@ void MYSQL_BIN_LOG::new_file_without_loc
>
> @param need_lock Set to 1 if caller has not locked LOCK_log
>
> + @retval
> + nonzero - error
> +
> @note
> The new file name is stored last in the index file
> */
>
> -void MYSQL_BIN_LOG::new_file_impl(bool need_lock)
> +int MYSQL_BIN_LOG::new_file_impl(bool need_lock)
> {
> - char new_name[FN_REFLEN], *new_name_ptr, *old_name;
> + int error= 0, close_on_error= FALSE;
> + char new_name[FN_REFLEN], *new_name_ptr, *old_name, *file_to_open;
>
> DBUG_ENTER("MYSQL_BIN_LOG::new_file_impl");
> if (!is_open())
> {
> DBUG_PRINT("info",("log is closed"));
> - DBUG_VOID_RETURN;
> + DBUG_RETURN(error);
> }
>
> if (need_lock)
> @@ -3793,7 +3806,7 @@ void MYSQL_BIN_LOG::new_file_impl(bool n
> We have to do this here and not in open as we want to store the
> new file name in the current binary log file.
> */
> - if (generate_new_name(new_name, name))
> + if ((error= generate_new_name(new_name, name)))
> goto end;
> new_name_ptr=new_name;
>
> @@ -3807,7 +3820,13 @@ void MYSQL_BIN_LOG::new_file_impl(bool n
> */
> Rotate_log_event r(new_name+dirname_length(new_name),
> 0, LOG_EVENT_OFFSET, is_relay_log ?
> Rotate_log_event::RELAY_LOG : 0);
> - r.write(&log_file);
> + if(DBUG_EVALUATE_IF("fault_injection_new_file_rotate_event",
> (error=close_on_error=TRUE), FALSE) ||
> + (error= r.write(&log_file)))
> + {
> + close_on_error= TRUE;
> + my_printf_error(ER_ERROR_ON_WRITE, ER(ER_CANT_OPEN_FILE), MYF(0), name,
> errno);
> + goto end;
> + }
> bytes_written += r.data_written;
> }
> /*
> @@ -3835,17 +3854,49 @@ void MYSQL_BIN_LOG::new_file_impl(bool n
> */
>
> /* reopen index binlog file, BUG#34582 */
> - if (!open_index_file(index_file_name, 0, FALSE))
> - open(old_name, log_type, new_name_ptr,
> - io_cache_type, no_auto_events, max_size, 1, FALSE);
> + if ((error= ((file_to_open= index_file_name) &&
> + (error= open_index_file(index_file_name, 0, FALSE))) ||
> + ((file_to_open= new_name_ptr) &&
> + (error= open(old_name, log_type, new_name_ptr,
> + io_cache_type, no_auto_events,
> + max_size, 1, FALSE)))))
> + {
> + my_printf_error(ER_CANT_OPEN_FILE, ER(ER_CANT_OPEN_FILE),
> + MYF(0), file_to_open, error);
> + close_on_error= TRUE;
> + }
> my_free(old_name,MYF(0));
>
> end:
> +
> + if (error && close_on_error /* rotate or reopen failed */)
> + {
> + /*
> + Close whatever was left opened.
> +
> + We are keeping the behavior as it exists today, ie,
> + we disable logging and move on (see: BUG#51014).
> +
> + TODO: as part of WL#1790 consider other approaches:
> + - kill mysql (safety);
> + - try multiple locations for opening a log file;
> + - switch server to protected/readonly mode
> + - ...
> + */
> + close(LOG_CLOSE_INDEX);
> + sql_print_error("Could not open %s for logging (error %d). "
> + "Turning logging off for the whole duration "
> + "of the MySQL server process. To turn it on "
> + "again: fix the cause, shutdown the MySQL "
> + "server and restart it.",
> + new_name_ptr, errno);
> + }
> +
> if (need_lock)
> pthread_mutex_unlock(&LOCK_log);
> pthread_mutex_unlock(&LOCK_index);
>
> - DBUG_VOID_RETURN;
> + DBUG_RETURN(error);
> }
>
>
> @@ -3868,8 +3919,7 @@ bool MYSQL_BIN_LOG::append(Log_event* ev
> bytes_written+= ev->data_written;
> DBUG_PRINT("info",("max_size: %lu",max_size));
> if ((uint) my_b_append_tell(&log_file) > max_size)
> - new_file_without_locking();
> -
> + error= new_file_without_locking();
> err:
> pthread_mutex_unlock(&LOCK_log);
> signal_update(); // Safe as we don't call close
> @@ -3898,8 +3948,7 @@ bool MYSQL_BIN_LOG::appendv(const char*
> } while ((buf=va_arg(args,const char*)) && (len=va_arg(args,uint)));
> DBUG_PRINT("info",("max_size: %lu",max_size));
> if ((uint) my_b_append_tell(&log_file) > max_size)
> - new_file_without_locking();
> -
> + error= new_file_without_locking();
> err:
> if (!error)
> signal_update();
> @@ -4248,7 +4297,7 @@ MYSQL_BIN_LOG::flush_and_set_pending_row
> if (!error)
> {
> signal_update();
> - rotate_and_purge(RP_LOCK_LOG_IS_ALREADY_LOCKED);
> + error= rotate_and_purge(RP_LOCK_LOG_IS_ALREADY_LOCKED);
> }
> }
>
> @@ -4444,7 +4493,9 @@ bool MYSQL_BIN_LOG::write(Log_event *eve
> if (flush_and_sync())
> goto err;
> signal_update();
> - rotate_and_purge(RP_LOCK_LOG_IS_ALREADY_LOCKED);
> + if ((error= rotate_and_purge(RP_LOCK_LOG_IS_ALREADY_LOCKED)))
> + goto err;
> +
> }
> error=0;
>
> @@ -4527,8 +4578,19 @@ bool general_log_write(THD *thd, enum en
> return FALSE;
> }
>
> -void MYSQL_BIN_LOG::rotate_and_purge(uint flags)
> +/**
> + @note
> + If rotation fails, for instance the server was unable
> + to create a new log file, we still try to write an
> + incident event to the current log.
> +
> + @retval
> + nonzero - error
> +*/
> +int MYSQL_BIN_LOG::rotate_and_purge(uint flags)
> {
> + int error= 0;
> + DBUG_ENTER("MYSQL_BIN_LOG::rotate_and_purge");
> #ifdef HAVE_REPLICATION
> bool check_purge= false;
> #endif
> @@ -4537,26 +4599,38 @@ void MYSQL_BIN_LOG::rotate_and_purge(uin
> if ((flags & RP_FORCE_ROTATE) ||
> (my_b_tell(&log_file) >= (my_off_t) max_size))
> {
> - new_file_without_locking();
> + if ((error= new_file_without_locking()))
> + /**
> + Be conservative... There are possible lost events (eg,
> + failing to log the Execute_load_query_log_event
> + on a LOAD DATA while using a non-transactional
> + table)!
> +
> + We give it a shot and try to write an incident event anyway
> + to the current log.
> + */
> + if (!write_incident(current_thd, FALSE))
> + flush_and_sync();
> +
> #ifdef HAVE_REPLICATION
> check_purge= true;
> #endif
> }
> if (!(flags & RP_LOCK_LOG_IS_ALREADY_LOCKED))
> pthread_mutex_unlock(&LOCK_log);
> -
> #ifdef HAVE_REPLICATION
> /*
> NOTE: Run purge_logs wo/ holding LOCK_log
> as it otherwise will deadlock in ndbcluster_binlog_index_purge_file
> */
> - if (check_purge && expire_logs_days)
> + if (!error && check_purge && expire_logs_days)
> {
> time_t purge_time= my_time(0) - expire_logs_days*24*60*60;
> if (purge_time >= 0)
> purge_logs_before_date(purge_time);
> }
> #endif
> + DBUG_RETURN(error);
> }
>
> uint MYSQL_BIN_LOG::next_file_id()
> @@ -4755,7 +4829,7 @@ bool MYSQL_BIN_LOG::write_incident(THD *
> if (!error && !(error= flush_and_sync()))
> {
> signal_update();
> - rotate_and_purge(RP_LOCK_LOG_IS_ALREADY_LOCKED);
> + error= rotate_and_purge(RP_LOCK_LOG_IS_ALREADY_LOCKED);
> }
> pthread_mutex_unlock(&LOCK_log);
> }
> @@ -4867,7 +4941,8 @@ bool MYSQL_BIN_LOG::write(THD *thd, IO_C
> pthread_mutex_unlock(&LOCK_prep_xids);
> }
> else
> - rotate_and_purge(RP_LOCK_LOG_IS_ALREADY_LOCKED);
> + if (rotate_and_purge(RP_LOCK_LOG_IS_ALREADY_LOCKED))
> + goto err;
> }
> VOID(pthread_mutex_unlock(&LOCK_log));
>
> @@ -5658,7 +5733,7 @@ int TC_LOG_MMAP::sync()
> cookie points directly to the memory where xid was logged.
> */
>
> -void TC_LOG_MMAP::unlog(ulong cookie, my_xid xid)
> +int TC_LOG_MMAP::unlog(ulong cookie, my_xid xid)
> {
> PAGE *p=pages+(cookie/tc_log_page_size);
> my_xid *x=(my_xid *)(data+cookie);
> @@ -5676,6 +5751,7 @@ void TC_LOG_MMAP::unlog(ulong cookie, my
> if (p->waiters == 0) // the page is in pool and ready to rock
> pthread_cond_signal(&COND_pool); // ping ... for overflow()
> pthread_mutex_unlock(&p->lock);
> + return 0;
> }
>
> void TC_LOG_MMAP::close()
> @@ -5917,8 +5993,9 @@ int TC_LOG_BINLOG::log_xid(THD *thd, my_
> DBUG_RETURN(!binlog_end_trans(thd, trx_data, &xle, TRUE));
> }
>
> -void TC_LOG_BINLOG::unlog(ulong cookie, my_xid xid)
> +int TC_LOG_BINLOG::unlog(ulong cookie, my_xid xid)
> {
> + DBUG_ENTER("TC_LOG_BINLOG::unlog");
> pthread_mutex_lock(&LOCK_prep_xids);
> DBUG_ASSERT(prepared_xids > 0);
> if (--prepared_xids == 0) {
> @@ -5926,7 +6003,7 @@ void TC_LOG_BINLOG::unlog(ulong cookie,
> pthread_cond_signal(&COND_prep_xids);
> }
> pthread_mutex_unlock(&LOCK_prep_xids);
> - rotate_and_purge(0); // as ::write() did not rotate
> + DBUG_RETURN(rotate_and_purge(0)); // as ::write() did not rotate
> }
>
> int TC_LOG_BINLOG::recover(IO_CACHE *log, Format_description_log_event *fdle)
>
> === modified file 'sql/log.h'
> --- a/sql/log.h 2010-08-02 19:48:56 +0000
> +++ b/sql/log.h 2010-09-10 10:21:38 +0000
> @@ -39,7 +39,7 @@ class TC_LOG
> virtual int open(const char *opt_name)=0;
> virtual void close()=0;
> virtual int log_xid(THD *thd, my_xid xid)=0;
> - virtual void unlog(ulong cookie, my_xid xid)=0;
> + virtual int unlog(ulong cookie, my_xid xid)=0;
> };
>
> class TC_LOG_DUMMY: public TC_LOG // use it to disable the logging
> @@ -49,7 +49,7 @@ public:
> int open(const char *opt_name) { return 0; }
> void close() { }
> int log_xid(THD *thd, my_xid xid) { return 1; }
> - void unlog(ulong cookie, my_xid xid) { }
> + int unlog(ulong cookie, my_xid xid) { return 0; }
> };
>
> #ifdef HAVE_MMAP
> @@ -94,7 +94,7 @@ class TC_LOG_MMAP: public TC_LOG
> int open(const char *opt_name);
> void close();
> int log_xid(THD *thd, my_xid xid);
> - void unlog(ulong cookie, my_xid xid);
> + int unlog(ulong cookie, my_xid xid);
> int recover();
>
> private:
> @@ -283,8 +283,8 @@ class MYSQL_BIN_LOG: public TC_LOG, priv
> new_file() is locking. new_file_without_locking() does not acquire
> LOCK_log.
> */
> - void new_file_without_locking();
> - void new_file_impl(bool need_lock);
> + int new_file_without_locking();
> + int new_file_impl(bool need_lock);
>
> public:
> MYSQL_LOG::generate_name;
> @@ -314,7 +314,7 @@ public:
> int open(const char *opt_name);
> void close();
> int log_xid(THD *thd, my_xid xid);
> - void unlog(ulong cookie, my_xid xid);
> + int unlog(ulong cookie, my_xid xid);
> int recover(IO_CACHE *log, Format_description_log_event *fdle);
> #if !defined(MYSQL_CLIENT)
> int flush_and_set_pending_rows_event(THD *thd, Rows_log_event* event);
> @@ -354,7 +354,7 @@ public:
> bool open_index_file(const char *index_file_name_arg,
> const char *log_name, bool need_mutex);
> /* Use this to start writing a new log file */
> - void new_file();
> + int new_file();
>
> void reset_gathered_updates(THD *thd);
> bool write(Log_event* event_info); // binary log write
> @@ -379,7 +379,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);
> - void rotate_and_purge(uint flags);
> + int rotate_and_purge(uint flags);
> bool flush_and_sync();
> int purge_logs(const char *to_log, bool included,
> bool need_mutex, bool need_update_threads,
>
> === modified file 'sql/rpl_injector.cc'
> --- a/sql/rpl_injector.cc 2010-01-28 21:51:40 +0000
> +++ b/sql/rpl_injector.cc 2010-09-10 10:21:38 +0000
> @@ -229,8 +229,7 @@ int injector::record_incident(THD *thd,
> Incident_log_event ev(thd, incident);
> if (int error= mysql_bin_log.write(&ev))
> return error;
> - mysql_bin_log.rotate_and_purge(RP_FORCE_ROTATE);
> - return 0;
> + return mysql_bin_log.rotate_and_purge(RP_FORCE_ROTATE);
> }
>
> int injector::record_incident(THD *thd, Incident incident, LEX_STRING const
> message)
> @@ -238,6 +237,5 @@ int injector::record_incident(THD *thd,
> Incident_log_event ev(thd, incident, message);
> if (int error= mysql_bin_log.write(&ev))
> return error;
> - mysql_bin_log.rotate_and_purge(RP_FORCE_ROTATE);
> - return 0;
> + return mysql_bin_log.rotate_and_purge(RP_FORCE_ROTATE);
> }
>
> === modified file 'sql/slave.cc'
> --- a/sql/slave.cc 2010-07-20 18:07:36 +0000
> +++ b/sql/slave.cc 2010-09-10 10:21:38 +0000
> @@ -3388,8 +3388,7 @@ static int process_io_rotate(Master_info
> Rotate the relay log makes binlog format detection easier (at next slave
> start or mysqlbinlog)
> */
> - rotate_relay_log(mi); /* will take the right mutexes */
> - DBUG_RETURN(0);
> + DBUG_RETURN(rotate_relay_log(mi) /* will take the right mutexes */);
> }
>
> /*
> @@ -4418,10 +4417,11 @@ err:
> is void).
> */
>
> -void rotate_relay_log(Master_info* mi)
> +int rotate_relay_log(Master_info* mi)
> {
> DBUG_ENTER("rotate_relay_log");
> Relay_log_info* rli= &mi->rli;
> + int error= 0;
>
> /* We don't lock rli->run_lock. This would lead to deadlocks. */
> pthread_mutex_lock(&mi->run_lock);
> @@ -4437,7 +4437,8 @@ void rotate_relay_log(Master_info* mi)
> }
>
> /* If the relay log is closed, new_file() will do nothing. */
> - rli->relay_log.new_file();
> + if ((error= rli->relay_log.new_file()))
> + goto end;
>
> /*
> We harvest now, because otherwise BIN_LOG_HEADER_SIZE will not immediately
> @@ -4455,7 +4456,7 @@ void rotate_relay_log(Master_info* mi)
> rli->relay_log.harvest_bytes_written(&rli->log_space_total);
> end:
> pthread_mutex_unlock(&mi->run_lock);
> - DBUG_VOID_RETURN;
> + DBUG_RETURN(error);
> }
>
>
>
> === modified file 'sql/slave.h'
> --- a/sql/slave.h 2009-12-14 16:32:22 +0000
> +++ b/sql/slave.h 2010-09-10 10:21:38 +0000
> @@ -189,7 +189,7 @@ int purge_relay_logs(Relay_log_info* rli
> const char** errmsg);
> void set_slave_thread_options(THD* thd);
> void set_slave_thread_default_charset(THD *thd, Relay_log_info const *rli);
> -void rotate_relay_log(Master_info* mi);
> +int rotate_relay_log(Master_info* mi);
> int apply_event_and_update_pos(Log_event* ev, THD* thd, Relay_log_info* rli);
>
> pthread_handler_t handle_slave_io(void *arg);
>
> === modified file 'sql/sql_load.cc'
> --- a/sql/sql_load.cc 2010-08-03 02:22:19 +0000
> +++ b/sql/sql_load.cc 2010-09-10 10:21:38 +0000
> @@ -567,6 +567,13 @@ int mysql_load(THD *thd,sql_exchange *ex
> transactional_table,
> errcode);
> }
> +
> + /*
> + Flushing the IO CACHE while writing the execute load query log event
> + may result in error (for instance, because the max_binlog_size has been
> + reached, and rotation of the binary log failed).
> + */
> + error= error || mysql_bin_log.get_log_file()->error;
> }
> if (error)
> goto err;
>
> === modified file 'sql/sql_parse.cc'
> --- a/sql/sql_parse.cc 2010-08-18 04:56:06 +0000
> +++ b/sql/sql_parse.cc 2010-09-10 10:21:38 +0000
> @@ -3226,7 +3226,11 @@ end_with_restore_list:
> {
> Incident_log_event ev(thd, incident);
> (void) mysql_bin_log.write(&ev); /* error is ignored */
> - mysql_bin_log.rotate_and_purge(RP_FORCE_ROTATE);
> + if (mysql_bin_log.rotate_and_purge(RP_FORCE_ROTATE))
> + {
> + res= 1;
> + break;
> + }
> }
> DBUG_PRINT("debug", ("Just after generate_incident()"));
> }
> @@ -4042,7 +4046,7 @@ end_with_restore_list:
> reload_acl_and_cache() will tell us if we are allowed to write to the
> binlog or not.
> */
> - if (!reload_acl_and_cache(thd, lex->type, first_table,
> &write_to_binlog))
> + if (!(res= reload_acl_and_cache(thd, lex->type, first_table,
> &write_to_binlog)))
> {
> /*
> We WANT to write and we CAN write.
> @@ -6926,12 +6930,16 @@ bool reload_acl_and_cache(THD *thd, ulon
> tmp_write_to_binlog= 0;
> if( mysql_bin_log.is_open() )
> {
> - mysql_bin_log.rotate_and_purge(RP_FORCE_ROTATE);
> + if (mysql_bin_log.rotate_and_purge(RP_FORCE_ROTATE))
> + return 1;
> }
> #ifdef HAVE_REPLICATION
> + int rotate_error= 0;
> pthread_mutex_lock(&LOCK_active_mi);
> - rotate_relay_log(active_mi);
> + rotate_error= rotate_relay_log(active_mi);
> pthread_mutex_unlock(&LOCK_active_mi);
> + if (rotate_error)
> + return 1;
> #endif
>
> /* flush slow and general logs */
>
> text/bzr-bundle 类型 附件
> (bzr/luis.soares@stripped)
> # Bazaar merge directive format 2 (Bazaar 0.90)
> # revision_id: luis.soares@stripped
> # target_branch: file:///home/lsoares/Workspace/bzr/work/bugfixing\
> # /46166/mysql-5.1-bugteam-commit/
> # testament_sha1: 89d2083569e8d0d0c2a6c024be0341ad61f657ff
> # timestamp: 2010-09-10 11:21:49 +0100
> # source_branch: /home/lsoares/Workspace/bzr/clones/mysql-5.1-bugteam
> # base_revision_id: martin.hansson@stripped\
> # x92t31cz3xa9exn2
> #
> # Begin bundle
> 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
>
>