diff options
Diffstat (limited to 'mysql-test/extra/binlog_tests')
-rw-r--r-- | mysql-test/extra/binlog_tests/binlog_incident-master.opt | 1 | ||||
-rw-r--r-- | mysql-test/extra/binlog_tests/binlog_incident.inc | 68 | ||||
-rw-r--r-- | mysql-test/extra/binlog_tests/binlog_index.inc | 278 | ||||
-rw-r--r-- | mysql-test/extra/binlog_tests/binlog_ioerr.inc | 36 | ||||
-rw-r--r-- | mysql-test/extra/binlog_tests/binlog_mysqlbinlog-cp932.inc | 50 | ||||
-rw-r--r-- | mysql-test/extra/binlog_tests/binlog_row_annotate.inc | 215 | ||||
-rw-r--r-- | mysql-test/extra/binlog_tests/binlog_write_error.inc | 108 | ||||
-rw-r--r-- | mysql-test/extra/binlog_tests/binlog_xa_recover.inc | 281 | ||||
-rw-r--r-- | mysql-test/extra/binlog_tests/database.test | 2 |
9 files changed, 1038 insertions, 1 deletions
diff --git a/mysql-test/extra/binlog_tests/binlog_incident-master.opt b/mysql-test/extra/binlog_tests/binlog_incident-master.opt new file mode 100644 index 00000000000..57ce0081ae5 --- /dev/null +++ b/mysql-test/extra/binlog_tests/binlog_incident-master.opt @@ -0,0 +1 @@ +--loose-debug=+d,incident_database_resync_on_replace
\ No newline at end of file diff --git a/mysql-test/extra/binlog_tests/binlog_incident.inc b/mysql-test/extra/binlog_tests/binlog_incident.inc new file mode 100644 index 00000000000..8ec67746f26 --- /dev/null +++ b/mysql-test/extra/binlog_tests/binlog_incident.inc @@ -0,0 +1,68 @@ +# +# This include file is used by more than one test suite +# (currently rpl and binlog_encryption). +# Please check all dependent tests after modifying it +# +# Usage: +# +# --let $use_remote_mysqlbinlog= 1 # optional +# --let $binlog_start_pos= <binlog position> # optional +# --let $binlog_file= <binlog filename> # optional +# +# --source extra/binlog_tests/binlog_incident.inc +# +# The script uses MYSQLBINLOG to verify certain results. +# By default, it uses binary logs directly. If it is undesirable, +# this behavior can be overridden by setting $use_remote_binlog +# as shown above. +# +# All values will be unset after every execution of the script, +# so if they are needed, they should be set explicitly before each call. +# + +# The purpose of this test is to provide a reference for how the +# incident log event is represented in the output from the mysqlbinlog +# program. + +source include/have_log_bin.inc; +source include/have_debug.inc; +source include/binlog_start_pos.inc; + +let $MYSQLD_DATADIR= `select @@datadir`; +RESET MASTER; + +CREATE TABLE t1 (a INT); + +INSERT INTO t1 VALUES (1),(2),(3); +SELECT * FROM t1; + +# This will generate an incident log event and store it in the binary +# log before the replace statement. +REPLACE INTO t1 VALUES (4); + +DROP TABLE t1; +FLUSH LOGS; + +if ($binlog_start_pos) +{ + --let $startpos= --start-position=$binlog_start_pos + --let $binlog_start_pos= +} +--let $filename= master-bin.000001 +if ($binlog_file) +{ + --let $filename= $binlog_file + --let $binlog_file= +} +--let $mysqlbinlog_args= $MYSQLD_DATADIR/$filename +if ($use_remote_mysqlbinlog) +{ + --let $mysqlbinlog_args= --read-from-remote-server --protocol=tcp --host=127.0.0.1 --port=$MASTER_MYPORT -uroot $filename + --let $use_remote_mysqlbinlog= 0 +} +exec $MYSQL_BINLOG $startpos $mysqlbinlog_args >$MYSQLTEST_VARDIR/tmp/binlog_incident-bug44442.sql; +--disable_query_log +eval SELECT cont LIKE '%RELOAD DATABASE; # Shall generate syntax error%' AS `Contain RELOAD DATABASE` FROM (SELECT load_file('$MYSQLTEST_VARDIR/tmp/binlog_incident-bug44442.sql') AS cont) AS tbl; +--enable_query_log + +remove_file $MYSQLTEST_VARDIR/tmp/binlog_incident-bug44442.sql; diff --git a/mysql-test/extra/binlog_tests/binlog_index.inc b/mysql-test/extra/binlog_tests/binlog_index.inc new file mode 100644 index 00000000000..50215aef9a9 --- /dev/null +++ b/mysql-test/extra/binlog_tests/binlog_index.inc @@ -0,0 +1,278 @@ +# +# This include file is used by more than one test suite +# (currently binlog and binlog_encryption). +# Please check all dependent tests after modifying it +# + +# +# testing of purging of binary log files bug#18199/Bug#18453 +# +source include/have_log_bin.inc; +source include/not_embedded.inc; +# Don't test this under valgrind, memory leaks will occur +--source include/not_valgrind.inc +source include/have_debug.inc; +# Avoid CrashReporter popup on Mac +--source include/not_crashrep.inc +call mtr.add_suppression('Attempting backtrace'); +call mtr.add_suppression('MYSQL_BIN_LOG::purge_logs failed to process registered files that would be purged.'); +call mtr.add_suppression('MYSQL_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('MYSQL_BIN_LOG::purge_logs failed to clean registers before purging logs.'); +flush tables; + +let $old=`select @@debug`; + +RESET MASTER; + +let $MYSQLD_DATADIR= `select @@datadir`; +let $INDEX=$MYSQLD_DATADIR/master-bin.index; + +# +# testing purge binary logs TO +# + +flush logs; +flush logs; +flush logs; + +source include/show_binary_logs.inc; +remove_file $MYSQLD_DATADIR/master-bin.000001; +flush tables; + +# there must be a warning with file names +replace_regex /\.[\\\/]master/master/; +--source include/wait_for_binlog_checkpoint.inc +purge binary logs TO 'master-bin.000004'; + +--echo *** must show a list starting from the 'TO' argument of PURGE *** +source include/show_binary_logs.inc; + +# +# testing purge binary logs BEFORE +# + +reset master; + +flush logs; +flush logs; +flush logs; +remove_file $MYSQLD_DATADIR/master-bin.000001; + +--echo *** must be a warning master-bin.000001 was not found *** +let $date=`select NOW() + INTERVAL 1 MINUTE`; +--disable_query_log +replace_regex /\.[\\\/]master/master/; +--source include/wait_for_binlog_checkpoint.inc +eval purge binary logs BEFORE '$date'; +--enable_query_log + +--echo *** must show one record, of the active binlog, left in the index file after PURGE *** +source include/show_binary_logs.inc; + +# +# testing a fatal error +# Turning a binlog file into a directory must be a portable setup +# + +reset master; + +flush logs; +flush logs; +flush logs; + +remove_file $MYSQLD_DATADIR/master-bin.000001; +mkdir $MYSQLD_DATADIR/master-bin.000001; + +--source include/wait_for_binlog_checkpoint.inc +--error ER_BINLOG_PURGE_FATAL_ERR +purge binary logs TO 'master-bin.000002'; +replace_regex /\.[\\\/]master/master/; +show warnings; +rmdir $MYSQLD_DATADIR/master-bin.000001; +--disable_warnings +reset master; +--enable_warnings + +--echo # crash_purge_before_update_index +flush logs; + +--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +SET SESSION debug_dbug="+d,crash_purge_before_update_index"; +--source include/wait_for_binlog_checkpoint.inc +--error 2013 +purge binary logs TO 'master-bin.000002'; + +--enable_reconnect +--source include/wait_until_connected_again.inc + +file_exists $MYSQLD_DATADIR/master-bin.000001; +file_exists $MYSQLD_DATADIR/master-bin.000002; +file_exists $MYSQLD_DATADIR/master-bin.000003; +--chmod 0644 $INDEX +-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +-- eval SET @index=LOAD_FILE('$index') +-- replace_regex /\.[\\\/]master/master/ +SELECT @index; + +--echo # crash_purge_non_critical_after_update_index +flush logs; + +--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +SET SESSION debug_dbug="+d,crash_purge_non_critical_after_update_index"; +--source include/wait_for_binlog_checkpoint.inc +--error 2013 +purge binary logs TO 'master-bin.000004'; + +--enable_reconnect +--source include/wait_until_connected_again.inc + +--error 1 +file_exists $MYSQLD_DATADIR/master-bin.000001; +--error 1 +file_exists $MYSQLD_DATADIR/master-bin.000002; +--error 1 +file_exists $MYSQLD_DATADIR/master-bin.000003; +--chmod 0644 $INDEX +-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +-- eval SET @index=LOAD_FILE('$index') +-- replace_regex /\.[\\\/]master/master/ +SELECT @index; + +--echo # crash_purge_critical_after_update_index +flush logs; + +--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +SET SESSION debug_dbug="+d,crash_purge_critical_after_update_index"; +--source include/wait_for_binlog_checkpoint.inc +--error 2013 +purge binary logs TO 'master-bin.000006'; + +--enable_reconnect +--source include/wait_until_connected_again.inc + +--error 1 +file_exists $MYSQLD_DATADIR/master-bin.000004; +--error 1 +file_exists $MYSQLD_DATADIR/master-bin.000005; +file_exists $MYSQLD_DATADIR/master-bin.000006; +file_exists $MYSQLD_DATADIR/master-bin.000007; +--error 1 +file_exists $MYSQLD_DATADIR/master-bin.000008; +--chmod 0644 $INDEX +-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +-- eval SET @index=LOAD_FILE('$index') +-- replace_regex /\.[\\\/]master/master/ +SELECT @index; + +--echo # crash_create_non_critical_before_update_index +--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +SET SESSION debug_dbug="+d,crash_create_non_critical_before_update_index"; +--error 2013 +flush logs; + +--enable_reconnect +--source include/wait_until_connected_again.inc + +file_exists $MYSQLD_DATADIR/master-bin.000008; +--error 1 +file_exists $MYSQLD_DATADIR/master-bin.000009; +--chmod 0644 $INDEX +-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +-- eval SET @index=LOAD_FILE('$index') +-- replace_regex /\.[\\\/]master/master/ +SELECT @index; + +--echo # crash_create_critical_before_update_index +--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +SET SESSION debug_dbug="+d,crash_create_critical_before_update_index"; +--error 2013 +flush logs; + +--enable_reconnect +--source include/wait_until_connected_again.inc + +file_exists $MYSQLD_DATADIR/master-bin.000009; +--error 1 +file_exists $MYSQLD_DATADIR/master-bin.000010; +--error 1 +file_exists $MYSQLD_DATADIR/master-bin.000011; +--chmod 0644 $INDEX +-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +-- eval SET @index=LOAD_FILE('$index') +-- replace_regex /\.[\\\/]master/master/ +SELECT @index; + +--echo # crash_create_after_update_index +--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +SET SESSION debug_dbug="+d,crash_create_after_update_index"; +--error 2013 +flush logs; + +--enable_reconnect +--source include/wait_until_connected_again.inc + +file_exists $MYSQLD_DATADIR/master-bin.000010; +file_exists $MYSQLD_DATADIR/master-bin.000011; +--chmod 0644 $INDEX +-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +-- eval SET @index=LOAD_FILE('$index') +-- replace_regex /\.[\\\/]master/master/ +SELECT @index; + +--echo # +--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 # + +--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_dbug="+d,fault_injection_registering_index"; +-- replace_regex /\.[\\\/]master/master/ +-- 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 +-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +-- eval SET @index=LOAD_FILE('$index') +-- replace_regex /\.[\\\/]master/master/ +SELECT @index; + +--echo # fault_injection_updating_index +SET SESSION debug_dbug="+d,fault_injection_updating_index"; +-- replace_regex /\.[\\\/]master/master/ +-- 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 +-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +-- eval SET @index=LOAD_FILE('$index') +-- replace_regex /\.[\\\/]master/master/ +SELECT @index; + +eval SET SESSION debug_dbug="$old"; + +--echo End of tests diff --git a/mysql-test/extra/binlog_tests/binlog_ioerr.inc b/mysql-test/extra/binlog_tests/binlog_ioerr.inc new file mode 100644 index 00000000000..8d1069bacb0 --- /dev/null +++ b/mysql-test/extra/binlog_tests/binlog_ioerr.inc @@ -0,0 +1,36 @@ +# +# This include file is used by more than one test suite +# (currently binlog and binlog_encryption). +# Please check all dependent tests after modifying it +# + +source include/have_debug.inc; +source include/have_innodb.inc; +source include/have_log_bin.inc; +source include/have_binlog_format_mixed_or_statement.inc; + +CALL mtr.add_suppression("Error writing file 'master-bin'"); + +RESET MASTER; + +CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=innodb; +INSERT INTO t1 VALUES(0); +SET SESSION debug_dbug='+d,fail_binlog_write_1'; +--error ER_ERROR_ON_WRITE +INSERT INTO t1 VALUES(1); +--error ER_ERROR_ON_WRITE +INSERT INTO t1 VALUES(2); +SET SESSION debug_dbug=''; +INSERT INTO t1 VALUES(3); +SELECT * FROM t1; + +# Actually the output from this currently shows a bug. +# The injected IO error leaves partially written transactions in the binlog in +# the form of stray "BEGIN" events. +# These should disappear from the output if binlog error handling is improved +# (see MySQL Bug#37148 and WL#1790). +--replace_regex /\/\* xid=.* \*\//\/* XID *\// /Server ver: .*, Binlog ver: .*/Server ver: #, Binlog ver: #/ /table_id: [0-9]+/table_id: #/ +--replace_column 1 BINLOG 2 POS 5 ENDPOS +SHOW BINLOG EVENTS; + +DROP TABLE t1; diff --git a/mysql-test/extra/binlog_tests/binlog_mysqlbinlog-cp932.inc b/mysql-test/extra/binlog_tests/binlog_mysqlbinlog-cp932.inc new file mode 100644 index 00000000000..ac637b2da03 --- /dev/null +++ b/mysql-test/extra/binlog_tests/binlog_mysqlbinlog-cp932.inc @@ -0,0 +1,50 @@ +# +# This include file is used by more than one test suite +# (currently binlog and binlog_encryption). +# Please check all dependent tests after modifying it +# +# Usage: +# --let $use_remote_mysqlbinlog= 1 # optional +# --source extra/binlog_tests/binlog_mysqlbinlog-cp932.inc +# +# By default, the script calls mysqlbinlog to read binary logs directly. +# If it is undesirable, this behavior can be overridden by setting +# $use_remote_binlog as shown above. +# The value will be unset after every execution of the script, +# so if it is needed, it should be set explicitly before each call. + + +# disabled in embedded until tools running is fixed with embedded +--source include/not_embedded.inc + +-- source include/have_binlog_format_mixed_or_statement.inc +-- source include/have_cp932.inc +-- source include/have_log_bin.inc + +RESET MASTER; + +# Bug#16217 (mysql client did not know how not switch its internal charset) +create table t3 (f text character set utf8); +create table t4 (f text character set cp932); +--exec $MYSQL --default-character-set=utf8 test -e "insert into t3 values(_utf8'ソ')" +--exec $MYSQL --default-character-set=cp932 test -e "insert into t4 values(_cp932'ƒ\');" +flush logs; +rename table t3 to t03, t4 to t04; +let $MYSQLD_DATADIR= `select @@datadir`; + +--let $mysqlbinlog_args= $MYSQLD_DATADIR/master-bin.000001 +if ($use_remote_mysqlbinlog) +{ + --let $mysqlbinlog_args= --read-from-remote-server --protocol=tcp --host=127.0.0.1 --port=$MASTER_MYPORT -uroot master-bin.000001 + --let $use_remote_mysqlbinlog= 0 +} + +--exec $MYSQL_BINLOG --short-form $mysqlbinlog_args | $MYSQL --default-character-set=utf8 +# original and recovered data must be equal +select HEX(f) from t03; +select HEX(f) from t3; +select HEX(f) from t04; +select HEX(f) from t4; + +drop table t3, t4, t03, t04; +--echo End of 5.0 tests diff --git a/mysql-test/extra/binlog_tests/binlog_row_annotate.inc b/mysql-test/extra/binlog_tests/binlog_row_annotate.inc new file mode 100644 index 00000000000..b3784ea9606 --- /dev/null +++ b/mysql-test/extra/binlog_tests/binlog_row_annotate.inc @@ -0,0 +1,215 @@ +# +# This include file is used by more than one test suite +# (currently binlog and binlog_encryption). +# Please check all dependent tests after modifying it +# +# Usage: +# --let $use_remote_mysqlbinlog= 1 # optional +# --source extra/binlog_tests/binlog_row_annotate.inc +# +# By default, the script uses mysqlbinlog both with direct access to files +# and via connection to the server. In some cases, direct access to files +# might be impossible (e.g. with encryption). If use_remote_mysqlbinlog +# flag is set, this part of the logic will be omitted. +# + +############################################################################### +# WL47: Store in binlog text of statements that caused RBR events +# new event: ANNOTATE_ROWS_EVENT +# new master option: --binlog-annotate-row-events +# new mysqlbinlog option: --skip-annotate-row-events +# +# Intended to test that: +# *** If the --binlog-annotate-row-events option is switched on on master +# then Annotate_rows events: +# - are generated; +# - are generated only once for "multi-table-maps" rbr queries; +# - are not generated when the corresponding queries are filtered away; +# - are generated when the corresponding queries are filtered away partialy +# (e.g. in case of multi-delete). +# *** Annotate_rows events are printed by mysqlbinlog started without +# --skip-annotate-row-events options both in remote and local cases. +# *** Annotate_rows events are not printed by mysqlbinlog started with +# --skip-annotate-row-events options both in remote and local cases. +############################################################################### + +set @old_binlog_checksum=@@binlog_checksum; +set global binlog_checksum=NONE; + +--source include/have_log_bin.inc +--source include/binlog_start_pos.inc +--source include/have_binlog_format_row.inc + +--disable_query_log + +set sql_mode=""; + +# Fix timestamp to avoid varying results +SET timestamp=1000000000; + +# Delete all existing binary logs +RESET MASTER; + +--disable_warnings +DROP DATABASE IF EXISTS test1; +DROP DATABASE IF EXISTS test2; +DROP DATABASE IF EXISTS test3; +DROP DATABASE IF EXISTS xtest1; +DROP DATABASE IF EXISTS xtest2; +--enable_warnings + +CREATE DATABASE test1; +CREATE TABLE test1.t1(a int); + +CREATE DATABASE test2; +CREATE TABLE test2.t2(a int); +CREATE VIEW test2.v2 AS SELECT * FROM test2.t2; + +CREATE DATABASE test3; +CREATE TABLE test3.t3(a int); + +CREATE DATABASE xtest1; +CREATE TABLE xtest1.xt1(a int); + +CREATE DATABASE xtest2; +CREATE TABLE xtest2.xt2(a int); + +# By default SESSION binlog_annotate_row_events = OFF + +INSERT INTO test1.t1 VALUES (1), (2), (3); + +SET SESSION binlog_annotate_row_events = ON; + +INSERT INTO test2.t2 VALUES (1), (2), (3); +INSERT INTO test3.t3 VALUES (1), (2), (3); + +# This query generates two Table maps but the Annotate +# event should appear only once before the first Table map +DELETE test1.t1, test2.t2 + FROM test1.t1 INNER JOIN test2.t2 INNER JOIN test3.t3 + WHERE test1.t1.a=test2.t2.a AND test2.t2.a=test3.t3.a; + +# This event should be filtered out together with Annotate event +INSERT INTO xtest1.xt1 VALUES (1), (2), (3); + +# This event should pass the filter +INSERT INTO test2.v2 VALUES (1), (2), (3); + +# This event should pass the filter only for test2.t2 part +DELETE xtest1.xt1, test2.t2 + FROM xtest1.xt1 INNER JOIN test2.t2 INNER JOIN test3.t3 + WHERE xtest1.xt1.a=test2.t2.a AND test2.t2.a=test3.t3.a; + +# These events should be filtered out together with Annotate events +INSERT INTO xtest1.xt1 VALUES (1), (2), (3); +INSERT INTO xtest2.xt2 VALUES (1), (2), (3); +DELETE xtest1.xt1, xtest2.xt2 + FROM xtest1.xt1 INNER JOIN xtest2.xt2 INNER JOIN test3.t3 + WHERE xtest1.xt1.a=xtest2.xt2.a AND xtest2.xt2.a=test3.t3.a; + +FLUSH LOGS; +--enable_query_log + +--echo ##################################################################################### +--echo # The following Annotate_rows events should appear below: +--echo # - INSERT INTO test2.t2 VALUES (1), (2), (3) +--echo # - INSERT INTO test3.t3 VALUES (1), (2), (3) +--echo # - DELETE test1.t1, test2.t2 FROM <...> +--echo # - INSERT INTO test2.t2 VALUES (1), (2), (3) +--echo # - DELETE xtest1.xt1, test2.t2 FROM <...> +--echo ##################################################################################### + +let $start_pos= `select @binlog_start_pos`; +--replace_column 2 # 5 # +--replace_result $start_pos <start_pos> +--replace_regex /table_id: [0-9]+/table_id: #/ /\/\* xid=.* \*\//\/* xid= *\// +--eval show binlog events in 'master-bin.000001' from $start_pos + +if (!$use_remote_mysqlbinlog) +{ + --echo # + --echo ##################################################################################### + --echo # mysqlbinlog + --echo # The following Annotates should appear in this output: + --echo # - INSERT INTO test2.t2 VALUES (1), (2), (3) + --echo # - INSERT INTO test3.t3 VALUES (1), (2), (3) + --echo # - DELETE test1.t1, test2.t2 FROM <...> (with two subsequent Table maps) + --echo # - INSERT INTO test2.t2 VALUES (1), (2), (3) + --echo # - DELETE xtest1.xt1, test2.t2 FROM <...> (with one subsequent Table map) + --echo ##################################################################################### + + let $MYSQLD_DATADIR= `select @@datadir`; + --replace_regex /server id [0-9]*/server id #/ /server v [^ ]*/server v #.##.##/ /exec_time=[0-9]*/exec_time=#/ /thread_id=[0-9]*/thread_id=#/ /table id [0-9]*/table id #/ /mapped to number [0-9]*/mapped to number #/ /end_log_pos [0-9]*/end_log_pos #/ /# at [0-9]*/# at #/ + --exec $MYSQL_BINLOG --base64-output=decode-rows -v -v $MYSQLD_DATADIR/master-bin.000001 + + --echo # + --echo ##################################################################################### + --echo # mysqlbinlog --database=test1 + --echo # The following Annotate should appear in this output: + --echo # - DELETE test1.t1, test2.t2 FROM <...> + --echo ##################################################################################### + + let $MYSQLD_DATADIR= `select @@datadir`; + --replace_regex /server id [0-9]*/server id #/ /server v [^ ]*/server v #.##.##/ /exec_time=[0-9]*/exec_time=#/ /thread_id=[0-9]*/thread_id=#/ /table id [0-9]*/table id #/ /mapped to number [0-9]*/mapped to number #/ /end_log_pos [0-9]*/end_log_pos #/ /# at [0-9]*/# at #/ + --exec $MYSQL_BINLOG --base64-output=decode-rows --database=test1 -v -v $MYSQLD_DATADIR/master-bin.000001 + + --echo # + --echo ##################################################################################### + --echo # mysqlbinlog --skip-annotate-row-events + --echo # No Annotates should appear in this output + --echo ##################################################################################### + + let $MYSQLD_DATADIR= `select @@datadir`; + --replace_regex /server id [0-9]*/server id #/ /server v [^ ]*/server v #.##.##/ /exec_time=[0-9]*/exec_time=#/ /thread_id=[0-9]*/thread_id=#/ /table id [0-9]*/table id #/ /mapped to number [0-9]*/mapped to number #/ /end_log_pos [0-9]*/end_log_pos #/ /# at [0-9]*/# at #/ + --exec $MYSQL_BINLOG --base64-output=decode-rows --skip-annotate-row-events -v -v $MYSQLD_DATADIR/master-bin.000001 + + --let $use_remote_mysqlbinlog= 0 +} + +--echo # +--echo ##################################################################################### +--echo # mysqlbinlog --read-from-remote-server +--echo # The following Annotates should appear in this output: +--echo # - INSERT INTO test2.t2 VALUES (1), (2), (3) +--echo # - INSERT INTO test3.t3 VALUES (1), (2), (3) +--echo # - DELETE test1.t1, test2.t2 FROM <...> (with two subsequent Table maps) +--echo # - INSERT INTO test2.t2 VALUES (1), (2), (3) +--echo # - DELETE xtest1.xt1, test2.t2 FROM <...> (with one subsequent Table map) +--echo ##################################################################################### + +let $MYSQLD_DATADIR= `select @@datadir`; +--replace_regex /server id [0-9]*/server id #/ /server v [^ ]*/server v #.##.##/ /exec_time=[0-9]*/exec_time=#/ /thread_id=[0-9]*/thread_id=#/ /table id [0-9]*/table id #/ /mapped to number [0-9]*/mapped to number #/ /end_log_pos [0-9]*/end_log_pos #/ /# at [0-9]*/# at #/ +--exec $MYSQL_BINLOG --base64-output=decode-rows -v -v --read-from-remote-server --user=root --host=localhost --port=$MASTER_MYPORT master-bin.000001 + +--echo # +--echo ##################################################################################### +--echo # mysqlbinlog --read-from-remote-server --database=test1 +--echo # The following Annotate should appear in this output: +--echo # - DELETE test1.t1, test2.t2 FROM <...> +--echo ##################################################################################### + +let $MYSQLD_DATADIR= `select @@datadir`; +--replace_regex /server id [0-9]*/server id #/ /server v [^ ]*/server v #.##.##/ /exec_time=[0-9]*/exec_time=#/ /thread_id=[0-9]*/thread_id=#/ /table id [0-9]*/table id #/ /mapped to number [0-9]*/mapped to number #/ /end_log_pos [0-9]*/end_log_pos #/ /# at [0-9]*/# at #/ +--exec $MYSQL_BINLOG --base64-output=decode-rows --database=test1 -v -v --read-from-remote-server --user=root --host=localhost --port=$MASTER_MYPORT master-bin.000001 + +--echo # +--echo ##################################################################################### +--echo # mysqlbinlog --read-from-remote-server --skip-annotate-row-events +--echo # No Annotates should appear in this output +--echo ##################################################################################### + +let $MYSQLD_DATADIR= `select @@datadir`; +--replace_regex /server id [0-9]*/server id #/ /server v [^ ]*/server v #.##.##/ /exec_time=[0-9]*/exec_time=#/ /thread_id=[0-9]*/thread_id=#/ /table id [0-9]*/table id #/ /mapped to number [0-9]*/mapped to number #/ /end_log_pos [0-9]*/end_log_pos #/ /# at [0-9]*/# at #/ +--exec $MYSQL_BINLOG --base64-output=decode-rows --skip-annotate-row-events -v -v --read-from-remote-server --user=root --host=localhost --port=$MASTER_MYPORT master-bin.000001 + +# Clean-up + +--disable_query_log +set global binlog_checksum=@old_binlog_checksum; +DROP DATABASE test1; +DROP DATABASE test2; +DROP DATABASE test3; +DROP DATABASE xtest1; +DROP DATABASE xtest2; +--enable_query_log + diff --git a/mysql-test/extra/binlog_tests/binlog_write_error.inc b/mysql-test/extra/binlog_tests/binlog_write_error.inc new file mode 100644 index 00000000000..da66dbf5a95 --- /dev/null +++ b/mysql-test/extra/binlog_tests/binlog_write_error.inc @@ -0,0 +1,108 @@ +# +# This include file is used by more than one test suite +# (currently binlog and binlog_encryption). +# Please check all dependent tests after modifying it +# + +# +# === Name === +# +# binlog_write_error.test +# +# === Description === +# +# This test case check if the error of writing binlog file is properly +# reported and handled when executing statements. +# +# === Related Bugs === +# +# BUG#37148 +# + +source include/have_log_bin.inc; +source include/have_debug.inc; +source include/have_binlog_format_mixed_or_statement.inc; + +--echo # +--echo # Initialization +--echo # + +disable_warnings; +DROP TABLE IF EXISTS t1, t2; +DROP FUNCTION IF EXISTS f1; +DROP FUNCTION IF EXISTS f2; +DROP PROCEDURE IF EXISTS p1; +DROP PROCEDURE IF EXISTS p2; +DROP TRIGGER IF EXISTS tr1; +DROP TRIGGER IF EXISTS tr2; +DROP VIEW IF EXISTS v1, v2; +enable_warnings; + +--echo # +--echo # Test injecting binlog write error when executing queries +--echo # + +let $query= CREATE TABLE t1 (a INT); +source include/binlog_inject_error.inc; + +INSERT INTO t1 VALUES (1),(2),(3); + +let $query= INSERT INTO t1 VALUES (4),(5),(6); +source include/binlog_inject_error.inc; + +let $query= UPDATE t1 set a=a+1; +source include/binlog_inject_error.inc; + +let $query= DELETE FROM t1; +source include/binlog_inject_error.inc; + +let $query= CREATE TRIGGER tr1 AFTER INSERT ON t1 FOR EACH ROW INSERT INTO t1 VALUES (new.a + 100); +source include/binlog_inject_error.inc; + +let $query= DROP TRIGGER tr1; +source include/binlog_inject_error.inc; + +let $query= ALTER TABLE t1 ADD (b INT); +source include/binlog_inject_error.inc; + +let $query= CREATE VIEW v1 AS SELECT a FROM t1; +source include/binlog_inject_error.inc; + +let $query= DROP VIEW v1; +source include/binlog_inject_error.inc; + +let $query= CREATE PROCEDURE p1(OUT rows INT) SELECT count(*) INTO rows FROM t1; +source include/binlog_inject_error.inc; + +let $query= DROP PROCEDURE p1; +source include/binlog_inject_error.inc; + +let $query= DROP TABLE t1; +source include/binlog_inject_error.inc; + +let $query= CREATE FUNCTION f1() RETURNS INT return 1; +source include/binlog_inject_error.inc; + +let $query= DROP FUNCTION f1; +source include/binlog_inject_error.inc; + +let $query= CREATE USER user1; +source include/binlog_inject_error.inc; + +let $query= REVOKE ALL PRIVILEGES, GRANT OPTION FROM user1; +source include/binlog_inject_error.inc; + +let $query= DROP USER user1; +source include/binlog_inject_error.inc; + +--echo # +--echo # Cleanup +--echo # + +disable_warnings; +DROP TABLE IF EXISTS t1, t2; +DROP FUNCTION IF EXISTS f1; +DROP PROCEDURE IF EXISTS p1; +DROP TRIGGER IF EXISTS tr1; +DROP VIEW IF EXISTS v1, v2; +enable_warnings; diff --git a/mysql-test/extra/binlog_tests/binlog_xa_recover.inc b/mysql-test/extra/binlog_tests/binlog_xa_recover.inc new file mode 100644 index 00000000000..de2703377cc --- /dev/null +++ b/mysql-test/extra/binlog_tests/binlog_xa_recover.inc @@ -0,0 +1,281 @@ +# +# This include file is used by more than one test suite +# (currently binlog and binlog_encryption). +# Please check all dependent tests after modifying it +# + +--source include/have_innodb.inc +--source include/have_debug.inc +--source include/have_debug_sync.inc +--source include/have_binlog_format_row.inc +# Valgrind does not work well with test that crashes the server +--source include/not_valgrind.inc + +# (We do not need to restore these settings, as we crash the server). +SET GLOBAL max_binlog_size= 4096; +SET GLOBAL innodb_flush_log_at_trx_commit= 1; +RESET MASTER; + +CREATE TABLE t1 (a INT PRIMARY KEY, b MEDIUMTEXT) ENGINE=Innodb; +# Insert some data to force a couple binlog rotations (3), so we get some +# normal binlog checkpoints before starting the test. +INSERT INTO t1 VALUES (100, REPEAT("x", 4100)); +# Wait for the master-bin.000002 binlog checkpoint to appear. +--let $wait_for_all= 0 +--let $show_statement= SHOW BINLOG EVENTS IN "master-bin.000002" +--let $field= Info +--let $condition= = "master-bin.000002" +--source include/wait_show_condition.inc +INSERT INTO t1 VALUES (101, REPEAT("x", 4100)); +--let $wait_for_all= 0 +--let $show_statement= SHOW BINLOG EVENTS IN "master-bin.000003" +--let $field= Info +--let $condition= = "master-bin.000003" +--source include/wait_show_condition.inc +INSERT INTO t1 VALUES (102, REPEAT("x", 4100)); +--let $wait_for_all= 0 +--let $show_statement= SHOW BINLOG EVENTS IN "master-bin.000004" +--let $field= Info +--let $condition= = "master-bin.000004" +--source include/wait_show_condition.inc + +# Now start a bunch of transactions that span multiple binlog +# files. Leave then in the state prepared-but-not-committed in the engine +# and crash the server. Check that crash recovery is able to recover all +# of them. +# +# We use debug_sync to get all the transactions into the prepared state before +# we commit any of them. This is because the prepare step flushes the InnoDB +# redo log - including any commits made before, so recovery would become +# unnecessary, decreasing the value of this test. +# +# We arrange to have con1 with a prepared transaction in master-bin.000004, +# con2 and con3 with a prepared transaction in master-bin.000005, and a new +# empty master-bin.000006. So the latest binlog checkpoint should be +# master-bin.000006. + +connect(con1,localhost,root,,); +# First wait after prepare and before write to binlog. +SET DEBUG_SYNC= "ha_commit_trans_before_log_and_order SIGNAL con1_wait WAIT_FOR con1_cont"; +# Then complete InnoDB commit in memory (but not commit checkpoint / write to +# disk), and hang until crash, leaving a transaction to be XA recovered. +SET DEBUG_SYNC= "commit_after_group_release_commit_ordered SIGNAL con1_ready WAIT_FOR _ever"; +send INSERT INTO t1 VALUES (1, REPEAT("x", 4100)); + +connection default; +SET DEBUG_SYNC= "now WAIT_FOR con1_wait"; + +connect(con2,localhost,root,,); +SET DEBUG_SYNC= "ha_commit_trans_before_log_and_order SIGNAL con2_wait WAIT_FOR con2_cont"; +SET DEBUG_SYNC= "commit_after_group_release_commit_ordered SIGNAL con2_ready WAIT_FOR _ever"; +send INSERT INTO t1 VALUES (2, NULL); + +connection default; +SET DEBUG_SYNC= "now WAIT_FOR con2_wait"; + +connect(con3,localhost,root,,); +SET DEBUG_SYNC= "ha_commit_trans_before_log_and_order SIGNAL con3_wait WAIT_FOR con3_cont"; +SET DEBUG_SYNC= "commit_after_group_release_commit_ordered SIGNAL con3_ready WAIT_FOR _ever"; +send INSERT INTO t1 VALUES (3, REPEAT("x", 4100)); + +connection default; +SET DEBUG_SYNC= "now WAIT_FOR con3_wait"; + +connect(con4,localhost,root,,); +SET DEBUG_SYNC= "ha_commit_trans_before_log_and_order SIGNAL con4_wait WAIT_FOR con4_cont"; +SET SESSION debug_dbug="+d,crash_commit_after_log"; +send INSERT INTO t1 VALUES (4, NULL); + +connection default; +SET DEBUG_SYNC= "now WAIT_FOR con4_wait"; + +SET DEBUG_SYNC= "now SIGNAL con1_cont"; +SET DEBUG_SYNC= "now WAIT_FOR con1_ready"; +SET DEBUG_SYNC= "now SIGNAL con2_cont"; +SET DEBUG_SYNC= "now WAIT_FOR con2_ready"; +SET DEBUG_SYNC= "now SIGNAL con3_cont"; +SET DEBUG_SYNC= "now WAIT_FOR con3_ready"; + +# Check that everything is committed in binary log. +--source include/show_binary_logs.inc +--let $binlog_file= master-bin.000003 +--let $binlog_start= 4 +--source include/show_binlog_events.inc +--let $binlog_file= master-bin.000004 +--source include/show_binlog_events.inc +--let $binlog_file= master-bin.000005 +--source include/show_binlog_events.inc +--let $binlog_file= master-bin.000006 +--source include/show_binlog_events.inc + + +# Check that server will not purge too much. +PURGE BINARY LOGS TO "master-bin.000006"; +--source include/show_binary_logs.inc + +# Now crash the server with one more transaction in prepared state. +--write_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +wait-binlog_xa_recover.test +EOF +--error 0,2006,2013 +SET DEBUG_SYNC= "now SIGNAL con4_cont"; +connection con4; +--error 2006,2013 +reap; + +--append_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +restart-group_commit_binlog_pos.test +EOF + +connection default; +--enable_reconnect +--source include/wait_until_connected_again.inc + +# Check that all transactions are recovered. +SELECT a FROM t1 ORDER BY a; + +--echo Test that with multiple binlog checkpoints, recovery starts from the last one. +SET GLOBAL max_binlog_size= 4096; +SET GLOBAL innodb_flush_log_at_trx_commit= 1; +RESET MASTER; + +# Rotate to binlog master-bin.000003 while delaying binlog checkpoints. +# So we get multiple binlog checkpoints in master-bin.000003. +# Then complete the checkpoints, crash, and check that we only scan +# the necessary binlog file (ie. that we use the _last_ checkpoint). + +connect(con10,localhost,root,,); +SET DEBUG_SYNC= "commit_after_group_release_commit_ordered SIGNAL con10_ready WAIT_FOR con10_cont"; +send INSERT INTO t1 VALUES (10, REPEAT("x", 4100)); + +connection default; +SET DEBUG_SYNC= "now WAIT_FOR con10_ready"; + +connect(con11,localhost,root,,); +SET DEBUG_SYNC= "commit_after_group_release_commit_ordered SIGNAL con11_ready WAIT_FOR con11_cont"; +send INSERT INTO t1 VALUES (11, REPEAT("x", 4100)); + +connection default; +SET DEBUG_SYNC= "now WAIT_FOR con11_ready"; + +connect(con12,localhost,root,,); +SET DEBUG_SYNC= "commit_after_group_release_commit_ordered SIGNAL con12_ready WAIT_FOR con12_cont"; +send INSERT INTO t1 VALUES (12, REPEAT("x", 4100)); + +connection default; +SET DEBUG_SYNC= "now WAIT_FOR con12_ready"; +INSERT INTO t1 VALUES (13, NULL); + +--source include/show_binary_logs.inc +--let $binlog_file= master-bin.000004 +--let $binlog_start= 4 +--source include/show_binlog_events.inc + +SET DEBUG_SYNC= "now SIGNAL con10_cont"; +connection con10; +reap; +connection default; + +# We need to sync the test case with the background processing of the +# commit checkpoint, otherwise we get nondeterministic results. +SET @old_dbug= @@global.DEBUG_DBUG; +SET GLOBAL debug_dbug="+d,binlog_background_checkpoint_processed"; + +SET DEBUG_SYNC= "now SIGNAL con12_cont"; +connection con12; +reap; +connection default; +SET DEBUG_SYNC= "now WAIT_FOR binlog_background_checkpoint_processed"; +SET GLOBAL debug_dbug= @old_dbug; + +SET DEBUG_SYNC= "now SIGNAL con11_cont"; +connection con11; +reap; + +connection default; +# Wait for the last (master-bin.000004) binlog checkpoint to appear. +--let $wait_for_all= 0 +--let $show_statement= SHOW BINLOG EVENTS IN "master-bin.000004" +--let $field= Info +--let $condition= = "master-bin.000004" +--source include/wait_show_condition.inc + +--echo Checking that master-bin.000004 is the last binlog checkpoint +--source include/show_binlog_events.inc + +--echo Now crash the server +# It is not too easy to test XA recovery, as it runs early during server +# startup, before any connections can be made. +# What we do is set a DBUG error insert which will crash if XA recovery +# starts from any other binlog than master-bin.000004 (check the file +# binlog_xa_recover-master.opt). Then we will fail here if XA recovery +# would start from the wrong place. +--write_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +wait-binlog_xa_recover.test +EOF +SET SESSION debug_dbug="+d,crash_commit_after_log"; +--error 2006,2013 +INSERT INTO t1 VALUES (14, NULL); + +--append_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +restart-group_commit_binlog_pos.test +EOF + +connection default; +--enable_reconnect +--source include/wait_until_connected_again.inc + +# Check that all transactions are recovered. +SELECT a FROM t1 ORDER BY a; + + +--echo *** Check that recovery works if we crashed early during rotate, before +--echo *** binlog checkpoint event could be written. + +SET GLOBAL max_binlog_size= 4096; +SET GLOBAL innodb_flush_log_at_trx_commit= 1; +RESET MASTER; + +# We need some initial data to reach binlog master-bin.000004. Otherwise +# crash recovery fails due to the error insert used for previous test. +INSERT INTO t1 VALUES (21, REPEAT("x", 4100)); +INSERT INTO t1 VALUES (22, REPEAT("x", 4100)); +# Wait for the master-bin.000003 binlog checkpoint to appear. +--let $wait_for_all= 0 +--let $show_statement= SHOW BINLOG EVENTS IN "master-bin.000003" +--let $field= Info +--let $condition= = "master-bin.000003" +--source include/wait_show_condition.inc +INSERT INTO t1 VALUES (23, REPEAT("x", 4100)); +# Wait for the last (master-bin.000004) binlog checkpoint to appear. +--let $wait_for_all= 0 +--let $show_statement= SHOW BINLOG EVENTS IN "master-bin.000004" +--let $field= Info +--let $condition= = "master-bin.000004" +--source include/wait_show_condition.inc + +--write_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +wait-binlog_xa_recover.test +EOF +SET SESSION debug_dbug="+d,crash_before_write_checkpoint_event"; +--error 2006,2013 +INSERT INTO t1 VALUES (24, REPEAT("x", 4100)); + +--append_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +restart-group_commit_binlog_pos.test +EOF + +--enable_reconnect +--source include/wait_until_connected_again.inc + +# Check that all transactions are recovered. +SELECT a FROM t1 ORDER BY a; + +--source include/show_binary_logs.inc +--let $binlog_file= master-bin.000004 +--let $binlog_start= 4 +--source include/show_binlog_events.inc + +# Cleanup +connection default; +DROP TABLE t1; diff --git a/mysql-test/extra/binlog_tests/database.test b/mysql-test/extra/binlog_tests/database.test index 6b3da087f01..097a501cc34 100644 --- a/mysql-test/extra/binlog_tests/database.test +++ b/mysql-test/extra/binlog_tests/database.test @@ -52,7 +52,7 @@ eval SELECT 'hello' INTO OUTFILE 'fake_file.$prefix'; # Use '/' instead of '\' in the error message. On windows platform, dir is # formed with '\'. ---replace_regex /\\testing_1\\*/\/testing_1\// /66/39/ /17/39/ /File exists/Directory not empty/ +--replace_regex /\\testing_1\\*/\/testing_1\// /66/39/ /93/39/ /17/39/ /247/39/ /File exists/Directory not empty/ --error 1010 DROP DATABASE testing_1; let $wait_binlog_event= DROP TABLE IF EXIST; |