[Maria-developers] Please review MDEV-9038 Binlog encryption tests
$MYSQLTEST_VARDIR/tmp/binlog_incident.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.sql') AS cont) AS tbl; +--enable_query_log
Hi Sergei, Please let me know if you want to review the binlog encryption tests, otherwise I can just push them into 10.1. There are no changes apart from tests, and in this form they've passed a buildbot round on a development tree. After they're merged into 10.2, several tests will fail, this is expected. I will attach to the JIRA issue a separate patch which should fix them after the merge. Regards, /E -------- Forwarded Message -------- Subject: [Commits] ff7bee0: MDEV-9038 Binlog encryption tests Date: Mon, 28 Nov 2016 02:47:14 +0200 (EET) From: elenst@montyprogram.com Reply-To: maria-developers@lists.launchpad.net To: commits@mariadb.org revision-id: ff7bee04f8abb6d95adc73fcfe7e213b5972d698 (mariadb-10.1.19-14-gff7bee0) parent(s): a68d1352b60bfc3a424fd290a4f5a1beae1bb71e author: Elena Stepanova committer: Elena Stepanova timestamp: 2016-11-27 18:09:19 +0200 message: MDEV-9038 Binlog encryption tests --- mysql-test/mysql-test-run.pl | 1 + .../suite/binlog_encryption/binlog_index.result | 187 ++ .../suite/binlog_encryption/binlog_index.test | 276 ++ .../suite/binlog_encryption/binlog_ioerr.result | 32 + .../suite/binlog_encryption/binlog_ioerr.test | 33 + .../binlog_mysqlbinlog-cp932-master.opt | 1 + .../binlog_mysqlbinlog-cp932.result | 19 + .../binlog_mysqlbinlog-cp932.test | 32 + .../binlog_row_annotate-master.opt | 1 + .../binlog_encryption/binlog_row_annotate.result | 724 ++++++ .../binlog_encryption/binlog_row_annotate.test | 160 ++ .../binlog_encryption/binlog_write_error.result | 108 + .../binlog_encryption/binlog_write_error.test | 106 + .../binlog_encryption/binlog_xa_recover-master.opt | 1 + .../binlog_encryption/binlog_xa_recover.result | 240 ++ .../suite/binlog_encryption/binlog_xa_recover.test | 304 +++ mysql-test/suite/binlog_encryption/disabled.def | 1 + .../binlog_encryption/encrypted_master.result | 694 +++++ .../suite/binlog_encryption/encrypted_master.test | 188 ++ .../encrypted_master_lost_key.result | 111 + .../encrypted_master_lost_key.test | 206 ++ .../encrypted_master_switch_to_unencrypted.test | 137 + .../suite/binlog_encryption/encrypted_slave.cnf | 12 + .../suite/binlog_encryption/encrypted_slave.result | 247 ++ .../suite/binlog_encryption/encrypted_slave.test | 122 + .../encryption_algorithms.combinations | 5 + .../binlog_encryption/encryption_algorithms.inc | 2 + .../suite/binlog_encryption/encryption_combo.cnf | 5 + .../binlog_encryption/encryption_combo.result | 94 + .../suite/binlog_encryption/encryption_combo.test | 136 + mysql-test/suite/binlog_encryption/grep_binlog.inc | 54 + .../master_switch_to_unencrypted.cnf | 4 + mysql-test/suite/binlog_encryption/multisource.cnf | 17 + .../suite/binlog_encryption/multisource.result | 228 ++ .../suite/binlog_encryption/multisource.test | 335 +++ mysql-test/suite/binlog_encryption/my.cnf | 27 + .../suite/binlog_encryption/restart_server.inc | 35 + .../suite/binlog_encryption/rpl_binlog_errors.cnf | 7 + .../binlog_encryption/rpl_binlog_errors.result | 280 ++ .../suite/binlog_encryption/rpl_binlog_errors.test | 439 ++++ .../rpl_cant_read_event_incident.result | 26 + .../rpl_cant_read_event_incident.test | 92 + .../suite/binlog_encryption/rpl_checksum.cnf | 10 + .../suite/binlog_encryption/rpl_checksum.result | 157 ++ .../suite/binlog_encryption/rpl_checksum.test | 326 +++ .../binlog_encryption/rpl_checksum_cache.result | 136 + .../binlog_encryption/rpl_checksum_cache.test | 271 ++ .../suite/binlog_encryption/rpl_corruption.cnf | 9 + .../suite/binlog_encryption/rpl_corruption.result | 63 + .../suite/binlog_encryption/rpl_corruption.test | 193 ++ .../suite/binlog_encryption/rpl_gtid_basic.cnf | 24 + .../suite/binlog_encryption/rpl_gtid_basic.result | 558 ++++ .../suite/binlog_encryption/rpl_gtid_basic.test | 644 +++++ .../suite/binlog_encryption/rpl_incident.cnf | 7 + .../suite/binlog_encryption/rpl_incident.result | 42 + .../suite/binlog_encryption/rpl_incident.test | 72 + .../binlog_encryption/rpl_init_slave_errors.result | 22 + .../binlog_encryption/rpl_init_slave_errors.test | 100 + .../binlog_encryption/rpl_loaddata_local.result | 134 + .../binlog_encryption/rpl_loaddata_local.test | 233 ++ .../suite/binlog_encryption/rpl_loadfile.result | 262 ++ .../suite/binlog_encryption/rpl_loadfile.test | 137 + .../rpl_mixed_binlog_max_cache_size.result | 210 ++ .../rpl_mixed_binlog_max_cache_size.test | 489 ++++ mysql-test/suite/binlog_encryption/rpl_packet.cnf | 10 + .../suite/binlog_encryption/rpl_packet.result | 83 + mysql-test/suite/binlog_encryption/rpl_packet.test | 199 ++ .../suite/binlog_encryption/rpl_parallel.result | 2025 +++++++++++++++ .../suite/binlog_encryption/rpl_parallel.test | 2729 ++++++++++++++++++++ .../rpl_parallel_show_binlog_events_purge_logs.cnf | 6 + ...l_parallel_show_binlog_events_purge_logs.result | 13 + ...rpl_parallel_show_binlog_events_purge_logs.test | 39 + .../binlog_encryption/rpl_relayrotate-slave.opt | 5 + .../suite/binlog_encryption/rpl_relayrotate.result | 20 + .../suite/binlog_encryption/rpl_relayrotate.test | 21 + .../suite/binlog_encryption/rpl_semi_sync.result | 488 ++++ .../suite/binlog_encryption/rpl_semi_sync.test | 606 +++++ .../binlog_encryption/rpl_skip_replication.cnf | 6 + .../binlog_encryption/rpl_skip_replication.result | 312 +++ .../binlog_encryption/rpl_skip_replication.test | 401 +++ .../binlog_encryption/rpl_special_charset.opt | 1 + .../binlog_encryption/rpl_special_charset.result | 10 + .../binlog_encryption/rpl_special_charset.test | 35 + .../rpl_sporadic_master-master.opt | 1 + .../binlog_encryption/rpl_sporadic_master.result | 28 + .../binlog_encryption/rpl_sporadic_master.test | 34 + mysql-test/suite/binlog_encryption/rpl_ssl.result | 55 + mysql-test/suite/binlog_encryption/rpl_ssl.test | 126 + .../rpl_stm_relay_ign_space-slave.opt | 1 + .../rpl_stm_relay_ign_space.result | 6 + .../binlog_encryption/rpl_stm_relay_ign_space.test | 117 + .../rpl_switch_stm_row_mixed.result | 457 ++++ .../rpl_switch_stm_row_mixed.test | 634 +++++ .../suite/binlog_encryption/rpl_sync-master.opt | 2 + .../suite/binlog_encryption/rpl_sync-slave.opt | 2 + mysql-test/suite/binlog_encryption/rpl_sync.result | 53 + mysql-test/suite/binlog_encryption/rpl_sync.test | 180 ++ .../rpl_temporal_format_default_to_default.cnf | 6 + .../rpl_temporal_format_default_to_default.result | 91 + .../rpl_temporal_format_default_to_default.test | 82 + .../rpl_temporal_format_mariadb53_to_mysql56.cnf | 6 + ...rpl_temporal_format_mariadb53_to_mysql56.result | 95 + .../rpl_temporal_format_mariadb53_to_mysql56.test | 18 + .../rpl_temporal_format_mysql56_to_mariadb53.cnf | 6 + ...rpl_temporal_format_mysql56_to_mariadb53.result | 95 + .../rpl_temporal_format_mysql56_to_mariadb53.test | 8 + .../suite/binlog_encryption/rpl_typeconv.result | 548 ++++ .../suite/binlog_encryption/rpl_typeconv.test | 81 + mysql-test/suite/binlog_encryption/suite.pm | 18 + mysql-test/suite/binlog_encryption/testdata.inc | 207 ++ mysql-test/suite/binlog_encryption/testdata.opt | 1 + mysql-test/unstable-tests | 4 + 112 files changed, 19799 insertions(+) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 2bd89f5..2485b94 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -170,6 +170,7 @@ my @DEFAULT_SUITES= qw( main- archive- binlog- + binlog_encryption- csv- encryption- federated- diff --git a/mysql-test/suite/binlog_encryption/binlog_index.result b/mysql-test/suite/binlog_encryption/binlog_index.result new file mode 100644 index 0000000..8cdca86 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/binlog_index.result @@ -0,0 +1,187 @@ +call mtr.add_suppression('Attempting backtrace'); +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.'); +flush tables; +RESET MASTER; +flush logs; +flush logs; +flush logs; +show binary logs; +Log_name File_size +master-bin.000001 # +master-bin.000002 # +master-bin.000003 # +master-bin.000004 # +flush tables; +purge binary logs TO 'master-bin.000004'; +Warnings: +Warning 1612 Being purged log master-bin.000001 was not found +*** must show a list starting from the 'TO' argument of PURGE *** +show binary logs; +Log_name File_size +master-bin.000004 # +reset master; +flush logs; +flush logs; +flush logs; +*** must be a warning master-bin.000001 was not found *** +Warnings: +Warning 1612 Being purged log master-bin.000001 was not found +*** must show one record, of the active binlog, left in the index file after PURGE *** +show binary logs; +Log_name File_size +master-bin.000004 # +reset master; +flush logs; +flush logs; +flush logs; +purge binary logs TO 'master-bin.000002'; +ERROR HY000: Fatal error during log purge +show warnings; +Level Code Message +Warning 1377 a problem with deleting master-bin.000001; consider examining correspondence of your binlog index file to the actual binlog files +Error 1377 Fatal error during log purge +reset master; +# crash_purge_before_update_index +flush logs; +SET SESSION debug_dbug="+d,crash_purge_before_update_index"; +purge binary logs TO 'master-bin.000002'; +ERROR HY000: Lost connection to MySQL server during query +SET @index=LOAD_FILE('MYSQLTEST_VARDIR/mysqld.1/data//master-bin.index'); +SELECT @index; +@index +master-bin.000001 +master-bin.000002 +master-bin.000003 + +# crash_purge_non_critical_after_update_index +flush logs; +SET SESSION debug_dbug="+d,crash_purge_non_critical_after_update_index"; +purge binary logs TO 'master-bin.000004'; +ERROR HY000: Lost connection to MySQL server during query +SET @index=LOAD_FILE('MYSQLTEST_VARDIR/mysqld.1/data//master-bin.index'); +SELECT @index; +@index +master-bin.000004 +master-bin.000005 + +# crash_purge_critical_after_update_index +flush logs; +SET SESSION debug_dbug="+d,crash_purge_critical_after_update_index"; +purge binary logs TO 'master-bin.000006'; +ERROR HY000: Lost connection to MySQL server during query +SET @index=LOAD_FILE('MYSQLTEST_VARDIR/mysqld.1/data//master-bin.index'); +SELECT @index; +@index +master-bin.000006 +master-bin.000007 + +# crash_create_non_critical_before_update_index +SET SESSION debug_dbug="+d,crash_create_non_critical_before_update_index"; +flush logs; +ERROR HY000: Lost connection to MySQL server during query +SET @index=LOAD_FILE('MYSQLTEST_VARDIR/mysqld.1/data//master-bin.index'); +SELECT @index; +@index +master-bin.000006 +master-bin.000007 +master-bin.000008 + +# crash_create_critical_before_update_index +SET SESSION debug_dbug="+d,crash_create_critical_before_update_index"; +flush logs; +ERROR HY000: Lost connection to MySQL server during query +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 + +# crash_create_after_update_index +SET SESSION debug_dbug="+d,crash_create_after_update_index"; +flush logs; +ERROR HY000: Lost connection to MySQL server during query +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 + +# +# 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. +# +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_dbug="+d,fault_injection_registering_index"; +flush logs; +ERROR HY000: Can't open file: 'master-bin.000012' (errno: 1 "Operation not permitted") +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 +master-bin.000006 +master-bin.000007 +master-bin.000008 +master-bin.000009 +master-bin.000010 +master-bin.000011 +master-bin.000012 + +# fault_injection_updating_index +SET SESSION debug_dbug="+d,fault_injection_updating_index"; +flush logs; +ERROR HY000: Can't open file: 'master-bin.000013' (errno: 1 "Operation not permitted") +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 +master-bin.000006 +master-bin.000007 +master-bin.000008 +master-bin.000009 +master-bin.000010 +master-bin.000011 +master-bin.000012 +master-bin.000013 + +SET SESSION debug_dbug=""; +End of tests diff --git a/mysql-test/suite/binlog_encryption/binlog_index.test b/mysql-test/suite/binlog_encryption/binlog_index.test new file mode 100644 index 0000000..b85bf6c --- /dev/null +++ b/mysql-test/suite/binlog_encryption/binlog_index.test @@ -0,0 +1,276 @@ +# +# The test was taken as is from the binlog suite +# + +# +# 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('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.'); +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/suite/binlog_encryption/binlog_ioerr.result b/mysql-test/suite/binlog_encryption/binlog_ioerr.result new file mode 100644 index 0000000..6b3120b --- /dev/null +++ b/mysql-test/suite/binlog_encryption/binlog_ioerr.result @@ -0,0 +1,32 @@ +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'; +INSERT INTO t1 VALUES(1); +ERROR HY000: Error writing file 'master-bin' (errno: 28 "No space left on device") +INSERT INTO t1 VALUES(2); +ERROR HY000: Error writing file 'master-bin' (errno: 28 "No space left on device") +SET SESSION debug_dbug=''; +INSERT INTO t1 VALUES(3); +SELECT * FROM t1; +a +0 +3 +SHOW BINLOG EVENTS; +Log_name Pos Event_type Server_id End_log_pos Info +BINLOG POS Format_desc 1 ENDPOS Server ver: #, Binlog ver: # +BINLOG POS Start_encryption 1 ENDPOS +BINLOG POS Gtid_list 1 ENDPOS [] +BINLOG POS Binlog_checkpoint 1 ENDPOS master-bin.000001 +BINLOG POS Gtid 1 ENDPOS GTID 0-1-1 +BINLOG POS Query 1 ENDPOS use `test`; CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=innodb +BINLOG POS Gtid 1 ENDPOS BEGIN GTID 0-1-2 +BINLOG POS Query 1 ENDPOS use `test`; INSERT INTO t1 VALUES(0) +BINLOG POS Xid 1 ENDPOS COMMIT /* XID */ +BINLOG POS Gtid 1 ENDPOS BEGIN GTID 0-1-3 +BINLOG POS Gtid 1 ENDPOS BEGIN GTID 0-1-4 +BINLOG POS Gtid 1 ENDPOS BEGIN GTID 0-1-5 +BINLOG POS Query 1 ENDPOS use `test`; INSERT INTO t1 VALUES(3) +BINLOG POS Xid 1 ENDPOS COMMIT /* XID */ +DROP TABLE t1; diff --git a/mysql-test/suite/binlog_encryption/binlog_ioerr.test b/mysql-test/suite/binlog_encryption/binlog_ioerr.test new file mode 100644 index 0000000..4758d86 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/binlog_ioerr.test @@ -0,0 +1,33 @@ +# +# The test was taken from the binlog suite as is, only result file was modified +# + +source include/have_debug.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/suite/binlog_encryption/binlog_mysqlbinlog-cp932-master.opt b/mysql-test/suite/binlog_encryption/binlog_mysqlbinlog-cp932-master.opt new file mode 100644 index 0000000..bb0cda4 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/binlog_mysqlbinlog-cp932-master.opt @@ -0,0 +1 @@ +--max-binlog-size=8192 diff --git a/mysql-test/suite/binlog_encryption/binlog_mysqlbinlog-cp932.result b/mysql-test/suite/binlog_encryption/binlog_mysqlbinlog-cp932.result new file mode 100644 index 0000000..cbf6159 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/binlog_mysqlbinlog-cp932.result @@ -0,0 +1,19 @@ +RESET MASTER; +create table t3 (f text character set utf8); +create table t4 (f text character set cp932); +flush logs; +rename table t3 to t03, t4 to t04; +select HEX(f) from t03; +HEX(f) +E382BD +select HEX(f) from t3; +HEX(f) +E382BD +select HEX(f) from t04; +HEX(f) +835C +select HEX(f) from t4; +HEX(f) +835C +drop table t3, t4, t03, t04; +End of 5.0 tests diff --git a/mysql-test/suite/binlog_encryption/binlog_mysqlbinlog-cp932.test b/mysql-test/suite/binlog_encryption/binlog_mysqlbinlog-cp932.test new file mode 100644 index 0000000..68056e1 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/binlog_mysqlbinlog-cp932.test @@ -0,0 +1,32 @@ +# +# The test was taken almost as is from the binlog suite, except that +# mysqlbinlog cannot read encrypted files directly, so it reads +# from the server instead +# + +# 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`; +--exec $MYSQL_BINLOG --read-from-remote-server --port=$MASTER_MYPORT -uroot --short-form master-bin.000001 | $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/suite/binlog_encryption/binlog_row_annotate-master.opt b/mysql-test/suite/binlog_encryption/binlog_row_annotate-master.opt new file mode 100644 index 0000000..344a4ff --- /dev/null +++ b/mysql-test/suite/binlog_encryption/binlog_row_annotate-master.opt @@ -0,0 +1 @@ +--timezone=GMT-3 --binlog-do-db=test1 --binlog-do-db=test2 --binlog-do-db=test3 --binlog-checksum=NONE diff --git a/mysql-test/suite/binlog_encryption/binlog_row_annotate.result b/mysql-test/suite/binlog_encryption/binlog_row_annotate.result new file mode 100644 index 0000000..d32b80b --- /dev/null +++ b/mysql-test/suite/binlog_encryption/binlog_row_annotate.result @@ -0,0 +1,724 @@ +##################################################################################### +# The following Annotate_rows events should appear below: +# - INSERT INTO test2.t2 VALUES (1), (2), (3) +# - INSERT INTO test3.t3 VALUES (1), (2), (3) +# - DELETE test1.t1, test2.t2 FROM <...> +# - INSERT INTO test2.t2 VALUES (1), (2), (3) +# - DELETE xtest1.xt1, test2.t2 FROM <...> +##################################################################################### +show binlog events in 'master-bin.000001' from <start_pos>; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Start_encryption 1 # +master-bin.000001 # Gtid_list 1 # [] +master-bin.000001 # Binlog_checkpoint 1 # master-bin.000001 +master-bin.000001 # Gtid 1 # GTID 0-1-1 +master-bin.000001 # Query 1 # DROP DATABASE IF EXISTS test1 +master-bin.000001 # Gtid 1 # GTID 0-1-2 +master-bin.000001 # Query 1 # DROP DATABASE IF EXISTS test2 +master-bin.000001 # Gtid 1 # GTID 0-1-3 +master-bin.000001 # Query 1 # DROP DATABASE IF EXISTS test3 +master-bin.000001 # Gtid 1 # GTID 0-1-4 +master-bin.000001 # Query 1 # CREATE DATABASE test1 +master-bin.000001 # Gtid 1 # GTID 0-1-5 +master-bin.000001 # Query 1 # CREATE DATABASE test2 +master-bin.000001 # Gtid 1 # GTID 0-1-6 +master-bin.000001 # Query 1 # CREATE DATABASE test3 +master-bin.000001 # Gtid 1 # BEGIN GTID 0-1-7 +master-bin.000001 # Table_map 1 # table_id: # (test1.t1) +master-bin.000001 # Write_rows_v1 1 # table_id: # flags: STMT_END_F +master-bin.000001 # Query 1 # COMMIT +master-bin.000001 # Gtid 1 # BEGIN GTID 0-1-8 +master-bin.000001 # Annotate_rows 1 # INSERT INTO test2.t2 VALUES (1), (2), (3) +master-bin.000001 # Table_map 1 # table_id: # (test2.t2) +master-bin.000001 # Write_rows_v1 1 # table_id: # flags: STMT_END_F +master-bin.000001 # Query 1 # COMMIT +master-bin.000001 # Gtid 1 # BEGIN GTID 0-1-9 +master-bin.000001 # Annotate_rows 1 # INSERT INTO test3.t3 VALUES (1), (2), (3) +master-bin.000001 # Table_map 1 # table_id: # (test3.t3) +master-bin.000001 # Write_rows_v1 1 # table_id: # flags: STMT_END_F +master-bin.000001 # Query 1 # COMMIT +master-bin.000001 # Gtid 1 # BEGIN GTID 0-1-10 +master-bin.000001 # Annotate_rows 1 # 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 +master-bin.000001 # Table_map 1 # table_id: # (test1.t1) +master-bin.000001 # Table_map 1 # table_id: # (test2.t2) +master-bin.000001 # Delete_rows_v1 1 # table_id: # +master-bin.000001 # Delete_rows_v1 1 # table_id: # flags: STMT_END_F +master-bin.000001 # Query 1 # COMMIT +master-bin.000001 # Gtid 1 # BEGIN GTID 0-1-11 +master-bin.000001 # Annotate_rows 1 # INSERT INTO test2.v2 VALUES (1), (2), (3) +master-bin.000001 # Table_map 1 # table_id: # (test2.t2) +master-bin.000001 # Write_rows_v1 1 # table_id: # flags: STMT_END_F +master-bin.000001 # Query 1 # COMMIT +master-bin.000001 # Gtid 1 # BEGIN GTID 0-1-12 +master-bin.000001 # Annotate_rows 1 # 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 +master-bin.000001 # Table_map 1 # table_id: # (test2.t2) +master-bin.000001 # Delete_rows_v1 1 # table_id: # flags: STMT_END_F +master-bin.000001 # Query 1 # COMMIT +master-bin.000001 # Rotate 1 # master-bin.000002;pos=4 +# +##################################################################################### +# mysqlbinlog --read-from-remote-server +# The following Annotates should appear in this output: +# - INSERT INTO test2.t2 VALUES (1), (2), (3) +# - INSERT INTO test3.t3 VALUES (1), (2), (3) +# - DELETE test1.t1, test2.t2 FROM <...> (with two subsequent Table maps) +# - INSERT INTO test2.t2 VALUES (1), (2), (3) +# - DELETE xtest1.xt1, test2.t2 FROM <...> (with one subsequent Table map) +##################################################################################### +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/; +/*!40019 SET @@session.max_insert_delayed_threads=0*/; +/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; +DELIMITER /*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # Start: binlog v 4, server v #.##.## created 010909 4:46:40 at startup +ROLLBACK/*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # Gtid list [] +# at # +#010909 4:46:40 server id # end_log_pos # Binlog checkpoint master-bin.000001 +# at # +#010909 4:46:40 server id # end_log_pos # GTID 0-1-1 ddl +/*!100101 SET @@session.skip_parallel_replication=0*//*!*/; +/*!100001 SET @@session.gtid_domain_id=0*//*!*/; +/*!100001 SET @@session.server_id=1*//*!*/; +/*!100001 SET @@session.gtid_seq_no=1*//*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0 +SET TIMESTAMP=1000000000/*!*/; +SET @@session.pseudo_thread_id=#/*!*/; +SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/; +SET @@session.sql_mode=0/*!*/; +SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/; +/*!\C latin1 *//*!*/; +SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/; +SET @@session.lc_time_names=0/*!*/; +SET @@session.collation_database=DEFAULT/*!*/; +DROP DATABASE IF EXISTS test1 +/*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # GTID 0-1-2 ddl +/*!100001 SET @@session.gtid_seq_no=2*//*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0 +SET TIMESTAMP=1000000000/*!*/; +DROP DATABASE IF EXISTS test2 +/*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # GTID 0-1-3 ddl +/*!100001 SET @@session.gtid_seq_no=3*//*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0 +SET TIMESTAMP=1000000000/*!*/; +DROP DATABASE IF EXISTS test3 +/*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # GTID 0-1-4 ddl +/*!100001 SET @@session.gtid_seq_no=4*//*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0 +SET TIMESTAMP=1000000000/*!*/; +CREATE DATABASE test1 +/*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # GTID 0-1-5 ddl +/*!100001 SET @@session.gtid_seq_no=5*//*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0 +SET TIMESTAMP=1000000000/*!*/; +CREATE DATABASE test2 +/*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # GTID 0-1-6 ddl +/*!100001 SET @@session.gtid_seq_no=6*//*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0 +SET TIMESTAMP=1000000000/*!*/; +CREATE DATABASE test3 +/*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # GTID 0-1-7 +/*!100001 SET @@session.gtid_seq_no=7*//*!*/; +BEGIN +/*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # Table_map: `test1`.`t1` mapped to number # +# at # +#010909 4:46:40 server id # end_log_pos # Write_rows: table id # flags: STMT_END_F +### INSERT INTO `test1`.`t1` +### SET +### @1=1 /* INT meta=0 nullable=1 is_null=0 */ +### INSERT INTO `test1`.`t1` +### SET +### @1=2 /* INT meta=0 nullable=1 is_null=0 */ +### INSERT INTO `test1`.`t1` +### SET +### @1=3 /* INT meta=0 nullable=1 is_null=0 */ +# at # +#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0 +SET TIMESTAMP=1000000000/*!*/; +COMMIT +/*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # GTID 0-1-8 +/*!100001 SET @@session.gtid_seq_no=8*//*!*/; +BEGIN +/*!*/; +# at # +# at # +#010909 4:46:40 server id # end_log_pos # Annotate_rows: +#Q> INSERT INTO test2.t2 VALUES (1), (2), (3) +#010909 4:46:40 server id # end_log_pos # Table_map: `test2`.`t2` mapped to number # +# at # +#010909 4:46:40 server id # end_log_pos # Write_rows: table id # flags: STMT_END_F +### INSERT INTO `test2`.`t2` +### SET +### @1=1 /* INT meta=0 nullable=1 is_null=0 */ +### INSERT INTO `test2`.`t2` +### SET +### @1=2 /* INT meta=0 nullable=1 is_null=0 */ +### INSERT INTO `test2`.`t2` +### SET +### @1=3 /* INT meta=0 nullable=1 is_null=0 */ +# at # +#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0 +SET TIMESTAMP=1000000000/*!*/; +COMMIT +/*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # GTID 0-1-9 +/*!100001 SET @@session.gtid_seq_no=9*//*!*/; +BEGIN +/*!*/; +# at # +# at # +#010909 4:46:40 server id # end_log_pos # Annotate_rows: +#Q> INSERT INTO test3.t3 VALUES (1), (2), (3) +#010909 4:46:40 server id # end_log_pos # Table_map: `test3`.`t3` mapped to number # +# at # +#010909 4:46:40 server id # end_log_pos # Write_rows: table id # flags: STMT_END_F +### INSERT INTO `test3`.`t3` +### SET +### @1=1 /* INT meta=0 nullable=1 is_null=0 */ +### INSERT INTO `test3`.`t3` +### SET +### @1=2 /* INT meta=0 nullable=1 is_null=0 */ +### INSERT INTO `test3`.`t3` +### SET +### @1=3 /* INT meta=0 nullable=1 is_null=0 */ +# at # +#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0 +SET TIMESTAMP=1000000000/*!*/; +COMMIT +/*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # GTID 0-1-10 +/*!100001 SET @@session.gtid_seq_no=10*//*!*/; +BEGIN +/*!*/; +# at # +# at # +#010909 4:46:40 server id # end_log_pos # Annotate_rows: +#Q> DELETE test1.t1, test2.t2 +#Q> FROM test1.t1 INNER JOIN test2.t2 INNER JOIN test3.t3 +#Q> WHERE test1.t1.a=test2.t2.a AND test2.t2.a=test3.t3 +#010909 4:46:40 server id # end_log_pos # Table_map: `test1`.`t1` mapped to number # +# at # +#010909 4:46:40 server id # end_log_pos # Table_map: `test2`.`t2` mapped to number # +# at # +# at # +#010909 4:46:40 server id # end_log_pos # Delete_rows: table id # +#010909 4:46:40 server id # end_log_pos # Delete_rows: table id # flags: STMT_END_F +### DELETE FROM `test1`.`t1` +### WHERE +### @1=1 /* INT meta=0 nullable=1 is_null=0 */ +### DELETE FROM `test1`.`t1` +### WHERE +### @1=2 /* INT meta=0 nullable=1 is_null=0 */ +### DELETE FROM `test1`.`t1` +### WHERE +### @1=3 /* INT meta=0 nullable=1 is_null=0 */ +### DELETE FROM `test2`.`t2` +### WHERE +### @1=1 /* INT meta=0 nullable=1 is_null=0 */ +### DELETE FROM `test2`.`t2` +### WHERE +### @1=2 /* INT meta=0 nullable=1 is_null=0 */ +### DELETE FROM `test2`.`t2` +### WHERE +### @1=3 /* INT meta=0 nullable=1 is_null=0 */ +# at # +#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0 +SET TIMESTAMP=1000000000/*!*/; +COMMIT +/*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # GTID 0-1-11 +/*!100001 SET @@session.gtid_seq_no=11*//*!*/; +BEGIN +/*!*/; +# at # +# at # +#010909 4:46:40 server id # end_log_pos # Annotate_rows: +#Q> INSERT INTO test2.v2 VALUES (1), (2), (3) +#010909 4:46:40 server id # end_log_pos # Table_map: `test2`.`t2` mapped to number # +# at # +#010909 4:46:40 server id # end_log_pos # Write_rows: table id # flags: STMT_END_F +### INSERT INTO `test2`.`t2` +### SET +### @1=1 /* INT meta=0 nullable=1 is_null=0 */ +### INSERT INTO `test2`.`t2` +### SET +### @1=2 /* INT meta=0 nullable=1 is_null=0 */ +### INSERT INTO `test2`.`t2` +### SET +### @1=3 /* INT meta=0 nullable=1 is_null=0 */ +# at # +#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0 +SET TIMESTAMP=1000000000/*!*/; +COMMIT +/*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # GTID 0-1-12 +/*!100001 SET @@session.gtid_seq_no=12*//*!*/; +BEGIN +/*!*/; +# at # +# at # +#010909 4:46:40 server id # end_log_pos # Annotate_rows: +#Q> DELETE xtest1.xt1, test2.t2 +#Q> FROM xtest1.xt1 INNER JOIN test2.t2 INNER JOIN test3.t3 +#Q> WHERE xtest1.xt1.a=test2.t2.a AND test2.t2.a=test3.t3 +#010909 4:46:40 server id # end_log_pos # Table_map: `test2`.`t2` mapped to number # +# at # +#010909 4:46:40 server id # end_log_pos # Delete_rows: table id # flags: STMT_END_F +### DELETE FROM `test2`.`t2` +### WHERE +### @1=3 /* INT meta=0 nullable=1 is_null=0 */ +### DELETE FROM `test2`.`t2` +### WHERE +### @1=2 /* INT meta=0 nullable=1 is_null=0 */ +### DELETE FROM `test2`.`t2` +### WHERE +### @1=1 /* INT meta=0 nullable=1 is_null=0 */ +# at # +#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0 +SET TIMESTAMP=1000000000/*!*/; +COMMIT +/*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # Rotate to master-bin.000002 pos: 4 +DELIMITER ; +# End of log file +ROLLBACK /* added by mysqlbinlog */; +/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/; +# +##################################################################################### +# mysqlbinlog --read-from-remote-server --database=test1 +# The following Annotate should appear in this output: +# - DELETE test1.t1, test2.t2 FROM <...> +##################################################################################### +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/; +/*!40019 SET @@session.max_insert_delayed_threads=0*/; +/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; +DELIMITER /*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # Start: binlog v 4, server v #.##.## created 010909 4:46:40 at startup +ROLLBACK/*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # Gtid list [] +# at # +#010909 4:46:40 server id # end_log_pos # Binlog checkpoint master-bin.000001 +# at # +#010909 4:46:40 server id # end_log_pos # GTID 0-1-1 ddl +/*!100101 SET @@session.skip_parallel_replication=0*//*!*/; +/*!100001 SET @@session.gtid_domain_id=0*//*!*/; +/*!100001 SET @@session.server_id=1*//*!*/; +/*!100001 SET @@session.gtid_seq_no=1*//*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0 +SET TIMESTAMP=1000000000/*!*/; +SET @@session.pseudo_thread_id=#/*!*/; +SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/; +SET @@session.sql_mode=0/*!*/; +SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/; +/*!\C latin1 *//*!*/; +SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/; +SET @@session.lc_time_names=0/*!*/; +SET @@session.collation_database=DEFAULT/*!*/; +DROP DATABASE IF EXISTS test1 +/*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # GTID 0-1-2 ddl +/*!100001 SET @@session.gtid_seq_no=2*//*!*/; +# at # +# at # +#010909 4:46:40 server id # end_log_pos # GTID 0-1-3 ddl +/*!100001 SET @@session.gtid_seq_no=3*//*!*/; +# at # +# at # +#010909 4:46:40 server id # end_log_pos # GTID 0-1-4 ddl +/*!100001 SET @@session.gtid_seq_no=4*//*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0 +SET TIMESTAMP=1000000000/*!*/; +CREATE DATABASE test1 +/*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # GTID 0-1-5 ddl +/*!100001 SET @@session.gtid_seq_no=5*//*!*/; +# at # +# at # +#010909 4:46:40 server id # end_log_pos # GTID 0-1-6 ddl +/*!100001 SET @@session.gtid_seq_no=6*//*!*/; +# at # +# at # +#010909 4:46:40 server id # end_log_pos # GTID 0-1-7 +/*!100001 SET @@session.gtid_seq_no=7*//*!*/; +BEGIN +/*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # Table_map: `test1`.`t1` mapped to number # +# at # +#010909 4:46:40 server id # end_log_pos # Write_rows: table id # flags: STMT_END_F +### INSERT INTO `test1`.`t1` +### SET +### @1=1 /* INT meta=0 nullable=1 is_null=0 */ +### INSERT INTO `test1`.`t1` +### SET +### @1=2 /* INT meta=0 nullable=1 is_null=0 */ +### INSERT INTO `test1`.`t1` +### SET +### @1=3 /* INT meta=0 nullable=1 is_null=0 */ +# at # +#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0 +SET TIMESTAMP=1000000000/*!*/; +COMMIT +/*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # GTID 0-1-8 +/*!100001 SET @@session.gtid_seq_no=8*//*!*/; +BEGIN +/*!*/; +# at # +# at # +# at # +# at # +#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0 +SET TIMESTAMP=1000000000/*!*/; +COMMIT +/*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # GTID 0-1-9 +/*!100001 SET @@session.gtid_seq_no=9*//*!*/; +BEGIN +/*!*/; +# at # +# at # +# at # +# at # +#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0 +SET TIMESTAMP=1000000000/*!*/; +COMMIT +/*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # GTID 0-1-10 +/*!100001 SET @@session.gtid_seq_no=10*//*!*/; +BEGIN +/*!*/; +# at # +# at # +#010909 4:46:40 server id # end_log_pos # Annotate_rows: +#Q> DELETE test1.t1, test2.t2 +#Q> FROM test1.t1 INNER JOIN test2.t2 INNER JOIN test3.t3 +#Q> WHERE test1.t1.a=test2.t2.a AND test2.t2.a=test3.t3 +#010909 4:46:40 server id # end_log_pos # Table_map: `test1`.`t1` mapped to number # +# at # +# at # +# at # +#010909 4:46:40 server id # end_log_pos # Delete_rows: table id # +### DELETE FROM `test1`.`t1` +### WHERE +### @1=1 /* INT meta=0 nullable=1 is_null=0 */ +### DELETE FROM `test1`.`t1` +### WHERE +### @1=2 /* INT meta=0 nullable=1 is_null=0 */ +### DELETE FROM `test1`.`t1` +### WHERE +### @1=3 /* INT meta=0 nullable=1 is_null=0 */ +'/*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0 +SET TIMESTAMP=1000000000/*!*/; +COMMIT +/*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # GTID 0-1-11 +/*!100001 SET @@session.gtid_seq_no=11*//*!*/; +BEGIN +/*!*/; +# at # +# at # +# at # +# at # +#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0 +SET TIMESTAMP=1000000000/*!*/; +COMMIT +/*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # GTID 0-1-12 +/*!100001 SET @@session.gtid_seq_no=12*//*!*/; +BEGIN +/*!*/; +# at # +# at # +# at # +# at # +#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0 +SET TIMESTAMP=1000000000/*!*/; +COMMIT +/*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # Rotate to master-bin.000002 pos: 4 +DELIMITER ; +# End of log file +ROLLBACK /* added by mysqlbinlog */; +/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/; +# +##################################################################################### +# mysqlbinlog --read-from-remote-server --skip-annotate-row-events +# No Annotates should appear in this output +##################################################################################### +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/; +/*!40019 SET @@session.max_insert_delayed_threads=0*/; +/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; +DELIMITER /*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # Start: binlog v 4, server v #.##.## created 010909 4:46:40 at startup +ROLLBACK/*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # Gtid list [] +# at # +#010909 4:46:40 server id # end_log_pos # Binlog checkpoint master-bin.000001 +# at # +#010909 4:46:40 server id # end_log_pos # GTID 0-1-1 ddl +/*!100101 SET @@session.skip_parallel_replication=0*//*!*/; +/*!100001 SET @@session.gtid_domain_id=0*//*!*/; +/*!100001 SET @@session.server_id=1*//*!*/; +/*!100001 SET @@session.gtid_seq_no=1*//*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0 +SET TIMESTAMP=1000000000/*!*/; +SET @@session.pseudo_thread_id=#/*!*/; +SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/; +SET @@session.sql_mode=0/*!*/; +SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/; +/*!\C latin1 *//*!*/; +SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/; +SET @@session.lc_time_names=0/*!*/; +SET @@session.collation_database=DEFAULT/*!*/; +DROP DATABASE IF EXISTS test1 +/*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # GTID 0-1-2 ddl +/*!100001 SET @@session.gtid_seq_no=2*//*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0 +SET TIMESTAMP=1000000000/*!*/; +DROP DATABASE IF EXISTS test2 +/*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # GTID 0-1-3 ddl +/*!100001 SET @@session.gtid_seq_no=3*//*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0 +SET TIMESTAMP=1000000000/*!*/; +DROP DATABASE IF EXISTS test3 +/*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # GTID 0-1-4 ddl +/*!100001 SET @@session.gtid_seq_no=4*//*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0 +SET TIMESTAMP=1000000000/*!*/; +CREATE DATABASE test1 +/*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # GTID 0-1-5 ddl +/*!100001 SET @@session.gtid_seq_no=5*//*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0 +SET TIMESTAMP=1000000000/*!*/; +CREATE DATABASE test2 +/*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # GTID 0-1-6 ddl +/*!100001 SET @@session.gtid_seq_no=6*//*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0 +SET TIMESTAMP=1000000000/*!*/; +CREATE DATABASE test3 +/*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # GTID 0-1-7 +/*!100001 SET @@session.gtid_seq_no=7*//*!*/; +BEGIN +/*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # Table_map: `test1`.`t1` mapped to number # +# at # +#010909 4:46:40 server id # end_log_pos # Write_rows: table id # flags: STMT_END_F +### INSERT INTO `test1`.`t1` +### SET +### @1=1 /* INT meta=0 nullable=1 is_null=0 */ +### INSERT INTO `test1`.`t1` +### SET +### @1=2 /* INT meta=0 nullable=1 is_null=0 */ +### INSERT INTO `test1`.`t1` +### SET +### @1=3 /* INT meta=0 nullable=1 is_null=0 */ +# at # +#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0 +SET TIMESTAMP=1000000000/*!*/; +COMMIT +/*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # GTID 0-1-8 +/*!100001 SET @@session.gtid_seq_no=8*//*!*/; +BEGIN +/*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # Table_map: `test2`.`t2` mapped to number # +# at # +#010909 4:46:40 server id # end_log_pos # Write_rows: table id # flags: STMT_END_F +### INSERT INTO `test2`.`t2` +### SET +### @1=1 /* INT meta=0 nullable=1 is_null=0 */ +### INSERT INTO `test2`.`t2` +### SET +### @1=2 /* INT meta=0 nullable=1 is_null=0 */ +### INSERT INTO `test2`.`t2` +### SET +### @1=3 /* INT meta=0 nullable=1 is_null=0 */ +# at # +#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0 +SET TIMESTAMP=1000000000/*!*/; +COMMIT +/*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # GTID 0-1-9 +/*!100001 SET @@session.gtid_seq_no=9*//*!*/; +BEGIN +/*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # Table_map: `test3`.`t3` mapped to number # +# at # +#010909 4:46:40 server id # end_log_pos # Write_rows: table id # flags: STMT_END_F +### INSERT INTO `test3`.`t3` +### SET +### @1=1 /* INT meta=0 nullable=1 is_null=0 */ +### INSERT INTO `test3`.`t3` +### SET +### @1=2 /* INT meta=0 nullable=1 is_null=0 */ +### INSERT INTO `test3`.`t3` +### SET +### @1=3 /* INT meta=0 nullable=1 is_null=0 */ +# at # +#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0 +SET TIMESTAMP=1000000000/*!*/; +COMMIT +/*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # GTID 0-1-10 +/*!100001 SET @@session.gtid_seq_no=10*//*!*/; +BEGIN +/*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # Table_map: `test1`.`t1` mapped to number # +# at # +#010909 4:46:40 server id # end_log_pos # Table_map: `test2`.`t2` mapped to number # +# at # +# at # +#010909 4:46:40 server id # end_log_pos # Delete_rows: table id # +#010909 4:46:40 server id # end_log_pos # Delete_rows: table id # flags: STMT_END_F +### DELETE FROM `test1`.`t1` +### WHERE +### @1=1 /* INT meta=0 nullable=1 is_null=0 */ +### DELETE FROM `test1`.`t1` +### WHERE +### @1=2 /* INT meta=0 nullable=1 is_null=0 */ +### DELETE FROM `test1`.`t1` +### WHERE +### @1=3 /* INT meta=0 nullable=1 is_null=0 */ +### DELETE FROM `test2`.`t2` +### WHERE +### @1=1 /* INT meta=0 nullable=1 is_null=0 */ +### DELETE FROM `test2`.`t2` +### WHERE +### @1=2 /* INT meta=0 nullable=1 is_null=0 */ +### DELETE FROM `test2`.`t2` +### WHERE +### @1=3 /* INT meta=0 nullable=1 is_null=0 */ +# at # +#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0 +SET TIMESTAMP=1000000000/*!*/; +COMMIT +/*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # GTID 0-1-11 +/*!100001 SET @@session.gtid_seq_no=11*//*!*/; +BEGIN +/*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # Table_map: `test2`.`t2` mapped to number # +# at # +#010909 4:46:40 server id # end_log_pos # Write_rows: table id # flags: STMT_END_F +### INSERT INTO `test2`.`t2` +### SET +### @1=1 /* INT meta=0 nullable=1 is_null=0 */ +### INSERT INTO `test2`.`t2` +### SET +### @1=2 /* INT meta=0 nullable=1 is_null=0 */ +### INSERT INTO `test2`.`t2` +### SET +### @1=3 /* INT meta=0 nullable=1 is_null=0 */ +# at # +#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0 +SET TIMESTAMP=1000000000/*!*/; +COMMIT +/*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # GTID 0-1-12 +/*!100001 SET @@session.gtid_seq_no=12*//*!*/; +BEGIN +/*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # Table_map: `test2`.`t2` mapped to number # +# at # +#010909 4:46:40 server id # end_log_pos # Delete_rows: table id # flags: STMT_END_F +### DELETE FROM `test2`.`t2` +### WHERE +### @1=3 /* INT meta=0 nullable=1 is_null=0 */ +### DELETE FROM `test2`.`t2` +### WHERE +### @1=2 /* INT meta=0 nullable=1 is_null=0 */ +### DELETE FROM `test2`.`t2` +### WHERE +### @1=1 /* INT meta=0 nullable=1 is_null=0 */ +# at # +#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0 +SET TIMESTAMP=1000000000/*!*/; +COMMIT +/*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # Rotate to master-bin.000002 pos: 4 +DELIMITER ; +# End of log file +ROLLBACK /* added by mysqlbinlog */; +/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/; diff --git a/mysql-test/suite/binlog_encryption/binlog_row_annotate.test b/mysql-test/suite/binlog_encryption/binlog_row_annotate.test new file mode 100644 index 0000000..2e6790f --- /dev/null +++ b/mysql-test/suite/binlog_encryption/binlog_row_annotate.test @@ -0,0 +1,160 @@ +# +# The test was taken from the binlog suite, a part of it was removed +# because mysqlbinlog is not able to read encrypted logs directly +# + +############################################################################### +# 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. +############################################################################### + +--source include/have_log_bin.inc +--source include/have_binlog_format_row.inc +--source include/binlog_start_pos.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; + +let $MYSQLD_DATADIR= `select @@datadir`; + +--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 + +--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 ##################################################################################### + +--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 ##################################################################################### + +--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 ##################################################################################### + +--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 +DROP DATABASE test1; +DROP DATABASE test2; +DROP DATABASE test3; +DROP DATABASE xtest1; +DROP DATABASE xtest2; +--enable_query_log + diff --git a/mysql-test/suite/binlog_encryption/binlog_write_error.result b/mysql-test/suite/binlog_encryption/binlog_write_error.result new file mode 100644 index 0000000..28cffb3 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/binlog_write_error.result @@ -0,0 +1,108 @@ +# +# Initialization +# +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; +# +# Test injecting binlog write error when executing queries +# +SET GLOBAL debug_dbug='d,injecting_fault_writing'; +CREATE TABLE t1 (a INT); +CREATE TABLE t1 (a INT); +ERROR HY000: Error writing file 'master-bin' ((errno: #) +SET GLOBAL debug_dbug=''; +INSERT INTO t1 VALUES (1),(2),(3); +SET GLOBAL debug_dbug='d,injecting_fault_writing'; +INSERT INTO t1 VALUES (4),(5),(6); +INSERT INTO t1 VALUES (4),(5),(6); +ERROR HY000: Error writing file 'master-bin' ((errno: #) +SET GLOBAL debug_dbug=''; +SET GLOBAL debug_dbug='d,injecting_fault_writing'; +UPDATE t1 set a=a+1; +UPDATE t1 set a=a+1; +ERROR HY000: Error writing file 'master-bin' ((errno: #) +SET GLOBAL debug_dbug=''; +SET GLOBAL debug_dbug='d,injecting_fault_writing'; +DELETE FROM t1; +DELETE FROM t1; +ERROR HY000: Error writing file 'master-bin' ((errno: #) +SET GLOBAL debug_dbug=''; +SET GLOBAL debug_dbug='d,injecting_fault_writing'; +CREATE TRIGGER tr1 AFTER INSERT ON t1 FOR EACH ROW INSERT INTO t1 VALUES (new.a + 100); +CREATE TRIGGER tr1 AFTER INSERT ON t1 FOR EACH ROW INSERT INTO t1 VALUES (new.a + 100); +ERROR HY000: Error writing file 'master-bin' ((errno: #) +SET GLOBAL debug_dbug=''; +SET GLOBAL debug_dbug='d,injecting_fault_writing'; +DROP TRIGGER tr1; +DROP TRIGGER tr1; +ERROR HY000: Error writing file 'master-bin' ((errno: #) +SET GLOBAL debug_dbug=''; +SET GLOBAL debug_dbug='d,injecting_fault_writing'; +ALTER TABLE t1 ADD (b INT); +ALTER TABLE t1 ADD (b INT); +ERROR HY000: Error writing file 'master-bin' ((errno: #) +SET GLOBAL debug_dbug=''; +SET GLOBAL debug_dbug='d,injecting_fault_writing'; +CREATE VIEW v1 AS SELECT a FROM t1; +CREATE VIEW v1 AS SELECT a FROM t1; +ERROR HY000: Error writing file 'master-bin' ((errno: #) +SET GLOBAL debug_dbug=''; +SET GLOBAL debug_dbug='d,injecting_fault_writing'; +DROP VIEW v1; +DROP VIEW v1; +ERROR HY000: Error writing file 'master-bin' ((errno: #) +SET GLOBAL debug_dbug=''; +SET GLOBAL debug_dbug='d,injecting_fault_writing'; +CREATE PROCEDURE p1(OUT rows INT) SELECT count(*) INTO rows FROM t1; +CREATE PROCEDURE p1(OUT rows INT) SELECT count(*) INTO rows FROM t1; +ERROR HY000: Error writing file 'master-bin' ((errno: #) +SET GLOBAL debug_dbug=''; +SET GLOBAL debug_dbug='d,injecting_fault_writing'; +DROP PROCEDURE p1; +DROP PROCEDURE p1; +ERROR HY000: Error writing file 'master-bin' ((errno: #) +SET GLOBAL debug_dbug=''; +SET GLOBAL debug_dbug='d,injecting_fault_writing'; +DROP TABLE t1; +DROP TABLE t1; +ERROR HY000: Error writing file 'master-bin' ((errno: #) +SET GLOBAL debug_dbug=''; +SET GLOBAL debug_dbug='d,injecting_fault_writing'; +CREATE FUNCTION f1() RETURNS INT return 1; +CREATE FUNCTION f1() RETURNS INT return 1; +ERROR HY000: Error writing file 'master-bin' ((errno: #) +SET GLOBAL debug_dbug=''; +SET GLOBAL debug_dbug='d,injecting_fault_writing'; +DROP FUNCTION f1; +DROP FUNCTION f1; +ERROR HY000: Error writing file 'master-bin' ((errno: #) +SET GLOBAL debug_dbug=''; +SET GLOBAL debug_dbug='d,injecting_fault_writing'; +CREATE USER user1; +CREATE USER user1; +ERROR HY000: Error writing file 'master-bin' ((errno: #) +SET GLOBAL debug_dbug=''; +SET GLOBAL debug_dbug='d,injecting_fault_writing'; +REVOKE ALL PRIVILEGES, GRANT OPTION FROM user1; +REVOKE ALL PRIVILEGES, GRANT OPTION FROM user1; +ERROR HY000: Error writing file 'master-bin' ((errno: #) +SET GLOBAL debug_dbug=''; +SET GLOBAL debug_dbug='d,injecting_fault_writing'; +DROP USER user1; +DROP USER user1; +ERROR HY000: Error writing file 'master-bin' ((errno: #) +SET GLOBAL debug_dbug=''; +# +# Cleanup +# +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; diff --git a/mysql-test/suite/binlog_encryption/binlog_write_error.test b/mysql-test/suite/binlog_encryption/binlog_write_error.test new file mode 100644 index 0000000..aa0e705 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/binlog_write_error.test @@ -0,0 +1,106 @@ +# +# The test was taken from the binlog suite as is +# + +# +# === 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/suite/binlog_encryption/binlog_xa_recover-master.opt b/mysql-test/suite/binlog_encryption/binlog_xa_recover-master.opt new file mode 100644 index 0000000..3c44f9f --- /dev/null +++ b/mysql-test/suite/binlog_encryption/binlog_xa_recover-master.opt @@ -0,0 +1 @@ +--skip-stack-trace --skip-core-file --loose-debug-dbug=+d,xa_recover_expect_master_bin_000004 diff --git a/mysql-test/suite/binlog_encryption/binlog_xa_recover.result b/mysql-test/suite/binlog_encryption/binlog_xa_recover.result new file mode 100644 index 0000000..6719d89 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/binlog_xa_recover.result @@ -0,0 +1,240 @@ +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 INTO t1 VALUES (100, REPEAT("x", 4100)); +INSERT INTO t1 VALUES (101, REPEAT("x", 4100)); +INSERT INTO t1 VALUES (102, REPEAT("x", 4100)); +connect con1,localhost,root,,; +SET DEBUG_SYNC= "ha_commit_trans_before_log_and_order SIGNAL con1_wait WAIT_FOR con1_cont"; +SET DEBUG_SYNC= "commit_after_group_release_commit_ordered SIGNAL con1_ready WAIT_FOR _ever"; +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"; +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"; +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"; +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"; +show binary logs; +Log_name File_size +master-bin.000001 # +master-bin.000002 # +master-bin.000003 # +master-bin.000004 # +master-bin.000005 # +master-bin.000006 # +include/show_binlog_events.inc +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000003 # Format_desc # # SERVER_VERSION, BINLOG_VERSION +master-bin.000003 # Start_encryption # # +master-bin.000003 # Gtid_list # # [#-#-#] +master-bin.000003 # Binlog_checkpoint # # master-bin.000002 +master-bin.000003 # Binlog_checkpoint # # master-bin.000003 +master-bin.000003 # Gtid # # BEGIN GTID #-#-# +master-bin.000003 # Table_map # # table_id: # (test.t1) +master-bin.000003 # Write_rows_v1 # # table_id: # flags: STMT_END_F +master-bin.000003 # Xid # # COMMIT /* XID */ +master-bin.000003 # Rotate # # master-bin.000004;pos=POS +include/show_binlog_events.inc +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000004 # Format_desc # # SERVER_VERSION, BINLOG_VERSION +master-bin.000004 # Start_encryption # # +master-bin.000004 # Gtid_list # # [#-#-#] +master-bin.000004 # Binlog_checkpoint # # master-bin.000003 +master-bin.000004 # Binlog_checkpoint # # master-bin.000004 +master-bin.000004 # Gtid # # BEGIN GTID #-#-# +master-bin.000004 # Table_map # # table_id: # (test.t1) +master-bin.000004 # Write_rows_v1 # # table_id: # flags: STMT_END_F +master-bin.000004 # Xid # # COMMIT /* XID */ +master-bin.000004 # Rotate # # master-bin.000005;pos=POS +include/show_binlog_events.inc +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000005 # Format_desc # # SERVER_VERSION, BINLOG_VERSION +master-bin.000005 # Start_encryption # # +master-bin.000005 # Gtid_list # # [#-#-#] +master-bin.000005 # Binlog_checkpoint # # master-bin.000004 +master-bin.000005 # Gtid # # BEGIN GTID #-#-# +master-bin.000005 # Table_map # # table_id: # (test.t1) +master-bin.000005 # Write_rows_v1 # # table_id: # flags: STMT_END_F +master-bin.000005 # Xid # # COMMIT /* XID */ +master-bin.000005 # Gtid # # BEGIN GTID #-#-# +master-bin.000005 # Table_map # # table_id: # (test.t1) +master-bin.000005 # Write_rows_v1 # # table_id: # flags: STMT_END_F +master-bin.000005 # Xid # # COMMIT /* XID */ +master-bin.000005 # Rotate # # master-bin.000006;pos=POS +include/show_binlog_events.inc +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000006 # Format_desc # # SERVER_VERSION, BINLOG_VERSION +master-bin.000006 # Start_encryption # # +master-bin.000006 # Gtid_list # # [#-#-#] +master-bin.000006 # Binlog_checkpoint # # master-bin.000004 +PURGE BINARY LOGS TO "master-bin.000006"; +show binary logs; +Log_name File_size +master-bin.000004 # +master-bin.000005 # +master-bin.000006 # +SET DEBUG_SYNC= "now SIGNAL con4_cont"; +connection con4; +Got one of the listed errors +connection default; +SELECT a FROM t1 ORDER BY a; +a +1 +2 +3 +4 +100 +101 +102 +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; +connect con10,localhost,root,,; +SET DEBUG_SYNC= "commit_after_group_release_commit_ordered SIGNAL con10_ready WAIT_FOR con10_cont"; +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"; +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"; +INSERT INTO t1 VALUES (12, REPEAT("x", 4100)); +connection default; +SET DEBUG_SYNC= "now WAIT_FOR con12_ready"; +INSERT INTO t1 VALUES (13, NULL); +show binary logs; +Log_name File_size +master-bin.000001 # +master-bin.000002 # +master-bin.000003 # +master-bin.000004 # +include/show_binlog_events.inc +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000004 # Format_desc # # SERVER_VERSION, BINLOG_VERSION +master-bin.000004 # Start_encryption # # +master-bin.000004 # Gtid_list # # [#-#-#] +master-bin.000004 # Binlog_checkpoint # # master-bin.000001 +master-bin.000004 # Gtid # # BEGIN GTID #-#-# +master-bin.000004 # Table_map # # table_id: # (test.t1) +master-bin.000004 # Write_rows_v1 # # table_id: # flags: STMT_END_F +master-bin.000004 # Xid # # COMMIT /* XID */ +SET DEBUG_SYNC= "now SIGNAL con10_cont"; +connection con10; +connection default; +SET @old_dbug= @@global.DEBUG_DBUG; +SET GLOBAL debug_dbug="+d,binlog_background_checkpoint_processed"; +SET DEBUG_SYNC= "now SIGNAL con12_cont"; +connection con12; +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; +connection default; +Checking that master-bin.000004 is the last binlog checkpoint +include/show_binlog_events.inc +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000004 # Format_desc # # SERVER_VERSION, BINLOG_VERSION +master-bin.000004 # Start_encryption # # +master-bin.000004 # Gtid_list # # [#-#-#] +master-bin.000004 # Binlog_checkpoint # # master-bin.000001 +master-bin.000004 # Gtid # # BEGIN GTID #-#-# +master-bin.000004 # Table_map # # table_id: # (test.t1) +master-bin.000004 # Write_rows_v1 # # table_id: # flags: STMT_END_F +master-bin.000004 # Xid # # COMMIT /* XID */ +master-bin.000004 # Binlog_checkpoint # # master-bin.000002 +master-bin.000004 # Binlog_checkpoint # # master-bin.000004 +Now crash the server +SET SESSION debug_dbug="+d,crash_commit_after_log"; +INSERT INTO t1 VALUES (14, NULL); +Got one of the listed errors +connection default; +SELECT a FROM t1 ORDER BY a; +a +1 +2 +3 +4 +10 +11 +12 +13 +14 +100 +101 +102 +*** Check that recovery works if we crashed early during rotate, before +*** binlog checkpoint event could be written. +SET GLOBAL max_binlog_size= 4096; +SET GLOBAL innodb_flush_log_at_trx_commit= 1; +RESET MASTER; +INSERT INTO t1 VALUES (21, REPEAT("x", 4100)); +INSERT INTO t1 VALUES (22, REPEAT("x", 4100)); +INSERT INTO t1 VALUES (23, REPEAT("x", 4100)); +SET SESSION debug_dbug="+d,crash_before_write_checkpoint_event"; +INSERT INTO t1 VALUES (24, REPEAT("x", 4100)); +Got one of the listed errors +SELECT a FROM t1 ORDER BY a; +a +1 +2 +3 +4 +10 +11 +12 +13 +14 +21 +22 +23 +24 +100 +101 +102 +show binary logs; +Log_name File_size +master-bin.000001 # +master-bin.000002 # +master-bin.000003 # +master-bin.000004 # +master-bin.000005 # +include/show_binlog_events.inc +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000004 # Format_desc # # SERVER_VERSION, BINLOG_VERSION +master-bin.000004 # Start_encryption # # +master-bin.000004 # Gtid_list # # [#-#-#] +master-bin.000004 # Binlog_checkpoint # # master-bin.000003 +master-bin.000004 # Binlog_checkpoint # # master-bin.000004 +master-bin.000004 # Gtid # # BEGIN GTID #-#-# +master-bin.000004 # Table_map # # table_id: # (test.t1) +master-bin.000004 # Write_rows_v1 # # table_id: # flags: STMT_END_F +master-bin.000004 # Xid # # COMMIT /* XID */ +master-bin.000004 # Rotate # # master-bin.000005;pos=POS +connection default; +DROP TABLE t1; diff --git a/mysql-test/suite/binlog_encryption/binlog_xa_recover.test b/mysql-test/suite/binlog_encryption/binlog_xa_recover.test new file mode 100644 index 0000000..6aa90ae --- /dev/null +++ b/mysql-test/suite/binlog_encryption/binlog_xa_recover.test @@ -0,0 +1,304 @@ +# +# The test was taken from the binlog suite as is, only result file was modified +# + +--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 + +--enable_connect_log + +# (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" +--disable_connect_log +--source include/wait_show_condition.inc +--enable_connect_log +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" +--disable_connect_log +--source include/wait_show_condition.inc +--enable_connect_log +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" +--disable_connect_log +--source include/wait_show_condition.inc +--enable_connect_log + +# 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. +--disable_connect_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 +--enable_connect_log + + +# Check that server will not purge too much. +PURGE BINARY LOGS TO "master-bin.000006"; +--disable_connect_log +--source include/show_binary_logs.inc +--enable_connect_log + +# 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 +--disable_connect_log +--source include/wait_until_connected_again.inc +--enable_connect_log + +# 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); + +--disable_connect_log +--source include/show_binary_logs.inc +--let $binlog_file= master-bin.000004 +--let $binlog_start= 4 +--source include/show_binlog_events.inc +--enable_connect_log + +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" +--disable_connect_log +--source include/wait_show_condition.inc + +--echo Checking that master-bin.000004 is the last binlog checkpoint +--source include/show_binlog_events.inc +--enable_connect_log + +--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 +--disable_connect_log +--source include/wait_until_connected_again.inc +--enable_connect_log + +# 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" +--disable_connect_log +--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 +--enable_connect_log + +--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 +--disable_connect_log +--source include/wait_until_connected_again.inc +--enable_connect_log + +# Check that all transactions are recovered. +SELECT a FROM t1 ORDER BY a; + +--disable_connect_log +--source include/show_binary_logs.inc +--let $binlog_file= master-bin.000004 +--let $binlog_start= 4 +--source include/show_binlog_events.inc +--enable_connect_log + +# Cleanup +connection default; +DROP TABLE t1; diff --git a/mysql-test/suite/binlog_encryption/disabled.def b/mysql-test/suite/binlog_encryption/disabled.def new file mode 100644 index 0000000..cb780c4 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/disabled.def @@ -0,0 +1 @@ +encrypted_master_switch_to_unencrypted : MDEV-11288 (server crash) diff --git a/mysql-test/suite/binlog_encryption/encrypted_master.result b/mysql-test/suite/binlog_encryption/encrypted_master.result new file mode 100644 index 0000000..efa92e0 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/encrypted_master.result @@ -0,0 +1,694 @@ +################# +# Initialization +################# +include/rpl_init.inc [topology=1->2] +connection server_2; +include/stop_slave_sql.inc +connection server_1; +SET @binlog_annotate_row_events.save= @@global.binlog_annotate_row_events; +SET @binlog_checksum.save= @@global.binlog_checksum; +SET @master_verify_checksum.save= @@global.master_verify_checksum; +SET @binlog_row_image.save= @@global.binlog_row_image; +#################################################### +# Test 1: simple binlog, no checksum, no annotation +#################################################### +connection server_1; +SET binlog_annotate_row_events= 0; +SET GLOBAL binlog_annotate_row_events= 0; +SET GLOBAL binlog_checksum= NONE; +SET GLOBAL master_verify_checksum= 0; +call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT"); +CREATE DATABASE database_name_to_encrypt; +USE database_name_to_encrypt; +CREATE USER user_name_to_encrypt; +GRANT ALL ON database_name_to_encrypt.* TO user_name_to_encrypt; +SET PASSWORD FOR user_name_to_encrypt = PASSWORD('password_to_encrypt'); +CREATE TABLE innodb_table_name_to_encrypt ( +int_column_name_to_encrypt INT AUTO_INCREMENT PRIMARY KEY, +timestamp_column_name_to_encrypt TIMESTAMP(6) NULL, +blob_column_name_to_encrypt BLOB, +virt_column_name_to_encrypt INT AS (int_column_name_to_encrypt % 10) VIRTUAL, +pers_column_name_to_encrypt INT AS (int_column_name_to_encrypt) PERSISTENT, +INDEX `index_name_to_encrypt`(`timestamp_column_name_to_encrypt`) +) ENGINE=InnoDB +PARTITION BY RANGE (int_column_name_to_encrypt) +SUBPARTITION BY KEY (int_column_name_to_encrypt) +SUBPARTITIONS 2 ( +PARTITION partition0_name_to_encrypt VALUES LESS THAN (100), +PARTITION partition1_name_to_encrypt VALUES LESS THAN (MAXVALUE) +) +; +CREATE TABLE myisam_table_name_to_encrypt ( +int_column_name_to_encrypt INT AUTO_INCREMENT PRIMARY KEY, +char_column_name_to_encrypt VARCHAR(255), +datetime_column_name_to_encrypt DATETIME, +text_column_name_to_encrypt TEXT +) ENGINE=MyISAM; +CREATE TABLE aria_table_name_to_encrypt ( +int_column_name_to_encrypt INT AUTO_INCREMENT PRIMARY KEY, +varchar_column_name_to_encrypt VARCHAR(1024), +enum_column_name_to_encrypt ENUM( +'enum_value1_to_encrypt', +'enum_value2_to_encrypt' + ), +timestamp_column_name_to_encrypt TIMESTAMP(6) NULL, +blob_column_name_to_encrypt BLOB +) ENGINE=Aria; +CREATE TRIGGER trigger_name_to_encrypt +AFTER INSERT ON myisam_table_name_to_encrypt FOR EACH ROW +INSERT INTO aria_table_name_to_encrypt (varchar_column_name_to_encrypt) +VALUES (NEW.char_column_name_to_encrypt); +CREATE DEFINER=user_name_to_encrypt VIEW view_name_to_encrypt +AS SELECT * FROM innodb_table_name_to_encrypt; +CREATE FUNCTION func_name_to_encrypt (func_parameter_to_encrypt INT) +RETURNS VARCHAR(64) +RETURN 'func_result_to_encrypt'; +CREATE PROCEDURE proc_name_to_encrypt ( +IN proc_in_parameter_to_encrypt CHAR(32), +OUT proc_out_parameter_to_encrypt INT +) +BEGIN +DECLARE procvar_name_to_encrypt CHAR(64) DEFAULT 'procvar_val_to_encrypt'; +DECLARE cursor_name_to_encrypt CURSOR FOR +SELECT virt_column_name_to_encrypt FROM innodb_table_name_to_encrypt; +DECLARE EXIT HANDLER FOR NOT FOUND +BEGIN +SET @stmt_var_to_encrypt = CONCAT( +"SELECT + IF (RAND()>0.5,'enum_value2_to_encrypt','enum_value1_to_encrypt') + FROM innodb_table_name_to_encrypt + INTO OUTFILE '", proc_in_parameter_to_encrypt, "'"); +PREPARE stmt_to_encrypt FROM @stmt_var_to_encrypt; +EXECUTE stmt_to_encrypt; +DEALLOCATE PREPARE stmt_to_encrypt; +END; +OPEN cursor_name_to_encrypt; +proc_label_to_encrypt: LOOP +FETCH cursor_name_to_encrypt INTO procvar_name_to_encrypt; +END LOOP; +CLOSE cursor_name_to_encrypt; +END $$ +CREATE SERVER server_name_to_encrypt +FOREIGN DATA WRAPPER mysql +OPTIONS (HOST 'host_name_to_encrypt'); +connect con1,localhost,user_name_to_encrypt,password_to_encrypt,database_name_to_encrypt; +CREATE TEMPORARY TABLE tmp_table_name_to_encrypt ( +float_column_name_to_encrypt FLOAT, +binary_column_name_to_encrypt BINARY(64) +); +disconnect con1; +connection server_1; +CREATE INDEX index_name_to_encrypt +ON myisam_table_name_to_encrypt (datetime_column_name_to_encrypt); +ALTER DATABASE database_name_to_encrypt CHARACTER SET utf8; +ALTER TABLE innodb_table_name_to_encrypt +MODIFY timestamp_column_name_to_encrypt TIMESTAMP NOT NULL +DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP +; +ALTER ALGORITHM=MERGE VIEW view_name_to_encrypt +AS SELECT * FROM innodb_table_name_to_encrypt; +RENAME TABLE innodb_table_name_to_encrypt TO new_table_name_to_encrypt; +ALTER TABLE new_table_name_to_encrypt RENAME TO innodb_table_name_to_encrypt; +set @user_var1_to_encrypt= 'dyncol1_val_to_encrypt'; +set @user_var2_to_encrypt= 'dyncol2_name_to_encrypt'; +INSERT INTO view_name_to_encrypt VALUES +(1, NOW(6), COLUMN_CREATE('dyncol1_name_to_encrypt',@user_var1_to_encrypt), NULL, NULL), +(2, NOW(6), COLUMN_CREATE(@user_var2_to_encrypt,'dyncol2_val_to_encrypt'), NULL, NULL) +; +BEGIN NOT ATOMIC +DECLARE counter_name_to_encrypt INT DEFAULT 0; +START TRANSACTION; +WHILE counter_name_to_encrypt<12 DO +INSERT INTO innodb_table_name_to_encrypt +SELECT NULL, NOW(6), blob_column_name_to_encrypt, NULL, NULL +FROM innodb_table_name_to_encrypt +ORDER BY int_column_name_to_encrypt; +SET counter_name_to_encrypt = counter_name_to_encrypt+1; +END WHILE; +COMMIT; +END +$$ +INSERT INTO myisam_table_name_to_encrypt +SELECT NULL, 'char_literal_to_encrypt', NULL, 'text_to_encrypt'; +INSERT INTO myisam_table_name_to_encrypt (char_column_name_to_encrypt) +SELECT char_column_name_to_encrypt FROM myisam_table_name_to_encrypt; +INSERT INTO myisam_table_name_to_encrypt (char_column_name_to_encrypt) +SELECT char_column_name_to_encrypt FROM myisam_table_name_to_encrypt; +INSERT INTO myisam_table_name_to_encrypt (char_column_name_to_encrypt) +SELECT char_column_name_to_encrypt FROM myisam_table_name_to_encrypt; +CALL proc_name_to_encrypt('file_name_to_encrypt',@useless_var_to_encrypt); +TRUNCATE TABLE aria_table_name_to_encrypt; +LOAD DATA INFILE 'file_name_to_encrypt' INTO TABLE aria_table_name_to_encrypt +(enum_column_name_to_encrypt); +LOAD DATA LOCAL INFILE '<DATADIR>/database_name_to_encrypt/file_name_to_encrypt' +INTO TABLE aria_table_name_to_encrypt (enum_column_name_to_encrypt); +UPDATE view_name_to_encrypt SET blob_column_name_to_encrypt = +COLUMN_CREATE('dyncol1_name_to_encrypt',func_name_to_encrypt(0)) +; +DELETE FROM aria_table_name_to_encrypt ORDER BY int_column_name_to_encrypt LIMIT 10; +ANALYZE TABLE myisam_table_name_to_encrypt; +CHECK TABLE aria_table_name_to_encrypt; +CHECKSUM TABLE innodb_table_name_to_encrypt, myisam_table_name_to_encrypt; +RENAME USER user_name_to_encrypt to new_user_name_to_encrypt; +REVOKE ALL PRIVILEGES, GRANT OPTION FROM new_user_name_to_encrypt; +DROP DATABASE database_name_to_encrypt; +DROP USER new_user_name_to_encrypt; +DROP SERVER server_name_to_encrypt; +#################################################### +# Test 2: binlog with checksum, no annotated events +#################################################### +connection server_1; +SET binlog_annotate_row_events= 0; +SET GLOBAL binlog_annotate_row_events= 0; +SET GLOBAL binlog_checksum= CRC32; +SET GLOBAL master_verify_checksum= 1; +call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT"); +CREATE DATABASE database_name_to_encrypt; +USE database_name_to_encrypt; +CREATE USER user_name_to_encrypt; +GRANT ALL ON database_name_to_encrypt.* TO user_name_to_encrypt; +SET PASSWORD FOR user_name_to_encrypt = PASSWORD('password_to_encrypt'); +CREATE TABLE innodb_table_name_to_encrypt ( +int_column_name_to_encrypt INT AUTO_INCREMENT PRIMARY KEY, +timestamp_column_name_to_encrypt TIMESTAMP(6) NULL, +blob_column_name_to_encrypt BLOB, +virt_column_name_to_encrypt INT AS (int_column_name_to_encrypt % 10) VIRTUAL, +pers_column_name_to_encrypt INT AS (int_column_name_to_encrypt) PERSISTENT, +INDEX `index_name_to_encrypt`(`timestamp_column_name_to_encrypt`) +) ENGINE=InnoDB +PARTITION BY RANGE (int_column_name_to_encrypt) +SUBPARTITION BY KEY (int_column_name_to_encrypt) +SUBPARTITIONS 2 ( +PARTITION partition0_name_to_encrypt VALUES LESS THAN (100), +PARTITION partition1_name_to_encrypt VALUES LESS THAN (MAXVALUE) +) +; +CREATE TABLE myisam_table_name_to_encrypt ( +int_column_name_to_encrypt INT AUTO_INCREMENT PRIMARY KEY, +char_column_name_to_encrypt VARCHAR(255), +datetime_column_name_to_encrypt DATETIME, +text_column_name_to_encrypt TEXT +) ENGINE=MyISAM; +CREATE TABLE aria_table_name_to_encrypt ( +int_column_name_to_encrypt INT AUTO_INCREMENT PRIMARY KEY, +varchar_column_name_to_encrypt VARCHAR(1024), +enum_column_name_to_encrypt ENUM( +'enum_value1_to_encrypt', +'enum_value2_to_encrypt' + ), +timestamp_column_name_to_encrypt TIMESTAMP(6) NULL, +blob_column_name_to_encrypt BLOB +) ENGINE=Aria; +CREATE TRIGGER trigger_name_to_encrypt +AFTER INSERT ON myisam_table_name_to_encrypt FOR EACH ROW +INSERT INTO aria_table_name_to_encrypt (varchar_column_name_to_encrypt) +VALUES (NEW.char_column_name_to_encrypt); +CREATE DEFINER=user_name_to_encrypt VIEW view_name_to_encrypt +AS SELECT * FROM innodb_table_name_to_encrypt; +CREATE FUNCTION func_name_to_encrypt (func_parameter_to_encrypt INT) +RETURNS VARCHAR(64) +RETURN 'func_result_to_encrypt'; +CREATE PROCEDURE proc_name_to_encrypt ( +IN proc_in_parameter_to_encrypt CHAR(32), +OUT proc_out_parameter_to_encrypt INT +) +BEGIN +DECLARE procvar_name_to_encrypt CHAR(64) DEFAULT 'procvar_val_to_encrypt'; +DECLARE cursor_name_to_encrypt CURSOR FOR +SELECT virt_column_name_to_encrypt FROM innodb_table_name_to_encrypt; +DECLARE EXIT HANDLER FOR NOT FOUND +BEGIN +SET @stmt_var_to_encrypt = CONCAT( +"SELECT + IF (RAND()>0.5,'enum_value2_to_encrypt','enum_value1_to_encrypt') + FROM innodb_table_name_to_encrypt + INTO OUTFILE '", proc_in_parameter_to_encrypt, "'"); +PREPARE stmt_to_encrypt FROM @stmt_var_to_encrypt; +EXECUTE stmt_to_encrypt; +DEALLOCATE PREPARE stmt_to_encrypt; +END; +OPEN cursor_name_to_encrypt; +proc_label_to_encrypt: LOOP +FETCH cursor_name_to_encrypt INTO procvar_name_to_encrypt; +END LOOP; +CLOSE cursor_name_to_encrypt; +END $$ +CREATE SERVER server_name_to_encrypt +FOREIGN DATA WRAPPER mysql +OPTIONS (HOST 'host_name_to_encrypt'); +connect con1,localhost,user_name_to_encrypt,password_to_encrypt,database_name_to_encrypt; +CREATE TEMPORARY TABLE tmp_table_name_to_encrypt ( +float_column_name_to_encrypt FLOAT, +binary_column_name_to_encrypt BINARY(64) +); +disconnect con1; +connection server_1; +CREATE INDEX index_name_to_encrypt +ON myisam_table_name_to_encrypt (datetime_column_name_to_encrypt); +ALTER DATABASE database_name_to_encrypt CHARACTER SET utf8; +ALTER TABLE innodb_table_name_to_encrypt +MODIFY timestamp_column_name_to_encrypt TIMESTAMP NOT NULL +DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP +; +ALTER ALGORITHM=MERGE VIEW view_name_to_encrypt +AS SELECT * FROM innodb_table_name_to_encrypt; +RENAME TABLE innodb_table_name_to_encrypt TO new_table_name_to_encrypt; +ALTER TABLE new_table_name_to_encrypt RENAME TO innodb_table_name_to_encrypt; +set @user_var1_to_encrypt= 'dyncol1_val_to_encrypt'; +set @user_var2_to_encrypt= 'dyncol2_name_to_encrypt'; +INSERT INTO view_name_to_encrypt VALUES +(1, NOW(6), COLUMN_CREATE('dyncol1_name_to_encrypt',@user_var1_to_encrypt), NULL, NULL), +(2, NOW(6), COLUMN_CREATE(@user_var2_to_encrypt,'dyncol2_val_to_encrypt'), NULL, NULL) +; +BEGIN NOT ATOMIC +DECLARE counter_name_to_encrypt INT DEFAULT 0; +START TRANSACTION; +WHILE counter_name_to_encrypt<12 DO +INSERT INTO innodb_table_name_to_encrypt +SELECT NULL, NOW(6), blob_column_name_to_encrypt, NULL, NULL +FROM innodb_table_name_to_encrypt +ORDER BY int_column_name_to_encrypt; +SET counter_name_to_encrypt = counter_name_to_encrypt+1; +END WHILE; +COMMIT; +END +$$ +INSERT INTO myisam_table_name_to_encrypt +SELECT NULL, 'char_literal_to_encrypt', NULL, 'text_to_encrypt'; +INSERT INTO myisam_table_name_to_encrypt (char_column_name_to_encrypt) +SELECT char_column_name_to_encrypt FROM myisam_table_name_to_encrypt; +INSERT INTO myisam_table_name_to_encrypt (char_column_name_to_encrypt) +SELECT char_column_name_to_encrypt FROM myisam_table_name_to_encrypt; +INSERT INTO myisam_table_name_to_encrypt (char_column_name_to_encrypt) +SELECT char_column_name_to_encrypt FROM myisam_table_name_to_encrypt; +CALL proc_name_to_encrypt('file_name_to_encrypt',@useless_var_to_encrypt); +TRUNCATE TABLE aria_table_name_to_encrypt; +LOAD DATA INFILE 'file_name_to_encrypt' INTO TABLE aria_table_name_to_encrypt +(enum_column_name_to_encrypt); +LOAD DATA LOCAL INFILE '<DATADIR>/database_name_to_encrypt/file_name_to_encrypt' +INTO TABLE aria_table_name_to_encrypt (enum_column_name_to_encrypt); +UPDATE view_name_to_encrypt SET blob_column_name_to_encrypt = +COLUMN_CREATE('dyncol1_name_to_encrypt',func_name_to_encrypt(0)) +; +DELETE FROM aria_table_name_to_encrypt ORDER BY int_column_name_to_encrypt LIMIT 10; +ANALYZE TABLE myisam_table_name_to_encrypt; +CHECK TABLE aria_table_name_to_encrypt; +CHECKSUM TABLE innodb_table_name_to_encrypt, myisam_table_name_to_encrypt; +RENAME USER user_name_to_encrypt to new_user_name_to_encrypt; +REVOKE ALL PRIVILEGES, GRANT OPTION FROM new_user_name_to_encrypt; +DROP DATABASE database_name_to_encrypt; +DROP USER new_user_name_to_encrypt; +DROP SERVER server_name_to_encrypt; +#################################################### +# Test 3: binlog with checksum and annotated events +#################################################### +connection server_1; +SET binlog_annotate_row_events= 1; +SET GLOBAL binlog_annotate_row_events= 1; +SET GLOBAL binlog_checksum= CRC32; +SET GLOBAL master_verify_checksum= 1; +call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT"); +CREATE DATABASE database_name_to_encrypt; +USE database_name_to_encrypt; +CREATE USER user_name_to_encrypt; +GRANT ALL ON database_name_to_encrypt.* TO user_name_to_encrypt; +SET PASSWORD FOR user_name_to_encrypt = PASSWORD('password_to_encrypt'); +CREATE TABLE innodb_table_name_to_encrypt ( +int_column_name_to_encrypt INT AUTO_INCREMENT PRIMARY KEY, +timestamp_column_name_to_encrypt TIMESTAMP(6) NULL, +blob_column_name_to_encrypt BLOB, +virt_column_name_to_encrypt INT AS (int_column_name_to_encrypt % 10) VIRTUAL, +pers_column_name_to_encrypt INT AS (int_column_name_to_encrypt) PERSISTENT, +INDEX `index_name_to_encrypt`(`timestamp_column_name_to_encrypt`) +) ENGINE=InnoDB +PARTITION BY RANGE (int_column_name_to_encrypt) +SUBPARTITION BY KEY (int_column_name_to_encrypt) +SUBPARTITIONS 2 ( +PARTITION partition0_name_to_encrypt VALUES LESS THAN (100), +PARTITION partition1_name_to_encrypt VALUES LESS THAN (MAXVALUE) +) +; +CREATE TABLE myisam_table_name_to_encrypt ( +int_column_name_to_encrypt INT AUTO_INCREMENT PRIMARY KEY, +char_column_name_to_encrypt VARCHAR(255), +datetime_column_name_to_encrypt DATETIME, +text_column_name_to_encrypt TEXT +) ENGINE=MyISAM; +CREATE TABLE aria_table_name_to_encrypt ( +int_column_name_to_encrypt INT AUTO_INCREMENT PRIMARY KEY, +varchar_column_name_to_encrypt VARCHAR(1024), +enum_column_name_to_encrypt ENUM( +'enum_value1_to_encrypt', +'enum_value2_to_encrypt' + ), +timestamp_column_name_to_encrypt TIMESTAMP(6) NULL, +blob_column_name_to_encrypt BLOB +) ENGINE=Aria; +CREATE TRIGGER trigger_name_to_encrypt +AFTER INSERT ON myisam_table_name_to_encrypt FOR EACH ROW +INSERT INTO aria_table_name_to_encrypt (varchar_column_name_to_encrypt) +VALUES (NEW.char_column_name_to_encrypt); +CREATE DEFINER=user_name_to_encrypt VIEW view_name_to_encrypt +AS SELECT * FROM innodb_table_name_to_encrypt; +CREATE FUNCTION func_name_to_encrypt (func_parameter_to_encrypt INT) +RETURNS VARCHAR(64) +RETURN 'func_result_to_encrypt'; +CREATE PROCEDURE proc_name_to_encrypt ( +IN proc_in_parameter_to_encrypt CHAR(32), +OUT proc_out_parameter_to_encrypt INT +) +BEGIN +DECLARE procvar_name_to_encrypt CHAR(64) DEFAULT 'procvar_val_to_encrypt'; +DECLARE cursor_name_to_encrypt CURSOR FOR +SELECT virt_column_name_to_encrypt FROM innodb_table_name_to_encrypt; +DECLARE EXIT HANDLER FOR NOT FOUND +BEGIN +SET @stmt_var_to_encrypt = CONCAT( +"SELECT + IF (RAND()>0.5,'enum_value2_to_encrypt','enum_value1_to_encrypt') + FROM innodb_table_name_to_encrypt + INTO OUTFILE '", proc_in_parameter_to_encrypt, "'"); +PREPARE stmt_to_encrypt FROM @stmt_var_to_encrypt; +EXECUTE stmt_to_encrypt; +DEALLOCATE PREPARE stmt_to_encrypt; +END; +OPEN cursor_name_to_encrypt; +proc_label_to_encrypt: LOOP +FETCH cursor_name_to_encrypt INTO procvar_name_to_encrypt; +END LOOP; +CLOSE cursor_name_to_encrypt; +END $$ +CREATE SERVER server_name_to_encrypt +FOREIGN DATA WRAPPER mysql +OPTIONS (HOST 'host_name_to_encrypt'); +connect con1,localhost,user_name_to_encrypt,password_to_encrypt,database_name_to_encrypt; +CREATE TEMPORARY TABLE tmp_table_name_to_encrypt ( +float_column_name_to_encrypt FLOAT, +binary_column_name_to_encrypt BINARY(64) +); +disconnect con1; +connection server_1; +CREATE INDEX index_name_to_encrypt +ON myisam_table_name_to_encrypt (datetime_column_name_to_encrypt); +ALTER DATABASE database_name_to_encrypt CHARACTER SET utf8; +ALTER TABLE innodb_table_name_to_encrypt +MODIFY timestamp_column_name_to_encrypt TIMESTAMP NOT NULL +DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP +; +ALTER ALGORITHM=MERGE VIEW view_name_to_encrypt +AS SELECT * FROM innodb_table_name_to_encrypt; +RENAME TABLE innodb_table_name_to_encrypt TO new_table_name_to_encrypt; +ALTER TABLE new_table_name_to_encrypt RENAME TO innodb_table_name_to_encrypt; +set @user_var1_to_encrypt= 'dyncol1_val_to_encrypt'; +set @user_var2_to_encrypt= 'dyncol2_name_to_encrypt'; +INSERT INTO view_name_to_encrypt VALUES +(1, NOW(6), COLUMN_CREATE('dyncol1_name_to_encrypt',@user_var1_to_encrypt), NULL, NULL), +(2, NOW(6), COLUMN_CREATE(@user_var2_to_encrypt,'dyncol2_val_to_encrypt'), NULL, NULL) +; +BEGIN NOT ATOMIC +DECLARE counter_name_to_encrypt INT DEFAULT 0; +START TRANSACTION; +WHILE counter_name_to_encrypt<12 DO +INSERT INTO innodb_table_name_to_encrypt +SELECT NULL, NOW(6), blob_column_name_to_encrypt, NULL, NULL +FROM innodb_table_name_to_encrypt +ORDER BY int_column_name_to_encrypt; +SET counter_name_to_encrypt = counter_name_to_encrypt+1; +END WHILE; +COMMIT; +END +$$ +INSERT INTO myisam_table_name_to_encrypt +SELECT NULL, 'char_literal_to_encrypt', NULL, 'text_to_encrypt'; +INSERT INTO myisam_table_name_to_encrypt (char_column_name_to_encrypt) +SELECT char_column_name_to_encrypt FROM myisam_table_name_to_encrypt; +INSERT INTO myisam_table_name_to_encrypt (char_column_name_to_encrypt) +SELECT char_column_name_to_encrypt FROM myisam_table_name_to_encrypt; +INSERT INTO myisam_table_name_to_encrypt (char_column_name_to_encrypt) +SELECT char_column_name_to_encrypt FROM myisam_table_name_to_encrypt; +CALL proc_name_to_encrypt('file_name_to_encrypt',@useless_var_to_encrypt); +TRUNCATE TABLE aria_table_name_to_encrypt; +LOAD DATA INFILE 'file_name_to_encrypt' INTO TABLE aria_table_name_to_encrypt +(enum_column_name_to_encrypt); +LOAD DATA LOCAL INFILE '<DATADIR>/database_name_to_encrypt/file_name_to_encrypt' +INTO TABLE aria_table_name_to_encrypt (enum_column_name_to_encrypt); +UPDATE view_name_to_encrypt SET blob_column_name_to_encrypt = +COLUMN_CREATE('dyncol1_name_to_encrypt',func_name_to_encrypt(0)) +; +DELETE FROM aria_table_name_to_encrypt ORDER BY int_column_name_to_encrypt LIMIT 10; +ANALYZE TABLE myisam_table_name_to_encrypt; +CHECK TABLE aria_table_name_to_encrypt; +CHECKSUM TABLE innodb_table_name_to_encrypt, myisam_table_name_to_encrypt; +RENAME USER user_name_to_encrypt to new_user_name_to_encrypt; +REVOKE ALL PRIVILEGES, GRANT OPTION FROM new_user_name_to_encrypt; +DROP DATABASE database_name_to_encrypt; +DROP USER new_user_name_to_encrypt; +DROP SERVER server_name_to_encrypt; +#################################################### +# Test 4: binlog with annotated events and binlog_row_image=minimal +#################################################### +connection server_1; +SET binlog_annotate_row_events= 1; +SET GLOBAL binlog_annotate_row_events= 1; +SET GLOBAL binlog_checksum= NONE; +SET GLOBAL master_verify_checksum= 0; +SET GLOBAL binlog_row_image= MINIMAL; +SET binlog_row_image= MINIMAL; +call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT"); +CREATE DATABASE database_name_to_encrypt; +USE database_name_to_encrypt; +CREATE USER user_name_to_encrypt; +GRANT ALL ON database_name_to_encrypt.* TO user_name_to_encrypt; +SET PASSWORD FOR user_name_to_encrypt = PASSWORD('password_to_encrypt'); +CREATE TABLE innodb_table_name_to_encrypt ( +int_column_name_to_encrypt INT AUTO_INCREMENT PRIMARY KEY, +timestamp_column_name_to_encrypt TIMESTAMP(6) NULL, +blob_column_name_to_encrypt BLOB, +virt_column_name_to_encrypt INT AS (int_column_name_to_encrypt % 10) VIRTUAL, +pers_column_name_to_encrypt INT AS (int_column_name_to_encrypt) PERSISTENT, +INDEX `index_name_to_encrypt`(`timestamp_column_name_to_encrypt`) +) ENGINE=InnoDB +PARTITION BY RANGE (int_column_name_to_encrypt) +SUBPARTITION BY KEY (int_column_name_to_encrypt) +SUBPARTITIONS 2 ( +PARTITION partition0_name_to_encrypt VALUES LESS THAN (100), +PARTITION partition1_name_to_encrypt VALUES LESS THAN (MAXVALUE) +) +; +CREATE TABLE myisam_table_name_to_encrypt ( +int_column_name_to_encrypt INT AUTO_INCREMENT PRIMARY KEY, +char_column_name_to_encrypt VARCHAR(255), +datetime_column_name_to_encrypt DATETIME, +text_column_name_to_encrypt TEXT +) ENGINE=MyISAM; +CREATE TABLE aria_table_name_to_encrypt ( +int_column_name_to_encrypt INT AUTO_INCREMENT PRIMARY KEY, +varchar_column_name_to_encrypt VARCHAR(1024), +enum_column_name_to_encrypt ENUM( +'enum_value1_to_encrypt', +'enum_value2_to_encrypt' + ), +timestamp_column_name_to_encrypt TIMESTAMP(6) NULL, +blob_column_name_to_encrypt BLOB +) ENGINE=Aria; +CREATE TRIGGER trigger_name_to_encrypt +AFTER INSERT ON myisam_table_name_to_encrypt FOR EACH ROW +INSERT INTO aria_table_name_to_encrypt (varchar_column_name_to_encrypt) +VALUES (NEW.char_column_name_to_encrypt); +CREATE DEFINER=user_name_to_encrypt VIEW view_name_to_encrypt +AS SELECT * FROM innodb_table_name_to_encrypt; +CREATE FUNCTION func_name_to_encrypt (func_parameter_to_encrypt INT) +RETURNS VARCHAR(64) +RETURN 'func_result_to_encrypt'; +CREATE PROCEDURE proc_name_to_encrypt ( +IN proc_in_parameter_to_encrypt CHAR(32), +OUT proc_out_parameter_to_encrypt INT +) +BEGIN +DECLARE procvar_name_to_encrypt CHAR(64) DEFAULT 'procvar_val_to_encrypt'; +DECLARE cursor_name_to_encrypt CURSOR FOR +SELECT virt_column_name_to_encrypt FROM innodb_table_name_to_encrypt; +DECLARE EXIT HANDLER FOR NOT FOUND +BEGIN +SET @stmt_var_to_encrypt = CONCAT( +"SELECT + IF (RAND()>0.5,'enum_value2_to_encrypt','enum_value1_to_encrypt') + FROM innodb_table_name_to_encrypt + INTO OUTFILE '", proc_in_parameter_to_encrypt, "'"); +PREPARE stmt_to_encrypt FROM @stmt_var_to_encrypt; +EXECUTE stmt_to_encrypt; +DEALLOCATE PREPARE stmt_to_encrypt; +END; +OPEN cursor_name_to_encrypt; +proc_label_to_encrypt: LOOP +FETCH cursor_name_to_encrypt INTO procvar_name_to_encrypt; +END LOOP; +CLOSE cursor_name_to_encrypt; +END $$ +CREATE SERVER server_name_to_encrypt +FOREIGN DATA WRAPPER mysql +OPTIONS (HOST 'host_name_to_encrypt'); +connect con1,localhost,user_name_to_encrypt,password_to_encrypt,database_name_to_encrypt; +CREATE TEMPORARY TABLE tmp_table_name_to_encrypt ( +float_column_name_to_encrypt FLOAT, +binary_column_name_to_encrypt BINARY(64) +); +disconnect con1; +connection server_1; +CREATE INDEX index_name_to_encrypt +ON myisam_table_name_to_encrypt (datetime_column_name_to_encrypt); +ALTER DATABASE database_name_to_encrypt CHARACTER SET utf8; +ALTER TABLE innodb_table_name_to_encrypt +MODIFY timestamp_column_name_to_encrypt TIMESTAMP NOT NULL +DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP +; +ALTER ALGORITHM=MERGE VIEW view_name_to_encrypt +AS SELECT * FROM innodb_table_name_to_encrypt; +RENAME TABLE innodb_table_name_to_encrypt TO new_table_name_to_encrypt; +ALTER TABLE new_table_name_to_encrypt RENAME TO innodb_table_name_to_encrypt; +set @user_var1_to_encrypt= 'dyncol1_val_to_encrypt'; +set @user_var2_to_encrypt= 'dyncol2_name_to_encrypt'; +INSERT INTO view_name_to_encrypt VALUES +(1, NOW(6), COLUMN_CREATE('dyncol1_name_to_encrypt',@user_var1_to_encrypt), NULL, NULL), +(2, NOW(6), COLUMN_CREATE(@user_var2_to_encrypt,'dyncol2_val_to_encrypt'), NULL, NULL) +; +BEGIN NOT ATOMIC +DECLARE counter_name_to_encrypt INT DEFAULT 0; +START TRANSACTION; +WHILE counter_name_to_encrypt<12 DO +INSERT INTO innodb_table_name_to_encrypt +SELECT NULL, NOW(6), blob_column_name_to_encrypt, NULL, NULL +FROM innodb_table_name_to_encrypt +ORDER BY int_column_name_to_encrypt; +SET counter_name_to_encrypt = counter_name_to_encrypt+1; +END WHILE; +COMMIT; +END +$$ +INSERT INTO myisam_table_name_to_encrypt +SELECT NULL, 'char_literal_to_encrypt', NULL, 'text_to_encrypt'; +INSERT INTO myisam_table_name_to_encrypt (char_column_name_to_encrypt) +SELECT char_column_name_to_encrypt FROM myisam_table_name_to_encrypt; +INSERT INTO myisam_table_name_to_encrypt (char_column_name_to_encrypt) +SELECT char_column_name_to_encrypt FROM myisam_table_name_to_encrypt; +INSERT INTO myisam_table_name_to_encrypt (char_column_name_to_encrypt) +SELECT char_column_name_to_encrypt FROM myisam_table_name_to_encrypt; +CALL proc_name_to_encrypt('file_name_to_encrypt',@useless_var_to_encrypt); +TRUNCATE TABLE aria_table_name_to_encrypt; +LOAD DATA INFILE 'file_name_to_encrypt' INTO TABLE aria_table_name_to_encrypt +(enum_column_name_to_encrypt); +LOAD DATA LOCAL INFILE '<DATADIR>/database_name_to_encrypt/file_name_to_encrypt' +INTO TABLE aria_table_name_to_encrypt (enum_column_name_to_encrypt); +UPDATE view_name_to_encrypt SET blob_column_name_to_encrypt = +COLUMN_CREATE('dyncol1_name_to_encrypt',func_name_to_encrypt(0)) +; +DELETE FROM aria_table_name_to_encrypt ORDER BY int_column_name_to_encrypt LIMIT 10; +ANALYZE TABLE myisam_table_name_to_encrypt; +CHECK TABLE aria_table_name_to_encrypt; +CHECKSUM TABLE innodb_table_name_to_encrypt, myisam_table_name_to_encrypt; +RENAME USER user_name_to_encrypt to new_user_name_to_encrypt; +REVOKE ALL PRIVILEGES, GRANT OPTION FROM new_user_name_to_encrypt; +DROP DATABASE database_name_to_encrypt; +DROP USER new_user_name_to_encrypt; +DROP SERVER server_name_to_encrypt; +############################# +# Final checks for the master +############################# +# +# The next step will cause a perl error if the search does not +# meet the expectations. +# Pattern to look for: _to_encrypt +# Files to search: master-bin.0* +# Expected result: 0 +# (0 means the pattern should not be found, 1 means it should be found) +# +Did not find any occurrences of '_to_encrypt' in master-bin.0* +# +# The next step will cause a perl error if the search does not +# meet the expectations. +# Pattern to look for: COMMIT +# Files to search: master-bin.0* +# Expected result: 0 +# (0 means the pattern should not be found, 1 means it should be found) +# +Did not find any occurrences of 'COMMIT' in master-bin.0* +# +# The next step will cause a perl error if the search does not +# meet the expectations. +# Pattern to look for: TIMESTAMP +# Files to search: master-bin.0* +# Expected result: 0 +# (0 means the pattern should not be found, 1 means it should be found) +# +Did not find any occurrences of 'TIMESTAMP' in master-bin.0* +include/save_master_pos.inc +############################# +# Final checks for the slave +############################# +connection server_2; +include/sync_io_with_master.inc +# +# The next step will cause a perl error if the search does not +# meet the expectations. +# Pattern to look for: _to_encrypt +# Files to search: slave-relay-bin.0* +# Expected result: 1 +# (0 means the pattern should not be found, 1 means it should be found) +# +Found occurrences of '_to_encrypt' in slave-relay-bin.0* +# +# The next step will cause a perl error if the search does not +# meet the expectations. +# Pattern to look for: COMMIT +# Files to search: slave-relay-bin.0* +# Expected result: 1 +# (0 means the pattern should not be found, 1 means it should be found) +# +Found occurrences of 'COMMIT' in slave-relay-bin.0* +# +# The next step will cause a perl error if the search does not +# meet the expectations. +# Pattern to look for: TIMESTAMP +# Files to search: slave-relay-bin.0* +# Expected result: 1 +# (0 means the pattern should not be found, 1 means it should be found) +# +Found occurrences of 'TIMESTAMP' in slave-relay-bin.0* +include/start_slave.inc +include/sync_slave_sql_with_io.inc +# +# The next step will cause a perl error if the search does not +# meet the expectations. +# Pattern to look for: _to_encrypt +# Files to search: slave-bin.0* +# Expected result: 1 +# (0 means the pattern should not be found, 1 means it should be found) +# +Found occurrences of '_to_encrypt' in slave-bin.0* +# +# The next step will cause a perl error if the search does not +# meet the expectations. +# Pattern to look for: COMMIT +# Files to search: slave-bin.0* +# Expected result: 1 +# (0 means the pattern should not be found, 1 means it should be found) +# +Found occurrences of 'COMMIT' in slave-bin.0* +# +# The next step will cause a perl error if the search does not +# meet the expectations. +# Pattern to look for: TIMESTAMP +# Files to search: slave-bin.0* +# Expected result: 1 +# (0 means the pattern should not be found, 1 means it should be found) +# +Found occurrences of 'TIMESTAMP' in slave-bin.0* +########## +# Cleanup +########## +connection server_1; +SET GLOBAL binlog_annotate_row_events= @binlog_annotate_row_events.save; +SET GLOBAL binlog_checksum= @binlog_checksum.save; +SET GLOBAL master_verify_checksum= @master_verify_checksum.save; +SET GLOBAL binlog_row_image= @binlog_row_image.save; +include/rpl_end.inc diff --git a/mysql-test/suite/binlog_encryption/encrypted_master.test b/mysql-test/suite/binlog_encryption/encrypted_master.test new file mode 100644 index 0000000..cbf79c0 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/encrypted_master.test @@ -0,0 +1,188 @@ +# +# The test checks that basic DDL and DML events are encrypted +# in the binary log on master. +# The test is to be run with all binlog formats +# (combinations for rpl_init.inc take care of that). +# +# +# The test runs with the encrypted master and non-encrypted slave. +# It generates a sequence of events on master, and checks that +# - all events are encrypted on master; +# - slave is able to replicate from the master; +# - relay logs and binary logs are not encrypted on slave. +# +# The same exercise is repeated +# - without annotated binlog events and without binlog checksums; +# - with binlog checksums; +# - with annotated events and binlog checksums; +# - with annotated events, default checksums and minimal binlog row image +# + +--source encryption_algorithms.inc +--source include/have_innodb.inc +--enable_connect_log + +--echo ################# +--echo # Initialization +--echo ################# + +--disable_connect_log +--let $rpl_topology= 1->2 +--source include/rpl_init.inc +--enable_connect_log + +# We stop SQL thread because we want to have +# all relay logs at the end of the test flow + +--connection server_2 +--disable_connect_log +--source include/stop_slave_sql.inc +--enable_connect_log + +--connection server_1 + +SET @binlog_annotate_row_events.save= @@global.binlog_annotate_row_events; +SET @binlog_checksum.save= @@global.binlog_checksum; +SET @master_verify_checksum.save= @@global.master_verify_checksum; +SET @binlog_row_image.save= @@global.binlog_row_image; + +--echo #################################################### +--echo # Test 1: simple binlog, no checksum, no annotation +--echo #################################################### + +--connection server_1 + +SET binlog_annotate_row_events= 0; +SET GLOBAL binlog_annotate_row_events= 0; +SET GLOBAL binlog_checksum= NONE; +SET GLOBAL master_verify_checksum= 0; + +--source testdata.inc + +--echo #################################################### +--echo # Test 2: binlog with checksum, no annotated events +--echo #################################################### + +--connection server_1 + +SET binlog_annotate_row_events= 0; +SET GLOBAL binlog_annotate_row_events= 0; +SET GLOBAL binlog_checksum= CRC32; +SET GLOBAL master_verify_checksum= 1; + +--source testdata.inc + +--echo #################################################### +--echo # Test 3: binlog with checksum and annotated events +--echo #################################################### + +--connection server_1 + +SET binlog_annotate_row_events= 1; +SET GLOBAL binlog_annotate_row_events= 1; +SET GLOBAL binlog_checksum= CRC32; +SET GLOBAL master_verify_checksum= 1; + +--source testdata.inc + +--echo #################################################### +--echo # Test 4: binlog with annotated events and binlog_row_image=minimal +--echo #################################################### + +--connection server_1 + +SET binlog_annotate_row_events= 1; +SET GLOBAL binlog_annotate_row_events= 1; +SET GLOBAL binlog_checksum= NONE; +SET GLOBAL master_verify_checksum= 0; +SET GLOBAL binlog_row_image= MINIMAL; +SET binlog_row_image= MINIMAL; + +--source testdata.inc + +--echo ############################# +--echo # Final checks for the master +--echo ############################# + +--let search_files=master-bin.0* +--let search_pattern= _to_encrypt +--let search_result= 0 +--source grep_binlog.inc + +--let search_files=master-bin.0* +--let search_pattern= COMMIT +--let search_result= 0 +--source grep_binlog.inc + +--let search_files=master-bin.0* +--let search_pattern= TIMESTAMP +--let search_result= 0 +--source grep_binlog.inc + +--disable_connect_log +--source include/save_master_pos.inc +--enable_connect_log + +--echo ############################# +--echo # Final checks for the slave +--echo ############################# + +# Wait for the IO thread to write everything to relay logs + +--connection server_2 + +--disable_connect_log +--source include/sync_io_with_master.inc + +# Check that relay logs are unencrypted + +--let search_files=slave-relay-bin.0* +--let search_pattern= _to_encrypt +--let search_result= 1 +--source grep_binlog.inc + +--let search_files=slave-relay-bin.0* +--let search_pattern= COMMIT +--let search_result= 1 +--source grep_binlog.inc + +--let search_files=slave-relay-bin.0* +--let search_pattern= TIMESTAMP +--let search_result= 1 +--source grep_binlog.inc + + +# Re-enable SQL thread, let it catch up with IO thread +# and check slave binary logs + +--source include/start_slave.inc +--source include/sync_slave_sql_with_io.inc +--enable_connect_log + +--let search_files=slave-bin.0* +--let search_pattern= _to_encrypt +--let search_result= 1 +--source grep_binlog.inc + +--let search_files=slave-bin.0* +--let search_pattern= COMMIT +--let search_result= 1 +--source grep_binlog.inc + +--let search_files=slave-bin.0* +--let search_pattern= TIMESTAMP +--let search_result= 1 +--source grep_binlog.inc + +--echo ########## +--echo # Cleanup +--echo ########## + +--connection server_1 +SET GLOBAL binlog_annotate_row_events= @binlog_annotate_row_events.save; +SET GLOBAL binlog_checksum= @binlog_checksum.save; +SET GLOBAL master_verify_checksum= @master_verify_checksum.save; +SET GLOBAL binlog_row_image= @binlog_row_image.save; + +--disable_connect_log +--source include/rpl_end.inc diff --git a/mysql-test/suite/binlog_encryption/encrypted_master_lost_key.result b/mysql-test/suite/binlog_encryption/encrypted_master_lost_key.result new file mode 100644 index 0000000..13af8cb --- /dev/null +++ b/mysql-test/suite/binlog_encryption/encrypted_master_lost_key.result @@ -0,0 +1,111 @@ +################# +# Initialization +################# +include/rpl_init.inc [topology=1->2] +connection server_2; +include/stop_slave.inc +##################################################### +# Pre-test 1: Initial key value +##################################################### +connection server_1; +CREATE TABLE table1_to_encrypt ( +pk INT AUTO_INCREMENT PRIMARY KEY, +ts TIMESTAMP NULL, +b BLOB +) ENGINE=MyISAM; +INSERT INTO table1_to_encrypt VALUES (NULL,NOW(),'data_to_encrypt'); +INSERT INTO table1_to_encrypt SELECT NULL,NOW(),b FROM table1_to_encrypt; +SET binlog_format=ROW; +INSERT INTO table1_to_encrypt SELECT NULL,NOW(),b FROM table1_to_encrypt; +INSERT INTO table1_to_encrypt SELECT NULL,NOW(),b FROM table1_to_encrypt; +# +# The next step will cause a perl error if the search does not +# meet the expectations. +# Pattern to look for: table1_to_encrypt +# Files to search: master-bin.0* +# Expected result: 0 +# (0 means the pattern should not be found, 1 means it should be found) +# +Did not find any occurrences of 'table1_to_encrypt' in master-bin.0* +####################################################### +# Pre-test 2: restart master with a different key value +####################################################### +connection default; +connection server_1; +CREATE TABLE table2_to_encrypt ( +pk INT AUTO_INCREMENT PRIMARY KEY, +ts TIMESTAMP NULL, +b BLOB +) ENGINE=MyISAM; +INSERT INTO table2_to_encrypt VALUES (NULL,NOW(),'data_to_encrypt'); +INSERT INTO table2_to_encrypt SELECT NULL,NOW(),b FROM table2_to_encrypt; +SET binlog_format=ROW; +INSERT INTO table2_to_encrypt SELECT NULL,NOW(),b FROM table2_to_encrypt; +INSERT INTO table2_to_encrypt SELECT NULL,NOW(),b FROM table2_to_encrypt; +# +# The next step will cause a perl error if the search does not +# meet the expectations. +# Pattern to look for: table2_to_encrypt +# Files to search: master-bin.0* +# Expected result: 0 +# (0 means the pattern should not be found, 1 means it should be found) +# +Did not find any occurrences of 'table2_to_encrypt' in master-bin.0* +##################################################### +# Pre-test 3: restart master again with the right key +##################################################### +connection default; +connection server_1; +CREATE TABLE table3_to_encrypt ( +pk INT AUTO_INCREMENT PRIMARY KEY, +ts TIMESTAMP NULL, +b BLOB +) ENGINE=MyISAM; +INSERT INTO table3_to_encrypt VALUES (NULL,NOW(),'data_to_encrypt'); +INSERT INTO table3_to_encrypt SELECT NULL,NOW(),b FROM table3_to_encrypt; +INSERT INTO table3_to_encrypt SELECT NULL,NOW(),b FROM table3_to_encrypt; +FLUSH BINARY LOGS; +INSERT INTO table3_to_encrypt SELECT NULL,NOW(),b FROM table3_to_encrypt; +# WARNING: Part of the test was disabled due to MDEV-11323 +##################################################### +# Test 2: check that replication works if it starts +# from a good binary log +##################################################### +connection server_2; +include/stop_slave.inc +Warnings: +Note 1255 Slave already has been stopped +RESET SLAVE ALL; +DROP DATABASE test; +CREATE DATABASE test; +USE test; +CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=<MASTER_PORT>, MASTER_USER='root', MASTER_LOG_FILE='master-bin.000003'; +include/start_slave.inc +SHOW TABLES; +Tables_in_test +table3_to_encrypt +##################################################### +# Test 3: check that replication works if we purge +# master logs up to the good one +##################################################### +connection server_2; +connection server_1; +PURGE BINARY LOGS TO 'master-bin.000003'; +connection server_2; +include/stop_slave.inc +RESET SLAVE ALL; +DROP DATABASE test; +CREATE DATABASE test; +USE test; +CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=<MASTER_PORT>, MASTER_USER='root'; +include/start_slave.inc +SHOW TABLES; +Tables_in_test +table3_to_encrypt +########## +# Cleanup +########## +connection server_1; +DROP TABLE table1_to_encrypt, table2_to_encrypt, table3_to_encrypt; +connection server_2; +include/rpl_end.inc diff --git a/mysql-test/suite/binlog_encryption/encrypted_master_lost_key.test b/mysql-test/suite/binlog_encryption/encrypted_master_lost_key.test new file mode 100644 index 0000000..2e6cbfd --- /dev/null +++ b/mysql-test/suite/binlog_encryption/encrypted_master_lost_key.test @@ -0,0 +1,206 @@ +# +# TODO: finalize the test when MDEV-11323 is fixed or clarified; +# and write here what it actually checks. +# The part where slave synchronizes with master will need +# to be changed, but how it is changed depends on MDEV-11323. +# +# The test checks effects and workarounds for the situation when +# the key used to encrypt previous binary logs on master has been lost, +# and master runs with a different one. +# +# The test starts with encrypted binlogs on master. +# It stops replication, generates a few statement and row events +# on the master, then restarts the server with encrypted binlog, +# but with a different value for key 1. +# +# Then it resumes replication and checks what happens when the server +# tries to feed the binary logs to the slave (it should not work). +# +# Then it resets the slave, configures it to start from a "good" +# master binlog log, for which the master has a key, starts replication +# and checks that it works. +# +# Then it resets the slave again, purges binary logs on master up +# to the "good" one, starts replication and checks that it works. +# + +--source include/have_binlog_format_mixed.inc + +--echo ################# +--echo # Initialization +--echo ################# + +--let $rpl_topology= 1->2 +--source include/rpl_init.inc + +--enable_connect_log + +# We stop replication because we want it to happen after the switch + +--connection server_2 +--disable_connect_log +--source include/stop_slave.inc +--enable_connect_log + +--echo ##################################################### +--echo # Pre-test 1: Initial key value +--echo ##################################################### + +--connection server_1 + +CREATE TABLE table1_to_encrypt ( + pk INT AUTO_INCREMENT PRIMARY KEY, + ts TIMESTAMP NULL, + b BLOB +) ENGINE=MyISAM; + +INSERT INTO table1_to_encrypt VALUES (NULL,NOW(),'data_to_encrypt'); +INSERT INTO table1_to_encrypt SELECT NULL,NOW(),b FROM table1_to_encrypt; +SET binlog_format=ROW; +INSERT INTO table1_to_encrypt SELECT NULL,NOW(),b FROM table1_to_encrypt; +INSERT INTO table1_to_encrypt SELECT NULL,NOW(),b FROM table1_to_encrypt; + +# Make sure that binary logs are encrypted + +--let search_files=master-bin.0* +--let search_pattern= table1_to_encrypt +--let search_result= 0 +--source grep_binlog.inc + +--echo ####################################################### +--echo # Pre-test 2: restart master with a different key value +--echo ####################################################### + +--write_file $MYSQL_TMP_DIR/master_lose_key.key +1;00000AAAAAAAAAAAAAAAAAAAAAA00000 +EOF + +--let $rpl_server_parameters= --loose-file-key-management-filename=$MYSQL_TMP_DIR/master_lose_key.key + +--let $rpl_server_number= 1 +--source restart_server.inc + +CREATE TABLE table2_to_encrypt ( + pk INT AUTO_INCREMENT PRIMARY KEY, + ts TIMESTAMP NULL, + b BLOB +) ENGINE=MyISAM; + +INSERT INTO table2_to_encrypt VALUES (NULL,NOW(),'data_to_encrypt'); +INSERT INTO table2_to_encrypt SELECT NULL,NOW(),b FROM table2_to_encrypt; +SET binlog_format=ROW; +INSERT INTO table2_to_encrypt SELECT NULL,NOW(),b FROM table2_to_encrypt; +INSERT INTO table2_to_encrypt SELECT NULL,NOW(),b FROM table2_to_encrypt; + +# Make sure that binary logs are encrypted + +--let search_files=master-bin.0* +--let search_pattern= table2_to_encrypt +--let search_result= 0 +--source grep_binlog.inc + +--echo ##################################################### +--echo # Pre-test 3: restart master again with the right key +--echo ##################################################### + +--let $rpl_server_parameters= +--let $rpl_server_number= 1 +--source restart_server.inc + +--let $good_master_binlog= query_get_value(SHOW MASTER STATUS,File,1) + +CREATE TABLE table3_to_encrypt ( + pk INT AUTO_INCREMENT PRIMARY KEY, + ts TIMESTAMP NULL, + b BLOB +) ENGINE=MyISAM; + +INSERT INTO table3_to_encrypt VALUES (NULL,NOW(),'data_to_encrypt'); +INSERT INTO table3_to_encrypt SELECT NULL,NOW(),b FROM table3_to_encrypt; +INSERT INTO table3_to_encrypt SELECT NULL,NOW(),b FROM table3_to_encrypt; +FLUSH BINARY LOGS; +INSERT INTO table3_to_encrypt SELECT NULL,NOW(),b FROM table3_to_encrypt; + +--save_master_pos + +# TODO: Fix and re-enable after MDEV-11323 is closed +--disable_parsing + +--echo ##################################################### +--echo # Test 1: check how replication goes when it reaches +--echo # the log with a wrong key +--echo ##################################################### +--connection server_2 + +--disable_connect_log +--source include/start_slave.inc +--enable_connect_log +--sync_with_master + +--sorted_result +SHOW TABLES; + +--enable_parsing +--echo # WARNING: Part of the test was disabled due to MDEV-11323 + +--echo ##################################################### +--echo # Test 2: check that replication works if it starts +--echo # from a good binary log +--echo ##################################################### +--connection server_2 + +--disable_connect_log +--source include/stop_slave.inc +RESET SLAVE ALL; +DROP DATABASE test; +CREATE DATABASE test; +USE test; +--replace_result $SERVER_MYPORT_1 <MASTER_PORT> +eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=$SERVER_MYPORT_1, MASTER_USER='root', MASTER_LOG_FILE='$good_master_binlog'; +--source include/start_slave.inc +--enable_connect_log +--sync_with_master + +--sorted_result +SHOW TABLES; + +--echo ##################################################### +--echo # Test 3: check that replication works if we purge +--echo # master logs up to the good one +--echo ##################################################### +--connection server_2 + +--connection server_1 +eval PURGE BINARY LOGS TO '$good_master_binlog'; + +--connection server_2 +--disable_connect_log +--source include/stop_slave.inc +RESET SLAVE ALL; +DROP DATABASE test; +CREATE DATABASE test; +USE test; +--replace_result $SERVER_MYPORT_1 <MASTER_PORT> +eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=$SERVER_MYPORT_1, MASTER_USER='root'; +--source include/start_slave.inc +--enable_connect_log +--sync_with_master + +--sorted_result +SHOW TABLES; + +--echo ########## +--echo # Cleanup +--echo ########## + +--connection server_1 + +DROP TABLE table1_to_encrypt, table2_to_encrypt, table3_to_encrypt; + +--save_master_pos + +--connection server_2 +--sync_with_master + +--disable_connect_log +--source include/rpl_end.inc diff --git a/mysql-test/suite/binlog_encryption/encrypted_master_switch_to_unencrypted.test b/mysql-test/suite/binlog_encryption/encrypted_master_switch_to_unencrypted.test new file mode 100644 index 0000000..ec8be86 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/encrypted_master_switch_to_unencrypted.test @@ -0,0 +1,137 @@ +# +# TODO: write here what the test checks after MDEV-11288 is fixed +# +# The test starts with unencrypted master. +# It stops replication, generates a few statement and row events +# on the master, then restarts the server with encrypted binlog, +# generates some more events and restarts it back without encryption +# (no encryption plugin). +# Then it resumes replication and checks what happens when the server +# tries to feed the binary logs (included the encrypted ones) +# to the slave. +# + +--source include/have_binlog_format_mixed.inc + +--echo ################# +--echo # Initialization +--echo ################# + +--let $rpl_topology= 1->2 +--source include/rpl_init.inc + +--enable_connect_log + +# We stop replication because we want it to happen after the switch + +--connection server_2 +--disable_connect_log +--source include/stop_slave.inc +--enable_connect_log + +--echo ##################################################### +--echo # Part 1: unencrypted master +--echo ##################################################### + +--connection server_1 + +CREATE TABLE table1_no_encryption ( + pk INT AUTO_INCREMENT PRIMARY KEY, + ts TIMESTAMP NULL, + b BLOB +) ENGINE=MyISAM; + +INSERT INTO table1_no_encryption VALUES (NULL,NOW(),'data_no_encryption'); +INSERT INTO table1_no_encryption SELECT NULL,NOW(),b FROM table1_no_encryption; +FLUSH BINARY LOGS; +SET binlog_format=ROW; +INSERT INTO table1_no_encryption SELECT NULL,NOW(),b FROM table1_no_encryption; +INSERT INTO table1_no_encryption SELECT NULL,NOW(),b FROM table1_no_encryption; + +# Make sure that binary logs are not encrypted + +--let search_files=master-bin.0* +--let search_pattern= table1_no_encryption +--let search_result= 1 +--source grep_binlog.inc + +--echo ##################################################### +--echo # Part 2: restart master, now with binlog encryption +--echo ##################################################### + +--let $rpl_server_parameters= --encrypt-binlog=1 --plugin-load-add=$FILE_KEY_MANAGEMENT_SO --file-key-management --loose-file-key-management-filename=$MYSQL_TEST_DIR/std_data/keys.txt + +--let $rpl_server_number= 1 +--source restart_server.inc + +CREATE TABLE table2_to_encrypt ( + pk INT AUTO_INCREMENT PRIMARY KEY, + ts TIMESTAMP NULL, + b BLOB +) ENGINE=MyISAM; + +INSERT INTO table2_to_encrypt VALUES (NULL,NOW(),'data_to_encrypt'); +INSERT INTO table2_to_encrypt SELECT NULL,NOW(),b FROM table2_to_encrypt; +FLUSH BINARY LOGS; +SET binlog_format=ROW; +INSERT INTO table2_to_encrypt SELECT NULL,NOW(),b FROM table2_to_encrypt; +INSERT INTO table2_to_encrypt SELECT NULL,NOW(),b FROM table2_to_encrypt; + +# Make sure that binary logs are encrypted + +--let search_files=master-bin.0* +--let search_pattern= table2_to_encrypt +--let search_result= 0 +--source grep_binlog.inc + +--echo ##################################################### +--echo # Part 3: restart master again without encryption +--echo ##################################################### + +--let $rpl_server_parameters= --encrypt-binlog=0 +--let $rpl_server_number= 1 +--source restart_server.inc + +CREATE TABLE table3_no_encryption ( + pk INT AUTO_INCREMENT PRIMARY KEY, + ts TIMESTAMP NULL, + b BLOB +) ENGINE=MyISAM; + +INSERT INTO table3_no_encryption VALUES (NULL,NOW(),'data_no_encryption'); +INSERT INTO table3_no_encryption SELECT NULL,NOW(),b FROM table3_no_encryption; +INSERT INTO table3_no_encryption SELECT NULL,NOW(),b FROM table3_no_encryption; + +--save_master_pos + +--echo ##################################################### +--echo # Check: resume replication and check how it goes +--echo ##################################################### +--connection server_2 + +--disable_connect_log +--source include/start_slave.inc +--enable_connect_log +--sync_with_master + +--sorted_result +SHOW TABLES; + +--echo ########## +--echo # Cleanup +--echo ########## + +--connection server_1 + +SELECT COUNT(*) FROM table1_no_encryption; +SELECT COUNT(*) FROM table2_to_encrypt; +SELECT COUNT(*) FROM table3_no_encryption; +DROP TABLE table1_no_encryption, table2_to_encrypt, table3_no_encryption; + +--save_master_pos + +--connection server_2 +--sync_with_master + +--disable_connect_log +--source include/rpl_end.inc diff --git a/mysql-test/suite/binlog_encryption/encrypted_slave.cnf b/mysql-test/suite/binlog_encryption/encrypted_slave.cnf new file mode 100644 index 0000000..fac94db --- /dev/null +++ b/mysql-test/suite/binlog_encryption/encrypted_slave.cnf @@ -0,0 +1,12 @@ +!include my.cnf + +[mysqld.1] +encrypt-binlog=0 + +[mysqld.2] +#log-slave-updates +encrypt-binlog +plugin-load-add= @ENV.FILE_KEY_MANAGEMENT_SO +file-key-management +loose-file-key-management-filename= @ENV.MYSQL_TEST_DIR/std_data/keys.txt +binlog_checksum=NONE diff --git a/mysql-test/suite/binlog_encryption/encrypted_slave.result b/mysql-test/suite/binlog_encryption/encrypted_slave.result new file mode 100644 index 0000000..b02904e --- /dev/null +++ b/mysql-test/suite/binlog_encryption/encrypted_slave.result @@ -0,0 +1,247 @@ +################# +# Initialization +################# +include/rpl_init.inc [topology=1->2] +connection server_2; +include/stop_slave_sql.inc +################# +# Test flow +################# +connection server_1; +call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT"); +CREATE DATABASE database_name_to_encrypt; +USE database_name_to_encrypt; +CREATE USER user_name_to_encrypt; +GRANT ALL ON database_name_to_encrypt.* TO user_name_to_encrypt; +SET PASSWORD FOR user_name_to_encrypt = PASSWORD('password_to_encrypt'); +CREATE TABLE innodb_table_name_to_encrypt ( +int_column_name_to_encrypt INT AUTO_INCREMENT PRIMARY KEY, +timestamp_column_name_to_encrypt TIMESTAMP(6) NULL, +blob_column_name_to_encrypt BLOB, +virt_column_name_to_encrypt INT AS (int_column_name_to_encrypt % 10) VIRTUAL, +pers_column_name_to_encrypt INT AS (int_column_name_to_encrypt) PERSISTENT, +INDEX `index_name_to_encrypt`(`timestamp_column_name_to_encrypt`) +) ENGINE=InnoDB +PARTITION BY RANGE (int_column_name_to_encrypt) +SUBPARTITION BY KEY (int_column_name_to_encrypt) +SUBPARTITIONS 2 ( +PARTITION partition0_name_to_encrypt VALUES LESS THAN (100), +PARTITION partition1_name_to_encrypt VALUES LESS THAN (MAXVALUE) +) +; +CREATE TABLE myisam_table_name_to_encrypt ( +int_column_name_to_encrypt INT AUTO_INCREMENT PRIMARY KEY, +char_column_name_to_encrypt VARCHAR(255), +datetime_column_name_to_encrypt DATETIME, +text_column_name_to_encrypt TEXT +) ENGINE=MyISAM; +CREATE TABLE aria_table_name_to_encrypt ( +int_column_name_to_encrypt INT AUTO_INCREMENT PRIMARY KEY, +varchar_column_name_to_encrypt VARCHAR(1024), +enum_column_name_to_encrypt ENUM( +'enum_value1_to_encrypt', +'enum_value2_to_encrypt' + ), +timestamp_column_name_to_encrypt TIMESTAMP(6) NULL, +blob_column_name_to_encrypt BLOB +) ENGINE=Aria; +CREATE TRIGGER trigger_name_to_encrypt +AFTER INSERT ON myisam_table_name_to_encrypt FOR EACH ROW +INSERT INTO aria_table_name_to_encrypt (varchar_column_name_to_encrypt) +VALUES (NEW.char_column_name_to_encrypt); +CREATE DEFINER=user_name_to_encrypt VIEW view_name_to_encrypt +AS SELECT * FROM innodb_table_name_to_encrypt; +CREATE FUNCTION func_name_to_encrypt (func_parameter_to_encrypt INT) +RETURNS VARCHAR(64) +RETURN 'func_result_to_encrypt'; +CREATE PROCEDURE proc_name_to_encrypt ( +IN proc_in_parameter_to_encrypt CHAR(32), +OUT proc_out_parameter_to_encrypt INT +) +BEGIN +DECLARE procvar_name_to_encrypt CHAR(64) DEFAULT 'procvar_val_to_encrypt'; +DECLARE cursor_name_to_encrypt CURSOR FOR +SELECT virt_column_name_to_encrypt FROM innodb_table_name_to_encrypt; +DECLARE EXIT HANDLER FOR NOT FOUND +BEGIN +SET @stmt_var_to_encrypt = CONCAT( +"SELECT + IF (RAND()>0.5,'enum_value2_to_encrypt','enum_value1_to_encrypt') + FROM innodb_table_name_to_encrypt + INTO OUTFILE '", proc_in_parameter_to_encrypt, "'"); +PREPARE stmt_to_encrypt FROM @stmt_var_to_encrypt; +EXECUTE stmt_to_encrypt; +DEALLOCATE PREPARE stmt_to_encrypt; +END; +OPEN cursor_name_to_encrypt; +proc_label_to_encrypt: LOOP +FETCH cursor_name_to_encrypt INTO procvar_name_to_encrypt; +END LOOP; +CLOSE cursor_name_to_encrypt; +END $$ +CREATE SERVER server_name_to_encrypt +FOREIGN DATA WRAPPER mysql +OPTIONS (HOST 'host_name_to_encrypt'); +connect con1,localhost,user_name_to_encrypt,password_to_encrypt,database_name_to_encrypt; +CREATE TEMPORARY TABLE tmp_table_name_to_encrypt ( +float_column_name_to_encrypt FLOAT, +binary_column_name_to_encrypt BINARY(64) +); +disconnect con1; +connection server_1; +CREATE INDEX index_name_to_encrypt +ON myisam_table_name_to_encrypt (datetime_column_name_to_encrypt); +ALTER DATABASE database_name_to_encrypt CHARACTER SET utf8; +ALTER TABLE innodb_table_name_to_encrypt +MODIFY timestamp_column_name_to_encrypt TIMESTAMP NOT NULL +DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP +; +ALTER ALGORITHM=MERGE VIEW view_name_to_encrypt +AS SELECT * FROM innodb_table_name_to_encrypt; +RENAME TABLE innodb_table_name_to_encrypt TO new_table_name_to_encrypt; +ALTER TABLE new_table_name_to_encrypt RENAME TO innodb_table_name_to_encrypt; +set @user_var1_to_encrypt= 'dyncol1_val_to_encrypt'; +set @user_var2_to_encrypt= 'dyncol2_name_to_encrypt'; +INSERT INTO view_name_to_encrypt VALUES +(1, NOW(6), COLUMN_CREATE('dyncol1_name_to_encrypt',@user_var1_to_encrypt), NULL, NULL), +(2, NOW(6), COLUMN_CREATE(@user_var2_to_encrypt,'dyncol2_val_to_encrypt'), NULL, NULL) +; +BEGIN NOT ATOMIC +DECLARE counter_name_to_encrypt INT DEFAULT 0; +START TRANSACTION; +WHILE counter_name_to_encrypt<12 DO +INSERT INTO innodb_table_name_to_encrypt +SELECT NULL, NOW(6), blob_column_name_to_encrypt, NULL, NULL +FROM innodb_table_name_to_encrypt +ORDER BY int_column_name_to_encrypt; +SET counter_name_to_encrypt = counter_name_to_encrypt+1; +END WHILE; +COMMIT; +END +$$ +INSERT INTO myisam_table_name_to_encrypt +SELECT NULL, 'char_literal_to_encrypt', NULL, 'text_to_encrypt'; +INSERT INTO myisam_table_name_to_encrypt (char_column_name_to_encrypt) +SELECT char_column_name_to_encrypt FROM myisam_table_name_to_encrypt; +INSERT INTO myisam_table_name_to_encrypt (char_column_name_to_encrypt) +SELECT char_column_name_to_encrypt FROM myisam_table_name_to_encrypt; +INSERT INTO myisam_table_name_to_encrypt (char_column_name_to_encrypt) +SELECT char_column_name_to_encrypt FROM myisam_table_name_to_encrypt; +CALL proc_name_to_encrypt('file_name_to_encrypt',@useless_var_to_encrypt); +TRUNCATE TABLE aria_table_name_to_encrypt; +LOAD DATA INFILE 'file_name_to_encrypt' INTO TABLE aria_table_name_to_encrypt +(enum_column_name_to_encrypt); +LOAD DATA LOCAL INFILE '<DATADIR>/database_name_to_encrypt/file_name_to_encrypt' +INTO TABLE aria_table_name_to_encrypt (enum_column_name_to_encrypt); +UPDATE view_name_to_encrypt SET blob_column_name_to_encrypt = +COLUMN_CREATE('dyncol1_name_to_encrypt',func_name_to_encrypt(0)) +; +DELETE FROM aria_table_name_to_encrypt ORDER BY int_column_name_to_encrypt LIMIT 10; +ANALYZE TABLE myisam_table_name_to_encrypt; +CHECK TABLE aria_table_name_to_encrypt; +CHECKSUM TABLE innodb_table_name_to_encrypt, myisam_table_name_to_encrypt; +RENAME USER user_name_to_encrypt to new_user_name_to_encrypt; +REVOKE ALL PRIVILEGES, GRANT OPTION FROM new_user_name_to_encrypt; +DROP DATABASE database_name_to_encrypt; +DROP USER new_user_name_to_encrypt; +DROP SERVER server_name_to_encrypt; +################# +# Master binlog checks +################# +# +# The next step will cause a perl error if the search does not +# meet the expectations. +# Pattern to look for: _to_encrypt +# Files to search: master-bin.0* +# Expected result: 1 +# (0 means the pattern should not be found, 1 means it should be found) +# +Found occurrences of '_to_encrypt' in master-bin.0* +# +# The next step will cause a perl error if the search does not +# meet the expectations. +# Pattern to look for: COMMIT +# Files to search: master-bin.0* +# Expected result: 1 +# (0 means the pattern should not be found, 1 means it should be found) +# +Found occurrences of 'COMMIT' in master-bin.0* +# +# The next step will cause a perl error if the search does not +# meet the expectations. +# Pattern to look for: TIMESTAMP +# Files to search: master-bin.0* +# Expected result: 1 +# (0 means the pattern should not be found, 1 means it should be found) +# +Found occurrences of 'TIMESTAMP' in master-bin.0* +include/save_master_pos.inc +################# +# Relay log checks +################# +connection server_2; +include/sync_io_with_master.inc +# +# The next step will cause a perl error if the search does not +# meet the expectations. +# Pattern to look for: _to_encrypt +# Files to search: slave-relay-bin.0* +# Expected result: 0 +# (0 means the pattern should not be found, 1 means it should be found) +# +Did not find any occurrences of '_to_encrypt' in slave-relay-bin.0* +# +# The next step will cause a perl error if the search does not +# meet the expectations. +# Pattern to look for: COMMIT +# Files to search: slave-relay-bin.0* +# Expected result: 0 +# (0 means the pattern should not be found, 1 means it should be found) +# +Did not find any occurrences of 'COMMIT' in slave-relay-bin.0* +# +# The next step will cause a perl error if the search does not +# meet the expectations. +# Pattern to look for: TIMESTAMP +# Files to search: slave-relay-bin.0* +# Expected result: 0 +# (0 means the pattern should not be found, 1 means it should be found) +# +Did not find any occurrences of 'TIMESTAMP' in slave-relay-bin.0* +################# +# Slave binlog checks +################# +include/start_slave.inc +include/sync_slave_sql_with_io.inc +include/sync_io_with_master.inc +# +# The next step will cause a perl error if the search does not +# meet the expectations. +# Pattern to look for: _to_encrypt +# Files to search: slave-bin.0* +# Expected result: 0 +# (0 means the pattern should not be found, 1 means it should be found) +# +Did not find any occurrences of '_to_encrypt' in slave-bin.0* +# +# The next step will cause a perl error if the search does not +# meet the expectations. +# Pattern to look for: COMMIT +# Files to search: slave-bin.0* +# Expected result: 0 +# (0 means the pattern should not be found, 1 means it should be found) +# +Did not find any occurrences of 'COMMIT' in slave-bin.0* +# +# The next step will cause a perl error if the search does not +# meet the expectations. +# Pattern to look for: TIMESTAMP +# Files to search: slave-bin.0* +# Expected result: 0 +# (0 means the pattern should not be found, 1 means it should be found) +# +Did not find any occurrences of 'TIMESTAMP' in slave-bin.0* +########## +# Cleanup +########## +include/rpl_end.inc diff --git a/mysql-test/suite/binlog_encryption/encrypted_slave.test b/mysql-test/suite/binlog_encryption/encrypted_slave.test new file mode 100644 index 0000000..b13d6d8 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/encrypted_slave.test @@ -0,0 +1,122 @@ +# +# The test checks that basic DDL and DML events are encrypted +# in the relay and binary logs on slave. +# The test is to be run with all binlog formats +# (combinations for rpl_init.inc take care of that). +# +# The test runs with the non-encrypted master and encrypted slave. +# It generates a sequence of events on master and checks that +# relay logs and binary logs are encrypted on slave. +# + +--source encryption_algorithms.inc +--source include/have_innodb.inc + +--echo ################# +--echo # Initialization +--echo ################# + +--let $rpl_topology= 1->2 +--source include/rpl_init.inc + +--enable_connect_log +--connection server_2 + +# We stop SQL thread because we want to have +# all relay logs at the end of the test flow + +--disable_connect_log +--source include/stop_slave_sql.inc +--enable_connect_log + +--echo ################# +--echo # Test flow +--echo ################# + +--connection server_1 +--source testdata.inc + +--echo ################# +--echo # Master binlog checks +--echo ################# + +--let search_files=master-bin.0* +--let search_pattern= _to_encrypt +--let search_result= 1 +--source grep_binlog.inc + +--let search_files=master-bin.0* +--let search_pattern= COMMIT +--let search_result= 1 +--source grep_binlog.inc + +--let search_files=master-bin.0* +--let search_pattern= TIMESTAMP +--let search_result= 1 +--source grep_binlog.inc + +--disable_connect_log +--source include/save_master_pos.inc +--enable_connect_log + +--echo ################# +--echo # Relay log checks +--echo ################# + +--connection server_2 +--disable_connect_log +--source include/sync_io_with_master.inc +--enable_connect_log + +--let search_files=slave-relay-bin.0* +--let search_pattern= _to_encrypt +--let search_result= 0 +--source grep_binlog.inc + +--let search_files=slave-relay-bin.0* +--let search_pattern= COMMIT +--let search_result= 0 +--source grep_binlog.inc + +--let search_files=slave-relay-bin.0* +--let search_pattern= TIMESTAMP +--let search_result= 0 +--source grep_binlog.inc + +--echo ################# +--echo # Slave binlog checks +--echo ################# + +# Re-enable SQL thread, let it catch up with IO thread +# and check slave binary logs + +--disable_connect_log +--source include/start_slave.inc +--source include/sync_slave_sql_with_io.inc +--enable_connect_log + +--disable_connect_log +--source include/sync_io_with_master.inc +--enable_connect_log + +--let search_files=slave-bin.0* +--let search_pattern= _to_encrypt +--let search_result= 0 +--source grep_binlog.inc + +--let search_files=slave-bin.0* +--let search_pattern= COMMIT +--let search_result= 0 +--source grep_binlog.inc + +--let search_files=slave-bin.0* +--let search_pattern= TIMESTAMP +--let search_result= 0 +--source grep_binlog.inc + +--echo ########## +--echo # Cleanup +--echo ########## + +--disable_connect_log +--source include/rpl_end.inc diff --git a/mysql-test/suite/binlog_encryption/encryption_algorithms.combinations b/mysql-test/suite/binlog_encryption/encryption_algorithms.combinations new file mode 100644 index 0000000..6bda5a6 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/encryption_algorithms.combinations @@ -0,0 +1,5 @@ +[ctr] +loose-file-key-management-encryption-algorithm=aes_ctr + +[cbc] +loose-file-key-management-encryption-algorithm=aes_cbc diff --git a/mysql-test/suite/binlog_encryption/encryption_algorithms.inc b/mysql-test/suite/binlog_encryption/encryption_algorithms.inc new file mode 100644 index 0000000..ca55962 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/encryption_algorithms.inc @@ -0,0 +1,2 @@ +# Empty include file just to enable encryption algorithm combinations +# for those tests which need them diff --git a/mysql-test/suite/binlog_encryption/encryption_combo.cnf b/mysql-test/suite/binlog_encryption/encryption_combo.cnf new file mode 100644 index 0000000..bc4ecbc --- /dev/null +++ b/mysql-test/suite/binlog_encryption/encryption_combo.cnf @@ -0,0 +1,5 @@ +!include my.cnf + +[mysqld.1] +encrypt-binlog=0 + diff --git a/mysql-test/suite/binlog_encryption/encryption_combo.result b/mysql-test/suite/binlog_encryption/encryption_combo.result new file mode 100644 index 0000000..06d7862 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/encryption_combo.result @@ -0,0 +1,94 @@ +################# +# Initialization +################# +include/rpl_init.inc [topology=1->2] +connection server_2; +include/stop_slave.inc +##################################################### +# Part 1: unencrypted master +##################################################### +connection server_1; +CREATE TABLE table1_no_encryption ( +pk INT AUTO_INCREMENT PRIMARY KEY, +ts TIMESTAMP NULL, +b BLOB +) ENGINE=MyISAM; +INSERT INTO table1_no_encryption VALUES (NULL,NOW(),'data_no_encryption'); +INSERT INTO table1_no_encryption SELECT NULL,NOW(),b FROM table1_no_encryption; +FLUSH BINARY LOGS; +SET binlog_format=ROW; +INSERT INTO table1_no_encryption SELECT NULL,NOW(),b FROM table1_no_encryption; +INSERT INTO table1_no_encryption SELECT NULL,NOW(),b FROM table1_no_encryption; +# +# The next step will cause a perl error if the search does not +# meet the expectations. +# Pattern to look for: table1_no_encryption +# Files to search: master-bin.0* +# Expected result: 1 +# (0 means the pattern should not be found, 1 means it should be found) +# +Found occurrences of 'table1_no_encryption' in master-bin.0* +##################################################### +# Part 2: restart master, now with binlog encryption +##################################################### +connection default; +connection server_1; +CREATE TABLE table2_to_encrypt ( +pk INT AUTO_INCREMENT PRIMARY KEY, +ts TIMESTAMP NULL, +b BLOB +) ENGINE=MyISAM; +INSERT INTO table2_to_encrypt VALUES (NULL,NOW(),'data_to_encrypt'); +INSERT INTO table2_to_encrypt SELECT NULL,NOW(),b FROM table2_to_encrypt; +FLUSH BINARY LOGS; +SET binlog_format=ROW; +INSERT INTO table2_to_encrypt SELECT NULL,NOW(),b FROM table2_to_encrypt; +INSERT INTO table2_to_encrypt SELECT NULL,NOW(),b FROM table2_to_encrypt; +# +# The next step will cause a perl error if the search does not +# meet the expectations. +# Pattern to look for: table2_to_encrypt +# Files to search: master-bin.0* +# Expected result: 0 +# (0 means the pattern should not be found, 1 means it should be found) +# +Did not find any occurrences of 'table2_to_encrypt' in master-bin.0* +##################################################### +# Part 3: restart master again without encryption +##################################################### +connection default; +connection server_1; +CREATE TABLE table3_no_encryption ( +pk INT AUTO_INCREMENT PRIMARY KEY, +ts TIMESTAMP NULL, +b BLOB +) ENGINE=MyISAM; +INSERT INTO table3_no_encryption VALUES (NULL,NOW(),'data_no_encryption'); +INSERT INTO table3_no_encryption SELECT NULL,NOW(),b FROM table3_no_encryption; +INSERT INTO table3_no_encryption SELECT NULL,NOW(),b FROM table3_no_encryption; +##################################################### +# Check: resume replication and check that it works +##################################################### +connection server_2; +include/start_slave.inc +SHOW TABLES; +Tables_in_test +table1_no_encryption +table2_to_encrypt +table3_no_encryption +########## +# Cleanup +########## +connection server_1; +SELECT COUNT(*) FROM table1_no_encryption; +COUNT(*) +8 +SELECT COUNT(*) FROM table2_to_encrypt; +COUNT(*) +8 +SELECT COUNT(*) FROM table3_no_encryption; +COUNT(*) +4 +DROP TABLE table1_no_encryption, table2_to_encrypt, table3_no_encryption; +connection server_2; +include/rpl_end.inc diff --git a/mysql-test/suite/binlog_encryption/encryption_combo.test b/mysql-test/suite/binlog_encryption/encryption_combo.test new file mode 100644 index 0000000..fe733fd --- /dev/null +++ b/mysql-test/suite/binlog_encryption/encryption_combo.test @@ -0,0 +1,136 @@ +# +# The test checks that master with decryption capabilities can switch +# between encrypted and unencrypted logs (with server restart), +# and can feed the mix of encrypted/unencrypted logs to a slave. +# +# The test starts with unencrypted master. +# It stops replication, generates a few statement and row events +# on the master, then restarts the server with encrypted binlog, +# generates some more events and restarts it back with unencrypted binlog. +# Then it resumes replication and checks that all events +# are replicated successfully. +# + +--source include/have_binlog_format_mixed.inc + +--echo ################# +--echo # Initialization +--echo ################# + +--let $rpl_topology= 1->2 +--source include/rpl_init.inc + +--enable_connect_log + +# We stop replication because we want it to happen after the switch + +--connection server_2 +--disable_connect_log +--source include/stop_slave.inc +--enable_connect_log + +--echo ##################################################### +--echo # Part 1: unencrypted master +--echo ##################################################### + +--connection server_1 + +CREATE TABLE table1_no_encryption ( + pk INT AUTO_INCREMENT PRIMARY KEY, + ts TIMESTAMP NULL, + b BLOB +) ENGINE=MyISAM; + +INSERT INTO table1_no_encryption VALUES (NULL,NOW(),'data_no_encryption'); +INSERT INTO table1_no_encryption SELECT NULL,NOW(),b FROM table1_no_encryption; +FLUSH BINARY LOGS; +SET binlog_format=ROW; +INSERT INTO table1_no_encryption SELECT NULL,NOW(),b FROM table1_no_encryption; +INSERT INTO table1_no_encryption SELECT NULL,NOW(),b FROM table1_no_encryption; + +# Make sure that binary logs are not encrypted + +--let search_files=master-bin.0* +--let search_pattern= table1_no_encryption +--let search_result= 1 +--source grep_binlog.inc + +--echo ##################################################### +--echo # Part 2: restart master, now with binlog encryption +--echo ##################################################### + +--let $rpl_server_parameters= --encrypt-binlog=1 +--let $rpl_server_number= 1 +--source restart_server.inc + +CREATE TABLE table2_to_encrypt ( + pk INT AUTO_INCREMENT PRIMARY KEY, + ts TIMESTAMP NULL, + b BLOB +) ENGINE=MyISAM; + +INSERT INTO table2_to_encrypt VALUES (NULL,NOW(),'data_to_encrypt'); +INSERT INTO table2_to_encrypt SELECT NULL,NOW(),b FROM table2_to_encrypt; +FLUSH BINARY LOGS; +SET binlog_format=ROW; +INSERT INTO table2_to_encrypt SELECT NULL,NOW(),b FROM table2_to_encrypt; +INSERT INTO table2_to_encrypt SELECT NULL,NOW(),b FROM table2_to_encrypt; + +# Make sure that binary logs are encrypted + +--let search_files=master-bin.0* +--let search_pattern= table2_to_encrypt +--let search_result= 0 +--source grep_binlog.inc + +--echo ##################################################### +--echo # Part 3: restart master again without encryption +--echo ##################################################### + +--let $rpl_server_parameters= --encrypt-binlog=0 +--let $rpl_server_number= 1 +--source restart_server.inc + +CREATE TABLE table3_no_encryption ( + pk INT AUTO_INCREMENT PRIMARY KEY, + ts TIMESTAMP NULL, + b BLOB +) ENGINE=MyISAM; + +INSERT INTO table3_no_encryption VALUES (NULL,NOW(),'data_no_encryption'); +INSERT INTO table3_no_encryption SELECT NULL,NOW(),b FROM table3_no_encryption; +INSERT INTO table3_no_encryption SELECT NULL,NOW(),b FROM table3_no_encryption; + +--save_master_pos + +--echo ##################################################### +--echo # Check: resume replication and check that it works +--echo ##################################################### +--connection server_2 + +--disable_connect_log +--source include/start_slave.inc +--enable_connect_log +--sync_with_master + +--sorted_result +SHOW TABLES; + +--echo ########## +--echo # Cleanup +--echo ########## + +--connection server_1 + +SELECT COUNT(*) FROM table1_no_encryption; +SELECT COUNT(*) FROM table2_to_encrypt; +SELECT COUNT(*) FROM table3_no_encryption; +DROP TABLE table1_no_encryption, table2_to_encrypt, table3_no_encryption; + +--save_master_pos + +--connection server_2 +--sync_with_master + +--disable_connect_log +--source include/rpl_end.inc diff --git a/mysql-test/suite/binlog_encryption/grep_binlog.inc b/mysql-test/suite/binlog_encryption/grep_binlog.inc new file mode 100644 index 0000000..378ae56 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/grep_binlog.inc @@ -0,0 +1,54 @@ +# +# This include file checks whether the given pattern is present +# in the given binary log(s) +# The search logic returns 0 if no occurrences are found, +# and 1 otherwise. +# The result can be reverted depending on search_result configured +# in the outer test. +# +# Usage: +# --let search_files= filename | filename_prefix* +# --let search_pattern= <search pattern> (default '_to_encrypt') +# --let search_result= 0|1 (default 0, which means "should not be found") +# --source grep_binlog.inc + +if (! $search_result) +{ + --let search_result= 0 +} +if (! $search_pattern) +{ + --let search_pattern= _to_encrypt +} +--let datadir= `SELECT @@datadir` + +--echo # +--echo # The next step will cause a perl error if the search does not +--echo # meet the expectations. +--echo # Pattern to look for: $search_pattern +--echo # Files to search: $search_files +--echo # Expected result: $search_result +--echo # (0 means the pattern should not be found, 1 means it should be found) +--echo # + +--error $search_result +perl; + $|= 1; + use strict; + use warnings; + my @content= (); + my @fnames= glob("$ENV{datadir}/$ENV{search_files}"); + if (not scalar(@fnames)) { + die "File pattern $ENV{search_files} must be wrong, no files found\n"; + } + foreach my $f (@fnames) { + open(FILE, "<", $f) or die "Could not open file $f: $!\n"; + @content= (@content, grep(/$ENV{search_pattern}/, <FILE>)); + close FILE; + } + print( (scalar(@content) ? "Found" : "Did not find any"). " occurrences of '$ENV{search_pattern}' in $ENV{search_files}\n"); + exit (scalar(@content) ? 1 : 0); +EOF + +# Unset the mandatory option +--let search_files= diff --git a/mysql-test/suite/binlog_encryption/master_switch_to_unencrypted.cnf b/mysql-test/suite/binlog_encryption/master_switch_to_unencrypted.cnf new file mode 100644 index 0000000..1cbb6cf --- /dev/null +++ b/mysql-test/suite/binlog_encryption/master_switch_to_unencrypted.cnf @@ -0,0 +1,4 @@ +!include my.cnf + +[mysqld.1] +encrypt-binlog=0 diff --git a/mysql-test/suite/binlog_encryption/multisource.cnf b/mysql-test/suite/binlog_encryption/multisource.cnf new file mode 100644 index 0000000..52db51d --- /dev/null +++ b/mysql-test/suite/binlog_encryption/multisource.cnf @@ -0,0 +1,17 @@ +!include my.cnf + +[mysqld.1] +log-bin=master-bin + +[mysqld.2] +log-bin=master-bin + +[mysqld.3] +innodb +log-bin=slave-bin +server-id=3 +log-warnings=2 + +[ENV] +SERVER_MYPORT_3= @mysqld.3.port +SERVER_MYSOCK_3= @mysqld.3.socket diff --git a/mysql-test/suite/binlog_encryption/multisource.result b/mysql-test/suite/binlog_encryption/multisource.result new file mode 100644 index 0000000..d99a377 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/multisource.result @@ -0,0 +1,228 @@ +connect slave,127.0.0.1,root,,,$SERVER_MYPORT_3; +change master 'abc' to relay_log_file=''; +ERROR HY000: Failed initializing relay log position: Could not find target log during relay log initialization +change master 'abc2' to master_host=''; +ERROR HY000: Incorrect arguments to MASTER_HOST +change master 'master1' to +master_port=MYPORT_1, +master_host='127.0.0.1', +master_user='root'; +start slave 'master1'; +set default_master_connection = 'master1'; +include/wait_for_slave_to_start.inc +connect master1,127.0.0.1,root,,,$SERVER_MYPORT_1; +connection slave; +# +# Checking SHOW SLAVE 'master1' STATUS +# +Master_Port = 'MYPORT_1' +Relay_Log_File = 'mysqld-relay-bin-master1.000002' +Slave_IO_Running = 'Yes' +Slave_SQL_Running = 'Yes' +Last_Errno = '0' +Last_SQL_Errno = '0' +# +# Checking SHOW SLAVE STATUS +# +Master_Port = 'MYPORT_1' +Relay_Log_File = 'mysqld-relay-bin-master1.000002' +Slave_IO_Running = 'Yes' +Slave_SQL_Running = 'Yes' +Last_Errno = '0' +Last_SQL_Errno = '0' +# +# Checking SHOW ALL SLAVES STATUS +# +Connection_name = 'master1' +Master_Port = 'MYPORT_1' +Relay_Log_File = 'mysqld-relay-bin-master1.000002' +Slave_IO_Running = 'Yes' +Slave_SQL_Running = 'Yes' +Last_Errno = '0' +Last_SQL_Errno = '0' +Slave_heartbeat_period = '60.000' +# +connection master1; +drop database if exists db1; +create database db1; +use db1; +create table t1 (i int auto_increment, f1 varchar(16), primary key pk (i,f1)) engine=MyISAM; +insert into t1 (f1) values ('one'),('two'); +connection slave; +select * from db1.t1; +i f1 +1 one +2 two +# List of relay log files in the datadir +mysqld-relay-bin-master1.000001 +mysqld-relay-bin-master1.000002 +mysqld-relay-bin-master1.index +include/show_events.inc +Log_name Pos Event_type Server_id End_log_pos Info +mysqld-relay-bin-master1.000001 # Format_desc # # SERVER_VERSION, BINLOG_VERSION +mysqld-relay-bin-master1.000001 # Rotate # # mysqld-relay-bin-master1.000002;pos=4 +include/show_events.inc +Log_name Pos Event_type Server_id End_log_pos Info +mysqld-relay-bin-master1.000002 # Format_desc # # SERVER_VERSION, BINLOG_VERSION +mysqld-relay-bin-master1.000002 # Rotate # # master-bin.000001;pos=POS +mysqld-relay-bin-master1.000002 # Format_desc # # SERVER_VERSION, BINLOG_VERSION +mysqld-relay-bin-master1.000002 # Gtid_list # # [] +mysqld-relay-bin-master1.000002 # Binlog_checkpoint # # master-bin.000001 +mysqld-relay-bin-master1.000002 # Gtid # # GTID #-#-# +mysqld-relay-bin-master1.000002 # Query # # drop database if exists db1 +mysqld-relay-bin-master1.000002 # Gtid # # GTID #-#-# +mysqld-relay-bin-master1.000002 # Query # # create database db1 +mysqld-relay-bin-master1.000002 # Gtid # # GTID #-#-# +mysqld-relay-bin-master1.000002 # Query # # use `db1`; create table t1 (i int auto_increment, f1 varchar(16), primary key pk (i,f1)) engine=MyISAM +mysqld-relay-bin-master1.000002 # Gtid # # BEGIN GTID #-#-# +mysqld-relay-bin-master1.000002 # Intvar # # INSERT_ID=1 +mysqld-relay-bin-master1.000002 # Query # # use `db1`; insert into t1 (f1) values ('one'),('two') +mysqld-relay-bin-master1.000002 # Query # # COMMIT +change master 'master1' to +master_port=MYPORT_2, +master_host='127.0.0.1', +master_user='root'; +ERROR HY000: This operation cannot be performed as you have a running slave 'master1'; run STOP SLAVE 'master1' first +change master to +master_port=MYPORT_2, +master_host='127.0.0.1', +master_user='root'; +ERROR HY000: This operation cannot be performed as you have a running slave 'master1'; run STOP SLAVE 'master1' first +change master 'master2' to +master_port=MYPORT_1, +master_host='127.0.0.1', +master_user='root'; +ERROR HY000: Connection 'master2' conflicts with existing connection 'master1' +set default_master_connection = ''; +change master to +master_port=MYPORT_2, +master_host='127.0.0.1', +master_user='root'; +start slave; +include/wait_for_slave_to_start.inc +# +# Checking SHOW ALL SLAVES STATUS +# +Connection_name = '' +Connection_name = 'master1' +Master_Port = 'MYPORT_2' +Master_Port = 'MYPORT_1' +Relay_Log_File = 'mysqld-relay-bin.000002' +Relay_Log_File = 'mysqld-relay-bin-master1.000002' +Slave_IO_Running = 'Yes' +Slave_IO_Running = 'Yes' +Slave_SQL_Running = 'Yes' +Slave_SQL_Running = 'Yes' +Last_Errno = '0' +Last_Errno = '0' +Last_SQL_Errno = '0' +Last_SQL_Errno = '0' +Slave_heartbeat_period = '60.000' +Slave_heartbeat_period = '60.000' +# +connection master1; +insert into t1 (f1) values ('three'); +connect master2,127.0.0.1,root,,,$SERVER_MYPORT_2; +drop database if exists db2; +create database db2; +use db2; +create table t1 (pk int auto_increment primary key, f1 int) engine=InnoDB; +begin; +insert into t1 (f1) values (1),(2); +connection slave; +connection master2; +connection slave; +select * from db1.t1; +i f1 +1 one +2 two +3 three +select * from db2.t1; +pk f1 +connection master2; +commit; +connection slave; +select * from db2.t1; +pk f1 +1 1 +2 2 +connection master1; +flush logs; +connection slave; +connection master1; +purge binary logs to 'master-bin.000002'; +show binary logs; +Log_name File_size +master-bin.000002 filesize +insert into t1 (f1) values ('four'); +create table db1.t3 (f1 int) engine=InnoDB; +connection slave; +# +# Checking SHOW ALL SLAVES STATUS +# +Connection_name = '' +Connection_name = 'master1' +Master_Port = 'MYPORT_2' +Master_Port = 'MYPORT_1' +Relay_Log_File = 'mysqld-relay-bin.000002' +Relay_Log_File = 'mysqld-relay-bin-master1.000004' +Slave_IO_Running = 'Yes' +Slave_IO_Running = 'Yes' +Slave_SQL_Running = 'Yes' +Slave_SQL_Running = 'Yes' +Last_Errno = '0' +Last_Errno = '0' +Last_SQL_Errno = '0' +Last_SQL_Errno = '0' +Slave_heartbeat_period = '60.000' +Slave_heartbeat_period = '60.000' +# +select * from db1.t1; +i f1 +1 one +2 two +3 three +4 four +include/show_events.inc +Log_name Pos Event_type Server_id End_log_pos Info +mysqld-relay-bin.000001 # Format_desc # # SERVER_VERSION, BINLOG_VERSION +mysqld-relay-bin.000001 # Rotate # # mysqld-relay-bin.000002;pos=4 +include/show_events.inc +Log_name Pos Event_type Server_id End_log_pos Info +mysqld-relay-bin.000002 # Format_desc # # SERVER_VERSION, BINLOG_VERSION +mysqld-relay-bin.000002 # Rotate # # master-bin.000001;pos=POS +mysqld-relay-bin.000002 # Format_desc # # SERVER_VERSION, BINLOG_VERSION +mysqld-relay-bin.000002 # Gtid_list # # [] +mysqld-relay-bin.000002 # Binlog_checkpoint # # master-bin.000001 +mysqld-relay-bin.000002 # Gtid # # GTID #-#-# +mysqld-relay-bin.000002 # Query # # drop database if exists db2 +mysqld-relay-bin.000002 # Gtid # # GTID #-#-# +mysqld-relay-bin.000002 # Query # # create database db2 +mysqld-relay-bin.000002 # Gtid # # GTID #-#-# +mysqld-relay-bin.000002 # Query # # use `db2`; create table t1 (pk int auto_increment primary key, f1 int) engine=InnoDB +mysqld-relay-bin.000002 # Gtid # # BEGIN GTID #-#-# +mysqld-relay-bin.000002 # Intvar # # INSERT_ID=1 +mysqld-relay-bin.000002 # Query # # use `db2`; insert into t1 (f1) values (1),(2) +mysqld-relay-bin.000002 # Xid # # COMMIT /* XID */ +disconnect slave; +connect slave,127.0.0.1,root,,,$SERVER_MYPORT_3; +stop slave io_thread; +show status like 'Slave_running'; +Variable_name Value +Slave_running OFF +set default_master_connection = 'master1'; +show status like 'Slave_running'; +Variable_name Value +Slave_running ON +drop database db1; +drop database db2; +include/reset_master_slave.inc +disconnect slave; +connection master1; +drop database db1; +include/reset_master_slave.inc +disconnect master1; +connection master2; +drop database db2; +include/reset_master_slave.inc +disconnect master2; diff --git a/mysql-test/suite/binlog_encryption/multisource.test b/mysql-test/suite/binlog_encryption/multisource.test new file mode 100644 index 0000000..28ad114 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/multisource.test @@ -0,0 +1,335 @@ +# +# The test was taken from the multi_source suite, with some minor changes. +# The purpose is to check that a slave can replicate from an encrypted +# and non-encrypted master simultaneously. In the test, server_1 is +# encrypted, and server_2 is not +# + +# +# Test basic replication functionality +# in multi-source setup +# + +--source include/not_embedded.inc +--source include/binlog_start_pos.inc +--let $rpl_server_count= 0 + +--enable_connect_log + +--connect (slave,127.0.0.1,root,,,$SERVER_MYPORT_3) + +# MDEV-3984: crash/read of freed memory when changing master with named connection +# This fails after adding the new master 'abc', check we do not free twice. +--error ER_RELAY_LOG_INIT +change master 'abc' to relay_log_file=''; +# This fails before adding the new master, check that we do free it. +--error ER_WRONG_ARGUMENTS +change master 'abc2' to master_host=''; + + +# Start replication from the first master + +--replace_result $SERVER_MYPORT_1 MYPORT_1 +eval change master 'master1' to +master_port=$SERVER_MYPORT_1, +master_host='127.0.0.1', +master_user='root'; + +start slave 'master1'; +set default_master_connection = 'master1'; +--disable_connect_log +--source include/wait_for_slave_to_start.inc +--enable_connect_log + +--connect (master1,127.0.0.1,root,,,$SERVER_MYPORT_1) +--save_master_pos + +--connection slave +--sync_with_master 0,'master1' + +# Here and further: add an extra check on SQL thread status +# as the normal sync is not always enough +--disable_connect_log +--source suite/multi_source/wait_for_sql_thread_read_all.inc +--enable_connect_log + +# each of the 3 commands should produce +# 'master1' status + +let $wait_for_all= 1; +let $show_statement= SHOW ALL SLAVES STATUS; +let $field= Slave_IO_State; +let $condition= = 'Waiting for master to send event'; +--disable_connect_log +--source include/wait_show_condition.inc +--enable_connect_log + +--echo # +--echo # Checking SHOW SLAVE 'master1' STATUS +--echo # +--let $status_items= Master_Port, Relay_Log_File, Slave_IO_Running, Slave_SQL_Running, Last_Errno, Last_SQL_Errno +--let $slave_field_result_replace= /$SERVER_MYPORT_1/MYPORT_1/ +--let $slave_name= 'master1' +--disable_connect_log +--source include/show_slave_status.inc +--enable_connect_log +--let $slave_name= + +--echo # +--echo # Checking SHOW SLAVE STATUS +--echo # +--disable_connect_log +--source include/show_slave_status.inc +--enable_connect_log + +--echo # +--echo # Checking SHOW ALL SLAVES STATUS +--echo # +--let $all_slaves_status= 1 +--let $status_items= Connection_name, Master_Port, Relay_Log_File, Slave_IO_Running, Slave_SQL_Running, Last_Errno, Last_SQL_Errno, Slave_heartbeat_period +--disable_connect_log +--source include/show_slave_status.inc +--enable_connect_log +--let $all_slaves_status= +--echo # + + +# Check that replication actually works + +--connection master1 + +--disable_warnings +drop database if exists db1; +--enable_warnings +create database db1; +use db1; +create table t1 (i int auto_increment, f1 varchar(16), primary key pk (i,f1)) engine=MyISAM; +insert into t1 (f1) values ('one'),('two'); +--save_master_pos + +--connection slave +--sync_with_master 0,'master1' + +--sorted_result +select * from db1.t1; + +--let $datadir = `SELECT @@datadir` + +--echo # List of relay log files in the datadir +--list_files $datadir mysqld-relay-bin-master1.* + +# Check that relay logs are recognizable + +let binlog_start=4; +let binlog_file=; +--disable_connect_log +source include/show_relaylog_events.inc; +let binlog_file= mysqld-relay-bin-master1.000002; +source include/show_relaylog_events.inc; +--enable_connect_log + +# Try to configure connection with the same name again, +# should get an error because the slave is running + +--replace_result $SERVER_MYPORT_2 MYPORT_2 +--error ER_SLAVE_MUST_STOP +eval change master 'master1' to +master_port=$SERVER_MYPORT_2, +master_host='127.0.0.1', +master_user='root'; + +# Try to configure using the default connection name +# (which is 'master1' at the moment), +# again, should get an error + +--replace_result $SERVER_MYPORT_2 MYPORT_2 +--error ER_SLAVE_MUST_STOP +eval change master to +master_port=$SERVER_MYPORT_2, +master_host='127.0.0.1', +master_user='root'; + +# Try to configure a connection with the same master +# using a different name, should get a conflict + +--replace_result $SERVER_MYPORT_1 MYPORT_1 +--error ER_CONNECTION_ALREADY_EXISTS +eval change master 'master2' to +master_port=$SERVER_MYPORT_1, +master_host='127.0.0.1', +master_user='root'; + + +# Set up a proper 'default' connection to master2 + +set default_master_connection = ''; + +--replace_result $SERVER_MYPORT_2 MYPORT_2 +eval change master to +master_port=$SERVER_MYPORT_2, +master_host='127.0.0.1', +master_user='root'; + +start slave; +--disable_connect_log +--source include/wait_for_slave_to_start.inc + +--source suite/multi_source/wait_for_sql_thread_read_all.inc +--enable_connect_log + +# See both connections in the same status output + +let $wait_for_all= 1; +let $show_statement= SHOW ALL SLAVES STATUS; +let $field= Slave_IO_State; +let $condition= = 'Waiting for master to send event'; +--disable_connect_log +--source include/wait_show_condition.inc +--enable_connect_log + +--echo # +--echo # Checking SHOW ALL SLAVES STATUS +--echo # +--let $all_slaves_status= 1 +--let $status_items= Connection_name, Master_Port, Relay_Log_File, Slave_IO_Running, Slave_SQL_Running, Last_Errno, Last_SQL_Errno, Slave_heartbeat_period +--let $slave_field_result_replace= /$SERVER_MYPORT_1/MYPORT_1/ /$SERVER_MYPORT_2/MYPORT_2/ +--disable_connect_log +--source include/show_slave_status.inc +--enable_connect_log +--let $all_slaves_status= +--echo # + +# Check that replication from two servers actually works + +--connection master1 + +insert into t1 (f1) values ('three'); +--save_master_pos + +--connect (master2,127.0.0.1,root,,,$SERVER_MYPORT_2) + +--disable_warnings +drop database if exists db2; +--enable_warnings +create database db2; +use db2; +create table t1 (pk int auto_increment primary key, f1 int) engine=InnoDB; +begin; +insert into t1 (f1) values (1),(2); + +--connection slave +--sync_with_master 0,'master1' + +--connection master2 +--save_master_pos + +--connection slave +--sync_with_master 0 +--sorted_result +select * from db1.t1; +select * from db2.t1; + +--connection master2 +commit; +--save_master_pos + +--connection slave +--sync_with_master 0 +--sorted_result +select * from db2.t1; + +# Flush and purge logs on one master, +# make sure slaves don't get confused + +--connection master1 +flush logs; +--disable_connect_log +--source include/wait_for_binlog_checkpoint.inc +--enable_connect_log +--save_master_pos +--connection slave +--sync_with_master 0, 'master1' + +--connection master1 +purge binary logs to 'master-bin.000002'; +let filesize=`select $binlog_start_pos+119+36`; +--replace_result $filesize filesize +show binary logs; +insert into t1 (f1) values ('four'); +create table db1.t3 (f1 int) engine=InnoDB; +--save_master_pos + +--connection slave +--sync_with_master 0,'master1' + +--disable_connect_log +--source suite/multi_source/wait_for_sql_thread_read_all.inc +--enable_connect_log + +let $wait_for_all= 1; +let $show_statement= SHOW ALL SLAVES STATUS; +let $field= Slave_IO_State; +let $condition= = 'Waiting for master to send event'; +--disable_connect_log +--source include/wait_show_condition.inc +--enable_connect_log + +--echo # +--echo # Checking SHOW ALL SLAVES STATUS +--echo # +--let $all_slaves_status= 1 +--let $status_items= Connection_name, Master_Port, Relay_Log_File, Slave_IO_Running, Slave_SQL_Running, Last_Errno, Last_SQL_Errno, Slave_heartbeat_period +--let $slave_field_result_replace= /$SERVER_MYPORT_1/MYPORT_1/ /$SERVER_MYPORT_2/MYPORT_2/ +--disable_connect_log +--source include/show_slave_status.inc +--enable_connect_log +--let $all_slaves_status= +--echo # + +--sorted_result +select * from db1.t1; + +# This should show relay log events for the default master +# (the one with the empty name) +let binlog_file=; +--disable_connect_log +source include/show_relaylog_events.inc; +let binlog_file= mysqld-relay-bin.000002; +source include/show_relaylog_events.inc; +--enable_connect_log + +# Make sure we don't lose control over replication connections +# after reconnecting to the slave + +--disconnect slave +--connect (slave,127.0.0.1,root,,,$SERVER_MYPORT_3) + +stop slave io_thread; +show status like 'Slave_running'; +set default_master_connection = 'master1'; +show status like 'Slave_running'; + +# Cleanup + +drop database db1; +drop database db2; + +--disable_connect_log +--source suite/multi_source/reset_master_slave.inc +--enable_connect_log +--disconnect slave + +--connection master1 +drop database db1; +--disable_connect_log +--source suite/multi_source/reset_master_slave.inc +--enable_connect_log +--disconnect master1 + +--connection master2 +drop database db2; +--disable_connect_log +--source suite/multi_source/reset_master_slave.inc +--enable_connect_log +--disconnect master2 + diff --git a/mysql-test/suite/binlog_encryption/my.cnf b/mysql-test/suite/binlog_encryption/my.cnf new file mode 100644 index 0000000..d787ebe --- /dev/null +++ b/mysql-test/suite/binlog_encryption/my.cnf @@ -0,0 +1,27 @@ +!include include/default_mysqld.cnf +!include include/default_client.cnf + +[mysqld.1] +innodb +plugin-load-add= @ENV.FILE_KEY_MANAGEMENT_SO +loose-file-key-management-filename= @ENV.MYSQLTEST_VARDIR/std_data/keys.txt +encrypt-binlog +log-basename= master + +[mysqld.2] +#!use-slave-opt +innodb +log-slave-updates +log-basename= slave + +[ENV] + +# We will adopt tests with master-slave setup as well as rpl_init setup, +# so need both sets of variables +MASTER_MYPORT= @mysqld.1.port +SERVER_MYPORT_1= @mysqld.1.port +SERVER_MYSOCK_1= @mysqld.1.socket + +SLAVE_MYPORT= @mysqld.2.port +SERVER_MYPORT_2= @mysqld.2.port +SERVER_MYSOCK_2= @mysqld.2.socket diff --git a/mysql-test/suite/binlog_encryption/restart_server.inc b/mysql-test/suite/binlog_encryption/restart_server.inc new file mode 100644 index 0000000..6cd0788 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/restart_server.inc @@ -0,0 +1,35 @@ +# +# We can not use the common include/restart_mysqld.inc or include/rpl_restart_server.inc, +# because they have hardcoded connection names (master, master1) +# which are not initiated by rpl_init.inc. +# This is the relevant and simplified part of the same set of scripts. +# +# ==== Usage ==== +# +# --let $rpl_server_number= N +# Number to identify the server that needs to reconnect. +# 1 is the master server, 2 the slave server +# [--let $rpl_server_parameters= --flag1 --flag2 ...] +# --source restart_server.inc +# + +--let $_cur_con= $CURRENT_CONNECTION + +--connection default +--enable_reconnect + +--connection $_cur_con +--enable_reconnect +--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.$rpl_server_number.expect + +shutdown_server 10; + +--source include/wait_until_disconnected.inc + +--let $_rpl_start_server_command= restart +if ($rpl_server_parameters) +{ + --let $_rpl_start_server_command= restart:$rpl_server_parameters +} +--exec echo "$_rpl_start_server_command" > $MYSQLTEST_VARDIR/tmp/mysqld.$rpl_server_number.expect +--source include/wait_until_connected_again.inc diff --git a/mysql-test/suite/binlog_encryption/rpl_binlog_errors.cnf b/mysql-test/suite/binlog_encryption/rpl_binlog_errors.cnf new file mode 100644 index 0000000..2d3db66 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_binlog_errors.cnf @@ -0,0 +1,7 @@ +!include my.cnf + +[mysqld.1] +max_binlog_size=4096 + +[mysqld.2] +skip-slave-start diff --git a/mysql-test/suite/binlog_encryption/rpl_binlog_errors.result b/mysql-test/suite/binlog_encryption/rpl_binlog_errors.result new file mode 100644 index 0000000..6c111ee --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_binlog_errors.result @@ -0,0 +1,280 @@ +include/master-slave.inc +[connection master] +####################################################################### +####################### PART 1: MASTER TESTS ########################## +####################################################################### +connection slave; +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; +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_dbug="+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_dbug=@old_debug; +RESET MASTER; +###################### TEST #3 +CREATE TABLE t1 (a INT); +CREATE TABLE t2 (a VARCHAR(16384)) Engine=InnoDB; +CREATE TABLE t4 (a VARCHAR(16384)); +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_dbug=@old_debug; +DELETE FROM t2; +RESET MASTER; +###################### TEST #4 +SET GLOBAL debug_dbug="+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_dbug=@old_debug; +DELETE FROM t2; +RESET MASTER; +###################### TEST #5 +SET GLOBAL debug_dbug="+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_dbug=@old_debug; +DELETE FROM t2; +RESET MASTER; +###################### TEST #6 +SET GLOBAL debug_dbug="+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_dbug=@old_debug; +DELETE FROM t2; +RESET MASTER; +###################### TEST #7 +SET GLOBAL debug_dbug="+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_dbug=@old_debug; +include/show_binlog_events.inc +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Incident # # #1 (LOST_EVENTS) +DELETE FROM t4; +RESET MASTER; +###################### TEST #8 +SET GLOBAL debug_dbug="+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_dbug=@old_debug; +###################### TEST #9 +SET GLOBAL debug_dbug="+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_dbug=@old_debug; +###################### 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_dbug="+d,fault_injection_registering_index"; +FLUSH LOGS; +ERROR HY000: Can't open file: 'master-bin.000002' (errno: 1 "Operation not permitted") +SET GLOBAL debug_dbug="-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 +include/rpl_restart_server.inc [server_number=1] +SET GLOBAL debug_dbug="+d,fault_injection_openning_index"; +FLUSH LOGS; +ERROR HY000: Can't open file: 'master-bin.index' (errno: 1 "Operation not permitted") +SET GLOBAL debug_dbug="-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; +include/rpl_restart_server.inc [server_number=1] +###################### TEST #12 +SET GLOBAL debug_dbug="+d,fault_injection_new_file_rotate_event"; +FLUSH LOGS; +ERROR HY000: Can't open file: 'master-bin' (errno: 2 "No such file or directory") +SET GLOBAL debug_dbug="-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; +include/rpl_restart_server.inc [server_number=1] +DROP TABLE t1, t2, t4; +RESET MASTER; +connection slave; +include/start_slave.inc +connection master; +####################################################################### +####################### PART 2: SLAVE TESTS ########################### +####################################################################### +include/rpl_reset.inc +connection 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_dbug="+d,error_unique_log_filename"; +START SLAVE io_thread; +include/wait_for_slave_io_error.inc [errno=1595] +Last_IO_Error = 'Relay log write failure: could not queue event from master' +SET GLOBAL debug_dbug="-d,error_unique_log_filename"; +SET GLOBAL debug_dbug=@old_debug; +include/rpl_restart_server.inc [server_number=2] +###################### TEST #14 +SET @old_debug=@@global.debug; +include/stop_slave.inc +SET GLOBAL debug_dbug="+d,fault_injection_new_file_rotate_event"; +START SLAVE io_thread; +include/wait_for_slave_io_error.inc [errno=1595] +Last_IO_Error = 'Relay log write failure: could not queue event from master' +SET GLOBAL debug_dbug="-d,fault_injection_new_file_rotate_event"; +SET GLOBAL debug_dbug=@old_debug; +include/rpl_restart_server.inc [server_number=2] +###################### TEST #15 +SET @old_debug=@@global.debug; +include/stop_slave.inc +SET GLOBAL debug_dbug="+d,fault_injection_registering_index"; +START SLAVE io_thread; +include/wait_for_slave_io_error.inc [errno=1595] +Last_IO_Error = 'Relay log write failure: could not queue event from master' +SET GLOBAL debug_dbug="-d,fault_injection_registering_index"; +SET GLOBAL debug_dbug=@old_debug; +include/rpl_restart_server.inc [server_number=2] +###################### TEST #16 +SET @old_debug=@@global.debug; +include/stop_slave.inc +SET GLOBAL debug_dbug="+d,fault_injection_openning_index"; +START SLAVE io_thread; +include/wait_for_slave_io_error.inc [errno=1595] +Last_IO_Error = 'Relay log write failure: could not queue event from master' +SET GLOBAL debug_dbug="-d,fault_injection_openning_index"; +SET GLOBAL debug_dbug=@old_debug; +include/rpl_restart_server.inc [server_number=2] +include/stop_slave_sql.inc +Warnings: +Note 1255 Slave already has been stopped +RESET SLAVE; +RESET MASTER; +include/rpl_end.inc diff --git a/mysql-test/suite/binlog_encryption/rpl_binlog_errors.test b/mysql-test/suite/binlog_encryption/rpl_binlog_errors.test new file mode 100644 index 0000000..b830652 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_binlog_errors.test @@ -0,0 +1,439 @@ +# +# The test was taken from the rpl suite as is +# + +# 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/have_debug.inc +-- source include/master-slave.inc + +--enable_connect_log + +-- echo ####################################################################### +-- echo ####################### PART 1: MASTER TESTS ########################## +-- echo ####################################################################### + + +### ACTION: stopping slave as it is not needed for the first part of +### the test + +-- connection slave +--disable_connect_log +-- source include/stop_slave.inc +--enable_connect_log +-- 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 +--disable_connect_log +-- source include/show_binary_logs.inc +--enable_connect_log + +-- 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_dbug="+d,error_unique_log_filename"; +-- error ER_NO_UNIQUE_LOGFILE +FLUSH LOGS; +-- echo # assert: must show one binlog +--disable_connect_log +-- source include/show_binary_logs.inc +--enable_connect_log + +### ACTION: clean up and move to next test +SET GLOBAL debug_dbug=@old_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 VARCHAR(16384)) Engine=InnoDB; +CREATE TABLE t4 (a VARCHAR(16384)); +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 +--disable_connect_log +-- source include/show_binary_logs.inc +--enable_connect_log + +# clean up the table and the binlog to be used in next part of test +SET GLOBAL debug_dbug=@old_debug; +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_dbug="+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_dbug=@old_debug; +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_dbug="+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_dbug=@old_debug; +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_dbug="+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_dbug=@old_debug; +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_dbug="+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_dbug=@old_debug; +-- let $binlog_limit= 5,1 +--disable_connect_log +-- source include/show_binlog_events.inc +--enable_connect_log + +# 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_dbug="+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_dbug=@old_debug; + +-- echo ###################### TEST #9 + +### ASSERTION: check that if we disable binlogging, then statements +### succeed. +SET GLOBAL debug_dbug="+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_dbug=@old_debug; + +-- 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_dbug="+d,fault_injection_registering_index"; +-- replace_regex /\.[\\\/]master/master/ +-- error ER_CANT_OPEN_FILE +FLUSH LOGS; +SET GLOBAL debug_dbug="-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 +--let $rpl_server_number= 1 +--disable_connect_log +--source include/rpl_restart_server.inc +--enable_connect_log + +# +d,fault_injection_openning_index => injects fault on MYSQL_BIN_LOG::open_index_file +SET GLOBAL debug_dbug="+d,fault_injection_openning_index"; +-- replace_regex /\.[\\\/]master/master/ +-- error ER_CANT_OPEN_FILE +FLUSH LOGS; +SET GLOBAL debug_dbug="-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 +--let $rpl_server_number= 1 +--disable_connect_log +--source include/rpl_restart_server.inc +--enable_connect_log + +-- 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_dbug="+d,fault_injection_new_file_rotate_event"; +-- error ER_ERROR_ON_WRITE +FLUSH LOGS; +SET GLOBAL debug_dbug="-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 +--let $rpl_server_number= 1 +--disable_connect_log +--source include/rpl_restart_server.inc +--enable_connect_log + +## clean up +DROP TABLE t1, t2, t4; +RESET MASTER; + +# restart slave again +-- connection slave +--disable_connect_log +-- source include/start_slave.inc +--enable_connect_log +-- connection master + +-- echo ####################################################################### +-- echo ####################### PART 2: SLAVE TESTS ########################### +-- echo ####################################################################### + +### setup +--disable_connect_log +--source include/rpl_reset.inc +--enable_connect_log +-- 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 +--disable_connect_log +-- source include/io_thd_fault_injection.inc +--enable_connect_log + +-- 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 +--disable_connect_log +-- source include/io_thd_fault_injection.inc +--enable_connect_log + +-- 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 +--disable_connect_log +-- source include/io_thd_fault_injection.inc +--enable_connect_log + +-- 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 +--disable_connect_log +-- source include/io_thd_fault_injection.inc +--enable_connect_log + +### clean up +--disable_connect_log +-- source include/stop_slave_sql.inc +--enable_connect_log +RESET SLAVE; +RESET MASTER; +--let $rpl_only_running_threads= 1 +--disable_connect_log +--source include/rpl_end.inc diff --git a/mysql-test/suite/binlog_encryption/rpl_cant_read_event_incident.result b/mysql-test/suite/binlog_encryption/rpl_cant_read_event_incident.result new file mode 100644 index 0000000..5aff978 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_cant_read_event_incident.result @@ -0,0 +1,26 @@ +include/master-slave.inc +[connection master] +connection slave; +include/stop_slave.inc +connection master; +call mtr.add_suppression("Error in Log_event::read_log_event()"); +include/rpl_stop_server.inc [server_number=1] +include/rpl_start_server.inc [server_number=1] +show binlog events; +ERROR HY000: Error when executing command SHOW BINLOG EVENTS: Wrong offset or I/O error +connection slave; +call mtr.add_suppression("Slave I/O: Got fatal error 1236 from master when reading data from binary log"); +reset slave; +start slave; +include/wait_for_slave_param.inc [Last_IO_Errno] +Last_IO_Errno = '1236' +Last_IO_Error = 'Got fatal error 1236 from master when reading data from binary log: 'binlog truncated in the middle of event; consider out of disk space on master; the first event '.' at XXX, the last event read from 'master-bin.000001' at XXX, the last byte read from 'master-bin.000001' at XXX.'' +connection master; +reset master; +connection slave; +stop slave; +reset slave; +drop table if exists t; +reset master; +End of the tests +include/rpl_end.inc diff --git a/mysql-test/suite/binlog_encryption/rpl_cant_read_event_incident.test b/mysql-test/suite/binlog_encryption/rpl_cant_read_event_incident.test new file mode 100644 index 0000000..5aa70b8 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_cant_read_event_incident.test @@ -0,0 +1,92 @@ +# +# The test was taken from the rpl suite as is +# + +# +# Bug#11747416 : 32228 A disk full makes binary log corrupt. +# +# +# The test demonstrates reading from binlog error propagation to slave +# and reporting there. +# Conditions for the bug include a crash at time of the last event to +# the binlog was written partly. With the fixes the event is not sent out +# any longer, but rather the dump thread sends out a sound error message. +# +# Crash is not simulated. A binlog with partly written event in its end is installed +# and replication is started from it. +# + +--source include/master-slave.inc +--source include/have_binlog_format_mixed.inc + +--enable_connect_log + +--connection slave +# Make sure the slave is stopped while we are messing with master. +# Otherwise we get occasional failures as the slave manages to re-connect +# to the newly started master and we get extra events applied, causing +# conflicts. +--disable_connect_log +--source include/stop_slave.inc +--enable_connect_log + +--connection master +call mtr.add_suppression("Error in Log_event::read_log_event()"); +--let $datadir= `SELECT @@datadir` + +--let $rpl_server_number= 1 +--disable_connect_log +--source include/rpl_stop_server.inc +--enable_connect_log + +--remove_file $datadir/master-bin.000001 +--copy_file $MYSQL_TEST_DIR/std_data/bug11747416_32228_binlog.000001 $datadir/master-bin.000001 + +--let $rpl_server_number= 1 +--disable_connect_log +--source include/rpl_start_server.inc + +--source include/wait_until_connected_again.inc +--enable_connect_log + +# evidence of the partial binlog +--error ER_ERROR_WHEN_EXECUTING_COMMAND +show binlog events; + +--connection slave +call mtr.add_suppression("Slave I/O: Got fatal error 1236 from master when reading data from binary log"); +reset slave; +start slave; + +# ER_MASTER_FATAL_ERROR_READING_BINLOG 1236 +--let $slave_param=Last_IO_Errno +--let $slave_param_value=1236 +--disable_connect_log +--source include/wait_for_slave_param.inc + +--let $slave_field_result_replace= / at [0-9]*/ at XXX/ +--let $status_items= Last_IO_Errno, Last_IO_Error +--source include/show_slave_status.inc +--enable_connect_log + +# +# Cleanup +# + +--connection master +reset master; + +--connection slave +stop slave; +reset slave; +# Table was created from binlog, it may not be created if SQL thread is running +# slowly and IO thread reaches incident before SQL thread applies it. +--disable_warnings +drop table if exists t; +--enable_warnings +reset master; + +--echo End of the tests +--let $rpl_only_running_threads= 1 +--disable_connect_log +--source include/rpl_end.inc diff --git a/mysql-test/suite/binlog_encryption/rpl_checksum.cnf b/mysql-test/suite/binlog_encryption/rpl_checksum.cnf new file mode 100644 index 0000000..9d7ada8 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_checksum.cnf @@ -0,0 +1,10 @@ +!include my.cnf + +[mysqld.1] +binlog-checksum=CRC32 + +[mysqld.2] +binlog-checksum=CRC32 +plugin-load-add= @ENV.FILE_KEY_MANAGEMENT_SO +loose-file-key-management-filename=@ENV.MYSQLTEST_VARDIR/std_data/keys.txt +encrypt-binlog diff --git a/mysql-test/suite/binlog_encryption/rpl_checksum.result b/mysql-test/suite/binlog_encryption/rpl_checksum.result new file mode 100644 index 0000000..1ba9ff8 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_checksum.result @@ -0,0 +1,157 @@ +include/master-slave.inc +[connection master] +call mtr.add_suppression('Slave can not handle replication events with the checksum that master is configured to log'); +call mtr.add_suppression('Replication event checksum verification failed'); +call mtr.add_suppression('Relay log write failure: could not queue event from master'); +call mtr.add_suppression('Master is configured to log replication events with checksum, but will not send such events to slaves that cannot process them'); +connection slave; +set @save_slave_sql_verify_checksum = @@global.slave_sql_verify_checksum; +connection master; +set @save_master_verify_checksum = @@global.master_verify_checksum; +show binary logs; +Log_name File_size +master-bin.000001 # +set @@global.binlog_checksum = NONE; +select @@global.binlog_checksum; +@@global.binlog_checksum +NONE +*** must be rotations seen *** +show binary logs; +Log_name File_size +master-bin.000001 # +master-bin.000002 # +connection master; +set @@global.binlog_checksum = NONE; +create table t1 (a int); +flush logs; +flush logs; +flush logs; +connection slave; +flush logs; +flush logs; +flush logs; +select count(*) as zero from t1; +zero +0 +include/stop_slave.inc +connection master; +set @@global.binlog_checksum = CRC32; +insert into t1 values (1) /* will not be applied on slave due to simulation */; +connection slave; +set @@global.debug_dbug='d,simulate_slave_unaware_checksum'; +start slave; +include/wait_for_slave_io_error.inc [errno=1236] +select count(*) as zero from t1; +zero +0 +set @@global.debug_dbug=''; +include/start_slave.inc +connection master; +set @@global.master_verify_checksum = 1; +set @@session.debug_dbug='d,simulate_checksum_test_failure'; +show binlog events; +ERROR HY000: Error when executing command SHOW BINLOG EVENTS: Wrong offset or I/O error +set @@session.debug_dbug=''; +set @@global.master_verify_checksum = default; +connection slave; +connection slave; +include/stop_slave.inc +connection master; +create table t2 (a int); +connection slave; +set @@global.debug_dbug='d,simulate_checksum_test_failure'; +start slave io_thread; +include/wait_for_slave_io_error.inc [errno=1595,1913] +set @@global.debug_dbug=''; +start slave io_thread; +include/wait_for_slave_param.inc [Read_Master_Log_Pos] +set @@global.slave_sql_verify_checksum = 1; +set @@global.debug_dbug='d,simulate_checksum_test_failure'; +start slave sql_thread; +include/wait_for_slave_sql_error.inc [errno=1593] +Last_SQL_Error = 'Error initializing relay log position: I/O error reading event at position 4' +set @@global.debug_dbug=''; +include/start_slave.inc +connection master; +connection slave; +select count(*) as 'must be zero' from t2; +must be zero +0 +connection slave; +stop slave; +reset slave; +set @@global.binlog_checksum= IF(floor((rand()*1000)%2), "CRC32", "NONE"); +flush logs; +connection master; +set @@global.binlog_checksum= CRC32; +reset master; +flush logs; +create table t3 (a int, b char(5)); +connection slave; +include/start_slave.inc +connection master; +connection slave; +select count(*) as 'must be zero' from t3; +must be zero +0 +include/stop_slave.inc +change master to master_host='127.0.0.1',master_port=MASTER_PORT, master_user='root'; +connection master; +flush logs; +reset master; +insert into t3 value (1, @@global.binlog_checksum); +connection slave; +include/start_slave.inc +flush logs; +connection master; +connection slave; +select count(*) as 'must be one' from t3; +must be one +1 +connection master; +set @@global.binlog_checksum= IF(floor((rand()*1000)%2), "CRC32", "NONE"); +insert into t3 value (1, @@global.binlog_checksum); +connection slave; +connection master; +drop table t1, t2, t3; +set @@global.master_verify_checksum = @save_master_verify_checksum; +connection slave; +*** Bug#59123 / MDEV-5799: INCIDENT_EVENT checksum written to error log as garbage characters *** +connection master; +CREATE TABLE t4 (a INT PRIMARY KEY); +INSERT INTO t4 VALUES (1); +SET sql_log_bin=0; +CALL mtr.add_suppression("\\[ERROR\\] Can't generate a unique log-filename"); +SET sql_log_bin=1; +SET @old_dbug= @@GLOBAL.debug_dbug; +SET debug_dbug= '+d,binlog_inject_new_name_error'; +FLUSH LOGS; +ERROR HY000: Can't generate a unique log-filename master-bin.(1-999) + +SET debug_dbug= @old_dbug; +INSERT INTO t4 VALUES (2); +connection slave; +include/wait_for_slave_sql_error.inc [errno=1590] +Last_SQL_Error = 'The incident LOST_EVENTS occurred on the master. Message: error writing to the binary log' +FOUND /Slave SQL: The incident LOST_EVENTS occurred on the master\. Message: error writing to the binary log, Internal MariaDB error code: 1590/ in mysqld.2.err +SELECT * FROM t4 ORDER BY a; +a +1 +STOP SLAVE IO_THREAD; +SET sql_slave_skip_counter= 1; +include/start_slave.inc +connection master; +connection slave; +SELECT * FROM t4 ORDER BY a; +a +1 +2 +connection slave; +set @@global.binlog_checksum = CRC32; +set @@global.slave_sql_verify_checksum = @save_slave_sql_verify_checksum; +End of tests +connection master; +DROP TABLE t4; +set @@global.binlog_checksum = CRC32; +set @@global.master_verify_checksum = @save_master_verify_checksum; +include/rpl_end.inc diff --git a/mysql-test/suite/binlog_encryption/rpl_checksum.test b/mysql-test/suite/binlog_encryption/rpl_checksum.test new file mode 100644 index 0000000..2334c63 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_checksum.test @@ -0,0 +1,326 @@ +# +# The test was taken from the rpl suite, parts related to checking +# the variable itself were removed. The test is run with encrypted +# binlogs on master and slave +# + +# WL2540 replication events checksum +# Testing configuration parameters + +--source include/master-slave.inc +--source include/have_debug.inc +--source include/have_binlog_format_mixed.inc + +--enable_connect_log + +call mtr.add_suppression('Slave can not handle replication events with the checksum that master is configured to log'); +call mtr.add_suppression('Replication event checksum verification failed'); +# due to C failure simulation +call mtr.add_suppression('Relay log write failure: could not queue event from master'); +call mtr.add_suppression('Master is configured to log replication events with checksum, but will not send such events to slaves that cannot process them'); + +connection slave; + +set @save_slave_sql_verify_checksum = @@global.slave_sql_verify_checksum; + +connection master; + +set @save_master_verify_checksum = @@global.master_verify_checksum; + +--disable_connect_log +source include/show_binary_logs.inc; +set @@global.binlog_checksum = NONE; +select @@global.binlog_checksum; +--echo *** must be rotations seen *** +source include/show_binary_logs.inc; +--enable_connect_log + +# +# B. Old Slave to New master conditions +# +# while master does not send a checksum-ed binlog the Old Slave can +# work with the New Master + +connection master; + +set @@global.binlog_checksum = NONE; +create table t1 (a int); + +# testing that binlog rotation preserves opt_binlog_checksum value +flush logs; +flush logs; +flush logs; + +sync_slave_with_master; +#connection slave; +# checking that rotation on the slave side leaves slave stable +flush logs; +flush logs; +flush logs; +select count(*) as zero from t1; + +--disable_connect_log +source include/stop_slave.inc; +--enable_connect_log + +connection master; +set @@global.binlog_checksum = CRC32; +--disable_connect_log +-- source include/wait_for_binlog_checkpoint.inc +--enable_connect_log +insert into t1 values (1) /* will not be applied on slave due to simulation */; + +# instruction to the dump thread + +connection slave; +set @@global.debug_dbug='d,simulate_slave_unaware_checksum'; +start slave; +--let $slave_io_errno= 1236 +--let $show_slave_io_error= 0 +--disable_connect_log +source include/wait_for_slave_io_error.inc; +--enable_connect_log + +select count(*) as zero from t1; +set @@global.debug_dbug=''; +--disable_connect_log +source include/start_slave.inc; +--enable_connect_log + +# +# C. checksum failure simulations +# + +# C1. Failure by a client thread +connection master; +set @@global.master_verify_checksum = 1; +set @@session.debug_dbug='d,simulate_checksum_test_failure'; +--error ER_ERROR_WHEN_EXECUTING_COMMAND +show binlog events; +set @@session.debug_dbug=''; +set @@global.master_verify_checksum = default; + +#connection master; +sync_slave_with_master; + +connection slave; +--disable_connect_log +source include/stop_slave.inc; +--enable_connect_log + +connection master; +create table t2 (a int); +let $pos_master= query_get_value(SHOW MASTER STATUS, Position, 1); + +connection slave; + +# C2. Failure by IO thread +# instruction to io thread +set @@global.debug_dbug='d,simulate_checksum_test_failure'; +start slave io_thread; +# When the checksum error is detected, the slave sets error code 1913 +# (ER_NETWORK_READ_EVENT_CHECKSUM_FAILURE) in queue_event(), then immediately +# sets error 1595 (ER_SLAVE_RELAY_LOG_WRITE_FAILURE) in handle_slave_io(). +# So we usually get 1595, but it is occasionally possible to get 1913. +--let $slave_io_errno= 1595,1913 +--let $show_slave_io_error= 0 +--disable_connect_log +source include/wait_for_slave_io_error.inc; +--enable_connect_log +set @@global.debug_dbug=''; + +# to make IO thread re-read it again w/o the failure +start slave io_thread; +let $slave_param= Read_Master_Log_Pos; +let $slave_param_value= $pos_master; +--disable_connect_log +source include/wait_for_slave_param.inc; +--enable_connect_log + +# C3. Failure by SQL thread +# instruction to sql thread; +set @@global.slave_sql_verify_checksum = 1; + +set @@global.debug_dbug='d,simulate_checksum_test_failure'; + +start slave sql_thread; +--let $slave_sql_errno= 1593 +--let $show_slave_sql_error= 1 +--disable_connect_log +source include/wait_for_slave_sql_error.inc; +--enable_connect_log + +# resuming SQL thread to parse out the event w/o the failure + +set @@global.debug_dbug=''; +--disable_connect_log +source include/start_slave.inc; +--enable_connect_log + +connection master; +sync_slave_with_master; + +#connection slave; +select count(*) as 'must be zero' from t2; + +# +# D. Reset slave, Change-Master, Binlog & Relay-log rotations with +# random value on binlog_checksum on both master and slave +# +connection slave; +stop slave; +reset slave; + +# randomize slave server's own checksum policy +set @@global.binlog_checksum= IF(floor((rand()*1000)%2), "CRC32", "NONE"); +flush logs; + +connection master; +set @@global.binlog_checksum= CRC32; +reset master; +flush logs; +create table t3 (a int, b char(5)); + +connection slave; +--disable_connect_log +source include/start_slave.inc; +--enable_connect_log + +connection master; +sync_slave_with_master; + +#connection slave; +select count(*) as 'must be zero' from t3; +--disable_connect_log +source include/stop_slave.inc; +--enable_connect_log +--replace_result $MASTER_MYPORT MASTER_PORT +eval change master to master_host='127.0.0.1',master_port=$MASTER_MYPORT, master_user='root'; + +connection master; +flush logs; +reset master; +insert into t3 value (1, @@global.binlog_checksum); + +connection slave; +--disable_connect_log +source include/start_slave.inc; +--enable_connect_log +flush logs; + +connection master; +sync_slave_with_master; + +#connection slave; +select count(*) as 'must be one' from t3; + +connection master; +set @@global.binlog_checksum= IF(floor((rand()*1000)%2), "CRC32", "NONE"); +insert into t3 value (1, @@global.binlog_checksum); +sync_slave_with_master; + +#connection slave; + +#clean-up + +connection master; +drop table t1, t2, t3; +set @@global.master_verify_checksum = @save_master_verify_checksum; + +# +# BUG#58564: flush_read_lock fails in mysql-trunk-bugfixing after merging with WL#2540 +# +# Sanity check that verifies that no assertions are triggered because +# of old FD events (generated by versions prior to server released with +# checksums feature) +# +# There is no need for query log, if something wrong this should trigger +# an assertion + +--disable_query_log + +BINLOG ' +MfmqTA8BAAAAZwAAAGsAAAABAAQANS41LjctbTMtZGVidWctbG9nAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAx+apMEzgNAAgAEgAEBAQEEgAAVAAEGggAAAAICAgCAA== +'; + +--enable_query_log + +#connection slave; +sync_slave_with_master; + + +--echo *** Bug#59123 / MDEV-5799: INCIDENT_EVENT checksum written to error log as garbage characters *** + +--connection master + +--disable_connect_log +--source include/wait_for_binlog_checkpoint.inc +--enable_connect_log +CREATE TABLE t4 (a INT PRIMARY KEY); +INSERT INTO t4 VALUES (1); + +SET sql_log_bin=0; +CALL mtr.add_suppression("\\[ERROR\\] Can't generate a unique log-filename"); +SET sql_log_bin=1; +SET @old_dbug= @@GLOBAL.debug_dbug; +SET debug_dbug= '+d,binlog_inject_new_name_error'; +--error ER_NO_UNIQUE_LOGFILE +FLUSH LOGS; +SET debug_dbug= @old_dbug; + +INSERT INTO t4 VALUES (2); + +--connection slave +--let $slave_sql_errno= 1590 +--disable_connect_log +--source include/wait_for_slave_sql_error.inc +--enable_connect_log + +# Search the error log for the error message. +# The bug was that 4 garbage bytes were output in the middle of the error +# message; by searching for a pattern that spans that location, we can +# catch the error. +let $log_error_= `SELECT @@GLOBAL.log_error`; +if(!$log_error_) +{ + # MySQL Server on windows is started with --console and thus + # does not know the location of its .err log, use default location + let $log_error_ = $MYSQLTEST_VARDIR/log/mysqld.2.err; +} +--let SEARCH_FILE= $log_error_ +--let SEARCH_RANGE=-50000 +--let SEARCH_PATTERN= Slave SQL: The incident LOST_EVENTS occurred on the master\. Message: error writing to the binary log, Internal MariaDB error code: 1590 +--disable_connect_log +--source include/search_pattern_in_file.inc +--enable_connect_log + +SELECT * FROM t4 ORDER BY a; +STOP SLAVE IO_THREAD; +SET sql_slave_skip_counter= 1; +--disable_connect_log +--source include/start_slave.inc +--enable_connect_log + +--connection master +--save_master_pos + +--connection slave +--sync_with_master +SELECT * FROM t4 ORDER BY a; + + +--connection slave +set @@global.binlog_checksum = CRC32; +set @@global.slave_sql_verify_checksum = @save_slave_sql_verify_checksum; + +--echo End of tests + +--connection master +DROP TABLE t4; + +set @@global.binlog_checksum = CRC32; +set @@global.master_verify_checksum = @save_master_verify_checksum; + +--disable_connect_log +--source include/rpl_end.inc diff --git a/mysql-test/suite/binlog_encryption/rpl_checksum_cache.result b/mysql-test/suite/binlog_encryption/rpl_checksum_cache.result new file mode 100644 index 0000000..d316749 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_checksum_cache.result @@ -0,0 +1,136 @@ +include/master-slave.inc +[connection master] +call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statement is unsafe because it uses a system function that may return a different value on the slave. Statement: insert into t2 set data=repeat.*'a', @act_size.*"); +call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statement is unsafe because it uses a system function that may return a different value on the slave. Statement: insert into t1 values.* NAME_CONST.*'n',.*, @data .*"); +connection master; +set @save_binlog_cache_size = @@global.binlog_cache_size; +set @save_binlog_checksum = @@global.binlog_checksum; +set @save_master_verify_checksum = @@global.master_verify_checksum; +set @@global.binlog_cache_size = 4096; +set @@global.binlog_checksum = CRC32; +set @@global.master_verify_checksum = 1; +connection slave; +include/stop_slave.inc +include/start_slave.inc +connection master; +flush status; +show status like "binlog_cache_use"; +Variable_name Value +Binlog_cache_use 0 +show status like "binlog_cache_disk_use"; +Variable_name Value +Binlog_cache_disk_use 0 +drop table if exists t1; +create table t1 (a int PRIMARY KEY, b CHAR(32)) engine=innodb; +create procedure test.p_init (n int, size int) +begin +while n > 0 do +select round(RAND() * size) into @act_size; +set @data = repeat('a', @act_size); +insert into t1 values(n, @data ); +set n= n-1; +end while; +end| +begin; +call test.p_init(4000, 32); +commit; +show status like "binlog_cache_use"; +Variable_name Value +Binlog_cache_use 1 +*** binlog_cache_disk_use must be non-zero *** +show status like "binlog_cache_disk_use"; +Variable_name Value +Binlog_cache_disk_use 1 +connection slave; +include/diff_tables.inc [master:test.t1, slave:test.t1] +connection master; +begin; +delete from t1; +commit; +connection slave; +connection master; +flush status; +create table t2(a int auto_increment primary key, data VARCHAR(12288)) ENGINE=Innodb; +show status like "binlog_cache_use"; +Variable_name Value +Binlog_cache_use 1 +*** binlog_cache_disk_use must be non-zero *** +show status like "binlog_cache_disk_use"; +Variable_name Value +Binlog_cache_disk_use 1 +connection slave; +include/diff_tables.inc [master:test.t2, slave:test.t2] +connection master; +begin; +delete from t2; +commit; +connection slave; +connection master; +flush status; +create table t3(a int auto_increment primary key, data VARCHAR(8192)) engine=innodb; +show status like "binlog_cache_use"; +Variable_name Value +Binlog_cache_use 1 +*** binlog_cache_disk_use must be non-zero *** +show status like "binlog_cache_disk_use"; +Variable_name Value +Binlog_cache_disk_use 1 +connection slave; +include/diff_tables.inc [master:test.t3, slave:test.t3] +connection master; +begin; +delete from t3; +commit; +connection slave; +connection master; +flush status; +create procedure test.p1 (n int) +begin +while n > 0 do +case (select (round(rand()*100) % 3) + 1) +when 1 then +select round(RAND() * 32) into @act_size; +set @data = repeat('a', @act_size); +insert into t1 values(n, @data); +when 2 then +begin +select round(8192 + RAND() * 4096) into @act_size; +insert into t2 set data=repeat('a', @act_size); +end; +when 3 then +begin +select round(3686.4000 + RAND() * 819.2000) into @act_size; +insert into t3 set data= repeat('a', @act_size); +end; +end case; +set n= n-1; +end while; +end| +set autocommit= 0; +begin; +call test.p1(1000); +commit; +show status like "binlog_cache_use"; +Variable_name Value +Binlog_cache_use 1 +*** binlog_cache_disk_use must be non-zero *** +show status like "binlog_cache_disk_use"; +Variable_name Value +Binlog_cache_disk_use 1 +connection slave; +include/diff_tables.inc [master:test.t1, slave:test.t1] +include/diff_tables.inc [master:test.t2, slave:test.t2] +include/diff_tables.inc [master:test.t3, slave:test.t3] +connection master; +begin; +delete from t1; +delete from t2; +delete from t3; +commit; +drop table t1, t2, t3; +set @@global.binlog_cache_size = @save_binlog_cache_size; +set @@global.binlog_checksum = @save_binlog_checksum; +set @@global.master_verify_checksum = @save_master_verify_checksum; +drop procedure test.p_init; +drop procedure test.p1; +include/rpl_end.inc diff --git a/mysql-test/suite/binlog_encryption/rpl_checksum_cache.test b/mysql-test/suite/binlog_encryption/rpl_checksum_cache.test new file mode 100644 index 0000000..2629e1f --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_checksum_cache.test @@ -0,0 +1,271 @@ +# +# The test was taken from the rpl suite as is +# + +-- source include/master-slave.inc + +--enable_connect_log + +--disable_warnings +call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statement is unsafe because it uses a system function that may return a different value on the slave. Statement: insert into t2 set data=repeat.*'a', @act_size.*"); +call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statement is unsafe because it uses a system function that may return a different value on the slave. Statement: insert into t1 values.* NAME_CONST.*'n',.*, @data .*"); +--enable_warnings + +connection master; +set @save_binlog_cache_size = @@global.binlog_cache_size; +set @save_binlog_checksum = @@global.binlog_checksum; +set @save_master_verify_checksum = @@global.master_verify_checksum; +set @@global.binlog_cache_size = 4096; +set @@global.binlog_checksum = CRC32; +set @@global.master_verify_checksum = 1; + +# restart slave to force the dump thread to verify events (on master side) +connection slave; +--disable_connect_log +source include/stop_slave.inc; +source include/start_slave.inc; +--enable_connect_log + +connection master; + +# +# Testing a critical part of checksum handling dealing with transaction cache. +# The cache's buffer size is set to be less than the transaction's footprint +# in binlog. +# +# To verify combined buffer-by-buffer read out of the file and fixing crc per event +# there are the following parts: +# +# 1. the event size is much less than the cache's buffer +# 2. the event size is bigger than the cache's buffer +# 3. the event size if approximately the same as the cache's buffer +# 4. all in above + +# +# 1. the event size is much less than the cache's buffer +# + +flush status; +show status like "binlog_cache_use"; +show status like "binlog_cache_disk_use"; +--disable_warnings +drop table if exists t1; +--enable_warnings + +# +# parameter to ensure the test slightly varies binlog content +# between different invocations +# +let $deviation_size=32; +eval create table t1 (a int PRIMARY KEY, b CHAR($deviation_size)) engine=innodb; + +# Now we are going to create transaction which is long enough so its +# transaction binlog will be flushed to disk... + +delimiter |; +create procedure test.p_init (n int, size int) +begin + while n > 0 do + select round(RAND() * size) into @act_size; + set @data = repeat('a', @act_size); + insert into t1 values(n, @data ); + set n= n-1; + end while; +end| + +delimiter ;| + +let $1 = 4000; # PB2 can run it slow to time out on following sync_slave_with_master:s + +begin; +--disable_warnings +# todo: check if it is really so. +#+Note 1592 Unsafe statement binlogged in statement format since BINLOG_FORMAT = STATEMENT. Reason for unsafeness: Statement uses a system function whose value may differ on slave. +eval call test.p_init($1, $deviation_size); +--enable_warnings +commit; + +show status like "binlog_cache_use"; +--echo *** binlog_cache_disk_use must be non-zero *** +show status like "binlog_cache_disk_use"; + +sync_slave_with_master; + +let $diff_tables=master:test.t1, slave:test.t1; +--disable_connect_log +source include/diff_tables.inc; +--enable_connect_log + +# undoing changes with verifying the above once again +connection master; + +begin; +delete from t1; +commit; + +sync_slave_with_master; + + +# +# 2. the event size is bigger than the cache's buffer +# +connection master; + +flush status; +let $t2_data_size= `select 3 * @@global.binlog_cache_size`; +let $t2_aver_size= `select 2 * @@global.binlog_cache_size`; +let $t2_max_rand= `select 1 * @@global.binlog_cache_size`; + +eval create table t2(a int auto_increment primary key, data VARCHAR($t2_data_size)) ENGINE=Innodb; +let $1=100; +--disable_query_log +begin; +while ($1) +{ + eval select round($t2_aver_size + RAND() * $t2_max_rand) into @act_size; + set @data = repeat('a', @act_size); + insert into t2 set data = @data; + dec $1; +} +commit; +--enable_query_log +show status like "binlog_cache_use"; +--echo *** binlog_cache_disk_use must be non-zero *** +show status like "binlog_cache_disk_use"; + +sync_slave_with_master; + +let $diff_tables=master:test.t2, slave:test.t2; +--disable_connect_log +source include/diff_tables.inc; +--enable_connect_log + +# undoing changes with verifying the above once again +connection master; + +begin; +delete from t2; +commit; + +sync_slave_with_master; + +# +# 3. the event size if approximately the same as the cache's buffer +# + +connection master; + +flush status; +let $t3_data_size= `select 2 * @@global.binlog_cache_size`; +let $t3_aver_size= `select (9 * @@global.binlog_cache_size) / 10`; +let $t3_max_rand= `select (2 * @@global.binlog_cache_size) / 10`; + +eval create table t3(a int auto_increment primary key, data VARCHAR($t3_data_size)) engine=innodb; + +let $1= 300; +--disable_query_log +begin; +while ($1) +{ + eval select round($t3_aver_size + RAND() * $t3_max_rand) into @act_size; + insert into t3 set data= repeat('a', @act_size); + dec $1; +} +commit; +--enable_query_log +show status like "binlog_cache_use"; +--echo *** binlog_cache_disk_use must be non-zero *** +show status like "binlog_cache_disk_use"; + +sync_slave_with_master; + +let $diff_tables=master:test.t3, slave:test.t3; +--disable_connect_log +source include/diff_tables.inc; +--enable_connect_log + +# undoing changes with verifying the above once again +connection master; + +begin; +delete from t3; +commit; + +sync_slave_with_master; + + +# +# 4. all in above +# + +connection master; +flush status; + +delimiter |; +eval create procedure test.p1 (n int) +begin + while n > 0 do + case (select (round(rand()*100) % 3) + 1) + when 1 then + select round(RAND() * $deviation_size) into @act_size; + set @data = repeat('a', @act_size); + insert into t1 values(n, @data); + when 2 then + begin + select round($t2_aver_size + RAND() * $t2_max_rand) into @act_size; + insert into t2 set data=repeat('a', @act_size); + end; + when 3 then + begin + select round($t3_aver_size + RAND() * $t3_max_rand) into @act_size; + insert into t3 set data= repeat('a', @act_size); + end; + end case; + set n= n-1; + end while; +end| +delimiter ;| + +let $1= 1000; +set autocommit= 0; +begin; +--disable_warnings +eval call test.p1($1); +--enable_warnings +commit; + +show status like "binlog_cache_use"; +--echo *** binlog_cache_disk_use must be non-zero *** +show status like "binlog_cache_disk_use"; + +sync_slave_with_master; + +let $diff_tables=master:test.t1, slave:test.t1; +--disable_connect_log +source include/diff_tables.inc; + +let $diff_tables=master:test.t2, slave:test.t2; +source include/diff_tables.inc; + +let $diff_tables=master:test.t3, slave:test.t3; +source include/diff_tables.inc; +--enable_connect_log + + +connection master; + +begin; +delete from t1; +delete from t2; +delete from t3; +commit; + +drop table t1, t2, t3; +set @@global.binlog_cache_size = @save_binlog_cache_size; +set @@global.binlog_checksum = @save_binlog_checksum; +set @@global.master_verify_checksum = @save_master_verify_checksum; +drop procedure test.p_init; +drop procedure test.p1; + +--disable_connect_log +--source include/rpl_end.inc diff --git a/mysql-test/suite/binlog_encryption/rpl_corruption.cnf b/mysql-test/suite/binlog_encryption/rpl_corruption.cnf new file mode 100644 index 0000000..7f7d0ee --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_corruption.cnf @@ -0,0 +1,9 @@ +!include my.cnf + +[mysqld.1] +binlog-checksum=CRC32 +master-verify-checksum=1 + +[mysqld.2] +binlog-checksum=CRC32 +slave-sql-verify-checksum=1 diff --git a/mysql-test/suite/binlog_encryption/rpl_corruption.result b/mysql-test/suite/binlog_encryption/rpl_corruption.result new file mode 100644 index 0000000..14a67b3 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_corruption.result @@ -0,0 +1,63 @@ +include/master-slave.inc +[connection master] +call mtr.add_suppression('Found invalid event in binary log'); +call mtr.add_suppression('Slave I/O: Relay log write failure: could not queue event from master'); +call mtr.add_suppression('event read from binlog did not pass crc check'); +call mtr.add_suppression('Replication event checksum verification failed'); +call mtr.add_suppression('Event crc check failed! Most likely there is event corruption'); +call mtr.add_suppression('Slave SQL: Error initializing relay log position: I/O error reading event at position .*, error.* 1593'); +SET @old_master_verify_checksum = @@master_verify_checksum; +# 1. Creating test table/data and set corruption position for testing +connection master; +* insert/update/delete rows in table t1 * +CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY, b VARCHAR(10), c VARCHAR(100)); +include/stop_slave.inc +# 2. Corruption in master binlog and SHOW BINLOG EVENTS +SET GLOBAL debug_dbug="+d,corrupt_read_log_event_char"; +SHOW BINLOG EVENTS; +ERROR HY000: Error when executing command SHOW BINLOG EVENTS: Wrong offset or I/O error +SET GLOBAL debug_dbug="-d,corrupt_read_log_event_char"; +# 3. Master read a corrupted event from binlog and send the error to slave +SET GLOBAL debug_dbug="+d,corrupt_read_log_event2_set"; +connection slave; +START SLAVE IO_THREAD; +include/wait_for_slave_io_error.inc [errno=1236] +connection master; +SET GLOBAL debug_dbug="-d,corrupt_read_log_event2_set"; +# 4. Master read a corrupted event from binlog and send it to slave +connection master; +SET GLOBAL master_verify_checksum=0; +SET GLOBAL debug_dbug="+d,corrupt_read_log_event2_set"; +connection slave; +START SLAVE IO_THREAD; +include/wait_for_slave_io_error.inc [errno=1595,1913] +connection master; +SET GLOBAL debug_dbug="-d,corrupt_read_log_event2_set"; +SET GLOBAL debug_dbug= ""; +SET GLOBAL master_verify_checksum=1; +# 5. Slave. Corruption in network +connection slave; +SET GLOBAL debug_dbug="+d,corrupt_queue_event"; +START SLAVE IO_THREAD; +include/wait_for_slave_io_error.inc [errno=1595,1913] +SET GLOBAL debug_dbug="-d,corrupt_queue_event"; +# 6. Slave. Corruption in relay log +SET GLOBAL debug_dbug="+d,corrupt_read_log_event_char"; +START SLAVE SQL_THREAD; +include/wait_for_slave_sql_error.inc [errno=1593] +SET GLOBAL debug_dbug="-d,corrupt_read_log_event_char"; +SET GLOBAL debug_dbug= ""; +# 7. Seek diff for tables on master and slave +connection slave; +include/start_slave.inc +connection master; +connection slave; +include/diff_tables.inc [master:test.t1, slave:test.t1] +# 8. Clean up +connection master; +SET GLOBAL debug_dbug= ""; +SET GLOBAL master_verify_checksum = @old_master_verify_checksum; +DROP TABLE t1; +connection slave; +SET GLOBAL debug_dbug= ""; +include/rpl_end.inc diff --git a/mysql-test/suite/binlog_encryption/rpl_corruption.test b/mysql-test/suite/binlog_encryption/rpl_corruption.test new file mode 100644 index 0000000..6413369 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_corruption.test @@ -0,0 +1,193 @@ +# +# The test was taken from the rpl suite as is +# + +############################################################ +# Purpose: WL#5064 Testing with corrupted events. +# The test emulates the corruption at the vary stages +# of replication: +# - in binlog file +# - in network +# - in relay log +############################################################ + +# +# The tests intensively utilize @@global.debug. Note, +# Bug#11765758 - 58754, +# @@global.debug is read by the slave threads through dbug-interface. +# Hence, before a client thread set @@global.debug we have to ensure that: +# (a) the slave threads are stopped, or (b) the slave threads are in +# sync and waiting. + +--source include/have_debug.inc +--source include/master-slave.inc + +--enable_connect_log + +# Block legal errors for MTR +call mtr.add_suppression('Found invalid event in binary log'); +call mtr.add_suppression('Slave I/O: Relay log write failure: could not queue event from master'); +call mtr.add_suppression('event read from binlog did not pass crc check'); +call mtr.add_suppression('Replication event checksum verification failed'); +call mtr.add_suppression('Event crc check failed! Most likely there is event corruption'); +call mtr.add_suppression('Slave SQL: Error initializing relay log position: I/O error reading event at position .*, error.* 1593'); + +SET @old_master_verify_checksum = @@master_verify_checksum; + +# Creating test table/data and set corruption position for testing +--echo # 1. Creating test table/data and set corruption position for testing +--connection master +--echo * insert/update/delete rows in table t1 * +# Corruption algorithm modifies only the first event and +# then will be reset. To avoid checking always the first event +# from binlog (usually it is FD) we randomly execute different +# statements and set position for corruption inside events. + +CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY, b VARCHAR(10), c VARCHAR(100)); +--disable_query_log +let $i=`SELECT 3+CEILING(10*RAND())`; +let $j=1; +let $pos=0; +while ($i) { + eval INSERT INTO t1 VALUES ($j, 'a', NULL); + if (`SELECT RAND() > 0.7`) + { + eval UPDATE t1 SET c = REPEAT('a', 20) WHERE a = $j; + } + if (`SELECT RAND() > 0.8`) + { + eval DELETE FROM t1 WHERE a = $j; + } + if (!$pos) { + let $pos= query_get_value(SHOW MASTER STATUS, Position, 1); + --sync_slave_with_master + --disable_connect_log + --source include/stop_slave.inc + --enable_connect_log + --disable_query_log + --connection master + } + dec $i; + inc $j; +} +--enable_query_log + + +# Emulate corruption in binlog file when SHOW BINLOG EVENTS is executing +--echo # 2. Corruption in master binlog and SHOW BINLOG EVENTS +SET GLOBAL debug_dbug="+d,corrupt_read_log_event_char"; +--echo SHOW BINLOG EVENTS; +--disable_query_log +send_eval SHOW BINLOG EVENTS FROM $pos; +--enable_query_log +--error ER_ERROR_WHEN_EXECUTING_COMMAND +reap; + +SET GLOBAL debug_dbug="-d,corrupt_read_log_event_char"; + +# Emulate corruption on master with crc checking on master +--echo # 3. Master read a corrupted event from binlog and send the error to slave + +# We have a rare but nasty potential race here: if the dump thread on +# the master for the _old_ slave connection has not yet discovered +# that the slave has disconnected, we will inject the corrupt event on +# the wrong connection, and the test will fail +# (+d,corrupt_read_log_event2 corrupts only one event). +# So kill any lingering dump thread (we need to kill; otherwise dump thread +# could manage to send all events down the socket before seeing it close, and +# hang forever waiting for new binlog events to be created). +let $id= `select id from information_schema.processlist where command = "Binlog Dump"`; +if ($id) +{ + --disable_query_log + --error 0,1094 + eval kill $id; + --enable_query_log +} +let $wait_condition= + SELECT COUNT(*)=0 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE command = 'Binlog Dump'; +--disable_connect_log +--source include/wait_condition.inc +--enable_connect_log + +SET GLOBAL debug_dbug="+d,corrupt_read_log_event2_set"; +--connection slave +START SLAVE IO_THREAD; +let $slave_io_errno= 1236; +--let $slave_timeout= 10 +--disable_connect_log +--source include/wait_for_slave_io_error.inc +--enable_connect_log +--connection master +SET GLOBAL debug_dbug="-d,corrupt_read_log_event2_set"; + +# Emulate corruption on master without crc checking on master +--echo # 4. Master read a corrupted event from binlog and send it to slave +--connection master +SET GLOBAL master_verify_checksum=0; +SET GLOBAL debug_dbug="+d,corrupt_read_log_event2_set"; +--connection slave +START SLAVE IO_THREAD; +# When the checksum error is detected, the slave sets error code 1913 +# (ER_NETWORK_READ_EVENT_CHECKSUM_FAILURE) in queue_event(), then immediately +# sets error 1595 (ER_SLAVE_RELAY_LOG_WRITE_FAILURE) in handle_slave_io(). +# So we usually get 1595, but it is occasionally possible to get 1913. +let $slave_io_errno= 1595,1913; +--disable_connect_log +--source include/wait_for_slave_io_error.inc +--enable_connect_log +--connection master +SET GLOBAL debug_dbug="-d,corrupt_read_log_event2_set"; +SET GLOBAL debug_dbug= ""; +SET GLOBAL master_verify_checksum=1; + +# Emulate corruption in network +--echo # 5. Slave. Corruption in network +--connection slave +SET GLOBAL debug_dbug="+d,corrupt_queue_event"; +START SLAVE IO_THREAD; +let $slave_io_errno= 1595,1913; +--disable_connect_log +--source include/wait_for_slave_io_error.inc +--enable_connect_log +SET GLOBAL debug_dbug="-d,corrupt_queue_event"; + +# Emulate corruption in relay log +--echo # 6. Slave. Corruption in relay log + +SET GLOBAL debug_dbug="+d,corrupt_read_log_event_char"; + +START SLAVE SQL_THREAD; +let $slave_sql_errno= 1593; +--disable_connect_log +--source include/wait_for_slave_sql_error.inc +--enable_connect_log + +SET GLOBAL debug_dbug="-d,corrupt_read_log_event_char"; +SET GLOBAL debug_dbug= ""; + +# Start normal replication and compare same table on master +# and slave +--echo # 7. Seek diff for tables on master and slave +--connection slave +--disable_connect_log +--source include/start_slave.inc +--enable_connect_log +--connection master +--sync_slave_with_master +let $diff_tables= master:test.t1, slave:test.t1; +--disable_connect_log +--source include/diff_tables.inc +--enable_connect_log + +# Clean up +--echo # 8. Clean up +--connection master +SET GLOBAL debug_dbug= ""; +SET GLOBAL master_verify_checksum = @old_master_verify_checksum; +DROP TABLE t1; +--sync_slave_with_master +SET GLOBAL debug_dbug= ""; + +--disable_connect_log +--source include/rpl_end.inc diff --git a/mysql-test/suite/binlog_encryption/rpl_gtid_basic.cnf b/mysql-test/suite/binlog_encryption/rpl_gtid_basic.cnf new file mode 100644 index 0000000..ae47ef7 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_gtid_basic.cnf @@ -0,0 +1,24 @@ +!include my.cnf + +[mysqld.1] +log-slave-updates + +[mysqld.2] +init-rpl-role= slave +master-retry-count= 10 +skip-slave-start + +[mysqld.3] +log-slave-updates +innodb + +[mysqld.4] +log-slave-updates +innodb + +[ENV] +SERVER_MYPORT_3= @mysqld.3.port +SERVER_MYSOCK_3= @mysqld.3.socket + +SERVER_MYPORT_4= @mysqld.4.port +SERVER_MYSOCK_4= @mysqld.4.socket diff --git a/mysql-test/suite/binlog_encryption/rpl_gtid_basic.result b/mysql-test/suite/binlog_encryption/rpl_gtid_basic.result new file mode 100644 index 0000000..c1fbeb8 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_gtid_basic.result @@ -0,0 +1,558 @@ +include/rpl_init.inc [topology=1->2->3->4] +connection server_1; +*** GTID position should be empty here *** +SELECT BINLOG_GTID_POS('<BINLOG_FILE>',<BINLOG_POS>); +BINLOG_GTID_POS('<BINLOG_FILE>',<BINLOG_POS>) + +CREATE TABLE t1 (a INT PRIMARY KEY, b VARCHAR(10)) ENGINE=MyISAM; +CREATE TABLE t2 (a INT PRIMARY KEY, b VARCHAR(10)) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1, "m1"); +INSERT INTO t1 VALUES (2, "m2"), (3, "m3"), (4, "m4"); +INSERT INTO t2 VALUES (1, "i1"); +BEGIN; +INSERT INTO t2 VALUES (2, "i2"), (3, "i3"); +INSERT INTO t2 VALUES (4, "i4"); +COMMIT; +*** GTID position should be non-empty here *** +SELECT BINLOG_GTID_POS('<BINLOG_FILE>',<BINLOG_POS>); +BINLOG_GTID_POS('<BINLOG_FILE>',<BINLOG_POS>) +<GTID_POS_SERVER_1> +connection server_2; +*** GTID position should be the same as on server_1 *** +SELECT BINLOG_GTID_POS('<BINLOG_FILE>',<BINLOG_POS>); +BINLOG_GTID_POS('<BINLOG_FILE>',<BINLOG_POS>) +<GTID_POS_SERVER_1> +SELECT * FROM t1 ORDER BY a; +a b +1 m1 +2 m2 +3 m3 +4 m4 +SELECT * FROM t2 ORDER BY a; +a b +1 i1 +2 i2 +3 i3 +4 i4 +connection server_3; +SELECT * FROM t1 ORDER BY a; +a b +1 m1 +2 m2 +3 m3 +4 m4 +SELECT * FROM t2 ORDER BY a; +a b +1 i1 +2 i2 +3 i3 +4 i4 +connection server_4; +SELECT * FROM t1 ORDER BY a; +a b +1 m1 +2 m2 +3 m3 +4 m4 +SELECT * FROM t2 ORDER BY a; +a b +1 i1 +2 i2 +3 i3 +4 i4 +*** Now take out D, let it fall behind a bit, and then test re-attaching it to A *** +connection server_4; +include/stop_slave.inc +connection server_1; +INSERT INTO t1 VALUES (5, "m1a"); +INSERT INTO t2 VALUES (5, "i1a"); +connection server_4; +CHANGE MASTER TO master_host = '127.0.0.1', master_port = MASTER_PORT, +MASTER_USE_GTID=CURRENT_POS; +include/start_slave.inc +SELECT * FROM t1 ORDER BY a; +a b +1 m1 +2 m2 +3 m3 +4 m4 +5 m1a +SELECT * FROM t2 ORDER BY a; +a b +1 i1 +2 i2 +3 i3 +4 i4 +5 i1a +*** Now move B to D (C is still replicating from B) *** +connection server_2; +include/stop_slave.inc +CHANGE MASTER TO master_host = '127.0.0.1', master_port = SERVER_MYPORT_4, +MASTER_USE_GTID=CURRENT_POS; +include/start_slave.inc +connection server_4; +UPDATE t2 SET b="j1a" WHERE a=5; +connection server_2; +SELECT * FROM t1 ORDER BY a; +a b +1 m1 +2 m2 +3 m3 +4 m4 +5 m1a +SELECT * FROM t2 ORDER BY a; +a b +1 i1 +2 i2 +3 i3 +4 i4 +5 j1a +*** Now move C to D, after letting it fall a little behind *** +connection server_3; +include/stop_slave.inc +connection server_1; +INSERT INTO t2 VALUES (6, "i6b"); +INSERT INTO t2 VALUES (7, "i7b"); +include/save_master_gtid.inc +connection server_3; +CHANGE MASTER TO master_host = '127.0.0.1', master_port = SERVER_MYPORT_4, +MASTER_USE_GTID=CURRENT_POS; +include/start_slave.inc +include/sync_with_master_gtid.inc +SELECT * FROM t2 ORDER BY a; +a b +1 i1 +2 i2 +3 i3 +4 i4 +5 j1a +6 i6b +7 i7b +*** Now change everything back to what it was, to make rpl_end.inc happy +connection server_2; +include/sync_with_master_gtid.inc +include/stop_slave.inc +CHANGE MASTER TO master_host = '127.0.0.1', master_port = MASTER_MYPORT; +include/start_slave.inc +include/wait_for_slave_to_start.inc +connection server_3; +include/stop_slave.inc +CHANGE MASTER TO master_host = '127.0.0.1', master_port = SLAVE_MYPORT; +include/start_slave.inc +include/sync_with_master_gtid.inc +connection server_4; +include/stop_slave.inc +CHANGE MASTER TO master_host = '127.0.0.1', master_port = SERVER_MYPORT_3; +include/start_slave.inc +connection server_1; +DROP TABLE t1,t2; +include/save_master_gtid.inc +*** A few more checks for BINLOG_GTID_POS function *** +SELECT BINLOG_GTID_POS(); +ERROR 42000: Incorrect parameter count in the call to native function 'BINLOG_GTID_POS' +SELECT BINLOG_GTID_POS('a'); +ERROR 42000: Incorrect parameter count in the call to native function 'BINLOG_GTID_POS' +SELECT BINLOG_GTID_POS('a',1,NULL); +ERROR 42000: Incorrect parameter count in the call to native function 'BINLOG_GTID_POS' +SELECT BINLOG_GTID_POS(1,'a'); +BINLOG_GTID_POS(1,'a') +NULL +Warnings: +Warning 1292 Truncated incorrect INTEGER value: 'a' +SELECT BINLOG_GTID_POS(NULL,NULL); +BINLOG_GTID_POS(NULL,NULL) +NULL +SELECT BINLOG_GTID_POS('',1); +BINLOG_GTID_POS('',1) + +SELECT BINLOG_GTID_POS('a',1); +BINLOG_GTID_POS('a',1) +NULL +SELECT BINLOG_GTID_POS('master-bin.000001',-1); +BINLOG_GTID_POS('master-bin.000001',-1) +NULL +SELECT BINLOG_GTID_POS('master-bin.000001',0); +BINLOG_GTID_POS('master-bin.000001',0) + +SELECT BINLOG_GTID_POS('master-bin.000001',18446744073709551615); +BINLOG_GTID_POS('master-bin.000001',18446744073709551615) +NULL +SELECT BINLOG_GTID_POS('master-bin.000001',18446744073709551616); +BINLOG_GTID_POS('master-bin.000001',18446744073709551616) +NULL +Warnings: +Warning 1916 Got overflow when converting '18446744073709551616' to INT. Value truncated. +*** Some tests of @@GLOBAL.gtid_binlog_state *** +connection server_2; +include/sync_with_master_gtid.inc +include/stop_slave.inc +connection server_1; +SET @old_state= @@GLOBAL.gtid_binlog_state; +SET GLOBAL gtid_binlog_state = ''; +ERROR HY000: This operation is not allowed if any GTID has been logged to the binary log. Run RESET MASTER first to erase the log +RESET MASTER; +SET GLOBAL gtid_binlog_state = ''; +FLUSH LOGS; +show binary logs; +Log_name File_size +master-bin.000001 # +master-bin.000002 # +SET GLOBAL gtid_binlog_state = '0-1-10,1-2-20,0-3-30'; +show binary logs; +Log_name File_size +master-bin.000001 # +include/show_binlog_events.inc +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Format_desc # # SERVER_VERSION, BINLOG_VERSION +master-bin.000001 # Start_encryption # # +master-bin.000001 # Gtid_list # # [#-#-#] +master-bin.000001 # Binlog_checkpoint # # master-bin.000001 +SET GLOBAL gtid_binlog_state = @old_state; +ERROR HY000: This operation is not allowed if any GTID has been logged to the binary log. Run RESET MASTER first to erase the log +RESET MASTER; +SET GLOBAL gtid_binlog_state = @old_state; +CREATE TABLE t1 (a INT PRIMARY KEY); +SET gtid_seq_no=100; +INSERT INTO t1 VALUES (1); +include/save_master_gtid.inc +connection server_2; +include/start_slave.inc +include/sync_with_master_gtid.inc +SELECT * FROM t1; +a +1 +Gtid_IO_Pos = '0-1-100' +*** Test @@LAST_GTID and MASTER_GTID_WAIT() *** +connection server_1; +DROP TABLE t1; +CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB; +connection server_2; +include/stop_slave.inc +connect m1,127.0.0.1,root,,test,$SERVER_MYPORT_1,; +SELECT @@last_gtid; +@@last_gtid + +SET gtid_seq_no=110; +SELECT @@last_gtid; +@@last_gtid + +BEGIN; +SELECT @@last_gtid; +@@last_gtid + +INSERT INTO t1 VALUES (2); +SELECT @@last_gtid; +@@last_gtid + +COMMIT; +SELECT @@last_gtid; +@@last_gtid +0-1-110 +connect s1,127.0.0.1,root,,test,$SERVER_MYPORT_2,; +SET @pos= '0-1-110'; +SELECT master_gtid_wait(NULL); +master_gtid_wait(NULL) +NULL +SELECT master_gtid_wait('', NULL); +master_gtid_wait('', NULL) +0 +SHOW STATUS LIKE 'Master_gtid_wait_count'; +Variable_name Value +Master_gtid_wait_count 1 +SHOW STATUS LIKE 'Master_gtid_wait_timeouts'; +Variable_name Value +Master_gtid_wait_timeouts 0 +SHOW STATUS LIKE 'Master_gtid_wait_time'; +Variable_name Value +Master_gtid_wait_time 0 +SELECT master_gtid_wait(@pos, 0.5); +master_gtid_wait(@pos, 0.5) +-1 +SELECT * FROM t1 ORDER BY a; +a +SELECT master_gtid_wait(@pos); +connection server_2; +include/start_slave.inc +connection s1; +master_gtid_wait(@pos) +0 +SELECT * FROM t1 ORDER BY a; +a +2 +include/stop_slave.inc +connection server_1; +SET gtid_domain_id= 1; +INSERT INTO t1 VALUES (3); +connection s1; +SET @pos= 'POS'; +SELECT master_gtid_wait(@pos, 0); +master_gtid_wait(@pos, 0) +-1 +SELECT * FROM t1 WHERE a >= 3; +a +SELECT master_gtid_wait(@pos, -1); +connection server_2; +include/start_slave.inc +connection s1; +master_gtid_wait(@pos, -1) +0 +SELECT * FROM t1 WHERE a >= 3; +a +3 +SELECT master_gtid_wait('1-1-1', 0); +master_gtid_wait('1-1-1', 0) +0 +connection s1; +SELECT master_gtid_wait('2-1-1,1-1-4,0-1-110'); +connect s2,127.0.0.1,root,,test,$SERVER_MYPORT_2,; +SELECT master_gtid_wait('0-1-1000', 0.5); +connect s3,127.0.0.1,root,,test,$SERVER_MYPORT_2,; +SELECT master_gtid_wait('0-1-2000'); +connect s4,127.0.0.1,root,,test,$SERVER_MYPORT_2,; +SELECT master_gtid_wait('2-1-10'); +connect s5,127.0.0.1,root,,test,$SERVER_MYPORT_2,; +SELECT master_gtid_wait('2-1-6', 1); +connect s6,127.0.0.1,root,,test,$SERVER_MYPORT_2,; +SELECT master_gtid_wait('2-1-5'); +connect s7,127.0.0.1,root,,test,$SERVER_MYPORT_2,; +SELECT master_gtid_wait('2-1-10'); +connect s8,127.0.0.1,root,,test,$SERVER_MYPORT_2,; +SELECT master_gtid_wait('2-1-5,1-1-4,0-1-110'); +connect s9,127.0.0.1,root,,test,$SERVER_MYPORT_2,; +SELECT master_gtid_wait('2-1-2'); +connection server_2; +SHOW STATUS LIKE 'Master_gtid_wait_timeouts'; +Variable_name Value +Master_gtid_wait_timeouts 0 +SHOW STATUS LIKE 'Master_gtid_wait_count'; +Variable_name Value +Master_gtid_wait_count 3 +SELECT master_gtid_wait('1-1-1'); +master_gtid_wait('1-1-1') +0 +SHOW STATUS LIKE 'Master_gtid_wait_timeouts'; +Variable_name Value +Master_gtid_wait_timeouts 0 +SHOW STATUS LIKE 'Master_gtid_wait_count'; +Variable_name Value +Master_gtid_wait_count 4 +SET @a= MASTER_GTID_WAIT_TIME; +SELECT IF(@a <= 100*1000*1000, "OK", CONCAT("Error: wait time ", @a, " is larger than expected")) +AS Master_gtid_wait_time_as_expected; +Master_gtid_wait_time_as_expected +OK +connect s10,127.0.0.1,root,,test,$SERVER_MYPORT_2,; +SELECT master_gtid_wait('0-1-109'); +connection server_2; +SHOW STATUS LIKE 'Master_gtid_wait_timeouts'; +Variable_name Value +Master_gtid_wait_timeouts 0 +SHOW STATUS LIKE 'Master_gtid_wait_count'; +Variable_name Value +Master_gtid_wait_count 4 +SELECT master_gtid_wait('2-1-2', 0.5); +master_gtid_wait('2-1-2', 0.5) +-1 +SHOW STATUS LIKE 'Master_gtid_wait_timeouts'; +Variable_name Value +Master_gtid_wait_timeouts 1 +SHOW STATUS LIKE 'Master_gtid_wait_count'; +Variable_name Value +Master_gtid_wait_count 5 +SET @a= MASTER_GTID_WAIT_TIME; +SELECT IF(@a BETWEEN 0.4*1000*1000 AND 100*1000*1000, "OK", CONCAT("Error: wait time ", @a, " not as expected")) AS Master_gtid_wait_time_as_expected; +Master_gtid_wait_time_as_expected +OK +KILL QUERY KILL_ID; +connection s3; +ERROR 70100: Query execution was interrupted +connection server_1; +SET gtid_domain_id=2; +SET gtid_seq_no=2; +INSERT INTO t1 VALUES (4); +connection s9; +master_gtid_wait('2-1-2') +0 +connection server_2; +KILL CONNECTION KILL_ID; +connection s6; +Got one of the listed errors +connection server_1; +SET gtid_domain_id=1; +SET gtid_seq_no=4; +INSERT INTO t1 VALUES (5); +SET gtid_domain_id=2; +SET gtid_seq_no=5; +INSERT INTO t1 VALUES (6); +connection s8; +master_gtid_wait('2-1-5,1-1-4,0-1-110') +0 +connection s1; +master_gtid_wait('2-1-1,1-1-4,0-1-110') +0 +connection s2; +master_gtid_wait('0-1-1000', 0.5) +-1 +connection s5; +master_gtid_wait('2-1-6', 1) +-1 +connection s10; +master_gtid_wait('0-1-109') +0 +connection server_1; +SET gtid_domain_id=2; +SET gtid_seq_no=10; +INSERT INTO t1 VALUES (7); +connection s4; +master_gtid_wait('2-1-10') +0 +connection s7; +master_gtid_wait('2-1-10') +0 +*** Test gtid_slave_pos when used with GTID *** +connection server_2; +include/stop_slave.inc +connection server_1; +SET gtid_domain_id=2; +SET gtid_seq_no=1000; +INSERT INTO t1 VALUES (10); +INSERT INTO t1 VALUES (11); +connection server_2; +SET sql_slave_skip_counter= 1; +include/start_slave.inc +SELECT * FROM t1 WHERE a >= 10 ORDER BY a; +a +11 +SELECT IF(LOCATE("2-1-1001", @@GLOBAL.gtid_slave_pos)>0, "Ok", CONCAT("ERROR! expected GTID 2-1-1001 not found in gtid_slave_pos: ", @@GLOBAL.gtid_slave_pos)) AS status; +status +Ok +include/stop_slave.inc +connection server_1; +SET gtid_domain_id=2; +SET gtid_seq_no=1010; +INSERT INTO t1 VALUES (12); +INSERT INTO t1 VALUES (13); +connection server_2; +SET sql_slave_skip_counter= 2; +include/start_slave.inc +SELECT * FROM t1 WHERE a >= 10 ORDER BY a; +a +11 +13 +SELECT IF(LOCATE("2-1-1011", @@GLOBAL.gtid_slave_pos)>0, "Ok", CONCAT("ERROR! expected GTID 2-1-1011 not found in gtid_slave_pos: ", @@GLOBAL.gtid_slave_pos)) AS status; +status +Ok +include/stop_slave.inc +connection server_1; +SET gtid_domain_id=2; +SET gtid_seq_no=1020; +INSERT INTO t1 VALUES (14); +INSERT INTO t1 VALUES (15); +INSERT INTO t1 VALUES (16); +connection server_2; +SET sql_slave_skip_counter= 3; +include/start_slave.inc +SELECT * FROM t1 WHERE a >= 10 ORDER BY a; +a +11 +13 +15 +16 +SELECT IF(LOCATE("2-1-1022", @@GLOBAL.gtid_slave_pos)>0, "Ok", CONCAT("ERROR! expected GTID 2-1-1022 not found in gtid_slave_pos: ", @@GLOBAL.gtid_slave_pos)) AS status; +status +Ok +include/stop_slave.inc +connection server_1; +SET gtid_domain_id=2; +SET gtid_seq_no=1030; +INSERT INTO t1 VALUES (17); +INSERT INTO t1 VALUES (18); +INSERT INTO t1 VALUES (19); +connection server_2; +SET sql_slave_skip_counter= 5; +include/start_slave.inc +SELECT * FROM t1 WHERE a >= 10 ORDER BY a; +a +11 +13 +15 +16 +19 +SELECT IF(LOCATE("2-1-1032", @@GLOBAL.gtid_slave_pos)>0, "Ok", CONCAT("ERROR! expected GTID 2-1-1032 not found in gtid_slave_pos: ", @@GLOBAL.gtid_slave_pos)) AS status; +status +Ok +include/stop_slave.inc +connection server_1; +SET gtid_domain_id=3; +SET gtid_seq_no=100; +CREATE TABLE t2 (a INT PRIMARY KEY); +DROP TABLE t2; +SET gtid_domain_id=2; +SET gtid_seq_no=1040; +INSERT INTO t1 VALUES (20); +connection server_2; +SET @saved_mode= @@GLOBAL.slave_ddl_exec_mode; +SET GLOBAL slave_ddl_exec_mode=STRICT; +SET sql_slave_skip_counter=1; +START SLAVE UNTIL master_gtid_pos="3-1-100"; +include/sync_with_master_gtid.inc +include/wait_for_slave_to_stop.inc +SELECT * FROM t2; +ERROR 42S02: Table 'test.t2' doesn't exist +SELECT IF(LOCATE("3-1-100", @@GLOBAL.gtid_slave_pos)>0, "Ok", CONCAT("ERROR! expected GTID 3-1-100 not found in gtid_slave_pos: ", @@GLOBAL.gtid_slave_pos)) AS status; +status +Ok +SET sql_log_bin=0; +CALL mtr.add_suppression("Slave: Unknown table 'test\\.t2' Error_code: 1051"); +SET sql_log_bin=1; +START SLAVE; +include/wait_for_slave_sql_error.inc [errno=1051] +SELECT IF(LOCATE("3-1-100", @@GLOBAL.gtid_slave_pos)>0, "Ok", CONCAT("ERROR! expected GTID 3-1-100 not found in gtid_slave_pos: ", @@GLOBAL.gtid_slave_pos)) AS status; +status +Ok +STOP SLAVE IO_THREAD; +SET sql_slave_skip_counter=2; +include/start_slave.inc +SELECT * FROM t1 WHERE a >= 20 ORDER BY a; +a +20 +SELECT IF(LOCATE("3-1-101", @@GLOBAL.gtid_slave_pos)>0, "Ok", CONCAT("ERROR! expected GTID 3-1-101 not found in gtid_slave_pos: ", @@GLOBAL.gtid_slave_pos)) AS status; +status +Ok +SELECT IF(LOCATE("2-1-1040", @@GLOBAL.gtid_slave_pos)>0, "Ok", CONCAT("ERROR! expected GTID 2-1-1040 not found in gtid_slave_pos: ", @@GLOBAL.gtid_slave_pos)) AS status; +status +Ok +SET GLOBAL slave_ddl_exec_mode= @saved_mode; +*** Test GTID-connecting to a master with out-of-order sequence numbers in the binlog. *** +connection server_1; +SET gtid_domain_id= @@GLOBAL.gtid_domain_id; +INSERT INTO t1 VALUES (31); +connection server_2; +SET gtid_domain_id= @@GLOBAL.gtid_domain_id; +INSERT INTO t1 VALUES (32); +connection server_1; +INSERT INTO t1 VALUES (33); +connection server_2; +connection server_3; +include/stop_slave.inc +connection server_1; +INSERT INTO t1 VALUES (34); +connection server_2; +connection server_3; +include/start_slave.inc +SELECT * FROM t1 WHERE a >= 30 ORDER BY a; +a +31 +32 +33 +34 +connection server_4; +SELECT * FROM t1 WHERE a >= 30 ORDER BY a; +a +31 +32 +33 +34 +connection server_1; +DROP TABLE t1; +include/rpl_end.inc diff --git a/mysql-test/suite/binlog_encryption/rpl_gtid_basic.test b/mysql-test/suite/binlog_encryption/rpl_gtid_basic.test new file mode 100644 index 0000000..1ce2a25 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_gtid_basic.test @@ -0,0 +1,644 @@ +# +# The test was taken from the rpl suite as is +# + +--let $rpl_topology=1->2->3->4 +--source include/rpl_init.inc + +--enable_connect_log + +# Set up a 4-deep replication topology, then test various fail-overs +# using GTID. +# +# A -> B -> C -> D + +connection server_1; +--disable_connect_log +--source include/wait_for_binlog_checkpoint.inc +--enable_connect_log +--let $binlog_file = query_get_value(SHOW MASTER STATUS,File,1) +--let $binlog_pos = query_get_value(SHOW MASTER STATUS,Position,1) +--echo *** GTID position should be empty here *** +--replace_result $binlog_file <BINLOG_FILE> $binlog_pos <BINLOG_POS> +eval SELECT BINLOG_GTID_POS('$binlog_file',$binlog_pos); + +CREATE TABLE t1 (a INT PRIMARY KEY, b VARCHAR(10)) ENGINE=MyISAM; +CREATE TABLE t2 (a INT PRIMARY KEY, b VARCHAR(10)) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1, "m1"); +INSERT INTO t1 VALUES (2, "m2"), (3, "m3"), (4, "m4"); +INSERT INTO t2 VALUES (1, "i1"); +BEGIN; +INSERT INTO t2 VALUES (2, "i2"), (3, "i3"); +INSERT INTO t2 VALUES (4, "i4"); +COMMIT; +save_master_pos; +--disable_connect_log +source include/wait_for_binlog_checkpoint.inc; +--enable_connect_log +--let $binlog_file = query_get_value(SHOW MASTER STATUS,File,1) +--let $binlog_pos = query_get_value(SHOW MASTER STATUS,Position,1) +--let $gtid_pos_server_1 = `SELECT @@gtid_binlog_pos` +--echo *** GTID position should be non-empty here *** +--replace_result $binlog_file <BINLOG_FILE> $binlog_pos <BINLOG_POS> $gtid_pos_server_1 <GTID_POS_SERVER_1> +eval SELECT BINLOG_GTID_POS('$binlog_file',$binlog_pos); + +connection server_2; +sync_with_master; +--disable_connect_log +source include/wait_for_binlog_checkpoint.inc; +--enable_connect_log +--let $binlog_file = query_get_value(SHOW MASTER STATUS,File,1) +--let $binlog_pos = query_get_value(SHOW MASTER STATUS,Position,1) +--echo *** GTID position should be the same as on server_1 *** +--replace_result $binlog_file <BINLOG_FILE> $binlog_pos <BINLOG_POS> $gtid_pos_server_1 <GTID_POS_SERVER_1> +eval SELECT BINLOG_GTID_POS('$binlog_file',$binlog_pos); +SELECT * FROM t1 ORDER BY a; +SELECT * FROM t2 ORDER BY a; +save_master_pos; + +connection server_3; +sync_with_master; +SELECT * FROM t1 ORDER BY a; +SELECT * FROM t2 ORDER BY a; +save_master_pos; + +connection server_4; +sync_with_master; +SELECT * FROM t1 ORDER BY a; +SELECT * FROM t2 ORDER BY a; + + +--echo *** Now take out D, let it fall behind a bit, and then test re-attaching it to A *** +connection server_4; +--disable_connect_log +--source include/stop_slave.inc +--enable_connect_log + +connection server_1; +INSERT INTO t1 VALUES (5, "m1a"); +INSERT INTO t2 VALUES (5, "i1a"); +save_master_pos; + +connection server_4; +--replace_result $MASTER_MYPORT MASTER_PORT +eval CHANGE MASTER TO master_host = '127.0.0.1', master_port = $MASTER_MYPORT, + MASTER_USE_GTID=CURRENT_POS; +--disable_connect_log +--source include/start_slave.inc +--enable_connect_log +sync_with_master; +SELECT * FROM t1 ORDER BY a; +SELECT * FROM t2 ORDER BY a; + +--echo *** Now move B to D (C is still replicating from B) *** +connection server_2; +--disable_connect_log +--source include/stop_slave.inc +--enable_connect_log +--replace_result $SERVER_MYPORT_4 SERVER_MYPORT_4 +eval CHANGE MASTER TO master_host = '127.0.0.1', master_port = $SERVER_MYPORT_4, + MASTER_USE_GTID=CURRENT_POS; +--disable_connect_log +--source include/start_slave.inc +--enable_connect_log + +connection server_4; +UPDATE t2 SET b="j1a" WHERE a=5; +save_master_pos; + +connection server_2; +sync_with_master; +SELECT * FROM t1 ORDER BY a; +SELECT * FROM t2 ORDER BY a; + +--echo *** Now move C to D, after letting it fall a little behind *** +connection server_3; +--disable_connect_log +--source include/stop_slave.inc +--enable_connect_log + +connection server_1; +INSERT INTO t2 VALUES (6, "i6b"); +INSERT INTO t2 VALUES (7, "i7b"); +--disable_connect_log +--source include/save_master_gtid.inc +--enable_connect_log + +connection server_3; +--replace_result $SERVER_MYPORT_4 SERVER_MYPORT_4 +eval CHANGE MASTER TO master_host = '127.0.0.1', master_port = $SERVER_MYPORT_4, + MASTER_USE_GTID=CURRENT_POS; +--disable_connect_log +--source include/start_slave.inc +--source include/sync_with_master_gtid.inc +--enable_connect_log +SELECT * FROM t2 ORDER BY a; + +--echo *** Now change everything back to what it was, to make rpl_end.inc happy +# Also check that MASTER_USE_GTID=CURRENT_POS is still enabled. +connection server_2; +# We need to sync up server_2 before switching. If it happened to have reached +# the point 'UPDATE t2 SET b="j1a" WHERE a=5' it will fail to connect to +# server_1, which is (deliberately) missing that transaction. +--disable_connect_log +--source include/sync_with_master_gtid.inc +--source include/stop_slave.inc +--replace_result $MASTER_MYPORT MASTER_MYPORT +eval CHANGE MASTER TO master_host = '127.0.0.1', master_port = $MASTER_MYPORT; +--source include/start_slave.inc +--source include/wait_for_slave_to_start.inc +--enable_connect_log + +connection server_3; +--disable_connect_log +--source include/stop_slave.inc +--replace_result $SLAVE_MYPORT SLAVE_MYPORT +eval CHANGE MASTER TO master_host = '127.0.0.1', master_port = $SLAVE_MYPORT; +--source include/start_slave.inc +--source include/sync_with_master_gtid.inc +--enable_connect_log + +connection server_4; +--disable_connect_log +--source include/stop_slave.inc +--replace_result $SERVER_MYPORT_3 SERVER_MYPORT_3 +eval CHANGE MASTER TO master_host = '127.0.0.1', master_port = $SERVER_MYPORT_3; +--source include/start_slave.inc +--enable_connect_log + +connection server_1; +DROP TABLE t1,t2; +--disable_connect_log +--source include/save_master_gtid.inc +--enable_connect_log + +--echo *** A few more checks for BINLOG_GTID_POS function *** +--let $valid_binlog_name = query_get_value(SHOW BINARY LOGS,Log_name,1) +--error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT +SELECT BINLOG_GTID_POS(); +--error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT +SELECT BINLOG_GTID_POS('a'); +--error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT +SELECT BINLOG_GTID_POS('a',1,NULL); +SELECT BINLOG_GTID_POS(1,'a'); +SELECT BINLOG_GTID_POS(NULL,NULL); +SELECT BINLOG_GTID_POS('',1); +SELECT BINLOG_GTID_POS('a',1); +eval SELECT BINLOG_GTID_POS('$valid_binlog_name',-1); +eval SELECT BINLOG_GTID_POS('$valid_binlog_name',0); +eval SELECT BINLOG_GTID_POS('$valid_binlog_name',18446744073709551615); +eval SELECT BINLOG_GTID_POS('$valid_binlog_name',18446744073709551616); + + +--echo *** Some tests of @@GLOBAL.gtid_binlog_state *** +--connection server_2 +--disable_connect_log +--source include/sync_with_master_gtid.inc +--source include/stop_slave.inc +--enable_connect_log + +--connection server_1 +SET @old_state= @@GLOBAL.gtid_binlog_state; + +--error ER_BINLOG_MUST_BE_EMPTY +SET GLOBAL gtid_binlog_state = ''; +RESET MASTER; +SET GLOBAL gtid_binlog_state = ''; +FLUSH LOGS; +--disable_connect_log +--source include/show_binary_logs.inc +SET GLOBAL gtid_binlog_state = '0-1-10,1-2-20,0-3-30'; +--source include/show_binary_logs.inc +--let $binlog_file= master-bin.000001 +--let $binlog_start= 4 +--source include/show_binlog_events.inc +--enable_connect_log +#SELECT @@GLOBAL.gtid_binlog_pos; +#SELECT @@GLOBAL.gtid_binlog_state; +--error ER_BINLOG_MUST_BE_EMPTY +SET GLOBAL gtid_binlog_state = @old_state; +RESET MASTER; +SET GLOBAL gtid_binlog_state = @old_state; + +# Check that slave can reconnect again, despite the RESET MASTER, as we +# restored the state. + +CREATE TABLE t1 (a INT PRIMARY KEY); +SET gtid_seq_no=100; +INSERT INTO t1 VALUES (1); +--disable_connect_log +--source include/save_master_gtid.inc +--enable_connect_log + +--connection server_2 +--disable_connect_log +--source include/start_slave.inc +--enable_connect_log +# We cannot just use sync_with_master as we've done RESET MASTER, so +# slave old-style position is wrong. +# So sync on gtid position instead. +--disable_connect_log +--source include/sync_with_master_gtid.inc +--enable_connect_log + +SELECT * FROM t1; +# Check that the IO gtid position in SHOW SLAVE STATUS is also correct. +--let $status_items= Gtid_IO_Pos +--disable_connect_log +--source include/show_slave_status.inc +--enable_connect_log + +--echo *** Test @@LAST_GTID and MASTER_GTID_WAIT() *** + +--connection server_1 +DROP TABLE t1; +CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB; +--save_master_pos + +--connection server_2 +--sync_with_master +--disable_connect_log +--source include/stop_slave.inc +--enable_connect_log + +--connect (m1,127.0.0.1,root,,test,$SERVER_MYPORT_1,) +SELECT @@last_gtid; +SET gtid_seq_no=110; +SELECT @@last_gtid; +BEGIN; +SELECT @@last_gtid; +INSERT INTO t1 VALUES (2); +SELECT @@last_gtid; +COMMIT; +SELECT @@last_gtid; +--let $pos= `SELECT @@gtid_binlog_pos` + +--connect (s1,127.0.0.1,root,,test,$SERVER_MYPORT_2,) +eval SET @pos= '$pos'; +# Check NULL argument. +SELECT master_gtid_wait(NULL); +# Check empty argument returns immediately. +SELECT master_gtid_wait('', NULL); +# Check this gets counted +SHOW STATUS LIKE 'Master_gtid_wait_count'; +SHOW STATUS LIKE 'Master_gtid_wait_timeouts'; +SHOW STATUS LIKE 'Master_gtid_wait_time'; +# Let's check that we get a timeout +SELECT master_gtid_wait(@pos, 0.5); +SELECT * FROM t1 ORDER BY a; +# Now actually wait until the slave reaches the position +send SELECT master_gtid_wait(@pos); + +--connection server_2 +--disable_connect_log +--source include/start_slave.inc +--enable_connect_log + +--connection s1 +reap; +SELECT * FROM t1 ORDER BY a; + +# Test waiting on a domain that does not exist yet. +--disable_connect_log +--source include/stop_slave.inc +--enable_connect_log + +--connection server_1 +SET gtid_domain_id= 1; +INSERT INTO t1 VALUES (3); +--let $pos= `SELECT @@gtid_binlog_pos` + +--connection s1 +--replace_result $pos POS +eval SET @pos= '$pos'; +SELECT master_gtid_wait(@pos, 0); +SELECT * FROM t1 WHERE a >= 3; +send SELECT master_gtid_wait(@pos, -1); + +--connection server_2 +--disable_connect_log +--source include/start_slave.inc +--enable_connect_log + +--connection s1 +reap; +SELECT * FROM t1 WHERE a >= 3; +# Waiting for only part of the position. +SELECT master_gtid_wait('1-1-1', 0); + +# Now test a lot of parallel master_gtid_wait() calls, completing in different +# order, and some of which time out or get killed on the way. + +--connection s1 +send SELECT master_gtid_wait('2-1-1,1-1-4,0-1-110'); + +--connect (s2,127.0.0.1,root,,test,$SERVER_MYPORT_2,) +# This will time out. No event 0-1-1000 exists +send SELECT master_gtid_wait('0-1-1000', 0.5); + +--connect (s3,127.0.0.1,root,,test,$SERVER_MYPORT_2,) +# This one we will kill +--let $kill1_id= `SELECT connection_id()` +send SELECT master_gtid_wait('0-1-2000'); + +--connect (s4,127.0.0.1,root,,test,$SERVER_MYPORT_2,) +send SELECT master_gtid_wait('2-1-10'); + +--connect (s5,127.0.0.1,root,,test,$SERVER_MYPORT_2,) +send SELECT master_gtid_wait('2-1-6', 1); + +# This one we will kill also. +--connect (s6,127.0.0.1,root,,test,$SERVER_MYPORT_2,) +--let $kill2_id= `SELECT connection_id()` +send SELECT master_gtid_wait('2-1-5'); + +--connect (s7,127.0.0.1,root,,test,$SERVER_MYPORT_2,) +send SELECT master_gtid_wait('2-1-10'); + +--connect (s8,127.0.0.1,root,,test,$SERVER_MYPORT_2,) +send SELECT master_gtid_wait('2-1-5,1-1-4,0-1-110'); + +--connect (s9,127.0.0.1,root,,test,$SERVER_MYPORT_2,) +send SELECT master_gtid_wait('2-1-2'); + +--connection server_2 +# This one completes immediately. +SHOW STATUS LIKE 'Master_gtid_wait_timeouts'; +SHOW STATUS LIKE 'Master_gtid_wait_count'; +SELECT master_gtid_wait('1-1-1'); +SHOW STATUS LIKE 'Master_gtid_wait_timeouts'; +SHOW STATUS LIKE 'Master_gtid_wait_count'; +let $wait_time = query_get_value(SHOW STATUS LIKE 'Master_gtid_wait_time', Value, 1); +--replace_result $wait_time MASTER_GTID_WAIT_TIME +eval SET @a= $wait_time; +SELECT IF(@a <= 100*1000*1000, "OK", CONCAT("Error: wait time ", @a, " is larger than expected")) + AS Master_gtid_wait_time_as_expected; + + +--connect (s10,127.0.0.1,root,,test,$SERVER_MYPORT_2,) +send SELECT master_gtid_wait('0-1-109'); + +--connection server_2 +# This one should time out. +SHOW STATUS LIKE 'Master_gtid_wait_timeouts'; +SHOW STATUS LIKE 'Master_gtid_wait_count'; +SELECT master_gtid_wait('2-1-2', 0.5); +SHOW STATUS LIKE 'Master_gtid_wait_timeouts'; +SHOW STATUS LIKE 'Master_gtid_wait_count'; +let $wait_time = query_get_value(SHOW STATUS LIKE 'Master_gtid_wait_time', Value, 1); +--replace_result $wait_time MASTER_GTID_WAIT_TIME +eval SET @a= $wait_time; +# We expect a wait time of just a bit over 0.5 seconds. But thread scheduling +# and timer inaccuracies could introduce significant jitter. So allow a +# generous interval. +SELECT IF(@a BETWEEN 0.4*1000*1000 AND 100*1000*1000, "OK", CONCAT("Error: wait time ", @a, " not as expected")) AS Master_gtid_wait_time_as_expected; + +--replace_result $kill1_id KILL_ID +eval KILL QUERY $kill1_id; +--connection s3 +--error ER_QUERY_INTERRUPTED +reap; + +--connection server_1 +SET gtid_domain_id=2; +SET gtid_seq_no=2; +INSERT INTO t1 VALUES (4); + +--connection s9 +reap; + +--connection server_2 +--replace_result $kill2_id KILL_ID +eval KILL CONNECTION $kill2_id; + +--connection s6 +--error 2013,ER_CONNECTION_KILLED +reap; + +--connection server_1 +SET gtid_domain_id=1; +SET gtid_seq_no=4; +INSERT INTO t1 VALUES (5); +SET gtid_domain_id=2; +SET gtid_seq_no=5; +INSERT INTO t1 VALUES (6); + +--connection s8 +reap; +--connection s1 +reap; +--connection s2 +reap; +--connection s5 +reap; +--connection s10 +reap; + +--connection server_1 +SET gtid_domain_id=2; +SET gtid_seq_no=10; +INSERT INTO t1 VALUES (7); + +--connection s4 +reap; +--connection s7 +reap; + + +--echo *** Test gtid_slave_pos when used with GTID *** + +--connection server_2 +--disable_connect_log +--source include/stop_slave.inc +--enable_connect_log + +--connection server_1 +SET gtid_domain_id=2; +SET gtid_seq_no=1000; +INSERT INTO t1 VALUES (10); +INSERT INTO t1 VALUES (11); +--save_master_pos + +--connection server_2 +SET sql_slave_skip_counter= 1; +--disable_connect_log +--source include/start_slave.inc +--enable_connect_log +--sync_with_master +SELECT * FROM t1 WHERE a >= 10 ORDER BY a; +SELECT IF(LOCATE("2-1-1001", @@GLOBAL.gtid_slave_pos)>0, "Ok", CONCAT("ERROR! expected GTID 2-1-1001 not found in gtid_slave_pos: ", @@GLOBAL.gtid_slave_pos)) AS status; + +--disable_connect_log +--source include/stop_slave.inc +--enable_connect_log + +--connection server_1 +SET gtid_domain_id=2; +SET gtid_seq_no=1010; +INSERT INTO t1 VALUES (12); +INSERT INTO t1 VALUES (13); +--save_master_pos + +--connection server_2 +SET sql_slave_skip_counter= 2; +--disable_connect_log +--source include/start_slave.inc +--enable_connect_log +--sync_with_master +SELECT * FROM t1 WHERE a >= 10 ORDER BY a; +SELECT IF(LOCATE("2-1-1011", @@GLOBAL.gtid_slave_pos)>0, "Ok", CONCAT("ERROR! expected GTID 2-1-1011 not found in gtid_slave_pos: ", @@GLOBAL.gtid_slave_pos)) AS status; + +--disable_connect_log +--source include/stop_slave.inc +--enable_connect_log + +--connection server_1 +SET gtid_domain_id=2; +SET gtid_seq_no=1020; +INSERT INTO t1 VALUES (14); +INSERT INTO t1 VALUES (15); +INSERT INTO t1 VALUES (16); +--save_master_pos + +--connection server_2 +SET sql_slave_skip_counter= 3; +--disable_connect_log +--source include/start_slave.inc +--enable_connect_log +--sync_with_master +SELECT * FROM t1 WHERE a >= 10 ORDER BY a; +SELECT IF(LOCATE("2-1-1022", @@GLOBAL.gtid_slave_pos)>0, "Ok", CONCAT("ERROR! expected GTID 2-1-1022 not found in gtid_slave_pos: ", @@GLOBAL.gtid_slave_pos)) AS status; + +--disable_connect_log +--source include/stop_slave.inc +--enable_connect_log + +--connection server_1 +SET gtid_domain_id=2; +SET gtid_seq_no=1030; +INSERT INTO t1 VALUES (17); +INSERT INTO t1 VALUES (18); +INSERT INTO t1 VALUES (19); +--save_master_pos + +--connection server_2 +SET sql_slave_skip_counter= 5; +--disable_connect_log +--source include/start_slave.inc +--enable_connect_log +--sync_with_master +SELECT * FROM t1 WHERE a >= 10 ORDER BY a; +SELECT IF(LOCATE("2-1-1032", @@GLOBAL.gtid_slave_pos)>0, "Ok", CONCAT("ERROR! expected GTID 2-1-1032 not found in gtid_slave_pos: ", @@GLOBAL.gtid_slave_pos)) AS status; + + +--disable_connect_log +--source include/stop_slave.inc +--enable_connect_log + +--connection server_1 +SET gtid_domain_id=3; +SET gtid_seq_no=100; +CREATE TABLE t2 (a INT PRIMARY KEY); +DROP TABLE t2; +SET gtid_domain_id=2; +SET gtid_seq_no=1040; +INSERT INTO t1 VALUES (20); +--save_master_pos + +--connection server_2 +SET @saved_mode= @@GLOBAL.slave_ddl_exec_mode; +SET GLOBAL slave_ddl_exec_mode=STRICT; +SET sql_slave_skip_counter=1; +START SLAVE UNTIL master_gtid_pos="3-1-100"; +--let $master_pos=3-1-100 +--disable_connect_log +--source include/sync_with_master_gtid.inc +--source include/wait_for_slave_to_stop.inc +--enable_connect_log +--error ER_NO_SUCH_TABLE +SELECT * FROM t2; +SELECT IF(LOCATE("3-1-100", @@GLOBAL.gtid_slave_pos)>0, "Ok", CONCAT("ERROR! expected GTID 3-1-100 not found in gtid_slave_pos: ", @@GLOBAL.gtid_slave_pos)) AS status; + +# Start the slave again, it should fail on the DROP TABLE as the table is not there. +SET sql_log_bin=0; +CALL mtr.add_suppression("Slave: Unknown table 'test\\.t2' Error_code: 1051"); +SET sql_log_bin=1; +START SLAVE; +--let $slave_sql_errno=1051 +--disable_connect_log +--source include/wait_for_slave_sql_error.inc +--enable_connect_log +SELECT IF(LOCATE("3-1-100", @@GLOBAL.gtid_slave_pos)>0, "Ok", CONCAT("ERROR! expected GTID 3-1-100 not found in gtid_slave_pos: ", @@GLOBAL.gtid_slave_pos)) AS status; + +STOP SLAVE IO_THREAD; +SET sql_slave_skip_counter=2; +--disable_connect_log +--source include/start_slave.inc +--enable_connect_log +--sync_with_master + +SELECT * FROM t1 WHERE a >= 20 ORDER BY a; +SELECT IF(LOCATE("3-1-101", @@GLOBAL.gtid_slave_pos)>0, "Ok", CONCAT("ERROR! expected GTID 3-1-101 not found in gtid_slave_pos: ", @@GLOBAL.gtid_slave_pos)) AS status; +SELECT IF(LOCATE("2-1-1040", @@GLOBAL.gtid_slave_pos)>0, "Ok", CONCAT("ERROR! expected GTID 2-1-1040 not found in gtid_slave_pos: ", @@GLOBAL.gtid_slave_pos)) AS status; + +SET GLOBAL slave_ddl_exec_mode= @saved_mode; + + +--echo *** Test GTID-connecting to a master with out-of-order sequence numbers in the binlog. *** + +# Create an out-of-order binlog on server 2. +# Let server 3 replicate to an out-of-order point, stop it, restart it, +# and check that it replicates correctly despite the out-of-order. + +--connection server_1 +SET gtid_domain_id= @@GLOBAL.gtid_domain_id; +INSERT INTO t1 VALUES (31); +--save_master_pos + +--connection server_2 +--sync_with_master +SET gtid_domain_id= @@GLOBAL.gtid_domain_id; +INSERT INTO t1 VALUES (32); + +--connection server_1 +INSERT INTO t1 VALUES (33); +--save_master_pos + +--connection server_2 +--sync_with_master +--save_master_pos + +--connection server_3 +--sync_with_master +--disable_connect_log +--source include/stop_slave.inc +--enable_connect_log + +--connection server_1 +INSERT INTO t1 VALUES (34); +--save_master_pos + +--connection server_2 +--sync_with_master +--save_master_pos + +--connection server_3 +--disable_connect_log +--source include/start_slave.inc +--enable_connect_log +--sync_with_master +SELECT * FROM t1 WHERE a >= 30 ORDER BY a; +--save_master_pos + +--connection server_4 +--sync_with_master +SELECT * FROM t1 WHERE a >= 30 ORDER BY a; + + +# Clean up. +--connection server_1 +DROP TABLE t1; + + +--disable_connect_log +--source include/rpl_end.inc diff --git a/mysql-test/suite/binlog_encryption/rpl_incident.cnf b/mysql-test/suite/binlog_encryption/rpl_incident.cnf new file mode 100644 index 0000000..7294976 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_incident.cnf @@ -0,0 +1,7 @@ +!include my.cnf + +[mysqld.1] +binlog_checksum=NONE + +[mysqld.2] +binlog_checksum=NONE diff --git a/mysql-test/suite/binlog_encryption/rpl_incident.result b/mysql-test/suite/binlog_encryption/rpl_incident.result new file mode 100644 index 0000000..ab1aa50 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_incident.result @@ -0,0 +1,42 @@ +include/master-slave.inc +[connection master] +RESET MASTER; +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1),(2),(3); +SELECT * FROM t1; +a +1 +2 +3 +SET GLOBAL debug_dbug= '+d,incident_database_resync_on_replace,*'; +REPLACE INTO t1 VALUES (4); +SELECT * FROM t1; +a +1 +2 +3 +4 +connection slave; +call mtr.add_suppression("Slave SQL.*The incident LOST_EVENTS occurred on the master.* 1590"); +include/wait_for_slave_sql_error.inc [errno=1590] +Last_SQL_Error = 'The incident LOST_EVENTS occurred on the master. Message: <none>' +SELECT * FROM t1; +a +1 +2 +3 +SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1; +START SLAVE; +SELECT * FROM t1; +a +1 +2 +3 +4 +connection master; +DROP TABLE t1; +FLUSH LOGS; +Contain RELOAD DATABASE +1 +connection slave; +include/rpl_end.inc diff --git a/mysql-test/suite/binlog_encryption/rpl_incident.test b/mysql-test/suite/binlog_encryption/rpl_incident.test new file mode 100644 index 0000000..a069a01 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_incident.test @@ -0,0 +1,72 @@ +# +# The test is a combination of rpl.rpl_incident and binlog.binlog_incident +# tests, with some modifications in each +# + +--source include/master-slave.inc +--source include/have_debug.inc + +--enable_connect_log + +RESET MASTER; + +--let $binlog_start_pos= query_get_value(SHOW MASTER STATUS,Position,1) +--let $binlog_file= query_get_value(SHOW MASTER STATUS,File,1) + +CREATE TABLE t1 (a INT); + +INSERT INTO t1 VALUES (1),(2),(3); +SELECT * FROM t1; + +let $debug_save= `SELECT @@GLOBAL.debug`; +SET GLOBAL debug_dbug= '+d,incident_database_resync_on_replace,*'; + +# This will generate an incident log event and store it in the binary +# log before the replace statement. +REPLACE INTO t1 VALUES (4); +--save_master_pos +SELECT * FROM t1; + +--disable_query_log +eval SET GLOBAL debug_dbug= '$debug_save'; +--enable_query_log + +connection slave; +# Wait until SQL thread stops with error LOST_EVENT on master +call mtr.add_suppression("Slave SQL.*The incident LOST_EVENTS occurred on the master.* 1590"); +let $slave_sql_errno= 1590; +let $show_slave_sql_error= 1; +--disable_query_log +source include/wait_for_slave_sql_error.inc; +--enable_query_log + +# The 4 should not be inserted into the table, since the incident log +# event should have stop the slave. +SELECT * FROM t1; + +SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1; +START SLAVE; +--sync_with_master + +# Now, we should have inserted the row into the table and the slave +# should be running. We should also have rotated to a new binary log. + +SELECT * FROM t1; + +connection master; + +DROP TABLE t1; +FLUSH LOGS; + +exec $MYSQL_BINLOG --read-from-remote-server --port=$MASTER_MYPORT --protocol=tcp -uroot --start-position=$binlog_start_pos $binlog_file + +remove_file $MYSQLTEST_VARDIR/tmp/binlog_incident.sql; + +--sync_slave_with_master + +--disable_connect_log + +--source include/rpl_end.inc diff --git a/mysql-test/suite/binlog_encryption/rpl_init_slave_errors.result b/mysql-test/suite/binlog_encryption/rpl_init_slave_errors.result new file mode 100644 index 0000000..9174281 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_init_slave_errors.result @@ -0,0 +1,22 @@ +include/master-slave.inc +[connection master] +connection slave; +stop slave; +reset slave; +connection slave; +SET GLOBAL debug_dbug= "d,simulate_io_slave_error_on_init,simulate_sql_slave_error_on_init"; +start slave; +include/wait_for_slave_sql_error.inc [errno=1593] +Last_SQL_Error = 'Failed during slave thread initialization' +call mtr.add_suppression("Failed during slave.* thread initialization"); +SET GLOBAL debug_dbug= ""; +connection slave; +reset slave; +SET GLOBAL init_slave= "garbage"; +start slave; +include/wait_for_slave_sql_error.inc [errno=1064] +Last_SQL_Error = 'Slave SQL thread aborted. Can't execute init_slave query' +SET GLOBAL init_slave= ""; +include/stop_slave_io.inc +RESET SLAVE; +include/rpl_end.inc diff --git a/mysql-test/suite/binlog_encryption/rpl_init_slave_errors.test b/mysql-test/suite/binlog_encryption/rpl_init_slave_errors.test new file mode 100644 index 0000000..8447852 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_init_slave_errors.test @@ -0,0 +1,100 @@ +# +# The test was taken from the rpl suite as is +# + +###################################################################### +# Some errors that cause the slave SQL thread to stop are not shown in +# the Slave_SQL_Error column of "SHOW SLAVE STATUS". Instead, the error +# is only in the server's error log. +# +# Two failures and their respective reporting are verified: +# +# 1 - Failures during slave thread initialization +# 2 - Failures while processing queries passed through the init_slave +# option. +# +# In order to check the first type of failure, we inject a fault in the +# SQL/IO Threads through SET GLOBAL debug. +# +# To check the second type, we set @@global.init_slave to an invalid +# command thus preventing the initialization of the SQL Thread. +# +# Obs: +# 1 - Note that testing failures while initializing the relay log position +# is hard as the same function is called before the code reaches the point +# that we want to test. +# +# 2 - This test does not target failures that are reported while applying +# events such as duplicate keys, errors while reading the relay-log.bin*, +# etc. Such errors are already checked on other tests. +###################################################################### + +###################################################################### +# Configuring the Environment +###################################################################### +source include/have_debug.inc; +source include/master-slave.inc; +source include/have_log_bin.inc; + +--enable_connect_log + +connection slave; + +--disable_warnings +stop slave; +--enable_warnings +reset slave; + +###################################################################### +# Injecting faults in the threads' initialization +###################################################################### +connection slave; + +# Set debug flags on slave to force errors to occur +SET GLOBAL debug_dbug= "d,simulate_io_slave_error_on_init,simulate_sql_slave_error_on_init"; + +start slave; + +# +# slave is going to stop because of emulated failures +# but there won't be any crashes nor asserts hit. +# +# 1593 = ER_SLAVE_FATAL_ERROR +--let $slave_sql_errno= 1593 +--let $show_slave_sql_error= 1 +--disable_connect_log +--source include/wait_for_slave_sql_error.inc +--enable_connect_log + +call mtr.add_suppression("Failed during slave.* thread initialization"); + +SET GLOBAL debug_dbug= ""; + +###################################################################### +# Injecting faults in the init_slave option +###################################################################### +connection slave; + +reset slave; + +SET GLOBAL init_slave= "garbage"; + +start slave; +# 1064 = ER_PARSE_ERROR +--let $slave_sql_errno= 1064 +--let $show_slave_sql_error= 1 +--disable_connect_log +--source include/wait_for_slave_sql_error.inc +--enable_connect_log + +###################################################################### +# Clean up +###################################################################### +SET GLOBAL init_slave= ""; + +# Clean up Last_SQL_Error +--disable_connect_log +--source include/stop_slave_io.inc +RESET SLAVE; +--let $rpl_only_running_threads= 1 +--source include/rpl_end.inc diff --git a/mysql-test/suite/binlog_encryption/rpl_loaddata_local.result b/mysql-test/suite/binlog_encryption/rpl_loaddata_local.result new file mode 100644 index 0000000..f0d24df --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_loaddata_local.result @@ -0,0 +1,134 @@ +include/master-slave.inc +[connection master] +create table t1(a int); +select * into outfile 'MYSQLD_DATADIR/rpl_loaddatalocal.select_outfile' from t1; +truncate table t1; +load data local infile 'MYSQLD_DATADIR/rpl_loaddatalocal.select_outfile' into table t1; +connection slave; +select a,count(*) from t1 group by a; +a count(*) +1 10000 +connection master; +drop table t1; +connection slave; +connection master; +create table t1(a int); +insert into t1 values (1), (2), (2), (3); +select * into outfile 'MYSQLD_DATADIR/rpl_loaddatalocal.select_outfile' from t1; +drop table t1; +create table t1(a int primary key); +load data local infile 'MYSQLD_DATADIR/rpl_loaddatalocal.select_outfile' into table t1; +Warnings: +Warning 1062 Duplicate entry '2' for key 'PRIMARY' +SELECT * FROM t1 ORDER BY a; +a +1 +2 +3 +connection slave; +SELECT * FROM t1 ORDER BY a; +a +1 +2 +3 +connection master; +drop table t1; +connection slave; +==== Bug22504 Initialize ==== +connection master; +SET sql_mode='ignore_space'; +CREATE TABLE t1(a int); +insert into t1 values (1), (2), (3), (4); +select * into outfile 'MYSQLD_DATADIR/rpl_loaddatalocal.select_outfile' from t1; +truncate table t1; +load data local infile 'MYSQLD_DATADIR/rpl_loaddatalocal.select_outfile' into table t1; +SELECT * FROM t1 ORDER BY a; +a +1 +2 +3 +4 +connection slave; +SELECT * FROM t1 ORDER BY a; +a +1 +2 +3 +4 +==== Clean up ==== +connection master; +DROP TABLE t1; +connection slave; + +Bug #43746: +"return wrong query string when parse 'load data infile' sql statement" + +connection master; +SELECT @@SESSION.sql_mode INTO @old_mode; +SET sql_mode='ignore_space'; +CREATE TABLE t1(a int); +INSERT INTO t1 VALUES (1), (2), (3), (4); +SELECT * INTO OUTFILE 'MYSQLD_DATADIR/bug43746.sql' FROM t1; +TRUNCATE TABLE t1; +LOAD DATA LOCAL INFILE 'MYSQLD_DATADIR/bug43746.sql' INTO TABLE t1; +LOAD/* look mum, with comments in weird places! */DATA/* oh hai */LOCAL INFILE 'MYSQLD_DATADIR/bug43746.sql'/* we are */INTO/* from the internets */TABLE t1; +LOAD DATA/*!10000 LOCAL */INFILE 'MYSQLD_DATADIR/bug43746.sql' INTO TABLE t1; +LOAD DATA LOCAL INFILE 'MYSQLD_DATADIR/bug43746.sql' /*!10000 INTO */ TABLE t1; +LOAD DATA LOCAL INFILE 'MYSQLD_DATADIR/bug43746.sql' /*!10000 INTO TABLE */ t1; +LOAD DATA /*!10000 LOCAL INFILE 'MYSQLD_DATADIR/bug43746.sql' INTO TABLE */ t1; +LOAD DATA/*!10000 LOCAL */INFILE 'MYSQLD_DATADIR/bug43746.sql'/*!10000 INTO*/TABLE t1; +LOAD DATA/*!10000 LOCAL */INFILE 'MYSQLD_DATADIR/bug43746.sql'/* empty */INTO TABLE t1; +LOAD DATA/*!10000 LOCAL */INFILE 'MYSQLD_DATADIR/bug43746.sql' INTO/* empty */TABLE t1; +LOAD/*!999999 special comments that do not expand */DATA/*!999999 code from the future */LOCAL INFILE 'MYSQLD_DATADIR/bug43746.sql'/*!999999 have flux capacitor */INTO/*!999999 will travel */TABLE t1; +SET sql_mode='PIPES_AS_CONCAT,ANSI_QUOTES,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER'; +LOAD DATA LOCAL INFILE 'MYSQLD_DATADIR/bug43746.sql' INTO TABLE t1; +connection slave; + +Bug #59267: +"LOAD DATA LOCAL INFILE not executed on slave with SBR" + +connection master; +SELECT * INTO OUTFILE 'MYSQLD_DATADIR/bug59267.sql' FROM t1; +TRUNCATE TABLE t1; +LOAD DATA LOCAL INFILE 'MYSQLD_DATADIR/bug59267.sql' INTO TABLE t1; +SELECT 'Master', COUNT(*) FROM t1; +Master COUNT(*) +Master 44 +connection slave; +SELECT 'Slave', COUNT(*) FROM t1; +Slave COUNT(*) +Slave 44 +connection master; +DROP TABLE t1; +SET SESSION sql_mode=@old_mode; +connection slave; +connection master; + +Bug #60580/#11902767: +"statement improperly replicated crashes slave sql thread" + +connection master; +CREATE TABLE t1(f1 INT, f2 INT); +CREATE TABLE t2(f1 INT, f2 TIMESTAMP); +INSERT INTO t2 VALUES(1, '2011-03-22 21:01:28'); +INSERT INTO t2 VALUES(2, '2011-03-21 21:01:28'); +INSERT INTO t2 VALUES(3, '2011-03-20 21:01:28'); +CREATE TABLE t3 AS SELECT * FROM t2; +CREATE VIEW v1 AS SELECT * FROM t2 +WHERE f1 IN (SELECT f1 FROM t3 WHERE (t3.f2 IS NULL)); +SELECT 1 INTO OUTFILE 'MYSQLD_DATADIR/bug60580.csv' FROM DUAL; +LOAD DATA LOCAL INFILE 'MYSQLD_DATADIR/bug60580.csv' INTO TABLE t1 (@f1) SET f2 = (SELECT f1 FROM v1 WHERE f1=@f1); +SELECT * FROM t1; +f1 f2 +NULL NULL +connection slave; +SELECT * FROM t1; +f1 f2 +NULL NULL +connection master; +DROP VIEW v1; +DROP TABLE t1, t2, t3; +connection slave; +connection master; +include/rpl_end.inc +# End of 5.1 tests diff --git a/mysql-test/suite/binlog_encryption/rpl_loaddata_local.test b/mysql-test/suite/binlog_encryption/rpl_loaddata_local.test new file mode 100644 index 0000000..937ae77 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_loaddata_local.test @@ -0,0 +1,233 @@ +# +# The test was taken from the rpl suite (rpl_loaddatalocal.test) +# + +# See if "LOAD DATA LOCAL INFILE" is well replicated +# (LOAD DATA LOCAL INFILE is not written to the binlog +# the same way as LOAD DATA INFILE : Append_blocks are smaller). +# In MySQL 4.0 <4.0.12 there were 2 bugs with LOAD DATA LOCAL INFILE : +# - the loaded file was not written entirely to the master's binlog, +# only the first 4KB, 8KB or 16KB usually. +# - the loaded file's first line was not written entirely to the +# master's binlog (1st char was absent) +source include/master-slave.inc; + +--enable_connect_log + +create table t1(a int); +let $1=10000; +disable_query_log; +set SQL_LOG_BIN=0; +while ($1) +{ + insert into t1 values(1); + dec $1; +} +set SQL_LOG_BIN=1; +enable_query_log; +let $MYSQLD_DATADIR= `select @@datadir`; +--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR +eval select * into outfile '$MYSQLD_DATADIR/rpl_loaddatalocal.select_outfile' from t1; +#This will generate a 20KB file, now test LOAD DATA LOCAL +truncate table t1; +--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR +eval load data local infile '$MYSQLD_DATADIR/rpl_loaddatalocal.select_outfile' into table t1; +--remove_file $MYSQLD_DATADIR/rpl_loaddatalocal.select_outfile +sync_slave_with_master; +select a,count(*) from t1 group by a; +connection master; +drop table t1; +sync_slave_with_master; + +# End of 4.1 tests + +# +# Now let us test how well we replicate LOAD DATA LOCAL in situation when +# we met duplicates in tables to which we are adding rows. +# (It supposed that LOAD DATA LOCAL ignores such errors) +# +connection master; +create table t1(a int); +insert into t1 values (1), (2), (2), (3); +--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR +eval select * into outfile '$MYSQLD_DATADIR/rpl_loaddatalocal.select_outfile' from t1; +drop table t1; +create table t1(a int primary key); +--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR +eval load data local infile '$MYSQLD_DATADIR/rpl_loaddatalocal.select_outfile' into table t1; +--remove_file $MYSQLD_DATADIR/rpl_loaddatalocal.select_outfile +SELECT * FROM t1 ORDER BY a; +save_master_pos; +connection slave; +sync_with_master; +SELECT * FROM t1 ORDER BY a; +connection master; +drop table t1; +save_master_pos; +connection slave; +sync_with_master; + + +# +# Bug22504 load data infile sql statement in replication architecture get error +# +--echo ==== Bug22504 Initialize ==== + +--connection master + +SET sql_mode='ignore_space'; +CREATE TABLE t1(a int); +insert into t1 values (1), (2), (3), (4); +--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR +eval select * into outfile '$MYSQLD_DATADIR/rpl_loaddatalocal.select_outfile' from t1; +truncate table t1; +--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR +eval load data local infile '$MYSQLD_DATADIR/rpl_loaddatalocal.select_outfile' into table t1; +--remove_file $MYSQLD_DATADIR/rpl_loaddatalocal.select_outfile +SELECT * FROM t1 ORDER BY a; + +sync_slave_with_master; +SELECT * FROM t1 ORDER BY a; + +--echo ==== Clean up ==== + +connection master; +DROP TABLE t1; + +sync_slave_with_master; + +--echo +--echo Bug #43746: +--echo "return wrong query string when parse 'load data infile' sql statement" +--echo + +connection master; +let $MYSQLD_DATADIR= `select @@datadir`; +SELECT @@SESSION.sql_mode INTO @old_mode; + +SET sql_mode='ignore_space'; + +CREATE TABLE t1(a int); +INSERT INTO t1 VALUES (1), (2), (3), (4); + +--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR +eval SELECT * INTO OUTFILE '$MYSQLD_DATADIR/bug43746.sql' FROM t1; +TRUNCATE TABLE t1; + +--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR +eval LOAD DATA LOCAL INFILE '$MYSQLD_DATADIR/bug43746.sql' INTO TABLE t1; + +--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR +eval LOAD/* look mum, with comments in weird places! */DATA/* oh hai */LOCAL INFILE '$MYSQLD_DATADIR/bug43746.sql'/* we are */INTO/* from the internets */TABLE t1; + +--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR +eval LOAD DATA/*!10000 LOCAL */INFILE '$MYSQLD_DATADIR/bug43746.sql' INTO TABLE t1; + +--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR +eval LOAD DATA LOCAL INFILE '$MYSQLD_DATADIR/bug43746.sql' /*!10000 INTO */ TABLE t1; + +--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR +eval LOAD DATA LOCAL INFILE '$MYSQLD_DATADIR/bug43746.sql' /*!10000 INTO TABLE */ t1; + +--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR +eval LOAD DATA /*!10000 LOCAL INFILE '$MYSQLD_DATADIR/bug43746.sql' INTO TABLE */ t1; + +--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR +eval LOAD DATA/*!10000 LOCAL */INFILE '$MYSQLD_DATADIR/bug43746.sql'/*!10000 INTO*/TABLE t1; + +--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR +eval LOAD DATA/*!10000 LOCAL */INFILE '$MYSQLD_DATADIR/bug43746.sql'/* empty */INTO TABLE t1; + +--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR +eval LOAD DATA/*!10000 LOCAL */INFILE '$MYSQLD_DATADIR/bug43746.sql' INTO/* empty */TABLE t1; + +--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR +eval LOAD/*!999999 special comments that do not expand */DATA/*!999999 code from the future */LOCAL INFILE '$MYSQLD_DATADIR/bug43746.sql'/*!999999 have flux capacitor */INTO/*!999999 will travel */TABLE t1; + +SET sql_mode='PIPES_AS_CONCAT,ANSI_QUOTES,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER'; + +--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR +eval LOAD DATA LOCAL INFILE '$MYSQLD_DATADIR/bug43746.sql' INTO TABLE t1; + +sync_slave_with_master; + +--echo +--echo Bug #59267: +--echo "LOAD DATA LOCAL INFILE not executed on slave with SBR" +--echo + +connection master; + +--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR +eval SELECT * INTO OUTFILE '$MYSQLD_DATADIR/bug59267.sql' FROM t1; +TRUNCATE TABLE t1; + +--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR +eval LOAD DATA LOCAL INFILE '$MYSQLD_DATADIR/bug59267.sql' INTO TABLE t1; + +SELECT 'Master', COUNT(*) FROM t1; + +--sync_slave_with_master +SELECT 'Slave', COUNT(*) FROM t1; + +# cleanup +connection master; + +--remove_file $MYSQLD_DATADIR/bug43746.sql +--remove_file $MYSQLD_DATADIR/bug59267.sql + +DROP TABLE t1; +SET SESSION sql_mode=@old_mode; + +sync_slave_with_master; + +connection master; + +--echo +--echo Bug #60580/#11902767: +--echo "statement improperly replicated crashes slave sql thread" +--echo + +connection master; +let $MYSQLD_DATADIR= `select @@datadir`; + +CREATE TABLE t1(f1 INT, f2 INT); +CREATE TABLE t2(f1 INT, f2 TIMESTAMP); + +INSERT INTO t2 VALUES(1, '2011-03-22 21:01:28'); +INSERT INTO t2 VALUES(2, '2011-03-21 21:01:28'); +INSERT INTO t2 VALUES(3, '2011-03-20 21:01:28'); + +CREATE TABLE t3 AS SELECT * FROM t2; + +CREATE VIEW v1 AS SELECT * FROM t2 + WHERE f1 IN (SELECT f1 FROM t3 WHERE (t3.f2 IS NULL)); + +--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR +eval SELECT 1 INTO OUTFILE '$MYSQLD_DATADIR/bug60580.csv' FROM DUAL; + +--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR +eval LOAD DATA LOCAL INFILE '$MYSQLD_DATADIR/bug60580.csv' INTO TABLE t1 (@f1) SET f2 = (SELECT f1 FROM v1 WHERE f1=@f1); + +SELECT * FROM t1; + +sleep 1; + +sync_slave_with_master; + +SELECT * FROM t1; + +--remove_file $MYSQLD_DATADIR/bug60580.csv + +connection master; + +DROP VIEW v1; +DROP TABLE t1, t2, t3; + +sync_slave_with_master; + +connection master; +--disable_connect_log +--source include/rpl_end.inc + +--echo # End of 5.1 tests diff --git a/mysql-test/suite/binlog_encryption/rpl_loadfile.result b/mysql-test/suite/binlog_encryption/rpl_loadfile.result new file mode 100644 index 0000000..e6f2a37 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_loadfile.result @@ -0,0 +1,262 @@ +include/master-slave.inc +[connection master] +connection master; +DROP PROCEDURE IF EXISTS test.p1; +DROP TABLE IF EXISTS test.t1; +CREATE TABLE test.t1 (a INT, blob_column LONGBLOB, PRIMARY KEY(a)); +INSERT INTO test.t1 VALUES(1,'test'); +UPDATE test.t1 SET blob_column=LOAD_FILE('../../std_data/words2.dat') WHERE a=1; +create procedure test.p1() +begin +INSERT INTO test.t1 VALUES(2,'test'); +UPDATE test.t1 SET blob_column=LOAD_FILE('../../std_data/words2.dat') WHERE a=2; +end| +CALL test.p1(); +SELECT * FROM test.t1 ORDER BY blob_column; +a blob_column +1 abase +abased +abasement +abasements +abases +abash +abashed +abashes +abashing +abasing +abate +abated +abatement +abatements +abater +abates +abating +Abba +abbe +abbey +abbeys +abbot +abbots +Abbott +abbreviate +abbreviated +abbreviates +abbreviating +abbreviation +abbreviations +Abby +abdomen +abdomens +abdominal +abduct +abducted +abduction +abductions +abductor +abductors +abducts +Abe +abed +Abel +Abelian +Abelson +Aberdeen +Abernathy +aberrant +aberration + +2 abase +abased +abasement +abasements +abases +abash +abashed +abashes +abashing +abasing +abate +abated +abatement +abatements +abater +abates +abating +Abba +abbe +abbey +abbeys +abbot +abbots +Abbott +abbreviate +abbreviated +abbreviates +abbreviating +abbreviation +abbreviations +Abby +abdomen +abdomens +abdominal +abduct +abducted +abduction +abductions +abductor +abductors +abducts +Abe +abed +Abel +Abelian +Abelson +Aberdeen +Abernathy +aberrant +aberration + +connection slave; +connection slave; +SELECT * FROM test.t1 ORDER BY blob_column; +a blob_column +1 abase +abased +abasement +abasements +abases +abash +abashed +abashes +abashing +abasing +abate +abated +abatement +abatements +abater +abates +abating +Abba +abbe +abbey +abbeys +abbot +abbots +Abbott +abbreviate +abbreviated +abbreviates +abbreviating +abbreviation +abbreviations +Abby +abdomen +abdomens +abdominal +abduct +abducted +abduction +abductions +abductor +abductors +abducts +Abe +abed +Abel +Abelian +Abelson +Aberdeen +Abernathy +aberrant +aberration + +2 abase +abased +abasement +abasements +abases +abash +abashed +abashes +abashing +abasing +abate +abated +abatement +abatements +abater +abates +abating +Abba +abbe +abbey +abbeys +abbot +abbots +Abbott +abbreviate +abbreviated +abbreviates +abbreviating +abbreviation +abbreviations +Abby +abdomen +abdomens +abdominal +abduct +abducted +abduction +abductions +abductor +abductors +abducts +Abe +abed +Abel +Abelian +Abelson +Aberdeen +Abernathy +aberrant +aberration + +connection master; +DROP PROCEDURE IF EXISTS test.p1; +DROP TABLE test.t1; +connection slave; +include/rpl_reset.inc +connection master; +SELECT repeat('x',20) INTO OUTFILE 'MYSQLTEST_VARDIR/tmp/bug_39701.data'; +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 (t text); +CREATE PROCEDURE p(file varchar(4096)) +BEGIN +INSERT INTO t1 VALUES (LOAD_FILE(file)); +END| +connection slave; +include/stop_slave.inc +connection master; +CALL p('MYSQLTEST_VARDIR/tmp/bug_39701.data'); +connection slave; +include/start_slave.inc +connection master; +connection slave; +include/diff_tables.inc [master:t1, slave:t1] +connection master; +DROP TABLE t1; +DROP PROCEDURE p; +include/rpl_end.inc +# +# Check that the loaded data is encrypted in the master binlog +# +# +# The next step will cause a perl error if the search does not +# meet the expectations. +# Pattern to look for: xxxxxxxxxxx +# Files to search: master-bin.0* +# Expected result: 0 +# (0 means the pattern should not be found, 1 means it should be found) +# +Did not find any occurrences of 'xxxxxxxxxxx' in master-bin.0* diff --git a/mysql-test/suite/binlog_encryption/rpl_loadfile.test b/mysql-test/suite/binlog_encryption/rpl_loadfile.test new file mode 100644 index 0000000..2452cd8 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_loadfile.test @@ -0,0 +1,137 @@ +# +# The test was taken from the rpl suite, with an additional check +# for binlog encryption at the end +# + +############################################################################# +# Original Author: JBM # +# Original Date: Aug/18/2005 # +############################################################################# +# TEST: To test the LOAD_FILE() in rbr # +############################################################################# +# Change Author: JBM +# Change Date: 2006-01-16 +########## + +# Includes +-- source include/have_binlog_format_mixed_or_row.inc +-- source include/master-slave.inc +--enable_connect_log +-- source extra/rpl_tests/rpl_loadfile.test + +# BUG#39701: Mixed binlog format does not switch to row mode on LOAD_FILE +# +# DESCRIPTION +# +# Problem: when using load_file string function and mixed binlogging format +# there was no switch to row based binlogging format. This leads +# to scenarios on which the slave replicates the statement and it +# will try to load the file from local file system, which in most +# likely it will not exist. +# +# Solution: +# Marking this function as unsafe for statement format, makes the +# statement using it to be logged in row based format. As such, data +# replicated from the master, becomes the content of the loaded file. +# Consequently, the slave receives the necessary data to complete +# the load_file instruction correctly. +# +# IMPLEMENTATION +# +# The test is implemented as follows: +# +# On Master, +# i) write to file the desired content. +# ii) create table and stored procedure with load_file +# iii) stop slave +# iii) execute load_file +# iv) remove file +# +# On Slave, +# v) start slave +# vi) sync it with master so that it gets the updates from binlog (which +# should have bin logged in row format). +# +# If the the binlog format does not change to row, then the assertion +# done in the following step fails. This happens because tables differ +# since the file does not exist anymore, meaning that when slave +# attempts to execute LOAD_FILE statement it inserts NULL on table +# instead of the same contents that the master loaded when it executed +# the procedure (which was executed when file existed). +# +# vii) assert that the contents of master and slave +# table are the same + +--disable_connect_log +--source include/rpl_reset.inc +--enable_connect_log + +connection master; +let $file= $MYSQLTEST_VARDIR/tmp/bug_39701.data; + +--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +--eval SELECT repeat('x',20) INTO OUTFILE '$file' + +disable_warnings; +DROP TABLE IF EXISTS t1; +enable_warnings; + +CREATE TABLE t1 (t text); +DELIMITER |; +CREATE PROCEDURE p(file varchar(4096)) + BEGIN + INSERT INTO t1 VALUES (LOAD_FILE(file)); + END| +DELIMITER ;| + +# stop slave before issuing the load_file on master +connection slave; +--disable_connect_log +source include/stop_slave.inc; +--enable_connect_log + +connection master; + +# test: check that logging falls back to rbr. +--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +--eval CALL p('$file') + +# test: remove the file from the filesystem and assert that slave still +# gets the loaded file +remove_file $file; + +# now that the file is removed it is safe (regarding what we want to test) +# to start slave +connection slave; +--disable_connect_log +source include/start_slave.inc; +--enable_connect_log + +connection master; +sync_slave_with_master; + +# assertion: assert that the slave got the updates even +# if the file was removed before the slave started, +# meaning that contents were indeed transfered +# through binlog (in row format) +let $diff_tables= master:t1, slave:t1; +--disable_connect_log +source include/diff_tables.inc; +--enable_connect_log + +# CLEAN UP +--connection master +DROP TABLE t1; +DROP PROCEDURE p; + +--disable_connect_log +--source include/rpl_end.inc + +--echo # +--echo # Check that the loaded data is encrypted in the master binlog +--echo # + +--let search_files=master-bin.0* +--let search_pattern= xxxxxxxxxxx +--let search_result= 0 +--source grep_binlog.inc diff --git a/mysql-test/suite/binlog_encryption/rpl_mixed_binlog_max_cache_size.result b/mysql-test/suite/binlog_encryption/rpl_mixed_binlog_max_cache_size.result new file mode 100644 index 0000000..388c8e6 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_mixed_binlog_max_cache_size.result @@ -0,0 +1,210 @@ +include/master-slave.inc +[connection master] +call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT"); +SET GLOBAL max_binlog_cache_size = 4096; +SET GLOBAL binlog_cache_size = 4096; +SET GLOBAL max_binlog_stmt_cache_size = 4096; +SET GLOBAL binlog_stmt_cache_size = 4096; +disconnect master; +connect master,127.0.0.1,root,,test,$MASTER_MYPORT,; +CREATE TABLE t1(a INT PRIMARY KEY, data VARCHAR(30000)) ENGINE=Innodb; +CREATE TABLE t2(a INT PRIMARY KEY, data VARCHAR(30000)) ENGINE=MyIsam; +CREATE TABLE t3(a INT PRIMARY KEY, data VARCHAR(30000)) ENGINE=Innodb; +######################################################################################## +# 1 - SINGLE STATEMENT +######################################################################################## +connection master; +*** Single statement on transactional table *** +Got one of the listed errors +*** Single statement on non-transactional table *** +Got one of the listed errors +include/wait_for_slave_sql_error_and_skip.inc [errno=1590] +*** Single statement on both transactional and non-transactional tables. *** +Got one of the listed errors +include/wait_for_slave_sql_error_and_skip.inc [errno=1590] +include/diff_tables.inc [master:t1,slave:t1] +######################################################################################## +# 2 - BEGIN - IMPLICIT COMMIT by DDL +######################################################################################## +connection master; +TRUNCATE TABLE t1; +TRUNCATE TABLE t2; +TRUNCATE TABLE t3; +set default_storage_engine=innodb; +BEGIN; +Got one of the listed errors +Got one of the listed errors +Got one of the listed errors +INSERT INTO t1 (a, data) VALUES (7, 's');; +INSERT INTO t2 (a, data) VALUES (8, 's');; +INSERT INTO t1 (a, data) VALUES (9, 's');; +ALTER TABLE t3 ADD COLUMN d int; +BEGIN; +Got one of the listed errors +Got one of the listed errors +INSERT INTO t1 (a, data) VALUES (19, 's');; +INSERT INTO t2 (a, data) VALUES (20, 's');; +INSERT INTO t1 (a, data) VALUES (21, 's');; +CREATE TABLE t4 SELECT * FROM t1; +BEGIN; +Got one of the listed errors +Got one of the listed errors +INSERT INTO t1 (a, data) VALUES (27, 's');; +INSERT INTO t2 (a, data) VALUES (28, 's');; +INSERT INTO t1 (a, data) VALUES (29, 's');; +CREATE TABLE t5 (a int); +connection slave; +include/diff_tables.inc [master:t1,slave:t1] +######################################################################################## +# 3 - BEGIN - COMMIT +######################################################################################## +connection master; +TRUNCATE TABLE t1; +TRUNCATE TABLE t2; +TRUNCATE TABLE t3; +BEGIN; +Got one of the listed errors +Got one of the listed errors +Got one of the listed errors +COMMIT; +connection slave; +include/diff_tables.inc [master:t1,slave:t1] +######################################################################################## +# 4 - BEGIN - ROLLBACK +######################################################################################## +connection master; +TRUNCATE TABLE t1; +TRUNCATE TABLE t2; +TRUNCATE TABLE t3; +BEGIN; +Got one of the listed errors +Got one of the listed errors +Got one of the listed errors +ROLLBACK; +Warnings: +Warning 1196 Some non-transactional changed tables couldn't be rolled back +connection slave; +include/diff_tables.inc [master:t1,slave:t1] +######################################################################################## +# 5 - PROCEDURE +######################################################################################## +connection master; +TRUNCATE TABLE t1; +TRUNCATE TABLE t2; +TRUNCATE TABLE t3; +CREATE PROCEDURE p1(pd VARCHAR(30000)) +BEGIN +INSERT INTO t1 (a, data) VALUES (1, pd); +INSERT INTO t1 (a, data) VALUES (2, pd); +INSERT INTO t1 (a, data) VALUES (3, pd); +INSERT INTO t1 (a, data) VALUES (4, pd); +INSERT INTO t1 (a, data) VALUES (5, 's'); +END// +TRUNCATE TABLE t1; +TRUNCATE TABLE t1; +BEGIN; +Got one of the listed errors +COMMIT; +TRUNCATE TABLE t1; +BEGIN; +Got one of the listed errors +ROLLBACK; +connection slave; +include/diff_tables.inc [master:t1,slave:t1] +######################################################################################## +# 6 - XID +######################################################################################## +connection master; +TRUNCATE TABLE t1; +TRUNCATE TABLE t2; +TRUNCATE TABLE t3; +BEGIN; +Got one of the listed errors +Got one of the listed errors +Got one of the listed errors +INSERT INTO t1 (a, data) VALUES (7, 's');; +INSERT INTO t2 (a, data) VALUES (8, 's');; +INSERT INTO t1 (a, data) VALUES (9, 's');; +ROLLBACK TO sv; +Warnings: +Warning 1196 Some non-transactional changed tables couldn't be rolled back +COMMIT; +connection slave; +include/diff_tables.inc [master:t1,slave:t1] +######################################################################################## +# 7 - NON-TRANS TABLE +######################################################################################## +connection master; +TRUNCATE TABLE t1; +TRUNCATE TABLE t2; +TRUNCATE TABLE t3; +BEGIN; +Got one of the listed errors +Got one of the listed errors +Got one of the listed errors +INSERT INTO t1 (a, data) VALUES (8, 's');; +INSERT INTO t1 (a, data) VALUES (9, 's');; +INSERT INTO t2 (a, data) VALUES (10, 's');; +INSERT INTO t1 (a, data) VALUES (11, 's');; +COMMIT; +BEGIN; +Got one of the listed errors +COMMIT; +connection slave; +include/diff_tables.inc [master:t1,slave:t1] +######################################################################## +# 8 - Bug#55375(Regression Bug) Transaction bigger than +# max_binlog_cache_size crashes slave +######################################################################## +# [ On Slave ] +SET GLOBAL max_binlog_cache_size = 4096; +SET GLOBAL binlog_cache_size = 4096; +SET GLOBAL max_binlog_stmt_cache_size = 4096; +SET GLOBAL binlog_stmt_cache_size = 4096; +include/stop_slave.inc +include/start_slave.inc +CALL mtr.add_suppression("Multi-statement transaction required more than 'max_binlog_cache_size' bytes of storage.*"); +CALL mtr.add_suppression("Multi-statement transaction required more than 'max_binlog_stmt_cache_size' bytes of storage.*"); +CALL mtr.add_suppression("Writing one row to the row-based binary log failed.*"); +CALL mtr.add_suppression("Slave SQL.*The incident LOST_EVENTS occurred on the master. Message: error writing to the binary log"); +connection master; +TRUNCATE t1; +connection slave; +connection master; +SET GLOBAL max_binlog_cache_size= ORIGINAL_VALUE; +SET GLOBAL binlog_cache_size= ORIGINAL_VALUE; +SET GLOBAL max_binlog_stmt_cache_size= ORIGINAL_VALUE; +SET GLOBAL binlog_stmt_cache_size= ORIGINAL_VALUE; +disconnect master; +connect master,127.0.0.1,root,,test,$MASTER_MYPORT,; +BEGIN; +Repeat statement 'INSERT INTO t1 VALUES($n, repeat("a", 32))' 128 times +COMMIT; +connection slave; +include/wait_for_slave_sql_error.inc [errno=1197] +SELECT count(*) FROM t1; +count(*) +0 +include/show_binlog_events.inc +SET GLOBAL max_binlog_cache_size= ORIGINAL_VALUE; +SET GLOBAL binlog_cache_size= ORIGINAL_VALUE; +SET GLOBAL max_binlog_stmt_cache_size= ORIGINAL_VALUE; +SET GLOBAL binlog_stmt_cache_size= ORIGINAL_VALUE; +include/stop_slave.inc +include/start_slave.inc +connection master; +connection slave; +SELECT count(*) FROM t1; +count(*) +128 +######################################################################################## +# CLEAN +######################################################################################## +connection master; +DROP TABLE t1; +DROP TABLE t2; +DROP TABLE t3; +DROP TABLE IF EXISTS t4; +DROP TABLE t5; +DROP PROCEDURE p1; +include/rpl_end.inc diff --git a/mysql-test/suite/binlog_encryption/rpl_mixed_binlog_max_cache_size.test b/mysql-test/suite/binlog_encryption/rpl_mixed_binlog_max_cache_size.test new file mode 100644 index 0000000..28c43d2 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_mixed_binlog_max_cache_size.test @@ -0,0 +1,489 @@ +# +# The test was taken from the rpl suite, with some structural changes +# + +--source include/master-slave.inc +--source include/not_embedded.inc +--source include/not_windows.inc +--source include/have_binlog_format_mixed.inc + +--enable_connect_log + +######################################################################################## +# This test verifies if the binlog is not corrupted when the cache buffer is not +# big enough to accommodate the changes and is divided in five steps: +# +# 1 - Single Statements: +# 1.1 - Single statement on transactional table. +# 1.2 - Single statement on non-transactional table. +# 1.3 - Single statement on both transactional and non-transactional tables. +# In both 1.2 and 1.3, an incident event is logged to notify the user that the +# master and slave are diverging. +# +# 2 - Transactions ended by an implicit commit. +# +# 3 - Transactions ended by a COMMIT. +# +# 4 - Transactions ended by a ROLLBACK. +# +# 5 - Transactions with a failing statement that updates a non-transactional +# table. In this case, a failure means that the statement does not get into +# the cache and an incident event is logged to notify the user that the master +# and slave are diverging. +# +######################################################################################## + +call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT"); + +let $old_max_binlog_cache_size= query_get_value(SHOW VARIABLES LIKE "max_binlog_cache_size", Value, 1); +let $old_binlog_cache_size= query_get_value(SHOW VARIABLES LIKE "binlog_cache_size", Value, 1); +let $old_max_binlog_stmt_cache_size= query_get_value(SHOW VARIABLES LIKE "max_binlog_stmt_cache_size", Value, 1); +let $old_binlog_stmt_cache_size= query_get_value(SHOW VARIABLES LIKE "binlog_stmt_cache_size", Value, 1); + +SET GLOBAL max_binlog_cache_size = 4096; +SET GLOBAL binlog_cache_size = 4096; +SET GLOBAL max_binlog_stmt_cache_size = 4096; +SET GLOBAL binlog_stmt_cache_size = 4096; +disconnect master; +connect (master,127.0.0.1,root,,test,$MASTER_MYPORT,); + +CREATE TABLE t1(a INT PRIMARY KEY, data VARCHAR(30000)) ENGINE=Innodb; +CREATE TABLE t2(a INT PRIMARY KEY, data VARCHAR(30000)) ENGINE=MyIsam; +CREATE TABLE t3(a INT PRIMARY KEY, data VARCHAR(30000)) ENGINE=Innodb; + +let $data = `select concat('"', repeat('a',2000), '"')`; + +--echo ######################################################################################## +--echo # 1 - SINGLE STATEMENT +--echo ######################################################################################## + +connection master; + +--echo *** Single statement on transactional table *** +--disable_query_log +--error ER_TRANS_CACHE_FULL, ER_STMT_CACHE_FULL, ER_ERROR_ON_WRITE +eval INSERT INTO t1 (a, data) VALUES (1, + CONCAT($data, $data, $data, $data, $data)); +--enable_query_log + +--echo *** Single statement on non-transactional table *** +--disable_query_log +--error ER_TRANS_CACHE_FULL, ER_STMT_CACHE_FULL, ER_ERROR_ON_WRITE +eval INSERT INTO t2 (a, data) VALUES (2, + CONCAT($data, $data, $data, $data, $data, $data)); +--enable_query_log + +# Incident event +# 1590=ER_SLAVE_INCIDENT +--let $slave_sql_errno= 1590 +--disable_connect_log +--source include/wait_for_slave_sql_error_and_skip.inc +--enable_connect_log + +--disable_query_log +eval INSERT INTO t1 (a, data) VALUES (3, $data); +eval INSERT INTO t1 (a, data) VALUES (4, $data); +eval INSERT INTO t1 (a, data) VALUES (5, $data); +eval INSERT INTO t2 (a, data) VALUES (3, $data); +eval INSERT INTO t2 (a, data) VALUES (4, $data); +eval INSERT INTO t2 (a, data) VALUES (5, $data); +--enable_query_log + +--echo *** Single statement on both transactional and non-transactional tables. *** +--disable_query_log +--error ER_TRANS_CACHE_FULL, ER_STMT_CACHE_FULL, ER_ERROR_ON_WRITE +eval UPDATE t2, t1 SET t2.data = CONCAT($data, $data, $data, $data), + t1.data = CONCAT($data, $data, $data, $data); +--enable_query_log + +# 1590=ER_SLAVE_INCIDENT +--let $slave_sql_errno= 1590 +--let $slave_skip_counter= `SELECT IF(@@binlog_format = 'ROW', 2, 1)` +--disable_connect_log +--source include/wait_for_slave_sql_error_and_skip.inc + +--let $diff_tables= master:t1,slave:t1 +--source include/diff_tables.inc +--enable_connect_log + +--echo ######################################################################################## +--echo # 2 - BEGIN - IMPLICIT COMMIT by DDL +--echo ######################################################################################## + +connection master; +TRUNCATE TABLE t1; +TRUNCATE TABLE t2; +TRUNCATE TABLE t3; +set default_storage_engine=innodb; + +BEGIN; +--disable_query_log +--eval INSERT INTO t1 (a, data) VALUES (1, $data); +--eval INSERT INTO t1 (a, data) VALUES (2, $data); +--eval INSERT INTO t1 (a, data) VALUES (3, $data); +--error ER_TRANS_CACHE_FULL, ER_STMT_CACHE_FULL, ER_ERROR_ON_WRITE +--eval INSERT INTO t1 (a, data) VALUES (4, $data); +--error ER_TRANS_CACHE_FULL, ER_STMT_CACHE_FULL, ER_ERROR_ON_WRITE +--eval INSERT INTO t1 (a, data) VALUES (5, $data); +--error ER_TRANS_CACHE_FULL, ER_STMT_CACHE_FULL, ER_ERROR_ON_WRITE +--eval INSERT INTO t1 (a, data) VALUES (6, $data); +--enable_query_log +--eval INSERT INTO t1 (a, data) VALUES (7, 's'); +--eval INSERT INTO t2 (a, data) VALUES (8, 's'); +--eval INSERT INTO t1 (a, data) VALUES (9, 's'); + +ALTER TABLE t3 ADD COLUMN d int; + +--disable_query_log +--eval INSERT INTO t2 (a, data) VALUES (10, $data); +--eval INSERT INTO t2 (a, data) VALUES (11, $data); +--eval INSERT INTO t2 (a, data) VALUES (12, $data); +--eval INSERT INTO t2 (a, data) VALUES (13, $data); +--enable_query_log + +BEGIN; +--disable_query_log +--eval INSERT INTO t1 (a, data) VALUES (14, $data); +--eval INSERT INTO t1 (a, data) VALUES (15, $data); +--eval INSERT INTO t1 (a, data) VALUES (16, $data); +--error ER_TRANS_CACHE_FULL, ER_STMT_CACHE_FULL, ER_ERROR_ON_WRITE +--eval INSERT INTO t1 (a, data) VALUES (17, $data); +--error ER_TRANS_CACHE_FULL, ER_STMT_CACHE_FULL, ER_ERROR_ON_WRITE +--eval INSERT INTO t1 (a, data) VALUES (18, $data); +--enable_query_log +--eval INSERT INTO t1 (a, data) VALUES (19, 's'); +--eval INSERT INTO t2 (a, data) VALUES (20, 's'); +--eval INSERT INTO t1 (a, data) VALUES (21, 's'); + +if (`SELECT @@binlog_format = 'STATEMENT' || @@binlog_format = 'MIXED'`) +{ + CREATE TABLE t4 SELECT * FROM t1; +} +if (`SELECT @@binlog_format = 'ROW'`) +{ + --error ER_TRANS_CACHE_FULL, ER_STMT_CACHE_FULL, ER_ERROR_ON_WRITE + CREATE TABLE t4 SELECT * FROM t1; +} + +--disable_query_log +--eval INSERT INTO t2 (a, data) VALUES (15, $data); +--enable_query_log + +BEGIN; +--disable_query_log +--eval INSERT INTO t1 (a, data) VALUES (22, $data); +--eval INSERT INTO t1 (a, data) VALUES (23, $data); +--eval INSERT INTO t1 (a, data) VALUES (24, $data); +--error ER_TRANS_CACHE_FULL, ER_STMT_CACHE_FULL, ER_ERROR_ON_WRITE +--eval INSERT INTO t1 (a, data) VALUES (25, $data); +--error ER_TRANS_CACHE_FULL, ER_STMT_CACHE_FULL, ER_ERROR_ON_WRITE +--eval INSERT INTO t1 (a, data) VALUES (26, $data); +--enable_query_log +--eval INSERT INTO t1 (a, data) VALUES (27, 's'); +--eval INSERT INTO t2 (a, data) VALUES (28, 's'); +--eval INSERT INTO t1 (a, data) VALUES (29, 's'); + +CREATE TABLE t5 (a int); + +--sync_slave_with_master +--let $diff_tables= master:t1,slave:t1 +--disable_connect_log +--source include/diff_tables.inc +--enable_connect_log + +--echo ######################################################################################## +--echo # 3 - BEGIN - COMMIT +--echo ######################################################################################## + +connection master; +TRUNCATE TABLE t1; +TRUNCATE TABLE t2; +TRUNCATE TABLE t3; + +BEGIN; +--disable_query_log +--eval INSERT INTO t1 (a, data) VALUES (1, $data); +--eval INSERT INTO t1 (a, data) VALUES (2, $data); +--eval INSERT INTO t1 (a, data) VALUES (3, $data); +--error ER_TRANS_CACHE_FULL, ER_STMT_CACHE_FULL, ER_ERROR_ON_WRITE +--eval INSERT INTO t1 (a, data) VALUES (4, $data); +--error ER_TRANS_CACHE_FULL, ER_STMT_CACHE_FULL, ER_ERROR_ON_WRITE +--eval INSERT INTO t1 (a, data) VALUES (5, $data); +--error ER_TRANS_CACHE_FULL, ER_STMT_CACHE_FULL, ER_ERROR_ON_WRITE +--eval INSERT INTO t1 (a, data) VALUES (6, $data); +--eval INSERT INTO t1 (a, data) VALUES (7, 's'); +--eval INSERT INTO t2 (a, data) VALUES (8, 's'); +--eval INSERT INTO t1 (a, data) VALUES (9, 's'); +--enable_query_log +COMMIT; + +--sync_slave_with_master +--let $diff_tables= master:t1,slave:t1 +--disable_connect_log +--source include/diff_tables.inc +--enable_connect_log + +--echo ######################################################################################## +--echo # 4 - BEGIN - ROLLBACK +--echo ######################################################################################## + +connection master; +TRUNCATE TABLE t1; +TRUNCATE TABLE t2; +TRUNCATE TABLE t3; + +BEGIN; +--disable_query_log +--eval INSERT INTO t1 (a, data) VALUES (1, $data); +--eval INSERT INTO t1 (a, data) VALUES (2, $data); +--eval INSERT INTO t1 (a, data) VALUES (3, $data); +--error ER_TRANS_CACHE_FULL, ER_STMT_CACHE_FULL, ER_ERROR_ON_WRITE +--eval INSERT INTO t1 (a, data) VALUES (4, $data); +--error ER_TRANS_CACHE_FULL, ER_STMT_CACHE_FULL, ER_ERROR_ON_WRITE +--eval INSERT INTO t1 (a, data) VALUES (5, $data); +--error ER_TRANS_CACHE_FULL, ER_STMT_CACHE_FULL, ER_ERROR_ON_WRITE +--eval INSERT INTO t1 (a, data) VALUES (6, $data); +--eval INSERT INTO t1 (a, data) VALUES (7, 's'); +--eval INSERT INTO t2 (a, data) VALUES (8, 's'); +--eval INSERT INTO t1 (a, data) VALUES (9, 's'); +--enable_query_log +ROLLBACK; + +--sync_slave_with_master +--let $diff_tables= master:t1,slave:t1 +--disable_connect_log +--source include/diff_tables.inc +--enable_connect_log + +--echo ######################################################################################## +--echo # 5 - PROCEDURE +--echo ######################################################################################## + +connection master; +TRUNCATE TABLE t1; +TRUNCATE TABLE t2; +TRUNCATE TABLE t3; + +DELIMITER //; + +CREATE PROCEDURE p1(pd VARCHAR(30000)) +BEGIN + INSERT INTO t1 (a, data) VALUES (1, pd); + INSERT INTO t1 (a, data) VALUES (2, pd); + INSERT INTO t1 (a, data) VALUES (3, pd); + INSERT INTO t1 (a, data) VALUES (4, pd); + INSERT INTO t1 (a, data) VALUES (5, 's'); +END// + +DELIMITER ;// + +TRUNCATE TABLE t1; + +--disable_query_log +eval CALL p1($data); +--enable_query_log + +TRUNCATE TABLE t1; + +BEGIN; +--disable_query_log +--error ER_TRANS_CACHE_FULL, ER_STMT_CACHE_FULL, ER_ERROR_ON_WRITE +eval CALL p1($data); +--enable_query_log +COMMIT; + +TRUNCATE TABLE t1; + +BEGIN; +--disable_query_log +--error ER_TRANS_CACHE_FULL, ER_STMT_CACHE_FULL, ER_ERROR_ON_WRITE +eval CALL p1($data); +--enable_query_log +ROLLBACK; + +--sync_slave_with_master +--let $diff_tables= master:t1,slave:t1 +--disable_connect_log +--source include/diff_tables.inc +--enable_connect_log + +--echo ######################################################################################## +--echo # 6 - XID +--echo ######################################################################################## + +connection master; +TRUNCATE TABLE t1; +TRUNCATE TABLE t2; +TRUNCATE TABLE t3; + +BEGIN; +--disable_query_log +--eval INSERT INTO t1 (a, data) VALUES (1, $data); +--eval INSERT INTO t1 (a, data) VALUES (2, $data); +--eval INSERT INTO t1 (a, data) VALUES (3, $data); +--error ER_TRANS_CACHE_FULL, ER_STMT_CACHE_FULL, ER_ERROR_ON_WRITE +--eval INSERT INTO t1 (a, data) VALUES (4, $data); +SAVEPOINT sv; +--error ER_TRANS_CACHE_FULL, ER_STMT_CACHE_FULL, ER_ERROR_ON_WRITE +--eval INSERT INTO t1 (a, data) VALUES (5, $data); +--error ER_TRANS_CACHE_FULL, ER_STMT_CACHE_FULL, ER_ERROR_ON_WRITE +--eval INSERT INTO t1 (a, data) VALUES (6, $data); +--enable_query_log +--eval INSERT INTO t1 (a, data) VALUES (7, 's'); +--eval INSERT INTO t2 (a, data) VALUES (8, 's'); +--eval INSERT INTO t1 (a, data) VALUES (9, 's'); +ROLLBACK TO sv; +COMMIT; + +--sync_slave_with_master +--let $diff_tables= master:t1,slave:t1 +--disable_connect_log +--source include/diff_tables.inc +--enable_connect_log + +--echo ######################################################################################## +--echo # 7 - NON-TRANS TABLE +--echo ######################################################################################## + +connection master; +TRUNCATE TABLE t1; +TRUNCATE TABLE t2; +TRUNCATE TABLE t3; + +BEGIN; +--disable_query_log +--eval INSERT INTO t1 (a, data) VALUES (1, $data); +--eval INSERT INTO t1 (a, data) VALUES (2, $data); +--eval INSERT INTO t2 (a, data) VALUES (3, $data); +--eval INSERT INTO t1 (a, data) VALUES (4, $data); +--error ER_TRANS_CACHE_FULL, ER_STMT_CACHE_FULL, ER_ERROR_ON_WRITE +--eval INSERT INTO t1 (a, data) VALUES (5, $data); +--error ER_TRANS_CACHE_FULL, ER_STMT_CACHE_FULL, ER_ERROR_ON_WRITE +--eval INSERT INTO t1 (a, data) VALUES (6, $data); +--error ER_TRANS_CACHE_FULL, ER_STMT_CACHE_FULL, ER_ERROR_ON_WRITE +--eval INSERT INTO t1 (a, data) VALUES (7, $data); +--eval UPDATE t2 SET data= CONCAT($data, $data); +--enable_query_log +--eval INSERT INTO t1 (a, data) VALUES (8, 's'); +--eval INSERT INTO t1 (a, data) VALUES (9, 's'); +--eval INSERT INTO t2 (a, data) VALUES (10, 's'); +--eval INSERT INTO t1 (a, data) VALUES (11, 's'); +COMMIT; + +BEGIN; +--disable_query_log +--eval INSERT INTO t1 (a, data) VALUES (15, $data); +--eval INSERT INTO t1 (a, data) VALUES (16, $data); +--eval INSERT INTO t2 (a, data) VALUES (17, $data); +--eval INSERT INTO t1 (a, data) VALUES (18, $data); +--error ER_TRANS_CACHE_FULL, ER_STMT_CACHE_FULL, ER_ERROR_ON_WRITE +--eval INSERT INTO t1 (a, data) VALUES (19, $data); +--enable_query_log +COMMIT; + +--sync_slave_with_master +--let $diff_tables= master:t1,slave:t1 +--disable_connect_log +--source include/diff_tables.inc +--enable_connect_log + +--echo ######################################################################## +--echo # 8 - Bug#55375(Regression Bug) Transaction bigger than +--echo # max_binlog_cache_size crashes slave +--echo ######################################################################## + +--echo # [ On Slave ] +SET GLOBAL max_binlog_cache_size = 4096; +SET GLOBAL binlog_cache_size = 4096; +SET GLOBAL max_binlog_stmt_cache_size = 4096; +SET GLOBAL binlog_stmt_cache_size = 4096; + +--disable_connect_log +source include/stop_slave.inc; +source include/start_slave.inc; +--enable_connect_log +CALL mtr.add_suppression("Multi-statement transaction required more than 'max_binlog_cache_size' bytes of storage.*"); +CALL mtr.add_suppression("Multi-statement transaction required more than 'max_binlog_stmt_cache_size' bytes of storage.*"); +CALL mtr.add_suppression("Writing one row to the row-based binary log failed.*"); +CALL mtr.add_suppression("Slave SQL.*The incident LOST_EVENTS occurred on the master. Message: error writing to the binary log"); + +connection master; +TRUNCATE t1; + +sync_slave_with_master; +--let binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1) +--let binlog_file= query_get_value(SHOW MASTER STATUS, File, 1) + +connection master; +--replace_result $old_max_binlog_cache_size ORIGINAL_VALUE +--eval SET GLOBAL max_binlog_cache_size= $old_max_binlog_cache_size +--replace_result $old_binlog_cache_size ORIGINAL_VALUE +--eval SET GLOBAL binlog_cache_size= $old_binlog_cache_size +--replace_result $old_max_binlog_stmt_cache_size ORIGINAL_VALUE +--eval SET GLOBAL max_binlog_stmt_cache_size= $old_max_binlog_stmt_cache_size +--replace_result $old_binlog_stmt_cache_size ORIGINAL_VALUE +--eval SET GLOBAL binlog_stmt_cache_size= $old_binlog_stmt_cache_size +disconnect master; +connect (master,127.0.0.1,root,,test,$MASTER_MYPORT,); + +--let $n=128 +BEGIN; +--disable_query_log +--echo Repeat statement 'INSERT INTO t1 VALUES(\$n, repeat("a", 32))' $n times +while ($n) +{ + --eval INSERT INTO t1 VALUES ($n, repeat("a", 32)) + --dec $n +} +--enable_query_log +COMMIT; + +--connection slave +--let $slave_sql_errno= 1197 +if (`SELECT @@binlog_format = 'ROW'`) +{ + --let $slave_sql_errno= 1534 +} +--disable_connect_log +source include/wait_for_slave_sql_error.inc; + +SELECT count(*) FROM t1; +source include/show_binlog_events.inc; +--enable_connect_log + +--replace_result $old_max_binlog_cache_size ORIGINAL_VALUE +--eval SET GLOBAL max_binlog_cache_size= $old_max_binlog_cache_size +--replace_result $old_binlog_cache_size ORIGINAL_VALUE +--eval SET GLOBAL binlog_cache_size= $old_binlog_cache_size +--replace_result $old_max_binlog_stmt_cache_size ORIGINAL_VALUE +--eval SET GLOBAL max_binlog_stmt_cache_size= $old_max_binlog_stmt_cache_size +--replace_result $old_binlog_stmt_cache_size ORIGINAL_VALUE +--eval SET GLOBAL binlog_stmt_cache_size= $old_binlog_stmt_cache_size + +--disable_connect_log +source include/stop_slave.inc; +source include/start_slave.inc; +--enable_connect_log + +connection master; +sync_slave_with_master; +SELECT count(*) FROM t1; + +--echo ######################################################################################## +--echo # CLEAN +--echo ######################################################################################## + +connection master; +DROP TABLE t1; +DROP TABLE t2; +DROP TABLE t3; +# t4 exists only if binlog_format!=row, so so a warning is generated +# if binog_format=row +--disable_warnings +DROP TABLE IF EXISTS t4; +--enable_warnings +DROP TABLE t5; +DROP PROCEDURE p1; + +--disable_connect_log +--source include/rpl_end.inc diff --git a/mysql-test/suite/binlog_encryption/rpl_packet.cnf b/mysql-test/suite/binlog_encryption/rpl_packet.cnf new file mode 100644 index 0000000..0f01aec --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_packet.cnf @@ -0,0 +1,10 @@ +!include my.cnf + +[mysqld.1] +max_allowed_packet=1024 +net_buffer_length=1024 + +[mysqld.2] +max_allowed_packet=1024 +net_buffer_length=1024 +slave_max_allowed_packet=1024 diff --git a/mysql-test/suite/binlog_encryption/rpl_packet.result b/mysql-test/suite/binlog_encryption/rpl_packet.result new file mode 100644 index 0000000..4a2a5d7 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_packet.result @@ -0,0 +1,83 @@ +include/master-slave.inc +[connection master] +call mtr.add_suppression("Slave I/O: Got a packet bigger than 'slave_max_allowed_packet' bytes, .*error.* 1153"); +call mtr.add_suppression("Log entry on master is longer than slave_max_allowed_packet"); +drop database if exists DB_NAME_OF_MAX_LENGTH_AKA_NAME_LEN_64_BYTES_____________________; +create database DB_NAME_OF_MAX_LENGTH_AKA_NAME_LEN_64_BYTES_____________________; +connection master; +SET @@global.max_allowed_packet=1024; +SET @@global.net_buffer_length=1024; +connection slave; +include/stop_slave.inc +include/start_slave.inc +disconnect master; +connect master,localhost,root,,DB_NAME_OF_MAX_LENGTH_AKA_NAME_LEN_64_BYTES_____________________; +connection master; +select @@net_buffer_length, @@max_allowed_packet; +@@net_buffer_length @@max_allowed_packet +1024 1024 +create table `t1` (`f1` LONGTEXT) ENGINE=MyISAM; +INSERT INTO `t1`(`f1`) VALUES ('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaa aaaaaaaaaaaaaaaaaaa1023'); +connection slave; +select count(*) from `DB_NAME_OF_MAX_LENGTH_AKA_NAME_LEN_64_BYTES_____________________`.`t1` /* must be 1 */; +count(*) +1 +SHOW STATUS LIKE 'Slave_running'; +Variable_name Value +Slave_running ON +select * from information_schema.session_status where variable_name= 'SLAVE_RUNNING'; +VARIABLE_NAME VARIABLE_VALUE +SLAVE_RUNNING ON +connection master; +drop database DB_NAME_OF_MAX_LENGTH_AKA_NAME_LEN_64_BYTES_____________________; +connection slave; +connection master; +SET @@global.max_allowed_packet=4096; +SET @@global.net_buffer_length=4096; +connection slave; +include/stop_slave.inc +include/start_slave.inc +disconnect master; +connect master, localhost, root; +connection master; +CREATE TABLE `t1` (`f1` LONGTEXT) ENGINE=MyISAM; +connection slave; +connection master; +INSERT INTO `t1`(`f1`) VALUES ('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa2048'); +connection slave; +include/wait_for_slave_io_error.inc [errno=1153] +Last_IO_Error = 'Got a packet bigger than 'slave_max_allowed_packet' bytes' +include/stop_slave_sql.inc +include/rpl_reset.inc +connection master; +DROP TABLE t1; +connection slave; +connection master; +CREATE TABLE t1 (f1 int PRIMARY KEY, f2 LONGTEXT, f3 LONGTEXT) ENGINE=MyISAM; +connection slave; +connection master; +INSERT INTO t1(f1, f2, f3) VALUES(1, REPEAT('a', @@global.max_allowed_packet), REPEAT('b', @@global.max_allowed_packet)); +connection slave; +include/wait_for_slave_io_error.inc [errno=1153] +Last_IO_Error = 'Got a packet bigger than 'slave_max_allowed_packet' bytes' +STOP SLAVE; +RESET SLAVE; +connection master; +RESET MASTER; +SET @max_allowed_packet_0= @@session.max_allowed_packet; +SHOW BINLOG EVENTS; +SET @max_allowed_packet_1= @@session.max_allowed_packet; +SHOW BINLOG EVENTS; +SET @max_allowed_packet_2= @@session.max_allowed_packet; +==== clean up ==== +connection master; +DROP TABLE t1; +SET @@global.max_allowed_packet= 1024; +Warnings: +Warning 1708 The value of 'max_allowed_packet' should be no less than the value of 'net_buffer_length' +SET @@global.net_buffer_length= 1024; +SET @@global.slave_max_allowed_packet= 1073741824; +connection slave; +DROP TABLE t1; +RESET SLAVE; +include/rpl_end.inc diff --git a/mysql-test/suite/binlog_encryption/rpl_packet.test b/mysql-test/suite/binlog_encryption/rpl_packet.test new file mode 100644 index 0000000..42b77a8 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_packet.test @@ -0,0 +1,199 @@ +# +# The test was taken from the rpl suite as is +# + +# ==== Purpose ==== +# +# Check replication protocol packet size handling +# +# ==== Related bugs ==== +# Bug#19402 SQL close to the size of the max_allowed_packet fails on slave +# BUG#23755: Replicated event larger that max_allowed_packet infinitely re-transmits +# BUG#42914: No LAST_IO_ERROR for max_allowed_packet errors +# BUG#55322: SHOW BINLOG EVENTS increases @@SESSION.MAX_ALLOWED_PACKET + +# max-out size db name +source include/master-slave.inc; +source include/have_binlog_format_row.inc; + +--enable_connect_log + +call mtr.add_suppression("Slave I/O: Got a packet bigger than 'slave_max_allowed_packet' bytes, .*error.* 1153"); +call mtr.add_suppression("Log entry on master is longer than slave_max_allowed_packet"); +let $db= DB_NAME_OF_MAX_LENGTH_AKA_NAME_LEN_64_BYTES_____________________; +disable_warnings; +eval drop database if exists $db; +enable_warnings; +eval create database $db; + +connection master; +let $old_max_allowed_packet= `SELECT @@global.max_allowed_packet`; +let $old_net_buffer_length= `SELECT @@global.net_buffer_length`; +let $old_slave_max_allowed_packet= `SELECT @@global.slave_max_allowed_packet`; +SET @@global.max_allowed_packet=1024; +SET @@global.net_buffer_length=1024; + +sync_slave_with_master; +# Restart slave for setting to take effect +--disable_connect_log +source include/stop_slave.inc; +source include/start_slave.inc; +--enable_connect_log + +# Reconnect to master for new setting to take effect +disconnect master; + +# alas, can't use eval here; if db name changed apply the change here +connect (master,localhost,root,,DB_NAME_OF_MAX_LENGTH_AKA_NAME_LEN_64_BYTES_____________________); + +connection master; +select @@net_buffer_length, @@max_allowed_packet; + +create table `t1` (`f1` LONGTEXT) ENGINE=MyISAM; + +INSERT INTO `t1`(`f1`) VALUES ('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaa aaaaaaaaaaaaaaaaaaa1023'); +sync_slave_with_master; + +eval select count(*) from `$db`.`t1` /* must be 1 */; + +SHOW STATUS LIKE 'Slave_running'; +select * from information_schema.session_status where variable_name= 'SLAVE_RUNNING'; +connection master; +eval drop database $db; +sync_slave_with_master; + +# +# Bug #23755: Replicated event larger that max_allowed_packet infinitely re-transmits +# +# Check that a situation when the size of event on the master is greater than +# max_allowed_packet on the slave does not lead to infinite re-transmits. + +connection master; + +# Change the max packet size on master + +SET @@global.max_allowed_packet=4096; +SET @@global.net_buffer_length=4096; + +# Restart slave for new setting to take effect +connection slave; +--disable_connect_log +source include/stop_slave.inc; +source include/start_slave.inc; +--enable_connect_log + +# Reconnect to master for new setting to take effect +disconnect master; +connect (master, localhost, root); +connection master; + +CREATE TABLE `t1` (`f1` LONGTEXT) ENGINE=MyISAM; + +sync_slave_with_master; + +connection master; + +INSERT INTO `t1`(`f1`) VALUES ('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa2048'); + + +# +# Bug#42914: The slave I/O thread must stop after trying to read the above +# event, However there is no Last_IO_Error report. +# + +# The slave I/O thread must stop after trying to read the above event +connection slave; +# 1153 = ER_NET_PACKET_TOO_LARGE +--let $slave_io_errno= 1153 +--let $show_slave_io_error= 1 +--disable_connect_log +--source include/wait_for_slave_io_error.inc +--enable_connect_log + +# TODO: this is needed because of BUG#55790. Remove once that is fixed. +--disable_connect_log +--source include/stop_slave_sql.inc +--enable_connect_log + +# +# Bug#42914: On the master, if a binary log event is larger than +# max_allowed_packet, the error message ER_MASTER_FATAL_ERROR_READING_BINLOG +# is sent to a slave when it requests a dump from the master, thus leading the +# I/O thread to stop. However, there is no Last_IO_Error reported. +# + +--let $rpl_only_running_threads= 1 +--disable_connect_log +--source include/rpl_reset.inc +--enable_connect_log +--connection master +DROP TABLE t1; +--sync_slave_with_master + + +connection master; +CREATE TABLE t1 (f1 int PRIMARY KEY, f2 LONGTEXT, f3 LONGTEXT) ENGINE=MyISAM; +sync_slave_with_master; + +connection master; +INSERT INTO t1(f1, f2, f3) VALUES(1, REPEAT('a', @@global.max_allowed_packet), REPEAT('b', @@global.max_allowed_packet)); + +connection slave; +# The slave I/O thread must stop after receiving +# 1153 = ER_NET_PACKET_TOO_LARGE +--let $slave_io_errno= 1153 +--let $show_slave_io_error= 1 +--disable_connect_log +--source include/wait_for_slave_io_error.inc +--enable_connect_log + +# Remove the bad binlog and clear error status on slave. +STOP SLAVE; +RESET SLAVE; +--connection master +RESET MASTER; + + +# +# BUG#55322: SHOW BINLOG EVENTS increases @@SESSION.MAX_ALLOWED_PACKET +# +# In BUG#55322, @@session.max_allowed_packet increased each time SHOW +# BINLOG EVENTS was issued. To verify that this bug is fixed, we +# execute SHOW BINLOG EVENTS twice and check that max_allowed_packet +# never changes. We turn off the result log because we don't care +# about the contents of the binlog. + +--disable_result_log +SET @max_allowed_packet_0= @@session.max_allowed_packet; +SHOW BINLOG EVENTS; +SET @max_allowed_packet_1= @@session.max_allowed_packet; +SHOW BINLOG EVENTS; +SET @max_allowed_packet_2= @@session.max_allowed_packet; +--enable_result_log +if (`SELECT NOT(@max_allowed_packet_0 = @max_allowed_packet_1 AND @max_allowed_packet_1 = @max_allowed_packet_2)`) +{ + --echo ERROR: max_allowed_packet changed after executing SHOW BINLOG EVENTS + --disable_connect_log + --source include/show_rpl_debug_info.inc + --enable_connect_log + SELECT @max_allowed_packet_0, @max_allowed_packet_1, @max_allowed_packet_2; + --die @max_allowed_packet changed after executing SHOW BINLOG EVENTS +} + + +--echo ==== clean up ==== +connection master; +DROP TABLE t1; +eval SET @@global.max_allowed_packet= $old_max_allowed_packet; +eval SET @@global.net_buffer_length= $old_net_buffer_length; +eval SET @@global.slave_max_allowed_packet= $old_slave_max_allowed_packet; +# slave is stopped +connection slave; +DROP TABLE t1; + +# Clear Last_IO_Error +RESET SLAVE; + +--disable_connect_log +--source include/rpl_end.inc +# End of tests diff --git a/mysql-test/suite/binlog_encryption/rpl_parallel.result b/mysql-test/suite/binlog_encryption/rpl_parallel.result new file mode 100644 index 0000000..9774836 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_parallel.result @@ -0,0 +1,2025 @@ +include/master-slave.inc +[connection master] +connection server_2; +SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads; +SET GLOBAL slave_parallel_threads=10; +ERROR HY000: This operation cannot be performed as you have a running slave ''; run STOP SLAVE '' first +include/stop_slave.inc +SET GLOBAL slave_parallel_threads=10; +SELECT IF(COUNT(*) < 10, "OK", CONCAT("Found too many system user processes: ", COUNT(*))) FROM information_schema.processlist WHERE user = "system user"; +IF(COUNT(*) < 10, "OK", CONCAT("Found too many system user processes: ", COUNT(*))) +OK +CHANGE MASTER TO master_use_gtid=slave_pos; +include/start_slave.inc +SELECT IF(COUNT(*) >= 10, "OK", CONCAT("Found too few system user processes: ", COUNT(*))) FROM information_schema.processlist WHERE user = "system user"; +IF(COUNT(*) >= 10, "OK", CONCAT("Found too few system user processes: ", COUNT(*))) +OK +include/stop_slave.inc +SELECT IF(COUNT(*) < 10, "OK", CONCAT("Found too many system user processes: ", COUNT(*))) FROM information_schema.processlist WHERE user = "system user"; +IF(COUNT(*) < 10, "OK", CONCAT("Found too many system user processes: ", COUNT(*))) +OK +include/start_slave.inc +SELECT IF(COUNT(*) >= 10, "OK", CONCAT("Found too few system user processes: ", COUNT(*))) FROM information_schema.processlist WHERE user = "system user"; +IF(COUNT(*) >= 10, "OK", CONCAT("Found too few system user processes: ", COUNT(*))) +OK +*** Test long-running query in domain 1 can run in parallel with short queries in domain 0 *** +connection server_1; +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +CREATE TABLE t1 (a int PRIMARY KEY) ENGINE=MyISAM; +CREATE TABLE t2 (a int PRIMARY KEY) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1); +INSERT INTO t2 VALUES (1); +connection server_2; +connect con_temp1,127.0.0.1,root,,test,$SERVER_MYPORT_2,; +LOCK TABLE t1 WRITE; +connection server_1; +SET gtid_domain_id=1; +INSERT INTO t1 VALUES (2); +SET gtid_domain_id=0; +INSERT INTO t2 VALUES (2); +INSERT INTO t2 VALUES (3); +BEGIN; +INSERT INTO t2 VALUES (4); +INSERT INTO t2 VALUES (5); +COMMIT; +INSERT INTO t2 VALUES (6); +connection server_2; +SELECT * FROM t2 ORDER by a; +a +1 +2 +3 +4 +5 +6 +connection con_temp1; +SELECT * FROM t1; +a +1 +UNLOCK TABLES; +connection server_2; +SELECT * FROM t1 ORDER BY a; +a +1 +2 +*** Test two transactions in different domains committed in opposite order on slave but in a single group commit. *** +connection server_2; +include/stop_slave.inc +connection server_1; +SET sql_log_bin=0; +CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) +RETURNS INT DETERMINISTIC +BEGIN +RETURN x; +END +|| +SET sql_log_bin=1; +SET @old_format= @@SESSION.binlog_format; +SET binlog_format='statement'; +SET gtid_domain_id=1; +INSERT INTO t2 VALUES (foo(10, +'commit_before_enqueue SIGNAL ready1 WAIT_FOR cont1', +'commit_after_release_LOCK_prepare_ordered SIGNAL ready2')); +connection server_2; +FLUSH LOGS; +SET sql_log_bin=0; +CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) +RETURNS INT DETERMINISTIC +BEGIN +IF d1 != '' THEN +SET debug_sync = d1; +END IF; +IF d2 != '' THEN +SET debug_sync = d2; +END IF; +RETURN x; +END +|| +SET sql_log_bin=1; +SET @old_format=@@GLOBAL.binlog_format; +SET GLOBAL binlog_format=statement; +SET GLOBAL slave_parallel_threads=0; +SET GLOBAL slave_parallel_threads=10; +include/start_slave.inc +SET debug_sync='now WAIT_FOR ready1'; +connection server_1; +SET gtid_domain_id=2; +INSERT INTO t2 VALUES (foo(11, +'commit_before_enqueue SIGNAL ready3 WAIT_FOR cont3', +'commit_after_release_LOCK_prepare_ordered SIGNAL ready4 WAIT_FOR cont4')); +SET gtid_domain_id=0; +SELECT * FROM t2 WHERE a >= 10 ORDER BY a; +a +10 +11 +connection server_2; +SET debug_sync='now WAIT_FOR ready3'; +SET debug_sync='now SIGNAL cont3'; +SET debug_sync='now WAIT_FOR ready4'; +SET debug_sync='now SIGNAL cont1'; +SET debug_sync='now WAIT_FOR ready2'; +SET debug_sync='now SIGNAL cont4'; +SELECT * FROM t2 WHERE a >= 10 ORDER BY a; +a +10 +11 +include/show_binlog_events.inc +Log_name Pos Event_type Server_id End_log_pos Info +slave-bin.000002 # Binlog_checkpoint # # slave-bin.000002 +slave-bin.000002 # Gtid # # BEGIN GTID #-#-# cid=# +slave-bin.000002 # Query # # use `test`; INSERT INTO t2 VALUES (foo(11, +'commit_before_enqueue SIGNAL ready3 WAIT_FOR cont3', +'commit_after_release_LOCK_prepare_ordered SIGNAL ready4 WAIT_FOR cont4')) +slave-bin.000002 # Xid # # COMMIT /* XID */ +slave-bin.000002 # Gtid # # BEGIN GTID #-#-# cid=# +slave-bin.000002 # Query # # use `test`; INSERT INTO t2 VALUES (foo(10, +'commit_before_enqueue SIGNAL ready1 WAIT_FOR cont1', +'commit_after_release_LOCK_prepare_ordered SIGNAL ready2')) +slave-bin.000002 # Xid # # COMMIT /* XID */ +FLUSH LOGS; +connection server_2; +include/stop_slave.inc +SET GLOBAL slave_parallel_threads=0; +SET GLOBAL slave_parallel_threads=10; +SET debug_sync='RESET'; +include/start_slave.inc +*** Test that group-committed transactions on the master can replicate in parallel on the slave. *** +connection server_1; +SET debug_sync='RESET'; +FLUSH LOGS; +CREATE TABLE t3 (a INT PRIMARY KEY, b INT) ENGINE=InnoDB; +INSERT INTO t3 VALUES (1,1), (3,3), (5,5), (7,7); +connection server_2; +connection con_temp1; +BEGIN; +INSERT INTO t3 VALUES (2,102); +connect con_temp2,127.0.0.1,root,,test,$SERVER_MYPORT_2,; +BEGIN; +INSERT INTO t3 VALUES (4,104); +connect con_temp3,127.0.0.1,root,,test,$SERVER_MYPORT_1,; +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued1 WAIT_FOR master_cont1'; +SET binlog_format=statement; +INSERT INTO t3 VALUES (2, foo(12, +'commit_after_release_LOCK_prepare_ordered SIGNAL slave_queued1 WAIT_FOR slave_cont1', +'')); +connection server_1; +SET debug_sync='now WAIT_FOR master_queued1'; +connect con_temp4,127.0.0.1,root,,test,$SERVER_MYPORT_1,; +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued2'; +SET binlog_format=statement; +INSERT INTO t3 VALUES (4, foo(14, +'commit_after_release_LOCK_prepare_ordered SIGNAL slave_queued2', +'')); +connection server_1; +SET debug_sync='now WAIT_FOR master_queued2'; +connect con_temp5,127.0.0.1,root,,test,$SERVER_MYPORT_1,; +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued3'; +SET binlog_format=statement; +INSERT INTO t3 VALUES (6, foo(16, +'group_commit_waiting_for_prior SIGNAL slave_queued3', +'')); +connection server_1; +SET debug_sync='now WAIT_FOR master_queued3'; +SET debug_sync='now SIGNAL master_cont1'; +connection con_temp3; +connection con_temp4; +connection con_temp5; +SET debug_sync='RESET'; +connection server_1; +SELECT * FROM t3 ORDER BY a; +a b +1 1 +2 12 +3 3 +4 14 +5 5 +6 16 +7 7 +include/show_binlog_events.inc +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000002 # Binlog_checkpoint # # master-bin.000001 +master-bin.000002 # Binlog_checkpoint # # master-bin.000002 +master-bin.000002 # Gtid # # GTID #-#-# +master-bin.000002 # Query # # use `test`; CREATE TABLE t3 (a INT PRIMARY KEY, b INT) ENGINE=InnoDB +master-bin.000002 # Gtid # # BEGIN GTID #-#-# +master-bin.000002 # Query # # use `test`; INSERT INTO t3 VALUES (1,1), (3,3), (5,5), (7,7) +master-bin.000002 # Xid # # COMMIT /* XID */ +master-bin.000002 # Gtid # # BEGIN GTID #-#-# cid=# +master-bin.000002 # Query # # use `test`; INSERT INTO t3 VALUES (2, foo(12, +'commit_after_release_LOCK_prepare_ordered SIGNAL slave_queued1 WAIT_FOR slave_cont1', +'')) +master-bin.000002 # Xid # # COMMIT /* XID */ +master-bin.000002 # Gtid # # BEGIN GTID #-#-# cid=# +master-bin.000002 # Query # # use `test`; INSERT INTO t3 VALUES (4, foo(14, +'commit_after_release_LOCK_prepare_ordered SIGNAL slave_queued2', +'')) +master-bin.000002 # Xid # # COMMIT /* XID */ +master-bin.000002 # Gtid # # BEGIN GTID #-#-# cid=# +master-bin.000002 # Query # # use `test`; INSERT INTO t3 VALUES (6, foo(16, +'group_commit_waiting_for_prior SIGNAL slave_queued3', +'')) +master-bin.000002 # Xid # # COMMIT /* XID */ +connection server_2; +SET debug_sync='now WAIT_FOR slave_queued3'; +connection con_temp1; +ROLLBACK; +connection server_2; +SET debug_sync='now WAIT_FOR slave_queued1'; +connection con_temp2; +ROLLBACK; +connection server_2; +SET debug_sync='now WAIT_FOR slave_queued2'; +SET debug_sync='now SIGNAL slave_cont1'; +SELECT * FROM t3 ORDER BY a; +a b +1 1 +2 12 +3 3 +4 14 +5 5 +6 16 +7 7 +include/show_binlog_events.inc +Log_name Pos Event_type Server_id End_log_pos Info +slave-bin.000003 # Binlog_checkpoint # # slave-bin.000003 +slave-bin.000003 # Gtid # # GTID #-#-# +slave-bin.000003 # Query # # use `test`; CREATE TABLE t3 (a INT PRIMARY KEY, b INT) ENGINE=InnoDB +slave-bin.000003 # Gtid # # BEGIN GTID #-#-# +slave-bin.000003 # Query # # use `test`; INSERT INTO t3 VALUES (1,1), (3,3), (5,5), (7,7) +slave-bin.000003 # Xid # # COMMIT /* XID */ +slave-bin.000003 # Gtid # # BEGIN GTID #-#-# cid=# +slave-bin.000003 # Query # # use `test`; INSERT INTO t3 VALUES (2, foo(12, +'commit_after_release_LOCK_prepare_ordered SIGNAL slave_queued1 WAIT_FOR slave_cont1', +'')) +slave-bin.000003 # Xid # # COMMIT /* XID */ +slave-bin.000003 # Gtid # # BEGIN GTID #-#-# cid=# +slave-bin.000003 # Query # # use `test`; INSERT INTO t3 VALUES (4, foo(14, +'commit_after_release_LOCK_prepare_ordered SIGNAL slave_queued2', +'')) +slave-bin.000003 # Xid # # COMMIT /* XID */ +slave-bin.000003 # Gtid # # BEGIN GTID #-#-# cid=# +slave-bin.000003 # Query # # use `test`; INSERT INTO t3 VALUES (6, foo(16, +'group_commit_waiting_for_prior SIGNAL slave_queued3', +'')) +slave-bin.000003 # Xid # # COMMIT /* XID */ +*** Test STOP SLAVE in parallel mode *** +connection server_2; +include/stop_slave.inc +SET debug_sync='RESET'; +SET GLOBAL slave_parallel_threads=0; +SET GLOBAL slave_parallel_threads=10; +connection server_1; +SET binlog_direct_non_transactional_updates=0; +SET sql_log_bin=0; +CALL mtr.add_suppression("Statement is unsafe because it accesses a non-transactional table after accessing a transactional table within the same transaction"); +SET sql_log_bin=1; +BEGIN; +INSERT INTO t2 VALUES (20); +INSERT INTO t1 VALUES (20); +INSERT INTO t2 VALUES (21); +INSERT INTO t3 VALUES (20, 20); +COMMIT; +INSERT INTO t3 VALUES(21, 21); +INSERT INTO t3 VALUES(22, 22); +SET binlog_format=@old_format; +connection con_temp1; +BEGIN; +INSERT INTO t2 VALUES (21); +connection server_2; +START SLAVE; +connection con_temp2; +SET @old_dbug= @@GLOBAL.debug_dbug; +SET GLOBAL debug_dbug="+d,rpl_parallel_wait_for_done_trigger"; +STOP SLAVE; +connection con_temp1; +SET debug_sync='now WAIT_FOR wait_for_done_waiting'; +ROLLBACK; +connection con_temp2; +SET GLOBAL debug_dbug=@old_dbug; +SET debug_sync='RESET'; +connection server_2; +include/wait_for_slave_to_stop.inc +SELECT * FROM t1 WHERE a >= 20 ORDER BY a; +a +20 +SELECT * FROM t2 WHERE a >= 20 ORDER BY a; +a +20 +21 +SELECT * FROM t3 WHERE a >= 20 ORDER BY a; +a b +20 20 +include/start_slave.inc +SELECT * FROM t1 WHERE a >= 20 ORDER BY a; +a +20 +SELECT * FROM t2 WHERE a >= 20 ORDER BY a; +a +20 +21 +SELECT * FROM t3 WHERE a >= 20 ORDER BY a; +a b +20 20 +21 21 +22 22 +connection server_2; +include/stop_slave.inc +SET GLOBAL binlog_format=@old_format; +SET GLOBAL slave_parallel_threads=0; +SET GLOBAL slave_parallel_threads=10; +include/start_slave.inc +*** Test killing slave threads at various wait points *** +*** 1. Test killing transaction waiting in commit for previous transaction to commit *** +connection con_temp3; +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued1 WAIT_FOR master_cont1'; +SET binlog_format=statement; +INSERT INTO t3 VALUES (31, foo(31, +'commit_before_prepare_ordered WAIT_FOR t2_waiting', +'commit_after_prepare_ordered SIGNAL t1_ready WAIT_FOR t1_cont')); +connection server_1; +SET debug_sync='now WAIT_FOR master_queued1'; +connection con_temp4; +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued2'; +SET binlog_format=statement; +BEGIN; +INSERT INTO t3 VALUES (32, foo(32, +'ha_write_row_end SIGNAL t2_query WAIT_FOR t2_cont', +'')); +INSERT INTO t3 VALUES (33, foo(33, +'group_commit_waiting_for_prior SIGNAL t2_waiting', +'group_commit_waiting_for_prior_killed SIGNAL t2_killed')); +COMMIT; +connection server_1; +SET debug_sync='now WAIT_FOR master_queued2'; +connection con_temp5; +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued3'; +SET binlog_format=statement; +INSERT INTO t3 VALUES (34, foo(34, +'', +'')); +connection server_1; +SET debug_sync='now WAIT_FOR master_queued3'; +SET debug_sync='now SIGNAL master_cont1'; +connection con_temp3; +connection con_temp4; +connection con_temp5; +connection server_1; +SELECT * FROM t3 WHERE a >= 30 ORDER BY a; +a b +31 31 +32 32 +33 33 +34 34 +SET debug_sync='RESET'; +connection server_2; +SET sql_log_bin=0; +CALL mtr.add_suppression("Query execution was interrupted"); +CALL mtr.add_suppression("Commit failed due to failure of an earlier commit on which this one depends"); +CALL mtr.add_suppression("Slave: Connection was killed"); +SET sql_log_bin=1; +SET debug_sync='now WAIT_FOR t2_query'; +SET debug_sync='now SIGNAL t2_cont'; +SET debug_sync='now WAIT_FOR t1_ready'; +KILL THD_ID; +SET debug_sync='now WAIT_FOR t2_killed'; +SET debug_sync='now SIGNAL t1_cont'; +include/wait_for_slave_sql_error.inc [errno=1317,1927,1964] +STOP SLAVE IO_THREAD; +SELECT * FROM t3 WHERE a >= 30 ORDER BY a; +a b +31 31 +SET debug_sync='RESET'; +SET GLOBAL slave_parallel_threads=0; +SET GLOBAL slave_parallel_threads=10; +SET sql_log_bin=0; +DROP FUNCTION foo; +CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) +RETURNS INT DETERMINISTIC +BEGIN +RETURN x; +END +|| +SET sql_log_bin=1; +connection server_1; +INSERT INTO t3 VALUES (39,0); +connection server_2; +include/start_slave.inc +SELECT * FROM t3 WHERE a >= 30 ORDER BY a; +a b +31 31 +32 32 +33 33 +34 34 +39 0 +SET sql_log_bin=0; +DROP FUNCTION foo; +CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) +RETURNS INT DETERMINISTIC +BEGIN +IF d1 != '' THEN +SET debug_sync = d1; +END IF; +IF d2 != '' THEN +SET debug_sync = d2; +END IF; +RETURN x; +END +|| +SET sql_log_bin=1; +connection server_2; +include/stop_slave.inc +SET GLOBAL binlog_format=@old_format; +SET GLOBAL slave_parallel_threads=0; +SET GLOBAL slave_parallel_threads=10; +include/start_slave.inc +*** 2. Same as (1), but without restarting IO thread after kill of SQL threads *** +connection con_temp3; +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued1 WAIT_FOR master_cont1'; +SET binlog_format=statement; +INSERT INTO t3 VALUES (41, foo(41, +'commit_before_prepare_ordered WAIT_FOR t2_waiting', +'commit_after_prepare_ordered SIGNAL t1_ready WAIT_FOR t1_cont')); +connection server_1; +SET debug_sync='now WAIT_FOR master_queued1'; +connection con_temp4; +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued2'; +SET binlog_format=statement; +BEGIN; +INSERT INTO t3 VALUES (42, foo(42, +'ha_write_row_end SIGNAL t2_query WAIT_FOR t2_cont', +'')); +INSERT INTO t3 VALUES (43, foo(43, +'group_commit_waiting_for_prior SIGNAL t2_waiting', +'group_commit_waiting_for_prior_killed SIGNAL t2_killed')); +COMMIT; +connection server_1; +SET debug_sync='now WAIT_FOR master_queued2'; +connection con_temp5; +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued3'; +SET binlog_format=statement; +INSERT INTO t3 VALUES (44, foo(44, +'', +'')); +connection server_1; +SET debug_sync='now WAIT_FOR master_queued3'; +SET debug_sync='now SIGNAL master_cont1'; +connection con_temp3; +connection con_temp4; +connection con_temp5; +connection server_1; +SELECT * FROM t3 WHERE a >= 40 ORDER BY a; +a b +41 41 +42 42 +43 43 +44 44 +SET debug_sync='RESET'; +connection server_2; +SET debug_sync='now WAIT_FOR t2_query'; +SET debug_sync='now SIGNAL t2_cont'; +SET debug_sync='now WAIT_FOR t1_ready'; +KILL THD_ID; +SET debug_sync='now WAIT_FOR t2_killed'; +SET debug_sync='now SIGNAL t1_cont'; +include/wait_for_slave_sql_error.inc [errno=1317,1927,1964] +SET debug_sync='RESET'; +SET GLOBAL slave_parallel_threads=0; +SET GLOBAL slave_parallel_threads=10; +SET sql_log_bin=0; +DROP FUNCTION foo; +CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) +RETURNS INT DETERMINISTIC +BEGIN +RETURN x; +END +|| +SET sql_log_bin=1; +connection server_1; +INSERT INTO t3 VALUES (49,0); +connection server_2; +START SLAVE SQL_THREAD; +SELECT * FROM t3 WHERE a >= 40 ORDER BY a; +a b +41 41 +42 42 +43 43 +44 44 +49 0 +SET sql_log_bin=0; +DROP FUNCTION foo; +CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) +RETURNS INT DETERMINISTIC +BEGIN +IF d1 != '' THEN +SET debug_sync = d1; +END IF; +IF d2 != '' THEN +SET debug_sync = d2; +END IF; +RETURN x; +END +|| +SET sql_log_bin=1; +connection server_2; +include/stop_slave.inc +SET GLOBAL binlog_format=@old_format; +SET GLOBAL slave_parallel_threads=0; +SET GLOBAL slave_parallel_threads=10; +include/start_slave.inc +*** 3. Same as (2), but not using gtid mode *** +connection server_2; +include/stop_slave.inc +CHANGE MASTER TO master_use_gtid=no; +include/start_slave.inc +connection server_1; +connection con_temp3; +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued1 WAIT_FOR master_cont1'; +SET binlog_format=statement; +INSERT INTO t3 VALUES (51, foo(51, +'commit_before_prepare_ordered WAIT_FOR t2_waiting', +'commit_after_prepare_ordered SIGNAL t1_ready WAIT_FOR t1_cont')); +connection server_1; +SET debug_sync='now WAIT_FOR master_queued1'; +connection con_temp4; +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued2'; +SET binlog_format=statement; +BEGIN; +INSERT INTO t3 VALUES (52, foo(52, +'ha_write_row_end SIGNAL t2_query WAIT_FOR t2_cont', +'')); +INSERT INTO t3 VALUES (53, foo(53, +'group_commit_waiting_for_prior SIGNAL t2_waiting', +'group_commit_waiting_for_prior_killed SIGNAL t2_killed')); +COMMIT; +connection server_1; +SET debug_sync='now WAIT_FOR master_queued2'; +connection con_temp5; +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued3'; +SET binlog_format=statement; +INSERT INTO t3 VALUES (54, foo(54, +'', +'')); +connection server_1; +SET debug_sync='now WAIT_FOR master_queued3'; +SET debug_sync='now SIGNAL master_cont1'; +connection con_temp3; +connection con_temp4; +connection con_temp5; +connection server_1; +SELECT * FROM t3 WHERE a >= 50 ORDER BY a; +a b +51 51 +52 52 +53 53 +54 54 +SET debug_sync='RESET'; +connection server_2; +SET debug_sync='now WAIT_FOR t2_query'; +SET debug_sync='now SIGNAL t2_cont'; +SET debug_sync='now WAIT_FOR t1_ready'; +KILL THD_ID; +SET debug_sync='now WAIT_FOR t2_killed'; +SET debug_sync='now SIGNAL t1_cont'; +include/wait_for_slave_sql_error.inc [errno=1317,1927,1964] +SELECT * FROM t3 WHERE a >= 50 ORDER BY a; +a b +51 51 +SET debug_sync='RESET'; +SET GLOBAL slave_parallel_threads=0; +SET GLOBAL slave_parallel_threads=10; +SET sql_log_bin=0; +DROP FUNCTION foo; +CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) +RETURNS INT DETERMINISTIC +BEGIN +RETURN x; +END +|| +SET sql_log_bin=1; +connection server_1; +INSERT INTO t3 VALUES (59,0); +connection server_2; +START SLAVE SQL_THREAD; +SELECT * FROM t3 WHERE a >= 50 ORDER BY a; +a b +51 51 +52 52 +53 53 +54 54 +59 0 +SET sql_log_bin=0; +DROP FUNCTION foo; +CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) +RETURNS INT DETERMINISTIC +BEGIN +IF d1 != '' THEN +SET debug_sync = d1; +END IF; +IF d2 != '' THEN +SET debug_sync = d2; +END IF; +RETURN x; +END +|| +SET sql_log_bin=1; +include/stop_slave.inc +CHANGE MASTER TO master_use_gtid=slave_pos; +include/start_slave.inc +connection server_2; +include/stop_slave.inc +SET GLOBAL binlog_format=@old_format; +SET GLOBAL slave_parallel_threads=0; +SET GLOBAL slave_parallel_threads=4; +include/start_slave.inc +*** 4. Test killing thread that is waiting to start transaction until previous transaction commits *** +connection server_1; +SET binlog_format=statement; +SET gtid_domain_id=2; +BEGIN; +INSERT INTO t3 VALUES (70, foo(70, +'rpl_parallel_start_waiting_for_prior SIGNAL t4_waiting', '')); +INSERT INTO t3 VALUES (60, foo(60, +'ha_write_row_end SIGNAL d2_query WAIT_FOR d2_cont2', +'rpl_parallel_end_of_group SIGNAL d2_done WAIT_FOR d2_cont')); +COMMIT; +SET gtid_domain_id=0; +connection server_2; +SET debug_sync='now WAIT_FOR d2_query'; +connection server_1; +SET gtid_domain_id=1; +BEGIN; +INSERT INTO t3 VALUES (61, foo(61, +'rpl_parallel_start_waiting_for_prior SIGNAL t3_waiting', +'rpl_parallel_start_waiting_for_prior_killed SIGNAL t3_killed')); +INSERT INTO t3 VALUES (62, foo(62, +'ha_write_row_end SIGNAL d1_query WAIT_FOR d1_cont2', +'rpl_parallel_end_of_group SIGNAL d1_done WAIT_FOR d1_cont')); +COMMIT; +SET gtid_domain_id=0; +connection server_2; +SET debug_sync='now WAIT_FOR d1_query'; +connection server_1; +SET gtid_domain_id=0; +INSERT INTO t3 VALUES (63, foo(63, +'ha_write_row_end SIGNAL d0_query WAIT_FOR d0_cont2', +'rpl_parallel_end_of_group SIGNAL d0_done WAIT_FOR d0_cont')); +connection server_2; +SET debug_sync='now WAIT_FOR d0_query'; +connection server_1; +SET gtid_domain_id=3; +BEGIN; +INSERT INTO t3 VALUES (68, foo(68, +'rpl_parallel_start_waiting_for_prior SIGNAL t2_waiting', '')); +INSERT INTO t3 VALUES (69, foo(69, +'ha_write_row_end SIGNAL d3_query WAIT_FOR d3_cont2', +'rpl_parallel_end_of_group SIGNAL d3_done WAIT_FOR d3_cont')); +COMMIT; +SET gtid_domain_id=0; +connection server_2; +SET debug_sync='now WAIT_FOR d3_query'; +SET debug_sync='now SIGNAL d2_cont2'; +SET debug_sync='now WAIT_FOR d2_done'; +SET debug_sync='now SIGNAL d1_cont2'; +SET debug_sync='now WAIT_FOR d1_done'; +SET debug_sync='now SIGNAL d0_cont2'; +SET debug_sync='now WAIT_FOR d0_done'; +SET debug_sync='now SIGNAL d3_cont2'; +SET debug_sync='now WAIT_FOR d3_done'; +connection con_temp3; +SET binlog_format=statement; +INSERT INTO t3 VALUES (64, foo(64, +'rpl_parallel_before_mark_start_commit SIGNAL t1_waiting WAIT_FOR t1_cont', '')); +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued2 WAIT_FOR master_cont2'; +INSERT INTO t3 VALUES (65, foo(65, '', '')); +connection server_1; +SET debug_sync='now WAIT_FOR master_queued2'; +connection con_temp4; +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued3'; +INSERT INTO t3 VALUES (66, foo(66, '', '')); +connection server_1; +SET debug_sync='now WAIT_FOR master_queued3'; +connection con_temp5; +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued4'; +INSERT INTO t3 VALUES (67, foo(67, '', '')); +connection server_1; +SET debug_sync='now WAIT_FOR master_queued4'; +SET debug_sync='now SIGNAL master_cont2'; +connection con_temp3; +connection con_temp4; +connection con_temp5; +connection server_1; +SELECT * FROM t3 WHERE a >= 60 ORDER BY a; +a b +60 60 +61 61 +62 62 +63 63 +64 64 +65 65 +66 66 +67 67 +68 68 +69 69 +70 70 +SET debug_sync='RESET'; +connection server_2; +SET debug_sync='now SIGNAL d0_cont'; +SET debug_sync='now WAIT_FOR t1_waiting'; +SET debug_sync='now SIGNAL d3_cont'; +SET debug_sync='now WAIT_FOR t2_waiting'; +SET debug_sync='now SIGNAL d1_cont'; +SET debug_sync='now WAIT_FOR t3_waiting'; +SET debug_sync='now SIGNAL d2_cont'; +SET debug_sync='now WAIT_FOR t4_waiting'; +KILL THD_ID; +SET debug_sync='now WAIT_FOR t3_killed'; +SET debug_sync='now SIGNAL t1_cont'; +include/wait_for_slave_sql_error.inc [errno=1317,1927,1964] +STOP SLAVE IO_THREAD; +SELECT * FROM t3 WHERE a >= 60 AND a != 65 ORDER BY a; +a b +60 60 +61 61 +62 62 +63 63 +64 64 +68 68 +69 69 +70 70 +SET debug_sync='RESET'; +SET GLOBAL slave_parallel_threads=0; +SET GLOBAL slave_parallel_threads=10; +SET sql_log_bin=0; +DROP FUNCTION foo; +CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) +RETURNS INT DETERMINISTIC +BEGIN +RETURN x; +END +|| +SET sql_log_bin=1; +connection server_1; +UPDATE t3 SET b=b+1 WHERE a=60; +connection server_2; +include/start_slave.inc +SELECT * FROM t3 WHERE a >= 60 ORDER BY a; +a b +60 61 +61 61 +62 62 +63 63 +64 64 +65 65 +66 66 +67 67 +68 68 +69 69 +70 70 +SET sql_log_bin=0; +DROP FUNCTION foo; +CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) +RETURNS INT DETERMINISTIC +BEGIN +IF d1 != '' THEN +SET debug_sync = d1; +END IF; +IF d2 != '' THEN +SET debug_sync = d2; +END IF; +RETURN x; +END +|| +SET sql_log_bin=1; +connection server_2; +include/stop_slave.inc +SET GLOBAL binlog_format=@old_format; +SET GLOBAL slave_parallel_threads=0; +SET GLOBAL slave_parallel_threads=10; +include/start_slave.inc +*** 5. Test killing thread that is waiting for queue of max length to shorten *** +SET @old_max_queued= @@GLOBAL.slave_parallel_max_queued; +SET GLOBAL slave_parallel_max_queued=9000; +connection server_1; +SET binlog_format=statement; +INSERT INTO t3 VALUES (80, foo(0, +'ha_write_row_end SIGNAL query_waiting WAIT_FOR query_cont', '')); +connection server_2; +SET debug_sync='now WAIT_FOR query_waiting'; +SET @old_dbug= @@GLOBAL.debug_dbug; +SET GLOBAL debug_dbug="+d,rpl_parallel_wait_queue_max"; +connection server_1; +SELECT * FROM t3 WHERE a >= 80 ORDER BY a; +a b +80 0 +81 10000 +connection server_2; +SET debug_sync='now WAIT_FOR wait_queue_ready'; +KILL THD_ID; +SET debug_sync='now WAIT_FOR wait_queue_killed'; +SET debug_sync='now SIGNAL query_cont'; +include/wait_for_slave_sql_error.inc [errno=1317,1927,1964] +STOP SLAVE IO_THREAD; +SET GLOBAL debug_dbug=@old_dbug; +SET GLOBAL slave_parallel_max_queued= @old_max_queued; +connection server_1; +INSERT INTO t3 VALUES (82,0); +SET binlog_format=@old_format; +connection server_2; +SET debug_sync='RESET'; +include/start_slave.inc +SELECT * FROM t3 WHERE a >= 80 ORDER BY a; +a b +80 0 +81 10000 +82 0 +connection server_2; +include/stop_slave.inc +SET GLOBAL binlog_format=@old_format; +SET GLOBAL slave_parallel_threads=0; +SET GLOBAL slave_parallel_threads=10; +include/start_slave.inc +*** MDEV-5788 Incorrect free of rgi->deferred_events in parallel replication *** +connection server_2; +include/stop_slave.inc +SET GLOBAL replicate_ignore_table="test.t3"; +SET GLOBAL slave_parallel_threads=2; +include/start_slave.inc +connection server_1; +INSERT INTO t3 VALUES (100, rand()); +INSERT INTO t3 VALUES (101, rand()); +connection server_2; +connection server_1; +INSERT INTO t3 VALUES (102, rand()); +INSERT INTO t3 VALUES (103, rand()); +INSERT INTO t3 VALUES (104, rand()); +INSERT INTO t3 VALUES (105, rand()); +connection server_2; +include/stop_slave.inc +SET GLOBAL replicate_ignore_table=""; +include/start_slave.inc +connection server_1; +INSERT INTO t3 VALUES (106, rand()); +INSERT INTO t3 VALUES (107, rand()); +connection server_2; +SELECT * FROM t3 WHERE a >= 100 ORDER BY a; +a b +106 # +107 # +*** MDEV-5921: In parallel replication, an error is not correctly signalled to the next transaction *** +connection server_2; +include/stop_slave.inc +SET GLOBAL slave_parallel_threads=10; +include/start_slave.inc +connection server_1; +INSERT INTO t3 VALUES (110, 1); +connection server_2; +SELECT * FROM t3 WHERE a >= 110 ORDER BY a; +a b +110 1 +SET sql_log_bin=0; +INSERT INTO t3 VALUES (111, 666); +SET sql_log_bin=1; +connection server_1; +connect con1,127.0.0.1,root,,test,$SERVER_MYPORT_1,; +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued1 WAIT_FOR master_cont1'; +INSERT INTO t3 VALUES (111, 2); +connection server_1; +SET debug_sync='now WAIT_FOR master_queued1'; +connect con2,127.0.0.1,root,,test,$SERVER_MYPORT_1,; +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued2'; +INSERT INTO t3 VALUES (112, 3); +connection server_1; +SET debug_sync='now WAIT_FOR master_queued2'; +SET debug_sync='now SIGNAL master_cont1'; +connection con1; +connection con2; +SET debug_sync='RESET'; +connection server_2; +include/wait_for_slave_sql_error.inc [errno=1062] +include/wait_for_slave_sql_to_stop.inc +SELECT * FROM t3 WHERE a >= 110 ORDER BY a; +a b +110 1 +111 666 +SET sql_log_bin=0; +DELETE FROM t3 WHERE a=111 AND b=666; +SET sql_log_bin=1; +START SLAVE SQL_THREAD; +SELECT * FROM t3 WHERE a >= 110 ORDER BY a; +a b +110 1 +111 2 +112 3 +***MDEV-5914: Parallel replication deadlock due to InnoDB lock conflicts *** +connection server_2; +include/stop_slave.inc +connection server_1; +CREATE TABLE t4 (a INT PRIMARY KEY, b INT, KEY b_idx(b)) ENGINE=InnoDB; +INSERT INTO t4 VALUES (1,NULL), (2,2), (3,NULL), (4,4), (5, NULL), (6, 6); +connection con1; +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued1 WAIT_FOR master_cont1'; +UPDATE t4 SET b=NULL WHERE a=6; +connection server_1; +SET debug_sync='now WAIT_FOR master_queued1'; +connection con2; +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued2'; +DELETE FROM t4 WHERE b <= 3; +connection server_1; +SET debug_sync='now WAIT_FOR master_queued2'; +SET debug_sync='now SIGNAL master_cont1'; +connection con1; +connection con2; +SET debug_sync='RESET'; +connection server_2; +include/start_slave.inc +include/stop_slave.inc +SELECT * FROM t4 ORDER BY a; +a b +1 NULL +3 NULL +4 4 +5 NULL +6 NULL +connection server_1; +DELETE FROM t4; +INSERT INTO t4 VALUES (1,NULL), (2,2), (3,NULL), (4,4), (5, NULL), (6, 6); +connection con1; +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued1 WAIT_FOR master_cont1'; +INSERT INTO t4 VALUES (7, NULL); +connection server_1; +SET debug_sync='now WAIT_FOR master_queued1'; +connection con2; +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued2'; +DELETE FROM t4 WHERE b <= 3; +connection server_1; +SET debug_sync='now WAIT_FOR master_queued2'; +SET debug_sync='now SIGNAL master_cont1'; +connection con1; +connection con2; +SET debug_sync='RESET'; +connection server_2; +include/start_slave.inc +include/stop_slave.inc +SELECT * FROM t4 ORDER BY a; +a b +1 NULL +3 NULL +4 4 +5 NULL +6 6 +7 NULL +connection server_1; +DELETE FROM t4; +INSERT INTO t4 VALUES (1,NULL), (2,2), (3,NULL), (4,4), (5, NULL), (6, 6); +connection con1; +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued1 WAIT_FOR master_cont1'; +UPDATE t4 SET b=NULL WHERE a=6; +connection server_1; +SET debug_sync='now WAIT_FOR master_queued1'; +connection con2; +SET @old_format= @@SESSION.binlog_format; +SET binlog_format='statement'; +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued2'; +DELETE FROM t4 WHERE b <= 1; +connection server_1; +SET debug_sync='now WAIT_FOR master_queued2'; +SET debug_sync='now SIGNAL master_cont1'; +connection con1; +connection con2; +SET @old_format=@@GLOBAL.binlog_format; +SET debug_sync='RESET'; +connection server_2; +SET @old_dbug= @@GLOBAL.debug_dbug; +SET GLOBAL debug_dbug="+d,disable_thd_need_ordering_with"; +include/start_slave.inc +SET GLOBAL debug_dbug=@old_dbug; +SELECT * FROM t4 ORDER BY a; +a b +1 NULL +2 2 +3 NULL +4 4 +5 NULL +6 NULL +SET @last_gtid= 'GTID'; +SELECT IF(@@gtid_slave_pos LIKE CONCAT('%',@last_gtid,'%'), "GTID found ok", +CONCAT("GTID ", @last_gtid, " not found in gtid_slave_pos=", @@gtid_slave_pos)) +AS result; +result +GTID found ok +SELECT "ROW FOUND" AS `Is the row found?` + FROM mysql.gtid_slave_pos +WHERE CONCAT(domain_id, "-", server_id, "-", seq_no) = @last_gtid; +Is the row found? +ROW FOUND +*** MDEV-5938: Exec_master_log_pos not updated at log rotate in parallel replication *** +connection server_2; +include/stop_slave.inc +SET GLOBAL slave_parallel_threads=1; +SET DEBUG_SYNC= 'RESET'; +include/start_slave.inc +connection server_1; +CREATE TABLE t5 (a INT PRIMARY KEY, b INT); +INSERT INTO t5 VALUES (1,1); +INSERT INTO t5 VALUES (2,2), (3,8); +INSERT INTO t5 VALUES (4,16); +connection server_2; +test_check +OK +test_check +OK +connection server_1; +FLUSH LOGS; +connection server_2; +test_check +OK +test_check +OK +*** MDEV_6435: Incorrect error handling when query binlogged partially on master with "killed" error *** +connection server_1; +CREATE TABLE t6 (a INT) ENGINE=MyISAM; +CREATE TRIGGER tr AFTER INSERT ON t6 FOR EACH ROW SET @a = 1; +connection con1; +SET @old_format= @@binlog_format; +SET binlog_format= statement; +SET debug_sync='sp_head_execute_before_loop SIGNAL ready WAIT_FOR cont'; +INSERT INTO t6 VALUES (1), (2), (3); +connection server_1; +SET debug_sync='now WAIT_FOR ready'; +KILL QUERY CONID; +SET debug_sync='now SIGNAL cont'; +connection con1; +ERROR 70100: Query execution was interrupted +SET binlog_format= @old_format; +SET debug_sync='RESET'; +connection server_1; +SET debug_sync='RESET'; +connection server_2; +include/wait_for_slave_sql_error.inc [errno=1317] +STOP SLAVE IO_THREAD; +SET GLOBAL gtid_slave_pos= 'AFTER_ERROR_GTID_POS'; +include/start_slave.inc +connection server_1; +INSERT INTO t6 VALUES (4); +SELECT * FROM t6 ORDER BY a; +a +1 +4 +connection server_2; +SELECT * FROM t6 ORDER BY a; +a +4 +*** MDEV-6551: Some replication errors are ignored if slave_parallel_threads > 0 *** +connection server_1; +INSERT INTO t2 VALUES (31); +include/save_master_gtid.inc +connection server_2; +include/sync_with_master_gtid.inc +include/stop_slave.inc +SET GLOBAL slave_parallel_threads= 0; +include/start_slave.inc +SET sql_log_bin= 0; +INSERT INTO t2 VALUES (32); +SET sql_log_bin= 1; +connection server_1; +INSERT INTO t2 VALUES (32); +FLUSH LOGS; +INSERT INTO t2 VALUES (33); +INSERT INTO t2 VALUES (34); +SELECT * FROM t2 WHERE a >= 30 ORDER BY a; +a +31 +32 +33 +34 +include/save_master_gtid.inc +connection server_2; +include/wait_for_slave_sql_error.inc [errno=1062] +connection server_2; +include/stop_slave_io.inc +SET GLOBAL slave_parallel_threads=10; +START SLAVE; +include/wait_for_slave_sql_error.inc [errno=1062] +START SLAVE SQL_THREAD; +include/wait_for_slave_sql_error.inc [errno=1062] +SELECT * FROM t2 WHERE a >= 30 ORDER BY a; +a +31 +32 +SET sql_slave_skip_counter= 1; +ERROR HY000: When using parallel replication and GTID with multiple replication domains, @@sql_slave_skip_counter can not be used. Instead, setting @@gtid_slave_pos explicitly can be used to skip to after a given GTID position. +include/stop_slave_io.inc +include/start_slave.inc +include/sync_with_master_gtid.inc +SELECT * FROM t2 WHERE a >= 30 ORDER BY a; +a +31 +32 +33 +34 +*** MDEV-6775: Wrong binlog order in parallel replication *** +connection server_1; +DELETE FROM t4; +INSERT INTO t4 VALUES (1,NULL), (3,NULL), (4,4), (5, NULL), (6, 6); +include/save_master_gtid.inc +connection server_2; +include/sync_with_master_gtid.inc +include/stop_slave.inc +SET @old_dbug= @@GLOBAL.debug_dbug; +SET GLOBAL debug_dbug="+d,inject_binlog_commit_before_get_LOCK_log"; +SET @old_format=@@GLOBAL.binlog_format; +SET GLOBAL binlog_format=ROW; +SET GLOBAL slave_parallel_threads=0; +SET GLOBAL slave_parallel_threads=10; +connection con1; +SET @old_format= @@binlog_format; +SET binlog_format= statement; +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued1 WAIT_FOR master_cont1'; +UPDATE t4 SET b=NULL WHERE a=6; +connection server_1; +SET debug_sync='now WAIT_FOR master_queued1'; +connection con2; +SET @old_format= @@binlog_format; +SET binlog_format= statement; +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued2'; +DELETE FROM t4 WHERE b <= 3; +connection server_1; +SET debug_sync='now WAIT_FOR master_queued2'; +SET debug_sync='now SIGNAL master_cont1'; +connection con1; +SET binlog_format= @old_format; +connection con2; +SET binlog_format= @old_format; +SET debug_sync='RESET'; +SELECT * FROM t4 ORDER BY a; +a b +1 NULL +3 NULL +4 4 +5 NULL +6 NULL +connection server_2; +include/start_slave.inc +SET debug_sync= 'now WAIT_FOR waiting'; +SELECT * FROM t4 ORDER BY a; +a b +1 NULL +3 NULL +4 4 +5 NULL +6 NULL +SET debug_sync= 'now SIGNAL cont'; +include/stop_slave.inc +SET GLOBAL debug_dbug=@old_dbug; +SET GLOBAL binlog_format= @old_format; +SET GLOBAL slave_parallel_threads=0; +SET GLOBAL slave_parallel_threads=10; +include/start_slave.inc +*** MDEV-7237: Parallel replication: incorrect relaylog position after stop/start the slave *** +connection server_1; +INSERT INTO t2 VALUES (40); +connection server_2; +include/stop_slave.inc +CHANGE MASTER TO master_use_gtid=no; +SET @old_dbug= @@GLOBAL.debug_dbug; +SET GLOBAL debug_dbug="+d,rpl_parallel_scheduled_gtid_0_x_100"; +SET GLOBAL debug_dbug="+d,rpl_parallel_wait_for_done_trigger"; +SET GLOBAL slave_parallel_threads=0; +SET GLOBAL slave_parallel_threads=10; +connection server_1; +INSERT INTO t2 VALUES (41); +INSERT INTO t2 VALUES (42); +SET @old_format= @@binlog_format; +SET binlog_format= statement; +DELETE FROM t2 WHERE a=40; +SET binlog_format= @old_format; +INSERT INTO t2 VALUES (43); +INSERT INTO t2 VALUES (44); +FLUSH LOGS; +INSERT INTO t2 VALUES (45); +SET gtid_seq_no=100; +INSERT INTO t2 VALUES (46); +connection con_temp2; +BEGIN; +SELECT * FROM t2 WHERE a=40 FOR UPDATE; +a +40 +connection server_2; +include/start_slave.inc +SET debug_sync= 'now WAIT_FOR scheduled_gtid_0_x_100'; +STOP SLAVE; +connection con_temp2; +SET debug_sync= 'now WAIT_FOR wait_for_done_waiting'; +ROLLBACK; +connection server_2; +include/wait_for_slave_sql_to_stop.inc +SELECT * FROM t2 WHERE a >= 40 ORDER BY a; +a +41 +42 +include/start_slave.inc +SELECT * FROM t2 WHERE a >= 40 ORDER BY a; +a +41 +42 +43 +44 +45 +46 +include/stop_slave.inc +SET GLOBAL debug_dbug=@old_dbug; +SET DEBUG_SYNC= 'RESET'; +SET GLOBAL slave_parallel_threads=0; +SET GLOBAL slave_parallel_threads=10; +CHANGE MASTER TO master_use_gtid=slave_pos; +include/start_slave.inc +*** MDEV-7326 Server deadlock in connection with parallel replication *** +connection server_2; +include/stop_slave.inc +SET GLOBAL slave_parallel_threads=0; +SET GLOBAL slave_parallel_threads=3; +SET GLOBAL debug_dbug="+d,rpl_parallel_simulate_temp_err_xid"; +include/start_slave.inc +connection server_1; +SET @old_format= @@SESSION.binlog_format; +SET binlog_format= STATEMENT; +INSERT INTO t1 VALUES (foo(50, +"rpl_parallel_start_waiting_for_prior SIGNAL t3_ready", +"rpl_parallel_end_of_group SIGNAL prep_ready WAIT_FOR prep_cont")); +connection server_2; +SET DEBUG_SYNC= "now WAIT_FOR prep_ready"; +connection server_1; +INSERT INTO t2 VALUES (foo(50, +"rpl_parallel_simulate_temp_err_xid SIGNAL t1_ready1 WAIT_FOR t1_cont1", +"rpl_parallel_retry_after_unmark SIGNAL t1_ready2 WAIT_FOR t1_cont2")); +connection server_2; +SET DEBUG_SYNC= "now WAIT_FOR t1_ready1"; +connection server_1; +INSERT INTO t1 VALUES (foo(51, +"rpl_parallel_before_mark_start_commit SIGNAL t2_ready1 WAIT_FOR t2_cont1", +"rpl_parallel_after_mark_start_commit SIGNAL t2_ready2")); +connection server_2; +SET DEBUG_SYNC= "now WAIT_FOR t2_ready1"; +SET DEBUG_SYNC= "now SIGNAL t1_cont1"; +SET DEBUG_SYNC= "now WAIT_FOR t1_ready2"; +connection server_1; +INSERT INTO t1 VALUES (52); +SET BINLOG_FORMAT= @old_format; +SELECT * FROM t2 WHERE a>=50 ORDER BY a; +a +50 +SELECT * FROM t1 WHERE a>=50 ORDER BY a; +a +50 +51 +52 +connection server_2; +SET DEBUG_SYNC= "now SIGNAL prep_cont"; +SET DEBUG_SYNC= "now WAIT_FOR t3_ready"; +SET DEBUG_SYNC= "now SIGNAL t2_cont1"; +SET DEBUG_SYNC= "now WAIT_FOR t2_ready2"; +SET DEBUG_SYNC= "now SIGNAL t1_cont2"; +connection server_1; +connection server_2; +SELECT * FROM t2 WHERE a>=50 ORDER BY a; +a +50 +SELECT * FROM t1 WHERE a>=50 ORDER BY a; +a +50 +51 +52 +SET DEBUG_SYNC="reset"; +include/stop_slave.inc +SET GLOBAL debug_dbug=@old_dbug; +SET GLOBAL slave_parallel_threads=0; +SET GLOBAL slave_parallel_threads=10; +include/start_slave.inc +*** MDEV-7326 Server deadlock in connection with parallel replication *** +connection server_2; +include/stop_slave.inc +SET GLOBAL slave_parallel_threads=0; +SET GLOBAL slave_parallel_threads=3; +SET GLOBAL debug_dbug="+d,rpl_parallel_simulate_temp_err_xid"; +include/start_slave.inc +connection server_1; +SET @old_format= @@SESSION.binlog_format; +SET binlog_format= STATEMENT; +INSERT INTO t1 VALUES (foo(60, +"rpl_parallel_start_waiting_for_prior SIGNAL t3_ready", +"rpl_parallel_end_of_group SIGNAL prep_ready WAIT_FOR prep_cont")); +connection server_2; +SET DEBUG_SYNC= "now WAIT_FOR prep_ready"; +connection server_1; +INSERT INTO t2 VALUES (foo(60, +"rpl_parallel_simulate_temp_err_xid SIGNAL t1_ready1 WAIT_FOR t1_cont1", +"rpl_parallel_retry_after_unmark SIGNAL t1_ready2 WAIT_FOR t1_cont2")); +connection server_2; +SET DEBUG_SYNC= "now WAIT_FOR t1_ready1"; +connection con_temp3; +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued1 WAIT_FOR master_cont1'; +SET binlog_format=statement; +INSERT INTO t1 VALUES (foo(61, +"rpl_parallel_before_mark_start_commit SIGNAL t2_ready1 WAIT_FOR t2_cont1", +"rpl_parallel_after_mark_start_commit SIGNAL t2_ready2")); +connection server_1; +SET debug_sync='now WAIT_FOR master_queued1'; +connection con_temp4; +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued2'; +INSERT INTO t6 VALUES (62); +connection server_1; +SET debug_sync='now WAIT_FOR master_queued2'; +SET debug_sync='now SIGNAL master_cont1'; +connection con_temp3; +connection con_temp4; +connection server_1; +SET debug_sync='RESET'; +SET BINLOG_FORMAT= @old_format; +SELECT * FROM t2 WHERE a>=60 ORDER BY a; +a +60 +SELECT * FROM t1 WHERE a>=60 ORDER BY a; +a +60 +61 +SELECT * FROM t6 WHERE a>=60 ORDER BY a; +a +62 +connection server_2; +SET DEBUG_SYNC= "now WAIT_FOR t2_ready1"; +SET DEBUG_SYNC= "now SIGNAL t1_cont1"; +SET DEBUG_SYNC= "now WAIT_FOR t1_ready2"; +connection server_2; +SET DEBUG_SYNC= "now SIGNAL prep_cont"; +SET DEBUG_SYNC= "now WAIT_FOR t3_ready"; +SET DEBUG_SYNC= "now SIGNAL t2_cont1"; +SET DEBUG_SYNC= "now WAIT_FOR t2_ready2"; +SET DEBUG_SYNC= "now SIGNAL t1_cont2"; +connection server_1; +connection server_2; +SELECT * FROM t2 WHERE a>=60 ORDER BY a; +a +60 +SELECT * FROM t1 WHERE a>=60 ORDER BY a; +a +60 +61 +SELECT * FROM t6 WHERE a>=60 ORDER BY a; +a +62 +SET DEBUG_SYNC="reset"; +include/stop_slave.inc +SET GLOBAL debug_dbug=@old_dbug; +SET GLOBAL slave_parallel_threads=0; +SET GLOBAL slave_parallel_threads=10; +include/start_slave.inc +*** MDEV-7335: Potential parallel slave deadlock with specific binlog corruption *** +connection server_2; +include/stop_slave.inc +SET GLOBAL slave_parallel_threads=1; +SET @old_dbug= @@GLOBAL.debug_dbug; +SET GLOBAL debug_dbug="+d,slave_discard_xid_for_gtid_0_x_1000"; +connection server_1; +INSERT INTO t2 VALUES (101); +INSERT INTO t2 VALUES (102); +INSERT INTO t2 VALUES (103); +INSERT INTO t2 VALUES (104); +INSERT INTO t2 VALUES (105); +SET gtid_seq_no=1000; +INSERT INTO t2 VALUES (106); +INSERT INTO t2 VALUES (107); +INSERT INTO t2 VALUES (108); +INSERT INTO t2 VALUES (109); +INSERT INTO t2 VALUES (110); +INSERT INTO t2 VALUES (111); +INSERT INTO t2 VALUES (112); +INSERT INTO t2 VALUES (113); +INSERT INTO t2 VALUES (114); +INSERT INTO t2 VALUES (115); +INSERT INTO t2 VALUES (116); +INSERT INTO t2 VALUES (117); +INSERT INTO t2 VALUES (118); +INSERT INTO t2 VALUES (119); +INSERT INTO t2 VALUES (120); +INSERT INTO t2 VALUES (121); +INSERT INTO t2 VALUES (122); +INSERT INTO t2 VALUES (123); +INSERT INTO t2 VALUES (124); +INSERT INTO t2 VALUES (125); +INSERT INTO t2 VALUES (126); +INSERT INTO t2 VALUES (127); +INSERT INTO t2 VALUES (128); +INSERT INTO t2 VALUES (129); +INSERT INTO t2 VALUES (130); +include/save_master_gtid.inc +connection server_2; +include/start_slave.inc +include/sync_with_master_gtid.inc +SELECT * FROM t2 WHERE a >= 100 ORDER BY a; +a +101 +102 +103 +104 +105 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +include/stop_slave.inc +SET GLOBAL debug_dbug=@old_dbug; +SET GLOBAL slave_parallel_threads=10; +include/start_slave.inc +*** MDEV-6676 - test syntax of @@slave_parallel_mode *** +connection server_2; +Parallel_Mode = 'conservative' +include/stop_slave.inc +SET GLOBAL slave_parallel_mode='aggressive'; +Parallel_Mode = 'aggressive' +SET GLOBAL slave_parallel_mode='conservative'; +Parallel_Mode = 'conservative' +*** MDEV-6676 - test that empty parallel_mode does not replicate in parallel *** +connection server_1; +INSERT INTO t2 VALUES (1040); +include/save_master_gtid.inc +connection server_2; +SET GLOBAL slave_parallel_mode='none'; +SET @old_dbug= @@GLOBAL.debug_dbug; +SET GLOBAL debug_dbug="+d,slave_crash_if_parallel_apply"; +include/start_slave.inc +include/sync_with_master_gtid.inc +SELECT * FROM t2 WHERE a >= 1040 ORDER BY a; +a +1040 +include/stop_slave.inc +SET GLOBAL debug_dbug=@old_dbug; +*** MDEV-6676 - test disabling domain-based parallel replication *** +connection server_1; +SET gtid_domain_id = 1; +INSERT INTO t2 VALUES (1041); +INSERT INTO t2 VALUES (1042); +INSERT INTO t2 VALUES (1043); +INSERT INTO t2 VALUES (1044); +INSERT INTO t2 VALUES (1045); +INSERT INTO t2 VALUES (1046); +DELETE FROM t2 WHERE a >= 1041; +SET gtid_domain_id = 2; +INSERT INTO t2 VALUES (1041); +INSERT INTO t2 VALUES (1042); +INSERT INTO t2 VALUES (1043); +INSERT INTO t2 VALUES (1044); +INSERT INTO t2 VALUES (1045); +INSERT INTO t2 VALUES (1046); +SET gtid_domain_id = 0; +include/save_master_gtid.inc +connection server_2; +SET GLOBAL slave_parallel_mode=minimal; +include/start_slave.inc +include/sync_with_master_gtid.inc +SELECT * FROM t2 WHERE a >= 1040 ORDER BY a; +a +1040 +1041 +1042 +1043 +1044 +1045 +1046 +include/stop_slave.inc +SET GLOBAL slave_parallel_mode='conservative'; +include/start_slave.inc +*** MDEV-7847: "Slave worker thread retried transaction 10 time(s) in vain, giving up", followed by replication hanging *** +*** MDEV-7882: Excessive transaction retry in parallel replication *** +connection server_1; +CREATE TABLE t7 (a int PRIMARY KEY, b INT) ENGINE=InnoDB; +CREATE TABLE t8 (a int PRIMARY KEY, b INT) ENGINE=InnoDB; +connection server_2; +include/stop_slave.inc +SET GLOBAL slave_parallel_threads=40; +SELECT @old_retries:=@@GLOBAL.slave_transaction_retries; +@old_retries:=@@GLOBAL.slave_transaction_retries +10 +SET GLOBAL slave_transaction_retries= 5; +connection server_1; +INSERT INTO t7 VALUES (1,1), (2,2), (3,3), (4,4), (5,5); +SET @old_dbug= @@SESSION.debug_dbug; +SET @commit_id= 42; +SET SESSION debug_dbug="+d,binlog_force_commit_id"; +INSERT INTO t8 VALUES (1,1); +INSERT INTO t8 VALUES (2,2); +INSERT INTO t8 VALUES (3,3); +INSERT INTO t8 VALUES (4,4); +INSERT INTO t8 VALUES (5,5); +INSERT INTO t8 VALUES (6,6); +INSERT INTO t8 VALUES (7,7); +INSERT INTO t8 VALUES (8,8); +UPDATE t7 SET b=9 WHERE a=3; +UPDATE t7 SET b=10 WHERE a=3; +UPDATE t7 SET b=11 WHERE a=3; +INSERT INTO t8 VALUES (12,12); +INSERT INTO t8 VALUES (13,13); +UPDATE t7 SET b=14 WHERE a=3; +UPDATE t7 SET b=15 WHERE a=3; +INSERT INTO t8 VALUES (16,16); +UPDATE t7 SET b=17 WHERE a=3; +INSERT INTO t8 VALUES (18,18); +INSERT INTO t8 VALUES (19,19); +UPDATE t7 SET b=20 WHERE a=3; +INSERT INTO t8 VALUES (21,21); +UPDATE t7 SET b=22 WHERE a=3; +INSERT INTO t8 VALUES (23,24); +INSERT INTO t8 VALUES (24,24); +UPDATE t7 SET b=25 WHERE a=3; +INSERT INTO t8 VALUES (26,26); +UPDATE t7 SET b=27 WHERE a=3; +BEGIN; +INSERT INTO t8 VALUES (28,28); +INSERT INTO t8 VALUES (29,28), (30,28); +INSERT INTO t8 VALUES (31,28); +INSERT INTO t8 VALUES (32,28); +INSERT INTO t8 VALUES (33,28); +INSERT INTO t8 VALUES (34,28); +INSERT INTO t8 VALUES (35,28); +INSERT INTO t8 VALUES (36,28); +INSERT INTO t8 VALUES (37,28); +INSERT INTO t8 VALUES (38,28); +INSERT INTO t8 VALUES (39,28); +INSERT INTO t8 VALUES (40,28); +INSERT INTO t8 VALUES (41,28); +INSERT INTO t8 VALUES (42,28); +COMMIT; +SET @commit_id=43; +INSERT INTO t8 VALUES (43,43); +INSERT INTO t8 VALUES (44,44); +UPDATE t7 SET b=45 WHERE a=3; +INSERT INTO t8 VALUES (46,46); +INSERT INTO t8 VALUES (47,47); +UPDATE t7 SET b=48 WHERE a=3; +INSERT INTO t8 VALUES (49,49); +INSERT INTO t8 VALUES (50,50); +SET @commit_id=44; +INSERT INTO t8 VALUES (51,51); +INSERT INTO t8 VALUES (52,52); +UPDATE t7 SET b=53 WHERE a=3; +INSERT INTO t8 VALUES (54,54); +INSERT INTO t8 VALUES (55,55); +UPDATE t7 SET b=56 WHERE a=3; +INSERT INTO t8 VALUES (57,57); +UPDATE t7 SET b=58 WHERE a=3; +INSERT INTO t8 VALUES (58,58); +INSERT INTO t8 VALUES (59,59); +INSERT INTO t8 VALUES (60,60); +INSERT INTO t8 VALUES (61,61); +UPDATE t7 SET b=62 WHERE a=3; +INSERT INTO t8 VALUES (63,63); +INSERT INTO t8 VALUES (64,64); +INSERT INTO t8 VALUES (65,65); +INSERT INTO t8 VALUES (66,66); +UPDATE t7 SET b=67 WHERE a=3; +INSERT INTO t8 VALUES (68,68); +UPDATE t7 SET b=69 WHERE a=3; +UPDATE t7 SET b=70 WHERE a=3; +UPDATE t7 SET b=71 WHERE a=3; +INSERT INTO t8 VALUES (72,72); +UPDATE t7 SET b=73 WHERE a=3; +UPDATE t7 SET b=74 WHERE a=3; +UPDATE t7 SET b=75 WHERE a=3; +UPDATE t7 SET b=76 WHERE a=3; +INSERT INTO t8 VALUES (77,77); +UPDATE t7 SET b=78 WHERE a=3; +INSERT INTO t8 VALUES (79,79); +UPDATE t7 SET b=80 WHERE a=3; +INSERT INTO t8 VALUES (81,81); +UPDATE t7 SET b=82 WHERE a=3; +INSERT INTO t8 VALUES (83,83); +UPDATE t7 SET b=84 WHERE a=3; +SET @commit_id=45; +INSERT INTO t8 VALUES (85,85); +UPDATE t7 SET b=86 WHERE a=3; +INSERT INTO t8 VALUES (87,87); +SET @commit_id=46; +INSERT INTO t8 VALUES (88,88); +INSERT INTO t8 VALUES (89,89); +INSERT INTO t8 VALUES (90,90); +SET SESSION debug_dbug=@old_dbug; +INSERT INTO t8 VALUES (91,91); +INSERT INTO t8 VALUES (92,92); +INSERT INTO t8 VALUES (93,93); +INSERT INTO t8 VALUES (94,94); +INSERT INTO t8 VALUES (95,95); +INSERT INTO t8 VALUES (96,96); +INSERT INTO t8 VALUES (97,97); +INSERT INTO t8 VALUES (98,98); +INSERT INTO t8 VALUES (99,99); +SELECT * FROM t7 ORDER BY a; +a b +1 1 +2 2 +3 86 +4 4 +5 5 +SELECT * FROM t8 ORDER BY a; +a b +1 1 +2 2 +3 3 +4 4 +5 5 +6 6 +7 7 +8 8 +12 12 +13 13 +16 16 +18 18 +19 19 +21 21 +23 24 +24 24 +26 26 +28 28 +29 28 +30 28 +31 28 +32 28 +33 28 +34 28 +35 28 +36 28 +37 28 +38 28 +39 28 +40 28 +41 28 +42 28 +43 43 +44 44 +46 46 +47 47 +49 49 +50 50 +51 51 +52 52 +54 54 +55 55 +57 57 +58 58 +59 59 +60 60 +61 61 +63 63 +64 64 +65 65 +66 66 +68 68 +72 72 +77 77 +79 79 +81 81 +83 83 +85 85 +87 87 +88 88 +89 89 +90 90 +91 91 +92 92 +93 93 +94 94 +95 95 +96 96 +97 97 +98 98 +99 99 +include/save_master_gtid.inc +connection server_2; +include/start_slave.inc +include/sync_with_master_gtid.inc +SELECT * FROM t7 ORDER BY a; +a b +1 1 +2 2 +3 86 +4 4 +5 5 +SELECT * FROM t8 ORDER BY a; +a b +1 1 +2 2 +3 3 +4 4 +5 5 +6 6 +7 7 +8 8 +12 12 +13 13 +16 16 +18 18 +19 19 +21 21 +23 24 +24 24 +26 26 +28 28 +29 28 +30 28 +31 28 +32 28 +33 28 +34 28 +35 28 +36 28 +37 28 +38 28 +39 28 +40 28 +41 28 +42 28 +43 43 +44 44 +46 46 +47 47 +49 49 +50 50 +51 51 +52 52 +54 54 +55 55 +57 57 +58 58 +59 59 +60 60 +61 61 +63 63 +64 64 +65 65 +66 66 +68 68 +72 72 +77 77 +79 79 +81 81 +83 83 +85 85 +87 87 +88 88 +89 89 +90 90 +91 91 +92 92 +93 93 +94 94 +95 95 +96 96 +97 97 +98 98 +99 99 +include/stop_slave.inc +SET GLOBAL slave_transaction_retries= @old_retries; +SET GLOBAL slave_parallel_threads=10; +include/start_slave.inc +*** MDEV-7888: ANALYZE TABLE does wakeup_subsequent_commits(), causing wrong binlog order and parallel replication hang *** +connection server_2; +include/stop_slave.inc +SET @old_dbug= @@GLOBAL.debug_dbug; +SET GLOBAL debug_dbug= '+d,inject_analyze_table_sleep'; +connection server_1; +SET @old_dbug= @@SESSION.debug_dbug; +SET SESSION debug_dbug="+d,binlog_force_commit_id"; +SET @commit_id= 10000; +ANALYZE TABLE t2; +Table Op Msg_type Msg_text +test.t2 analyze status OK +INSERT INTO t3 VALUES (120, 0); +SET @commit_id= 10001; +INSERT INTO t3 VALUES (121, 0); +SET SESSION debug_dbug=@old_dbug; +SELECT * FROM t3 WHERE a >= 120 ORDER BY a; +a b +120 0 +121 0 +include/save_master_gtid.inc +connection server_2; +include/start_slave.inc +include/sync_with_master_gtid.inc +SELECT * FROM t3 WHERE a >= 120 ORDER BY a; +a b +120 0 +121 0 +include/stop_slave.inc +SET GLOBAL debug_dbug= @old_dbug; +include/start_slave.inc +*** MDEV-7929: record_gtid() for non-transactional event group calls wakeup_subsequent_commits() too early, causing slave hang. *** +connection server_2; +include/stop_slave.inc +SET @old_dbug= @@GLOBAL.debug_dbug; +SET GLOBAL debug_dbug= '+d,inject_record_gtid_serverid_100_sleep'; +connection server_1; +SET @old_dbug= @@SESSION.debug_dbug; +SET SESSION debug_dbug="+d,binlog_force_commit_id"; +SET @old_server_id= @@SESSION.server_id; +SET SESSION server_id= 100; +SET @commit_id= 10010; +ALTER TABLE t1 COMMENT "Hulubulu!"; +SET SESSION server_id= @old_server_id; +INSERT INTO t3 VALUES (130, 0); +SET @commit_id= 10011; +INSERT INTO t3 VALUES (131, 0); +SET SESSION debug_dbug=@old_dbug; +SELECT * FROM t3 WHERE a >= 130 ORDER BY a; +a b +130 0 +131 0 +include/save_master_gtid.inc +connection server_2; +include/start_slave.inc +include/sync_with_master_gtid.inc +SELECT * FROM t3 WHERE a >= 130 ORDER BY a; +a b +130 0 +131 0 +include/stop_slave.inc +SET GLOBAL debug_dbug= @old_dbug; +include/start_slave.inc +*** MDEV-8031: Parallel replication stops on "connection killed" error (probably incorrectly handled deadlock kill) *** +connection server_1; +INSERT INTO t3 VALUES (201,0), (202,0); +include/save_master_gtid.inc +connection server_2; +include/sync_with_master_gtid.inc +include/stop_slave.inc +SET @old_dbug= @@GLOBAL.debug_dbug; +SET GLOBAL debug_dbug= '+d,inject_mdev8031'; +connection server_1; +SET @old_dbug= @@SESSION.debug_dbug; +SET SESSION debug_dbug="+d,binlog_force_commit_id"; +SET @commit_id= 10200; +INSERT INTO t3 VALUES (203, 1); +INSERT INTO t3 VALUES (204, 1); +INSERT INTO t3 VALUES (205, 1); +UPDATE t3 SET b=b+1 WHERE a=201; +UPDATE t3 SET b=b+1 WHERE a=201; +UPDATE t3 SET b=b+1 WHERE a=201; +UPDATE t3 SET b=b+1 WHERE a=202; +UPDATE t3 SET b=b+1 WHERE a=202; +UPDATE t3 SET b=b+1 WHERE a=202; +UPDATE t3 SET b=b+1 WHERE a=202; +UPDATE t3 SET b=b+1 WHERE a=203; +UPDATE t3 SET b=b+1 WHERE a=203; +UPDATE t3 SET b=b+1 WHERE a=204; +UPDATE t3 SET b=b+1 WHERE a=204; +UPDATE t3 SET b=b+1 WHERE a=204; +UPDATE t3 SET b=b+1 WHERE a=203; +UPDATE t3 SET b=b+1 WHERE a=205; +UPDATE t3 SET b=b+1 WHERE a=205; +SET SESSION debug_dbug=@old_dbug; +SELECT * FROM t3 WHERE a>=200 ORDER BY a; +a b +201 3 +202 4 +203 4 +204 4 +205 3 +include/save_master_gtid.inc +connection server_2; +include/start_slave.inc +include/sync_with_master_gtid.inc +SELECT * FROM t3 WHERE a>=200 ORDER BY a; +a b +201 3 +202 4 +203 4 +204 4 +205 3 +include/stop_slave.inc +SET GLOBAL debug_dbug= @old_dbug; +include/start_slave.inc +*** Check getting deadlock killed inside open_binlog() during retry. *** +connection server_2; +include/stop_slave.inc +SET @old_dbug= @@GLOBAL.debug_dbug; +SET GLOBAL debug_dbug= '+d,inject_retry_event_group_open_binlog_kill'; +SET @old_max= @@GLOBAL.max_relay_log_size; +SET GLOBAL max_relay_log_size= 4096; +connection server_1; +SET @old_dbug= @@SESSION.debug_dbug; +SET SESSION debug_dbug="+d,binlog_force_commit_id"; +SET @commit_id= 10210; +Omit long queries that cause relaylog rotations and transaction retries... +SET SESSION debug_dbug=@old_dbug; +SELECT * FROM t3 WHERE a>=200 ORDER BY a; +a b +201 6 +202 8 +203 7 +204 7 +205 5 +include/save_master_gtid.inc +connection server_2; +include/start_slave.inc +include/sync_with_master_gtid.inc +SELECT * FROM t3 WHERE a>=200 ORDER BY a; +a b +201 6 +202 8 +203 7 +204 7 +205 5 +include/stop_slave.inc +SET GLOBAL debug_dbug= @old_debg; +SET GLOBAL max_relay_log_size= @old_max; +include/start_slave.inc +*** MDEV-8302: Duplicate key with parallel replication *** +connection server_2; +include/stop_slave.inc +/* Inject a small sleep which makes the race easier to hit. */ +SET @old_dbug=@@GLOBAL.debug_dbug; +SET GLOBAL debug_dbug="+d,inject_mdev8302"; +connection server_1; +INSERT INTO t7 VALUES (100,1), (101,2), (102,3), (103,4), (104,5); +SET @old_dbug= @@SESSION.debug_dbug; +SET @commit_id= 20000; +SET SESSION debug_dbug="+d,binlog_force_commit_id"; +SET SESSION debug_dbug=@old_dbug; +SELECT * FROM t7 ORDER BY a; +a b +1 1 +2 2 +3 86 +4 4 +5 5 +100 5 +101 1 +102 2 +103 3 +104 4 +include/save_master_gtid.inc +connection server_2; +include/start_slave.inc +include/sync_with_master_gtid.inc +SELECT * FROM t7 ORDER BY a; +a b +1 1 +2 2 +3 86 +4 4 +5 5 +100 5 +101 1 +102 2 +103 3 +104 4 +include/stop_slave.inc +SET GLOBAL debug_dbug=@old_dbug; +include/start_slave.inc +*** MDEV-8725: Assertion on ROLLBACK statement in the binary log *** +connection server_1; +BEGIN; +INSERT INTO t2 VALUES (2000); +INSERT INTO t1 VALUES (2000); +INSERT INTO t2 VALUES (2001); +ROLLBACK; +SELECT * FROM t1 WHERE a>=2000 ORDER BY a; +a +2000 +SELECT * FROM t2 WHERE a>=2000 ORDER BY a; +a +include/save_master_gtid.inc +connection server_2; +include/sync_with_master_gtid.inc +SELECT * FROM t1 WHERE a>=2000 ORDER BY a; +a +2000 +SELECT * FROM t2 WHERE a>=2000 ORDER BY a; +a +connection server_2; +include/stop_slave.inc +SET GLOBAL slave_parallel_threads=@old_parallel_threads; +include/start_slave.inc +SET DEBUG_SYNC= 'RESET'; +connection server_1; +DROP function foo; +DROP TABLE t1,t2,t3,t4,t5,t6,t7,t8; +SET DEBUG_SYNC= 'RESET'; +include/rpl_end.inc diff --git a/mysql-test/suite/binlog_encryption/rpl_parallel.test b/mysql-test/suite/binlog_encryption/rpl_parallel.test new file mode 100644 index 0000000..51eae32 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_parallel.test @@ -0,0 +1,2729 @@ +# +# The test was taken from the rpl suite as is +# + +--source include/have_debug.inc +--source include/have_debug_sync.inc +--source include/master-slave.inc + +--enable_connect_log + +# Test various aspects of parallel replication. + +--connection server_2 +SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads; +--error ER_SLAVE_MUST_STOP +SET GLOBAL slave_parallel_threads=10; +--disable_connect_log +--source include/stop_slave.inc +--enable_connect_log +SET GLOBAL slave_parallel_threads=10; + +# Check that we do not spawn any worker threads when no slave is running. +SELECT IF(COUNT(*) < 10, "OK", CONCAT("Found too many system user processes: ", COUNT(*))) FROM information_schema.processlist WHERE user = "system user"; + +CHANGE MASTER TO master_use_gtid=slave_pos; +--disable_connect_log +--source include/start_slave.inc +--enable_connect_log + +# Check that worker threads get spawned when slave starts. +SELECT IF(COUNT(*) >= 10, "OK", CONCAT("Found too few system user processes: ", COUNT(*))) FROM information_schema.processlist WHERE user = "system user"; +# ... and that worker threads get removed when slave stops. +--disable_connect_log +--source include/stop_slave.inc +--enable_connect_log +SELECT IF(COUNT(*) < 10, "OK", CONCAT("Found too many system user processes: ", COUNT(*))) FROM information_schema.processlist WHERE user = "system user"; +--disable_connect_log +--source include/start_slave.inc +--enable_connect_log +SELECT IF(COUNT(*) >= 10, "OK", CONCAT("Found too few system user processes: ", COUNT(*))) FROM information_schema.processlist WHERE user = "system user"; + +--echo *** Test long-running query in domain 1 can run in parallel with short queries in domain 0 *** + +--connection server_1 +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +CREATE TABLE t1 (a int PRIMARY KEY) ENGINE=MyISAM; +CREATE TABLE t2 (a int PRIMARY KEY) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1); +INSERT INTO t2 VALUES (1); +--save_master_pos + +--connection server_2 +--sync_with_master + +# Block the table t1 to simulate a replicated query taking a long time. +--connect (con_temp1,127.0.0.1,root,,test,$SERVER_MYPORT_2,) +LOCK TABLE t1 WRITE; + +--connection server_1 +SET gtid_domain_id=1; +# This query will be blocked on the slave until UNLOCK TABLES. +INSERT INTO t1 VALUES (2); +SET gtid_domain_id=0; +# These t2 queries can be replicated in parallel with the prior t1 query, as +# they are in a separate replication domain. +INSERT INTO t2 VALUES (2); +INSERT INTO t2 VALUES (3); +BEGIN; +INSERT INTO t2 VALUES (4); +INSERT INTO t2 VALUES (5); +COMMIT; +INSERT INTO t2 VALUES (6); + +--connection server_2 +--let $wait_condition= SELECT COUNT(*) = 6 FROM t2 +--disable_connect_log +--source include/wait_condition.inc +--enable_connect_log + +SELECT * FROM t2 ORDER by a; + +--connection con_temp1 +SELECT * FROM t1; +UNLOCK TABLES; + +--connection server_2 +--let $wait_condition= SELECT COUNT(*) = 2 FROM t1 +--disable_connect_log +--source include/wait_condition.inc +--enable_connect_log + +SELECT * FROM t1 ORDER BY a; + + +--echo *** Test two transactions in different domains committed in opposite order on slave but in a single group commit. *** +--connection server_2 +--disable_connect_log +--source include/stop_slave.inc +--enable_connect_log + +--connection server_1 +# Use a stored function to inject a debug_sync into the appropriate THD. +# The function does nothing on the master, and on the slave it injects the +# desired debug_sync action(s). +SET sql_log_bin=0; +--delimiter || +CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) + RETURNS INT DETERMINISTIC + BEGIN + RETURN x; + END +|| +--delimiter ; +SET sql_log_bin=1; + +SET @old_format= @@SESSION.binlog_format; +SET binlog_format='statement'; +SET gtid_domain_id=1; +INSERT INTO t2 VALUES (foo(10, + 'commit_before_enqueue SIGNAL ready1 WAIT_FOR cont1', + 'commit_after_release_LOCK_prepare_ordered SIGNAL ready2')); + +--connection server_2 +FLUSH LOGS; +--disable_connect_log +--source include/wait_for_binlog_checkpoint.inc +--enable_connect_log +SET sql_log_bin=0; +--delimiter || +CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) + RETURNS INT DETERMINISTIC + BEGIN + IF d1 != '' THEN + SET debug_sync = d1; + END IF; + IF d2 != '' THEN + SET debug_sync = d2; + END IF; + RETURN x; + END +|| +--delimiter ; +SET sql_log_bin=1; +SET @old_format=@@GLOBAL.binlog_format; +SET GLOBAL binlog_format=statement; +# We need to restart all parallel threads for the new global setting to +# be copied to the session-level values. +SET GLOBAL slave_parallel_threads=0; +SET GLOBAL slave_parallel_threads=10; +--disable_connect_log +--source include/start_slave.inc +--enable_connect_log + +# First make sure the first insert is ready to commit, but not queued yet. +SET debug_sync='now WAIT_FOR ready1'; + +--connection server_1 +SET gtid_domain_id=2; +INSERT INTO t2 VALUES (foo(11, + 'commit_before_enqueue SIGNAL ready3 WAIT_FOR cont3', + 'commit_after_release_LOCK_prepare_ordered SIGNAL ready4 WAIT_FOR cont4')); +SET gtid_domain_id=0; +SELECT * FROM t2 WHERE a >= 10 ORDER BY a; + +--connection server_2 +# Now wait for the second insert to queue itself as the leader, and then +# wait for more commits to queue up. +SET debug_sync='now WAIT_FOR ready3'; +SET debug_sync='now SIGNAL cont3'; +SET debug_sync='now WAIT_FOR ready4'; +# Now allow the first insert to queue up to participate in group commit. +SET debug_sync='now SIGNAL cont1'; +SET debug_sync='now WAIT_FOR ready2'; +# Finally allow the second insert to proceed and do the group commit. +SET debug_sync='now SIGNAL cont4'; + +--let $wait_condition= SELECT COUNT(*) = 2 FROM t2 WHERE a >= 10 +--disable_connect_log +--source include/wait_condition.inc +--enable_connect_log +SELECT * FROM t2 WHERE a >= 10 ORDER BY a; +# The two INSERT transactions should have been committed in opposite order, +# but in the same group commit (seen by precense of cid=# in the SHOW +# BINLOG output). +--let $binlog_file= slave-bin.000002 +--disable_connect_log +--source include/show_binlog_events.inc +--enable_connect_log +FLUSH LOGS; +--disable_connect_log +--source include/wait_for_binlog_checkpoint.inc +--enable_connect_log + +# Restart all the slave parallel worker threads, to clear all debug_sync actions. +--connection server_2 +--disable_connect_log +--source include/stop_slave.inc +--enable_connect_log +SET GLOBAL slave_parallel_threads=0; +SET GLOBAL slave_parallel_threads=10; +SET debug_sync='RESET'; +--disable_connect_log +--source include/start_slave.inc +--enable_connect_log + + +--echo *** Test that group-committed transactions on the master can replicate in parallel on the slave. *** +--connection server_1 +SET debug_sync='RESET'; +FLUSH LOGS; +--disable_connect_log +--source include/wait_for_binlog_checkpoint.inc +--enable_connect_log +CREATE TABLE t3 (a INT PRIMARY KEY, b INT) ENGINE=InnoDB; +# Create some sentinel rows so that the rows inserted in parallel fall into +# separate gaps and do not cause gap lock conflicts. +INSERT INTO t3 VALUES (1,1), (3,3), (5,5), (7,7); +--save_master_pos +--connection server_2 +--sync_with_master + +# We want to test that the transactions can execute out-of-order on +# the slave, but still end up committing in-order, and in a single +# group commit. +# +# The idea is to group-commit three transactions together on the master: +# A, B, and C. On the slave, C will execute the insert first, then A, +# and then B. But B manages to complete before A has time to commit, so +# all three end up committing together. +# +# So we start by setting up some row locks that will block transactions +# A and B from executing, allowing C to run first. + +--connection con_temp1 +BEGIN; +INSERT INTO t3 VALUES (2,102); +--connect (con_temp2,127.0.0.1,root,,test,$SERVER_MYPORT_2,) +BEGIN; +INSERT INTO t3 VALUES (4,104); + +# On the master, queue three INSERT transactions as a single group commit. +--connect (con_temp3,127.0.0.1,root,,test,$SERVER_MYPORT_1,) +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued1 WAIT_FOR master_cont1'; +SET binlog_format=statement; +send INSERT INTO t3 VALUES (2, foo(12, + 'commit_after_release_LOCK_prepare_ordered SIGNAL slave_queued1 WAIT_FOR slave_cont1', + '')); + +--connection server_1 +SET debug_sync='now WAIT_FOR master_queued1'; + +--connect (con_temp4,127.0.0.1,root,,test,$SERVER_MYPORT_1,) +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued2'; +SET binlog_format=statement; +send INSERT INTO t3 VALUES (4, foo(14, + 'commit_after_release_LOCK_prepare_ordered SIGNAL slave_queued2', + '')); + +--connection server_1 +SET debug_sync='now WAIT_FOR master_queued2'; + +--connect (con_temp5,127.0.0.1,root,,test,$SERVER_MYPORT_1,) +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued3'; +SET binlog_format=statement; +send INSERT INTO t3 VALUES (6, foo(16, + 'group_commit_waiting_for_prior SIGNAL slave_queued3', + '')); + +--connection server_1 +SET debug_sync='now WAIT_FOR master_queued3'; +SET debug_sync='now SIGNAL master_cont1'; + +--connection con_temp3 +REAP; +--connection con_temp4 +REAP; +--connection con_temp5 +REAP; +SET debug_sync='RESET'; + +--connection server_1 +SELECT * FROM t3 ORDER BY a; +--let $binlog_file= master-bin.000002 +--disable_connect_log +--source include/show_binlog_events.inc +--enable_connect_log + +# First, wait until insert 3 is ready to queue up for group commit, but is +# waiting for insert 2 to commit before it can do so itself. +--connection server_2 +SET debug_sync='now WAIT_FOR slave_queued3'; + +# Next, let insert 1 proceed, and allow it to queue up as the group commit +# leader, but let it wait for insert 2 to also queue up before proceeding. +--connection con_temp1 +ROLLBACK; +--connection server_2 +SET debug_sync='now WAIT_FOR slave_queued1'; + +# Now let insert 2 proceed and queue up. +--connection con_temp2 +ROLLBACK; +--connection server_2 +SET debug_sync='now WAIT_FOR slave_queued2'; +# And finally, we can let insert 1 proceed and do the group commit with all +# three insert transactions together. +SET debug_sync='now SIGNAL slave_cont1'; + +# Wait for the commit to complete and check that all three transactions +# group-committed together (will be seen in the binlog as all three having +# cid=# on their GTID event). +--let $wait_condition= SELECT COUNT(*) = 3 FROM t3 WHERE a IN (2,4,6) +--disable_connect_log +--source include/wait_condition.inc +--enable_connect_log +SELECT * FROM t3 ORDER BY a; +--let $binlog_file= slave-bin.000003 +--disable_connect_log +--source include/show_binlog_events.inc +--enable_connect_log + + +--echo *** Test STOP SLAVE in parallel mode *** +--connection server_2 +--disable_connect_log +--source include/stop_slave.inc +--enable_connect_log +# Respawn all worker threads to clear any left-over debug_sync or other stuff. +SET debug_sync='RESET'; +SET GLOBAL slave_parallel_threads=0; +SET GLOBAL slave_parallel_threads=10; + +--connection server_1 +# Set up a couple of transactions. The first will be blocked halfway +# through on a lock, and while it is blocked we initiate STOP SLAVE. +# We then test that the halfway-initiated transaction is allowed to +# complete, but no subsequent ones. +# We have to use statement-based mode and set +# binlog_direct_non_transactional_updates=0; otherwise the binlog will +# be split into two event groups, one for the MyISAM part and one for the +# InnoDB part. +SET binlog_direct_non_transactional_updates=0; +SET sql_log_bin=0; +CALL mtr.add_suppression("Statement is unsafe because it accesses a non-transactional table after accessing a transactional table within the same transaction"); +SET sql_log_bin=1; +BEGIN; +INSERT INTO t2 VALUES (20); +--disable_warnings +INSERT INTO t1 VALUES (20); +--enable_warnings +INSERT INTO t2 VALUES (21); +INSERT INTO t3 VALUES (20, 20); +COMMIT; +INSERT INTO t3 VALUES(21, 21); +INSERT INTO t3 VALUES(22, 22); +SET binlog_format=@old_format; +--save_master_pos + +# Start a connection that will block the replicated transaction halfway. +--connection con_temp1 +BEGIN; +INSERT INTO t2 VALUES (21); + +--connection server_2 +START SLAVE; +# Wait for the MyISAM change to be visible, after which replication will wait +# for con_temp1 to roll back. +--let $wait_condition= SELECT COUNT(*) = 1 FROM t1 WHERE a=20 +--disable_connect_log +--source include/wait_condition.inc +--enable_connect_log + +--connection con_temp2 +# Initiate slave stop. It will have to wait for the current event group +# to complete. +# The dbug injection causes debug_sync to signal 'wait_for_done_waiting' +# when the SQL driver thread is ready. +SET @old_dbug= @@GLOBAL.debug_dbug; +SET GLOBAL debug_dbug="+d,rpl_parallel_wait_for_done_trigger"; +send STOP SLAVE; + +--connection con_temp1 +SET debug_sync='now WAIT_FOR wait_for_done_waiting'; +ROLLBACK; + +--connection con_temp2 +reap; +SET GLOBAL debug_dbug=@old_dbug; +SET debug_sync='RESET'; + +--connection server_2 +--disable_connect_log +--source include/wait_for_slave_to_stop.inc +--enable_connect_log +# We should see the first transaction applied, but not the two others. +SELECT * FROM t1 WHERE a >= 20 ORDER BY a; +SELECT * FROM t2 WHERE a >= 20 ORDER BY a; +SELECT * FROM t3 WHERE a >= 20 ORDER BY a; + +--disable_connect_log +--source include/start_slave.inc +--enable_connect_log +--sync_with_master +SELECT * FROM t1 WHERE a >= 20 ORDER BY a; +SELECT * FROM t2 WHERE a >= 20 ORDER BY a; +SELECT * FROM t3 WHERE a >= 20 ORDER BY a; + + +--connection server_2 +# Respawn all worker threads to clear any left-over debug_sync or other stuff. +--disable_connect_log +--source include/stop_slave.inc +--enable_connect_log +SET GLOBAL binlog_format=@old_format; +SET GLOBAL slave_parallel_threads=0; +SET GLOBAL slave_parallel_threads=10; +--disable_connect_log +--source include/start_slave.inc +--enable_connect_log + + +--echo *** Test killing slave threads at various wait points *** +--echo *** 1. Test killing transaction waiting in commit for previous transaction to commit *** + +# Set up three transactions on the master that will be group-committed +# together so they can be replicated in parallel on the slave. +--connection con_temp3 +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued1 WAIT_FOR master_cont1'; +SET binlog_format=statement; +send INSERT INTO t3 VALUES (31, foo(31, + 'commit_before_prepare_ordered WAIT_FOR t2_waiting', + 'commit_after_prepare_ordered SIGNAL t1_ready WAIT_FOR t1_cont')); + +--connection server_1 +SET debug_sync='now WAIT_FOR master_queued1'; + +--connection con_temp4 +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued2'; +SET binlog_format=statement; +BEGIN; +# This insert is just so we can get T2 to wait while a query is running that we +# can see in SHOW PROCESSLIST so we can get its thread_id to kill later. +INSERT INTO t3 VALUES (32, foo(32, + 'ha_write_row_end SIGNAL t2_query WAIT_FOR t2_cont', + '')); +# This insert sets up debug_sync points so that T2 will tell when it is at its +# wait point where we want to kill it - and when it has been killed. +INSERT INTO t3 VALUES (33, foo(33, + 'group_commit_waiting_for_prior SIGNAL t2_waiting', + 'group_commit_waiting_for_prior_killed SIGNAL t2_killed')); +send COMMIT; + +--connection server_1 +SET debug_sync='now WAIT_FOR master_queued2'; + +--connection con_temp5 +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued3'; +SET binlog_format=statement; +send INSERT INTO t3 VALUES (34, foo(34, + '', + '')); + +--connection server_1 +SET debug_sync='now WAIT_FOR master_queued3'; +SET debug_sync='now SIGNAL master_cont1'; + +--connection con_temp3 +REAP; +--connection con_temp4 +REAP; +--connection con_temp5 +REAP; + +--connection server_1 +SELECT * FROM t3 WHERE a >= 30 ORDER BY a; +SET debug_sync='RESET'; + +--connection server_2 +SET sql_log_bin=0; +CALL mtr.add_suppression("Query execution was interrupted"); +CALL mtr.add_suppression("Commit failed due to failure of an earlier commit on which this one depends"); +CALL mtr.add_suppression("Slave: Connection was killed"); +SET sql_log_bin=1; +# Wait until T2 is inside executing its insert of 32, then find it in SHOW +# PROCESSLIST to know its thread id for KILL later. +SET debug_sync='now WAIT_FOR t2_query'; +--let $thd_id= `SELECT ID FROM INFORMATION_SCHEMA.PROCESSLIST WHERE INFO LIKE '%foo(32%' AND INFO NOT LIKE '%LIKE%'` +SET debug_sync='now SIGNAL t2_cont'; + +# Wait until T2 has entered its wait for T1 to commit, and T1 has +# progressed into its commit phase. +SET debug_sync='now WAIT_FOR t1_ready'; + +# Now kill the transaction T2. +--replace_result $thd_id THD_ID +eval KILL $thd_id; + +# Wait until T2 has reacted on the kill. +SET debug_sync='now WAIT_FOR t2_killed'; + +# Now we can allow T1 to proceed. +SET debug_sync='now SIGNAL t1_cont'; + +--let $slave_sql_errno= 1317,1927,1964 +--disable_connect_log +--source include/wait_for_slave_sql_error.inc +--enable_connect_log +STOP SLAVE IO_THREAD; +SELECT * FROM t3 WHERE a >= 30 ORDER BY a; + +# Now we have to disable the debug_sync statements, so they do not trigger +# when the events are retried. +SET debug_sync='RESET'; +SET GLOBAL slave_parallel_threads=0; +SET GLOBAL slave_parallel_threads=10; +SET sql_log_bin=0; +DROP FUNCTION foo; +--delimiter || +CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) + RETURNS INT DETERMINISTIC + BEGIN + RETURN x; + END +|| +--delimiter ; +SET sql_log_bin=1; + +--connection server_1 +INSERT INTO t3 VALUES (39,0); +--save_master_pos + +--connection server_2 +--disable_connect_log +--source include/start_slave.inc +--enable_connect_log +--sync_with_master +SELECT * FROM t3 WHERE a >= 30 ORDER BY a; +# Restore the foo() function. +SET sql_log_bin=0; +DROP FUNCTION foo; +--delimiter || +CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) + RETURNS INT DETERMINISTIC + BEGIN + IF d1 != '' THEN + SET debug_sync = d1; + END IF; + IF d2 != '' THEN + SET debug_sync = d2; + END IF; + RETURN x; + END +|| +--delimiter ; +SET sql_log_bin=1; + + +--connection server_2 +# Respawn all worker threads to clear any left-over debug_sync or other stuff. +--disable_connect_log +--source include/stop_slave.inc +--enable_connect_log +SET GLOBAL binlog_format=@old_format; +SET GLOBAL slave_parallel_threads=0; +SET GLOBAL slave_parallel_threads=10; +--disable_connect_log +--source include/start_slave.inc +--enable_connect_log + + +--echo *** 2. Same as (1), but without restarting IO thread after kill of SQL threads *** + +# Set up three transactions on the master that will be group-committed +# together so they can be replicated in parallel on the slave. +--connection con_temp3 +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued1 WAIT_FOR master_cont1'; +SET binlog_format=statement; +send INSERT INTO t3 VALUES (41, foo(41, + 'commit_before_prepare_ordered WAIT_FOR t2_waiting', + 'commit_after_prepare_ordered SIGNAL t1_ready WAIT_FOR t1_cont')); + +--connection server_1 +SET debug_sync='now WAIT_FOR master_queued1'; + +--connection con_temp4 +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued2'; +SET binlog_format=statement; +BEGIN; +# This insert is just so we can get T2 to wait while a query is running that we +# can see in SHOW PROCESSLIST so we can get its thread_id to kill later. +INSERT INTO t3 VALUES (42, foo(42, + 'ha_write_row_end SIGNAL t2_query WAIT_FOR t2_cont', + '')); +# This insert sets up debug_sync points so that T2 will tell when it is at its +# wait point where we want to kill it - and when it has been killed. +INSERT INTO t3 VALUES (43, foo(43, + 'group_commit_waiting_for_prior SIGNAL t2_waiting', + 'group_commit_waiting_for_prior_killed SIGNAL t2_killed')); +send COMMIT; + +--connection server_1 +SET debug_sync='now WAIT_FOR master_queued2'; + +--connection con_temp5 +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued3'; +SET binlog_format=statement; +send INSERT INTO t3 VALUES (44, foo(44, + '', + '')); + +--connection server_1 +SET debug_sync='now WAIT_FOR master_queued3'; +SET debug_sync='now SIGNAL master_cont1'; + +--connection con_temp3 +REAP; +--connection con_temp4 +REAP; +--connection con_temp5 +REAP; + +--connection server_1 +SELECT * FROM t3 WHERE a >= 40 ORDER BY a; +SET debug_sync='RESET'; + +--connection server_2 +# Wait until T2 is inside executing its insert of 42, then find it in SHOW +# PROCESSLIST to know its thread id for KILL later. +SET debug_sync='now WAIT_FOR t2_query'; +--let $thd_id= `SELECT ID FROM INFORMATION_SCHEMA.PROCESSLIST WHERE INFO LIKE '%foo(42%' AND INFO NOT LIKE '%LIKE%'` +SET debug_sync='now SIGNAL t2_cont'; + +# Wait until T2 has entered its wait for T1 to commit, and T1 has +# progressed into its commit phase. +SET debug_sync='now WAIT_FOR t1_ready'; + +# Now kill the transaction T2. +--replace_result $thd_id THD_ID +eval KILL $thd_id; + +# Wait until T2 has reacted on the kill. +SET debug_sync='now WAIT_FOR t2_killed'; + +# Now we can allow T1 to proceed. +SET debug_sync='now SIGNAL t1_cont'; + +--let $slave_sql_errno= 1317,1927,1964 +--disable_connect_log +--source include/wait_for_slave_sql_error.inc +--enable_connect_log + +# Now we have to disable the debug_sync statements, so they do not trigger +# when the events are retried. +SET debug_sync='RESET'; +SET GLOBAL slave_parallel_threads=0; +SET GLOBAL slave_parallel_threads=10; +SET sql_log_bin=0; +DROP FUNCTION foo; +--delimiter || +CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) + RETURNS INT DETERMINISTIC + BEGIN + RETURN x; + END +|| +--delimiter ; +SET sql_log_bin=1; + +--connection server_1 +INSERT INTO t3 VALUES (49,0); +--save_master_pos + +--connection server_2 +START SLAVE SQL_THREAD; +--sync_with_master +SELECT * FROM t3 WHERE a >= 40 ORDER BY a; +# Restore the foo() function. +SET sql_log_bin=0; +DROP FUNCTION foo; +--delimiter || +CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) + RETURNS INT DETERMINISTIC + BEGIN + IF d1 != '' THEN + SET debug_sync = d1; + END IF; + IF d2 != '' THEN + SET debug_sync = d2; + END IF; + RETURN x; + END +|| +--delimiter ; +SET sql_log_bin=1; + + +--connection server_2 +# Respawn all worker threads to clear any left-over debug_sync or other stuff. +--disable_connect_log +--source include/stop_slave.inc +--enable_connect_log +SET GLOBAL binlog_format=@old_format; +SET GLOBAL slave_parallel_threads=0; +SET GLOBAL slave_parallel_threads=10; +--disable_connect_log +--source include/start_slave.inc +--enable_connect_log + + +--echo *** 3. Same as (2), but not using gtid mode *** + +--connection server_2 +--disable_connect_log +--source include/stop_slave.inc +--enable_connect_log +CHANGE MASTER TO master_use_gtid=no; +--disable_connect_log +--source include/start_slave.inc +--enable_connect_log + +--connection server_1 +# Set up three transactions on the master that will be group-committed +# together so they can be replicated in parallel on the slave. +--connection con_temp3 +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued1 WAIT_FOR master_cont1'; +SET binlog_format=statement; +send INSERT INTO t3 VALUES (51, foo(51, + 'commit_before_prepare_ordered WAIT_FOR t2_waiting', + 'commit_after_prepare_ordered SIGNAL t1_ready WAIT_FOR t1_cont')); + +--connection server_1 +SET debug_sync='now WAIT_FOR master_queued1'; + +--connection con_temp4 +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued2'; +SET binlog_format=statement; +BEGIN; +# This insert is just so we can get T2 to wait while a query is running that we +# can see in SHOW PROCESSLIST so we can get its thread_id to kill later. +INSERT INTO t3 VALUES (52, foo(52, + 'ha_write_row_end SIGNAL t2_query WAIT_FOR t2_cont', + '')); +# This insert sets up debug_sync points so that T2 will tell when it is at its +# wait point where we want to kill it - and when it has been killed. +INSERT INTO t3 VALUES (53, foo(53, + 'group_commit_waiting_for_prior SIGNAL t2_waiting', + 'group_commit_waiting_for_prior_killed SIGNAL t2_killed')); +send COMMIT; + +--connection server_1 +SET debug_sync='now WAIT_FOR master_queued2'; + +--connection con_temp5 +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued3'; +SET binlog_format=statement; +send INSERT INTO t3 VALUES (54, foo(54, + '', + '')); + +--connection server_1 +SET debug_sync='now WAIT_FOR master_queued3'; +SET debug_sync='now SIGNAL master_cont1'; + +--connection con_temp3 +REAP; +--connection con_temp4 +REAP; +--connection con_temp5 +REAP; + +--connection server_1 +SELECT * FROM t3 WHERE a >= 50 ORDER BY a; +SET debug_sync='RESET'; + +--connection server_2 +# Wait until T2 is inside executing its insert of 52, then find it in SHOW +# PROCESSLIST to know its thread id for KILL later. +SET debug_sync='now WAIT_FOR t2_query'; +--let $thd_id= `SELECT ID FROM INFORMATION_SCHEMA.PROCESSLIST WHERE INFO LIKE '%foo(52%' AND INFO NOT LIKE '%LIKE%'` +SET debug_sync='now SIGNAL t2_cont'; + +# Wait until T2 has entered its wait for T1 to commit, and T1 has +# progressed into its commit phase. +SET debug_sync='now WAIT_FOR t1_ready'; + +# Now kill the transaction T2. +--replace_result $thd_id THD_ID +eval KILL $thd_id; + +# Wait until T2 has reacted on the kill. +SET debug_sync='now WAIT_FOR t2_killed'; + +# Now we can allow T1 to proceed. +SET debug_sync='now SIGNAL t1_cont'; + +--let $slave_sql_errno= 1317,1927,1964 +--disable_connect_log +--source include/wait_for_slave_sql_error.inc +--enable_connect_log +SELECT * FROM t3 WHERE a >= 50 ORDER BY a; + +# Now we have to disable the debug_sync statements, so they do not trigger +# when the events are retried. +SET debug_sync='RESET'; +SET GLOBAL slave_parallel_threads=0; +SET GLOBAL slave_parallel_threads=10; +SET sql_log_bin=0; +DROP FUNCTION foo; +--delimiter || +CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) + RETURNS INT DETERMINISTIC + BEGIN + RETURN x; + END +|| +--delimiter ; +SET sql_log_bin=1; + +--connection server_1 +INSERT INTO t3 VALUES (59,0); +--save_master_pos + +--connection server_2 +START SLAVE SQL_THREAD; +--sync_with_master +SELECT * FROM t3 WHERE a >= 50 ORDER BY a; +# Restore the foo() function. +SET sql_log_bin=0; +DROP FUNCTION foo; +--delimiter || +CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) + RETURNS INT DETERMINISTIC + BEGIN + IF d1 != '' THEN + SET debug_sync = d1; + END IF; + IF d2 != '' THEN + SET debug_sync = d2; + END IF; + RETURN x; + END +|| +--delimiter ; +SET sql_log_bin=1; + + +--disable_connect_log +--source include/stop_slave.inc +--enable_connect_log +CHANGE MASTER TO master_use_gtid=slave_pos; +--disable_connect_log +--source include/start_slave.inc +--enable_connect_log + +--connection server_2 +# Respawn all worker threads to clear any left-over debug_sync or other stuff. +--disable_connect_log +--source include/stop_slave.inc +--enable_connect_log +SET GLOBAL binlog_format=@old_format; +SET GLOBAL slave_parallel_threads=0; +SET GLOBAL slave_parallel_threads=4; +--disable_connect_log +--source include/start_slave.inc +--enable_connect_log + + +--echo *** 4. Test killing thread that is waiting to start transaction until previous transaction commits *** + +# We set up four transactions T1, T2, T3, and T4 on the master. T2, T3, and T4 +# can run in parallel with each other (same group commit and commit id), +# but not in parallel with T1. +# +# We use four worker threads, each Ti will be queued on each their own +# worker thread. We will delay T1 commit, T3 will wait for T1 to begin +# commit before it can start. We will kill T3 during this wait, and +# check that everything works correctly. +# +# It is rather tricky to get the correct thread id of the worker to kill. +# We start by injecting four dummy transactions in a debug_sync-controlled +# manner to be able to get known thread ids for the workers in a pool with +# just 4 worker threads. Then we let in each of the real test transactions +# T1-T4 one at a time in a way which allows us to know which transaction +# ends up with which thread id. + +--connection server_1 +SET binlog_format=statement; +SET gtid_domain_id=2; +BEGIN; +# This debug_sync will linger on and be used to control T4 later. +INSERT INTO t3 VALUES (70, foo(70, + 'rpl_parallel_start_waiting_for_prior SIGNAL t4_waiting', '')); +INSERT INTO t3 VALUES (60, foo(60, + 'ha_write_row_end SIGNAL d2_query WAIT_FOR d2_cont2', + 'rpl_parallel_end_of_group SIGNAL d2_done WAIT_FOR d2_cont')); +COMMIT; +SET gtid_domain_id=0; + +--connection server_2 +SET debug_sync='now WAIT_FOR d2_query'; +--let $d2_thd_id= `SELECT ID FROM INFORMATION_SCHEMA.PROCESSLIST WHERE INFO LIKE '%foo(60%' AND INFO NOT LIKE '%LIKE%'` + +--connection server_1 +SET gtid_domain_id=1; +BEGIN; +# These debug_sync's will linger on and be used to control T3 later. +INSERT INTO t3 VALUES (61, foo(61, + 'rpl_parallel_start_waiting_for_prior SIGNAL t3_waiting', + 'rpl_parallel_start_waiting_for_prior_killed SIGNAL t3_killed')); +INSERT INTO t3 VALUES (62, foo(62, + 'ha_write_row_end SIGNAL d1_query WAIT_FOR d1_cont2', + 'rpl_parallel_end_of_group SIGNAL d1_done WAIT_FOR d1_cont')); +COMMIT; +SET gtid_domain_id=0; + +--connection server_2 +SET debug_sync='now WAIT_FOR d1_query'; +--let $d1_thd_id= `SELECT ID FROM INFORMATION_SCHEMA.PROCESSLIST WHERE INFO LIKE '%foo(62%' AND INFO NOT LIKE '%LIKE%'` + +--connection server_1 +SET gtid_domain_id=0; +INSERT INTO t3 VALUES (63, foo(63, + 'ha_write_row_end SIGNAL d0_query WAIT_FOR d0_cont2', + 'rpl_parallel_end_of_group SIGNAL d0_done WAIT_FOR d0_cont')); + +--connection server_2 +SET debug_sync='now WAIT_FOR d0_query'; +--let $d0_thd_id= `SELECT ID FROM INFORMATION_SCHEMA.PROCESSLIST WHERE INFO LIKE '%foo(63%' AND INFO NOT LIKE '%LIKE%'` + +--connection server_1 +SET gtid_domain_id=3; +BEGIN; +# These debug_sync's will linger on and be used to control T2 later. +INSERT INTO t3 VALUES (68, foo(68, + 'rpl_parallel_start_waiting_for_prior SIGNAL t2_waiting', '')); +INSERT INTO t3 VALUES (69, foo(69, + 'ha_write_row_end SIGNAL d3_query WAIT_FOR d3_cont2', + 'rpl_parallel_end_of_group SIGNAL d3_done WAIT_FOR d3_cont')); +COMMIT; +SET gtid_domain_id=0; + +--connection server_2 +SET debug_sync='now WAIT_FOR d3_query'; +--let $d3_thd_id= `SELECT ID FROM INFORMATION_SCHEMA.PROCESSLIST WHERE INFO LIKE '%foo(69%' AND INFO NOT LIKE '%LIKE%'` + +SET debug_sync='now SIGNAL d2_cont2'; +SET debug_sync='now WAIT_FOR d2_done'; +SET debug_sync='now SIGNAL d1_cont2'; +SET debug_sync='now WAIT_FOR d1_done'; +SET debug_sync='now SIGNAL d0_cont2'; +SET debug_sync='now WAIT_FOR d0_done'; +SET debug_sync='now SIGNAL d3_cont2'; +SET debug_sync='now WAIT_FOR d3_done'; + +# Now prepare the real transactions T1, T2, T3, T4 on the master. + +--connection con_temp3 +# Create transaction T1. +SET binlog_format=statement; +INSERT INTO t3 VALUES (64, foo(64, + 'rpl_parallel_before_mark_start_commit SIGNAL t1_waiting WAIT_FOR t1_cont', '')); + +# Create transaction T2, as a group commit leader on the master. +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued2 WAIT_FOR master_cont2'; +send INSERT INTO t3 VALUES (65, foo(65, '', '')); + +--connection server_1 +SET debug_sync='now WAIT_FOR master_queued2'; + +--connection con_temp4 +# Create transaction T3, participating in T2's group commit. +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued3'; +send INSERT INTO t3 VALUES (66, foo(66, '', '')); + +--connection server_1 +SET debug_sync='now WAIT_FOR master_queued3'; + +--connection con_temp5 +# Create transaction T4, participating in group commit with T2 and T3. +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued4'; +send INSERT INTO t3 VALUES (67, foo(67, '', '')); + +--connection server_1 +SET debug_sync='now WAIT_FOR master_queued4'; +SET debug_sync='now SIGNAL master_cont2'; + +--connection con_temp3 +REAP; +--connection con_temp4 +REAP; +--connection con_temp5 +REAP; + +--connection server_1 +SELECT * FROM t3 WHERE a >= 60 ORDER BY a; +SET debug_sync='RESET'; + +--connection server_2 +# Now we have the four transactions pending for replication on the slave. +# Let them be queued for our three worker threads in a controlled fashion. +# We put them at a stage where T1 is delayed and T3 is waiting for T1 to +# commit before T3 can start. Then we kill T3. + +# Make the worker D0 free, and wait for T1 to be queued in it. +SET debug_sync='now SIGNAL d0_cont'; +SET debug_sync='now WAIT_FOR t1_waiting'; + +# Make the worker D3 free, and wait for T2 to be queued in it. +SET debug_sync='now SIGNAL d3_cont'; +SET debug_sync='now WAIT_FOR t2_waiting'; + +# Now release worker D1, and wait for T3 to be queued in it. +# T3 will wait for T1 to commit before it can start. +SET debug_sync='now SIGNAL d1_cont'; +SET debug_sync='now WAIT_FOR t3_waiting'; + +# Release worker D2. Wait for T4 to be queued, so we are sure it has +# received the debug_sync signal (else we might overwrite it with the +# next debug_sync). +SET debug_sync='now SIGNAL d2_cont'; +SET debug_sync='now WAIT_FOR t4_waiting'; + +# Now we kill the waiting transaction T3 in worker D1. +--replace_result $d1_thd_id THD_ID +eval KILL $d1_thd_id; + +# Wait until T3 has reacted on the kill. +SET debug_sync='now WAIT_FOR t3_killed'; + +# Now we can allow T1 to proceed. +SET debug_sync='now SIGNAL t1_cont'; + +--let $slave_sql_errno= 1317,1927,1964 +--disable_connect_log +--source include/wait_for_slave_sql_error.inc +--enable_connect_log +STOP SLAVE IO_THREAD; +# Since T2, T3, and T4 run in parallel, we can not be sure if T2 will have time +# to commit or not before the stop. However, T1 should commit, and T3/T4 may +# not have committed. (After slave restart we check that all become committed +# eventually). +SELECT * FROM t3 WHERE a >= 60 AND a != 65 ORDER BY a; + +# Now we have to disable the debug_sync statements, so they do not trigger +# when the events are retried. +SET debug_sync='RESET'; +SET GLOBAL slave_parallel_threads=0; +SET GLOBAL slave_parallel_threads=10; +SET sql_log_bin=0; +DROP FUNCTION foo; +--delimiter || +CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) + RETURNS INT DETERMINISTIC + BEGIN + RETURN x; + END +|| +--delimiter ; +SET sql_log_bin=1; + +--connection server_1 +UPDATE t3 SET b=b+1 WHERE a=60; +--save_master_pos + +--connection server_2 +--disable_connect_log +--source include/start_slave.inc +--enable_connect_log +--sync_with_master +SELECT * FROM t3 WHERE a >= 60 ORDER BY a; +# Restore the foo() function. +SET sql_log_bin=0; +DROP FUNCTION foo; +--delimiter || +CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) + RETURNS INT DETERMINISTIC + BEGIN + IF d1 != '' THEN + SET debug_sync = d1; + END IF; + IF d2 != '' THEN + SET debug_sync = d2; + END IF; + RETURN x; + END +|| +--delimiter ; +SET sql_log_bin=1; + +--connection server_2 +# Respawn all worker threads to clear any left-over debug_sync or other stuff. +--disable_connect_log +--source include/stop_slave.inc +--enable_connect_log +SET GLOBAL binlog_format=@old_format; +SET GLOBAL slave_parallel_threads=0; +SET GLOBAL slave_parallel_threads=10; +--disable_connect_log +--source include/start_slave.inc +--enable_connect_log + + +--echo *** 5. Test killing thread that is waiting for queue of max length to shorten *** + +# Find the thread id of the driver SQL thread that we want to kill. +--let $wait_condition= SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE STATE LIKE '%Slave has read all relay log%' +--disable_connect_log +--source include/wait_condition.inc +--enable_connect_log +--let $thd_id= `SELECT ID FROM INFORMATION_SCHEMA.PROCESSLIST WHERE STATE LIKE '%Slave has read all relay log%'` +SET @old_max_queued= @@GLOBAL.slave_parallel_max_queued; +SET GLOBAL slave_parallel_max_queued=9000; + +--connection server_1 +--let bigstring= `SELECT REPEAT('x', 10000)` +SET binlog_format=statement; +# Create an event that will wait to be signalled. +INSERT INTO t3 VALUES (80, foo(0, + 'ha_write_row_end SIGNAL query_waiting WAIT_FOR query_cont', '')); + +--connection server_2 +SET debug_sync='now WAIT_FOR query_waiting'; +# Inject that the SQL driver thread will signal `wait_queue_ready' to debug_sync +# as it goes to wait for the event queue to become smaller than the value of +# @@slave_parallel_max_queued. +SET @old_dbug= @@GLOBAL.debug_dbug; +SET GLOBAL debug_dbug="+d,rpl_parallel_wait_queue_max"; + +--connection server_1 +--disable_query_log +# Create an event that will fill up the queue. +# The Xid event at the end of the event group will have to wait for the Query +# event with the INSERT to drain so the queue becomes shorter. However that in +# turn waits for the prior event group to continue. +eval INSERT INTO t3 VALUES (81, LENGTH('$bigstring')); +--enable_query_log +SELECT * FROM t3 WHERE a >= 80 ORDER BY a; + +--connection server_2 +SET debug_sync='now WAIT_FOR wait_queue_ready'; + +--replace_result $thd_id THD_ID +eval KILL $thd_id; + +SET debug_sync='now WAIT_FOR wait_queue_killed'; +SET debug_sync='now SIGNAL query_cont'; + +--let $slave_sql_errno= 1317,1927,1964 +--disable_connect_log +--source include/wait_for_slave_sql_error.inc +--enable_connect_log +STOP SLAVE IO_THREAD; + +SET GLOBAL debug_dbug=@old_dbug; +SET GLOBAL slave_parallel_max_queued= @old_max_queued; + +--connection server_1 +INSERT INTO t3 VALUES (82,0); +SET binlog_format=@old_format; +--save_master_pos + +--connection server_2 +SET debug_sync='RESET'; +--disable_connect_log +--source include/start_slave.inc +--enable_connect_log +--sync_with_master +SELECT * FROM t3 WHERE a >= 80 ORDER BY a; + + +--connection server_2 +--disable_connect_log +--source include/stop_slave.inc +--enable_connect_log +SET GLOBAL binlog_format=@old_format; +SET GLOBAL slave_parallel_threads=0; +SET GLOBAL slave_parallel_threads=10; +--disable_connect_log +--source include/start_slave.inc +--enable_connect_log + +--echo *** MDEV-5788 Incorrect free of rgi->deferred_events in parallel replication *** + +--connection server_2 +# Use just two worker threads, so we are sure to get the rpl_group_info added +# to the free list, which is what triggered the bug. +--disable_connect_log +--source include/stop_slave.inc +--enable_connect_log +SET GLOBAL replicate_ignore_table="test.t3"; +SET GLOBAL slave_parallel_threads=2; +--disable_connect_log +--source include/start_slave.inc +--enable_connect_log + +--connection server_1 +INSERT INTO t3 VALUES (100, rand()); +INSERT INTO t3 VALUES (101, rand()); + +--save_master_pos + +--connection server_2 +--sync_with_master + +--connection server_1 +INSERT INTO t3 VALUES (102, rand()); +INSERT INTO t3 VALUES (103, rand()); +INSERT INTO t3 VALUES (104, rand()); +INSERT INTO t3 VALUES (105, rand()); + +--save_master_pos + +--connection server_2 +--sync_with_master +--disable_connect_log +--source include/stop_slave.inc +--enable_connect_log +SET GLOBAL replicate_ignore_table=""; +--disable_connect_log +--source include/start_slave.inc +--enable_connect_log + +--connection server_1 +INSERT INTO t3 VALUES (106, rand()); +INSERT INTO t3 VALUES (107, rand()); +--save_master_pos + +--connection server_2 +--sync_with_master +--replace_column 2 # +SELECT * FROM t3 WHERE a >= 100 ORDER BY a; + + +--echo *** MDEV-5921: In parallel replication, an error is not correctly signalled to the next transaction *** + +--connection server_2 +--disable_connect_log +--source include/stop_slave.inc +--enable_connect_log +SET GLOBAL slave_parallel_threads=10; +--disable_connect_log +--source include/start_slave.inc +--enable_connect_log + +--connection server_1 +INSERT INTO t3 VALUES (110, 1); +--save_master_pos + +--connection server_2 +--sync_with_master +SELECT * FROM t3 WHERE a >= 110 ORDER BY a; +# Inject a duplicate key error. +SET sql_log_bin=0; +INSERT INTO t3 VALUES (111, 666); +SET sql_log_bin=1; + +--connection server_1 + +# Create a group commit with two inserts, the first one conflicts with a row on the slave +--connect (con1,127.0.0.1,root,,test,$SERVER_MYPORT_1,) +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued1 WAIT_FOR master_cont1'; +send INSERT INTO t3 VALUES (111, 2); +--connection server_1 +SET debug_sync='now WAIT_FOR master_queued1'; + +--connect (con2,127.0.0.1,root,,test,$SERVER_MYPORT_1,) +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued2'; +send INSERT INTO t3 VALUES (112, 3); + +--connection server_1 +SET debug_sync='now WAIT_FOR master_queued2'; +SET debug_sync='now SIGNAL master_cont1'; + +--connection con1 +REAP; +--connection con2 +REAP; +SET debug_sync='RESET'; +--save_master_pos + +--connection server_2 +--let $slave_sql_errno= 1062 +--disable_connect_log +--source include/wait_for_slave_sql_error.inc +--source include/wait_for_slave_sql_to_stop.inc +--enable_connect_log +# We should not see the row (112,3) here, it should be rolled back due to +# error signal from the prior transaction. +SELECT * FROM t3 WHERE a >= 110 ORDER BY a; +SET sql_log_bin=0; +DELETE FROM t3 WHERE a=111 AND b=666; +SET sql_log_bin=1; +START SLAVE SQL_THREAD; +--sync_with_master +SELECT * FROM t3 WHERE a >= 110 ORDER BY a; + + +--echo ***MDEV-5914: Parallel replication deadlock due to InnoDB lock conflicts *** +--connection server_2 +--disable_connect_log +--source include/stop_slave.inc +--enable_connect_log + +--connection server_1 +CREATE TABLE t4 (a INT PRIMARY KEY, b INT, KEY b_idx(b)) ENGINE=InnoDB; +INSERT INTO t4 VALUES (1,NULL), (2,2), (3,NULL), (4,4), (5, NULL), (6, 6); + +# Create a group commit with UPDATE and DELETE, in that order. +# The bug was that while the UPDATE's row lock does not block the DELETE, the +# DELETE's gap lock _does_ block the UPDATE. This could cause a deadlock +# on the slave. +--connection con1 +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued1 WAIT_FOR master_cont1'; +send UPDATE t4 SET b=NULL WHERE a=6; +--connection server_1 +SET debug_sync='now WAIT_FOR master_queued1'; + +--connection con2 +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued2'; +send DELETE FROM t4 WHERE b <= 3; + +--connection server_1 +SET debug_sync='now WAIT_FOR master_queued2'; +SET debug_sync='now SIGNAL master_cont1'; + +--connection con1 +REAP; +--connection con2 +REAP; +SET debug_sync='RESET'; +--save_master_pos + +--connection server_2 +--disable_connect_log +--source include/start_slave.inc +--sync_with_master +--source include/stop_slave.inc +--enable_connect_log + +SELECT * FROM t4 ORDER BY a; + + +# Another example, this one with INSERT vs. DELETE +--connection server_1 +DELETE FROM t4; +INSERT INTO t4 VALUES (1,NULL), (2,2), (3,NULL), (4,4), (5, NULL), (6, 6); + +# Create a group commit with INSERT and DELETE, in that order. +# The bug was that while the INSERT's insert intention lock does not block +# the DELETE, the DELETE's gap lock _does_ block the INSERT. This could cause +# a deadlock on the slave. +--connection con1 +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued1 WAIT_FOR master_cont1'; +send INSERT INTO t4 VALUES (7, NULL); +--connection server_1 +SET debug_sync='now WAIT_FOR master_queued1'; + +--connection con2 +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued2'; +send DELETE FROM t4 WHERE b <= 3; + +--connection server_1 +SET debug_sync='now WAIT_FOR master_queued2'; +SET debug_sync='now SIGNAL master_cont1'; + +--connection con1 +REAP; +--connection con2 +REAP; +SET debug_sync='RESET'; +--save_master_pos + +--connection server_2 +--disable_connect_log +--source include/start_slave.inc +--sync_with_master +--source include/stop_slave.inc +--enable_connect_log + +SELECT * FROM t4 ORDER BY a; + + +# MDEV-6549, failing to update gtid_slave_pos for a transaction that was retried. +# The problem was that when a transaction updates the mysql.gtid_slave_pos +# table, it clears the flag that marks that there is a GTID position that +# needs to be updated. Then, if the transaction got killed after that due +# to a deadlock, the subsequent retry would fail to notice that the GTID needs +# to be recorded in gtid_slave_pos. +# +# (In the original bug report, the symptom was an assertion; this was however +# just a side effect of the missing update of gtid_slave_pos, which also +# happened to cause a missing clear of OPTION_GTID_BEGIN). +--connection server_1 +DELETE FROM t4; +INSERT INTO t4 VALUES (1,NULL), (2,2), (3,NULL), (4,4), (5, NULL), (6, 6); + +# Create two transactions that can run in parallel on the slave but cause +# a deadlock if the second runs before the first. +--connection con1 +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued1 WAIT_FOR master_cont1'; +send UPDATE t4 SET b=NULL WHERE a=6; +--connection server_1 +SET debug_sync='now WAIT_FOR master_queued1'; + +--connection con2 +# Must use statement-based binlogging. Otherwise the transaction will not be +# binlogged at all, as it modifies no rows. +SET @old_format= @@SESSION.binlog_format; +SET binlog_format='statement'; +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued2'; +send DELETE FROM t4 WHERE b <= 1; + +--connection server_1 +SET debug_sync='now WAIT_FOR master_queued2'; +SET debug_sync='now SIGNAL master_cont1'; + +--connection con1 +REAP; +--connection con2 +REAP; +SET @old_format=@@GLOBAL.binlog_format; +SET debug_sync='RESET'; +--save_master_pos +--let $last_gtid= `SELECT @@last_gtid` + +--connection server_2 +# Disable the usual skip of gap locks for transactions that are run in +# parallel, using DBUG. This allows the deadlock to occur, and this in turn +# triggers a retry of the second transaction, and the code that was buggy and +# caused the gtid_slave_pos update to be skipped in the retry. +SET @old_dbug= @@GLOBAL.debug_dbug; +SET GLOBAL debug_dbug="+d,disable_thd_need_ordering_with"; +--disable_connect_log +--source include/start_slave.inc +--enable_connect_log +--sync_with_master +SET GLOBAL debug_dbug=@old_dbug; + +SELECT * FROM t4 ORDER BY a; +# Check that the GTID of the second transaction was correctly recorded in +# gtid_slave_pos, in the variable as well as in the table. +--replace_result $last_gtid GTID +eval SET @last_gtid= '$last_gtid'; +SELECT IF(@@gtid_slave_pos LIKE CONCAT('%',@last_gtid,'%'), "GTID found ok", + CONCAT("GTID ", @last_gtid, " not found in gtid_slave_pos=", @@gtid_slave_pos)) + AS result; +SELECT "ROW FOUND" AS `Is the row found?` + FROM mysql.gtid_slave_pos + WHERE CONCAT(domain_id, "-", server_id, "-", seq_no) = @last_gtid; + + +--echo *** MDEV-5938: Exec_master_log_pos not updated at log rotate in parallel replication *** +--connection server_2 +--disable_connect_log +--source include/stop_slave.inc +--enable_connect_log +SET GLOBAL slave_parallel_threads=1; +SET DEBUG_SYNC= 'RESET'; +--disable_connect_log +--source include/start_slave.inc +--enable_connect_log + +--connection server_1 +CREATE TABLE t5 (a INT PRIMARY KEY, b INT); +INSERT INTO t5 VALUES (1,1); +INSERT INTO t5 VALUES (2,2), (3,8); +INSERT INTO t5 VALUES (4,16); +--save_master_pos + +--connection server_2 +--sync_with_master +let $io_file= query_get_value(SHOW SLAVE STATUS, Master_Log_File, 1); +let $io_pos= query_get_value(SHOW SLAVE STATUS, Read_Master_Log_Pos, 1); +let $sql_file= query_get_value(SHOW SLAVE STATUS, Relay_Master_Log_File, 1); +let $sql_pos= query_get_value(SHOW SLAVE STATUS, Exec_Master_Log_Pos, 1); +--disable_query_log +eval SELECT IF('$io_file' = '$sql_file', "OK", "Not ok, $io_file <> $sql_file") AS test_check; +eval SELECT IF('$io_pos' = '$sql_pos', "OK", "Not ok, $io_pos <> $sql_pos") AS test_check; +--enable_query_log + +--connection server_1 +FLUSH LOGS; +--disable_connect_log +--source include/wait_for_binlog_checkpoint.inc +--enable_connect_log +--save_master_pos + +--connection server_2 +--sync_with_master +let $io_file= query_get_value(SHOW SLAVE STATUS, Master_Log_File, 1); +let $io_pos= query_get_value(SHOW SLAVE STATUS, Read_Master_Log_Pos, 1); +let $sql_file= query_get_value(SHOW SLAVE STATUS, Relay_Master_Log_File, 1); +let $sql_pos= query_get_value(SHOW SLAVE STATUS, Exec_Master_Log_Pos, 1); +--disable_query_log +eval SELECT IF('$io_file' = '$sql_file', "OK", "Not ok, $io_file <> $sql_file") AS test_check; +eval SELECT IF('$io_pos' = '$sql_pos', "OK", "Not ok, $io_pos <> $sql_pos") AS test_check; +--enable_query_log + + +--echo *** MDEV_6435: Incorrect error handling when query binlogged partially on master with "killed" error *** + +--connection server_1 +CREATE TABLE t6 (a INT) ENGINE=MyISAM; +CREATE TRIGGER tr AFTER INSERT ON t6 FOR EACH ROW SET @a = 1; + +--connection con1 +SET @old_format= @@binlog_format; +SET binlog_format= statement; +--let $conid = `SELECT CONNECTION_ID()` +SET debug_sync='sp_head_execute_before_loop SIGNAL ready WAIT_FOR cont'; +send INSERT INTO t6 VALUES (1), (2), (3); + +--connection server_1 +SET debug_sync='now WAIT_FOR ready'; +--replace_result $conid CONID +eval KILL QUERY $conid; +SET debug_sync='now SIGNAL cont'; + +--connection con1 +--error ER_QUERY_INTERRUPTED +--reap +SET binlog_format= @old_format; +SET debug_sync='RESET'; +--let $after_error_gtid_pos= `SELECT @@gtid_binlog_pos` + +--connection server_1 +SET debug_sync='RESET'; + + +--connection server_2 +--let $slave_sql_errno= 1317 +--disable_connect_log +--source include/wait_for_slave_sql_error.inc +--enable_connect_log +STOP SLAVE IO_THREAD; +--replace_result $after_error_gtid_pos AFTER_ERROR_GTID_POS +eval SET GLOBAL gtid_slave_pos= '$after_error_gtid_pos'; +--disable_connect_log +--source include/start_slave.inc +--enable_connect_log + +--connection server_1 +INSERT INTO t6 VALUES (4); +SELECT * FROM t6 ORDER BY a; +--save_master_pos + +--connection server_2 +--sync_with_master +SELECT * FROM t6 ORDER BY a; + + +--echo *** MDEV-6551: Some replication errors are ignored if slave_parallel_threads > 0 *** + +--connection server_1 +INSERT INTO t2 VALUES (31); +--let $gtid1= `SELECT @@LAST_GTID` +--disable_connect_log +--source include/save_master_gtid.inc +--enable_connect_log + +--connection server_2 +--disable_connect_log +--source include/sync_with_master_gtid.inc +--source include/stop_slave.inc +SET GLOBAL slave_parallel_threads= 0; +--source include/start_slave.inc +--enable_connect_log + +# Force a duplicate key error on the slave. +SET sql_log_bin= 0; +INSERT INTO t2 VALUES (32); +SET sql_log_bin= 1; + +--connection server_1 +INSERT INTO t2 VALUES (32); +--let $gtid2= `SELECT @@LAST_GTID` +# Rotate the binlog; the bug is triggered when the master binlog file changes +# after the event group that causes the duplicate key error. +FLUSH LOGS; +INSERT INTO t2 VALUES (33); +INSERT INTO t2 VALUES (34); +SELECT * FROM t2 WHERE a >= 30 ORDER BY a; +--disable_connect_log +--source include/save_master_gtid.inc +--enable_connect_log + +--connection server_2 +--let $slave_sql_errno= 1062 +--disable_connect_log +--source include/wait_for_slave_sql_error.inc +--enable_connect_log + +--connection server_2 +--disable_connect_log +--source include/stop_slave_io.inc +--enable_connect_log +SET GLOBAL slave_parallel_threads=10; +START SLAVE; + +--let $slave_sql_errno= 1062 +--disable_connect_log +--source include/wait_for_slave_sql_error.inc +--enable_connect_log + +# Note: IO thread is still running at this point. +# The bug seems to have been that restarting the SQL thread after an error with +# the IO thread still running, somehow picks up a later relay log position and +# thus ends up skipping the failing event, rather than re-executing. + +START SLAVE SQL_THREAD; +--let $slave_sql_errno= 1062 +--disable_connect_log +--source include/wait_for_slave_sql_error.inc +--enable_connect_log + +SELECT * FROM t2 WHERE a >= 30 ORDER BY a; + +# Skip the duplicate error, so we can proceed. +--error ER_SLAVE_SKIP_NOT_IN_GTID +SET sql_slave_skip_counter= 1; +--disable_connect_log +--source include/stop_slave_io.inc +--enable_connect_log +--disable_query_log +eval SET GLOBAL gtid_slave_pos = REPLACE(@@gtid_slave_pos, "$gtid1", "$gtid2"); +--enable_query_log +--disable_connect_log +--source include/start_slave.inc +--source include/sync_with_master_gtid.inc +--enable_connect_log + +SELECT * FROM t2 WHERE a >= 30 ORDER BY a; + + +--echo *** MDEV-6775: Wrong binlog order in parallel replication *** +--connection server_1 +# A bit tricky bug to reproduce. On the master, we binlog in statement-mode +# two transactions, an UPDATE followed by a DELETE. On the slave, we replicate +# with binlog-mode set to ROW, which means the DELETE, which modifies no rows, +# is not binlogged. Then we inject a wait in the group commit code on the +# slave, shortly before the actual commit of the UPDATE. The bug was that the +# DELETE could wake up from wait_for_prior_commit() before the commit of the +# UPDATE. So the test could see the slave position updated to after DELETE, +# while the UPDATE was still not visible. +DELETE FROM t4; +INSERT INTO t4 VALUES (1,NULL), (3,NULL), (4,4), (5, NULL), (6, 6); +--disable_connect_log +--source include/save_master_gtid.inc +--enable_connect_log + +--connection server_2 +--disable_connect_log +--source include/sync_with_master_gtid.inc +--source include/stop_slave.inc +--enable_connect_log +SET @old_dbug= @@GLOBAL.debug_dbug; +SET GLOBAL debug_dbug="+d,inject_binlog_commit_before_get_LOCK_log"; +SET @old_format=@@GLOBAL.binlog_format; +SET GLOBAL binlog_format=ROW; +# Re-spawn the worker threads to be sure they pick up the new binlog format +SET GLOBAL slave_parallel_threads=0; +SET GLOBAL slave_parallel_threads=10; + +--connection con1 +SET @old_format= @@binlog_format; +SET binlog_format= statement; +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued1 WAIT_FOR master_cont1'; +send UPDATE t4 SET b=NULL WHERE a=6; +--connection server_1 +SET debug_sync='now WAIT_FOR master_queued1'; + +--connection con2 +SET @old_format= @@binlog_format; +SET binlog_format= statement; +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued2'; +send DELETE FROM t4 WHERE b <= 3; + +--connection server_1 +SET debug_sync='now WAIT_FOR master_queued2'; +SET debug_sync='now SIGNAL master_cont1'; + +--connection con1 +REAP; +SET binlog_format= @old_format; +--connection con2 +REAP; +SET binlog_format= @old_format; +SET debug_sync='RESET'; +--save_master_pos +SELECT * FROM t4 ORDER BY a; + +--connection server_2 +--disable_connect_log +--source include/start_slave.inc +--enable_connect_log +SET debug_sync= 'now WAIT_FOR waiting'; +--sync_with_master +SELECT * FROM t4 ORDER BY a; +SET debug_sync= 'now SIGNAL cont'; + +# Re-spawn the worker threads to remove any DBUG injections or DEBUG_SYNC. +--disable_connect_log +--source include/stop_slave.inc +--enable_connect_log +SET GLOBAL debug_dbug=@old_dbug; +SET GLOBAL binlog_format= @old_format; +SET GLOBAL slave_parallel_threads=0; +SET GLOBAL slave_parallel_threads=10; +--disable_connect_log +--source include/start_slave.inc +--enable_connect_log + + +--echo *** MDEV-7237: Parallel replication: incorrect relaylog position after stop/start the slave *** +--connection server_1 +INSERT INTO t2 VALUES (40); +--save_master_pos + +--connection server_2 +--sync_with_master +--disable_connect_log +--source include/stop_slave.inc +--enable_connect_log +CHANGE MASTER TO master_use_gtid=no; +SET @old_dbug= @@GLOBAL.debug_dbug; +# This DBUG injection causes a DEBUG_SYNC signal "scheduled_gtid_0_x_100" when +# GTID 0-1-100 has been scheduled for and fetched by a worker thread. +SET GLOBAL debug_dbug="+d,rpl_parallel_scheduled_gtid_0_x_100"; +# This DBUG injection causes a DEBUG_SYNC signal "wait_for_done_waiting" when +# STOP SLAVE has signalled all worker threads to stop. +SET GLOBAL debug_dbug="+d,rpl_parallel_wait_for_done_trigger"; +# Reset worker threads to make DBUG setting catch on. +SET GLOBAL slave_parallel_threads=0; +SET GLOBAL slave_parallel_threads=10; + + +--connection server_1 +# Setup some transaction for the slave to replicate. +INSERT INTO t2 VALUES (41); +INSERT INTO t2 VALUES (42); +# Need to log the DELETE in statement format, so we can see it in processlist. +SET @old_format= @@binlog_format; +SET binlog_format= statement; +DELETE FROM t2 WHERE a=40; +SET binlog_format= @old_format; +INSERT INTO t2 VALUES (43); +INSERT INTO t2 VALUES (44); +# Force the slave to switch to a new relay log file. +FLUSH LOGS; +INSERT INTO t2 VALUES (45); +# Inject a GTID 0-1-100, which will trigger a DEBUG_SYNC signal when this +# transaction has been fetched by a worker thread. +SET gtid_seq_no=100; +INSERT INTO t2 VALUES (46); +--save_master_pos + +--connection con_temp2 +# Temporarily block the DELETE on a=40 from completing. +BEGIN; +SELECT * FROM t2 WHERE a=40 FOR UPDATE; + + +--connection server_2 +--disable_connect_log +--source include/start_slave.inc +--enable_connect_log + +# Wait for a worker thread to start on the DELETE that will be blocked +# temporarily by the SELECT FOR UPDATE. +--let $wait_condition= SELECT count(*) > 0 FROM information_schema.processlist WHERE state='updating' and info LIKE '%DELETE FROM t2 WHERE a=40%' +--disable_connect_log +--source include/wait_condition.inc +--enable_connect_log + +# The DBUG injection set above will make the worker thread signal the following +# debug_sync when the GTID 0-1-100 has been reached by a worker thread. +# Thus, at this point, the SQL driver thread has reached the next +# relay log file name, while a worker thread is still processing a +# transaction in the previous relay log file, blocked on the SELECT FOR +# UPDATE. +SET debug_sync= 'now WAIT_FOR scheduled_gtid_0_x_100'; +# At this point, the SQL driver thread is in the new relay log file, while +# the DELETE from the old relay log file is not yet complete. We will stop +# the slave at this point. The bug was that the DELETE statement would +# update the slave position to the _new_ relay log file name instead of +# its own old file name. Thus, by stoping and restarting the slave at this +# point, we would get an error at restart due to incorrect position. (If +# we would let the slave catch up before stopping, the incorrect position +# would be corrected by a later transaction). + +send STOP SLAVE; + +--connection con_temp2 +# Wait for STOP SLAVE to have proceeded sufficiently that it has signalled +# all worker threads to stop; this ensures that we will stop after the DELETE +# transaction (and not after a later transaction that might have been able +# to set a fixed position). +SET debug_sync= 'now WAIT_FOR wait_for_done_waiting'; +# Now release the row lock that was blocking the replication of DELETE. +ROLLBACK; + +--connection server_2 +reap; +--disable_connect_log +--source include/wait_for_slave_sql_to_stop.inc +--enable_connect_log +SELECT * FROM t2 WHERE a >= 40 ORDER BY a; +# Now restart the slave. With the bug present, this would start at an +# incorrect relay log position, causing relay log read error (or if unlucky, +# silently skip a number of events). +--disable_connect_log +--source include/start_slave.inc +--enable_connect_log +--sync_with_master +SELECT * FROM t2 WHERE a >= 40 ORDER BY a; +--disable_connect_log +--source include/stop_slave.inc +--enable_connect_log +SET GLOBAL debug_dbug=@old_dbug; +SET DEBUG_SYNC= 'RESET'; +SET GLOBAL slave_parallel_threads=0; +SET GLOBAL slave_parallel_threads=10; +CHANGE MASTER TO master_use_gtid=slave_pos; +--disable_connect_log +--source include/start_slave.inc +--enable_connect_log + + +--echo *** MDEV-7326 Server deadlock in connection with parallel replication *** +# We use three transactions, each in a separate group commit. +# T1 does mark_start_commit(), then gets a deadlock error. +# T2 wakes up and starts running +# T1 does unmark_start_commit() +# T3 goes to wait for T2 to start its commit +# T2 does mark_start_commit() +# The bug was that at this point, T3 got deadlocked. Because T1 has unmarked(), +# T3 did not yet see the count_committing_event_groups reach its target value +# yet. But when T1 later re-did mark_start_commit(), it failed to send a wakeup +# to T3. + +--connection server_2 +--disable_connect_log +--source include/stop_slave.inc +--enable_connect_log +SET GLOBAL slave_parallel_threads=0; +SET GLOBAL slave_parallel_threads=3; +SET GLOBAL debug_dbug="+d,rpl_parallel_simulate_temp_err_xid"; +--disable_connect_log +--source include/start_slave.inc +--enable_connect_log + +--connection server_1 +SET @old_format= @@SESSION.binlog_format; +SET binlog_format= STATEMENT; +# This debug_sync will linger on and be used to control T3 later. +INSERT INTO t1 VALUES (foo(50, + "rpl_parallel_start_waiting_for_prior SIGNAL t3_ready", + "rpl_parallel_end_of_group SIGNAL prep_ready WAIT_FOR prep_cont")); +--save_master_pos +--connection server_2 +# Wait for the debug_sync point for T3 to be set. But let the preparation +# transaction remain hanging, so that T1 and T2 will be scheduled for the +# remaining two worker threads. +SET DEBUG_SYNC= "now WAIT_FOR prep_ready"; + +--connection server_1 +INSERT INTO t2 VALUES (foo(50, + "rpl_parallel_simulate_temp_err_xid SIGNAL t1_ready1 WAIT_FOR t1_cont1", + "rpl_parallel_retry_after_unmark SIGNAL t1_ready2 WAIT_FOR t1_cont2")); +--save_master_pos + +--connection server_2 +SET DEBUG_SYNC= "now WAIT_FOR t1_ready1"; +# T1 has now done mark_start_commit(). It will later do a rollback and retry. + +--connection server_1 +# Use a MyISAM table for T2 and T3, so they do not trigger the +# rpl_parallel_simulate_temp_err_xid DBUG insertion on XID event. +INSERT INTO t1 VALUES (foo(51, + "rpl_parallel_before_mark_start_commit SIGNAL t2_ready1 WAIT_FOR t2_cont1", + "rpl_parallel_after_mark_start_commit SIGNAL t2_ready2")); + +--connection server_2 +SET DEBUG_SYNC= "now WAIT_FOR t2_ready1"; +# T2 has now started running, but has not yet done mark_start_commit() +SET DEBUG_SYNC= "now SIGNAL t1_cont1"; +SET DEBUG_SYNC= "now WAIT_FOR t1_ready2"; +# T1 has now done unmark_start_commit() in preparation for its retry. + +--connection server_1 +INSERT INTO t1 VALUES (52); +SET BINLOG_FORMAT= @old_format; +SELECT * FROM t2 WHERE a>=50 ORDER BY a; +SELECT * FROM t1 WHERE a>=50 ORDER BY a; + +--connection server_2 +# Let the preparation transaction complete, so that the same worker thread +# can continue with the transaction T3. +SET DEBUG_SYNC= "now SIGNAL prep_cont"; +SET DEBUG_SYNC= "now WAIT_FOR t3_ready"; +# T3 has now gone to wait for T2 to start committing +SET DEBUG_SYNC= "now SIGNAL t2_cont1"; +SET DEBUG_SYNC= "now WAIT_FOR t2_ready2"; +# T2 has now done mark_start_commit(). +# Let things run, and check that T3 does not get deadlocked. +SET DEBUG_SYNC= "now SIGNAL t1_cont2"; +--sync_with_master + +--connection server_1 +--save_master_pos +--connection server_2 +--sync_with_master +SELECT * FROM t2 WHERE a>=50 ORDER BY a; +SELECT * FROM t1 WHERE a>=50 ORDER BY a; +SET DEBUG_SYNC="reset"; + +# Re-spawn the worker threads to remove any DBUG injections or DEBUG_SYNC. +--disable_connect_log +--source include/stop_slave.inc +--enable_connect_log +SET GLOBAL debug_dbug=@old_dbug; +SET GLOBAL slave_parallel_threads=0; +SET GLOBAL slave_parallel_threads=10; +--disable_connect_log +--source include/start_slave.inc +--enable_connect_log + + +--echo *** MDEV-7326 Server deadlock in connection with parallel replication *** +# Similar to the previous test, but with T2 and T3 in the same GCO. +# We use three transactions, T1 in one group commit and T2/T3 in another. +# T1 does mark_start_commit(), then gets a deadlock error. +# T2 wakes up and starts running +# T1 does unmark_start_commit() +# T3 goes to wait for T1 to start its commit +# T2 does mark_start_commit() +# The bug was that at this point, T3 got deadlocked. T2 increments the +# count_committing_event_groups but does not signal T3, as they are in +# the same GCO. Then later when T1 increments, it would also not signal +# T3, because now the count_committing_event_groups is not equal to the +# wait_count of T3 (it is one larger). + +--connection server_2 +--disable_connect_log +--source include/stop_slave.inc +--enable_connect_log +SET GLOBAL slave_parallel_threads=0; +SET GLOBAL slave_parallel_threads=3; +SET GLOBAL debug_dbug="+d,rpl_parallel_simulate_temp_err_xid"; +--disable_connect_log +--source include/start_slave.inc +--enable_connect_log + +--connection server_1 +SET @old_format= @@SESSION.binlog_format; +SET binlog_format= STATEMENT; +# This debug_sync will linger on and be used to control T3 later. +INSERT INTO t1 VALUES (foo(60, + "rpl_parallel_start_waiting_for_prior SIGNAL t3_ready", + "rpl_parallel_end_of_group SIGNAL prep_ready WAIT_FOR prep_cont")); +--save_master_pos +--connection server_2 +# Wait for the debug_sync point for T3 to be set. But let the preparation +# transaction remain hanging, so that T1 and T2 will be scheduled for the +# remaining two worker threads. +SET DEBUG_SYNC= "now WAIT_FOR prep_ready"; + +--connection server_1 +INSERT INTO t2 VALUES (foo(60, + "rpl_parallel_simulate_temp_err_xid SIGNAL t1_ready1 WAIT_FOR t1_cont1", + "rpl_parallel_retry_after_unmark SIGNAL t1_ready2 WAIT_FOR t1_cont2")); +--save_master_pos + +--connection server_2 +SET DEBUG_SYNC= "now WAIT_FOR t1_ready1"; +# T1 has now done mark_start_commit(). It will later do a rollback and retry. + +# Do T2 and T3 in a single group commit. +# Use a MyISAM table for T2 and T3, so they do not trigger the +# rpl_parallel_simulate_temp_err_xid DBUG insertion on XID event. +--connection con_temp3 +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued1 WAIT_FOR master_cont1'; +SET binlog_format=statement; +send INSERT INTO t1 VALUES (foo(61, + "rpl_parallel_before_mark_start_commit SIGNAL t2_ready1 WAIT_FOR t2_cont1", + "rpl_parallel_after_mark_start_commit SIGNAL t2_ready2")); + +--connection server_1 +SET debug_sync='now WAIT_FOR master_queued1'; + +--connection con_temp4 +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued2'; +send INSERT INTO t6 VALUES (62); + +--connection server_1 +SET debug_sync='now WAIT_FOR master_queued2'; +SET debug_sync='now SIGNAL master_cont1'; + +--connection con_temp3 +REAP; +--connection con_temp4 +REAP; + +--connection server_1 +SET debug_sync='RESET'; +SET BINLOG_FORMAT= @old_format; +SELECT * FROM t2 WHERE a>=60 ORDER BY a; +SELECT * FROM t1 WHERE a>=60 ORDER BY a; +SELECT * FROM t6 WHERE a>=60 ORDER BY a; + +--connection server_2 +SET DEBUG_SYNC= "now WAIT_FOR t2_ready1"; +# T2 has now started running, but has not yet done mark_start_commit() +SET DEBUG_SYNC= "now SIGNAL t1_cont1"; +SET DEBUG_SYNC= "now WAIT_FOR t1_ready2"; +# T1 has now done unmark_start_commit() in preparation for its retry. + +--connection server_2 +# Let the preparation transaction complete, so that the same worker thread +# can continue with the transaction T3. +SET DEBUG_SYNC= "now SIGNAL prep_cont"; +SET DEBUG_SYNC= "now WAIT_FOR t3_ready"; +# T3 has now gone to wait for T2 to start committing +SET DEBUG_SYNC= "now SIGNAL t2_cont1"; +SET DEBUG_SYNC= "now WAIT_FOR t2_ready2"; +# T2 has now done mark_start_commit(). +# Let things run, and check that T3 does not get deadlocked. +SET DEBUG_SYNC= "now SIGNAL t1_cont2"; +--sync_with_master + +--connection server_1 +--save_master_pos +--connection server_2 +--sync_with_master +SELECT * FROM t2 WHERE a>=60 ORDER BY a; +SELECT * FROM t1 WHERE a>=60 ORDER BY a; +SELECT * FROM t6 WHERE a>=60 ORDER BY a; +SET DEBUG_SYNC="reset"; + +# Re-spawn the worker threads to remove any DBUG injections or DEBUG_SYNC. +--disable_connect_log +--source include/stop_slave.inc +--enable_connect_log +SET GLOBAL debug_dbug=@old_dbug; +SET GLOBAL slave_parallel_threads=0; +SET GLOBAL slave_parallel_threads=10; +--disable_connect_log +--source include/start_slave.inc +--enable_connect_log + +--echo *** MDEV-7335: Potential parallel slave deadlock with specific binlog corruption *** + +--connection server_2 +--disable_connect_log +--source include/stop_slave.inc +--enable_connect_log +SET GLOBAL slave_parallel_threads=1; +SET @old_dbug= @@GLOBAL.debug_dbug; +SET GLOBAL debug_dbug="+d,slave_discard_xid_for_gtid_0_x_1000"; + +--connection server_1 +INSERT INTO t2 VALUES (101); +INSERT INTO t2 VALUES (102); +INSERT INTO t2 VALUES (103); +INSERT INTO t2 VALUES (104); +INSERT INTO t2 VALUES (105); +# Inject a partial event group (missing XID at the end). The bug was that such +# partial group was not handled appropriately, leading to server deadlock. +SET gtid_seq_no=1000; +INSERT INTO t2 VALUES (106); +INSERT INTO t2 VALUES (107); +INSERT INTO t2 VALUES (108); +INSERT INTO t2 VALUES (109); +INSERT INTO t2 VALUES (110); +INSERT INTO t2 VALUES (111); +INSERT INTO t2 VALUES (112); +INSERT INTO t2 VALUES (113); +INSERT INTO t2 VALUES (114); +INSERT INTO t2 VALUES (115); +INSERT INTO t2 VALUES (116); +INSERT INTO t2 VALUES (117); +INSERT INTO t2 VALUES (118); +INSERT INTO t2 VALUES (119); +INSERT INTO t2 VALUES (120); +INSERT INTO t2 VALUES (121); +INSERT INTO t2 VALUES (122); +INSERT INTO t2 VALUES (123); +INSERT INTO t2 VALUES (124); +INSERT INTO t2 VALUES (125); +INSERT INTO t2 VALUES (126); +INSERT INTO t2 VALUES (127); +INSERT INTO t2 VALUES (128); +INSERT INTO t2 VALUES (129); +INSERT INTO t2 VALUES (130); +--disable_connect_log +--source include/save_master_gtid.inc +--enable_connect_log + +--connection server_2 +--disable_connect_log +--source include/start_slave.inc +--source include/sync_with_master_gtid.inc +--enable_connect_log +# The partial event group (a=106) should be rolled back and thus missing. +SELECT * FROM t2 WHERE a >= 100 ORDER BY a; + +--disable_connect_log +--source include/stop_slave.inc +--enable_connect_log +SET GLOBAL debug_dbug=@old_dbug; +SET GLOBAL slave_parallel_threads=10; +--disable_connect_log +--source include/start_slave.inc +--enable_connect_log + +--echo *** MDEV-6676 - test syntax of @@slave_parallel_mode *** +--connection server_2 + +--let $status_items= Parallel_Mode +--disable_connect_log +--source include/show_slave_status.inc +--source include/stop_slave.inc +--enable_connect_log +SET GLOBAL slave_parallel_mode='aggressive'; +--let $status_items= Parallel_Mode +--disable_connect_log +--source include/show_slave_status.inc +SET GLOBAL slave_parallel_mode='conservative'; +--let $status_items= Parallel_Mode +--source include/show_slave_status.inc +--enable_connect_log + + +--echo *** MDEV-6676 - test that empty parallel_mode does not replicate in parallel *** +--connection server_1 +INSERT INTO t2 VALUES (1040); +--disable_connect_log +--source include/save_master_gtid.inc +--enable_connect_log + +--connection server_2 +SET GLOBAL slave_parallel_mode='none'; +# Test that we do not use parallel apply, by injecting an unconditional +# crash in the parallel apply code. +SET @old_dbug= @@GLOBAL.debug_dbug; +SET GLOBAL debug_dbug="+d,slave_crash_if_parallel_apply"; +--disable_connect_log +--source include/start_slave.inc +--source include/sync_with_master_gtid.inc +SELECT * FROM t2 WHERE a >= 1040 ORDER BY a; +--source include/stop_slave.inc +--enable_connect_log +SET GLOBAL debug_dbug=@old_dbug; + + +--echo *** MDEV-6676 - test disabling domain-based parallel replication *** +--connection server_1 +# Let's do a bunch of transactions that will conflict if run out-of-order in +# domain-based parallel replication mode. +SET gtid_domain_id = 1; +INSERT INTO t2 VALUES (1041); +INSERT INTO t2 VALUES (1042); +INSERT INTO t2 VALUES (1043); +INSERT INTO t2 VALUES (1044); +INSERT INTO t2 VALUES (1045); +INSERT INTO t2 VALUES (1046); +DELETE FROM t2 WHERE a >= 1041; +SET gtid_domain_id = 2; +INSERT INTO t2 VALUES (1041); +INSERT INTO t2 VALUES (1042); +INSERT INTO t2 VALUES (1043); +INSERT INTO t2 VALUES (1044); +INSERT INTO t2 VALUES (1045); +INSERT INTO t2 VALUES (1046); +SET gtid_domain_id = 0; +--disable_connect_log +--source include/save_master_gtid.inc +--enable_connect_log +--connection server_2 +SET GLOBAL slave_parallel_mode=minimal; +--disable_connect_log +--source include/start_slave.inc +--source include/sync_with_master_gtid.inc +SELECT * FROM t2 WHERE a >= 1040 ORDER BY a; +--source include/stop_slave.inc +SET GLOBAL slave_parallel_mode='conservative'; +--source include/start_slave.inc +--enable_connect_log + + +--echo *** MDEV-7847: "Slave worker thread retried transaction 10 time(s) in vain, giving up", followed by replication hanging *** +--echo *** MDEV-7882: Excessive transaction retry in parallel replication *** + +--connection server_1 +CREATE TABLE t7 (a int PRIMARY KEY, b INT) ENGINE=InnoDB; +CREATE TABLE t8 (a int PRIMARY KEY, b INT) ENGINE=InnoDB; +--save_master_pos + +--connection server_2 +--sync_with_master +--disable_connect_log +--source include/stop_slave.inc +--enable_connect_log +SET GLOBAL slave_parallel_threads=40; +SELECT @old_retries:=@@GLOBAL.slave_transaction_retries; +SET GLOBAL slave_transaction_retries= 5; + + +# Using dbug error injection, we artificially create event groups with a lot of +# conflicting transactions in each event group. The bugs were originally seen +# "in the wild" with transactions that did not conflict on the master, and only +# conflicted very rarely on the slave (maybe some edge case with InnoDB btree +# page splits or something like that). The event groups here loosely reflect +# the structure of the original failure's group commits. + + +--connection server_1 +INSERT INTO t7 VALUES (1,1), (2,2), (3,3), (4,4), (5,5); +SET @old_dbug= @@SESSION.debug_dbug; +SET @commit_id= 42; +SET SESSION debug_dbug="+d,binlog_force_commit_id"; +INSERT INTO t8 VALUES (1,1); +INSERT INTO t8 VALUES (2,2); +INSERT INTO t8 VALUES (3,3); +INSERT INTO t8 VALUES (4,4); +INSERT INTO t8 VALUES (5,5); +INSERT INTO t8 VALUES (6,6); +INSERT INTO t8 VALUES (7,7); +INSERT INTO t8 VALUES (8,8); + +UPDATE t7 SET b=9 WHERE a=3; +UPDATE t7 SET b=10 WHERE a=3; +UPDATE t7 SET b=11 WHERE a=3; + +INSERT INTO t8 VALUES (12,12); +INSERT INTO t8 VALUES (13,13); + +UPDATE t7 SET b=14 WHERE a=3; +UPDATE t7 SET b=15 WHERE a=3; + +INSERT INTO t8 VALUES (16,16); + +UPDATE t7 SET b=17 WHERE a=3; + +INSERT INTO t8 VALUES (18,18); +INSERT INTO t8 VALUES (19,19); + +UPDATE t7 SET b=20 WHERE a=3; + +INSERT INTO t8 VALUES (21,21); + +UPDATE t7 SET b=22 WHERE a=3; + +INSERT INTO t8 VALUES (23,24); +INSERT INTO t8 VALUES (24,24); + +UPDATE t7 SET b=25 WHERE a=3; + +INSERT INTO t8 VALUES (26,26); + +UPDATE t7 SET b=27 WHERE a=3; + +BEGIN; +INSERT INTO t8 VALUES (28,28); +INSERT INTO t8 VALUES (29,28), (30,28); +INSERT INTO t8 VALUES (31,28); +INSERT INTO t8 VALUES (32,28); +INSERT INTO t8 VALUES (33,28); +INSERT INTO t8 VALUES (34,28); +INSERT INTO t8 VALUES (35,28); +INSERT INTO t8 VALUES (36,28); +INSERT INTO t8 VALUES (37,28); +INSERT INTO t8 VALUES (38,28); +INSERT INTO t8 VALUES (39,28); +INSERT INTO t8 VALUES (40,28); +INSERT INTO t8 VALUES (41,28); +INSERT INTO t8 VALUES (42,28); +COMMIT; + + +SET @commit_id=43; +INSERT INTO t8 VALUES (43,43); +INSERT INTO t8 VALUES (44,44); + +UPDATE t7 SET b=45 WHERE a=3; + +INSERT INTO t8 VALUES (46,46); +INSERT INTO t8 VALUES (47,47); + +UPDATE t7 SET b=48 WHERE a=3; + +INSERT INTO t8 VALUES (49,49); +INSERT INTO t8 VALUES (50,50); + + +SET @commit_id=44; +INSERT INTO t8 VALUES (51,51); +INSERT INTO t8 VALUES (52,52); + +UPDATE t7 SET b=53 WHERE a=3; + +INSERT INTO t8 VALUES (54,54); +INSERT INTO t8 VALUES (55,55); + +UPDATE t7 SET b=56 WHERE a=3; + +INSERT INTO t8 VALUES (57,57); + +UPDATE t7 SET b=58 WHERE a=3; + +INSERT INTO t8 VALUES (58,58); +INSERT INTO t8 VALUES (59,59); +INSERT INTO t8 VALUES (60,60); +INSERT INTO t8 VALUES (61,61); + +UPDATE t7 SET b=62 WHERE a=3; + +INSERT INTO t8 VALUES (63,63); +INSERT INTO t8 VALUES (64,64); +INSERT INTO t8 VALUES (65,65); +INSERT INTO t8 VALUES (66,66); + +UPDATE t7 SET b=67 WHERE a=3; + +INSERT INTO t8 VALUES (68,68); + +UPDATE t7 SET b=69 WHERE a=3; +UPDATE t7 SET b=70 WHERE a=3; +UPDATE t7 SET b=71 WHERE a=3; + +INSERT INTO t8 VALUES (72,72); + +UPDATE t7 SET b=73 WHERE a=3; +UPDATE t7 SET b=74 WHERE a=3; +UPDATE t7 SET b=75 WHERE a=3; +UPDATE t7 SET b=76 WHERE a=3; + +INSERT INTO t8 VALUES (77,77); + +UPDATE t7 SET b=78 WHERE a=3; + +INSERT INTO t8 VALUES (79,79); + +UPDATE t7 SET b=80 WHERE a=3; + +INSERT INTO t8 VALUES (81,81); + +UPDATE t7 SET b=82 WHERE a=3; + +INSERT INTO t8 VALUES (83,83); + +UPDATE t7 SET b=84 WHERE a=3; + + +SET @commit_id=45; +INSERT INTO t8 VALUES (85,85); +UPDATE t7 SET b=86 WHERE a=3; +INSERT INTO t8 VALUES (87,87); + + +SET @commit_id=46; +INSERT INTO t8 VALUES (88,88); +INSERT INTO t8 VALUES (89,89); +INSERT INTO t8 VALUES (90,90); + +SET SESSION debug_dbug=@old_dbug; + +INSERT INTO t8 VALUES (91,91); +INSERT INTO t8 VALUES (92,92); +INSERT INTO t8 VALUES (93,93); +INSERT INTO t8 VALUES (94,94); +INSERT INTO t8 VALUES (95,95); +INSERT INTO t8 VALUES (96,96); +INSERT INTO t8 VALUES (97,97); +INSERT INTO t8 VALUES (98,98); +INSERT INTO t8 VALUES (99,99); + + +SELECT * FROM t7 ORDER BY a; +SELECT * FROM t8 ORDER BY a; +--disable_connect_log +--source include/save_master_gtid.inc +--enable_connect_log + + +--connection server_2 +--disable_connect_log +--source include/start_slave.inc +--source include/sync_with_master_gtid.inc +SELECT * FROM t7 ORDER BY a; +SELECT * FROM t8 ORDER BY a; + +--source include/stop_slave.inc +SET GLOBAL slave_transaction_retries= @old_retries; +SET GLOBAL slave_parallel_threads=10; +--source include/start_slave.inc +--enable_connect_log + + +--echo *** MDEV-7888: ANALYZE TABLE does wakeup_subsequent_commits(), causing wrong binlog order and parallel replication hang *** + +--connection server_2 +--disable_connect_log +--source include/stop_slave.inc +--enable_connect_log +SET @old_dbug= @@GLOBAL.debug_dbug; +SET GLOBAL debug_dbug= '+d,inject_analyze_table_sleep'; + +--connection server_1 +# Inject two group commits. The bug was that ANALYZE TABLE would call +# wakeup_subsequent_commits() too early, allowing the following transaction +# in the same group to run ahead and binlog and free the GCO. Then we get +# wrong binlog order and later access freed GCO, which causes lost wakeup +# of following GCO and thus replication hang. +# We injected a small sleep in ANALYZE to make the race easier to hit (this +# can only cause false negatives in versions with the bug, not false positives, +# so sleep is ok here. And it's in general not possible to trigger reliably +# the race with debug_sync, since the bugfix makes the race impossible). + +SET @old_dbug= @@SESSION.debug_dbug; +SET SESSION debug_dbug="+d,binlog_force_commit_id"; + +# Group commit with cid=10000, two event groups. +SET @commit_id= 10000; +ANALYZE TABLE t2; +INSERT INTO t3 VALUES (120, 0); + +# Group commit with cid=10001, one event group. +SET @commit_id= 10001; +INSERT INTO t3 VALUES (121, 0); + +SET SESSION debug_dbug=@old_dbug; + +SELECT * FROM t3 WHERE a >= 120 ORDER BY a; +--disable_connect_log +--source include/save_master_gtid.inc +--enable_connect_log + +--connection server_2 +--disable_connect_log +--source include/start_slave.inc +--source include/sync_with_master_gtid.inc + +SELECT * FROM t3 WHERE a >= 120 ORDER BY a; + +--source include/stop_slave.inc +SET GLOBAL debug_dbug= @old_dbug; +--source include/start_slave.inc +--enable_connect_log + + +--echo *** MDEV-7929: record_gtid() for non-transactional event group calls wakeup_subsequent_commits() too early, causing slave hang. *** + +--connection server_2 +--disable_connect_log +--source include/stop_slave.inc +--enable_connect_log +SET @old_dbug= @@GLOBAL.debug_dbug; +SET GLOBAL debug_dbug= '+d,inject_record_gtid_serverid_100_sleep'; + +--connection server_1 +# Inject two group commits. The bug was that record_gtid for a +# non-transactional event group would commit its own transaction, which would +# cause ha_commit_trans() to call wakeup_subsequent_commits() too early. This +# in turn lead to access to freed group_commit_orderer object, losing a wakeup +# and causing slave threads to hang. +# We inject a small sleep in the corresponding record_gtid() to make the race +# easier to hit. + +SET @old_dbug= @@SESSION.debug_dbug; +SET SESSION debug_dbug="+d,binlog_force_commit_id"; + +# Group commit with cid=10010, two event groups. +SET @old_server_id= @@SESSION.server_id; +SET SESSION server_id= 100; +SET @commit_id= 10010; +ALTER TABLE t1 COMMENT "Hulubulu!"; +SET SESSION server_id= @old_server_id; +INSERT INTO t3 VALUES (130, 0); + +# Group commit with cid=10011, one event group. +SET @commit_id= 10011; +INSERT INTO t3 VALUES (131, 0); + +SET SESSION debug_dbug=@old_dbug; + +SELECT * FROM t3 WHERE a >= 130 ORDER BY a; +--disable_connect_log +--source include/save_master_gtid.inc +--enable_connect_log + +--connection server_2 +--disable_connect_log +--source include/start_slave.inc +--source include/sync_with_master_gtid.inc + +SELECT * FROM t3 WHERE a >= 130 ORDER BY a; + +--source include/stop_slave.inc +SET GLOBAL debug_dbug= @old_dbug; +--source include/start_slave.inc +--enable_connect_log + + +--echo *** MDEV-8031: Parallel replication stops on "connection killed" error (probably incorrectly handled deadlock kill) *** + +--connection server_1 +INSERT INTO t3 VALUES (201,0), (202,0); +--disable_connect_log +--source include/save_master_gtid.inc +--enable_connect_log + +--connection server_2 +--disable_connect_log +--source include/sync_with_master_gtid.inc +--source include/stop_slave.inc +--enable_connect_log +SET @old_dbug= @@GLOBAL.debug_dbug; +SET GLOBAL debug_dbug= '+d,inject_mdev8031'; + +--connection server_1 +# We artificially create a situation that hopefully resembles the original +# bug which was only seen "in the wild", and only once. +# Setup a fake group commit with lots of conflicts that will lead to deadloc +# kill. The slave DBUG injection causes the slave to be deadlock killed at +# a particular point during the retry, and then later do a small sleep at +# another critical point where the prior transaction then has a chance to +# complete. Finally an extra KILL check catches an unhandled, lingering +# deadlock kill. So rather artificial, but at least it exercises the +# relevant code paths. +SET @old_dbug= @@SESSION.debug_dbug; +SET SESSION debug_dbug="+d,binlog_force_commit_id"; + +SET @commit_id= 10200; +INSERT INTO t3 VALUES (203, 1); +INSERT INTO t3 VALUES (204, 1); +INSERT INTO t3 VALUES (205, 1); +UPDATE t3 SET b=b+1 WHERE a=201; +UPDATE t3 SET b=b+1 WHERE a=201; +UPDATE t3 SET b=b+1 WHERE a=201; +UPDATE t3 SET b=b+1 WHERE a=202; +UPDATE t3 SET b=b+1 WHERE a=202; +UPDATE t3 SET b=b+1 WHERE a=202; +UPDATE t3 SET b=b+1 WHERE a=202; +UPDATE t3 SET b=b+1 WHERE a=203; +UPDATE t3 SET b=b+1 WHERE a=203; +UPDATE t3 SET b=b+1 WHERE a=204; +UPDATE t3 SET b=b+1 WHERE a=204; +UPDATE t3 SET b=b+1 WHERE a=204; +UPDATE t3 SET b=b+1 WHERE a=203; +UPDATE t3 SET b=b+1 WHERE a=205; +UPDATE t3 SET b=b+1 WHERE a=205; +SET SESSION debug_dbug=@old_dbug; + +SELECT * FROM t3 WHERE a>=200 ORDER BY a; +--disable_connect_log +--source include/save_master_gtid.inc +--enable_connect_log + +--connection server_2 +--disable_connect_log +--source include/start_slave.inc +--source include/sync_with_master_gtid.inc + +SELECT * FROM t3 WHERE a>=200 ORDER BY a; +--source include/stop_slave.inc +SET GLOBAL debug_dbug= @old_dbug; +--source include/start_slave.inc +--enable_connect_log + + +--echo *** Check getting deadlock killed inside open_binlog() during retry. *** + +--connection server_2 +--disable_connect_log +--source include/stop_slave.inc +--enable_connect_log +SET @old_dbug= @@GLOBAL.debug_dbug; +SET GLOBAL debug_dbug= '+d,inject_retry_event_group_open_binlog_kill'; +SET @old_max= @@GLOBAL.max_relay_log_size; +SET GLOBAL max_relay_log_size= 4096; + +--connection server_1 +SET @old_dbug= @@SESSION.debug_dbug; +SET SESSION debug_dbug="+d,binlog_force_commit_id"; + +--let $large= `SELECT REPEAT("*", 8192)` +SET @commit_id= 10210; +--echo Omit long queries that cause relaylog rotations and transaction retries... +--disable_query_log +eval UPDATE t3 SET b=b+1 WHERE a=201 /* $large */; +eval UPDATE t3 SET b=b+1 WHERE a=201 /* $large */; +eval UPDATE t3 SET b=b+1 WHERE a=201 /* $large */; +eval UPDATE t3 SET b=b+1 WHERE a=202 /* $large */; +eval UPDATE t3 SET b=b+1 WHERE a=202 /* $large */; +eval UPDATE t3 SET b=b+1 WHERE a=202 /* $large */; +eval UPDATE t3 SET b=b+1 WHERE a=202 /* $large */; +eval UPDATE t3 SET b=b+1 WHERE a=203 /* $large */; +eval UPDATE t3 SET b=b+1 WHERE a=203 /* $large */; +eval UPDATE t3 SET b=b+1 WHERE a=204 /* $large */; +eval UPDATE t3 SET b=b+1 WHERE a=204 /* $large */; +eval UPDATE t3 SET b=b+1 WHERE a=204 /* $large */; +eval UPDATE t3 SET b=b+1 WHERE a=203 /* $large */; +eval UPDATE t3 SET b=b+1 WHERE a=205 /* $large */; +eval UPDATE t3 SET b=b+1 WHERE a=205 /* $large */; +--enable_query_log +SET SESSION debug_dbug=@old_dbug; + +SELECT * FROM t3 WHERE a>=200 ORDER BY a; +--disable_connect_log +--source include/save_master_gtid.inc +--enable_connect_log + +--connection server_2 +--disable_connect_log +--source include/start_slave.inc +--source include/sync_with_master_gtid.inc + +SELECT * FROM t3 WHERE a>=200 ORDER BY a; +--source include/stop_slave.inc +SET GLOBAL debug_dbug= @old_debg; +SET GLOBAL max_relay_log_size= @old_max; +--source include/start_slave.inc +--enable_connect_log + + +--echo *** MDEV-8302: Duplicate key with parallel replication *** + +--connection server_2 +--disable_connect_log +--source include/stop_slave.inc +--enable_connect_log +/* Inject a small sleep which makes the race easier to hit. */ +SET @old_dbug=@@GLOBAL.debug_dbug; +SET GLOBAL debug_dbug="+d,inject_mdev8302"; + + +--connection server_1 +INSERT INTO t7 VALUES (100,1), (101,2), (102,3), (103,4), (104,5); + +# Artificially create a bunch of group commits with conflicting transactions. +# The bug happened when T1 and T2 was in one group commit, and T3 was in the +# following group commit. T2 is a DELETE of a row with same primary key as a +# row that T3 inserts. T1 and T2 can conflict, causing T2 to be deadlock +# killed after starting to commit. The bug was that T2 could roll back before +# doing unmark_start_commit(); this could allow T3 to run before the retry +# of T2, causing duplicate key violation. + +SET @old_dbug= @@SESSION.debug_dbug; +SET @commit_id= 20000; +SET SESSION debug_dbug="+d,binlog_force_commit_id"; + +--let $n = 100 +--disable_query_log +while ($n) +{ + eval UPDATE t7 SET b=b+1 WHERE a=100+($n MOD 5); + eval DELETE FROM t7 WHERE a=100+($n MOD 5); + + SET @commit_id = @commit_id + 1; + eval INSERT INTO t7 VALUES (100+($n MOD 5), $n); + SET @commit_id = @commit_id + 1; + dec $n; +} +--enable_query_log +SET SESSION debug_dbug=@old_dbug; + + +SELECT * FROM t7 ORDER BY a; +--disable_connect_log +--source include/save_master_gtid.inc +--enable_connect_log + + +--connection server_2 +--disable_connect_log +--source include/start_slave.inc +--source include/sync_with_master_gtid.inc +SELECT * FROM t7 ORDER BY a; + +--source include/stop_slave.inc +SET GLOBAL debug_dbug=@old_dbug; +--source include/start_slave.inc +--enable_connect_log + + + +--echo *** MDEV-8725: Assertion on ROLLBACK statement in the binary log *** +--connection server_1 +# Inject an event group terminated by ROLLBACK, by mixing MyISAM and InnoDB +# in a transaction. The bug was an assertion on the ROLLBACK due to +# mark_start_commit() being already called. +--disable_warnings +BEGIN; +INSERT INTO t2 VALUES (2000); +INSERT INTO t1 VALUES (2000); +INSERT INTO t2 VALUES (2001); +ROLLBACK; +--enable_warnings +SELECT * FROM t1 WHERE a>=2000 ORDER BY a; +SELECT * FROM t2 WHERE a>=2000 ORDER BY a; +--disable_connect_log +--source include/save_master_gtid.inc +--enable_connect_log + +--connection server_2 +--disable_connect_log +--source include/sync_with_master_gtid.inc +--enable_connect_log +SELECT * FROM t1 WHERE a>=2000 ORDER BY a; +SELECT * FROM t2 WHERE a>=2000 ORDER BY a; + + +# Clean up. +--connection server_2 +--disable_connect_log +--source include/stop_slave.inc +SET GLOBAL slave_parallel_threads=@old_parallel_threads; +--source include/start_slave.inc +SET DEBUG_SYNC= 'RESET'; +--enable_connect_log + +--connection server_1 +DROP function foo; +DROP TABLE t1,t2,t3,t4,t5,t6,t7,t8; +SET DEBUG_SYNC= 'RESET'; + +--disable_connect_log +--source include/rpl_end.inc diff --git a/mysql-test/suite/binlog_encryption/rpl_parallel_show_binlog_events_purge_logs.cnf b/mysql-test/suite/binlog_encryption/rpl_parallel_show_binlog_events_purge_logs.cnf new file mode 100644 index 0000000..b8e22e9 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_parallel_show_binlog_events_purge_logs.cnf @@ -0,0 +1,6 @@ +!include my.cnf + +[mysqld.2] +plugin-load-add= @ENV.FILE_KEY_MANAGEMENT_SO +loose-file-key-management-filename=@ENV.MYSQLTEST_VARDIR/std_data/keys.txt +encrypt-binlog diff --git a/mysql-test/suite/binlog_encryption/rpl_parallel_show_binlog_events_purge_logs.result b/mysql-test/suite/binlog_encryption/rpl_parallel_show_binlog_events_purge_logs.result new file mode 100644 index 0000000..204db2b --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_parallel_show_binlog_events_purge_logs.result @@ -0,0 +1,13 @@ +include/master-slave.inc +[connection master] +connection slave; +SET DEBUG_SYNC= 'after_show_binlog_events SIGNAL on_show_binlog_events WAIT_FOR end'; +SHOW BINLOG EVENTS; +connection slave1; +SET DEBUG_SYNC= 'now WAIT_FOR on_show_binlog_events'; +FLUSH LOGS; +SET DEBUG_SYNC= 'now SIGNAL end'; +connection slave; +SET DEBUG_SYNC= 'RESET'; +connection master; +include/rpl_end.inc diff --git a/mysql-test/suite/binlog_encryption/rpl_parallel_show_binlog_events_purge_logs.test b/mysql-test/suite/binlog_encryption/rpl_parallel_show_binlog_events_purge_logs.test new file mode 100644 index 0000000..fa21200 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_parallel_show_binlog_events_purge_logs.test @@ -0,0 +1,39 @@ +# +# The test was taken from the rpl suite as is. It is run with encrypted +# binlogs on master and slave +# + +# BUG#13979418: SHOW BINLOG EVENTS MAY CRASH THE SERVER +# +# The function mysql_show_binlog_events has a local stack variable +# 'LOG_INFO linfo;', which is assigned to thd->current_linfo, however +# this variable goes out of scope and is destroyed before clean +# thd->current_linfo. +# +# This test case runs SHOW BINLOG EVENTS and FLUSH LOGS to make sure +# that with the fix local variable linfo is valid along all +# mysql_show_binlog_events function scope. +# +--source include/have_debug_sync.inc +--source include/master-slave.inc + +--enable_connect_log + +--connection slave +SET DEBUG_SYNC= 'after_show_binlog_events SIGNAL on_show_binlog_events WAIT_FOR end'; +--send SHOW BINLOG EVENTS + +--connection slave1 +SET DEBUG_SYNC= 'now WAIT_FOR on_show_binlog_events'; +FLUSH LOGS; +SET DEBUG_SYNC= 'now SIGNAL end'; + +--connection slave +--disable_result_log +--reap +--enable_result_log +SET DEBUG_SYNC= 'RESET'; + +--connection master +--disable_connect_log +--source include/rpl_end.inc diff --git a/mysql-test/suite/binlog_encryption/rpl_relayrotate-slave.opt b/mysql-test/suite/binlog_encryption/rpl_relayrotate-slave.opt new file mode 100644 index 0000000..1665aec --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_relayrotate-slave.opt @@ -0,0 +1,5 @@ +--max_relay_log_size=16384 +--log-warnings +--plugin-load-add=$FILE_KEY_MANAGEMENT_SO +--loose-file-key-management-filename=$MYSQLTEST_VARDIR/std_data/keys.txt +--encrypt-binlog diff --git a/mysql-test/suite/binlog_encryption/rpl_relayrotate.result b/mysql-test/suite/binlog_encryption/rpl_relayrotate.result new file mode 100644 index 0000000..142626e --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_relayrotate.result @@ -0,0 +1,20 @@ +include/master-slave.inc +[connection master] +connection master; +connection slave; +connection slave; +stop slave; +connection master; +create table t1 (a int) engine=innodb; +connection slave; +reset slave; +start slave; +stop slave; +start slave; +select max(a) from t1; +max(a) +8000 +connection master; +drop table t1; +connection slave; +include/rpl_end.inc diff --git a/mysql-test/suite/binlog_encryption/rpl_relayrotate.test b/mysql-test/suite/binlog_encryption/rpl_relayrotate.test new file mode 100644 index 0000000..ee5266e --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_relayrotate.test @@ -0,0 +1,21 @@ +# +# The test was taken from the rpl suite as is, but we will run it +# with the encrypted slave (not just encrypted master as most of +# adopted tests) +# + +####################################################### +# Wrapper for rpl_relayrotate.test to allow multi # +# Engines to reuse test code. By JBM 2006-02-15 # +####################################################### + +# Slow test, don't run during staging part +-- source include/not_staging.inc +-- source include/master-slave.inc + +--enable_connect_log + +let $engine_type=innodb; +-- source extra/rpl_tests/rpl_relayrotate.test +--disable_connect_log +--source include/rpl_end.inc diff --git a/mysql-test/suite/binlog_encryption/rpl_semi_sync.result b/mysql-test/suite/binlog_encryption/rpl_semi_sync.result new file mode 100644 index 0000000..6d57468 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_semi_sync.result @@ -0,0 +1,488 @@ +include/master-slave.inc +[connection master] +connection master; +call mtr.add_suppression("Timeout waiting for reply of binlog"); +call mtr.add_suppression("Read semi-sync reply"); +call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT."); +connection slave; +call mtr.add_suppression("Master server does not support semi-sync"); +call mtr.add_suppression("Semi-sync slave .* reply"); +call mtr.add_suppression("Slave SQL.*Request to stop slave SQL Thread received while applying a group that has non-transactional changes; waiting for completion of the group"); +connection master; +# +# Uninstall semi-sync plugins on master and slave +# +connection slave; +include/stop_slave.inc +reset slave; +set global rpl_semi_sync_master_enabled= 0; +set global rpl_semi_sync_slave_enabled= 0; +connection master; +reset master; +set global rpl_semi_sync_master_enabled= 0; +set global rpl_semi_sync_slave_enabled= 0; +# +# Main test of semi-sync replication start here +# +connection master; +set global rpl_semi_sync_master_timeout= 60000; +[ default state of semi-sync on master should be OFF ] +show variables like 'rpl_semi_sync_master_enabled'; +Variable_name Value +rpl_semi_sync_master_enabled OFF +[ enable semi-sync on master ] +set global rpl_semi_sync_master_enabled = 1; +show variables like 'rpl_semi_sync_master_enabled'; +Variable_name Value +rpl_semi_sync_master_enabled ON +[ status of semi-sync on master should be ON even without any semi-sync slaves ] +show status like 'Rpl_semi_sync_master_clients'; +Variable_name Value +Rpl_semi_sync_master_clients 0 +show status like 'Rpl_semi_sync_master_status'; +Variable_name Value +Rpl_semi_sync_master_status ON +show status like 'Rpl_semi_sync_master_yes_tx'; +Variable_name Value +Rpl_semi_sync_master_yes_tx 0 +# +# BUG#45672 Semisync repl: ActiveTranx:insert_tranx_node: transaction node allocation failed +# BUG#45673 Semisynch reports correct operation even if no slave is connected +# +[ status of semi-sync on master should be OFF ] +show status like 'Rpl_semi_sync_master_clients'; +Variable_name Value +Rpl_semi_sync_master_clients 0 +show status like 'Rpl_semi_sync_master_status'; +Variable_name Value +Rpl_semi_sync_master_status OFF +show status like 'Rpl_semi_sync_master_yes_tx'; +Variable_name Value +Rpl_semi_sync_master_yes_tx 0 +reset master; +connection slave; +[ default state of semi-sync on slave should be OFF ] +show variables like 'rpl_semi_sync_slave_enabled'; +Variable_name Value +rpl_semi_sync_slave_enabled OFF +[ enable semi-sync on slave ] +set global rpl_semi_sync_slave_enabled = 1; +show variables like 'rpl_semi_sync_slave_enabled'; +Variable_name Value +rpl_semi_sync_slave_enabled ON +include/start_slave.inc +connection master; +[ initial master state after the semi-sync slave connected ] +show status like 'Rpl_semi_sync_master_clients'; +Variable_name Value +Rpl_semi_sync_master_clients 1 +show status like 'Rpl_semi_sync_master_status'; +Variable_name Value +Rpl_semi_sync_master_status ON +show status like 'Rpl_semi_sync_master_no_tx'; +Variable_name Value +Rpl_semi_sync_master_no_tx 0 +show status like 'Rpl_semi_sync_master_yes_tx'; +Variable_name Value +Rpl_semi_sync_master_yes_tx 0 +create table t1(a int) engine = ENGINE_TYPE; +[ master state after CREATE TABLE statement ] +show status like 'Rpl_semi_sync_master_status'; +Variable_name Value +Rpl_semi_sync_master_status ON +show status like 'Rpl_semi_sync_master_no_tx'; +Variable_name Value +Rpl_semi_sync_master_no_tx 0 +show status like 'Rpl_semi_sync_master_yes_tx'; +Variable_name Value +Rpl_semi_sync_master_yes_tx 1 +select CONNECTIONS_NORMAL_SLAVE - CONNECTIONS_NORMAL_SLAVE as 'Should be 0'; +Should be 0 +0 +[ insert records to table ] +insert t1 values (10); +insert t1 values (9); +insert t1 values (8); +insert t1 values (7); +insert t1 values (6); +insert t1 values (5); +insert t1 values (4); +insert t1 values (3); +insert t1 values (2); +insert t1 values (1); +[ master status after inserts ] +show status like 'Rpl_semi_sync_master_status'; +Variable_name Value +Rpl_semi_sync_master_status ON +show status like 'Rpl_semi_sync_master_no_tx'; +Variable_name Value +Rpl_semi_sync_master_no_tx 0 +show status like 'Rpl_semi_sync_master_yes_tx'; +Variable_name Value +Rpl_semi_sync_master_yes_tx 11 +connection slave; +[ slave status after replicated inserts ] +show status like 'Rpl_semi_sync_slave_status'; +Variable_name Value +Rpl_semi_sync_slave_status ON +select count(distinct a) from t1; +count(distinct a) +10 +select min(a) from t1; +min(a) +1 +select max(a) from t1; +max(a) +10 + +# BUG#50157 +# semi-sync replication crashes when replicating a transaction which +# include 'CREATE TEMPORARY TABLE `MyISAM_t` SELECT * FROM `Innodb_t` ; +connection master; +SET SESSION AUTOCOMMIT= 0; +CREATE TABLE t2(c1 INT) ENGINE=innodb; +connection slave; +connection master; +BEGIN; + +# Even though it is in a transaction, this statement is binlogged into binlog +# file immediately. +CREATE TEMPORARY TABLE t3 SELECT c1 FROM t2 where 1=1; + +# These statements will not be binlogged until the transaction is committed +INSERT INTO t2 VALUES(11); +INSERT INTO t2 VALUES(22); +COMMIT; +DROP TABLE t2, t3; +SET SESSION AUTOCOMMIT= 1; +connection slave; +# +# Test semi-sync master will switch OFF after one transaction +# timeout waiting for slave reply. +# +connection slave; +include/stop_slave.inc +connection master; +set global rpl_semi_sync_master_timeout= 5000; +[ master status should be ON ] +show status like 'Rpl_semi_sync_master_status'; +Variable_name Value +Rpl_semi_sync_master_status ON +show status like 'Rpl_semi_sync_master_no_tx'; +Variable_name Value +Rpl_semi_sync_master_no_tx 0 +show status like 'Rpl_semi_sync_master_yes_tx'; +Variable_name Value +Rpl_semi_sync_master_yes_tx 14 +show status like 'Rpl_semi_sync_master_clients'; +Variable_name Value +Rpl_semi_sync_master_clients 1 +[ semi-sync replication of these transactions will fail ] +insert into t1 values (500); +[ master status should be OFF ] +show status like 'Rpl_semi_sync_master_status'; +Variable_name Value +Rpl_semi_sync_master_status OFF +show status like 'Rpl_semi_sync_master_no_tx'; +Variable_name Value +Rpl_semi_sync_master_no_tx 1 +show status like 'Rpl_semi_sync_master_yes_tx'; +Variable_name Value +Rpl_semi_sync_master_yes_tx 14 +delete from t1 where a=10; +delete from t1 where a=9; +delete from t1 where a=8; +delete from t1 where a=7; +delete from t1 where a=6; +delete from t1 where a=5; +delete from t1 where a=4; +delete from t1 where a=3; +delete from t1 where a=2; +delete from t1 where a=1; +insert into t1 values (100); +[ master status should be OFF ] +show status like 'Rpl_semi_sync_master_status'; +Variable_name Value +Rpl_semi_sync_master_status OFF +show status like 'Rpl_semi_sync_master_no_tx'; +Variable_name Value +Rpl_semi_sync_master_no_tx 12 +show status like 'Rpl_semi_sync_master_yes_tx'; +Variable_name Value +Rpl_semi_sync_master_yes_tx 14 +# +# Test semi-sync status on master will be ON again when slave catches up +# +connection slave; +[ slave status should be OFF ] +show status like 'Rpl_semi_sync_slave_status'; +Variable_name Value +Rpl_semi_sync_slave_status OFF +include/start_slave.inc +[ slave status should be ON ] +show status like 'Rpl_semi_sync_slave_status'; +Variable_name Value +Rpl_semi_sync_slave_status ON +select count(distinct a) from t1; +count(distinct a) +2 +select min(a) from t1; +min(a) +100 +select max(a) from t1; +max(a) +500 +connection master; +[ master status should be ON again after slave catches up ] +show status like 'Rpl_semi_sync_master_status'; +Variable_name Value +Rpl_semi_sync_master_status ON +show status like 'Rpl_semi_sync_master_no_tx'; +Variable_name Value +Rpl_semi_sync_master_no_tx 12 +show status like 'Rpl_semi_sync_master_yes_tx'; +Variable_name Value +Rpl_semi_sync_master_yes_tx 14 +show status like 'Rpl_semi_sync_master_clients'; +Variable_name Value +Rpl_semi_sync_master_clients 1 +# +# Test disable/enable master semi-sync on the fly. +# +drop table t1; +connection slave; +include/stop_slave.inc +# +# Flush status +# +connection master; +[ Semi-sync master status variables before FLUSH STATUS ] +SHOW STATUS LIKE 'Rpl_semi_sync_master_no_tx'; +Variable_name Value +Rpl_semi_sync_master_no_tx 12 +SHOW STATUS LIKE 'Rpl_semi_sync_master_yes_tx'; +Variable_name Value +Rpl_semi_sync_master_yes_tx 15 +FLUSH NO_WRITE_TO_BINLOG STATUS; +[ Semi-sync master status variables after FLUSH STATUS ] +SHOW STATUS LIKE 'Rpl_semi_sync_master_no_tx'; +Variable_name Value +Rpl_semi_sync_master_no_tx 0 +SHOW STATUS LIKE 'Rpl_semi_sync_master_yes_tx'; +Variable_name Value +Rpl_semi_sync_master_yes_tx 0 +connection master; +show master logs; +Log_name master-bin.000001 +File_size # +show variables like 'rpl_semi_sync_master_enabled'; +Variable_name Value +rpl_semi_sync_master_enabled ON +[ disable semi-sync on the fly ] +set global rpl_semi_sync_master_enabled=0; +show variables like 'rpl_semi_sync_master_enabled'; +Variable_name Value +rpl_semi_sync_master_enabled OFF +show status like 'Rpl_semi_sync_master_status'; +Variable_name Value +Rpl_semi_sync_master_status OFF +[ enable semi-sync on the fly ] +set global rpl_semi_sync_master_enabled=1; +show variables like 'rpl_semi_sync_master_enabled'; +Variable_name Value +rpl_semi_sync_master_enabled ON +show status like 'Rpl_semi_sync_master_status'; +Variable_name Value +Rpl_semi_sync_master_status ON +# +# Test RESET MASTER/SLAVE +# +connection slave; +include/start_slave.inc +connection master; +create table t1 (a int) engine = ENGINE_TYPE; +drop table t1; +connection slave; +show status like 'Rpl_relay%'; +Variable_name Value +[ test reset master ] +connection master; +reset master; +show status like 'Rpl_semi_sync_master_status'; +Variable_name Value +Rpl_semi_sync_master_status ON +show status like 'Rpl_semi_sync_master_no_tx'; +Variable_name Value +Rpl_semi_sync_master_no_tx 0 +show status like 'Rpl_semi_sync_master_yes_tx'; +Variable_name Value +Rpl_semi_sync_master_yes_tx 0 +connection slave; +include/stop_slave.inc +reset slave; +connection master; +kill query _tid; +connection slave; +include/start_slave.inc +connection master; +create table t1 (a int) engine = ENGINE_TYPE; +insert into t1 values (1); +insert into t1 values (2), (3); +connection slave; +select * from t1; +a +1 +2 +3 +connection master; +[ master semi-sync status should be ON ] +show status like 'Rpl_semi_sync_master_status'; +Variable_name Value +Rpl_semi_sync_master_status ON +show status like 'Rpl_semi_sync_master_no_tx'; +Variable_name Value +Rpl_semi_sync_master_no_tx 0 +show status like 'Rpl_semi_sync_master_yes_tx'; +Variable_name Value +Rpl_semi_sync_master_yes_tx 3 +# +# Start semi-sync replication without SUPER privilege +# +connection slave; +include/stop_slave.inc +reset slave; +connection master; +reset master; +kill query _tid; +set sql_log_bin=0; +grant replication slave on *.* to rpl@127.0.0.1 identified by 'rpl_password'; +flush privileges; +set sql_log_bin=1; +connection slave; +grant replication slave on *.* to rpl@127.0.0.1 identified by 'rpl_password'; +flush privileges; +change master to master_user='rpl',master_password='rpl_password'; +include/start_slave.inc +show status like 'Rpl_semi_sync_slave_status'; +Variable_name Value +Rpl_semi_sync_slave_status ON +connection master; +[ master semi-sync should be ON ] +show status like 'Rpl_semi_sync_master_clients'; +Variable_name Value +Rpl_semi_sync_master_clients 1 +show status like 'Rpl_semi_sync_master_status'; +Variable_name Value +Rpl_semi_sync_master_status ON +show status like 'Rpl_semi_sync_master_no_tx'; +Variable_name Value +Rpl_semi_sync_master_no_tx 0 +show status like 'Rpl_semi_sync_master_yes_tx'; +Variable_name Value +Rpl_semi_sync_master_yes_tx 0 +insert into t1 values (4); +insert into t1 values (5); +[ master semi-sync should be ON ] +show status like 'Rpl_semi_sync_master_clients'; +Variable_name Value +Rpl_semi_sync_master_clients 1 +show status like 'Rpl_semi_sync_master_status'; +Variable_name Value +Rpl_semi_sync_master_status ON +show status like 'Rpl_semi_sync_master_no_tx'; +Variable_name Value +Rpl_semi_sync_master_no_tx 0 +show status like 'Rpl_semi_sync_master_yes_tx'; +Variable_name Value +Rpl_semi_sync_master_yes_tx 2 +# +# Test semi-sync slave connect to non-semi-sync master +# +connection slave; +include/stop_slave.inc +SHOW STATUS LIKE 'Rpl_semi_sync_slave_status'; +Variable_name Value +Rpl_semi_sync_slave_status OFF +connection master; +kill query _tid; +[ Semi-sync status on master should be ON ] +show status like 'Rpl_semi_sync_master_clients'; +Variable_name Value +Rpl_semi_sync_master_clients 0 +show status like 'Rpl_semi_sync_master_status'; +Variable_name Value +Rpl_semi_sync_master_status ON +set global rpl_semi_sync_master_enabled= 0; +connection slave; +SHOW VARIABLES LIKE 'rpl_semi_sync_slave_enabled'; +Variable_name Value +rpl_semi_sync_slave_enabled ON +include/start_slave.inc +connection master; +insert into t1 values (8); +[ master semi-sync clients should be 1, status should be OFF ] +show status like 'Rpl_semi_sync_master_clients'; +Variable_name Value +Rpl_semi_sync_master_clients 1 +show status like 'Rpl_semi_sync_master_status'; +Variable_name Value +Rpl_semi_sync_master_status OFF +connection slave; +show status like 'Rpl_semi_sync_slave_status'; +Variable_name Value +Rpl_semi_sync_slave_status ON +connection slave; +include/stop_slave.inc +connection master; +set global rpl_semi_sync_master_enabled= 0; +connection slave; +SHOW VARIABLES LIKE 'rpl_semi_sync_slave_enabled'; +Variable_name Value +rpl_semi_sync_slave_enabled ON +include/start_slave.inc +connection master; +insert into t1 values (10); +connection slave; +# +# Test non-semi-sync slave connect to semi-sync master +# +connection master; +set global rpl_semi_sync_master_timeout= 5000; +set global rpl_semi_sync_master_enabled= 1; +connection slave; +include/stop_slave.inc +SHOW STATUS LIKE 'Rpl_semi_sync_slave_status'; +Variable_name Value +Rpl_semi_sync_slave_status OFF +[ uninstall semi-sync slave plugin ] +set global rpl_semi_sync_slave_enabled= 0; +[ reinstall semi-sync slave plugin and disable semi-sync ] +SHOW VARIABLES LIKE 'rpl_semi_sync_slave_enabled'; +Variable_name Value +rpl_semi_sync_slave_enabled OFF +SHOW STATUS LIKE 'Rpl_semi_sync_slave_status'; +Variable_name Value +Rpl_semi_sync_slave_status OFF +include/start_slave.inc +SHOW STATUS LIKE 'Rpl_semi_sync_slave_status'; +Variable_name Value +Rpl_semi_sync_slave_status OFF +# +# Clean up +# +connection slave; +include/stop_slave.inc +set global rpl_semi_sync_slave_enabled= 0; +connection master; +set global rpl_semi_sync_master_enabled= 0; +connection slave; +change master to master_user='root',master_password=''; +include/start_slave.inc +connection master; +drop table t1; +connection slave; +connection master; +drop user rpl@127.0.0.1; +flush privileges; +set global rpl_semi_sync_master_timeout= default; +include/rpl_end.inc diff --git a/mysql-test/suite/binlog_encryption/rpl_semi_sync.test b/mysql-test/suite/binlog_encryption/rpl_semi_sync.test new file mode 100644 index 0000000..275e095 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_semi_sync.test @@ -0,0 +1,606 @@ +# +# The test was taken from the rpl suite as is +# + +source include/have_semisync.inc; +source include/not_embedded.inc; +source include/master-slave.inc; + +--enable_connect_log + +let $engine_type= InnoDB; + +# Suppress warnings that might be generated during the test +connection master; +call mtr.add_suppression("Timeout waiting for reply of binlog"); +call mtr.add_suppression("Read semi-sync reply"); +call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT."); +connection slave; +call mtr.add_suppression("Master server does not support semi-sync"); +call mtr.add_suppression("Semi-sync slave .* reply"); +call mtr.add_suppression("Slave SQL.*Request to stop slave SQL Thread received while applying a group that has non-transactional changes; waiting for completion of the group"); +connection master; + +# wait for dying connections (if any) to disappear +let $wait_condition= select count(*) = 0 from information_schema.processlist where command='killed'; +--disable_connect_log +--source include/wait_condition.inc +--enable_connect_log + +# After fix of BUG#45848, semi-sync slave should not create any extra +# connections on master, save the count of connections before start +# semi-sync slave for comparison below. +let $_connections_normal_slave= query_get_value(SHOW STATUS LIKE 'Threads_connected', Value, 1); + +--echo # +--echo # Uninstall semi-sync plugins on master and slave +--echo # +connection slave; +--disable_connect_log +source include/stop_slave.inc; +--enable_connect_log +reset slave; +set global rpl_semi_sync_master_enabled= 0; +set global rpl_semi_sync_slave_enabled= 0; + +connection master; +reset master; +set global rpl_semi_sync_master_enabled= 0; +set global rpl_semi_sync_slave_enabled= 0; + +--echo # +--echo # Main test of semi-sync replication start here +--echo # + +connection master; + +set global rpl_semi_sync_master_timeout= 60000; # 60s + +echo [ default state of semi-sync on master should be OFF ]; +show variables like 'rpl_semi_sync_master_enabled'; + +echo [ enable semi-sync on master ]; +set global rpl_semi_sync_master_enabled = 1; +show variables like 'rpl_semi_sync_master_enabled'; + +echo [ status of semi-sync on master should be ON even without any semi-sync slaves ]; +show status like 'Rpl_semi_sync_master_clients'; +show status like 'Rpl_semi_sync_master_status'; +show status like 'Rpl_semi_sync_master_yes_tx'; + +--echo # +--echo # BUG#45672 Semisync repl: ActiveTranx:insert_tranx_node: transaction node allocation failed +--echo # BUG#45673 Semisynch reports correct operation even if no slave is connected +--echo # + +# BUG#45672 When semi-sync is enabled on master, it would allocate +# transaction node even without semi-sync slave connected, and would +# finally result in transaction node allocation error. +# +# Semi-sync master will pre-allocate 'max_connections' transaction +# nodes, so here we do more than that much transactions to check if it +# will fail or not. +# select @@global.max_connections + 1; +let $i= `select @@global.max_connections + 1`; +disable_query_log; +eval create table t1 (a int) engine=$engine_type; +while ($i) +{ + eval insert into t1 values ($i); + dec $i; +} +drop table t1; +enable_query_log; + +# BUG#45673 +echo [ status of semi-sync on master should be OFF ]; +show status like 'Rpl_semi_sync_master_clients'; +show status like 'Rpl_semi_sync_master_status'; +--replace_result 305 304 +show status like 'Rpl_semi_sync_master_yes_tx'; + +# reset master to make sure the following test will start with a clean environment +reset master; + +connection slave; + +echo [ default state of semi-sync on slave should be OFF ]; +show variables like 'rpl_semi_sync_slave_enabled'; + +echo [ enable semi-sync on slave ]; +set global rpl_semi_sync_slave_enabled = 1; +show variables like 'rpl_semi_sync_slave_enabled'; +--disable_connect_log +source include/start_slave.inc; +--enable_connect_log + +connection master; + +# NOTE: Rpl_semi_sync_master_client will only be updated when +# semi-sync slave has started binlog dump request +let $status_var= Rpl_semi_sync_master_clients; +let $status_var_value= 1; +--disable_connect_log +source include/wait_for_status_var.inc; +--enable_connect_log + +echo [ initial master state after the semi-sync slave connected ]; +show status like 'Rpl_semi_sync_master_clients'; +show status like 'Rpl_semi_sync_master_status'; +show status like 'Rpl_semi_sync_master_no_tx'; +show status like 'Rpl_semi_sync_master_yes_tx'; + +replace_result $engine_type ENGINE_TYPE; +eval create table t1(a int) engine = $engine_type; + +echo [ master state after CREATE TABLE statement ]; +show status like 'Rpl_semi_sync_master_status'; +show status like 'Rpl_semi_sync_master_no_tx'; +show status like 'Rpl_semi_sync_master_yes_tx'; + +# After fix of BUG#45848, semi-sync slave should not create any extra +# connections on master. +let $_connections_semisync_slave= query_get_value(SHOW STATUS LIKE 'Threads_connected', Value, 1); +replace_result $_connections_normal_slave CONNECTIONS_NORMAL_SLAVE $_connections_semisync_slave CONNECTIONS_SEMISYNC_SLAVE; +eval select $_connections_semisync_slave - $_connections_normal_slave as 'Should be 0'; + +echo [ insert records to table ]; +insert t1 values (10); +insert t1 values (9); +insert t1 values (8); +insert t1 values (7); +insert t1 values (6); +insert t1 values (5); +insert t1 values (4); +insert t1 values (3); +insert t1 values (2); +insert t1 values (1); + +echo [ master status after inserts ]; +show status like 'Rpl_semi_sync_master_status'; +show status like 'Rpl_semi_sync_master_no_tx'; +show status like 'Rpl_semi_sync_master_yes_tx'; + +sync_slave_with_master; + +echo [ slave status after replicated inserts ]; +show status like 'Rpl_semi_sync_slave_status'; + +select count(distinct a) from t1; +select min(a) from t1; +select max(a) from t1; + +--echo +--echo # BUG#50157 +--echo # semi-sync replication crashes when replicating a transaction which +--echo # include 'CREATE TEMPORARY TABLE `MyISAM_t` SELECT * FROM `Innodb_t` ; + +connection master; +SET SESSION AUTOCOMMIT= 0; +CREATE TABLE t2(c1 INT) ENGINE=innodb; +sync_slave_with_master; + +connection master; +BEGIN; +--echo +--echo # Even though it is in a transaction, this statement is binlogged into binlog +--echo # file immediately. +--disable_warnings +CREATE TEMPORARY TABLE t3 SELECT c1 FROM t2 where 1=1; +--enable_warnings +--echo +--echo # These statements will not be binlogged until the transaction is committed +INSERT INTO t2 VALUES(11); +INSERT INTO t2 VALUES(22); +COMMIT; + +DROP TABLE t2, t3; +SET SESSION AUTOCOMMIT= 1; +sync_slave_with_master; + + +--echo # +--echo # Test semi-sync master will switch OFF after one transaction +--echo # timeout waiting for slave reply. +--echo # +connection slave; +--disable_connect_log +source include/stop_slave.inc; +--enable_connect_log + +connection master; +set global rpl_semi_sync_master_timeout= 5000; + +# The first semi-sync check should be on because after slave stop, +# there are no transactions on the master. +echo [ master status should be ON ]; +show status like 'Rpl_semi_sync_master_status'; +show status like 'Rpl_semi_sync_master_no_tx'; +--replace_result 305 304 +show status like 'Rpl_semi_sync_master_yes_tx'; +show status like 'Rpl_semi_sync_master_clients'; + +echo [ semi-sync replication of these transactions will fail ]; +insert into t1 values (500); + +# Wait for the semi-sync replication of this transaction to timeout +let $status_var= Rpl_semi_sync_master_status; +let $status_var_value= OFF; +--disable_connect_log +source include/wait_for_status_var.inc; +--enable_connect_log + +# The second semi-sync check should be off because one transaction +# times out during waiting. +echo [ master status should be OFF ]; +show status like 'Rpl_semi_sync_master_status'; +show status like 'Rpl_semi_sync_master_no_tx'; +--replace_result 305 304 +show status like 'Rpl_semi_sync_master_yes_tx'; + +# Semi-sync status on master is now OFF, so all these transactions +# will be replicated asynchronously. +delete from t1 where a=10; +delete from t1 where a=9; +delete from t1 where a=8; +delete from t1 where a=7; +delete from t1 where a=6; +delete from t1 where a=5; +delete from t1 where a=4; +delete from t1 where a=3; +delete from t1 where a=2; +delete from t1 where a=1; + +insert into t1 values (100); + +echo [ master status should be OFF ]; +show status like 'Rpl_semi_sync_master_status'; +show status like 'Rpl_semi_sync_master_no_tx'; +--replace_result 305 304 +show status like 'Rpl_semi_sync_master_yes_tx'; + +--echo # +--echo # Test semi-sync status on master will be ON again when slave catches up +--echo # + +# Save the master position for later use. +save_master_pos; + +connection slave; + +echo [ slave status should be OFF ]; +show status like 'Rpl_semi_sync_slave_status'; +--disable_connect_log +source include/start_slave.inc; +--enable_connect_log +sync_with_master; + +echo [ slave status should be ON ]; +show status like 'Rpl_semi_sync_slave_status'; + +select count(distinct a) from t1; +select min(a) from t1; +select max(a) from t1; + +connection master; + +# The master semi-sync status should be on again after slave catches up. +echo [ master status should be ON again after slave catches up ]; +show status like 'Rpl_semi_sync_master_status'; +show status like 'Rpl_semi_sync_master_no_tx'; +--replace_result 305 304 +show status like 'Rpl_semi_sync_master_yes_tx'; +show status like 'Rpl_semi_sync_master_clients'; + +--echo # +--echo # Test disable/enable master semi-sync on the fly. +--echo # + +drop table t1; +sync_slave_with_master; + +--disable_connect_log +source include/stop_slave.inc; +--enable_connect_log + +--echo # +--echo # Flush status +--echo # +connection master; +echo [ Semi-sync master status variables before FLUSH STATUS ]; +SHOW STATUS LIKE 'Rpl_semi_sync_master_no_tx'; +SHOW STATUS LIKE 'Rpl_semi_sync_master_yes_tx'; +# Do not write the FLUSH STATUS to binlog, to make sure we'll get a +# clean status after this. +FLUSH NO_WRITE_TO_BINLOG STATUS; +echo [ Semi-sync master status variables after FLUSH STATUS ]; +SHOW STATUS LIKE 'Rpl_semi_sync_master_no_tx'; +SHOW STATUS LIKE 'Rpl_semi_sync_master_yes_tx'; + +connection master; + +--disable_connect_log +source include/show_master_logs.inc; +--enable_connect_log +show variables like 'rpl_semi_sync_master_enabled'; + +echo [ disable semi-sync on the fly ]; +set global rpl_semi_sync_master_enabled=0; +show variables like 'rpl_semi_sync_master_enabled'; +show status like 'Rpl_semi_sync_master_status'; + +echo [ enable semi-sync on the fly ]; +set global rpl_semi_sync_master_enabled=1; +show variables like 'rpl_semi_sync_master_enabled'; +show status like 'Rpl_semi_sync_master_status'; + +--echo # +--echo # Test RESET MASTER/SLAVE +--echo # + +connection slave; + +--disable_connect_log +source include/start_slave.inc; +--enable_connect_log + +connection master; + +replace_result $engine_type ENGINE_TYPE; +eval create table t1 (a int) engine = $engine_type; +drop table t1; + +##show status like 'Rpl_semi_sync_master_status'; + +sync_slave_with_master; +--replace_column 2 # +show status like 'Rpl_relay%'; + +echo [ test reset master ]; +connection master; + +reset master; + +show status like 'Rpl_semi_sync_master_status'; +show status like 'Rpl_semi_sync_master_no_tx'; +show status like 'Rpl_semi_sync_master_yes_tx'; + +connection slave; + +--disable_connect_log +source include/stop_slave.inc; +--enable_connect_log +reset slave; + +# Kill the dump thread on master for previous slave connection and +# wait for it to exit +connection master; +let $_tid= `select id from information_schema.processlist where command = 'Binlog Dump' limit 1`; +if ($_tid) +{ + --replace_result $_tid _tid + eval kill query $_tid; + + # After dump thread exit, Rpl_semi_sync_master_clients will be 0 + let $status_var= Rpl_semi_sync_master_clients; + let $status_var_value= 0; +--disable_connect_log + source include/wait_for_status_var.inc; +--enable_connect_log +} + +connection slave; +--disable_connect_log +source include/start_slave.inc; +--enable_connect_log + +connection master; + +# Wait for dump thread to start, Rpl_semi_sync_master_clients will be +# 1 after dump thread started. +let $status_var= Rpl_semi_sync_master_clients; +let $status_var_value= 1; +--disable_connect_log +source include/wait_for_status_var.inc; +--enable_connect_log + +replace_result $engine_type ENGINE_TYPE; +eval create table t1 (a int) engine = $engine_type; +insert into t1 values (1); +insert into t1 values (2), (3); + +sync_slave_with_master; + +select * from t1; + +connection master; + +echo [ master semi-sync status should be ON ]; +show status like 'Rpl_semi_sync_master_status'; +show status like 'Rpl_semi_sync_master_no_tx'; +show status like 'Rpl_semi_sync_master_yes_tx'; + +--echo # +--echo # Start semi-sync replication without SUPER privilege +--echo # +connection slave; +--disable_connect_log +source include/stop_slave.inc; +--enable_connect_log +reset slave; +connection master; +reset master; + +# Kill the dump thread on master for previous slave connection and wait for it to exit +let $_tid= `select id from information_schema.processlist where command = 'Binlog Dump' limit 1`; +if ($_tid) +{ + --replace_result $_tid _tid + eval kill query $_tid; + + # After dump thread exit, Rpl_semi_sync_master_clients will be 0 + let $status_var= Rpl_semi_sync_master_clients; + let $status_var_value= 0; + --disable_connect_log + source include/wait_for_status_var.inc; + --enable_connect_log +} + +# Do not binlog the following statement because it will generate +# different events for ROW and STATEMENT format +set sql_log_bin=0; +grant replication slave on *.* to rpl@127.0.0.1 identified by 'rpl_password'; +flush privileges; +set sql_log_bin=1; +connection slave; +grant replication slave on *.* to rpl@127.0.0.1 identified by 'rpl_password'; +flush privileges; +change master to master_user='rpl',master_password='rpl_password'; +--disable_connect_log +source include/start_slave.inc; +--enable_connect_log +show status like 'Rpl_semi_sync_slave_status'; +connection master; + +# Wait for the semi-sync binlog dump thread to start +let $status_var= Rpl_semi_sync_master_clients; +let $status_var_value= 1; +--disable_connect_log +source include/wait_for_status_var.inc; +--enable_connect_log +echo [ master semi-sync should be ON ]; +show status like 'Rpl_semi_sync_master_clients'; +show status like 'Rpl_semi_sync_master_status'; +show status like 'Rpl_semi_sync_master_no_tx'; +show status like 'Rpl_semi_sync_master_yes_tx'; +insert into t1 values (4); +insert into t1 values (5); +echo [ master semi-sync should be ON ]; +show status like 'Rpl_semi_sync_master_clients'; +show status like 'Rpl_semi_sync_master_status'; +show status like 'Rpl_semi_sync_master_no_tx'; +show status like 'Rpl_semi_sync_master_yes_tx'; + +--echo # +--echo # Test semi-sync slave connect to non-semi-sync master +--echo # + +# Disable semi-sync on master +connection slave; +--disable_connect_log +source include/stop_slave.inc; +--enable_connect_log +SHOW STATUS LIKE 'Rpl_semi_sync_slave_status'; + +connection master; + +# Kill the dump thread on master for previous slave connection and wait for it to exit +let $_tid= `select id from information_schema.processlist where command = 'Binlog Dump' limit 1`; +if ($_tid) +{ + --replace_result $_tid _tid + eval kill query $_tid; + + # After dump thread exit, Rpl_semi_sync_master_clients will be 0 + let $status_var= Rpl_semi_sync_master_clients; + let $status_var_value= 0; + --disable_connect_log + source include/wait_for_status_var.inc; + --enable_connect_log +} + +echo [ Semi-sync status on master should be ON ]; +show status like 'Rpl_semi_sync_master_clients'; +show status like 'Rpl_semi_sync_master_status'; +set global rpl_semi_sync_master_enabled= 0; + +connection slave; +SHOW VARIABLES LIKE 'rpl_semi_sync_slave_enabled'; +--disable_connect_log +source include/start_slave.inc; +--enable_connect_log +connection master; +insert into t1 values (8); +let $status_var= Rpl_semi_sync_master_clients; +let $status_var_value= 1; +--disable_connect_log +source include/wait_for_status_var.inc; +--enable_connect_log +echo [ master semi-sync clients should be 1, status should be OFF ]; +show status like 'Rpl_semi_sync_master_clients'; +show status like 'Rpl_semi_sync_master_status'; +sync_slave_with_master; +show status like 'Rpl_semi_sync_slave_status'; + +# Uninstall semi-sync plugin on master +connection slave; +--disable_connect_log +source include/stop_slave.inc; +--enable_connect_log +connection master; +set global rpl_semi_sync_master_enabled= 0; + +connection slave; +SHOW VARIABLES LIKE 'rpl_semi_sync_slave_enabled'; +--disable_connect_log +source include/start_slave.inc; +--enable_connect_log + +connection master; +insert into t1 values (10); +sync_slave_with_master; + +--echo # +--echo # Test non-semi-sync slave connect to semi-sync master +--echo # + +connection master; +set global rpl_semi_sync_master_timeout= 5000; # 5s +set global rpl_semi_sync_master_enabled= 1; + +connection slave; +--disable_connect_log +source include/stop_slave.inc; +--enable_connect_log +SHOW STATUS LIKE 'Rpl_semi_sync_slave_status'; + +echo [ uninstall semi-sync slave plugin ]; +set global rpl_semi_sync_slave_enabled= 0; + +echo [ reinstall semi-sync slave plugin and disable semi-sync ]; +SHOW VARIABLES LIKE 'rpl_semi_sync_slave_enabled'; +SHOW STATUS LIKE 'Rpl_semi_sync_slave_status'; +--disable_connect_log +source include/start_slave.inc; +--enable_connect_log +SHOW STATUS LIKE 'Rpl_semi_sync_slave_status'; + +--echo # +--echo # Clean up +--echo # + +connection slave; +--disable_connect_log +source include/stop_slave.inc; +--enable_connect_log +set global rpl_semi_sync_slave_enabled= 0; + +connection master; +set global rpl_semi_sync_master_enabled= 0; + +connection slave; +change master to master_user='root',master_password=''; +--disable_connect_log +source include/start_slave.inc; +--enable_connect_log + +connection master; +drop table t1; +sync_slave_with_master; + +connection master; +drop user rpl@127.0.0.1; +flush privileges; +set global rpl_semi_sync_master_timeout= default; +--disable_connect_log +--source include/rpl_end.inc diff --git a/mysql-test/suite/binlog_encryption/rpl_skip_replication.cnf b/mysql-test/suite/binlog_encryption/rpl_skip_replication.cnf new file mode 100644 index 0000000..b8e22e9 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_skip_replication.cnf @@ -0,0 +1,6 @@ +!include my.cnf + +[mysqld.2] +plugin-load-add= @ENV.FILE_KEY_MANAGEMENT_SO +loose-file-key-management-filename=@ENV.MYSQLTEST_VARDIR/std_data/keys.txt +encrypt-binlog diff --git a/mysql-test/suite/binlog_encryption/rpl_skip_replication.result b/mysql-test/suite/binlog_encryption/rpl_skip_replication.result new file mode 100644 index 0000000..ded85f3 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_skip_replication.result @@ -0,0 +1,312 @@ +include/master-slave.inc +[connection master] +connection slave; +CREATE USER 'nonsuperuser'@'127.0.0.1'; +GRANT ALTER,CREATE,DELETE,DROP,EVENT,INSERT,PROCESS,REPLICATION SLAVE, +SELECT,UPDATE ON *.* TO 'nonsuperuser'@'127.0.0.1'; +connect nonpriv, 127.0.0.1, nonsuperuser,, test, $SLAVE_MYPORT,; +connection nonpriv; +SET GLOBAL replicate_events_marked_for_skip=FILTER_ON_MASTER; +ERROR 42000: Access denied; you need (at least one of) the SUPER privilege(s) for this operation +disconnect nonpriv; +connection slave; +DROP USER'nonsuperuser'@'127.0.0.1'; +SELECT @@global.replicate_events_marked_for_skip; +@@global.replicate_events_marked_for_skip +REPLICATE +SET GLOBAL replicate_events_marked_for_skip=FILTER_ON_SLAVE; +ERROR HY000: This operation cannot be performed as you have a running slave ''; run STOP SLAVE '' first +SELECT @@global.replicate_events_marked_for_skip; +@@global.replicate_events_marked_for_skip +REPLICATE +STOP SLAVE; +SET SESSION replicate_events_marked_for_skip=FILTER_ON_MASTER; +ERROR HY000: Variable 'replicate_events_marked_for_skip' is a GLOBAL variable and should be set with SET GLOBAL +SELECT @@global.replicate_events_marked_for_skip; +@@global.replicate_events_marked_for_skip +REPLICATE +SET GLOBAL replicate_events_marked_for_skip=FILTER_ON_MASTER; +SELECT @@global.replicate_events_marked_for_skip; +@@global.replicate_events_marked_for_skip +FILTER_ON_MASTER +START SLAVE; +connection master; +SELECT @@skip_replication; +@@skip_replication +0 +SET GLOBAL skip_replication=1; +ERROR HY000: Variable 'skip_replication' is a SESSION variable and can't be used with SET GLOBAL +SELECT @@skip_replication; +@@skip_replication +0 +CREATE TABLE t1 (a INT PRIMARY KEY, b INT) ENGINE=myisam; +CREATE TABLE t2 (a INT PRIMARY KEY, b INT) ENGINE=innodb; +INSERT INTO t1(a) VALUES (1); +INSERT INTO t2(a) VALUES (1); +SET skip_replication=1; +CREATE TABLE t3 (a INT PRIMARY KEY, b INT) ENGINE=myisam; +INSERT INTO t1(a) VALUES (2); +INSERT INTO t2(a) VALUES (2); +FLUSH NO_WRITE_TO_BINLOG LOGS; +connection slave; +connection slave; +SHOW TABLES; +Tables_in_test +t1 +t2 +SELECT * FROM t1; +a b +1 NULL +SELECT * FROM t2; +a b +1 NULL +connection master; +DROP TABLE t3; +FLUSH NO_WRITE_TO_BINLOG LOGS; +connection slave; +connection slave; +STOP SLAVE; +SET GLOBAL replicate_events_marked_for_skip=FILTER_ON_SLAVE; +START SLAVE; +connection master; +SET skip_replication=1; +CREATE TABLE t3 (a INT PRIMARY KEY, b INT) ENGINE=myisam; +INSERT INTO t1(a) VALUES (3); +INSERT INTO t2(a) VALUES (3); +FLUSH NO_WRITE_TO_BINLOG LOGS; +connection slave; +connection slave; +SHOW TABLES; +Tables_in_test +t1 +t2 +SELECT * FROM t1; +a b +1 NULL +SELECT * FROM t2; +a b +1 NULL +connection master; +DROP TABLE t3; +FLUSH NO_WRITE_TO_BINLOG LOGS; +connection slave; +connection slave; +STOP SLAVE; +SET GLOBAL replicate_events_marked_for_skip=REPLICATE; +START SLAVE; +connection master; +SET skip_replication=1; +CREATE TABLE t3 (a INT PRIMARY KEY, b INT) ENGINE=myisam; +INSERT INTO t3(a) VALUES(2); +connection slave; +connection slave; +SELECT * FROM t3; +a b +2 NULL +connection master; +DROP TABLE t3; +TRUNCATE t1; +connection slave; +connection slave; +RESET MASTER; +connection master; +SET skip_replication=0; +INSERT INTO t1 VALUES (1,0); +SET skip_replication=1; +INSERT INTO t1 VALUES (2,0); +SET skip_replication=0; +INSERT INTO t1 VALUES (3,0); +connection slave; +connection slave; +SELECT * FROM t1 ORDER by a; +a b +1 0 +2 0 +3 0 +STOP SLAVE; +SET GLOBAL replicate_events_marked_for_skip=FILTER_ON_MASTER; +connection master; +TRUNCATE t1; +SELECT * FROM t1 ORDER by a; +a b +1 0 +2 0 +3 0 +connection slave; +START SLAVE; +connection master; +connection slave; +connection slave; +SELECT * FROM t1 ORDER by a; +a b +1 0 +3 0 +connection master; +TRUNCATE t1; +connection slave; +connection slave; +STOP SLAVE; +SET GLOBAL sql_slave_skip_counter=6; +SET GLOBAL replicate_events_marked_for_skip=FILTER_ON_SLAVE; +START SLAVE; +connection master; +SET @old_binlog_format= @@binlog_format; +SET binlog_format= statement; +SET skip_replication=0; +INSERT INTO t1 VALUES (1,5); +SET skip_replication=1; +INSERT INTO t1 VALUES (2,5); +SET skip_replication=0; +INSERT INTO t1 VALUES (3,5); +INSERT INTO t1 VALUES (4,5); +SET binlog_format= @old_binlog_format; +connection slave; +connection slave; +SELECT * FROM t1; +a b +4 5 +connection slave; +include/stop_slave.inc +SET @old_slave_binlog_format= @@global.binlog_format; +SET GLOBAL binlog_format= row; +include/start_slave.inc +connection master; +TRUNCATE t1; +SET @old_binlog_format= @@binlog_format; +SET binlog_format= row; +BINLOG 'wlZOTw8BAAAA8QAAAPUAAAAAAAQANS41LjIxLU1hcmlhREItZGVidWctbG9nAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAEzgNAAgAEgAEBAQEEgAA2QAEGggAAAAICAgCAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAA371saA=='; +BINLOG 'wlZOTxMBAAAAKgAAAGMBAAAAgCkAAAAAAAEABHRlc3QAAnQxAAIDAwAC +wlZOTxcBAAAAJgAAAIkBAAAAgCkAAAAAAAEAAv/8AQAAAAgAAAA='; +BINLOG 'wlZOTxMBAAAAKgAAADwCAAAAACkAAAAAAAEABHRlc3QAAnQxAAIDAwAC +wlZOTxcBAAAAJgAAAGICAAAAACkAAAAAAAEAAv/8AgAAAAgAAAA='; +SET binlog_format= @old_binlog_format; +SELECT * FROM t1 ORDER BY a; +a b +1 8 +2 8 +connection slave; +connection slave; +SELECT * FROM t1 ORDER by a; +a b +2 8 +include/stop_slave.inc +SET GLOBAL binlog_format= @old_slave_binlog_format; +include/start_slave.inc +connection master; +SET skip_replication=0; +BEGIN; +SET skip_replication=0; +ERROR HY000: Cannot modify @@session.skip_replication inside a transaction +SET skip_replication=1; +ERROR HY000: Cannot modify @@session.skip_replication inside a transaction +ROLLBACK; +SET skip_replication=1; +BEGIN; +SET skip_replication=0; +ERROR HY000: Cannot modify @@session.skip_replication inside a transaction +SET skip_replication=1; +ERROR HY000: Cannot modify @@session.skip_replication inside a transaction +COMMIT; +SET autocommit=0; +INSERT INTO t2(a) VALUES(100); +SET skip_replication=1; +ERROR HY000: Cannot modify @@session.skip_replication inside a transaction +ROLLBACK; +SET autocommit=1; +SET skip_replication=1; +CREATE FUNCTION foo (x INT) RETURNS INT BEGIN SET SESSION skip_replication=x; RETURN x; END| +CREATE PROCEDURE bar(x INT) BEGIN SET SESSION skip_replication=x; END| +CREATE FUNCTION baz (x INT) RETURNS INT BEGIN CALL bar(x); RETURN x; END| +SELECT foo(0); +ERROR HY000: Cannot modify @@session.skip_replication inside a stored function or trigger +SELECT baz(0); +ERROR HY000: Cannot modify @@session.skip_replication inside a stored function or trigger +SET @a= foo(1); +ERROR HY000: Cannot modify @@session.skip_replication inside a stored function or trigger +SET @a= baz(1); +ERROR HY000: Cannot modify @@session.skip_replication inside a stored function or trigger +UPDATE t2 SET b=foo(0); +ERROR HY000: Cannot modify @@session.skip_replication inside a stored function or trigger +UPDATE t2 SET b=baz(0); +ERROR HY000: Cannot modify @@session.skip_replication inside a stored function or trigger +INSERT INTO t1 VALUES (101, foo(1)); +ERROR HY000: Cannot modify @@session.skip_replication inside a stored function or trigger +INSERT INTO t1 VALUES (101, baz(0)); +ERROR HY000: Cannot modify @@session.skip_replication inside a stored function or trigger +SELECT @@skip_replication; +@@skip_replication +1 +CALL bar(0); +SELECT @@skip_replication; +@@skip_replication +0 +CALL bar(1); +SELECT @@skip_replication; +@@skip_replication +1 +DROP FUNCTION foo; +DROP PROCEDURE bar; +DROP FUNCTION baz; +connection master; +SET skip_replication= 0; +TRUNCATE t1; +connection slave; +connection slave; +STOP SLAVE; +SET GLOBAL replicate_events_marked_for_skip=FILTER_ON_MASTER; +START SLAVE IO_THREAD; +connection master; +SET skip_replication= 1; +INSERT INTO t1(a) VALUES (1); +SET skip_replication= 0; +INSERT INTO t1(a) VALUES (2); +include/save_master_pos.inc +connection slave; +include/sync_io_with_master.inc +STOP SLAVE IO_THREAD; +SET GLOBAL replicate_events_marked_for_skip=REPLICATE; +START SLAVE; +connection master; +connection slave; +connection slave; +SELECT * FROM t1; +a b +2 NULL +connection master; +SET skip_replication= 0; +TRUNCATE t1; +connection slave; +connection slave; +STOP SLAVE; +SET GLOBAL replicate_events_marked_for_skip=FILTER_ON_SLAVE; +START SLAVE IO_THREAD; +connection master; +SET skip_replication= 1; +INSERT INTO t1(a) VALUES (1); +SET skip_replication= 0; +INSERT INTO t1(a) VALUES (2); +include/save_master_pos.inc +connection slave; +include/sync_io_with_master.inc +STOP SLAVE IO_THREAD; +SET GLOBAL replicate_events_marked_for_skip=REPLICATE; +START SLAVE; +connection master; +connection slave; +connection slave; +SELECT * FROM t1 ORDER BY a; +a b +1 NULL +2 NULL +connection master; +SET skip_replication=0; +DROP TABLE t1,t2; +connection slave; +STOP SLAVE; +SET GLOBAL replicate_events_marked_for_skip=REPLICATE; +START SLAVE; +include/rpl_end.inc diff --git a/mysql-test/suite/binlog_encryption/rpl_skip_replication.test b/mysql-test/suite/binlog_encryption/rpl_skip_replication.test new file mode 100644 index 0000000..84672f1 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_skip_replication.test @@ -0,0 +1,401 @@ +# +# The test was taken from the rpl suite. +# Since mysqlbinlog cannot read encrypted logs directly, it was +# switched to read-from-remote-server mode. +# The test is run with master and slave binlogs encrypted +# + +--source include/master-slave.inc +--enable_connect_log + +connection slave; +# Test that SUPER is required to change @@replicate_events_marked_for_skip. +CREATE USER 'nonsuperuser'@'127.0.0.1'; +GRANT ALTER,CREATE,DELETE,DROP,EVENT,INSERT,PROCESS,REPLICATION SLAVE, + SELECT,UPDATE ON *.* TO 'nonsuperuser'@'127.0.0.1'; +connect(nonpriv, 127.0.0.1, nonsuperuser,, test, $SLAVE_MYPORT,); +connection nonpriv; +--error ER_SPECIFIC_ACCESS_DENIED_ERROR +SET GLOBAL replicate_events_marked_for_skip=FILTER_ON_MASTER; +disconnect nonpriv; +connection slave; +DROP USER'nonsuperuser'@'127.0.0.1'; + +SELECT @@global.replicate_events_marked_for_skip; +--error ER_SLAVE_MUST_STOP +SET GLOBAL replicate_events_marked_for_skip=FILTER_ON_SLAVE; +SELECT @@global.replicate_events_marked_for_skip; +STOP SLAVE; +--error ER_GLOBAL_VARIABLE +SET SESSION replicate_events_marked_for_skip=FILTER_ON_MASTER; +SELECT @@global.replicate_events_marked_for_skip; +SET GLOBAL replicate_events_marked_for_skip=FILTER_ON_MASTER; +SELECT @@global.replicate_events_marked_for_skip; +START SLAVE; + +connection master; +SELECT @@skip_replication; +--error ER_LOCAL_VARIABLE +SET GLOBAL skip_replication=1; +SELECT @@skip_replication; + +CREATE TABLE t1 (a INT PRIMARY KEY, b INT) ENGINE=myisam; +CREATE TABLE t2 (a INT PRIMARY KEY, b INT) ENGINE=innodb; +INSERT INTO t1(a) VALUES (1); +INSERT INTO t2(a) VALUES (1); + + +# Test that master-side filtering works. +SET skip_replication=1; + +CREATE TABLE t3 (a INT PRIMARY KEY, b INT) ENGINE=myisam; +INSERT INTO t1(a) VALUES (2); +INSERT INTO t2(a) VALUES (2); + +# Inject a rotate event in the binlog stream sent to slave (otherwise we will +# fail sync_slave_with_master as the last event on the master is not present +# on the slave). +FLUSH NO_WRITE_TO_BINLOG LOGS; + +sync_slave_with_master; +connection slave; +SHOW TABLES; +SELECT * FROM t1; +SELECT * FROM t2; + +connection master; +DROP TABLE t3; + +FLUSH NO_WRITE_TO_BINLOG LOGS; +sync_slave_with_master; + + +# Test that slave-side filtering works. +connection slave; +STOP SLAVE; +SET GLOBAL replicate_events_marked_for_skip=FILTER_ON_SLAVE; +START SLAVE; + +connection master; +SET skip_replication=1; +CREATE TABLE t3 (a INT PRIMARY KEY, b INT) ENGINE=myisam; +INSERT INTO t1(a) VALUES (3); +INSERT INTO t2(a) VALUES (3); + +# Inject a rotate event in the binlog stream sent to slave (otherwise we will +# fail sync_slave_with_master as the last event on the master is not present +# on the slave). +FLUSH NO_WRITE_TO_BINLOG LOGS; + +sync_slave_with_master; +connection slave; +SHOW TABLES; +SELECT * FROM t1; +SELECT * FROM t2; + +connection master; +DROP TABLE t3; + +FLUSH NO_WRITE_TO_BINLOG LOGS; +sync_slave_with_master; +connection slave; +STOP SLAVE; +SET GLOBAL replicate_events_marked_for_skip=REPLICATE; +START SLAVE; + + +# Test that events with @@skip_replication=1 are not filtered when filtering is +# not set on slave. +connection master; +SET skip_replication=1; +CREATE TABLE t3 (a INT PRIMARY KEY, b INT) ENGINE=myisam; +INSERT INTO t3(a) VALUES(2); +sync_slave_with_master; +connection slave; +SELECT * FROM t3; +connection master; +DROP TABLE t3; + +# +# Test that the slave will preserve the @@skip_replication flag in its +# own binlog. +# + +TRUNCATE t1; +sync_slave_with_master; +connection slave; +RESET MASTER; + +connection master; +SET skip_replication=0; +INSERT INTO t1 VALUES (1,0); +SET skip_replication=1; +INSERT INTO t1 VALUES (2,0); +SET skip_replication=0; +INSERT INTO t1 VALUES (3,0); + +sync_slave_with_master; +connection slave; +# Since slave has @@replicate_events_marked_for_skip=REPLICATE, it should have +# applied all events. +SELECT * FROM t1 ORDER by a; + +STOP SLAVE; +SET GLOBAL replicate_events_marked_for_skip=FILTER_ON_MASTER; +let $SLAVE_DATADIR= `select @@datadir`; + +connection master; +TRUNCATE t1; + +# Now apply the slave binlog to the master, to check that both the slave +# and mysqlbinlog will preserve the @@skip_replication flag. +--exec $MYSQL_BINLOG --read-from-remote-server --protocol=tcp --host=127.0.0.1 --port=$SLAVE_MYPORT -uroot slave-bin.000001 > $MYSQLTEST_VARDIR/tmp/rpl_skip_replication.binlog +--exec $MYSQL test < $MYSQLTEST_VARDIR/tmp/rpl_skip_replication.binlog + +# The master should have all three events. +SELECT * FROM t1 ORDER by a; + +# The slave should be missing event 2, which is marked with the +# @@skip_replication flag. + +connection slave; +START SLAVE; + +connection master; +sync_slave_with_master; + +connection slave; +SELECT * FROM t1 ORDER by a; + +# +# Test that @@sql_slave_skip_counter does not count skipped @@skip_replication +# events. +# + +connection master; +TRUNCATE t1; + +sync_slave_with_master; +connection slave; +STOP SLAVE; +# We will skip two INSERTs (in addition to any skipped due to +# @@skip_replication). Since from 5.5 every statement is wrapped in +# BEGIN ... END, we need to skip 6 events for this. +SET GLOBAL sql_slave_skip_counter=6; +SET GLOBAL replicate_events_marked_for_skip=FILTER_ON_SLAVE; +START SLAVE; + +connection master; +# Need to fix @@binlog_format to get consistent event count. +SET @old_binlog_format= @@binlog_format; +SET binlog_format= statement; +SET skip_replication=0; +INSERT INTO t1 VALUES (1,5); +SET skip_replication=1; +INSERT INTO t1 VALUES (2,5); +SET skip_replication=0; +INSERT INTO t1 VALUES (3,5); +INSERT INTO t1 VALUES (4,5); +SET binlog_format= @old_binlog_format; + +sync_slave_with_master; +connection slave; + +# The slave should have skipped the first three inserts (number 1 and 3 due +# to @@sql_slave_skip_counter=2, number 2 due to +# @@replicate_events_marked_for_skip=FILTER_ON_SLAVE). So only number 4 +# should be left. +SELECT * FROM t1; + + +# +# Check that BINLOG statement preserves the @@skip_replication flag. +# +connection slave; +# Need row @@binlog_format for BINLOG statements containing row events. +--disable_connect_log +--source include/stop_slave.inc +--enable_connect_log +SET @old_slave_binlog_format= @@global.binlog_format; +SET GLOBAL binlog_format= row; +--disable_connect_log +--source include/start_slave.inc +--enable_connect_log + +connection master; +TRUNCATE t1; + +SET @old_binlog_format= @@binlog_format; +SET binlog_format= row; +# Format description log event. +BINLOG 'wlZOTw8BAAAA8QAAAPUAAAAAAAQANS41LjIxLU1hcmlhREItZGVidWctbG9nAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAEzgNAAgAEgAEBAQEEgAA2QAEGggAAAAICAgCAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAA371saA=='; +# INSERT INTO t1 VALUES (1,8) # with @@skip_replication=1 +BINLOG 'wlZOTxMBAAAAKgAAAGMBAAAAgCkAAAAAAAEABHRlc3QAAnQxAAIDAwAC +wlZOTxcBAAAAJgAAAIkBAAAAgCkAAAAAAAEAAv/8AQAAAAgAAAA='; +# INSERT INTO t1 VALUES (2,8) # with @@skip_replication=0 +BINLOG 'wlZOTxMBAAAAKgAAADwCAAAAACkAAAAAAAEABHRlc3QAAnQxAAIDAwAC +wlZOTxcBAAAAJgAAAGICAAAAACkAAAAAAAEAAv/8AgAAAAgAAAA='; +SET binlog_format= @old_binlog_format; + +SELECT * FROM t1 ORDER BY a; +sync_slave_with_master; +connection slave; +# Slave should have only the second insert, the first should be ignored due to +# the @@skip_replication flag. +SELECT * FROM t1 ORDER by a; + +--disable_connect_log +--source include/stop_slave.inc +--enable_connect_log +SET GLOBAL binlog_format= @old_slave_binlog_format; +--disable_connect_log +--source include/start_slave.inc +--enable_connect_log + + +# Test that it is not possible to change @@skip_replication inside a +# transaction or statement, thereby replicating only parts of statements +# or transactions. +connection master; +SET skip_replication=0; + +BEGIN; +--error ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_SKIP_REPLICATION +SET skip_replication=0; +--error ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_SKIP_REPLICATION +SET skip_replication=1; +ROLLBACK; +SET skip_replication=1; +BEGIN; +--error ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_SKIP_REPLICATION +SET skip_replication=0; +--error ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_SKIP_REPLICATION +SET skip_replication=1; +COMMIT; +SET autocommit=0; +INSERT INTO t2(a) VALUES(100); +--error ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_SKIP_REPLICATION +SET skip_replication=1; +ROLLBACK; +SET autocommit=1; + +SET skip_replication=1; +--delimiter | +CREATE FUNCTION foo (x INT) RETURNS INT BEGIN SET SESSION skip_replication=x; RETURN x; END| +CREATE PROCEDURE bar(x INT) BEGIN SET SESSION skip_replication=x; END| +CREATE FUNCTION baz (x INT) RETURNS INT BEGIN CALL bar(x); RETURN x; END| +--delimiter ; +--error ER_STORED_FUNCTION_PREVENTS_SWITCH_SKIP_REPLICATION +SELECT foo(0); +--error ER_STORED_FUNCTION_PREVENTS_SWITCH_SKIP_REPLICATION +SELECT baz(0); +--error ER_STORED_FUNCTION_PREVENTS_SWITCH_SKIP_REPLICATION +SET @a= foo(1); +--error ER_STORED_FUNCTION_PREVENTS_SWITCH_SKIP_REPLICATION +SET @a= baz(1); +--error ER_STORED_FUNCTION_PREVENTS_SWITCH_SKIP_REPLICATION +UPDATE t2 SET b=foo(0); +--error ER_STORED_FUNCTION_PREVENTS_SWITCH_SKIP_REPLICATION +UPDATE t2 SET b=baz(0); +--error ER_STORED_FUNCTION_PREVENTS_SWITCH_SKIP_REPLICATION +INSERT INTO t1 VALUES (101, foo(1)); +--error ER_STORED_FUNCTION_PREVENTS_SWITCH_SKIP_REPLICATION +INSERT INTO t1 VALUES (101, baz(0)); +SELECT @@skip_replication; +CALL bar(0); +SELECT @@skip_replication; +CALL bar(1); +SELECT @@skip_replication; +DROP FUNCTION foo; +DROP PROCEDURE bar; +DROP FUNCTION baz; + + +# Test that master-side filtering happens on the master side, and that +# slave-side filtering happens on the slave. + +# First test that events do not reach the slave when master-side filtering +# is configured. Do this by replicating first with only the IO thread running +# and master-side filtering; then change to no filtering and start the SQL +# thread. This should still skip the events, as master-side filtering +# means the events never reached the slave. +connection master; +SET skip_replication= 0; +TRUNCATE t1; +sync_slave_with_master; +connection slave; +STOP SLAVE; +SET GLOBAL replicate_events_marked_for_skip=FILTER_ON_MASTER; +START SLAVE IO_THREAD; +connection master; +SET skip_replication= 1; +INSERT INTO t1(a) VALUES (1); +SET skip_replication= 0; +INSERT INTO t1(a) VALUES (2); +--disable_connect_log +--source include/save_master_pos.inc +--enable_connect_log +connection slave; +--disable_connect_log +--source include/sync_io_with_master.inc +--enable_connect_log +STOP SLAVE IO_THREAD; +SET GLOBAL replicate_events_marked_for_skip=REPLICATE; +START SLAVE; +connection master; +sync_slave_with_master; +connection slave; +# Now only the second insert of (2) should be visible, as the first was +# filtered on the master, so even though the SQL thread ran without skipping +# events, it will never see the event in the first place. +SELECT * FROM t1; + +# Now tests that when slave-side filtering is configured, events _do_ reach +# the slave. +connection master; +SET skip_replication= 0; +TRUNCATE t1; +sync_slave_with_master; +connection slave; +STOP SLAVE; +SET GLOBAL replicate_events_marked_for_skip=FILTER_ON_SLAVE; +START SLAVE IO_THREAD; +connection master; +SET skip_replication= 1; +INSERT INTO t1(a) VALUES (1); +SET skip_replication= 0; +INSERT INTO t1(a) VALUES (2); +--disable_connect_log +--source include/save_master_pos.inc +--enable_connect_log +connection slave; +--disable_connect_log +--source include/sync_io_with_master.inc +--enable_connect_log +STOP SLAVE IO_THREAD; +SET GLOBAL replicate_events_marked_for_skip=REPLICATE; +START SLAVE; +connection master; +sync_slave_with_master; +connection slave; +# Now both inserts should be visible. Since filtering was configured to be +# slave-side, the event is in the relay log, and when the SQL thread ran we +# had disabled filtering again. +SELECT * FROM t1 ORDER BY a; + + +# Clean up. +connection master; +SET skip_replication=0; +DROP TABLE t1,t2; +connection slave; +STOP SLAVE; +SET GLOBAL replicate_events_marked_for_skip=REPLICATE; +START SLAVE; + +--disable_connect_log +--source include/rpl_end.inc diff --git a/mysql-test/suite/binlog_encryption/rpl_special_charset.opt b/mysql-test/suite/binlog_encryption/rpl_special_charset.opt new file mode 100644 index 0000000..b071fb2 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_special_charset.opt @@ -0,0 +1 @@ +--character-set-server=utf16 diff --git a/mysql-test/suite/binlog_encryption/rpl_special_charset.result b/mysql-test/suite/binlog_encryption/rpl_special_charset.result new file mode 100644 index 0000000..218ced9 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_special_charset.result @@ -0,0 +1,10 @@ +include/master-slave.inc +[connection master] +call mtr.add_suppression("Cannot use utf16 as character_set_client"); +CREATE TABLE t1(i VARCHAR(20)); +INSERT INTO t1 VALUES (0xFFFF); +connection slave; +include/diff_tables.inc [master:t1, slave:t1] +connection master; +DROP TABLE t1; +include/rpl_end.inc diff --git a/mysql-test/suite/binlog_encryption/rpl_special_charset.test b/mysql-test/suite/binlog_encryption/rpl_special_charset.test new file mode 100644 index 0000000..9ad630d --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_special_charset.test @@ -0,0 +1,35 @@ +# +# The test was taken from the rpl suite as is +# + +################################################################################ +# Bug#19855907 IO THREAD AUTHENTICATION ISSUE WITH SOME CHARACTER SETS +# Problem: IO thread fails to connect to master if servers are configured with +# special character sets like utf16, utf32, ucs2. +# +# Analysis: MySQL server does not support few special character sets like +# utf16,utf32 and ucs2 as "client's character set"(eg: utf16,utf32, ucs2). +# When IO thread is trying to connect to Master, it sets server's character +# set as client's character set. When Slave server is started with these +# special character sets, IO thread (a connection to Master) fails because +# of the above said reason. +# +# Fix: If server's character set is not supported as client's character set, +# then set default's client character set(latin1) as client's character set. +############################################################################### +--source include/master-slave.inc +--enable_connect_log + +call mtr.add_suppression("Cannot use utf16 as character_set_client"); +CREATE TABLE t1(i VARCHAR(20)); +INSERT INTO t1 VALUES (0xFFFF); +--sync_slave_with_master +--let diff_tables=master:t1, slave:t1 +--disable_connect_log +--source include/diff_tables.inc +--enable_connect_log +# Cleanup +--connection master +DROP TABLE t1; +--disable_connect_log +--source include/rpl_end.inc diff --git a/mysql-test/suite/binlog_encryption/rpl_sporadic_master-master.opt b/mysql-test/suite/binlog_encryption/rpl_sporadic_master-master.opt new file mode 100644 index 0000000..5f038b6 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_sporadic_master-master.opt @@ -0,0 +1 @@ +--debug-sporadic-binlog-dump-fail --debug-max-binlog-dump-events=2 diff --git a/mysql-test/suite/binlog_encryption/rpl_sporadic_master.result b/mysql-test/suite/binlog_encryption/rpl_sporadic_master.result new file mode 100644 index 0000000..32ae637 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_sporadic_master.result @@ -0,0 +1,28 @@ +include/master-slave.inc +[connection master] +create table t2(n int); +create table t1(n int not null auto_increment primary key); +insert into t1 values (NULL),(NULL); +truncate table t1; +insert into t1 values (4),(NULL); +connection slave; +include/stop_slave.inc +include/start_slave.inc +connection master; +insert into t1 values (NULL),(NULL); +flush logs; +truncate table t1; +insert into t1 values (10),(NULL),(NULL),(NULL),(NULL),(NULL); +connection slave; +select * from t1 ORDER BY n; +n +10 +11 +12 +13 +14 +15 +connection master; +drop table t1,t2; +connection slave; +include/rpl_end.inc diff --git a/mysql-test/suite/binlog_encryption/rpl_sporadic_master.test b/mysql-test/suite/binlog_encryption/rpl_sporadic_master.test new file mode 100644 index 0000000..e6c14f8 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_sporadic_master.test @@ -0,0 +1,34 @@ +# +# The test was taken from the rpl suite as is +# + +# test to see if replication can continue when master sporadically fails on +# COM_BINLOG_DUMP and additionally limits the number of events per dump + +source include/master-slave.inc; +--enable_connect_log + +create table t2(n int); +create table t1(n int not null auto_increment primary key); +insert into t1 values (NULL),(NULL); +truncate table t1; +# We have to use 4 in the following to make this test work with all table types +insert into t1 values (4),(NULL); +sync_slave_with_master; +--disable_connect_log +--source include/stop_slave.inc +--source include/start_slave.inc +--enable_connect_log +connection master; +insert into t1 values (NULL),(NULL); +flush logs; +truncate table t1; +insert into t1 values (10),(NULL),(NULL),(NULL),(NULL),(NULL); +sync_slave_with_master; +select * from t1 ORDER BY n; +connection master; +drop table t1,t2; +sync_slave_with_master; + +--disable_connect_log +--source include/rpl_end.inc diff --git a/mysql-test/suite/binlog_encryption/rpl_ssl.result b/mysql-test/suite/binlog_encryption/rpl_ssl.result new file mode 100644 index 0000000..0b3a6cd --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_ssl.result @@ -0,0 +1,55 @@ +include/master-slave.inc +[connection master] +connection master; +create user replssl@localhost; +grant replication slave on *.* to replssl@localhost require ssl; +create table t1 (t int auto_increment, KEY(t)); +connection slave; +stop slave; +change master to +master_user='replssl', +master_password='', +master_ssl=1, +master_ssl_ca ='MYSQL_TEST_DIR/std_data/cacert.pem', +master_ssl_cert='MYSQL_TEST_DIR/std_data/client-cert.pem', +master_ssl_key='MYSQL_TEST_DIR/std_data/client-key.pem'; +start slave; +connection master; +insert into t1 values(1); +connection slave; +select * from t1; +t +1 +Master_SSL_Allowed = 'Yes' +Master_SSL_CA_Path = '' +Master_SSL_CA_File = 'MYSQL_TEST_DIR/std_data/cacert.pem' +Master_SSL_Cert = 'MYSQL_TEST_DIR/std_data/client-cert.pem' +Master_SSL_Key = 'MYSQL_TEST_DIR/std_data/client-key.pem' +include/check_slave_is_running.inc +STOP SLAVE; +select * from t1; +t +1 +connection master; +insert into t1 values (NULL); +connection slave; +include/wait_for_slave_to_start.inc +Master_SSL_Allowed = 'Yes' +Master_SSL_CA_Path = '' +Master_SSL_CA_File = 'MYSQL_TEST_DIR/std_data/cacert.pem' +Master_SSL_Cert = 'MYSQL_TEST_DIR/std_data/client-cert.pem' +Master_SSL_Key = 'MYSQL_TEST_DIR/std_data/client-key.pem' +include/check_slave_is_running.inc +connection master; +drop user replssl@localhost; +drop table t1; +connection slave; +include/stop_slave.inc +CHANGE MASTER TO +master_user = 'root', +master_ssl = 0, +master_ssl_ca = '', +master_ssl_cert = '', +master_ssl_key = ''; +End of 5.0 tests +include/rpl_end.inc diff --git a/mysql-test/suite/binlog_encryption/rpl_ssl.test b/mysql-test/suite/binlog_encryption/rpl_ssl.test new file mode 100644 index 0000000..ed39045 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_ssl.test @@ -0,0 +1,126 @@ +# +# The test was taken from the rpl suite as is +# + +--enable_connect_log + +--disable_connect_log +source include/have_ssl_communication.inc; +source include/master-slave.inc; +--enable_connect_log + +# create a user for replication that requires ssl encryption +connection master; +create user replssl@localhost; +grant replication slave on *.* to replssl@localhost require ssl; +create table t1 (t int auto_increment, KEY(t)); + +sync_slave_with_master; + +# Set slave to use SSL for connection to master +stop slave; +--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR +eval change master to + master_user='replssl', + master_password='', + master_ssl=1, + master_ssl_ca ='$MYSQL_TEST_DIR/std_data/cacert.pem', + master_ssl_cert='$MYSQL_TEST_DIR/std_data/client-cert.pem', + master_ssl_key='$MYSQL_TEST_DIR/std_data/client-key.pem'; +start slave; + +# Switch to master and insert one record, then sync it to slave +connection master; +insert into t1 values(1); +sync_slave_with_master; + +# The record should now be on slave +select * from t1; + +# The slave is synced and waiting/reading from master +# SHOW SLAVE STATUS will show "Waiting for master to send event" +let $status_items= Master_SSL_Allowed, Master_SSL_CA_Path, Master_SSL_CA_File, Master_SSL_Cert, Master_SSL_Key; +--disable_connect_log +source include/show_slave_status.inc; +source include/check_slave_is_running.inc; +--enable_connect_log + +# Stop the slave, as reported in bug#21871 it would hang +STOP SLAVE; + +select * from t1; + +# Do the same thing a number of times +disable_query_log; +disable_result_log; +# 2007-11-27 mats Bug #32756 Starting and stopping the slave in a loop can lose rows +# After discussions with Engineering, I'm disabling this part of the test to avoid it causing +# red trees. +disable_parsing; +let $i= 100; +while ($i) +{ + start slave; + connection master; + insert into t1 values (NULL); + select * from t1; # Some variance + connection slave; + select * from t1; # Some variance + stop slave; + dec $i; +} +enable_parsing; +START SLAVE; +enable_query_log; +enable_result_log; +connection master; +# INSERT one more record to make sure +# the sync has something to do +insert into t1 values (NULL); +let $master_count= `select count(*) from t1`; + +sync_slave_with_master; +--disable_connect_log +--source include/wait_for_slave_to_start.inc +source include/show_slave_status.inc; +source include/check_slave_is_running.inc; +--enable_connect_log + +let $slave_count= `select count(*) from t1`; + +if ($slave_count != $master_count) +{ + echo master and slave differed in number of rows; + echo master: $master_count; + echo slave: $slave_count; + + connection master; + echo === master ===; + select count(*) t1; + select * from t1; + connection slave; + echo === slave ===; + select count(*) t1; + select * from t1; + query_vertical show slave status; +} + +connection master; +drop user replssl@localhost; +drop table t1; +sync_slave_with_master; + +--disable_connect_log +--source include/stop_slave.inc +--enable_connect_log +CHANGE MASTER TO + master_user = 'root', + master_ssl = 0, + master_ssl_ca = '', + master_ssl_cert = '', + master_ssl_key = ''; + +--echo End of 5.0 tests +--let $rpl_only_running_threads= 1 +--disable_connect_log +--source include/rpl_end.inc diff --git a/mysql-test/suite/binlog_encryption/rpl_stm_relay_ign_space-slave.opt b/mysql-test/suite/binlog_encryption/rpl_stm_relay_ign_space-slave.opt new file mode 100644 index 0000000..f780540 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_stm_relay_ign_space-slave.opt @@ -0,0 +1 @@ +--relay-log-space-limit=8192 --relay-log-purge --max-relay-log-size=4096 diff --git a/mysql-test/suite/binlog_encryption/rpl_stm_relay_ign_space.result b/mysql-test/suite/binlog_encryption/rpl_stm_relay_ign_space.result new file mode 100644 index 0000000..3113eec --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_stm_relay_ign_space.result @@ -0,0 +1,6 @@ +include/master-slave.inc +[connection master] +include/assert.inc [Assert that relay log space is close to the limit] +include/diff_tables.inc [master:test.t1,slave:test.t1] +connection slave; +include/rpl_end.inc diff --git a/mysql-test/suite/binlog_encryption/rpl_stm_relay_ign_space.test b/mysql-test/suite/binlog_encryption/rpl_stm_relay_ign_space.test new file mode 100644 index 0000000..164577b --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_stm_relay_ign_space.test @@ -0,0 +1,117 @@ +# +# The test was taken from the the rpl suite as is +# + +--enable_connect_log + +# +# BUG#12400313 / BUG#64503 test case +# +# +# Description +# ----------- +# +# This test case starts the slave server with: +# --relay-log-space-limit=8192 --relay-log-purge --max-relay-log-size=4096 +# +# Then it issues some queries that will cause the slave to reach +# relay-log-space-limit. We lock the table so that the SQL thread is +# not able to purge the log and then we issue some more statements. +# +# The purpose is to show that the IO thread will honor the limits +# while the SQL thread is not able to purge the relay logs, which did +# not happen before this patch. In addition we assert that while +# ignoring the limit (SQL thread needs to rotate before purging), the +# IO thread does not do it in an uncontrolled manner. + +--disable_connect_log +--source include/have_binlog_format_statement.inc +--source include/master-slave.inc +--enable_connect_log + +--disable_query_log +CREATE TABLE t1 (c1 TEXT) engine=InnoDB; + +INSERT INTO t1 VALUES ('xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxx'); +INSERT INTO t1 VALUES ('xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxx'); +INSERT INTO t1 VALUES ('xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxx'); +INSERT INTO t1 VALUES ('xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxx'); + +--sync_slave_with_master + +# wait for the SQL thread to sleep +--let $show_statement= SHOW PROCESSLIST +--let $field= State +--let $condition= = 'Slave has read all relay log; waiting for the slave I/O thread to update it' +--disable_connect_log +--source include/wait_show_condition.inc +--enable_connect_log + +# now the io thread has set rli->ignore_space_limit +# lets lock the table so that once the SQL thread awakes +# it blocks there and does not set rli->ignore_space_limit +# back to zero +LOCK TABLE t1 WRITE; + +# now issue more statements that will overflow the +# rli->log_space_limit (in this case ~10K) +--connection master + +INSERT INTO t1 VALUES ('xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxx'); +INSERT INTO t1 VALUES ('xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxx'); +INSERT INTO t1 VALUES ('xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxx'); +INSERT INTO t1 VALUES ('xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxx'); +INSERT INTO t1 VALUES ('xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxx'); +INSERT INTO t1 VALUES ('xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxx'); +INSERT INTO t1 VALUES ('xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxx'); +INSERT INTO t1 VALUES ('xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxx'); +INSERT INTO t1 VALUES ('xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxx'); +INSERT INTO t1 VALUES ('xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxx'); + +--connection slave + +# ASSERT that the IO thread waits for the SQL thread to release some +# space before continuing +--let $show_statement= SHOW PROCESSLIST +--let $field= State +--let $condition= LIKE 'Waiting for %' +# before the patch (IO would have transfered everything) +#--let $condition= = 'Waiting for master to send event' +# after the patch (now it waits for space to be freed) +#--let $condition= = 'Waiting for the slave SQL thread to free enough relay log space' +--disable_connect_log +--source include/wait_show_condition.inc +--enable_connect_log + +# without the patch we can uncomment the following two lines and +# watch the IO thread synchronize with the master, thus writing +# relay logs way over the space limit +#--connection master +#--source include/sync_slave_io_with_master.inc + +## ASSERT that the IO thread has honored the limit+few bytes required to be able to purge +--let $relay_log_space_while_sql_is_executing = query_get_value(SHOW SLAVE STATUS, Relay_Log_Space, 1) +--let $relay_log_space_limit = query_get_value(SHOW VARIABLES LIKE "relay_log_space_limit", Value, 1) +--let $assert_text= Assert that relay log space is close to the limit +--let $assert_cond= $relay_log_space_while_sql_is_executing <= $relay_log_space_limit * 1.15 +--disable_connect_log +--source include/assert.inc +--enable_connect_log + +# unlock the table and let SQL thread continue applying events +UNLOCK TABLES; + +--connection master +--sync_slave_with_master +--let $diff_tables=master:test.t1,slave:test.t1 +--disable_connect_log +--source include/diff_tables.inc +--enable_connect_log + +--connection master +DROP TABLE t1; +--enable_query_log +--sync_slave_with_master + +--disable_connect_log +--source include/rpl_end.inc diff --git a/mysql-test/suite/binlog_encryption/rpl_switch_stm_row_mixed.result b/mysql-test/suite/binlog_encryption/rpl_switch_stm_row_mixed.result new file mode 100644 index 0000000..289e516 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_switch_stm_row_mixed.result @@ -0,0 +1,457 @@ +include/master-slave.inc +[connection master] +connection master; +drop database if exists mysqltest1; +create database mysqltest1; +use mysqltest1; +set @my_binlog_format= @@global.binlog_format; +set session binlog_format=mixed; +show session variables like "binlog_format%"; +Variable_name Value +binlog_format MIXED +set session binlog_format=statement; +show session variables like "binlog_format%"; +Variable_name Value +binlog_format STATEMENT +set session binlog_format=row; +show session variables like "binlog_format%"; +Variable_name Value +binlog_format ROW +set global binlog_format=DEFAULT; +show global variables like "binlog_format%"; +Variable_name Value +binlog_format STATEMENT +set global binlog_format=MIXED; +show global variables like "binlog_format%"; +Variable_name Value +binlog_format MIXED +set global binlog_format=STATEMENT; +show global variables like "binlog_format%"; +Variable_name Value +binlog_format STATEMENT +set global binlog_format=ROW; +show global variables like "binlog_format%"; +Variable_name Value +binlog_format ROW +show session variables like "binlog_format%"; +Variable_name Value +binlog_format ROW +select @@global.binlog_format, @@session.binlog_format; +@@global.binlog_format @@session.binlog_format +ROW ROW +CREATE TABLE t1 (a varchar(100)); +prepare stmt1 from 'insert into t1 select concat(UUID(),?)'; +set @string="emergency_1_"; +insert into t1 values("work_2_"); +execute stmt1 using @string; +deallocate prepare stmt1; +prepare stmt1 from 'insert into t1 select ?'; +insert into t1 values(concat(UUID(),"work_3_")); +execute stmt1 using @string; +deallocate prepare stmt1; +insert into t1 values(concat("for_4_",UUID())); +insert into t1 select "yesterday_5_"; +create temporary table tmp(a char(100)); +insert into tmp values("see_6_"); +set binlog_format=statement; +ERROR HY000: Cannot switch out of the row-based binary log format when the session has open temporary tables +insert into t1 select * from tmp; +drop temporary table tmp; +set binlog_format=statement; +show global variables like "binlog_format%"; +Variable_name Value +binlog_format ROW +show session variables like "binlog_format%"; +Variable_name Value +binlog_format STATEMENT +select @@global.binlog_format, @@session.binlog_format; +@@global.binlog_format @@session.binlog_format +ROW STATEMENT +set global binlog_format=statement; +show global variables like "binlog_format%"; +Variable_name Value +binlog_format STATEMENT +show session variables like "binlog_format%"; +Variable_name Value +binlog_format STATEMENT +select @@global.binlog_format, @@session.binlog_format; +@@global.binlog_format @@session.binlog_format +STATEMENT STATEMENT +prepare stmt1 from 'insert into t1 select ?'; +set @string="emergency_7_"; +insert into t1 values("work_8_"); +execute stmt1 using @string; +deallocate prepare stmt1; +prepare stmt1 from 'insert into t1 select ?'; +insert into t1 values("work_9_"); +execute stmt1 using @string; +deallocate prepare stmt1; +insert into t1 values("for_10_"); +insert into t1 select "yesterday_11_"; +set binlog_format=statement; +select @@global.binlog_format, @@session.binlog_format; +@@global.binlog_format @@session.binlog_format +STATEMENT STATEMENT +set global binlog_format=statement; +select @@global.binlog_format, @@session.binlog_format; +@@global.binlog_format @@session.binlog_format +STATEMENT STATEMENT +prepare stmt1 from 'insert into t1 select ?'; +set @string="emergency_12_"; +insert into t1 values("work_13_"); +execute stmt1 using @string; +deallocate prepare stmt1; +prepare stmt1 from 'insert into t1 select ?'; +insert into t1 values("work_14_"); +execute stmt1 using @string; +deallocate prepare stmt1; +insert into t1 values("for_15_"); +insert into t1 select "yesterday_16_"; +set global binlog_format=mixed; +select @@global.binlog_format, @@session.binlog_format; +@@global.binlog_format @@session.binlog_format +MIXED STATEMENT +set binlog_format=default; +select @@global.binlog_format, @@session.binlog_format; +@@global.binlog_format @@session.binlog_format +MIXED MIXED +prepare stmt1 from 'insert into t1 select concat(UUID(),?)'; +set @string="emergency_17_"; +insert into t1 values("work_18_"); +execute stmt1 using @string; +deallocate prepare stmt1; +prepare stmt1 from 'insert into t1 select ?'; +insert into t1 values(concat(UUID(),"work_19_")); +execute stmt1 using @string; +deallocate prepare stmt1; +insert into t1 values(concat("for_20_",UUID())); +insert into t1 select "yesterday_21_"; +prepare stmt1 from 'insert into t1 select ?'; +insert into t1 values(concat(UUID(),"work_22_")); +execute stmt1 using @string; +deallocate prepare stmt1; +insert into t1 values(concat("for_23_",UUID())); +insert into t1 select "yesterday_24_"; +create table t2 ENGINE=MyISAM select rpad(UUID(),100,' '); +create table t3 select 1 union select UUID(); +create table t4 select * from t1 where 3 in (select 1 union select 2 union select UUID() union select 3); +create table t5 select * from t1 where 3 in (select 1 union select 2 union select curdate() union select 3); +Warnings: +Warning 1292 Incorrect datetime value: '3' +insert into t5 select UUID() from t1 where 3 in (select 1 union select 2 union select 3 union select * from t4); +create procedure foo() +begin +insert into t1 values("work_25_"); +insert into t1 values(concat("for_26_",UUID())); +insert into t1 select "yesterday_27_"; +end| +create procedure foo2() +begin +insert into t1 values(concat("emergency_28_",UUID())); +insert into t1 values("work_29_"); +insert into t1 values(concat("for_30_",UUID())); +set session binlog_format=row; # accepted for stored procs +insert into t1 values("more work_31_"); +set session binlog_format=mixed; +end| +create function foo3() returns bigint unsigned +begin +set session binlog_format=row; # rejected for stored funcs +insert into t1 values("alarm"); +return 100; +end| +create procedure foo4(x varchar(100)) +begin +insert into t1 values(concat("work_250_",x)); +insert into t1 select "yesterday_270_"; +end| +call foo(); +call foo2(); +call foo4("hello"); +call foo4(UUID()); +call foo4("world"); +select foo3(); +ERROR HY000: Cannot change the binary logging format inside a stored function or trigger +select * from t1 where a="alarm"; +a +drop function foo3; +create function foo3() returns bigint unsigned +begin +insert into t1 values("foo3_32_"); +call foo(); +return 100; +end| +insert into t2 select foo3(); +prepare stmt1 from 'insert into t2 select foo3()'; +execute stmt1; +execute stmt1; +deallocate prepare stmt1; +create function foo4() returns bigint unsigned +begin +insert into t2 select foo3(); +return 100; +end| +select foo4(); +foo4() +100 +prepare stmt1 from 'select foo4()'; +execute stmt1; +foo4() +100 +execute stmt1; +foo4() +100 +deallocate prepare stmt1; +create function foo5() returns bigint unsigned +begin +insert into t2 select UUID(); +return 100; +end| +select foo5(); +foo5() +100 +prepare stmt1 from 'select foo5()'; +execute stmt1; +foo5() +100 +execute stmt1; +foo5() +100 +deallocate prepare stmt1; +create function foo6(x varchar(100)) returns bigint unsigned +begin +insert into t2 select x; +return 100; +end| +select foo6("foo6_1_"); +foo6("foo6_1_") +100 +select foo6(concat("foo6_2_",UUID())); +foo6(concat("foo6_2_",UUID())) +100 +prepare stmt1 from 'select foo6(concat("foo6_3_",UUID()))'; +execute stmt1; +foo6(concat("foo6_3_",UUID())) +100 +execute stmt1; +foo6(concat("foo6_3_",UUID())) +100 +deallocate prepare stmt1; +create view v1 as select uuid(); +create table t11 (data varchar(255)); +insert into t11 select * from v1; +insert into t11 select TABLE_NAME from INFORMATION_SCHEMA.TABLES where TABLE_SCHEMA='mysqltest1' and TABLE_NAME IN ('v1','t11'); +prepare stmt1 from "insert into t11 select TABLE_NAME from INFORMATION_SCHEMA.TABLES where TABLE_SCHEMA='mysqltest1' and TABLE_NAME IN ('v1','t11')"; +execute stmt1; +execute stmt1; +deallocate prepare stmt1; +create trigger t11_bi before insert on t11 for each row +begin +set NEW.data = concat(NEW.data,UUID()); +end| +insert into t11 values("try_560_"); +insert delayed into t2 values("delay_1_"); +insert delayed into t2 values(concat("delay_2_",UUID())); +insert delayed into t2 values("delay_6_"); +insert delayed into t2 values(rand()); +set @a=2.345; +insert delayed into t2 values(@a); +connection slave; +connection master; +create table t20 select * from t1; +create table t21 select * from t2; +create table t22 select * from t3; +drop table t1,t2,t3; +create table t1 (a int primary key auto_increment, b varchar(100)); +create table t2 (a int primary key auto_increment, b varchar(100)); +create table t3 (b varchar(100)); +create function f (x varchar(100)) returns int deterministic +begin +insert into t1 values(null,x); +insert into t2 values(null,x); +return 1; +end| +select f("try_41_"); +f("try_41_") +1 +connection slave; +use mysqltest1; +insert into t2 values(2,null),(3,null),(4,null); +delete from t2 where a>=2; +connection master; +select f("try_42_"); +f("try_42_") +1 +connection slave; +insert into t2 values(3,null),(4,null); +delete from t2 where a>=3; +connection master; +prepare stmt1 from 'select f(?)'; +set @string="try_43_"; +insert into t1 values(null,"try_44_"); +execute stmt1 using @string; +f(?) +1 +deallocate prepare stmt1; +connection slave; +connection master; +create table t12 select * from t1; +drop table t1; +create table t1 (a int, b varchar(100), key(a)); +select f("try_45_"); +f("try_45_") +1 +create table t13 select * from t1; +drop table t1; +create table t1 (a int primary key auto_increment, b varchar(100)); +drop function f; +create table t14 (unique (a)) select * from t2; +truncate table t2; +create function f1 (x varchar(100)) returns int deterministic +begin +insert into t1 values(null,x); +return 1; +end| +create function f2 (x varchar(100)) returns int deterministic +begin +insert into t2 values(null,x); +return 1; +end| +select f1("try_46_"),f2("try_47_"); +f1("try_46_") f2("try_47_") +1 1 +connection slave; +insert into t2 values(2,null),(3,null),(4,null); +delete from t2 where a>=2; +connection master; +select f1("try_48_"),f2("try_49_"); +f1("try_48_") f2("try_49_") +1 1 +insert into t3 values(concat("try_50_",f1("try_51_"),f2("try_52_"))); +connection slave; +connection master; +drop function f2; +create function f2 (x varchar(100)) returns int deterministic +begin +declare y int; +insert into t1 values(null,x); +set y = (select count(*) from t2); +return y; +end| +select f1("try_53_"),f2("try_54_"); +f1("try_53_") f2("try_54_") +1 3 +connection slave; +connection master; +drop function f2; +create trigger t1_bi before insert on t1 for each row +begin +insert into t2 values(null,"try_55_"); +end| +insert into t1 values(null,"try_56_"); +alter table t1 modify a int, drop primary key; +insert into t1 values(null,"try_57_"); +connection slave; +connection master; +CREATE TEMPORARY TABLE t15 SELECT UUID(); +create table t16 like t15; +INSERT INTO t16 SELECT * FROM t15; +insert into t16 values("try_65_"); +drop table t15; +insert into t16 values("try_66_"); +connection slave; +connection master; +select count(*) from t1; +count(*) +7 +select count(*) from t2; +count(*) +5 +select count(*) from t3; +count(*) +1 +select count(*) from t4; +count(*) +29 +select count(*) from t5; +count(*) +58 +select count(*) from t11; +count(*) +8 +select count(*) from t20; +count(*) +66 +select count(*) from t21; +count(*) +19 +select count(*) from t22; +count(*) +2 +select count(*) from t12; +count(*) +4 +select count(*) from t13; +count(*) +1 +select count(*) from t14; +count(*) +4 +select count(*) from t16; +count(*) +3 +connection slave; +connection master; +DROP TABLE IF EXISTS t11; +SET SESSION BINLOG_FORMAT=STATEMENT; +CREATE TABLE t11 (song VARCHAR(255)); +LOCK TABLES t11 WRITE; +SET SESSION BINLOG_FORMAT=ROW; +INSERT INTO t11 VALUES('Several Species of Small Furry Animals Gathered Together in a Cave and Grooving With a Pict'); +SET SESSION BINLOG_FORMAT=STATEMENT; +INSERT INTO t11 VALUES('Careful With That Axe, Eugene'); +UNLOCK TABLES; +SELECT * FROM t11; +song Several Species of Small Furry Animals Gathered Together in a Cave and Grooving With a Pict +song Careful With That Axe, Eugene +connection slave; +USE mysqltest1; +SELECT * FROM t11; +song Several Species of Small Furry Animals Gathered Together in a Cave and Grooving With a Pict +song Careful With That Axe, Eugene +connection master; +DROP TABLE IF EXISTS t12; +SET SESSION BINLOG_FORMAT=MIXED; +CREATE TABLE t12 (data LONG); +LOCK TABLES t12 WRITE; +INSERT INTO t12 VALUES(UUID()); +UNLOCK TABLES; +connection slave; +connection master; +CREATE FUNCTION my_user() +RETURNS CHAR(64) +BEGIN +DECLARE user CHAR(64); +SELECT USER() INTO user; +RETURN user; +END $$ +CREATE FUNCTION my_current_user() +RETURNS CHAR(64) +BEGIN +DECLARE user CHAR(64); +SELECT CURRENT_USER() INTO user; +RETURN user; +END $$ +DROP TABLE IF EXISTS t13; +CREATE TABLE t13 (data CHAR(64)); +INSERT INTO t13 VALUES (USER()); +INSERT INTO t13 VALUES (my_user()); +INSERT INTO t13 VALUES (CURRENT_USER()); +INSERT INTO t13 VALUES (my_current_user()); +connection slave; +connection master; +drop database mysqltest1; +connection slave; +connection master; +set global binlog_format =@my_binlog_format; +include/rpl_end.inc diff --git a/mysql-test/suite/binlog_encryption/rpl_switch_stm_row_mixed.test b/mysql-test/suite/binlog_encryption/rpl_switch_stm_row_mixed.test new file mode 100644 index 0000000..fc43c6a --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_switch_stm_row_mixed.test @@ -0,0 +1,634 @@ +# +# The test was taken from the rpl suite with cosmetic changes +# + +# +# rpl_switch_stm_row_mixed tests covers +# +# - Master is switching explicitly between STATEMENT, ROW, and MIXED +# binlog format showing when it is possible and when not. +# - Master switching from MIXED to RBR implicitly listing all use +# cases, e.g a query invokes UUID(), thereafter to serve as the +# definition of MIXED binlog format +# - correctness of execution + +--enable_connect_log + +--disable_connect_log +-- source include/have_binlog_format_mixed_or_row.inc +-- source include/master-slave.inc +--enable_connect_log + +# Since this test generates row-based events in the binary log, the +# slave SQL thread cannot be in STATEMENT mode to execute this test, +# so we only execute it for MIXED and ROW as default value of +# BINLOG_FORMAT. + +connection master; +--disable_warnings +drop database if exists mysqltest1; +create database mysqltest1; +--enable_warnings +use mysqltest1; + +# Save binlog format +set @my_binlog_format= @@global.binlog_format; + +# play with switching +set session binlog_format=mixed; +show session variables like "binlog_format%"; +set session binlog_format=statement; +show session variables like "binlog_format%"; +set session binlog_format=row; +show session variables like "binlog_format%"; + +set global binlog_format=DEFAULT; +show global variables like "binlog_format%"; +set global binlog_format=MIXED; +show global variables like "binlog_format%"; +set global binlog_format=STATEMENT; +show global variables like "binlog_format%"; +set global binlog_format=ROW; +show global variables like "binlog_format%"; +show session variables like "binlog_format%"; +select @@global.binlog_format, @@session.binlog_format; + +CREATE TABLE t1 (a varchar(100)); + +prepare stmt1 from 'insert into t1 select concat(UUID(),?)'; +set @string="emergency_1_"; +insert into t1 values("work_2_"); +execute stmt1 using @string; +deallocate prepare stmt1; + +prepare stmt1 from 'insert into t1 select ?'; +insert into t1 values(concat(UUID(),"work_3_")); +execute stmt1 using @string; +deallocate prepare stmt1; + +insert into t1 values(concat("for_4_",UUID())); +insert into t1 select "yesterday_5_"; + +# verify that temp tables prevent a switch to SBR +create temporary table tmp(a char(100)); +insert into tmp values("see_6_"); +--error ER_TEMP_TABLE_PREVENTS_SWITCH_OUT_OF_RBR +set binlog_format=statement; +insert into t1 select * from tmp; +drop temporary table tmp; + +# Now we go to SBR +set binlog_format=statement; +show global variables like "binlog_format%"; +show session variables like "binlog_format%"; +select @@global.binlog_format, @@session.binlog_format; +set global binlog_format=statement; +show global variables like "binlog_format%"; +show session variables like "binlog_format%"; +select @@global.binlog_format, @@session.binlog_format; + +prepare stmt1 from 'insert into t1 select ?'; +set @string="emergency_7_"; +insert into t1 values("work_8_"); +execute stmt1 using @string; +deallocate prepare stmt1; + +prepare stmt1 from 'insert into t1 select ?'; +insert into t1 values("work_9_"); +execute stmt1 using @string; +deallocate prepare stmt1; + +insert into t1 values("for_10_"); +insert into t1 select "yesterday_11_"; + +# test statement (is not default after wl#3368) +set binlog_format=statement; +select @@global.binlog_format, @@session.binlog_format; +set global binlog_format=statement; +select @@global.binlog_format, @@session.binlog_format; + +prepare stmt1 from 'insert into t1 select ?'; +set @string="emergency_12_"; +insert into t1 values("work_13_"); +execute stmt1 using @string; +deallocate prepare stmt1; + +prepare stmt1 from 'insert into t1 select ?'; +insert into t1 values("work_14_"); +execute stmt1 using @string; +deallocate prepare stmt1; + +insert into t1 values("for_15_"); +insert into t1 select "yesterday_16_"; + +# and now the mixed mode + +set global binlog_format=mixed; +select @@global.binlog_format, @@session.binlog_format; +set binlog_format=default; +select @@global.binlog_format, @@session.binlog_format; + +prepare stmt1 from 'insert into t1 select concat(UUID(),?)'; +set @string="emergency_17_"; +insert into t1 values("work_18_"); +execute stmt1 using @string; +deallocate prepare stmt1; + +prepare stmt1 from 'insert into t1 select ?'; +insert into t1 values(concat(UUID(),"work_19_")); +execute stmt1 using @string; +deallocate prepare stmt1; + +insert into t1 values(concat("for_20_",UUID())); +insert into t1 select "yesterday_21_"; + +prepare stmt1 from 'insert into t1 select ?'; +insert into t1 values(concat(UUID(),"work_22_")); +execute stmt1 using @string; +deallocate prepare stmt1; + +insert into t1 values(concat("for_23_",UUID())); +insert into t1 select "yesterday_24_"; + +# Test of CREATE TABLE SELECT + +create table t2 ENGINE=MyISAM select rpad(UUID(),100,' '); +create table t3 select 1 union select UUID(); +--disable_warnings +create table t4 select * from t1 where 3 in (select 1 union select 2 union select UUID() union select 3); +--enable_warnings +create table t5 select * from t1 where 3 in (select 1 union select 2 union select curdate() union select 3); +# what if UUID() is first: +--disable_warnings +insert into t5 select UUID() from t1 where 3 in (select 1 union select 2 union select 3 union select * from t4); +--enable_warnings + +# inside a stored procedure + +delimiter |; +create procedure foo() +begin +insert into t1 values("work_25_"); +insert into t1 values(concat("for_26_",UUID())); +insert into t1 select "yesterday_27_"; +end| +create procedure foo2() +begin +insert into t1 values(concat("emergency_28_",UUID())); +insert into t1 values("work_29_"); +insert into t1 values(concat("for_30_",UUID())); +set session binlog_format=row; # accepted for stored procs +insert into t1 values("more work_31_"); +set session binlog_format=mixed; +end| +create function foo3() returns bigint unsigned +begin + set session binlog_format=row; # rejected for stored funcs + insert into t1 values("alarm"); + return 100; +end| +create procedure foo4(x varchar(100)) +begin +insert into t1 values(concat("work_250_",x)); +insert into t1 select "yesterday_270_"; +end| +delimiter ;| +call foo(); +call foo2(); +call foo4("hello"); +call foo4(UUID()); +call foo4("world"); + +# test that can't SET in a stored function +--error ER_STORED_FUNCTION_PREVENTS_SWITCH_BINLOG_FORMAT +select foo3(); +select * from t1 where a="alarm"; + +# Tests of stored functions/triggers/views for BUG#20930 "Mixed +# binlogging mode does not work with stored functions, triggers, +# views" + +# Function which calls procedure +drop function foo3; +delimiter |; +create function foo3() returns bigint unsigned +begin + insert into t1 values("foo3_32_"); + call foo(); + return 100; +end| +delimiter ;| +insert into t2 select foo3(); + +prepare stmt1 from 'insert into t2 select foo3()'; +execute stmt1; +execute stmt1; +deallocate prepare stmt1; + +# Test if stored function calls stored function which calls procedure +# which requires row-based. + +delimiter |; +create function foo4() returns bigint unsigned +begin + insert into t2 select foo3(); + return 100; +end| +delimiter ;| +select foo4(); + +prepare stmt1 from 'select foo4()'; +execute stmt1; +execute stmt1; +deallocate prepare stmt1; + +# A simple stored function +delimiter |; +create function foo5() returns bigint unsigned +begin + insert into t2 select UUID(); + return 100; +end| +delimiter ;| +select foo5(); + +prepare stmt1 from 'select foo5()'; +execute stmt1; +execute stmt1; +deallocate prepare stmt1; + +# A simple stored function where UUID() is in the argument +delimiter |; +create function foo6(x varchar(100)) returns bigint unsigned +begin + insert into t2 select x; + return 100; +end| +delimiter ;| +select foo6("foo6_1_"); +select foo6(concat("foo6_2_",UUID())); + +prepare stmt1 from 'select foo6(concat("foo6_3_",UUID()))'; +execute stmt1; +execute stmt1; +deallocate prepare stmt1; + + +# Test of views using UUID() + +create view v1 as select uuid(); +create table t11 (data varchar(255)); +insert into t11 select * from v1; +# Test of querying INFORMATION_SCHEMA which parses the view's body, +# to verify that it binlogs statement-based (is not polluted by +# the parsing of the view's body). +insert into t11 select TABLE_NAME from INFORMATION_SCHEMA.TABLES where TABLE_SCHEMA='mysqltest1' and TABLE_NAME IN ('v1','t11'); +prepare stmt1 from "insert into t11 select TABLE_NAME from INFORMATION_SCHEMA.TABLES where TABLE_SCHEMA='mysqltest1' and TABLE_NAME IN ('v1','t11')"; +execute stmt1; +execute stmt1; +deallocate prepare stmt1; + +# Test of triggers with UUID() +delimiter |; +create trigger t11_bi before insert on t11 for each row +begin + set NEW.data = concat(NEW.data,UUID()); +end| +delimiter ;| +insert into t11 values("try_560_"); + +# Test that INSERT DELAYED works in mixed mode (BUG#20649) +insert delayed into t2 values("delay_1_"); +insert delayed into t2 values(concat("delay_2_",UUID())); +insert delayed into t2 values("delay_6_"); + +# Test for BUG#20633 (INSERT DELAYED RAND()/user_variable does not +# replicate fine in statement-based ; we test that in mixed mode it +# works). +insert delayed into t2 values(rand()); +set @a=2.345; +insert delayed into t2 values(@a); + +# With INSERT DELAYED, rows are written to the binlog after they are +# written to the table. Therefore, it is not enough to wait until the +# rows make it to t2 on the master (the rows may not be in the binlog +# at that time, and may still not be in the binlog when +# sync_slave_with_master is later called). Instead, we wait until the +# rows make it to t2 on the slave. We first call +# sync_slave_with_master, so that we are sure that t2 has been created +# on the slave. +sync_slave_with_master; +let $wait_condition= SELECT COUNT(*) = 19 FROM mysqltest1.t2; + +--disable_connect_log +--source include/wait_condition.inc +--enable_connect_log +connection master; + +# If you want to do manual testing of the mixed mode regarding UDFs (not +# testable automatically as quite platform- and compiler-dependent), +# you just need to set the variable below to 1, and to +# "make udf_example.so" in sql/, and to copy sql/udf_example.so to +# MYSQL_TEST_DIR/lib/mysql. +let $you_want_to_test_UDF=0; +if ($you_want_to_test_UDF) +{ + CREATE FUNCTION metaphon RETURNS STRING SONAME 'udf_example.so'; + prepare stmt1 from 'insert into t1 select metaphon(?)'; + set @string="emergency_133_"; + insert into t1 values("work_134_"); + execute stmt1 using @string; + deallocate prepare stmt1; + prepare stmt1 from 'insert into t1 select ?'; + insert into t1 values(metaphon("work_135_")); + execute stmt1 using @string; + deallocate prepare stmt1; + insert into t1 values(metaphon("for_136_")); + insert into t1 select "yesterday_137_"; + create table t6 select metaphon("for_138_"); + create table t7 select 1 union select metaphon("for_139_"); + create table t8 select * from t1 where 3 in (select 1 union select 2 union select metaphon("for_140_") union select 3); + create table t9 select * from t1 where 3 in (select 1 union select 2 union select curdate() union select 3); +} + +create table t20 select * from t1; # save for comparing later +create table t21 select * from t2; +create table t22 select * from t3; +drop table t1,t2,t3; + +# This tests the fix to +# BUG#19630 stored function inserting into two auto_increment breaks statement-based binlog +# We verify that under the mixed binlog mode, a stored function +# modifying at least two tables having an auto_increment column, +# is binlogged row-based. Indeed in statement-based binlogging, +# only the auto_increment value generated for the first table +# is recorded in the binlog, the value generated for the 2nd table +# lacking. + +create table t1 (a int primary key auto_increment, b varchar(100)); +create table t2 (a int primary key auto_increment, b varchar(100)); +create table t3 (b varchar(100)); +delimiter |; +create function f (x varchar(100)) returns int deterministic +begin + insert into t1 values(null,x); + insert into t2 values(null,x); + return 1; +end| +delimiter ;| +select f("try_41_"); +# Two operations which compensate each other except that their net +# effect is that they advance the auto_increment counter of t2 on slave: +sync_slave_with_master; +use mysqltest1; +insert into t2 values(2,null),(3,null),(4,null); +delete from t2 where a>=2; + +connection master; +# this is the call which didn't replicate well +select f("try_42_"); +sync_slave_with_master; + +# now use prepared statement and test again, just to see that the RBB +# mode isn't set at PREPARE but at EXECUTE. + +insert into t2 values(3,null),(4,null); +delete from t2 where a>=3; + +connection master; +prepare stmt1 from 'select f(?)'; +set @string="try_43_"; +insert into t1 values(null,"try_44_"); # should be SBB +execute stmt1 using @string; # should be RBB +deallocate prepare stmt1; +sync_slave_with_master; + +# verify that if only one table has auto_inc, it does not trigger RBB +# (we'll check in binlog further below) + +connection master; +create table t12 select * from t1; # save for comparing later +drop table t1; +create table t1 (a int, b varchar(100), key(a)); +select f("try_45_"); + +# restore table's key +create table t13 select * from t1; +drop table t1; +create table t1 (a int primary key auto_increment, b varchar(100)); + +# now test if it's two functions, each of them inserts in one table + +drop function f; +# we need a unique key to have sorting of rows by mysqldump +create table t14 (unique (a)) select * from t2; +truncate table t2; +delimiter |; +create function f1 (x varchar(100)) returns int deterministic +begin + insert into t1 values(null,x); + return 1; +end| +create function f2 (x varchar(100)) returns int deterministic +begin + insert into t2 values(null,x); + return 1; +end| +delimiter ;| +select f1("try_46_"),f2("try_47_"); + +sync_slave_with_master; +insert into t2 values(2,null),(3,null),(4,null); +delete from t2 where a>=2; + +connection master; +# Test with SELECT and INSERT +select f1("try_48_"),f2("try_49_"); +insert into t3 values(concat("try_50_",f1("try_51_"),f2("try_52_"))); +sync_slave_with_master; + +# verify that if f2 does only read on an auto_inc table, this does not +# switch to RBB +connection master; +drop function f2; +delimiter |; +create function f2 (x varchar(100)) returns int deterministic +begin + declare y int; + insert into t1 values(null,x); + set y = (select count(*) from t2); + return y; +end| +delimiter ;| +select f1("try_53_"),f2("try_54_"); +sync_slave_with_master; + +# And now, a normal statement with a trigger (no stored functions) + +connection master; +drop function f2; +delimiter |; +create trigger t1_bi before insert on t1 for each row +begin + insert into t2 values(null,"try_55_"); +end| +delimiter ;| +insert into t1 values(null,"try_56_"); +# and now remove one auto_increment and verify SBB +alter table t1 modify a int, drop primary key; +insert into t1 values(null,"try_57_"); +sync_slave_with_master; + +# Test for BUG#20499 "mixed mode with temporary table breaks binlog" +# Slave used to have only 2 rows instead of 3. +connection master; +CREATE TEMPORARY TABLE t15 SELECT UUID(); +create table t16 like t15; +INSERT INTO t16 SELECT * FROM t15; +# we'll verify that this one is done RBB +insert into t16 values("try_65_"); +drop table t15; +# we'll verify that this one is done SBB +insert into t16 values("try_66_"); +sync_slave_with_master; + +# and now compare: + +connection master; + +# first check that data on master is sensible +select count(*) from t1; +select count(*) from t2; +select count(*) from t3; +select count(*) from t4; +select count(*) from t5; +select count(*) from t11; +select count(*) from t20; +select count(*) from t21; +select count(*) from t22; +select count(*) from t12; +select count(*) from t13; +select count(*) from t14; +select count(*) from t16; +if ($you_want_to_test_UDF) +{ + select count(*) from t6; + select count(*) from t7; + select count(*) from t8; + select count(*) from t9; +} + +sync_slave_with_master; + +# +# Bug#20863 If binlog format is changed between update and unlock of +# tables, wrong binlog +# + +connection master; +DROP TABLE IF EXISTS t11; +SET SESSION BINLOG_FORMAT=STATEMENT; +CREATE TABLE t11 (song VARCHAR(255)); +LOCK TABLES t11 WRITE; +SET SESSION BINLOG_FORMAT=ROW; +INSERT INTO t11 VALUES('Several Species of Small Furry Animals Gathered Together in a Cave and Grooving With a Pict'); +SET SESSION BINLOG_FORMAT=STATEMENT; +INSERT INTO t11 VALUES('Careful With That Axe, Eugene'); +UNLOCK TABLES; + +--query_vertical SELECT * FROM t11 +sync_slave_with_master; +USE mysqltest1; +--query_vertical SELECT * FROM t11 + +connection master; +DROP TABLE IF EXISTS t12; +SET SESSION BINLOG_FORMAT=MIXED; +CREATE TABLE t12 (data LONG); +LOCK TABLES t12 WRITE; +INSERT INTO t12 VALUES(UUID()); +UNLOCK TABLES; +sync_slave_with_master; + +# +# BUG#28086: SBR of USER() becomes corrupted on slave +# + +connection master; + +# Just to get something that is non-trivial, albeit still simple, we +# stuff the result of USER() and CURRENT_USER() into a variable. +--delimiter $$ +CREATE FUNCTION my_user() + RETURNS CHAR(64) +BEGIN + DECLARE user CHAR(64); + SELECT USER() INTO user; + RETURN user; +END $$ +--delimiter ; + +--delimiter $$ +CREATE FUNCTION my_current_user() + RETURNS CHAR(64) +BEGIN + DECLARE user CHAR(64); + SELECT CURRENT_USER() INTO user; + RETURN user; +END $$ +--delimiter ; + +DROP TABLE IF EXISTS t13; +CREATE TABLE t13 (data CHAR(64)); +INSERT INTO t13 VALUES (USER()); +INSERT INTO t13 VALUES (my_user()); +INSERT INTO t13 VALUES (CURRENT_USER()); +INSERT INTO t13 VALUES (my_current_user()); + +sync_slave_with_master; + +# as we're using UUID we don't SELECT but use "diff" like in rpl_row_UUID +--exec $MYSQL_DUMP --compact --order-by-primary --skip-extended-insert --no-create-info mysqltest1 > $MYSQLTEST_VARDIR/tmp/rpl_switch_stm_row_mixed_master.sql +--exec $MYSQL_DUMP_SLAVE --compact --order-by-primary --skip-extended-insert --no-create-info mysqltest1 > $MYSQLTEST_VARDIR/tmp/rpl_switch_stm_row_mixed_slave.sql + +# Let's compare. Note: If they match test will pass, if they do not match +# the test will show that the diff statement failed and not reject file +# will be created. You will need to go to the mysql-test dir and diff +# the files your self to see what is not matching + +diff_files $MYSQLTEST_VARDIR/tmp/rpl_switch_stm_row_mixed_master.sql $MYSQLTEST_VARDIR/tmp/rpl_switch_stm_row_mixed_slave.sql; + +connection master; + +# Now test that mysqlbinlog works fine on a binlog generated by the +# mixed mode + +# BUG#11312 "DELIMITER is not written to the binary log that causes +# syntax error" makes that mysqlbinlog will fail if we pass it the +# text of queries; this forces us to use --base64-output here. + +# BUG#20929 "BINLOG command causes invalid free plus assertion +# failure" makes mysqld segfault when receiving --base64-output + +# So I can't enable this piece of test +# SIGH + +if ($enable_when_11312_or_20929_fixed) +{ +--exec $MYSQL_BINLOG --base64-output $MYSQLTEST_VARDIR/log/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/mysqlbinlog_mixed.sql +drop database mysqltest1; +--exec $MYSQL < $MYSQLTEST_VARDIR/tmp/mysqlbinlog_mixed.sql +--exec $MYSQL_DUMP --compact --order-by-primary --skip-extended-insert --no-create-info mysqltest1 > $MYSQLTEST_VARDIR/tmp/rpl_switch_stm_row_mixed_master.sql +# the old mysqldump output on slave is the same as what it was on +# master before restoring on master. +diff_files $MYSQLTEST_VARDIR/tmp/rpl_switch_stm_row_mixed_master.sql $MYSQLTEST_VARDIR/tmp/rpl_switch_stm_row_mixed_slave.sql; +} + +drop database mysqltest1; +sync_slave_with_master; + +connection master; +# Restore binlog format setting +set global binlog_format =@my_binlog_format; +--disable_connect_log +--source include/rpl_end.inc diff --git a/mysql-test/suite/binlog_encryption/rpl_sync-master.opt b/mysql-test/suite/binlog_encryption/rpl_sync-master.opt new file mode 100644 index 0000000..04b06bf --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_sync-master.opt @@ -0,0 +1,2 @@ +--default-storage-engine=MyISAM +--loose-innodb-file-per-table=0 diff --git a/mysql-test/suite/binlog_encryption/rpl_sync-slave.opt b/mysql-test/suite/binlog_encryption/rpl_sync-slave.opt new file mode 100644 index 0000000..2e8be18 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_sync-slave.opt @@ -0,0 +1,2 @@ +--sync-relay-log-info=1 --relay-log-recovery=1 --loose-innodb_file_format_check=1 --default-storage-engine=MyISAM --loose-innodb-file-per-table=0 +--skip-core-file --skip-slave-start diff --git a/mysql-test/suite/binlog_encryption/rpl_sync.result b/mysql-test/suite/binlog_encryption/rpl_sync.result new file mode 100644 index 0000000..1240c44 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_sync.result @@ -0,0 +1,53 @@ +=====Configuring the enviroment=======; +include/master-slave.inc +[connection master] +call mtr.add_suppression('Attempting backtrace'); +call mtr.add_suppression("Recovery from master pos .* and file master-bin.000001"); +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +flush tables; +CREATE TABLE t1(a INT, PRIMARY KEY(a)) engine=innodb; +insert into t1(a) values(1); +insert into t1(a) values(2); +insert into t1(a) values(3); +=====Inserting data on the master but without the SQL Thread being running=======; +connection slave; +connection slave; +include/stop_slave_sql.inc +connection master; +insert into t1(a) values(4); +insert into t1(a) values(5); +insert into t1(a) values(6); +=====Removing relay log files and crashing/recoverying the slave=======; +connection slave; +include/stop_slave_io.inc +SET SESSION debug_dbug="d,crash_before_rotate_relaylog"; +FLUSH LOGS; +ERROR HY000: Lost connection to MySQL server during query +include/rpl_reconnect.inc +=====Dumping and comparing tables=======; +include/start_slave.inc +connection master; +connection slave; +include/diff_tables.inc [master:t1,slave:t1] +=====Corrupting the master.info=======; +connection slave; +include/stop_slave.inc +connection master; +FLUSH LOGS; +insert into t1(a) values(7); +insert into t1(a) values(8); +insert into t1(a) values(9); +connection slave; +SET SESSION debug_dbug="d,crash_before_rotate_relaylog"; +FLUSH LOGS; +ERROR HY000: Lost connection to MySQL server during query +include/rpl_reconnect.inc +=====Dumping and comparing tables=======; +include/start_slave.inc +connection master; +connection slave; +include/diff_tables.inc [master:t1,slave:t1] +=====Clean up=======; +connection master; +drop table t1; +include/rpl_end.inc diff --git a/mysql-test/suite/binlog_encryption/rpl_sync.test b/mysql-test/suite/binlog_encryption/rpl_sync.test new file mode 100644 index 0000000..6f97165 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_sync.test @@ -0,0 +1,180 @@ +# +# The test was taken from the rpl suite, with cosmetic fixes +# + +--enable_connect_log + +######################################################################################## +# This test verifies the options --sync-relay-log-info and --relay-log-recovery by +# crashing the slave in two different situations: +# (case-1) - Corrupt the relay log with changes which were not processed by +# the SQL Thread and crashes it. +# (case-2) - Corrupt the master.info with wrong coordinates and crashes it. +# +# Case 1: +# 1 - Stops the SQL Thread +# 2 - Inserts new records into the master. +# 3 - Corrupts the relay-log.bin* which most likely has such changes. +# 4 - Crashes the slave +# 5 - Verifies if the slave is sync with the master which means that the information +# loss was circumvented by the recovery process. +# +# Case 2: +# 1 - Stops the SQL/IO Threads +# 2 - Inserts new records into the master. +# 3 - Corrupts the master.info with wrong coordinates. +# 4 - Crashes the slave +# 5 - Verifies if the slave is sync with the master which means that the information +# loss was circumvented by the recovery process. +######################################################################################## + +######################################################################################## +# Configuring the environment +######################################################################################## +--echo =====Configuring the enviroment=======; + +--disable_connect_log +--source include/master-slave.inc +--source include/not_embedded.inc +--source include/not_valgrind.inc +--source include/have_debug.inc +--source include/not_crashrep.inc +--enable_connect_log + +call mtr.add_suppression('Attempting backtrace'); +call mtr.add_suppression("Recovery from master pos .* and file master-bin.000001"); +# Use innodb so we do not get "table should be repaired" issues. +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +flush tables; +CREATE TABLE t1(a INT, PRIMARY KEY(a)) engine=innodb; + +insert into t1(a) values(1); +insert into t1(a) values(2); +insert into t1(a) values(3); + +######################################################################################## +# Case 1: Corrupt a relay-log.bin* +######################################################################################## +--echo =====Inserting data on the master but without the SQL Thread being running=======; +sync_slave_with_master; + +connection slave; +let $MYSQLD_SLAVE_DATADIR= `select @@datadir`; +--replace_result $MYSQLD_SLAVE_DATADIR MYSQLD_SLAVE_DATADIR +--copy_file $MYSQLD_SLAVE_DATADIR/master.info $MYSQLD_SLAVE_DATADIR/master.backup +--disable_connect_log +--source include/stop_slave_sql.inc +--enable_connect_log + +connection master; +insert into t1(a) values(4); +insert into t1(a) values(5); +insert into t1(a) values(6); + +--echo =====Removing relay log files and crashing/recoverying the slave=======; +connection slave; +--disable_connect_log +--source include/stop_slave_io.inc +--enable_connect_log + +let $file= query_get_value("SHOW SLAVE STATUS", Relay_Log_File, 1); + +--let FILE_TO_CORRUPT= $MYSQLD_SLAVE_DATADIR/$file +perl; +$file= $ENV{'FILE_TO_CORRUPT'}; +open(FILE, ">$file") || die "Unable to open $file."; +truncate(FILE,0); +print FILE "failure"; +close ($file); +EOF + +--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.2.expect +SET SESSION debug_dbug="d,crash_before_rotate_relaylog"; +--error 2013 +FLUSH LOGS; + +--let $rpl_server_number= 2 +--disable_connect_log +--source include/rpl_reconnect.inc +--enable_connect_log + +--echo =====Dumping and comparing tables=======; +--disable_connect_log +--source include/start_slave.inc +--enable_connect_log + +connection master; +sync_slave_with_master; + +let $diff_tables=master:t1,slave:t1; +--disable_connect_log +source include/diff_tables.inc; +--enable_connect_log + +######################################################################################## +# Case 2: Corrupt a master.info +######################################################################################## +--echo =====Corrupting the master.info=======; +connection slave; +--disable_connect_log +--source include/stop_slave.inc +--enable_connect_log + +connection master; +FLUSH LOGS; + +insert into t1(a) values(7); +insert into t1(a) values(8); +insert into t1(a) values(9); + +connection slave; +let MYSQLD_SLAVE_DATADIR=`select @@datadir`; + +--perl +use strict; +use warnings; +my $src= "$ENV{'MYSQLD_SLAVE_DATADIR'}/master.backup"; +my $dst= "$ENV{'MYSQLD_SLAVE_DATADIR'}/master.info"; +open(FILE, "<", $src) or die; +my @content= <FILE>; +close FILE; +open(FILE, ">", $dst) or die; +binmode FILE; +print FILE @content; +close FILE; +EOF + +--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.2.expect +SET SESSION debug_dbug="d,crash_before_rotate_relaylog"; +--error 2013 +FLUSH LOGS; + +--let $rpl_server_number= 2 +--disable_connect_log +--source include/rpl_reconnect.inc +--enable_connect_log + +--echo =====Dumping and comparing tables=======; +--disable_connect_log +--source include/start_slave.inc +--enable_connect_log + +connection master; +sync_slave_with_master; + +let $diff_tables=master:t1,slave:t1; +--disable_connect_log +source include/diff_tables.inc; +--enable_connect_log + +######################################################################################## +# Clean up +######################################################################################## +--echo =====Clean up=======; +connection master; +drop table t1; + +--remove_file $MYSQLD_SLAVE_DATADIR/master.backup +--disable_connect_log +--source include/rpl_end.inc + diff --git a/mysql-test/suite/binlog_encryption/rpl_temporal_format_default_to_default.cnf b/mysql-test/suite/binlog_encryption/rpl_temporal_format_default_to_default.cnf new file mode 100644 index 0000000..b8e22e9 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_temporal_format_default_to_default.cnf @@ -0,0 +1,6 @@ +!include my.cnf + +[mysqld.2] +plugin-load-add= @ENV.FILE_KEY_MANAGEMENT_SO +loose-file-key-management-filename=@ENV.MYSQLTEST_VARDIR/std_data/keys.txt +encrypt-binlog diff --git a/mysql-test/suite/binlog_encryption/rpl_temporal_format_default_to_default.result b/mysql-test/suite/binlog_encryption/rpl_temporal_format_default_to_default.result new file mode 100644 index 0000000..d61255c --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_temporal_format_default_to_default.result @@ -0,0 +1,91 @@ +include/master-slave.inc +[connection master] +connection master; +SELECT @@global.mysql56_temporal_format AS on_master; +on_master +1 +connection slave; +SELECT @@global.mysql56_temporal_format AS on_slave; +on_slave +1 +connection master; +CREATE TABLE t1 +( +c0 TIME(0), +c1 TIME(1), +c2 TIME(2), +c3 TIME(3), +c4 TIME(4), +c5 TIME(5), +c6 TIME(6) +); +CREATE TABLE t2 +( +c0 TIMESTAMP(0), +c1 TIMESTAMP(1), +c2 TIMESTAMP(2), +c3 TIMESTAMP(3), +c4 TIMESTAMP(4), +c5 TIMESTAMP(5), +c6 TIMESTAMP(6) +); +CREATE TABLE t3 +( +c0 DATETIME(0), +c1 DATETIME(1), +c2 DATETIME(2), +c3 DATETIME(3), +c4 DATETIME(4), +c5 DATETIME(5), +c6 DATETIME(6) +); +INSERT INTO t1 VALUES ('01:01:01','01:01:01.1','01:01:01.11','01:01:01.111','01:01:01.1111','01:01:01.11111','01:01:01.111111'); +INSERT INTO t2 VALUES ('2001-01-01 01:01:01','2001-01-01 01:01:01.1','2001-01-01 01:01:01.11','2001-01-01 01:01:01.111','2001-01-01 01:01:01.1111','2001-01-01 01:01:01.11111','2001-01-01 01:01:01.111111'); +INSERT INTO t3 VALUES ('2001-01-01 01:01:01','2001-01-01 01:01:01.1','2001-01-01 01:01:01.11','2001-01-01 01:01:01.111','2001-01-01 01:01:01.1111','2001-01-01 01:01:01.11111','2001-01-01 01:01:01.111111'); +SELECT TABLE_NAME, TABLE_ROWS, AVG_ROW_LENGTH,DATA_LENGTH FROM INFORMATION_SCHEMA.TABLES +WHERE TABLE_NAME RLIKE 't[1-3]' ORDER BY TABLE_NAME; +TABLE_NAME TABLE_ROWS AVG_ROW_LENGTH DATA_LENGTH +t1 1 34 34 +t2 1 41 41 +t3 1 48 48 +connection slave; +connection slave; +SELECT * FROM t1;; +c0 01:01:01 +c1 01:01:01.1 +c2 01:01:01.11 +c3 01:01:01.111 +c4 01:01:01.1111 +c5 01:01:01.11111 +c6 01:01:01.111111 +SELECT * FROM t2;; +c0 2001-01-01 01:01:01 +c1 2001-01-01 01:01:01.1 +c2 2001-01-01 01:01:01.11 +c3 2001-01-01 01:01:01.111 +c4 2001-01-01 01:01:01.1111 +c5 2001-01-01 01:01:01.11111 +c6 2001-01-01 01:01:01.111111 +SELECT * FROM t3;; +c0 2001-01-01 01:01:01 +c1 2001-01-01 01:01:01.1 +c2 2001-01-01 01:01:01.11 +c3 2001-01-01 01:01:01.111 +c4 2001-01-01 01:01:01.1111 +c5 2001-01-01 01:01:01.11111 +c6 2001-01-01 01:01:01.111111 +SELECT TABLE_NAME, TABLE_ROWS, AVG_ROW_LENGTH,DATA_LENGTH FROM INFORMATION_SCHEMA.TABLES +WHERE TABLE_NAME RLIKE 't[1-3]' ORDER BY TABLE_NAME; +TABLE_NAME TABLE_ROWS AVG_ROW_LENGTH DATA_LENGTH +t1 1 34 34 +t2 1 41 41 +t3 1 48 48 +connection master; +DROP TABLE t1; +DROP TABLE t2; +DROP TABLE t3; +connection slave; +SET @@global.mysql56_temporal_format=DEFAULT; +connection master; +SET @@global.mysql56_temporal_format=DEFAULT; +include/rpl_end.inc diff --git a/mysql-test/suite/binlog_encryption/rpl_temporal_format_default_to_default.test b/mysql-test/suite/binlog_encryption/rpl_temporal_format_default_to_default.test new file mode 100644 index 0000000..74d8968 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_temporal_format_default_to_default.test @@ -0,0 +1,82 @@ +# +# The test was taken from the rpl suite as is +# + +--source include/master-slave.inc +--enable_connect_log + +if ($force_master_mysql56_temporal_format) +{ + connection master; + eval SET @@global.mysql56_temporal_format=$force_master_mysql56_temporal_format; +} + +if ($force_slave_mysql56_temporal_format) +{ + connection slave; + eval SET @@global.mysql56_temporal_format=$force_slave_mysql56_temporal_format; +} + +connection master; +SELECT @@global.mysql56_temporal_format AS on_master; +connection slave; +SELECT @@global.mysql56_temporal_format AS on_slave; +connection master; + +CREATE TABLE t1 +( + c0 TIME(0), + c1 TIME(1), + c2 TIME(2), + c3 TIME(3), + c4 TIME(4), + c5 TIME(5), + c6 TIME(6) +); +CREATE TABLE t2 +( + c0 TIMESTAMP(0), + c1 TIMESTAMP(1), + c2 TIMESTAMP(2), + c3 TIMESTAMP(3), + c4 TIMESTAMP(4), + c5 TIMESTAMP(5), + c6 TIMESTAMP(6) +); + +CREATE TABLE t3 +( + c0 DATETIME(0), + c1 DATETIME(1), + c2 DATETIME(2), + c3 DATETIME(3), + c4 DATETIME(4), + c5 DATETIME(5), + c6 DATETIME(6) +); +INSERT INTO t1 VALUES ('01:01:01','01:01:01.1','01:01:01.11','01:01:01.111','01:01:01.1111','01:01:01.11111','01:01:01.111111'); +INSERT INTO t2 VALUES ('2001-01-01 01:01:01','2001-01-01 01:01:01.1','2001-01-01 01:01:01.11','2001-01-01 01:01:01.111','2001-01-01 01:01:01.1111','2001-01-01 01:01:01.11111','2001-01-01 01:01:01.111111'); +INSERT INTO t3 VALUES ('2001-01-01 01:01:01','2001-01-01 01:01:01.1','2001-01-01 01:01:01.11','2001-01-01 01:01:01.111','2001-01-01 01:01:01.1111','2001-01-01 01:01:01.11111','2001-01-01 01:01:01.111111'); +SELECT TABLE_NAME, TABLE_ROWS, AVG_ROW_LENGTH,DATA_LENGTH FROM INFORMATION_SCHEMA.TABLES +WHERE TABLE_NAME RLIKE 't[1-3]' ORDER BY TABLE_NAME; +sync_slave_with_master; + +connection slave; +--query_vertical SELECT * FROM t1; +--query_vertical SELECT * FROM t2; +--query_vertical SELECT * FROM t3; +SELECT TABLE_NAME, TABLE_ROWS, AVG_ROW_LENGTH,DATA_LENGTH FROM INFORMATION_SCHEMA.TABLES +WHERE TABLE_NAME RLIKE 't[1-3]' ORDER BY TABLE_NAME; + +connection master; +DROP TABLE t1; +DROP TABLE t2; +DROP TABLE t3; + +connection slave; +SET @@global.mysql56_temporal_format=DEFAULT; +connection master; +SET @@global.mysql56_temporal_format=DEFAULT; + +--disable_connect_log +--source include/rpl_end.inc diff --git a/mysql-test/suite/binlog_encryption/rpl_temporal_format_mariadb53_to_mysql56.cnf b/mysql-test/suite/binlog_encryption/rpl_temporal_format_mariadb53_to_mysql56.cnf new file mode 100644 index 0000000..b8e22e9 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_temporal_format_mariadb53_to_mysql56.cnf @@ -0,0 +1,6 @@ +!include my.cnf + +[mysqld.2] +plugin-load-add= @ENV.FILE_KEY_MANAGEMENT_SO +loose-file-key-management-filename=@ENV.MYSQLTEST_VARDIR/std_data/keys.txt +encrypt-binlog diff --git a/mysql-test/suite/binlog_encryption/rpl_temporal_format_mariadb53_to_mysql56.result b/mysql-test/suite/binlog_encryption/rpl_temporal_format_mariadb53_to_mysql56.result new file mode 100644 index 0000000..5c51816 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_temporal_format_mariadb53_to_mysql56.result @@ -0,0 +1,95 @@ +include/master-slave.inc +[connection master] +connection master; +SET @@global.mysql56_temporal_format=false;; +connection slave; +SET @@global.mysql56_temporal_format=true;; +connection master; +SELECT @@global.mysql56_temporal_format AS on_master; +on_master +0 +connection slave; +SELECT @@global.mysql56_temporal_format AS on_slave; +on_slave +1 +connection master; +CREATE TABLE t1 +( +c0 TIME(0), +c1 TIME(1), +c2 TIME(2), +c3 TIME(3), +c4 TIME(4), +c5 TIME(5), +c6 TIME(6) +); +CREATE TABLE t2 +( +c0 TIMESTAMP(0), +c1 TIMESTAMP(1), +c2 TIMESTAMP(2), +c3 TIMESTAMP(3), +c4 TIMESTAMP(4), +c5 TIMESTAMP(5), +c6 TIMESTAMP(6) +); +CREATE TABLE t3 +( +c0 DATETIME(0), +c1 DATETIME(1), +c2 DATETIME(2), +c3 DATETIME(3), +c4 DATETIME(4), +c5 DATETIME(5), +c6 DATETIME(6) +); +INSERT INTO t1 VALUES ('01:01:01','01:01:01.1','01:01:01.11','01:01:01.111','01:01:01.1111','01:01:01.11111','01:01:01.111111'); +INSERT INTO t2 VALUES ('2001-01-01 01:01:01','2001-01-01 01:01:01.1','2001-01-01 01:01:01.11','2001-01-01 01:01:01.111','2001-01-01 01:01:01.1111','2001-01-01 01:01:01.11111','2001-01-01 01:01:01.111111'); +INSERT INTO t3 VALUES ('2001-01-01 01:01:01','2001-01-01 01:01:01.1','2001-01-01 01:01:01.11','2001-01-01 01:01:01.111','2001-01-01 01:01:01.1111','2001-01-01 01:01:01.11111','2001-01-01 01:01:01.111111'); +SELECT TABLE_NAME, TABLE_ROWS, AVG_ROW_LENGTH,DATA_LENGTH FROM INFORMATION_SCHEMA.TABLES +WHERE TABLE_NAME RLIKE 't[1-3]' ORDER BY TABLE_NAME; +TABLE_NAME TABLE_ROWS AVG_ROW_LENGTH DATA_LENGTH +t1 1 33 33 +t2 1 41 41 +t3 1 50 50 +connection slave; +connection slave; +SELECT * FROM t1;; +c0 01:01:01 +c1 01:01:01.1 +c2 01:01:01.11 +c3 01:01:01.111 +c4 01:01:01.1111 +c5 01:01:01.11111 +c6 01:01:01.111111 +SELECT * FROM t2;; +c0 2001-01-01 01:01:01 +c1 2001-01-01 01:01:01.1 +c2 2001-01-01 01:01:01.11 +c3 2001-01-01 01:01:01.111 +c4 2001-01-01 01:01:01.1111 +c5 2001-01-01 01:01:01.11111 +c6 2001-01-01 01:01:01.111111 +SELECT * FROM t3;; +c0 2001-01-01 01:01:01 +c1 2001-01-01 01:01:01.1 +c2 2001-01-01 01:01:01.11 +c3 2001-01-01 01:01:01.111 +c4 2001-01-01 01:01:01.1111 +c5 2001-01-01 01:01:01.11111 +c6 2001-01-01 01:01:01.111111 +SELECT TABLE_NAME, TABLE_ROWS, AVG_ROW_LENGTH,DATA_LENGTH FROM INFORMATION_SCHEMA.TABLES +WHERE TABLE_NAME RLIKE 't[1-3]' ORDER BY TABLE_NAME; +TABLE_NAME TABLE_ROWS AVG_ROW_LENGTH DATA_LENGTH +t1 1 34 34 +t2 1 41 41 +t3 1 48 48 +connection master; +DROP TABLE t1; +DROP TABLE t2; +DROP TABLE t3; +connection slave; +SET @@global.mysql56_temporal_format=DEFAULT; +connection master; +SET @@global.mysql56_temporal_format=DEFAULT; +include/rpl_end.inc diff --git a/mysql-test/suite/binlog_encryption/rpl_temporal_format_mariadb53_to_mysql56.test b/mysql-test/suite/binlog_encryption/rpl_temporal_format_mariadb53_to_mysql56.test new file mode 100644 index 0000000..6ac5fe6 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_temporal_format_mariadb53_to_mysql56.test @@ -0,0 +1,18 @@ +# +# The test was taken from the rpl suite as is +# + +# +# MariaDB-5.3 fractional temporal types do not store metadata +# when running with --binlog-format=row, thus can replicate +# only into a field with exactly the same data type and format. +# +# Skip when running with --binlog-format=row. +# But mixed and statement formats should work without problems. +# +-- source include/have_binlog_format_mixed_or_statement.inc + +--let $force_master_mysql56_temporal_format=false; +--let $force_slave_mysql56_temporal_format=true; + +--source rpl_temporal_format_default_to_default.test diff --git a/mysql-test/suite/binlog_encryption/rpl_temporal_format_mysql56_to_mariadb53.cnf b/mysql-test/suite/binlog_encryption/rpl_temporal_format_mysql56_to_mariadb53.cnf new file mode 100644 index 0000000..b8e22e9 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_temporal_format_mysql56_to_mariadb53.cnf @@ -0,0 +1,6 @@ +!include my.cnf + +[mysqld.2] +plugin-load-add= @ENV.FILE_KEY_MANAGEMENT_SO +loose-file-key-management-filename=@ENV.MYSQLTEST_VARDIR/std_data/keys.txt +encrypt-binlog diff --git a/mysql-test/suite/binlog_encryption/rpl_temporal_format_mysql56_to_mariadb53.result b/mysql-test/suite/binlog_encryption/rpl_temporal_format_mysql56_to_mariadb53.result new file mode 100644 index 0000000..9d086d3 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_temporal_format_mysql56_to_mariadb53.result @@ -0,0 +1,95 @@ +include/master-slave.inc +[connection master] +connection master; +SET @@global.mysql56_temporal_format=true;; +connection slave; +SET @@global.mysql56_temporal_format=false;; +connection master; +SELECT @@global.mysql56_temporal_format AS on_master; +on_master +1 +connection slave; +SELECT @@global.mysql56_temporal_format AS on_slave; +on_slave +0 +connection master; +CREATE TABLE t1 +( +c0 TIME(0), +c1 TIME(1), +c2 TIME(2), +c3 TIME(3), +c4 TIME(4), +c5 TIME(5), +c6 TIME(6) +); +CREATE TABLE t2 +( +c0 TIMESTAMP(0), +c1 TIMESTAMP(1), +c2 TIMESTAMP(2), +c3 TIMESTAMP(3), +c4 TIMESTAMP(4), +c5 TIMESTAMP(5), +c6 TIMESTAMP(6) +); +CREATE TABLE t3 +( +c0 DATETIME(0), +c1 DATETIME(1), +c2 DATETIME(2), +c3 DATETIME(3), +c4 DATETIME(4), +c5 DATETIME(5), +c6 DATETIME(6) +); +INSERT INTO t1 VALUES ('01:01:01','01:01:01.1','01:01:01.11','01:01:01.111','01:01:01.1111','01:01:01.11111','01:01:01.111111'); +INSERT INTO t2 VALUES ('2001-01-01 01:01:01','2001-01-01 01:01:01.1','2001-01-01 01:01:01.11','2001-01-01 01:01:01.111','2001-01-01 01:01:01.1111','2001-01-01 01:01:01.11111','2001-01-01 01:01:01.111111'); +INSERT INTO t3 VALUES ('2001-01-01 01:01:01','2001-01-01 01:01:01.1','2001-01-01 01:01:01.11','2001-01-01 01:01:01.111','2001-01-01 01:01:01.1111','2001-01-01 01:01:01.11111','2001-01-01 01:01:01.111111'); +SELECT TABLE_NAME, TABLE_ROWS, AVG_ROW_LENGTH,DATA_LENGTH FROM INFORMATION_SCHEMA.TABLES +WHERE TABLE_NAME RLIKE 't[1-3]' ORDER BY TABLE_NAME; +TABLE_NAME TABLE_ROWS AVG_ROW_LENGTH DATA_LENGTH +t1 1 34 34 +t2 1 41 41 +t3 1 48 48 +connection slave; +connection slave; +SELECT * FROM t1;; +c0 01:01:01 +c1 01:01:01.1 +c2 01:01:01.11 +c3 01:01:01.111 +c4 01:01:01.1111 +c5 01:01:01.11111 +c6 01:01:01.111111 +SELECT * FROM t2;; +c0 2001-01-01 01:01:01 +c1 2001-01-01 01:01:01.1 +c2 2001-01-01 01:01:01.11 +c3 2001-01-01 01:01:01.111 +c4 2001-01-01 01:01:01.1111 +c5 2001-01-01 01:01:01.11111 +c6 2001-01-01 01:01:01.111111 +SELECT * FROM t3;; +c0 2001-01-01 01:01:01 +c1 2001-01-01 01:01:01.1 +c2 2001-01-01 01:01:01.11 +c3 2001-01-01 01:01:01.111 +c4 2001-01-01 01:01:01.1111 +c5 2001-01-01 01:01:01.11111 +c6 2001-01-01 01:01:01.111111 +SELECT TABLE_NAME, TABLE_ROWS, AVG_ROW_LENGTH,DATA_LENGTH FROM INFORMATION_SCHEMA.TABLES +WHERE TABLE_NAME RLIKE 't[1-3]' ORDER BY TABLE_NAME; +TABLE_NAME TABLE_ROWS AVG_ROW_LENGTH DATA_LENGTH +t1 1 33 33 +t2 1 41 41 +t3 1 50 50 +connection master; +DROP TABLE t1; +DROP TABLE t2; +DROP TABLE t3; +connection slave; +SET @@global.mysql56_temporal_format=DEFAULT; +connection master; +SET @@global.mysql56_temporal_format=DEFAULT; +include/rpl_end.inc diff --git a/mysql-test/suite/binlog_encryption/rpl_temporal_format_mysql56_to_mariadb53.test b/mysql-test/suite/binlog_encryption/rpl_temporal_format_mysql56_to_mariadb53.test new file mode 100644 index 0000000..cf135fb --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_temporal_format_mysql56_to_mariadb53.test @@ -0,0 +1,8 @@ +# +# The test was taken from the rpl suite as is +# + +--let $force_master_mysql56_temporal_format=true; +--let $force_slave_mysql56_temporal_format=false; + +--source rpl_temporal_format_default_to_default.test diff --git a/mysql-test/suite/binlog_encryption/rpl_typeconv.result b/mysql-test/suite/binlog_encryption/rpl_typeconv.result new file mode 100644 index 0000000..988962f --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_typeconv.result @@ -0,0 +1,548 @@ +include/master-slave.inc +[connection master] +connection slave; +set @saved_slave_type_conversions = @@global.slave_type_conversions; +CREATE TABLE type_conversions ( +TestNo INT AUTO_INCREMENT PRIMARY KEY, +Source TEXT, +Target TEXT, +Flags TEXT, +On_Master TEXT, +On_Slave TEXT, +Expected TEXT, +Compare INT, +Error TEXT); +SELECT @@global.slave_type_conversions; +@@global.slave_type_conversions + +SET GLOBAL SLAVE_TYPE_CONVERSIONS=''; +SELECT @@global.slave_type_conversions; +@@global.slave_type_conversions + +SET GLOBAL SLAVE_TYPE_CONVERSIONS='ALL_NON_LOSSY'; +SELECT @@global.slave_type_conversions; +@@global.slave_type_conversions +ALL_NON_LOSSY +SET GLOBAL SLAVE_TYPE_CONVERSIONS='ALL_LOSSY'; +SELECT @@global.slave_type_conversions; +@@global.slave_type_conversions +ALL_LOSSY +SET GLOBAL SLAVE_TYPE_CONVERSIONS='ALL_LOSSY,ALL_NON_LOSSY'; +SELECT @@global.slave_type_conversions; +@@global.slave_type_conversions +ALL_LOSSY,ALL_NON_LOSSY +SET GLOBAL SLAVE_TYPE_CONVERSIONS='ALL_LOSSY,ALL_NON_LOSSY,NONEXISTING_BIT'; +ERROR 42000: Variable 'slave_type_conversions' can't be set to the value of 'NONEXISTING_BIT' +SELECT @@global.slave_type_conversions; +@@global.slave_type_conversions +ALL_LOSSY,ALL_NON_LOSSY +connection slave; +SET GLOBAL SLAVE_TYPE_CONVERSIONS=''; +**** Running tests with @@SLAVE_TYPE_CONVERSIONS = '' **** +include/rpl_reset.inc +connection slave; +SET GLOBAL SLAVE_TYPE_CONVERSIONS='ALL_NON_LOSSY'; +**** Running tests with @@SLAVE_TYPE_CONVERSIONS = 'ALL_NON_LOSSY' **** +include/rpl_reset.inc +connection slave; +SET GLOBAL SLAVE_TYPE_CONVERSIONS='ALL_LOSSY'; +**** Running tests with @@SLAVE_TYPE_CONVERSIONS = 'ALL_LOSSY' **** +include/rpl_reset.inc +connection slave; +SET GLOBAL SLAVE_TYPE_CONVERSIONS='ALL_LOSSY,ALL_NON_LOSSY'; +**** Running tests with @@SLAVE_TYPE_CONVERSIONS = 'ALL_LOSSY,ALL_NON_LOSSY' **** +include/rpl_reset.inc +connection slave; +**** Result of conversions **** +Source_Type Target_Type All_Type_Conversion_Flags Value_On_Slave +TINYBLOB TINYBLOB <Correct value> +TINYBLOB BLOB <Correct error> +TINYBLOB MEDIUMBLOB <Correct error> +TINYBLOB LONGBLOB <Correct error> +BLOB TINYBLOB <Correct error> +BLOB BLOB <Correct value> +BLOB MEDIUMBLOB <Correct error> +BLOB LONGBLOB <Correct error> +MEDIUMBLOB TINYBLOB <Correct error> +MEDIUMBLOB BLOB <Correct error> +MEDIUMBLOB MEDIUMBLOB <Correct value> +MEDIUMBLOB LONGBLOB <Correct error> +LONGBLOB TINYBLOB <Correct error> +LONGBLOB BLOB <Correct error> +LONGBLOB MEDIUMBLOB <Correct error> +LONGBLOB LONGBLOB <Correct value> +GEOMETRY BLOB <Correct error> +BLOB GEOMETRY <Correct error> +GEOMETRY GEOMETRY <Correct value> +BIT(1) BIT(1) <Correct value> +DATE DATE <Correct value> +ENUM('master',' ENUM('master',' <Correct value> +CHAR(10) ENUM('master',' <Correct error> +CHAR(10) SET('master','s <Correct error> +ENUM('master',' CHAR(10) <Correct error> +SET('master','s CHAR(10) <Correct error> +SET('master','s SET('master','s <Correct value> +SET('master','s SET('master','s <Correct value> +SET('0','1','2' SET('0','1','2' <Correct value> +SET('0','1','2' SET('0','1','2' <Correct error> +SET('0','1','2' SET('0','1','2' <Correct error> +SET('0','1','2' SET('0','1','2' <Correct error> +TINYINT TINYINT <Correct value> +TINYINT SMALLINT <Correct error> +TINYINT MEDIUMINT <Correct error> +TINYINT INT <Correct error> +TINYINT BIGINT <Correct error> +SMALLINT TINYINT <Correct error> +SMALLINT TINYINT <Correct error> +SMALLINT TINYINT UNSIGNE <Correct error> +SMALLINT SMALLINT <Correct value> +SMALLINT MEDIUMINT <Correct error> +SMALLINT INT <Correct error> +SMALLINT BIGINT <Correct error> +MEDIUMINT TINYINT <Correct error> +MEDIUMINT TINYINT <Correct error> +MEDIUMINT TINYINT UNSIGNE <Correct error> +MEDIUMINT SMALLINT <Correct error> +MEDIUMINT MEDIUMINT <Correct value> +MEDIUMINT INT <Correct error> +MEDIUMINT BIGINT <Correct error> +INT TINYINT <Correct error> +INT TINYINT <Correct error> +INT TINYINT UNSIGNE <Correct error> +INT SMALLINT <Correct error> +INT MEDIUMINT <Correct error> +INT INT <Correct value> +INT BIGINT <Correct error> +BIGINT TINYINT <Correct error> +BIGINT SMALLINT <Correct error> +BIGINT MEDIUMINT <Correct error> +BIGINT INT <Correct error> +BIGINT BIGINT <Correct value> +CHAR(20) CHAR(20) <Correct value> +CHAR(20) CHAR(30) <Correct error> +CHAR(20) CHAR(10) <Correct error> +CHAR(20) VARCHAR(20) <Correct error> +CHAR(20) VARCHAR(30) <Correct error> +CHAR(20) VARCHAR(10) <Correct error> +CHAR(20) TINYTEXT <Correct error> +CHAR(20) TEXT <Correct error> +CHAR(20) MEDIUMTEXT <Correct error> +CHAR(20) LONGTEXT <Correct error> +VARCHAR(20) VARCHAR(20) <Correct value> +VARCHAR(20) VARCHAR(30) <Correct error> +VARCHAR(20) VARCHAR(10) <Correct error> +VARCHAR(20) CHAR(30) <Correct error> +VARCHAR(20) CHAR(10) <Correct error> +VARCHAR(20) TINYTEXT <Correct error> +VARCHAR(20) TEXT <Correct error> +VARCHAR(20) MEDIUMTEXT <Correct error> +VARCHAR(20) LONGTEXT <Correct error> +VARCHAR(500) VARCHAR(500) <Correct value> +VARCHAR(500) VARCHAR(510) <Correct error> +VARCHAR(500) VARCHAR(255) <Correct error> +VARCHAR(500) TINYTEXT <Correct error> +VARCHAR(500) TEXT <Correct error> +VARCHAR(500) MEDIUMTEXT <Correct error> +VARCHAR(500) LONGTEXT <Correct error> +TINYTEXT VARCHAR(500) <Correct error> +TEXT VARCHAR(500) <Correct error> +MEDIUMTEXT VARCHAR(500) <Correct error> +LONGTEXT VARCHAR(500) <Correct error> +TINYTEXT CHAR(255) <Correct error> +TINYTEXT CHAR(250) <Correct error> +TEXT CHAR(255) <Correct error> +MEDIUMTEXT CHAR(255) <Correct error> +LONGTEXT CHAR(255) <Correct error> +TINYTEXT TINYTEXT <Correct value> +TINYTEXT TEXT <Correct error> +TEXT TINYTEXT <Correct error> +DECIMAL(10,5) DECIMAL(10,5) <Correct value> +DECIMAL(10,5) DECIMAL(10,6) <Correct error> +DECIMAL(10,5) DECIMAL(11,5) <Correct error> +DECIMAL(10,5) DECIMAL(11,6) <Correct error> +DECIMAL(10,5) DECIMAL(10,4) <Correct error> +DECIMAL(10,5) DECIMAL(9,5) <Correct error> +DECIMAL(10,5) DECIMAL(9,4) <Correct error> +FLOAT DECIMAL(10,5) <Correct error> +DOUBLE DECIMAL(10,5) <Correct error> +DECIMAL(10,5) FLOAT <Correct error> +DECIMAL(10,5) DOUBLE <Correct error> +FLOAT FLOAT <Correct value> +DOUBLE DOUBLE <Correct value> +FLOAT DOUBLE <Correct error> +DOUBLE FLOAT <Correct error> +BIT(5) BIT(5) <Correct value> +BIT(5) BIT(6) <Correct error> +BIT(6) BIT(5) <Correct error> +BIT(5) BIT(12) <Correct error> +BIT(12) BIT(5) <Correct error> +TINYBLOB TINYBLOB ALL_NON_LOSSY <Correct value> +TINYBLOB BLOB ALL_NON_LOSSY <Correct value> +TINYBLOB MEDIUMBLOB ALL_NON_LOSSY <Correct value> +TINYBLOB LONGBLOB ALL_NON_LOSSY <Correct value> +BLOB TINYBLOB ALL_NON_LOSSY <Correct error> +BLOB BLOB ALL_NON_LOSSY <Correct value> +BLOB MEDIUMBLOB ALL_NON_LOSSY <Correct value> +BLOB LONGBLOB ALL_NON_LOSSY <Correct value> +MEDIUMBLOB TINYBLOB ALL_NON_LOSSY <Correct error> +MEDIUMBLOB BLOB ALL_NON_LOSSY <Correct error> +MEDIUMBLOB MEDIUMBLOB ALL_NON_LOSSY <Correct value> +MEDIUMBLOB LONGBLOB ALL_NON_LOSSY <Correct value> +LONGBLOB TINYBLOB ALL_NON_LOSSY <Correct error> +LONGBLOB BLOB ALL_NON_LOSSY <Correct error> +LONGBLOB MEDIUMBLOB ALL_NON_LOSSY <Correct error> +LONGBLOB LONGBLOB ALL_NON_LOSSY <Correct value> +GEOMETRY BLOB ALL_NON_LOSSY <Correct error> +BLOB GEOMETRY ALL_NON_LOSSY <Correct error> +GEOMETRY GEOMETRY ALL_NON_LOSSY <Correct value> +BIT(1) BIT(1) ALL_NON_LOSSY <Correct value> +DATE DATE ALL_NON_LOSSY <Correct value> +ENUM('master',' ENUM('master',' ALL_NON_LOSSY <Correct value> +CHAR(10) ENUM('master',' ALL_NON_LOSSY <Correct error> +CHAR(10) SET('master','s ALL_NON_LOSSY <Correct error> +ENUM('master',' CHAR(10) ALL_NON_LOSSY <Correct error> +SET('master','s CHAR(10) ALL_NON_LOSSY <Correct error> +SET('master','s SET('master','s ALL_NON_LOSSY <Correct value> +SET('master','s SET('master','s ALL_NON_LOSSY <Correct value> +SET('0','1','2' SET('0','1','2' ALL_NON_LOSSY <Correct value> +SET('0','1','2' SET('0','1','2' ALL_NON_LOSSY <Correct value> +SET('0','1','2' SET('0','1','2' ALL_NON_LOSSY <Correct error> +SET('0','1','2' SET('0','1','2' ALL_NON_LOSSY <Correct error> +TINYINT TINYINT ALL_NON_LOSSY <Correct value> +TINYINT SMALLINT ALL_NON_LOSSY <Correct value> +TINYINT MEDIUMINT ALL_NON_LOSSY <Correct value> +TINYINT INT ALL_NON_LOSSY <Correct value> +TINYINT BIGINT ALL_NON_LOSSY <Correct value> +SMALLINT TINYINT ALL_NON_LOSSY <Correct error> +SMALLINT TINYINT ALL_NON_LOSSY <Correct error> +SMALLINT TINYINT UNSIGNE ALL_NON_LOSSY <Correct error> +SMALLINT SMALLINT ALL_NON_LOSSY <Correct value> +SMALLINT MEDIUMINT ALL_NON_LOSSY <Correct value> +SMALLINT INT ALL_NON_LOSSY <Correct value> +SMALLINT BIGINT ALL_NON_LOSSY <Correct value> +MEDIUMINT TINYINT ALL_NON_LOSSY <Correct error> +MEDIUMINT TINYINT ALL_NON_LOSSY <Correct error> +MEDIUMINT TINYINT UNSIGNE ALL_NON_LOSSY <Correct error> +MEDIUMINT SMALLINT ALL_NON_LOSSY <Correct error> +MEDIUMINT MEDIUMINT ALL_NON_LOSSY <Correct value> +MEDIUMINT INT ALL_NON_LOSSY <Correct value> +MEDIUMINT BIGINT ALL_NON_LOSSY <Correct value> +INT TINYINT ALL_NON_LOSSY <Correct error> +INT TINYINT ALL_NON_LOSSY <Correct error> +INT TINYINT UNSIGNE ALL_NON_LOSSY <Correct error> +INT SMALLINT ALL_NON_LOSSY <Correct error> +INT MEDIUMINT ALL_NON_LOSSY <Correct error> +INT INT ALL_NON_LOSSY <Correct value> +INT BIGINT ALL_NON_LOSSY <Correct value> +BIGINT TINYINT ALL_NON_LOSSY <Correct error> +BIGINT SMALLINT ALL_NON_LOSSY <Correct error> +BIGINT MEDIUMINT ALL_NON_LOSSY <Correct error> +BIGINT INT ALL_NON_LOSSY <Correct error> +BIGINT BIGINT ALL_NON_LOSSY <Correct value> +CHAR(20) CHAR(20) ALL_NON_LOSSY <Correct value> +CHAR(20) CHAR(30) ALL_NON_LOSSY <Correct value> +CHAR(20) CHAR(10) ALL_NON_LOSSY <Correct error> +CHAR(20) VARCHAR(20) ALL_NON_LOSSY <Correct value> +CHAR(20) VARCHAR(30) ALL_NON_LOSSY <Correct value> +CHAR(20) VARCHAR(10) ALL_NON_LOSSY <Correct error> +CHAR(20) TINYTEXT ALL_NON_LOSSY <Correct value> +CHAR(20) TEXT ALL_NON_LOSSY <Correct value> +CHAR(20) MEDIUMTEXT ALL_NON_LOSSY <Correct value> +CHAR(20) LONGTEXT ALL_NON_LOSSY <Correct value> +VARCHAR(20) VARCHAR(20) ALL_NON_LOSSY <Correct value> +VARCHAR(20) VARCHAR(30) ALL_NON_LOSSY <Correct value> +VARCHAR(20) VARCHAR(10) ALL_NON_LOSSY <Correct error> +VARCHAR(20) CHAR(30) ALL_NON_LOSSY <Correct value> +VARCHAR(20) CHAR(10) ALL_NON_LOSSY <Correct error> +VARCHAR(20) TINYTEXT ALL_NON_LOSSY <Correct value> +VARCHAR(20) TEXT ALL_NON_LOSSY <Correct value> +VARCHAR(20) MEDIUMTEXT ALL_NON_LOSSY <Correct value> +VARCHAR(20) LONGTEXT ALL_NON_LOSSY <Correct value> +VARCHAR(500) VARCHAR(500) ALL_NON_LOSSY <Correct value> +VARCHAR(500) VARCHAR(510) ALL_NON_LOSSY <Correct value> +VARCHAR(500) VARCHAR(255) ALL_NON_LOSSY <Correct error> +VARCHAR(500) TINYTEXT ALL_NON_LOSSY <Correct error> +VARCHAR(500) TEXT ALL_NON_LOSSY <Correct value> +VARCHAR(500) MEDIUMTEXT ALL_NON_LOSSY <Correct value> +VARCHAR(500) LONGTEXT ALL_NON_LOSSY <Correct value> +TINYTEXT VARCHAR(500) ALL_NON_LOSSY <Correct value> +TEXT VARCHAR(500) ALL_NON_LOSSY <Correct error> +MEDIUMTEXT VARCHAR(500) ALL_NON_LOSSY <Correct error> +LONGTEXT VARCHAR(500) ALL_NON_LOSSY <Correct error> +TINYTEXT CHAR(255) ALL_NON_LOSSY <Correct value> +TINYTEXT CHAR(250) ALL_NON_LOSSY <Correct error> +TEXT CHAR(255) ALL_NON_LOSSY <Correct error> +MEDIUMTEXT CHAR(255) ALL_NON_LOSSY <Correct error> +LONGTEXT CHAR(255) ALL_NON_LOSSY <Correct error> +TINYTEXT TINYTEXT ALL_NON_LOSSY <Correct value> +TINYTEXT TEXT ALL_NON_LOSSY <Correct value> +TEXT TINYTEXT ALL_NON_LOSSY <Correct error> +DECIMAL(10,5) DECIMAL(10,5) ALL_NON_LOSSY <Correct value> +DECIMAL(10,5) DECIMAL(10,6) ALL_NON_LOSSY <Correct value> +DECIMAL(10,5) DECIMAL(11,5) ALL_NON_LOSSY <Correct value> +DECIMAL(10,5) DECIMAL(11,6) ALL_NON_LOSSY <Correct value> +DECIMAL(10,5) DECIMAL(10,4) ALL_NON_LOSSY <Correct error> +DECIMAL(10,5) DECIMAL(9,5) ALL_NON_LOSSY <Correct error> +DECIMAL(10,5) DECIMAL(9,4) ALL_NON_LOSSY <Correct error> +FLOAT DECIMAL(10,5) ALL_NON_LOSSY <Correct error> +DOUBLE DECIMAL(10,5) ALL_NON_LOSSY <Correct error> +DECIMAL(10,5) FLOAT ALL_NON_LOSSY <Correct error> +DECIMAL(10,5) DOUBLE ALL_NON_LOSSY <Correct error> +FLOAT FLOAT ALL_NON_LOSSY <Correct value> +DOUBLE DOUBLE ALL_NON_LOSSY <Correct value> +FLOAT DOUBLE ALL_NON_LOSSY <Correct value> +DOUBLE FLOAT ALL_NON_LOSSY <Correct error> +BIT(5) BIT(5) ALL_NON_LOSSY <Correct value> +BIT(5) BIT(6) ALL_NON_LOSSY <Correct value> +BIT(6) BIT(5) ALL_NON_LOSSY <Correct error> +BIT(5) BIT(12) ALL_NON_LOSSY <Correct value> +BIT(12) BIT(5) ALL_NON_LOSSY <Correct error> +TINYBLOB TINYBLOB ALL_LOSSY <Correct value> +TINYBLOB BLOB ALL_LOSSY <Correct error> +TINYBLOB MEDIUMBLOB ALL_LOSSY <Correct error> +TINYBLOB LONGBLOB ALL_LOSSY <Correct error> +BLOB TINYBLOB ALL_LOSSY <Correct value> +BLOB BLOB ALL_LOSSY <Correct value> +BLOB MEDIUMBLOB ALL_LOSSY <Correct error> +BLOB LONGBLOB ALL_LOSSY <Correct error> +MEDIUMBLOB TINYBLOB ALL_LOSSY <Correct value> +MEDIUMBLOB BLOB ALL_LOSSY <Correct value> +MEDIUMBLOB MEDIUMBLOB ALL_LOSSY <Correct value> +MEDIUMBLOB LONGBLOB ALL_LOSSY <Correct error> +LONGBLOB TINYBLOB ALL_LOSSY <Correct value> +LONGBLOB BLOB ALL_LOSSY <Correct value> +LONGBLOB MEDIUMBLOB ALL_LOSSY <Correct value> +LONGBLOB LONGBLOB ALL_LOSSY <Correct value> +GEOMETRY BLOB ALL_LOSSY <Correct error> +BLOB GEOMETRY ALL_LOSSY <Correct error> +GEOMETRY GEOMETRY ALL_LOSSY <Correct value> +BIT(1) BIT(1) ALL_LOSSY <Correct value> +DATE DATE ALL_LOSSY <Correct value> +ENUM('master',' ENUM('master',' ALL_LOSSY <Correct value> +CHAR(10) ENUM('master',' ALL_LOSSY <Correct error> +CHAR(10) SET('master','s ALL_LOSSY <Correct error> +ENUM('master',' CHAR(10) ALL_LOSSY <Correct error> +SET('master','s CHAR(10) ALL_LOSSY <Correct error> +SET('master','s SET('master','s ALL_LOSSY <Correct value> +SET('master','s SET('master','s ALL_LOSSY <Correct value> +SET('0','1','2' SET('0','1','2' ALL_LOSSY <Correct value> +SET('0','1','2' SET('0','1','2' ALL_LOSSY <Correct error> +SET('0','1','2' SET('0','1','2' ALL_LOSSY <Correct value> +SET('0','1','2' SET('0','1','2' ALL_LOSSY <Correct value> +TINYINT TINYINT ALL_LOSSY <Correct value> +TINYINT SMALLINT ALL_LOSSY <Correct error> +TINYINT MEDIUMINT ALL_LOSSY <Correct error> +TINYINT INT ALL_LOSSY <Correct error> +TINYINT BIGINT ALL_LOSSY <Correct error> +SMALLINT TINYINT ALL_LOSSY <Correct value> +SMALLINT TINYINT ALL_LOSSY <Correct value> +SMALLINT TINYINT UNSIGNE ALL_LOSSY <Correct value> +SMALLINT SMALLINT ALL_LOSSY <Correct value> +SMALLINT MEDIUMINT ALL_LOSSY <Correct error> +SMALLINT INT ALL_LOSSY <Correct error> +SMALLINT BIGINT ALL_LOSSY <Correct error> +MEDIUMINT TINYINT ALL_LOSSY <Correct value> +MEDIUMINT TINYINT ALL_LOSSY <Correct value> +MEDIUMINT TINYINT UNSIGNE ALL_LOSSY <Correct value> +MEDIUMINT SMALLINT ALL_LOSSY <Correct value> +MEDIUMINT MEDIUMINT ALL_LOSSY <Correct value> +MEDIUMINT INT ALL_LOSSY <Correct error> +MEDIUMINT BIGINT ALL_LOSSY <Correct error> +INT TINYINT ALL_LOSSY <Correct value> +INT TINYINT ALL_LOSSY <Correct value> +INT TINYINT UNSIGNE ALL_LOSSY <Correct value> +INT SMALLINT ALL_LOSSY <Correct value> +INT MEDIUMINT ALL_LOSSY <Correct value> +INT INT ALL_LOSSY <Correct value> +INT BIGINT ALL_LOSSY <Correct error> +BIGINT TINYINT ALL_LOSSY <Correct value> +BIGINT SMALLINT ALL_LOSSY <Correct value> +BIGINT MEDIUMINT ALL_LOSSY <Correct value> +BIGINT INT ALL_LOSSY <Correct value> +BIGINT BIGINT ALL_LOSSY <Correct value> +CHAR(20) CHAR(20) ALL_LOSSY <Correct value> +CHAR(20) CHAR(30) ALL_LOSSY <Correct error> +CHAR(20) CHAR(10) ALL_LOSSY <Correct value> +CHAR(20) VARCHAR(20) ALL_LOSSY <Correct error> +CHAR(20) VARCHAR(30) ALL_LOSSY <Correct error> +CHAR(20) VARCHAR(10) ALL_LOSSY <Correct value> +CHAR(20) TINYTEXT ALL_LOSSY <Correct error> +CHAR(20) TEXT ALL_LOSSY <Correct error> +CHAR(20) MEDIUMTEXT ALL_LOSSY <Correct error> +CHAR(20) LONGTEXT ALL_LOSSY <Correct error> +VARCHAR(20) VARCHAR(20) ALL_LOSSY <Correct value> +VARCHAR(20) VARCHAR(30) ALL_LOSSY <Correct error> +VARCHAR(20) VARCHAR(10) ALL_LOSSY <Correct value> +VARCHAR(20) CHAR(30) ALL_LOSSY <Correct error> +VARCHAR(20) CHAR(10) ALL_LOSSY <Correct value> +VARCHAR(20) TINYTEXT ALL_LOSSY <Correct error> +VARCHAR(20) TEXT ALL_LOSSY <Correct error> +VARCHAR(20) MEDIUMTEXT ALL_LOSSY <Correct error> +VARCHAR(20) LONGTEXT ALL_LOSSY <Correct error> +VARCHAR(500) VARCHAR(500) ALL_LOSSY <Correct value> +VARCHAR(500) VARCHAR(510) ALL_LOSSY <Correct error> +VARCHAR(500) VARCHAR(255) ALL_LOSSY <Correct value> +VARCHAR(500) TINYTEXT ALL_LOSSY <Correct value> +VARCHAR(500) TEXT ALL_LOSSY <Correct error> +VARCHAR(500) MEDIUMTEXT ALL_LOSSY <Correct error> +VARCHAR(500) LONGTEXT ALL_LOSSY <Correct error> +TINYTEXT VARCHAR(500) ALL_LOSSY <Correct error> +TEXT VARCHAR(500) ALL_LOSSY <Correct value> +MEDIUMTEXT VARCHAR(500) ALL_LOSSY <Correct value> +LONGTEXT VARCHAR(500) ALL_LOSSY <Correct value> +TINYTEXT CHAR(255) ALL_LOSSY <Correct error> +TINYTEXT CHAR(250) ALL_LOSSY <Correct value> +TEXT CHAR(255) ALL_LOSSY <Correct value> +MEDIUMTEXT CHAR(255) ALL_LOSSY <Correct value> +LONGTEXT CHAR(255) ALL_LOSSY <Correct value> +TINYTEXT TINYTEXT ALL_LOSSY <Correct value> +TINYTEXT TEXT ALL_LOSSY <Correct error> +TEXT TINYTEXT ALL_LOSSY <Correct value> +DECIMAL(10,5) DECIMAL(10,5) ALL_LOSSY <Correct value> +DECIMAL(10,5) DECIMAL(10,6) ALL_LOSSY <Correct error> +DECIMAL(10,5) DECIMAL(11,5) ALL_LOSSY <Correct error> +DECIMAL(10,5) DECIMAL(11,6) ALL_LOSSY <Correct error> +DECIMAL(10,5) DECIMAL(10,4) ALL_LOSSY <Correct value> +DECIMAL(10,5) DECIMAL(9,5) ALL_LOSSY <Correct value> +DECIMAL(10,5) DECIMAL(9,4) ALL_LOSSY <Correct value> +FLOAT DECIMAL(10,5) ALL_LOSSY <Correct value> +DOUBLE DECIMAL(10,5) ALL_LOSSY <Correct value> +DECIMAL(10,5) FLOAT ALL_LOSSY <Correct value> +DECIMAL(10,5) DOUBLE ALL_LOSSY <Correct value> +FLOAT FLOAT ALL_LOSSY <Correct value> +DOUBLE DOUBLE ALL_LOSSY <Correct value> +FLOAT DOUBLE ALL_LOSSY <Correct error> +DOUBLE FLOAT ALL_LOSSY <Correct value> +BIT(5) BIT(5) ALL_LOSSY <Correct value> +BIT(5) BIT(6) ALL_LOSSY <Correct error> +BIT(6) BIT(5) ALL_LOSSY <Correct value> +BIT(5) BIT(12) ALL_LOSSY <Correct error> +BIT(12) BIT(5) ALL_LOSSY <Correct value> +TINYBLOB TINYBLOB ALL_LOSSY,ALL_NON_LOSSY <Correct value> +TINYBLOB BLOB ALL_LOSSY,ALL_NON_LOSSY <Correct value> +TINYBLOB MEDIUMBLOB ALL_LOSSY,ALL_NON_LOSSY <Correct value> +TINYBLOB LONGBLOB ALL_LOSSY,ALL_NON_LOSSY <Correct value> +BLOB TINYBLOB ALL_LOSSY,ALL_NON_LOSSY <Correct value> +BLOB BLOB ALL_LOSSY,ALL_NON_LOSSY <Correct value> +BLOB MEDIUMBLOB ALL_LOSSY,ALL_NON_LOSSY <Correct value> +BLOB LONGBLOB ALL_LOSSY,ALL_NON_LOSSY <Correct value> +MEDIUMBLOB TINYBLOB ALL_LOSSY,ALL_NON_LOSSY <Correct value> +MEDIUMBLOB BLOB ALL_LOSSY,ALL_NON_LOSSY <Correct value> +MEDIUMBLOB MEDIUMBLOB ALL_LOSSY,ALL_NON_LOSSY <Correct value> +MEDIUMBLOB LONGBLOB ALL_LOSSY,ALL_NON_LOSSY <Correct value> +LONGBLOB TINYBLOB ALL_LOSSY,ALL_NON_LOSSY <Correct value> +LONGBLOB BLOB ALL_LOSSY,ALL_NON_LOSSY <Correct value> +LONGBLOB MEDIUMBLOB ALL_LOSSY,ALL_NON_LOSSY <Correct value> +LONGBLOB LONGBLOB ALL_LOSSY,ALL_NON_LOSSY <Correct value> +GEOMETRY BLOB ALL_LOSSY,ALL_NON_LOSSY <Correct error> +BLOB GEOMETRY ALL_LOSSY,ALL_NON_LOSSY <Correct error> +GEOMETRY GEOMETRY ALL_LOSSY,ALL_NON_LOSSY <Correct value> +BIT(1) BIT(1) ALL_LOSSY,ALL_NON_LOSSY <Correct value> +DATE DATE ALL_LOSSY,ALL_NON_LOSSY <Correct value> +ENUM('master',' ENUM('master',' ALL_LOSSY,ALL_NON_LOSSY <Correct value> +CHAR(10) ENUM('master',' ALL_LOSSY,ALL_NON_LOSSY <Correct error> +CHAR(10) SET('master','s ALL_LOSSY,ALL_NON_LOSSY <Correct error> +ENUM('master',' CHAR(10) ALL_LOSSY,ALL_NON_LOSSY <Correct error> +SET('master','s CHAR(10) ALL_LOSSY,ALL_NON_LOSSY <Correct error> +SET('master','s SET('master','s ALL_LOSSY,ALL_NON_LOSSY <Correct value> +SET('master','s SET('master','s ALL_LOSSY,ALL_NON_LOSSY <Correct value> +SET('0','1','2' SET('0','1','2' ALL_LOSSY,ALL_NON_LOSSY <Correct value> +SET('0','1','2' SET('0','1','2' ALL_LOSSY,ALL_NON_LOSSY <Correct value> +SET('0','1','2' SET('0','1','2' ALL_LOSSY,ALL_NON_LOSSY <Correct value> +SET('0','1','2' SET('0','1','2' ALL_LOSSY,ALL_NON_LOSSY <Correct value> +TINYINT TINYINT ALL_LOSSY,ALL_NON_LOSSY <Correct value> +TINYINT SMALLINT ALL_LOSSY,ALL_NON_LOSSY <Correct value> +TINYINT MEDIUMINT ALL_LOSSY,ALL_NON_LOSSY <Correct value> +TINYINT INT ALL_LOSSY,ALL_NON_LOSSY <Correct value> +TINYINT BIGINT ALL_LOSSY,ALL_NON_LOSSY <Correct value> +SMALLINT TINYINT ALL_LOSSY,ALL_NON_LOSSY <Correct value> +SMALLINT TINYINT ALL_LOSSY,ALL_NON_LOSSY <Correct value> +SMALLINT TINYINT UNSIGNE ALL_LOSSY,ALL_NON_LOSSY <Correct value> +SMALLINT SMALLINT ALL_LOSSY,ALL_NON_LOSSY <Correct value> +SMALLINT MEDIUMINT ALL_LOSSY,ALL_NON_LOSSY <Correct value> +SMALLINT INT ALL_LOSSY,ALL_NON_LOSSY <Correct value> +SMALLINT BIGINT ALL_LOSSY,ALL_NON_LOSSY <Correct value> +MEDIUMINT TINYINT ALL_LOSSY,ALL_NON_LOSSY <Correct value> +MEDIUMINT TINYINT ALL_LOSSY,ALL_NON_LOSSY <Correct value> +MEDIUMINT TINYINT UNSIGNE ALL_LOSSY,ALL_NON_LOSSY <Correct value> +MEDIUMINT SMALLINT ALL_LOSSY,ALL_NON_LOSSY <Correct value> +MEDIUMINT MEDIUMINT ALL_LOSSY,ALL_NON_LOSSY <Correct value> +MEDIUMINT INT ALL_LOSSY,ALL_NON_LOSSY <Correct value> +MEDIUMINT BIGINT ALL_LOSSY,ALL_NON_LOSSY <Correct value> +INT TINYINT ALL_LOSSY,ALL_NON_LOSSY <Correct value> +INT TINYINT ALL_LOSSY,ALL_NON_LOSSY <Correct value> +INT TINYINT UNSIGNE ALL_LOSSY,ALL_NON_LOSSY <Correct value> +INT SMALLINT ALL_LOSSY,ALL_NON_LOSSY <Correct value> +INT MEDIUMINT ALL_LOSSY,ALL_NON_LOSSY <Correct value> +INT INT ALL_LOSSY,ALL_NON_LOSSY <Correct value> +INT BIGINT ALL_LOSSY,ALL_NON_LOSSY <Correct value> +BIGINT TINYINT ALL_LOSSY,ALL_NON_LOSSY <Correct value> +BIGINT SMALLINT ALL_LOSSY,ALL_NON_LOSSY <Correct value> +BIGINT MEDIUMINT ALL_LOSSY,ALL_NON_LOSSY <Correct value> +BIGINT INT ALL_LOSSY,ALL_NON_LOSSY <Correct value> +BIGINT BIGINT ALL_LOSSY,ALL_NON_LOSSY <Correct value> +CHAR(20) CHAR(20) ALL_LOSSY,ALL_NON_LOSSY <Correct value> +CHAR(20) CHAR(30) ALL_LOSSY,ALL_NON_LOSSY <Correct value> +CHAR(20) CHAR(10) ALL_LOSSY,ALL_NON_LOSSY <Correct value> +CHAR(20) VARCHAR(20) ALL_LOSSY,ALL_NON_LOSSY <Correct value> +CHAR(20) VARCHAR(30) ALL_LOSSY,ALL_NON_LOSSY <Correct value> +CHAR(20) VARCHAR(10) ALL_LOSSY,ALL_NON_LOSSY <Correct value> +CHAR(20) TINYTEXT ALL_LOSSY,ALL_NON_LOSSY <Correct value> +CHAR(20) TEXT ALL_LOSSY,ALL_NON_LOSSY <Correct value> +CHAR(20) MEDIUMTEXT ALL_LOSSY,ALL_NON_LOSSY <Correct value> +CHAR(20) LONGTEXT ALL_LOSSY,ALL_NON_LOSSY <Correct value> +VARCHAR(20) VARCHAR(20) ALL_LOSSY,ALL_NON_LOSSY <Correct value> +VARCHAR(20) VARCHAR(30) ALL_LOSSY,ALL_NON_LOSSY <Correct value> +VARCHAR(20) VARCHAR(10) ALL_LOSSY,ALL_NON_LOSSY <Correct value> +VARCHAR(20) CHAR(30) ALL_LOSSY,ALL_NON_LOSSY <Correct value> +VARCHAR(20) CHAR(10) ALL_LOSSY,ALL_NON_LOSSY <Correct value> +VARCHAR(20) TINYTEXT ALL_LOSSY,ALL_NON_LOSSY <Correct value> +VARCHAR(20) TEXT ALL_LOSSY,ALL_NON_LOSSY <Correct value> +VARCHAR(20) MEDIUMTEXT ALL_LOSSY,ALL_NON_LOSSY <Correct value> +VARCHAR(20) LONGTEXT ALL_LOSSY,ALL_NON_LOSSY <Correct value> +VARCHAR(500) VARCHAR(500) ALL_LOSSY,ALL_NON_LOSSY <Correct value> +VARCHAR(500) VARCHAR(510) ALL_LOSSY,ALL_NON_LOSSY <Correct value> +VARCHAR(500) VARCHAR(255) ALL_LOSSY,ALL_NON_LOSSY <Correct value> +VARCHAR(500) TINYTEXT ALL_LOSSY,ALL_NON_LOSSY <Correct value> +VARCHAR(500) TEXT ALL_LOSSY,ALL_NON_LOSSY <Correct value> +VARCHAR(500) MEDIUMTEXT ALL_LOSSY,ALL_NON_LOSSY <Correct value> +VARCHAR(500) LONGTEXT ALL_LOSSY,ALL_NON_LOSSY <Correct value> +TINYTEXT VARCHAR(500) ALL_LOSSY,ALL_NON_LOSSY <Correct value> +TEXT VARCHAR(500) ALL_LOSSY,ALL_NON_LOSSY <Correct value> +MEDIUMTEXT VARCHAR(500) ALL_LOSSY,ALL_NON_LOSSY <Correct value> +LONGTEXT VARCHAR(500) ALL_LOSSY,ALL_NON_LOSSY <Correct value> +TINYTEXT CHAR(255) ALL_LOSSY,ALL_NON_LOSSY <Correct value> +TINYTEXT CHAR(250) ALL_LOSSY,ALL_NON_LOSSY <Correct value> +TEXT CHAR(255) ALL_LOSSY,ALL_NON_LOSSY <Correct value> +MEDIUMTEXT CHAR(255) ALL_LOSSY,ALL_NON_LOSSY <Correct value> +LONGTEXT CHAR(255) ALL_LOSSY,ALL_NON_LOSSY <Correct value> +TINYTEXT TINYTEXT ALL_LOSSY,ALL_NON_LOSSY <Correct value> +TINYTEXT TEXT ALL_LOSSY,ALL_NON_LOSSY <Correct value> +TEXT TINYTEXT ALL_LOSSY,ALL_NON_LOSSY <Correct value> +DECIMAL(10,5) DECIMAL(10,5) ALL_LOSSY,ALL_NON_LOSSY <Correct value> +DECIMAL(10,5) DECIMAL(10,6) ALL_LOSSY,ALL_NON_LOSSY <Correct value> +DECIMAL(10,5) DECIMAL(11,5) ALL_LOSSY,ALL_NON_LOSSY <Correct value> +DECIMAL(10,5) DECIMAL(11,6) ALL_LOSSY,ALL_NON_LOSSY <Correct value> +DECIMAL(10,5) DECIMAL(10,4) ALL_LOSSY,ALL_NON_LOSSY <Correct value> +DECIMAL(10,5) DECIMAL(9,5) ALL_LOSSY,ALL_NON_LOSSY <Correct value> +DECIMAL(10,5) DECIMAL(9,4) ALL_LOSSY,ALL_NON_LOSSY <Correct value> +FLOAT DECIMAL(10,5) ALL_LOSSY,ALL_NON_LOSSY <Correct value> +DOUBLE DECIMAL(10,5) ALL_LOSSY,ALL_NON_LOSSY <Correct value> +DECIMAL(10,5) FLOAT ALL_LOSSY,ALL_NON_LOSSY <Correct value> +DECIMAL(10,5) DOUBLE ALL_LOSSY,ALL_NON_LOSSY <Correct value> +FLOAT FLOAT ALL_LOSSY,ALL_NON_LOSSY <Correct value> +DOUBLE DOUBLE ALL_LOSSY,ALL_NON_LOSSY <Correct value> +FLOAT DOUBLE ALL_LOSSY,ALL_NON_LOSSY <Correct value> +DOUBLE FLOAT ALL_LOSSY,ALL_NON_LOSSY <Correct value> +BIT(5) BIT(5) ALL_LOSSY,ALL_NON_LOSSY <Correct value> +BIT(5) BIT(6) ALL_LOSSY,ALL_NON_LOSSY <Correct value> +BIT(6) BIT(5) ALL_LOSSY,ALL_NON_LOSSY <Correct value> +BIT(5) BIT(12) ALL_LOSSY,ALL_NON_LOSSY <Correct value> +BIT(12) BIT(5) ALL_LOSSY,ALL_NON_LOSSY <Correct value> +DROP TABLE type_conversions; +call mtr.add_suppression("Slave SQL.*Column 1 of table .test.t1. cannot be converted from type.* error.* 1677"); +connection master; +DROP TABLE t1; +connection slave; +set global slave_type_conversions = @saved_slave_type_conversions; +include/rpl_end.inc diff --git a/mysql-test/suite/binlog_encryption/rpl_typeconv.test b/mysql-test/suite/binlog_encryption/rpl_typeconv.test new file mode 100644 index 0000000..9d565c4 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/rpl_typeconv.test @@ -0,0 +1,81 @@ +# +# The test was taken from the rpl suite as is +# + +--enable_connect_log + +--disable_connect_log +--source include/have_binlog_format_row.inc +--source include/master-slave.inc +--enable_connect_log + +connection slave; +set @saved_slave_type_conversions = @@global.slave_type_conversions; +CREATE TABLE type_conversions ( + TestNo INT AUTO_INCREMENT PRIMARY KEY, + Source TEXT, + Target TEXT, + Flags TEXT, + On_Master TEXT, + On_Slave TEXT, + Expected TEXT, + Compare INT, + Error TEXT); + +SELECT @@global.slave_type_conversions; +SET GLOBAL SLAVE_TYPE_CONVERSIONS=''; +SELECT @@global.slave_type_conversions; +SET GLOBAL SLAVE_TYPE_CONVERSIONS='ALL_NON_LOSSY'; +SELECT @@global.slave_type_conversions; +SET GLOBAL SLAVE_TYPE_CONVERSIONS='ALL_LOSSY'; +SELECT @@global.slave_type_conversions; +SET GLOBAL SLAVE_TYPE_CONVERSIONS='ALL_LOSSY,ALL_NON_LOSSY'; +SELECT @@global.slave_type_conversions; +--error ER_WRONG_VALUE_FOR_VAR +SET GLOBAL SLAVE_TYPE_CONVERSIONS='ALL_LOSSY,ALL_NON_LOSSY,NONEXISTING_BIT'; +SELECT @@global.slave_type_conversions; + +# Checking strict interpretation of type conversions +connection slave; +SET GLOBAL SLAVE_TYPE_CONVERSIONS=''; +source extra/rpl_tests/type_conversions.test; + +# Checking lossy integer type conversions +connection slave; +SET GLOBAL SLAVE_TYPE_CONVERSIONS='ALL_NON_LOSSY'; +source extra/rpl_tests/type_conversions.test; + +# Checking non-lossy integer type conversions +connection slave; +SET GLOBAL SLAVE_TYPE_CONVERSIONS='ALL_LOSSY'; +source extra/rpl_tests/type_conversions.test; + +# Checking all type conversions +connection slave; +SET GLOBAL SLAVE_TYPE_CONVERSIONS='ALL_LOSSY,ALL_NON_LOSSY'; +source extra/rpl_tests/type_conversions.test; + +connection slave; +--echo **** Result of conversions **** +disable_query_log; +SELECT RPAD(Source, 15, ' ') AS Source_Type, + RPAD(Target, 15, ' ') AS Target_Type, + RPAD(Flags, 25, ' ') AS All_Type_Conversion_Flags, + IF(Compare IS NULL AND Error IS NOT NULL, '<Correct error>', + IF(Compare, '<Correct value>', + CONCAT("'", On_Slave, "' != '", Expected, "'"))) + AS Value_On_Slave + FROM type_conversions; +enable_query_log; +DROP TABLE type_conversions; + +call mtr.add_suppression("Slave SQL.*Column 1 of table .test.t1. cannot be converted from type.* error.* 1677"); + +connection master; +DROP TABLE t1; +sync_slave_with_master; + +set global slave_type_conversions = @saved_slave_type_conversions; + +--disable_connect_log +--source include/rpl_end.inc diff --git a/mysql-test/suite/binlog_encryption/suite.pm b/mysql-test/suite/binlog_encryption/suite.pm new file mode 100644 index 0000000..f1d5e3a --- /dev/null +++ b/mysql-test/suite/binlog_encryption/suite.pm @@ -0,0 +1,18 @@ +package My::Suite::BinlogEncryption; + +@ISA = qw(My::Suite); + +return "No file key management plugin" unless defined $ENV{FILE_KEY_MANAGEMENT_SO}; + +sub skip_combinations { + my @combinations; + + $skip{'encryption_algorithms.combinations'} = [ 'ctr' ] + unless $::mysqld_variables{'version-ssl-library'} =~ /OpenSSL (\S+)/ + and $1 ge "1.0.1"; + + %skip; +} + +bless { }; + diff --git a/mysql-test/suite/binlog_encryption/testdata.inc b/mysql-test/suite/binlog_encryption/testdata.inc new file mode 100644 index 0000000..f949911 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/testdata.inc @@ -0,0 +1,207 @@ +# +# This include file creates some basic events which should go to the binary log. +# What happens to the binary log depends on the test which calls the file, +# and should be checked from the test. +# +# Names are intentionally long and ugly, to make grepping more reliable. +# +# Some of events are considered unsafe for SBR (not necessarily correctly, +# but here isn't the place to check the logic), so we just suppress the warning. +# +# For those few queries which produce result sets (e.g. ANALYZE, CHECKSUM etc.), +# we don't care about the result, so it will not be printed to the output. + +call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT"); + +# +# Some DDL +# + +CREATE DATABASE database_name_to_encrypt; +USE database_name_to_encrypt; + +CREATE USER user_name_to_encrypt; +GRANT ALL ON database_name_to_encrypt.* TO user_name_to_encrypt; +SET PASSWORD FOR user_name_to_encrypt = PASSWORD('password_to_encrypt'); + +CREATE TABLE innodb_table_name_to_encrypt ( + int_column_name_to_encrypt INT AUTO_INCREMENT PRIMARY KEY, + timestamp_column_name_to_encrypt TIMESTAMP(6) NULL, + blob_column_name_to_encrypt BLOB, + virt_column_name_to_encrypt INT AS (int_column_name_to_encrypt % 10) VIRTUAL, + pers_column_name_to_encrypt INT AS (int_column_name_to_encrypt) PERSISTENT, + INDEX `index_name_to_encrypt`(`timestamp_column_name_to_encrypt`) +) ENGINE=InnoDB + PARTITION BY RANGE (int_column_name_to_encrypt) + SUBPARTITION BY KEY (int_column_name_to_encrypt) + SUBPARTITIONS 2 ( + PARTITION partition0_name_to_encrypt VALUES LESS THAN (100), + PARTITION partition1_name_to_encrypt VALUES LESS THAN (MAXVALUE) + ) +; + +CREATE TABLE myisam_table_name_to_encrypt ( + int_column_name_to_encrypt INT AUTO_INCREMENT PRIMARY KEY, + char_column_name_to_encrypt VARCHAR(255), + datetime_column_name_to_encrypt DATETIME, + text_column_name_to_encrypt TEXT +) ENGINE=MyISAM; + +CREATE TABLE aria_table_name_to_encrypt ( + int_column_name_to_encrypt INT AUTO_INCREMENT PRIMARY KEY, + varchar_column_name_to_encrypt VARCHAR(1024), + enum_column_name_to_encrypt ENUM( + 'enum_value1_to_encrypt', + 'enum_value2_to_encrypt' + ), + timestamp_column_name_to_encrypt TIMESTAMP(6) NULL, + blob_column_name_to_encrypt BLOB +) ENGINE=Aria; + +CREATE TRIGGER trigger_name_to_encrypt + AFTER INSERT ON myisam_table_name_to_encrypt FOR EACH ROW + INSERT INTO aria_table_name_to_encrypt (varchar_column_name_to_encrypt) + VALUES (NEW.char_column_name_to_encrypt); + +CREATE DEFINER=user_name_to_encrypt VIEW view_name_to_encrypt + AS SELECT * FROM innodb_table_name_to_encrypt; + +CREATE FUNCTION func_name_to_encrypt (func_parameter_to_encrypt INT) + RETURNS VARCHAR(64) + RETURN 'func_result_to_encrypt'; + +--delimiter $$ +CREATE PROCEDURE proc_name_to_encrypt ( + IN proc_in_parameter_to_encrypt CHAR(32), + OUT proc_out_parameter_to_encrypt INT +) +BEGIN + DECLARE procvar_name_to_encrypt CHAR(64) DEFAULT 'procvar_val_to_encrypt'; + DECLARE cursor_name_to_encrypt CURSOR FOR + SELECT virt_column_name_to_encrypt FROM innodb_table_name_to_encrypt; + DECLARE EXIT HANDLER FOR NOT FOUND + BEGIN + SET @stmt_var_to_encrypt = CONCAT( + "SELECT + IF (RAND()>0.5,'enum_value2_to_encrypt','enum_value1_to_encrypt') + FROM innodb_table_name_to_encrypt + INTO OUTFILE '", proc_in_parameter_to_encrypt, "'"); + PREPARE stmt_to_encrypt FROM @stmt_var_to_encrypt; + EXECUTE stmt_to_encrypt; + DEALLOCATE PREPARE stmt_to_encrypt; + END; + OPEN cursor_name_to_encrypt; + proc_label_to_encrypt: LOOP + FETCH cursor_name_to_encrypt INTO procvar_name_to_encrypt; + END LOOP; + CLOSE cursor_name_to_encrypt; +END $$ +--delimiter ; + +CREATE SERVER server_name_to_encrypt + FOREIGN DATA WRAPPER mysql + OPTIONS (HOST 'host_name_to_encrypt'); + +--let $_cur_con= $CURRENT_CONNECTION +--connect (con1,localhost,user_name_to_encrypt,password_to_encrypt,database_name_to_encrypt) +CREATE TEMPORARY TABLE tmp_table_name_to_encrypt ( + float_column_name_to_encrypt FLOAT, + binary_column_name_to_encrypt BINARY(64) +); +--disconnect con1 +--connection $_cur_con + +CREATE INDEX index_name_to_encrypt + ON myisam_table_name_to_encrypt (datetime_column_name_to_encrypt); + +ALTER DATABASE database_name_to_encrypt CHARACTER SET utf8; + +ALTER TABLE innodb_table_name_to_encrypt + MODIFY timestamp_column_name_to_encrypt TIMESTAMP NOT NULL + DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP +; + +ALTER ALGORITHM=MERGE VIEW view_name_to_encrypt + AS SELECT * FROM innodb_table_name_to_encrypt; + +RENAME TABLE innodb_table_name_to_encrypt TO new_table_name_to_encrypt; +ALTER TABLE new_table_name_to_encrypt RENAME TO innodb_table_name_to_encrypt; + +# +# Some DML +# + +--disable_warnings + +set @user_var1_to_encrypt= 'dyncol1_val_to_encrypt'; +set @user_var2_to_encrypt= 'dyncol2_name_to_encrypt'; + +INSERT INTO view_name_to_encrypt VALUES + (1, NOW(6), COLUMN_CREATE('dyncol1_name_to_encrypt',@user_var1_to_encrypt), NULL, NULL), + (2, NOW(6), COLUMN_CREATE(@user_var2_to_encrypt,'dyncol2_val_to_encrypt'), NULL, NULL) +; +--delimiter $$ +BEGIN NOT ATOMIC + DECLARE counter_name_to_encrypt INT DEFAULT 0; + START TRANSACTION; + WHILE counter_name_to_encrypt<12 DO + INSERT INTO innodb_table_name_to_encrypt + SELECT NULL, NOW(6), blob_column_name_to_encrypt, NULL, NULL + FROM innodb_table_name_to_encrypt + ORDER BY int_column_name_to_encrypt; + SET counter_name_to_encrypt = counter_name_to_encrypt+1; + END WHILE; + COMMIT; + END +$$ +--delimiter ; + +INSERT INTO myisam_table_name_to_encrypt + SELECT NULL, 'char_literal_to_encrypt', NULL, 'text_to_encrypt'; +INSERT INTO myisam_table_name_to_encrypt (char_column_name_to_encrypt) + SELECT char_column_name_to_encrypt FROM myisam_table_name_to_encrypt; +INSERT INTO myisam_table_name_to_encrypt (char_column_name_to_encrypt) + SELECT char_column_name_to_encrypt FROM myisam_table_name_to_encrypt; +INSERT INTO myisam_table_name_to_encrypt (char_column_name_to_encrypt) + SELECT char_column_name_to_encrypt FROM myisam_table_name_to_encrypt; + +CALL proc_name_to_encrypt('file_name_to_encrypt',@useless_var_to_encrypt); + +TRUNCATE TABLE aria_table_name_to_encrypt; + +LOAD DATA INFILE 'file_name_to_encrypt' INTO TABLE aria_table_name_to_encrypt + (enum_column_name_to_encrypt); + +--let datadir= `SELECT @@datadir` +--replace_result $datadir <DATADIR> +eval LOAD DATA LOCAL INFILE '$datadir/database_name_to_encrypt/file_name_to_encrypt' + INTO TABLE aria_table_name_to_encrypt (enum_column_name_to_encrypt); +--remove_file $datadir/database_name_to_encrypt/file_name_to_encrypt + +UPDATE view_name_to_encrypt SET blob_column_name_to_encrypt = + COLUMN_CREATE('dyncol1_name_to_encrypt',func_name_to_encrypt(0)) +; + +DELETE FROM aria_table_name_to_encrypt ORDER BY int_column_name_to_encrypt LIMIT 10; + +--enable_warnings + +# +# Other statements +# + +--disable_result_log +ANALYZE TABLE myisam_table_name_to_encrypt; +CHECK TABLE aria_table_name_to_encrypt; +CHECKSUM TABLE innodb_table_name_to_encrypt, myisam_table_name_to_encrypt; +--enable_result_log +RENAME USER user_name_to_encrypt to new_user_name_to_encrypt; +REVOKE ALL PRIVILEGES, GRANT OPTION FROM new_user_name_to_encrypt; + +# +# Cleanup +# + +DROP DATABASE database_name_to_encrypt; +DROP USER new_user_name_to_encrypt; +DROP SERVER server_name_to_encrypt; diff --git a/mysql-test/suite/binlog_encryption/testdata.opt b/mysql-test/suite/binlog_encryption/testdata.opt new file mode 100644 index 0000000..b0c5b9c --- /dev/null +++ b/mysql-test/suite/binlog_encryption/testdata.opt @@ -0,0 +1 @@ +--partition diff --git a/mysql-test/unstable-tests b/mysql-test/unstable-tests index 8c79ab0..afd7a3c 100644 --- a/mysql-test/unstable-tests +++ b/mysql-test/unstable-tests @@ -89,6 +89,10 @@ binlog.binlog_xa_recover : MDEV-8517 - Extra checkpoint #---------------------------------------------------------------- +binlog_encryption.* : Added in 10.1.20 + +#---------------------------------------------------------------- + connect.tbl : MDEV-9844, MDEV-10179 - sporadic crashes, valgrind warnings, wrong results connect.jdbc : New test, added on 2016-07-15 connect.jdbc-new : New test, added on 2016-07-14
participants (1)
-
Elena Stepanova