GIF89a;
Direktori : /usr/share/mysql-test/suite/binlog/t/ |
Current File : //usr/share/mysql-test/suite/binlog/t/binlog_error_action.test |
############################################################################### # Bug#11758766:MYSQLD CONTINUES OPERATION WITHOUT LOGGING WHEN BINLOGS # CANNOT BE WRITTEN # # Problem: # ======== # If an error occurs that prevents mysqld writing to the binary logs (disk # full, readonly filesystem, etc) then the logs are disabled and operations # continue. This can lead to out of sync slaves and improper backups. # # Test: # ===== # A new option "binlog_error_action" has been introduced whose values # are "IGNORE" or "ABORT". When binlogging becomes impossible if user sets # the variable to "ABORT" server will stop if user sets it to "IGNORE" binlog # will be turned off and server will continue. 4 different test cases are # added to check both the behaviours. ############################################################################### --source include/have_log_bin.inc --source include/not_embedded.inc --source include/have_binlog_format_statement.inc # Don't test this under valgrind, memory leaks will occur --source include/not_valgrind.inc --source include/have_debug.inc --source include/have_debug_sync.inc # Avoid CrashReporter popup on Mac --source include/not_crashrep.inc call mtr.add_suppression("MYSQL_BIN_LOG::add_log_to_index failed to copy index file to crash safe index file."); call mtr.add_suppression("Disk is full writing *"); call mtr.add_suppression("Retry in 60 secs. *"); call mtr.add_suppression("Error writing file*"); call mtr.add_suppression("Could not open .*"); call mtr.add_suppression("Could not use .*"); call mtr.add_suppression("Can't generate a unique log-filename master-bin"); call mtr.add_suppression("The server was unable to create a new log file *"); call mtr.add_suppression("An error occurred during flush stage of the commit"); call mtr.add_suppression("An error occurred during sync stage of the commit"); call mtr.add_suppression("Either disk is full or file system is read only"); call mtr.add_suppression("Attempting backtrace. You can use the following information to find out"); let $old=`select @@debug`; RESET MASTER; --echo Test case1 # Make binlog index readonly and check the behaviour with ABORT let $MYSQLD_DATADIR= `select @@datadir`; let $INDEX=$MYSQLD_DATADIR/master-bin.index; --chmod 0444 $INDEX SET GLOBAL binlog_error_action= ABORT_SERVER; --exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect --error ER_BINLOG_LOGGING_IMPOSSIBLE flush logs; --chmod 0666 $INDEX --exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect --enable_reconnect --source include/wait_until_connected_again.inc --echo Test case2 # Make MYSQL_BIN_LOG::open_binlog fail with debug simulation and test # the behaviour in case of ABORT SET SESSION debug="+d,fault_injection_updating_index"; SET GLOBAL binlog_error_action= ABORT_SERVER; --exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect --error ER_BINLOG_LOGGING_IMPOSSIBLE flush logs; --exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect --enable_reconnect --source include/wait_until_connected_again.inc --echo Test case3 # Simulate diskfull during opening of binlog and check for diskfull error # behaviour where binlogging impossible error is to abort the server. SET SESSION debug="+d,simulate_disk_full_on_open_binlog"; SET GLOBAL binlog_error_action= ABORT_SERVER; --exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect --error ER_BINLOG_LOGGING_IMPOSSIBLE flush logs; --exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect --enable_reconnect --source include/wait_until_connected_again.inc --echo Test case4 SET SESSION debug="+d,fault_injection_init_name"; SET GLOBAL binlog_error_action= ABORT_SERVER; --exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect --error ER_BINLOG_LOGGING_IMPOSSIBLE flush logs; --exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect --enable_reconnect --source include/wait_until_connected_again.inc --echo Test case5 # Make binlog index readonly and check the behaviour with IGNORE --chmod 0444 $INDEX --replace_regex /\.[\\\/]master/master/ /errno: 13 - .*\)/errno: 13 - Permission denied)/ --error 29 flush logs; CREATE TABLE t1 ( f int ); SHOW TABLES; DROP TABLE t1; --chmod 0666 $INDEX --source include/restart_mysqld.inc --echo Test case6 # Make MYSQL_BIN_LOG::open_binlog fail with debug simulation and test # the behaviour in case of IGNORE SET SESSION debug="+d,fault_injection_updating_index"; --replace_regex /\.[\\\/]master/master/ /errno: 1 - .*\)/errno: 1 - Operation not permitted)/ --error ER_CANT_OPEN_FILE flush logs; CREATE TABLE t2 (f int ); SHOW TABLES; DROP TABLE t2; SET SESSION debug="-d,fault_injection_updating_index"; --source include/restart_mysqld.inc --echo Test case7 # Simulate diskfull during opening of binlog and check for diskfull error # behaviour where binlogging impossible error is to continue the server # after the error. SET SESSION debug="+d,simulate_disk_full_on_open_binlog"; --replace_regex /\.[\\\/]master/master/ /Errcode: 28 - .*\)/Errcode: 28 - No space left on device)/ # error EE_WRITE with error code number 3 is expected. --error 3 flush logs; SET SESSION debug="-d,simulate_disk_full_on_open_binlog"; --source include/restart_mysqld.inc --echo Test case8 SET SESSION debug="+d,fault_injection_init_name"; --replace_regex /\.[\\\/]master/master/ /errno: 1 - .*\)/errno: 1 - Operation not permitted)/ --error ER_CANT_OPEN_FILE flush logs; CREATE TABLE t2 (f int ); SHOW TABLES; DROP TABLE t2; SET SESSION debug="-d,fault_injection_init_name"; --source include/restart_mysqld.inc ############################################################################### # Bug#20805298: BINLOG_ERROR_ACTION DOESN'T HANDLE SOME # FAILURES DURING BINLOG ROTATION # # Problem: # ======== # Hardware errors in binlog partition during binlog rotate are not handled by # binlog_error_action. # # Test: # ===== # Simulate failure during creation of new binary log file name. Set # binlog_error_action to "IGNORE_ERROR" and observe that the binary log gets # disabled and the server continues by logging an appropriate error message in # error log file. Set binlog_error_action to "ABORT_ERROR" and observe that # the # server aborts when creation of new binarylog file name fails. ############################################################################### --echo Test case09 # Test error scenario with binlog_error_action=IGNORE_ERROR CREATE TABLE t1 (a INT) ENGINE=InnoDB; SET SESSION debug='+d,error_unique_log_filename'; --error ER_NO_UNIQUE_LOGFILE FLUSH LOGS; DROP TABLE t1; eval SET SESSION debug="$debug_save"; # Test to prove that binary log is disabled --error ER_NO_BINARY_LOGGING SHOW BINARY LOGS; --source include/restart_mysqld.inc --echo Test case10 # Test error scenario with binlog_error_action=ABORT_SERVER CREATE TABLE t1 (a INT) ENGINE=InnoDB; SET GLOBAL binlog_error_action=ABORT_SERVER; SET SESSION debug='+d,error_unique_log_filename'; --exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect --error ER_BINLOG_LOGGING_IMPOSSIBLE FLUSH LOGS; --exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect --enable_reconnect --source include/wait_until_connected_again.inc DROP TABLE t1; ############################################################################### # BUG#16666407BINLOG WRITE ERRORS SILENTLY IGNORED # BUG#20938915 2PC SUCCEEDS EVEN THOUGH BINLOG FLUSH/SYNC FAILS ############################################################################### ############################ --echo Test case11 ############################ # Simulate error during flushing cache to file and test the behaviour # when binlog_error_action is set to ABORT_SERVER/IGNORE_ERROR. # Case 11.1 (binlog_error_action = ABORT_SERVER) --source include/shutdown_mysqld.inc --remove_file $MYSQLTEST_VARDIR/tmp/binlog_error_action.err --source include/start_mysqld.inc RESET MASTER; CREATE TABLE t1(i INT); --let $log_pos_before = query_get_value("SHOW BINARY LOGS", File_size, 1) SET SESSION debug = "+d,simulate_error_during_flush_cache_to_file"; SET GLOBAL binlog_error_action = ABORT_SERVER; --exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect # Check that flush error causing server to abort and client gets # ER_BINLOG_LOGGING_IMPOSSIBLE when binlog_error_action= 'ABORT_SERVER'. --error ER_BINLOG_LOGGING_IMPOSSIBLE INSERT INTO t1 VALUES (1); --exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect --enable_reconnect --source include/wait_until_connected_again.inc # Check that error present in error log --let SEARCH_FILE = $MYSQLTEST_VARDIR/tmp/binlog_error_action.err --let SEARCH_PATTERN = An error occurred during flush stage of the commit. 'binlog_error_action' is set to 'ABORT_SERVER'. --source include/search_pattern_in_file.inc # Check that transaction is not committed --let $assert_cond= COUNT(*) = 0 FROM t1; --let $assert_text= Count of elements in t1 should be 0. --source include/assert.inc # Check that transaction is not binlogged as well --let $log_pos_after = query_get_value("SHOW BINARY LOGS", File_size, 1) --let $assert_cond = $log_pos_before = $log_pos_after --let $assert_text = Query is not binlogged as expected. --source include/assert.inc # Case 11.2 (binlog_error_action = IGNORE_ERROR) RESET MASTER; --let $log_pos_before = query_get_value("SHOW BINARY LOGS", File_size, 1) SET SESSION debug ="+d,simulate_error_during_flush_cache_to_file"; SET GLOBAL binlog_error_action= IGNORE_ERROR; INSERT INTO t1 VALUES (2); # Check that transaction is committed --let $assert_cond = COUNT(*) = 1 FROM t1; --let $assert_text = Count of elements in t1 should be 1. --source include/assert.inc # Restart so that binary log is enabled again and we can do the below test --source include/restart_mysqld.inc # Check that transaction is not binlogged --let $log_pos_after = query_get_value("SHOW BINARY LOGS", File_size, 1) --let $assert_cond = $log_pos_before = $log_pos_after --let $assert_text = Query is not binlogged as expected. --source include/assert.inc # Check that error present in error log --let SEARCH_FILE = $MYSQLTEST_VARDIR/tmp/binlog_error_action.err --let SEARCH_PATTERN = An error occurred during flush stage of the commit. 'binlog_error_action' is set to 'IGNORE_ERROR'. --source include/search_pattern_in_file.inc # Cleanup DROP TABLE t1; RESET MASTER; ############################ --echo Test case12 ############################ # Simulate error during syncing binlog file and test the behaviour # when binlog_error_action is set to ABORT_SERVER/IGNORE_ERROR. # Set sync_binlog=1 just to make sure that logic enters into sync phase. # Case 12.1 (binlog_error_action = ABORT_SERVER) SET GLOBAL sync_binlog = 1; CREATE TABLE t1(i INT); SET SESSION debug = "+d,simulate_error_during_sync_binlog_file"; SET GLOBAL binlog_error_action = ABORT_SERVER; --exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect # Check that sync error causing server to abort and client gets # ER_BINLOG_LOGGING_IMPOSSIBLE when binlog_error_action= 'ABORT_SERVER'. --error ER_BINLOG_LOGGING_IMPOSSIBLE INSERT INTO t1 VALUES (1); --exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect --enable_reconnect --source include/wait_until_connected_again.inc # Cleanup DELETE FROM t1; RESET MASTER; # Case 12.2 (binlog_error_action = IGNORE_ERROR) SET SESSION debug = "+d,simulate_error_during_sync_binlog_file"; SET GLOBAL binlog_error_action = IGNORE_ERROR; INSERT INTO t1 VALUES (2); # Check that transaction is committed --let $assert_cond = COUNT(*) = 1 FROM t1; --let $assert_text = Count of elements in t1 should be 1. --source include/assert.inc # Cleanup DROP table t1; SET SESSION debug = "-d,simulate_error_during_sync_binlog_file"; --source include/restart_mysqld.inc RESET MASTER; ############################ --echo Test case13 ############################ # Simulate error during flushing events to binlog cache and test the behaviour # when binlog_error_action is set to ABORT_SERVER/IGNORE_ERROR. # Case 13.1 (binlog_error_action = ABORT_SERVER) CREATE TABLE t1(i INT); --let $log_pos_before = query_get_value("SHOW BINARY LOGS", File_size, 1) SET SESSION debug = "+d,simulate_do_write_cache_failure"; SET GLOBAL binlog_error_action = ABORT_SERVER; --exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect # Check that write cache error is causing server to abort and client gets # ER_BINLOG_LOGGING_IMPOSSIBLE when binlog_error_action= 'ABORT_SERVER'. --error ER_BINLOG_LOGGING_IMPOSSIBLE INSERT INTO t1 VALUES (1); --exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect --enable_reconnect --source include/wait_until_connected_again.inc # Check that transaction is not committed --let $assert_cond = COUNT(*) = 0 FROM t1; --let $assert_text = Count of elements in t1 should be 0. --source include/assert.inc # Check that transaction is not binlogged as well --let $log_pos_after = query_get_value("SHOW BINARY LOGS", File_size, 1) --let $assert_cond = $log_pos_before = $log_pos_after --let $assert_text = Query is not binlogged as expected. --source include/assert.inc # Cleanup RESET MASTER; # Case 13.2 (binlog_error_action = IGNORE_ERROR) SET SESSION debug = "+d,simulate_do_write_cache_failure"; SET GLOBAL binlog_error_action = IGNORE_ERROR; INSERT INTO t1 VALUES (2); # Check that transaction is committed (binlog check cannot be done # as we would have written STOP_EVENT in the binlog while closing # it) --let $assert_cond = COUNT(*) = 1 FROM t1; --let $assert_text = Count of elements in t1 should be 1. --source include/assert.inc # Cleanup DROP table t1; --source include/restart_mysqld.inc RESET MASTER; ############################ --echo Test case14 ############################ # Simulating a situation when a transaction is about to # enter ordered_commit and another transaction closed # binary log due to an error. SET GLOBAL binlog_error_action = IGNORE_ERROR; SET GLOBAL sync_binlog = 1; CREATE TABLE t1(i INT); CREATE TABLE t2(i INT); connect(con1,localhost,root,,); connect(con2,localhost,root,,); --connection con1 SET DEBUG_SYNC = "waiting_to_enter_flush_stage SIGNAL about_to_enter_flush_stage WAIT_FOR binlog_closed"; --send INSERT INTO t1 values (1); --connection default SET DEBUG_SYNC = "now wait_for about_to_enter_flush_stage"; --connection con2 SET DEBUG_SYNC = "after_binlog_closed_due_to_error SIGNAL binlog_closed"; SET SESSION debug = "+d,simulate_error_during_sync_binlog_file"; --send INSERT INTO t2 values (2); --connection con1 --reap --connection con2 --reap # Cleanup --disconnect con1 --disconnect con2 --connection default DROP table t1, t2; --source include/restart_mysqld.inc ############################ --echo Test case15 ############################ # Simulating a situation when a transaction is about to # close binary log due to a sync error (about to acquire lock_log) # and another transaction in the middle of flush stage (holding # lock_log. SET GLOBAL binlog_error_action = IGNORE_ERROR; SET GLOBAL sync_binlog = 1; CREATE TABLE t1(i INT); CREATE TABLE t2(i INT); connect(con1,localhost,root,,); connect(con2,localhost,root,,); --connection con1 SET DEBUG_SYNC = "before_binlog_closed_due_to_error SIGNAL binlog_about_to_be_closed WAIT_FOR in_the_middle_of_flush_stage"; SET SESSION debug = "+d,simulate_error_during_sync_binlog_file"; --send INSERT INTO t1 values (1); --connection default SET DEBUG_SYNC = "now wait_for binlog_about_to_be_closed"; --connection con2 SET DEBUG_SYNC = "waiting_in_the_middle_of_flush_stage SIGNAL in_the_middle_of_flush_stage"; --send INSERT INTO t2 values (2); --connection con1 --reap --connection con2 --reap # Claenup --disconnect con1 --disconnect con2 --connection default DROP table t1, t2; --source include/shutdown_mysqld.inc --remove_file $MYSQLTEST_VARDIR/tmp/binlog_error_action.err --source include/start_mysqld.inc ############################ --echo Test case16 ############################ # Simulating a situation where two binlog groups encounter # errors (one flush error, one sync error) at the same time # and both of them try to close the binary log. SET GLOBAL binlog_error_action = IGNORE_ERROR; SET GLOBAL sync_binlog = 1; CREATE TABLE t1(i INT); CREATE TABLE t2(i INT); connect(con1,localhost,root,,); connect(con2,localhost,root,,); --connection con1 SET DEBUG_SYNC = "before_binlog_closed_due_to_error SIGNAL binlog_about_to_be_closed WAIT_FOR another_group_encountered_flush_error"; SET SESSION debug = "+d,simulate_error_during_sync_binlog_file"; --send INSERT INTO t1 values (1); --connection default SET DEBUG_SYNC = "now wait_for binlog_about_to_be_closed"; --connection con2 SET DEBUG_SYNC = "before_binlog_closed_due_to_error SIGNAL another_group_encountered_flush_error"; SET SESSION debug ="+d,simulate_error_during_flush_cache_to_file"; --send INSERT INTO t2 values (2); --connection con1 --reap --connection con2 --reap --replace_regex /[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2} [0-9]+/--TIME--/ /flush|sync stage/flush_or_sync stage/ --let GREP_FILE=$MYSQLTEST_VARDIR/tmp/binlog_error_action.err --let GREP_PATTERN=An error occurred during --source extra/rpl_tests/grep_pattern.inc # Claenup --disconnect con1 --disconnect con2 --connection default DROP table t1, t2; --source include/restart_mysqld.inc