From 3f619478f796eddbba6e39502fe941b285dd97b1 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sat, 4 May 2024 20:00:34 +0200 Subject: Adding upstream version 1:10.11.6. Signed-off-by: Daniel Baumann --- mysql-test/suite/rpl/include/check_type.inc | 70 + .../suite/rpl/include/create_or_drop_sync_func.inc | 75 + .../rpl/include/create_recursive_construct.inc | 405 +++++ .../rpl/include/delayed_slave_wait_on_query.inc | 55 + mysql-test/suite/rpl/include/hrtime.inc | 27 + .../suite/rpl/include/mdev-31448_conservative.inc | 68 + .../suite/rpl/include/mdev-31448_optimistic.inc | 94 + mysql-test/suite/rpl/include/multisource.inc | 312 ++++ .../rpl/include/mysqlbinlog_slave_consistency.inc | 194 +++ mysql-test/suite/rpl/include/rpl_EE_err.test | 23 + .../suite/rpl/include/rpl_auto_increment.test | 317 ++++ .../include/rpl_auto_increment_insert_view.test | 43 + .../include/rpl_auto_increment_invoke_trigger.test | 79 + .../include/rpl_autoinc_func_invokes_trigger.test | 55 + .../rpl/include/rpl_binlog_max_cache_size.test | 461 +++++ mysql-test/suite/rpl/include/rpl_blackhole.test | 30 + .../suite/rpl/include/rpl_blackhole_basic.test | 97 ++ .../suite/rpl/include/rpl_change_master_demote.inc | 89 + mysql-test/suite/rpl/include/rpl_charset.test | 148 ++ .../rpl/include/rpl_check_table_consistency.inc | 63 + .../suite/rpl/include/rpl_commit_after_flush.test | 14 + mysql-test/suite/rpl/include/rpl_conflicts.test | 170 ++ mysql-test/suite/rpl/include/rpl_ddl.test | 531 ++++++ mysql-test/suite/rpl/include/rpl_deadlock.test | 153 ++ .../suite/rpl/include/rpl_delete_no_where.test | 17 + .../rpl/include/rpl_drop_create_temp_table.inc | 1047 +++++++++++ .../rpl/include/rpl_drop_create_temp_table.test | 564 ++++++ .../suite/rpl/include/rpl_extra_col_master.test | 1023 +++++++++++ .../suite/rpl/include/rpl_extra_col_slave.test | 913 ++++++++++ .../suite/rpl/include/rpl_failed_optimize.test | 28 + mysql-test/suite/rpl/include/rpl_flsh_tbls.test | 72 + .../include/rpl_get_master_version_and_clock.test | 83 + .../rpl/include/rpl_implicit_commit_binlog.test | 145 ++ mysql-test/suite/rpl/include/rpl_innodb.test | 171 ++ .../suite/rpl/include/rpl_insert_delayed.test | 163 ++ mysql-test/suite/rpl/include/rpl_insert_id.test | 567 ++++++ mysql-test/suite/rpl/include/rpl_insert_id_pk.test | 83 + .../suite/rpl/include/rpl_insert_ignore.test | 121 ++ mysql-test/suite/rpl/include/rpl_loaddata.test | 247 +++ mysql-test/suite/rpl/include/rpl_loadfile.test | 32 + mysql-test/suite/rpl/include/rpl_log.test | 151 ++ .../rpl/include/rpl_lower_case_table_names.test | 141 ++ .../suite/rpl/include/rpl_max_relay_size.test | 118 ++ .../suite/rpl/include/rpl_mixed_check_db.inc | 11 + .../suite/rpl/include/rpl_mixed_check_event.inc | 15 + .../suite/rpl/include/rpl_mixed_check_select.inc | 19 + .../suite/rpl/include/rpl_mixed_check_table.inc | 14 + .../suite/rpl/include/rpl_mixed_check_user.inc | 13 + .../suite/rpl/include/rpl_mixed_check_view.inc | 15 + .../suite/rpl/include/rpl_mixed_clear_tables.inc | 9 + mysql-test/suite/rpl/include/rpl_mixed_ddl.inc | 81 + mysql-test/suite/rpl/include/rpl_mixed_dml.inc | 340 ++++ .../rpl/include/rpl_mixed_show_binlog_format.inc | 10 + .../suite/rpl/include/rpl_mixing_engines.inc | 639 +++++++ .../suite/rpl/include/rpl_mixing_engines.test | 1816 ++++++++++++++++++++ mysql-test/suite/rpl/include/rpl_multi_query.test | 26 + mysql-test/suite/rpl/include/rpl_multi_update.test | 33 + .../suite/rpl/include/rpl_multi_update2.test | 63 + .../suite/rpl/include/rpl_multi_update3.test | 223 +++ mysql-test/suite/rpl/include/rpl_not_null.test | 360 ++++ .../suite/rpl/include/rpl_parallel_29322.inc | 112 ++ .../include/rpl_parallel_incorrect_relay_pos.inc | 128 ++ mysql-test/suite/rpl/include/rpl_partition.inc | 104 ++ mysql-test/suite/rpl/include/rpl_partition.test | 262 +++ .../suite/rpl/include/rpl_record_compare.test | 64 + mysql-test/suite/rpl/include/rpl_relayrotate.test | 77 + mysql-test/suite/rpl/include/rpl_reset_slave.test | 116 ++ .../rpl/include/rpl_reset_slave_all_check.inc | 48 + mysql-test/suite/rpl/include/rpl_row_UUID.test | 79 + mysql-test/suite/rpl/include/rpl_row_annotate.test | 185 ++ mysql-test/suite/rpl/include/rpl_row_basic.test | 675 ++++++++ mysql-test/suite/rpl/include/rpl_row_blob.test | 175 ++ .../suite/rpl/include/rpl_row_delayed_ins.test | 21 + mysql-test/suite/rpl/include/rpl_row_func003.test | 81 + mysql-test/suite/rpl/include/rpl_row_img.test | 241 +++ .../suite/rpl/include/rpl_row_img_blobs.test | 179 ++ .../suite/rpl/include/rpl_row_img_sequence.inc | 92 + mysql-test/suite/rpl/include/rpl_row_sp002.test | 208 +++ mysql-test/suite/rpl/include/rpl_row_sp003.test | 81 + mysql-test/suite/rpl/include/rpl_row_sp006.test | 84 + mysql-test/suite/rpl/include/rpl_row_sp007.test | 46 + .../suite/rpl/include/rpl_row_tabledefs.test | 232 +++ mysql-test/suite/rpl/include/rpl_set_null.test | 82 + mysql-test/suite/rpl/include/rpl_set_statement.inc | 26 + .../suite/rpl/include/rpl_show_binlog_events.inc | 17 + .../rpl_show_log_events_with_varying_options.inc | 11 + .../suite/rpl/include/rpl_show_relaylog_events.inc | 65 + .../suite/rpl/include/rpl_shutdown_wait_slaves.inc | 91 + .../rpl/include/rpl_slave_max_statement_time.inc | 79 + .../suite/rpl/include/rpl_start_stop_slave.test | 216 +++ mysql-test/suite/rpl/include/rpl_stm_EE_err2.test | 41 + .../rpl/include/rpl_stm_create_if_not_exists.test | 268 +++ .../suite/rpl/include/rpl_stop_middle_group.test | 148 ++ mysql-test/suite/rpl/include/rpl_stop_slave.test | 56 + .../suite/rpl/include/rpl_sv_relay_space.test | 24 + .../suite/rpl/include/rpl_test_framework.inc | 85 + .../suite/rpl/include/rpl_tmp_table_and_DDL.test | 159 ++ mysql-test/suite/rpl/include/rpl_trig004.test | 48 + mysql-test/suite/rpl/include/rpl_truncate.test | 13 + .../suite/rpl/include/rpl_truncate_helper.test | 29 + .../suite/rpl/include/rpl_xa_empty_transaction.inc | 10 + .../include/rpl_xa_empty_transaction_test_case.inc | 131 ++ .../suite/rpl/include/rpl_xa_mixed_engines.inc | 183 ++ mysql-test/suite/rpl/include/sql_multisource.inc | 45 + .../suite/rpl/include/sql_out_of_order_gtid.inc | 43 + mysql-test/suite/rpl/include/start_alter_basic.inc | 60 + .../suite/rpl/include/start_alter_concurrent.inc | 230 +++ .../suite/rpl/include/start_alter_include.inc | 64 + .../suite/rpl/include/start_alter_options.inc | 399 +++++ mysql-test/suite/rpl/include/type_conversions.test | 1272 ++++++++++++++ 110 files changed, 20131 insertions(+) create mode 100644 mysql-test/suite/rpl/include/check_type.inc create mode 100644 mysql-test/suite/rpl/include/create_or_drop_sync_func.inc create mode 100644 mysql-test/suite/rpl/include/create_recursive_construct.inc create mode 100644 mysql-test/suite/rpl/include/delayed_slave_wait_on_query.inc create mode 100644 mysql-test/suite/rpl/include/hrtime.inc create mode 100644 mysql-test/suite/rpl/include/mdev-31448_conservative.inc create mode 100644 mysql-test/suite/rpl/include/mdev-31448_optimistic.inc create mode 100644 mysql-test/suite/rpl/include/multisource.inc create mode 100644 mysql-test/suite/rpl/include/mysqlbinlog_slave_consistency.inc create mode 100644 mysql-test/suite/rpl/include/rpl_EE_err.test create mode 100644 mysql-test/suite/rpl/include/rpl_auto_increment.test create mode 100644 mysql-test/suite/rpl/include/rpl_auto_increment_insert_view.test create mode 100644 mysql-test/suite/rpl/include/rpl_auto_increment_invoke_trigger.test create mode 100644 mysql-test/suite/rpl/include/rpl_autoinc_func_invokes_trigger.test create mode 100644 mysql-test/suite/rpl/include/rpl_binlog_max_cache_size.test create mode 100644 mysql-test/suite/rpl/include/rpl_blackhole.test create mode 100644 mysql-test/suite/rpl/include/rpl_blackhole_basic.test create mode 100644 mysql-test/suite/rpl/include/rpl_change_master_demote.inc create mode 100644 mysql-test/suite/rpl/include/rpl_charset.test create mode 100644 mysql-test/suite/rpl/include/rpl_check_table_consistency.inc create mode 100644 mysql-test/suite/rpl/include/rpl_commit_after_flush.test create mode 100644 mysql-test/suite/rpl/include/rpl_conflicts.test create mode 100644 mysql-test/suite/rpl/include/rpl_ddl.test create mode 100644 mysql-test/suite/rpl/include/rpl_deadlock.test create mode 100644 mysql-test/suite/rpl/include/rpl_delete_no_where.test create mode 100644 mysql-test/suite/rpl/include/rpl_drop_create_temp_table.inc create mode 100644 mysql-test/suite/rpl/include/rpl_drop_create_temp_table.test create mode 100644 mysql-test/suite/rpl/include/rpl_extra_col_master.test create mode 100644 mysql-test/suite/rpl/include/rpl_extra_col_slave.test create mode 100644 mysql-test/suite/rpl/include/rpl_failed_optimize.test create mode 100644 mysql-test/suite/rpl/include/rpl_flsh_tbls.test create mode 100644 mysql-test/suite/rpl/include/rpl_get_master_version_and_clock.test create mode 100644 mysql-test/suite/rpl/include/rpl_implicit_commit_binlog.test create mode 100644 mysql-test/suite/rpl/include/rpl_innodb.test create mode 100644 mysql-test/suite/rpl/include/rpl_insert_delayed.test create mode 100644 mysql-test/suite/rpl/include/rpl_insert_id.test create mode 100644 mysql-test/suite/rpl/include/rpl_insert_id_pk.test create mode 100644 mysql-test/suite/rpl/include/rpl_insert_ignore.test create mode 100644 mysql-test/suite/rpl/include/rpl_loaddata.test create mode 100644 mysql-test/suite/rpl/include/rpl_loadfile.test create mode 100644 mysql-test/suite/rpl/include/rpl_log.test create mode 100644 mysql-test/suite/rpl/include/rpl_lower_case_table_names.test create mode 100644 mysql-test/suite/rpl/include/rpl_max_relay_size.test create mode 100644 mysql-test/suite/rpl/include/rpl_mixed_check_db.inc create mode 100644 mysql-test/suite/rpl/include/rpl_mixed_check_event.inc create mode 100644 mysql-test/suite/rpl/include/rpl_mixed_check_select.inc create mode 100644 mysql-test/suite/rpl/include/rpl_mixed_check_table.inc create mode 100644 mysql-test/suite/rpl/include/rpl_mixed_check_user.inc create mode 100644 mysql-test/suite/rpl/include/rpl_mixed_check_view.inc create mode 100644 mysql-test/suite/rpl/include/rpl_mixed_clear_tables.inc create mode 100644 mysql-test/suite/rpl/include/rpl_mixed_ddl.inc create mode 100644 mysql-test/suite/rpl/include/rpl_mixed_dml.inc create mode 100644 mysql-test/suite/rpl/include/rpl_mixed_show_binlog_format.inc create mode 100644 mysql-test/suite/rpl/include/rpl_mixing_engines.inc create mode 100644 mysql-test/suite/rpl/include/rpl_mixing_engines.test create mode 100644 mysql-test/suite/rpl/include/rpl_multi_query.test create mode 100644 mysql-test/suite/rpl/include/rpl_multi_update.test create mode 100644 mysql-test/suite/rpl/include/rpl_multi_update2.test create mode 100644 mysql-test/suite/rpl/include/rpl_multi_update3.test create mode 100644 mysql-test/suite/rpl/include/rpl_not_null.test create mode 100644 mysql-test/suite/rpl/include/rpl_parallel_29322.inc create mode 100644 mysql-test/suite/rpl/include/rpl_parallel_incorrect_relay_pos.inc create mode 100644 mysql-test/suite/rpl/include/rpl_partition.inc create mode 100644 mysql-test/suite/rpl/include/rpl_partition.test create mode 100644 mysql-test/suite/rpl/include/rpl_record_compare.test create mode 100644 mysql-test/suite/rpl/include/rpl_relayrotate.test create mode 100644 mysql-test/suite/rpl/include/rpl_reset_slave.test create mode 100644 mysql-test/suite/rpl/include/rpl_reset_slave_all_check.inc create mode 100644 mysql-test/suite/rpl/include/rpl_row_UUID.test create mode 100644 mysql-test/suite/rpl/include/rpl_row_annotate.test create mode 100644 mysql-test/suite/rpl/include/rpl_row_basic.test create mode 100644 mysql-test/suite/rpl/include/rpl_row_blob.test create mode 100644 mysql-test/suite/rpl/include/rpl_row_delayed_ins.test create mode 100644 mysql-test/suite/rpl/include/rpl_row_func003.test create mode 100644 mysql-test/suite/rpl/include/rpl_row_img.test create mode 100644 mysql-test/suite/rpl/include/rpl_row_img_blobs.test create mode 100644 mysql-test/suite/rpl/include/rpl_row_img_sequence.inc create mode 100644 mysql-test/suite/rpl/include/rpl_row_sp002.test create mode 100644 mysql-test/suite/rpl/include/rpl_row_sp003.test create mode 100644 mysql-test/suite/rpl/include/rpl_row_sp006.test create mode 100644 mysql-test/suite/rpl/include/rpl_row_sp007.test create mode 100644 mysql-test/suite/rpl/include/rpl_row_tabledefs.test create mode 100644 mysql-test/suite/rpl/include/rpl_set_null.test create mode 100644 mysql-test/suite/rpl/include/rpl_set_statement.inc create mode 100644 mysql-test/suite/rpl/include/rpl_show_binlog_events.inc create mode 100644 mysql-test/suite/rpl/include/rpl_show_log_events_with_varying_options.inc create mode 100644 mysql-test/suite/rpl/include/rpl_show_relaylog_events.inc create mode 100644 mysql-test/suite/rpl/include/rpl_shutdown_wait_slaves.inc create mode 100644 mysql-test/suite/rpl/include/rpl_slave_max_statement_time.inc create mode 100644 mysql-test/suite/rpl/include/rpl_start_stop_slave.test create mode 100644 mysql-test/suite/rpl/include/rpl_stm_EE_err2.test create mode 100644 mysql-test/suite/rpl/include/rpl_stm_create_if_not_exists.test create mode 100644 mysql-test/suite/rpl/include/rpl_stop_middle_group.test create mode 100644 mysql-test/suite/rpl/include/rpl_stop_slave.test create mode 100644 mysql-test/suite/rpl/include/rpl_sv_relay_space.test create mode 100644 mysql-test/suite/rpl/include/rpl_test_framework.inc create mode 100644 mysql-test/suite/rpl/include/rpl_tmp_table_and_DDL.test create mode 100644 mysql-test/suite/rpl/include/rpl_trig004.test create mode 100644 mysql-test/suite/rpl/include/rpl_truncate.test create mode 100644 mysql-test/suite/rpl/include/rpl_truncate_helper.test create mode 100644 mysql-test/suite/rpl/include/rpl_xa_empty_transaction.inc create mode 100644 mysql-test/suite/rpl/include/rpl_xa_empty_transaction_test_case.inc create mode 100644 mysql-test/suite/rpl/include/rpl_xa_mixed_engines.inc create mode 100644 mysql-test/suite/rpl/include/sql_multisource.inc create mode 100644 mysql-test/suite/rpl/include/sql_out_of_order_gtid.inc create mode 100644 mysql-test/suite/rpl/include/start_alter_basic.inc create mode 100644 mysql-test/suite/rpl/include/start_alter_concurrent.inc create mode 100644 mysql-test/suite/rpl/include/start_alter_include.inc create mode 100644 mysql-test/suite/rpl/include/start_alter_options.inc create mode 100644 mysql-test/suite/rpl/include/type_conversions.test (limited to 'mysql-test/suite/rpl/include') diff --git a/mysql-test/suite/rpl/include/check_type.inc b/mysql-test/suite/rpl/include/check_type.inc new file mode 100644 index 00000000..c72754ca --- /dev/null +++ b/mysql-test/suite/rpl/include/check_type.inc @@ -0,0 +1,70 @@ +# Helper file to perform one insert of a value into a table with +# different types on master and slave. The file will insert the +# result into the type_conversions table *on the slave* to get a +# summary of failing and succeeding tests. + +# Input: +# $source_type Type on the master +# $target_type Type on the slave +# $source_value Value on the master (inserted into the table) +# $target_value Value on the slave (expected value in the table +# on the slave) +# $can_convert True if conversion shall work, false if it +# shall generate an error +# $engine_type The storage engine to be used for storing table +# on both master and slave + +if (!$engine_type) +{ + # Use the default storage engine + let $engine_type=`SELECT @@default_storage_engine`; +} + +connection master; +disable_warnings; +DROP TABLE IF EXISTS t1; +enable_warnings; +if ($source_temp_format) +{ + --eval SET @@global.mysql56_temporal_format= $source_temp_format +} +eval CREATE TABLE t1( + pk INT NOT NULL PRIMARY KEY, + a $source_type +) ENGINE=$engine_type; +sync_slave_with_master; +if ($target_temp_format) +{ + --eval SET @@global.mysql56_temporal_format= $source_temp_format +} +eval ALTER TABLE t1 MODIFY a $target_type; + +connection master; +eval INSERT INTO t1 VALUES(1, $source_value); +if ($can_convert) { + sync_slave_with_master; + eval SELECT a = $target_value into @compare FROM t1; + eval INSERT INTO type_conversions SET + Source = "$source_type", + Target = "$target_type", + Flags = @@slave_type_conversions, + On_Master = $source_value, + Expected = $target_value, + Compare = @compare; + UPDATE type_conversions + SET On_Slave = (SELECT a FROM t1) + WHERE TestNo = LAST_INSERT_ID(); +} +if (!$can_convert) { + connection slave; + wait_for_slave_to_stop; + let $error = query_get_value("SHOW SLAVE STATUS", Last_SQL_Error, 1); + eval INSERT INTO type_conversions SET + Source = "$source_type", + Target = "$target_type", + Flags = @@slave_type_conversions, + On_Master = $source_value, + Error = "$error"; + SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1; + START SLAVE; +} diff --git a/mysql-test/suite/rpl/include/create_or_drop_sync_func.inc b/mysql-test/suite/rpl/include/create_or_drop_sync_func.inc new file mode 100644 index 00000000..74cde5de --- /dev/null +++ b/mysql-test/suite/rpl/include/create_or_drop_sync_func.inc @@ -0,0 +1,75 @@ +# Creates or drops a stored function as a part of debug-sync based +# synchronization mechanism between replication servers. +# +# Parameters: +# $create_or_drop= [create] +# $server_master = [master] +# $server_slave = [slave] +if (!$create_or_drop) +{ + --let $create_or_drop=create +} + +if (`select strcmp('$create_or_drop', 'create') = 0`) +{ + if (!$server_master) + { + --let $server_master=master + } + if (!$server_slave) + { + --let $server_slave=slave + } + + --connection $server_master + # 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; + + --connection $server_slave + + 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; +} + +if (`select strcmp('$create_or_drop', 'drop') = 0`) +{ + if (!$server_slave) + { + --let $server_slave=slave= + } + if (!$server_master) + { + --let $server_master=master + } + --connection $server_slave + SET DEBUG_SYNC='RESET'; + + --connection $server_master + SET DEBUG_SYNC='RESET'; + DROP FUNCTION foo; +} diff --git a/mysql-test/suite/rpl/include/create_recursive_construct.inc b/mysql-test/suite/rpl/include/create_recursive_construct.inc new file mode 100644 index 00000000..4a094a68 --- /dev/null +++ b/mysql-test/suite/rpl/include/create_recursive_construct.inc @@ -0,0 +1,405 @@ +# ==== Purpose ==== +# +# Creates a stored routine, stored function, trigger, view, or +# prepared statement (commonly referred to as "recursive construct") +# that invokes a given unsafe statement. +# +# Then, it invokes the created recursive construct several times: +# +# - With SQL_LOG_BIN = 1 and binlog_format = STATEMENT, to verify +# that it gives a warning. +# +# - With SQL_LOG_BIN = 0 and binlog_format = STATEMENT, to verify that +# there is no warning and nothing is logged. +# +# - With SQL_LOG_BIN = 1 and binlog_format = MIXED, to verify that it +# writes row events to the binlog. +# +# - In some cases, the recursive construct can be invoked so that it +# has no side-effects but returns a value that may be +# nondeterministic. An example is a function that returns UUID(). +# The function does not have side effects but its a return value +# that may differ on slave. Such statements are invoked so that +# the return value is discarded (e.g., SELECT func()), with +# SQL_LOG_BIN = 1 and binlog_format = STATEMENT. In this case, no +# warning should be given and nothing should be written to the +# binlog. +# +# This is an auxiliary file particularly targeted to being used by the +# test binlog_unsafe. In this context, the purpose is to check how +# warnings for unsafe statements are propagated in recursive +# constructs. +# +# The statement to invoke ("input") is described using mtr variables, +# and the resulting recursive construct ("output") is stored in mtr +# variables in a similar fashion. To create several levels of nested +# recursive constructs, source this file once, then copy the values of +# appropriate output variables to the input variables, and then source +# this file again. +# +# +# ==== Usage ==== +# +# See binlog_unsafe for an example of how to use this file. +# +# let $CRC_ARG_level= ; +# let $CRC_ARG_type= ; +# let $CRC_ARG_stmt_sidef= ; +# let $CRC_ARG_value= ; +# let $CRC_ARG_sel_retval= ; +# let $CRC_ARG_sel_sidef= ; +# let $CRC_ARG_desc= ; +# source suite/rpl/include/create_recursive_construct.inc; +# let $my_stmt_sidef= $CRC_RET_stmt_sidef; +# let $my_value= $CRC_RET_value; +# let $my_sel_sidef= $CRC_RET_sel_sidef; +# let $my_sel_retval= $CRC_RET_sel_retval; +# let $my_drop= $CRC_RET_drop; +# let $my_is_toplevel= $CRC_RET_top_is_toplevel; +# let $my_desc= $CRC_RET_desc; +# +# $CRC_ARG_* are used as input parameters (arguments) to this file: +# +# $CRC_ARG_level is the recursion depth: 1 for the innermost +# statement created, 2 for a statement that invokes a statement on +# level 1, etc. +# +# $CRC_ARG_type is an integer from 0 to 6, indicating what type of +# statement shall be created: +# 0 - Create a stored function where the return value depends on +# the value of the given statement. +# 1 - Create a stored function that invokes the given statement as +# a side-effect but may not return a value that depends on it. +# 2 - Create a stored routine that invokes the given statement. +# 3 - Create a trigger (on table trigger_table_$CRC_ARG_level) that +# invokes the given statement. +# 4 - Create a view that returns a value that depends on the value +# of the given statement. +# 5 - Create a view that invokes the given statement but may return +# a value that does not depend on it. +# 6 - Create a prepared statement that invokes the given statement. +# +# $CRC_ARG_stmt_sidef is the statement to invoke. It should be a +# statement that can be invoked on its own (not sub-statement), +# which causes something unsafe to be written to the binlog. +# +# $CRC_ARG_value is a sub-statement holding the value of the given +# statement. Can be empty if the given statement does not have a +# value. Typically, this is non-empty if the given statement is a +# function call or user variable, but not if it is a stored routine +# call, INSERT, SELECT, etc (because none of them has a value). +# $CRC_ARG_value is used only when $CRC_ARG_type=6. +# +# $CRC_ARG_sel_sidef is a SELECT sub-statement that invokes the +# statement as a side-effect, but returns a result set that may not +# depend on the statement. Can be empty if the statement cannot +# produce a result set from a SELECT. $CRC_ARG_sel_sidef is used +# only if $CRC_ARG_type=2 +# +# $CRC_ARG_sel_retval is a SELECT sub-statement that does not have +# side-effects, but returns a result set that depends on the unsafe +# statement. Can be empty if the statement cannot be invoked from a +# SELECT. $CRC_ARG_sel_retval is used only if $CRC_ARG_type=3. +# +# $CRC_ARG_desc is a human-readable description of the statement to +# invoke. +# +# $CRC_RET_* are used as output parameters (return values) of this +# file: +# +# $CRC_RET_stmt_sidef is a statement invoking the resulting recursive +# construct. +# +# $CRC_RET_value is a sub-statement invoking the resulting recursive +# construct and returning the value of the recursive construct. +# This is the empty string if the resulting recursive construct does +# not have a value. In particular, this is non-empty only if +# $CRC_ARG_value=7. +# +# $CRC_RET_sel_sidef is a SELECT sub-statement that invokes the +# resulting recursive construct as a side-effect but where the +# result set may not depend on the recursive construct. This is the +# empty string if the recursive construct cannot be invoked from a +# SELECT. In particular, this is non-empty only if $CRC_ARG_value=6 +# or $CRC_ARG_value=2. +# +# $CRC_RET_sel_retval is a SELECT sub-statement that does not have +# side-effects, but returns a result set depending on the unsafe +# statement. This is the empty string if the recursive construct +# cannot produce a result set from a SELECT. In particular, this is +# non-empty only if $CRC_ARG_value=7 or $CRC_ARG_value=3. +# +# $CRC_RET_drop is a statement that drops the created object. I.e., +# it is one of 'DROP FUNCTION ', 'DROP PROCEDURE ', etc. +# +# $CRC_RET_top_is_toplevel is 0 normally, or 1 if the resulting +# recursive construct can only be called from a top-level statement. +# In particular, this is 1 only when $CRC_ARG_value=1, because +# prepared statements cannot be invoked from other recursive +# constructs. +# +# $CRC_RET_desc is a text string that describes the invokation of +# the recursive construct in a human-readable fashion. +# +# Assumptions +# +# Before sourcing this file with $CRC_ARG_level=X, you need to +# create three tables: tX, taX and trigger_table_X. These are used +# as auxiliary tables. + + +#--echo debug: >>>>ENTER create_recursive_construct +#--echo debug: level=$CRC_ARG_level +#--echo debug: type=$CRC_ARG_type +#--echo debug: stmt_sidef=$CRC_ARG_stmt_sidef +#--echo debug: value=$CRC_ARG_value +#--echo debug: sel_retval=$CRC_ARG_sel_retval +#--echo debug: sel_sidef=$CRC_ARG_sel_sidef + +--let $CRC_RET_stmt_sidef= +--let $CRC_RET_value= +--let $CRC_RET_sel_retval= +--let $CRC_RET_sel_sidef= +--let $CRC_RET_drop= +--let $CRC_RET_is_toplevel= 1 +--let $CRC_RET_desc= +--let $CRC_name= +--let $CRC_create= + +######## func_retval ######## +# if inside if in lieu of AND operand +if ($CRC_ARG_type == 0) { + if ($CRC_ARG_value) { + # It will be safe to call this function and discard the return + # value, but it will be unsafe to use return value (e.g., in + # INSERT...SELECT). + --let $CRC_name= func_retval_$CRC_ARG_level + --let $CRC_create= CREATE FUNCTION $CRC_name() RETURNS VARCHAR(100) BEGIN INSERT INTO ta$CRC_ARG_level VALUES (47); RETURN $CRC_ARG_value; END + --let $CRC_RET_stmt_sidef= INSERT INTO t$CRC_ARG_level VALUES ($CRC_name()) + --let $CRC_RET_value= $CRC_name() + --let $CRC_RET_sel_sidef= + --let $CRC_RET_sel_retval= SELECT $CRC_name() + --let $CRC_RET_drop= DROP FUNCTION $CRC_name + --let $CRC_RET_is_toplevel= 0 + --let $CRC_RET_desc= function $CRC_name returning value from $CRC_ARG_desc + } +} + +######## func_sidef ######## +if ($CRC_ARG_type == 1) { + # It will be unsafe to call func even if you discard return value. + --let $CRC_name= func_sidef_$CRC_ARG_level + --let $CRC_create= CREATE FUNCTION $CRC_name() RETURNS VARCHAR(100) BEGIN INSERT INTO ta$CRC_ARG_level VALUES (47); $CRC_ARG_stmt_sidef; RETURN 0; END + --let $CRC_RET_stmt_sidef= INSERT INTO t$CRC_ARG_level SELECT $CRC_name() + --let $CRC_RET_value= + --let $CRC_RET_sel_retval= + --let $CRC_RET_sel_sidef= SELECT $CRC_name() + --let $CRC_RET_drop= DROP FUNCTION $CRC_name + --let $CRC_RET_is_toplevel= 0 + --let $CRC_RET_desc= function $CRC_name invoking $CRC_ARG_desc +} + +######## proc ######## +if ($CRC_ARG_type == 2) { + # It will be unsafe to call this procedure. + --let $CRC_name= proc_$CRC_ARG_level + --let $CRC_create= CREATE PROCEDURE $CRC_name() BEGIN $CRC_ARG_stmt_sidef; INSERT INTO ta$CRC_ARG_level VALUES (47); END + --let $CRC_RET_stmt_sidef= CALL $CRC_name() + --let $CRC_RET_value= + --let $CRC_RET_sel_retval= + --let $CRC_RET_sel_sidef= + --let $CRC_RET_drop= DROP PROCEDURE $CRC_name + --let $CRC_RET_is_toplevel= 0 + --let $CRC_RET_desc= procedure $CRC_name invoking $CRC_ARG_desc +} + +######## trig ######## +if ($CRC_ARG_type == 3) { + # It will be unsafe to invoke this trigger. + --let $CRC_name= trig_$CRC_ARG_level + --let $CRC_create= CREATE TRIGGER $CRC_name BEFORE INSERT ON trigger_table_$CRC_ARG_level FOR EACH ROW BEGIN INSERT INTO ta$CRC_ARG_level VALUES (47); $CRC_ARG_stmt_sidef; END + --let $CRC_RET_stmt_sidef= INSERT INTO trigger_table_$CRC_ARG_level VALUES (1) + --let $CRC_RET_value= + --let $CRC_RET_sel_retval= + --let $CRC_RET_sel_sidef= + --let $CRC_RET_drop= DROP TRIGGER $CRC_name + --let $CRC_RET_is_toplevel= 0 + --let $CRC_RET_desc= trigger $CRC_name invoking $CRC_ARG_desc +} + +######## view_retval ######## +if ($CRC_ARG_type == 4) { + if ($CRC_ARG_sel_retval) { + # It will be safe to select from this view if you discard the result + # set, but unsafe to use result set (e.g., in INSERT..SELECT). + --let $CRC_name= view_retval_$CRC_ARG_level + --let $CRC_create= CREATE VIEW $CRC_name AS $CRC_ARG_sel_retval + --let $CRC_RET_stmt_sidef= INSERT INTO t$CRC_ARG_LEVEL SELECT * FROM $CRC_name + --let $CRC_RET_value= + --let $CRC_RET_sel_retval= SELECT * FROM $CRC_name + --let $CRC_RET_sel_sidef= + --let $CRC_RET_drop= DROP VIEW $CRC_name + --let $CRC_RET_is_toplevel= 0 + --let $CRC_RET_desc= view $CRC_name returning value from $CRC_ARG_desc + } +} + +######## view_sidef ######## +if ($CRC_ARG_type == 5) { + if ($CRC_ARG_sel_sidef) { + # It will be unsafe to select from this view, even if you discard + # the return value. + --let $CRC_name= view_sidef_$CRC_ARG_level + --let $CRC_create= CREATE VIEW $CRC_name AS $CRC_ARG_sel_sidef + --let $CRC_RET_stmt_sidef= INSERT INTO t$CRC_ARG_level SELECT * FROM $CRC_name + --let $CRC_RET_value= + --let $CRC_RET_sel_retval= + --let $CRC_RET_sel_sidef= SELECT * FROM $CRC_name + --let $CRC_RET_drop= DROP VIEW $CRC_name + --let $CRC_RET_is_toplevel= 0 + --let $CRC_RET_desc= view $CRC_name invoking $CRC_ARG_desc + } +} + +######## prep ######## +if ($CRC_ARG_type == 6) { + # It will be unsafe to execute this prepared statement + --let $CRC_name= prep_$CRC_ARG_level + --let $CRC_create= PREPARE $CRC_name FROM "$CRC_ARG_stmt_sidef" + --let $CRC_RET_stmt_sidef= EXECUTE $CRC_name + --let $CRC_RET_value= + --let $CRC_RET_sel_retval= + --let $CRC_RET_sel_sidef= + --let $CRC_RET_drop= DROP PREPARE $CRC_name + --let $CRC_RET_is_toplevel= 1 + --let $CRC_RET_desc= prepared statement $CRC_name invoking $CRC_ARG_desc +} + +######## no recursive construct: just return the given statement ######## +if ($CRC_ARG_type == 7) { + # CRC_ARG_type=7 is a special case. We just set $CRC_RET_x = + # $CRC_ARG_x. This way, the $CRC_ARG_stmt gets executed directly + # (below). In binlog_unsafe.test, it is used to invoke the unsafe + # statement created in the outermost loop directly, without + # enclosing it in a recursive construct. + --let $CRC_RET_stmt_sidef= $CRC_ARG_stmt_sidef + --let $CRC_RET_value= $CRC_ARG_value + --let $CRC_RET_sel_retval= $CRC_ARG_sel_retval + --let $CRC_RET_sel_sidef= $CRC_ARG_sel_sidef + --let $CRC_RET_drop= + --let $CRC_RET_is_toplevel= 1 + --let $CRC_RET_desc= $CRC_ARG_desc +} + +######## execute! ######## +if ($CRC_RET_stmt_sidef) { + --echo + --echo Invoking $CRC_RET_desc. + if ($CRC_create) { + --disable_ps_protocol + --eval $CRC_create + --enable_ps_protocol + } + + --echo * binlog_format = STATEMENT: expect $CRC_ARG_expected_number_of_warnings warnings. + --eval $CRC_RET_stmt_sidef + --let $n_warnings= `SHOW COUNT(*) WARNINGS` + if ($n_warnings != $CRC_ARG_expected_number_of_warnings) { + --echo ******** Failure! Expected $CRC_ARG_expected_number_of_warnings warnings, got $n_warnings warnings. ******** + SHOW WARNINGS; + SHOW BINLOG EVENTS; + --die Wrong number of warnings. + } + + # These queries are run without query log, to make result file more + # readable. Debug info is only printed if something abnormal + # happens. + --disable_query_log + + --echo * SQL_LOG_BIN = 0: expect nothing logged and no warning. + SET SQL_LOG_BIN = 0; + RESET MASTER; + --eval $CRC_RET_stmt_sidef + --let $n_warnings= `SHOW COUNT(*) WARNINGS` + if ($n_warnings) { + --echo ******** Failure! Expected 0 warnings, got $n_warnings warnings. ******** + SHOW WARNINGS; + SHOW BINLOG EVENTS; + --die Wrong number of warnings. + } + # There should be no events after format description, Gtid list, and binlog checkpoint. + --let $binlog_event= query_get_value(SHOW BINLOG EVENTS, Event_type, 4) + if ($binlog_event != No such row) { + --enable_query_log + --echo ******** Failure! Something was written to the binlog despite SQL_LOG_BIN=0 ******** + SHOW BINLOG EVENTS; + --die Binlog not empty + } + SET SQL_LOG_BIN = 1; + + --echo * binlog_format = MIXED: expect row events in binlog and no warning. + SET binlog_format = MIXED; + RESET MASTER; + --eval $CRC_RET_stmt_sidef + --let $n_warnings= `SHOW COUNT(*) WARNINGS` + if ($n_warnings) { + --echo ******** Failure! Expected 0 warnings, got $n_warnings warnings. ******** + SHOW WARNINGS; + SHOW BINLOG EVENTS; + --die Warnings printed + } + --let $event_type= query_get_value(SHOW BINLOG EVENTS, Event_type, 6) + # The first event is format_description, the second is Gtid list, the + # third is Binlog_checkpoint, the fourth Gtid, and the fifth should be + # our Query for 'INSERT DELAYED' unsafe_type 3, which is safe after + # the fix of bug#54579. + if (`SELECT $unsafe_type = 3 AND '$event_type' != 'Query'`) { + --enable_query_log + --echo ******** Failure! Event number 5 was a '$event_type', not a 'Query'. ******** + SHOW BINLOG EVENTS; + --die Wrong events in binlog. + } + # The first event is format_description, the second is Gtid list, + # the third is Binlog_checkpoint, the fourth is Query_event('BEGIN'), + # the fifth is Annotate_rows, and the sixth should be our Table_map + # for unsafe statement. + if (`SELECT $unsafe_type != 3 AND '$event_type' != 'Table_map'`) { + --enable_query_log + --echo ******** Failure! Event number 6 was a '$event_type', not a 'Table_map'. ******** + SHOW BINLOG EVENTS; + --die Wrong events in binlog. + } + SET binlog_format = STATEMENT; + + --enable_query_log +} + +# Invoke created object, discarding the return value. This should not +# give any warning. +if ($CRC_RET_sel_retval) { + --echo * Invoke statement so that return value is dicarded: expect no warning. + --disable_result_log + --eval $CRC_RET_sel_retval + --enable_result_log + + # Currently, due to a bug, we do get warnings here, so we don't + # fail. When the bug is fixed, we should execute the following. + + #--let $n_warnings= `SHOW COUNT(*) WARNINGS` + #if ($n_warnings) { + # --enable_query_log + # --echo Failure! Expected 0 warnings, got $n_warnings warnings. + # SHOW WARNINGS; + # SHOW BINLOG EVENTS; + # --die Wrong number of warnings. + #} +} + +#--echo debug: <<<next_gco || tmp_gco->last_sub_id > sub_id); +# in the buggy version. + +--echo # Initialize test data +--connection master +create table t1 (a int) engine=innodb; +create table t2 (a int) engine=innodb; + +insert into t1 values (1); +--source include/save_master_gtid.inc + +--connection slave +call mtr.add_suppression("Connection was killed"); +call mtr.add_suppression("Can.t find record"); + +--source include/sync_with_master_gtid.inc +--source include/stop_slave.inc +set @save.slave_parallel_threads= @@global.slave_parallel_threads; +set @save.slave_parallel_mode= @@global.slave_parallel_mode; +set @@global.slave_parallel_threads= 3; +set @@global.slave_parallel_mode= OPTIMISTIC; + +--connection slave1 +begin; +update t1 set a=2 where a=1; + +--connection master +set @old_dbug= @@session.debug_dbug; +set @@session.debug_dbug="+d,binlog_force_commit_id"; + +# GCO 1 +set @commit_id= 10000; +# T1 +update t1 set a=2 where a=1; + +if (!$killed_trx_commits) +{ +set @commit_id= 10001; +# T2 +set statement skip_parallel_replication=1 for insert into t2 values (1); +} + +if ($killed_trx_commits) +{ +insert into t2 values (1); +} +# GCO 2 +# T3 +drop table t2; + +--connection slave +--source include/start_slave.inc + +--echo # wait for T1 +--let $wait_condition= SELECT count(*)=1 FROM information_schema.processlist WHERE state LIKE 'Update_rows_log_event::find_row(-1)%' and command LIKE 'Slave_worker'; +--source include/wait_condition.inc + +--echo # wait for T2 +--let $wait_condition= SELECT count(*)=1 FROM information_schema.processlist WHERE state LIKE 'Waiting for prior transaction to commit%' and command LIKE 'Slave_worker'; +--source include/wait_condition.inc +--let $t2_tid= `SELECT ID FROM INFORMATION_SCHEMA.PROCESSLIST WHERE STATE LIKE 'Waiting for prior transaction to commit%' and command LIKE 'Slave_worker'` +--echo # wait for T3 +--let $wait_condition= SELECT count(*)=1 FROM information_schema.processlist WHERE state LIKE 'Waiting for prior transaction to start commit%' and command LIKE 'Slave_worker'; +--source include/wait_condition.inc + +--evalp kill $t2_tid +# give some little time for T2 to re-sink into the same state +--let $slave_param=Last_Errno +--let $slave_param_value=1927 +--source include/wait_for_slave_param.inc +--connection slave1 +commit; + +--connection slave +--let $slave_timeout=1032 +--source include/wait_for_slave_sql_to_stop.inc + +update t1 set a=1 where a=2; +set @@global.slave_parallel_threads = @save.slave_parallel_threads; +set @@global.slave_parallel_mode = @save.slave_parallel_mode; +--source include/start_slave.inc + +--echo # +--echo # Cleanup +--connection master +drop table t1; +--source include/save_master_gtid.inc + +--connection slave +--source include/sync_with_master_gtid.inc + diff --git a/mysql-test/suite/rpl/include/multisource.inc b/mysql-test/suite/rpl/include/multisource.inc new file mode 100644 index 00000000..96c4a9aa --- /dev/null +++ b/mysql-test/suite/rpl/include/multisource.inc @@ -0,0 +1,312 @@ +# +# This include file is used by more than one test suite +# (currently multisource and binlog_encryption). +# Please check all dependent tests after modifying it +# +# Usage: +# --source suite/rpl/include/multisource.inc +# +# By default, the script expects the length of the 2nd binary log to be +# $binlog_start_pos + length(Gtid_list event) + 2 x length(Binlog_checkpoint event) +# Some tests can have specific configuration which would change it, + +# +# Test basic replication functionality +# in multi-source setup +# + +--source include/not_embedded.inc +--source include/have_innodb.inc +--source include/have_perfschema.inc +--source include/binlog_start_pos.inc +--let $rpl_server_count= 0 + +--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'; +--source include/wait_for_slave_to_start.inc + +--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 +--source include/wait_for_sql_thread_read_all.inc + +# 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'; +--source include/wait_show_condition.inc + +--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' +--source include/show_slave_status.inc +--let $slave_name= + +--echo # +--echo # Checking SHOW SLAVE STATUS +--echo # +--source include/show_slave_status.inc + +--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 +--source include/show_slave_status.inc +--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=; +source include/show_relaylog_events.inc; +let binlog_file= mysqld-relay-bin-master1.000002; +source include/show_relaylog_events.inc; + +# 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', +master_use_gtid=no; + +start slave; +--source include/wait_for_slave_to_start.inc + +--source include/wait_for_sql_thread_read_all.inc + +# 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'; +--source include/wait_show_condition.inc + +--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/ +--source include/show_slave_status.inc +--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; +--source include/wait_for_binlog_checkpoint.inc +--save_master_pos +--connection slave +--sync_with_master 0, 'master1' + +--connection master1 +purge binary logs to 'master-bin.000002'; +# Additional events: 43 (Gtid_list) + 2 x 44 (Binlog_checkpoint) = 131 +let filesize=`select $binlog_start_pos+131`; +--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' + +--source include/wait_for_sql_thread_read_all.inc + +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'; +--source include/wait_show_condition.inc + +--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/ +--source include/show_slave_status.inc +--let $all_slaves_status= +--echo # + +--echo # +--echo # MDEV:16437: merge 5.7 P_S replication instrumentation and tables +--echo # +--replace_column 2 # +query_vertical SELECT * FROM performance_schema.replication_applier_status_by_coordinator; + +--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=; +source include/show_relaylog_events.inc; +let binlog_file= mysqld-relay-bin.000002; +source include/show_relaylog_events.inc; + +# 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; + +--source include/reset_master_slave.inc +--disconnect slave + +--connection master1 +drop database db1; +--source include/reset_master_slave.inc +--disconnect master1 + +--connection master2 +drop database db2; +--source include/reset_master_slave.inc +--disconnect master2 + diff --git a/mysql-test/suite/rpl/include/mysqlbinlog_slave_consistency.inc b/mysql-test/suite/rpl/include/mysqlbinlog_slave_consistency.inc new file mode 100644 index 00000000..48e4399d --- /dev/null +++ b/mysql-test/suite/rpl/include/mysqlbinlog_slave_consistency.inc @@ -0,0 +1,194 @@ +# This file provides the structure to run a single test that ensures the +# mariadb-binlog command line tool is consistent with replicas for event +# filtering. The test is configured using the following input parameters, where +# each is nullable (i.e. it will not be used to configure mariadb-binlog or +# the replica). +# +# param $do_domain_ids : A list of domain ids to include in replication +# param $ignore_domain_ids : A list of domain ids to exclude from replication +# param $ignore_server_ids : A list of server ids to exclude from replication +# param $start_position : The GTID positions to begin replication from in +# the specified domains +# param $stop_position : The GTID positions that mark the end of an event +# stream in a particular domain +# +# param $con1 : The connection name of the primary server +# param $con2 : The connection name of the replica server +# param $strict_mode : Uses input and checks for out of order GTIDs +# param $strict_mode_err : A boolean that provides expectations for strict +# mode to error +# param $slave_sql_errno : Expected error number of the slave SQL thread + + +--let $include_filename= mysqlbinlog_slave_consistency.inc +--source include/begin_include_file.inc + +--enable_query_log + +if (!$con1) +{ + --let $con1=master +} +if (!$con2) +{ + --let $con2=slave +} + +if (!$strict_mode) +{ + --connection $con2 + set @@global.gtid_strict_mode=0; + --let $sql_input_file=include/sql_multisource.inc +} + +if ($strict_mode) +{ + --connection $con2 + set @@global.gtid_strict_mode=1; + --let $sql_input_file=include/sql_out_of_order_gtid.inc +} + +--connection $con2 +--source include/stop_slave.inc + +--connection $con1 +--echo # Populating $con1 data +--source $sql_input_file +--source include/save_master_gtid.inc + +--let $MYSQLD_DATADIR=`select @@datadir` +--let $MYSQLBINLOG_STDERR=$MYSQLD_DATADIR/mysqlbinlog_stderr.out +--let BINLOG_FILENAME= query_get_value(SHOW BINARY LOGS, Log_name, 1) +--let BINLOG_FILE_PARAM= $MYSQLD_DATADIR/$BINLOG_FILENAME.orig +--copy_file $MYSQLD_DATADIR/$BINLOG_FILENAME $BINLOG_FILE_PARAM + +--connection $con2 +--let $msbl_args= +if (`SELECT strcmp("$start_position","") != 0`) +{ + eval set global gtid_slave_pos="$start_position"; + --let $msbl_args= $msbl_args --start-position=$start_position +} + +--let $cm_args= MASTER_USE_GTID=slave_pos +if (`SELECT strcmp("$do_domain_ids","") != 0`) +{ + --let $cm_args= $cm_args, DO_DOMAIN_IDS=($do_domain_ids) + --let $msbl_args= $msbl_args --do-domain-ids=$do_domain_ids +} +if (`SELECT strcmp("$ignore_domain_ids","") != 0`) +{ + --let $cm_args= $cm_args, IGNORE_DOMAIN_IDS=($ignore_domain_ids) + --let $msbl_args= $msbl_args --ignore-domain-ids=$ignore_domain_ids +} +if (`SELECT strcmp("$ignore_server_ids","") != 0`) +{ + --let $cm_args= $cm_args, IGNORE_SERVER_IDS=($ignore_server_ids) + --let $msbl_args= $msbl_args --ignore-server-ids=$ignore_server_ids +} +if ($strict_mode) +{ + --let $msbl_args= $msbl_args --gtid-strict-mode +} +eval CHANGE MASTER TO $cm_args; + +--let $start_slave_args= +if (`SELECT strcmp("$stop_position","") != 0`) +{ + --let $start_slave_args= UNTIL master_gtid_pos="$stop_position" + --let $msbl_args= $msbl_args --stop-position=$stop_position +} + +eval START SLAVE $start_slave_args; + +if ($slave_sql_errno) +{ + --echo # $con2 SQL Thread error expected - waiting for errno $slave_sql_errno + --source include/wait_for_slave_sql_error.inc +} + +# If we are not expecting an error, wait for con2 to catch up +if (!$slave_sql_errno) +{ + --echo # No $con2 error expecting - waiting for $con2 to catch up to $con1 + + # Stop position was not specified + if (`SELECT strcmp("$stop_position","") = 0`) + { + --source include/sync_with_master_gtid.inc + } + + # Stop position was specified + if (`SELECT strcmp("$stop_position","") != 0`) + { + --echo # Because there is a stop position we wait for all events to process + --echo # and $con2 to automatically stop + --source include/wait_for_slave_to_stop.inc + } +} + +--echo # Stop $con2 so it stops receiving $con1 events. +--source include/stop_slave.inc + +--connection $con1 +DROP TABLE IF EXISTS t1, t2, t3, t4, t5; +RESET MASTER; +--echo # MYSQL_BINLOG BINLOG_FILE_PARAM $msbl_args 2> MYSQLBINLOG_STDERR | MYSQL +--exec $MYSQL_BINLOG $BINLOG_FILE_PARAM $msbl_args 2> $MYSQLBINLOG_STDERR | $MYSQL + +--source include/rpl_check_table_consistency.inc + +if ($strict_mode) +{ + --echo # Strict mode enabled - checking mysqlbinlog error output for out + --echo # of order GTIDs + --let SEARCH_FILE=$MYSQLBINLOG_STDERR + --let SEARCH_PATTERN=Found out of order GTID + if ($strict_mode_err) + { + --echo # Expecting to find out of order GTID error.. + } + if (!$strict_mode_err) + { + --echo # Not expecting to find out of order GTID error.. + } + --source include/search_pattern_in_file.inc +} + +--echo # Test finished - resetting $con1 and $con2.. +--connection $con2 +RESET SLAVE; +RESET MASTER; +set global gtid_slave_pos=""; +CHANGE MASTER TO DO_DOMAIN_IDS=(), IGNORE_DOMAIN_IDS=(), IGNORE_SERVER_IDS=(); + +--connection $con1 +RESET MASTER; +DROP TABLE IF EXISTS t1, t2, t3, t4, t5; +--source include/save_master_gtid.inc + +--connection $con2 +--source include/start_slave.inc +--source include/wait_for_slave_to_start.inc +--source include/sync_with_master_gtid.inc +--source include/stop_slave.inc +RESET SLAVE; +set global gtid_slave_pos=""; +RESET MASTER; + +--connection $con1 +RESET MASTER; + +--connection $con2 +if ($strict_mode) +{ + set @@global.gtid_strict_mode=0; +} +--source include/start_slave.inc + +--connection $con1 +--remove_file $BINLOG_FILE_PARAM +--remove_file $MYSQLBINLOG_STDERR + +--let $include_filename= mysqlbinlog_slave_consistency.inc +--source include/end_include_file.inc diff --git a/mysql-test/suite/rpl/include/rpl_EE_err.test b/mysql-test/suite/rpl/include/rpl_EE_err.test new file mode 100644 index 00000000..fa135d12 --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_EE_err.test @@ -0,0 +1,23 @@ +# The test is not relevant when testing replication of error codes for +# statements that are not replicated. The test below could be changed +# to rely on the replication of error codes for statements that are not +# replicated row-based. +# +# See if an EE_ error in one event of the master's binlog stops replication +# (it should not: in this configuration the EE_ error is probably not +# critical). Example: you do a DROP TABLE on a table which has no MYI file +# check if START SLAVE, RESET SLAVE, CHANGE MASTER reset Last_slave_error and +# Last_slave_errno in SHOW SLAVE STATUS (1st and 3rd commands did not: bug 986). +#################################### +#"REQUIREMENT: A master DROP TABLE on a table with non-existing MYI +# file must be correctly replicated to the slave" +#################################### +-- source include/master-slave.inc + +eval create table t1 (a int) engine=$engine_type; +flush tables t1; +let $MYSQLD_DATADIR= `select @@datadir`; +remove_file $MYSQLD_DATADIR/test/t1.MYI ; +drop table if exists t1; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/include/rpl_auto_increment.test b/mysql-test/suite/rpl/include/rpl_auto_increment.test new file mode 100644 index 00000000..67286c37 --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_auto_increment.test @@ -0,0 +1,317 @@ +# +# Test of auto_increment with offset +# +-- source include/master-slave.inc + +eval create table t1 (a int not null auto_increment,b int, primary key (a)) engine=$engine_type2 auto_increment=3; +insert into t1 values (NULL,1),(NULL,2),(NULL,3); +select * from t1; + +sync_slave_with_master; +select * from t1; +connection master; +drop table t1; + +eval create table t1 (a int not null auto_increment,b int, primary key (a)) engine=$engine_type2; +insert into t1 values (1,1),(NULL,2),(3,3),(NULL,4); +delete from t1 where b=4; +insert into t1 values (NULL,5),(NULL,6); +select * from t1; + +sync_slave_with_master; +select * from t1; +connection master; + +drop table t1; + +set @@session.auto_increment_increment=100, @@session.auto_increment_offset=10; +show variables like "auto_inc%"; + +eval create table t1 (a int not null auto_increment, primary key (a)) engine=$engine_type2; +# Insert with 2 insert statements to get better testing of logging +insert into t1 values (NULL),(5),(NULL); +insert into t1 values (250),(NULL); +select * from t1; +insert into t1 values (1000); +set @@insert_id=400; +insert into t1 values(NULL),(NULL); +select * from t1; + +sync_slave_with_master; +select * from t1; +connection master; +drop table t1; + +# +# Same test with innodb (as the innodb code is a bit different) +# +eval create table t1 (a int not null auto_increment, primary key (a)) engine=$engine_type; +# Insert with 2 insert statements to get better testing of logging +insert into t1 values (NULL),(5),(NULL); +insert into t1 values (250),(NULL); +select * from t1; +insert into t1 values (1000); +set @@insert_id=400; +insert into t1 values(NULL),(NULL); +select * from t1; + +sync_slave_with_master; +select * from t1; +connection master; +drop table t1; + +set @@session.auto_increment_increment=1, @@session.auto_increment_offset=1; +eval create table t1 (a int not null auto_increment, primary key (a)) engine=$engine_type2; +# Insert with 2 insert statements to get better testing of logging +insert into t1 values (NULL),(5),(NULL),(NULL); +insert into t1 values (500),(NULL),(502),(NULL),(NULL); +select * from t1; +set @@insert_id=600; +--error ER_DUP_ENTRY +insert into t1 values(600),(NULL),(NULL); +set @@insert_id=600; +insert ignore into t1 values(600),(NULL),(NULL),(610),(NULL); +select * from t1; + +sync_slave_with_master; +select * from t1; +connection master; +drop table t1; + +# +# Test that auto-increment works when slave has rows in the table +# +set @@session.auto_increment_increment=10, @@session.auto_increment_offset=1; + +eval create table t1 (a int not null auto_increment, primary key (a)) engine=$engine_type2; + +sync_slave_with_master; +insert into t1 values(2),(12),(22),(32),(42); +connection master; + +insert into t1 values (NULL),(NULL); +insert into t1 values (3),(NULL),(NULL); +select * from t1; + +sync_slave_with_master; +select * from t1; + +# Test for BUG#20524 "auto_increment_* not observed when inserting +# a too large value". When an autogenerated value was bigger than the +# maximum possible value of the field, it was truncated to that max +# possible value, without being "rounded down" to still honour +# auto_increment_* variables. + +connection master; +drop table t1; +create table t1 (a tinyint not null auto_increment primary key) engine=myisam; +insert into t1 values(103); +set auto_increment_increment=11; +set auto_increment_offset=4; +insert into t1 values(null); +insert into t1 values(null); +--error 167 +insert into t1 values(null); +select a, mod(a-@@auto_increment_offset,@@auto_increment_increment) from t1 order by a; + +# same but with a larger value +create table t2 (a tinyint unsigned not null auto_increment primary key) engine=myisam; +set auto_increment_increment=10; +set auto_increment_offset=1; +set insert_id=1000; +insert into t2 values(10); +--error 167 +insert into t2 values(null); +select a, mod(a-@@auto_increment_offset,@@auto_increment_increment) from t2 order by a; + +# An offset so big that even first value does not fit +create table t3 like t1; +set auto_increment_increment=1000; +set auto_increment_offset=700; +--error 167 +insert into t3 values(null); +select * from t3 order by a; +sync_slave_with_master; +select * from t1 order by a; +select * from t2 order by a; +select * from t3 order by a; + +connection master; + +drop table t1,t2,t3; +sync_slave_with_master; + +# +# BUG#41986 Replication slave does not pick up proper AUTO_INCREMENT value for Innodb tables +# +connection master; +set auto_increment_increment=1; +set auto_increment_offset=1; +CREATE TABLE t1 (id MEDIUMINT NOT NULL AUTO_INCREMENT PRIMARY KEY) ENGINE=innodb; +INSERT INTO t1 VALUES (NULL), (NULL), (NULL); +show create table t1; + +sync_slave_with_master; +show create table t1; + +connection master; +drop table t1; + +# +# BUG#45999 Row based replication fails when auto_increment field = 0. +# Store engine of Slaves auto-generates new sequence numbers for +# auto_increment fields if the values of them are 0. There is an inconsistency +# between slave and master. When MODE_NO_AUTO_VALUE_ON_ZERO are masters treat +# +source include/rpl_reset.inc; + +connection master; +--disable_warnings +DROP TABLE IF EXISTS t1; +DROP TABLE IF EXISTS t2; +--enable_warnings + +eval CREATE TABLE t1 (id INT NOT NULL AUTO_INCREMENT PRIMARY KEY) ENGINE=$engine_type; +eval CREATE TABLE t2 (id INT NOT NULL AUTO_INCREMENT PRIMARY KEY) ENGINE=$engine_type2; +SET SQL_MODE=''; +# Value of the id will be 1; +INSERT INTO t1 VALUES(NULL); +INSERT INTO t2 VALUES(NULL); +SELECT * FROM t1; +SELECT * FROM t2; +# Value of the id will be 2; +INSERT INTO t1 VALUES(); +INSERT INTO t2 VALUES(); +SELECT * FROM t1; +SELECT * FROM t2; +# Value of the id will be 3. The master treats 0 as NULL or empty because +# NO_AUTO_VALUE_ON_ZERO is not assign to SQL_MODE. +INSERT INTO t1 VALUES(0); +INSERT INTO t2 VALUES(0); +SELECT * FROM t1; +SELECT * FROM t2; + +SET SQL_MODE=NO_AUTO_VALUE_ON_ZERO; +# Value of the id will be 0. The master does not treat 0 as NULL or empty +# because NO_AUTO_VALUE_ON_ZERO has assigned to SQL_MODE. +INSERT INTO t1 VALUES(0); +INSERT INTO t2 VALUES(0); +SELECT * FROM t1; +SELECT * FROM t2; + +INSERT INTO t1 VALUES(4); +INSERT INTO t2 VALUES(4); +FLUSH LOGS; +sync_slave_with_master; + +let $diff_tables= master:t1, slave:t1; +source include/diff_tables.inc; + +let $diff_tables= master:t2, slave:t2; +source include/diff_tables.inc; + +connection master; +DROP TABLE t1; +DROP TABLE t2; +sync_slave_with_master; + +connection master; +let $MYSQLD_DATADIR= `SELECT @@DATADIR`; +--exec $MYSQL_BINLOG $MYSQLD_DATADIR/master-bin.000001 | $MYSQL test +sync_slave_with_master; + +let $diff_tables= master:t1, slave:t1; +source include/diff_tables.inc; + +let $diff_tables= master:t2, slave:t2; +source include/diff_tables.inc; + +# End cleanup +--connection master +DROP TABLE t1; +DROP TABLE t2; +SET SQL_MODE=''; +sync_slave_with_master; + +# +# Bug#54201: "SET INSERT_ID" event must be ignored if corresponding event is +# ignored. +# +connection master; + +CREATE TABLE t1(s VARCHAR(10)) ENGINE=myisam; +# -slave.opt has --replicate-ignore-table=test.t_ignored1 +CREATE TABLE t_ignored1(id INT AUTO_INCREMENT PRIMARY KEY) ENGINE=myisam; +call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statement is unsafe because it invokes a trigger or a stored function that inserts into an AUTO_INCREMENT column"); +sync_slave_with_master; + +connection slave; + +CREATE TABLE test.slave_only(id INT AUTO_INCREMENT PRIMARY KEY) ENGINE=myisam; +INSERT INTO slave_only VALUES(NULL); +CREATE TRIGGER t1_update AFTER UPDATE ON t1 FOR EACH ROW INSERT INTO slave_only VALUES(NULL); + +connection master; + +INSERT INTO t_ignored1 VALUES(NULL); +INSERT INTO t1 VALUES('s'); +UPDATE t1 SET s='s1'; + +# With Bug#54201, slave stops with duplicate key error here due to trigger +# using the insert_id from insert on master into t1_ignored1 +sync_slave_with_master; +connection slave; +SELECT * FROM t1; + +connection master; +CREATE TABLE t_ignored2(id INT AUTO_INCREMENT PRIMARY KEY) ENGINE=myisam; +sync_slave_with_master; + +connection slave; +STOP SLAVE; +# Ignore the next INSERT into t_ignored2 and the INSERT_ID event just before it. +SET GLOBAL sql_slave_skip_counter = 2; +START SLAVE; + +connection master; +INSERT INTO t_ignored2 VALUES(NULL); +UPDATE t1 SET s='s2'; +sync_slave_with_master; + +connection slave; +SELECT * FROM t1; +SHOW TABLES LIKE 't\_ignored_'; +SELECT * FROM t_ignored2; +DROP TABLE slave_only; + +connection master; +DROP TABLE t1; +DROP TABLE t_ignored1; +DROP TABLE t_ignored2; + +# +# BUG#56662 +# The test verifies if the assertion of "next_insert_id == 0" +# will fail in ha_external_lock() function. +# +connection master; +CREATE TABLE t1 (id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, data INT) ENGINE=innodb; + +BEGIN; +--echo # Set sql_mode with NO_AUTO_VALUE_ON_ZERO for allowing +--echo # zero to fill the auto_increment field. +SET SQL_MODE=NO_AUTO_VALUE_ON_ZERO; +INSERT INTO t1(id,data) VALUES(0,2); +--echo # Resetting sql_mode without NO_AUTO_VALUE_ON_ZERO to +--echo # affect the execution of the transaction on slave. +SET SQL_MODE=0; +COMMIT; +SELECT * FROM t1; +sync_slave_with_master; +SELECT * FROM t1; + +connection master; +DROP TABLE t1; +sync_slave_with_master; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/include/rpl_auto_increment_insert_view.test b/mysql-test/suite/rpl/include/rpl_auto_increment_insert_view.test new file mode 100644 index 00000000..30b25955 --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_auto_increment_insert_view.test @@ -0,0 +1,43 @@ +# +# This test verifies if inserting data into view that invokes a +# trigger will make the autoinc values become inconsistent on +# master and slave. +# +connection master; +CREATE TABLE t1(i1 int not null auto_increment, c1 INT, primary key(i1)) engine=innodb; +CREATE TABLE t2(i1 int not null auto_increment, c2 INT, primary key(i1)) engine=innodb; +CREATE TABLE t3(i1 int not null auto_increment, a int, primary key(i1)) engine=innodb; +eval create trigger tr16 $insert_action on t1 for each row insert into t3(a) values(new.c1); +eval create trigger tr17 $insert_action on t2 for each row insert into t3(a) values(new.c2); +begin; +INSERT INTO t1(c1) VALUES (11), (12); +INSERT INTO t2(c2) VALUES (13), (14); + +CREATE VIEW v16 AS SELECT c1, c2 FROM t1, t2; + +INSERT INTO v16(c1) VALUES (15),(16); +INSERT INTO v16(c2) VALUES (17),(18); + +connection master1; +INSERT INTO v16(c1) VALUES (19),(20); +INSERT INTO v16(c2) VALUES (21),(22); + +connection master; +INSERT INTO v16(c1) VALUES (23), (24); +INSERT INTO v16(c1) VALUES (25), (26); +commit; +sync_slave_with_master; +--echo #Test if the results are consistent on master and slave +--echo #for 'INSERT DATA INTO VIEW WHICH INVOKES TRIGGERS' +let $diff_tables= master:t3, slave:t3; +source include/diff_tables.inc; + +connection master; +DROP TABLE t1; +DROP TABLE t2; +DROP TABLE t3; +DROP VIEW v16; +sync_slave_with_master; + + + diff --git a/mysql-test/suite/rpl/include/rpl_auto_increment_invoke_trigger.test b/mysql-test/suite/rpl/include/rpl_auto_increment_invoke_trigger.test new file mode 100644 index 00000000..f93d4353 --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_auto_increment_invoke_trigger.test @@ -0,0 +1,79 @@ +# +# This test verifies if concurrent transactions that invoke a +# trigger that inserts more than one values into one or more +# tables with an auto_increment column will make the autoinc +# values become inconsistent on master and slave. +# + +connection master; +create table t1(a int, b int) engine=innodb; +create table t2(i1 int not null auto_increment, a int, primary key(i1)) engine=innodb; +eval create trigger tr1 $trigger_action on t1 for each row insert into t2(a) values(6); + +create table t3(a int, b int) engine=innodb; +create table t4(i1 int not null auto_increment, a int, primary key(i1)) engine=innodb; +create table t5(a int) engine=innodb; +delimiter |; +eval create trigger tr2 $trigger_action on t3 for each row begin + insert into t4(a) values(f1_insert_triggered()); + insert into t4(a) values(f1_insert_triggered()); + insert into t5(a) values(8); +end | +delimiter ;| + +create table t6(i1 int not null auto_increment, a int, primary key(i1)) engine=innodb; +delimiter //; +CREATE FUNCTION f1_insert_triggered() RETURNS INTEGER +BEGIN + INSERT INTO t6(a) values(2),(3); + RETURN 1; +END// +delimiter ;// + +begin; +let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1); +insert into t1(a,b) values(1,1),(2,1); +insert into t3(a,b) values(1,1),(2,1); +update t1 set a = a + 5 where b = 1; +update t3 set a = a + 5 where b = 1; +delete from t1 where b = 1; +delete from t3 where b = 1; + +connection master1; +#The default autocommit is set to 1, so the statement is auto committed +insert into t2(a) values(3); +insert into t4(a) values(3); + +connection master; +commit; +insert into t1(a,b) values(4,2); +insert into t3(a,b) values(4,2); +update t1 set a = a + 5 where b = 2; +update t3 set a = a + 5 where b = 2; +delete from t1 where b = 2; +delete from t3 where b = 2; +--echo # To verify if insert/update in an autoinc column causes statement to be logged in row format +source include/show_binlog_events.inc; +commit; + +connection master; +sync_slave_with_master; +--echo #Test if the results are consistent on master and slave +--echo #for 'INVOKES A TRIGGER with $trigger_action action' +let $diff_tables= master:t2, slave:t2; +source include/diff_tables.inc; +let $diff_tables= master:t4, slave:t4; +source include/diff_tables.inc; +let $diff_tables= master:t6, slave:t6; +source include/diff_tables.inc; + +connection master; +DROP TABLE t1; +DROP TABLE t2; +DROP TABLE t3; +DROP TABLE t4; +DROP TABLE t5; +DROP TABLE t6; +DROP FUNCTION f1_insert_triggered; +sync_slave_with_master; + diff --git a/mysql-test/suite/rpl/include/rpl_autoinc_func_invokes_trigger.test b/mysql-test/suite/rpl/include/rpl_autoinc_func_invokes_trigger.test new file mode 100644 index 00000000..d7c26ea4 --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_autoinc_func_invokes_trigger.test @@ -0,0 +1,55 @@ +# +# This test verifies if concurrent transactions that call a +# function which invokes a 'after/before insert action' trigger +# that inserts more than one values into a table with autoinc +# column will make the autoinc values become inconsistent on +# master and slave. +# + +connection master; +create table t1(a int) engine=innodb; +create table t2(i1 int not null auto_increment, a int, primary key(i1)) engine=innodb; +create table t3(i1 int not null auto_increment, a int, primary key(i1)) engine=innodb; +delimiter |; +CREATE FUNCTION f1_two_inserts_trigger() RETURNS INTEGER +BEGIN + INSERT INTO t2(a) values(2),(3); + INSERT INTO t2(a) values(2),(3); + RETURN 1; +END | +eval create trigger tr11 $insert_action on t2 for each row begin + insert into t3(a) values(new.a); + insert into t3(a) values(new.a); +end | +delimiter ;| +begin; +let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1); +insert into t1(a) values(f1_two_inserts_trigger()); + +connection master1; +#The default autocommit is set to 1, so the statement is auto committed +insert into t2(a) values(4),(5); + +connection master; +commit; +insert into t1(a) values(f1_two_inserts_trigger()); +--echo # To verify if insert/update in an autoinc column causes statement to be logged in row format +source include/show_binlog_events.inc; +commit; + +connection master; +sync_slave_with_master; +--echo #Test if the results are consistent on master and slave +--echo #for 'CALLS A FUNCTION which INVOKES A TRIGGER with $insert_action action' +let $diff_tables= master:t2, slave:t2; +source include/diff_tables.inc; +let $diff_tables= master:t3, slave:t3; +source include/diff_tables.inc; + +connection master; +drop table t1; +drop table t2; +drop table t3; +drop function f1_two_inserts_trigger; +sync_slave_with_master; + diff --git a/mysql-test/suite/rpl/include/rpl_binlog_max_cache_size.test b/mysql-test/suite/rpl/include/rpl_binlog_max_cache_size.test new file mode 100644 index 00000000..2634a602 --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_binlog_max_cache_size.test @@ -0,0 +1,461 @@ +######################################################################################## +# 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. +# +######################################################################################## + +--connection slave +--source include/stop_slave.inc +CHANGE MASTER TO MASTER_USE_GTID=NO; +--source include/start_slave.inc +--connection master + +call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT"); +call mtr.add_suppression("Write to binary log failed: Multi-row statements required more than .max_binlog_stmt_cache_size"); +call mtr.add_suppression("Write to binary log failed: Multi-statement transaction required more than .max_binlog_cache_size"); + +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, 1534 +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, 1534 +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 +--source include/wait_for_slave_sql_error_and_skip.inc + +--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)` +--source include/wait_for_slave_sql_error_and_skip.inc + +--let $diff_tables= master:t1,slave:t1 +--source include/diff_tables.inc + +--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 +--source include/diff_tables.inc + +--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 +--source include/diff_tables.inc + +--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 +--source include/diff_tables.inc + +--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 +--source include/diff_tables.inc + +--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 +--source include/diff_tables.inc + +--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 +--source include/diff_tables.inc + +--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; + +source include/stop_slave.inc; +source 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; + +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 +} +source include/wait_for_slave_sql_error.inc; + +SELECT count(*) FROM t1; +source include/show_binlog_events.inc; + +--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 + +source include/stop_slave.inc; +source include/start_slave.inc; + +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; diff --git a/mysql-test/suite/rpl/include/rpl_blackhole.test b/mysql-test/suite/rpl/include/rpl_blackhole.test new file mode 100644 index 00000000..6e7102b4 --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_blackhole.test @@ -0,0 +1,30 @@ +# Check replication of one statement assuming that the engine on the +# slave is a blackhole engine. + +# Input: +# $statement Statement to evaluate, it is assumed to change t1 + +# 1. Evaluate statement on master, it is assumed to change t1 +# 2. Wait for statement to be processed on slave +# 3. SELECT from table t1 to see what was written +# 4. Compare position on slave before executing statement and after +# executing statement. If difference is >0, then something was +# written to the binary log on the slave. + +# On Connection Slave +let $before = query_get_value("SHOW MASTER STATUS", Position, 1); + +connection master; +eval $statement; + +sync_slave_with_master; +--echo # Expect 0 +SELECT COUNT(*) FROM t1; +let $after = query_get_value("SHOW MASTER STATUS", Position, 1); +let $something_written = `select $after - $before != 0`; +if ($something_written) { + --echo >>> Something was written to binary log <<< +} +if (!$something_written) { + --echo >>> Nothing was written to binary log <<< +} diff --git a/mysql-test/suite/rpl/include/rpl_blackhole_basic.test b/mysql-test/suite/rpl/include/rpl_blackhole_basic.test new file mode 100644 index 00000000..c315906d --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_blackhole_basic.test @@ -0,0 +1,97 @@ +# PURPOSE. Test that blackhole works with replication in all three +# modes: STATEMENT, MIXED, and ROW. +# +# METHOD. We start by creating a table on the master and then change +# the engine to use blackhole on the slave. +# +# After insert/update/delete of one or more rows, the test the +# proceeds to check that replication is running after replicating an +# change, that the blackhole engine does not contain anything (which +# is just a check that the correct engine is used), and that something +# is written to the binary log. +# +# Whe check INSERT, UPDATE, and DELETE statement for tables with no +# key (forcing a range search on the slave), primary keys (using a +# primary key lookup), and index/key with multiple matches (forcing an +# index search). + +# We start with no primary key +CREATE TABLE t1 (a INT, b INT, c INT); +CREATE TABLE t2 (a INT, b INT, c INT); + +sync_slave_with_master; +ALTER TABLE t1 ENGINE=BLACKHOLE; + +connection master; +INSERT INTO t2 VALUES (1,9,1), (2,9,2), (3,9,3), (4,9,4); +sync_slave_with_master; + +# Test insert, no primary key +let $statement = INSERT INTO t1 VALUES (1,1,1),(2,1,2),(3,1,3),(4,1,4); +source include/rpl_blackhole.test; + +# Test update, no primary key +let $statement = UPDATE t1 SET c = 2*c WHERE a % 2 = 0 AND b = 1; +source include/rpl_blackhole.test; + +# Test delete, no primary key +let $statement = DELETE FROM t1 WHERE a % 2 = 0 AND b = 1; +source include/rpl_blackhole.test; + +# Test INSERT-SELECT into Blackhole, no primary key +let $statement = INSERT INTO t1 SELECT * FROM t2; +source include/rpl_blackhole.test; + +# +# The MASTER has MyISAM as the engine for both tables. The SLAVE has Blackhole +# on t1 (transactional engine) and MyISAM on t2 (non-transactional engine). +# +# In MIXED mode, the command "INSERT INTO t2 SELECT * FROM t1" is logged as +# statement on the master. On the slave, it is tagged as unsafe because the +# statement mixes both transactional and non-transactional engines and as such +# its changes are logged as rows. However, due to the nature of the blackhole +# engine, no rows are returned and thus any chain replication would make the +# next master on the chain diverge. +# +# Fo this reason, we have disabled the statement. +# +# Test INSERT-SELECT from Blackhole, no primary key +# let $statement = INSERT INTO t2 SELECT * FROM t1; +# source include/rpl_blackhole.test; +# + +connection master; +ALTER TABLE t1 ADD PRIMARY KEY pk_t1 (a,b); +sync_slave_with_master; + +# Test insert, primary key +let $statement = INSERT INTO t1 VALUES (1,2,1),(2,2,2),(3,2,3),(4,2,4); +source include/rpl_blackhole.test; + +# Test update, primary key +let $statement = UPDATE t1 SET c = 2*c WHERE a % 2 = 0 AND b = 2; +source include/rpl_blackhole.test; + +# Test delete, primary key +let $statement = DELETE FROM t1 WHERE a % 2 = 0 AND b = 2; +source include/rpl_blackhole.test; + +connection master; +ALTER TABLE t1 DROP PRIMARY KEY, ADD KEY key_t1 (a); +sync_slave_with_master; + +# Test insert, key +let $statement = INSERT INTO t1 VALUES (1,3,1),(2,3,2),(3,3,3),(4,3,4); +source include/rpl_blackhole.test; + +# Test update, key +let $statement = UPDATE t1 SET c = 2*c WHERE a % 2 = 0 AND b = 3; +source include/rpl_blackhole.test; + +# Test delete, key +let $statement = DELETE FROM t1 WHERE a % 2 = 0 AND b = 3; +source include/rpl_blackhole.test; + +connection master; +DROP TABLE t1,t2; +sync_slave_with_master; diff --git a/mysql-test/suite/rpl/include/rpl_change_master_demote.inc b/mysql-test/suite/rpl/include/rpl_change_master_demote.inc new file mode 100644 index 00000000..4c563454 --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_change_master_demote.inc @@ -0,0 +1,89 @@ +# +# This file tests that a master can be demoted to a slave using +# CHANGE MASTER TO MASTER_DEMOTE_TO_SLAVE=1 and replication will work correctly +# afterwards. +# +# param $ignore_domain_ids : List of GTID domain ids to use for +# CHANGE MASTER TO IGNORE_DOMAIN_IDS +# + +--let $include_filename= rpl_change_master_demote.inc +--source include/begin_include_file.inc + +--echo ############################################## +--echo # Connection semantics change: +--echo # * True primary is now connection 'slave' +--echo # * True replica is now connection 'master' +--echo ############################################## + +--connection master +SELECT VARIABLE_NAME, GLOBAL_VALUE FROM INFORMATION_SCHEMA.SYSTEM_VARIABLES WHERE VARIABLE_NAME LIKE 'gtid_binlog_pos' OR VARIABLE_NAME LIKE 'gtid_slave_pos' OR VARIABLE_NAME LIKE 'gtid_current_pos' ORDER BY VARIABLE_NAME ASC; + +--let $extra_cm_args= +if (`SELECT strcmp("$ignore_domain_ids","") != 0`) +{ + --let $extra_cm_args=, ignore_domain_ids=($ignore_domain_ids) +} + +--echo # First ensure gtid_slave_pos after master_demote_to_slave matches +--echo # gtid_current_pos calculation +--let $current_pos= `SELECT @@gtid_current_pos` +--replace_result $SLAVE_MYPORT SLAVE_PORT +--eval CHANGE MASTER TO master_host='127.0.0.1', master_port=$SLAVE_MYPORT, master_user='root', master_use_gtid=slave_pos, master_demote_to_slave=1 $extra_cm_args +SELECT VARIABLE_NAME, GLOBAL_VALUE FROM INFORMATION_SCHEMA.SYSTEM_VARIABLES WHERE VARIABLE_NAME LIKE 'gtid_binlog_pos' OR VARIABLE_NAME LIKE 'gtid_slave_pos' OR VARIABLE_NAME LIKE 'gtid_current_pos' ORDER BY VARIABLE_NAME ASC; +--let $slave_pos= `SELECT @@gtid_slave_pos` +--echo # Validating gtid_slave_pos == gtid_binlog_pos.. +if ($slave_pos != $current_pos) +{ + SELECT VARIABLE_NAME, GLOBAL_VALUE FROM INFORMATION_SCHEMA.SYSTEM_VARIABLES WHERE VARIABLE_NAME LIKE 'gtid_binlog_pos' OR VARIABLE_NAME LIKE 'gtid_slave_pos' OR VARIABLE_NAME LIKE 'gtid_current_pos' ORDER BY VARIABLE_NAME ASC; + die gtid_slave_pos calculation after master_demote_to_slave=1 differs from gtid_current_pos; +} +--echo # ..success + +--source include/start_slave.inc + +--connection slave +--source include/stop_slave.inc + +--echo # Ensuring replication works correctly after role swap +--connection slave +set session gtid_domain_id= 0; +CREATE TABLE repl_t (a int); +INSERT INTO repl_t VALUES (1); +--source include/save_master_gtid.inc + +--connection master +--source include/sync_with_master_gtid.inc +--echo # Validating that replication works.. +--let $n_replicated_rows= query_get_value(SELECT COUNT(*) FROM repl_t, COUNT(*), 1) +if ($n_replicated_rows != 1) +{ + die "Replication is broken"; +} +--echo # ..success + +--echo # Cleaning up replication check data +--connection slave +DROP TABLE repl_t; +--source include/save_master_gtid.inc + +--connection master +--source include/sync_with_master_gtid.inc +SELECT VARIABLE_NAME, GLOBAL_VALUE FROM INFORMATION_SCHEMA.SYSTEM_VARIABLES WHERE VARIABLE_NAME LIKE 'gtid_binlog_pos' OR VARIABLE_NAME LIKE 'gtid_slave_pos' OR VARIABLE_NAME LIKE 'gtid_current_pos' ORDER BY VARIABLE_NAME ASC; + +--echo ############################################## +--echo # Connection semantics change: +--echo # * True primary is back to connection 'master' +--echo # * True replica is back to connection 'slave' +--echo ############################################## + +--connection master +--source include/stop_slave.inc + +--connection slave +--replace_result $MASTER_MYPORT MASTER_PORT +--eval CHANGE MASTER TO master_host='127.0.0.1', master_port=$MASTER_MYPORT, master_user='root', master_use_gtid=slave_pos, master_demote_to_slave=1 +--source include/start_slave.inc + +--let $include_filename= rpl_change_master_demote.inc +--source include/end_include_file.inc diff --git a/mysql-test/suite/rpl/include/rpl_charset.test b/mysql-test/suite/rpl/include/rpl_charset.test new file mode 100644 index 00000000..e67122cb --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_charset.test @@ -0,0 +1,148 @@ +# Replication of character sets. +# This test will fail if the server/client does not support enough charsets. + +source include/master-slave.inc; +set timestamp=1000000000; + +create database mysqltest2 character set latin2; +set @@character_set_server=latin5; +create database mysqltest3; +show create database mysqltest2; +show create database mysqltest3; +sync_slave_with_master; +show create database mysqltest2; +show create database mysqltest3; + +connection master; +set @@collation_server=armscii8_bin; +drop database mysqltest3; +create database mysqltest3; +show create database mysqltest3; +sync_slave_with_master; +show create database mysqltest3; + +connection master; +use mysqltest2; +create table t1 (a int auto_increment primary key, b varchar(100)); +set character_set_client=cp850, collation_connection=latin2_croatian_ci; +insert into t1 (b) values(@@character_set_server); +insert into t1 (b) values(@@collation_server); +# character_set_database and collation_database are not tested as they +# needn't be replicated (Bar said in Jan 2005). +insert into t1 (b) values(@@character_set_client); +# collation_client does not exist +insert into t1 (b) values(@@character_set_connection); +insert into t1 (b) values(@@collation_connection); +select * from t1 order by a; +sync_slave_with_master; +select * from mysqltest2.t1 order by a; + +connection master; +set character_set_client=latin1, collation_connection=latin1_german1_ci; +truncate table t1; +insert into t1 (b) values(@@collation_connection); +insert into t1 (b) values(LEAST("Müller","Muffler")); +set collation_connection=latin1_german2_ci; +insert into t1 (b) values(@@collation_connection); +insert into t1 (b) values(LEAST("Müller","Muffler")); +select * from t1 order by a; +sync_slave_with_master; +select * from mysqltest2.t1 order by a; + +# Presently charset info is not logged with LOAD DATA but it will +# change in Jan 2005 when Dmitri pushes his new LOAD DATA, +# before 5.0.3 goes out. When done, LOAD DATA INFILE should be tested +# here. + +# See if user var is prefixed with collation in binlog and replicated well. +# Note: replication of user variables is broken as far as derivation is +# concerned. That's because when we store a user variable in the binlog, +# we lose its derivation. So later on the slave, it's impossible to +# know if the collation was explicit or not, so we use DERIVATION_NONE, +# which provokes error messages (like 'Illegal mix of collation') when +# we replay the master's INSERT/etc statements. +connection master; +set @a= _cp850 'Müller' collate cp850_general_ci; +truncate table t1; +insert into t1 (b) values(collation(@a)); +select * from t1 order by a; +sync_slave_with_master; +select * from mysqltest2.t1 order by a; + +connection master; +drop database mysqltest2; +drop database mysqltest3; +sync_slave_with_master; + +# Check that we can change global.collation_server (since 5.0.3) + +set global character_set_server=latin2; +set global character_set_server=latin1; # back +connection master; +set global character_set_server=latin2; +set global character_set_server=latin1; # back + +# Test of wrong character set numbers; +error 1115; +set character_set_client=9999999; +error 1273; +set collation_server=9999998; + +# This one was contributed by Sergey Petrunia (BUG#3943) + +use test; +CREATE TABLE t1 (c1 VARBINARY(255), c2 VARBINARY(255)); +SET CHARACTER_SET_CLIENT=koi8r, + CHARACTER_SET_CONNECTION=cp1251, + CHARACTER_SET_RESULTS=koi8r; +INSERT INTO t1 (c1, c2) VALUES ('îÕ, ÚÁ ÒÙÂÁÌËÕ','îÕ, ÚÁ ÒÙÂÁÌËÕ'); +select hex(c1), hex(c2) from t1; +sync_slave_with_master; +select hex(c1), hex(c2) from t1; + +connection master; +drop table t1; +sync_slave_with_master; + +# +# BUG#6676: Derivation of variables must be correct on slave +# +connection master; +eval create table `t1` ( + `pk` varchar(10) not null default '', + primary key (`pk`) +) engine=$engine_type default charset=latin1; +set @p=_latin1 'test'; +update t1 set pk='test' where pk=@p; +drop table t1; + +# End of 4.1 tests + + +--echo # +--echo # Start of 10.3 tests +--echo # + + +--echo # +--echo # MDEV-12685 Oracle-compatible function CHR() +--echo # + +connection master; +CREATE DATABASE db1 DEFAULT CHARACTER SET latin1 COLLATE latin1_bin; +USE db1; +CREATE TABLE t1 AS SELECT CHR(0x60); +sync_slave_with_master; +SHOW CREATE TABLE db1.t1; +connection master; +USE test; +DROP DATABASE db1; +sync_slave_with_master; + + +--echo # +--echo # End of 10.3 tests +--echo # + + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/include/rpl_check_table_consistency.inc b/mysql-test/suite/rpl/include/rpl_check_table_consistency.inc new file mode 100644 index 00000000..957a5d52 --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_check_table_consistency.inc @@ -0,0 +1,63 @@ +# This file provides logic to ensure that all tables in a database are the +# same between two connections. +# +# param $check_db : The name of the database to validate all tables are the +# same within (test by default) +# param $con1 : The connection name of the primary server, defaults to +# master +# param $con2 : The connection name of the replica server, defaults to +# slave + +--let $include_filename= rpl_check_table_consistency.inc +--source include/begin_include_file.inc + +if (!$con1) +{ + --let $con1= master +} +if (!$con2) +{ + --let $con2= slave +} +if (!$check_db) +{ + --let $check_db= test +} + +--connection $con2 +--let $n_tables= `select count(*) from information_schema.tables WHERE table_schema = '$check_db'` + +--echo # Checking consistency of '$check_db' database tables between $con1 and $con2 + +--connection $con1 +--let $c1_n_tables= `select count(*) from information_schema.tables WHERE table_schema = '$check_db'` +if (`SELECT $c1_n_tables != $n_tables`) +{ + die "$con1 had $c1_n_tables tables but $con2 had $n_tables after binlog replay"; +} +--echo # Both servers have $n_tables tables + +--let $ctr= 1 +--echo # Verifying integrity of tables.. +while($ctr <= $n_tables) +{ + --let $cksum_tbl= query_get_value(SELECT table_name FROM information_schema.tables WHERE table_schema = 'test' ORDER BY table_name ASC, table_name, $ctr) + --connection $con1 + --let $c1_cksum= `CHECKSUM TABLE $cksum_tbl` + --connection $con2 + --let $c2_cksum= `CHECKSUM TABLE $cksum_tbl` + + if ($c1_cksum != $c2_cksum) + { + die "Table $cksum_tbl differs between connections $con1 and $con2"; + } + if ($c1_cksum == $c2_cksum) + { + --echo # $cksum_tbl is equivalent on $con1 and $con2 + } + --let $ctr= `SELECT $ctr+1` +} +--echo # All tables are consistent + +--let $include_filename= rpl_check_table_consistency.inc +--source include/end_include_file.inc diff --git a/mysql-test/suite/rpl/include/rpl_commit_after_flush.test b/mysql-test/suite/rpl/include/rpl_commit_after_flush.test new file mode 100644 index 00000000..7de4f421 --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_commit_after_flush.test @@ -0,0 +1,14 @@ +eval CREATE TABLE t1 (a INT) ENGINE=$engine_type; + +begin; +insert into t1 values(1); +flush tables with read lock; +commit; +sync_slave_with_master; +# cleanup +connection master; +unlock tables; +drop table t1; +sync_slave_with_master; + +# End of 4.1 tests diff --git a/mysql-test/suite/rpl/include/rpl_conflicts.test b/mysql-test/suite/rpl/include/rpl_conflicts.test new file mode 100644 index 00000000..a8c796af --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_conflicts.test @@ -0,0 +1,170 @@ +# ==== Purpose ==== +# +# Test that slave behaves well in some conflict situations. The +# following are tested: +# +# - The slave SQL thread sees an 'INSERT' of a row with a key that +# already exists in the table; +# +# - The slave SQL thread sees a 'DELETE' of a row that does not +# exist in the table. +# +# In statement-logging mode, the first conflict type causes the slave +# to stop with an error and the second conflict is ignored. +# +# In row-logging mode, the slave behavior depends the value of +# @@slave_exec_mode on the slave: if @@slave_exec_mode is IDEMPOTENT, +# the slave should ignore the conflicting statement and continue +# normally. If @@slave_exec_mode is STRICT, the slave should stop +# with an error. +# +# This test was previously named rpl_stm_mystery22/rpl_row_mystery22. +# +# +# ==== Method ==== +# +# Create a table on master and slave, insert a row on slave, and +# insert the same row on master. +# +# Create a table on master and slave, insert a row on master with +# binlogging turned off, and remove the row on master with binlogging +# turned on. +# +# +# ==== Related bugs ==== +# +# BUG#31552: Replication breaks when deleting rows from out-of-sync table without PK +# BUG#31609: Not all RBR slave errors reported as errors +# +# Bug in this test case: +# BUG#37718: rpl.rpl_stm_mystery22 fails sporadically on pushbuild +# +# +# ==== Usage ==== +# +# This file assumes the following: +# +# - The test language variable $slave_is_idempotent is set to 1 if the +# slave is expected to stop on duplicate key errors (i.e., if the +# binlog is in statement mode or +# @@global.slave_exec_mode=STRICT). It is set to 0 otherwise. +# +# - Replication has been initialized by include/master-slave.inc +# +# - The test adds a suppression for the following warning: +# Slave: Can't find record in 't1' error.* 1032 + + +--echo ==== Initialize ==== + +connection master; +CREATE TABLE t1(a INT PRIMARY KEY); +sync_slave_with_master; + + +--echo ==== Test: SQL thread sees 'INSERT' of existing key ==== + +--echo ---- Prepare slave so that it will get duplicate key error ---- +# This row will be in the way of the row inserted by master. +INSERT INTO t1 VALUES (1); + +--echo ---- Insert rows on master ---- +connection master; +# Insert the same row on master +INSERT INTO t1 VALUES (1); +save_master_pos; +SELECT * FROM t1; + +connection slave; + +# If we are statement-logging or if slave_exec_mode=STRICT, we now +# expect to see an error on the slave. Otherwise (i.e., we are +# row-logging and slave_exec_mode=IDEMPOTENT), we expect that the +# duplicate row is ignored by the slave and replication continues. +if (`SELECT @@global.binlog_format != 'ROW' OR @@global.slave_exec_mode = 'STRICT'`) { + --echo ---- Wait until slave stops with an error ---- + # Wait until the slave tries to run the query, fails with duplicate + # key error, and stops the SQL thread. + let $slave_sql_errno= 1062; # ER_DUP_ENTRY + source include/wait_for_slave_sql_error.inc; + + --let $err= query_get_value("SHOW SLAVE STATUS", Last_SQL_Error, 1) + --replace_regex /end_log_pos [0-9]+/end_log_pos END_LOG_POS/ + --disable_query_log + --eval SELECT "$err" as 'Last_SQL_Error (expected "duplicate key" error)' + --enable_query_log + call mtr.add_suppression("Slave SQL.*Duplicate entry .1. for key .PRIMARY.* error.* 1062"); + + SELECT * FROM t1; + + --echo ---- Resolve the conflict on the slave and restart SQL thread ---- + DELETE FROM t1 WHERE a = 1; + START SLAVE SQL_THREAD; + source include/wait_for_slave_sql_to_start.inc; +} + +--echo ---- Sync slave and verify that there is no error ---- +sync_with_master; +let $err= query_get_value("SHOW SLAVE STATUS", Last_SQL_Error, 1); +--echo Last_SQL_Error = '$err' (expected no error) +SELECT * FROM t1; + + +--echo ==== Test: SQL thread sees 'DELETE' of non-existing row ==== + +--echo ---- On master, insert two rows, the second with binlogging off ---- +connection master; +DELETE FROM t1; +INSERT INTO t1 VALUES (1); + +sync_slave_with_master; +DELETE FROM t1 WHERE a = 1; + +--echo ---- On master, remove the row that does not exist on slave ---- +connection master; +DELETE FROM t1 WHERE a = 1; +SELECT * FROM t1; +save_master_pos; + +connection slave; + +# If we are row-logging and slave_exec_mode is STRICT, we now expect +# an error since the row to delete does not exist on slave. Otherwise +# (i.e., either we are statement-logging or slave_exec_mode is +# IDEMPOTENT), the absence of the row to delete is ignored and +# replication continues. +if (`SELECT @@global.binlog_format = 'ROW' AND @@global.slave_exec_mode = 'STRICT'`) { + --echo ---- Wait until slave stops with an error ---- + call mtr.add_suppression("Slave SQL.*Can.t find record in .t1., error.* 1032"); + let $slave_sql_errno= 1032; # ER_KEY_NOT_FOUND + source include/wait_for_slave_sql_error.inc; + + --let $err= query_get_value("SHOW SLAVE STATUS", Last_SQL_Error, 1) + --replace_regex /end_log_pos [0-9]+/end_log_pos END_LOG_POS/ + --disable_query_log + --eval SELECT "$err" as 'Last_SQL_Error (expected "duplicate key" error)' + --enable_query_log + + SELECT * FROM t1; + + --echo ---- Resolve the conflict on the slave and restart SQL thread ---- + INSERT INTO t1 VALUES (1); + START SLAVE SQL_THREAD; + source include/wait_for_slave_sql_to_start.inc; +} + +--echo ---- Sync slave and verify that there is no error ---- +# The slave should sync ok, and SHOW SLAVE STATUS should give no +# error. +sync_with_master; +let $err= query_get_value("SHOW SLAVE STATUS", Last_SQL_Error, 1); +--echo Last_SQL_Error = $err (expected no error) +SELECT * FROM t1; + + +--echo ==== Clean up ==== + +connection master; +DROP TABLE t1; + +--sync_slave_with_master diff --git a/mysql-test/suite/rpl/include/rpl_ddl.test b/mysql-test/suite/rpl/include/rpl_ddl.test new file mode 100644 index 00000000..e3083a7f --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_ddl.test @@ -0,0 +1,531 @@ +################# suite/rpl/include/rpl_ddl.test ######################## +# # +# DDL statements (sometimes with implicit COMMIT) and other stuff # +# executed on the master and it's propagation into the slave. # +# # +# The variables # +# $engine_type -- storage engine to be tested/used for the # +# permanent tables within the master # +# $temp_engine_type -- storage engine which supports TEMPORARY # +# tables <> $engine_type # +# $temp_engine_type must point to an all # +# time available storage engine # +# 2007-02 MySQL 5.1 MyISAM and MEMORY only # +# $show_binlog -- print binlog entries # +# 0 - no (default) + fits to the file with # +# results # +# 1 - yes (important for debugging) # +# This variable is used within # +# include/rpl_stmt_seq.inc. # +# $manipulate -- Manipulation of the binary logs # +# 0 - do nothing # +# 1 - so that the output of SHOW BINLOG # +# EVENTS IN contains only # +# commands of the current test sequence # +# This is especially useful, if the # +# $show_binlog is set to 1 and many # +# subtest are executed. # +# This variable is used within # +# include/rpl_stmt_seq.inc. # +# have to be set before sourcing this script. # +# # +# General assumption about the ideal replication behaviour: # +# Whatever on the master is executed the content of the slave must # +# be in sync with it. # +# # +# Tests of special interest: # +# a) Which DDL commands cause an implicit COMMIT ? # +# This is also of interest outside of replication. # +# b) Transactions modifying table content ending with # +# - explicit COMMIT or ROLLBACK # +# - implicit COMMIT because the connection to the master # +# executed a corresponding DDL statement or runs in # +# AUTOCOMMIT mode # +# - something similar to "implicit COMMIT" if the storage # +# engine (master) is not transactional # +# c) Command which change no data like SELECT or SHOW # +# They do not change anything within the master but # +# this must be also valid for the slave. # +# # +####################################################################### + +# Last update: +# 2007-02-12 ML: - slave needs AUTOCOMMIT = 1, because we want to check only +# the propagation of actions of the master connection. +# - replace comments via SQL by "--echo ..." +# - remove some bugs within the testscripts +# - remove the use of include/rpl_stmt_seq2.inc +# +# +# NOTES: +# 2006-11-15 Lars: Matthias (ML) is the "owner" of this test case. +# So, please get him to review it whenever you want to +# do changes to it. +# +# PLEASE BE CAREFUL, WHEN MODIFYING THE TESTS !! +# +# Typical test architecture (--> include/rpl_stmt_seq.inc) +# -------------------------------------------------------- +# 1. Master (no AUTOCOMMIT!): INSERT INTO mysqltest1.t1 without commit +# 2. Master and slave: Check the content of mysqltest1.t1 +# 3. Master (no AUTOCOMMIT!): EXECUTE the statement to be tested +# 4. Master and slave: Check the content of mysqltest1.t1 +# 5. Master (no AUTOCOMMIT!): ROLLBACK +# 6. Master and slave: Check the content of mysqltest1.t1 +# If the previous into mysqltest1.t1 inserted row is visible, +# than the statement to be tested caused an explicit COMMIT +# (statement = COMMIT) or an implicit COMMIT (example CREATE TABLE). +# If the previous into mysqltest1.t1 inserted row is not visible, +# than the statement to be tested caused either an explicit ROLLBACK +# (statement = ROLLBACK), an implicit ROLLBACK (deadlock etc. but +# not tested here) or it does not cause any transaction end. +# 7. Flush the logs +# +# Some rules: +# ----------- +# 1. Any use of mysqltest1.t1 within the statement to be tested must be +# avoided if possible. The only known exception is around LOCK TABLE. +# +# 2. The test logics needs for +# master connection: AUTOCOMMIT = 0 +# slave connection: AUTOCOMMIT = 1 +# The master connection is the actor and the slave connection is +# only an observer. I.e. the slave connection must not influence +# the activities of master connection. +# +# 3. !All! objects to be dropped, renamed, altered ... must be created +# before the tests start. +# --> less switching of AUTOCOMMIT mode on master side. +# +# 4. Never use a test object, which was direct or indirect affected by a +# preceding test sequence again. +# If one preceding test sequence hits a (sometimes not visible, +# because the sql error code of the statement might be 0) bug +# and these rules are ignored, a following test sequence might earn ugly +# effects like failing 'sync_slave_with_master', crashes of the slave or +# abort of the test case etc.. This means during analysis the first look +# points into a totally wrong area. +# Except table mysqltest1.t1 where ONLY DML is allowed. +# +# 5. This file is used in several tests (t/rpl_ddl_.test). +# Please be aware that every change of the current file affects +# the results of these tests. +# +# ML: Some maybe banal hints: +# 1. The fact that we have here a master - slave replication does +# not cause that many general MySQL properties do not apply. +# Example: +# The connection to the slave is just a simple session and not a however +# magic working "copy" of the master session or something similar. +# - TEMPORARY TABLES and @variables are session specific +# - the slave session cannot see these things of the master. +# 2. The slave connection must not call sync_slave_with_master. +# 3. SHOW STATUS SLAVE must be run within the slave connection. +# 4. Testcase analysis becomes much more comfortable if +# $show_binlog within include/rpl_stmt_seq.inc is set to 1. +# + +############################################################### +# Some preparations +############################################################### +set global sql_mode=''; +set local sql_mode=''; +# The sync_slave_with_master is needed to make the xids deterministic. +sync_slave_with_master; + +connection master; +SET AUTOCOMMIT = 1; +# +# 2. CREATE all objects needed +# working database is mysqltest1 +# working table (transactional!) is mysqltest1.t1 +# +CREATE DATABASE mysqltest1; +CREATE DATABASE mysqltest2; +eval CREATE TABLE mysqltest1.t1 (f1 BIGINT) ENGINE=$engine_type; +# Prevent Bug#26687 rpl_ddl test fails if run with --innodb option +# The testscript (suite/rpl/rpl_ddl.test) + the expected result need that the +# slave uses MyISAM for the table mysqltest.t1. +sync_slave_with_master; +connection slave; +if (`SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES + WHERE TABLE_SCHEMA = 'mysqltest1' AND TABLE_NAME = 't1' AND ENGINE <> 'MyISAM'`) +{ + skip This test needs on slave side: InnoDB disabled, default engine: MyISAM; +} +connection master; +INSERT INTO mysqltest1.t1 SET f1= 0; +eval CREATE TABLE mysqltest1.t2 (f1 BIGINT) ENGINE=$engine_type; +eval CREATE TABLE mysqltest1.t3 (f1 BIGINT) ENGINE=$engine_type; +eval CREATE TABLE mysqltest1.t4 (f1 BIGINT) ENGINE=$engine_type; +eval CREATE TABLE mysqltest1.t5 (f1 BIGINT) ENGINE=$engine_type; +eval CREATE TABLE mysqltest1.t6 (f1 BIGINT) ENGINE=$engine_type; +CREATE INDEX my_idx6 ON mysqltest1.t6(f1); +eval CREATE TABLE mysqltest1.t7 (f1 BIGINT) ENGINE=$engine_type; +INSERT INTO mysqltest1.t7 SET f1= 0; +eval CREATE TABLE mysqltest1.t8 (f1 BIGINT) ENGINE=$engine_type; +eval CREATE TABLE mysqltest1.t9 (f1 BIGINT) ENGINE=$engine_type; +eval CREATE TABLE mysqltest1.t10 (f1 BIGINT) ENGINE=$engine_type; +eval CREATE TABLE mysqltest1.t11 (f1 BIGINT) ENGINE=$engine_type; +eval CREATE TABLE mysqltest1.t12 (f1 BIGINT) ENGINE=$engine_type; +eval CREATE TABLE mysqltest1.t13 (f1 BIGINT) ENGINE=$engine_type; +eval CREATE TABLE mysqltest1.t14 (f1 BIGINT) ENGINE=$engine_type; +eval CREATE TABLE mysqltest1.t15 (f1 BIGINT) ENGINE=$engine_type; +eval CREATE TABLE mysqltest1.t16 (f1 BIGINT) ENGINE=$engine_type; +eval CREATE TABLE mysqltest1.t17 (f1 BIGINT) ENGINE=$engine_type; +eval CREATE TABLE mysqltest1.t18 (f1 BIGINT) ENGINE=$engine_type; +eval CREATE TABLE mysqltest1.t19 (f1 BIGINT) ENGINE=$engine_type; +eval CREATE TEMPORARY TABLE mysqltest1.t23 (f1 BIGINT) ENGINE=$temp_engine_type; + +# +# 3. master sessions: never do AUTOCOMMIT +# slave sessions: do AUTOCOMMIT +# +SET AUTOCOMMIT = 0; +use mysqltest1; +sync_slave_with_master; +connection slave; +SET AUTOCOMMIT = 1; +use mysqltest1; +connection master; + + +# We don't want to abort the whole test if one statement sent +# to the server gets an error, because the following test +# sequences are nearly independend of the previous statements. +--disable_abort_on_error + +############################################################### +# Banal case: commands which should never commit +# Just for checking if the test sequence is usable +############################################################### + +let $my_stmt= SELECT 1; +let $my_master_commit= false; +let $my_slave_commit= false; +--source include/rpl_stmt_seq.inc + +let $my_stmt= SELECT COUNT(*) FROM t1; +let $my_master_commit= false; +let $my_slave_commit= false; +--source include/rpl_stmt_seq.inc + +############################################################### +# Banal case: (explicit) COMMIT and ROLLBACK +# Just for checking if the test sequence is usable +############################################################### + +let $my_stmt= COMMIT; +let $my_master_commit= true; +let $my_slave_commit= true; +--source include/rpl_stmt_seq.inc + +let $my_stmt= ROLLBACK; +let $my_master_commit= false; +let $my_slave_commit= false; +--source include/rpl_stmt_seq.inc + +############################################################### +# Cases with commands very similar to COMMIT +############################################################### + +let $my_stmt= SET AUTOCOMMIT=1; +let $my_master_commit= true; +let $my_slave_commit= true; +--source include/rpl_stmt_seq.inc +SET AUTOCOMMIT=0; + +let $my_stmt= START TRANSACTION; +let $my_master_commit= true; +let $my_slave_commit= true; +--source include/rpl_stmt_seq.inc + +let $my_stmt= BEGIN; +let $my_master_commit= true; +let $my_slave_commit= true; +--source include/rpl_stmt_seq.inc + +############################################################### +# Cases with (BASE) TABLES and (UPDATABLE) VIEWs +############################################################### + +let $my_stmt= DROP TABLE mysqltest1.t2; +let $my_master_commit= true; +let $my_slave_commit= true; +--source include/rpl_stmt_seq.inc +SHOW TABLES LIKE 't2'; +connection slave; +SHOW TABLES LIKE 't2'; +connection master; + +let $my_stmt= DROP TEMPORARY TABLE mysqltest1.t23; +let $my_master_commit= false; +let $my_slave_commit= false; +--source include/rpl_stmt_seq.inc +SHOW TABLES LIKE 't23'; +connection slave; +SHOW TABLES LIKE 't23'; +connection master; + +let $my_stmt= RENAME TABLE mysqltest1.t3 to mysqltest1.t20; +let $my_master_commit= true; +let $my_slave_commit= true; +--source include/rpl_stmt_seq.inc +SHOW TABLES LIKE 't20'; +connection slave; +SHOW TABLES LIKE 't20'; +connection master; + +let $my_stmt= ALTER TABLE mysqltest1.t4 ADD column f2 BIGINT; +let $my_master_commit= true; +let $my_slave_commit= true; +--source include/rpl_stmt_seq.inc +describe mysqltest1.t4; +connection slave; +describe mysqltest1.t4; +connection master; + +let $my_stmt= CREATE TABLE mysqltest1.t21 (f1 BIGINT) ENGINE= $engine_type; +let $my_master_commit= true; +let $my_slave_commit= true; +--source include/rpl_stmt_seq.inc + +let $engine=''; +let $eng_type=''; + +let $my_stmt= CREATE TEMPORARY TABLE mysqltest1.t22 (f1 BIGINT) ENGINE=$temp_engine_type; +let $my_master_commit= false; +let $my_slave_commit= false; +--source include/rpl_stmt_seq.inc + +let $my_stmt= TRUNCATE TABLE mysqltest1.t7; +let $my_master_commit= true; +let $my_slave_commit= true; +--source include/rpl_stmt_seq.inc +SELECT * FROM mysqltest1.t7; +sync_slave_with_master; +connection slave; +SELECT * FROM mysqltest1.t7; +connection master; + +############################################################### +# Cases with LOCK/UNLOCK +############################################################### + +# Attention: +# We have to LOCK mysqltest1.t1 here, though it violates the testing +# philosophy. +# Mysql response in case without previous LOCK TABLES mysqltest1.t1 +# is: +# SELECT MAX(...) FROM mysqltest1.t1 is +# ERROR HY000: Table 't1' was not locked with LOCK TABLES +let $my_stmt= LOCK TABLES mysqltest1.t1 WRITE, mysqltest1.t8 READ; +let $my_master_commit= true; +let $my_slave_commit= true; +--source include/rpl_stmt_seq.inc +UNLOCK TABLES; + +# No prior locking +let $my_stmt= UNLOCK TABLES; +let $my_master_commit= false; +let $my_slave_commit= false; +--source include/rpl_stmt_seq.inc + +# With prior read locking +# Attention: +# This subtest generates an error since the rpl_stmt_seq.inc +# tries to insert into t1. +LOCK TABLES mysqltest1.t1 READ; +let $my_stmt= UNLOCK TABLES; +let $my_master_commit= false; +let $my_slave_commit= false; +--source include/rpl_stmt_seq.inc + +# With prior write locking +LOCK TABLES mysqltest1.t1 WRITE, mysqltest1.t8 READ; +let $my_stmt= UNLOCK TABLES; +let $my_master_commit= true; +let $my_slave_commit= true; +--source include/rpl_stmt_seq.inc + +############################################################### +# Cases with INDEXES +############################################################### + +let $my_stmt= DROP INDEX my_idx6 ON mysqltest1.t6; +let $my_master_commit= true; +let $my_slave_commit= true; +--source include/rpl_stmt_seq.inc +SHOW INDEX FROM mysqltest1.t6; +connection slave; +SHOW INDEX FROM mysqltest1.t6; +connection master; + +let $my_stmt= CREATE INDEX my_idx5 ON mysqltest1.t5(f1); +let $my_master_commit= true; +let $my_slave_commit= true; +--source include/rpl_stmt_seq.inc +SHOW INDEX FROM mysqltest1.t5; +connection slave; +SHOW INDEX FROM mysqltest1.t5; +connection master; + +############################################################### +# Cases with DATABASE +############################################################### + +let $my_stmt= DROP DATABASE mysqltest2; +let $my_master_commit= true; +let $my_slave_commit= true; +--source include/rpl_stmt_seq.inc +SHOW DATABASES LIKE "mysqltest2"; +connection slave; +SHOW DATABASES LIKE "mysqltest2"; +connection master; + +let $my_stmt= CREATE DATABASE mysqltest3; +let $my_master_commit= true; +let $my_slave_commit= true; +--source include/rpl_stmt_seq.inc +SHOW DATABASES LIKE "mysqltest3"; +connection slave; +SHOW DATABASES LIKE "mysqltest3"; +connection master; + +# End of 4.1 tests + +############################################################### +# Cases with STORED PROCEDUREs +############################################################### +let $my_stmt= CREATE PROCEDURE p1() READS SQL DATA SELECT "this is p1"; +let $my_master_commit= true; +let $my_slave_commit= true; +--source include/rpl_stmt_seq.inc +--vertical_results +--replace_column 5 # 6 # +SHOW PROCEDURE STATUS LIKE 'p1'; +connection slave; +--replace_column 5 # 6 # +SHOW PROCEDURE STATUS LIKE 'p1'; +connection master; +--horizontal_results + +let $my_stmt= ALTER PROCEDURE p1 COMMENT "I have been altered"; +let $my_master_commit= true; +let $my_slave_commit= true; +--source include/rpl_stmt_seq.inc +--vertical_results +--replace_column 5 # 6 # +SHOW PROCEDURE STATUS LIKE 'p1'; +connection slave; +--replace_column 5 # 6 # +SHOW PROCEDURE STATUS LIKE 'p1'; +connection master; +--horizontal_results + +let $my_stmt= DROP PROCEDURE p1; +let $my_master_commit= true; +let $my_slave_commit= true; +--source include/rpl_stmt_seq.inc +--vertical_results +SHOW PROCEDURE STATUS LIKE 'p1'; +connection slave; +SHOW PROCEDURE STATUS LIKE 'p1'; +connection master; +--horizontal_results + +############################################################### +# Cases with VIEWs +############################################################### +let $my_stmt= CREATE OR REPLACE VIEW v1 as select * from t1; +let $my_master_commit= true; +let $my_slave_commit= true; +--source include/rpl_stmt_seq.inc +SHOW CREATE VIEW v1; +connection slave; +SHOW CREATE VIEW v1; +connection master; + +let $my_stmt= ALTER VIEW v1 AS select f1 from t1; +let $my_master_commit= true; +let $my_slave_commit= true; +--source include/rpl_stmt_seq.inc +SHOW CREATE VIEW v1; +connection slave; +SHOW CREATE VIEW v1; +connection master; + +let $my_stmt= DROP VIEW IF EXISTS v1; +let $my_master_commit= true; +let $my_slave_commit= true; +--source include/rpl_stmt_seq.inc +--error 1146 +SHOW CREATE VIEW v1; +connection slave; +--error 1146 +SHOW CREATE VIEW v1; +connection master; + +############################################################### +# Cases with TRIGGERs +############################################################### +let $my_stmt= CREATE TRIGGER trg1 BEFORE INSERT ON t1 FOR EACH ROW SET @a:=1; +let $my_master_commit= true; +let $my_slave_commit= true; +--source include/rpl_stmt_seq.inc +--replace_column 6 # +SHOW TRIGGERS; +connection slave; +--replace_column 6 # +SHOW TRIGGERS; +connection master; + +let $my_stmt= DROP TRIGGER trg1; +let $my_master_commit= true; +let $my_slave_commit= true; +--source include/rpl_stmt_seq.inc +SHOW TRIGGERS; +connection slave; +SHOW TRIGGERS; +connection master; + +############################################################### +# Cases with USERs +############################################################### +let $my_stmt= CREATE USER user1@localhost; +let $my_master_commit= true; +let $my_slave_commit= true; +--source include/rpl_stmt_seq.inc +SELECT user FROM mysql.user WHERE user = 'user1'; +connection slave; +SELECT user FROM mysql.user WHERE user = 'user1'; +connection master; + +let $my_stmt= RENAME USER user1@localhost TO rename1@localhost; +let $my_master_commit= true; +let $my_slave_commit= true; +--source include/rpl_stmt_seq.inc +SELECT user FROM mysql.user WHERE user = 'rename1'; +connection slave; +SELECT user FROM mysql.user WHERE user = 'rename1'; +connection master; + +let $my_stmt= DROP USER rename1@localhost; +let $my_master_commit= true; +let $my_slave_commit= true; +--source include/rpl_stmt_seq.inc +SELECT user FROM mysql.user WHERE user = 'rename1'; +connection slave; +SELECT user FROM mysql.user WHERE user = 'rename1'; + +############################################################### +# Cleanup +############################################################### +use test; +connection master; +DROP TEMPORARY TABLE mysqltest1.t22; +DROP DATABASE mysqltest1; +# mysqltest2 was alreday DROPPED some tests before. +DROP DATABASE mysqltest3; + +set global sql_mode=default; diff --git a/mysql-test/suite/rpl/include/rpl_deadlock.test b/mysql-test/suite/rpl/include/rpl_deadlock.test new file mode 100644 index 00000000..7fcf5cbd --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_deadlock.test @@ -0,0 +1,153 @@ +# See if slave restarts the transaction after failing on an InnoDB deadlock error. + +# Note: testing what happens when too many retries is possible, but +# needs large waits when running with --debug, so we don't do it. +# The same way, this test may not test what is expected when run +# under Valgrind, timings are too short then (with --valgrind I +# (Guilhem) have seen the test manage to provoke lock wait timeout +# error but not deadlock error; that is ok as code deals with the two +# errors in exactly the same way. + +--source include/have_perfschema.inc +--source include/master-slave.inc + +# 0) Prepare tables and data +--echo *** Prepare tables and data *** + +connection master; +eval CREATE TABLE t1 (a INT NOT NULL, KEY(a)) ENGINE=$engine_type; +eval CREATE TABLE t2 (a INT) ENGINE=$engine_type; +eval CREATE TABLE t3 (a INT NOT NULL, KEY(a)) ENGINE=$engine_type; +sync_slave_with_master; + +SHOW CREATE TABLE t1; +SHOW CREATE TABLE t2; +SHOW CREATE TABLE t3; +SHOW VARIABLES LIKE 'slave_transaction_retries'; +--source include/stop_slave.inc + +connection master; +BEGIN; +INSERT INTO t1 VALUES (1); +# We make a long transaction here +INSERT INTO t2 VALUES (2), (2), (2), (2), (2), (2), (2), (2), (2), (2); +INSERT INTO t3 VALUES (3); +COMMIT; +save_master_pos; +# Save BEGIN event into variable +let $master_pos_begin= query_get_value(SHOW BINLOG EVENTS, Pos, 10); +--echo + +# 1) Test deadlock +# Block slave SQL thread, wait retries of transaction, unlock slave before lock timeout +--echo *** Test deadlock *** + +connection slave; +BEGIN; +SELECT * FROM t1 FOR UPDATE; +# Save variable 'Slave_retried_transactions' before deadlock +let $slave_retried_transactions= query_get_value(SHOW GLOBAL STATUS LIKE 'Slave_retried_transactions', Value, 1); +# Run the START SLAVE in a separate connection. Otherwise it terminates +# the SELECT FOR UPDATE transaction (START SLAVE does implicit COMMIT!). +connection slave1; +START SLAVE; +# Wait until SQL thread blocked: variable 'Slave_retried_transactions' will incremented +let $status_var= Slave_retried_transactions; +let $status_var_value= $slave_retried_transactions; +let $status_type= GLOBAL; +let $status_var_comparsion= >; +--source include/wait_for_status_var.inc +connection slave; +SELECT COUNT(*) FROM t2; +COMMIT; + +--echo +--echo # Test that the performance schema coulumn shows > 0 values. +--echo + +--let $assert_text= current number of retries should be more than the value saved before deadlock. +--let $assert_cond= [SELECT COUNT_TRANSACTIONS_RETRIES FROM performance_schema.replication_applier_status, COUNT_TRANSACTIONS_RETRIES, 1] > "$slave_retried_transactions" +--source include/assert.inc + +source include/check_slave_is_running.inc; +sync_with_master; + +# Check the data +SELECT * FROM t1; +SELECT * FROM t3; +# Check that no error is reported +source include/check_slave_is_running.inc; +--echo + +# 2) Test lock wait timeout +# Block slave and wait lock timeout error +--echo *** Test lock wait timeout *** + +connection slave; +--source include/stop_slave.inc +DELETE FROM t2; +# Set slave position to the BEGIN log event +--replace_result $master_pos_begin +eval CHANGE MASTER TO MASTER_LOG_POS=$master_pos_begin, MASTER_USE_GTID=NO; +BEGIN; +# Hold lock +SELECT * FROM t1 FOR UPDATE; +# Wait until slave stopped with error 'Lock wait timeout exceeded' +connection slave1; +START SLAVE; +let $slave_sql_errno= 1205; +--source include/wait_for_slave_sql_error.inc +connection slave; +SELECT COUNT(*) FROM t2; +COMMIT; +--source include/start_slave.inc +sync_with_master; +# Check data from tables +SELECT * FROM t1; +SELECT * FROM t3; +# Check that no error is reported +source include/check_slave_is_running.inc; +--echo + +# 3) Test lock wait timeout and purged relay log +# Set max_relay_log_size=0, block slave and wait lock timeout error. +# Restart slave and check that no erros appear +--echo *** Test lock wait timeout and purged relay logs *** + +connection slave; +SET @my_max_relay_log_size= @@global.max_relay_log_size; +SET global max_relay_log_size=0; +--source include/stop_slave.inc +DELETE FROM t2; +# Set slave position to the BEGIN log event +--replace_result $master_pos_begin +eval CHANGE MASTER TO MASTER_LOG_POS=$master_pos_begin, MASTER_USE_GTID=NO; +BEGIN; +# Hold lock +SELECT * FROM t1 FOR UPDATE; +# Wait until slave stopped with error 'Lock wait timeout exceeded' +connection slave1; +START SLAVE; +let $slave_sql_errno= 1205; +--source include/wait_for_slave_sql_error.inc +connection slave; +SELECT COUNT(*) FROM t2; +COMMIT; +--source include/start_slave.inc +sync_with_master; +# Check data from tables +SELECT * FROM t1; +SELECT * FROM t3; +# Check that no error is reported +source include/check_slave_is_running.inc; +--echo + +# Clean up +--echo *** Clean up *** +connection master; +DROP TABLE t1,t2,t3; +sync_slave_with_master; +SET global max_relay_log_size= @my_max_relay_log_size; + +--echo End of 5.1 tests +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/include/rpl_delete_no_where.test b/mysql-test/suite/rpl/include/rpl_delete_no_where.test new file mode 100644 index 00000000..914bedc6 --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_delete_no_where.test @@ -0,0 +1,17 @@ +# Test to see if a DELETE which triggers a fast deletion of all rows +# (not internally row-per-row but more like a TRUNCATE, MyISAM +# supports that), is replicated (BUG#13576). + +eval create table t1 (a int, b int) engine=$engine_type; +insert into t1 values(1,1); +sync_slave_with_master; +select * from t1; +connection master; +delete from t1; +sync_slave_with_master; +select * from t1; + +# cleanup +connection master; +drop table t1; +sync_slave_with_master; diff --git a/mysql-test/suite/rpl/include/rpl_drop_create_temp_table.inc b/mysql-test/suite/rpl/include/rpl_drop_create_temp_table.inc new file mode 100644 index 00000000..bbc7209e --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_drop_create_temp_table.inc @@ -0,0 +1,1047 @@ +--source include/have_innodb.inc +--disable_abort_on_error + +if (`SELECT HEX(@commands) = HEX('configure')`) +{ + connection master; + + # + # Index that is used as an Id to tables that trigger errors. + # + --let $tt_error_counter=0 + --let $nt_error_counter=0 + + # + # Creates a T-table that is never dropped. + # + --eval CREATE TABLE tt_xx_1 ( id INT ) ENGINE = Innodb + + # + # Creates a N-table that is never dropped. + # + --eval CREATE TABLE nt_xx_1 ( id INT ) ENGINE = MyIsam + + # + # Creates a T-table that is never dropped. + # + --eval CREATE TABLE tt_error_1 ( id INT, PRIMARY KEY (id) ) ENGINE = Innodb + + # + # Creates a N-table that is never dropped. + # + --eval CREATE TABLE nt_error_1 ( id INT, PRIMARY KEY (id) ) ENGINE = MyIsam + + # + # Creates a T-table that is never dropped. + # + --eval CREATE TABLE tt_error_2 ( id INT, PRIMARY KEY (id) ) ENGINE = Innodb + + # + # Creates a N-table that is never dropped. + # + --eval CREATE TABLE nt_error_2 ( id INT, PRIMARY KEY (id) ) ENGINE = MyIsam + + # + # Create a trigger nt_error_2 --> tt_error_2 + # + DELIMITER |; + CREATE TRIGGER tr_i_nt_2_to_tt_2 AFTER INSERT ON nt_error_2 FOR EACH ROW + BEGIN + DECLARE in_stmt_id INTEGER; + INSERT INTO tt_error_2(id) VALUES (NEW.id); + END| + DELIMITER ;| + + # + # Creates a Temporary N-table that is never dropped. + # + --eval CREATE TEMPORARY TABLE nt_tmp_xx_1 ( id INT ) ENGINE = MyIsam + + # + # Creates a Temporary T-table that is never dropped. + # + --eval CREATE TEMPORARY TABLE tt_tmp_xx_1 ( id INT ) ENGINE = Innodb + + # + # In what follows, we create a set of tables that are used + # throughout this test case. The number of tables to be + # created is give by the variable $tot_table. + # + # + # Creates Temporay N-tables that are automatically dropped and recreated + # when a command ends. + # + --let $n= $tot_table + while ($n) + { + --eval DROP TEMPORARY TABLE IF EXISTS nt_tmp_$n + --eval CREATE TEMPORARY TABLE nt_tmp_$n ( id INT ) ENGINE = MyIsam + --disable_query_log + --eval SET @check_temp='$available_n_temp' + --enable_query_log + # + # Updates the $available_n_temp that keeps track of the created + # temporary N-tables. + # + if (`SELECT HEX(@check_temp) != HEX('')`) + { + --let $available_n_temp= $available_n_temp,nt_tmp_$n + } + if (`SELECT HEX(@check_temp) = HEX('')`) + { + --let $available_n_temp= nt_tmp_$n + } + --dec $n + } + + # + # Creates Temporay T-tables that are automatically dropped and recreated + # when a command ends. + # + --let $n= $tot_table + while ($n) + { + --eval DROP TEMPORARY TABLE IF EXISTS tt_tmp_$n + --eval CREATE TEMPORARY TABLE tt_tmp_$n ( id INT ) ENGINE = Innodb + --disable_query_log + --eval SET @check_temp='$available_t_temp' + --enable_query_log + # + # Updates the $available_t_temp that keeps track of the created + # temporary T-tables. + # + if (`SELECT HEX(@check_temp) != HEX('')`) + { + --let $available_t_temp= $available_t_temp,tt_tmp_$n + } + if (`SELECT HEX(@check_temp) = HEX('')`) + { + --let $available_t_temp= tt_tmp_$n + } + --dec $n + } + + # + # Creates N-tables that are automatically dropped and recreated + # when a command ends. + # + --let $n= $tot_table + while ($n) + { + --eval DROP TABLE IF EXISTS nt_$n + --eval CREATE TABLE nt_$n ( id INT ) ENGINE = MyIsam + --disable_query_log + --eval SET @check_temp='$available_n' + --enable_query_log + # + # Updates the $available_n that keeps track of the created + # N-tables. + # + if (`SELECT HEX(@check_temp) != HEX('')`) + { + --let $available_n= $available_n,nt_$n + } + if (`SELECT HEX(@check_temp) = HEX('')`) + { + --let $available_n= nt_$n + } + --dec $n + } + + # + # Creates T-tables that are automatically dropped and recreated + # when a command ends. + # + --let $n= $tot_table + while ($n) + { + --eval DROP TABLE IF EXISTS tt_$n + --eval CREATE TABLE tt_$n ( id INT ) ENGINE = Innodb + --disable_query_log + --eval SET @check_temp='$available_t' + --enable_query_log + # + # Updates the $available_t that keeps track of the created + # T-tables. + # + if (`SELECT HEX(@check_temp) != HEX('')`) + { + --let $available_t= $available_t,tt_$n + } + if (`SELECT HEX(@check_temp) = HEX('')`) + { + --let $available_t= tt_$n + } + --dec $n + } + + --let $dropped_t_temp= + --let $dropped_n_temp= + + --let $dropped_t= + --let $dropped_n= + + let $pos_trans_command= query_get_value("SHOW MASTER STATUS", Position, 1); + + SET @commands= ''; +} + +# +# Drops tables and synchronizes master and slave. +# + +if (`SELECT HEX(@commands) = HEX('clean')`) +{ + connection master; + + DROP TABLE IF EXISTS tt_xx_1; + + DROP TABLE IF EXISTS nt_xx_1; + + DROP TABLE IF EXISTS tt_error_1; + + DROP TABLE IF EXISTS nt_error_1; + + DROP TABLE IF EXISTS tt_error_2; + + DROP TABLE IF EXISTS nt_error_2; + + DROP TEMPORARY TABLE IF EXISTS tt_tmp_xx_1; + DROP TEMPORARY TABLE IF EXISTS nt_tmp_xx_1; + + --let $n= $tot_table + while ($n) + { + --eval DROP TABLE IF EXISTS nt_$n + --eval DROP TEMPORARY TABLE IF EXISTS tt_tmp_$n + --eval DROP TEMPORARY TABLE IF EXISTS nt_tmp_$n + --dec $n + } + + --let $n= $tot_table + while ($n) + { + --eval DROP TABLE IF EXISTS tt_$n + --dec $n + } + + sync_slave_with_master; + + SET @commands= ''; +} + +# +# This is the core of the test is responsible for processing +# the following commands: +# +# B - Begin +# C - Commit +# R - Rollback +# +# +# T - Inserts a row into a T-table +# N-Temp - Inserts a row into a temporary N-table. +# +# +# T-SELECT-N-Temp - Selects from a temporary N-table and inserts +# into a T-table. +# N-SELECT-N-Temp - Selects from a temporary N-table and inserts +# into a N-table. +# T-SELECT-T-Temp - Selects from a temporary T-table and inserts +# into a T-table. +# N-SELECT-T-Temp - Selects from a temporary T-table and inserts +# into a N-table. +# +# +# Create-N-Temp - Creates a temporary N-table if a temporary N-table +# was dropped before +# Create-T-Temp - Creates a temporary T-table if a temporary T-table +# was dropped before +# +# +# Drop-Temp-T-Temp - Drops a temporary T-table if there is any +# Drop-Temp-N-Temp - Drops a temporary N-table if there is any +# Drop-Temp-TN-Temp - Drops both a temporary T-table and N-table if there +# is any +# Drop-Temp-TT-Temp - Drops two temporary T-tables if there is any +# Drop-Temp-NN-Temp - Drops two temporary N-tables if there is any +# Drop-Temp-Xe-Temp - Tries to drop a temporary table that does not exist +# Drop-Temp-NXe-Temp - Drops a temporary N-table if there is any and +# a temporary table that does not exist +# Drop-Temp-TXe-Temp - Drops a temporary T-table if there is any and +# a temporary table that does not exist +# +# +# Drop-Temp-If-Xe-Temp - Tries to drop a temporary table that does not exist +# Drop-Temp-If-TXe-Temp - Drops a temporary T-table if there is any and +# a temporary table that does not exist +# +# +# Drop-T - Drops a T-table if there is any +# Drop-N - Drops a N-table if there is any +# Drop-Xe - Tries to drop a table that does not exist +# Drop-TXe - Drops a T-table if there is any and a table that does +# not exist +# Drop-NXe - Drops a N-table if there is any and a table that does +# not exist +# Drop-TN - Drops both a T-table and N-table if there is any +# Drop-TT - Drops two T-tables if there is any +# Drop-NN - Drops two N-tables if there is any +# Drop-N-TN-Temp - Drops a N-table and both a temporary T-table and +# N-table if there is any +# +# +# Drop-If-Xe - Tries to drop a table that does not exist +# Drop-If-TXe - Drops a T-table if there is any and a table that does +# not exist +# Drop-If-NXe - Drops a N-table if there is any and a table that does +# not exist +# +while (`SELECT HEX(@commands) != HEX('')`) +{ + --disable_query_log + SET @command= SUBSTRING_INDEX(@commands, ' ', 1); + let $command= `SELECT @command`; + --eval SET @check_commands= '$commands' + if (`SELECT HEX(@check_commands) = HEX('''')`) + { + let $commands= `SELECT @commands`; + } + + if (`SELECT HEX(@command) = HEX('B')`) + { + --enable_query_log + eval BEGIN; + --disable_query_log + } + + if (`SELECT HEX(@command) = HEX('T')`) + { + --enable_query_log + eval INSERT INTO tt_xx_1() VALUES (1); + --disable_query_log + } + + if (`SELECT HEX(@command) = HEX('N')`) + { + --enable_query_log + eval INSERT INTO nt_xx_1() VALUES (1); + --disable_query_log + } + + if (`SELECT HEX(@command) = HEX('Te')`) + { + --enable_query_log + --inc $tt_error_counter + eval INSERT INTO tt_error_1() VALUES ($tt_error_counter), ($tt_error_counter); + --disable_query_log + } + + if (`SELECT HEX(@command) = HEX('Ne')`) + { + --enable_query_log + --inc $nt_error_counter + eval INSERT INTO nt_error_1() VALUES ($nt_error_counter), ($nt_error_counter); + --disable_query_log + } + + if (`SELECT HEX(@command) = HEX('NeT-trig')`) + { + --enable_query_log + --inc $nt_error_counter + eval INSERT INTO nt_error_1() VALUES ($nt_error_counter), ($nt_error_counter); + --disable_query_log + } + + if (`SELECT HEX(@command) = HEX('N-Temp')`) + { + --enable_query_log + eval INSERT INTO nt_tmp_xx_1() VALUES (1); + --disable_query_log + } + + if (`SELECT HEX(@command) = HEX('N-SELECT-N-Temp')`) + { + --enable_query_log + eval INSERT INTO nt_xx_1 SELECT * FROM nt_tmp_xx_1; + --disable_query_log + } + + if (`SELECT HEX(@command) = HEX('N-SELECT-T-Temp')`) + { + --enable_query_log + eval INSERT INTO nt_xx_1 SELECT * FROM tt_tmp_xx_1; + --disable_query_log + } + + if (`SELECT HEX(@command) = HEX('T-SELECT-N-Temp')`) + { + --enable_query_log + eval INSERT INTO tt_xx_1 SELECT * FROM nt_tmp_xx_1; + --disable_query_log + } + + if (`SELECT HEX(@command) = HEX('T-SELECT-T-Temp')`) + { + --enable_query_log + eval INSERT INTO tt_xx_1 SELECT * FROM tt_tmp_xx_1; + --disable_query_log + } + + if (`SELECT HEX(@command) = HEX('Create-N-Temp') || HEX(@command) = HEX('Create-T-Temp')`) + { + if (`SELECT HEX(@command) = HEX('Create-N-Temp')`) + { + --let $dropped_temp=$dropped_n_temp + --let $available_temp=$available_n_temp + } + if (`SELECT HEX(@command) = HEX('Create-T-Temp')`) + { + --let $dropped_temp=$dropped_t_temp + --let $available_temp=$available_t_temp + } + + --eval SET @check_temp='$dropped_temp' + if (`SELECT HEX(@check_temp) != HEX('')`) + { + SET @temp= SUBSTRING_INDEX(@check_temp, ',', 1); + let $table=`SELECT @temp`; + --eval SET @check_temp='$available_temp' + if (`SELECT HEX(@check_temp) != HEX('')`) + { + --let $available_temp= $available_temp,$table + } + if (`SELECT HEX(@check_temp) = HEX('')`) + { + --let $available_temp= $table + } + --eval SET @check_temp='$dropped_temp' + --eval SET @table_temp='$table' + SET @check_temp= LTRIM(SUBSTRING(@check_temp, LENGTH(@table_temp) + 2)); + --let $dropped_temp= `SELECT @check_temp` + + if (`SELECT HEX(@command) = HEX('Create-N-Temp')`) + { + --enable_query_log + --eval CREATE TEMPORARY TABLE $table ( id INT ) engine= MyIsam + --disable_query_log + + --let $available_n_temp= $available_temp + --let $dropped_n_temp= $dropped_temp + } + if (`SELECT HEX(@command) = HEX('Create-T-Temp')`) + { + --enable_query_log + --eval CREATE TEMPORARY TABLE $table ( id INT ) engine= Innodb + --disable_query_log + + --let $available_t_temp= $available_temp + --let $dropped_t_temp= $dropped_temp + } + } + } + + if (`SELECT HEX(@command) = HEX('Drop-Temp-N-Temp') || HEX(@command) = HEX('Drop-Temp-T-Temp') || HEX(@command) = HEX('Drop-T') || HEX(@command) = HEX('Drop-N')`) + { + if (`SELECT HEX(@command) = HEX('Drop-Temp-N-Temp')`) + { + --let $dropped_temp=$dropped_n_temp + --let $available_temp=$available_n_temp + } + if (`SELECT HEX(@command) = HEX('Drop-Temp-T-Temp')`) + { + --let $dropped_temp=$dropped_t_temp + --let $available_temp=$available_t_temp + } + if (`SELECT HEX(@command) = HEX('Drop-N')`) + { + --let $dropped_temp=$dropped_n + --let $available_temp=$available_n + } + if (`SELECT HEX(@command) = HEX('Drop-T')`) + { + --let $dropped_temp=$dropped_t + --let $available_temp=$available_t + } + + --eval SET @check_temp='$available_temp' + if (`SELECT HEX(@check_temp) != HEX('')`) + { + SET @temp= SUBSTRING_INDEX(@check_temp, ',', 1); + let $table=`SELECT @temp`; + --eval SET @check_temp='$dropped_temp' + if (`SELECT HEX(@check_temp) != HEX('')`) + { + --let $dropped_temp= $dropped_temp,$table + } + if (`SELECT HEX(@check_temp) = HEX('')`) + { + --let $dropped_temp= $table + } + --eval SET @check_temp='$available_temp' + --eval SET @table_temp='$table' + SET @check_temp= LTRIM(SUBSTRING(@check_temp, LENGTH(@table_temp) + 2)); + --let $available_temp= `SELECT @check_temp` + + if (`SELECT HEX(@command) = HEX('Drop-Temp-N-Temp')`) + { + --enable_query_log + --eval DROP TEMPORARY TABLE $table + --disable_query_log + + --let $available_n_temp= $available_temp + --let $dropped_n_temp= $dropped_temp + } + if (`SELECT HEX(@command) = HEX('Drop-Temp-T-Temp')`) + { + --enable_query_log + --eval DROP TEMPORARY TABLE $table + --disable_query_log + + --let $available_t_temp= $available_temp + --let $dropped_t_temp= $dropped_temp + } + if (`SELECT HEX(@command) = HEX('Drop-N')`) + { + --enable_query_log + --eval DROP TABLE $table + --disable_query_log + + --let $available_n= $available_temp + --let $dropped_n= $dropped_temp + } + if (`SELECT HEX(@command) = HEX('Drop-T')`) + { + --enable_query_log + --eval DROP TABLE $table + --disable_query_log + + --let $available_t= $available_temp + --let $dropped_t= $dropped_temp + } + } + } + + if (`SELECT HEX(@command) = HEX('Drop-Temp-Xe-Temp')`) + { + --enable_query_log + --eval DROP TEMPORARY TABLE tt_xx_1 + --disable_query_log + } + + if (`SELECT HEX(@command) = HEX('Drop-Temp-If-Xe-Temp')`) + { + --enable_query_log + --eval DROP TEMPORARY TABLE IF EXISTS tt_xx_1 + --disable_query_log + } + + if (`SELECT HEX(@command) = HEX('Drop-Xe')`) + { + --enable_query_log + --eval DROP TABLE xx_1 + --disable_query_log + } + + if (`SELECT HEX(@command) = HEX('Drop-If-Xe')`) + { + --enable_query_log + --eval DROP TABLE IF EXISTS xx_1 + --disable_query_log + } + + if (`SELECT HEX(@command) = HEX('Drop-Temp-NXe-Temp') || HEX(@command) = HEX('Drop-Temp-TXe-Temp') || HEX(@command) = HEX('Drop-NXe') || HEX(@command) = HEX('Drop-TXe') || HEX(@command) = HEX('Drop-Temp-If-NXe-Temp') || HEX(@command) = HEX('Drop-Temp-If-TXe-Temp') || HEX(@command) = HEX('Drop-If-NXe') || HEX(@command) = HEX('Drop-If-TXe')`) + { + if (`SELECT HEX(@command) = HEX('Drop-Temp-NXe-Temp') || HEX(@command) = HEX('Drop-Temp-If-NXe-Temp')`) + { + --let $dropped_temp=$dropped_n_temp + --let $available_temp=$available_n_temp + } + if (`SELECT HEX(@command) = HEX('Drop-Temp-TXe-Temp') || HEX(@command) = HEX('Drop-Temp-If-TXe-Temp')`) + { + --let $dropped_temp=$dropped_t_temp + --let $available_temp=$available_t_temp + } + if (`SELECT HEX(@command) = HEX('Drop-NXe') || HEX(@command) = HEX('Drop-If-NXe')`) + { + --let $dropped_temp=$dropped_n + --let $available_temp=$available_n + } + if (`SELECT HEX(@command) = HEX('Drop-TXe') || HEX(@command) = HEX('Drop-If-TXe')`) + { + --let $dropped_temp=$dropped_t + --let $available_temp=$available_t + } + + --eval SET @check_temp='$available_temp' + if (`SELECT HEX(@check_temp) != HEX('')`) + { + SET @temp= SUBSTRING_INDEX(@check_temp, ',', 1); + let $table=`SELECT @temp`; + --eval SET @check_temp='$dropped_temp' + if (`SELECT HEX(@check_temp) != HEX('')`) + { + --let $dropped_temp= $dropped_temp,$table + } + if (`SELECT HEX(@check_temp) = HEX('')`) + { + --let $dropped_n_temp= $table + } + --eval SET @check_temp='$available_temp' + --eval SET @table_temp='$table' + SET @check_temp= LTRIM(SUBSTRING(@check_temp, LENGTH(@table_temp) + 2)); + --let $available_temp= `SELECT @check_temp` + + if (`SELECT HEX(@command) = HEX('Drop-Temp-NXe-Temp')`) + { + --enable_query_log + --eval DROP TEMPORARY TABLE $table, tt_1 + --disable_query_log + + --let $available_n_temp= $available_temp + --let $dropped_n_temp= $dropped_temp + } + if (`SELECT HEX(@command) = HEX('Drop-Temp-If-NXe-Temp')`) + { + --enable_query_log + --eval DROP TEMPORARY TABLE IF EXISTS $table, tt_1 + --disable_query_log + + --let $available_n_temp= $available_temp + --let $dropped_n_temp= $dropped_temp + } + if (`SELECT HEX(@command) = HEX('Drop-Temp-TXe-Temp')`) + { + --enable_query_log + --eval DROP TEMPORARY TABLE $table, tt_1 + --disable_query_log + + --let $available_t_temp= $available_temp + --let $dropped_t_temp= $dropped_temp + } + if (`SELECT HEX(@command) = HEX('Drop-Temp-If-TXe-Temp')`) + { + --enable_query_log + --eval DROP TEMPORARY TABLE IF EXISTS $table, tt_1 + --disable_query_log + + --let $available_t_temp= $available_temp + --let $dropped_t_temp= $dropped_temp + } + if (`SELECT HEX(@command) = HEX('Drop-NXe')`) + { + --enable_query_log + --eval DROP TABLE $table, xx_1 + --disable_query_log + + --let $available_n= $available_temp + --let $dropped_n= $dropped_temp + } + if (`SELECT HEX(@command) = HEX('Drop-If-NXe')`) + { + --enable_query_log + --eval DROP TABLE IF EXISTS $table, xx_1 + --disable_query_log + + --let $available_n= $available_temp + --let $dropped_n= $dropped_temp + } + if (`SELECT HEX(@command) = HEX('Drop-TXe')`) + { + --enable_query_log + --eval DROP TABLE $table, xx_1 + --disable_query_log + + --let $available_t= $available_temp + --let $dropped_t= $dropped_temp + } + if (`SELECT HEX(@command) = HEX('Drop-If-TXe')`) + { + --enable_query_log + --eval DROP TABLE IF EXISTS $table, xx_1 + --disable_query_log + + --let $available_t= $available_temp + --let $dropped_t= $dropped_temp + } + } + } + + if (`SELECT HEX(@command) = HEX('Drop-Temp-NN-Temp') || HEX(@command) = HEX('Drop-Temp-TT-Temp') || HEX(@command) = HEX('Drop-NN') || HEX(@command) = HEX('Drop-TT')`) + { + if (`SELECT HEX(@command) = HEX('Drop-Temp-NN-Temp')`) + { + --let $dropped_temp=$dropped_n_temp + --let $available_temp=$available_n_temp + } + if (`SELECT HEX(@command) = HEX('Drop-Temp-TT-Temp')`) + { + --let $dropped_temp=$dropped_t_temp + --let $available_temp=$available_t_temp + } + if (`SELECT HEX(@command) = HEX('Drop-NN')`) + { + --let $dropped_temp=$dropped_n + --let $available_temp=$available_n + } + if (`SELECT HEX(@command) = HEX('Drop-TT')`) + { + --let $dropped_temp=$dropped_t + --let $available_temp=$available_t + } + + --eval SET @check_temp='$available_temp' + if (`SELECT HEX(@check_temp) != HEX('')`) + { + --let $n= 2 + while (`SELECT HEX(@check_temp) != HEX('') && $n != 0`) + { + SET @temp= SUBSTRING_INDEX(@check_temp, ',', 1); + let $table=`SELECT @temp`; + --eval SET @check_temp='$dropped_temp' + if (`SELECT HEX(@check_temp) != HEX('')`) + { + --let $dropped_temp= $dropped_temp,$table + } + if (`SELECT HEX(@check_temp) = HEX('')`) + { + --let $dropped_temp= $table + } + if ($n == 1) + { + --let $table_1= $table + } + if ($n == 2) + { + --let $table_2= $table + } + + --dec $n + --eval SET @check_temp='$available_temp' + --eval SET @table_temp='$table' + SET @check_temp= LTRIM(SUBSTRING(@check_temp, LENGTH(@table_temp) + 2)); + --let $available_temp= `SELECT @check_temp` + } + + if (`SELECT HEX(@command) = HEX('Drop-Temp-NN-Temp') && $n = 0`) + { + --enable_query_log + --eval DROP TEMPORARY TABLE $table_1, $table_2 + --disable_query_log + + --let $available_n_temp= $available_temp + --let $dropped_n_temp= $dropped_temp + } + if (`SELECT HEX(@command) = HEX('Drop-Temp-TT-Temp') && $n= 0`) + { + --enable_query_log + --eval DROP TEMPORARY TABLE $table_1, $table_2 + --disable_query_log + + --let $available_t_temp= $available_temp + --let $dropped_t_temp= $dropped_temp + } + if (`SELECT HEX(@command) = HEX('Drop-NN') && $n = 0`) + { + --enable_query_log + --eval DROP TABLE $table_1, $table_2 + --disable_query_log + + --let $available_n= $available_temp + --let $dropped_n= $dropped_temp + } + if (`SELECT HEX(@command) = HEX('Drop-TT') && $n= 0`) + { + --enable_query_log + --eval DROP TABLE $table_1, $table_2 + --disable_query_log + + --let $available_t= $available_temp + --let $dropped_t= $dropped_temp + } + } + } + + if (`SELECT HEX(@command) = HEX('Drop-Temp-TN-Temp')`) + { + --eval SET @check_temp_t='$available_t_temp' + --eval SET @check_temp_n='$available_n_temp' + if (`SELECT HEX(@check_temp_t) != HEX('') && HEX(@check_temp_n) != HEX('')`) + { + SET @temp_t= SUBSTRING_INDEX(@check_temp_t, ',', 1); + let $table_t=`SELECT @temp_t`; + --eval SET @check_temp_t='$dropped_t_temp' + if (`SELECT HEX(@check_temp_t) != HEX('')`) + { + --let $dropped_t_temp= $dropped_t_temp,$table_t + } + if (`SELECT HEX(@check_temp_t) = HEX('')`) + { + --let $dropped_t_temp= $table_t + } + --eval SET @check_temp='$available_t_temp' + --eval SET @table_temp='$table_t' + SET @check_temp= LTRIM(SUBSTRING(@check_temp, LENGTH(@table_temp) + 2)); + --let $available_t_temp= `SELECT @check_temp` + + SET @temp_n= SUBSTRING_INDEX(@check_temp_n, ',', 1); + let $table_n=`SELECT @temp_n`; + --eval SET @check_temp_n='$dropped_n_temp' + if (`SELECT HEX(@check_temp_n) != HEX('')`) + { + --let $dropped_n_temp= $dropped_n_temp,$table_n + } + if (`SELECT HEX(@check_temp_n) = HEX('')`) + { + --let $dropped_n_temp= $table_n + } + --eval SET @check_temp='$available_n_temp' + --eval SET @table_temp='$table_n' + SET @check_temp= LTRIM(SUBSTRING(@check_temp, LENGTH(@table_temp) + 2)); + --let $available_n_temp= `SELECT @check_temp` + + --enable_query_log + --eval DROP TEMPORARY TABLE $table_t, $table_n + --disable_query_log + } + } + + if (`SELECT HEX(@command) = HEX('Drop-TN')`) + { + --eval SET @check_temp_t='$available_t' + --eval SET @check_temp_n='$available_n' + if (`SELECT HEX(@check_temp_t) != HEX('') && HEX(@check_temp_n) != HEX('')`) + { + SET @temp_t= SUBSTRING_INDEX(@check_temp_t, ',', 1); + let $table_t=`SELECT @temp_t`; + --eval SET @check_temp_t='$dropped_t' + if (`SELECT HEX(@check_temp_t) != HEX('')`) + { + --let $dropped_t= $dropped_t,$table_t + } + if (`SELECT HEX(@check_temp_t) = HEX('')`) + { + --let $dropped_t= $table_t + } + --eval SET @check_temp='$available_t' + --eval SET @table_temp='$table_t' + SET @check_temp= LTRIM(SUBSTRING(@check_temp, LENGTH(@table_temp) + 2)); + --let $available_t= `SELECT @check_temp` + + SET @temp_n= SUBSTRING_INDEX(@check_temp_n, ',', 1); + let $table_n=`SELECT @temp_n`; + --eval SET @check_temp_n='$dropped_n' + if (`SELECT HEX(@check_temp_n) != HEX('')`) + { + --let $dropped_n= $dropped_n,$table_n + } + if (`SELECT HEX(@check_temp_n) = HEX('')`) + { + --let $dropped_n= $table_n + } + --eval SET @check_temp='$available_n' + --eval SET @table_temp='$table_n' + SET @check_temp= LTRIM(SUBSTRING(@check_temp, LENGTH(@table_temp) + 2)); + --let $available_t= `SELECT @check_temp` + + --enable_query_log + --eval DROP TABLE $table_t, $table_n + --disable_query_log + } + } + + if (`SELECT HEX(@command) = HEX('Drop-N-TN-Temp') || HEX(@command) = HEX('Drop-TN-Temp')`) + { + --eval SET @check_temp_t='$available_t_temp' + --eval SET @check_temp_n='$available_n_temp' + if (`SELECT HEX(@command) = HEX('Drop-N-TN-Temp')`) + { + --eval SET @check_n='$available_n' + } + if (`SELECT HEX(@command) = HEX('Drop-TN-Temp')`) + { + # + # Just to be possible to go through the next if... + # + --eval SET @check_n='...' + } + if (`SELECT HEX(@check_temp_t) != HEX('') && HEX(@check_temp_n) != HEX('') && HEX(@check_n) != HEX('')`) + { + SET @temp_t= SUBSTRING_INDEX(@check_temp_t, ',', 1); + let $table_temp_t=`SELECT @temp_t`; + --eval SET @check_temp_t='$dropped_t_temp' + if (`SELECT HEX(@check_temp_t) != HEX('')`) + { + --let $dropped_t_temp= $dropped_t_temp,$table_temp_t + } + if (`SELECT HEX(@check_temp_t) = HEX('')`) + { + --let $dropped_t_temp= $table_temp_t + } + --eval SET @check_temp='$available_t_temp' + --eval SET @table_temp='$table_temp_t' + SET @check_temp= LTRIM(SUBSTRING(@check_temp, LENGTH(@table_temp) + 2)); + --let $available_t_temp= `SELECT @check_temp` + + SET @temp_n= SUBSTRING_INDEX(@check_temp_n, ',', 1); + let $table_temp_n=`SELECT @temp_n`; + --eval SET @check_temp_n='$dropped_n_temp' + if (`SELECT HEX(@check_temp_n) != HEX('')`) + { + --let $dropped_n_temp= $dropped_n_temp,$table_temp_n + } + if (`SELECT HEX(@check_temp_n) = HEX('')`) + { + --let $dropped_n_temp= $table_temp_n + } + --eval SET @check_temp='$available_n_temp' + --eval SET @table_temp='$table_temp_n' + SET @check_temp= LTRIM(SUBSTRING(@check_temp, LENGTH(@table_temp) + 2)); + --let $available_n_temp= `SELECT @check_temp` + + if (`SELECT HEX(@command) = HEX('Drop-N-TN-Temp')`) + { + SET @temp_n= SUBSTRING_INDEX(@check_n, ',', 1); + let $table_n=`SELECT @temp_n`; + --eval SET @check_n='$dropped_n' + if (`SELECT HEX(@check_n) != HEX('')`) + { + --let $dropped_n= $dropped_n,$table_n + } + if (`SELECT HEX(@check_n) = HEX('')`) + { + --let $dropped_n= $table_n + } + --eval SET @check_temp='$available_n' + --eval SET @table_temp='$table_n' + SET @check_temp= LTRIM(SUBSTRING(@check_temp, LENGTH(@table_temp) + 2)); + --let $available_n= `SELECT @check_temp` + + --enable_query_log + --eval DROP TABLE $table_temp_t, $table_temp_n, $table_n + --disable_query_log + } + if (`SELECT HEX(@command) = HEX('Drop-TN-Temp')`) + { + --enable_query_log + --eval DROP TABLE $table_temp_t, $table_temp_n + --disable_query_log + } + } + } + + if (`SELECT HEX(@command) = HEX('C')`) + { + --enable_query_log + --error 0, ER_GET_ERRMSG + eval COMMIT; + --disable_query_log + } + + if (`SELECT HEX(@command) = HEX('R')`) + { + --enable_query_log + --error 0, ER_GET_ERRMSG + --replace_column 2 # + eval ROLLBACK; + --disable_query_log + } + + SET @commands= LTRIM(SUBSTRING(@commands, LENGTH(@command) + 1)); + if (`SELECT HEX(@commands) = HEX('')`) + { + let $binlog_start= $pos_trans_command; + --echo -b-b-b-b-b-b-b-b-b-b-b- >> $commands << -b-b-b-b-b-b-b-b-b-b-b- + # Use other connection because include/show_binlog_events.inc + # executes SELECT UUID(), which switches to row-logging when + # binlog_format=mixed, if there are open temporary tables. This is + # due to BUG#13692513. + --connection server_1 + --source include/show_binlog_events.inc + --connection master + --echo -e-e-e-e-e-e-e-e-e-e-e- >> $commands << -e-e-e-e-e-e-e-e-e-e-e- + --echo + + --disable_warnings + --let $available_n_temp= + --let $dropped_n_temp= + --let $n= $tot_table + while ($n) + { + --eval DROP TEMPORARY TABLE IF EXISTS nt_tmp_$n + --eval CREATE TEMPORARY TABLE nt_tmp_$n ( id INT ) ENGINE = MyIsam + --eval SET @check_temp='$available_n_temp' + if (`SELECT HEX(@check_temp) != HEX('')`) + { + --let $available_n_temp= $available_n_temp,nt_tmp_$n + } + if (`SELECT HEX(@check_temp) = HEX('')`) + { + --let $available_n_temp= nt_tmp_$n + } + --dec $n + } + + --let $available_t_temp= + --let $dropped_t_temp= + --let $n= $tot_table + while ($n) + { + --eval DROP TEMPORARY TABLE IF EXISTS tt_tmp_$n + --eval CREATE TEMPORARY TABLE tt_tmp_$n ( id INT ) ENGINE = Innodb + --eval SET @check_temp='$available_t_temp' + if (`SELECT HEX(@check_temp) != HEX('')`) + { + --let $available_t_temp= $available_t_temp,tt_tmp_$n + } + if (`SELECT HEX(@check_temp) = HEX('')`) + { + --let $available_t_temp= tt_tmp_$n + } + --dec $n + } + + --let $available_t= + --let $dropped_t= + --let $n= $tot_table + while ($n) + { + --eval DROP TABLE IF EXISTS tt_$n + --eval CREATE TABLE tt_$n ( id INT ) ENGINE = Innodb + --eval SET @check_temp='$available_t' + if (`SELECT HEX(@check_temp) != HEX('')`) + { + --let $available_t= $available_t,tt_$n + } + if (`SELECT HEX(@check_temp) = HEX('')`) + { + --let $available_t= tt_$n + } + --dec $n + } + + --let $available_n= + --let $dropped_n= + --let $n= $tot_table + while ($n) + { + --eval DROP TABLE IF EXISTS nt_$n + --eval CREATE TABLE nt_$n ( id INT ) ENGINE = MyIsam + --eval SET @check_temp='$available_n' + if (`SELECT HEX(@check_temp) != HEX('')`) + { + --let $available_n= $available_n,nt_$n + } + if (`SELECT HEX(@check_temp) = HEX('')`) + { + --let $available_n= nt_$n + } + --dec $n + } + --enable_warnings + + let $pos_trans_command= query_get_value("SHOW MASTER STATUS", Position, 1); + let $commands= ''; + } + --enable_query_log +} diff --git a/mysql-test/suite/rpl/include/rpl_drop_create_temp_table.test b/mysql-test/suite/rpl/include/rpl_drop_create_temp_table.test new file mode 100644 index 00000000..6eb725d4 --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_drop_create_temp_table.test @@ -0,0 +1,564 @@ +############################################################################### +# In this test case, we check how changes to temporary tables are written +# to the binary log. +# +# +# B - Begin +# C - Commit +# R - Rollback +# +# +# T - Inserts a row into a T-table +# +# +# T-SELECT-N-Temp - Selects from a temporary N-table and inserts +# into a T-table. +# N-SELECT-N-Temp - Selects from a temporary N-table and inserts +# into a N-table. +# T-SELECT-T-Temp - Selects from a temporary T-table and inserts +# into a T-table. +# N-SELECT-T-Temp - Selects from a temporary T-table and inserts +# into a N-table. + +# Create-N-Temp - Creates a temporary N-table if a temporary N-table +# was dropped before +# Create-T-Temp - Creates a temporary T-table if a temporary T-table +# was dropped before +# +# +# Drop-Temp-T-Temp - Drops a temporary T-table if there is any +# Drop-Temp-N-Temp - Drops a temporary N-table if there is any +# Drop-Temp-TN-Temp - Drops both a temporary T-table and N-table if there +# is any +# Drop-Temp-TT-Temp - Drops two temporary T-tables if there is any +# Drop-Temp-NN-Temp - Drops two temporary N-tables if there is any +# +# Note: MDEV-20091: DROP TEMPORARY TABLE IF EXISTS statements will be written +# to binlog only if the corresponding temporary table exists. +# +# Drop-Temp-Xe-Temp - Tries to drop a temporary table that does not exist +# Drop-Temp-NXe-Temp - Drops a temporary N-table if there is any and +# a temporary table that does not exist +# Drop-Temp-TXe-Temp - Drops a temporary T-table if there is any and +# a temporary table that does not exist +# +# +# Drop-Temp-If-Xe-Temp - Tries to drop a temporary table that does not exist +# Drop-Temp-If-TXe-Temp - Drops a temporary T-table if there is any and +# a temporary table that does not exist +# +# +# Drop-T - Drops a T-table if there is any +# Drop-N - Drops a N-table if there is any +# Drop-Xe - Tries to drop a table that does not exist +# Drop-TXe - Drops a T-table if there is any and a table that does +# not exist +# Drop-NXe - Drops a N-table if there is any and a table that does +# not exist +# Drop-TN - Drops both a T-table and N-table if there is any +# Drop-TT - Drops two T-tables if there is any +# Drop-NN - Drops two N-tables if there is any +# Drop-N-TN-Temp - Drops a N-table and both a temporary T-table and +# N-table if there is any +# +# +# Drop-If-Xe - Tries to drop a table that does not exist +# Drop-If-TXe - Drops a T-table if there is any and a table that does +# not exist +# +# +# This test uses the commands available at: +# suite/rpl/include/rpl_drop_create_temp_table.inc +# +############################################################################### + + +--echo ######################################################################### +--echo # CONFIGURATION +--echo ######################################################################### + +call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT."); + +--let $tot_table= 2 +SET @commands= 'configure'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +--echo ######################################################################### +--echo # 1 - Tables dropped by "DROP TEMPORARY TABLE" +--echo ######################################################################### +connection master; + +--echo +--echo # +--echo #1) Generates in the binlog what follows: +--echo # +SET @commands= 'Drop-Temp-T-Temp'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'Drop-Temp-N-Temp'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'Drop-Temp-Xe-Temp'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'Drop-Temp-If-Xe-Temp'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'Drop-Temp-TXe-Temp'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'Drop-Temp-If-TXe-Temp'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'Drop-Temp-NXe-Temp'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'Drop-Temp-If-NXe-Temp'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'Drop-Temp-TN-Temp'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'Drop-Temp-TT-Temp'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'Drop-Temp-NN-Temp'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +--echo +--echo # +--echo #2) Generates in the binlog what follows: +--echo # +SET @commands= 'B T Drop-Temp-T-Temp C'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'B T Drop-Temp-T-Temp N Drop-Temp-T-Temp C'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'B T Drop-Temp-N-Temp C'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'B T Drop-Temp-N-Temp N Drop-Temp-N-Temp C'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'B T Drop-Temp-Xe-Temp C'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'B T Drop-Temp-Xe-Temp N Drop-Temp-Xe-Temp C'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'B T Drop-Temp-If-Xe-Temp C'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'B T Drop-Temp-If-Xe-Temp N Drop-Temp-If-Xe-Temp C'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'B T Drop-Temp-TXe-Temp C'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'B T Drop-Temp-TXe-Temp N Drop-Temp-TXe-Temp C'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'B T Drop-Temp-If-TXe-Temp C'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'B T Drop-Temp-If-TXe-Temp N Drop-Temp-If-TXe-Temp C'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'B T Drop-Temp-NXe-Temp C'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'B T Drop-Temp-NXe-Temp N Drop-Temp-NXe-Temp C'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'B T Drop-Temp-If-NXe-Temp C'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'B T Drop-Temp-If-NXe-Temp N Drop-Temp-If-NXe-Temp C'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'B T Drop-Temp-TN-Temp C'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'B T Drop-Temp-TN-Temp N Drop-Temp-TN-Temp C'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'B T Drop-Temp-TT-Temp C'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'B T Drop-Temp-TT-Temp N Drop-Temp-TT-Temp C'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'B T Drop-Temp-NN-Temp C'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'B T Drop-Temp-NN-Temp N Drop-Temp-NN-Temp C'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'B T Drop-Temp-NN-Temp N Drop-Temp-NN-Temp Ne C'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'B T Drop-Temp-NN-Temp N Drop-Temp-NN-Temp Te C'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'B T Drop-Temp-NN-Temp N Drop-Temp-NN-Temp NeT-trig C'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +--echo +--echo # +--echo #3) Generates in the binlog what follows: +--echo # +SET @commands= 'B T Drop-Temp-T-Temp R'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'B T Drop-Temp-T-Temp N Drop-Temp-T-Temp R'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'B T Drop-Temp-N-Temp R'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'B T Drop-Temp-N-Temp N Drop-Temp-N-Temp R'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'B T Drop-Temp-Xe-Temp R'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'B T Drop-Temp-Xe-Temp N Drop-Temp-Xe-Temp R'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'B T Drop-Temp-If-Xe-Temp R'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'B T Drop-Temp-If-Xe-Temp N Drop-Temp-If-Xe-Temp R'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'B T Drop-Temp-TXe-Temp R'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'B T Drop-Temp-TXe-Temp N Drop-Temp-TXe-Temp R'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'B T Drop-Temp-If-TXe-Temp R'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'B T Drop-Temp-If-TXe-Temp N Drop-Temp-If-TXe-Temp R'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'B T Drop-Temp-NXe-Temp R'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'B T Drop-Temp-NXe-Temp N Drop-Temp-NXe-Temp R'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'B T Drop-Temp-If-NXe-Temp R'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'B T Drop-Temp-If-NXe-Temp N Drop-Temp-If-NXe-Temp R'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'B T Drop-Temp-TN-Temp R'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'B T Drop-Temp-TN-Temp N Drop-Temp-TN-Temp R'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'B T Drop-Temp-TT-Temp R'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'B T Drop-Temp-TT-Temp N Drop-Temp-TT-Temp R'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'B T Drop-Temp-NN-Temp R'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'B T Drop-Temp-NN-Temp N Drop-Temp-NN-Temp R'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'B T Drop-Temp-NN-Temp N Drop-Temp-NN-Temp Ne R'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'B T Drop-Temp-NN-Temp N Drop-Temp-NN-Temp Te R'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'B T Drop-Temp-NN-Temp N Drop-Temp-NN-Temp NeT-trig R'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +--echo ######################################################################### +--echo # 2 - Tables dropped by "DROP TABLE" +--echo ######################################################################### +connection master; + +--echo +--echo # +--echo #1) Generates in the binlog what follows: +--echo # +SET @commands= 'Drop-T'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'Drop-N'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'Drop-Xe'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'Drop-If-Xe'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'Drop-TXe'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'Drop-If-TXe'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'Drop-NXe'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'Drop-If-NXe'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'Drop-TN'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'Drop-TT'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'Drop-NN'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'Drop-N-TN-Temp'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'Drop-TN-Temp'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +--echo +--echo # +--echo #2) Generates in the binlog what follows: +--echo # +SET @commands= 'B T Drop-T'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'B T Drop-N'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'B T Drop-Xe'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'B T Drop-If-Xe'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'B T Drop-TXe'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'B T Drop-If-TXe'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'B T Drop-NXe'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'B T Drop-If-NXe'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'B T Drop-TN'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'B T Drop-TT'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'B T Drop-NN'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'B T Drop-N-TN-Temp'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'B T Drop-TN-Temp'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +--echo ######################################################################### +--echo # 3 - CREATE TEMPORARY TABLE +--echo ######################################################################### +connection master; + +--echo +--echo # +--echo #1) Generates in the binlog what follows: +--echo # +SET @commands= 'Drop-Temp-N-Temp Create-N-Temp Drop-Temp-N-Temp Drop-Temp-N-Temp'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'Drop-Temp-T-Temp Create-T-Temp Drop-Temp-T-Temp Drop-Temp-T-Temp'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +--echo +--echo # +--echo #2) Generates in the binlog what follows: +--echo # +SET @commands= 'B T Drop-Temp-N-Temp Create-N-Temp Drop-Temp-N-Temp Drop-Temp-N-Temp C'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'B Drop-Temp-T-Temp Create-T-Temp Drop-Temp-T-Temp Drop-Temp-T-Temp C'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'B Drop-Temp-T-Temp Create-T-Temp Drop-Temp-T-Temp Drop-Temp-T-Temp Ne C'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'B Drop-Temp-T-Temp Create-T-Temp Drop-Temp-T-Temp Drop-Temp-T-Temp Te C'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'B Drop-Temp-T-Temp Create-T-Temp Drop-Temp-T-Temp Drop-Temp-T-Temp NeT-trig C'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +--echo +--echo # +--echo #3) Generates in the binlog what follows: +--echo # +SET @commands= 'B T Drop-Temp-N-Temp Create-N-Temp Drop-Temp-N-Temp Drop-Temp-N-Temp R'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'B Drop-Temp-T-Temp Create-T-Temp Drop-Temp-T-Temp Drop-Temp-T-Temp R'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'B Drop-Temp-T-Temp Create-T-Temp Drop-Temp-T-Temp Drop-Temp-T-Temp Ne R'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'B Drop-Temp-T-Temp Create-T-Temp Drop-Temp-T-Temp Drop-Temp-T-Temp Te R'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'B Drop-Temp-T-Temp Create-T-Temp Drop-Temp-T-Temp Drop-Temp-T-Temp NeT-trig R'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +--echo ######################################################################### +--echo # 4 - CHANGING TEMPORARY TABLES +--echo ######################################################################### +connection master; + +--echo +--echo # +--echo #1) Generates in the binlog what follows: +--echo # +SET @commands= 'B N N-Temp N-SELECT-N-Temp N-Temp C'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'B N N-Temp T-SELECT-N-Temp N-Temp C'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'B N N-Temp N-SELECT-T-Temp N-Temp C'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'B N N-Temp T-SELECT-T-Temp N-Temp C'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'B N N-Temp T-SELECT-T-Temp N-Temp Ne C'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'B N N-Temp T-SELECT-T-Temp N-Temp Te C'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'B N N-Temp T-SELECT-T-Temp N-Temp NeT-trig C'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +--echo +--echo +--echo # +--echo #2) Generates in the binlog what follows: +--echo # +SET @commands= 'B N N-Temp N-SELECT-N-Temp N-Temp R'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'B N N-Temp T-SELECT-N-Temp N-Temp R'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'B N N-Temp N-SELECT-T-Temp N-Temp R'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'B N N-Temp T-SELECT-T-Temp N-Temp R'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'B N N-Temp T-SELECT-T-Temp N-Temp Ne R'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'B N N-Temp T-SELECT-T-Temp N-Temp Te R'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'B N N-Temp T-SELECT-T-Temp N-Temp NeT-trig R'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +--echo # > MDEV-26833 +--echo # Errored out and rolled back Te statement should not produce any event to binlog +--echo # in the following cases: + +SET @sav_var = @@session.binlog_direct_non_transactional_updates; + +SET @@session.binlog_direct_non_transactional_updates = ON; +SET @commands= 'B T Drop-Temp-TT-Temp Te C'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc +SET @commands= 'Drop-Temp-T-Temp B T Create-T-Temp Te C'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc +SET @commands= 'B T Drop-Temp-TN-Temp Te C'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc +SET @commands= 'B T N-Temp Te C'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'B T Drop-Temp-TT-Temp Te R'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc +SET @commands= 'Drop-Temp-T-Temp B T Create-T-Temp Te R'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc +SET @commands= 'B T Drop-Temp-TN-Temp Te R'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc +SET @commands= 'B T N-Temp Te R'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +--echo # Non-transactional side effects. +SET @commands= 'B T N-Temp Te Ne C'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc +SET @commands= 'B T N-Temp Te Ne R'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @@session.binlog_direct_non_transactional_updates = OFF; +SET @commands= 'B T Drop-Temp-TT-Temp Te C'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc +SET @commands= 'Drop-Temp-T-Temp B T Create-T-Temp Te C'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc +SET @commands= 'B T Drop-Temp-TN-Temp Te C'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc +SET @commands= 'B T N-Temp Te C'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @commands= 'B T Drop-Temp-TT-Temp Te R'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc +SET @commands= 'Drop-Temp-T-Temp B T Create-T-Temp Te R'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc +SET @commands= 'B T Drop-Temp-TN-Temp Te R'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc +SET @commands= 'B T N-Temp Te R'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +--echo # Non-transactional side effects. +SET @commands= 'B T N-Temp Te Ne C'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc +SET @commands= 'B T N-Temp Te Ne R'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc + +SET @@session.binlog_direct_non_transactional_updates = @sav_var; +--echo # < MDEV-26833 + +--echo ################################################################################### +--echo # CHECK CONSISTENCY +--echo ################################################################################### +connection master; +sync_slave_with_master; + +let $MYSQLD_DATADIR= `SELECT @@datadir`; + +if (`select @@session.binlog_format != 'STATEMENT'`) +{ + --exec $MYSQL_DUMP --compact --order-by-primary --skip-extended-insert --no-create-info test > $MYSQLD_DATADIR/test-temporary-master.sql + --exec $MYSQL_DUMP_SLAVE --compact --order-by-primary --skip-extended-insert --no-create-info test > $MYSQLD_DATADIR/test-temporary-slave.sql + --diff_files $MYSQLD_DATADIR/test-temporary-master.sql $MYSQLD_DATADIR/test-temporary-slave.sql +} + +--echo ######################################################################### +--echo # CLEAN +--echo ######################################################################### +SET @commands= 'clean'; +--source suite/rpl/include/rpl_drop_create_temp_table.inc diff --git a/mysql-test/suite/rpl/include/rpl_extra_col_master.test b/mysql-test/suite/rpl/include/rpl_extra_col_master.test new file mode 100644 index 00000000..a7abe69d --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_extra_col_master.test @@ -0,0 +1,1023 @@ +############################################################# +# Purpose: To test having extra columns on the master WL#3915 +# engine inspecific sourced part +############################################################# + +# +# Setup differently defined tables on master and slave +# + +# Def on master: t (f_1 type_m_1,... f_s type_m_s, f_s1, f_m) +# Def on slave: t (f_1 type_s_1,... f_s type_s_s) +# where type_mi,type_si (0 < i-1 100; +# check that slave's table content is identical to master +select * from t1 order by n; +# only the auto_inc counter differs. + +connection master; +replace into t1 values(null,100),(null,350); +select * from t1 order by n; +sync_slave_with_master; +select * from t1 order by n; + +# Same test as for REPLACE, but for ON DUPLICATE KEY UPDATE + +# We first check that if we update a row using a value larger than the +# table's counter, the counter for next row is bigger than the +# after-value of the updated row. +connection master; +--disable_warnings ONCE +insert into t1 values (NULL,400),(3,500),(NULL,600) on duplicate key UPDATE n=1000; +select * from t1 order by n; +sync_slave_with_master; +select * from t1 order by n; + +# and now test for the bug: +connection master; +drop table t1; +eval create table t1 (n int primary key auto_increment not null, + b int, unique(b)) engine=$engine_type; +insert into t1 values(null,100); +select * from t1 order by n; +sync_slave_with_master; +insert into t1 values(null,200),(null,300); +delete from t1 where b <> 100; +select * from t1 order by n; + +connection master; +--disable_warnings ONCE +insert into t1 values(null,100),(null,350) on duplicate key update n=2; +select * from t1 order by n; +sync_slave_with_master; +select * from t1 order by n; + +connection master; +drop table t1; +sync_slave_with_master; + +# +# BUG#24432 "INSERT... ON DUPLICATE KEY UPDATE skips auto_increment values" +# + +connection master; +# testcase with INSERT VALUES +eval CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY AUTO_INCREMENT, b INT, + UNIQUE(b)) ENGINE=$engine_type; +--disable_warnings ONCE +INSERT INTO t1(b) VALUES(1),(1),(2) ON DUPLICATE KEY UPDATE t1.b=10; +SELECT * FROM t1 ORDER BY a; +sync_slave_with_master; +SELECT * FROM t1 ORDER BY a; +connection master; +drop table t1; + +# tescase with INSERT SELECT +eval CREATE TABLE t1 ( + id bigint(20) unsigned NOT NULL auto_increment, + field_1 int(10) unsigned NOT NULL, + field_2 varchar(255) NOT NULL, + field_3 varchar(255) NOT NULL, + PRIMARY KEY (id), + UNIQUE KEY field_1 (field_1, field_2) +) ENGINE=$engine_type; +eval CREATE TABLE t2 ( + field_a int(10) unsigned NOT NULL, + field_b varchar(255) NOT NULL, + field_c varchar(255) NOT NULL +) ENGINE=$engine_type; +INSERT INTO t2 (field_a, field_b, field_c) VALUES (1, 'a', '1a'); +INSERT INTO t2 (field_a, field_b, field_c) VALUES (2, 'b', '2b'); +INSERT INTO t2 (field_a, field_b, field_c) VALUES (3, 'c', '3c'); +INSERT INTO t2 (field_a, field_b, field_c) VALUES (4, 'd', '4d'); +INSERT INTO t2 (field_a, field_b, field_c) VALUES (5, 'e', '5e'); +# Updating table t1 based on values from table t2 +--disable_warnings +INSERT INTO t1 (field_1, field_2, field_3) +SELECT t2.field_a, t2.field_b, t2.field_c +FROM t2 +ON DUPLICATE KEY UPDATE +t1.field_3 = t2.field_c; +--enable_warnings +# Inserting new record into t2 +INSERT INTO t2 (field_a, field_b, field_c) VALUES (6, 'f', '6f'); +# Updating t1 again +--disable_warnings +INSERT INTO t1 (field_1, field_2, field_3) +SELECT t2.field_a, t2.field_b, t2.field_c +FROM t2 +ON DUPLICATE KEY UPDATE +t1.field_3 = t2.field_c; +--enable_warnings +SELECT * FROM t1 ORDER BY id; +sync_slave_with_master; +SELECT * FROM t1 ORDER BY id; +connection master; +drop table t1, t2; + +# +# BUG#20339: stored procedure using LAST_INSERT_ID() does not +# replicate statement-based. +# +# There is another version of the test for bug#20339 above that is +# actually originates in 5.1, and this is the version that is merged +# from 5.0. +# +connection master; + +--disable_warnings +DROP PROCEDURE IF EXISTS p1; +DROP TABLE IF EXISTS t1, t2; +--enable_warnings + +# Reset result of LAST_INSERT_ID(). +SELECT LAST_INSERT_ID(0); + +eval CREATE TABLE t1 ( + id INT NOT NULL DEFAULT 0, + last_id INT, + PRIMARY KEY (id) +) ENGINE=$engine_type; + +eval CREATE TABLE t2 ( + id INT NOT NULL AUTO_INCREMENT, + last_id INT, + PRIMARY KEY (id) +) ENGINE=$engine_type; + +delimiter |; +CREATE PROCEDURE p1() +BEGIN + INSERT INTO t2 (last_id) VALUES (LAST_INSERT_ID()); + INSERT INTO t1 (last_id) VALUES (LAST_INSERT_ID()); +END| +delimiter ;| + +CALL p1(); +SELECT * FROM t1 ORDER BY id; +SELECT * FROM t2 ORDER BY id; + +sync_slave_with_master; +SELECT * FROM t1 ORDER BY id; +SELECT * FROM t2 ORDER BY id; + +connection master; + +DROP PROCEDURE p1; +DROP TABLE t1, t2; + + +# +# BUG#21726: Incorrect result with multiple invocations of +# LAST_INSERT_ID +# +--disable_warnings +DROP PROCEDURE IF EXISTS p1; +DROP FUNCTION IF EXISTS f1; +DROP FUNCTION IF EXISTS f2; +DROP FUNCTION IF EXISTS f3; +DROP TABLE IF EXISTS t1, t2; +--enable_warnings + +eval CREATE TABLE t1 ( + i INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + j INT DEFAULT 0 +) ENGINE=$engine_type; +eval CREATE TABLE t2 (i INT) ENGINE=$engine_type; + +delimiter |; +CREATE PROCEDURE p1() +BEGIN + INSERT INTO t1 (i) VALUES (NULL); + INSERT INTO t2 (i) VALUES (LAST_INSERT_ID()); + INSERT INTO t1 (i) VALUES (NULL), (NULL); + INSERT INTO t2 (i) VALUES (LAST_INSERT_ID()); +END | + +CREATE FUNCTION f1() RETURNS INT MODIFIES SQL DATA +BEGIN + INSERT INTO t1 (i) VALUES (NULL); + INSERT INTO t2 (i) VALUES (LAST_INSERT_ID()); + INSERT INTO t1 (i) VALUES (NULL), (NULL); + INSERT INTO t2 (i) VALUES (LAST_INSERT_ID()); + RETURN 0; +END | + +CREATE FUNCTION f2() RETURNS INT NOT DETERMINISTIC + RETURN LAST_INSERT_ID() | + +CREATE FUNCTION f3() RETURNS INT MODIFIES SQL DATA +BEGIN + INSERT INTO t2 (i) VALUES (LAST_INSERT_ID()); + RETURN 0; +END | +delimiter ;| + +INSERT INTO t1 VALUES (NULL, -1); +CALL p1(); +--disable_ps2_protocol +--disable_warnings ONCE +SELECT f1(); +--enable_ps2_protocol +INSERT INTO t1 VALUES (NULL, f2()), (NULL, LAST_INSERT_ID()), + (NULL, LAST_INSERT_ID()), (NULL, f2()), (NULL, f2()); +INSERT INTO t1 VALUES (NULL, f2()); +# Test replication of substitution "IS NULL" -> "= LAST_INSERT_ID". +INSERT INTO t1 VALUES (NULL, 0), (NULL, LAST_INSERT_ID()); +UPDATE t1 SET j= -1 WHERE i IS NULL; + +# Test statement-based replication of function calls. +INSERT INTO t1 (i) VALUES (NULL); + +# Here, we rely on having set @@concurrent_insert= 0 (see comment at +# the top of this file). +connection master1; +INSERT INTO t1 (i) VALUES (NULL); + +connection master; +--disable_ps2_protocol +SELECT f3(); +--enable_ps2_protocol + +SELECT * FROM t1 ORDER BY i; +SELECT * FROM t2 ORDER BY i; + +sync_slave_with_master; +SELECT * FROM t1; +SELECT * FROM t2; + +connection master; +DROP PROCEDURE p1; +DROP FUNCTION f1; +DROP FUNCTION f2; +DROP FUNCTION f3; +DROP TABLE t1, t2; + + +sync_slave_with_master; + +--echo # +--echo # End of 5.0 tests +--echo # + +# Tests in this file are tightly bound together. Recreate t2. +connection master; +eval create table t2 ( + id int not null auto_increment, + last_id int, + primary key (id) +) engine=$engine_type; + + +# Test for BUG#20341 "stored function inserting into one +# auto_increment puts bad data in slave" + +connection master; +truncate table t2; +# no auto_increment +eval create table t1 (id tinyint primary key) engine=$engine_type; + +delimiter |; +create function insid() returns int +begin + insert into t2 (last_id) values (0); + return 0; +end| +delimiter ;| +set sql_log_bin=0; +insert into t2 (id) values(1),(2),(3); +delete from t2; +set sql_log_bin=1; +#inside SELECT, then inside INSERT +--disable_ps2_protocol +--disable_warnings ONCE +select insid(); +--enable_ps2_protocol +set sql_log_bin=0; +insert into t2 (id) values(5),(6),(7); +delete from t2 where id>=5; +set sql_log_bin=1; +--disable_warnings ONCE +insert into t1 select insid(); +select * from t1 order by id; +select * from t2 order by id; + +sync_slave_with_master; +select * from t1 order by id; +select * from t2 order by id; + +connection master; +drop table t1; +drop function insid; + +truncate table t2; +eval create table t1 (n int primary key auto_increment not null, + b int, unique(b)) engine=$engine_type; +delimiter |; +create procedure foo() +begin + insert into t1 values(null,10); + insert ignore into t1 values(null,10); + insert ignore into t1 values(null,10); + insert into t2 values(null,3); +end| +delimiter ;| +--disable_warnings ONCE +call foo(); +select * from t1 order by n; +select * from t2 order by id; + +sync_slave_with_master; +select * from t1 order by n; +select * from t2 order by id; + +connection master; +drop table t1, t2; +drop procedure foo; +SET @@global.concurrent_insert= @old_concurrent_insert; +set @@session.sql_auto_is_null=default; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/include/rpl_insert_id_pk.test b/mysql-test/suite/rpl/include/rpl_insert_id_pk.test new file mode 100644 index 00000000..f6152180 --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_insert_id_pk.test @@ -0,0 +1,83 @@ +########################################################### +# See if queries that use both auto_increment and LAST_INSERT_ID() +# are replicated well +############################################################ +# REQUIREMENT +# Auto increment should work for a table with auto_increment column +# and primary key. +############################################################## + +# We also check how the foreign_key_check variable is replicated + +-- source include/master-slave.inc +call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT."); + +#should work for both SBR and RBR + +create table t1(a int auto_increment, primary key(a)); +create table t2(b int auto_increment, c int, primary key(b)); +insert into t1 values (1),(2),(3); +insert into t1 values (null); +insert into t2 values (null,last_insert_id()); +sync_slave_with_master; +select * from t1 ORDER BY a; +select * from t2 ORDER BY b; +connection master; +#check if multi-line inserts, +#which set last_insert_id to the first id inserted, +#are replicated the same way +drop table t1; +drop table t2; +--disable_warnings +eval create table t1(a int auto_increment, key(a)) engine=$engine_type; +eval create table t2(b int auto_increment, c int, key(b), foreign key(b) references t1(a)) engine=$engine_type; +--enable_warnings +SET FOREIGN_KEY_CHECKS=0; +insert into t1 values (10); +insert into t1 values (null),(null),(null); +insert into t2 values (5,0); +insert into t2 values (null,last_insert_id()); +SET FOREIGN_KEY_CHECKS=1; +sync_slave_with_master; +select * from t1; +select * from t2; +connection master; + +# check if INSERT SELECT in auto_increment is well replicated (bug #490) + +drop table t2; +drop table t1; +create table t1(a int auto_increment, primary key(a)); +create table t2(b int auto_increment, c int, primary key(b)); +insert into t1 values (10); +insert into t1 values (null),(null),(null); +insert into t2 values (5,0); +--disable_warnings ONCE +insert into t2 (c) select * from t1 ORDER BY a; +select * from t2 ORDER BY b; +sync_slave_with_master; +select * from t1 ORDER BY a; +select * from t2 ORDER BY b; +connection master; +drop table t1; +drop table t2; +sync_slave_with_master; + +# +# Bug#8412: Error codes reported in binary log for CHARACTER SET, +# FOREIGN_KEY_CHECKS +# +connection master; +SET TIMESTAMP=1000000000; +CREATE TABLE t1 ( a INT UNIQUE ); +SET FOREIGN_KEY_CHECKS=0; +# Duplicate Key Errors codes +--error 1022, ER_DUP_ENTRY +INSERT INTO t1 VALUES (1),(1); +sync_slave_with_master; +connection master; +drop table t1; + +# End of 4.1 tests + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/include/rpl_insert_ignore.test b/mysql-test/suite/rpl/include/rpl_insert_ignore.test new file mode 100644 index 00000000..f422ef35 --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_insert_ignore.test @@ -0,0 +1,121 @@ +# Testcase for BUG#6287 "Slave skips auto_increment values in Replication with InnoDB" +# The bug was that if on master, INSERT IGNORE ignored some +# rows, and the table was InnoDB with auto_inc column, then on slave +# some rows received an auto_inc bigger than on master. +# Slave needs to be started with --innodb to store table in InnoDB. +# Same test for MyISAM (which had no bug). + +--connection master +eval CREATE TABLE t1 ( + a int unsigned not null auto_increment primary key, + b int unsigned, + unique (b) +) ENGINE=$engine_type; + +eval CREATE TABLE t2 ( + a int unsigned, # to force INSERT SELECT to have a certain order + b int unsigned +) ENGINE=$engine_type; + + +INSERT INTO t1 VALUES (NULL, 1); +INSERT INTO t1 VALUES (NULL, 2); +INSERT INTO t1 VALUES (NULL, 3); +INSERT INTO t1 VALUES (NULL, 4); + +# An alternation of values which will conflict in t1 and will not. + +INSERT INTO t2 VALUES (1, 1); +INSERT INTO t2 VALUES (2, 2); +INSERT INTO t2 VALUES (3, 5); +INSERT INTO t2 VALUES (4, 3); +INSERT INTO t2 VALUES (5, 4); +INSERT INTO t2 VALUES (6, 6); +--disable_warnings ONCE +INSERT IGNORE INTO t1 SELECT NULL, t2.b FROM t2 ORDER BY t2.a; +--let $assert_cond= COUNT(*) = 6 FROM t1 +--let $assert_text= Count of elements in t1 should be 6. +--source include/assert.inc + +# Compare master and slave +--sync_slave_with_master +--let $diff_tables= master:test.t1 , slave:test.t1 +--source include/diff_tables.inc + +# BUG#59338 Inconsistency in binlog for statements that don't change any rows STATEMENT SBR +# An insert ignore that does not update anything must be written to the binary log in SBR +# and MIXED modes. We check this property by counting occurrences in t1 before and after +# the insert and comparing the binlog positions. The count should be the same in both points +# and the statement should be in the binary log. +--connection master +--let $binlog_file= query_get_value("SHOW MASTER STATUS", File, 1) +--let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1) +--let $statement_file=INSERT IGNORE INTO t1 SELECT NULL, t2.b FROM t2 ORDER BY t2.a +--disable_warnings ONCE +--eval $statement_file + +--let $assert_cond= COUNT(*) = 6 FROM t1 +--let $assert_text= Count of elements in t1 should be 6. +--source include/assert.inc + +if (`SELECT @@BINLOG_FORMAT != 'STATEMENT'`) +{ + --let $binlog_position_cmp= = + --let $assert_cond= [SHOW MASTER STATUS, Position, 1] $binlog_position_cmp $binlog_start + --let $assert_text= In SBR or MIXED modes, the event in the binlog should be the same that was executed. In RBR mode, binlog position should stay unchanged. +} +if (`SELECT @@BINLOG_FORMAT = 'STATEMENT'`) +{ + --let $assert_cond= \'[\'SHOW BINLOG EVENTS IN "$binlog_file" FROM $binlog_start LIMIT 2, 1\', Info, 1]\' LIKE \'%$statement_file\' + --let $assert_text= In SBR or MIXED modes, the event in the binlog should be the same that was executed. In RBR mode, binlog position should stay unchanged. +} + +--source include/assert.inc + +# An insert duplicate that does not update anything must be written to the binary +# log in SBR and MIXED modes. We check this property by summing a before and after +# the update and comparing the binlog positions. The sum should be the same at both +# points and the statement should be in the binary log. +--disable_warnings +DROP TABLE t1; +DROP TABLE t2; +--enable_warnings +eval CREATE TABLE t1 ( + a INT UNSIGNED NOT NULL PRIMARY KEY +) ENGINE=$engine_type; + +eval CREATE TABLE t2 ( + a INT UNSIGNED +) ENGINE=$engine_type; + +INSERT INTO t1 VALUES (1); +INSERT INTO t2 VALUES (1); + +--let $binlog_file= query_get_value("SHOW MASTER STATUS", File, 1) +--let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1) +--let $statement_file=INSERT INTO t1 SELECT t2.a FROM t2 ORDER BY t2.a ON DUPLICATE KEY UPDATE t1.a= t1.a +--disable_warnings ONCE +--eval $statement_file + +--let $assert_cond= SUM(a) = 1 FROM t1 +--let $assert_text= Sum of elements in t1 should be 1. +--source include/assert.inc + +if (`SELECT @@BINLOG_FORMAT != 'STATEMENT'`) +{ + --let $binlog_position_cmp= = + --let $assert_cond= [SHOW MASTER STATUS, Position, 1] $binlog_position_cmp $binlog_start + --let $assert_text= In SBR or MIXED modes, the event in the binlog should be the same that was executed. In RBR mode, binlog position should stay unchanged. +} +if (`SELECT @@BINLOG_FORMAT = 'STATEMENT'`) +{ + --let $assert_cond= \'[\'SHOW BINLOG EVENTS IN "$binlog_file" FROM $binlog_start LIMIT 1, 1\', Info, 1]\' LIKE \'%$statement_file\' + --let $assert_text= In SBR or MIXED modes, the event in the binlog should be the same that was executed. In RBR mode, binlog position should stay unchanged. +} +--source include/assert.inc + + +# Clean up +--connection master +drop table t1, t2; +--sync_slave_with_master diff --git a/mysql-test/suite/rpl/include/rpl_loaddata.test b/mysql-test/suite/rpl/include/rpl_loaddata.test new file mode 100644 index 00000000..0a6d03aa --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_loaddata.test @@ -0,0 +1,247 @@ +# See if replication of a "LOAD DATA in an autoincrement column" +# Honours autoincrement values +# i.e. if the master and slave have the same sequence +# +# check replication of load data for temporary tables with additional +# parameters +# +# check if duplicate entries trigger an error (they should unless IGNORE or +# REPLACE was used on the master) (bug 571). +# +# check if START SLAVE, RESET SLAVE, CHANGE MASTER reset Last_slave_error and +# Last_slave_errno in SHOW SLAVE STATUS (1st and 3rd commands did not: bug 986) + +source include/have_innodb.inc; +source include/master-slave.inc; + +--disable_query_log +CALL mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT"); +--enable_query_log + +select last_insert_id(); +create table t1(a int not null auto_increment, b int, primary key(a) ); +eval load data $lock_option infile '../../std_data/rpl_loaddata.dat' into table t1; +# verify that LAST_INSERT_ID() is set by LOAD DATA INFILE +select last_insert_id(); + +create temporary table t2 (day date,id int(9),category enum('a','b','c'),name varchar(60)); +eval load data $lock_option infile '../../std_data/rpl_loaddata2.dat' into table t2 fields terminated by ',' optionally enclosed by '%' escaped by '@' lines terminated by '\n##\n' starting by '>' ignore 1 lines; + +create table t3 (day date,id int(9),category enum('a','b','c'),name varchar(60)); +--disable_warnings +insert into t3 select * from t2; +--enable_warnings + +sync_slave_with_master; + +select * from t1; +select * from t3; + +connection master; + +drop table t1; +drop table t2; +drop table t3; +create table t1(a int, b int, unique(b)); + +sync_slave_with_master; + +# See if slave stops when there's a duplicate entry for key error in LOAD DATA + +insert into t1 values(1,10); + +connection master; +eval load data $lock_option infile '../../std_data/rpl_loaddata.dat' into table t1; + +save_master_pos; +connection slave; +# 1062 = ER_DUP_ENTRY +call mtr.add_suppression("Slave SQL.*Error .Duplicate entry .10. for key .b.. on query.* error.* 1062"); +call mtr.add_suppression("Slave SQL.*Query caused different errors on master and slave.*Error on master:.*error code=1062.*Error on slave:.*error.* 0"); +--let $slave_sql_errno= 1062 +--source include/wait_for_slave_sql_error_and_skip.inc + +# Skip the bad event and see if error is cleared in SHOW SLAVE STATUS by START +# SLAVE, even though we are not executing any event (as sql_slave_skip_counter +# takes us directly to the end of the relay log). + +sync_with_master; +--source include/check_slave_no_error.inc + +# Trigger error again to test CHANGE MASTER + +connection master; +set sql_log_bin=0; +delete from t1; +set sql_log_bin=1; +eval load data $lock_option infile '../../std_data/rpl_loaddata.dat' into table t1; +save_master_pos; +connection slave; +# The SQL slave thread should be stopped now. +# Exec_Master_Log_Pos should point to the start of Execute event +# for last load data. +# 1062 = ER_DUP_ENTRY +--let $slave_sql_errno= 1062 +--source include/wait_for_slave_sql_error.inc + +# CHANGE MASTER and see if error is cleared in SHOW SLAVE STATUS. +--source include/stop_slave_io.inc +change master to master_user='test'; +change master to master_user='root'; +--source include/check_slave_no_error.inc + +# Trigger error again to test RESET SLAVE + +set global sql_slave_skip_counter=1; +start slave; +sync_with_master; +connection master; +set sql_log_bin=0; +delete from t1; +set sql_log_bin=1; +eval load data $lock_option infile '../../std_data/rpl_loaddata.dat' into table t1; +save_master_pos; +connection slave; +# The SQL slave thread should be stopped now. +# 1062 = ER_DUP_ENTRY +--let $slave_sql_errno= 1062 +--source include/wait_for_slave_sql_error.inc + +# RESET SLAVE and see if error is cleared in SHOW SLAVE STATUS. +stop slave; +--source include/reset_slave.inc +--source include/check_slave_no_error.inc + +# Finally, see if logging is done ok on master for a failing LOAD DATA INFILE + +connection master; +reset master; +eval create table t2 (day date,id int(9),category enum('a','b','c'),name varchar(60), +unique(day)) engine=$engine_type; # no transactions +--error ER_DUP_ENTRY +eval load data $lock_option infile '../../std_data/rpl_loaddata2.dat' into table t2 fields +terminated by ',' optionally enclosed by '%' escaped by '@' lines terminated by +'\n##\n' starting by '>' ignore 1 lines; +select * from t2; +save_master_pos; +connection slave; +start slave; +sync_with_master; +select * from t2; + +# verify that if no error on slave, this is an error + +alter table t2 drop key day; +connection master; +delete from t2; +--error ER_DUP_ENTRY +eval load data $lock_option infile '../../std_data/rpl_loaddata2.dat' into table t2 fields +terminated by ',' optionally enclosed by '%' escaped by '@' lines terminated by +'\n##\n' starting by '>' ignore 1 lines; +connection slave; + +if (`SELECT @@global.binlog_format != 'ROW'`) +{ + # Query causes error on master but not on slave. This causes the slave to + # stop with error code 0 (which is wrong: see BUG#57287) + --let $slave_sql_errno= 0 + --source include/wait_for_slave_sql_error.inc + drop table t1, t2; +} +connection master; +drop table t1, t2; + +# BUG#17233 LOAD DATA INFILE: failure causes mysqld dbug_assert, binlog not flushed +CREATE TABLE t1 (word CHAR(20) NOT NULL PRIMARY KEY) ENGINE=INNODB; + +--error ER_DUP_ENTRY +eval LOAD DATA $lock_option INFILE "../../std_data/words.dat" INTO TABLE t1; + +DROP TABLE t1; + +# BUG#48297: Schema name is ignored when LOAD DATA is written into binlog, +# replication aborts +-- let $rpl_only_running_threads= 1 +-- source include/rpl_reset.inc + +-- let $db1= b48297_db1 +-- let $db2= b42897_db2 + +-- connection master + +-- disable_warnings +-- eval drop database if exists $db1 +-- eval drop database if exists $db2 +-- enable_warnings + +-- eval create database $db1 +-- eval create database $db2 + +-- eval use $db1 +-- eval CREATE TABLE t1 (c1 VARCHAR(256)) engine=$engine_type; + +-- eval use $db2 + +-- echo ### assertion: works with cross-referenced database +-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +-- eval LOAD DATA $lock_option LOCAL INFILE '$MYSQLTEST_VARDIR/std_data/loaddata5.dat' INTO TABLE $db1.t1 + +-- eval use $db1 +-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +-- echo ### assertion: works with fully qualified name on current database +-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +-- eval LOAD DATA $lock_option LOCAL INFILE '$MYSQLTEST_VARDIR/std_data/loaddata5.dat' INTO TABLE $db1.t1 + +-- echo ### assertion: works without fully qualified name on current database +-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +-- eval LOAD DATA $lock_option LOCAL INFILE '$MYSQLTEST_VARDIR/std_data/loaddata5.dat' INTO TABLE t1 + +-- echo ### create connection without default database +connect (conn2,localhost,root,,*NO-ONE*); +-- connection conn2 +-- echo ### assertion: works without stating the default database +-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +-- eval LOAD DATA $lock_option LOCAL INFILE '$MYSQLTEST_VARDIR/std_data/loaddata5.dat' INTO TABLE $db1.t1 + +# We cannot disconnect right away because when inserting +# concurrently in a MyISAM table, the server is sending an OK +# to the client before updating the table state (where the +# number of records is kept). See: BUG#37521 and BUG#29334. +# So we need to wait, otherwise we would be having sporadic +# failures as reported here: BUG#50451. + +# 12 = 3 rows per each LOAD DATA executed x 4 +-- let $count= 12 +-- let $table= $db1.t1 +--source include/wait_until_rows_count.inc + +-- disconnect conn2 +-- connection master + +-- sync_slave_with_master +-- eval use $db1 + +let $diff_tables= master:$db1.t1, slave:$db1.t1; +source include/diff_tables.inc; + +-- connection master + +-- eval DROP DATABASE $db1 +-- eval DROP DATABASE $db2 + +-- sync_slave_with_master + +# BUG#49479: LOAD DATA INFILE is binlogged without escaping field names +-- source include/rpl_reset.inc +-- connection master +use test; +CREATE TABLE t1 (`key` TEXT, `text` TEXT); + +LOAD DATA INFILE '../../std_data/loaddata2.dat' REPLACE INTO TABLE `t1` FIELDS TERMINATED BY ','; +SELECT * FROM t1; + +-- sync_slave_with_master +-- connection master +DROP TABLE t1; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/include/rpl_loadfile.test b/mysql-test/suite/rpl/include/rpl_loadfile.test new file mode 100644 index 00000000..9073e5e3 --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_loadfile.test @@ -0,0 +1,32 @@ +# Begin clean up test section +--disable_warnings +connection master; +DROP PROCEDURE IF EXISTS test.p1; +DROP TABLE IF EXISTS test.t1; +--enable_warnings + +# Section 1 test + +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; +delimiter |; +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| +delimiter ;| + +CALL test.p1(); +SELECT * FROM test.t1 ORDER BY blob_column; +save_master_pos; +sync_slave_with_master; +connection slave; +SELECT * FROM test.t1 ORDER BY blob_column; + +# Cleanup +connection master; +DROP PROCEDURE IF EXISTS test.p1; +DROP TABLE test.t1; +sync_slave_with_master; diff --git a/mysql-test/suite/rpl/include/rpl_log.test b/mysql-test/suite/rpl/include/rpl_log.test new file mode 100644 index 00000000..f885602e --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_log.test @@ -0,0 +1,151 @@ +# Requires statement logging + +# Clean up old slave's binlogs. +# The slave is started with --log-slave-updates +# and this test does SHOW BINLOG EVENTS on the slave's +# binlog. But previous tests can influence the current test's +# binlog (e.g. a temporary table in the previous test has not +# been explicitly deleted, and at the beginning of the current +# test the slave immediately writes DROP TEMPORARY TABLE this_old_table). +# We wait for the slave to have written all he wants to the binlog +# (otherwise RESET MASTER may come too early). +sync_slave_with_master; +source include/stop_slave.inc; +--source include/wait_for_slave_to_stop.inc +reset master; +reset slave; +start slave; +--source include/wait_for_slave_to_start.inc + +let $VERSION=`select version()`; +# Lets run this test in STRICT MODE (DROP TABLE is not DROP TABLE IF EXISTS) +connection slave; +set @save_slave_ddl_exec_mode=@@global.slave_ddl_exec_mode; +set @@global.slave_ddl_exec_mode=STRICT; +connection master; + +eval create table t1(n int not null auto_increment primary key)ENGINE=$engine_type; +insert into t1 values (NULL); +drop table t1; +let $LOAD_FILE= ../../std_data/words.dat; +if (!`SELECT length(load_file('$LOAD_FILE'))`){ + let $LOAD_FILE= ../$LOAD_FILE; +} +eval create table t1 (word char(20) not null)ENGINE=$engine_type; +--replace_result $LOAD_FILE LOAD_FILE +eval load data infile '$LOAD_FILE' into table t1 ignore 1 lines; +select count(*) from t1; +source include/show_binlog_events.inc; + +let $binlog_limit= 2; +source include/show_binlog_events.inc; + +let $binlog_limit= 3; +source include/show_binlog_events.inc; + +let $binlog_limit= 2,5; +source include/show_binlog_events.inc; +let $binlog_limit=; +flush logs; +--source include/wait_for_binlog_checkpoint.inc + +# We need an extra update before doing save_master_pos. +# Otherwise, an unlikely scenario may occur: +# * When the master's binlog_dump thread reads the end of master-bin.001, +# it send the rotate event which is at this end, plus a fake rotate event +# because it's starting to read a new binlog. +# save_master_pos will record the position of the first of the two rotate +# (because the fake one is not in the master's binlog anyway). +# * Later the slave waits for the position of the first rotate event, +# and it may quickly stop (in 'slave stop') without having received the fake +# one. +# So, depending on a few milliseconds, we end up with 2 rotate events in the +# relay log or one, which influences the output of SHOW SLAVE STATUS, making +# it not predictable and causing random test failures. +# To make it predictable, we do a useless update now, but which has the +# interest of making the slave catch both rotate events. + +let $skip_checkpoint_events=1; + +eval create table t3 (a int)ENGINE=$engine_type; + +# Sync slave and force it to start on another binary log + +#show rows of t1 on master +connection master; +select * from t1 order by 1 asc; + +sync_slave_with_master; + +#check t1 on slave to ensure whether it's identical with on master +select * from t1 order by 1 asc; +flush logs; +source include/stop_slave.inc; +source include/start_slave.inc; +connection master; + +# Create some entries for second log + +eval create table t2 (n int)ENGINE=$engine_type; +insert into t2 values (1); +source include/show_binlog_events.inc; + +let $binlog_file= query_get_value(SHOW MASTER STATUS, File, 1); +source include/show_binlog_events.inc; + +--replace_column 2 # +show binary logs; +sync_slave_with_master; +--replace_column 2 # +show binary logs; + +let $binlog_file=; +source include/show_binlog_events.inc; + +let $binlog_file= query_get_value(SHOW MASTER STATUS, File, 1); +source include/show_binlog_events.inc; +let $binlog_file=; + +source include/check_slave_is_running.inc; + +# Need to recode the following + +#show new master for slave with master_log_file='master-bin.000001' and master_log_pos=4 and master_server_id=1; +#show new master for slave with master_log_file='master-bin.000001' and master_log_pos=79 and master_server_id=1; +#show new master for slave with master_log_file='master-bin.000001' and master_log_pos=311 and master_server_id=1; +#show new master for slave with master_log_file='master-bin.000002' and master_log_pos=4 and master_server_id=1; +#show new master for slave with master_log_file='master-bin.000002' and master_log_pos=122 and master_server_id=1; + +--error 1220 +show binlog events in 'slave-bin.000005' from 4; + +connection master; + +# The table drops caused Cluster Replication wrapper to fail as event ID would never be the same.# Moving drops here. + +DROP TABLE t1; +DROP TABLE t2; +DROP TABLE t3; + +# +# Bug #6880: LAST_INSERT_ID() within a statement +# + +# Reset binlog so that show binlog events will not show the tests +# above. +source include/rpl_reset.inc; +connection master; + +create table t1(a int auto_increment primary key, b int); +insert into t1 values (NULL, 1); +set insert_id=5; +insert into t1 values (NULL, last_insert_id()), (NULL, last_insert_id()); +source include/show_binlog_events.inc; +select * from t1; +drop table t1; + +# End of 4.1 tests + +sync_slave_with_master; +set @@global.slave_ddl_exec_mode=@save_slave_ddl_exec_mode; +connection master; diff --git a/mysql-test/suite/rpl/include/rpl_lower_case_table_names.test b/mysql-test/suite/rpl/include/rpl_lower_case_table_names.test new file mode 100644 index 00000000..fa48142e --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_lower_case_table_names.test @@ -0,0 +1,141 @@ +# BUG#37656 +# +# This test aims at checking whether lower_case_table_names=1 option works +# for database names and table names. +# +# This test checks the following (when lower_case_table_names=1 is set on slave): +# (i) creating a database on upper case on master results in lower case +# database name on slave +# (ii) creating tables with upper case names on master results in lower case +# table names on slave +# (iii) loading data infile into capitalized table name on master replicates to +# lower case table name on slave +# (iv) Propagating changes from upper case table names on into correspondent +# lower case table names on slave works. + + +# setup: create database and tables +-- echo ******** [ MASTER ] ******** +-- let $dbname_upper= BUG_37656 +-- let $dbname_lower= `SELECT LOWER('$dbname_upper')` +-- eval CREATE DATABASE $dbname_upper +-- eval use $dbname_upper + +# assert: database names are in upper case in master and lower +# case in slave +-- eval show databases like '$dbname_upper' +sync_slave_with_master; +-- echo ******** [ SLAVE ] ******** +--eval show databases like '$dbname_lower' + +-- connection master +-- echo ******** [ MASTER ] ******** +CREATE TABLE T1 (a int); +-- eval CREATE TABLE T2 (b int) ENGINE=$engine +CREATE TABLE T3 (txt TEXT); + +# assert: that tables exist on master with upper case names +show tables; + +# assert: that tables exist on slave but with lower case names +-- sync_slave_with_master +-- echo ******** [ SLAVE ] ******** +-- eval use $dbname_lower +show tables; + +# action: lets create t1 for asserting below that t1 does not get changes +# from master (slave configured with --replicate-ignore-db=$dbname_lower.t1) +CREATE TABLE t1 (a INT); + +# action: fill data into tables +-- connection master +-- echo ******** [ MASTER ] ******** +-- eval use $dbname_upper +INSERT INTO T1 VALUES (1); +INSERT INTO T2 VALUES (1); +if (`SELECT @@session.binlog_format != 'ROW'`) +{ + -- eval LOAD DATA INFILE '../../std_data/words.dat' INTO TABLE $dbname_upper.T3 +} + +if (`SELECT @@session.binlog_format = 'ROW'`) +{ + use test; + -- eval INSERT INTO $dbname_upper.T1 VALUES (2) + -- eval INSERT INTO $dbname_upper.T2 VALUES (2) + -- eval LOAD DATA INFILE '../../std_data/words.dat' INTO TABLE $dbname_upper.T3 +} +# assert: lower case tables on lower case database on slave +# get updates from upper case tables on upper case +# database on master +-- sync_slave_with_master +-- echo ******** [ SLAVE ] ******** + +# assert: changes for slave's t1 were filterd out +if (`SELECT count(*) != 0 FROM t1`) +{ + -- echo UNEXPECTED DATA on $dbname_lower.t1 as table is filtered by replicate-ignore-table rules +} + +-- let $diff_tables=master:$dbname_upper.T2, slave:$dbname_lower.t2 +-- source include/diff_tables.inc + +-- let $diff_tables=master:$dbname_upper.T3, slave:$dbname_lower.t3 +-- source include/diff_tables.inc + +# clean up +-- connection master +-- echo ******** [ MASTER ] ******** +-- eval DROP DATABASE $dbname_upper +-- sync_slave_with_master + + +# +# BUG#50653: drop procedure implicitely treats db name in a case sensitive way +# + +-- connection master + +-- let $dbname= B50653 +-- let $procname= b50653_proc + +-- eval CREATE DATABASE $dbname +-- eval USE $dbname +-- eval CREATE PROCEDURE $procname() BEGIN SELECT 1; END + +if (`SELECT count(*) = 1 FROM mysql.proc WHERE name like '$dbname'`) +{ + -- die Procedure not created on MASTER +} + +-- sync_slave_with_master +if (`SELECT count(*) = 1 FROM mysql.proc WHERE name like '$dbname'`) +{ + -- die Procedure not created on SLAVE +} + +-- connection master +-- eval DROP PROCEDURE $procname + +if (`SELECT count(*) FROM mysql.proc WHERE name like '$dbname'`) +{ + -- die Procedure not dropped on MASTER +} + +-- sync_slave_with_master +if (`SELECT count(*) FROM mysql.proc WHERE name like '$dbname'`) +{ + -- die Procedure not dropped on SLAVE +} + +-- let $last_error = query_get_value("SHOW SLAVE STATUS", Last_SQL_Errno, 1) +if ($last_error) +{ + -- die UNEXPECTED SLAVE SQL error: $last_error +} + +-- connection master +-- eval DROP DATABASE $dbname +-- sync_slave_with_master + +-- source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/include/rpl_max_relay_size.test b/mysql-test/suite/rpl/include/rpl_max_relay_size.test new file mode 100644 index 00000000..0fcff5eb --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_max_relay_size.test @@ -0,0 +1,118 @@ +# Test of options max_binlog_size and max_relay_log_size and +# how they act (if max_relay_log_size == 0, use max_binlog_size +# for relay logs too). +# Test of manual relay log rotation with FLUSH LOGS. + +# Requires statement logging +-- source include/master-slave.inc + +connection slave; +stop slave; +connection master; + +--echo # +--echo # Generate a big enough master's binlog to cause relay log rotations +--echo # + +create table t1 (a int); +let $1=800; +disable_query_log; +begin; +while ($1) +{ +# eval means expand $ expressions + eval insert into t1 values( $1 ); + dec $1; +} +enable_query_log; +drop table t1; +save_master_pos; +connection slave; +reset slave; + +--echo # +--echo # Test 1 +--echo # + +set @my_max_binlog_size= @@global.max_binlog_size, @my_max_relay_log_size=@@global.max_relay_log_size; +set global max_binlog_size=8192; +set global max_relay_log_size=8192-1; # mapped to 4096 +select @@global.max_relay_log_size; +start slave; +sync_with_master; +--source include/check_slave_is_running.inc + +--echo # +--echo # Test 2 +--echo # + +stop slave; +reset slave; +set global max_relay_log_size=(5*4096); +query_vertical select @@global.max_relay_log_size; +start slave; +sync_with_master; +--source include/check_slave_is_running.inc + +--echo # +--echo # Test 3: max_relay_log_size = 0 +--echo # + +stop slave; +reset slave; +set global max_relay_log_size=0; +query_vertical select @@global.max_relay_log_size; +start slave; +sync_with_master; +--source include/check_slave_is_running.inc + +--echo # +--echo # Test 4: Tests below are mainly to ensure that we have not coded with wrong assumptions +--echo # + +stop slave; +reset slave; +# test of relay log rotation when the slave is stopped +# (to make sure it does not crash). +flush logs; + +--echo # +--echo # Test 5 +--echo # + +reset slave; +start slave; +sync_with_master; +# test of relay log rotation when the slave is started +flush logs; +# We have now easy way to be sure that the SQL thread has now deleted the +# log we just closed. But a trick to achieve this is do an update on the master. +connection master; +create table t1 (a int); +sync_slave_with_master; +--source include/check_slave_is_running.inc + +--echo # +--echo # Test 6: one more rotation, to be sure Relay_Log_Space is correctly updated +--echo # + +flush logs; +connection master; +drop table t1; +sync_slave_with_master; +--source include/check_slave_is_running.inc + +connection master; +# test that the absence of relay logs does not make a master crash +flush logs; +source include/show_master_status.inc; + +# Restore max_binlog_size +connection slave; +set global max_binlog_size= @my_max_binlog_size; +set global max_relay_log_size= @my_max_relay_log_size; + +--echo # +--echo # End of 4.1 tests +--echo # +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/include/rpl_mixed_check_db.inc b/mysql-test/suite/rpl/include/rpl_mixed_check_db.inc new file mode 100644 index 00000000..403b34ae --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_mixed_check_db.inc @@ -0,0 +1,11 @@ +######################################### +# Author: Serge Kozlov skozlov@mysql.com +# Date: 07/10/2006 +# Purpose: Showing all databases started from "test_rpl" +# Requirements: +######################################### + +SHOW DATABASES LIKE 'test_rpl%'; +sync_slave_with_master; +SHOW DATABASES LIKE 'test_rpl%'; +connection master; diff --git a/mysql-test/suite/rpl/include/rpl_mixed_check_event.inc b/mysql-test/suite/rpl/include/rpl_mixed_check_event.inc new file mode 100644 index 00000000..6732f637 --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_mixed_check_event.inc @@ -0,0 +1,15 @@ +######################################### +# Author: Serge Kozlov skozlov@mysql.com +# Date: 07/10/2006 +# Purpose: Showing events from work tables on master and on slave +# Requirements: +######################################### + +--replace_column 8 # 9 # +SHOW EVENTS; +sync_slave_with_master; +USE test_rpl; +--replace_column 8 # 9 # +SHOW EVENTS; +connection master; + diff --git a/mysql-test/suite/rpl/include/rpl_mixed_check_select.inc b/mysql-test/suite/rpl/include/rpl_mixed_check_select.inc new file mode 100644 index 00000000..d2702109 --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_mixed_check_select.inc @@ -0,0 +1,19 @@ +######################################### +# Author: Serge Kozlov skozlov@mysql.com +# Date: 07/10/2006 +# Purpose: Showing data from work tables on master and on slave +# Requirements: +######################################### + +SELECT COUNT(*) FROM t1; +SELECT * FROM t1 ORDER BY a; +SELECT COUNT(*) FROM t2; +SELECT * FROM t2 ORDER BY a; +sync_slave_with_master; +USE test_rpl; +SELECT COUNT(*) FROM t1; +SELECT * FROM t1 ORDER BY a; +SELECT COUNT(*) FROM t2; +SELECT * FROM t2 ORDER BY a; +connection master; + diff --git a/mysql-test/suite/rpl/include/rpl_mixed_check_table.inc b/mysql-test/suite/rpl/include/rpl_mixed_check_table.inc new file mode 100644 index 00000000..80f40ea7 --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_mixed_check_table.inc @@ -0,0 +1,14 @@ +######################################### +# Author: Serge Kozlov skozlov@mysql.com +# Date: 07/10/2006 +# Purpose: Checking created tables on master and same tables on slave +# Requirements: +######################################### + +SHOW CREATE TABLE t1; +SHOW CREATE TABLE t2; +sync_slave_with_master; +USE test_rpl; +SHOW CREATE TABLE t1; +SHOW CREATE TABLE t2; +connection master; diff --git a/mysql-test/suite/rpl/include/rpl_mixed_check_user.inc b/mysql-test/suite/rpl/include/rpl_mixed_check_user.inc new file mode 100644 index 00000000..548fdf78 --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_mixed_check_user.inc @@ -0,0 +1,13 @@ +######################################### +# Author: Serge Kozlov skozlov@mysql.com +# Date: 07/10/2006 +# Purpose: Showing user info on master and on slave +# Requirements: +######################################### + +SELECT host, user, password, plugin, authentication_string, select_priv FROM mysql.user WHERE user LIKE 'user_test_rpl%'; +sync_slave_with_master; +USE test_rpl; +SELECT host, user, password, plugin, authentication_string, select_priv FROM mysql.user WHERE user LIKE 'user_test_rpl%'; +connection master; + diff --git a/mysql-test/suite/rpl/include/rpl_mixed_check_view.inc b/mysql-test/suite/rpl/include/rpl_mixed_check_view.inc new file mode 100644 index 00000000..2ad8c34d --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_mixed_check_view.inc @@ -0,0 +1,15 @@ +######################################### +# Author: Serge Kozlov skozlov@mysql.com +# Date: 07/10/2006 +# Purpose: Showing view from work tables on master and on slave +# Requirements: +######################################### + +SHOW CREATE VIEW v1; +SELECT * FROM v1 ORDER BY a; +sync_slave_with_master; +USE test_rpl; +SHOW CREATE VIEW v1; +SELECT * FROM v1 ORDER BY a; +connection master; + diff --git a/mysql-test/suite/rpl/include/rpl_mixed_clear_tables.inc b/mysql-test/suite/rpl/include/rpl_mixed_clear_tables.inc new file mode 100644 index 00000000..83dc9f75 --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_mixed_clear_tables.inc @@ -0,0 +1,9 @@ +######################################### +# Author: Serge Kozlov skozlov@mysql.com +# Date: 07/10/2006 +# Purpose: Delete all rows from work tables (t1, t2) on master +# Requirements: +######################################### + +DELETE FROM t1; +DELETE FROM t2; diff --git a/mysql-test/suite/rpl/include/rpl_mixed_ddl.inc b/mysql-test/suite/rpl/include/rpl_mixed_ddl.inc new file mode 100644 index 00000000..6e4aad56 --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_mixed_ddl.inc @@ -0,0 +1,81 @@ +######################################### +# Purpose: testing the replication in mixed mode +# Requirements: define binlog format for mysqld as in example below: +# ./mysql-test-run.pl --mysqld=--binlog-format=mixed +######################################### + +--source include/master-slave.inc + +# Check MIXED on both master and slave +connection master; +--source suite/rpl/include/rpl_mixed_show_binlog_format.inc +connection slave; +--source suite/rpl/include/rpl_mixed_show_binlog_format.inc +connection master; + + +# DDL for databases +--echo +--echo ******************** DDL for database ******************** +--disable_warnings +DROP DATABASE IF EXISTS test_rpl; +DROP DATABASE IF EXISTS test_rpl_1; +--enable_warnings +CREATE DATABASE test_rpl_1 CHARACTER SET utf8 COLLATE utf8_general_ci; +ALTER DATABASE test_rpl_1 CHARACTER SET latin1 COLLATE latin1_general_ci; +DROP DATABASE test_rpl_1; +CREATE DATABASE test_rpl CHARACTER SET utf8 COLLATE utf8_general_ci; +ALTER DATABASE test_rpl CHARACTER SET latin1 COLLATE latin1_swedish_ci; +--source suite/rpl/include/rpl_mixed_check_db.inc + +USE test_rpl; + +# DDL for tables +--echo +--echo ******************** DDL for tables ******************** +eval CREATE TABLE t0 (a int auto_increment not null, c int not null, PRIMARY KEY(a), KEY index2 (c)) ENGINE=$engine_type; +ALTER TABLE t0 DROP INDEX index2; +ALTER TABLE t0 ADD COLUMN b char(254); +ALTER TABLE t0 ADD INDEX index1 (b); +ALTER TABLE t0 DROP COLUMN c; +RENAME TABLE t0 TO t1; +CREATE TABLE t2 LIKE t1; +--source suite/rpl/include/rpl_mixed_check_table.inc + +# DDL for logfiles +# skipped + +# DDL for tablespaces +# skipped + +# DDL for indexes +--echo +--echo ******************** DDL for indexes ******************** +ALTER TABLE t2 ADD COLUMN d datetime; +CREATE INDEX index2 on t2 (d); +CREATE INDEX index3 on t2 (a, d); +--source suite/rpl/include/rpl_mixed_check_table.inc +ALTER TABLE t2 DROP COLUMN d; + + +# BINLOG EVENTS +--echo +--echo +--echo ******************** SHOW BINLOG EVENTS ******************** +source include/show_binlog_events.inc; +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 test_rpl > $MYSQLTEST_VARDIR/tmp/rpl_switch_stm_row_mixed_master.sql +--exec $MYSQL_DUMP_SLAVE --compact --order-by-primary --skip-extended-insert --no-create-info test_rpl > $MYSQLTEST_VARDIR/tmp/rpl_switch_stm_row_mixed_slave.sql + +connection master; +drop database test_rpl; +sync_slave_with_master; + +# 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 +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/include/rpl_mixed_dml.inc b/mysql-test/suite/rpl/include/rpl_mixed_dml.inc new file mode 100644 index 00000000..e9e1fd51 --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_mixed_dml.inc @@ -0,0 +1,340 @@ +######################################### +# Purpose: testing the replication in mixed mode +# Requirements: define binlog format for mysqld as in example below: +# ./mysql-test-run.pl --mysqld=--binlog-format=mixed +######################################### + +--source include/master-slave.inc + +# Check MIXED on both master and slave +connection master; +--source suite/rpl/include/rpl_mixed_show_binlog_format.inc +connection slave; +--source suite/rpl/include/rpl_mixed_show_binlog_format.inc +connection master; + + +CREATE DATABASE test_rpl; + +--echo +--echo ******************** PREPARE TESTING ******************** +USE test_rpl; +eval CREATE TABLE t1 (a int auto_increment not null, b char(254), PRIMARY KEY(a)) ENGINE=$engine_type; +eval CREATE TABLE t2 (a int auto_increment not null, b char(254), PRIMARY KEY(a)) ENGINE=$engine_type; + +# DELETE +INSERT INTO t1 VALUES(1, 't1, text 1'); +INSERT INTO t1 VALUES(2, 't1, text 2'); +INSERT INTO t2 VALUES(1, 't2, text 1'); +--echo +--echo ******************** DELETE ******************** +DELETE FROM t1 WHERE a = 1; +DELETE FROM t2 WHERE b <> SYS_GUID(); +--source suite/rpl/include/rpl_mixed_check_select.inc +--source suite/rpl/include/rpl_mixed_clear_tables.inc + +# INSERT +--echo +--echo ******************** INSERT ******************** +INSERT INTO t1 VALUES(1, 't1, text 1'); +INSERT INTO t1 VALUES(2, SYS_GUID()); +INSERT INTO t2 SELECT * FROM t1; +INSERT INTO t2 VALUES (1, 't1, text 1') ON DUPLICATE KEY UPDATE b = 't2, text 1'; +DELETE FROM t1 WHERE a = 2; +DELETE FROM t2 WHERE a = 2; +--source suite/rpl/include/rpl_mixed_check_select.inc +--source suite/rpl/include/rpl_mixed_clear_tables.inc + +--echo +--echo ******************** LOAD DATA INFILE ******************** +--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +eval LOAD DATA INFILE '$MYSQLTEST_VARDIR/std_data/rpl_mixed.dat' INTO TABLE t1 FIELDS TERMINATED BY '|' ; +SELECT * FROM t1 ORDER BY a; +--source suite/rpl/include/rpl_mixed_check_select.inc +--source suite/rpl/include/rpl_mixed_clear_tables.inc + +# REPLACE +--echo +--echo ******************** REPLACE ******************** +INSERT INTO t1 VALUES(1, 't1, text 1'); +INSERT INTO t1 VALUES(2, 't1, text 2'); +INSERT INTO t1 VALUES(3, 't1, text 3'); +REPLACE INTO t1 VALUES(1, 't1, text 11'); +REPLACE INTO t1 VALUES(2, SYS_GUID()); +REPLACE INTO t1 SET a=3, b='t1, text 33'; +DELETE FROM t1 WHERE a = 2; +--source suite/rpl/include/rpl_mixed_check_select.inc +--source suite/rpl/include/rpl_mixed_clear_tables.inc + +# SELECT +--echo +--echo ******************** SELECT ******************** +INSERT INTO t1 VALUES(1, 't1, text 1'); +SELECT * FROM t1 WHERE b <> SYS_GUID() ORDER BY a; +--source suite/rpl/include/rpl_mixed_clear_tables.inc + +# JOIN +--echo +--echo ******************** JOIN ******************** +INSERT INTO t1 VALUES(1, 'CCC'); +INSERT INTO t1 VALUES(2, 'DDD'); +INSERT INTO t2 VALUES(1, 'DDD'); +INSERT INTO t2 VALUES(2, 'CCC'); +SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a ORDER BY t1.a,t2.a; +SELECT * FROM t1 INNER JOIN t2 ON t1.b = t2.b ORDER BY t1.a,t2.a; +--source suite/rpl/include/rpl_mixed_clear_tables.inc + +# UNION +--echo +--echo ******************** UNION ******************** +INSERT INTO t1 VALUES(1, 't1, text 1'); +INSERT INTO t2 VALUES(1, 't2, text 1'); +SELECT * FROM t1 UNION SELECT * FROM t2 WHERE t2.b <> SYS_GUID(); +--source suite/rpl/include/rpl_mixed_clear_tables.inc + +# TRUNCATE +--echo +--echo ******************** TRUNCATE ******************** +INSERT INTO t1 VALUES(1, 't1, text 1'); +--source suite/rpl/include/rpl_mixed_check_select.inc +TRUNCATE t1; +--source suite/rpl/include/rpl_mixed_check_select.inc +--source suite/rpl/include/rpl_mixed_clear_tables.inc + +# UPDATE +--echo +--echo ******************** UPDATE ******************** +INSERT INTO t1 VALUES(1, 't1, text 1'); +INSERT INTO t2 VALUES(1, 't2, text 1'); +UPDATE t1 SET b = 't1, text 1 updated' WHERE a = 1; +--source suite/rpl/include/rpl_mixed_check_select.inc +UPDATE t1, t2 SET t1.b = 'test', t2.b = 'test'; +--source suite/rpl/include/rpl_mixed_check_select.inc +--source suite/rpl/include/rpl_mixed_clear_tables.inc + +# DESCRIBE +--echo +--echo ******************** DESCRIBE ******************** +DESCRIBE t1; +DESCRIBE t2 b; + +# USE +--echo +--echo ******************** USE ******************** +USE test_rpl; + +# TRANSACTION +--echo +--echo ******************** TRANSACTION ******************** +START TRANSACTION; +INSERT INTO t1 VALUES (1, 'start'); +COMMIT; +--source suite/rpl/include/rpl_mixed_check_select.inc +START TRANSACTION; +INSERT INTO t1 VALUES (2, 'rollback'); +ROLLBACK; +--source suite/rpl/include/rpl_mixed_check_select.inc +START TRANSACTION; +INSERT INTO t1 VALUES (3, 'before savepoint s1'); +SAVEPOINT s1; +INSERT INTO t1 VALUES (4, 'after savepoint s1'); +ROLLBACK TO SAVEPOINT s1; +--source suite/rpl/include/rpl_mixed_check_select.inc +START TRANSACTION; +INSERT INTO t1 VALUES (5, 'before savepoint s2'); +SAVEPOINT s2; +INSERT INTO t1 VALUES (6, 'after savepoint s2'); +INSERT INTO t1 VALUES (7, CONCAT('with SYS_GUID() ',SYS_GUID())); +RELEASE SAVEPOINT s2; +COMMIT; +DELETE FROM t1 WHERE a = 7; +--source suite/rpl/include/rpl_mixed_check_select.inc +--source suite/rpl/include/rpl_mixed_clear_tables.inc + +# LOCK TABLES +--echo +--echo ******************** LOCK TABLES ******************** +LOCK TABLES t1 READ , t2 READ; +UNLOCK TABLES; + +# TRANSACTION ISOLATION LEVEL +--echo +--echo ******************** TRANSACTION ISOLATION LEVEL ******************** +SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; +SET TRANSACTION ISOLATION LEVEL READ COMMITTED; +SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; +SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; + +# XA +# skipped + +# CREATE USER +--echo +--echo ******************** CREATE USER ******************** +CREATE USER 'user_test_rpl'@'localhost' IDENTIFIED BY PASSWORD '*1111111111111111111111111111111111111111'; +--source suite/rpl/include/rpl_mixed_check_user.inc + +# GRANT +--echo +--echo ******************** GRANT ******************** +GRANT SELECT ON *.* TO 'user_test_rpl'@'localhost'; +--source suite/rpl/include/rpl_mixed_check_user.inc + +# REVOKE +--echo +--echo ******************** REVOKE ******************** +REVOKE SELECT ON *.* FROM 'user_test_rpl'@'localhost'; +--source suite/rpl/include/rpl_mixed_check_user.inc + +# SET PASSWORD +--echo +--echo ******************** SET PASSWORD ******************** +SET PASSWORD FOR 'user_test_rpl'@'localhost' = '*0000000000000000000000000000000000000000'; +--source suite/rpl/include/rpl_mixed_check_user.inc + +# RENAME USER +--echo +--echo ******************** RENAME USER ******************** +RENAME USER 'user_test_rpl'@'localhost' TO 'user_test_rpl_2'@'localhost'; +--source suite/rpl/include/rpl_mixed_check_user.inc + +# DROP USER +--echo +--echo ******************** DROP USER ******************** +DROP USER 'user_test_rpl_2'@'localhost'; +--source suite/rpl/include/rpl_mixed_check_user.inc + +# Prepring for some following operations +INSERT INTO t1 VALUES(100, 'test'); + +# ANALYZE +--echo +--echo ******************** ANALYZE ******************** +ANALYZE TABLE t1; + +# BACKUP TABLE +# skipped because deprecated + +# CHECK TABLE +--echo +--echo ******************** CHECK TABLE ******************** +CHECK TABLE t1; + +# CHECKSUM TABLE +--echo +--echo ******************** CHECKSUM TABLE ******************** +CHECKSUM TABLE t1; + +# OPTIMIZE TABLE +--echo +--echo ******************** OPTIMIZE TABLE ******************** +OPTIMIZE TABLE t1; + +# REPAIR TABLE +--echo +--echo ******************** REPAIR TABLE ******************** +REPAIR TABLE t1; + +# SET VARIABLE +--echo +--echo ******************** SET VARIABLE ******************** +SET @test_rpl_var = 1; +SHOW VARIABLES LIKE 'test_rpl_var'; + +# SHOW +--echo +--echo ******************** SHOW ******************** +--source suite/rpl/include/rpl_mixed_check_db.inc + + +# PROCEDURE +--echo +--echo ******************** PROCEDURE ******************** +DELIMITER |; +CREATE PROCEDURE p1 () +BEGIN + UPDATE t1 SET b = 'test' WHERE a = 201; +END| +CREATE PROCEDURE p2 () +BEGIN + UPDATE t1 SET b = SYS_GUID() WHERE a = 202; +END| +DELIMITER ;| +INSERT INTO t1 VALUES(201, 'test 201'); +CALL p1(); +INSERT INTO t1 VALUES(202, 'test 202'); +CALL p2(); +DELETE FROM t1 WHERE a = 202; +--source suite/rpl/include/rpl_mixed_check_select.inc +ALTER PROCEDURE p1 COMMENT 'p1'; +DROP PROCEDURE p1; +DROP PROCEDURE p2; +--source suite/rpl/include/rpl_mixed_clear_tables.inc + +# TRIGGER +--echo +--echo ******************** TRIGGER ******************** +DELIMITER |; +CREATE TRIGGER tr1 BEFORE INSERT ON t1 +FOR EACH ROW BEGIN + INSERT INTO t2 SET a = NEW.a, b = NEW.b; +END| +DELIMITER ;| +INSERT INTO t1 VALUES (1, 'test'); +--source suite/rpl/include/rpl_mixed_check_select.inc +--source suite/rpl/include/rpl_mixed_clear_tables.inc +DROP TRIGGER tr1; + +# EVENTS +--echo +--echo +--echo ******************** EVENTS ******************** +INSERT INTO t1 VALUES(1, 'test1'); +CREATE EVENT e1 ON SCHEDULE EVERY '1' SECOND COMMENT 'e_second_comment' DO DELETE FROM t1; +--source suite/rpl/include/rpl_mixed_check_event.inc +--source suite/rpl/include/rpl_mixed_check_select.inc +--sleep 2 +--source suite/rpl/include/rpl_mixed_check_select.inc +ALTER EVENT e1 RENAME TO e2; +--sleep 2 +--source suite/rpl/include/rpl_mixed_check_event.inc +--source suite/rpl/include/rpl_mixed_check_select.inc +DROP EVENT e2; +--source suite/rpl/include/rpl_mixed_check_event.inc +--source suite/rpl/include/rpl_mixed_clear_tables.inc + +# VIEWS +--echo +--echo ******************** VIEWS ******************** +INSERT INTO t1 VALUES(1, 'test1'); +INSERT INTO t1 VALUES(2, 'test2'); +CREATE VIEW v1 AS SELECT * FROM t1 WHERE a = 1; +CREATE VIEW v2 AS SELECT * FROM t1 WHERE b <> SYS_GUID(); +--source suite/rpl/include/rpl_mixed_check_view.inc +ALTER VIEW v1 AS SELECT * FROM t1 WHERE a = 2; +--source suite/rpl/include/rpl_mixed_check_view.inc +DROP VIEW v1; +DROP VIEW v2; +--source suite/rpl/include/rpl_mixed_clear_tables.inc + +# BINLOG EVENTS +--echo +--echo +--echo ******************** SHOW BINLOG EVENTS ******************** +--source include/show_binlog_events.inc +sync_slave_with_master; +# as we're using SYS_GUID we don't SELECT but use "diff" like in rpl_row_SYS_GUID +--exec $MYSQL_DUMP --compact --order-by-primary --skip-extended-insert --no-create-info test_rpl > $MYSQLTEST_VARDIR/tmp/rpl_switch_stm_row_mixed_master.sql +--exec $MYSQL_DUMP_SLAVE --compact --order-by-primary --skip-extended-insert --no-create-info test_rpl > $MYSQLTEST_VARDIR/tmp/rpl_switch_stm_row_mixed_slave.sql + +connection master; +drop database test_rpl; +sync_slave_with_master; + +# 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 +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/include/rpl_mixed_show_binlog_format.inc b/mysql-test/suite/rpl/include/rpl_mixed_show_binlog_format.inc new file mode 100644 index 00000000..3cd6d72f --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_mixed_show_binlog_format.inc @@ -0,0 +1,10 @@ +######################################### +# Author: Serge Kozlov skozlov@mysql.com +# Date: 07/10/2006 +# Purpose: Showing binlog_format variables on current server (master or slave) +# Requirements: +######################################### + +show global variables like 'binlog_format%'; +show session variables like 'binlog_format%'; +select @@global.binlog_format, @@session.binlog_format; diff --git a/mysql-test/suite/rpl/include/rpl_mixing_engines.inc b/mysql-test/suite/rpl/include/rpl_mixing_engines.inc new file mode 100644 index 00000000..c78a6a0e --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_mixing_engines.inc @@ -0,0 +1,639 @@ +# ==== Purpose ==== +# +# This is an auxiliary file used by rpl_mixing_engines.test. It +# executes SQL statements according to a format string, as specified in +# rpl_mixing_engines.test. In addition, it accepts the special format +# strings 'configure' and 'clean', used before and after everything else. +# +# ==== Usage ==== +# +# --let $commands= command1 command2 ... +# --let $database_name= name +# [--let $verbose= 1] +# --source include/rpl_mixing_engines.inc +# +# Parameters: +# +# $commands +# Space-separated list of commands. See rpl_mixing_engines.test +# for a list of all commands. +# +# $database_name +# Name of database to use. If $commands is 'configure' or +# 'clean', and the database name is not 'test', then the +# database is created or dropped, respectively. +# +# $verbose +# By default, show_binlog_events.inc is sourced after all +# commands have been processed, showing the result of all +# commands. If this flag is set, then show_binlog_events.inc is +# also sourced once after each command, showing only the result +# of that command. + +--echo rpl_mixing_engines.inc [commands=$commands] + +--let $rme_initial_commands= $commands + +if ($commands == 'configure') +{ + connection master; + + --disable_query_log + if ($database_name != 'test') + { + --eval CREATE DATABASE $database_name + } + --eval use $database_name + --enable_query_log + + eval CREATE TABLE nt_1 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = MyISAM; + eval CREATE TABLE nt_2 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = MyISAM; + eval CREATE TABLE nt_3 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = MyISAM; + eval CREATE TABLE nt_4 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = MyISAM; + eval CREATE TABLE nt_5 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = MyISAM; + eval CREATE TABLE nt_6 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = MyISAM; + eval CREATE TABLE tt_1 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = $engine_type; + eval CREATE TABLE tt_2 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = $engine_type; + eval CREATE TABLE tt_3 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = $engine_type; + eval CREATE TABLE tt_4 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = $engine_type; + eval CREATE TABLE tt_5 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = $engine_type; + eval CREATE TABLE tt_6 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = $engine_type; + + INSERT INTO nt_1(trans_id, stmt_id) VALUES(1,1); + INSERT INTO nt_2(trans_id, stmt_id) VALUES(1,1); + INSERT INTO nt_3(trans_id, stmt_id) VALUES(1,1); + INSERT INTO nt_4(trans_id, stmt_id) VALUES(1,1); + INSERT INTO nt_5(trans_id, stmt_id) VALUES(1,1); + INSERT INTO nt_6(trans_id, stmt_id) VALUES(1,1); + + INSERT INTO tt_1(trans_id, stmt_id) VALUES(1,1); + INSERT INTO tt_2(trans_id, stmt_id) VALUES(1,1); + INSERT INTO tt_3(trans_id, stmt_id) VALUES(1,1); + INSERT INTO tt_4(trans_id, stmt_id) VALUES(1,1); + INSERT INTO tt_5(trans_id, stmt_id) VALUES(1,1); + INSERT INTO tt_6(trans_id, stmt_id) VALUES(1,1); + + DELIMITER |; + + CREATE PROCEDURE pc_i_tt_5_suc (IN p_trans_id INTEGER, IN p_stmt_id INTEGER) + BEGIN + DECLARE in_stmt_id INTEGER; + SELECT max(stmt_id) INTO in_stmt_id FROM tt_5 WHERE trans_id= p_trans_id; + SELECT COALESCE(greatest(in_stmt_id + 1, p_stmt_id), 1) INTO in_stmt_id; + INSERT INTO tt_5(trans_id, stmt_id) VALUES (p_trans_id, in_stmt_id); + INSERT INTO tt_5(trans_id, stmt_id) VALUES (p_trans_id, in_stmt_id + 1); + END| + + CREATE PROCEDURE pc_i_nt_5_suc (IN p_trans_id INTEGER, IN p_stmt_id INTEGER) + BEGIN + DECLARE in_stmt_id INTEGER; + SELECT max(stmt_id) INTO in_stmt_id FROM nt_5 WHERE trans_id= p_trans_id; + SELECT COALESCE(greatest(in_stmt_id + 1, p_stmt_id), 1) INTO in_stmt_id; + INSERT INTO nt_5(trans_id, stmt_id) VALUES (p_trans_id, in_stmt_id); + INSERT INTO nt_5(trans_id, stmt_id) VALUES (p_trans_id, in_stmt_id + 1); + END| + + CREATE FUNCTION fc_i_tt_5_suc (p_trans_id INTEGER, p_stmt_id INTEGER) RETURNS VARCHAR(64) + BEGIN + DECLARE in_stmt_id INTEGER; + SELECT max(stmt_id) INTO in_stmt_id FROM tt_5 WHERE trans_id= p_trans_id; + SELECT COALESCE(greatest(in_stmt_id + 1, p_stmt_id), 1) INTO in_stmt_id; + INSERT INTO tt_5(trans_id, stmt_id) VALUES (p_trans_id, in_stmt_id); + INSERT INTO tt_5(trans_id, stmt_id) VALUES (p_trans_id, in_stmt_id + 1); + RETURN "fc_i_tt_5_suc"; + END| + + CREATE FUNCTION fc_i_nt_5_suc (p_trans_id INTEGER, p_stmt_id INTEGER) RETURNS VARCHAR(64) + BEGIN + DECLARE in_stmt_id INTEGER; + SELECT max(stmt_id) INTO in_stmt_id FROM nt_5 WHERE trans_id= p_trans_id; + SELECT COALESCE(greatest(in_stmt_id + 1, p_stmt_id), 1) INTO in_stmt_id; + INSERT INTO nt_5(trans_id, stmt_id) VALUES (p_trans_id, in_stmt_id); + INSERT INTO nt_5(trans_id, stmt_id) VALUES (p_trans_id, in_stmt_id + 1); + RETURN "fc_i_nt_5_suc"; + END| + + CREATE FUNCTION fc_i_nt_3_tt_3_suc (p_trans_id INTEGER, p_stmt_id INTEGER) RETURNS VARCHAR(64) + BEGIN + DECLARE in_stmt_id INTEGER; + SELECT max(stmt_id) INTO in_stmt_id FROM nt_3 WHERE trans_id= p_trans_id; + SELECT COALESCE(greatest(in_stmt_id + 1, p_stmt_id), 1) INTO in_stmt_id; + INSERT INTO nt_3(trans_id, stmt_id) VALUES (p_trans_id, in_stmt_id); + + SELECT max(stmt_id) INTO in_stmt_id FROM tt_3 WHERE trans_id= p_trans_id; + SELECT COALESCE(greatest(in_stmt_id + 1, p_stmt_id), 1) INTO in_stmt_id; + INSERT INTO tt_3(trans_id, stmt_id) VALUES (p_trans_id, in_stmt_id); + RETURN "fc_i_nt_3_tt_3_suc"; + END| + + CREATE TRIGGER tr_i_tt_3_to_nt_3 AFTER INSERT ON tt_3 FOR EACH ROW + BEGIN + DECLARE in_stmt_id INTEGER; + SELECT max(stmt_id) INTO in_stmt_id FROM nt_3 WHERE trans_id= NEW.trans_id; + SELECT COALESCE(greatest(in_stmt_id + 1, NEW.stmt_id), 1) INTO in_stmt_id; + INSERT INTO nt_3(trans_id, stmt_id) VALUES (NEW.trans_id, in_stmt_id); + INSERT INTO nt_3(trans_id, stmt_id) VALUES (NEW.trans_id, in_stmt_id + 1); + END| + + CREATE TRIGGER tr_i_nt_4_to_tt_4 AFTER INSERT ON nt_4 FOR EACH ROW + BEGIN + DECLARE in_stmt_id INTEGER; + SELECT max(stmt_id) INTO in_stmt_id FROM tt_4 WHERE trans_id= NEW.trans_id; + SELECT COALESCE(greatest(in_stmt_id + 1, NEW.stmt_id), 1) INTO in_stmt_id; + INSERT INTO tt_4(trans_id, stmt_id) VALUES (NEW.trans_id, in_stmt_id); + INSERT INTO tt_4(trans_id, stmt_id) VALUES (NEW.trans_id, in_stmt_id + 1); + END| + + CREATE TRIGGER tr_i_tt_5_to_tt_6 AFTER INSERT ON tt_5 FOR EACH ROW + BEGIN + DECLARE in_stmt_id INTEGER; + SELECT max(stmt_id) INTO in_stmt_id FROM tt_6 WHERE trans_id= NEW.trans_id; + SELECT COALESCE(greatest(in_stmt_id + 1, NEW.stmt_id, 1), 1) INTO in_stmt_id; + INSERT INTO tt_6(trans_id, stmt_id) VALUES (NEW.trans_id, in_stmt_id); + INSERT INTO tt_6(trans_id, stmt_id) VALUES (NEW.trans_id, in_stmt_id + 1); + END| + + CREATE TRIGGER tr_i_nt_5_to_nt_6 AFTER INSERT ON nt_5 FOR EACH ROW + BEGIN + DECLARE in_stmt_id INTEGER; + SELECT max(stmt_id) INTO in_stmt_id FROM nt_6 WHERE trans_id= NEW.trans_id; + SELECT COALESCE(greatest(in_stmt_id + 1, NEW.stmt_id), 1) INTO in_stmt_id; + INSERT INTO nt_6(trans_id, stmt_id) VALUES (NEW.trans_id, in_stmt_id); + INSERT INTO nt_6(trans_id, stmt_id) VALUES (NEW.trans_id, in_stmt_id + 1); + END| + + DELIMITER ;| + + let $pos_trans_command= query_get_value("SHOW MASTER STATUS", Position, 1); + + let $trans_id= 7; + let $tb_id= 1; + let $stmt_id= 1; + --let $commands= + let $sn= 0; +} + +if ($commands == 'clean') +{ + connection master; + + --disable_query_log + --eval use $database_name + --enable_query_log + + DROP TABLE tt_1; + DROP TABLE tt_2; + DROP TABLE tt_3; + DROP TABLE tt_4; + DROP TABLE tt_5; + DROP TABLE tt_6; + + DROP TABLE nt_1; + DROP TABLE nt_2; + DROP TABLE nt_3; + DROP TABLE nt_4; + DROP TABLE nt_5; + DROP TABLE nt_6; + + DROP PROCEDURE pc_i_tt_5_suc; + DROP PROCEDURE pc_i_nt_5_suc; + DROP FUNCTION fc_i_tt_5_suc; + DROP FUNCTION fc_i_nt_5_suc; + DROP FUNCTION fc_i_nt_3_tt_3_suc; + + --disable_query_log + if ($database_name != 'test') + { + --eval DROP DATABASE $database_name + } + --enable_query_log + + sync_slave_with_master; + + --let $commands= +} + +--disable_ps2_protocol +while ($commands != '') +{ + --disable_query_log + --eval use $database_name + --enable_query_log + + --disable_query_log + --let $command= `SELECT SUBSTRING_INDEX('$commands', ' ', 1)` + if ($verbose) + { + --echo -b-b-b-b-b-b-b-b-b-b-b- >> $command << -b-b-b-b-b-b-b-b-b-b-b- + let $pos_command= query_get_value("SHOW MASTER STATUS", Position, 1); + } + --enable_query_log + if ($command == 'B') + { + eval BEGIN; + } + if ($command == 'T') + { + #--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id) + eval INSERT INTO tt_1(trans_id, stmt_id) VALUES ($trans_id, $stmt_id); + inc $stmt_id; + } + if ($command == 'T-trig') + { + #--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id) + eval INSERT INTO tt_5(trans_id, stmt_id) VALUES ($trans_id, $stmt_id); + inc $stmt_id; + } + if ($command == 'T-func') + { + #--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id) + eval SELECT fc_i_tt_5_suc ($trans_id, $stmt_id); + inc $stmt_id; + } + if ($command == 'T-proc') + { + #--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id) + eval CALL pc_i_tt_5_suc ($trans_id, $stmt_id); + inc $stmt_id; + } + if ($command == 'eT') + { + #--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id) + let $old_trans_id= `SELECT max(trans_id) from tt_1`; + let $old_stmt_id= `SELECT max(stmt_id) from tt_1 where trans_id= $old_trans_id`; + --error ER_DUP_ENTRY, ER_DUP_KEY + eval INSERT INTO tt_1(trans_id, stmt_id) VALUES ($old_trans_id, $old_stmt_id); + inc $stmt_id; + } + if ($command == 'Te') + { + #--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id) + let $old_trans_id= `SELECT max(trans_id) from tt_1`; + let $old_stmt_id= `SELECT max(stmt_id) from tt_1 where trans_id= $old_trans_id`; + --error ER_DUP_ENTRY, ER_DUP_KEY + eval INSERT INTO tt_1(trans_id, stmt_id) VALUES ($trans_id, $stmt_id), ($old_trans_id, $old_stmt_id); + inc $stmt_id; + } + if ($command == 'Te-trig') + { + #--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id) + let $old_trans_id= `SELECT max(trans_id) from tt_5`; + let $old_stmt_id= `SELECT max(stmt_id) from tt_5 where trans_id= $old_trans_id`; + --error ER_DUP_ENTRY, ER_DUP_KEY + eval INSERT INTO tt_5(trans_id, stmt_id) VALUES ($trans_id, $stmt_id), ($old_trans_id, $old_stmt_id); + inc $stmt_id; + } + if ($command == 'Te-func') + { + #--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id) + let $old_trans_id= `SELECT max(trans_id) from tt_1`; + let $old_stmt_id= `SELECT max(stmt_id) from tt_1 where trans_id= $old_trans_id`; + --error ER_DUP_ENTRY, ER_DUP_KEY + eval INSERT INTO tt_1(trans_id, stmt_id, info) VALUES ($trans_id, $stmt_id, ''), ($old_trans_id, $old_stmt_id, fc_i_tt_5_suc ($trans_id, $stmt_id)); + inc $stmt_id; + } + if ($command == 'N') + { + #--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id) + eval INSERT INTO nt_1(trans_id, stmt_id) VALUES ($trans_id, $stmt_id); + inc $stmt_id; + } + if ($command == 'N-trig') + { + #--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id) + eval INSERT INTO nt_5(trans_id, stmt_id) VALUES ($trans_id, $stmt_id); + inc $stmt_id; + } + if ($command == 'N-func') + { + #--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id) + eval SELECT fc_i_nt_5_suc ($trans_id, $stmt_id); + inc $stmt_id; + } + if ($command == 'N-proc') + { + #--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id) + eval CALL pc_i_nt_5_suc ($trans_id, $stmt_id); + inc $stmt_id; + } + if ($command == 'eN') + { + #--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id) + let $old_trans_id= `SELECT max(trans_id) from nt_1`; + let $old_stmt_id= `SELECT max(stmt_id) from nt_1 where trans_id= $old_trans_id`; + --error ER_DUP_ENTRY, ER_DUP_KEY + eval INSERT INTO nt_1(trans_id, stmt_id) VALUES ($old_trans_id, $old_stmt_id); + inc $stmt_id; + } + if ($command == 'Ne') + { + #--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id) + let $old_trans_id= `SELECT max(trans_id) from nt_1`; + let $old_stmt_id= `SELECT max(stmt_id) from nt_1 where trans_id= $old_trans_id`; + --error ER_DUP_ENTRY, ER_DUP_KEY + eval INSERT INTO nt_1(trans_id, stmt_id) VALUES ($trans_id, $stmt_id), ($old_trans_id, $old_stmt_id); + inc $stmt_id; + } + if ($command == 'Ne-trig') + { + #--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id) + let $old_trans_id= `SELECT max(trans_id) from nt_5`; + let $old_stmt_id= `SELECT max(stmt_id) from nt_5 where trans_id= $old_trans_id`; + --error ER_DUP_ENTRY, ER_DUP_KEY + eval INSERT INTO nt_5(trans_id, stmt_id) VALUES ($trans_id, $stmt_id), ($old_trans_id, $old_stmt_id); + inc $stmt_id; + } + if ($command == 'Ne-func') + { + #--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id) + let $old_trans_id= `SELECT max(trans_id) from nt_1`; + let $old_stmt_id= `SELECT max(stmt_id) from nt_1 where trans_id= $old_trans_id`; + --error ER_DUP_ENTRY, ER_DUP_KEY + eval INSERT INTO nt_1(trans_id, stmt_id, info) VALUES ($trans_id, $stmt_id, ''), ($old_trans_id, $old_stmt_id, fc_i_nt_5_suc ($trans_id, $stmt_id)); + inc $stmt_id; + } + if ($command == 'tN') + { + #--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id) + eval INSERT INTO nt_1(trans_id, stmt_id, info) SELECT $trans_id, $stmt_id, COUNT(*) FROM tt_1; + inc $stmt_id; + } + if ($command == 'tNe') + { + #--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id) + let $old_trans_id= `SELECT max(trans_id) from nt_1`; + let $old_stmt_id= `SELECT max(stmt_id) from nt_1 where trans_id= $old_trans_id`; + --error ER_DUP_ENTRY, ER_DUP_KEY + eval INSERT INTO nt_1(trans_id, stmt_id, info) SELECT $trans_id, $stmt_id, COUNT(*) FROM tt_1 UNION SELECT $old_trans_id, $old_stmt_id, COUNT(*) FROM tt_1; + inc $stmt_id; + } + if ($command == 'nT') + { + #--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id) + eval INSERT INTO tt_1(trans_id, stmt_id, info) SELECT $trans_id, $stmt_id, COUNT(*) FROM nt_1; + inc $stmt_id; + } + if ($command == 'nTe') + { + #--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id) + let $old_trans_id= `SELECT max(trans_id) from tt_1`; + let $old_stmt_id= `SELECT max(stmt_id) from tt_1 where trans_id= $old_trans_id`; + --error ER_DUP_ENTRY, ER_DUP_KEY + eval INSERT INTO tt_1(trans_id, stmt_id, info) SELECT $trans_id, $stmt_id, COUNT(*) FROM nt_1 UNION SELECT $old_trans_id, $old_stmt_id, COUNT(*) FROM nt_1; + inc $stmt_id; + } + if ($command == 'NT') + { + #--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id) + eval UPDATE nt_3, tt_3 SET nt_3.info= "new text $trans_id --> $stmt_id", tt_3.info= "new text $trans_id --> $stmt_id" where nt_3.trans_id = tt_3.trans_id and tt_3.trans_id = 1; + inc $stmt_id; + } + if ($command == 'NT-trig') + { + #--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id) + eval INSERT INTO nt_4(trans_id, stmt_id) VALUES ($trans_id, $stmt_id); + inc $stmt_id; + } + if ($command == 'NT-func') + { + #--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id) + eval INSERT INTO nt_5(trans_id, stmt_id, info) VALUES ($trans_id, $stmt_id, fc_i_tt_5_suc($trans_id, $stmt_id)); + inc $stmt_id; + } + if ($command == 'NeT-trig') + { + #--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id) + let $old_trans_id= `SELECT max(trans_id) from nt_4`; + let $old_stmt_id= `SELECT max(stmt_id) from nt_4 where trans_id= $old_trans_id`; + --error ER_DUP_ENTRY, ER_DUP_KEY + eval INSERT INTO nt_4(trans_id, stmt_id) VALUES ($trans_id, $stmt_id), ($old_trans_id, $old_stmt_id); + inc $stmt_id; + } + if ($command == 'NeT-func') + { + #--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id) + let $old_trans_id= `SELECT max(trans_id) from nt_5`; + let $old_stmt_id= `SELECT max(stmt_id) from nt_5 where trans_id= $old_trans_id`; + --error ER_DUP_ENTRY, ER_DUP_KEY + eval INSERT INTO nt_5(trans_id, stmt_id, info) VALUES ($trans_id, $stmt_id, ''), ($old_trans_id, $old_stmt_id, fc_i_tt_5_suc ($trans_id, $stmt_id)); + inc $stmt_id; + } + if ($command == 'TN') + { + #--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id) + eval UPDATE tt_4, nt_4 SET tt_4.info= "new text $trans_id --> $stmt_id", nt_4.info= "new text $trans_id --> $stmt_id" where nt_4.trans_id = tt_4.trans_id and tt_4.trans_id = 1; + inc $stmt_id; + } + if ($command == 'TN-trig') + { + #--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id) + eval INSERT INTO tt_3(trans_id, stmt_id) VALUES ($trans_id, $stmt_id); + inc $stmt_id; + } + if ($command == 'TN-func') + { + #--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id) + eval INSERT INTO tt_5(trans_id, stmt_id, info) VALUES ($trans_id, $stmt_id, fc_i_nt_5_suc($trans_id, $stmt_id)); + inc $stmt_id; + } + if ($command == 'TeN-trig') + { + #--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id) + let $old_trans_id= `SELECT max(trans_id) from tt_3`; + let $old_stmt_id= `SELECT max(stmt_id) from tt_3 where trans_id= $old_trans_id`; + --error ER_DUP_ENTRY, ER_DUP_KEY + eval INSERT INTO tt_3(trans_id, stmt_id) VALUES ($trans_id, $stmt_id), ($old_trans_id, $old_stmt_id); + inc $stmt_id; + } + if ($command == 'TeN-func') + { + #--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id) + let $old_trans_id= `SELECT max(trans_id) from tt_5`; + let $old_stmt_id= `SELECT max(stmt_id) from tt_5 where trans_id= $old_trans_id`; + --error ER_DUP_ENTRY, ER_DUP_KEY + eval INSERT INTO tt_5(trans_id, stmt_id, info) VALUES ($trans_id, $stmt_id, ''), ($old_trans_id, $old_stmt_id, fc_i_nt_5_suc ($trans_id, $stmt_id)); + inc $stmt_id; + } + if ($command == 'set-T') + { + --eval SET @var= fc_i_tt_5_suc($trans_id, $stmt_id) + inc $stmt_id; + } + if ($command == 'set-N') + { + --eval SET @var= fc_i_nt_5_suc($trans_id, $stmt_id) + inc $stmt_id; + } + if ($command == 'set-NT') + { + --eval SET @var= fc_i_nt_3_tt_3_suc($trans_id, $stmt_id) + inc $stmt_id; + } + if ($command == 'CS-T->T') + { + --eval CREATE TABLE tt_xx_$tb_id (PRIMARY KEY(trans_id, stmt_id)) engine=$engine_type SELECT * FROM tt_1; + } + if ($command == 'CS-N->N') + { + --eval CREATE TABLE nt_xx_$tb_id (PRIMARY KEY(trans_id, stmt_id)) engine=MyIsam SELECT * FROM nt_1; + } + if ($command == 'CS-T->N') + { + --eval CREATE TABLE tt_xx_$tb_id (PRIMARY KEY(trans_id, stmt_id)) engine=$engine_type SELECT * FROM nt_1; + } + if ($command == 'CS-N->T') + { + --eval CREATE TABLE nt_xx_$tb_id (PRIMARY KEY(trans_id, stmt_id)) engine=MyIsam SELECT * FROM tt_1; + } + if ($command == 'CSe-T->T') + { + --error ER_DUP_ENTRY, ER_DUP_KEY + --eval CREATE TABLE tt_xx_$tb_id (PRIMARY KEY (stmt_id)) engine=$engine_type SELECT stmt_id FROM tt_1; + } + if ($command == 'CSe-N->N') + { + --error ER_DUP_ENTRY, ER_DUP_KEY + --eval CREATE TABLE nt_xx_$tb_id (PRIMARY KEY (stmt_id)) engine=MyIsam SELECT stmt_id FROM nt_1; + } + if ($command == 'CSe-T->N') + { + --error ER_DUP_ENTRY, ER_DUP_KEY + --eval CREATE TABLE tt_xx_$tb_id (PRIMARY KEY (stmt_id)) engine=$engine_type SELECT stmt_id FROM nt_1; + } + if ($command == 'CSe-N->T') + { + --error ER_DUP_ENTRY, ER_DUP_KEY + --eval CREATE TABLE nt_xx_$tb_id (PRIMARY KEY (stmt_id)) engine=MyIsam SELECT stmt_id FROM tt_1; + } + if ($command == 'CT') + { + --eval CREATE TEMPORARY TABLE tt_xx_$tb_id (a int) engine=$engine_type; + } + if ($command == 'IS-T<-N') + { + --eval INSERT INTO tt_xx_$tb_id(trans_id, stmt_id, info) SELECT trans_id, stmt_id, USER() FROM nt_1; + } + if ($command == 'ISe-T<-N') + { + --error ER_DUP_ENTRY, ER_DUP_KEY + --eval INSERT INTO tt_xx_$tb_id(trans_id, stmt_id, info) SELECT trans_id, trans_id, USER() FROM nt_1; + } + if ($command == 'IS-N<-T') + { + --eval INSERT INTO nt_xx_$tb_id(trans_id, stmt_id, info) SELECT trans_id, stmt_id, USER() FROM tt_1; + } + if ($command == 'ISe-N<-T') + { + --error ER_DUP_ENTRY, ER_DUP_KEY + --eval INSERT INTO nt_xx_$tb_id(trans_id, stmt_id, info) SELECT trans_id, trans_id, USER() FROM tt_1; + } + if ($command == 'IS-T<-T') + { + --eval INSERT INTO tt_xx_$tb_id(trans_id, stmt_id, info) SELECT trans_id, stmt_id, USER() FROM tt_1; + } + if ($command == 'ISe-T<-T') + { + --error ER_DUP_ENTRY, ER_DUP_KEY + --eval INSERT INTO tt_xx_$tb_id(trans_id, stmt_id, info) SELECT trans_id, trans_id, USER() FROM tt_1; + } + if ($command == 'IS-N<-N') + { + --eval INSERT INTO nt_xx_$tb_id(trans_id, stmt_id, info) SELECT trans_id, stmt_id, USER() FROM nt_1; + } + if ($command == 'ISe-N<-N') + { + --error ER_DUP_ENTRY, ER_DUP_KEY + --eval INSERT INTO nt_xx_$tb_id(trans_id, stmt_id, info) SELECT trans_id, trans_id, USER() FROM nt_1; + } + if ($command == 'trunc-CS-T') + { + eval TRUNCATE TABLE tt_xx_$tb_id; + } + if ($command == 'trunc-CS-N') + { + eval TRUNCATE TABLE nt_xx_$tb_id; + } + if ($command == 'trunc-CT') + { + eval TRUNCATE TABLE tt_xx_$tb_id; + } + if ($command == 'drop-CS') + { + --disable_warnings + eval DROP TABLE IF EXISTS tt_xx_$tb_id, nt_xx_$tb_id; + inc $tb_id; + --enable_warnings + } + if ($command == 'drop-CT') + { + --disable_warnings + eval DROP TEMPORARY TABLE IF EXISTS tt_xx_$tb_id; + inc $tb_id; + --enable_warnings + } + if ($command == 'C') + { + --error 0, ER_GET_ERRMSG + eval COMMIT; + } + if ($command == 'R') + { + --replace_column 2 # + --error 0, ER_GET_ERRMSG + eval ROLLBACK; + } + if ($command == 'Sn') + { + eval SAVEPOINT S_$sn; + --inc $sn + } + if ($command == 'Rn') + { + if ($sn) + { + --dec $sn + } + --replace_column 2 # + eval ROLLBACK TO S_$sn; + } + if ($command == 'Cn') + { + if ($sn) + { + --dec $sn + } + eval RELEASE SAVEPOINT S_$sn; + } + --disable_query_log + --let $commands= `SELECT LTRIM(SUBSTRING('$commands', LENGTH('$command') + 1))` + inc $stmt_id; + + let $binlog_start= $pos_command; + if ($verbose) + { + # Use other connection because include/show_binlog_events.inc + # executes SELECT UUID(), which switches to row-logging when + # binlog_format=mixed, if there are open temporary tables. This is + # due to BUG#13692513. + --connection server_1 + --source include/show_binlog_events.inc + --connection master + --echo -e-e-e-e-e-e-e-e-e-e-e- >> $command << -e-e-e-e-e-e-e-e-e-e-e- + } + if ($commands == '') + { + let $binlog_start= $pos_trans_command; + --echo -b-b-b-b-b-b-b-b-b-b-b- >> $rme_initial_commands << -b-b-b-b-b-b-b-b-b-b-b- + --connection server_1 + --source include/show_binlog_events.inc + --connection master + --echo -e-e-e-e-e-e-e-e-e-e-e- >> $rme_initial_commands << -e-e-e-e-e-e-e-e-e-e-e- + --echo + let $pos_trans_command= query_get_value("SHOW MASTER STATUS", Position, 1); + let $stmt_id= 1; + inc $trans_id; + } +} +--enable_ps2_protocol + +--let $commands= $rme_initial_commands diff --git a/mysql-test/suite/rpl/include/rpl_mixing_engines.test b/mysql-test/suite/rpl/include/rpl_mixing_engines.test new file mode 100644 index 00000000..fd466307 --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_mixing_engines.test @@ -0,0 +1,1816 @@ +################################################################################ +# - Introduction +# This checks if transactions that mixes transactional and non-transactional +# are correctly handled. There are several types of statements that require +# attention because of their special behavior in transactions: +# +# * Non-transactional updates that take place inside a transaction present +# problems for logging because (1) they are visible to other clients before +# the transaction is committed, and (2) they are not rolled back even if the +# transaction is rolled back. It is not always possible to log correctly in +# statement format when both transactional and non-transactional tables are +# used in the same transaction. +# +# * Statements that do an implicit commit (i.e., most but not all DDL, and +# some utility commands) are logged specially +# +# * Statements that update temporary tables need special treatment since they +# are not logged in row format. +# +# - Definitions +# +# To reason about logging different table types, we make some preliminary +# definitions. +# +# * A table that has a transactional engine is called a T-table. +# +# * A table that has a non-transactional engine is called an N-table. +# +# * A statement makes an N-write if it makes any type of change to the server +# state that will not be changed by a ROLLBACK. +# +# * Events are either appended to the Transaction Cache (TC) or to the +# Statement Cache (SC) or written directly to the binlog. +# +# - Preliminary Rules +# +# The following preliminary rules are actually consequences of the principle +# that statements shall be correctly logged when binlog_format=MIXED or ROW. +# They also apply when binlog_format=STATEMENT: this makes statement format +# work in many practical cases. +# +# * (Causality) If statement A is executed before statement B, and B is logged +# in statement format, and B reads tables that A may modifies, then B shall be +# logged after A. +# +# * (Durability) Events shall be written to the binary log at the moment they +# take effect. In particular, changes to N-tables shall be written to the +# binary log when they have been executed, and changes to T-tables shall be +# written to the binary log on commit. If --sync-binlog has been specified, +# then it suffices that events are be written to the binary log at the next +# synchronization point. +# +# * (causality-precedence) If causality and durability cannot both be +# fulfilled, then casuality is considered more important. +# +# - Rules for non-committing statements, except CREATE TEMPORARY TABLE...SELECT +# +# The preliminary rules above, together with the principles for logging format +# , have been used to construct the following rules. +# +# CALL statements are unrolled, so that each statement executed by the stored +# procedure is logged separately. (If a stored procedure A invokes a stored +# procedure B, then B is unrolled recursively). In the following, we assume +# that unrolling has already been done, and the word "statement" refers to a +# non-CALL top-level statement or a non-CALL sub-statement. +# +# Let S be a logged statement that does not have an implicit commit, except +# CREATE TEMPORARY TABLE...SELECT (This includes all "pure DML": INSERT, +# UPDATE, DELETE, REPLACE, TRUNCATE, SELECT, DO, CALL, EXECUTE, LOAD DATA +# INFILE, and BINLOG. It also includes CREATE TEMPORARY TABLE without SELECT, +# and DROP TEMPORARY TABLE. CREATE TEMPORARY TABLE...SELECT is handled in the +# next subsection). +# +# Before executing S, determine unsafeness: +# +# * If S either makes N-writes or reads from an N-table, and either S or a +# previous statement in the same transaction reads or writes to a T-table, +# then S is marked as unsafe. +# +# When logging S, determine where to log it by applying the following rules in +# order: +# +# * If S is to be logged in statement format (i.e., if one of the following +# holds: (1) STATEMENT; (2) MIXED and S is safe; (3) S is of DDL type, i.e., +# CREATE TEMPORARY TABLE): +# 1. If S produces an error and does not do any N-write, do not log. +# 2. Otherwise, if either S or any previous statement in the same +# transaction reads or writes in any T-tables, log to TC. +# 3. Otherwise, log to SC. +# +# * If S is to be logged in row format (i.e., if S is DML and one of the +# following holds: (1) ROW; (2) MIXED and S is unsafe): +# 1. Do not log row events that write to temporary tables. +# 2. Log row events that write to non-temporary N-tables to SC. +# 3. Log row events that write to non-temporary T-tables to TC, except +# rows that are rolled back due to an error. (Note: if there is an error, +# rows written to a T-table are kept if there are subsequent rows written +# to an N-table.) +# +# * At the end of S, write BEGIN + SC + COMMIT to the binlog and clear the +# SC. +# +# At end of transaction: +# +# * At COMMIT or implicit commit, where all XA tables in the transaction +# succeed in the "prepare" phase: +# 1. If the TC is non-empty, write BEGIN + TC + COMMIT to the binlog. +# 2. If the TC is empty, do nothing. +# +# * At ROLLBACK; or at COMMIT or implicit commit where some XA table fails +# in the "prepare" phase: +# 1. If the TC contains any N-write, write BEGIN + TC + ROLLBACK to the +# binlog. +# 2. If the TC does not contain any N-write, do nothing. +# +# * At ROLLBACK TO SAVEPOINT: +# 1. If the TC contains any N-write after the savepoint, write ROLLBACK TO +# SAVEPOINT to the TC. +# 2. Otherwise, clear the part of the TC that starts at the savepoint and +# extends to the end of the TC. (Bug#47327 breaks this rule) +# +# * Clear the TC at the end of the transaction. +# +# - Rules for CREATE [TEMPORARY] TABLE...SELECT +# +# First, unsafeness is determined as above (R-unsafe-transaction). Then the +# logging format is decided. Then the following rules apply. +# +# * If logging in statement format (i.e., one of the following holds: (1) +# STATEMENT; (2) MIXED and statement is safe): +# 1. If there is an error, do not write anything. +# 2. If there is no error and the TEMPORARY keyword is used, write the +# entire CREATE...SELECT statement to the TC. +# 3. If there is no error and the TEMPORARY keyword is not used, write the +# entire CREATE...SELECT directly to the binlog. +# +# * If logging in row format (i.e., one of the following holds: (1) ROW; (2) +# MIXED and statement is unsafe): +# 1. If the TEMPORARY keyword is used, do not write anything. +# 2. If the TEMPORARY keyword is not used, write CREATE TABLE (without +# select) + BEGIN + row events + COMMIT to the TC. If there is an error, +# clear the TC; otherwise flush the TC to the binlog at the end of the +# statement and then clear the TC. (Note: currently Bug#47899 breaks this +# rule) +# +# - Rules for committing statements, except CREATE [TEMPORARY] TABLE...SELECT +# +# * All other statements that have a pre-commit are written directly to the +# binlog. +# +# We use the include file rpl_mixing_engines.inc to generate sql commands from a +# format string. The format string consists of a sequence of 'codes' separated +# by spaces. The following codes exist: +# +# - Define the scope of a transaction: +# B - Begin. +# C - Commit. +# R - Rollback. +# Sn - Savepoint Sn. +# Rn - Rollback to Sn. +# +# - Change only T-Tables: +# T - Updates a T-Table. +# T-trig - Updates T-Tables through a trigger. +# T-func - Updates T-Tables through a function. +# T-proc - Updates T-Tables through a procedure. +# eT - Fails while updating the first tuple in a T-Table. +# Te - Fails while updating an n-tuple (n > 1) in a T-Table. +# Te-trig - Fails while updating an n-tuple (n > 1) in a T-Table. +# Te-func - Fails while updating an n-tuple (n > 1) in a T-Table. +# +# - Change only N-Tables +# N - Updates a N-Table. +# N-trig - Updates N-Tables through a trigger. +# N-func - Updates N-Tables through a function. +# N-proc - Updates N-Tables through a procedure. +# eN - Fails while updating the first tuple in a N-Table. +# Ne - Fails while updating an n-tuple (n > 1) in a N-Table. +# Ne-trig - Fails while updating an n-tuple (n > 1) in a N-Table. +# Ne-func - Fails while updating an n-tuple (n > 1) in a N-Table. +# +# - Read T-table and write N-table: +# tN - Updates a N-Table +# tNe - Fails while updating an n-tuple (n > 1) in a N-Table. +# +# - Read N-table and write T-table: +# nT - Updates a T-Table. +# nTe - Fails while updating an n-tuple (n > 1) in a T-Table. +# +# - Update both types of tables. First a N-Table and the a T-Table: +# NT - Upates both types of tables through an update statement. +# NT-trig - Updates both types of tables through a trigger. +# NT-func - Updates both types of tables through a procedure. +# NeT-trig - Fails while updating an n-tuple (n > 1) in a T-Table. +# NeT-func - Fails while updating an n-tuple (n > 1) in a T-Table. +# +# - Update both types of tables. First a T-Table and the a N-Table: +# TN - Upates both types of tables through an update statement. +# TN-trig - Updates both types of tables through a trigger. +# TN-func - Updates both types of tables through a procedure. +# TeN-trig - Fails while updating an n-tuple (n > 1) in a N-Table. +# TeN-func - Fails while updating an n-tuple (n > 1) in a N-Table. +# +# - This is CREATE...SELECT: +# CS-T->T - Creates a T-table selecting from a T-table. +# CS-N->N - Creates a N-table selecting from a N-table. +# CS-T->N - Creates a T-table selecting form a N-table. +# CS-N->T - Creates a N-table selecting from a T-table. +# CSe-T->T - Fails while creating a T-table selecting from a T-table. +# CSe-N->N - Fails while creating a N-table selecting from a N-table. +# CSe-T->N - Fails while creating a T-table selecting from a a N-table. +# CSe-N->T - Fails while creating a N-table selecting from a T-table. +# drop-CS - Drops any of the tables previously created. +# trunc-CS-T - Truncates a T-table previously created. +# trunc-CS-N - Truncates a N-table previously created. +# CT - Creates a temporary T-table. +# drop-CT - Drops a temporary T-table. +# +# - This is INSERT...SELECT: +# IS-T<-T - Inserts data from a T-table into a T-table. +# IS-T<-N - Inserts data from a N-table into a T-table. +# IS-N<-T - Inserts data from a T-table into a N-table. +# IS-N<-N - Inserts data from a N-table into a N-table. +# ISe-T<-T - Fails while inserting data from a T-table into a T-table. +# ISe-T<-N - Fails while inserting data from a N-table into a T-table. +# ISe-N<-T - Fails while inserting data from a T-table into a N-table. +# ISe-N<-N - Fails while inserting data from a N-table into a N-table. +# +# For the CREATE...SELECT and INSERT...SELECT, the table names are defined based +# on the variable $tb_id which is automatically incremented after each drop. +# This indirectly means that two tables cannot co-exist unless we manually keep +# the variable $tb_id. +# +# The format of the entries in the binlog depends on the mode and on the type +# statements: S - statement and R - row. And when it is clear from the context +# which statement is referred to, we sometimes use "M" to denote a "Mixed" +# statement, i.e., one that accesses both a T-table and an N-table. +# +# For further details, please, read WL#2687 and WL#5072. +################################################################################ +--echo ######################################################################### +--echo # CONFIGURATION +--echo ######################################################################### + +call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT"); + +--source include/big_test.inc + +--let $verbose= 1 +--let $commands= configure +--source suite/rpl/include/rpl_mixing_engines.inc + +--echo ######################################################################### +--echo # 1 - MIXING TRANSACTIONAL and NON-TRANSACTIONAL TABLES +--echo ######################################################################### +connection master; + +--echo +--echo +--echo +--echo +--echo # +--echo #1) Generates in the binlog what follows: +--echo # --> STMT "B T C" entries, format S. +--echo # --> ROW "B T C" entries, format R. +--echo # --> MIXED "B T C" entries, format S. +--echo # +--let $commands= T +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= T-trig +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= T-func +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= T-proc +--source suite/rpl/include/rpl_mixing_engines.inc + + +--echo +--echo +--echo +--echo +--echo # +--echo #1.e) Generates in the binlog what follows: +--echo # --> STMT empty. +--echo # --> ROW empty. +--echo # --> MIXED empty. +--echo # +--let $commands= eT +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= Te +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= Te-trig +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= Te-func +--source suite/rpl/include/rpl_mixing_engines.inc + +--echo +--echo +--echo +--echo +--echo # +--echo #2) Generates in the binlog what follows: +--echo # --> STMT "B N C" entry, format S. +--echo # --> ROW "B N C" entry, format R. +--echo # --> MIXED "B N C" entry, format S. +--echo # +--let $commands= N +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= N-trig +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= N-func +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= N-proc +--source suite/rpl/include/rpl_mixing_engines.inc + + +--echo +--echo +--echo +--echo +--echo # +--echo #2.e) Generates in the binlog what follows if a N-table is changed: +--echo # --> STMT "B N C" entry, format S. +--echo # --> ROW "B N C" entry, format R. +--echo # --> MIXED "B N C" entry, format S. +--echo # +--let $commands= eN +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= Ne +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= Ne-trig +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= Ne-func +--source suite/rpl/include/rpl_mixing_engines.inc + +--echo +--echo +--echo +--echo +--echo # +--echo #3) Generates in the binlog what follows: +--echo # --> STMT "B M C" entry if only N-Table is changed, format S. +--echo # --> STMT "B M C" entries, format S. +--echo # --> ROW "B N T B T C" entries, format R. +--echo # --> MIXED "B N T B T C" entries, format R. +--echo # +--let $commands= tN +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= nT +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= NT +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= NT-trig +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= NT-func +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= TN +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= TN-trig +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= TN-func +--source suite/rpl/include/rpl_mixing_engines.inc + + +--echo +--echo +--echo +--echo +--echo # +--echo #3.e) Generates in the binlog what follows: +--echo # --> STMT "B M C" entry if only N-Table is changed, format S. +--echo # --> STMT "B M R" entries, format S. +--echo # --> ROW "B N C" entry, format R. +--echo # --> MIXED "B N C" entry, format R. +--let $commands= tNe +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= nTe +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= NeT-trig +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= NeT-func +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= TeN-trig +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= TeN-func +--source suite/rpl/include/rpl_mixing_engines.inc + +--echo +--echo +--echo +--echo +--echo # +--echo #4) Generates in the binlog what follows: +--echo # --> STMT "B T T C" entries, format S. +--echo # --> ROW "B T T C" entries, format R. +--echo # --> MIXED "B T T C" entries, format S +--echo # +--let $commands= B T T C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B T T-trig C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B T T-func C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B T T-proc C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B T-trig T C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B T-trig T-trig C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B T-trig T-func C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B T-trig T-proc C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B T-func T C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B T-func T-trig C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B T-func T-func C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B T-func T-proc C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B T-proc T C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B T-proc T-trig C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B T-proc T-func C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B T-proc T-proc C +--source suite/rpl/include/rpl_mixing_engines.inc + + +--echo +--echo +--echo +--echo +--echo # +--echo #4.e) Generates in the binlog what follows: +--echo # --> STMT "B T C" entries, format S. +--echo # --> ROW "B T C" entries, format R. +--echo # --> MIXED "B T C" entries, format S. +--echo # +--let $commands= B T eT C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B T Te C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B T Te-trig C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B T Te-func C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B eT T C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B Te T C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B Te-trig T C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B Te-func T C +--source suite/rpl/include/rpl_mixing_engines.inc + + +--echo +--echo +--echo +--echo +--echo # +--echo #5) Generates in the binlog what follows: +--echo # --> STMT empty. +--echo # --> ROW empty. +--echo # --> MIXED empty. +--echo # +--let $commands= B T T R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B T T-trig R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B T T-func R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B T T-proc R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B T-trig T R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B T-trig T-trig R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B T-trig T-func R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B T-trig T-proc R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B T-func T R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B T-func T-trig R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B T-func T-func R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B T-func T-proc R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B T-proc T R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B T-proc T-trig R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B T-proc T-func R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B T-proc T-proc R +--source suite/rpl/include/rpl_mixing_engines.inc + + +--echo +--echo +--echo +--echo +--echo # +--echo #5.e) Generates in the binlog what follows: +--echo # --> STMT empty. +--echo # --> ROW empty. +--echo # --> MIXED empty. +--echo # +--let $commands= B T eT R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B T Te R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B T Te-trig R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B T Te-func R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B eT T R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B Te T R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B Te-trig T R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B Te-func T R +--source suite/rpl/include/rpl_mixing_engines.inc + + +--echo +--echo +--echo +--echo +--echo # +--echo #6) Generates in the binlog what follows: +--echo # --> STMT "B N C B N C" entries, format S. +--echo # --> ROW "B N C B N C" entries, format R. +--echo # --> MIXED "B N C B N C" entries, format S. +--echo # +--let $commands= B N N C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B N N-trig C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B N N-func C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B N N-proc C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B N-trig N C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B N-trig N-trig C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B N-trig N-func C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B N-trig N-proc C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B N-func N C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B N-func N-trig C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B N-func N-func C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B N-func N-proc C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B N-proc N C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B N-proc N-trig C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B N-proc N-func C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B N-proc N-proc C +--source suite/rpl/include/rpl_mixing_engines.inc + + +--echo +--echo +--echo +--echo +--echo # +--echo #6.e) Generates in the binlog what follows if a N-Table is changed: +--echo # --> STMT "B N C B N C" entries, format S. +--echo # --> ROW "B N C B N C" entries, format R. +--echo # --> MIXED "B N C B N C" entries, format S. +--echo # +--let $commands= B N eN C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B N Ne C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B N Ne-trig C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B N Ne-func C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B eN N C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B Ne N C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B Ne-trig N C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B Ne-func N C +--source suite/rpl/include/rpl_mixing_engines.inc + + +--echo +--echo +--echo +--echo +--echo # +--echo #7) Generates in the binlog what follows: +--echo # --> STMT "B N C B N C" entries, format S. +--echo # --> ROW "B N C B N C" entries, format R. +--echo # --> MIXED "B N C B N C" entries, format S. +--echo # +--let $commands= B N N R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B N N-trig R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B N N-func R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B N N-proc R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B N-trig N R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B N-trig N-trig R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B N-trig N-func R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B N-trig N-proc R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B N-func N R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B N-func N-trig R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B N-func N-func R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B N-func N-proc R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B N-proc N R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B N-proc N-trig R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B N-proc N-func R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B N-proc N-proc R +--source suite/rpl/include/rpl_mixing_engines.inc + + +--echo +--echo +--echo +--echo +--echo # +--echo #7.e) Generates in the binlog what follows if a N-Table is changed: +--echo # --> STMT "B N C B N C" entries, format S. +--echo # --> ROW "B N C B N C" entries, format R. +--echo # --> MIXED "B N C B N C" entries, format S. +--echo # +--let $commands= B N eN R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B N Ne R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B N Ne-trig R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B N Ne-func R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B eN N R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B Ne N R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B Ne-trig N R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B Ne-func N R +--source suite/rpl/include/rpl_mixing_engines.inc + + +--echo +--echo +--echo +--echo +--echo # +--echo #8) Generates in the binlog what follows: +--echo # --> STMT "B T N C" entries, format S. +--echo # --> ROW "B N C B T C" entries, format R. +--echo # --> MIXED "B N C B T C" entries, format R in N and S in T. +--echo # +--let $commands= B T N C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B T N-trig C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B T N-func C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B T N-proc C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B T-trig N C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B T-trig N-trig C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B T-trig N-func C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B T-trig N-proc C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B T-func N C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B T-func N-trig C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B T-func N-func C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B T-func N-proc C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B T-proc N C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B T-proc N-trig C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B T-proc N-func C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B T-proc N-proc C +--source suite/rpl/include/rpl_mixing_engines.inc + + +--echo +--echo +--echo +--echo +--echo # +--echo #8.e) Generates in the binlog what follows if T-* fails: +--echo # --> STMT "B N C" entry, format S. +--echo # --> ROW "B N C" entry, format R. +--echo # --> MIXED "B N C" entry, format R. +--echo # Otherwise, what follows if N-* fails and a N-Table is changed: +--echo # --> STMT "B T N C" entries, format S. +--echo # --> ROW "B N C B T C" entries, format R. +--echo # --> MIXED "B N C B T C" entries, format R in N and S in T. +--echo # +--let $commands= B eT N C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B Te N C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B T eN C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B T Ne C +--source suite/rpl/include/rpl_mixing_engines.inc + + +--echo +--echo +--echo +--echo +--echo # +--echo #9) Generates in the binlog what follows: +--echo # --> STMT "B T N R" entries, format S. +--echo # --> ROW "B N C" entry, format R. +--echo # --> MIXED "B N C" entry, format R. +--echo # +--let $commands= B T N R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B T N-trig R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B T N-func R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B T N-proc R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B T-trig N R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B T-trig N-trig R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B T-trig N-func R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B T-trig N-proc R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B T-func N R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B T-func N-trig R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B T-func N-func R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B T-func N-proc R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B T-proc N R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B T-proc N-trig R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B T-proc N-func R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B T-proc N-proc R +--source suite/rpl/include/rpl_mixing_engines.inc + + +--echo +--echo +--echo +--echo +--echo # +--echo #9.e) Generates in the binlog what follows if T* fails: +--echo # --> STMT "B N C" entry, format S. +--echo # --> ROW "B N C" entry, format R. +--echo # --> MIXED "B N C" entry, format R. +--echo # Otherwise, what follows if N* fails and a N-Table is changed: +--echo # --> STMT "B T N R" entries, format S. +--echo # --> ROW "B N C" entry, format R. +--echo # --> MIXED "B N C" entry, format R. +--echo # +--let $commands= B eT N R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B Te N R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B T eN R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B T Ne R +--source suite/rpl/include/rpl_mixing_engines.inc + + + +--echo +--echo +--echo +--echo +--echo # +--echo #10) Generates in the binlog: +--echo # --> STMT "B N C B T C" entries, format S. +--echo # --> ROW "B N C B T C" entries, format R. +--echo # --> MIXED "B N C B T C" entries, format S. +--echo # +--let $commands= B N T C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B N T-trig C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B N T-func C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B N T-proc C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B N-trig T C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B N-trig T-trig C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B N-trig T-func C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B N-trig T-proc C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B N-func T C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B N-func T-trig C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B N-func T-func C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B N-func T-proc C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B N-proc T C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B N-proc T-trig C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B N-proc T-func C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B N-proc T-proc C +--source suite/rpl/include/rpl_mixing_engines.inc + + +--echo +--echo +--echo +--echo +--echo # +--echo #11) Generates in the binlog what follows: +--echo # --> STMT "B N C" entries, format S. +--echo # --> ROW "B N C" entries, format R. +--echo # --> MIXED "B N C" entries, format S. +--echo # + +--let $commands= B N T R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B N T-proc R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B N T-trig R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B N T-func R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B N-trig T R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B N-trig T-trig R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B N-trig T-func R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B N-trig T-proc R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B N-func T R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B N-func T-trig R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B N-func T-func R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B N-func T-proc R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B N-proc T R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B N-proc T-proc R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B N-proc T-trig R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B N-proc T-func R +--source suite/rpl/include/rpl_mixing_engines.inc + + +--echo +--echo +--echo +--echo +--echo # +--echo #12) Generates in the binlog what follows: +--echo # --> STMT "B M C B T C" entries if in M only N-Table is changed, format S. +--echo # --> STMT "B M T C" entries, format S. +--echo # --> ROW "B N C B T T C" entries, format R. +--echo # --> MIXED "B N C B T T C" entries, format R in N/T and format S in T. +--echo # +--let $commands= B tN T C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B nT T C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B NT T C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B NT-trig T C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B NT-func T C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B TN T C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B TN-trig T C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B TN-func T C +--source suite/rpl/include/rpl_mixing_engines.inc + + +--echo +--echo +--echo +--echo +--echo # +--echo #12.e) Generates in the binlog what follows if a N-Table is changed: +--echo # --> STMT "B M C B T C" entries if in M only N-Table is changed, format S. +--echo # --> STMT "B M T C" entries, format S. +--echo # --> ROW "B N C B T T C" entries, format R. +--echo # --> MIXED "B N C B T T C" entries, format R in N/T and format S in T. + --echo # +--let $commands= B tNe T C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B nTe T C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B NeT-trig T C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B NeT-func T C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B TeN-trig T C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B TeN-func T C +--source suite/rpl/include/rpl_mixing_engines.inc + + +--echo +--echo +--echo +--echo +--echo # +--echo #13) "B M T R" generates in the binlog: +--echo # --> STMT "B M C B T R" entries if in M only N-Table is changed, format S. +--echo # --> STMT "B M T R" entries, format S. +--echo # --> ROW "B N C" entry, format R. +--echo # --> MIXED "B N C" entry, format R. +--echo # +--let $commands= B tN T R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B nT T R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B NT T R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B NT-trig T R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B NT-func T R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B TN T R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B TN-trig T R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B TN-func T R +--source suite/rpl/include/rpl_mixing_engines.inc + + +--echo +--echo +--echo +--echo +--echo # +--echo #13.e) Generates in the binlog what follows if a N-Table is changed: +--echo # --> STMT "B M C B T R" entries if in M only N-Table is changed, format S. +--echo # --> STMT "B M T R" entries, format S. +--echo # --> ROW "B N C" entry, format R. +--echo # --> MIXED "B N C" entry, format R. +--echo # +--let $commands= B tNe T R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B nTe T R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B NeT-trig T R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B NeT-func T R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B TeN-trig T R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B TeN-func T R +--source suite/rpl/include/rpl_mixing_engines.inc + + +--echo +--echo +--echo +--echo +--echo # +--echo #14) Generates in the binlog what follows if a N-Table is changed: +--echo # --> STMT "B T M C" entries, format S. +--echo # --> ROW "B N C B T T C" entries, format R. +--echo # --> MIXED "B N C B T T C" entries, format R in N/T and format S in T. +--echo # +--let $commands= B T tN C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B T nT C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B T NT C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B T NT-trig C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B T NT-func C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B T TN C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B T TN-trig C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B T TN-func C +--source suite/rpl/include/rpl_mixing_engines.inc + + +--echo +--echo +--echo +--echo +--echo # +--echo #14.e) Generates in the binlog what follows if a N-Table is changed: +--echo # --> STMT "B T M C" entries, format S. +--echo # --> ROW "B N C B T C" entry, format R. +--echo # --> MIXED "B N C B T C" entry, format R. +--echo # +--let $commands= B T tNe C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B T nTe C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B T NeT-trig C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B T NeT-func C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B T TeN-trig C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B T TeN-func C +--source suite/rpl/include/rpl_mixing_engines.inc + +--echo +--echo +--echo +--echo +--echo # +--echo #15) Generates in the binlog what follows if a N-Table is changed: +--echo # --> STMT "B T M R" entries, format S. +--echo # --> ROW "B N C" entry, format R. +--echo # --> MIXED "B N C" entry, format R. +--echo # +--let $commands= B T tN R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B T nT R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B T NT R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B T NT-trig R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B T NT-func R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B T TN R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B T TN-trig R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B T TN-func R +--source suite/rpl/include/rpl_mixing_engines.inc + + +--echo +--echo +--echo +--echo +--echo # +--echo #15.e) Generates in the binlog what follows if a N-Table is changed: +--echo # --> STMT "B T M R" entries, format S. +--echo # --> ROW "B N C" entry, format R. +--echo # --> MIXED "B N C" entry, format R. +--echo # +--let $commands= B T tNe R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B T nTe R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B T NeT-trig R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B T NeT-func R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B T TeN-trig R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B T TeN-func R +--source suite/rpl/include/rpl_mixing_engines.inc + + +--echo +--echo +--echo +--echo +--echo # +--echo #16) Generates in the binlog what follows if a N-Table is changed: +--echo # --> STMT "B M C B N C" entries if in M only N-Table is changed, format S. +--echo # --> STMT "B M N C" entries, format S. +--echo # --> ROW "B N C B N C B T C" entries, format R. +--echo # --> MIXED "B M C B N C" entries if in M only N-Table is changed, format S. +--echo # --> MIXED "B N C B N C B T C" entries, format R. +--echo # +--let $commands= B tN N C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B nT N C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B NT N C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B NT-trig N C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B NT-func N C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B TN N C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B TN-trig N C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B TN-func N C +--source suite/rpl/include/rpl_mixing_engines.inc + + +--echo +--echo +--echo +--echo +--echo # +--echo #16.e) Generates in the binlog what follows if a N-Table is changed: +--echo # --> STMT "B M C B N C" entries if in M only N-Table is changed, format S. +--echo # --> STMT "B M N C" entries, format S. +--echo # --> ROW "B N C B N C B T C" entries, format R. +--echo # --> MIXED "B M C B N C" entries if in M only N-Table is changed, format S. +--echo # --> MIXED "B N C B N C B T C" entries, format R. +--echo # +--let $commands= B tNe N C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B nTe N C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B NeT-trig N C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B NeT-func N C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B TeN-trig N C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B TeN-func N C +--source suite/rpl/include/rpl_mixing_engines.inc + +--echo +--echo +--echo +--echo +--echo # +--echo #17) Generates in the binlog what follows if a N-Table is changed: +--echo # --> STMT "B M C B N C" entries if in M only N-Table is changed, format S. +--echo # --> STMT "B M N R" entries, format S. +--echo # --> ROW "B N C B N C" entries, format R. +--echo # --> MIXED "B M C B N C" entries if in M only N-Table is changed, format S. +--echo # --> MIXED "B N C B N C" entries, format R. +--echo # +--let $commands= B tN N R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B nT N R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B NT N R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B NT-trig N R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B NT-func N R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B TN N R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B TN-trig N R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B TN-func N R +--source suite/rpl/include/rpl_mixing_engines.inc + + +--echo +--echo +--echo +--echo +--echo # +--echo #17.e) Generates in the binlog what follows if a N-Table is changed: +--echo # --> STMT "B M C B N C" entries if in M only N-Table is changed, format S. +--echo # --> STMT "B M N R" entries, format S. +--echo # --> ROW "B N C B N C" entries, format R. +--echo # --> MIXED "B M C B N C" entries if in M only N-Table is changed, format S. +--echo # --> MIXED "B N C B N C" entries, format R. +--echo # +--let $commands= B tNe N R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B nTe N R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B NeT-trig N R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B NeT-func N R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B TeN-trig N R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B TeN-func N R +--source suite/rpl/include/rpl_mixing_engines.inc + + +--echo +--echo +--echo +--echo +--echo # +--echo #18) Generates in the binlog what follows if a N-Table is changed: +--echo # --> STMT "B N C B M C" entries if in M only N-Table is changed, format S. +--echo # --> STMT "B N C B M C" entries, format S. +--echo # --> ROW "B N C B N C B T C" entries, format R. +--echo # --> MIXED "B N C B N C B T C" entries, format S in first N and format R in the other. +--echo # + +--let $commands= B N tN C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B N nT C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B N NT C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B N NT-trig C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B N NT-func C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B N TN C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B N TN-trig C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B N TN-func C +--source suite/rpl/include/rpl_mixing_engines.inc + + + +--echo +--echo +--echo +--echo +--echo # +--echo #18.e) Generates in the binlog what follows if a N-Table is changed: +--echo # --> STMT "B N C B M C" entries if in M only N-Table is changed, format S. +--echo # --> STMT "B N C B M C" entries, format S. +--echo # --> ROW "B N C B N C" entries, format R. +--echo # --> MIXED "B N C B N C" entries, format S in first N and format R in the other. +--echo # +--let $commands= B N tNe C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B N nTe C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B N NeT-trig C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B N NeT-func C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B N TeN-trig C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B N TeN-func C +--source suite/rpl/include/rpl_mixing_engines.inc + + +--echo +--echo +--echo +--echo +--echo # +--echo #19) Generates in the binlog what follows if a N-Table is changed: +--echo # --> STMT "B N C B M C" entries if in M only N-Table is changed, format S. +--echo # --> STMT "B N C B M R" entries, format S. +--echo # --> ROW "B N C B N C" entries, format R. +--echo # --> MIXED "B N C B N C" entries, format S in first N and format R in the other. +--echo # + +--let $commands= B N tN R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B N nT R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B N NT R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B N NT-trig R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B N NT-func R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B N TN R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B N TN-trig R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B N TN-func R +--source suite/rpl/include/rpl_mixing_engines.inc + + +--echo +--echo +--echo +--echo +--echo # +--echo #19.e) Generates in the binlog what follows if a N-Table is changed: +--echo # --> STMT "B N C B M C" entries if in M only N-Table is changed, format S. +--echo # --> STMT "B N C B M R" entries, format S. +--echo # --> ROW "B N C B N C" entries, format R. +--echo # --> MIXED "B N C B N C" entries, format S in first N and format R in the other. +--echo # +--let $commands= B N tNe R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B N nTe R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B N NeT-trig R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B N NeT-func R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B N TeN-trig R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B N TeN-func R +--source suite/rpl/include/rpl_mixing_engines.inc + +--echo ################################################################################### +--echo # 2 - SAVEPOINT +--echo ################################################################################### +--let $commands= B T Sn T Rn C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B N T Sn T Rn C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B T N Sn T Rn C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B T Sn N T Rn C +--source suite/rpl/include/rpl_mixing_engines.inc + +--echo ################################################################################### +--echo # 3 - CREATE TABLE...SELECT +--echo ################################################################################### +--let $commands= CSe-T->T CS-T->T drop-CS +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= CSe-N->N CS-N->N drop-CS +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= CSe-T->N CS-T->N drop-CS +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= CSe-N->T CS-N->T drop-CS +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= CSe-N->T CS-N->T drop-CS +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= CSe-N->T CS-N->T drop-CS +--source suite/rpl/include/rpl_mixing_engines.inc + + +--echo ################################################################################### +--echo # 4 - INSERT TABLE...SELECT +--echo ################################################################################### + +--let $commands= CS-T->T +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= trunc-CS-T B T IS-T<-N T C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= trunc-CS-T B T ISe-T<-N T C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= trunc-CS-T B IS-T<-N T C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= trunc-CS-T B ISe-T<-N T C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= drop-CS +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= CS-T->T +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= trunc-CS-T B T IS-T<-T T C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= trunc-CS-T B T ISe-T<-T T C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= trunc-CS-T B IS-T<-T T C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= trunc-CS-T B ISe-T<-T T C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= drop-CS +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= CS-N->N +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= trunc-CS-N B T IS-N<-T T C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= trunc-CS-N B T ISe-N<-T T C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= trunc-CS-N B IS-N<-T T C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= trunc-CS-N B ISe-N<-T T C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= drop-CS +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= CS-N->N +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= trunc-CS-N B T IS-N<-N T C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= trunc-CS-N B T ISe-N<-N T C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= trunc-CS-N B IS-N<-N T C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= trunc-CS-N B ISe-N<-N T C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= drop-CS +--source suite/rpl/include/rpl_mixing_engines.inc + + +--echo ################################################################################### +--echo # 5 - ROLLBACK TEMPORARY TABLE +--echo ################################################################################### +--let $commands= B T CT R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= drop-CT +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B T Sn T CT Rn R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= drop-CT +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B T CT T R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= drop-CT +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B tN CT T R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= drop-CT +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B CT T R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= drop-CT +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B N CT T R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= drop-CT +--source suite/rpl/include/rpl_mixing_engines.inc + + +--echo ################################################################################### +--echo # 5 - SET WITH ROW CHANGES +--echo ################################################################################### +--let $commands= set-T +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= set-N +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= set-NT +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B set-N set-T C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B set-T set-N C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B set-N set-T R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B set-T set-N R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B set-NT set-T C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B set-T set-NT C +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B set-NT set-T R +--source suite/rpl/include/rpl_mixing_engines.inc + +--let $commands= B set-T set-NT R +--source suite/rpl/include/rpl_mixing_engines.inc + + +--echo ################################################################################### +--echo # CHECK CONSISTENCY +--echo ################################################################################### +connection master; +sync_slave_with_master; + +--exec $MYSQL_DUMP --compact --order-by-primary --skip-extended-insert --no-create-info test > $MYSQLTEST_VARDIR/tmp/test-nmt-master.sql +--exec $MYSQL_DUMP_SLAVE --compact --order-by-primary --skip-extended-insert --no-create-info test > $MYSQLTEST_VARDIR/tmp/test-nmt-slave.sql +if (`select @@session.binlog_direct_non_transactional_updates = 0 || @@session.binlog_format != 'STATEMENT'`) +{ + --diff_files $MYSQLTEST_VARDIR/tmp/test-nmt-master.sql $MYSQLTEST_VARDIR/tmp/test-nmt-slave.sql +} + +--echo ################################################################################### +--echo # CLEAN +--echo ################################################################################### +--let $commands= clean +--source suite/rpl/include/rpl_mixing_engines.inc diff --git a/mysql-test/suite/rpl/include/rpl_multi_query.test b/mysql-test/suite/rpl/include/rpl_multi_query.test new file mode 100644 index 00000000..ae2a3aa4 --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_multi_query.test @@ -0,0 +1,26 @@ +# Test for BUG#8436: verify that a multi-query (i.e. one query +# containing several queries (assuming client has +# CLIENT_MULTI_STATEMENTS) will be binlogged ONE-query-per-event (not +# one binlog event containing all queries) + + +# PS doesn't support multi-statements +--disable_ps_protocol +-- source include/master-slave.inc +create database mysqltest; + +delimiter /; +create table mysqltest.t1 ( n int); +insert into mysqltest.t1 values(1)/ +insert into mysqltest.t1 values(2); +insert into mysqltest.t1 values(3); +insert into mysqltest.t1 values(4); +insert into mysqltest.t1 values(5)/ +delimiter ;/ +sync_slave_with_master; +select * from mysqltest.t1; +connection master; +source include/show_binlog_events.inc; +drop database mysqltest; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/include/rpl_multi_update.test b/mysql-test/suite/rpl/include/rpl_multi_update.test new file mode 100644 index 00000000..cdbdbc19 --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_multi_update.test @@ -0,0 +1,33 @@ +source include/master-slave.inc; + +call mtr.add_suppression('Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT.'); + +eval CREATE TABLE t1 ( + a int unsigned not null auto_increment primary key, + b int unsigned +) ENGINE=$engine_type; + +eval CREATE TABLE t2 ( + a int unsigned not null auto_increment primary key, + b int unsigned +) ENGINE=$engine_type; + +INSERT INTO t1 VALUES (NULL, 0); +--disable_warnings ONCE +INSERT INTO t1 SELECT NULL, 0 FROM t1; + +INSERT INTO t2 VALUES (NULL, 0), (NULL,1); + +SELECT * FROM t1 ORDER BY a; +SELECT * FROM t2 ORDER BY a; + +--disable_warnings ONCE +UPDATE t1, t2 SET t1.b = t2.b WHERE t1.a = t2.a; +sync_slave_with_master; + +# End of 4.1 tests + +connection master; +drop table t1, t2; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/include/rpl_multi_update2.test b/mysql-test/suite/rpl/include/rpl_multi_update2.test new file mode 100644 index 00000000..b85927a2 --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_multi_update2.test @@ -0,0 +1,63 @@ +# Let's verify that multi-update is not always skipped by slave if +# some replicate-* rules exist. +# (BUG#7011) + +--disable_warnings +drop table if exists t1,t2; +--enable_warnings + +eval CREATE TABLE t1 ( + a int unsigned not null auto_increment primary key, + b int unsigned +) ENGINE=$engine_type; + +eval CREATE TABLE t2 ( + a int unsigned not null auto_increment primary key, + b int unsigned +) ENGINE=$engine_type; + +INSERT INTO t1 VALUES (NULL, 0); + +--disable_warnings ONCE +INSERT INTO t1 SELECT NULL, 0 FROM t1; + +INSERT INTO t2 VALUES (NULL, 0), (NULL,1); + +SELECT * FROM t1 ORDER BY a; +SELECT * FROM t2 ORDER BY a; + +--disable_warnings ONCE +UPDATE t1, t2 SET t1.b = (t2.b+4) WHERE t1.a = t2.a; +SELECT * FROM t1 ORDER BY a; +SELECT * FROM t2 ORDER BY a; + +save_master_pos; +connection slave; +sync_with_master; +SELECT * FROM t1 ORDER BY a; +SELECT * FROM t2 ORDER BY a; + +connection master; +drop table t1,t2; +sync_slave_with_master; + +# +# BUG#13236 multi-update with subquery & --replicate-ignore-table +# +reset master; + +connection master; +CREATE TABLE t1 ( a INT ); +INSERT INTO t1 VALUES (0); +UPDATE t1, (SELECT 3 as b) AS x SET t1.a = x.b; +select * from t1; +sync_slave_with_master; + +connection slave; +select * from t1; + +connection master; +drop table t1; +sync_slave_with_master; + +# End of 4.1 tests diff --git a/mysql-test/suite/rpl/include/rpl_multi_update3.test b/mysql-test/suite/rpl/include/rpl_multi_update3.test new file mode 100644 index 00000000..f7d4815e --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_multi_update3.test @@ -0,0 +1,223 @@ +############################################################################## +# +# Let's verify that multi-update with a subselect does not cause the slave to crash +# (BUG#10442) +# +--disable_query_log +SELECT '-------- Test for BUG#9361 --------' as ""; +--enable_query_log + +eval CREATE TABLE t1 ( + a int unsigned not null auto_increment primary key, + b int unsigned +) ENGINE=$engine_type; + +eval CREATE TABLE t2 ( + a int unsigned not null auto_increment primary key, + b int unsigned +) ENGINE=$engine_type; + +INSERT INTO t1 VALUES (NULL, 0); + +--disable_warnings ONCE +INSERT INTO t1 SELECT NULL, 0 FROM t1; + +INSERT INTO t2 VALUES (NULL, 0), (NULL,1); + +SELECT * FROM t1 ORDER BY a; +SELECT * FROM t2 ORDER BY a; + +--disable_warnings ONCE +UPDATE t2, (SELECT a FROM t1 ORDER BY a) AS t SET t2.b = t.a+5 ; +SELECT * FROM t1 ORDER BY a; +SELECT * FROM t2 ORDER BY a; + +sync_slave_with_master; +connection slave; +SELECT * FROM t1 ORDER BY a; +SELECT * FROM t2 ORDER BY a; + +connection master; +drop table t1,t2; + +############################################################################## +# +# Test for BUG#9361: +# Subselects should work inside multi-updates +# +--disable_query_log +SELECT '-------- Test 1 for BUG#9361 --------' as ""; +--enable_query_log + +connection master; + +--disable_warnings +DROP TABLE IF EXISTS t1; +DROP TABLE IF EXISTS t2; +--enable_warnings + +CREATE TABLE t1 ( + a1 char(30), + a2 int, + a3 int, + a4 char(30), + a5 char(30) +); + +CREATE TABLE t2 ( + b1 int, + b2 char(30) +); + +# Insert one row per table +INSERT INTO t1 VALUES ('Yes', 1, NULL, 'foo', 'bar'); +INSERT INTO t2 VALUES (1, 'baz'); + +# This should update the row in t1 +UPDATE t1 a, t2 + SET a.a1 = 'No' + WHERE a.a2 = + (SELECT b1 + FROM t2 + WHERE b2 = 'baz') + AND a.a3 IS NULL + AND a.a4 = 'foo' + AND a.a5 = 'bar'; + +sync_slave_with_master; +connection slave; +SELECT * FROM t1; +SELECT * FROM t2; + +connection master; +DROP TABLE t1, t2; + +############################################################################## +# +# Second test for BUG#9361 +# + +--disable_query_log +SELECT '-------- Test 2 for BUG#9361 --------' as ""; +--enable_query_log + +connection master; + +--disable_warnings +DROP TABLE IF EXISTS t1; +DROP TABLE IF EXISTS t2; +DROP TABLE IF EXISTS t3; +--enable_warnings + +CREATE TABLE t1 ( + i INT, + j INT, + x INT, + y INT, + z INT +); + +CREATE TABLE t2 ( + i INT, + k INT, + x INT, + y INT, + z INT +); + +CREATE TABLE t3 ( + j INT, + k INT, + x INT, + y INT, + z INT +); + +INSERT INTO t1 VALUES ( 1, 2,13,14,15); +INSERT INTO t2 VALUES ( 1, 3,23,24,25); +INSERT INTO t3 VALUES ( 2, 3, 1,34,35), ( 2, 3, 1,34,36); + +UPDATE t1 AS a +INNER JOIN t2 AS b + ON a.i = b.i +INNER JOIN t3 AS c + ON a.j = c.j AND b.k = c.k +SET a.x = b.x, + a.y = b.y, + a.z = ( + SELECT sum(z) + FROM t3 + WHERE y = 34 + ) +WHERE b.x = 23; + +sync_slave_with_master; +connection slave; + +SELECT * FROM t1; + +connection master; +DROP TABLE t1, t2, t3; + +############################################################################## +# +# BUG#12618 +# +# TEST: Replication of a statement containing a join in a multi-update. + +DROP TABLE IF EXISTS t1; +DROP TABLE IF EXISTS t2; + +CREATE TABLE t1 ( + idp int(11) NOT NULL default '0', + idpro int(11) default NULL, + price decimal(19,4) default NULL, + PRIMARY KEY (idp) +); + +CREATE TABLE t2 ( + idpro int(11) NOT NULL default '0', + price decimal(19,4) default NULL, + nbprice int(11) default NULL, + PRIMARY KEY (idpro) +); + +INSERT INTO t1 VALUES + (1,1,'3.0000'), + (2,2,'1.0000'), + (3,1,'1.0000'), + (4,1,'4.0000'), + (5,3,'2.0000'), + (6,2,'4.0000'); + +INSERT INTO t2 VALUES + (1,'0.0000',0), + (2,'0.0000',0), + (3,'0.0000',0); + +# This update sets t2 to the minimal prices for each product +update + t2 + join + ( select idpro, min(price) as min_price, count(*) as nbr_price + from t1 + where idpro>0 and price>0 + group by idpro + ) as table_price +on t2.idpro = table_price.idpro +set t2.price = table_price.min_price, + t2.nbprice = table_price.nbr_price; + +select "-- MASTER AFTER JOIN --" as ""; +select * from t1; +select * from t2; + +sync_slave_with_master; + +select "-- SLAVE AFTER JOIN --" as ""; +select * from t1; +select * from t2; + +connection master; +DROP TABLE t1, t2; +# End of 4.1 tests diff --git a/mysql-test/suite/rpl/include/rpl_not_null.test b/mysql-test/suite/rpl/include/rpl_not_null.test new file mode 100644 index 00000000..cbb6b787 --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_not_null.test @@ -0,0 +1,360 @@ +################################################################################# +# This test checks if the replication between "null" fields to either "null" +# fields or "not null" fields works properly. In the first case, the execution +# should work fine. In the second case, it may fail according to the sql_mode +# being used. +# +# The test is devided in three main parts: +# +# 1 - NULL --> NULL (no failures) +# 2 - NULL --> NOT NULL ( sql-mode = STRICT and failures) +# 3 - NULL --> NOT NULL ( sql-mode != STRICT and no failures) +# +################################################################################# +connection master; + +SET SQL_LOG_BIN= 0; +eval CREATE TABLE t1(`a` INT, `b` DATE DEFAULT NULL, +`c` INT DEFAULT NULL, +PRIMARY KEY(`a`)) ENGINE=$engine DEFAULT CHARSET=LATIN1; + +eval CREATE TABLE t2(`a` INT, `b` DATE DEFAULT NULL, +PRIMARY KEY(`a`)) ENGINE=$engine DEFAULT CHARSET=LATIN1; + +eval CREATE TABLE t3(`a` INT, `b` DATE DEFAULT NULL, +PRIMARY KEY(`a`)) ENGINE=$engine DEFAULT CHARSET=LATIN1; + +eval CREATE TABLE t4(`a` INT, `b` DATE DEFAULT NULL, +`c` INT DEFAULT NULL, +PRIMARY KEY(`a`)) ENGINE=$engine DEFAULT CHARSET=LATIN1; +SET SQL_LOG_BIN= 1; + +connection slave; + +eval CREATE TABLE t1(`a` INT, `b` DATE DEFAULT NULL, +`c` INT DEFAULT NULL, +PRIMARY KEY(`a`)) ENGINE=$engine DEFAULT CHARSET=LATIN1; + +eval CREATE TABLE t2(`a` INT, `b` DATE DEFAULT NULL, +PRIMARY KEY(`a`)) ENGINE=$engine DEFAULT CHARSET=LATIN1; + +eval CREATE TABLE t3(`a` INT, `b` DATE DEFAULT '0000-00-00', +`c` INT DEFAULT 500, +PRIMARY KEY(`a`)) ENGINE=$engine DEFAULT CHARSET=LATIN1; + +eval CREATE TABLE t4(`a` INT, `b` DATE DEFAULT '0000-00-00', +PRIMARY KEY(`a`)) ENGINE=$engine DEFAULT CHARSET=LATIN1; + +--echo ************* EXECUTION WITH INSERTS ************* +connection master; +INSERT INTO t1(a,b,c) VALUES (1, null, 1); +INSERT INTO t1(a,b,c) VALUES (2,'1111-11-11', 2); +INSERT INTO t1(a,b) VALUES (3, null); +INSERT INTO t1(a,c) VALUES (4, 4); +INSERT INTO t1(a) VALUES (5); + +INSERT INTO t2(a,b) VALUES (1, null); +INSERT INTO t2(a,b) VALUES (2,'1111-11-11'); +INSERT INTO t2(a) VALUES (3); + +INSERT INTO t3(a,b) VALUES (1, null); +INSERT INTO t3(a,b) VALUES (2,'1111-11-11'); +INSERT INTO t3(a) VALUES (3); + +INSERT INTO t4(a,b,c) VALUES (1, null, 1); +INSERT INTO t4(a,b,c) VALUES (2,'1111-11-11', 2); +INSERT INTO t4(a,b) VALUES (3, null); +INSERT INTO t4(a,c) VALUES (4, 4); +INSERT INTO t4(a) VALUES (5); + +--echo ************* SHOWING THE RESULT SETS WITH INSERTS ************* +sync_slave_with_master; + +--echo TABLES t1 and t2 must be equal otherwise an error will be thrown. +let $diff_tables= master:t1, slave:t1; +source include/diff_tables.inc; + +let $diff_tables= master:t2, slave:t2; +source include/diff_tables.inc; + +--echo TABLES t2 and t3 must be different. +connection master; +SELECT * FROM t3 ORDER BY a; +connection slave; +SELECT * FROM t3 ORDER BY a; +connection master; +SELECT * FROM t4 ORDER BY a; +connection slave; +SELECT * FROM t4 ORDER BY a; + +--echo ************* EXECUTION WITH UPDATES and REPLACES ************* +connection master; +DELETE FROM t1; +INSERT INTO t1(a,b,c) VALUES (1,'1111-11-11', 1); +REPLACE INTO t1(a,b,c) VALUES (2,'1111-11-11', 2); +UPDATE t1 set b= NULL, c= 300 where a= 1; +REPLACE INTO t1(a,b,c) VALUES (2, NULL, 300); + +--echo ************* SHOWING THE RESULT SETS WITH UPDATES and REPLACES ************* +sync_slave_with_master; + +--echo TABLES t1 and t2 must be equal otherwise an error will be thrown. +let $diff_tables= master:t1, slave:t1; +source include/diff_tables.inc; + +--echo ************* CLEANING ************* +connection master; + +DROP TABLE t1; +DROP TABLE t2; +DROP TABLE t3; +DROP TABLE t4; + +sync_slave_with_master; + +connection master; + +SET SQL_LOG_BIN= 0; +eval CREATE TABLE t1 (`a` INT, `b` BIT DEFAULT NULL, `c` BIT DEFAULT NULL, +PRIMARY KEY (`a`)) ENGINE= $engine; +SET SQL_LOG_BIN= 1; + +connection slave; + +eval CREATE TABLE t1 (`a` INT, `b` BIT DEFAULT b'01', `c` BIT DEFAULT NULL, +PRIMARY KEY (`a`)) ENGINE= $engine; + +--echo ************* EXECUTION WITH INSERTS ************* +connection master; +INSERT INTO t1(a,b,c) VALUES (1, null, b'01'); +INSERT INTO t1(a,b,c) VALUES (2,b'00', b'01'); +INSERT INTO t1(a,b) VALUES (3, null); +INSERT INTO t1(a,c) VALUES (4, b'01'); +INSERT INTO t1(a) VALUES (5); + +--echo ************* SHOWING THE RESULT SETS WITH INSERTS ************* +--echo TABLES t1 and t2 must be different. +sync_slave_with_master; +connection master; +SELECT a,b+0,c+0 FROM t1 ORDER BY a; +connection slave; +SELECT a,b+0,c+0 FROM t1 ORDER BY a; + +--echo ************* EXECUTION WITH UPDATES and REPLACES ************* +connection master; +DELETE FROM t1; +INSERT INTO t1(a,b,c) VALUES (1,b'00', b'01'); +REPLACE INTO t1(a,b,c) VALUES (2,b'00',b'01'); +UPDATE t1 set b= NULL, c= b'00' where a= 1; +REPLACE INTO t1(a,b,c) VALUES (2, NULL, b'00'); + +--echo ************* SHOWING THE RESULT SETS WITH UPDATES and REPLACES ************* +--echo TABLES t1 and t2 must be equal otherwise an error will be thrown. +sync_slave_with_master; +let $diff_tables= master:t1, slave:t1; +source include/diff_tables.inc; + +connection master; + +DROP TABLE t1; + +sync_slave_with_master; + +--echo ################################################################################ +--echo # NULL ---> NOT NULL (STRICT MODE) +--echo # UNCOMMENT THIS AFTER FIXING BUG#43992 +--echo ################################################################################ +#connection slave; +#SET GLOBAL sql_mode="TRADITIONAL"; +# +#STOP SLAVE; +#--source include/wait_for_slave_to_stop.inc +#START SLAVE; +#--source include/wait_for_slave_to_start.inc +# +#let $y=0; +#while ($y < 6) +#{ +# connection master; +# +# SET SQL_LOG_BIN= 0; +# eval CREATE TABLE t1(`a` INT NOT NULL, `b` INT, +# PRIMARY KEY(`a`)) ENGINE=$engine DEFAULT CHARSET=LATIN1; +# eval CREATE TABLE t2(`a` INT NOT NULL, `b` INT, +# PRIMARY KEY(`a`)) ENGINE=$engine DEFAULT CHARSET=LATIN1; +# eval CREATE TABLE t3(`a` INT NOT NULL, `b` INT, +# PRIMARY KEY(`a`)) ENGINE=$engine DEFAULT CHARSET=LATIN1; +# SET SQL_LOG_BIN= 1; +# +# connection slave; +# +# eval CREATE TABLE t1(`a` INT NOT NULL, `b` INT NOT NULL, +# `c` INT NOT NULL, +# PRIMARY KEY(`a`)) ENGINE=$engine DEFAULT CHARSET=LATIN1; +# eval CREATE TABLE t2(`a` INT NOT NULL, `b` INT NOT NULL, +# `c` INT, +# PRIMARY KEY(`a`)) ENGINE=$engine DEFAULT CHARSET=LATIN1; +# eval CREATE TABLE t3(`a` INT NOT NULL, `b` INT NOT NULL, +# `c` INT DEFAULT 500, +# PRIMARY KEY(`a`)) ENGINE=$engine DEFAULT CHARSET=LATIN1; +# +# if ($y==0) +# { +# --echo ************* EXECUTION WITH INSERTS ************* +# connection master; +# INSERT INTO t1(a) VALUES (1); +# } +# +# if ($y==1) +# { +# --echo ************* EXECUTION WITH INSERTS ************* +# connection master; +# INSERT INTO t1(a, b) VALUES (1, NULL); +# } +# +# if ($y==2) +# { +# --echo ************* EXECUTION WITH UPDATES ************* +# connection master; +# INSERT INTO t3(a, b) VALUES (1, 1); +# INSERT INTO t3(a, b) VALUES (2, 1); +# UPDATE t3 SET b = NULL where a= 1; +# } +# +# if ($y==3) +# { +# --echo ************* EXECUTION WITH INSERTS/REPLACES ************* +# connection master; +# REPLACE INTO t3(a, b) VALUES (1, null); +# } +# +# if ($y==4) +# { +# --echo ************* EXECUTION WITH UPDATES/REPLACES ************* +# connection master; +# INSERT INTO t3(a, b) VALUES (1, 1); +# REPLACE INTO t3(a, b) VALUES (1, null); +# } +# +# if ($y==5) +# { +# --echo ************* EXECUTION WITH MULTI-ROW INSERTS ************* +# connection master; +# +# SET SQL_LOG_BIN= 0; +# INSERT INTO t2(a, b) VALUES (1, 1); +# INSERT INTO t2(a, b) VALUES (2, 1); +# INSERT INTO t2(a, b) VALUES (3, null); +# INSERT INTO t2(a, b) VALUES (4, 1); +# INSERT INTO t2(a, b) VALUES (5, 1); +# SET SQL_LOG_BIN= 1; +# +# INSERT INTO t2 SELECT a + 10, b from t2; +# --echo The statement below is just executed to stop processing +# INSERT INTO t1(a) VALUES (1); +# } +# +# --echo ************* SHOWING THE RESULT SETS ************* +# connection slave; +# --source include/wait_for_slave_sql_to_stop.inc +# connection master; +# SELECT * FROM t1 ORDER BY a; +# connection slave; +# SELECT * FROM t1 ORDER BY a; +# connection master; +# SELECT * FROM t2 ORDER BY a; +# connection slave; +# SELECT * FROM t2 ORDER BY a; +# connection master; +# SELECT * FROM t3 ORDER BY a; +# connection slave; +# SELECT * FROM t3 ORDER BY a; +# --source include/rpl_reset.inc +# +# connection master; +# +# DROP TABLE t1; +# DROP TABLE t2; +# DROP TABLE t3; +# +# sync_slave_with_master; +# +# inc $y; +#} +#connection slave; +#SET GLOBAL sql_mode=""; +# +#STOP SLAVE; +#source include/wait_for_slave_to_stop.inc; +#START SLAVE; +#--source include/wait_for_slave_to_start.inc + +--echo ################################################################################ +--echo # NULL ---> NOT NULL (NON-STRICT MODE) +--echo ################################################################################ +connection master; + +SET SQL_LOG_BIN= 0; +eval CREATE TABLE t1(`a` INT NOT NULL, `b` INT, +PRIMARY KEY(`a`)) ENGINE=$engine DEFAULT CHARSET=LATIN1; +eval CREATE TABLE t2(`a` INT NOT NULL, `b` INT, +PRIMARY KEY(`a`)) ENGINE=$engine DEFAULT CHARSET=LATIN1; +eval CREATE TABLE t3(`a` INT NOT NULL, `b` INT, +PRIMARY KEY(`a`)) ENGINE=$engine DEFAULT CHARSET=LATIN1; +SET SQL_LOG_BIN= 1; + +connection slave; + +eval CREATE TABLE t1(`a` INT NOT NULL, `b` INT NOT NULL, +`c` INT NOT NULL, +PRIMARY KEY(`a`)) ENGINE=$engine DEFAULT CHARSET=LATIN1; +eval CREATE TABLE t2(`a` INT NOT NULL, `b` INT NOT NULL, +`c` INT, +PRIMARY KEY(`a`)) ENGINE=$engine DEFAULT CHARSET=LATIN1; +eval CREATE TABLE t3(`a` INT NOT NULL, `b` INT NOT NULL, +`c` INT DEFAULT 500, +PRIMARY KEY(`a`)) ENGINE=$engine DEFAULT CHARSET=LATIN1; + +--echo ************* EXECUTION WITH INSERTS ************* +connection master; +INSERT INTO t1(a) VALUES (1); +INSERT INTO t1(a, b) VALUES (2, NULL); +INSERT INTO t1(a, b) VALUES (3, 1); + +INSERT INTO t2(a) VALUES (1); +INSERT INTO t2(a, b) VALUES (2, NULL); +INSERT INTO t2(a, b) VALUES (3, 1); + +INSERT INTO t3(a) VALUES (1); +INSERT INTO t3(a, b) VALUES (2, NULL); +INSERT INTO t3(a, b) VALUES (3, 1); +INSERT INTO t3(a, b) VALUES (4, 1); +REPLACE INTO t3(a, b) VALUES (5, null); + +REPLACE INTO t3(a, b) VALUES (3, null); +UPDATE t3 SET b = NULL where a = 4; + +--echo ************* SHOWING THE RESULT SETS ************* +connection master; +sync_slave_with_master; + +connection master; +SELECT * FROM t1 ORDER BY a; +connection slave; +SELECT * FROM t1 ORDER BY a; +connection master; +SELECT * FROM t2 ORDER BY a; +connection slave; +SELECT * FROM t2 ORDER BY a; +connection master; +SELECT * FROM t3 ORDER BY a; +connection slave; +SELECT * FROM t3 ORDER BY a; + +connection master; + +DROP TABLE t1; +DROP TABLE t2; +DROP TABLE t3; + +sync_slave_with_master; diff --git a/mysql-test/suite/rpl/include/rpl_parallel_29322.inc b/mysql-test/suite/rpl/include/rpl_parallel_29322.inc new file mode 100644 index 00000000..96d75f33 --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_parallel_29322.inc @@ -0,0 +1,112 @@ +# A "body" for rpl.rpl_parallel_29322 that runs having as input +# the master and slave @@global.explicit_defaults_for_timestamp. +# +# The Key notes +# ------------- +# On master: a sequence of binlog files is composed with +# different server versions. +# On slave: to first try enqueuing all master events. +# Due to binlog files are from different version +# servers when the new (of binlog 2) FD shows up the enqueuing +# will hiccup as workers have to +# process all events already scheduled (see wait_condition below). +# This part proves of the different server version the binlogs +# indeed are. +# After the worker is unblocked the exection proceeds. +# +# In the end compare table definitions and print table data +# to prove correctness. + +--connection slave +--source include/stop_slave.inc +--let $master_use_gtid_option=No +--source include/reset_slave.inc + +--connection master +--let $datadir= `SELECT @@datadir` + +reset master; # Master starts a new serious of binlog files + +create table t2 (a timestamp, b int); +show create table t2; +--save_master_pos + +--connection slave +--source include/start_slave.inc +--sync_with_master +--source include/stop_slave.inc + +# load for two $same_version_binlogs branches +--connection master +if (!$same_version_binlogs) +{ + insert into t2 values (null, 1); + flush binary logs; + flush binary logs; + insert into t2 values (null, 2); +} +if ($same_version_binlogs) +{ +--disable_query_log + --let $count=8 + while ($count) + { + --let $queries=4 + while ($queries) + { + insert into t2 values (null, 1); + --dec $queries + } + flush binary logs; + flush binary logs; + --dec $count + } +--enable_query_log +} +--save_master_pos + +if (!$same_version_binlogs) +{ + --move_file $datadir/master-bin.000002 $datadir/master-bin.000002.sav + --copy_file $MYSQL_TEST_DIR/std_data/mdev29078-mysql-bin.000001 $datadir/master-bin.000002 + --exec $MYSQL_BINLOG --short-form $datadir/master-bin.000002 + + # To demonstrate different version binlogs, hold back worker + # until the SQL thread state shows waiting. + --connection slave1 + lock table t2 write; +} + +--connection slave +--source include/start_slave.inc + +if (!$same_version_binlogs) +{ + --let $slave_waits_for=Waiting for worker threads to be idle + --let $wait_condition= SELECT COUNT(*) > 0 FROM information_schema.processlist WHERE state = "$slave_waits_for" + --source include/wait_condition.inc + + --connection slave1 + unlock tables; + + --connection slave + --sync_with_master + show create table t1; + set statement time_zone='+2:00' for select * from t1; + drop table t1; + + --connection master + --remove_file $datadir/master-bin.000002 + --move_file $datadir/master-bin.000002.sav $datadir/master-bin.000002 +} + +--connection slave +--sync_with_master +show create table t2; +--let $diff_tables=master:t2,slave:t2 +--source include/diff_tables.inc + +--connection master +drop table t2; + +--sync_slave_with_master diff --git a/mysql-test/suite/rpl/include/rpl_parallel_incorrect_relay_pos.inc b/mysql-test/suite/rpl/include/rpl_parallel_incorrect_relay_pos.inc new file mode 100644 index 00000000..3cf0afd6 --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_parallel_incorrect_relay_pos.inc @@ -0,0 +1,128 @@ +--echo *** MDEV-7237: Parallel replication: incorrect relaylog position after stop/start the slave *** + +--source include/have_innodb.inc +--source include/have_debug.inc +--source include/have_debug_sync.inc +--source include/master-slave.inc + +--connection server_2 +--source include/stop_slave.inc +CALL mtr.add_suppression("Commit failed due to failure of an earlier commit on which this one depends"); +SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads; +SET @old_parallel_mode=@@GLOBAL.slave_parallel_mode; +SET GLOBAL slave_parallel_threads=10; +# Test assumes that 'conservative' mode is in effect. i.e +# Do not start parallel execution of this event group until all prior groups +# have reached the commit phase. Upon execution of STOP SLAVE there can be one +# group which is executing and the rest are doing group commit order wait. +SET GLOBAL slave_parallel_mode='conservative'; +CHANGE MASTER TO master_use_gtid=slave_pos; +--source include/start_slave.inc + +--connection server_1 +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +CREATE TABLE t2 (a int PRIMARY KEY) ENGINE=InnoDB; +INSERT INTO t2 VALUES (40); +--save_master_pos + +--connection server_2 +--sync_with_master +--connect (con_temp2,127.0.0.1,root,,test,$SERVER_MYPORT_2,) +--source include/stop_slave.inc +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 +--source include/start_slave.inc + +# 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%' +--source include/wait_condition.inc + +# 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; +--source include/wait_for_slave_sql_to_stop.inc +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). +--source include/start_slave.inc +--sync_with_master +SELECT * FROM t2 WHERE a >= 40 ORDER BY a; + +# Clean up. +--source include/stop_slave.inc +SET GLOBAL debug_dbug=@old_dbug; +SET DEBUG_SYNC= 'RESET'; +SET GLOBAL slave_parallel_threads=@old_parallel_threads; +SET GLOBAL slave_parallel_mode=@old_parallel_mode; +CHANGE MASTER TO master_use_gtid=slave_pos; +--source include/start_slave.inc + +--connection server_1 +DROP TABLE t2; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/include/rpl_partition.inc b/mysql-test/suite/rpl/include/rpl_partition.inc new file mode 100644 index 00000000..9f16f769 --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_partition.inc @@ -0,0 +1,104 @@ +######## Create Table Section ######### +use test; + +#dt TIMESTAMP, user CHAR(255), uuidf LONGBLOB, +eval CREATE TABLE test.regular_tbl(id INT NOT NULL AUTO_INCREMENT, + dt TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE + CURRENT_TIMESTAMP, user CHAR(255), uuidf VARBINARY(255), + fkid INT, filler VARCHAR(255), + PRIMARY KEY(id)) + ENGINE=$engine_type; + +eval CREATE TABLE test.byrange_tbl(id INT NOT NULL AUTO_INCREMENT, + dt TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE + CURRENT_TIMESTAMP, user CHAR(255), uuidf VARBINARY(255), + fkid INT, filler VARCHAR(255), + PRIMARY KEY(id)) + ENGINE=$engine_type + PARTITION BY RANGE(id) + (PARTITION pa100 values less than (100), + PARTITION paMax values less than MAXVALUE); + +######## Create SPs, Functions, Views and Triggers Section ############## + +delimiter |; +CREATE PROCEDURE test.proc_norm() +BEGIN + DECLARE ins_count INT DEFAULT 99; + DECLARE cur_user VARCHAR(255); + DECLARE local_uuid VARCHAR(255); + + SET cur_user= "current_user@localhost"; + SET local_uuid= "36774b1c-6374-11df-a2ca-0ef7ac7a5f6c"; + + WHILE ins_count > 0 DO + # Must use local variables for statment based replication + INSERT INTO test.regular_tbl VALUES (NULL, NOW(), cur_user, local_uuid, + ins_count,'Non partitioned table! Going to test replication for MySQL'); + SET ins_count = ins_count - 1; + END WHILE; + +END| + +CREATE PROCEDURE test.proc_byrange() +BEGIN + DECLARE ins_count INT DEFAULT 200; + DECLARE cur_user VARCHAR(255); + DECLARE local_uuid VARCHAR(255); + + SET cur_user= "current_user@localhost"; + SET local_uuid= "36774b1c-6374-11df-a2ca-0ef7ac7a5f6c"; + + WHILE ins_count > 0 DO + INSERT INTO test.byrange_tbl VALUES (NULL, NOW(), cur_user, local_uuid, + ins_count + 100,'Partitioned table! Going to test replication for MySQL'); + SET ins_count = ins_count - 1; + END WHILE; + +END| + +delimiter ;| + +############ Finish Setup Section ################### + + +############ Test Section ################### + +CALL test.proc_norm(); +SELECT count(*) as "Master regular" FROM test.regular_tbl; +CALL test.proc_byrange(); +SELECT count(*) as "Master byrange" FROM test.byrange_tbl; +show create table test.byrange_tbl; +show create table test.regular_tbl; +ALTER TABLE test.byrange_tbl EXCHANGE PARTITION pa100 WITH TABLE test.regular_tbl; +--replace_column 2 date-time 3 USER 4 UUID +SELECT * FROM test.byrange_tbl ORDER BY fkid LIMIT 2; +--replace_column 2 date-time 3 USER 4 UUID +SELECT * FROM test.byrange_tbl ORDER BY fkid DESC LIMIT 2; +--replace_column 2 date-time 3 USER 4 UUID +SELECT * FROM test.regular_tbl ORDER BY fkid LIMIT 2; +--replace_column 2 date-time 3 USER 4 UUID +SELECT * FROM test.regular_tbl ORDER BY fkid DESC LIMIT 2; + +--sync_slave_with_master +connection slave; +show create table test.byrange_tbl; +show create table test.regular_tbl; +SELECT count(*) "Slave norm" FROM test.regular_tbl; +SELECT count(*) "Slave byrange" FROM test.byrange_tbl; +--replace_column 2 date-time 3 USER 4 UUID +SELECT * FROM test.byrange_tbl ORDER BY fkid LIMIT 2; +--replace_column 2 date-time 3 USER 4 UUID +SELECT * FROM test.byrange_tbl ORDER BY fkid DESC LIMIT 2; +--replace_column 2 date-time 3 USER 4 UUID +SELECT * FROM test.regular_tbl ORDER BY fkid LIMIT 2; +--replace_column 2 date-time 3 USER 4 UUID +SELECT * FROM test.regular_tbl ORDER BY fkid DESC LIMIT 2; + +###### CLEAN UP SECTION ############## + +connection master; +DROP PROCEDURE test.proc_norm; +DROP PROCEDURE test.proc_byrange; +DROP TABLE test.regular_tbl; +DROP TABLE test.byrange_tbl; diff --git a/mysql-test/suite/rpl/include/rpl_partition.test b/mysql-test/suite/rpl/include/rpl_partition.test new file mode 100644 index 00000000..119e3beb --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_partition.test @@ -0,0 +1,262 @@ +############################################################ +# Author: MATZ # +# Date: 2006-03-22 # +# Purpose: See if replication of partition tables work # +############################################################ + +connection master; +--disable_warnings +DROP TABLE IF EXISTS t1; +--enable_query_log + +--echo --- Start test 2 partition RANGE testing -- + +# Create table that is partitioned by range on year i.e. year(t) and +# replicate basice operations such at insert, update delete between 2 +# different storage engines Alter table and ensure table is handled +# Correctly on the slave +# Note that the storage engine should not be explicit: the default +# storage engine is used on master and slave. + +CREATE TABLE t1 (id MEDIUMINT NOT NULL, b1 BIT(8), vc VARCHAR(255), + bc CHAR(255), d DECIMAL(10,4) DEFAULT 0, + f FLOAT DEFAULT 0, total BIGINT UNSIGNED, + y YEAR, t DATE) + PARTITION BY RANGE (YEAR(t)) + (PARTITION p0 VALUES LESS THAN (1901), + PARTITION p1 VALUES LESS THAN (1946), + PARTITION p2 VALUES LESS THAN (1966), + PARTITION p3 VALUES LESS THAN (1986), + PARTITION p4 VALUES LESS THAN (2005), + PARTITION p5 VALUES LESS THAN MAXVALUE); + +--echo --- On master --- +SHOW CREATE TABLE t1; + +--echo --- On slave -- +sync_slave_with_master; +SHOW CREATE TABLE t1; + +--source include/rpl_multi_engine3.inc + +--echo --- Check that simple Alter statements are replicated correctly --- +ALTER TABLE t1 MODIFY vc TEXT; + +--echo --- On master --- +SHOW CREATE TABLE t1; + +--echo --- On slave --- +sync_slave_with_master; +SHOW CREATE TABLE t1; + +--echo --- Perform basic operation on master --- +--echo --- and ensure replicated correctly --- +--enable_query_log + +--source include/rpl_multi_engine3.inc + +--echo --- End test 2 partition RANGE testing --- + +DROP TABLE IF EXISTS t1; + +######################################################## + +--echo --- Start test 3 partition LIST testing --- +--echo --- Do setup --- +################################################# +# Requirment: Create table that is partitioned # +# by list on id i.e. (2,4). Pretend that we # +# missed one and alter to add. Then replicate # +# basice operations such at insert, update # +# delete between 2 different storage engines # +# Alter table and ensure table is handled # +# Correctly on the slave # +################################################# + + +CREATE TABLE t1 (id MEDIUMINT NOT NULL, b1 BIT(8), vc VARCHAR(255), + bc CHAR(255), d DECIMAL(10,4) DEFAULT 0, + f FLOAT DEFAULT 0, total BIGINT UNSIGNED, + y YEAR, t DATE) + PARTITION BY LIST(id) + (PARTITION p0 VALUES IN (2, 4), + PARTITION p1 VALUES IN (42, 142)); + +--echo --- Test 3 Alter to add partition --- + +ALTER TABLE t1 ADD PARTITION (PARTITION p2 VALUES IN (412)); + +--echo --- Show table on master --- + +SHOW CREATE TABLE t1; + +--echo --- Show table on slave --- + +sync_slave_with_master; +SHOW CREATE TABLE t1; + +--echo --- Perform basic operation on master --- +--echo --- and ensure replicated correctly --- + +--source include/rpl_multi_engine3.inc + +--echo --- Check that simple Alter statements are replicated correctly --- + +ALTER TABLE t1 MODIFY vc TEXT; + +--echo --- Show the new improved table on the master --- + +SHOW CREATE TABLE t1; + +--echo --- Make sure that our tables on slave are still same engine --- +--echo --- and that the alter statements replicated correctly --- + +sync_slave_with_master; +SHOW CREATE TABLE t1; + +--echo --- Perform basic operation on master --- +--echo --- and ensure replicated correctly --- + +--source include/rpl_multi_engine3.inc + +--echo --- End test 3 partition LIST testing --- +--echo --- Do Cleanup -- + +DROP TABLE IF EXISTS t1; + +######################################################## + +--echo --- Start test 4 partition HASH testing --- +--echo --- Do setup --- +################################################# +# Requirment: Create table that is partitioned # +# by hash on year i.e. YEAR(t). Then replicate # +# basice operations such at insert, update # +# delete between 2 different storage engines # +# Alter table and ensure table is handled # +# Correctly on the slave # +################################################# + + +CREATE TABLE t1 (id MEDIUMINT NOT NULL, b1 BIT(8), vc VARCHAR(255), + bc CHAR(255), d DECIMAL(10,4) DEFAULT 0, + f FLOAT DEFAULT 0, total BIGINT UNSIGNED, + y YEAR, t DATE) + PARTITION BY HASH( YEAR(t) ) + PARTITIONS 4; + +--echo --- show that tables have been created correctly --- + +SHOW CREATE TABLE t1; +sync_slave_with_master; +SHOW CREATE TABLE t1; + +--echo --- Perform basic operation on master --- +--echo --- and ensure replicated correctly --- + +--source include/rpl_multi_engine3.inc + +--echo --- Check that simple Alter statements are replicated correctly --- + +ALTER TABLE t1 MODIFY vc TEXT; + +--echo --- Show the new improved table on the master --- + +SHOW CREATE TABLE t1; + +--echo --- Make sure that our tables on slave are still same engine --- +--echo --- and that the alter statements replicated correctly --- + +sync_slave_with_master; +SHOW CREATE TABLE t1; + +--echo --- Perform basic operation on master --- +--echo --- and ensure replicated correctly --- + +--source include/rpl_multi_engine3.inc + +--echo --- End test 4 partition HASH testing --- +--echo --- Do Cleanup -- + +DROP TABLE IF EXISTS t1; + +######################################################## + +--echo --- Start test 5 partition by key testing --- +--echo --- Create Table Section --- + +################################################# +# Requirment: Create table that is partitioned # +# by key on id with 4 parts. Then replicate # +# basice operations such at insert, update # +# delete between 2 different storage engines # +# Alter table and ensure table is handled # +# Correctly on the slave # +################################################# + +CREATE TABLE t1 (id MEDIUMINT NOT NULL, b1 BIT(8), vc VARCHAR(255), + bc CHAR(255), d DECIMAL(10,4) DEFAULT 0, + f FLOAT DEFAULT 0, total BIGINT UNSIGNED, + y YEAR, t DATE,PRIMARY KEY(id)) + PARTITION BY KEY() + PARTITIONS 4; + +--echo --- Show tables on master --- + +SHOW CREATE TABLE t1; + +--echo --- Show tables on slave --- + +sync_slave_with_master; +SHOW CREATE TABLE t1; + +--echo --- Perform basic operation on master --- +--echo --- and ensure replicated correctly --- + +--source include/rpl_multi_engine3.inc + +# Okay lets see how it holds up to table changes +--echo --- Check that simple Alter statements are replicated correctly --- + +ALTER TABLE t1 DROP PRIMARY KEY, ADD PRIMARY KEY(id, total); + +--echo --- Show the new improved table on the master --- + +SHOW CREATE TABLE t1; + +--echo --- Make sure that our tables on slave are still right type --- +--echo --- and that the alter statements replicated correctly --- + +sync_slave_with_master; +SHOW CREATE TABLE t1; + +--echo --- Perform basic operation on master --- +--echo --- and ensure replicated correctly --- + +--source include/rpl_multi_engine3.inc + +--echo --- Check that simple Alter statements are replicated correctly --- + +ALTER TABLE t1 MODIFY vc TEXT; + +--echo --- Show the new improved table on the master --- + +SHOW CREATE TABLE t1; + +--echo --- Make sure that our tables on slave are still same engine --- +--echo --- and that the alter statements replicated correctly --- + +sync_slave_with_master; +SHOW CREATE TABLE t1; + +--echo --- Perform basic operation on master --- +--echo --- and ensure replicated correctly --- + +--source include/rpl_multi_engine3.inc + +--echo --- End test 5 key partition testing --- +--echo --- Do Cleanup --- + +DROP TABLE IF EXISTS t1; + +# End of 5.1 test case diff --git a/mysql-test/suite/rpl/include/rpl_record_compare.test b/mysql-test/suite/rpl/include/rpl_record_compare.test new file mode 100644 index 00000000..2bc088d1 --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_record_compare.test @@ -0,0 +1,64 @@ + +# +# BUG#52868: Wrong handling of NULL value during update, replication out of sync +# +-- echo ## case #1 - last_null_bit_pos==0 in record_compare without X bit + +-- source include/rpl_reset.inc +-- connection master + +-- eval CREATE TABLE t1 (c1 bigint(20) DEFAULT 0, c2 bigint(20) DEFAULT 0, c3 bigint(20) DEFAULT 0, c4 varchar(1) DEFAULT '', c5 bigint(20) DEFAULT 0, c6 bigint(20) DEFAULT 0, c7 bigint(20) DEFAULT 0, c8 bigint(20) DEFAULT 0) ENGINE=$engine DEFAULT CHARSET=latin1 + +INSERT INTO t1 ( c5, c6 ) VALUES ( 1 , 35 ); +INSERT INTO t1 ( c5, c6 ) VALUES ( NULL, 35 ); +-- disable_warnings +UPDATE IGNORE t1 SET c5 = 'a'; +-- enable_warnings +-- sync_slave_with_master + +-- let $diff_tables= master:t1, slave:t1 +-- source include/diff_tables.inc + +--connection master +DROP TABLE t1; +-- sync_slave_with_master + +-- echo ## case #1.1 - last_null_bit_pos==0 in record_compare with X bit +-- echo ## (1 column less and no varchar) +-- source include/rpl_reset.inc +-- connection master + +-- eval CREATE TABLE t1 (c1 bigint(20) DEFAULT 0, c2 bigint(20) DEFAULT 0, c3 bigint(20) DEFAULT 0, c4 bigint(20) DEFAULT 0, c5 bigint(20) DEFAULT 0, c6 bigint(20) DEFAULT 0, c7 bigint(20) DEFAULT 0) ENGINE=$engine DEFAULT CHARSET=latin1 + +INSERT INTO t1 ( c5, c6 ) VALUES ( 1 , 35 ); +INSERT INTO t1 ( c5, c6 ) VALUES ( NULL, 35 ); +-- disable_warnings +UPDATE IGNORE t1 SET c5 = 'a'; +-- enable_warnings +-- sync_slave_with_master + +-- let $diff_tables= master:t1, slave:t1 +-- source include/diff_tables.inc + +--connection master +DROP TABLE t1; +-- sync_slave_with_master + +-- echo ## case #2 - X bit is wrongly set. + +-- source include/rpl_reset.inc +-- connection master + +-- eval CREATE TABLE t1 (c1 int, c2 varchar(1) default '') ENGINE=$engine DEFAULT CHARSET= latin1 +INSERT INTO t1(c1) VALUES (10); +INSERT INTO t1(c1) VALUES (NULL); +UPDATE t1 SET c1= 0; +-- sync_slave_with_master + +-- let $diff_tables= master:t1, slave:t1 +-- source include/diff_tables.inc + +-- connection master +DROP TABLE t1; +-- sync_slave_with_master + diff --git a/mysql-test/suite/rpl/include/rpl_relayrotate.test b/mysql-test/suite/rpl/include/rpl_relayrotate.test new file mode 100644 index 00000000..28670fe0 --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_relayrotate.test @@ -0,0 +1,77 @@ +# When the relay log gets rotated while the I/O thread +# is reading a transaction, the transaction spans on two or more +# relay logs. If STOP SLAVE occurs while the SQL thread is +# executing a part of the transaction in the non-first relay logs, +# we test if START SLAVE will resume in the beginning of the +# transaction (i.e., step back to the first relay log) + +# The slave is started with max_binlog_size=16384 bytes, +# to force many rotations (approximately 30 rotations) + +# We have to sync with master, to ensure slave had time to start properly +# before we stop it. If not, we get errors about UNIX_TIMESTAMP() in the log. +connection master; +sync_slave_with_master; +connection slave; +stop slave; +connection master; +--disable_warnings +eval create table t1 (a int) engine=$engine_type; +--enable_warnings +let $1=8000; +disable_query_log; +begin; +while ($1) +{ +# eval means expand $ expressions + eval insert into t1 values( $1 ); + dec $1; +} +commit; +# This will generate a 500kB master's binlog, +# which corresponds to 30 slave's relay logs. +enable_query_log; +save_master_pos; +connection slave; +reset slave; +start slave; +# We wait 1 sec for the SQL thread to be somewhere in +# the middle of the transaction, hopefully not in +# the first relay log, and hopefully before the COMMIT. +# Usually it stops when the SQL thread is around the 15th relay log. +# We cannot use MASTER_POS_WAIT() as master's position +# increases only when the slave executes the COMMIT. +# Note that except when using Valgrind, 1 second is enough for the I/O slave +# thread to fetch the whole master's binlog. +sleep 1; +stop slave; +# We suppose the SQL thread stopped before COMMIT. +# If so the transaction was rolled back +# and the table is now empty. +# Now restart +start slave; +# And see if the table contains '8000' +# which proves that the transaction restarted at +# the right place. +# We must wait for the transaction to commit before +# reading, with a sync_with_master. +sync_with_master; +select max(a) from t1; +connection master; + +# The following DROP is a very important cleaning task: +# imagine the next test is run with --skip-innodb: it will do +# DROP TABLE IF EXISTS t1; but this will delete the frm and leave +# some data in the InnoDB datafile (because at that time mysqld +# does not know about InnoDB : --skip-innodb). So if later in the +# test suite a test wants to create an InnoDB table called t1, it +# will fail with +# InnoDB: Error: table t1 already exists in InnoDB internal +# InnoDB: data dictionary. Have you deleted the .frm file etc +drop table t1; +# wait until this drop is executed on slave +save_master_pos; +connection slave; +sync_with_master; + +# End of 4.1 tests diff --git a/mysql-test/suite/rpl/include/rpl_reset_slave.test b/mysql-test/suite/rpl/include/rpl_reset_slave.test new file mode 100644 index 00000000..d4c9d701 --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_reset_slave.test @@ -0,0 +1,116 @@ +# TBF - difference in row level logging +# Temp tables are not replicated in rbr, but it is still good to hit rbr with everthing + +# See SHOW SLAVE STATUS displays well after RESET SLAVE (it should display the +# --master-* options from mysqld, as this is what is going to be used next time +# slave threads will be started). In bug 985, it displayed old values (of before +# RESET SLAVE). +# See if slave crashes when doing a CREATE TEMPORARY TABLE twice, separated by +# RESET SLAVE. + +-- source include/master-slave.inc +sync_slave_with_master; +--disable_query_log +set sql_log_bin=0; +call mtr.add_suppression('Slave I/O: Get master BINLOG_CHECKSUM failed with error'); +set sql_log_bin=1; +--enable_query_log +let $status_items= Master_User, Master_Host; +source include/show_slave_status.inc; + +source include/stop_slave.inc; +change master to master_user='test'; +source include/show_slave_status.inc; + +--source include/reset_slave.inc +source include/show_slave_status.inc; + +change master to master_user='root'; +source include/start_slave.inc; +sync_with_master; +source include/show_slave_status.inc; + +# test of crash with temp tables & RESET SLAVE +# (test to see if RESET SLAVE clears temp tables in memory and disk) +source include/stop_slave.inc; +--source include/reset_slave.inc +source include/start_slave.inc; +connection master; +create temporary table t1 (a int); +sync_slave_with_master; +source include/stop_slave.inc; +--source include/reset_slave.inc +source include/start_slave.inc; +sync_with_master; +show status like 'slave_open_temp_tables'; +connection master; +drop temporary table if exists t1; +sync_slave_with_master; + +# +#Bug#34654 RESET SLAVE does not clear LAST_IO_Err* +# + +# clearing the status +source include/stop_slave.inc; +--source include/reset_slave.inc +source include/check_slave_no_error.inc; + +# +# verifying start slave resets Last_IO_Error and Last_IO_Errno. +# + +change master to master_user='impossible_user_name'; +start slave; +let $slave_io_errno= 1045; +--source include/wait_for_slave_io_error.inc +--source include/stop_slave_sql.inc + +change master to master_user='root'; +source include/start_slave.inc; +source include/check_slave_no_error.inc; + +# +# verifying reset slave resets Last_{IO,SQL}_Err{or,no} +# + +stop slave; +change master to master_user='impossible_user_name'; +start slave; +let $slave_io_errno= 1045; +--source include/wait_for_slave_io_error.inc +--source include/stop_slave_sql.inc + +--source include/reset_slave.inc +source include/check_slave_no_error.inc; +change master to master_user='root'; + + +# +# BUG#11809016 - NO WAY TO DISCOVER AN INSTANCE IS NO LONGER A SLAVE FOLLOWING MYSQL BUG#28796 +# + +--source include/reset_slave.inc +--source include/start_slave.inc + +--source include/stop_slave.inc +--let $_slave_master_host= query_get_value(SHOW SLAVE STATUS, Master_Host, 1) +--let $_slave_master_user= query_get_value(SHOW SLAVE STATUS, Master_User, 1) +--let $_slave_master_port= query_get_value(SHOW SLAVE STATUS, Master_Port, 1) + +reset slave all; +set @@global.gtid_slave_pos= ""; +--error ER_BAD_SLAVE +start slave; + +--let $_show_master_host= query_get_value(SHOW SLAVE STATUS, Master_Host, 1) +if ($_show_master_host != No such row) +{ + die; +} + +--replace_result $_slave_master_host MASTER_HOST $_slave_master_user MASTER_USER $_slave_master_port MASTER_PORT +--eval CHANGE MASTER TO MASTER_HOST= '$_slave_master_host', MASTER_USER= '$_slave_master_user', MASTER_PORT= $_slave_master_port +--source include/start_slave.inc + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/include/rpl_reset_slave_all_check.inc b/mysql-test/suite/rpl/include/rpl_reset_slave_all_check.inc new file mode 100644 index 00000000..adbaf32e --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_reset_slave_all_check.inc @@ -0,0 +1,48 @@ +# This file ensures that a slave's id filtering variables (i.e. DO_DOMAIN_IDS, +# IGNORE_DOMAIN_IDS, and IGNORE_SERVER_IDS) are cleared after issuing +# `RESET SLAVE ALL`. +# +# param $_do_domain_ids Integer list of values to use for DO_DOMAIN_IDS +# param $_ignore_domain_ids Integer list of values to use for IGNORE_DOMAIN_IDS +# param $_ignore_server_ids Integer list of values to use for IGNORE_SERVER_IDS +# + +--echo # Id filtering variable values should be empty initially +let $do_domain_ids_before= query_get_value(SHOW SLAVE STATUS, Replicate_Do_Domain_Ids, 1); +let $ignore_domain_ids_before= query_get_value(SHOW SLAVE STATUS, Replicate_Ignore_Domain_Ids, 1); +let $ignore_server_ids_before= query_get_value(SHOW SLAVE STATUS, Replicate_Ignore_Server_Ids, 1); + +if (`SELECT "$do_domain_ids_before" != "" OR + "$ignore_domain_ids_before" != "" OR + "$ignore_server_ids_before" != ""`) +{ + die("CHANGE MASTER TO id filter variables are not empty initially"); +} + + +--echo # Set id filtering variables +eval CHANGE MASTER TO DO_DOMAIN_IDS=$_do_domain_ids, IGNORE_DOMAIN_IDS=$_ignore_domain_ids, IGNORE_SERVER_IDS=$_ignore_server_ids, MASTER_USE_GTID=SLAVE_POS; +let $do_domain_ids_set= query_get_value(SHOW SLAVE STATUS, Replicate_Do_Domain_Ids, 1); +let $ignore_domain_ids_set= query_get_value(SHOW SLAVE STATUS, Replicate_Ignore_Domain_Ids, 1); +let $ignore_server_ids_set= query_get_value(SHOW SLAVE STATUS, Replicate_Ignore_Server_Ids, 1); +--echo # do domain id list: $do_domain_ids_set +--echo # ignore domain id list: $ignore_domain_ids_set +--echo # ignore server id list: $ignore_server_ids_set + + +--echo # RESET SLAVE ALL should clear values for all id filtering variables +RESET SLAVE ALL; +--replace_result $MASTER_MYPORT MASTER_MYPORT +eval change master to master_port=$MASTER_MYPORT, master_host='127.0.0.1', master_user='root'; +--source include/start_slave.inc +--source include/stop_slave.inc + +let $do_domain_ids_cleared= query_get_value(SHOW SLAVE STATUS, Replicate_Do_Domain_Ids, 1); +let $ignore_domain_ids_cleared= query_get_value(SHOW SLAVE STATUS, Replicate_Ignore_Domain_Ids, 1); +let $ignore_server_ids_cleared= query_get_value(SHOW SLAVE STATUS, Replicate_Ignore_Server_Ids, 1); +if (`SELECT "$do_domain_ids_cleared" != "" OR + "$ignore_domain_ids_cleared" != "" OR + "$ignore_server_ids_cleared" != ""`) +{ + die("RESET SLAVE ALL did not clear id filtering variables"); +} diff --git a/mysql-test/suite/rpl/include/rpl_row_UUID.test b/mysql-test/suite/rpl/include/rpl_row_UUID.test new file mode 100644 index 00000000..11eb3c6b --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_row_UUID.test @@ -0,0 +1,79 @@ +############################################################################# +# Original Author: JBM # +# Original Date: Aug/18/2005 # +############################################################################# +# TEST: To test the UUID() in rbr # +############################################################################# + +# Begin clean up test section +connection master; + +--disable_warnings +DROP PROCEDURE IF EXISTS test.p1; +DROP TABLE IF EXISTS test.t1; +--enable_warnings + +# Section 1 test + +eval CREATE TABLE test.t1 (a INT, blob_column LONGBLOB, vchar_column VARCHAR(100), PRIMARY KEY(a)) engine=$engine_type; +INSERT INTO test.t1 VALUES(1,UUID(),UUID()); +delimiter |; +create procedure test.p1() +begin + INSERT INTO test.t1 VALUES(2,UUID(),UUID()); + INSERT INTO test.t1 VALUES(3,UUID(),UUID()); +end| +delimiter ;| + +CALL test.p1(); + +# Now the same thing with a function + +delimiter |; +create function test.fn1(x int) + returns int +begin + insert into t1 values (4+x,UUID(),UUID()); + insert into t1 values (5+x,UUID(),UUID()); + return 0; +end| + +delimiter ;| +# test both in SELECT and in INSERT +--disable_ps2_protocol +select fn1(0); +--enable_ps2_protocol +eval create table t2 (a int) engine=$engine_type; +insert into t2 values(fn1(2)); + +sync_slave_with_master; +SHOW CREATE TABLE test.t1; + +# Dump the databases and so we can see if they match +# Another method would be to use SELECT INTO OUTFILE on master, +# then LOAD DATA INFILE in slave, and use a query to compare. +# This would have the advantage that it would not assume +# the system has a 'diff' +--exec $MYSQL_DUMP --compact --order-by-primary --skip-extended-insert --no-create-info test > $MYSQLTEST_VARDIR/tmp/rpl_row_UUID_master.sql +--exec $MYSQL_DUMP_SLAVE --compact --order-by-primary --skip-extended-insert --no-create-info test > $MYSQLTEST_VARDIR/tmp/rpl_row_UUID_slave.sql + +connection master; +# Let's cleanup + +DROP PROCEDURE test.p1; +DROP FUNCTION test.fn1; +DROP TABLE test.t1; +DROP TABLE test.t2; + +# 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_row_UUID_master.sql $MYSQLTEST_VARDIR/tmp/rpl_row_UUID_slave.sql; + +# Cleanup dump files. +# Long-term "system rm" is not portable; we could live without +# this cleanup as no other test will use these files and they'll +# be removed at next testsuite run. + diff --git a/mysql-test/suite/rpl/include/rpl_row_annotate.test b/mysql-test/suite/rpl/include/rpl_row_annotate.test new file mode 100644 index 00000000..8b4b704c --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_row_annotate.test @@ -0,0 +1,185 @@ +######################################################################## +# WL47: Store in binlog text of statements that caused RBR events +# new event : ANNOTATE_ROWS_EVENT +# new master option : --binlog-annotate-row-events +# new slave option : --replicate-annotate-row-events +######################################################################## +--source include/master-slave.inc +connect (master2,127.0.0.1,root,,test,$MASTER_MYPORT,); + +connection master; +--disable_query_log + +--disable_warnings +DROP DATABASE IF EXISTS test1; +--enable_warnings + +CREATE DATABASE test1; +USE test1; + +CREATE TABLE t1(a int primary key, b int); +CREATE TABLE t2(a int, b int); +CREATE TABLE t3(a int, b int); +CREATE TABLE t4(a int, b int); +CREATE TABLE xt1(a int, b int); +CREATE TABLE xt2(a int, b int); + +CREATE TABLE t5 ( + a INT PRIMARY KEY AUTO_INCREMENT, + b VARCHAR(10) CHARACTER SET utf8 COLLATE utf8_bin +); + +SET SESSION binlog_annotate_row_events = OFF; + +INSERT INTO t1 VALUES (0,0), (1,1); + +SET SESSION binlog_annotate_row_events = ON; + +UPDATE t1 SET b = b + 1; +REPLACE t1 VALUES (1,1), (2,2), (3,3); + +INSERT INTO t2 VALUES (1,1), (2,2), (3,3); +INSERT INTO t3 VALUES (1,1), (2,2), (3,3); +DELETE t1, t2 FROM t1 INNER JOIN t2 INNER JOIN t3 WHERE t1.a=t2.a AND t2.a=t3.a; + +INSERT INTO xt1 VALUES (1,1), (2,2), (3,3); +INSERT INTO t2 VALUES (1,1), (2,2), (3,3); +DELETE xt1, t2 FROM xt1 INNER JOIN t2 INNER JOIN t3 WHERE xt1.a=t2.a AND t2.a=t3.a; + +INSERT INTO xt1 VALUES (1,1), (2,2), (3,3); +INSERT INTO xt2 VALUES (1,1), (2,2), (3,3); +DELETE xt1, xt2 FROM xt1 INNER JOIN xt2 INNER JOIN t3 WHERE xt1.a=xt2.a AND xt2.a=t3.a; + +INSERT INTO t5(b) VALUES ('foo'), ('bar'), ('baz'); +SET NAMES latin1; +INSERT INTO t5(b) VALUES ('gås'); +SET NAMES utf8; +INSERT INTO t5(b) VALUES ('gÃ¥s'); +SET NAMES latin1; + +FLUSH LOGS; + +--echo ######################################################################## +--echo # TABLES ON MASTER +--echo ######################################################################## +--enable_query_log + +SELECT * FROM t1 ORDER BY a; +SELECT * FROM t2 ORDER BY a; +SELECT * FROM t3 ORDER BY a; +SELECT * FROM t5 ORDER BY a; + +sync_slave_with_master; +--echo ######################################################################## +--echo # TABLES ON SLAVE: should be the same as on master +--echo ######################################################################## +--disable_query_log +USE test1; +--enable_query_log + +SELECT * FROM t1 ORDER BY a; +SELECT * FROM t2 ORDER BY a; +SELECT * FROM t3 ORDER BY a; +SELECT * FROM t5 ORDER BY a; + +--echo ######################################################################## +--echo # EVENTS ON SLAVE +let $annotate= `select @@global.replicate_annotate_row_events`; +if ($annotate) +{ + --echo # The following Annotate_rows events should appear below: + --echo # - UPDATE t1 SET b = b + 1; + --echo # - REPLACE t1 VALUES (1,1), (2,2), (3,3); + --echo # - INSERT INTO t2 VALUES (1,1), (2,2), (3,3) + --echo # - INSERT INTO t3 VALUES (1,1), (2,2), (3,3) + --echo # - DELETE t1, t2 FROM <...> + --echo # - INSERT INTO t2 VALUES (1,1), (2,2), (3,3) + --echo # - DELETE xt1, t2 FROM <...> + --echo # - INSERT INTO t5(b) VALUES <...> (3 instances) +} +if (!$annotate) +{ + --echo # No Annotate_rows events should appear below +} + + + +--echo ######################################################################## +--echo # Ensure that a replication failure doesn't segfault - MDEV-7864 +--echo ######################################################################## +DELETE FROM t3 WHERE a=2; +connection master; +INSERT INTO t5 (a) SELECT a.a*10000+b.a*1000+c.a*100+d.a*10 FROM t5 a, t5 b, t5 c, t5 d; +INSERT INTO t3 (a) SELECT a FROM t5 WHERE a > 10; +DELETE t3 FROM t3 INNER JOIN t5 ON t3.a=t5.a; +connection slave; +--echo ---- Wait until slave stops with an error ---- +# Wait until the slave tries to run the query, fails with key not +# found error, and stops the SQL thread. +let $slave_sql_errno= 1032; # Can't find record +source include/wait_for_slave_sql_error.inc; +--let $err= query_get_value("SHOW SLAVE STATUS", Last_SQL_Error, 1) +--replace_regex /end_log_pos [0-9]+/end_log_pos END_LOG_POS/ +--disable_query_log +--eval SELECT "$err" as 'Last_SQL_Error (expected "Delete_rows_v1 event on table test1.t3; Can\'t find record in \'t3\'" error)' +--enable_query_log +call mtr.add_suppression("Can't find record in 't3'"); + +SET GLOBAL sql_slave_skip_counter=1; +START SLAVE; +connection master; +sync_slave_with_master; + +--echo ######################################################################## +FLUSH LOGS; + +--source include/binlog_start_pos.inc +let $start_pos= `select @binlog_start_pos`; +--replace_column 2 # 5 # +--replace_result $start_pos +--replace_regex /table_id: [0-9]+/table_id: #/ /\/\* xid=.* \*\//\/* xid= *\// +--eval show binlog events in 'slave-bin.000001' from $start_pos + +--echo # +--echo ######################################################################## +--echo # INSERTs DELAYED ON MASTERs +--echo ######################################################################## +connection master; +SET SESSION binlog_annotate_row_events = ON; +INSERT DELAYED INTO test1.t4 VALUES (1,1); +FLUSH TABLES test1.t4; +SELECT * FROM test1.t4 ORDER BY a; + +sync_slave_with_master; +connection master; +sync_slave_with_master; + +--echo ######################################################################## +--echo # ON SLAVE +--echo # No Annotate_rows events should appear below +--echo ######################################################################## +FLUSH LOGS; + +--exec $MYSQL --host=127.0.0.1 --port=$SLAVE_MYPORT test -e "show binlog events in 'slave-bin.000002'" > $MYSQLTEST_VARDIR/tmp/annotated_events.txt +perl; + open F, '<', "$ENV{MYSQLTEST_VARDIR}/tmp/annotated_events.txt" or die; + binmode STDOUT; + while (defined ($_ = )) { + if (/Annotate_rows/) { + s/[0-9]+\sAnnotate_rows\s[0-9]+\s[0-9]+/# Annotate_rows # #/; + print($_); + $_ = ; + s/[0-9]+\sTable_map\s[0-9]+\s[0-9]+\stable_id:\s[0-9]+/# Table_map # # table_id: #/; + print($_); + } + } +EOF + +# Clean-up +connection master; +--disable_query_log +DROP DATABASE test1; +sync_slave_with_master; +--enable_query_log + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/include/rpl_row_basic.test b/mysql-test/suite/rpl/include/rpl_row_basic.test new file mode 100644 index 00000000..33d5dd32 --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_row_basic.test @@ -0,0 +1,675 @@ +# +# Basic tests of row-level logging +# + +# +# First we test tables with only an index. +# + +#BUG#12662190 - COM_COMMIT IS NOT INCREMENTED FROM THE BINARY LOGS ON SLAVE, COM_BEGIN IS +#Testing command counters -BEFORE +#Storing the before counts of Slave +connection slave; +let $slave_com_commit_before= query_get_value(SHOW GLOBAL STATUS LIKE 'com_commit', Value, 1); +let $slave_com_insert_before= query_get_value(SHOW GLOBAL STATUS LIKE 'com_insert', Value, 1); +let $slave_com_delete_before= query_get_value(SHOW GLOBAL STATUS LIKE 'com_delete', Value, 1); +let $slave_com_update_before= query_get_value(SHOW GLOBAL STATUS LIKE 'com_update', Value, 1); + +connection master; +eval CREATE TABLE t1 (C1 CHAR(1), C2 CHAR(1), INDEX (C1)$extra_index_t1) ENGINE = $type ; +SELECT * FROM t1; +sync_slave_with_master; +SELECT * FROM t1; + +# Testing insert +connection master; +INSERT INTO t1 VALUES ('A','B'), ('X','Y'), ('X','X'); +INSERT INTO t1 VALUES ('A','C'), ('X','Z'), ('A','A'); +SELECT * FROM t1 ORDER BY C1,C2; +sync_slave_with_master; +SELECT * FROM t1 ORDER BY C1,C2; + +# Testing delete +# Observe that are several rows having the value for the index but only one +# should be deleted. +connection master; +DELETE FROM t1 WHERE C1 = C2; +SELECT * FROM t1 ORDER BY C1,C2; +sync_slave_with_master; +SELECT * FROM t1 ORDER BY C1,C2; + +# +# Testing update. +# Note that we have a condition on a column that is not part of the index for +# the table. The right row should be updated nevertheless. +# +connection master; +UPDATE t1 SET C2 = 'I' WHERE C1 = 'A' AND C2 = 'C'; +SELECT * FROM t1 ORDER BY C1,C2; +sync_slave_with_master; +SELECT * FROM t1 ORDER BY C1,C2; + +#BUG#12662190 - COM_COMMIT IS NOT INCREMENTED FROM THE BINARY LOGS ON SLAVE, COM_BEGIN IS +#Testing command counters -AFTER +#Storing the after counts of Slave +connection slave; +let $slave_com_commit_after= query_get_value(SHOW GLOBAL STATUS LIKE 'com_commit', Value, 1); +let $slave_com_insert_after= query_get_value(SHOW GLOBAL STATUS LIKE 'com_insert', Value, 1); +let $slave_com_delete_after= query_get_value(SHOW GLOBAL STATUS LIKE 'com_delete', Value, 1); +let $slave_com_update_after= query_get_value(SHOW GLOBAL STATUS LIKE 'com_update', Value, 1); + +#Commit count check +--let $assert_text= Counter for COM_COMMIT is consistent with the number of actual commits +--let $assert_cond= $slave_com_commit_after - $slave_com_commit_before = 4 +--source include/assert.inc +#Insert count check +--let $assert_text= Counter for COM_INSERT is consistent with the number of actual inserts +--let $assert_cond= $slave_com_insert_after - $slave_com_insert_before = 2 +--source include/assert.inc +#Delete count check +--let $assert_text= Counter for COM_DELETE is consistent with the number of actual deletes +--let $assert_cond= $slave_com_delete_after - $slave_com_delete_before = 1 +--source include/assert.inc +#Update count check +--let $assert_text= Counter for COM_UPDATE is consistent with the number of actual updates +--let $assert_cond= $slave_com_update_after - $slave_com_update_before = 1 +--source include/assert.inc + +# Testing update with a condition that does not match any rows, but +# which has a match for the index. +connection master; +UPDATE t1 SET c2 = 'Q' WHERE c1 = 'A' AND c2 = 'N'; +SELECT * FROM t1 ORDER BY c1,c2; +sync_slave_with_master; +SELECT * FROM t1 ORDER BY c1,c2; + +# +# Testing table with primary key +# +connection master; +eval CREATE TABLE t2 (c1 INT, c12 char(1), c2 INT, PRIMARY KEY (c1)) ENGINE = $type ; +INSERT INTO t2 + VALUES (1,'A',2), (2,'A',4), (3,'A',9), (4,'A',15), (5,'A',25), + (6,'A',35), (7,'A',50), (8,'A',64), (9,'A',81); +SELECT * FROM t2 ORDER BY c1,c2; +SELECT * FROM t2 WHERE c2 = c1 * c1 ORDER BY c1,c2; +sync_slave_with_master; +SELECT * FROM t2 ORDER BY c1,c2; +SELECT * FROM t2 WHERE c2 = c1 * c1 ORDER BY c1,c2; + +connection master; +UPDATE t2 SET c2 = c1*c1 WHERE c2 != c1*c1; +SELECT * FROM t2 WHERE c2 = c1 * c1 ORDER BY c1,c2; +sync_slave_with_master; +SELECT * FROM t2 WHERE c2 = c1 * c1 ORDER BY c1,c2; + +# Testing update with a condition that does not match any rows, but +# which has a match for the primary key. +connection master; +UPDATE t2 SET c12 = 'Q' WHERE c1 = 1 AND c2 = 999; +SELECT * FROM t2 ORDER BY c1,c2; +sync_slave_with_master; +SELECT * FROM t2 ORDER BY c1,c2; + +connection master; +DELETE FROM t2 WHERE c1 % 4 = 0; +SELECT * FROM t2 ORDER BY c1,c2; +sync_slave_with_master; +SELECT * FROM t2 ORDER BY c1,c2; + +connection master; +UPDATE t2 SET c12='X'; + +# +# Testing table with a multi-column primary key. +# +connection master; +eval CREATE TABLE t3 (C1 CHAR(1), C2 CHAR(1), pk1 INT, C3 CHAR(1), pk2 INT, PRIMARY KEY (pk1,pk2)) ENGINE = $type ; + +INSERT INTO t3 VALUES ('A','B',1,'B',1), ('X','Y',2,'B',1), ('X','X',3,'B',1); +INSERT INTO t3 VALUES ('A','C',1,'B',2), ('X','Z',2,'B',2), ('A','A',3,'B',2); +SELECT * FROM t3 ORDER BY C1,C2; +sync_slave_with_master; +SELECT * FROM t3 ORDER BY C1,C2; + +connection master; +DELETE FROM t3 WHERE C1 = C2; +SELECT * FROM t3 ORDER BY C1,C2; +sync_slave_with_master; +SELECT * FROM t3 ORDER BY C1,C2; + +connection master; +UPDATE t3 SET C2 = 'I' WHERE C1 = 'A' AND C2 = 'C'; +SELECT * FROM t3 ORDER BY C1,C2; +sync_slave_with_master; +SELECT * FROM t3 ORDER BY C1,C2; + +# +# Testing table without index or primary key +# +connection master; +eval CREATE TABLE t6 (C1 CHAR(1), C2 CHAR(1), C3 INT$extra_index_t6) ENGINE = $type; + +# Testing insert +INSERT INTO t6 VALUES ('A','B',1), ('X','Y',2), ('X','X',3); +INSERT INTO t6 VALUES ('A','C',4), ('X','Z',5), ('A','A',6); +SELECT * FROM t6 ORDER BY C3; +sync_slave_with_master; +SELECT * FROM t6 ORDER BY C3; + +# Testing delete +# Observe that are several rows having the value for the index but only one +# should be deleted. +connection master; +DELETE FROM t6 WHERE C1 = C2; +SELECT * FROM t6 ORDER BY C3; +sync_slave_with_master; +SELECT * FROM t6 ORDER BY C3; + +# +# Testing update. +# Note that we have a condition on a column that is not part of the index for +# the table. The right row should be updated nevertheless. +# +connection master; +UPDATE t6 SET C2 = 'I' WHERE C1 = 'A' AND C2 = 'C'; +SELECT * FROM t6 ORDER BY C3; +sync_slave_with_master; +SELECT * FROM t6 ORDER BY C3; + +# now mixing the 3 tables without begin/commit +connection master; +eval CREATE TABLE t5 (C1 CHAR(1), C2 CHAR(1), C3 INT PRIMARY KEY) ENGINE = $type ; +INSERT INTO t5 VALUES ('A','B',1), ('X','Y',2), ('X','X',3); +INSERT INTO t5 VALUES ('A','C',4), ('X','Z',5), ('A','A',6); + +UPDATE t5,t2,t3 SET t5.C2='Q', t2.c12='R', t3.C3 ='S' WHERE t5.C1 = t2.c12 AND t5.C1 = t3.C1; +SELECT * FROM t5,t2,t3 WHERE t5.C2='Q' AND t2.c12='R' AND t3.C3 ='S' ORDER BY t5.C3,t2.c1,t3.pk1,t3.pk2; +sync_slave_with_master; +SELECT * FROM t5,t2,t3 WHERE t5.C2='Q' AND t2.c12='R' AND t3.C3 ='S' ORDER BY t5.C3,t2.c1,t3.pk1,t3.pk2; + +# +# Testing special column types +# + +if (`select char_length('$bit_field_special') > 0`) { + connection slave; + SET @saved_slave_type_conversions = @@SLAVE_TYPE_CONVERSIONS; + eval SET GLOBAL SLAVE_TYPE_CONVERSIONS = '$bit_field_special'; +} + +connection master; +eval CREATE TABLE t4 (C1 CHAR(1) PRIMARY KEY, B1 BIT(1), B2 BIT(1) NOT NULL DEFAULT 0, C2 CHAR(1) NOT NULL DEFAULT 'A') ENGINE = $type ; + +INSERT INTO t4 SET C1 = 1; +SELECT C1,HEX(B1),HEX(B2) FROM t4 ORDER BY C1; +sync_slave_with_master; +SELECT C1,HEX(B1),HEX(B2) FROM t4 ORDER BY C1; + +if (`select char_length('$bit_field_special') > 0`) { + SET GLOBAL SLAVE_TYPE_CONVERSIONS = @saved_slave_type_conversions; +} + +# +# Testing conflicting operations +# +connection master; +eval CREATE TABLE t7 (C1 INT PRIMARY KEY, C2 INT) ENGINE = $type ; +sync_slave_with_master; +--echo --- original values --- +INSERT INTO t7 VALUES (1,3), (2,6), (3,9); +SELECT * FROM t7 ORDER BY C1; + +# since bug#31552/31609 idempotency is not default any longer. In order +# the preceding test INSERT INTO t7 to pass the mode is switched +# temprorarily +set @@global.slave_exec_mode= 'IDEMPOTENT'; + +connection master; +--echo --- new values inserted --- +INSERT INTO t7 VALUES (1,2), (2,4), (3,6); +SELECT * FROM t7 ORDER BY C1; +sync_slave_with_master; + +set @@global.slave_exec_mode= default; +--echo --- old values should be overwritten by replicated values --- +SELECT * FROM t7 ORDER BY C1; + +# +# A more complicated test where the table has several keys and we are +# causing a conflict for a key that is not "last". +# +connection master; +eval CREATE TABLE t8 (a INT PRIMARY KEY, b INT UNIQUE, c INT UNIQUE) ENGINE = $type ; + +# First we make sure that the constraints are correctly set. +INSERT INTO t8 VALUES (99,99,99); +--error ER_DUP_ENTRY +INSERT INTO t8 VALUES (99,22,33); +--error ER_DUP_ENTRY +INSERT INTO t8 VALUES (11,99,33); +--error ER_DUP_ENTRY +INSERT INTO t8 VALUES (11,22,99); +SELECT * FROM t8 ORDER BY a; + +sync_slave_with_master; +SELECT * FROM t8 ORDER BY a; +INSERT INTO t8 VALUES (1,2,3), (2,4,6), (3,6,9); +SELECT * FROM t8 ORDER BY a; + +# since bug#31552/31609 idempotency is not default any longer. In order +# the preceding test INSERT INTO t8 to pass the mode is switched +# temprorarily +set @@global.slave_exec_mode= 'IDEMPOTENT'; + +connection master; +# We insert a row that will cause conflict on the primary key but not +# on the other keys. +INSERT INTO t8 VALUES (2,4,8); +sync_slave_with_master; +set @@global.slave_exec_mode= default; + +SELECT * FROM t8 ORDER BY a; + +# BUG#31552: Replication breaks when deleting rows from out-of-sync +# table without PK + +--echo **** Test for BUG#31552 **** + +# Clean up t1 so that we can use it. +connection master; +DELETE FROM t1; +sync_slave_with_master; + +# Just to get a clean binary log +--source include/rpl_reset.inc + +connection master; +INSERT INTO t1 VALUES ('K','K'), ('L','L'), ('M','M'); +sync_slave_with_master; +# since bug#31552/31609 idempotency is not default any longer. In order +# the following test DELETE FROM t1 to pass the mode is switched +# temprorarily +set @@global.slave_exec_mode= 'IDEMPOTENT'; +DELETE FROM t1 WHERE C1 = 'L'; + +connection master; +DELETE FROM t1; +query_vertical SELECT COUNT(*) FROM t1 ORDER BY c1,c2; +sync_slave_with_master; +set @@global.slave_exec_mode= default; +source include/check_slave_is_running.inc; +query_vertical SELECT COUNT(*) FROM t1 ORDER BY c1,c2; + +# BUG#37076: TIMESTAMP/DATETIME values are not replicated correctly +# between machines with mixed endiannes +# (regression test) + +--echo **** Test for BUG#37076 **** +connection master; +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 (a TIMESTAMP, b DATETIME, c DATE); +INSERT INTO t1 VALUES( + '2005-11-14 01:01:01', '2005-11-14 01:01:02', '2005-11-14'); + +sync_slave_with_master slave; +SELECT * FROM t1; + +# +# cleanup +# + +connection master; +DROP TABLE IF EXISTS t1,t2,t3,t4,t5,t6,t7,t8; +sync_slave_with_master; + +# +# BUG#37426: RBR breaks for CHAR() UTF8 fields > 85 chars +# + +# We have 4 combinations to test with respect to the field length +# (i.e., the number of bytes) of the CHAR fields: +# +# 1. Replicating from CHAR<256 to CHAR<256 +# 2. Replicating from CHAR<256 to CHAR>255 +# 3. Replicating from CHAR>255 to CHAR<256 +# 4. Replicating from CHAR>255 to CHAR>255 + +# We also make a special case of using the max size of a field on the +# master, i.e. CHAR(255) in UTF-8, giving another three cases. +# +# 5. Replicating UTF-8 CHAR(255) to CHAR(<256) +# 6. Replicating UTF-8 CHAR(255) to CHAR(>255) +# 7. Replicating UTF-8 CHAR(255) to CHAR(255) UTF-8 + +connection master; +eval CREATE TABLE t1 (i INT NOT NULL, + c CHAR(16) CHARACTER SET utf8 NOT NULL, + j INT NOT NULL) ENGINE = $type ; + +eval CREATE TABLE t2 (i INT NOT NULL, + c CHAR(16) CHARACTER SET utf8 NOT NULL, + j INT NOT NULL) ENGINE = $type ; + +sync_slave_with_master; +ALTER TABLE t2 MODIFY c CHAR(128) CHARACTER SET utf8 NOT NULL; + +connection master; +eval CREATE TABLE t3 (i INT NOT NULL, + c CHAR(128) CHARACTER SET utf8 NOT NULL, + j INT NOT NULL) ENGINE = $type ; +sync_slave_with_master; +ALTER TABLE t3 MODIFY c CHAR(16) CHARACTER SET utf8 NOT NULL; + +connection master; +eval CREATE TABLE t4 (i INT NOT NULL, + c CHAR(128) CHARACTER SET utf8 NOT NULL, + j INT NOT NULL) ENGINE = $type ; + +eval CREATE TABLE t5 (i INT NOT NULL, + c CHAR(255) CHARACTER SET utf8 NOT NULL, + j INT NOT NULL) ENGINE = $type ; +sync_slave_with_master; +ALTER TABLE t5 MODIFY c CHAR(16) CHARACTER SET utf8 NOT NULL; + +connection master; +eval CREATE TABLE t6 (i INT NOT NULL, + c CHAR(255) CHARACTER SET utf8 NOT NULL, + j INT NOT NULL) ENGINE = $type ; +sync_slave_with_master; +ALTER TABLE t6 MODIFY c CHAR(128) CHARACTER SET utf8 NOT NULL; + +connection master; +eval CREATE TABLE t7 (i INT NOT NULL, + c CHAR(255) CHARACTER SET utf8 NOT NULL, + j INT NOT NULL) ENGINE = $type ; + +connection slave; +SET @saved_slave_type_conversions = @@slave_type_conversions; +SET GLOBAL SLAVE_TYPE_CONVERSIONS = 'ALL_NON_LOSSY'; + +--echo [expecting slave to replicate correctly] +connection master; +INSERT INTO t1 VALUES (1, "", 1); +INSERT INTO t1 VALUES (2, repeat(_utf8'a', 16), 2); +sync_slave_with_master; + +let $diff_tables= master:t1, slave:t1; +source include/diff_tables.inc; + +--echo [expecting slave to replicate correctly] +connection master; +INSERT INTO t2 VALUES (1, "", 1); +INSERT INTO t2 VALUES (2, repeat(_utf8'a', 16), 2); +sync_slave_with_master; + +let $diff_tables= master:t2, slave:t2; +source include/diff_tables.inc; + +connection slave; +SET GLOBAL SLAVE_TYPE_CONVERSIONS = @saved_slave_type_conversions; +call mtr.add_suppression("Slave SQL.*Table definition on master and slave does not match: Column 1 size mismatch.* error.* 1535"); +call mtr.add_suppression("Slave SQL.*Could not execute Delete_rows event on table test.t1.* error.* 1032"); +call mtr.add_suppression("Slave SQL.*Column 1 of table .test.t.. cannot be converted from type.*, error.* 1677"); +call mtr.add_suppression("Can't find record in 't1'"); + +--let $rpl_only_running_threads= 1 +--source include/rpl_reset.inc + +--echo [expecting slave to replicate correctly] +connection master; +INSERT INTO t4 VALUES (1, "", 1); +INSERT INTO t4 VALUES (2, repeat(_utf8'a', 128), 2); +sync_slave_with_master; + +let $diff_tables= master:t4, slave:t4; +source include/diff_tables.inc; + +--echo [expecting slave to stop] +connection master; +INSERT INTO t5 VALUES (1, "", 1); +INSERT INTO t5 VALUES (2, repeat(_utf8'a', 255), 2); + +connection slave; +# 1677 = ER_SLAVE_CONVERSION_FAILED +--let $slave_sql_errno= 1677 +--let $show_slave_sql_error= 1 +--source include/wait_for_slave_sql_error.inc + +--source include/rpl_reset.inc + +--echo [expecting slave to stop] +connection master; +INSERT INTO t6 VALUES (1, "", 1); +INSERT INTO t6 VALUES (2, repeat(_utf8'a', 255), 2); + +connection slave; +# 1677 = ER_SLAVE_CONVERSION_FAILED +--let $slave_sql_errno= 1677 +--let $show_slave_sql_error= 1 +--source include/wait_for_slave_sql_error.inc + +--source include/rpl_reset.inc + +--echo [expecting slave to replicate correctly] +connection master; +INSERT INTO t7 VALUES (1, "", 1); +INSERT INTO t7 VALUES (2, repeat(_utf8'a', 255), 2); +sync_slave_with_master; + +let $diff_tables= master:t7, slave:t7; +source include/diff_tables.inc; + +connection master; +drop table t1, t2, t3, t4, t5, t6, t7; +sync_slave_with_master; + +# +# BUG#32709: Assertion failed: trx_data->empty(), file .\log.cc, line 1293 +# + +connection master; +eval CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=$type; + +INSERT INTO t1 VALUES (1), (2), (3); +--error ER_DUP_ENTRY +UPDATE t1 SET a = 10; +INSERT INTO t1 VALUES (4); +sync_slave_with_master; + +let $diff_tables= master:t1, slave:t1; +source include/diff_tables.inc; + +connection master; +drop table t1; +sync_slave_with_master; + +# +# Bug #38230 Differences between master and slave after +# UPDATE or DELETE with LIMIT with pk +# +# the regression test verifies consistency via selecting + +--disable_abort_on_error + +--connection master + +--disable_warnings +DROP TABLE IF EXISTS t1, t2; +--enable_warnings + +eval CREATE TABLE t1 ( + `pk` int(11) NOT NULL AUTO_INCREMENT, + `int_nokey` int(11) NOT NULL, + `int_key` int(11) NOT NULL, + `date_key` date NOT NULL, + `date_nokey` date NOT NULL, + `time_key` time NOT NULL, + `time_nokey` time NOT NULL, + `datetime_key` datetime NOT NULL, + `datetime_nokey` datetime NOT NULL, + `varchar_key` varchar(1) NOT NULL, + `varchar_nokey` varchar(1) NOT NULL, + PRIMARY KEY (`pk`), + KEY `int_key` (`int_key`), + KEY `date_key` (`date_key`), + KEY `time_key` (`time_key`), + KEY `datetime_key` (`datetime_key`), + KEY `varchar_key` (`varchar_key`) +) ENGINE=$type; + +INSERT INTO t1 VALUES (1,8,5,'0000-00-00','0000-00-00','10:37:38','10:37:38','0000-00-00 00:00:00','0000-00-00 00:00:00','p','p'),(2,0,9,'0000-00-00','0000-00-00','00:00:00','00:00:00','2007-10-14 00:00:00','2007-10-14 00:00:00','d','d'); + +eval CREATE TABLE t2 ( + `pk` int(11) NOT NULL AUTO_INCREMENT, + `int_nokey` int(11) NOT NULL, + `int_key` int(11) NOT NULL, + `date_key` date NOT NULL, + `date_nokey` date NOT NULL, + `time_key` time NOT NULL, + `time_nokey` time NOT NULL, + `datetime_key` datetime NOT NULL, + `datetime_nokey` datetime NOT NULL, + `varchar_key` varchar(1) NOT NULL, + `varchar_nokey` varchar(1) NOT NULL, + PRIMARY KEY (`pk`), + KEY `int_key` (`int_key`), + KEY `date_key` (`date_key`), + KEY `time_key` (`time_key`), + KEY `datetime_key` (`datetime_key`), + KEY `varchar_key` (`varchar_key`) +) ENGINE=$type; + +INSERT INTO t2 VALUES (1,1,6,'2005-12-23','2005-12-23','02:24:28','02:24:28','0000-00-00 00:00:00','0000-00-00 00:00:00','g','g'),(2,0,3,'2009-09-14','2009-09-14','00:00:00','00:00:00','2000-01-30 16:39:40','2000-01-30 16:39:40','q','q'),(3,0,3,'0000-00-00','0000-00-00','00:00:00','00:00:00','0000-00-00 00:00:00','0000-00-00 00:00:00','c','c'),(4,1,6,'2007-03-29','2007-03-29','15:49:00','15:49:00','0000-00-00 00:00:00','0000-00-00 00:00:00','m','m'),(5,4,0,'2002-12-04','2002-12-04','00:00:00','00:00:00','0000-00-00 00:00:00','0000-00-00 00:00:00','o','o'),(6,9,0,'2005-01-28','2005-01-28','00:00:00','00:00:00','2001-05-18 00:00:00','2001-05-18 00:00:00','w','w'),(7,6,0,'0000-00-00','0000-00-00','06:57:25','06:57:25','0000-00-00 00:00:00','0000-00-00 00:00:00','m','m'),(8,0,0,'0000-00-00','0000-00-00','00:00:00','00:00:00','0000-00-00 00:00:00','0000-00-00 00:00:00','z','z'),(9,4,6,'2006-08-15','2006-08-15','00:00:00','00:00:00','2002-04-12 14:44:25','2002-04-12 14:44:25','j','j'),(10,0,5,'2006-12-20','2006-12-20','10:13:53','10:13:53','2008-07-22 00:00:00','2008-07-22 00:00:00','y','y'),(11,9,7,'0000-00-00','0000-00-00','00:00:00','00:00:00','2004-07-05 00:00:00','2004-07-05 00:00:00','{','{'),(12,4,3,'2007-01-26','2007-01-26','23:00:51','23:00:51','2001-05-16 00:00:00','2001-05-16 00:00:00','f','f'),(13,7,0,'2004-03-27','2004-03-27','00:00:00','00:00:00','2005-01-24 03:30:37','2005-01-24 03:30:37','',''),(14,6,0,'2006-07-26','2006-07-26','18:43:57','18:43:57','0000-00-00 00:00:00','0000-00-00 00:00:00','{','{'),(15,0,6,'2000-01-14','2000-01-14','00:00:00','00:00:00','2000-09-21 00:00:00','2000-09-21 00:00:00','o','o'),(16,9,8,'0000-00-00','0000-00-00','21:15:08','21:15:08','0000-00-00 00:00:00','0000-00-00 00:00:00','a','a'),(17,2,0,'2004-10-27','2004-10-27','00:00:00','00:00:00','2004-03-24 22:13:43','2004-03-24 22:13:43','',''),(18,7,4,'0000-00-00','0000-00-00','08:38:27','08:38:27','2002-03-18 19:51:44','2002-03-18 19:51:44','t','t'),(19,5,3,'2008-03-07','2008-03-07','03:29:07','03:29:07','2007-12-01 18:44:44','2007-12-01 18:44:44','t','t'),(20,0,0,'2002-04-09','2002-04-09','16:06:03','16:06:03','2009-04-22 00:00:00','2009-04-22 00:00:00','n','n'); + +DELETE FROM t2 WHERE `int_key` < 3 LIMIT 1; +UPDATE t1 SET `int_key` = 3 ORDER BY `pk` LIMIT 4; +DELETE FROM t2 WHERE `int_key` < 3 LIMIT 1; +DELETE FROM t2 WHERE `pk` < 6 LIMIT 1; +UPDATE t1 SET `int_key` = 6 ORDER BY `pk` LIMIT 3; +DELETE FROM t2 WHERE `pk` < 6 LIMIT 1; +UPDATE t1 SET `pk` = 6 ORDER BY `int_key` LIMIT 6; +DELETE FROM t2 WHERE `pk` < 7 LIMIT 1; +UPDATE t1 SET `int_key` = 4 ORDER BY `pk` LIMIT 6; + +--sync_slave_with_master +--echo *** results: t2 must be consistent **** + +let $diff_tables= master:t2, slave:t2; +source include/diff_tables.inc; + +--connection master +DROP TABLE t1, t2; + +--enable_abort_on_error + +--echo EOF OF TESTS + +# +# BUG#40004: Replication failure with no PK + no indexes +# + +# The test cases are taken from the bug report. It is difficult to +# produce a test case that generates a HA_ERR_RECORD_DELETED, so we go +# with the test cases we have. + +connection master; + +eval CREATE TABLE t1 (a int) ENGINE=$type; + +INSERT IGNORE INTO t1 VALUES (NULL); +INSERT INTO t1 ( a ) VALUES ( 0 ); +INSERT INTO t1 ( a ) VALUES ( 9 ); +INSERT INTO t1 ( a ) VALUES ( 2 ); +INSERT INTO t1 ( a ) VALUES ( 9 ); +INSERT INTO t1 ( a ) VALUES ( 5 ); + +UPDATE t1 SET a = 5 WHERE a = 9; +DELETE FROM t1 WHERE a < 6; +UPDATE t1 SET a = 9 WHERE a < 3; +INSERT INTO t1 ( a ) VALUES ( 3 ); +UPDATE t1 SET a = 0 WHERE a < 4; +UPDATE t1 SET a = 8 WHERE a < 5; + +sync_slave_with_master; + +let $diff_tables= master:t1, slave:t1; +source include/diff_tables.inc; + +connection master; +drop table t1; +sync_slave_with_master; + +# +# Bug #39752: Replication failure on RBR + MyISAM + no PK +# + +# The test cases are taken from the bug report. It is difficult to +# produce a test case that generates a HA_ERR_RECORD_DELETED, so we go +# with the test cases we have. + +connection master; + +# Since t1 contain a bit field, we have to do this trick to handle InnoDB +if (`select char_length('$bit_field_special') > 0`) { + connection slave; + SET @saved_slave_type_conversions = @@SLAVE_TYPE_CONVERSIONS; + eval SET GLOBAL SLAVE_TYPE_CONVERSIONS = '$bit_field_special'; +} + +--disable_warnings +connection master; +eval CREATE TABLE t1 (a bit) ENGINE=$type; +INSERT IGNORE INTO t1 VALUES (NULL); +INSERT INTO t1 ( a ) VALUES ( 0 ); +UPDATE t1 SET a = 0 WHERE a = 1 LIMIT 3; +INSERT IGNORE INTO t1 ( a ) VALUES ( 5 ); +DELETE FROM t1 WHERE a < 2 LIMIT 4; +DELETE FROM t1 WHERE a < 9 LIMIT 4; +INSERT IGNORE INTO t1 ( a ) VALUES ( 9 ); +UPDATE t1 SET a = 8 WHERE a = 0 LIMIT 6; +INSERT IGNORE INTO t1 ( a ) VALUES ( 8 ); +UPDATE t1 SET a = 0 WHERE a < 6 LIMIT 0; +INSERT IGNORE INTO t1 ( a ) VALUES ( 4 ); +INSERT IGNORE INTO t1 ( a ) VALUES ( 3 ); +UPDATE t1 SET a = 0 WHERE a = 7 LIMIT 6; +DELETE FROM t1 WHERE a = 4 LIMIT 7; +UPDATE IGNORE t1 SET a = 9 WHERE a < 2 LIMIT 9; +UPDATE t1 SET a = 0 WHERE a < 9 LIMIT 2; +DELETE FROM t1 WHERE a < 0 LIMIT 5; +INSERT IGNORE INTO t1 ( a ) VALUES ( 5 ); +UPDATE IGNORE t1 SET a = 4 WHERE a < 6 LIMIT 4; +INSERT IGNORE INTO t1 ( a ) VALUES ( 5 ); +UPDATE IGNORE t1 SET a = 9 WHERE a < 5 LIMIT 8; +DELETE FROM t1 WHERE a < 8 LIMIT 8; +INSERT IGNORE INTO t1 ( a ) VALUES ( 6 ); +DELETE FROM t1 WHERE a < 6 LIMIT 7; +UPDATE t1 SET a = 7 WHERE a = 3 LIMIT 7; +UPDATE t1 SET a = 8 WHERE a = 0 LIMIT 6; +INSERT IGNORE INTO t1 ( a ) VALUES ( 7 ); +DELETE FROM t1 WHERE a < 9 LIMIT 4; +INSERT IGNORE INTO t1 ( a ) VALUES ( 7 ); +INSERT IGNORE INTO t1 ( a ) VALUES ( 6 ); +UPDATE t1 SET a = 8 WHERE a = 3 LIMIT 4; +DELETE FROM t1 WHERE a = 2 LIMIT 9; +DELETE FROM t1 WHERE a = 1 LIMIT 4; +UPDATE t1 SET a = 4 WHERE a = 2 LIMIT 7; +INSERT INTO t1 ( a ) VALUES ( 0 ); +DELETE FROM t1 WHERE a < 3 LIMIT 0; +UPDATE t1 SET a = 8 WHERE a = 5 LIMIT 2; +INSERT INTO t1 ( a ) VALUES ( 1 ); +UPDATE IGNORE t1 SET a = 9 WHERE a < 5 LIMIT 3; +--enable_warnings + +sync_slave_with_master; + +if (`select char_length('$bit_field_special') > 0`) { + SET GLOBAL SLAVE_TYPE_CONVERSIONS = @saved_slave_type_conversions; +} + +let $diff_tables= master:t1, slave:t1; +source include/diff_tables.inc; + +connection master; +drop table t1; +sync_slave_with_master; diff --git a/mysql-test/suite/rpl/include/rpl_row_blob.test b/mysql-test/suite/rpl/include/rpl_row_blob.test new file mode 100644 index 00000000..5cd7b6b4 --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_row_blob.test @@ -0,0 +1,175 @@ +################################################# +# Author: JBM +# Date: 2006-01-06 +# Purpose: Test test that BLOBs are replicated +# correctly. +################################################ + +# Pre test clean up section +connection master; +--disable_warnings +DROP TABLE IF EXISTS test.t1; +DROP TABLE IF EXISTS test.t2; +--enable_warnings + +# Start test section +--echo ***** Table Create Section **** +--echo +--disable_warnings +--replace_result $engine_type # +eval CREATE TABLE test.t1 (c1 int not null auto_increment, +data LONGBLOB, PRIMARY KEY(c1))ENGINE=$engine_type; +--enable_warnings +--echo +--echo **** Data Insert Section test.t1 ***** +--echo +INSERT INTO test.t1 VALUES (NULL, NULL); +INSERT INTO test.t1 VALUES (NULL, repeat('a',1*1024)); +INSERT INTO test.t1 VALUES (NULL, repeat('b',16*1024)); +--echo + +--echo **** Data Insert Validation Master Section test.t1 **** +--echo +SELECT LENGTH(data) FROM test.t1 WHERE c1 = 1; +SELECT LENGTH(data) FROM test.t1 WHERE c1 = 2; +SELECT LENGTH(data) FROM test.t1 WHERE c1 = 3; +save_master_pos; +connection slave; +sync_with_master; +--echo +--echo **** Data Insert Validation Slave Section test.t1 **** +--echo +SELECT LENGTH(data) FROM test.t1 WHERE c1 = 1; +SELECT LENGTH(data) FROM test.t1 WHERE c1 = 2; +SELECT LENGTH(data) FROM test.t1 WHERE c1 = 3; +connection master; +--echo + +--echo **** Data Update Section test.t1 **** +--echo +UPDATE test.t1 set data=repeat('a',18*1024) where c1 = 1; +UPDATE t1 set data=repeat('c',17*1024) where c1 = 2; +--echo + +--echo **** Data Update Validation Master Section test.t1 **** +--echo +SELECT LENGTH(data) FROM test.t1 WHERE c1 = 1; +SELECT LENGTH(data) FROM test.t1 WHERE c1 = 2; +save_master_pos; +connection slave; +sync_with_master; +--echo +--echo **** Data Update Validation Slave Section test.t1 **** +--echo +SELECT LENGTH(data) FROM test.t1 WHERE c1 = 1; +SELECT LENGTH(data) FROM test.t1 WHERE c1 = 2; +connection master; +--echo +--echo **** End Test Section test.t1 **** +--echo + +--echo **** Create Table test.t2 **** +--echo +--disable_warnings +--replace_result $engine_type # +eval CREATE TABLE test.t2 ( + c1 INT NOT NULL PRIMARY KEY, + c2 TEXT, + c3 INT, + c4 LONGBLOB, + KEY(c3))ENGINE=$engine_type; +--enable_warnings +--echo + +--echo *** Setup Values For test.t2 *** +# x0 size 256 (current inline size) +set @x0 = '01234567012345670123456701234567'; +set @x0 = concat(@x0,@x0,@x0,@x0,@x0,@x0,@x0,@x0); + +# b1 length 2000+256 (blob part aligned) +set @b1 = 'b1'; +set @b1 = concat(@b1,@b1,@b1,@b1,@b1,@b1,@b1,@b1,@b1,@b1); +set @b1 = concat(@b1,@b1,@b1,@b1,@b1,@b1,@b1,@b1,@b1,@b1); +set @b1 = concat(@b1,@b1,@b1,@b1,@b1,@b1,@b1,@b1,@b1,@b1); +set @b1 = concat(@b1,@x0); +# d1 length 3000 +set @d1 = 'dd1'; +set @d1 = concat(@d1,@d1,@d1,@d1,@d1,@d1,@d1,@d1,@d1,@d1); +set @d1 = concat(@d1,@d1,@d1,@d1,@d1,@d1,@d1,@d1,@d1,@d1); +set @d1 = concat(@d1,@d1,@d1,@d1,@d1,@d1,@d1,@d1,@d1,@d1); + +# b2 length 20000 +set @b2 = 'b2'; +set @b2 = concat(@b2,@b2,@b2,@b2,@b2,@b2,@b2,@b2,@b2,@b2); +set @b2 = concat(@b2,@b2,@b2,@b2,@b2,@b2,@b2,@b2,@b2,@b2); +set @b2 = concat(@b2,@b2,@b2,@b2,@b2,@b2,@b2,@b2,@b2,@b2); +set @b2 = concat(@b2,@b2,@b2,@b2,@b2,@b2,@b2,@b2,@b2,@b2); + +# d2 length 30000 +set @d2 = 'dd2'; +set @d2 = concat(@d2,@d2,@d2,@d2,@d2,@d2,@d2,@d2,@d2,@d2); +set @d2 = concat(@d2,@d2,@d2,@d2,@d2,@d2,@d2,@d2,@d2,@d2); +set @d2 = concat(@d2,@d2,@d2,@d2,@d2,@d2,@d2,@d2,@d2,@d2); +set @d2 = concat(@d2,@d2,@d2,@d2,@d2,@d2,@d2,@d2,@d2,@d2); +--echo + +--echo **** Data Insert Section test.t2 ***** +--echo +INSERT INTO test.t2 VALUES(1,@b1,111,@d1); +INSERT INTO test.t2 VALUES(2,@b2,222,@d2); +--echo + +--echo **** Data Insert Validation Master Section test.t2 **** +--echo +SELECT c1, LENGTH(c2), SUBSTR(c2,1+2*900,2), LENGTH(c4), SUBSTR(c4,1+3*900,3) +FROM test.t2 WHERE c1=1; +SELECT c1, LENGTH(c2), SUBSTR(c2,1+2*900,2), LENGTH(c4), SUBSTR(c4,1+3*900,3) +FROM test.t2 WHERE c1=2; +save_master_pos; +connection slave; +sync_with_master; +--echo +--echo **** Data Insert Validation Slave Section test.t2 **** +--echo +SELECT c1, LENGTH(c2), SUBSTR(c2,1+2*900,2), LENGTH(c4), SUBSTR(c4,1+3*900,3) +FROM test.t2 WHERE c1=1; +SELECT c1, LENGTH(c2), SUBSTR(c2,1+2*900,2), LENGTH(c4), SUBSTR(c4,1+3*900,3) +FROM test.t2 WHERE c1=2; +connection master; +--echo + +--echo **** Data Update Section test.t2 **** +--echo +UPDATE test.t2 SET c2=@b2, c4=@d2 WHERE c1=1; +UPDATE test.t2 SET c2=@b1, c4=@d1 WHERE c1=2; +--echo + +--echo **** Data Update Validation Master Section test.t2 **** +--echo +SELECT c1, LENGTH(c2), SUBSTR(c2,1+2*900,2), LENGTH(c4), SUBSTR(c4,1+3*900,3) +FROM test.t2 WHERE c1=1; +SELECT c1, LENGTH(c2), SUBSTR(c2,1+2*900,2), LENGTH(c4), SUBSTR(c4,1+3*900,3) +FROM test.t2 WHERE c1=2; +save_master_pos; +connection slave; +sync_with_master; +--echo +--echo **** Data Update Validation Slave Section test.t2 **** +--echo +SELECT c1, LENGTH(c2), SUBSTR(c2,1+2*900,2), LENGTH(c4), SUBSTR(c4,1+3*900,3) +FROM test.t2 WHERE c1=1; +SELECT c1, LENGTH(c2), SUBSTR(c2,1+2*900,2), LENGTH(c4), SUBSTR(c4,1+3*900,3) +FROM test.t2 WHERE c1=2; +connection master; +--echo + +# Post test clean up section +--exec $MYSQL_DUMP --compact --order-by-primary --skip-extended-insert --no-create-info test > $MYSQLTEST_VARDIR/tmp/rpl_row_blob_master.sql +--exec $MYSQL_DUMP_SLAVE --compact --order-by-primary --skip-extended-insert --no-create-info test > $MYSQLTEST_VARDIR/tmp/rpl_row_blob_slave.sql + +diff_files $MYSQLTEST_VARDIR/tmp/rpl_row_blob_master.sql $MYSQLTEST_VARDIR/tmp/rpl_row_blob_slave.sql; + +DROP TABLE IF EXISTS test.t1; +DROP TABLE IF EXISTS test.t2; +# ensure cleanup on slave as well: +--sync_slave_with_master diff --git a/mysql-test/suite/rpl/include/rpl_row_delayed_ins.test b/mysql-test/suite/rpl/include/rpl_row_delayed_ins.test new file mode 100644 index 00000000..03c7b528 --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_row_delayed_ins.test @@ -0,0 +1,21 @@ +# See if INSERT DELAYED gets replicated +# Only in row-based, as we do SHOW BINLOG EVENTS + +-- source include/have_binlog_format_row.inc +-- source include/master-slave.inc + +connection master; +let $VERSION=`select version()`; +eval create table t1(a int not null primary key) engine=$engine_type; +insert delayed into t1 values (1); +insert delayed into t1 values (2); +insert delayed into t1 values (3); +flush tables t1; +SELECT * FROM t1 ORDER BY a; +sync_slave_with_master; + +SELECT * FROM t1 ORDER BY a; +connection master; +drop table t1; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/include/rpl_row_func003.test b/mysql-test/suite/rpl/include/rpl_row_func003.test new file mode 100644 index 00000000..f46f9edd --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_row_func003.test @@ -0,0 +1,81 @@ +############################################################################# +# Original Author: JBM # +# Original Date: Aug/15/2005 # +# Update: 08/29/2005 Comment out sleep. Only needed for debugging # +############################################################################# +# Note: Time changes and is not deteministic, so instead we dump both the # +# master and slave and diff the dumps. If the dumps differ then the # +# test case will fail. To run during diff failuers, comment out the # +# diff. # +# Test: Tests MySQL stored function using RAND() and a flow control. The # +# test inserts rows into a givin table with the function used in # +# the insert statement. Depending on the RAND() value returned # +# inside the function one set of text is returned. In addition, # +# it uses a transaction to see the effect a rollback has on master # +# Vs slave. # +############################################################################# + +CALL mtr.add_suppression('Statement may not be safe to log in statement format.'); + +# Begin clean up test section +connection master; +--disable_warnings +DROP FUNCTION IF EXISTS test.f1; +DROP TABLE IF EXISTS test.t1; + +--enable_warnings + +eval CREATE TABLE test.t1 (a INT NOT NULL AUTO_INCREMENT, c CHAR(16),PRIMARY KEY(a))ENGINE=$engine_type; + +delimiter |; +create function test.f1() RETURNS CHAR(16) +BEGIN + DECLARE tmp CHAR(16); + DECLARE var_name FLOAT; + SET var_name = RAND(); + IF var_name > .6 + THEN SET tmp = 'Texas'; + ELSE SET tmp = 'MySQL'; + END IF; +RETURN tmp; +END| +delimiter ;| + +--disable_warnings +INSERT INTO test.t1 VALUES (null,test.f1()),(null,test.f1()),(null,test.f1()); +INSERT INTO test.t1 VALUES (null,test.f1()),(null,test.f1()),(null,test.f1()); +--enable_warnings + +SET AUTOCOMMIT=0; +START TRANSACTION; +--disable_warnings +INSERT INTO test.t1 VALUES (null,test.f1()); +--enable_warnings +ROLLBACK; +SET AUTOCOMMIT=1; + + sync_slave_with_master; + connection master; + +# Time to dump the databases and so we can see if they match + +--exec $MYSQL_DUMP --compact --order-by-primary --skip-extended-insert --no-create-info test > $MYSQLTEST_VARDIR/tmp/func003_master.sql +--exec $MYSQL_DUMP_SLAVE --compact --order-by-primary --skip-extended-insert --no-create-info test > $MYSQLTEST_VARDIR/tmp/func003_slave.sql + +# First lets cleanup +DROP FUNCTION test.f1; +DROP TABLE test.t1; + + +# the test will show that the diff statement failed and no reject file +# will be created. You will need to go to the mysql-test dir and diff +# the files yourself to see what is not matching :-) File are located +# in $MYSQLTEST_VARDIR/tmp + +diff_files $MYSQLTEST_VARDIR/tmp/func003_master.sql $MYSQLTEST_VARDIR/tmp/func003_slave.sql; + +# Clean up +remove_file $MYSQLTEST_VARDIR/tmp/func003_master.sql; +remove_file $MYSQLTEST_VARDIR/tmp/func003_slave.sql; + +# End of 5.0 test case diff --git a/mysql-test/suite/rpl/include/rpl_row_img.test b/mysql-test/suite/rpl/include/rpl_row_img.test new file mode 100644 index 00000000..9cf2b6f9 --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_row_img.test @@ -0,0 +1,241 @@ +# WL#5096 +# +# Description +# =========== +# +# This test case checks replication between hosts with same index +# structure but may differ on engines. +# +# Usage +# ===== +# +# Before including this file the following variables should be set: +# * $server_1_engine +# * $server_2_engine +# * $server_3_engine +# +# Example: +# +# -- let $server_1_engine= Falcon +# -- let $server_2_engine= MyISAM +# -- let $server_3_engine= InnoDB +# +# -- source suite/rpl/include/rpl_row_img.test +# + +-- connection server_1 + +-- let $diff_table=test.t + +let $i= 12; +while($i) +{ + let $step= ""; + + -- connection server_1 + SET SQL_LOG_BIN=0; + + -- connection server_2 + SET SQL_LOG_BIN=0; + + -- connection server_3 + SET SQL_LOG_BIN=0; + + if ($i == 1) { + let $step= No keys; + --echo ******* TEST: $step + -- connection server_1 + --eval CREATE TABLE t (c1 int, c2 char(1), c3 char(1), c4 char(1)) engine= $server_1_engine; + -- connection server_2 + --eval CREATE TABLE t (c1 int, c2 char(1), c3 char(1), c4 char(1)) engine= $server_2_engine; + -- connection server_3 + --eval CREATE TABLE t (c1 int, c2 char(1), c3 char(1), c4 char(1)) engine= $server_3_engine; + + } + if ($i == 2) + { + let $step= One key; + --echo ******* TEST: $step + -- connection server_1 + --eval CREATE TABLE t (c1 int, c2 char(1), c3 char(1), c4 char(1), key(c1)) engine= $server_1_engine; + -- connection server_2 + --eval CREATE TABLE t (c1 int, c2 char(1), c3 char(1), c4 char(1), key(c1)) engine= $server_2_engine; + -- connection server_3 + --eval CREATE TABLE t (c1 int, c2 char(1), c3 char(1), c4 char(1), key(c1)) engine= $server_3_engine; + + } + if ($i == 3) + { + let $step= One Composite key; + --echo ****** TEST: $step + -- connection server_1 + --eval CREATE TABLE t (c1 int, c2 char(1), c3 char(1), c4 char(1), key(c1,c2)) engine= $server_1_engine; + -- connection server_2 + --eval CREATE TABLE t (c1 int, c2 char(1), c3 char(1), c4 char(1), key(c1,c2)) engine= $server_2_engine; + -- connection server_3 + --eval CREATE TABLE t (c1 int, c2 char(1), c3 char(1), c4 char(1), key(c1,c2)) engine= $server_3_engine; + } + if ($i == 4) + { + let $step= One Unique key; + --echo ****** TEST: $step + -- connection server_1 + --eval CREATE TABLE t (c1 int, c2 char(1), c3 char(1), c4 char(1), unique key(c1)) engine= $server_1_engine; + -- connection server_2 + --eval CREATE TABLE t (c1 int, c2 char(1), c3 char(1), c4 char(1), unique key(c1)) engine= $server_2_engine; + -- connection server_3 + --eval CREATE TABLE t (c1 int, c2 char(1), c3 char(1), c4 char(1), unique key(c1)) engine= $server_3_engine; + + } + if ($i == 5) + { + let $step= One Composite Unique key; + --echo ****** TEST: $step + -- connection server_1 + --eval CREATE TABLE t (c1 int, c2 char(1), c3 char(1), c4 char(1), unique key(c1,c2)) engine= $server_1_engine; + -- connection server_2 + --eval CREATE TABLE t (c1 int, c2 char(1), c3 char(1), c4 char(1), unique key(c1,c2)) engine= $server_2_engine; + -- connection server_3 + --eval CREATE TABLE t (c1 int, c2 char(1), c3 char(1), c4 char(1), unique key(c1,c2)) engine= $server_3_engine; + + } + if ($i == 6) + { + let $step= One Primary key; + --echo ****** TEST: $step + -- connection server_1 + --eval CREATE TABLE t (c1 int, c2 char(1), c3 char(1), c4 char(1), primary key(c1)) engine= $server_1_engine; + -- connection server_2 + --eval CREATE TABLE t (c1 int, c2 char(1), c3 char(1), c4 char(1), primary key(c1)) engine= $server_2_engine; + -- connection server_3 + --eval CREATE TABLE t (c1 int, c2 char(1), c3 char(1), c4 char(1), primary key(c1)) engine= $server_3_engine; + } + if ($i == 7) + { + let $step= One Composite Primary Key; + --echo ****** TEST: $step + -- connection server_1 + --eval CREATE TABLE t (c1 int, c2 char(1), c3 char(1), c4 char(1), primary key(c1,c2)) engine= $server_1_engine; + -- connection server_2 + --eval CREATE TABLE t (c1 int, c2 char(1), c3 char(1), c4 char(1), primary key(c1,c2)) engine= $server_2_engine; + -- connection server_3 + --eval CREATE TABLE t (c1 int, c2 char(1), c3 char(1), c4 char(1), primary key(c1,c2)) engine= $server_3_engine; + } + if ($i == 8) + { + let $step= One Composite key with holes; + --echo ****** TEST: $step + -- connection server_1 + --eval CREATE TABLE t (c1 int, c2 char(1), c3 char(1), c4 char(1), key(c1,c3)) engine= $server_1_engine; + -- connection server_2 + --eval CREATE TABLE t (c1 int, c2 char(1), c3 char(1), c4 char(1), key(c1,c3)) engine= $server_2_engine; + -- connection server_3 + --eval CREATE TABLE t (c1 int, c2 char(1), c3 char(1), c4 char(1), key(c1,c3)) engine= $server_3_engine; + } + if ($i == 9) + { + let $step= One Composite Unique key with holes; + --echo ****** TEST: $step + -- connection server_1 + --eval CREATE TABLE t (c1 int, c2 char(1), c3 char(1), c4 char(1), unique key(c1,c3)) engine= $server_1_engine; + -- connection server_2 + --eval CREATE TABLE t (c1 int, c2 char(1), c3 char(1), c4 char(1), unique key(c1,c3)) engine= $server_2_engine; + -- connection server_3 + --eval CREATE TABLE t (c1 int, c2 char(1), c3 char(1), c4 char(1), unique key(c1,c3)) engine= $server_3_engine; + } + if ($i == 10) + { + let $step= One Composite Primary Key with holes; + --echo ****** TEST: $step + -- connection server_1 + --eval CREATE TABLE t (c1 int, c2 char(1), c3 char(1), c4 char(1), primary key(c1,c3)) engine= $server_1_engine; + -- connection server_2 + --eval CREATE TABLE t (c1 int, c2 char(1), c3 char(1), c4 char(1), primary key(c1,c3)) engine= $server_2_engine; + -- connection server_3 + --eval CREATE TABLE t (c1 int, c2 char(1), c3 char(1), c4 char(1), primary key(c1,c3)) engine= $server_3_engine; + } + if ($i == 11) + { + let $step= One Composite NOT NULL Unique key with holes; + --echo ****** TEST: $step + -- connection server_1 + --eval CREATE TABLE t (c1 int NOT NULL, c2 char(1), c3 char(1) NOT NULL, c4 char(1), unique key(c1,c3)) engine= $server_1_engine; + -- connection server_2 + --eval CREATE TABLE t (c1 int NOT NULL, c2 char(1), c3 char(1) NOT NULL, c4 char(1), unique key(c1,c3)) engine= $server_2_engine; + -- connection server_3 + --eval CREATE TABLE t (c1 int NOT NULL, c2 char(1), c3 char(1) NOT NULL, c4 char(1), unique key(c1,c3)) engine= $server_3_engine; + } + if ($i == 12) + { + let $step= One Composite NOT NULL Unique key with holes in master, but NULLABLE on first slave; + --echo ****** TEST: $step + -- connection server_1 + --eval CREATE TABLE t (c1 int NOT NULL, c2 char(1), c3 char(1) NOT NULL, c4 char(1), unique key(c1,c3)) engine= $server_1_engine; + -- connection server_2 + --eval CREATE TABLE t (c1 int, c2 char(1), c3 char(1), c4 char(1), unique key(c1,c3)) engine= $server_2_engine; + -- connection server_3 + --eval CREATE TABLE t (c1 int NOT NULL, c2 char(1), c3 char(1) NOT NULL, c4 char(1), unique key(c1,c3)) engine= $server_3_engine; + } + + -- connection server_1 + SET SQL_LOG_BIN=1; + + -- connection server_2 + SET SQL_LOG_BIN=1; + + -- connection server_3 + SET SQL_LOG_BIN=1; + + -- connection server_1 + INSERT INTO t VALUES (1, '1', '1', '1' ); + INSERT INTO t VALUES (4, '4', '4', '4' ); + INSERT INTO t VALUES (7, '7', '7', '7' ); + + INSERT INTO t VALUES (9, '9', '9', NULL ); + + INSERT INTO t VALUES (2, '1', '2', '2' ); + INSERT INTO t VALUES (3, '1', '3', '2' ); + + -- source include/rpl_sync.inc + + -- connection server_1 + UPDATE t SET c4 = '7'; + + UPDATE t SET c4 = '5' WHERE c1 = 1; + UPDATE t SET c2 = '5' WHERE c1 = 1; + UPDATE t SET c1 = '5' WHERE c1 = 1; + + UPDATE t SET c4 = '8' WHERE c2 = '4'; + UPDATE t SET c1 = '8' WHERE c2 = '4'; + UPDATE t SET c2 = '8' WHERE c2 = '4'; + + UPDATE t SET c3 = '0' WHERE c4 = NULL; + UPDATE t SET c2 = '0' WHERE c4 = '0'; + + UPDATE t SET c2 = '2' WHERE c4 = '2'; + + -- source include/rpl_sync.inc + + -- let $diff_tables= server_1:$diff_table, server_2:$diff_table, server_3:$diff_table + -- source include/diff_tables.inc + + + -- connection server_1 + + DELETE FROM t WHERE c1 = 7; + DELETE FROM t WHERE c1 = 8; + DELETE FROM t; + + -- source include/rpl_sync.inc + + -- let $diff_tables= server_1:$diff_table, server_2:$diff_table, server_3:$diff_table + -- source include/diff_tables.inc + + -- connection server_1 + + DROP TABLE t; + + -- source include/rpl_sync.inc + + dec $i; +} diff --git a/mysql-test/suite/rpl/include/rpl_row_img_blobs.test b/mysql-test/suite/rpl/include/rpl_row_img_blobs.test new file mode 100644 index 00000000..9a706381 --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_row_img_blobs.test @@ -0,0 +1,179 @@ +# WL#5096 +# +# Description +# =========== +# +# This test case covers Requirements for replication using different +# combinations of indexes and blob fields. +# +# It acts as a complement for rpl_row_img_sanity tests as it checks +# that in a chained replication scenario, replication does not break. +# +# Usage +# ===== +# +# Before including this file the following variables should be set: +# * $server_1_engine +# * $server_2_engine +# * $server_3_engine +# +# Example: +# +# -- let $server_1_engine= Falcon +# -- let $server_2_engine= MyISAM +# -- let $server_3_engine= InnoDB +# +# -- source suite/rpl/include/rpl_row_img_blobs.test +# + +-- connection server_1 + +-- let $diff_table=test.t +let $i= 7; +while($i) +{ + -- connection server_1 + SET SQL_LOG_BIN=0; + + -- connection server_2 + SET SQL_LOG_BIN=0; + + -- connection server_3 + SET SQL_LOG_BIN=0; + + # + # The comments below (on create table) must be read with the SQL + # instructions issued later in mind. Declaring a table obviously is + # not enough to assert anything. + # + # Also, the tests in this file make more sense when performed with + # binlog_row_image configured as NOBLOB. + # + + if ($i == 1) { + -- echo ### Asserts that declaring a blob as part of a primary key does not break replication + -- connection server_1 + --eval CREATE TABLE t (c1 int, c2 blob, c3 int, primary key(c2(512))) engine= $server_1_engine; + -- connection server_2 + --eval CREATE TABLE t (c1 int, c2 blob, c3 int, primary key(c2(512))) engine= $server_2_engine; + -- connection server_3 + --eval CREATE TABLE t (c1 int, c2 blob, c3 int, primary key(c2(512))) engine= $server_3_engine; + } + if ($i == 2) + { + -- echo ### Asserts that declaring a blob as part of a unique (not null) key does not break replication + -- connection server_1 + --eval CREATE TABLE t (c1 int, c2 blob NOT NULL, c3 int, unique key(c2(512))) engine= $server_1_engine; + -- connection server_2 + --eval CREATE TABLE t (c1 int, c2 blob NOT NULL, c3 int, unique key(c2(512))) engine= $server_2_engine; + -- connection server_3 + --eval CREATE TABLE t (c1 int, c2 blob NOT NULL, c3 int, unique key(c2(512))) engine= $server_3_engine; + } + if ($i == 3) + { + -- echo ### Asserts that declaring a blob in a key does not break replication + -- connection server_1 + --eval CREATE TABLE t (c1 int, c2 blob, c3 int, key(c2(512))) engine= $server_1_engine; + -- connection server_2 + --eval CREATE TABLE t (c1 int, c2 blob, c3 int, key(c2(512))) engine= $server_2_engine; + -- connection server_3 + --eval CREATE TABLE t (c1 int, c2 blob, c3 int, key(c2(512))) engine= $server_3_engine; + + } + if ($i == 4) { + -- echo ### Asserts that updates without blobs in the BI (PK exists int the table) + -- echo ### will not break replication + -- connection server_1 + --eval CREATE TABLE t (c1 int, c2 blob, c3 int, primary key(c1)) engine= $server_1_engine; + -- connection server_2 + --eval CREATE TABLE t (c1 int, c2 blob, c3 int, primary key(c1)) engine= $server_2_engine; + -- connection server_3 + --eval CREATE TABLE t (c1 int, c2 blob, c3 int, primary key(c1)) engine= $server_3_engine; + + } + if ($i == 5) + { + -- echo ### Asserts that updates without blobs in the BI (UK NOT NULL exists in the table) + -- echo ### will not break replication + -- connection server_1 + --eval CREATE TABLE t (c1 int NOT NULL, c2 blob NOT NULL, c3 int, unique key(c1)) engine= $server_1_engine; + -- connection server_2 + --eval CREATE TABLE t (c1 int NOT NULL, c2 blob NOT NULL, c3 int, unique key(c1)) engine= $server_2_engine; + -- connection server_3 + --eval CREATE TABLE t (c1 int NOT NULL, c2 blob NOT NULL, c3 int, unique key(c1)) engine= $server_3_engine; + + } + if ($i == 6) + { + -- echo ### Asserts that updates without blobs in the AI (they are not updated) + -- echo ### will not break replication (check even if there is a key in the table) + -- connection server_1 + --eval CREATE TABLE t (c1 int, c2 blob, c3 int, key(c1)) engine= $server_1_engine; + -- connection server_2 + --eval CREATE TABLE t (c1 int, c2 blob, c3 int, key(c1)) engine= $server_2_engine; + -- connection server_3 + --eval CREATE TABLE t (c1 int, c2 blob, c3 int, key(c1)) engine= $server_3_engine; + + } + if ($i == 7) + { + -- echo ### Asserts that updates without blobs in the AI (they are not updated) + -- echo ### will not break replication (check when there is no key in the table) + -- connection server_1 + --eval CREATE TABLE t (c1 int, c2 blob, c3 int) engine= $server_1_engine; + -- connection server_2 + --eval CREATE TABLE t (c1 int, c2 blob, c3 int) engine= $server_2_engine; + -- connection server_3 + --eval CREATE TABLE t (c1 int, c2 blob, c3 int) engine= $server_3_engine; + } + + -- connection server_1 + SET SQL_LOG_BIN=1; + + -- connection server_2 + SET SQL_LOG_BIN=1; + + -- connection server_3 + SET SQL_LOG_BIN=1; + + -- connection server_1 + + -- let $blob1= "a" + -- let $blob2= "b" + -- let $blob3= "c" + + -- eval INSERT INTO t VALUES (1, $blob1, 10) + -- eval INSERT INTO t VALUES (2, $blob2, 20) + -- eval INSERT INTO t VALUES (3, $blob3, 30) + + -- source include/rpl_sync.inc + + -- connection server_1 + -- eval UPDATE t SET c1=10 WHERE c2=$blob1 + -- eval UPDATE t SET c1=20 WHERE c1=2 + -- eval UPDATE t SET c1=30 WHERE c3=30 + -- eval UPDATE t SET c3=40 WHERE c1=30 + + -- source include/rpl_sync.inc + + -- let $diff_tables= server_1:$diff_table, server_2:$diff_table, server_3:$diff_table + -- source include/diff_tables.inc + + -- connection server_1 + -- eval DELETE FROM t WHERE c2=$blob1 + -- eval DELETE FROM t WHERE c1=20 + -- eval DELETE FROM t + + -- source include/rpl_sync.inc + + -- let $diff_tables= server_1:$diff_table, server_2:$diff_table, server_3:$diff_table + -- source include/diff_tables.inc + + -- connection server_1 + + DROP TABLE t; + + -- source include/rpl_sync.inc + + dec $i; +} diff --git a/mysql-test/suite/rpl/include/rpl_row_img_sequence.inc b/mysql-test/suite/rpl/include/rpl_row_img_sequence.inc new file mode 100644 index 00000000..d9ed6f27 --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_row_img_sequence.inc @@ -0,0 +1,92 @@ +# +# This include file validates that sequence events are properly binlogged +# and replicated. +# +# Parameters: +# expected_columns (list, in) : A list of positive integers which +# correspond to the column numbers that should be output in a binary +# log's write_rows event +# + +--echo # Create sequences with specific engines per server +--connection server_1 +--eval SET STATEMENT sql_log_bin=0 FOR create sequence s1 cache=0 engine=$server_1_engine +--source include/save_master_gtid.inc + +--connection server_2 +--eval SET STATEMENT sql_log_bin=0 FOR create sequence s1 cache=0 engine=$server_2_engine +--source include/sync_with_master_gtid.inc + +--connection server_3 +--eval SET STATEMENT sql_log_bin=0 FOR create sequence s1 cache=0 engine=$server_3_engine +--source include/sync_with_master_gtid.inc + + +--echo # Pt.1 Ensure SETVAL replicates and binlogs correctly +--connection server_1 +SELECT SETVAL(s1, 10); +--source include/save_master_gtid.inc + +--echo # Validate SETVAL replicated correctly to other servers +--connection server_3 +--source include/sync_with_master_gtid.inc +--let $diff_tables= server_1:test.s1,server_2:test.s1,server_3:test.s1 +--source include/diff_tables.inc + +--echo # Validate server_1 binlogged SETVAL with the correct columns +--connection server_1 +--let binlog_filenamE= query_get_value(SHOW MASTER STATUS, File, 1) +FLUSH LOGS; +--source include/ensure_binlog_row_event_columns.inc + +--echo # Validate server_2 binlogged SETVAL with the correct columns +--connection server_2 +--let binlog_filename= query_get_value(SHOW MASTER STATUS, File, 1) +FLUSH LOGS; +--source include/ensure_binlog_row_event_columns.inc + +--echo # Validate server_3 binlogged SETVAL with the correct columns +--connection server_3 +--let binlog_filename= query_get_value(SHOW MASTER STATUS, File, 1) +FLUSH LOGS; +--source include/ensure_binlog_row_event_columns.inc + + +--echo # Pt.2 Ensure NEXTVAL replicates and binlogs correctly +--connection server_1 +--disable_ps2_protocol +SELECT NEXTVAL(s1); +--enable_ps2_protocol +--source include/save_master_gtid.inc + +--echo # Validate NEXTVAL replicated correctly to other servers +--connection server_3 +--source include/sync_with_master_gtid.inc +--let $diff_tables= server_1:test.s1,server_2:test.s1,server_3:test.s1 +--source include/diff_tables.inc + +--echo # Validate server_1 binlogged NEXTVAL with the correct columns +--connection server_1 +--let binlog_filename= query_get_value(SHOW MASTER STATUS, File, 1) +FLUSH LOGS; +--source include/ensure_binlog_row_event_columns.inc + +--echo # Validate server_2 binlogged NEXTVAL with the correct columns +--connection server_2 +--let binlog_filename= query_get_value(SHOW MASTER STATUS, File, 1) +FLUSH LOGS; +--source include/ensure_binlog_row_event_columns.inc + +--echo # Validate server_3 binlogged NEXTVAL with the correct columns +--connection server_3 +--let binlog_filename= query_get_value(SHOW MASTER STATUS, File, 1) +FLUSH LOGS; +--source include/ensure_binlog_row_event_columns.inc + + +--echo # Cleanup +--connection server_1 +DROP TABLE s1; +--source include/save_master_gtid.inc +--connection server_3 +--source include/sync_with_master_gtid.inc diff --git a/mysql-test/suite/rpl/include/rpl_row_sp002.test b/mysql-test/suite/rpl/include/rpl_row_sp002.test new file mode 100644 index 00000000..90c273eb --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_row_sp002.test @@ -0,0 +1,208 @@ +############################################################################# +# This test is being created to test out the non deterministic items with # +# row based replication. # +############################################################################# +# Test: Contains two stored procedures test one that insert data into tables# +# and use the LAST_INSERTED_ID() on tables with FOREIGN KEY(a) # +# REFERENCES ON DELETE CASCADE. This test also has a delete sp that # +# should cause a delete cascade. # +# The second test has a sp that will either insert rows or delete from# +# the table depending on the CASE outcome. The test uses this SP in a# +# transaction first rolling back and then commiting, # +############################################################################# + + + +# Includes +-- source include/have_binlog_format_row.inc +-- source include/master-slave.inc + +# Begin test section 1 + +eval CREATE TABLE test.t1 (a INT AUTO_INCREMENT KEY, t CHAR(6)) ENGINE=$engine_type; +eval CREATE TABLE test.t2 (a INT AUTO_INCREMENT KEY, f INT, FOREIGN KEY(a) REFERENCES test.t1(a) ON DELETE CASCADE) ENGINE=$engine_type; + +delimiter |; +create procedure test.p1(IN i CHAR(6)) +begin + INSERT INTO test.t1 (t) VALUES (i); + INSERT INTO test.t2 VALUES (NULL,LAST_INSERT_ID()); +end| +create procedure test.p2(IN i INT) +begin + DELETE FROM test.t1 where a < i; +end| +delimiter ;| + +let $message=< -- test 1 call p1 -- >; +--source include/show_msg.inc +SET FOREIGN_KEY_CHECKS=1; +call test.p1('texas'); +call test.p1('Live'); +call test.p1('next'); +call test.p1('to'); +call test.p1('OK'); +call test.p1('MySQL'); + +let $message=< -- test 1 select master after p1 -- >; +--source include/show_msg.inc + +SELECT * FROM test.t1; +SELECT * FROM test.t2; + +let $message=< -- test 1 select slave after p1 -- >; +--source include/show_msg.inc +sync_slave_with_master; +SELECT * FROM test.t1; +SELECT * FROM test.t2; + +let $message=< -- test 1 call p2 & select master -- >; +--source include/show_msg.inc +connection master; +call test.p2(4); +SELECT * FROM test.t1; +SELECT * FROM test.t2; + +let $message=< -- test 1 select slave after p2 -- >; +--source include/show_msg.inc +sync_slave_with_master; +SELECT * FROM test.t1; +SELECT * FROM test.t2; + +connection master; +#show binlog events; +let $message=< -- End test 1 Begin test 2 -- >; +--source include/show_msg.inc +# End test 1 Begin test 2 + +--disable_warnings +SET FOREIGN_KEY_CHECKS=0; +DROP PROCEDURE IF EXISTS test.p1; +DROP PROCEDURE IF EXISTS test.p2; +DROP TABLE IF EXISTS test.t1; +DROP TABLE IF EXISTS test.t2; +--enable_warnings +# End of cleanup + +eval CREATE TABLE test.t1 (a INT, t CHAR(6), PRIMARY KEY(a)) ENGINE=$engine_type; +eval CREATE TABLE test.t2 (a INT, f INT, FOREIGN KEY(a) REFERENCES test.t1(a) ON UPDATE CASCADE, PRIMARY KEY(a)) ENGINE=$engine_type; + +delimiter |; +CREATE PROCEDURE test.p1(IN nm INT, IN ch CHAR(6)) +BEGIN + INSERT INTO test.t1 (a,t) VALUES (nm, ch); + INSERT INTO test.t2 VALUES (nm, LAST_INSERT_ID()); +END| +CREATE PROCEDURE test.p2(IN i INT) +BEGIN + UPDATE test.t1 SET a = i*10 WHERE a = i; +END| +delimiter ;| +SET FOREIGN_KEY_CHECKS=1; +CALL test.p1(1,'texas'); +CALL test.p1(2,'Live'); +CALL test.p1(3,'next'); +CALL test.p1(4,'to'); +CALL test.p1(5,'OK'); +CALL test.p1(6,'MySQL'); + +let $message=< -- test 2 select Master after p1 -- >; +--source include/show_msg.inc +SELECT * FROM test.t1; +SELECT * FROM test.t2; + +let $message=< -- test 2 select Slave after p1 -- >; +--source include/show_msg.inc +sync_slave_with_master; +SELECT * FROM test.t1; +SELECT * FROM test.t2; + +let $message=< -- test 2 call p2 & select Master -- >; +--source include/show_msg.inc +connection master; +CALL test.p2(2); +CALL test.p2(4); +CALL test.p2(6); +SELECT * FROM test.t1; +SELECT * FROM test.t2; + +let $message=< -- test 1 select Slave after p2 -- >; +--source include/show_msg.inc +sync_slave_with_master; +SELECT * FROM test.t1; +SELECT * FROM test.t2; + +connection master; +#show binlog events; +let $message=< -- End test 2 Begin test 3 -- >; +--source include/show_msg.inc +# End test 2 begin test 3 + +eval CREATE TABLE test.t3 (a INT AUTO_INCREMENT KEY, t CHAR(6))ENGINE=$engine_type; + +delimiter |; +CREATE PROCEDURE test.p3(IN n INT) +begin +CASE n +WHEN 2 THEN + DELETE from test.t3; +ELSE + INSERT INTO test.t3 VALUES (NULL,'NONE'); +END CASE; +end| +delimiter ;| + +SET AUTOCOMMIT=0; +START TRANSACTION; + +-- disable_query_log +-- disable_result_log +let $n=50; +while ($n) +{ + eval call test.p3($n); + dec $n; +} +-- enable_result_log +-- enable_query_log + +ROLLBACK; +select * from test.t3; +sync_slave_with_master; +select * from test.t3; + +connection master; +START TRANSACTION; + +-- disable_query_log +-- disable_result_log +let $n=50; +while ($n) +{ + eval call test.p3($n); + dec $n; +} +-- enable_result_log +-- enable_query_log + +COMMIT; +select * from test.t3; +sync_slave_with_master; +select * from test.t3; + +connection master; +#show binlog events from 1627; + + +# First lets cleanup +SET AUTOCOMMIT=1; +SET FOREIGN_KEY_CHECKS=0; +DROP PROCEDURE test.p3; +DROP PROCEDURE test.p1; +DROP PROCEDURE test.p2; +DROP TABLE test.t1; +DROP TABLE test.t2; +DROP TABLE test.t3; + +# End of 5.0 test case +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/include/rpl_row_sp003.test b/mysql-test/suite/rpl/include/rpl_row_sp003.test new file mode 100644 index 00000000..829e42f2 --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_row_sp003.test @@ -0,0 +1,81 @@ +############################################################################# +# Original Author: JBM # +# Original Date: Aug/13/2005 Created from Bug 12335 # +############################################################################# + +# Begin clean up test section +connection master; +--disable_warnings +DROP PROCEDURE IF EXISTS test.p1; +DROP PROCEDURE IF EXISTS test.p2; +DROP TABLE IF EXISTS test.t1; +--enable_warnings +# End of cleanup + +# Begin test section 1 + +--disable_ps2_protocol +eval CREATE TABLE test.t1(a INT,PRIMARY KEY(a))ENGINE=$engine_type; + +delimiter |; +CREATE PROCEDURE test.p1() +BEGIN + INSERT INTO test.t1 VALUES (4); + SELECT get_lock("test", 100); + UPDATE test.t1 set a=a+4 WHERE a=4; +END| +CREATE PROCEDURE test.p2() +BEGIN + UPDATE test.t1 SET a=a+1; +END| +delimiter ;| + +SELECT get_lock("test", 200); + +connection master1; +send CALL test.p1(); + +connection master; +# Make sure that the call on master1 arrived at the get_lock. +let $wait_condition= + select count(*) = 1 from information_schema.processlist + where state = 'User lock' and + info = 'SELECT get_lock("test", 100)'; +--source include/wait_condition.inc +CALL test.p2(); +SELECT release_lock("test"); + +connection master1; +# Reap CALL test.p1() to ensure that it has fully completed +# before doing any selects on test.t1. +--reap +# Release lock acquired by it. +SELECT release_lock("test"); + +connection master; +SELECT * FROM test.t1; +sync_slave_with_master; +connection slave; +SELECT * FROM test.t1; + +connection master; +DROP TABLE IF EXISTS test.t1; +eval CREATE TABLE test.t1(a INT,PRIMARY KEY(a))ENGINE=$engine_type; +CALL test.p2(); +CALL test.p1(); +SELECT release_lock("test"); +SELECT * FROM test.t1; + +sync_slave_with_master; +connection slave; +SELECT * FROM test.t1; +connection master; +#show binlog events from 720; +--enable_ps2_protocol + +DROP PROCEDURE IF EXISTS test.p1; +DROP PROCEDURE IF EXISTS test.p2; +DROP TABLE IF EXISTS test.t1; +sync_slave_with_master; + +# End of 5.0 test case diff --git a/mysql-test/suite/rpl/include/rpl_row_sp006.test b/mysql-test/suite/rpl/include/rpl_row_sp006.test new file mode 100644 index 00000000..16a8374a --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_row_sp006.test @@ -0,0 +1,84 @@ +############################################################################# +# Original Author: JBM # +# Original Date: Aug/15/2005 # +# Updated: 08/29/2005 to remove sleeps # +############################################################################# +# Test: This test uses two SPs, one to populate a table, and another to use # +# Cursors, CURRENT_DATE(), loop control, date math and logic control # +# to populate a table with data from the first table. # +############################################################################# + +# Begin clean up test section +--disable_warnings +DROP TABLE IF EXISTS t1; +DROP TABLE IF EXISTS t2; +DROP PROCEDURE IF EXISTS p1; +DROP PROCEDURE IF EXISTS p2; +--enable_warnings +# End of cleanup + +# Begin test section 1 +eval CREATE TABLE IF NOT EXISTS t1(name CHAR(16), birth DATE,PRIMARY KEY(name))ENGINE=$engine_type; +eval CREATE TABLE IF NOT EXISTS t2(name CHAR(16), age INT ,PRIMARY KEY(name))ENGINE=$engine_type; + +delimiter |; +CREATE PROCEDURE p1() +BEGIN + DECLARE done INT DEFAULT 0; + DECLARE spa CHAR(16); + DECLARE spb INT; + DECLARE cur1 CURSOR FOR SELECT name, + (YEAR(CURDATE())-YEAR(birth))-(RIGHT(CURDATE(),5) $MYSQLTEST_VARDIR/tmp/sp006_master.sql +--exec $MYSQL_DUMP_SLAVE --compact --order-by-primary --skip-extended-insert --no-create-info test > $MYSQLTEST_VARDIR/tmp/sp006_slave.sql + + +DROP TABLE t1; +DROP TABLE t2; +DROP PROCEDURE p1; +DROP PROCEDURE p2; + +# Lets 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 :-) Failed test +# Dump files will be located in $MYSQLTEST_VARDIR/tmp. + +diff_files $MYSQLTEST_VARDIR/tmp/sp006_master.sql $MYSQLTEST_VARDIR/tmp/sp006_slave.sql; + +sync_slave_with_master; + +# End of 5.1 test case diff --git a/mysql-test/suite/rpl/include/rpl_row_sp007.test b/mysql-test/suite/rpl/include/rpl_row_sp007.test new file mode 100644 index 00000000..4a68dddf --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_row_sp007.test @@ -0,0 +1,46 @@ +############################################################################# +# TEST: SP that creates table, starts tranaction inserts. Save point, insert# +# rollback to save point and then commits. # +############################################################################# +# Includes +-- source include/have_binlog_format_row.inc +-- source include/master-slave.inc + +# Begin test section 1 +delimiter |; +eval CREATE PROCEDURE test.p1(IN i INT) +BEGIN + DECLARE CONTINUE HANDLER FOR sqlexception BEGIN END; + DROP TABLE IF EXISTS test.t1; + CREATE TABLE test.t1 (num INT,PRIMARY KEY(num))ENGINE=$engine_type; + START TRANSACTION; + INSERT INTO test.t1 VALUES(i); + savepoint t1_save; + INSERT INTO test.t1 VALUES (14); + ROLLBACK to savepoint t1_save; + COMMIT; +END| +delimiter ;| + +CALL test.p1(12); +SELECT * FROM test.t1; + +sync_slave_with_master; +SELECT * FROM test.t1; + +connection master; +CALL test.p1(13); +SELECT * FROM test.t1; + +sync_slave_with_master; +SELECT * FROM test.t1; + +connection master; +#show binlog events; + + +DROP PROCEDURE test.p1; +DROP TABLE test.t1; + +# End of 5.0 test case +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/include/rpl_row_tabledefs.test b/mysql-test/suite/rpl/include/rpl_row_tabledefs.test new file mode 100644 index 00000000..194079b1 --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_row_tabledefs.test @@ -0,0 +1,232 @@ +# Test how replication of tables work when the definition on the +# master and slave differs. + +# Consider making these part of the basic RBR tests. + +connection master; +--disable_warnings +--disable_query_log +DROP TABLE IF EXISTS t1_int,t1_bit,t1_char,t1_nodef; +DROP TABLE IF EXISTS t2,t3,t4,t5,t6,t9; +--enable_query_log +--enable_warnings +sync_slave_with_master; +STOP SLAVE; +SET @my_sql_mode= @@global.sql_mode; +SET GLOBAL SQL_MODE='STRICT_ALL_TABLES'; +START SLAVE; + +connection master; +eval CREATE TABLE t1_int (a INT PRIMARY KEY, b INT) ENGINE=$engine_type; +eval CREATE TABLE t1_bit (a INT PRIMARY KEY, b INT) ENGINE=$engine_type; +eval CREATE TABLE t1_char (a INT PRIMARY KEY, b INT) ENGINE=$engine_type; +eval CREATE TABLE t1_nodef (a INT PRIMARY KEY, b INT) ENGINE=$engine_type; +eval CREATE TABLE t2 (a INT PRIMARY KEY, b INT) ENGINE=$engine_type; +eval CREATE TABLE t3 (a INT PRIMARY KEY, b INT) ENGINE=$engine_type; +eval CREATE TABLE t4 (a INT) ENGINE=$engine_type; +eval CREATE TABLE t5 (a INT, b INT, c INT) ENGINE=$engine_type; +eval CREATE TABLE t6 (a INT, b INT, c INT) ENGINE=$engine_type; +eval CREATE TABLE t7 (a INT NOT NULL) ENGINE=$engine_type; +eval CREATE TABLE t8 (a INT NOT NULL) ENGINE=$engine_type; + +# Table used to detect that slave is running +eval CREATE TABLE t9 (a INT) ENGINE=$engine_type; + +sync_slave_with_master; + +# On the slave, we add one INT column last in table 't1_int', +ALTER TABLE t1_int ADD x INT DEFAULT 42; +# ... and add BIT columns last in table 't1_bit' to ensure that we +# have at least one extra null byte on the slave, +ALTER TABLE t1_bit + ADD x BIT(3) DEFAULT b'011', + ADD y BIT(5) DEFAULT b'10101', + ADD z BIT(2) DEFAULT b'10'; +# ... and add one CHAR column last in table 't1_char', +ALTER TABLE t1_char ADD x CHAR(20) DEFAULT 'Just a test'; +# ... and add one non-nullable INT column last in table 't1_text' +# with no default, +ALTER TABLE t1_nodef ADD x INT NOT NULL, ADD y INT NOT NULL, ADD z INT NOT NULL; +# ... and remove the last column in t2 +ALTER TABLE t2 DROP b; +# ... change the type of the single column in table 't4' +ALTER TABLE t4 MODIFY a FLOAT; +# ... change the type of the middle column of table 't5' +ALTER TABLE t5 MODIFY b FLOAT; +# ... change the type of the last column of table 't6' +ALTER TABLE t6 MODIFY c FLOAT; + +# ... add one byte worth of null bytes to the table on the slave +ALTER TABLE t7 ADD e1 INT, ADD e2 INT, ADD e3 INT, ADD e4 INT, + ADD e5 INT, ADD e6 INT, ADD e7 INT, ADD e8 INT; + +# ... add 8 columns that are nullable: t8 will not be entirely +# nullable and have no null bits (just an X bit) +ALTER TABLE t8 ADD e1 INT NOT NULL DEFAULT 0, ADD e2 INT NOT NULL DEFAULT 0, + ADD e3 INT NOT NULL DEFAULT 0, ADD e4 INT NOT NULL DEFAULT 0, + ADD e5 INT NOT NULL DEFAULT 0, ADD e6 INT NOT NULL DEFAULT 0, + ADD e7 INT NOT NULL DEFAULT 0, ADD e8 INT NOT NULL DEFAULT 0; + +# Insert some values for tables on slave side. These should not be +# modified when the row from the master is applied. +# since bug#31552/31609 idempotency is not default any longer. In order +# the following INSERTs to pass the mode is switched temprorarily +set @@global.slave_exec_mode= 'IDEMPOTENT'; + +# so the inserts are going to be overridden +INSERT INTO t1_int VALUES (2, 4, 4711); +INSERT INTO t1_char VALUES (2, 4, 'Foo is a bar'); +INSERT INTO t1_bit VALUES (2, 4, b'101', b'11100', b'01'); + +connection master; +INSERT INTO t1_int VALUES (1,2); +INSERT INTO t1_int VALUES (2,5); +INSERT INTO t1_bit VALUES (1,2); +INSERT INTO t1_bit VALUES (2,5); +INSERT INTO t1_char VALUES (1,2); +INSERT INTO t1_char VALUES (2,5); +SELECT * FROM t1_int ORDER BY a; +SELECT * FROM t1_bit ORDER BY a; +SELECT * FROM t1_char ORDER BY a; +sync_slave_with_master; +set @@global.slave_exec_mode= default; + +SELECT a,b,x FROM t1_int ORDER BY a; +SELECT a,b,HEX(x),HEX(y),HEX(z) FROM t1_bit ORDER BY a; +SELECT a,b,x FROM t1_char ORDER BY a; + +connection master; +UPDATE t1_int SET b=2*b WHERE a=2; +UPDATE t1_char SET b=2*b WHERE a=2; +UPDATE t1_bit SET b=2*b WHERE a=2; +SELECT * FROM t1_int ORDER BY a; +SELECT * FROM t1_bit ORDER BY a; +SELECT * FROM t1_char ORDER BY a; +sync_slave_with_master; +SELECT a,b,x FROM t1_int ORDER BY a; +SELECT a,b,HEX(x),HEX(y),HEX(z) FROM t1_bit ORDER BY a; +SELECT a,b,x FROM t1_char ORDER BY a; + +connection master; +INSERT INTO t9 VALUES (2); +sync_slave_with_master; +# Now slave is guaranteed to be running +connection master; +INSERT INTO t1_nodef VALUES (1,2); + +# Last insert on wider slave table succeeds while slave sql sql_mode permits. +# The previous version of the above test expected slave sql to stop. +# bug#38173 relaxed conditions to stop only with the strict mode. +sync_slave_with_master; +select count(*) from t1_nodef; + +# +# Replicating to tables with fewer columns at the end works as of WL#3228 +# +connection master; +INSERT INTO t9 VALUES (2); +sync_slave_with_master; +# Now slave is guaranteed to be running +connection master; +INSERT INTO t2 VALUES (2,4); +SELECT * FROM t2; +sync_slave_with_master; +SELECT * FROM t2; +--source include/check_slave_is_running.inc + +connection master; +INSERT INTO t9 VALUES (4); +sync_slave_with_master; +# Now slave is guaranteed to be running +connection master; +INSERT INTO t4 VALUES (4); +connection slave; +call mtr.add_suppression("Slave SQL.*Table definition on master and slave does not match: Column [012] type mismatch.* error.* 1535"); +call mtr.add_suppression("Slave SQL.*Column [0-9] of table .test.t[0-9]. cannot be converted from type.* error.* 1677"); +--let $slave_skip_counter= 2 +--let $slave_sql_errno= 1677 +--let $show_slave_sql_error= 1 +--source include/wait_for_slave_sql_error_and_skip.inc + +connection master; +INSERT INTO t9 VALUES (5); +sync_slave_with_master; +# Now slave is guaranteed to be running +connection master; +INSERT INTO t5 VALUES (5,10,25); +connection slave; +--let $slave_skip_counter= 2 +--let $slave_sql_errno= 1677 +--let $show_slave_sql_error= 1 +--source include/wait_for_slave_sql_error_and_skip.inc + +connection master; +INSERT INTO t9 VALUES (6); +sync_slave_with_master; +# Now slave is guaranteed to be running +connection master; +INSERT INTO t6 VALUES (6,12,36); +connection slave; +--let $slave_skip_counter= 2 +--let $slave_sql_errno= 1677 +--let $show_slave_sql_error= 1 +--source include/wait_for_slave_sql_error_and_skip.inc + +connection master; +INSERT INTO t9 VALUES (6); +sync_slave_with_master; +--source include/check_slave_is_running.inc + +# Testing some tables extra field that can be null and cannot be null +# (but have default values) + +connection master; +INSERT INTO t7 VALUES (1),(2),(3); +INSERT INTO t8 VALUES (1),(2),(3); +SELECT * FROM t7 ORDER BY a; +SELECT * FROM t8 ORDER BY a; +sync_slave_with_master; +SELECT * FROM t7 ORDER BY a; +SELECT * FROM t8 ORDER BY a; + +# We will now try to update and then delete a row on the master where +# the extra field on the slave does not have a default value. This +# update should not generate an error even though there is no default +# for the extra column. + +connection master; +TRUNCATE t1_nodef; +SET SQL_LOG_BIN=0; +INSERT INTO t1_nodef VALUES (1,2); +INSERT INTO t1_nodef VALUES (2,4); +SET SQL_LOG_BIN=1; +sync_slave_with_master; + +connection slave; +INSERT INTO t1_nodef VALUES (1,2,3,4,5); +INSERT INTO t1_nodef VALUES (2,4,6,8,10); + +connection master; +UPDATE t1_nodef SET b=2*b WHERE a=1; +SELECT * FROM t1_nodef ORDER BY a; + +sync_slave_with_master; +SELECT * FROM t1_nodef ORDER BY a; + +connection master; +DELETE FROM t1_nodef WHERE a=2; +SELECT * FROM t1_nodef ORDER BY a; + +sync_slave_with_master; +SELECT * FROM t1_nodef ORDER BY a; + +--echo **** Cleanup **** +connection master; +--disable_warnings +DROP TABLE IF EXISTS t1_int,t1_bit,t1_char,t1_nodef; +DROP TABLE IF EXISTS t2,t3,t4,t5,t6,t7,t8,t9; +--enable_warnings +sync_slave_with_master; + +# Restore sql_mode +SET @@global.sql_mode= @my_sql_mode; diff --git a/mysql-test/suite/rpl/include/rpl_set_null.test b/mysql-test/suite/rpl/include/rpl_set_null.test new file mode 100644 index 00000000..3755c8bb --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_set_null.test @@ -0,0 +1,82 @@ +# Both of the following tests check that comparison of binlog BI +# against SE record will not fail due to remains from previous values +# in the SE record (before a given field was set to null). +# +# In MIXED mode: +# - Insert and update are executed as statements +# - Delete is executed as a row event +# - Assertion: checks that comparison will not fail because the update +# statement will clear the record contents for the nulled +# field. If data was not cleared, some engines may keep +# the value and return it later as garbage - despite the +# fact that field is null. This may cause slave to +# falsely fail in the comparison (memcmp would fail +# because of "garbage" in record data). +# +# In ROW mode: +# - Insert, update and delete are executed as row events. +# - Assertion: checks that comparison will not fail because the update +# rows event will clear the record contents before +# feeding the new value to the SE. This protects against +# SEs that do not clear record contents when storing +# nulled fields. If the engine did not clear the data it +# would cause slave to falsely fail in the comparison +# (memcmp would fail because of "garbage" in record +# data). This scenario is pretty much the same described +# above in MIXED mode, but checks different execution +# path in the slave. + +# BUG#49481: RBR: MyISAM and bit fields may cause slave to stop on +# delete cant find record + +-- source include/rpl_reset.inc + +-- connection master +-- eval CREATE TABLE t1 (c1 BIT, c2 INT) Engine=$engine +INSERT INTO `t1` VALUES ( 1, 1 ); +UPDATE t1 SET c1=NULL where c2=1; +-- sync_slave_with_master + +-- let $diff_tables= master:t1, slave:t1 +-- source include/diff_tables.inc + +-- connection master +# triggers switch to row mode when on mixed +DELETE FROM t1 WHERE c2=1 LIMIT 1; +-- sync_slave_with_master + +-- let $diff_tables= master:t1, slave:t1 +-- source include/diff_tables.inc + +-- connection master +DROP TABLE t1; +-- sync_slave_with_master + +-- source include/rpl_reset.inc + +-- connection master + +# BUG#49482: RBR: Replication may break on deletes when MyISAM tables +# + char field are used + +-- eval CREATE TABLE t1 (c1 CHAR) Engine=$engine + +INSERT INTO t1 ( c1 ) VALUES ( 'w' ) ; +SELECT * FROM t1; +UPDATE t1 SET c1=NULL WHERE c1='w'; +-- sync_slave_with_master + +-- let $diff_tables= master:t1, slave:t1 +-- source include/diff_tables.inc + +-- connection master +# triggers switch to row mode when on mixed +DELETE FROM t1 LIMIT 2; +-- sync_slave_with_master + +-- let $diff_tables= master:t1, slave:t1 +-- source include/diff_tables.inc + +-- connection master +DROP TABLE t1; +-- sync_slave_with_master diff --git a/mysql-test/suite/rpl/include/rpl_set_statement.inc b/mysql-test/suite/rpl/include/rpl_set_statement.inc new file mode 100644 index 00000000..d1a1a6c0 --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_set_statement.inc @@ -0,0 +1,26 @@ +#Check if the variable is replicated correctly with "SET STATEMENT" +# Usage: +# $rpl_ssvt_var_name - the name of tested variable; +# $rpl_ssvt_var_value - the value to set; +# $rpl_ssvt_table - the table name to insert values. + +--connection master +eval SELECT @@$rpl_ssvt_var_name; + +--connection slave +eval SELECT @@$rpl_ssvt_var_name; + +--connection master +--disable_result_log +eval SET STATEMENT $rpl_ssvt_var_name=$rpl_ssvt_var_value FOR + INSERT INTO $rpl_ssvt_table VALUES(@@$rpl_ssvt_var_name); +--enable_result_log +eval SELECT @@$rpl_ssvt_var_name; + +--sync_slave_with_master +eval SELECT * FROM $rpl_ssvt_table; +eval SELECT @@$rpl_ssvt_var_name; + +--connection master +eval DELETE FROM $rpl_ssvt_table; + diff --git a/mysql-test/suite/rpl/include/rpl_show_binlog_events.inc b/mysql-test/suite/rpl/include/rpl_show_binlog_events.inc new file mode 100644 index 00000000..4530f8c6 --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_show_binlog_events.inc @@ -0,0 +1,17 @@ +# Include file for rpl_show_relaylog_events.inc + +--let $log_type= BINLOG +if ($is_relay_log) { + --let $log_type= RELAYLOG +} +--let $args= +if ($binlog_file != '') { + --let $args= IN +} +if ($binlog_limit) { + --let $args= $args LIMIT $binlog_limit +} +--echo ******** [$CURRENT_CONNECTION] SHOW $log_type EVENTS $args ******** +--source include/show_events.inc + + diff --git a/mysql-test/suite/rpl/include/rpl_show_log_events_with_varying_options.inc b/mysql-test/suite/rpl/include/rpl_show_log_events_with_varying_options.inc new file mode 100644 index 00000000..ce6f094a --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_show_log_events_with_varying_options.inc @@ -0,0 +1,11 @@ +# Include file for rpl_show_log_events.inc + +--let $binlog_limit= +--source suite/rpl/include/rpl_show_binlog_events.inc +--let $binlog_limit= 2 +--source suite/rpl/include/rpl_show_binlog_events.inc +--let $binlog_limit= 2,4 +--source suite/rpl/include/rpl_show_binlog_events.inc +--let $binlog_limit= +--let $binlog_file= +--source suite/rpl/include/rpl_show_binlog_events.inc diff --git a/mysql-test/suite/rpl/include/rpl_show_relaylog_events.inc b/mysql-test/suite/rpl/include/rpl_show_relaylog_events.inc new file mode 100644 index 00000000..d590eafd --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_show_relaylog_events.inc @@ -0,0 +1,65 @@ +-- connection master +-- source include/rpl_reset.inc + +-- connection master + +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1); +INSERT INTO t1 VALUES (2); +INSERT INTO t1 VALUES (3); + +# PART I +# +# SHOWs contents of binary logs on the master and both, binary and +# relay logs, on the slave. +# + +--let $is_relay_log= 0 +--let $binlog_file= query_get_value(SHOW MASTER STATUS, File, 1) +--source suite/rpl/include/rpl_show_log_events_with_varying_options.inc + +--sync_slave_with_master +--let $binlog_file= query_get_value(SHOW MASTER STATUS, File, 1) +--source suite/rpl/include/rpl_show_log_events_with_varying_options.inc + +--let $is_relay_log= 1 +--let $binlog_file= query_get_value(SHOW SLAVE STATUS, Relay_Log_File, 1) +--source suite/rpl/include/rpl_show_log_events_with_varying_options.inc + +# +# PART II +# +# Although this second part of the test may seem redudant it is +# actually needed to assert that SHOW RELAYLOG EVENTS works properly +# with respect to the ordering of the relay log in relay-log.index. +# +# If no file is specified with "IN" then first relay log file in +# relay-log.index (ie, the oldest one) should be picked and its +# contents displayed. The same happens for SHOW BINLOG EVENTS, so we +# show them both. All in all, this is the reason for re-assert after +# MASTER and SLAVE's FLUSH LOGS operations. +# + +FLUSH LOGS; +--source include/wait_for_binlog_checkpoint.inc +-- connection master +FLUSH LOGS; +--source include/wait_for_binlog_checkpoint.inc +DROP TABLE t1; + +--let $is_relay_log= 0 +--let $binlog_file= query_get_value(SHOW MASTER STATUS, File, 1) +--source suite/rpl/include/rpl_show_log_events_with_varying_options.inc + +--sync_slave_with_master +--let $binlog_file= query_get_value(SHOW MASTER STATUS, File, 1) +--source suite/rpl/include/rpl_show_log_events_with_varying_options.inc + +--let $is_relay_log= 1 +--let $binlog_file= query_get_value(SHOW SLAVE STATUS, Relay_Log_File, 1) +--source suite/rpl/include/rpl_show_log_events_with_varying_options.inc + + +# clear show_binlog_event/show_relaylog_events parameters +let $binlog_file= ; +let $binlog_limit= ; diff --git a/mysql-test/suite/rpl/include/rpl_shutdown_wait_slaves.inc b/mysql-test/suite/rpl/include/rpl_shutdown_wait_slaves.inc new file mode 100644 index 00000000..4726bbe1 --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_shutdown_wait_slaves.inc @@ -0,0 +1,91 @@ +--connection server_1 + +CREATE TABLE t1 (a INT) ENGINE=innodb; + +--save_master_pos + +--connection server_2 +--sync_with_master + +--connection server_3 +--sync_with_master + +--connection server_4 +--source include/stop_slave.inc + +--connection server_1 +--disable_query_log +--let $count=1000 +while ($count) +{ + INSERT INTO t1 SET a=1; + --dec $count +} +--enable_query_log +--save_master_pos + +# Shutdown master and restart server_4 who will be waiting for the master +# to start replication at its shutdown beginning phase. +# The being forked out server_4 dump thread must relate to a record +# in slave_list, and it won't start sending out binlog events +# until has received a signal from the shutdown thread. +# This also proves delivery to a started-in-middle-of-shutdown slave. +--connection server_1 +SET @@GLOBAL.debug_dbug="+d,simulate_delay_at_shutdown"; + +--connection server_4 +--source include/start_slave.inc + +--connection server_1 +--write_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +wait +EOF +# --shutdown_server +--send SHUTDOWN WAIT FOR ALL SLAVES +--reap +--source include/wait_until_disconnected.inc +# +# MDEV-18450 liveness condition: +# Despite shutdown even "late" slave #4 is in sync +# +--connection server_4 +--sync_with_master + +--connection server_3 +--sync_with_master + +--connection server_2 +--sync_with_master + +--connection server_1 +--append_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +restart +EOF + +--connection default +--enable_reconnect +--source include/wait_until_connected_again.inc +--connection server_1 +--enable_reconnect +--source include/wait_until_connected_again.inc + +# +# Cleanup +# +--connection server_1 +DROP TABLE t1; + +--connection server_2 +--disable_warnings +--source include/start_slave.inc +--enable_warnings + +--connection server_3 +--disable_warnings +--source include/start_slave.inc +--enable_warnings + +--connection server_4 +--disable_warnings +--source include/start_slave.inc +--enable_warnings diff --git a/mysql-test/suite/rpl/include/rpl_slave_max_statement_time.inc b/mysql-test/suite/rpl/include/rpl_slave_max_statement_time.inc new file mode 100644 index 00000000..e064fb07 --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_slave_max_statement_time.inc @@ -0,0 +1,79 @@ +# +# Helper test file to ensure that an event running on a slave which executes +# for longer than @@slave_max_statement_time will time out. By default, it will +# use the sleep function to imitate a long running function. This can be +# changed to use locks using the parameter with_lock. +# +# Parameters: +# with_lock (boolean, in) : Changes the long running command from using SLEEP +# to using locks. In particular, the MTR test will take the table level +# write lock on the slave side, while the slave concurrently tries to +# execute an insert statement. +# +# use_load_data (boolean, in) : If in row logging format, uses LOAD DATA +# INFILLE command to create Load_log_events to create the events which +# should time out +# + +--connection master +create table t1(a int not null auto_increment, b int, primary key(a)) engine=InnoDB; +--source include/save_master_gtid.inc + +--connection slave +--source include/sync_with_master_gtid.inc +--source include/stop_slave.inc +SET @old_slave_max_statement_time=@@GLOBAL.slave_max_statement_time; +SET GLOBAL slave_max_statement_time=0.75; + +--connection master +--echo # Long running command due to a lock conflict +if (!$use_load_data) +{ + INSERT INTO t1(b) VALUES (1); +} +if ($use_load_data) +{ + load data infile '../../std_data/rpl_loaddata.dat' into table t1; +} +--source include/save_master_gtid.inc + +--connection slave1 + BEGIN; INSERT INTO t1(b) VALUES (1); + +--connection slave + +--echo # Starting slave to receive event which will take longer to execute +--echo # than slave_max_statement_time +START SLAVE; + +# ER_SLAVE_STATEMENT_TIMEOUT +--let $slave_sql_errno= 4192 +--source include/wait_for_slave_sql_error.inc + +--echo # Ensuring event was not processed.. +--let $t1_count= `select count(*) from t1` +if ($t1_count != 0) +{ + --die Event should have timed out on the slave and not been executed +} +--echo # ..success + +--echo # Remove slave timeout and catch up to master +SET GLOBAL slave_max_statement_time=0; + +--connection slave1 + ROLLBACK; + +--source include/start_slave.inc +--source include/sync_with_master_gtid.inc + +--echo # Test case cleanup +--connection master +DROP TABLE t1; +--source include/save_master_gtid.inc + +--connection slave +--source include/sync_with_master_gtid.inc +--source include/stop_slave.inc +SET GLOBAL slave_max_statement_time=@old_slave_max_statement_time; +--source include/start_slave.inc diff --git a/mysql-test/suite/rpl/include/rpl_start_stop_slave.test b/mysql-test/suite/rpl/include/rpl_start_stop_slave.test new file mode 100644 index 00000000..ae5f8361 --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_start_stop_slave.test @@ -0,0 +1,216 @@ +# Slow test, don't run during staging part +source include/not_staging.inc; + +# +# Bug#6148 () +# +# Let the master do lots of insertions + +connection master; +call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT"); + +connection slave; +call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT"); + +connection master; +create table t1(n int); +sync_slave_with_master; +stop slave; +--source include/wait_for_slave_to_stop.inc +connection master; +let $1=2500; +disable_query_log; +while ($1) +{ + eval insert into t1 values($1); + dec $1; +} +enable_query_log; +save_master_pos; + +connection slave; +start slave; +let $wait_condition= SELECT COUNT(*) > 0 FROM t1; +source include/wait_condition.inc; +stop slave io_thread; +start slave io_thread; +source include/wait_for_slave_to_start.inc; +sync_with_master; + +connection master; +drop table t1; +sync_slave_with_master; + + +# +# Bug#38205 Row-based Replication (RBR) causes inconsistencies... +# Bug#319 if while a non-transactional slave is replicating a transaction... +# +# Verifying that STOP SLAVE does not interrupt excution of a group +# execution of events if the group can not roll back. +# Killing the sql thread continues to provide a "hard" stop (the +# part II, moved to the bugs suite as it's hard to make it +# deterministic with KILL). +# + +# +# Part I. The being stopped sql thread finishes first the current group of +# events if the group contains an event on a non-transaction table. + +connection master; +create table t1i(n int primary key) engine=innodb; +create table t2m(n int primary key) engine=myisam; +begin; +insert into t1i values (1); +insert into t1i values (2); +insert into t1i values (3); +commit; + +sync_slave_with_master; +connection slave; +begin; +insert into t1i values (5); + +connection master; +let $pos0_master= query_get_value(SHOW MASTER STATUS, Position, 1); +begin; +insert into t1i values (4); +insert into t2m values (1); # non-ta update to process +insert into t1i values (5); # to block at. to be played with stopped +commit; + +connection slave; +# slave sql thread must be locked out by the conn `slave' explicit lock +let $pos0_slave= query_get_value(SHOW SLAVE STATUS, Exec_Master_Log_Pos, 1); +--disable_query_log +eval select $pos0_master - $pos0_slave as zero; +--enable_query_log + +connection slave1; +let $count= 1; +let $table= t2m; +source include/wait_until_rows_count.inc; +send stop slave; + +connection slave; +rollback; # release the sql thread + +connection slave1; +reap; +source include/wait_for_slave_to_stop.inc; +let $sql_status= query_get_value(SHOW SLAVE STATUS, Slave_SQL_Running, 1); +--echo *** sql thread is *not* running: $sql_status *** + + +connection master; +let $pos1_master= query_get_value(SHOW MASTER STATUS, Position, 1); + +connection slave; + +let $pos1_slave= query_get_value(SHOW SLAVE STATUS, Exec_Master_Log_Pos, 1); + +--echo *** the prove: the stopped slave has finished the current transaction *** + +--disable_query_log +select count(*) as five from t1i; +eval select $pos1_master - $pos1_slave as zero; +eval select $pos1_slave > $pos0_slave as one; +--enable_query_log + +source include/start_slave.inc; + +# clean-up +connection master; +drop table t1i, t2m; + +sync_slave_with_master; + +--echo # +--echo # Bug#56096 STOP SLAVE hangs if executed in parallel with user sleep +--echo # + +--connection master + +--disable_warnings +DROP TABLE IF EXISTS t1; +--enable_warnings + +CREATE TABLE t1 (a INT ); + +sync_slave_with_master; + +--connection slave1 +--echo # lock table for synchronization +LOCK TABLES t1 WRITE; + +--connection master +--echo # insert into the table +INSERT INTO t1 SELECT SLEEP(4); + +--connection slave +--echo # Slave: wait for the insert +let $wait_condition= + SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.PROCESSLIST + WHERE STATE = "Waiting for table metadata lock" + AND INFO = "INSERT INTO t1 SELECT SLEEP(4)"; +--source include/wait_condition.inc + +--echo # send slave stop +--send STOP SLAVE + +--connection slave1 +--echo # wait for stop slave +let $wait_condition= + SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.PROCESSLIST + WHERE INFO = "STOP SLAVE"; +--source include/wait_condition.inc + +--echo # Slave1: unlock the table +UNLOCK TABLES; + +--connection slave +--echo # wait for the slave to stop +--reap +--source include/wait_for_slave_to_stop.inc + +--echo # Start slave again +--source include/start_slave.inc + +--echo # Clean up +--connection master +DROP TABLE t1; +sync_slave_with_master; + +# +# bug#3593869-64035 attempt to read a member of event_coordinates +# referenced by NULL pointer crashes server. +# Testing how out of valid range position value is handled with an error. +# + +--connection master +RESET MASTER; +let $master_pos= query_get_value(SHOW MASTER STATUS, Position, 1); +let $master_pos= `SELECT $master_pos + 1`; + +--connection slave +--source include/stop_slave.inc +--replace_regex /[0-9]+/MASTER_POS/ +eval CHANGE MASTER TO master_log_pos=$master_pos, master_use_gtid=no; + +START SLAVE; +# ER_MASTER_FATAL_ERROR_READING_BINLOG 1236 +--let $slave_param=Last_IO_Errno +--let $slave_param_value=1236 +--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 + +--source include/stop_slave.inc +RESET SLAVE; + +--connection master +RESET MASTER; + +# Slave is stopped by bug#3593869-64035 tests. diff --git a/mysql-test/suite/rpl/include/rpl_stm_EE_err2.test b/mysql-test/suite/rpl/include/rpl_stm_EE_err2.test new file mode 100644 index 00000000..2f443535 --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_stm_EE_err2.test @@ -0,0 +1,41 @@ +################################### +# Author: JBM +# Date: 2006-01-11 +# Purpose: Second test case from +# rpl_EE_err.test split out +# from orginal to make the +# first work with both RBR and SBR +################################### +#REQUIREMENT: An INSERT with a faked duplicate entry error on +#master should be replicated to slave and force the slave to stop +#(since the slave can't cause a faked error to re-occur). +################################### + +-- source include/master-slave.inc + +connection master; +eval create table t1 (a int, unique(a)) engine=$engine_type; +set sql_log_bin=0; +insert into t1 values(2); +set sql_log_bin=1; + +--error ER_DUP_ENTRY +insert into t1 values(1),(2); +drop table t1; + +connection slave; +--source include/wait_for_slave_sql_to_stop.inc +call mtr.add_suppression("Slave SQL.*Query caused different errors on master and slave.*Error on master:.* error code=1062.*Error on slave:.* error.* 0"); +let $error= query_get_value(SHOW SLAVE STATUS, Last_SQL_Error, 1); +let $errno= query_get_value(SHOW SLAVE STATUS, Last_SQL_Errno, 1); +--echo Error: "$error" (expected different error codes on master and slave) +--echo Errno: "$errno" (expected 0) +drop table t1; +--source include/stop_slave.inc +# Clear error messages. +RESET SLAVE; + +# End of 4.1 tests + +--let $rpl_only_running_threads= 1 +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/include/rpl_stm_create_if_not_exists.test b/mysql-test/suite/rpl/include/rpl_stm_create_if_not_exists.test new file mode 100644 index 00000000..cecbd45c --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_stm_create_if_not_exists.test @@ -0,0 +1,268 @@ +--echo +--echo +connection master; + +if ($is_temporary) +{ + --let $_temporary=TEMPORARY +} + +CREATE TABLE t2(c1 INT, c2 char(10)); +INSERT INTO t2 VALUES(1, 'abc'), (2, 'abc'); + +--echo +--echo # The original query should be binlogged if the table does not exist. +--echo # ------------------------------------------------------------------ +--echo +let binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1); +eval CREATE $_temporary TABLE IF NOT EXISTS t1 (c1 INT , c2 INT, c3 char(10), c4 INT KEY) + SELECT 'abc' AS c3, 1 AS c4; +source include/show_binlog_events.inc; + +--sync_slave_with_master +--connection master + +if (!$is_temporary) +{ + --let $diff_tables= master:t1,slave:t1 + --source include/diff_tables.inc +} + +--echo +--echo # The statement should be binlogged as two events. one is +--echo # 'CREATE $_temporary TABLE IF NOT EXISTS ..', another one is +--echo # 'INSERT ... SELECT'. +--echo # ------------------------------------------------------------------ +--echo +let binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1); +eval CREATE $_temporary TABLE IF NOT EXISTS t1 + SELECT 'abc', 2; +source include/show_binlog_events.inc; + +--sync_slave_with_master +--connection master + +if (!$is_temporary) +{ + --let $diff_tables= master:t1,slave:t1 + --source include/diff_tables.inc +} + +--echo +--echo # Verify if it can be binlogged with right database name when the table +--echo # is not in the default database +--echo +--disable_warnings +DROP DATABASE IF EXISTS db1; +--enable_warnings +CREATE DATABASE db1; +USE db1; + +let binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1); +eval CREATE $_temporary TABLE IF NOT EXISTS test.t1 + SELECT 'abc', 20; +source include/show_binlog_events.inc; + +--sync_slave_with_master +--connection master + +if (!$is_temporary) +{ + --let $diff_tables= master:test.t1,slave:test.t1 + --source include/diff_tables.inc +} +USE test; +DROP DATABASE db1; + +--echo +--echo # It should be binlogged as 'REPLACE ... SELECT' +--echo # if the original statement has option REPLACE +--echo +let binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1); +eval CREATE $_temporary TABLE IF NOT EXISTS t1 + REPLACE SELECT '123', 2; +source include/show_binlog_events.inc; + +--sync_slave_with_master +--connection master + +if (!$is_temporary) +{ + --let $diff_tables= master:t1,slave:t1 + --source include/diff_tables.inc +} + +--echo +--echo # It should be binlogged as 'INSERT IGNORE... SELECT' +--echo # if the original statement has option IGNORE +--echo +let binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1); +eval CREATE $_temporary TABLE IF NOT EXISTS t1 + IGNORE SELECT '123', 2; +source include/show_binlog_events.inc; + +--sync_slave_with_master +--connection master + +if (!$is_temporary) +{ + --let $diff_tables= master:t1,slave:t1 + --source include/diff_tables.inc +} + +--echo +--echo # Nothing should be binlogged if error happens and no any row is inserted +--echo +let binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1); +--error ER_DUP_ENTRY +eval CREATE $_temporary TABLE IF NOT EXISTS t1 + SELECT '123', 2; +source include/show_binlog_events.inc; + +--sync_slave_with_master +--connection master + +if (!$is_temporary) +{ + --let $diff_tables= master:t1,slave:t1 + --source include/diff_tables.inc +} + +--echo +--echo # Verify it can binlog well when there are some braces('(') +--echo +let binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1); +eval CREATE $_temporary TABLE IF NOT EXISTS t1 + (SELECT '123', 3) UNION (SELECT '123', 4); +eval CREATE $_temporary TABLE IF NOT EXISTS t1 + REPLACE (SELECT 'abc', 3) UNION (SELECT 'abc', 4); +eval CREATE $_temporary TABLE IF NOT EXISTS t1 + IGNORE (SELECT '123', 3) UNION (SELECT '123', 4); +source include/show_binlog_events.inc; + +--sync_slave_with_master +--connection master + +if (!$is_temporary) +{ + --let $diff_tables= master:t1,slave:t1 + --source include/diff_tables.inc +} + +if (!$is_temporary) +{ + --echo + --echo # Throw a warning that table already exists and don't insert anything + --echo + CREATE VIEW t3 AS SELECT * FROM t2; + let binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1); + + CREATE TABLE IF NOT EXISTS t3 + SELECT '123', 2; + source include/show_binlog_events.inc; + DROP VIEW t3; +} + +--echo +--echo # The statement can be binlogged correctly when it is in a SP/EVENT/TRIGGER +--echo + +--disable_warnings +DROP PROCEDURE IF EXISTS p1; +--enable_warnings +eval CREATE PROCEDURE p1(IN a INT) + CREATE $_temporary TABLE IF NOT EXISTS t1 SELECT '123', a; + +let binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1); +call p1(500); +call p1(600); +source include/show_binlog_events.inc; + +--sync_slave_with_master +--connection master + +if (!$is_temporary) +{ + --let $diff_tables= master:t1,slave:t1 + --source include/diff_tables.inc +} +DROP PROCEDURE p1; + +--echo +--echo # The statement can be binlogged correctly when it is in a prepared statement +--echo +eval PREPARE stm FROM "CREATE $_temporary TABLE IF NOT EXISTS t1 SELECT '123', ?"; + +let binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1); +SET @a= 700; +EXECUTE stm USING @a; +SET @a= 800; +EXECUTE stm USING @a; +source include/show_binlog_events.inc; + +--sync_slave_with_master +--connection master + +if (!$is_temporary) +{ + --let $diff_tables= master:t1,slave:t1 + --source include/diff_tables.inc +} + +--echo +--echo # The statement can be binlogged correctly when it is in a conditional comment +--echo +let binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1); + +--echo # The whole statement in a conditional comment +eval /*!CREATE $_temporary TABLE IF NOT EXISTS t1 + SELECT 'abc', 900*/; +source include/show_binlog_events.inc; +let binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1); + +--echo +--echo # There is an long comment before SELECT +eval /*!CREATE $_temporary /*blabla*/ TABLE IF NOT EXISTS t1 + SELECT 'abc', 901*/; +source include/show_binlog_events.inc; +let binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1); + +--echo +--echo # Conditional comment starts just from SELECT +eval CREATE $_temporary TABLE IF NOT EXISTS t1 + /*!SELECT 'abc',*/ 902; +source include/show_binlog_events.inc; +let binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1); + +--echo +--echo # Only SELECT keyword is in the conditional comment +eval CREATE $_temporary TABLE IF NOT EXISTS t1 + /*!SELECT*/ /*!'abc',*/ 904; +source include/show_binlog_events.inc; +let binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1); + +--echo +--echo # Conditional comment is after SELECT keyword +eval CREATE $_temporary TABLE IF NOT EXISTS t1 + SELECT /*!'abc',*/ 903; +source include/show_binlog_events.inc; +let binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1); + +--echo +--echo # Conditional comment ends just before SELECT keyword +eval /*!CREATE $_temporary TABLE IF NOT EXISTS t1 + */SELECT 'abc', 905; +source include/show_binlog_events.inc; + +--sync_slave_with_master +--connection master + +if (!$is_temporary) +{ + --let $diff_tables= master:t1,slave:t1 + --source include/diff_tables.inc +} + +DROP TABLE t2; +eval DROP $_temporary TABLE t1; + diff --git a/mysql-test/suite/rpl/include/rpl_stop_middle_group.test b/mysql-test/suite/rpl/include/rpl_stop_middle_group.test new file mode 100644 index 00000000..ac01fb04 --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_stop_middle_group.test @@ -0,0 +1,148 @@ +# Proving that stopping in the middle of applying a group of events +# does not have immediate effect if a non-transaction table has been changed. +# The slave sql thread has to try to finish applying first. +# The tests rely on simulation of the killed status. +# The matter of testing correlates to some of `rpl_start_stop_slave' that does +# not require `have_debug'. + +connection master; + +call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT"); + +create table tm (a int auto_increment primary key) engine=myisam; +create table ti (a int auto_increment primary key) engine=innodb; + +sync_slave_with_master; +SET @saved_dbug = @@GLOBAL.debug_dbug; +set @@global.debug_dbug="d,stop_slave_middle_group"; + +connection master; + +begin; +insert into ti set a=null; +insert into tm set a=null; # to simulate killed status on the slave +commit; + +connection slave; +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"); +call mtr.add_suppression("Slave SQL.*Slave SQL Thread stopped with incomplete event group having non-transactional changes"); + +# slave will catch the killed status but won't shut down immediately +# only after the whole group has done (commit) + +source include/wait_for_slave_sql_to_stop.inc; + +# checking: no error and the group is finished + +let $error= query_get_value("SHOW SLAVE STATUS", Last_SQL_Error, 1); +let $read = query_get_value("SHOW SLAVE STATUS", Read_Master_Log_Pos, 1); +let $exec = query_get_value("SHOW SLAVE STATUS", Exec_Master_Log_Pos, 1); +--disable_query_log +eval SELECT $read = $exec into @check; +--enable_query_log +eval SELECT "NO$error" AS Last_SQL_Error, @check as `true`; +select count(*) as one from tm; +select count(*) as one from ti; + +set @@global.debug_dbug=@saved_dbug; + +# +# bug#45940 issues around rli->last_event_start_time +# Testing of slave stopped after it had waited (in vain) for +# the group be finished. +# It could not be finished because of simulation of failure to +# receive the terminal part +# The test relay on simulation of the incomplete group in the relay log + +# Two cases are verified: a mixed transacton and a mixed multi-table update. +# +# The mixed transacton. +# +source include/start_slave.inc; + +connection master; + +truncate table tm; # cleanup of former tests +truncate table ti; + +#connection slave; +sync_slave_with_master; + +set @@global.debug_dbug="d,stop_slave_middle_group,incomplete_group_in_relay_log"; + +connection master; + +begin; +insert into ti set a=null; +insert into tm set a=null; +commit; + +connection slave; + +# slave will catch the killed status, won't shut down immediately +# but does it eventually having the whole group unfinished (not committed) + +source include/wait_for_slave_sql_to_stop.inc; + +# checking: the error and group unfinished + +let $error= query_get_value("SHOW SLAVE STATUS", Last_SQL_Error, 1); +let $read = query_get_value("SHOW SLAVE STATUS", Read_Master_Log_Pos, 1); +let $exec = query_get_value("SHOW SLAVE STATUS", Exec_Master_Log_Pos, 1); +--disable_query_log +eval SELECT $read - $exec > 0 into @check; +--enable_query_log +eval SELECT "$error" AS Last_SQL_Error, @check as `true`; +select count(*) as one from tm; +select count(*) as zero from ti; + +set @@global.debug_dbug=@saved_dbug; + +# +# The mixed multi-table update +# +stop slave; +truncate table tm; +source include/start_slave.inc; + +connection master; + +#connection slave; +sync_slave_with_master; +set @@global.debug_dbug="d,stop_slave_middle_group,incomplete_group_in_relay_log"; + +connection master; +update tm as t1, ti as t2 set t1.a=t1.a * 2, t2.a=t2.a * 2; + +connection slave; + +# slave will catch the killed status, won't shut down immediately +# but does it eventually having the whole group unfinished (not committed) +# + +source include/wait_for_slave_sql_to_stop.inc; + +# checking: the error and group unfinished + +let $error= query_get_value("SHOW SLAVE STATUS", Last_SQL_Error, 1); +let $read = query_get_value("SHOW SLAVE STATUS", Read_Master_Log_Pos, 1); +let $exec = query_get_value("SHOW SLAVE STATUS", Exec_Master_Log_Pos, 1); +--disable_query_log +eval SELECT $read - $exec > 0 into @check; +--enable_query_log +eval SELECT "$error" AS Last_SQL_Error, @check as `true`; +select max(a) as two from tm; +select max(a) as one from ti; + +SET @@GLOBAL.debug_dbug = @saved_dbug; +# +# clean-up +# + +# the sql thread has an error, so reset replication state +--let $rpl_only_running_threads= 1 +--source include/rpl_reset.inc + +connection master; +drop table tm, ti; +--sync_slave_with_master diff --git a/mysql-test/suite/rpl/include/rpl_stop_slave.test b/mysql-test/suite/rpl/include/rpl_stop_slave.test new file mode 100644 index 00000000..12f99ed1 --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_stop_slave.test @@ -0,0 +1,56 @@ +# +# Auxiliary file which is used to test BUG#56118 +# +# Slave should apply all statements in the transaction before stop if any +# temporary table is created or dropped. +# +# USEAGE: +# --let $tmp_table_stm= a SQL statement +# --source suite/rpl/include/rpl_stop_slave.test +# + +if (!$tmp_table_stm) +{ + --echo \$tmp_table_stm is NULL + --die $tmp_table_stm is NULL +} + +connection master; +BEGIN; +DELETE FROM t1; +eval $tmp_table_stm; +INSERT INTO t1 VALUES (1); +DROP TEMPORARY TABLE tt1; +COMMIT; + +connection slave; + +# To check if slave SQL thread is applying INSERT statement +let $show_statement= SHOW PROCESSLIST; +let $field= Info; +let $condition= LIKE 'INSERT%'; +source include/wait_show_condition.inc; + +send STOP SLAVE SQL_THREAD; + +connection slave1; +--echo # To resume slave SQL thread +SET DEBUG_SYNC= 'now SIGNAL signal.continue'; +SET DEBUG_SYNC= 'now WAIT_FOR signal.continued'; +SET DEBUG_SYNC= 'RESET'; + +connection slave; +reap; +source include/wait_for_slave_sql_to_stop.inc; + +--echo # Slave should stop after the transaction has committed. +--echo # So t1 on master is same to t1 on slave. +--let $diff_tables= master:t1, slave:t1 +--source include/diff_tables.inc + +connection slave; +START SLAVE SQL_THREAD; +source include/wait_for_slave_sql_to_start.inc; + +connection master; +sync_slave_with_master; diff --git a/mysql-test/suite/rpl/include/rpl_sv_relay_space.test b/mysql-test/suite/rpl/include/rpl_sv_relay_space.test new file mode 100644 index 00000000..6edbbf68 --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_sv_relay_space.test @@ -0,0 +1,24 @@ +source include/master-slave.inc; + +# +# Bug#7100 relay_log_space_max missing from SHOW VARIABLES +# +SHOW VARIABLES LIKE 'relay_log_space_limit'; + +# Matz says: I have no idea what this is supposed to test, but it has +# potential for generating different results with some storage engines +# that process rows in an order not dependent on the insertion order. + +eval CREATE TABLE t1 (name varchar(64), age smallint(3))ENGINE=$engine_type; +INSERT INTO t1 SET name='Andy', age=31; +INSERT INTO t1 SET name='Jacob', age=2; +INSERT INTO t1 SET name='Caleb', age=1; +ALTER TABLE t1 ADD id int(8) ZEROFILL AUTO_INCREMENT PRIMARY KEY, + ALGORITHM=COPY; +SELECT * FROM t1 ORDER BY id; +sync_slave_with_master; +SELECT * FROM t1 ORDER BY id; +connection master; +DROP TABLE t1; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/include/rpl_test_framework.inc b/mysql-test/suite/rpl/include/rpl_test_framework.inc new file mode 100644 index 00000000..dbcdd317 --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_test_framework.inc @@ -0,0 +1,85 @@ +# ==== Purpose ==== +# +# Auxiliary file used by suite/rpl/t/rpl_test_framework.test +# +# The purpose is to check that the sync chain generated in +# rpl_change_topology.inc (invoked from rpl_init.inc) is correct. This +# is done in two ways: +# (1) Print the sync chain. +# (2) Execute a statement and verify that it replicates to all slaves. +# +# +# ==== Implementation ==== +# +# Does this: +# (1) Set up a given replication topology (rpl_init.inc) +# (2) Print $rpl_sync_chain +# (3) Execute "DELETE FROM t1" and then "INSERT INTO t1" on the master +# (4) Sync and compare all servers. +# (5) Clean up the replication topology (rpl_end.inc) +# +# (Technical detail: Since DELETE FROM t1 is not executed at the end, +# some servers may have rows left in t1 from a previous invocation of +# rpl_test_framework.inc. Therefore, this file will only work in +# statement mode where "DELETE FROM t1" removes rows that exist on +# slave but not on master.) +# +# +# ==== Usage ==== +# +# --let $rpl_server_count= +# --let $rpl_topology= +# --let $masters= +# [--let $rpl_diff_servers= ] +# --source suite/rpl/include/rpl_test_framework.inc +# +# Parameters: +# $next_number +# The INSERT statement will insert $next_number into t1, and +# $next_number will increase by 1. +# +# $rpl_server_count, $rpl_topology: +# See include/rpl_init.inc +# +# $masters +# This should be a list of numbers, each identifying a server. +# The DELETE and INSERT statements will be executed on all servers +# in the list. +# +# $rpl_diff_servers +# See include/rpl_diff.inc + +--source include/rpl_init.inc +--source include/rpl_generate_sync_chain.inc +--echo rpl_sync_chain= '$rpl_sync_chain' + +--inc $next_number + +# Iterate over masters +while ($masters) +{ + --let $master_i= `SELECT SUBSTRING_INDEX('$masters', ',', 1)` + --let $masters= `SELECT SUBSTRING('$masters', LENGTH('$master_i') + 2)` + + # Connect to master and execute statement + connection server_$master_i; + DELETE FROM t1; + --eval INSERT INTO t1 VALUES ($next_number) +} + +--source include/rpl_sync.inc + +# Compare all servers. +--let $diff_tables= server_$rpl_server_count:t1 +--let $server_i= $rpl_server_count +--dec $server_i +while ($server_i) +{ + --let $diff_tables= server_$server_i:t1,$diff_tables + --dec $server_i +} +--source include/diff_tables.inc + +--let $diff_servers= +--let $masters= +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/include/rpl_tmp_table_and_DDL.test b/mysql-test/suite/rpl/include/rpl_tmp_table_and_DDL.test new file mode 100644 index 00000000..9cf28728 --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_tmp_table_and_DDL.test @@ -0,0 +1,159 @@ +# +# This test verify if executing DDL statement before trying to manipulate +# a temporary table causes row-based replication to break with error 'table +# does not exist'. +# + +# CREATE TABLE when a temporary table is open. +CREATE TEMPORARY TABLE t1 (a INT); +EVAL CREATE TABLE t2 (a INT, b INT) ENGINE= $ENGINE_TYPE; +INSERT INTO t1 VALUES (1); + +# CREATE EVENT when a temporary table is open. +CREATE EVENT e1 ON SCHEDULE EVERY 10 HOUR DO SELECT 1; +INSERT INTO t1 VALUES (1); + +# ALTER EVENT when a temporary table is open. +ALTER EVENT e1 ON SCHEDULE EVERY 20 HOUR DO SELECT 1; +INSERT INTO t1 VALUES (1); + +# DROP EVENT when a temporary table is open. +DROP EVENT IF EXISTS e1; +INSERT INTO t1 VALUES (1); + +# CREATE PROCEDURE when a temporary table is open. +CREATE PROCEDURE p1() SELECT 1; +INSERT INTO t1 VALUES (1); + +# Alter PROCEDURE when a temporary table is open. +ALTER PROCEDURE p1 SQL SECURITY INVOKER; +INSERT INTO t1 VALUES (1); + +# CREATE FUNCTION when a temporary table is open. +CREATE FUNCTION f1() RETURNS INT RETURN 123; +INSERT INTO t1 VALUES (1); + +# ALTER FUNCTION when a temporary table is open. +ALTER FUNCTION f1 SQL SECURITY INVOKER; +INSERT INTO t1 VALUES (1); + +# CREATE DATABASE when a temporary table is open. +CREATE DATABASE mysqltest1; +INSERT INTO t1 VALUES (1); + +# DROP DATABASE when a temporary table is open. +DROP DATABASE mysqltest1; +INSERT INTO t1 VALUES (1); + +# CREATE USER when a temporary table is open. +CREATE USER test_1@localhost; +INSERT INTO t1 VALUES (1); + +# GRANT select on table to user when a temporary table is open. +GRANT SELECT ON t2 TO test_1@localhost; +INSERT INTO t1 VALUES (1); + +# GRANT all on function to user when a temporary table is open. +GRANT ALL ON f1 TO test_1@localhost; +INSERT INTO t1 VALUES (1); + +# GRANT all on procedure to user when a temporary table is open. +GRANT ALL ON p1 TO test_1@localhost; +INSERT INTO t1 VALUES (1); + +# GRANT usage on *.* to user when a temporary table is open. +GRANT USAGE ON *.* TO test_1@localhost; +INSERT INTO t1 VALUES (1); + +# REVOKE ALL PRIVILEGES on function to user when a temporary table is open. +REVOKE ALL PRIVILEGES ON f1 FROM test_1@localhost; +INSERT INTO t1 VALUES (1); + +# REVOKE ALL PRIVILEGES on procedure to user when a temporary table is open. +REVOKE ALL PRIVILEGES ON p1 FROM test_1@localhost; +INSERT INTO t1 VALUES (1); + +# REVOKE ALL PRIVILEGES on table to user when a temporary table is open. +REVOKE ALL PRIVILEGES ON t2 FROM test_1@localhost; +INSERT INTO t1 VALUES (1); + +# REVOKE usage on *.* from user when a temporary table is open. +REVOKE USAGE ON *.* FROM test_1@localhost; +INSERT INTO t1 VALUES (1); + +# RENAME USER when a temporary table is open. +RENAME USER test_1@localhost TO test_2@localhost; +INSERT INTO t1 VALUES (1); + +# DROP USER when a temporary table is open. +DROP USER test_2@localhost; +INSERT INTO t1 VALUES (1); + +# Test ACL statement in sub statement +DELIMITER |; +CREATE PROCEDURE p2() +BEGIN + # CREATE USER when a temporary table is open. + CREATE TEMPORARY TABLE t3 (a INT); + CREATE USER test_2@localhost; + INSERT INTO t1 VALUES (1); + + # GRANT select on table to user when a temporary table is open. + GRANT SELECT ON t2 TO test_2@localhost; + INSERT INTO t1 VALUES (1); + + # GRANT all on function to user when a temporary table is open. + GRANT ALL ON f1 TO test_2@localhost; + INSERT INTO t1 VALUES (1); + + # GRANT all on procedure to user when a temporary table is open. + GRANT ALL ON p1 TO test_2@localhost; + INSERT INTO t1 VALUES (1); + + # GRANT usage on *.* to user when a temporary table is open. + GRANT USAGE ON *.* TO test_2@localhost; + INSERT INTO t1 VALUES (1); + + # REVOKE ALL PRIVILEGES on function to user when a temporary table is open. + REVOKE ALL PRIVILEGES ON f1 FROM test_2@localhost; + INSERT INTO t1 VALUES (1); + + # REVOKE ALL PRIVILEGES on procedure to user when a temporary table is open. + REVOKE ALL PRIVILEGES ON p1 FROM test_2@localhost; + INSERT INTO t1 VALUES (1); + + # REVOKE ALL PRIVILEGES on table to user when a temporary table is open. + REVOKE ALL PRIVILEGES ON t2 FROM test_2@localhost; + INSERT INTO t1 VALUES (1); + + # REVOKE usage on *.* from user when a temporary table is open. + REVOKE USAGE ON *.* FROM test_2@localhost; + INSERT INTO t1 VALUES (1); + + # RENAME USER when a temporary table is open. + RENAME USER test_2@localhost TO test_3@localhost; + INSERT INTO t1 VALUES (1); + + # DROP USER when a temporary table is open. + DROP USER test_3@localhost; + INSERT INTO t1 VALUES (1); + DROP TEMPORARY TABLE t3; +END | +DELIMITER ;| + +# DROP PROCEDURE when a temporary table is open. +DROP PROCEDURE p1; +INSERT INTO t1 VALUES (1); +DROP PROCEDURE p2; +INSERT INTO t1 VALUES (1); + +# DROP FUNCTION when a temporary table is open. +DROP FUNCTION f1; +INSERT INTO t1 VALUES (1); + +# DROP TABLE when a temporary table is open. +DROP TABLE t2; +INSERT INTO t1 VALUES (1); + +DROP TEMPORARY TABLE t1; + diff --git a/mysql-test/suite/rpl/include/rpl_trig004.test b/mysql-test/suite/rpl/include/rpl_trig004.test new file mode 100644 index 00000000..4988fe87 --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_trig004.test @@ -0,0 +1,48 @@ +############################################################################# +# Original Author: JBM # +# Original Date: Aug/09/2005 # +############################################################################# +# TEST: Use after insert and before inset triggers and stored procdures to # +# Update and insert data # +############################################################################# +# Change Auth: JBM # +# Date: 2006-02-14 # +#################################################### + +# Begin clean up test section +connection master; +--disable_warnings +--error 0,1360 +DROP TRIGGER test.t1_bi_t2; +DROP TABLE IF EXISTS test.t1; +DROP TABLE IF EXISTS test.t2; + + +eval CREATE TABLE test.t1 (n MEDIUMINT NOT NULL AUTO_INCREMENT, d FLOAT, PRIMARY KEY(n))ENGINE=$engine_type; +eval CREATE TABLE test.t2 (n MEDIUMINT NOT NULL, f FLOAT, PRIMARY KEY(n))ENGINE=$engine_type; + + +delimiter //; +CREATE TRIGGER test.t1_bi_t2 BEFORE INSERT ON test.t2 FOR EACH ROW INSERT INTO test.t1 VALUES (NULL, 1.234)// +delimiter ;// + +INSERT INTO test.t2 VALUES (1, 0.0); +--error ER_DUP_ENTRY +INSERT INTO test.t2 VALUES (1, 0.0); + +#show binlog events; +select * from test.t1; +select * from test.t2; +sync_slave_with_master; +connection slave; +select * from test.t1; +select * from test.t2; + +connection master; + +DROP TRIGGER test.t1_bi_t2; +DROP TABLE test.t1; +DROP TABLE test.t2; + +sync_slave_with_master; +# End of 5.0 test case diff --git a/mysql-test/suite/rpl/include/rpl_truncate.test b/mysql-test/suite/rpl/include/rpl_truncate.test new file mode 100644 index 00000000..c169dfd0 --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_truncate.test @@ -0,0 +1,13 @@ +# Test to check for the different version of truncating a table. +# The statements are "TRUNCATE tbl" and "DELETE FROM tbl". We check +# the behaviour of each possible value for BINLOG_FORMAT. + +--source include/master-slave.inc + +let $trunc_stmt = TRUNCATE TABLE; +--source suite/rpl/include/rpl_truncate_helper.test + +let $trunc_stmt = DELETE FROM; +--source suite/rpl/include/rpl_truncate_helper.test + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/include/rpl_truncate_helper.test b/mysql-test/suite/rpl/include/rpl_truncate_helper.test new file mode 100644 index 00000000..ddfba6c5 --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_truncate_helper.test @@ -0,0 +1,29 @@ +--source include/rpl_reset.inc + +connection master; +eval CREATE TABLE t1 (a INT, b LONG) ENGINE=$engine; +INSERT INTO t1 VALUES (1,1), (2,2); +sync_slave_with_master; +connection master; +eval $trunc_stmt t1; +sync_slave_with_master; + +let $diff_tables= master:t1, slave:t1; +source include/diff_tables.inc; + +--echo ==== Test using a table with delete triggers ==== +connection master; +SET @count := 1; +eval CREATE TABLE t2 (a INT, b LONG) ENGINE=$engine; +CREATE TRIGGER trg1 BEFORE DELETE ON t1 FOR EACH ROW SET @count := @count + 1; +sync_slave_with_master; +connection master; +eval $trunc_stmt t1; +sync_slave_with_master; + +let $diff_tables= master:t2, slave:t2; +source include/diff_tables.inc; + +connection master; +DROP TABLE t1,t2; +sync_slave_with_master; diff --git a/mysql-test/suite/rpl/include/rpl_xa_empty_transaction.inc b/mysql-test/suite/rpl/include/rpl_xa_empty_transaction.inc new file mode 100644 index 00000000..4cb4fe89 --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_xa_empty_transaction.inc @@ -0,0 +1,10 @@ +# +# Helper file to run each empty-due-to-err XA transaction test case both with +# and without detaching from the connection when the transaction is prepared. +# + +--let $use_disconnect=0 +--source rpl_xa_empty_transaction_test_case.inc + +--let $use_disconnect=1 +--source rpl_xa_empty_transaction_test_case.inc diff --git a/mysql-test/suite/rpl/include/rpl_xa_empty_transaction_test_case.inc b/mysql-test/suite/rpl/include/rpl_xa_empty_transaction_test_case.inc new file mode 100644 index 00000000..6368336b --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_xa_empty_transaction_test_case.inc @@ -0,0 +1,131 @@ +# +# Helper script to create an XA transaction and validate it was not +# binlogged +# +# Parameters +# $xa_completion_action : The action to end the XA transaction, either +# COMMIT or ROLLBACK +# $trx_statements : A comma separated list specifying how to build +# the statements of the transaction. Each item in +# the list is either T (for transactional) or N +# (for non-transactional). An empty list will not +# add any statements to the transaction. +# $use_disconnect : When TRUE, disconnect after preparing the XA +# transaction to test the detach/rollback case +# + +# +# Setup +--let $generic_assert_text= should not binlog XA transaction + +--connection server_1 +--let server_1_datadir=`select @@datadir` + +--connection server_2 +--let server_2_datadir=`select @@datadir` + +--connection server_3 +--let server_3_datadir=`select @@datadir` + +--let assert_file=$MYSQLTEST_VARDIR/tmp/binlog_decoded.out + +--connection server_1 +CREATE TABLE tm (a INT PRIMARY KEY) engine=myisam; +CREATE TABLE ti (a INT PRIMARY KEY) engine=innodb; +--source include/save_master_gtid.inc + +--connection server_3 +--source include/sync_with_master_gtid.inc + +--connection server_1 + +if ($use_disconnect) +{ + --source include/count_sessions.inc + --connect(con1,localhost,root,,) +} + +XA START 'x'; +--let $_stmt_items= $trx_statements +--let $_ctr= 1 +while($_stmt_items) +{ + --let $_cur_stmt= `SELECT SUBSTRING_INDEX('$_stmt_items', ',', 1)` + --let $_stmt_items= `SELECT LTRIM(SUBSTRING('$_stmt_items', LENGTH('$_cur_stmt') + 2))` + + if (`SELECT strcmp("$_cur_stmt","T") = 0`) + { + --let $target_table= ti + } + + if (`SELECT strcmp("$_cur_stmt","N") = 0`) + { + --let $target_table= tm + } + + --error ER_DUP_ENTRY + --eval INSERT INTO $target_table VALUES ($_ctr),($_ctr); + inc $_ctr; + +} +XA END 'x'; +XA PREPARE 'x'; + +if ($use_disconnect) +{ + --disconnect con1 + --connection server_1 + --source include/wait_until_count_sessions.inc + XA RECOVER; + + --error ER_XA_RBROLLBACK + --eval XA $xa_completion_action 'x'; +} +if (!$use_disconnect) +{ + --eval XA $xa_completion_action 'x'; +} + +--source include/save_master_gtid.inc + +--let binlog_filename= query_get_value(SHOW MASTER STATUS, File, 1) +FLUSH LOGS; + +--echo # MYSQL_BINLOG server_1_datadir/binlog_filename --result-file=assert_file +--exec $MYSQL_BINLOG $server_1_datadir/$binlog_filename --result-file=$assert_file + +--let assert_text= server_1 $generic_assert_text +--let assert_count= 0 +--let assert_select= XA START|XA END|XA PREPARE|XA COMMIT|XA ROLLBACK +--source include/assert_grep.inc + +--connection server_2 +--source include/sync_with_master_gtid.inc +--let binlog_filename= query_get_value(SHOW MASTER STATUS, File, 1) +FLUSH LOGS; + +--echo # MYSQL_BINLOG server_2_datadir/binlog_filename --result-file=assert_file +--exec $MYSQL_BINLOG $server_2_datadir/$binlog_filename --result-file=$assert_file + +--let assert_text= server_2 $generic_assert_text +--source include/assert_grep.inc + +--connection server_3 +--source include/sync_with_master_gtid.inc +--let binlog_filename= query_get_value(SHOW MASTER STATUS, File, 1) +FLUSH LOGS; + +--echo # MYSQL_BINLOG server_3_datadir/binlog_filename --result-file=assert_file +--exec $MYSQL_BINLOG $server_3_datadir/$binlog_filename --result-file=$assert_file + +--let assert_text= server_3 $generic_assert_text +--source include/assert_grep.inc + +# +# Cleanup +--connection server_1 +DROP TABLE ti,tm; +--source include/save_master_gtid.inc + +--connection server_3 +--source include/sync_with_master_gtid.inc diff --git a/mysql-test/suite/rpl/include/rpl_xa_mixed_engines.inc b/mysql-test/suite/rpl/include/rpl_xa_mixed_engines.inc new file mode 100644 index 00000000..0707a040 --- /dev/null +++ b/mysql-test/suite/rpl/include/rpl_xa_mixed_engines.inc @@ -0,0 +1,183 @@ +# +# The test file is invoked from rpl.rpl_xa_survive_disconnect_mixed_engines +# +# The test file is orginized as three sections: setup, run and cleanup. +# The main logics is resided in the run section which generates +# three types of XA transaction: two kinds of mixed and one on non-transactional +# table. +# +# param $command one of three of: 'setup', 'run' or 'cleanup' +# param $xa_terminate how to conclude: 'XA COMMIT' or 'XA ROLLBACK' +# param $one_phase 'one_phase' can be opted with XA COMMIT above +# param $xa_prepare_opt '1' or empty can be opted to test with and without XA PREPARE +# param $xid arbitrary name for xa trx, defaults to 'xa_trx' +# Note '' is merely to underline, not a part of the value. +# + +if ($command == setup) +{ + # Test randomizes the following variable's value: + SET @@session.binlog_direct_non_transactional_updates := if(floor(rand()*10)%2,'ON','OFF'); + CREATE TABLE t (a INT) ENGINE=innodb; + CREATE TABLE tm (a INT) ENGINE=myisam; +} +if (!$xid) +{ + --let $xid=xa_trx +} +if ($command == run) +{ + ## Non-temporary table cases + # Non transactional table goes first + --eval XA START '$xid' + --disable_warnings + INSERT INTO tm VALUES (1); + INSERT INTO t VALUES (1); + --enable_warnings + --eval XA END '$xid' + if ($xa_prepare_opt) + { + --eval XA PREPARE '$xid' + } + --eval $xa_terminate '$xid' $one_phase + + # Transactional table goes first + --eval XA START '$xid' + --disable_warnings + INSERT INTO t VALUES (2); + INSERT INTO tm VALUES (2); + --enable_warnings + --eval XA END '$xid' + if ($xa_prepare_opt) + { + --eval XA PREPARE '$xid' + } + --eval $xa_terminate '$xid' $one_phase + + # The pure non-transactional table + --eval XA START '$xid' + --disable_warnings + INSERT INTO tm VALUES (3); + --enable_warnings + --eval XA END '$xid' + if ($xa_prepare_opt) + { + --eval XA PREPARE '$xid' + } + --eval $xa_terminate '$xid' $one_phase + + ## Temporary tables + # create outside xa use at the tail + CREATE TEMPORARY TABLE tmp_i LIKE t; + CREATE TEMPORARY TABLE tmp_m LIKE tm; + --eval XA START '$xid' + --disable_warnings + INSERT INTO t VALUES (4); + INSERT INTO tm VALUES (4); + INSERT INTO tmp_i VALUES (4); + INSERT INTO tmp_m VALUES (4); + INSERT INTO t SELECT * FROM tmp_i; + INSERT INTO tm SELECT * FROM tmp_m; + --enable_warnings + --eval XA END '$xid' + if ($xa_prepare_opt) + { + --eval XA PREPARE '$xid' + } + --eval $xa_terminate '$xid' $one_phase + + # temporary tables at the head + --eval XA START '$xid' + --disable_warnings + INSERT INTO tmp_i VALUES (5); + INSERT INTO tmp_m VALUES (5); + INSERT INTO t SELECT * FROM tmp_i; + INSERT INTO tm SELECT * FROM tmp_m; + INSERT INTO t VALUES (5); + INSERT INTO tm VALUES (5); + --enable_warnings + --eval XA END '$xid' + if ($xa_prepare_opt) + { + --eval XA PREPARE '$xid' + } + --eval $xa_terminate '$xid' $one_phase + + # create inside xa use at the tail + DROP TEMPORARY TABLE tmp_i; + DROP TEMPORARY TABLE tmp_m; + + --eval XA START '$xid' + --disable_warnings + INSERT INTO t VALUES (6); + INSERT INTO tm VALUES (6); + CREATE TEMPORARY TABLE tmp_i LIKE t; + CREATE TEMPORARY TABLE tmp_m LIKE tm; + INSERT INTO tmp_i VALUES (6); + INSERT INTO tmp_m VALUES (6); + INSERT INTO t SELECT * FROM tmp_i; + INSERT INTO tm SELECT * FROM tmp_m; + --enable_warnings + --eval XA END '$xid' + if ($xa_prepare_opt) + { + --eval XA PREPARE '$xid' + } + --eval $xa_terminate '$xid' $one_phase + + # use at the head + DROP TEMPORARY TABLE tmp_i; + DROP TEMPORARY TABLE tmp_m; + --eval XA START '$xid' + --disable_warnings + CREATE TEMPORARY TABLE tmp_i LIKE t; + CREATE TEMPORARY TABLE tmp_m LIKE tm; + INSERT INTO tmp_i VALUES (7); + INSERT INTO tmp_m VALUES (7); + INSERT INTO t SELECT * FROM tmp_i; + INSERT INTO tm SELECT * FROM tmp_m; + INSERT INTO t VALUES (7); + INSERT INTO tm VALUES (7); + --enable_warnings + --eval XA END '$xid' + if ($xa_prepare_opt) + { + --eval XA PREPARE '$xid' + } + --eval $xa_terminate '$xid' $one_phase + + # use at the tail and drop + --eval XA START '$xid' + --disable_warnings + INSERT INTO t VALUES (8); + INSERT INTO tm VALUES (8); + INSERT INTO tmp_i VALUES (8); + INSERT INTO tmp_m VALUES (8); + INSERT INTO t SELECT * FROM tmp_i; + INSERT INTO tm SELECT * FROM tmp_m; + DROP TEMPORARY TABLE tmp_i; + DROP TEMPORARY TABLE tmp_m; + --enable_warnings + --eval XA END '$xid' + if ($xa_prepare_opt) + { + --eval XA PREPARE '$xid' + } + --eval $xa_terminate '$xid' $one_phase + + ## Ineffective transactional table operation case + + --eval XA START '$xid' + UPDATE t SET a = 99 where a = -1; + --eval XA END '$xid' + if ($xa_prepare_opt) + { + --eval XA PREPARE '$xid' + } + --eval $xa_terminate '$xid' $one_phase +} + +if ($command == cleanup) +{ + DROP TABLE t, tm; +} diff --git a/mysql-test/suite/rpl/include/sql_multisource.inc b/mysql-test/suite/rpl/include/sql_multisource.inc new file mode 100644 index 00000000..761b6842 --- /dev/null +++ b/mysql-test/suite/rpl/include/sql_multisource.inc @@ -0,0 +1,45 @@ +# Populate the active connection server with events that come from varying +# domain and server ids + +--disable_query_log + +# Save old state +let $ORIG_GTID_DOMAIN_ID = `select @@session.gtid_domain_id`; +let $ORIG_SERVER_ID = `select @@session.server_id`; + +SET @@session.gtid_domain_id= 0; +SET @@session.server_id= 1; +CREATE TABLE t1 (a int); + +SET @@session.server_id= 3; +CREATE TABLE t2 (a int); +INSERT INTO t2 values (3); + +SET @@session.gtid_domain_id= 1; +SET @@session.server_id= 1; +CREATE TABLE t3 (a int); +INSERT INTO t3 values (4); + +SET @@session.server_id= 4; +CREATE TABLE t4 (a int); +INSERT INTO t4 values (5); + +SET @@session.gtid_domain_id= 0; +SET @@session.server_id= 1; +INSERT INTO t1 values (1); + +SET @@session.gtid_domain_id= 2; +SET @@session.server_id= 1; +CREATE TABLE t5 (a int); +INSERT INTO t5 values (6); + +SET @@session.gtid_domain_id= 0; +SET @@session.server_id= 1; +INSERT INTO t1 values (2); + +FLUSH LOGS; + +--eval SET @@session.gtid_domain_id= $ORIG_GTID_DOMAIN_ID +--eval SET @@session.server_id= $ORIG_SERVER_ID + +--enable_query_log diff --git a/mysql-test/suite/rpl/include/sql_out_of_order_gtid.inc b/mysql-test/suite/rpl/include/sql_out_of_order_gtid.inc new file mode 100644 index 00000000..82291a88 --- /dev/null +++ b/mysql-test/suite/rpl/include/sql_out_of_order_gtid.inc @@ -0,0 +1,43 @@ +# SQL file with out of order GTIDs coming from various domains and servers + +--disable_query_log + +# Save old state +let $ORIG_GTID_DOMAIN_ID = `select @@session.gtid_domain_id`; +let $ORIG_SERVER_ID = `select @@session.server_id`; + +SET @@session.gtid_domain_id= 0; +SET @@session.server_id= 1; +CREATE TABLE t1 (a int); +INSERT INTO t1 values (1); + +SET @@session.server_id= 3; +CREATE TABLE t2 (a int); +SET @@session.gtid_seq_no= 6; +INSERT INTO t2 values (2); +SET @@session.gtid_seq_no= 5; +INSERT INTO t2 values (1); +SET @@session.gtid_seq_no= 7; +INSERT INTO t2 values (3); + +SET @@session.gtid_domain_id= 1; +SET @@session.server_id= 1; +CREATE TABLE t3 (a int); +INSERT INTO t3 values (1); +SET @@session.gtid_seq_no= 4; +INSERT INTO t3 values (3); +SET @@session.gtid_seq_no= 3; +INSERT INTO t3 values (2); +SET @@session.gtid_seq_no= 5; +INSERT INTO t3 values (4); + +SET @@session.gtid_domain_id= 0; +SET @@session.server_id= 1; +INSERT INTO t1 values (2); + +FLUSH LOGS; + +--eval SET @@session.gtid_domain_id= $ORIG_GTID_DOMAIN_ID +--eval SET @@session.server_id= $ORIG_SERVER_ID + +--enable_query_log diff --git a/mysql-test/suite/rpl/include/start_alter_basic.inc b/mysql-test/suite/rpl/include/start_alter_basic.inc new file mode 100644 index 00000000..f6e4b6b3 --- /dev/null +++ b/mysql-test/suite/rpl/include/start_alter_basic.inc @@ -0,0 +1,60 @@ +# +# Run start alter basic tests (CA/RA with given engine) +# Params:- +# $engine +# $sync_slave +# master_node and slave_node connection should be defined + +--echo # $engine +--connection master_node +--eval create table t1(a int, b int) engine=$engine; +insert into t1 values(1,1); +insert into t1 values(2,2); +--echo # Normal Alter +alter table t1 add column c int; +show create table t1; +--echo # Failed Alter +insert into t1 values(1,1, NULL); +--error ER_DUP_ENTRY +alter table t1 change a a int unique; +set @@session.binlog_alter_two_phase = 0; +alter table t1 change a a int; +set @@session.binlog_alter_two_phase = 1; +alter table t1 change a a int; +show create table t1; + +# The following restriction should be removed post MDEV-26005 fix. +# TODO MDEV-26130 , should be removed after fixing +#if ($engine != 'aria') +#{ +#--eval create temporary table tmp_tbl(a int, b int) engine=$engine; +#insert into tmp_tbl values(1,1); +#insert into tmp_tbl values(2,2); +#--echo # Normal Alter +#alter table tmp_tbl add column c int; +#--echo # Failed Alter +#insert into tmp_tbl values(1,1, NULL); +#--error ER_DUP_ENTRY +#alter table tmp_tbl change a a int unique ; +#show create table tmp_tbl; +#} +if ($sync_slave) +{ + --source include/save_master_gtid.inc + --connection slave_node + --source include/sync_with_master_gtid.inc + show create table t1; +} + +--connection master_node +drop table t1; +#if ($engine != 'aria') +#{ +#drop temporary table tmp_tbl; +#} +if ($sync_slave) +{ + --source include/save_master_gtid.inc + --connection slave_node + --source include/sync_with_master_gtid.inc +} diff --git a/mysql-test/suite/rpl/include/start_alter_concurrent.inc b/mysql-test/suite/rpl/include/start_alter_concurrent.inc new file mode 100644 index 00000000..e5472152 --- /dev/null +++ b/mysql-test/suite/rpl/include/start_alter_concurrent.inc @@ -0,0 +1,230 @@ +# +# ==== Purpose ==== +# +# Run concurrent split alter on given storage engine +# With concurrent 10 connections +# +# ==== Usage ==== +# +# --let $alter_engine= Engine Name (myisam , innodb ...) +# --let $alter_algorithm= ... +# --let $alter_online = [][ONLINE] +# --let $domain_1= +# --let $domain_2= +# --let $M_port= //Master port +# --let $S_port= //Slave port +# --let $sync_slave= // 0/1 whether to sync slave with master or not +# + + +--connection master_node +set global debug_dbug="+d,start_alter_delay_master"; + +--let $i= 1 +while($i < 11) +{ + if($i == 1 && $domain_1) + { + --eval set gtid_domain_id= $domain_1; + } + if($i == 6 && $domain_2) + { + --eval set gtid_domain_id= $domain_2; + } + --eval create table t$i( a int primary key, b int) engine=$alter_engine + --eval insert into t$i values(1,1),(2,2) + --inc $i +} + + +if ($sync_slave) +{ + --echo # Sync slave + --source include/save_master_gtid.inc + --connection slave_node + --source include/sync_with_master_gtid.inc + --connection master_node +} + +--let $i= 1 +while($i < 21) +{ + if($i == 1 || $i == 11) + { + if($domain_1) + { + --eval set global gtid_domain_id= $domain_1; + } + } + if($i == 6 || $i == 16) + { + if($domain_2) + { + --eval set global gtid_domain_id= $domain_2; + } + } + connect(con$i,127.0.0.1,root,,$db_name, $M_port); + --inc $i +} + +--let $i= 1 +while($i < 11) +{ + --connection con$i + --send_eval alter $alter_online table t$i add column c int, force, algorithm=$alter_algorithm + --inc $i +} + +--connection master_node +set DEBUG_SYNC= "now signal alter_cont"; + +--let $i= 1 +while($i < 11) +{ + --connection con$i + --reap + --inc $i +} +--connection master_node +set DEBUG_SYNC= 'RESET'; + +if ($sync_slave) +{ + --echo # Sync slave + --source include/save_master_gtid.inc + --connection slave_node + --source include/sync_with_master_gtid.inc + --connection master_node +} + + +--echo # Concurrent DML +--let $i= 1 +while($i < 11) +{ + --connection con$i + --send_eval alter table t$i add column d int, force, algorithm=$alter_algorithm + --inc $i +} + +if ($alter_algorithm == "inplace") +{ + --sleep 1 + --let $i= 11 + --let $j= 1 + while($i < 21) + { + --connection con$i + --send_eval insert into t$j values(5,5,5); + --inc $i + --inc $j + } + + --let $i= 11 + while($i < 21) + { + --connection con$i + --reap + --inc $i + } + + if ($sync_slave) + { + --echo # Sync slave + --source include/save_master_gtid.inc + --connection slave_node + --source include/sync_with_master_gtid.inc + --connection master_node + } +} +--connection master_node +set DEBUG_SYNC= "now signal alter_cont"; +--let $i= 1 +while($i < 11) +{ + --connection con$i + --reap + --inc $i +} +--connection master_node +set DEBUG_SYNC= 'RESET'; + +if ($sync_slave) +{ + --echo # Sync slave + --source include/save_master_gtid.inc + --connection slave_node + --source include/sync_with_master_gtid.inc + --connection master_node +} + + +--echo # Rollback tests +--let $i= 1 +while($i < 11) +{ + --connection con$i + --eval insert into t$i values(3,2,1,1) + --send_eval alter table t$i change b b int unique, force, algorithm=$alter_algorithm + --inc $i +} +--connection master_node +set DEBUG_SYNC= "now signal alter_cont"; + + +--let $i= 1 +while ($i < 11) +{ + --connection con$i + --error ER_DUP_ENTRY + --reap + --inc $i +} +--connection master_node +set DEBUG_SYNC= 'RESET'; + + +if ($sync_slave) +{ + --echo # Sync slave + --source include/save_master_gtid.inc + --connection slave_node + --source include/sync_with_master_gtid.inc + --connection master_node +} + +if ($sync_slave) +{ + --enable_query_log + --echo # diff_table of master and slave , we will do only in the case when + --echo # sync_slave is on + --let $i= 1 + while($i < 11) + { + --let $diff_tables= master_node:t$i, slave_node:t$i + source include/diff_tables.inc; + --inc $i + } + --disable_query_log +} + +--connection master_node +drop table t1,t2,t3,t4,t5,t6,t7,t8,t9,t10; + +if ($sync_slave) +{ + --echo # Sync slave + --source include/save_master_gtid.inc + --connection slave_node + --source include/sync_with_master_gtid.inc + --connection master_node +} + +--let $i= 1 +while ($i < 21) +{ + --disconnect con$i + --inc $i +} +--connection master_node +SET GLOBAL debug_dbug= ""; diff --git a/mysql-test/suite/rpl/include/start_alter_include.inc b/mysql-test/suite/rpl/include/start_alter_include.inc new file mode 100644 index 00000000..c66075c0 --- /dev/null +++ b/mysql-test/suite/rpl/include/start_alter_include.inc @@ -0,0 +1,64 @@ +# +# ==== Purpose ==== +# +# Run concurrent split alter on different storage engine and with sync to given +# master +# +# ==== Usage ==== +# --let $domain_1= +# --let $domain_2= +# --let $M_port= //Master port +# --let $S_port= //Slave port +# --let $sync_slave= +# --let $db_name= +# + +connect(master_node,127.0.0.1,root,,$db_name, $M_port); +if (!$sync_slave) +{ + --eval set gtid_domain_id= $domain_1; +} +connect(slave_node,127.0.0.1,root,,test, $S_port); +if (!$sync_slave) +{ + --eval set gtid_domain_id= $domain_2; +} + +--let $engine=myisam +--source include/start_alter_basic.inc + +--let $engine=innodb +--source include/start_alter_basic.inc + +--let $engine=aria +--source include/start_alter_basic.inc + +--disable_query_log +--disable_warnings +--connection master_node +--echo # concurrent alter Myisam +--let $alter_engine=myisam +--let $alter_algorithm=copy +--source include/start_alter_concurrent.inc + +--connection master_node +--echo # concurrent alter Aria +--let $alter_engine=aria +--let $alter_algorithm=copy +--source include/start_alter_concurrent.inc + +--connection master_node +--echo # concurrent alter Innodb copy +--let $alter_engine=innodb +--let $alter_algorithm=copy +--source include/start_alter_concurrent.inc + +--connection master_node +--echo # concurrent alter Innodb Inplace +--let $alter_engine=innodb +--let $alter_algorithm=inplace +--source include/start_alter_concurrent.inc +--disconnect master_node +--disconnect slave_node +--enable_warnings +--enable_query_log diff --git a/mysql-test/suite/rpl/include/start_alter_options.inc b/mysql-test/suite/rpl/include/start_alter_options.inc new file mode 100644 index 00000000..72c7104b --- /dev/null +++ b/mysql-test/suite/rpl/include/start_alter_options.inc @@ -0,0 +1,399 @@ +# This test will test all the option related to the Alter Table command +# NOTE not all alter statements will follow alter_algorithm since for some statements +# copy is only option +# parameters +# $alter_algorithm {DEFAULT|INPLACE|COPY|NOCOPY|INSTANT} +# $show_binlog +# +--let $force_needed= force , +# Error that is caused by a particular ALTER's option combination +--let $alter_error = 0 + +--connection slave +stop slave; +--let $gtid_strict_mode= `select @@gtid_strict_mode` +--let $slave_parallel_threads= `select @@slave_parallel_threads` +--let $slave_parallel_mode= `select @@slave_parallel_mode` +change master to master_use_gtid= current_pos; +SET GLOBAL slave_parallel_threads=4; +set global slave_parallel_mode=optimistic; +set global gtid_strict_mode=1; +start slave; +--connection master +set binlog_alter_two_phase=true; +create table t1(a int , b int) engine=innodb; +create table a1(a int , b int) engine=myisam; +create temporary table tmp_tbl(a int, b int) engine=innodb; + +# These are grammer rules for ALTER TABLE we will got through all alter table +# rules in this test. +# | ADD [COLUMN] [IF NOT EXISTS] col_name column_definition +# [FIRST | AFTER col_name ] +# | ADD [COLUMN] [IF NOT EXISTS] (col_name column_definition,...) +if (`select '$alter_algorithm' = 'instant' or '$alter_algorithm' = 'nocopy'`) +{ + --let $alter_error=ER_ALTER_OPERATION_NOT_SUPPORTED +} +--error 0,$alter_error +--eval alter table t1 add column if not exists c int , $force_needed algorithm=$alter_algorithm +if (`select '$alter_algorithm' = 'instant' or '$alter_algorithm' = 'nocopy'`) +{ + --let $alter_error=ER_ALTER_OPERATION_NOT_SUPPORTED +} +--error 0,$alter_error +--eval alter table t1 add column d int first, $force_needed algorithm=$alter_algorithm +if (`select '$alter_algorithm' = 'instant' or '$alter_algorithm' = 'nocopy'`) +{ + --let $alter_error=ER_BAD_FIELD_ERROR +} +--error 0,$alter_error +--eval alter table t1 add column e int after c, $force_needed algorithm=$alter_algorithm +if (`select '$alter_algorithm' = 'instant' or '$alter_algorithm' = 'nocopy'`) +{ + --let $alter_error=ER_BAD_FIELD_ERROR +} +--error 0,$alter_error +--eval alter table t1 add column f int after c, $force_needed add column g int first ,add column h char, algorithm=$alter_algorithm +if (`select '$alter_algorithm' = 'instant' or '$alter_algorithm' = 'nocopy'`) +{ + --let $alter_error=ER_CANT_DROP_FIELD_OR_KEY +} +--error 0,$alter_error +--eval alter table t1 drop column c, drop column d, drop column e, drop column f, drop column g , drop column h, $force_needed algorithm=$alter_algorithm +if ($alter_algorithm == 'copy') +{ +--eval alter table tmp_tbl add column if not exists c int , $force_needed algorithm=$alter_algorithm +--eval alter table tmp_tbl add column d int first, $force_needed algorithm=$alter_algorithm +--eval alter table tmp_tbl add column e int after c, $force_needed algorithm=$alter_algorithm +--eval alter table tmp_tbl add column f int after c, $force_needed add column g int first ,add column h char, algorithm=$alter_algorithm +--eval alter table tmp_tbl drop column c, drop column d, drop column e, drop column f, drop column g , drop column h, $force_needed algorithm=$alter_algorithm +} +--echo # show binlog and clear status +--sync_slave_with_master +if ($show_binlog) +{ + --source include/show_binlog_events.inc +} +reset master; +--connection master + + +# +# | ADD {INDEX|KEY} [IF NOT EXISTS] [index_name] +# [index_type] (index_col_name,...) [index_option] ... +# | ADD [CONSTRAINT [symbol]] +# UNIQUE [INDEX|KEY] [index_name] +# [index_type] (index_col_name,...) [index_option] ... +# +# | ADD FULLTEXT [INDEX|KEY] [index_name] +# (index_col_name,...) [index_option] ... +# | DROP [COLUMN] [IF EXISTS] col_name [RESTRICT|CASCADE] +# | DROP PRIMARY KEY +# | DROP {INDEX|KEY} [IF EXISTS] index_name +# | DROP FOREIGN KEY [IF EXISTS] fk_symbol +# | DROP CONSTRAINT [IF EXISTS] constraint_name +if (`select '$alter_algorithm' = 'instant' or '$alter_algorithm' = 'nocopy'`) +{ + --let $alter_error=ER_ALTER_OPERATION_NOT_SUPPORTED +} +--error 0,$alter_error +--eval alter table t1 add column f int after b, $force_needed add column g int first ,add column h varchar(100), algorithm=$alter_algorithm +if (`select '$alter_algorithm' = 'instant' or '$alter_algorithm' = 'nocopy'`) +{ + --let $alter_error=ER_KEY_COLUMN_DOES_NOT_EXIST +} +--error 0,$alter_error +--eval alter table t1 add index if not exists index_1(f), $force_needed algorithm=$alter_algorithm +if (`select '$alter_algorithm' = 'instant' or '$alter_algorithm' = 'nocopy'`) +{ + --let $alter_error=ER_CANT_DROP_FIELD_OR_KEY +} +--error 0,$alter_error +--eval alter table t1 drop index index_1, $force_needed algorithm=$alter_algorithm +if (`select '$alter_algorithm' = 'instant' or '$alter_algorithm' = 'nocopy'`) +{ + --let $alter_error=ER_KEY_COLUMN_DOES_NOT_EXIST +} +--error 0,$alter_error +--eval alter table t1 add unique key unique_1(g), $force_needed algorithm=$alter_algorithm +if (`select '$alter_algorithm' = 'instant' or '$alter_algorithm' = 'nocopy'`) +{ + --let $alter_error=ER_CANT_DROP_FIELD_OR_KEY +} +--error 0,$alter_error +--eval alter table t1 drop index unique_1, $force_needed algorithm=$alter_algorithm +if (`select '$alter_algorithm' = 'instant' or '$alter_algorithm' = 'nocopy'`) +{ + --let $alter_error=ER_KEY_COLUMN_DOES_NOT_EXIST +} +--error 0,$alter_error +--eval alter table t1 add fulltext key f_1(h), $force_needed algorithm=$alter_algorithm +if (`select '$alter_algorithm' = 'instant' or '$alter_algorithm' = 'nocopy'`) +{ + --let $alter_error=ER_CANT_DROP_FIELD_OR_KEY +} +--error 0,$alter_error +--eval alter table t1 drop column f, drop column g , $force_needed algorithm=$alter_algorithm +if ($alter_algorithm == 'copy') +{ +--eval alter table tmp_tbl add column f int after b, $force_needed add column g int first ,add column h varchar(100), algorithm=$alter_algorithm +if (`select '$alter_algorithm' = 'instant' or '$alter_algorithm' = 'nocopy'`) +{ + --let $alter_error=ER_KEY_COLUMN_DOES_NOT_EXIST +} +--error 0,$alter_error +--eval alter table tmp_tbl add index if not exists index_1(f), $force_needed algorithm=$alter_algorithm +--eval alter table tmp_tbl drop index index_1, $force_needed algorithm=$alter_algorithm +--eval alter table tmp_tbl add unique key unique_1(g), $force_needed algorithm=$alter_algorithm +--eval alter table tmp_tbl drop index unique_1, $force_needed algorithm=$alter_algorithm +--eval alter table tmp_tbl drop column f, drop column g , $force_needed algorithm=$alter_algorithm +} +# | ADD [CONSTRAINT [symbol]] PRIMARY KEY +# [index_type] (index_col_name,...) [index_option] ... +# primary key changes cant use inplace algorithm +if (`select '$alter_algorithm' = 'instant' or '$alter_algorithm' = 'nocopy'`) +{ + --let $alter_error=ER_KEY_COLUMN_DOES_NOT_EXIST +} +--error 0,$alter_error +--eval alter table t1 add primary key(h), $force_needed algorithm=copy +if (`select '$alter_algorithm' = 'instant' or '$alter_algorithm' = 'nocopy'`) +{ + --let $alter_error=ER_CANT_DROP_FIELD_OR_KEY +} +--error 0,$alter_error +--eval alter table t1 drop primary key, $force_needed algorithm=copy +if (`select '$alter_algorithm' = 'instant' or '$alter_algorithm' = 'nocopy'`) +{ + --let $alter_error=ER_CANT_DROP_FIELD_OR_KEY +} +--error 0,$alter_error +--eval alter table t1 drop column h, $force_needed algorithm=copy +if ($alter_algorithm == 'copy') +{ +--eval alter table tmp_tbl add primary key(h), $force_needed algorithm=copy +--eval alter table tmp_tbl drop primary key, $force_needed algorithm=copy +--eval alter table tmp_tbl drop column h, $force_needed algorithm=copy +} +--echo # show binlog and clear status +--sync_slave_with_master +if ($show_binlog) +{ + --source include/show_binlog_events.inc +} +reset master; +--connection master + +## NOTE force_needed and algorithm will not be used for system versioning +# | ADD PERIOD FOR SYSTEM_TIME (start_column_name, end_column_name) +# | ADD SYSTEM VERSIONING +# | DROP SYSTEM VERSIONING +if (`select '$alter_algorithm' = 'instant' or '$alter_algorithm' = 'nocopy'`) +{ + --let $alter_error=ER_ALTER_OPERATION_NOT_SUPPORTED +} +--error 0,$alter_error +--eval alter table t1 add column f varchar(100) after b, add column g varchar(100) first ,add column h char, $force_needed algorithm=$alter_algorithm +--eval alter table t1 add period for system_time(f,h) +--eval alter table t1 add system versioning +--eval alter table t1 drop system versioning +if (`select '$alter_algorithm' = 'instant' or '$alter_algorithm' = 'nocopy'`) +{ + --let $alter_error=ER_CANT_DROP_FIELD_OR_KEY +} +--error 0,$alter_error +--eval alter table t1 drop column f, drop column g , drop column h, $force_needed algorithm=$alter_algorithm +--echo # show binlog and clear status +if ($alter_algorithm == 'copy') +{ +--eval alter table tmp_tbl add column f varchar(100) after b, add column g varchar(100) first ,add column h char, $force_needed algorithm=$alter_algorithm +--eval alter table tmp_tbl drop column f, drop column g , drop column h, $force_needed algorithm=$alter_algorithm +} +--sync_slave_with_master +if ($show_binlog) +{ + --source include/show_binlog_events.inc +} +reset master; +--connection master + + +# | ALTER [COLUMN] col_name SET DEFAULT literal | (expression) +# | ALTER [COLUMN] col_name DROP DEFAULT +# | CHANGE [COLUMN] [IF EXISTS] old_col_name new_col_name column_definition +# [FIRST|AFTER col_name] +# | MODIFY [COLUMN] [IF EXISTS] col_name column_definition +# [FIRST | AFTER col_name] +if (`select '$alter_algorithm' = 'instant' or '$alter_algorithm' = 'nocopy'`) +{ + --let $alter_error=ER_ALTER_OPERATION_NOT_SUPPORTED +} +--error 0,$alter_error +--eval alter table t1 add column f varchar(100) after b,add column g varchar(100) first ,add column h char, $force_needed algorithm=$alter_algorithm ; +if (`select '$alter_algorithm' = 'instant' or '$alter_algorithm' = 'nocopy'`) +{ + --let $alter_error=ER_BAD_FIELD_ERROR +} +--error 0,$alter_error +--eval alter table t1 alter column f set default "****", $force_needed algorithm=$alter_algorithm ; +if (`select '$alter_algorithm' = 'instant' or '$alter_algorithm' = 'nocopy'`) +{ + --let $alter_error=ER_BAD_FIELD_ERROR +} +--error 0,$alter_error +--eval alter table t1 alter column f drop default, $force_needed algorithm=$alter_algorithm ; +if (`select '$alter_algorithm' = 'instant' or '$alter_algorithm' = 'nocopy'`) +{ + --let $alter_error=ER_BAD_FIELD_ERROR +} +--error 0,$alter_error +--eval alter table t1 change column g new_g char, $force_needed algorithm=copy; +if (`select '$alter_algorithm' = 'instant' or '$alter_algorithm' = 'nocopy'`) +{ + --let $alter_error=ER_BAD_FIELD_ERROR +} +--error 0,$alter_error +--eval alter table t1 modify column h varchar(100), $force_needed algorithm=copy; +if (`select '$alter_algorithm' = 'instant' or '$alter_algorithm' = 'nocopy'`) +{ + --let $alter_error=ER_CANT_DROP_FIELD_OR_KEY +} +--error 0,$alter_error +--eval alter table t1 drop column new_g ,drop column f, drop column h, $force_needed algorithm=$alter_algorithm ; +if ($alter_algorithm == 'copy') +{ +--eval alter table tmp_tbl add column f varchar(100) after b,add column g varchar(100) first ,add column h char, $force_needed algorithm=$alter_algorithm ; +--eval alter table tmp_tbl alter column f set default "****", $force_needed algorithm=$alter_algorithm ; +--eval alter table tmp_tbl alter column f drop default, $force_needed algorithm=$alter_algorithm ; +--eval alter table tmp_tbl change column g new_g char, $force_needed algorithm=copy; +--eval alter table tmp_tbl modify column h varchar(100), $force_needed algorithm=copy; +--eval alter table tmp_tbl drop column new_g ,drop column f, drop column h, $force_needed algorithm=$alter_algorithm ; +} +--echo # show binlog and clear status +--sync_slave_with_master +if ($show_binlog) +{ + --source include/show_binlog_events.inc +} +reset master; +--connection master + +# | DISABLE KEYS +# | ENABLE KEYS +# | RENAME [TO] new_tbl_name +# | ORDER BY col_name [, col_name] ... +# | RENAME COLUMN old_col_name TO new_col_name +# | RENAME {INDEX|KEY} old_index_name TO new_index_name +# | CONVERT TO CHARACTER SET charset_name [COLLATE collation_name] +# | [DEFAULT] CHARACTER SET [=] charset_name +# | [DEFAULT] COLLATE [=] collation_name +# | DISCARD TABLESPACE +# | IMPORT TABLESPACE +if (`select '$alter_algorithm' = 'instant' or '$alter_algorithm' = 'nocopy'`) +{ + --let $alter_error=ER_ALTER_OPERATION_NOT_SUPPORTED +} +--error 0,$alter_error +--eval alter table t1 add column f varchar(100) after b,add column g varchar(100) first ,add column h char, $force_needed algorithm=$alter_algorithm +if (`select '$alter_algorithm' = 'instant' or '$alter_algorithm' = 'nocopy'`) +{ + --let $alter_error=ER_KEY_COLUMN_DOES_NOT_EXIST +} +--error 0,$alter_error +--eval alter table t1 add index if not exists index_1(f), $force_needed algorithm=$alter_algorithm +--eval alter table t1 disable keys, $force_needed algorithm=copy +--eval alter table t1 enable keys, $force_needed algorithm=copy +if (`select '$alter_algorithm' = 'instant' or '$alter_algorithm' = 'nocopy'`) +{ + --let $alter_error=ER_ALTER_OPERATION_NOT_SUPPORTED +} +--error 0,$alter_error +--eval alter table t1 rename t2, $force_needed algorithm=$alter_algorithm +if (`select '$alter_algorithm' = 'instant' or '$alter_algorithm' = 'nocopy'`) +{ + --let $alter_error=ER_NO_SUCH_TABLE +} +--error 0,$alter_error +--eval alter table t2 rename t1, $force_needed algorithm=$alter_algorithm +--eval alter table a1 order by a +if (`select '$alter_algorithm' = 'instant' or '$alter_algorithm' = 'nocopy'`) +{ + --let $alter_error=ER_BAD_FIELD_ERROR +} +--error 0,$alter_error +--eval alter table t1 rename column f to new_f, $force_needed algorithm=copy +--eval alter table t1 convert to character set 'utf8', $force_needed algorithm=copy +--eval alter table t1 default character set 'utf8', $force_needed algorithm=copy +--eval alter table t1 default collate 'utf8_icelandic_ci', $force_needed algorithm=copy +if (`select '$alter_algorithm' = 'instant' or '$alter_algorithm' = 'nocopy'`) +{ + --let $alter_error=ER_CANT_DROP_FIELD_OR_KEY +} +--error 0,$alter_error +--eval alter table t1 drop column new_f ,drop column g, drop column h, $force_needed algorithm=$alter_algorithm +if ($alter_algorithm == 'copy') +{ +--eval alter table tmp_tbl add column f varchar(100) after b,add column g varchar(100) first ,add column h char, $force_needed algorithm=$alter_algorithm +--eval alter table tmp_tbl add index if not exists index_1(f), $force_needed algorithm=$alter_algorithm +--eval alter table tmp_tbl disable keys, $force_needed algorithm=copy +--eval alter table tmp_tbl enable keys, $force_needed algorithm=copy +--eval alter table a1 order by a +--eval alter table tmp_tbl rename column f to new_f, $force_needed algorithm=copy +--eval alter table tmp_tbl convert to character set 'utf8', $force_needed algorithm=copy +--eval alter table tmp_tbl default character set 'utf8', $force_needed algorithm=copy +--eval alter table tmp_tbl default collate 'utf8_icelandic_ci', $force_needed algorithm=copy +--eval alter table tmp_tbl drop column new_f ,drop column g, drop column h, $force_needed algorithm=$alter_algorithm +} +##--eval alter table t1 discard tablespace; +######--eval alter table t1 import tablespace; + +--echo # show binlog and clear status +--sync_slave_with_master +if ($show_binlog) +{ + --source include/show_binlog_events.inc +} +reset master; +--connection master + +# Only add partition and remove partition is tested +# | ADD PARTITION (partition_definition) +# | REMOVE PARTITIONING +if (`select '$alter_algorithm' = 'instant' or '$alter_algorithm' = 'nocopy'`) +{ + --let $alter_error=ER_ALTER_OPERATION_NOT_SUPPORTED +} +--error 0,$alter_error +--eval alter table t1 add column f varchar(100) after b,add column g varchar(100) first ,add column h char, $force_needed algorithm=$alter_algorithm +--eval alter table t1 partition by hash(b) partitions 8 +--eval alter table t1 remove partitioning +if (`select '$alter_algorithm' = 'instant' or '$alter_algorithm' = 'nocopy'`) +{ + --let $alter_error=ER_CANT_DROP_FIELD_OR_KEY +} +--error 0,$alter_error +--eval alter table t1 drop column f ,drop column g, drop column h, $force_needed algorithm=$alter_algorithm +if ($alter_algorithm == 'copy') +{ +--eval alter table tmp_tbl add column f varchar(100) after b,add column g varchar(100) first ,add column h char, $force_needed algorithm=$alter_algorithm +--eval alter table tmp_tbl drop column f ,drop column g, drop column h, $force_needed algorithm=$alter_algorithm +} +--echo # show binlog and clear status +--sync_slave_with_master +if ($show_binlog) +{ + --source include/show_binlog_events.inc +} +reset master; +--connection master + +# clean master/slave +--connection master +drop table t1, a1; +drop temporary table tmp_tbl; +--sync_slave_with_master +--source include/stop_slave.inc +--eval set global slave_parallel_threads = $slave_parallel_threads; +--eval set global slave_parallel_mode = $slave_parallel_mode; +--eval set global gtid_strict_mode = $gtid_strict_mode; +--source include/start_slave.inc diff --git a/mysql-test/suite/rpl/include/type_conversions.test b/mysql-test/suite/rpl/include/type_conversions.test new file mode 100644 index 00000000..edd46f14 --- /dev/null +++ b/mysql-test/suite/rpl/include/type_conversions.test @@ -0,0 +1,1272 @@ +# File containing different lossy and non-lossy type conversions. + +# Integral conversion testing, we do not reduce the test using +# transitivity of conversions since the implementation is not using a +# transitivity strategy. Instead we do an exhaustive testing. + +disable_query_log; +connection slave; +--let $conv = `select @@slave_type_conversions` +--echo **** Running tests with @@SLAVE_TYPE_CONVERSIONS = '$conv' **** + +let $if_is_lossy = `SELECT FIND_IN_SET('ALL_LOSSY', @@SLAVE_TYPE_CONVERSIONS)`; +let $if_is_non_lossy = `SELECT FIND_IN_SET('ALL_NON_LOSSY', @@SLAVE_TYPE_CONVERSIONS)`; + +# TINYBLOB + +let $source_type = TINYBLOB; +let $target_type = TINYBLOB; +let $source_value = 'aaa'; +let $target_value = 'aaa'; +let $can_convert = 1; +source suite/rpl/include/check_type.inc; + +let $source_type= TINYBLOB; +let $target_type= BLOB; +let $source_value= 'aaa'; +let $target_value= 'aaa'; +let $can_convert= $if_is_non_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= TINYBLOB; +let $target_type= MEDIUMBLOB; +let $source_value= 'aaa'; +let $target_value= 'aaa'; +let $can_convert= $if_is_non_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= TINYBLOB; +let $target_type= LONGBLOB; +let $source_value= 'aaa'; +let $target_value= 'aaa'; +let $can_convert= $if_is_non_lossy; +source suite/rpl/include/check_type.inc; + +# BLOB + +let $source_type = BLOB; +let $target_type = TINYBLOB; +let $source_value = 'aaa'; +let $target_value = 'aaa'; +let $can_convert = $if_is_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= BLOB; +let $target_type= BLOB; +let $source_value= 'aaa'; +let $target_value= 'aaa'; +let $can_convert= 1; +source suite/rpl/include/check_type.inc; + +let $source_type= BLOB; +let $target_type= MEDIUMBLOB; +let $source_value= 'aaa'; +let $target_value= 'aaa'; +let $can_convert= $if_is_non_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= BLOB; +let $target_type= LONGBLOB; +let $source_value= 'aaa'; +let $target_value= 'aaa'; +let $can_convert= $if_is_non_lossy; +source suite/rpl/include/check_type.inc; + +# MEDIUMBLOB + +let $source_type = MEDIUMBLOB; +let $target_type = TINYBLOB; +let $source_value = 'aaa'; +let $target_value = 'aaa'; +let $can_convert = $if_is_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= MEDIUMBLOB; +let $target_type= BLOB; +let $source_value= 'aaa'; +let $target_value= 'aaa'; +let $can_convert= $if_is_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= MEDIUMBLOB; +let $target_type= MEDIUMBLOB; +let $source_value= 'aaa'; +let $target_value= 'aaa'; +let $can_convert= 1; +source suite/rpl/include/check_type.inc; + +let $source_type= MEDIUMBLOB; +let $target_type= LONGBLOB; +let $source_value= 'aaa'; +let $target_value= 'aaa'; +let $can_convert= $if_is_non_lossy; +source suite/rpl/include/check_type.inc; + +# LONGBLOB + +let $source_type = LONGBLOB; +let $target_type = TINYBLOB; +let $source_value = 'aaa'; +let $target_value = 'aaa'; +let $can_convert = $if_is_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= LONGBLOB; +let $target_type= BLOB; +let $source_value= 'aaa'; +let $target_value= 'aaa'; +let $can_convert= $if_is_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= LONGBLOB; +let $target_type= MEDIUMBLOB; +let $source_value= 'aaa'; +let $target_value= 'aaa'; +let $can_convert= $if_is_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= LONGBLOB; +let $target_type= LONGBLOB; +let $source_value= 'aaa'; +let $target_value= 'aaa'; +let $can_convert= 1; +source suite/rpl/include/check_type.inc; + +# BUG#49836 (additional tests - GEOMETRY TYPE) + +let $source_type = GEOMETRY; +let $target_type = BLOB; +let $source_value = PointFromText('POINT(10 10)'); +let $target_value = PointFromText('POINT(10 10)'); +let $can_convert = 0; +source suite/rpl/include/check_type.inc; + +let $source_type = BLOB; +let $target_type = GEOMETRY; +let $source_value = 'aaa'; +let $target_value = 'aaa'; +let $can_convert = 0; +source suite/rpl/include/check_type.inc; + +let $source_type = GEOMETRY; +let $target_type = GEOMETRY; +let $source_value = PointFromText('POINT(10 10)'); +let $target_value = PointFromText('POINT(10 10)'); +let $can_convert = 1; +source suite/rpl/include/check_type.inc; + +let $source_type = BIT(1); +let $target_type = BIT(1); +let $source_value = b'1'; +let $target_value = b'1'; +let $can_convert = 1; +source suite/rpl/include/check_type.inc; + +let $source_type = DATE; +let $target_type = DATE; +let $source_value = '2009-11-21'; +let $target_value = '2009-11-21'; +let $can_convert = 1; +source suite/rpl/include/check_type.inc; + +let $source_type = ENUM('master','slave'); +let $target_type = ENUM('master','slave'); +let $source_value = 'master'; +let $target_value = 'master'; +let $can_convert = 1; +source suite/rpl/include/check_type.inc; + +let $source_type = CHAR(10); +let $target_type = ENUM('master','slave'); +let $source_value = 'master'; +let $target_value = 'master'; +let $can_convert = 0; +source suite/rpl/include/check_type.inc; + +let $source_type = CHAR(10); +let $target_type = SET('master','slave'); +let $source_value = 'master'; +let $target_value = 'master'; +let $can_convert = 0; +source suite/rpl/include/check_type.inc; + +let $source_type = ENUM('master','slave'); +let $target_type = CHAR(10); +let $source_value = 'master'; +let $target_value = 'master'; +let $can_convert = 0; +source suite/rpl/include/check_type.inc; + +let $source_type = SET('master','slave'); +let $target_type = CHAR(10); +let $source_value = 'master'; +let $target_value = 'master'; +let $can_convert = 0; +source suite/rpl/include/check_type.inc; + +let $source_type = SET('master','slave'); +let $target_type = SET('master','slave'); +let $source_value = ''; +let $target_value = ''; +let $can_convert = 1; +source suite/rpl/include/check_type.inc; + +let $source_type = SET('master','slave'); +let $target_type = SET('master','slave'); +let $source_value = 'master,slave'; +let $target_value = 'master,slave'; +let $can_convert = 1; +source suite/rpl/include/check_type.inc; + +let $source_type = SET('0','1','2','3','4','5','6'); +let $target_type = SET('0','1','2','3','4','5','6'); +let $source_value = '5'; +let $target_value = '5'; +let $can_convert = 1; +source suite/rpl/include/check_type.inc; + +let $source_type = SET('0','1','2','3','4','5','6'); +let $target_type = SET('0','1','2','3','4','5','6','7','8','9','10'); +let $source_value = '5'; +let $target_value = '5'; +let $can_convert = $if_is_non_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type = SET('0','1','2','3','4','5','6','7','8','9','10'); +let $target_type = SET('0','1','2','3','4','5','6'); +let $source_value = '5'; +let $target_value = '5'; +let $can_convert = $if_is_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type = SET('0','1','2','3','4','5','6','7','8','9','10'); +let $target_type = SET('0','1','2','3','4','5','6'); +let $source_value = '7'; +let $target_value = ''; +let $can_convert = $if_is_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type = TINYINT; +let $target_type = TINYINT; +let $source_value = 1; +let $target_value = 1; +let $can_convert = 1; +source suite/rpl/include/check_type.inc; + +let $source_type = TINYINT; +let $target_type = SMALLINT; +let $source_value = 1; +let $target_value = 1; +let $can_convert = $if_is_non_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= TINYINT; +let $target_type= MEDIUMINT; +let $source_value= 1; +let $target_value= 1; +let $can_convert = $if_is_non_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= TINYINT; +let $target_type= INT; +let $source_value= 1; +let $target_value= 1; +let $can_convert = $if_is_non_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= TINYINT; +let $target_type= BIGINT; +let $source_value= 1; +let $target_value= 1; +let $can_convert = $if_is_non_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= SMALLINT; +let $target_type= TINYINT; +let $source_value= 1; +let $target_value= 1; +let $can_convert = $if_is_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= SMALLINT; +let $target_type= TINYINT; +let $source_value= 1 << 9; +let $target_value= (1 << 7) - 1; +let $can_convert = $if_is_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= SMALLINT; +let $target_type= TINYINT UNSIGNED; +let $source_value= 1 << 9; +let $target_value= (1 << 8) - 1; +let $can_convert = $if_is_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= SMALLINT; +let $target_type= SMALLINT; +let $source_value= 1; +let $target_value= 1; +let $can_convert = 1; +source suite/rpl/include/check_type.inc; + +let $source_type= SMALLINT; +let $target_type= MEDIUMINT; +let $source_value= 1; +let $target_value= 1; +let $can_convert = $if_is_non_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= SMALLINT; +let $target_type= INT; +let $source_value= 1; +let $target_value= 1; +let $can_convert = $if_is_non_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= SMALLINT; +let $target_type= BIGINT; +let $source_value= 1; +let $target_value= 1; +let $can_convert = $if_is_non_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= MEDIUMINT; +let $target_type= TINYINT; +let $source_value= 1; +let $target_value= 1; +let $can_convert = $if_is_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= MEDIUMINT; +let $target_type= TINYINT; +let $source_value= 1 << 20; +let $target_value= (1 << 7) - 1; +let $can_convert = $if_is_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= MEDIUMINT; +let $target_type= TINYINT UNSIGNED; +let $source_value= 1 << 20; +let $target_value= (1 << 8) - 1; +let $can_convert = $if_is_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= MEDIUMINT; +let $target_type= SMALLINT; +let $source_value= 1; +let $target_value= 1; +let $can_convert = $if_is_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= MEDIUMINT; +let $target_type= MEDIUMINT; +let $source_value= 1; +let $target_value= 1; +let $can_convert = 1; +source suite/rpl/include/check_type.inc; + +let $source_type= MEDIUMINT; +let $target_type= INT; +let $source_value= 1; +let $target_value= 1; +let $can_convert = $if_is_non_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= MEDIUMINT; +let $target_type= BIGINT; +let $source_value= 1; +let $target_value= 1; +let $can_convert = $if_is_non_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= INT; +let $target_type= TINYINT; +let $source_value= 1; +let $target_value= 1; +let $can_convert = $if_is_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= INT; +let $target_type= TINYINT; +let $source_value= (1 << 30); +let $target_value= (1 << 7) - 1; +let $can_convert = $if_is_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= INT; +let $target_type= TINYINT UNSIGNED; +let $source_value= (1 << 30); +let $target_value= (1 << 8) - 1; +let $can_convert = $if_is_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= INT; +let $target_type= SMALLINT; +let $source_value= 1; +let $target_value= 1; +let $can_convert = $if_is_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= INT; +let $target_type= MEDIUMINT; +let $source_value= 1; +let $target_value= 1; +let $can_convert = $if_is_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= INT; +let $target_type= INT; +let $source_value= 1; +let $target_value= 1; +let $can_convert = 1; +source suite/rpl/include/check_type.inc; + +let $source_type= INT; +let $target_type= BIGINT; +let $source_value= 1; +let $target_value= 1; +let $can_convert = $if_is_non_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= BIGINT; +let $target_type= TINYINT; +let $source_value= 1; +let $target_value= 1; +let $can_convert = $if_is_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= BIGINT; +let $target_type= SMALLINT; +let $source_value= 1; +let $target_value= 1; +let $can_convert = $if_is_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= BIGINT; +let $target_type= MEDIUMINT; +let $source_value= 1; +let $target_value= 1; +let $can_convert = $if_is_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= BIGINT; +let $target_type= INT; +let $source_value= 1; +let $target_value= 1; +let $can_convert = $if_is_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= BIGINT; +let $target_type= BIGINT; +let $source_value= 1; +let $target_value= 1; +let $can_convert = 1; +source suite/rpl/include/check_type.inc; + +let $source_type= CHAR(20); +let $target_type= CHAR(20); +let $source_value= 'Smoothnoodlemaps'; +let $target_value= 'Smoothnoodlemaps'; +let $can_convert = 1; +source suite/rpl/include/check_type.inc; + +let $source_type= CHAR(20); +let $target_type= CHAR(30); +let $source_value= 'Smoothnoodlemaps'; +let $target_value= 'Smoothnoodlemaps'; +let $can_convert = $if_is_non_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= CHAR(20); +let $target_type= CHAR(10); +let $source_value= 'Smoothnoodlemaps'; +let $target_value= 'Smoothnood'; +let $can_convert = $if_is_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= CHAR(20); +let $target_type= VARCHAR(20); +let $source_value= 'Smoothnoodlemaps'; +let $target_value= 'Smoothnoodlemaps'; +let $can_convert = $if_is_non_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= CHAR(20); +let $target_type= VARCHAR(30); +let $source_value= 'Smoothnoodlemaps'; +let $target_value= 'Smoothnoodlemaps'; +let $can_convert = $if_is_non_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= CHAR(20); +let $target_type= VARCHAR(10); +let $source_value= 'Smoothnoodlemaps'; +let $target_value= 'Smoothnood'; +let $can_convert = $if_is_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= CHAR(20); +let $target_type= TINYTEXT; +let $source_value= 'Smoothnoodlemaps'; +let $target_value= 'Smoothnoodlemaps'; +let $can_convert = $if_is_non_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= CHAR(20); +let $target_type= TEXT; +let $source_value= 'Smoothnoodlemaps'; +let $target_value= 'Smoothnoodlemaps'; +let $can_convert = $if_is_non_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= CHAR(20); +let $target_type= MEDIUMTEXT; +let $source_value= 'Smoothnoodlemaps'; +let $target_value= 'Smoothnoodlemaps'; +let $can_convert = $if_is_non_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= CHAR(20); +let $target_type= LONGTEXT; +let $source_value= 'Smoothnoodlemaps'; +let $target_value= 'Smoothnoodlemaps'; +let $can_convert = $if_is_non_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= VARCHAR(20); +let $target_type= VARCHAR(20); +let $source_value= 'Smoothnoodlemaps'; +let $target_value= 'Smoothnoodlemaps'; +let $can_convert = 1; +source suite/rpl/include/check_type.inc; + +let $source_type= VARCHAR(20); +let $target_type= VARCHAR(30); +let $source_value= 'Smoothnoodlemaps'; +let $target_value= 'Smoothnoodlemaps'; +let $can_convert = $if_is_non_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= VARCHAR(20); +let $target_type= VARCHAR(10); +let $source_value= 'Smoothnoodlemaps'; +let $target_value= 'Smoothnood'; +let $can_convert = $if_is_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= VARCHAR(20); +let $target_type= CHAR(30); +let $source_value= 'Smoothnoodlemaps'; +let $target_value= 'Smoothnoodlemaps'; +let $can_convert = $if_is_non_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= VARCHAR(20); +let $target_type= CHAR(10); +let $source_value= 'Smoothnoodlemaps'; +let $target_value= 'Smoothnood'; +let $can_convert = $if_is_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= VARCHAR(20); +let $target_type= TINYTEXT; +let $source_value= 'Smoothnoodlemaps'; +let $target_value= 'Smoothnoodlemaps'; +let $can_convert = $if_is_non_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= VARCHAR(20); +let $target_type= TEXT; +let $source_value= 'Smoothnoodlemaps'; +let $target_value= 'Smoothnoodlemaps'; +let $can_convert = $if_is_non_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= VARCHAR(20); +let $target_type= MEDIUMTEXT; +let $source_value= 'Smoothnoodlemaps'; +let $target_value= 'Smoothnoodlemaps'; +let $can_convert = $if_is_non_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= VARCHAR(20); +let $target_type= LONGTEXT; +let $source_value= 'Smoothnoodlemaps'; +let $target_value= 'Smoothnoodlemaps'; +let $can_convert = $if_is_non_lossy; +source suite/rpl/include/check_type.inc; + +let $blob = `select repeat('abcd', 125)`; +let $truncated_blob = `select left('$blob', 255)`; + +let $source_type= VARCHAR(500); +let $target_type= VARCHAR(500); +let $source_value= '$blob'; +let $target_value= '$blob'; +let $can_convert = 1; +source suite/rpl/include/check_type.inc; + +let $source_type= VARCHAR(500); +let $target_type= VARCHAR(510); +let $source_value= '$blob'; +let $target_value= '$blob'; +let $can_convert = $if_is_non_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= VARCHAR(500); +let $target_type= VARCHAR(255); +let $source_value= '$blob'; +let $target_value= '$truncated_blob'; +let $can_convert = $if_is_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= VARCHAR(500); +let $target_type= TINYTEXT; +let $source_value= '$blob'; +let $target_value= '$truncated_blob'; +let $can_convert = $if_is_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= VARCHAR(500); +let $target_type= TEXT; +let $source_value= '$blob'; +let $target_value= '$blob'; +let $can_convert = $if_is_non_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= VARCHAR(500); +let $target_type= MEDIUMTEXT; +let $source_value= '$blob'; +let $target_value= '$blob'; +let $can_convert = $if_is_non_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= VARCHAR(500); +let $target_type= LONGTEXT; +let $source_value= '$blob'; +let $target_value= '$blob'; +let $can_convert = $if_is_non_lossy; +source suite/rpl/include/check_type.inc; + +let $tiny_blob = `select repeat('tiny blob ', 25)`; +let $truncated_tiny_blob = `select left('$tiny_blob', 254)`; + +let $source_type= TINYTEXT; +let $target_type= VARCHAR(500); +let $source_value= '$tiny_blob'; +let $target_value= '$tiny_blob'; +let $can_convert = $if_is_non_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= TEXT; +let $target_type= VARCHAR(500); +let $source_value= '$blob'; +let $target_value= '$blob'; +let $can_convert = $if_is_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= MEDIUMTEXT; +let $target_type= VARCHAR(500); +let $source_value= '$blob'; +let $target_value= '$blob'; +let $can_convert = $if_is_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= LONGTEXT; +let $target_type= VARCHAR(500); +let $source_value= '$blob'; +let $target_value= '$blob'; +let $can_convert = $if_is_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= TINYTEXT; +let $target_type= CHAR(255); +let $source_value= '$tiny_blob'; +let $target_value= '$tiny_blob'; +let $can_convert = $if_is_non_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= TINYTEXT; +let $target_type= CHAR(250); +let $source_value= '$tiny_blob'; +let $target_value= left('$tiny_blob', 250); +let $can_convert = $if_is_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= TEXT; +let $target_type= CHAR(255); +let $source_value= '$blob'; +let $target_value= left('$blob', 255); +let $can_convert = $if_is_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= MEDIUMTEXT; +let $target_type= CHAR(255); +let $source_value= '$blob'; +let $target_value= left('$blob', 255); +let $can_convert = $if_is_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= LONGTEXT; +let $target_type= CHAR(255); +let $source_value= '$blob'; +let $target_value= left('$blob', 255); +let $can_convert = $if_is_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= TINYTEXT; +let $target_type= TINYTEXT; +let $source_value= '$tiny_blob'; +let $target_value= '$tiny_blob'; +let $can_convert = 1; +source suite/rpl/include/check_type.inc; + +let $source_type= TINYTEXT; +let $target_type= TEXT; +let $source_value= '$tiny_blob'; +let $target_value= '$tiny_blob'; +let $can_convert = $if_is_non_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= TEXT; +let $target_type= TINYTEXT; +let $source_value= '$blob'; +let $target_value= left('$blob',255); +let $can_convert = $if_is_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= DECIMAL(10,5); +let $target_type= DECIMAL(10,5); +let $source_value= 3.14159; +let $target_value= 3.14159; +let $can_convert = 1; +source suite/rpl/include/check_type.inc; + +let $source_type= DECIMAL(10,5); +let $target_type= DECIMAL(10,6); +let $source_value= 3.14159; +let $target_value= 3.141590; +let $can_convert = $if_is_non_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= DECIMAL(10,5); +let $target_type= DECIMAL(11,5); +let $source_value= 3.14159; +let $target_value= 3.14159; +let $can_convert = $if_is_non_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= DECIMAL(10,5); +let $target_type= DECIMAL(11,6); +let $source_value= 3.14159; +let $target_value= 3.141590; +let $can_convert = $if_is_non_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= DECIMAL(10,5); +let $target_type= DECIMAL(10,4); +let $source_value= 3.14159; +let $target_value= 3.1416; +let $can_convert = $if_is_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= DECIMAL(10,5); +let $target_type= DECIMAL(9,5); +let $source_value= 3.14159; +let $target_value= 3.14159; +let $can_convert = $if_is_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= DECIMAL(10,5); +let $target_type= DECIMAL(9,4); +let $source_value= 3.14159; +let $target_value= 3.1416; +let $can_convert = $if_is_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= FLOAT; +let $target_type= DECIMAL(10,5); +let $source_value= 3.15625; +let $target_value= 3.15625; +let $can_convert = $if_is_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= DOUBLE; +let $target_type= DECIMAL(10,5); +let $source_value= 3.15625; +let $target_value= 3.15625; +let $can_convert = $if_is_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= DECIMAL(10,5); +let $target_type= FLOAT; +let $source_value= 3.15625; +let $target_value= 3.15625; +let $can_convert = $if_is_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= DECIMAL(10,5); +let $target_type= DOUBLE; +let $source_value= 3.15625; +let $target_value= 3.15625; +let $can_convert = $if_is_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= FLOAT; +let $target_type= FLOAT; +let $source_value= 3.15625; +let $target_value= 3.15625; +let $can_convert = 1; +source suite/rpl/include/check_type.inc; + +let $source_type= DOUBLE; +let $target_type= DOUBLE; +let $source_value= 3.15625; +let $target_value= 3.15625; +let $can_convert = 1; +source suite/rpl/include/check_type.inc; + +let $source_type= FLOAT; +let $target_type= DOUBLE; +let $source_value= 3.15625; +let $target_value= 3.15625; +let $can_convert = $if_is_non_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= DOUBLE; +let $target_type= FLOAT; +let $source_value= 3.15625; +let $target_value= 3.15625; +let $can_convert = $if_is_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= BIT(5); +let $target_type= BIT(5); +let $source_value= b'11001'; +let $target_value= b'11001'; +let $can_convert = 1; +source suite/rpl/include/check_type.inc; + +let $source_type= BIT(5); +let $target_type= BIT(6); +let $source_value= b'11001'; +let $target_value= b'11001'; +let $can_convert = $if_is_non_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= BIT(6); +let $target_type= BIT(5); +let $source_value= b'111001'; +let $target_value= b'11111'; +let $can_convert = $if_is_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= BIT(5); +let $target_type= BIT(12); +let $source_value= b'11001'; +let $target_value= b'11001'; +let $can_convert = $if_is_non_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= BIT(12); +let $target_type= BIT(5); +let $source_value= b'101100111000'; +let $target_value= b'11111'; +let $can_convert = $if_is_lossy; +source suite/rpl/include/check_type.inc; + + +--echo # +--echo # MDEV-15821 Row format replication from LONGBLOB COMPRESSED to LONGBLOB does not work +--echo # + +# This is to make sure that the compressed data is longer than 64K +SET column_compression_threshold=16*256*256; + +# TINYBLOB COMPRESSED + +let $source_type= TINYBLOB COMPRESSED; +let $target_type= TINYBLOB; +let $source_value= REPEAT('a',250); +let $target_value= REPEAT('a',250); +let $can_convert = $if_is_non_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= TINYBLOB COMPRESSED; +let $target_type= BLOB; +let $source_value= REPEAT('a',250); +let $target_value= REPEAT('a',250); +let $can_convert = $if_is_non_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= TINYBLOB COMPRESSED; +let $target_type= MEDIUMBLOB; +let $source_value= REPEAT('a',250); +let $target_value= REPEAT('a',250); +let $can_convert = $if_is_non_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= TINYBLOB COMPRESSED; +let $target_type= LONGBLOB; +let $source_value= REPEAT('a',250); +let $target_value= REPEAT('a',250); +let $can_convert = $if_is_non_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= TINYBLOB COMPRESSED; +let $target_type= VARBINARY(255); +let $source_value= REPEAT('a',250); +let $target_value= REPEAT('a',250); +let $can_convert = $if_is_non_lossy; +source suite/rpl/include/check_type.inc; + + +# BLOB COMPRESSED + +let $source_type= BLOB COMPRESSED; +let $target_type= TINYBLOB; +let $source_value= REPEAT('a',64000); +let $target_value= REPEAT('a',255); +let $can_convert = $if_is_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= BLOB COMPRESSED; +let $target_type= BLOB; +let $source_value= REPEAT('a',64000); +let $target_value= REPEAT('a',64000); +let $can_convert = $if_is_non_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= BLOB COMPRESSED; +let $target_type= MEDIUMBLOB; +let $source_value= REPEAT('a',64000); +let $target_value= REPEAT('a',64000); +let $can_convert = $if_is_non_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= BLOB COMPRESSED; +let $target_type= LONGBLOB; +let $source_value= REPEAT('a',64000); +let $target_value= REPEAT('a',64000); +let $can_convert = $if_is_non_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= BLOB COMPRESSED; +let $target_type= VARBINARY(65500); +let $source_value= REPEAT('a',65500); +let $target_value= REPEAT('a',65500); +let $can_convert = $if_is_lossy; +source suite/rpl/include/check_type.inc; + + +# MEDIUMBLOB COMPRESSED + +let $source_type= MEDIUMBLOB COMPRESSED; +let $target_type= TINYBLOB; +let $source_value= REPEAT('a',66000); +let $target_value= REPEAT('a',255); +let $can_convert = $if_is_lossy; +source suite/rpl/include/check_type.inc; + +# This failed before the fix +let $source_type= MEDIUMBLOB COMPRESSED; +let $target_type= BLOB; +let $source_value= REPEAT('a',66000); +let $target_value= REPEAT('a',65535); +let $can_convert = $if_is_lossy; +source suite/rpl/include/check_type.inc; + +# This failed before the fix +let $source_type= MEDIUMBLOB COMPRESSED; +let $target_type= MEDIUMBLOB; +let $source_value= REPEAT('a',66000); +let $target_value= REPEAT('a',66000); +let $can_convert = $if_is_non_lossy; +source suite/rpl/include/check_type.inc; + +# This failed before the fix +let $source_type= MEDIUMBLOB COMPRESSED; +let $target_type= LONGBLOB; +let $source_value= REPEAT('a',66000); +let $target_value= REPEAT('a',66000); +let $can_convert = $if_is_non_lossy; +source suite/rpl/include/check_type.inc; + +# This failed before the fix +let $source_type= MEDIUMBLOB COMPRESSED; +let $target_type= VARBINARY(65500); +let $source_value= REPEAT('a',66000); +let $target_value= REPEAT('a',65500); +let $can_convert = $if_is_lossy; +source suite/rpl/include/check_type.inc; + + +# LONGBLOB COMPRESSED + +let $source_type= LONGBLOB COMPRESSED; +let $target_type= TINYBLOB; +let $source_value= REPEAT('a',66000); +let $target_value= REPEAT('a',255); +let $can_convert = $if_is_lossy; +source suite/rpl/include/check_type.inc; + +# This failed before the fix +let $source_type= LONGBLOB COMPRESSED; +let $target_type= BLOB; +let $source_value= REPEAT('a',66000); +let $target_value= REPEAT('a',65535); +let $can_convert = $if_is_lossy; +source suite/rpl/include/check_type.inc; + +# This failed before the fix +let $source_type= LONGBLOB COMPRESSED; +let $target_type= MEDIUMBLOB; +let $source_value= REPEAT('a',66000); +let $target_value= REPEAT('a',66000); +let $can_convert = $if_is_lossy; +source suite/rpl/include/check_type.inc; + +# This failed before the fix +let $source_type= LONGBLOB COMPRESSED; +let $target_type= LONGBLOB; +let $source_value= REPEAT('a',66000); +let $target_value= REPEAT('a',66000); +let $can_convert = $if_is_non_lossy; +source suite/rpl/include/check_type.inc; + +# This failed before the fix +let $source_type= LONGBLOB COMPRESSED; +let $target_type= VARBINARY(65500); +let $source_value= REPEAT('a',66000); +let $target_value= REPEAT('a',65500); +let $can_convert = $if_is_lossy; +source suite/rpl/include/check_type.inc; + +SET column_compression_threshold=DEFAULT; +--echo # End of MDEV-15821 + + +--echo # +--echo # MDEV-15833 Row format replication between LONGBLOB and MEDIUMBLOB does not work for long values +--echo # + +# TINYBLOB + +let $source_type= TINYBLOB; +let $target_type= BLOB; +let $source_value= REPEAT('a',250); +let $target_value= REPEAT('a',250); +let $can_convert = $if_is_non_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= TINYBLOB; +let $target_type= MEDIUMBLOB; +let $source_value= REPEAT('a',250); +let $target_value= REPEAT('a',250); +let $can_convert = $if_is_non_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= TINYBLOB; +let $target_type= LONGBLOB; +let $source_value= REPEAT('a',250); +let $target_value= REPEAT('a',250); +let $can_convert = $if_is_non_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= TINYBLOB; +let $target_type= VARBINARY(255); +let $source_value= REPEAT('a',250); +let $target_value= REPEAT('a',250); +let $can_convert = $if_is_non_lossy; +source suite/rpl/include/check_type.inc; + + +# BLOB + +let $source_type= BLOB; +let $target_type= TINYBLOB; +let $source_value= REPEAT('a',64000); +let $target_value= REPEAT('a',255); +let $can_convert = $if_is_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= BLOB; +let $target_type= MEDIUMBLOB; +let $source_value= REPEAT('a',64000); +let $target_value= REPEAT('a',64000); +let $can_convert = $if_is_non_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= BLOB; +let $target_type= LONGBLOB; +let $source_value= REPEAT('a',64000); +let $target_value= REPEAT('a',64000); +let $can_convert = $if_is_non_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= BLOB; +let $target_type= VARBINARY(65500); +let $source_value= REPEAT('a',65535); +let $target_value= REPEAT('a',65500); +let $can_convert = $if_is_lossy; +source suite/rpl/include/check_type.inc; + + +# MEDIUMBLOB + +let $source_type= MEDIUMBLOB; +let $target_type= TINYBLOB; +let $source_value= REPEAT('a',66000); +let $target_value= REPEAT('a',255); +let $can_convert = $if_is_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= MEDIUMBLOB; +let $target_type= BLOB; +let $source_value= REPEAT('a',66000); +let $target_value= REPEAT('a',65535); +let $can_convert = $if_is_lossy; +source suite/rpl/include/check_type.inc; + +# This failed before the fix +let $source_type= MEDIUMBLOB; +let $target_type= LONGBLOB; +let $source_value= REPEAT('a',66000); +let $target_value= REPEAT('a',66000); +let $can_convert = $if_is_non_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= MEDIUMBLOB; +let $target_type= VARBINARY(65500); +let $source_value= REPEAT('a',66000); +let $target_value= REPEAT('a',65500); +let $can_convert = $if_is_lossy; +source suite/rpl/include/check_type.inc; + + +# LONGBLOB + +let $source_type= LONGBLOB; +let $target_type= TINYBLOB; +let $source_value= REPEAT('a',66000); +let $target_value= REPEAT('a',255); +let $can_convert = $if_is_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= LONGBLOB; +let $target_type= BLOB; +let $source_value= REPEAT('a',66000); +let $target_value= REPEAT('a',65535); +let $can_convert = $if_is_lossy; +source suite/rpl/include/check_type.inc; + +# This failed before the fix +let $source_type= LONGBLOB; +let $target_type= MEDIUMBLOB; +let $source_value= REPEAT('a',66000); +let $target_value= REPEAT('a',66000); +let $can_convert = $if_is_lossy; +source suite/rpl/include/check_type.inc; + +let $source_type= LONGBLOB; +let $target_type= VARBINARY(65500); +let $source_value= REPEAT('a',66000); +let $target_value= REPEAT('a',65500); +let $can_convert = $if_is_lossy; +source suite/rpl/include/check_type.inc; + +--echo # End of MDEV-15833 + +--echo # +--echo # MDEV-17098 DATE <-> DATETIME +--echo # + +# NON-LOSSY +let $source_temp_format= 1; # irrelevant with DATE though +let $source_type= DATE; +let $target_temp_format= 1; # to produce MYSQL_TYPE_DATETIME2 +let $target_type= DATETIME(6); +let $source_value= '2018-10-11'; +let $target_value= '2018-10-11 00:00:00.000000'; +let $can_convert = $if_is_non_lossy; +source suite/rpl/include/check_type.inc; + +let $source_temp_format= 1; +let $source_type= DATE; +let $target_temp_format= 0; # to produce "old" MYSQL_TYPE_DATETIME +let $target_type= DATETIME(6); +let $source_value= '2018-10-11'; +let $target_value= '2018-10-11 00:00:00.000000'; +let $can_convert = $if_is_non_lossy; +source suite/rpl/include/check_type.inc; + +let $source_temp_format= 0; +let $source_type= DATE; +let $target_temp_format= 1; +let $target_type= DATETIME(6); +let $source_value= '2018-10-11'; +let $target_value= '2018-10-11 00:00:00.000000'; +let $can_convert = $if_is_non_lossy; +source suite/rpl/include/check_type.inc; + +# zero-precision test version +let $source_temp_format= 1; +let $source_type= DATE; +let $target_temp_format= 1; +let $target_type= DATETIME(0); +let $source_value= '2018-10-11'; +let $target_value= '2018-10-11 00:00:00'; +let $can_convert = $if_is_non_lossy; +source suite/rpl/include/check_type.inc; + +# LOSSY +let $source_temp_format= 1; +let $source_type= DATETIME(6); +let $target_temp_format= 1; +let $target_type= DATE; +let $source_value= '2018-10-11 00:00:00.000001'; +let $target_value= '2018-10-11'; +let $can_convert = $if_is_lossy; +source suite/rpl/include/check_type.inc; + +let $source_temp_format= 1; +let $source_type= DATETIME(6); +let $target_temp_format= 0; +let $target_type= DATE; +let $source_value= '2018-10-11 00:00:00.000001'; +let $target_value= '2018-10-11'; +let $can_convert = $if_is_lossy; +source suite/rpl/include/check_type.inc; + +# zero-precision test version +let $source_temp_format= 1; +let $source_type= DATETIME(0); +let $target_temp_format= 1; +let $target_type= DATE; +let $source_value= '2018-10-11 00:00:00'; +let $target_value= '2018-10-11'; +let $can_convert = $if_is_lossy; +source suite/rpl/include/check_type.inc; + +# TODO: fix MDEV-17394 Row-based replication DATETIME(m) to +# DATETIME(s) does not work or incorrect +# +# +# let $source_temp_format= 0; +# let $source_type= DATETIME(6); +# let $target_temp_format= 1; +# let $target_type= DATE; +# ... +# let $source_temp_format= 0; +# let $source_type= DATETIME(6); +# let $target_temp_format= 0; +# let $target_type= DATE; +# ... + +let $source_temp_format=; +let $target_temp_format=; +--echo # End of MDEV-17098 + + +--source include/rpl_reset.inc +enable_query_log; -- cgit v1.2.3