From a175314c3e5827eb193872241446f2f8f5c9d33c Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sat, 4 May 2024 20:07:14 +0200 Subject: Adding upstream version 1:10.5.12. Signed-off-by: Daniel Baumann --- mysql-test/suite/rpl/t/circular_serverid0.cnf | 30 + mysql-test/suite/rpl/t/circular_serverid0.test | 103 +++ mysql-test/suite/rpl/t/create_or_replace.inc | 227 +++++++ mysql-test/suite/rpl/t/create_or_replace2.test | 42 ++ mysql-test/suite/rpl/t/create_or_replace_mix.cnf | 9 + mysql-test/suite/rpl/t/create_or_replace_mix.test | 4 + mysql-test/suite/rpl/t/create_or_replace_row.cnf | 9 + mysql-test/suite/rpl/t/create_or_replace_row.test | 4 + .../suite/rpl/t/create_or_replace_statement.cnf | 9 + .../suite/rpl/t/create_or_replace_statement.test | 4 + mysql-test/suite/rpl/t/create_select.cnf | 16 + mysql-test/suite/rpl/t/create_select.test | 37 ++ .../suite/rpl/t/failed_create_view-6409.test | 24 + .../suite/rpl/t/grant_replication_slave.test | 39 ++ .../suite/rpl/t/ignore_table_autoinc-9737.test | 35 + mysql-test/suite/rpl/t/kill_hard-6290.test | 11 + mysql-test/suite/rpl/t/kill_race_condition.test | 36 + mysql-test/suite/rpl/t/last_insert_id.cnf | 20 + mysql-test/suite/rpl/t/last_insert_id.test | 30 + mysql-test/suite/rpl/t/mdev_17588-slave.opt | 1 + mysql-test/suite/rpl/t/mdev_17588.test | 44 ++ .../suite/rpl/t/myisam_external_lock-slave.opt | 2 + mysql-test/suite/rpl/t/myisam_external_lock.test | 24 + mysql-test/suite/rpl/t/mysql-wsrep#110-2.test | 44 ++ mysql-test/suite/rpl/t/parallel_backup.test | 75 +++ mysql-test/suite/rpl/t/password_expiration.test | 53 ++ mysql-test/suite/rpl/t/rename.test | 33 + mysql-test/suite/rpl/t/replace.test | 24 + mysql-test/suite/rpl/t/rpl_000010-slave.opt | 1 + mysql-test/suite/rpl/t/rpl_000010.test | 16 + mysql-test/suite/rpl/t/rpl_000011-slave.opt | 1 + mysql-test/suite/rpl/t/rpl_000011.test | 34 + mysql-test/suite/rpl/t/rpl_000013.test | 55 ++ mysql-test/suite/rpl/t/rpl_000017.test | 47 ++ mysql-test/suite/rpl/t/rpl_15867.test | 11 + mysql-test/suite/rpl/t/rpl_15919-slave.opt | 1 + mysql-test/suite/rpl/t/rpl_15919.test | 18 + mysql-test/suite/rpl/t/rpl_EE_err.test | 2 + mysql-test/suite/rpl/t/rpl_LD_INFILE.test | 39 ++ mysql-test/suite/rpl/t/rpl_alter.test | 71 ++ mysql-test/suite/rpl/t/rpl_alter_db.test | 15 + .../suite/rpl/t/rpl_alter_extra_persistent.test | 106 +++ mysql-test/suite/rpl/t/rpl_alter_instant.test | 50 ++ .../suite/rpl/t/rpl_auto_increment-master.opt | 1 + .../suite/rpl/t/rpl_auto_increment-slave.opt | 1 + mysql-test/suite/rpl/t/rpl_auto_increment.test | 7 + .../suite/rpl/t/rpl_auto_increment_11932.test | 66 ++ .../suite/rpl/t/rpl_auto_increment_bug33029.test | 60 ++ .../suite/rpl/t/rpl_auto_increment_bug45679.test | 62 ++ .../rpl/t/rpl_auto_increment_update_failure.test | 211 ++++++ .../rpl/t/rpl_autogen_query_multi_byte_char.test | 87 +++ .../rpl/t/rpl_begin_commit_rollback-master.opt | 1 + .../rpl/t/rpl_begin_commit_rollback-slave.opt | 1 + .../suite/rpl/t/rpl_begin_commit_rollback.test | 173 +++++ mysql-test/suite/rpl/t/rpl_binlog_compress.test | 61 ++ mysql-test/suite/rpl/t/rpl_binlog_corruption.test | 50 ++ .../t/rpl_binlog_dump_slave_gtid_state_info.test | 121 ++++ mysql-test/suite/rpl/t/rpl_binlog_dup_entry.test | 72 ++ .../suite/rpl/t/rpl_binlog_errors-master.opt | 1 + mysql-test/suite/rpl/t/rpl_binlog_errors.test | 1 + mysql-test/suite/rpl/t/rpl_binlog_grant.test | 42 ++ mysql-test/suite/rpl/t/rpl_binlog_index.test | 217 ++++++ .../suite/rpl/t/rpl_binlog_rollback_cleanup.test | 46 ++ mysql-test/suite/rpl/t/rpl_bit.test | 92 +++ mysql-test/suite/rpl/t/rpl_bit_npk.test | 113 ++++ mysql-test/suite/rpl/t/rpl_blackhole.test | 25 + .../rpl/t/rpl_blackhole_row_annotate-master.opt | 1 + .../rpl/t/rpl_blackhole_row_annotate-slave.opt | 1 + .../suite/rpl/t/rpl_blackhole_row_annotate.test | 49 ++ mysql-test/suite/rpl/t/rpl_bug26395.test | 93 +++ mysql-test/suite/rpl/t/rpl_bug31076.test | 146 ++++ mysql-test/suite/rpl/t/rpl_bug33931.test | 49 ++ mysql-test/suite/rpl/t/rpl_bug37426.test | 22 + mysql-test/suite/rpl/t/rpl_bug38694-slave.opt | 1 + mysql-test/suite/rpl/t/rpl_bug38694.test | 13 + mysql-test/suite/rpl/t/rpl_bug41902.test | 67 ++ .../suite/rpl/t/rpl_cant_read_event_incident.test | 1 + mysql-test/suite/rpl/t/rpl_change_master.test | 111 ++++ mysql-test/suite/rpl/t/rpl_charset.test | 2 + mysql-test/suite/rpl/t/rpl_charset_sjis.test | 54 ++ mysql-test/suite/rpl/t/rpl_checksum-master.opt | 1 + mysql-test/suite/rpl/t/rpl_checksum.test | 1 + mysql-test/suite/rpl/t/rpl_checksum_cache.test | 1 + .../suite/rpl/t/rpl_circular_for_4_hosts.cnf | 24 + .../suite/rpl/t/rpl_circular_for_4_hosts.test | 336 ++++++++++ mysql-test/suite/rpl/t/rpl_colSize.test | 228 +++++++ mysql-test/suite/rpl/t/rpl_commit_after_flush.test | 5 + .../suite/rpl/t/rpl_concurrency_error-master.opt | 1 + mysql-test/suite/rpl/t/rpl_concurrency_error.test | 150 +++++ .../suite/rpl/t/rpl_conditional_comments.test | 84 +++ mysql-test/suite/rpl/t/rpl_connection.test | 24 + mysql-test/suite/rpl/t/rpl_corruption-master.opt | 1 + mysql-test/suite/rpl/t/rpl_corruption-slave.opt | 1 + mysql-test/suite/rpl/t/rpl_corruption.test | 1 + .../suite/rpl/t/rpl_create_database-master.opt | 1 + .../suite/rpl/t/rpl_create_database-slave.opt | 1 + mysql-test/suite/rpl/t/rpl_create_database.test | 73 ++ mysql-test/suite/rpl/t/rpl_create_drop_db.test | 33 + mysql-test/suite/rpl/t/rpl_create_drop_event.test | 27 + .../suite/rpl/t/rpl_create_drop_function.test | 54 ++ mysql-test/suite/rpl/t/rpl_create_drop_index.test | 17 + .../suite/rpl/t/rpl_create_drop_procedure.test | 81 +++ mysql-test/suite/rpl/t/rpl_create_drop_role.test | 48 ++ .../suite/rpl/t/rpl_create_drop_trigger.test | 48 ++ mysql-test/suite/rpl/t/rpl_create_drop_udf.test | 56 ++ mysql-test/suite/rpl/t/rpl_create_drop_user.test | 57 ++ mysql-test/suite/rpl/t/rpl_create_drop_view.test | 56 ++ .../suite/rpl/t/rpl_create_if_not_exists.test | 195 ++++++ .../suite/rpl/t/rpl_create_or_replace_fail.test | 56 ++ .../rpl/t/rpl_create_tmp_table_if_not_exists.test | 45 ++ mysql-test/suite/rpl/t/rpl_create_xa_prepared.inc | 9 + mysql-test/suite/rpl/t/rpl_critical_errors.test | 66 ++ .../suite/rpl/t/rpl_cross_version-master.opt | 1 + mysql-test/suite/rpl/t/rpl_cross_version.test | 48 ++ mysql-test/suite/rpl/t/rpl_ctype_latin1.test | 44 ++ mysql-test/suite/rpl/t/rpl_current_user.cnf | 8 + mysql-test/suite/rpl/t/rpl_current_user.test | 225 +++++++ mysql-test/suite/rpl/t/rpl_ddl-slave.opt | 1 + mysql-test/suite/rpl/t/rpl_ddl.test | 32 + .../suite/rpl/t/rpl_deadlock_innodb-slave.opt | 1 + mysql-test/suite/rpl/t/rpl_deadlock_innodb.test | 4 + mysql-test/suite/rpl/t/rpl_default.test | 29 + .../suite/rpl/t/rpl_delayed_slave.combinations | 4 + mysql-test/suite/rpl/t/rpl_delayed_slave.test | 424 ++++++++++++ mysql-test/suite/rpl/t/rpl_delayed_slave2.test | 65 ++ mysql-test/suite/rpl/t/rpl_delete_no_where.test | 4 + mysql-test/suite/rpl/t/rpl_do_grant.test | 350 ++++++++++ mysql-test/suite/rpl/t/rpl_domain_id_filter.test | 400 +++++++++++ .../suite/rpl/t/rpl_domain_id_filter_io_crash.test | 384 +++++++++++ .../rpl/t/rpl_domain_id_filter_master_crash.test | 87 +++ .../suite/rpl/t/rpl_domain_id_filter_parallel.test | 196 ++++++ .../suite/rpl/t/rpl_domain_id_filter_restart.test | 73 ++ mysql-test/suite/rpl/t/rpl_drop.test | 12 + mysql-test/suite/rpl/t/rpl_drop_db.test | 62 ++ mysql-test/suite/rpl/t/rpl_drop_db_fail.test | 34 + mysql-test/suite/rpl/t/rpl_drop_temp-slave.opt | 2 + mysql-test/suite/rpl/t/rpl_drop_temp.test | 94 +++ .../rpl/t/rpl_drop_temp_table_invalid_lex.test | 41 ++ mysql-test/suite/rpl/t/rpl_drop_view.test | 35 + mysql-test/suite/rpl/t/rpl_dual_pos_advance.test | 97 +++ .../rpl/t/rpl_dump_request_retry_warning.test | 60 ++ mysql-test/suite/rpl/t/rpl_empty_master_host.test | 53 ++ .../suite/rpl/t/rpl_err_ignoredtable-slave.opt | 1 + mysql-test/suite/rpl/t/rpl_err_ignoredtable.test | 70 ++ mysql-test/suite/rpl/t/rpl_events.test | 244 +++++++ .../suite/rpl/t/rpl_extra_col_master_innodb.test | 11 + .../suite/rpl/t/rpl_extra_col_master_myisam.test | 10 + .../suite/rpl/t/rpl_extra_col_slave_innodb.test | 7 + .../suite/rpl/t/rpl_extra_col_slave_myisam.test | 6 + mysql-test/suite/rpl/t/rpl_fail_register.test | 33 + .../suite/rpl/t/rpl_failed_drop_tbl_binlog.opt | 1 + mysql-test/suite/rpl/t/rpl_failed_optimize.test | 3 + mysql-test/suite/rpl/t/rpl_filter_dbs_dynamic.test | 63 ++ .../suite/rpl/t/rpl_filter_tables_dynamic.test | 217 ++++++ .../rpl/t/rpl_filter_tables_not_exist-slave.opt | 1 + .../suite/rpl/t/rpl_filter_tables_not_exist.test | 267 ++++++++ .../rpl/t/rpl_filter_wild_tables_dynamic.test | 49 ++ mysql-test/suite/rpl/t/rpl_flush_logs-master.opt | 1 + mysql-test/suite/rpl/t/rpl_flush_logs.test | 141 ++++ .../suite/rpl/t/rpl_flushlog_loop-master.opt | 1 + mysql-test/suite/rpl/t/rpl_flushlog_loop-slave.opt | 1 + mysql-test/suite/rpl/t/rpl_flushlog_loop.test | 46 ++ mysql-test/suite/rpl/t/rpl_foreign_key_innodb.test | 78 +++ mysql-test/suite/rpl/t/rpl_free_items-slave.opt | 1 + mysql-test/suite/rpl/t/rpl_free_items.test | 23 + mysql-test/suite/rpl/t/rpl_function_defaults.test | 86 +++ mysql-test/suite/rpl/t/rpl_geometry.test | 26 + mysql-test/suite/rpl/t/rpl_get_lock.test | 47 ++ .../t/rpl_get_master_version_and_clock-slave.opt | 1 + .../rpl/t/rpl_get_master_version_and_clock.test | 50 ++ mysql-test/suite/rpl/t/rpl_grant.test | 37 ++ mysql-test/suite/rpl/t/rpl_gtid_basic.cnf | 24 + mysql-test/suite/rpl/t/rpl_gtid_basic.test | 36 + mysql-test/suite/rpl/t/rpl_gtid_crash-master.opt | 1 + mysql-test/suite/rpl/t/rpl_gtid_crash-slave.opt | 1 + mysql-test/suite/rpl/t/rpl_gtid_crash.test | 668 +++++++++++++++++++ .../suite/rpl/t/rpl_gtid_crash_myisam-master.opt | 1 + mysql-test/suite/rpl/t/rpl_gtid_crash_myisam.test | 64 ++ mysql-test/suite/rpl/t/rpl_gtid_delete_domain.test | 101 +++ mysql-test/suite/rpl/t/rpl_gtid_errorhandling.test | 290 ++++++++ mysql-test/suite/rpl/t/rpl_gtid_errorlog.test | 85 +++ .../suite/rpl/t/rpl_gtid_excess_initial_delay.test | 58 ++ mysql-test/suite/rpl/t/rpl_gtid_ignored.test | 141 ++++ mysql-test/suite/rpl/t/rpl_gtid_master_promote.cnf | 35 + .../suite/rpl/t/rpl_gtid_master_promote.test | 270 ++++++++ mysql-test/suite/rpl/t/rpl_gtid_mdev4473.cnf | 18 + mysql-test/suite/rpl/t/rpl_gtid_mdev4473.test | 72 ++ mysql-test/suite/rpl/t/rpl_gtid_mdev4474.cnf | 11 + mysql-test/suite/rpl/t/rpl_gtid_mdev4474.test | 72 ++ mysql-test/suite/rpl/t/rpl_gtid_mdev4484.test | 106 +++ mysql-test/suite/rpl/t/rpl_gtid_mdev4485.cnf | 18 + mysql-test/suite/rpl/t/rpl_gtid_mdev4485.test | 41 ++ mysql-test/suite/rpl/t/rpl_gtid_mdev4820.test | 118 ++++ mysql-test/suite/rpl/t/rpl_gtid_mdev9033.cnf | 20 + mysql-test/suite/rpl/t/rpl_gtid_mdev9033.test | 72 ++ mysql-test/suite/rpl/t/rpl_gtid_misc.test | 50 ++ mysql-test/suite/rpl/t/rpl_gtid_nobinlog.cnf | 9 + mysql-test/suite/rpl/t/rpl_gtid_nobinlog.test | 66 ++ mysql-test/suite/rpl/t/rpl_gtid_reconnect.test | 206 ++++++ mysql-test/suite/rpl/t/rpl_gtid_sort.test | 77 +++ mysql-test/suite/rpl/t/rpl_gtid_startpos.test | 358 ++++++++++ mysql-test/suite/rpl/t/rpl_gtid_stop_start.cnf | 5 + mysql-test/suite/rpl/t/rpl_gtid_stop_start.test | 351 ++++++++++ mysql-test/suite/rpl/t/rpl_gtid_strict.test | 179 +++++ mysql-test/suite/rpl/t/rpl_gtid_until.test | 248 +++++++ mysql-test/suite/rpl/t/rpl_heartbeat.test | 172 +++++ mysql-test/suite/rpl/t/rpl_heartbeat_2slaves.cnf | 12 + mysql-test/suite/rpl/t/rpl_heartbeat_2slaves.test | 124 ++++ mysql-test/suite/rpl/t/rpl_heartbeat_basic.cnf | 7 + mysql-test/suite/rpl/t/rpl_heartbeat_basic.test | 565 ++++++++++++++++ mysql-test/suite/rpl/t/rpl_heartbeat_debug.test | 52 ++ mysql-test/suite/rpl/t/rpl_heartbeat_ssl.test | 56 ++ mysql-test/suite/rpl/t/rpl_hrtime.test | 7 + mysql-test/suite/rpl/t/rpl_hrtime_row.test | 3 + mysql-test/suite/rpl/t/rpl_idempotency.test | 107 +++ mysql-test/suite/rpl/t/rpl_ignore_grant-slave.opt | 1 + mysql-test/suite/rpl/t/rpl_ignore_grant.test | 55 ++ mysql-test/suite/rpl/t/rpl_ignore_revoke-slave.opt | 1 + mysql-test/suite/rpl/t/rpl_ignore_revoke.test | 52 ++ mysql-test/suite/rpl/t/rpl_ignore_table-slave.opt | 1 + mysql-test/suite/rpl/t/rpl_ignore_table.test | 198 ++++++ .../suite/rpl/t/rpl_ignore_table_update-slave.opt | 1 + .../suite/rpl/t/rpl_ignore_table_update.test | 35 + mysql-test/suite/rpl/t/rpl_incident.test | 1 + .../suite/rpl/t/rpl_incompatible_heartbeat.test | 44 ++ mysql-test/suite/rpl/t/rpl_init_slave-slave.opt | 1 + mysql-test/suite/rpl/t/rpl_init_slave.test | 34 + mysql-test/suite/rpl/t/rpl_init_slave_errors.test | 1 + mysql-test/suite/rpl/t/rpl_innodb-master.opt | 1 + .../suite/rpl/t/rpl_innodb_bug28430-master.opt | 1 + .../suite/rpl/t/rpl_innodb_bug28430-slave.opt | 1 + mysql-test/suite/rpl/t/rpl_innodb_bug28430.test | 163 +++++ mysql-test/suite/rpl/t/rpl_innodb_bug30888.opt | 1 + mysql-test/suite/rpl/t/rpl_innodb_bug30888.test | 66 ++ mysql-test/suite/rpl/t/rpl_innodb_bug68220.test | 53 ++ mysql-test/suite/rpl/t/rpl_innodb_mixed_ddl.test | 9 + mysql-test/suite/rpl/t/rpl_innodb_mixed_dml.test | 9 + mysql-test/suite/rpl/t/rpl_insert.test | 45 ++ mysql-test/suite/rpl/t/rpl_insert_delayed.test | 5 + mysql-test/suite/rpl/t/rpl_insert_id.test | 6 + mysql-test/suite/rpl/t/rpl_insert_id_pk.test | 6 + mysql-test/suite/rpl/t/rpl_insert_ignore.test | 15 + .../suite/rpl/t/rpl_invoked_features-master.opt | 1 + mysql-test/suite/rpl/t/rpl_invoked_features.test | 311 +++++++++ mysql-test/suite/rpl/t/rpl_ip_mix.cnf | 56 ++ mysql-test/suite/rpl/t/rpl_ip_mix.test | 48 ++ mysql-test/suite/rpl/t/rpl_ip_mix2.cnf | 56 ++ mysql-test/suite/rpl/t/rpl_ip_mix2.test | 49 ++ mysql-test/suite/rpl/t/rpl_ipv4_as_ipv6.cnf | 56 ++ mysql-test/suite/rpl/t/rpl_ipv4_as_ipv6.test | 63 ++ mysql-test/suite/rpl/t/rpl_ipv6.cnf | 56 ++ mysql-test/suite/rpl/t/rpl_ipv6.test | 49 ++ mysql-test/suite/rpl/t/rpl_killed_ddl-master.opt | 1 + mysql-test/suite/rpl/t/rpl_killed_ddl.test | 349 ++++++++++ .../rpl/t/rpl_known_bugs_detection-master.opt | 1 + .../suite/rpl/t/rpl_known_bugs_detection.test | 76 +++ .../rpl/t/rpl_lcase_tblnames_rewrite_db-slave.opt | 1 + .../suite/rpl/t/rpl_lcase_tblnames_rewrite_db.test | 60 ++ mysql-test/suite/rpl/t/rpl_loaddata.test | 4 + mysql-test/suite/rpl/t/rpl_loaddata_charset.test | 49 ++ .../suite/rpl/t/rpl_loaddata_fatal-slave.opt | 1 + mysql-test/suite/rpl/t/rpl_loaddata_fatal.test | 27 + mysql-test/suite/rpl/t/rpl_loaddata_m-master.opt | 1 + mysql-test/suite/rpl/t/rpl_loaddata_m.test | 51 ++ mysql-test/suite/rpl/t/rpl_loaddata_map-master.opt | 1 + mysql-test/suite/rpl/t/rpl_loaddata_map-slave.opt | 1 + mysql-test/suite/rpl/t/rpl_loaddata_map.test | 72 ++ mysql-test/suite/rpl/t/rpl_loaddata_s-slave.opt | 1 + mysql-test/suite/rpl/t/rpl_loaddata_s.test | 27 + mysql-test/suite/rpl/t/rpl_loaddata_simple.test | 15 + .../suite/rpl/t/rpl_loaddata_symlink-master.opt | 1 + .../suite/rpl/t/rpl_loaddata_symlink-master.sh | 2 + .../suite/rpl/t/rpl_loaddata_symlink-slave.opt | 1 + .../suite/rpl/t/rpl_loaddata_symlink-slave.sh | 2 + mysql-test/suite/rpl/t/rpl_loaddata_symlink.test | 22 + mysql-test/suite/rpl/t/rpl_loaddatalocal.test | 1 + mysql-test/suite/rpl/t/rpl_loadfile.test | 1 + mysql-test/suite/rpl/t/rpl_locale.test | 25 + mysql-test/suite/rpl/t/rpl_log_pos.test | 57 ++ .../suite/rpl/t/rpl_lost_events_on_rotate.test | 51 ++ .../suite/rpl/t/rpl_manual_change_index_file.test | 108 +++ mysql-test/suite/rpl/t/rpl_many_optimize.test | 23 + .../suite/rpl/t/rpl_mariadb_slave_capability.test | 158 +++++ .../suite/rpl/t/rpl_mark_optimize_tbl_ddl.test | 142 ++++ mysql-test/suite/rpl/t/rpl_master_pos_wait.test | 79 +++ mysql-test/suite/rpl/t/rpl_mdev-11092.opt | 1 + mysql-test/suite/rpl/t/rpl_mdev-11092.test | 53 ++ mysql-test/suite/rpl/t/rpl_mdev10863.test | 105 +++ mysql-test/suite/rpl/t/rpl_mdev12179.test | 316 +++++++++ mysql-test/suite/rpl/t/rpl_mdev359.test | 31 + mysql-test/suite/rpl/t/rpl_mdev382.test | 264 ++++++++ mysql-test/suite/rpl/t/rpl_mdev6020.test | 69 ++ mysql-test/suite/rpl/t/rpl_mdev6386-slave.opt | 1 + mysql-test/suite/rpl/t/rpl_mdev6386.test | 71 ++ mysql-test/suite/rpl/t/rpl_mdev8193.test | 56 ++ mysql-test/suite/rpl/t/rpl_mdev_17614.test | 121 ++++ mysql-test/suite/rpl/t/rpl_misc_functions-slave.sh | 1 + mysql-test/suite/rpl/t/rpl_misc_functions.test | 127 ++++ mysql-test/suite/rpl/t/rpl_mix_found_rows.test | 150 +++++ .../rpl/t/rpl_mixed_binlog_max_cache_size.test | 8 + mysql-test/suite/rpl/t/rpl_mixed_bit_pk.test | 83 +++ mysql-test/suite/rpl/t/rpl_mixed_ddl_dml.test | 51 ++ .../rpl/t/rpl_mixed_drop_create_temp_table.test | 12 + .../rpl/t/rpl_mixed_implicit_commit_binlog.test | 12 + .../suite/rpl/t/rpl_mixed_mixing_engines.test | 12 + .../suite/rpl/t/rpl_mixed_row_innodb-master.opt | 1 + mysql-test/suite/rpl/t/rpl_multi_delete-slave.opt | 1 + mysql-test/suite/rpl/t/rpl_multi_delete.test | 25 + mysql-test/suite/rpl/t/rpl_multi_delete2-slave.opt | 1 + mysql-test/suite/rpl/t/rpl_multi_delete2.test | 67 ++ mysql-test/suite/rpl/t/rpl_multi_engine.test | 102 +++ mysql-test/suite/rpl/t/rpl_multi_update.test | 2 + mysql-test/suite/rpl/t/rpl_multi_update2-slave.opt | 1 + mysql-test/suite/rpl/t/rpl_multi_update2.test | 9 + mysql-test/suite/rpl/t/rpl_multi_update3.test | 9 + mysql-test/suite/rpl/t/rpl_multi_update4-slave.opt | 1 + mysql-test/suite/rpl/t/rpl_multi_update4.test | 46 ++ .../rpl/t/rpl_mysql57_stm_temporal_round.test | 58 ++ .../rpl/t/rpl_mysql80_stm_temporal_round.test | 62 ++ mysql-test/suite/rpl/t/rpl_mysql_upgrade.test | 80 +++ mysql-test/suite/rpl/t/rpl_name_const.test | 45 ++ .../rpl/t/rpl_non_direct_mixed_mixing_engines.test | 15 + .../rpl/t/rpl_non_direct_row_mixing_engines.test | 17 + .../rpl/t/rpl_non_direct_stm_mixing_engines.test | 15 + .../rpl/t/rpl_nondeterministic_functions.test | 58 ++ mysql-test/suite/rpl/t/rpl_not_null_innodb.test | 20 + mysql-test/suite/rpl/t/rpl_not_null_myisam.test | 19 + mysql-test/suite/rpl/t/rpl_old_decimal.test | 25 + mysql-test/suite/rpl/t/rpl_old_master.test | 57 ++ mysql-test/suite/rpl/t/rpl_optimize.test | 65 ++ mysql-test/suite/rpl/t/rpl_packet-master.opt | 1 + mysql-test/suite/rpl/t/rpl_packet-slave.opt | 1 + mysql-test/suite/rpl/t/rpl_packet.test | 1 + mysql-test/suite/rpl/t/rpl_parallel2.test | 230 +++++++ .../rpl/t/rpl_parallel_analyze_table_hang.test | 1 + mysql-test/suite/rpl/t/rpl_parallel_charset.test | 56 ++ mysql-test/suite/rpl/t/rpl_parallel_conflicts.test | 269 ++++++++ .../t/rpl_parallel_deadlock_corrupt_binlog.test | 1 + mysql-test/suite/rpl/t/rpl_parallel_domain.test | 1 + .../t/rpl_parallel_domain_slave_single_grp.test | 1 + .../rpl/t/rpl_parallel_free_deferred_event.test | 1 + .../suite/rpl/t/rpl_parallel_gco_wait_kill.test | 1 + .../t/rpl_parallel_gtid_slave_pos_update_fail.test | 1 + .../rpl/t/rpl_parallel_ignore_error_on_rotate.test | 1 + .../suite/rpl/t/rpl_parallel_ignored_errors.test | 1 + .../rpl/t/rpl_parallel_incorrect_relay_pos.test | 1 + .../rpl/t/rpl_parallel_innodb_lock_conflict.test | 1 + mysql-test/suite/rpl/t/rpl_parallel_mdev6589.test | 133 ++++ .../rpl/t/rpl_parallel_missed_error_handling.test | 1 + mysql-test/suite/rpl/t/rpl_parallel_mode.test | 1 + mysql-test/suite/rpl/t/rpl_parallel_multilevel.cnf | 24 + .../suite/rpl/t/rpl_parallel_multilevel.test | 284 ++++++++ .../suite/rpl/t/rpl_parallel_multilevel2.cnf | 17 + .../suite/rpl/t/rpl_parallel_multilevel2.test | 80 +++ .../t/rpl_parallel_no_log_slave_updates-slave.opt | 1 + .../rpl/t/rpl_parallel_no_log_slave_updates.test | 201 ++++++ .../suite/rpl/t/rpl_parallel_optimistic.test | 583 ++++++++++++++++ .../rpl/t/rpl_parallel_optimistic_nobinlog.cnf | 10 + .../rpl/t/rpl_parallel_optimistic_nobinlog.test | 77 +++ .../suite/rpl/t/rpl_parallel_optimistic_until.test | 465 +++++++++++++ .../suite/rpl/t/rpl_parallel_optimistic_xa.test | 235 +++++++ .../t/rpl_parallel_optimistic_xa_lsu_off-slave.opt | 1 + .../rpl/t/rpl_parallel_optimistic_xa_lsu_off.test | 2 + .../rpl/t/rpl_parallel_partial_binlog_trans.test | 1 + mysql-test/suite/rpl/t/rpl_parallel_partition.test | 81 +++ .../rpl/t/rpl_parallel_record_gtid_wakeup.test | 1 + mysql-test/suite/rpl/t/rpl_parallel_retry.test | 486 ++++++++++++++ .../suite/rpl/t/rpl_parallel_retry_deadlock.test | 1 + .../suite/rpl/t/rpl_parallel_rollback_assert.test | 1 + ...rpl_parallel_show_binlog_events_purge_logs.test | 1 + .../suite/rpl/t/rpl_parallel_single_grpcmt.test | 1 + .../suite/rpl/t/rpl_parallel_slave_bgc_kill.test | 1 + .../suite/rpl/t/rpl_parallel_stop_on_con_kill.test | 1 + .../suite/rpl/t/rpl_parallel_stop_slave.test | 1 + .../suite/rpl/t/rpl_parallel_temptable-master.opt | 1 + mysql-test/suite/rpl/t/rpl_parallel_temptable.test | 271 ++++++++ .../rpl/t/rpl_parallel_wrong_binlog_order.test | 1 + .../rpl/t/rpl_parallel_wrong_exec_master_pos.test | 1 + .../suite/rpl/t/rpl_parallel_xa_same_xid.test | 138 ++++ mysql-test/suite/rpl/t/rpl_partition_archive.test | 12 + .../suite/rpl/t/rpl_partition_innodb-master.opt | 1 + mysql-test/suite/rpl/t/rpl_partition_innodb.test | 12 + mysql-test/suite/rpl/t/rpl_partition_memory.test | 11 + mysql-test/suite/rpl/t/rpl_partition_myisam.test | 11 + .../suite/rpl/t/rpl_password_boundaries.test | 101 +++ mysql-test/suite/rpl/t/rpl_performance_schema.test | 10 + mysql-test/suite/rpl/t/rpl_plugin_load.test | 59 ++ mysql-test/suite/rpl/t/rpl_ps.test | 94 +++ mysql-test/suite/rpl/t/rpl_rbr_to_sbr.test | 31 + .../suite/rpl/t/rpl_read_new_relay_log_info.test | 43 ++ .../suite/rpl/t/rpl_read_old_relay_log_info.test | 44 ++ mysql-test/suite/rpl/t/rpl_read_only.test | 129 ++++ mysql-test/suite/rpl/t/rpl_read_only2.test | 30 + .../suite/rpl/t/rpl_relay_max_extension.test | 109 +++ mysql-test/suite/rpl/t/rpl_relay_space_innodb.test | 3 + mysql-test/suite/rpl/t/rpl_relay_space_myisam.test | 2 + mysql-test/suite/rpl/t/rpl_relayrotate-slave.opt | 2 + mysql-test/suite/rpl/t/rpl_relayrotate.test | 1 + mysql-test/suite/rpl/t/rpl_relayspace-slave.opt | 1 + mysql-test/suite/rpl/t/rpl_relayspace.test | 52 ++ mysql-test/suite/rpl/t/rpl_reopen_temp_table.test | 43 ++ mysql-test/suite/rpl/t/rpl_replicate_do-slave.opt | 1 + mysql-test/suite/rpl/t/rpl_replicate_do.test | 65 ++ .../suite/rpl/t/rpl_replicate_ignore_db-slave.opt | 1 + .../suite/rpl/t/rpl_replicate_ignore_db.test | 31 + mysql-test/suite/rpl/t/rpl_report-slave.opt | 2 + mysql-test/suite/rpl/t/rpl_report.test | 22 + mysql-test/suite/rpl/t/rpl_report_port.test | 74 +++ mysql-test/suite/rpl/t/rpl_reset_slave_fail.test | 91 +++ mysql-test/suite/rpl/t/rpl_rewrt_db-slave.opt | 1 + mysql-test/suite/rpl/t/rpl_rewrt_db.test | 250 +++++++ mysql-test/suite/rpl/t/rpl_rotate_logs.cnf | 6 + mysql-test/suite/rpl/t/rpl_rotate_logs.test | 200 ++++++ .../rpl/t/rpl_rotate_purge_deadlock-master.opt | 1 + .../suite/rpl/t/rpl_rotate_purge_deadlock.test | 96 +++ mysql-test/suite/rpl/t/rpl_row_001.test | 51 ++ mysql-test/suite/rpl/t/rpl_row_4_bytes-master.opt | 2 + mysql-test/suite/rpl/t/rpl_row_4_bytes.test | 34 + mysql-test/suite/rpl/t/rpl_row_NOW.test | 75 +++ mysql-test/suite/rpl/t/rpl_row_USER.test | 59 ++ mysql-test/suite/rpl/t/rpl_row_UUID.test | 8 + .../suite/rpl/t/rpl_row_annotate_do-slave.opt | 1 + mysql-test/suite/rpl/t/rpl_row_annotate_do.test | 16 + .../suite/rpl/t/rpl_row_annotate_dont-slave.opt | 1 + mysql-test/suite/rpl/t/rpl_row_annotate_dont.test | 9 + .../suite/rpl/t/rpl_row_basic_11bugs-master.opt | 2 + mysql-test/suite/rpl/t/rpl_row_basic_11bugs.test | 242 +++++++ mysql-test/suite/rpl/t/rpl_row_basic_2myisam.test | 11 + mysql-test/suite/rpl/t/rpl_row_basic_3innodb.test | 11 + .../suite/rpl/t/rpl_row_basic_8partition.test | 190 ++++++ mysql-test/suite/rpl/t/rpl_row_big_table_id.opt | 1 + mysql-test/suite/rpl/t/rpl_row_big_table_id.test | 57 ++ .../suite/rpl/t/rpl_row_binlog_max_cache_size.test | 8 + mysql-test/suite/rpl/t/rpl_row_blob_innodb.test | 13 + mysql-test/suite/rpl/t/rpl_row_blob_myisam.test | 12 + mysql-test/suite/rpl/t/rpl_row_colSize.test | 173 +++++ mysql-test/suite/rpl/t/rpl_row_conflicts.test | 33 + .../suite/rpl/t/rpl_row_corruption-slave.opt | 1 + mysql-test/suite/rpl/t/rpl_row_corruption.test | 115 ++++ mysql-test/suite/rpl/t/rpl_row_create_select.test | 30 + mysql-test/suite/rpl/t/rpl_row_create_table.test | 285 ++++++++ mysql-test/suite/rpl/t/rpl_row_delayed_ins.test | 2 + mysql-test/suite/rpl/t/rpl_row_drop.test | 38 ++ .../rpl/t/rpl_row_drop_create_temp_table.test | 11 + .../suite/rpl/t/rpl_row_drop_temp_table.test | 54 ++ .../rpl/t/rpl_row_end_of_statement_loss-master.opt | 2 + .../suite/rpl/t/rpl_row_end_of_statement_loss.test | 66 ++ .../suite/rpl/t/rpl_row_err_daisychain-master.opt | 1 + .../suite/rpl/t/rpl_row_err_daisychain-slave.opt | 1 + mysql-test/suite/rpl/t/rpl_row_find_row.test | 103 +++ mysql-test/suite/rpl/t/rpl_row_find_row_debug.test | 57 ++ mysql-test/suite/rpl/t/rpl_row_flsh_tbls.test | 7 + mysql-test/suite/rpl/t/rpl_row_func001.test | 58 ++ mysql-test/suite/rpl/t/rpl_row_func002.test | 105 +++ mysql-test/suite/rpl/t/rpl_row_func003.test | 12 + mysql-test/suite/rpl/t/rpl_row_idempotency.test | 333 ++++++++++ mysql-test/suite/rpl/t/rpl_row_img.cnf | 21 + mysql-test/suite/rpl/t/rpl_row_img_blobs.cnf | 1 + mysql-test/suite/rpl/t/rpl_row_img_blobs.test | 59 ++ mysql-test/suite/rpl/t/rpl_row_img_eng_min.cnf | 1 + mysql-test/suite/rpl/t/rpl_row_img_eng_min.test | 39 ++ mysql-test/suite/rpl/t/rpl_row_img_eng_noblob.cnf | 1 + mysql-test/suite/rpl/t/rpl_row_img_eng_noblob.test | 39 ++ .../rpl/t/rpl_row_implicit_commit_binlog.test | 12 + mysql-test/suite/rpl/t/rpl_row_index_choice.test | 243 +++++++ mysql-test/suite/rpl/t/rpl_row_inexist_tbl.test | 40 ++ .../suite/rpl/t/rpl_row_lcase_tblnames-slave.opt | 1 + mysql-test/suite/rpl/t/rpl_row_lcase_tblnames.test | 12 + .../suite/rpl/t/rpl_row_loaddata_concurrent.test | 13 + mysql-test/suite/rpl/t/rpl_row_log-master.opt | 1 + mysql-test/suite/rpl/t/rpl_row_log-slave.opt | 1 + mysql-test/suite/rpl/t/rpl_row_log.test | 15 + .../suite/rpl/t/rpl_row_log_innodb-master.opt | 2 + mysql-test/suite/rpl/t/rpl_row_log_innodb.test | 13 + mysql-test/suite/rpl/t/rpl_row_max_relay_size.test | 9 + mysql-test/suite/rpl/t/rpl_row_merge_engine.test | 52 ++ mysql-test/suite/rpl/t/rpl_row_mixing_engines.test | 12 + .../suite/rpl/t/rpl_row_mysqlbinlog-master.opt | 1 + mysql-test/suite/rpl/t/rpl_row_mysqlbinlog.test | 285 ++++++++ .../suite/rpl/t/rpl_row_rec_comp_innodb.test | 11 + .../suite/rpl/t/rpl_row_rec_comp_myisam.test | 32 + mysql-test/suite/rpl/t/rpl_row_reset_slave.test | 5 + .../suite/rpl/t/rpl_row_rollback_to_savepoint.test | 312 +++++++++ .../suite/rpl/t/rpl_row_show_relaylog_events.test | 19 + mysql-test/suite/rpl/t/rpl_row_sp001.test | 145 ++++ mysql-test/suite/rpl/t/rpl_row_sp002_innodb.test | 3 + mysql-test/suite/rpl/t/rpl_row_sp003.test | 16 + mysql-test/suite/rpl/t/rpl_row_sp005.test | 102 +++ mysql-test/suite/rpl/t/rpl_row_sp006_InnoDB.test | 12 + mysql-test/suite/rpl/t/rpl_row_sp007_innodb.test | 3 + mysql-test/suite/rpl/t/rpl_row_sp008.test | 52 ++ mysql-test/suite/rpl/t/rpl_row_sp009.test | 98 +++ mysql-test/suite/rpl/t/rpl_row_sp010.test | 77 +++ mysql-test/suite/rpl/t/rpl_row_sp011.test | 112 ++++ mysql-test/suite/rpl/t/rpl_row_sp012.test | 74 +++ mysql-test/suite/rpl/t/rpl_row_spatial.test | 17 + .../suite/rpl/t/rpl_row_tabledefs_2myisam.test | 9 + .../suite/rpl/t/rpl_row_tabledefs_3innodb.test | 10 + mysql-test/suite/rpl/t/rpl_row_tbl_metadata.test | 338 ++++++++++ mysql-test/suite/rpl/t/rpl_row_to_stmt-master.opt | 1 + mysql-test/suite/rpl/t/rpl_row_to_stmt-slave.opt | 1 + mysql-test/suite/rpl/t/rpl_row_to_stmt.test | 23 + mysql-test/suite/rpl/t/rpl_row_trig001.test | 116 ++++ mysql-test/suite/rpl/t/rpl_row_trig002.test | 77 +++ mysql-test/suite/rpl/t/rpl_row_trig003.test | 155 +++++ mysql-test/suite/rpl/t/rpl_row_trig004.test | 15 + mysql-test/suite/rpl/t/rpl_row_triggers.test | 442 ++++++++++++ mysql-test/suite/rpl/t/rpl_row_trunc_temp.test | 35 + .../suite/rpl/t/rpl_row_type_conv_err_msg.test | 356 ++++++++++ mysql-test/suite/rpl/t/rpl_row_unsafe_funcs.test | 36 + mysql-test/suite/rpl/t/rpl_row_until.test | 150 +++++ mysql-test/suite/rpl/t/rpl_row_utf16.test | 26 + mysql-test/suite/rpl/t/rpl_row_utf32.test | 45 ++ mysql-test/suite/rpl/t/rpl_row_vcol_crash.test | 425 ++++++++++++ mysql-test/suite/rpl/t/rpl_row_view01.test | 85 +++ mysql-test/suite/rpl/t/rpl_row_virt.test | 27 + mysql-test/suite/rpl/t/rpl_row_wide_table.test | 340 ++++++++++ mysql-test/suite/rpl/t/rpl_savepoint.test | 43 ++ mysql-test/suite/rpl/t/rpl_semi_sync.test | 1 + .../suite/rpl/t/rpl_semi_sync_after_sync.test | 4 + .../suite/rpl/t/rpl_semi_sync_after_sync_row.test | 4 + .../suite/rpl/t/rpl_semi_sync_event-master.opt | 1 + mysql-test/suite/rpl/t/rpl_semi_sync_event.test | 90 +++ .../t/rpl_semi_sync_event_after_sync-master.opt | 1 + .../rpl/t/rpl_semi_sync_event_after_sync.test | 3 + .../suite/rpl/t/rpl_semi_sync_gtid_reconnect.test | 74 +++ .../suite/rpl/t/rpl_semi_sync_master_shutdown.test | 60 ++ .../suite/rpl/t/rpl_semi_sync_skip_repl.test | 66 ++ ...l_semi_sync_slave_compressed_protocol-slave.opt | 1 + .../t/rpl_semi_sync_slave_compressed_protocol.test | 55 ++ .../rpl/t/rpl_semi_sync_slave_reply_fail.test | 87 +++ .../rpl/t/rpl_semi_sync_wait_no_slave-master.opt | 1 + .../suite/rpl/t/rpl_semi_sync_wait_no_slave.test | 14 + .../suite/rpl/t/rpl_semi_sync_wait_point.opt | 1 + .../suite/rpl/t/rpl_semi_sync_wait_point.test | 253 +++++++ .../suite/rpl/t/rpl_semisync_ali_issues-master.opt | 1 + .../suite/rpl/t/rpl_semisync_ali_issues-slave.opt | 1 + .../suite/rpl/t/rpl_semisync_ali_issues.test | 425 ++++++++++++ mysql-test/suite/rpl/t/rpl_server_id1.test | 22 + mysql-test/suite/rpl/t/rpl_server_id2-slave.opt | 1 + mysql-test/suite/rpl/t/rpl_server_id2.test | 67 ++ .../suite/rpl/t/rpl_server_id_ignore-slave.opt | 1 + mysql-test/suite/rpl/t/rpl_server_id_ignore.test | 116 ++++ mysql-test/suite/rpl/t/rpl_session_var.test | 61 ++ mysql-test/suite/rpl/t/rpl_set_charset.test | 30 + mysql-test/suite/rpl/t/rpl_set_null_innodb.test | 7 + mysql-test/suite/rpl/t/rpl_set_null_myisam.test | 6 + mysql-test/suite/rpl/t/rpl_set_statement.test | 61 ++ .../rpl/t/rpl_set_statement_default_master.test | 34 + mysql-test/suite/rpl/t/rpl_show_slave_hosts.cnf | 20 + mysql-test/suite/rpl/t/rpl_show_slave_hosts.test | 52 ++ mysql-test/suite/rpl/t/rpl_show_slave_running.test | 83 +++ .../rpl/t/rpl_shutdown_wait_semisync_slaves.cnf | 16 + .../rpl/t/rpl_shutdown_wait_semisync_slaves.test | 46 ++ .../suite/rpl/t/rpl_shutdown_wait_slaves.cnf | 16 + .../suite/rpl/t/rpl_shutdown_wait_slaves.test | 11 + mysql-test/suite/rpl/t/rpl_skip_error-slave.opt | 1 + mysql-test/suite/rpl/t/rpl_skip_error.test | 175 +++++ .../suite/rpl/t/rpl_skip_incident-master.opt | 1 + mysql-test/suite/rpl/t/rpl_skip_incident-slave.opt | 1 + mysql-test/suite/rpl/t/rpl_skip_incident.test | 42 ++ mysql-test/suite/rpl/t/rpl_skip_replication.test | 1 + .../suite/rpl/t/rpl_slave_alias_replica.test | 102 +++ mysql-test/suite/rpl/t/rpl_slave_grp_exec.test | 186 ++++++ .../rpl/t/rpl_slave_invalid_external_user.test | 42 ++ mysql-test/suite/rpl/t/rpl_slave_load_in.test | 49 ++ .../suite/rpl/t/rpl_slave_load_remove_tmpfile.test | 80 +++ .../t/rpl_slave_load_tmpdir_not_exist-slave.opt | 1 + .../rpl/t/rpl_slave_load_tmpdir_not_exist.test | 22 + .../suite/rpl/t/rpl_slave_shutdown_mdev20821.cnf | 19 + .../suite/rpl/t/rpl_slave_shutdown_mdev20821.test | 171 +++++ mysql-test/suite/rpl/t/rpl_slave_skip.test | 293 ++++++++ mysql-test/suite/rpl/t/rpl_slave_status.test | 81 +++ .../suite/rpl/t/rpl_slow_query_log-slave.opt | 1 + mysql-test/suite/rpl/t/rpl_slow_query_log.test | 343 ++++++++++ mysql-test/suite/rpl/t/rpl_sp-master.opt | 1 + mysql-test/suite/rpl/t/rpl_sp-slave.opt | 1 + mysql-test/suite/rpl/t/rpl_sp.test | 730 ++++++++++++++++++++ mysql-test/suite/rpl/t/rpl_sp004.test | 92 +++ mysql-test/suite/rpl/t/rpl_sp_effects-master.opt | 1 + mysql-test/suite/rpl/t/rpl_sp_effects-slave.opt | 1 + mysql-test/suite/rpl/t/rpl_sp_effects.test | 286 ++++++++ mysql-test/suite/rpl/t/rpl_sp_variables.test | 28 + mysql-test/suite/rpl/t/rpl_spec_variables.test | 312 +++++++++ mysql-test/suite/rpl/t/rpl_special_charset.opt | 1 + mysql-test/suite/rpl/t/rpl_special_charset.test | 1 + .../suite/rpl/t/rpl_sporadic_master-master.opt | 1 + mysql-test/suite/rpl/t/rpl_sporadic_master.test | 1 + mysql-test/suite/rpl/t/rpl_ssl.test | 1 + mysql-test/suite/rpl/t/rpl_ssl1.test | 110 +++ .../suite/rpl/t/rpl_start_stop_slave-slave.opt | 1 + mysql-test/suite/rpl/t/rpl_start_stop_slave.test | 65 ++ mysql-test/suite/rpl/t/rpl_stm_000001.test | 118 ++++ mysql-test/suite/rpl/t/rpl_stm_EE_err2.test | 8 + .../rpl/t/rpl_stm_auto_increment_bug33029.test | 106 +++ .../suite/rpl/t/rpl_stm_binlog_direct-master.opt | 1 + .../suite/rpl/t/rpl_stm_binlog_max_cache_size.test | 8 + mysql-test/suite/rpl/t/rpl_stm_conflicts.test | 6 + .../rpl/t/rpl_stm_drop_create_temp_table.test | 12 + mysql-test/suite/rpl/t/rpl_stm_flsh_tbls.test | 6 + mysql-test/suite/rpl/t/rpl_stm_found_rows.test | 116 ++++ .../rpl/t/rpl_stm_implicit_commit_binlog.test | 12 + mysql-test/suite/rpl/t/rpl_stm_innodb.test | 9 + .../suite/rpl/t/rpl_stm_lcase_tblnames-slave.opt | 1 + mysql-test/suite/rpl/t/rpl_stm_lcase_tblnames.test | 12 + .../suite/rpl/t/rpl_stm_loaddata_concurrent.test | 14 + mysql-test/suite/rpl/t/rpl_stm_loadfile.test | 24 + mysql-test/suite/rpl/t/rpl_stm_log-slave.opt | 1 + mysql-test/suite/rpl/t/rpl_stm_log.test | 8 + mysql-test/suite/rpl/t/rpl_stm_maria.test | 59 ++ mysql-test/suite/rpl/t/rpl_stm_max_relay_size.test | 8 + .../rpl/t/rpl_stm_mix_show_relaylog_events.test | 19 + mysql-test/suite/rpl/t/rpl_stm_mixing_engines.test | 48 ++ mysql-test/suite/rpl/t/rpl_stm_multi_query.test | 7 + mysql-test/suite/rpl/t/rpl_stm_no_op.test | 94 +++ .../suite/rpl/t/rpl_stm_relay_ign_space-slave.opt | 1 + .../suite/rpl/t/rpl_stm_relay_ign_space.test | 1 + mysql-test/suite/rpl/t/rpl_stm_reset_slave.test | 6 + mysql-test/suite/rpl/t/rpl_stm_sp.test | 30 + mysql-test/suite/rpl/t/rpl_stm_sql_mode.test | 25 + .../suite/rpl/t/rpl_stm_start_stop_slave.test | 26 + .../suite/rpl/t/rpl_stm_stop_middle_group.test | 11 + mysql-test/suite/rpl/t/rpl_stm_until.test | 183 +++++ mysql-test/suite/rpl/t/rpl_stm_user_variables.test | 202 ++++++ mysql-test/suite/rpl/t/rpl_stop_slave.test | 140 ++++ .../suite/rpl/t/rpl_stop_slave_error-slave.opt | 1 + mysql-test/suite/rpl/t/rpl_stop_slave_error.test | 16 + .../rpl/t/rpl_strict_password_validation.test | 24 + .../suite/rpl/t/rpl_switch_stm_row_mixed.test | 1 + mysql-test/suite/rpl/t/rpl_sync-master.opt | 2 + mysql-test/suite/rpl/t/rpl_sync-slave.opt | 2 + mysql-test/suite/rpl/t/rpl_sync.test | 2 + mysql-test/suite/rpl/t/rpl_table_options.test | 38 ++ mysql-test/suite/rpl/t/rpl_temp_table.test | 85 +++ mysql-test/suite/rpl/t/rpl_temp_table_mix_row.test | 205 ++++++ .../t/rpl_temporal_format_default_to_default.test | 1 + ...rpl_temporal_format_mariadb53_to_mariadb53.test | 4 + .../rpl_temporal_format_mariadb53_to_mysql56.test | 14 + ...l_temporal_format_mariadb53_to_mysql56_dst.test | 37 ++ .../rpl_temporal_format_mysql56_to_mariadb53.test | 4 + .../t/rpl_temporal_format_mysql56_to_mysql56.test | 4 + mysql-test/suite/rpl/t/rpl_temporal_mysql56.test | 48 ++ .../rpl/t/rpl_temporal_mysql56_to_mariadb.test | 55 ++ .../rpl/t/rpl_temporal_mysql56_to_mariadb53.test | 2 + mysql-test/suite/rpl/t/rpl_temporal_round.test | 35 + mysql-test/suite/rpl/t/rpl_temporary.test | 416 ++++++++++++ mysql-test/suite/rpl/t/rpl_temporary_error2.test | 79 +++ .../suite/rpl/t/rpl_temporary_errors-slave.opt | 1 + mysql-test/suite/rpl/t/rpl_temporary_errors.test | 116 ++++ mysql-test/suite/rpl/t/rpl_test_framework.cnf | 28 + mysql-test/suite/rpl/t/rpl_test_framework.test | 143 ++++ mysql-test/suite/rpl/t/rpl_timezone-master.opt | 1 + mysql-test/suite/rpl/t/rpl_timezone-slave.opt | 1 + mysql-test/suite/rpl/t/rpl_timezone.test | 211 ++++++ mysql-test/suite/rpl/t/rpl_tmp_table_and_DDL.test | 169 +++++ .../suite/rpl/t/rpl_tmp_table_and_DDL_innodb.test | 55 ++ mysql-test/suite/rpl/t/rpl_trans_no_trans.test | 72 ++ mysql-test/suite/rpl/t/rpl_trigger.test | 585 ++++++++++++++++ mysql-test/suite/rpl/t/rpl_trunc_temp.test | 57 ++ mysql-test/suite/rpl/t/rpl_truncate_2myisam.test | 2 + mysql-test/suite/rpl/t/rpl_truncate_3innodb.test | 3 + mysql-test/suite/rpl/t/rpl_typeconv-slave.opt | 1 + mysql-test/suite/rpl/t/rpl_typeconv.test | 1 + mysql-test/suite/rpl/t/rpl_typeconv_innodb.test | 26 + mysql-test/suite/rpl/t/rpl_udf.test | 11 + mysql-test/suite/rpl/t/rpl_unsafe_statements.test | 176 +++++ mysql-test/suite/rpl/t/rpl_update.test | 15 + .../suite/rpl/t/rpl_upgrade_master_info.test | 168 +++++ mysql-test/suite/rpl/t/rpl_user.test | 73 ++ mysql-test/suite/rpl/t/rpl_user_variables.test | 385 +++++++++++ mysql-test/suite/rpl/t/rpl_variables.test | 738 +++++++++++++++++++++ mysql-test/suite/rpl/t/rpl_variables_stm.test | 616 +++++++++++++++++ mysql-test/suite/rpl/t/rpl_view.test | 171 +++++ mysql-test/suite/rpl/t/rpl_view_debug.test | 35 + mysql-test/suite/rpl/t/rpl_view_multi.test | 131 ++++ mysql-test/suite/rpl/t/rpl_xa-master.opt | 1 + mysql-test/suite/rpl/t/rpl_xa.inc | 355 ++++++++++ mysql-test/suite/rpl/t/rpl_xa.test | 5 + mysql-test/suite/rpl/t/rpl_xa_gap_lock-slave.opt | 1 + mysql-test/suite/rpl/t/rpl_xa_gap_lock.test | 137 ++++ .../rpl/t/rpl_xa_gtid_pos_auto_engine-master.opt | 1 + .../suite/rpl/t/rpl_xa_gtid_pos_auto_engine.test | 29 + .../suite/rpl/t/rpl_xa_survive_disconnect.test | 297 +++++++++ .../t/rpl_xa_survive_disconnect_lsu_off-slave.opt | 2 + .../rpl/t/rpl_xa_survive_disconnect_lsu_off.test | 8 + .../t/rpl_xa_survive_disconnect_mixed_engines.test | 68 ++ mysql-test/suite/rpl/t/sec_behind_master-5114.test | 63 ++ mysql-test/suite/rpl/t/semisync_future-7591.test | 32 + mysql-test/suite/rpl/t/semisync_memleak_4066.test | 14 + mysql-test/suite/rpl/t/sequence.cnf | 8 + mysql-test/suite/rpl/t/sequence.test | 52 ++ .../rpl/t/show_status_stop_slave_race-7126.test | 22 + .../suite/rpl/t/temporal_row-9560-master.opt | 1 + .../suite/rpl/t/temporal_row-9560.combinations | 6 + mysql-test/suite/rpl/t/temporal_row-9560.test | 20 + 695 files changed, 44903 insertions(+) create mode 100644 mysql-test/suite/rpl/t/circular_serverid0.cnf create mode 100644 mysql-test/suite/rpl/t/circular_serverid0.test create mode 100644 mysql-test/suite/rpl/t/create_or_replace.inc create mode 100644 mysql-test/suite/rpl/t/create_or_replace2.test create mode 100644 mysql-test/suite/rpl/t/create_or_replace_mix.cnf create mode 100644 mysql-test/suite/rpl/t/create_or_replace_mix.test create mode 100644 mysql-test/suite/rpl/t/create_or_replace_row.cnf create mode 100644 mysql-test/suite/rpl/t/create_or_replace_row.test create mode 100644 mysql-test/suite/rpl/t/create_or_replace_statement.cnf create mode 100644 mysql-test/suite/rpl/t/create_or_replace_statement.test create mode 100644 mysql-test/suite/rpl/t/create_select.cnf create mode 100644 mysql-test/suite/rpl/t/create_select.test create mode 100644 mysql-test/suite/rpl/t/failed_create_view-6409.test create mode 100644 mysql-test/suite/rpl/t/grant_replication_slave.test create mode 100644 mysql-test/suite/rpl/t/ignore_table_autoinc-9737.test create mode 100644 mysql-test/suite/rpl/t/kill_hard-6290.test create mode 100644 mysql-test/suite/rpl/t/kill_race_condition.test create mode 100644 mysql-test/suite/rpl/t/last_insert_id.cnf create mode 100644 mysql-test/suite/rpl/t/last_insert_id.test create mode 100644 mysql-test/suite/rpl/t/mdev_17588-slave.opt create mode 100644 mysql-test/suite/rpl/t/mdev_17588.test create mode 100644 mysql-test/suite/rpl/t/myisam_external_lock-slave.opt create mode 100644 mysql-test/suite/rpl/t/myisam_external_lock.test create mode 100644 mysql-test/suite/rpl/t/mysql-wsrep#110-2.test create mode 100644 mysql-test/suite/rpl/t/parallel_backup.test create mode 100644 mysql-test/suite/rpl/t/password_expiration.test create mode 100644 mysql-test/suite/rpl/t/rename.test create mode 100644 mysql-test/suite/rpl/t/replace.test create mode 100644 mysql-test/suite/rpl/t/rpl_000010-slave.opt create mode 100644 mysql-test/suite/rpl/t/rpl_000010.test create mode 100644 mysql-test/suite/rpl/t/rpl_000011-slave.opt create mode 100644 mysql-test/suite/rpl/t/rpl_000011.test create mode 100644 mysql-test/suite/rpl/t/rpl_000013.test create mode 100644 mysql-test/suite/rpl/t/rpl_000017.test create mode 100644 mysql-test/suite/rpl/t/rpl_15867.test create mode 100644 mysql-test/suite/rpl/t/rpl_15919-slave.opt create mode 100644 mysql-test/suite/rpl/t/rpl_15919.test create mode 100644 mysql-test/suite/rpl/t/rpl_EE_err.test create mode 100644 mysql-test/suite/rpl/t/rpl_LD_INFILE.test create mode 100644 mysql-test/suite/rpl/t/rpl_alter.test create mode 100644 mysql-test/suite/rpl/t/rpl_alter_db.test create mode 100644 mysql-test/suite/rpl/t/rpl_alter_extra_persistent.test create mode 100644 mysql-test/suite/rpl/t/rpl_alter_instant.test create mode 100644 mysql-test/suite/rpl/t/rpl_auto_increment-master.opt create mode 100644 mysql-test/suite/rpl/t/rpl_auto_increment-slave.opt create mode 100644 mysql-test/suite/rpl/t/rpl_auto_increment.test create mode 100644 mysql-test/suite/rpl/t/rpl_auto_increment_11932.test create mode 100644 mysql-test/suite/rpl/t/rpl_auto_increment_bug33029.test create mode 100644 mysql-test/suite/rpl/t/rpl_auto_increment_bug45679.test create mode 100644 mysql-test/suite/rpl/t/rpl_auto_increment_update_failure.test create mode 100644 mysql-test/suite/rpl/t/rpl_autogen_query_multi_byte_char.test create mode 100644 mysql-test/suite/rpl/t/rpl_begin_commit_rollback-master.opt create mode 100644 mysql-test/suite/rpl/t/rpl_begin_commit_rollback-slave.opt create mode 100644 mysql-test/suite/rpl/t/rpl_begin_commit_rollback.test create mode 100644 mysql-test/suite/rpl/t/rpl_binlog_compress.test create mode 100644 mysql-test/suite/rpl/t/rpl_binlog_corruption.test create mode 100644 mysql-test/suite/rpl/t/rpl_binlog_dump_slave_gtid_state_info.test create mode 100644 mysql-test/suite/rpl/t/rpl_binlog_dup_entry.test create mode 100644 mysql-test/suite/rpl/t/rpl_binlog_errors-master.opt create mode 100644 mysql-test/suite/rpl/t/rpl_binlog_errors.test create mode 100644 mysql-test/suite/rpl/t/rpl_binlog_grant.test create mode 100644 mysql-test/suite/rpl/t/rpl_binlog_index.test create mode 100644 mysql-test/suite/rpl/t/rpl_binlog_rollback_cleanup.test create mode 100644 mysql-test/suite/rpl/t/rpl_bit.test create mode 100644 mysql-test/suite/rpl/t/rpl_bit_npk.test create mode 100644 mysql-test/suite/rpl/t/rpl_blackhole.test create mode 100644 mysql-test/suite/rpl/t/rpl_blackhole_row_annotate-master.opt create mode 100644 mysql-test/suite/rpl/t/rpl_blackhole_row_annotate-slave.opt create mode 100644 mysql-test/suite/rpl/t/rpl_blackhole_row_annotate.test create mode 100644 mysql-test/suite/rpl/t/rpl_bug26395.test create mode 100644 mysql-test/suite/rpl/t/rpl_bug31076.test create mode 100644 mysql-test/suite/rpl/t/rpl_bug33931.test create mode 100644 mysql-test/suite/rpl/t/rpl_bug37426.test create mode 100644 mysql-test/suite/rpl/t/rpl_bug38694-slave.opt create mode 100644 mysql-test/suite/rpl/t/rpl_bug38694.test create mode 100644 mysql-test/suite/rpl/t/rpl_bug41902.test create mode 100644 mysql-test/suite/rpl/t/rpl_cant_read_event_incident.test create mode 100644 mysql-test/suite/rpl/t/rpl_change_master.test create mode 100644 mysql-test/suite/rpl/t/rpl_charset.test create mode 100644 mysql-test/suite/rpl/t/rpl_charset_sjis.test create mode 100644 mysql-test/suite/rpl/t/rpl_checksum-master.opt create mode 100644 mysql-test/suite/rpl/t/rpl_checksum.test create mode 100644 mysql-test/suite/rpl/t/rpl_checksum_cache.test create mode 100644 mysql-test/suite/rpl/t/rpl_circular_for_4_hosts.cnf create mode 100644 mysql-test/suite/rpl/t/rpl_circular_for_4_hosts.test create mode 100644 mysql-test/suite/rpl/t/rpl_colSize.test create mode 100644 mysql-test/suite/rpl/t/rpl_commit_after_flush.test create mode 100644 mysql-test/suite/rpl/t/rpl_concurrency_error-master.opt create mode 100644 mysql-test/suite/rpl/t/rpl_concurrency_error.test create mode 100644 mysql-test/suite/rpl/t/rpl_conditional_comments.test create mode 100644 mysql-test/suite/rpl/t/rpl_connection.test create mode 100644 mysql-test/suite/rpl/t/rpl_corruption-master.opt create mode 100644 mysql-test/suite/rpl/t/rpl_corruption-slave.opt create mode 100644 mysql-test/suite/rpl/t/rpl_corruption.test create mode 100644 mysql-test/suite/rpl/t/rpl_create_database-master.opt create mode 100644 mysql-test/suite/rpl/t/rpl_create_database-slave.opt create mode 100644 mysql-test/suite/rpl/t/rpl_create_database.test create mode 100644 mysql-test/suite/rpl/t/rpl_create_drop_db.test create mode 100644 mysql-test/suite/rpl/t/rpl_create_drop_event.test create mode 100644 mysql-test/suite/rpl/t/rpl_create_drop_function.test create mode 100644 mysql-test/suite/rpl/t/rpl_create_drop_index.test create mode 100644 mysql-test/suite/rpl/t/rpl_create_drop_procedure.test create mode 100644 mysql-test/suite/rpl/t/rpl_create_drop_role.test create mode 100644 mysql-test/suite/rpl/t/rpl_create_drop_trigger.test create mode 100644 mysql-test/suite/rpl/t/rpl_create_drop_udf.test create mode 100644 mysql-test/suite/rpl/t/rpl_create_drop_user.test create mode 100644 mysql-test/suite/rpl/t/rpl_create_drop_view.test create mode 100644 mysql-test/suite/rpl/t/rpl_create_if_not_exists.test create mode 100644 mysql-test/suite/rpl/t/rpl_create_or_replace_fail.test create mode 100644 mysql-test/suite/rpl/t/rpl_create_tmp_table_if_not_exists.test create mode 100644 mysql-test/suite/rpl/t/rpl_create_xa_prepared.inc create mode 100644 mysql-test/suite/rpl/t/rpl_critical_errors.test create mode 100644 mysql-test/suite/rpl/t/rpl_cross_version-master.opt create mode 100644 mysql-test/suite/rpl/t/rpl_cross_version.test create mode 100644 mysql-test/suite/rpl/t/rpl_ctype_latin1.test create mode 100644 mysql-test/suite/rpl/t/rpl_current_user.cnf create mode 100644 mysql-test/suite/rpl/t/rpl_current_user.test create mode 100644 mysql-test/suite/rpl/t/rpl_ddl-slave.opt create mode 100644 mysql-test/suite/rpl/t/rpl_ddl.test create mode 100644 mysql-test/suite/rpl/t/rpl_deadlock_innodb-slave.opt create mode 100644 mysql-test/suite/rpl/t/rpl_deadlock_innodb.test create mode 100644 mysql-test/suite/rpl/t/rpl_default.test create mode 100644 mysql-test/suite/rpl/t/rpl_delayed_slave.combinations create mode 100644 mysql-test/suite/rpl/t/rpl_delayed_slave.test create mode 100644 mysql-test/suite/rpl/t/rpl_delayed_slave2.test create mode 100644 mysql-test/suite/rpl/t/rpl_delete_no_where.test create mode 100644 mysql-test/suite/rpl/t/rpl_do_grant.test create mode 100644 mysql-test/suite/rpl/t/rpl_domain_id_filter.test create mode 100644 mysql-test/suite/rpl/t/rpl_domain_id_filter_io_crash.test create mode 100644 mysql-test/suite/rpl/t/rpl_domain_id_filter_master_crash.test create mode 100644 mysql-test/suite/rpl/t/rpl_domain_id_filter_parallel.test create mode 100644 mysql-test/suite/rpl/t/rpl_domain_id_filter_restart.test create mode 100644 mysql-test/suite/rpl/t/rpl_drop.test create mode 100644 mysql-test/suite/rpl/t/rpl_drop_db.test create mode 100644 mysql-test/suite/rpl/t/rpl_drop_db_fail.test create mode 100644 mysql-test/suite/rpl/t/rpl_drop_temp-slave.opt create mode 100644 mysql-test/suite/rpl/t/rpl_drop_temp.test create mode 100644 mysql-test/suite/rpl/t/rpl_drop_temp_table_invalid_lex.test create mode 100644 mysql-test/suite/rpl/t/rpl_drop_view.test create mode 100644 mysql-test/suite/rpl/t/rpl_dual_pos_advance.test create mode 100644 mysql-test/suite/rpl/t/rpl_dump_request_retry_warning.test create mode 100644 mysql-test/suite/rpl/t/rpl_empty_master_host.test create mode 100644 mysql-test/suite/rpl/t/rpl_err_ignoredtable-slave.opt create mode 100644 mysql-test/suite/rpl/t/rpl_err_ignoredtable.test create mode 100644 mysql-test/suite/rpl/t/rpl_events.test create mode 100644 mysql-test/suite/rpl/t/rpl_extra_col_master_innodb.test create mode 100644 mysql-test/suite/rpl/t/rpl_extra_col_master_myisam.test create mode 100644 mysql-test/suite/rpl/t/rpl_extra_col_slave_innodb.test create mode 100644 mysql-test/suite/rpl/t/rpl_extra_col_slave_myisam.test create mode 100644 mysql-test/suite/rpl/t/rpl_fail_register.test create mode 100644 mysql-test/suite/rpl/t/rpl_failed_drop_tbl_binlog.opt create mode 100644 mysql-test/suite/rpl/t/rpl_failed_optimize.test create mode 100644 mysql-test/suite/rpl/t/rpl_filter_dbs_dynamic.test create mode 100644 mysql-test/suite/rpl/t/rpl_filter_tables_dynamic.test create mode 100644 mysql-test/suite/rpl/t/rpl_filter_tables_not_exist-slave.opt create mode 100644 mysql-test/suite/rpl/t/rpl_filter_tables_not_exist.test create mode 100644 mysql-test/suite/rpl/t/rpl_filter_wild_tables_dynamic.test create mode 100644 mysql-test/suite/rpl/t/rpl_flush_logs-master.opt create mode 100644 mysql-test/suite/rpl/t/rpl_flush_logs.test create mode 100644 mysql-test/suite/rpl/t/rpl_flushlog_loop-master.opt create mode 100644 mysql-test/suite/rpl/t/rpl_flushlog_loop-slave.opt create mode 100644 mysql-test/suite/rpl/t/rpl_flushlog_loop.test create mode 100644 mysql-test/suite/rpl/t/rpl_foreign_key_innodb.test create mode 100644 mysql-test/suite/rpl/t/rpl_free_items-slave.opt create mode 100644 mysql-test/suite/rpl/t/rpl_free_items.test create mode 100644 mysql-test/suite/rpl/t/rpl_function_defaults.test create mode 100644 mysql-test/suite/rpl/t/rpl_geometry.test create mode 100644 mysql-test/suite/rpl/t/rpl_get_lock.test create mode 100644 mysql-test/suite/rpl/t/rpl_get_master_version_and_clock-slave.opt create mode 100644 mysql-test/suite/rpl/t/rpl_get_master_version_and_clock.test create mode 100644 mysql-test/suite/rpl/t/rpl_grant.test create mode 100644 mysql-test/suite/rpl/t/rpl_gtid_basic.cnf create mode 100644 mysql-test/suite/rpl/t/rpl_gtid_basic.test create mode 100644 mysql-test/suite/rpl/t/rpl_gtid_crash-master.opt create mode 100644 mysql-test/suite/rpl/t/rpl_gtid_crash-slave.opt create mode 100644 mysql-test/suite/rpl/t/rpl_gtid_crash.test create mode 100644 mysql-test/suite/rpl/t/rpl_gtid_crash_myisam-master.opt create mode 100644 mysql-test/suite/rpl/t/rpl_gtid_crash_myisam.test create mode 100644 mysql-test/suite/rpl/t/rpl_gtid_delete_domain.test create mode 100644 mysql-test/suite/rpl/t/rpl_gtid_errorhandling.test create mode 100644 mysql-test/suite/rpl/t/rpl_gtid_errorlog.test create mode 100644 mysql-test/suite/rpl/t/rpl_gtid_excess_initial_delay.test create mode 100644 mysql-test/suite/rpl/t/rpl_gtid_ignored.test create mode 100644 mysql-test/suite/rpl/t/rpl_gtid_master_promote.cnf create mode 100644 mysql-test/suite/rpl/t/rpl_gtid_master_promote.test create mode 100644 mysql-test/suite/rpl/t/rpl_gtid_mdev4473.cnf create mode 100644 mysql-test/suite/rpl/t/rpl_gtid_mdev4473.test create mode 100644 mysql-test/suite/rpl/t/rpl_gtid_mdev4474.cnf create mode 100644 mysql-test/suite/rpl/t/rpl_gtid_mdev4474.test create mode 100644 mysql-test/suite/rpl/t/rpl_gtid_mdev4484.test create mode 100644 mysql-test/suite/rpl/t/rpl_gtid_mdev4485.cnf create mode 100644 mysql-test/suite/rpl/t/rpl_gtid_mdev4485.test create mode 100644 mysql-test/suite/rpl/t/rpl_gtid_mdev4820.test create mode 100644 mysql-test/suite/rpl/t/rpl_gtid_mdev9033.cnf create mode 100644 mysql-test/suite/rpl/t/rpl_gtid_mdev9033.test create mode 100644 mysql-test/suite/rpl/t/rpl_gtid_misc.test create mode 100644 mysql-test/suite/rpl/t/rpl_gtid_nobinlog.cnf create mode 100644 mysql-test/suite/rpl/t/rpl_gtid_nobinlog.test create mode 100644 mysql-test/suite/rpl/t/rpl_gtid_reconnect.test create mode 100644 mysql-test/suite/rpl/t/rpl_gtid_sort.test create mode 100644 mysql-test/suite/rpl/t/rpl_gtid_startpos.test create mode 100644 mysql-test/suite/rpl/t/rpl_gtid_stop_start.cnf create mode 100644 mysql-test/suite/rpl/t/rpl_gtid_stop_start.test create mode 100644 mysql-test/suite/rpl/t/rpl_gtid_strict.test create mode 100644 mysql-test/suite/rpl/t/rpl_gtid_until.test create mode 100644 mysql-test/suite/rpl/t/rpl_heartbeat.test create mode 100644 mysql-test/suite/rpl/t/rpl_heartbeat_2slaves.cnf create mode 100644 mysql-test/suite/rpl/t/rpl_heartbeat_2slaves.test create mode 100644 mysql-test/suite/rpl/t/rpl_heartbeat_basic.cnf create mode 100644 mysql-test/suite/rpl/t/rpl_heartbeat_basic.test create mode 100644 mysql-test/suite/rpl/t/rpl_heartbeat_debug.test create mode 100644 mysql-test/suite/rpl/t/rpl_heartbeat_ssl.test create mode 100644 mysql-test/suite/rpl/t/rpl_hrtime.test create mode 100644 mysql-test/suite/rpl/t/rpl_hrtime_row.test create mode 100644 mysql-test/suite/rpl/t/rpl_idempotency.test create mode 100644 mysql-test/suite/rpl/t/rpl_ignore_grant-slave.opt create mode 100644 mysql-test/suite/rpl/t/rpl_ignore_grant.test create mode 100644 mysql-test/suite/rpl/t/rpl_ignore_revoke-slave.opt create mode 100644 mysql-test/suite/rpl/t/rpl_ignore_revoke.test create mode 100644 mysql-test/suite/rpl/t/rpl_ignore_table-slave.opt create mode 100644 mysql-test/suite/rpl/t/rpl_ignore_table.test create mode 100644 mysql-test/suite/rpl/t/rpl_ignore_table_update-slave.opt create mode 100644 mysql-test/suite/rpl/t/rpl_ignore_table_update.test create mode 100644 mysql-test/suite/rpl/t/rpl_incident.test create mode 100644 mysql-test/suite/rpl/t/rpl_incompatible_heartbeat.test create mode 100644 mysql-test/suite/rpl/t/rpl_init_slave-slave.opt create mode 100644 mysql-test/suite/rpl/t/rpl_init_slave.test create mode 100644 mysql-test/suite/rpl/t/rpl_init_slave_errors.test create mode 100644 mysql-test/suite/rpl/t/rpl_innodb-master.opt create mode 100644 mysql-test/suite/rpl/t/rpl_innodb_bug28430-master.opt create mode 100644 mysql-test/suite/rpl/t/rpl_innodb_bug28430-slave.opt create mode 100644 mysql-test/suite/rpl/t/rpl_innodb_bug28430.test create mode 100644 mysql-test/suite/rpl/t/rpl_innodb_bug30888.opt create mode 100644 mysql-test/suite/rpl/t/rpl_innodb_bug30888.test create mode 100644 mysql-test/suite/rpl/t/rpl_innodb_bug68220.test create mode 100644 mysql-test/suite/rpl/t/rpl_innodb_mixed_ddl.test create mode 100644 mysql-test/suite/rpl/t/rpl_innodb_mixed_dml.test create mode 100644 mysql-test/suite/rpl/t/rpl_insert.test create mode 100644 mysql-test/suite/rpl/t/rpl_insert_delayed.test create mode 100644 mysql-test/suite/rpl/t/rpl_insert_id.test create mode 100644 mysql-test/suite/rpl/t/rpl_insert_id_pk.test create mode 100644 mysql-test/suite/rpl/t/rpl_insert_ignore.test create mode 100644 mysql-test/suite/rpl/t/rpl_invoked_features-master.opt create mode 100644 mysql-test/suite/rpl/t/rpl_invoked_features.test create mode 100644 mysql-test/suite/rpl/t/rpl_ip_mix.cnf create mode 100644 mysql-test/suite/rpl/t/rpl_ip_mix.test create mode 100644 mysql-test/suite/rpl/t/rpl_ip_mix2.cnf create mode 100644 mysql-test/suite/rpl/t/rpl_ip_mix2.test create mode 100644 mysql-test/suite/rpl/t/rpl_ipv4_as_ipv6.cnf create mode 100644 mysql-test/suite/rpl/t/rpl_ipv4_as_ipv6.test create mode 100644 mysql-test/suite/rpl/t/rpl_ipv6.cnf create mode 100644 mysql-test/suite/rpl/t/rpl_ipv6.test create mode 100644 mysql-test/suite/rpl/t/rpl_killed_ddl-master.opt create mode 100644 mysql-test/suite/rpl/t/rpl_killed_ddl.test create mode 100644 mysql-test/suite/rpl/t/rpl_known_bugs_detection-master.opt create mode 100644 mysql-test/suite/rpl/t/rpl_known_bugs_detection.test create mode 100644 mysql-test/suite/rpl/t/rpl_lcase_tblnames_rewrite_db-slave.opt create mode 100644 mysql-test/suite/rpl/t/rpl_lcase_tblnames_rewrite_db.test create mode 100644 mysql-test/suite/rpl/t/rpl_loaddata.test create mode 100644 mysql-test/suite/rpl/t/rpl_loaddata_charset.test create mode 100644 mysql-test/suite/rpl/t/rpl_loaddata_fatal-slave.opt create mode 100644 mysql-test/suite/rpl/t/rpl_loaddata_fatal.test create mode 100644 mysql-test/suite/rpl/t/rpl_loaddata_m-master.opt create mode 100644 mysql-test/suite/rpl/t/rpl_loaddata_m.test create mode 100644 mysql-test/suite/rpl/t/rpl_loaddata_map-master.opt create mode 100644 mysql-test/suite/rpl/t/rpl_loaddata_map-slave.opt create mode 100644 mysql-test/suite/rpl/t/rpl_loaddata_map.test create mode 100644 mysql-test/suite/rpl/t/rpl_loaddata_s-slave.opt create mode 100644 mysql-test/suite/rpl/t/rpl_loaddata_s.test create mode 100644 mysql-test/suite/rpl/t/rpl_loaddata_simple.test create mode 100644 mysql-test/suite/rpl/t/rpl_loaddata_symlink-master.opt create mode 100644 mysql-test/suite/rpl/t/rpl_loaddata_symlink-master.sh create mode 100644 mysql-test/suite/rpl/t/rpl_loaddata_symlink-slave.opt create mode 100644 mysql-test/suite/rpl/t/rpl_loaddata_symlink-slave.sh create mode 100644 mysql-test/suite/rpl/t/rpl_loaddata_symlink.test create mode 100644 mysql-test/suite/rpl/t/rpl_loaddatalocal.test create mode 100644 mysql-test/suite/rpl/t/rpl_loadfile.test create mode 100644 mysql-test/suite/rpl/t/rpl_locale.test create mode 100644 mysql-test/suite/rpl/t/rpl_log_pos.test create mode 100644 mysql-test/suite/rpl/t/rpl_lost_events_on_rotate.test create mode 100644 mysql-test/suite/rpl/t/rpl_manual_change_index_file.test create mode 100644 mysql-test/suite/rpl/t/rpl_many_optimize.test create mode 100644 mysql-test/suite/rpl/t/rpl_mariadb_slave_capability.test create mode 100644 mysql-test/suite/rpl/t/rpl_mark_optimize_tbl_ddl.test create mode 100644 mysql-test/suite/rpl/t/rpl_master_pos_wait.test create mode 100644 mysql-test/suite/rpl/t/rpl_mdev-11092.opt create mode 100644 mysql-test/suite/rpl/t/rpl_mdev-11092.test create mode 100644 mysql-test/suite/rpl/t/rpl_mdev10863.test create mode 100644 mysql-test/suite/rpl/t/rpl_mdev12179.test create mode 100644 mysql-test/suite/rpl/t/rpl_mdev359.test create mode 100644 mysql-test/suite/rpl/t/rpl_mdev382.test create mode 100644 mysql-test/suite/rpl/t/rpl_mdev6020.test create mode 100644 mysql-test/suite/rpl/t/rpl_mdev6386-slave.opt create mode 100644 mysql-test/suite/rpl/t/rpl_mdev6386.test create mode 100644 mysql-test/suite/rpl/t/rpl_mdev8193.test create mode 100644 mysql-test/suite/rpl/t/rpl_mdev_17614.test create mode 100644 mysql-test/suite/rpl/t/rpl_misc_functions-slave.sh create mode 100644 mysql-test/suite/rpl/t/rpl_misc_functions.test create mode 100644 mysql-test/suite/rpl/t/rpl_mix_found_rows.test create mode 100644 mysql-test/suite/rpl/t/rpl_mixed_binlog_max_cache_size.test create mode 100644 mysql-test/suite/rpl/t/rpl_mixed_bit_pk.test create mode 100644 mysql-test/suite/rpl/t/rpl_mixed_ddl_dml.test create mode 100644 mysql-test/suite/rpl/t/rpl_mixed_drop_create_temp_table.test create mode 100644 mysql-test/suite/rpl/t/rpl_mixed_implicit_commit_binlog.test create mode 100644 mysql-test/suite/rpl/t/rpl_mixed_mixing_engines.test create mode 100644 mysql-test/suite/rpl/t/rpl_mixed_row_innodb-master.opt create mode 100644 mysql-test/suite/rpl/t/rpl_multi_delete-slave.opt create mode 100644 mysql-test/suite/rpl/t/rpl_multi_delete.test create mode 100644 mysql-test/suite/rpl/t/rpl_multi_delete2-slave.opt create mode 100644 mysql-test/suite/rpl/t/rpl_multi_delete2.test create mode 100644 mysql-test/suite/rpl/t/rpl_multi_engine.test create mode 100644 mysql-test/suite/rpl/t/rpl_multi_update.test create mode 100644 mysql-test/suite/rpl/t/rpl_multi_update2-slave.opt create mode 100644 mysql-test/suite/rpl/t/rpl_multi_update2.test create mode 100644 mysql-test/suite/rpl/t/rpl_multi_update3.test create mode 100644 mysql-test/suite/rpl/t/rpl_multi_update4-slave.opt create mode 100644 mysql-test/suite/rpl/t/rpl_multi_update4.test create mode 100644 mysql-test/suite/rpl/t/rpl_mysql57_stm_temporal_round.test create mode 100644 mysql-test/suite/rpl/t/rpl_mysql80_stm_temporal_round.test create mode 100644 mysql-test/suite/rpl/t/rpl_mysql_upgrade.test create mode 100644 mysql-test/suite/rpl/t/rpl_name_const.test create mode 100644 mysql-test/suite/rpl/t/rpl_non_direct_mixed_mixing_engines.test create mode 100644 mysql-test/suite/rpl/t/rpl_non_direct_row_mixing_engines.test create mode 100644 mysql-test/suite/rpl/t/rpl_non_direct_stm_mixing_engines.test create mode 100644 mysql-test/suite/rpl/t/rpl_nondeterministic_functions.test create mode 100644 mysql-test/suite/rpl/t/rpl_not_null_innodb.test create mode 100644 mysql-test/suite/rpl/t/rpl_not_null_myisam.test create mode 100644 mysql-test/suite/rpl/t/rpl_old_decimal.test create mode 100644 mysql-test/suite/rpl/t/rpl_old_master.test create mode 100644 mysql-test/suite/rpl/t/rpl_optimize.test create mode 100644 mysql-test/suite/rpl/t/rpl_packet-master.opt create mode 100644 mysql-test/suite/rpl/t/rpl_packet-slave.opt create mode 100644 mysql-test/suite/rpl/t/rpl_packet.test create mode 100644 mysql-test/suite/rpl/t/rpl_parallel2.test create mode 100644 mysql-test/suite/rpl/t/rpl_parallel_analyze_table_hang.test create mode 100644 mysql-test/suite/rpl/t/rpl_parallel_charset.test create mode 100644 mysql-test/suite/rpl/t/rpl_parallel_conflicts.test create mode 100644 mysql-test/suite/rpl/t/rpl_parallel_deadlock_corrupt_binlog.test create mode 100644 mysql-test/suite/rpl/t/rpl_parallel_domain.test create mode 100644 mysql-test/suite/rpl/t/rpl_parallel_domain_slave_single_grp.test create mode 100644 mysql-test/suite/rpl/t/rpl_parallel_free_deferred_event.test create mode 100644 mysql-test/suite/rpl/t/rpl_parallel_gco_wait_kill.test create mode 100644 mysql-test/suite/rpl/t/rpl_parallel_gtid_slave_pos_update_fail.test create mode 100644 mysql-test/suite/rpl/t/rpl_parallel_ignore_error_on_rotate.test create mode 100644 mysql-test/suite/rpl/t/rpl_parallel_ignored_errors.test create mode 100644 mysql-test/suite/rpl/t/rpl_parallel_incorrect_relay_pos.test create mode 100644 mysql-test/suite/rpl/t/rpl_parallel_innodb_lock_conflict.test create mode 100644 mysql-test/suite/rpl/t/rpl_parallel_mdev6589.test create mode 100644 mysql-test/suite/rpl/t/rpl_parallel_missed_error_handling.test create mode 100644 mysql-test/suite/rpl/t/rpl_parallel_mode.test create mode 100644 mysql-test/suite/rpl/t/rpl_parallel_multilevel.cnf create mode 100644 mysql-test/suite/rpl/t/rpl_parallel_multilevel.test create mode 100644 mysql-test/suite/rpl/t/rpl_parallel_multilevel2.cnf create mode 100644 mysql-test/suite/rpl/t/rpl_parallel_multilevel2.test create mode 100644 mysql-test/suite/rpl/t/rpl_parallel_no_log_slave_updates-slave.opt create mode 100644 mysql-test/suite/rpl/t/rpl_parallel_no_log_slave_updates.test create mode 100644 mysql-test/suite/rpl/t/rpl_parallel_optimistic.test create mode 100644 mysql-test/suite/rpl/t/rpl_parallel_optimistic_nobinlog.cnf create mode 100644 mysql-test/suite/rpl/t/rpl_parallel_optimistic_nobinlog.test create mode 100644 mysql-test/suite/rpl/t/rpl_parallel_optimistic_until.test create mode 100644 mysql-test/suite/rpl/t/rpl_parallel_optimistic_xa.test create mode 100644 mysql-test/suite/rpl/t/rpl_parallel_optimistic_xa_lsu_off-slave.opt create mode 100644 mysql-test/suite/rpl/t/rpl_parallel_optimistic_xa_lsu_off.test create mode 100644 mysql-test/suite/rpl/t/rpl_parallel_partial_binlog_trans.test create mode 100644 mysql-test/suite/rpl/t/rpl_parallel_partition.test create mode 100644 mysql-test/suite/rpl/t/rpl_parallel_record_gtid_wakeup.test create mode 100644 mysql-test/suite/rpl/t/rpl_parallel_retry.test create mode 100644 mysql-test/suite/rpl/t/rpl_parallel_retry_deadlock.test create mode 100644 mysql-test/suite/rpl/t/rpl_parallel_rollback_assert.test create mode 100644 mysql-test/suite/rpl/t/rpl_parallel_show_binlog_events_purge_logs.test create mode 100644 mysql-test/suite/rpl/t/rpl_parallel_single_grpcmt.test create mode 100644 mysql-test/suite/rpl/t/rpl_parallel_slave_bgc_kill.test create mode 100644 mysql-test/suite/rpl/t/rpl_parallel_stop_on_con_kill.test create mode 100644 mysql-test/suite/rpl/t/rpl_parallel_stop_slave.test create mode 100644 mysql-test/suite/rpl/t/rpl_parallel_temptable-master.opt create mode 100644 mysql-test/suite/rpl/t/rpl_parallel_temptable.test create mode 100644 mysql-test/suite/rpl/t/rpl_parallel_wrong_binlog_order.test create mode 100644 mysql-test/suite/rpl/t/rpl_parallel_wrong_exec_master_pos.test create mode 100644 mysql-test/suite/rpl/t/rpl_parallel_xa_same_xid.test create mode 100644 mysql-test/suite/rpl/t/rpl_partition_archive.test create mode 100644 mysql-test/suite/rpl/t/rpl_partition_innodb-master.opt create mode 100644 mysql-test/suite/rpl/t/rpl_partition_innodb.test create mode 100644 mysql-test/suite/rpl/t/rpl_partition_memory.test create mode 100644 mysql-test/suite/rpl/t/rpl_partition_myisam.test create mode 100644 mysql-test/suite/rpl/t/rpl_password_boundaries.test create mode 100644 mysql-test/suite/rpl/t/rpl_performance_schema.test create mode 100644 mysql-test/suite/rpl/t/rpl_plugin_load.test create mode 100644 mysql-test/suite/rpl/t/rpl_ps.test create mode 100644 mysql-test/suite/rpl/t/rpl_rbr_to_sbr.test create mode 100644 mysql-test/suite/rpl/t/rpl_read_new_relay_log_info.test create mode 100644 mysql-test/suite/rpl/t/rpl_read_old_relay_log_info.test create mode 100644 mysql-test/suite/rpl/t/rpl_read_only.test create mode 100644 mysql-test/suite/rpl/t/rpl_read_only2.test create mode 100644 mysql-test/suite/rpl/t/rpl_relay_max_extension.test create mode 100644 mysql-test/suite/rpl/t/rpl_relay_space_innodb.test create mode 100644 mysql-test/suite/rpl/t/rpl_relay_space_myisam.test create mode 100644 mysql-test/suite/rpl/t/rpl_relayrotate-slave.opt create mode 100644 mysql-test/suite/rpl/t/rpl_relayrotate.test create mode 100644 mysql-test/suite/rpl/t/rpl_relayspace-slave.opt create mode 100644 mysql-test/suite/rpl/t/rpl_relayspace.test create mode 100644 mysql-test/suite/rpl/t/rpl_reopen_temp_table.test create mode 100644 mysql-test/suite/rpl/t/rpl_replicate_do-slave.opt create mode 100644 mysql-test/suite/rpl/t/rpl_replicate_do.test create mode 100644 mysql-test/suite/rpl/t/rpl_replicate_ignore_db-slave.opt create mode 100644 mysql-test/suite/rpl/t/rpl_replicate_ignore_db.test create mode 100644 mysql-test/suite/rpl/t/rpl_report-slave.opt create mode 100644 mysql-test/suite/rpl/t/rpl_report.test create mode 100644 mysql-test/suite/rpl/t/rpl_report_port.test create mode 100644 mysql-test/suite/rpl/t/rpl_reset_slave_fail.test create mode 100644 mysql-test/suite/rpl/t/rpl_rewrt_db-slave.opt create mode 100644 mysql-test/suite/rpl/t/rpl_rewrt_db.test create mode 100644 mysql-test/suite/rpl/t/rpl_rotate_logs.cnf create mode 100644 mysql-test/suite/rpl/t/rpl_rotate_logs.test create mode 100644 mysql-test/suite/rpl/t/rpl_rotate_purge_deadlock-master.opt create mode 100644 mysql-test/suite/rpl/t/rpl_rotate_purge_deadlock.test create mode 100644 mysql-test/suite/rpl/t/rpl_row_001.test create mode 100644 mysql-test/suite/rpl/t/rpl_row_4_bytes-master.opt create mode 100644 mysql-test/suite/rpl/t/rpl_row_4_bytes.test create mode 100644 mysql-test/suite/rpl/t/rpl_row_NOW.test create mode 100644 mysql-test/suite/rpl/t/rpl_row_USER.test create mode 100644 mysql-test/suite/rpl/t/rpl_row_UUID.test create mode 100644 mysql-test/suite/rpl/t/rpl_row_annotate_do-slave.opt create mode 100644 mysql-test/suite/rpl/t/rpl_row_annotate_do.test create mode 100644 mysql-test/suite/rpl/t/rpl_row_annotate_dont-slave.opt create mode 100644 mysql-test/suite/rpl/t/rpl_row_annotate_dont.test create mode 100644 mysql-test/suite/rpl/t/rpl_row_basic_11bugs-master.opt create mode 100644 mysql-test/suite/rpl/t/rpl_row_basic_11bugs.test create mode 100644 mysql-test/suite/rpl/t/rpl_row_basic_2myisam.test create mode 100644 mysql-test/suite/rpl/t/rpl_row_basic_3innodb.test create mode 100644 mysql-test/suite/rpl/t/rpl_row_basic_8partition.test create mode 100644 mysql-test/suite/rpl/t/rpl_row_big_table_id.opt create mode 100644 mysql-test/suite/rpl/t/rpl_row_big_table_id.test create mode 100644 mysql-test/suite/rpl/t/rpl_row_binlog_max_cache_size.test create mode 100644 mysql-test/suite/rpl/t/rpl_row_blob_innodb.test create mode 100644 mysql-test/suite/rpl/t/rpl_row_blob_myisam.test create mode 100644 mysql-test/suite/rpl/t/rpl_row_colSize.test create mode 100644 mysql-test/suite/rpl/t/rpl_row_conflicts.test create mode 100644 mysql-test/suite/rpl/t/rpl_row_corruption-slave.opt create mode 100644 mysql-test/suite/rpl/t/rpl_row_corruption.test create mode 100644 mysql-test/suite/rpl/t/rpl_row_create_select.test create mode 100644 mysql-test/suite/rpl/t/rpl_row_create_table.test create mode 100644 mysql-test/suite/rpl/t/rpl_row_delayed_ins.test create mode 100644 mysql-test/suite/rpl/t/rpl_row_drop.test create mode 100644 mysql-test/suite/rpl/t/rpl_row_drop_create_temp_table.test create mode 100644 mysql-test/suite/rpl/t/rpl_row_drop_temp_table.test create mode 100644 mysql-test/suite/rpl/t/rpl_row_end_of_statement_loss-master.opt create mode 100644 mysql-test/suite/rpl/t/rpl_row_end_of_statement_loss.test create mode 100644 mysql-test/suite/rpl/t/rpl_row_err_daisychain-master.opt create mode 100644 mysql-test/suite/rpl/t/rpl_row_err_daisychain-slave.opt create mode 100644 mysql-test/suite/rpl/t/rpl_row_find_row.test create mode 100644 mysql-test/suite/rpl/t/rpl_row_find_row_debug.test create mode 100644 mysql-test/suite/rpl/t/rpl_row_flsh_tbls.test create mode 100644 mysql-test/suite/rpl/t/rpl_row_func001.test create mode 100644 mysql-test/suite/rpl/t/rpl_row_func002.test create mode 100644 mysql-test/suite/rpl/t/rpl_row_func003.test create mode 100644 mysql-test/suite/rpl/t/rpl_row_idempotency.test create mode 100644 mysql-test/suite/rpl/t/rpl_row_img.cnf create mode 100644 mysql-test/suite/rpl/t/rpl_row_img_blobs.cnf create mode 100644 mysql-test/suite/rpl/t/rpl_row_img_blobs.test create mode 100644 mysql-test/suite/rpl/t/rpl_row_img_eng_min.cnf create mode 100644 mysql-test/suite/rpl/t/rpl_row_img_eng_min.test create mode 100644 mysql-test/suite/rpl/t/rpl_row_img_eng_noblob.cnf create mode 100644 mysql-test/suite/rpl/t/rpl_row_img_eng_noblob.test create mode 100644 mysql-test/suite/rpl/t/rpl_row_implicit_commit_binlog.test create mode 100644 mysql-test/suite/rpl/t/rpl_row_index_choice.test create mode 100644 mysql-test/suite/rpl/t/rpl_row_inexist_tbl.test create mode 100644 mysql-test/suite/rpl/t/rpl_row_lcase_tblnames-slave.opt create mode 100644 mysql-test/suite/rpl/t/rpl_row_lcase_tblnames.test create mode 100644 mysql-test/suite/rpl/t/rpl_row_loaddata_concurrent.test create mode 100644 mysql-test/suite/rpl/t/rpl_row_log-master.opt create mode 100644 mysql-test/suite/rpl/t/rpl_row_log-slave.opt create mode 100644 mysql-test/suite/rpl/t/rpl_row_log.test create mode 100644 mysql-test/suite/rpl/t/rpl_row_log_innodb-master.opt create mode 100644 mysql-test/suite/rpl/t/rpl_row_log_innodb.test create mode 100644 mysql-test/suite/rpl/t/rpl_row_max_relay_size.test create mode 100644 mysql-test/suite/rpl/t/rpl_row_merge_engine.test create mode 100644 mysql-test/suite/rpl/t/rpl_row_mixing_engines.test create mode 100644 mysql-test/suite/rpl/t/rpl_row_mysqlbinlog-master.opt create mode 100644 mysql-test/suite/rpl/t/rpl_row_mysqlbinlog.test create mode 100644 mysql-test/suite/rpl/t/rpl_row_rec_comp_innodb.test create mode 100644 mysql-test/suite/rpl/t/rpl_row_rec_comp_myisam.test create mode 100644 mysql-test/suite/rpl/t/rpl_row_reset_slave.test create mode 100644 mysql-test/suite/rpl/t/rpl_row_rollback_to_savepoint.test create mode 100644 mysql-test/suite/rpl/t/rpl_row_show_relaylog_events.test create mode 100644 mysql-test/suite/rpl/t/rpl_row_sp001.test create mode 100644 mysql-test/suite/rpl/t/rpl_row_sp002_innodb.test create mode 100644 mysql-test/suite/rpl/t/rpl_row_sp003.test create mode 100644 mysql-test/suite/rpl/t/rpl_row_sp005.test create mode 100644 mysql-test/suite/rpl/t/rpl_row_sp006_InnoDB.test create mode 100644 mysql-test/suite/rpl/t/rpl_row_sp007_innodb.test create mode 100644 mysql-test/suite/rpl/t/rpl_row_sp008.test create mode 100644 mysql-test/suite/rpl/t/rpl_row_sp009.test create mode 100644 mysql-test/suite/rpl/t/rpl_row_sp010.test create mode 100644 mysql-test/suite/rpl/t/rpl_row_sp011.test create mode 100644 mysql-test/suite/rpl/t/rpl_row_sp012.test create mode 100644 mysql-test/suite/rpl/t/rpl_row_spatial.test create mode 100644 mysql-test/suite/rpl/t/rpl_row_tabledefs_2myisam.test create mode 100644 mysql-test/suite/rpl/t/rpl_row_tabledefs_3innodb.test create mode 100644 mysql-test/suite/rpl/t/rpl_row_tbl_metadata.test create mode 100644 mysql-test/suite/rpl/t/rpl_row_to_stmt-master.opt create mode 100644 mysql-test/suite/rpl/t/rpl_row_to_stmt-slave.opt create mode 100644 mysql-test/suite/rpl/t/rpl_row_to_stmt.test create mode 100644 mysql-test/suite/rpl/t/rpl_row_trig001.test create mode 100644 mysql-test/suite/rpl/t/rpl_row_trig002.test create mode 100644 mysql-test/suite/rpl/t/rpl_row_trig003.test create mode 100644 mysql-test/suite/rpl/t/rpl_row_trig004.test create mode 100644 mysql-test/suite/rpl/t/rpl_row_triggers.test create mode 100644 mysql-test/suite/rpl/t/rpl_row_trunc_temp.test create mode 100644 mysql-test/suite/rpl/t/rpl_row_type_conv_err_msg.test create mode 100644 mysql-test/suite/rpl/t/rpl_row_unsafe_funcs.test create mode 100644 mysql-test/suite/rpl/t/rpl_row_until.test create mode 100644 mysql-test/suite/rpl/t/rpl_row_utf16.test create mode 100644 mysql-test/suite/rpl/t/rpl_row_utf32.test create mode 100644 mysql-test/suite/rpl/t/rpl_row_vcol_crash.test create mode 100644 mysql-test/suite/rpl/t/rpl_row_view01.test create mode 100644 mysql-test/suite/rpl/t/rpl_row_virt.test create mode 100644 mysql-test/suite/rpl/t/rpl_row_wide_table.test create mode 100644 mysql-test/suite/rpl/t/rpl_savepoint.test create mode 100644 mysql-test/suite/rpl/t/rpl_semi_sync.test create mode 100644 mysql-test/suite/rpl/t/rpl_semi_sync_after_sync.test create mode 100644 mysql-test/suite/rpl/t/rpl_semi_sync_after_sync_row.test create mode 100644 mysql-test/suite/rpl/t/rpl_semi_sync_event-master.opt create mode 100644 mysql-test/suite/rpl/t/rpl_semi_sync_event.test create mode 100644 mysql-test/suite/rpl/t/rpl_semi_sync_event_after_sync-master.opt create mode 100644 mysql-test/suite/rpl/t/rpl_semi_sync_event_after_sync.test create mode 100644 mysql-test/suite/rpl/t/rpl_semi_sync_gtid_reconnect.test create mode 100644 mysql-test/suite/rpl/t/rpl_semi_sync_master_shutdown.test create mode 100644 mysql-test/suite/rpl/t/rpl_semi_sync_skip_repl.test create mode 100644 mysql-test/suite/rpl/t/rpl_semi_sync_slave_compressed_protocol-slave.opt create mode 100644 mysql-test/suite/rpl/t/rpl_semi_sync_slave_compressed_protocol.test create mode 100644 mysql-test/suite/rpl/t/rpl_semi_sync_slave_reply_fail.test create mode 100644 mysql-test/suite/rpl/t/rpl_semi_sync_wait_no_slave-master.opt create mode 100644 mysql-test/suite/rpl/t/rpl_semi_sync_wait_no_slave.test create mode 100644 mysql-test/suite/rpl/t/rpl_semi_sync_wait_point.opt create mode 100644 mysql-test/suite/rpl/t/rpl_semi_sync_wait_point.test create mode 100644 mysql-test/suite/rpl/t/rpl_semisync_ali_issues-master.opt create mode 100644 mysql-test/suite/rpl/t/rpl_semisync_ali_issues-slave.opt create mode 100644 mysql-test/suite/rpl/t/rpl_semisync_ali_issues.test create mode 100644 mysql-test/suite/rpl/t/rpl_server_id1.test create mode 100644 mysql-test/suite/rpl/t/rpl_server_id2-slave.opt create mode 100644 mysql-test/suite/rpl/t/rpl_server_id2.test create mode 100644 mysql-test/suite/rpl/t/rpl_server_id_ignore-slave.opt create mode 100644 mysql-test/suite/rpl/t/rpl_server_id_ignore.test create mode 100644 mysql-test/suite/rpl/t/rpl_session_var.test create mode 100644 mysql-test/suite/rpl/t/rpl_set_charset.test create mode 100644 mysql-test/suite/rpl/t/rpl_set_null_innodb.test create mode 100644 mysql-test/suite/rpl/t/rpl_set_null_myisam.test create mode 100644 mysql-test/suite/rpl/t/rpl_set_statement.test create mode 100644 mysql-test/suite/rpl/t/rpl_set_statement_default_master.test create mode 100644 mysql-test/suite/rpl/t/rpl_show_slave_hosts.cnf create mode 100644 mysql-test/suite/rpl/t/rpl_show_slave_hosts.test create mode 100644 mysql-test/suite/rpl/t/rpl_show_slave_running.test create mode 100644 mysql-test/suite/rpl/t/rpl_shutdown_wait_semisync_slaves.cnf create mode 100644 mysql-test/suite/rpl/t/rpl_shutdown_wait_semisync_slaves.test create mode 100644 mysql-test/suite/rpl/t/rpl_shutdown_wait_slaves.cnf create mode 100644 mysql-test/suite/rpl/t/rpl_shutdown_wait_slaves.test create mode 100644 mysql-test/suite/rpl/t/rpl_skip_error-slave.opt create mode 100644 mysql-test/suite/rpl/t/rpl_skip_error.test create mode 100644 mysql-test/suite/rpl/t/rpl_skip_incident-master.opt create mode 100644 mysql-test/suite/rpl/t/rpl_skip_incident-slave.opt create mode 100644 mysql-test/suite/rpl/t/rpl_skip_incident.test create mode 100644 mysql-test/suite/rpl/t/rpl_skip_replication.test create mode 100644 mysql-test/suite/rpl/t/rpl_slave_alias_replica.test create mode 100644 mysql-test/suite/rpl/t/rpl_slave_grp_exec.test create mode 100644 mysql-test/suite/rpl/t/rpl_slave_invalid_external_user.test create mode 100644 mysql-test/suite/rpl/t/rpl_slave_load_in.test create mode 100644 mysql-test/suite/rpl/t/rpl_slave_load_remove_tmpfile.test create mode 100644 mysql-test/suite/rpl/t/rpl_slave_load_tmpdir_not_exist-slave.opt create mode 100644 mysql-test/suite/rpl/t/rpl_slave_load_tmpdir_not_exist.test create mode 100644 mysql-test/suite/rpl/t/rpl_slave_shutdown_mdev20821.cnf create mode 100644 mysql-test/suite/rpl/t/rpl_slave_shutdown_mdev20821.test create mode 100644 mysql-test/suite/rpl/t/rpl_slave_skip.test create mode 100644 mysql-test/suite/rpl/t/rpl_slave_status.test create mode 100644 mysql-test/suite/rpl/t/rpl_slow_query_log-slave.opt create mode 100644 mysql-test/suite/rpl/t/rpl_slow_query_log.test create mode 100644 mysql-test/suite/rpl/t/rpl_sp-master.opt create mode 100644 mysql-test/suite/rpl/t/rpl_sp-slave.opt create mode 100644 mysql-test/suite/rpl/t/rpl_sp.test create mode 100644 mysql-test/suite/rpl/t/rpl_sp004.test create mode 100644 mysql-test/suite/rpl/t/rpl_sp_effects-master.opt create mode 100644 mysql-test/suite/rpl/t/rpl_sp_effects-slave.opt create mode 100644 mysql-test/suite/rpl/t/rpl_sp_effects.test create mode 100644 mysql-test/suite/rpl/t/rpl_sp_variables.test create mode 100644 mysql-test/suite/rpl/t/rpl_spec_variables.test create mode 100644 mysql-test/suite/rpl/t/rpl_special_charset.opt create mode 100644 mysql-test/suite/rpl/t/rpl_special_charset.test create mode 100644 mysql-test/suite/rpl/t/rpl_sporadic_master-master.opt create mode 100644 mysql-test/suite/rpl/t/rpl_sporadic_master.test create mode 100644 mysql-test/suite/rpl/t/rpl_ssl.test create mode 100644 mysql-test/suite/rpl/t/rpl_ssl1.test create mode 100644 mysql-test/suite/rpl/t/rpl_start_stop_slave-slave.opt create mode 100644 mysql-test/suite/rpl/t/rpl_start_stop_slave.test create mode 100644 mysql-test/suite/rpl/t/rpl_stm_000001.test create mode 100644 mysql-test/suite/rpl/t/rpl_stm_EE_err2.test create mode 100644 mysql-test/suite/rpl/t/rpl_stm_auto_increment_bug33029.test create mode 100644 mysql-test/suite/rpl/t/rpl_stm_binlog_direct-master.opt create mode 100644 mysql-test/suite/rpl/t/rpl_stm_binlog_max_cache_size.test create mode 100644 mysql-test/suite/rpl/t/rpl_stm_conflicts.test create mode 100644 mysql-test/suite/rpl/t/rpl_stm_drop_create_temp_table.test create mode 100644 mysql-test/suite/rpl/t/rpl_stm_flsh_tbls.test create mode 100644 mysql-test/suite/rpl/t/rpl_stm_found_rows.test create mode 100644 mysql-test/suite/rpl/t/rpl_stm_implicit_commit_binlog.test create mode 100644 mysql-test/suite/rpl/t/rpl_stm_innodb.test create mode 100644 mysql-test/suite/rpl/t/rpl_stm_lcase_tblnames-slave.opt create mode 100644 mysql-test/suite/rpl/t/rpl_stm_lcase_tblnames.test create mode 100644 mysql-test/suite/rpl/t/rpl_stm_loaddata_concurrent.test create mode 100644 mysql-test/suite/rpl/t/rpl_stm_loadfile.test create mode 100644 mysql-test/suite/rpl/t/rpl_stm_log-slave.opt create mode 100644 mysql-test/suite/rpl/t/rpl_stm_log.test create mode 100644 mysql-test/suite/rpl/t/rpl_stm_maria.test create mode 100644 mysql-test/suite/rpl/t/rpl_stm_max_relay_size.test create mode 100644 mysql-test/suite/rpl/t/rpl_stm_mix_show_relaylog_events.test create mode 100644 mysql-test/suite/rpl/t/rpl_stm_mixing_engines.test create mode 100644 mysql-test/suite/rpl/t/rpl_stm_multi_query.test create mode 100644 mysql-test/suite/rpl/t/rpl_stm_no_op.test create mode 100644 mysql-test/suite/rpl/t/rpl_stm_relay_ign_space-slave.opt create mode 100644 mysql-test/suite/rpl/t/rpl_stm_relay_ign_space.test create mode 100644 mysql-test/suite/rpl/t/rpl_stm_reset_slave.test create mode 100644 mysql-test/suite/rpl/t/rpl_stm_sp.test create mode 100644 mysql-test/suite/rpl/t/rpl_stm_sql_mode.test create mode 100644 mysql-test/suite/rpl/t/rpl_stm_start_stop_slave.test create mode 100644 mysql-test/suite/rpl/t/rpl_stm_stop_middle_group.test create mode 100644 mysql-test/suite/rpl/t/rpl_stm_until.test create mode 100644 mysql-test/suite/rpl/t/rpl_stm_user_variables.test create mode 100644 mysql-test/suite/rpl/t/rpl_stop_slave.test create mode 100644 mysql-test/suite/rpl/t/rpl_stop_slave_error-slave.opt create mode 100644 mysql-test/suite/rpl/t/rpl_stop_slave_error.test create mode 100644 mysql-test/suite/rpl/t/rpl_strict_password_validation.test create mode 100644 mysql-test/suite/rpl/t/rpl_switch_stm_row_mixed.test create mode 100644 mysql-test/suite/rpl/t/rpl_sync-master.opt create mode 100644 mysql-test/suite/rpl/t/rpl_sync-slave.opt create mode 100644 mysql-test/suite/rpl/t/rpl_sync.test create mode 100644 mysql-test/suite/rpl/t/rpl_table_options.test create mode 100644 mysql-test/suite/rpl/t/rpl_temp_table.test create mode 100644 mysql-test/suite/rpl/t/rpl_temp_table_mix_row.test create mode 100644 mysql-test/suite/rpl/t/rpl_temporal_format_default_to_default.test create mode 100644 mysql-test/suite/rpl/t/rpl_temporal_format_mariadb53_to_mariadb53.test create mode 100644 mysql-test/suite/rpl/t/rpl_temporal_format_mariadb53_to_mysql56.test create mode 100644 mysql-test/suite/rpl/t/rpl_temporal_format_mariadb53_to_mysql56_dst.test create mode 100644 mysql-test/suite/rpl/t/rpl_temporal_format_mysql56_to_mariadb53.test create mode 100644 mysql-test/suite/rpl/t/rpl_temporal_format_mysql56_to_mysql56.test create mode 100644 mysql-test/suite/rpl/t/rpl_temporal_mysql56.test create mode 100644 mysql-test/suite/rpl/t/rpl_temporal_mysql56_to_mariadb.test create mode 100644 mysql-test/suite/rpl/t/rpl_temporal_mysql56_to_mariadb53.test create mode 100644 mysql-test/suite/rpl/t/rpl_temporal_round.test create mode 100644 mysql-test/suite/rpl/t/rpl_temporary.test create mode 100644 mysql-test/suite/rpl/t/rpl_temporary_error2.test create mode 100644 mysql-test/suite/rpl/t/rpl_temporary_errors-slave.opt create mode 100644 mysql-test/suite/rpl/t/rpl_temporary_errors.test create mode 100644 mysql-test/suite/rpl/t/rpl_test_framework.cnf create mode 100644 mysql-test/suite/rpl/t/rpl_test_framework.test create mode 100644 mysql-test/suite/rpl/t/rpl_timezone-master.opt create mode 100644 mysql-test/suite/rpl/t/rpl_timezone-slave.opt create mode 100644 mysql-test/suite/rpl/t/rpl_timezone.test create mode 100644 mysql-test/suite/rpl/t/rpl_tmp_table_and_DDL.test create mode 100644 mysql-test/suite/rpl/t/rpl_tmp_table_and_DDL_innodb.test create mode 100644 mysql-test/suite/rpl/t/rpl_trans_no_trans.test create mode 100644 mysql-test/suite/rpl/t/rpl_trigger.test create mode 100644 mysql-test/suite/rpl/t/rpl_trunc_temp.test create mode 100644 mysql-test/suite/rpl/t/rpl_truncate_2myisam.test create mode 100644 mysql-test/suite/rpl/t/rpl_truncate_3innodb.test create mode 100644 mysql-test/suite/rpl/t/rpl_typeconv-slave.opt create mode 100644 mysql-test/suite/rpl/t/rpl_typeconv.test create mode 100644 mysql-test/suite/rpl/t/rpl_typeconv_innodb.test create mode 100644 mysql-test/suite/rpl/t/rpl_udf.test create mode 100644 mysql-test/suite/rpl/t/rpl_unsafe_statements.test create mode 100644 mysql-test/suite/rpl/t/rpl_update.test create mode 100644 mysql-test/suite/rpl/t/rpl_upgrade_master_info.test create mode 100644 mysql-test/suite/rpl/t/rpl_user.test create mode 100644 mysql-test/suite/rpl/t/rpl_user_variables.test create mode 100644 mysql-test/suite/rpl/t/rpl_variables.test create mode 100644 mysql-test/suite/rpl/t/rpl_variables_stm.test create mode 100644 mysql-test/suite/rpl/t/rpl_view.test create mode 100644 mysql-test/suite/rpl/t/rpl_view_debug.test create mode 100644 mysql-test/suite/rpl/t/rpl_view_multi.test create mode 100644 mysql-test/suite/rpl/t/rpl_xa-master.opt create mode 100644 mysql-test/suite/rpl/t/rpl_xa.inc create mode 100644 mysql-test/suite/rpl/t/rpl_xa.test create mode 100644 mysql-test/suite/rpl/t/rpl_xa_gap_lock-slave.opt create mode 100644 mysql-test/suite/rpl/t/rpl_xa_gap_lock.test create mode 100644 mysql-test/suite/rpl/t/rpl_xa_gtid_pos_auto_engine-master.opt create mode 100644 mysql-test/suite/rpl/t/rpl_xa_gtid_pos_auto_engine.test create mode 100644 mysql-test/suite/rpl/t/rpl_xa_survive_disconnect.test create mode 100644 mysql-test/suite/rpl/t/rpl_xa_survive_disconnect_lsu_off-slave.opt create mode 100644 mysql-test/suite/rpl/t/rpl_xa_survive_disconnect_lsu_off.test create mode 100644 mysql-test/suite/rpl/t/rpl_xa_survive_disconnect_mixed_engines.test create mode 100644 mysql-test/suite/rpl/t/sec_behind_master-5114.test create mode 100644 mysql-test/suite/rpl/t/semisync_future-7591.test create mode 100644 mysql-test/suite/rpl/t/semisync_memleak_4066.test create mode 100644 mysql-test/suite/rpl/t/sequence.cnf create mode 100644 mysql-test/suite/rpl/t/sequence.test create mode 100644 mysql-test/suite/rpl/t/show_status_stop_slave_race-7126.test create mode 100644 mysql-test/suite/rpl/t/temporal_row-9560-master.opt create mode 100644 mysql-test/suite/rpl/t/temporal_row-9560.combinations create mode 100644 mysql-test/suite/rpl/t/temporal_row-9560.test (limited to 'mysql-test/suite/rpl/t') diff --git a/mysql-test/suite/rpl/t/circular_serverid0.cnf b/mysql-test/suite/rpl/t/circular_serverid0.cnf new file mode 100644 index 00000000..277aac28 --- /dev/null +++ b/mysql-test/suite/rpl/t/circular_serverid0.cnf @@ -0,0 +1,30 @@ +!include ../my.cnf + +[mysqld.1] +gtid-domain-id=4 +server-id=4 +# +log-slave-updates +slave-parallel-threads=0 +gtid-strict-mode=1 +gtid-ignore-duplicates=1 + +# +# Max-size row events to minimum with the idea to create +# a number of Rows_log_event per Query. +# +binlog-row-event-max-size=1024 + +[mysqld.2] +gtid-domain-id=2 +server-id=2 +# +log-slave-updates +slave-parallel-threads=0 +gtid-strict-mode=1 +gtid-ignore-duplicates=1 +binlog-row-event-max-size=1024 +# The slave will be initialized with a @@global.dbug-var value +skip-slave-start=1 + + diff --git a/mysql-test/suite/rpl/t/circular_serverid0.test b/mysql-test/suite/rpl/t/circular_serverid0.test new file mode 100644 index 00000000..64cf231c --- /dev/null +++ b/mysql-test/suite/rpl/t/circular_serverid0.test @@ -0,0 +1,103 @@ +# +# Testing chain/circular replication scenario of MDEV-9670 +# The effect of the bug was that we got a commit with a GTID with server_id +# + +--source include/have_binlog_format_row.inc +--source include/have_innodb.inc +--source include/have_debug.inc +--source include/have_debug_sync.inc + +--let $rpl_topology= 1->2->1 +--source include/rpl_init.inc + +--let $rpl_connection_name= M4 +--let $rpl_server_number= 1 +--source include/rpl_connect.inc + +--let $rpl_connection_name= M2 +--let $rpl_server_number= 2 +--source include/rpl_connect.inc + +# The parameter reflects binlog-row-event-max-size @cnf. +--let $row_size=1024 + +--connection M2 +STOP SLAVE; +SET @old_debug= @@global.debug_dbug; +SET GLOBAL debug_dbug= "d,dbug.rows_events_to_delay_relay_logging"; +START SLAVE IO_THREAD; +--source include/wait_for_slave_io_to_start.inc + +--connection M2 +# This query also creates a Gtid event group whose Gtid will remain in +# ignored status for too long causing a following group split. + +CREATE TABLE t1 (a INT AUTO_INCREMENT PRIMARY KEY, b VARCHAR(30000)) ENGINE=innodb; +--sync_slave_with_master M4 + +# This INSERT will be logged as two Write_log events which the buggy +# slave applier would split. + +--connection M4 +eval INSERT INTO `t1` VALUES (null, repeat('a', $row_size)), (null, repeat('b', $row_size)); + +# START M2 IO thread and wait for its signal to follow with the SQL +# thread start. At this moment the SQL thread shall be having 2 and +# "half" groups to execute. The "hafl" one would be committed by the +# buggy applier after which the IO is released to queue the rest of +# the 3rd group which the SQL thread commits separately to complete +# the split. + +--connection M2 + +# wait for IO signal to start the SQL thread. IO will be hanging upon that. +SET debug_sync='now WAIT_FOR start_sql_thread'; + +# Now the slave server has relay log whose last group is incomplete. +# An unfixed slave server would go to "insert" a "fake" +# Gtid_list_log_event event which actually would commit the incomplete +# group. However before to actual commit do_apply_event() hits some assert. +# In the fixed server the fake Gtid_list_log_event is *not* inserted +# in the middle of a group. +START SLAVE SQL_THREAD; + +# Sleep for a little time to give SQL thread a chance to commit while +# the IO thread is hanging (see +# DBUG_EXECUTE_IF("dbug.rows_events_to_delay_relay_logging"...) in +# queue_event). Alternatively to reproduce the case when buggy slave +# wait for the 1st group commit + +#--let $count= 1 +#--let $table= t1 +#--source include/wait_until_rows_count.inc + +--sleep 2 + +# Demonstrate either no split group in the correct slave or the 1nd +# group in the buggy one +--source include/show_binlog_events.inc + +# Release the IO thread +SET debug_sync='now SIGNAL go_on_relay_logging'; + +# Sync servers +--sync_slave_with_master M4 +--connection M4 +--sync_slave_with_master M2 +--connection M2 + +# Demonstrate replication goes correctly not to create any split, or +# the 2nd group in the buggy slave +--source include/show_binlog_events.inc + +# +# Cleanup +# +--connection M4 +drop table t1; + +--connection M2 +SET GLOBAL debug_dbug= @old_debug; +SET debug_sync='RESET'; +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/create_or_replace.inc b/mysql-test/suite/rpl/t/create_or_replace.inc new file mode 100644 index 00000000..df46cc36 --- /dev/null +++ b/mysql-test/suite/rpl/t/create_or_replace.inc @@ -0,0 +1,227 @@ +# Test CREATE OR REPLACE TABLE in replication +--source include/have_innodb.inc + +--let $rpl_topology=1->2 +--source include/rpl_init.inc + +# Create help tables +create table t2 (a int) engine=myisam; +insert into t2 values (0),(1),(2),(2); +create temporary table t3 (a_in_temporary int) engine=myisam; + +--echo # +--echo # Check how create table and create or replace table are logged +--echo # + +save_master_pos; +connection server_2; +sync_with_master; +create table t1 (to_be_deleted int); + +connection server_1; +CREATE TABLE t1 AS SELECT 1 AS f1; +CREATE OR REPLACE TABLE t1 AS SELECT 2 AS f1; +CREATE OR REPLACE table t1 like t2; +CREATE OR REPLACE table t1 like t3; +drop table t1; + +--echo binlog from server 1 +--source include/show_binlog_events.inc +save_master_pos; +connection server_2; +sync_with_master; +--echo binlog from server 2 +--source include/show_binlog_events.inc + +connection server_1; + +--echo # +--echo # Ensure that also failed create_or_replace are logged +--echo # + +--let $binlog_start=query_get_value(SHOW MASTER STATUS, Position, 1) + +create table t1 (a int); +--error ER_TABLE_MUST_HAVE_COLUMNS +create or replace table t1; +drop table if exists t1; +# The following is not logged as t1 does not exists; +--error ER_DUP_ENTRY +create or replace table t1 (a int primary key) select a from t2; + +create table t1 (a int); +# This should as a delete as we will delete t1 +--error ER_DUP_ENTRY +create or replace table t1 (a int primary key) select a from t2; + +# Same with temporary table +create temporary table t9 (a int); + +--error ER_DUP_ENTRY +create or replace temporary table t9 (a int primary key) select a from t2; + +--echo binlog from server 1 +--source include/show_binlog_events.inc +save_master_pos; +connection server_2; +sync_with_master; +show tables; +connection server_1; + +--let $binlog_start=query_get_value(SHOW MASTER STATUS, Position, 1) +create table t1 (a int); +--error ER_DUP_FIELDNAME +create or replace table t1 (a int, a int) select * from t2; +--source include/show_binlog_events.inc + +drop table if exists t1,t2; +drop temporary table if exists t9; + +--echo # +--echo # Ensure that CREATE are run as CREATE OR REPLACE on slave +--echo # + +save_master_pos; +connection server_2; +sync_with_master; +create table t1 (server_2_to_be_delete int); +connection server_1; +create table t1 (new_table int); + +save_master_pos; +connection server_2; +sync_with_master; + +show create table t1; +connection server_1; +drop table t1; + +--echo # +--echo # Check how CREATE is logged on slave in case of conflicts +--echo # + +save_master_pos; +connection server_2; +sync_with_master; +--let $binlog_start=query_get_value(SHOW MASTER STATUS, Position, 1) +create table t1 (server_2_to_be_delete int); +create table t2 (server_2_to_be_delete int); +create table t4 (server_2_to_be_delete int); +set @org_binlog_format=@@binlog_format; +set @@global.binlog_format="ROW"; +stop slave; +--source include/wait_for_slave_to_stop.inc +start slave; +--source include/wait_for_slave_to_start.inc +connection server_1; +create temporary table t9 (a int); +insert into t9 values(1); +create table t1 (new_table int); +create table t2 select * from t9; +create table t4 like t9; +create table t5 select * from t9; +save_master_pos; +connection server_2; +sync_with_master; +--echo binlog from server 2 +--source include/show_binlog_events.inc +set @@global.binlog_format=@org_binlog_format; +stop slave; +--source include/wait_for_slave_to_stop.inc +start slave; +--source include/wait_for_slave_to_start.inc +connection server_1; +drop table t1,t2,t4,t5,t9; + +--echo # +--echo # Ensure that DROP TABLE is run as DROP IF NOT EXISTS +--echo # + +create table t1 (server_1_ver_1 int); +create table t4 (server_1_ver_2 int); + +save_master_pos; +connection server_2; +sync_with_master; +--let $binlog_start=query_get_value(SHOW MASTER STATUS, Position, 1) + +# Drop the table on the slave +drop table t1; +connection server_1; +drop table t1,t4; +create table t1 (server_2_ver_2 int); +save_master_pos; +connection server_2; +sync_with_master; +show create table t1; +--echo binlog from server 2 +--source include/show_binlog_events.inc +connection server_1; +drop table t1; + +--echo # +--echo # Ensure that CREATE ... SELECT is recorded as one GTID on the slave +--echo # + +save_master_pos; +connection server_2; +sync_with_master; +--let $binlog_start=query_get_value(SHOW MASTER STATUS, Position, 1) +connection server_1; + +create table t1 (a int); +insert into t1 values (0),(1),(2); +create table t2 engine=myisam select * from t1; +create or replace table t2 engine=innodb select * from t1; +save_master_pos; +connection server_2; +sync_with_master; +--echo binlog from server 2 +--source include/show_binlog_events.inc +connection server_1; +drop table t1; + +--echo # +--echo # Check logging of drop temporary table +--echo # + +drop temporary table t3; + +--let $binlog_start=query_get_value(SHOW MASTER STATUS, Position, 1) + +set @org_binlog_format=@@binlog_format; +set binlog_format="STATEMENT"; +create temporary table t5 (a int); +drop temporary table t5; +set binlog_format="ROW"; +create temporary table t6 (a int); +drop temporary table t6; +set binlog_format="STATEMENT"; +create temporary table t7 (a int); +set binlog_format="ROW"; +drop temporary table t7; +create temporary table t8 (a int); +--error ER_TEMP_TABLE_PREVENTS_SWITCH_OUT_OF_RBR +set binlog_format="STATEMENT"; +drop temporary table t8; +set @@binlog_format=@org_binlog_format; + +# MDEV-20091: +# 1. No DROP should be logged for non-existing tmp table, nor +# 2. at the connection close when its creation has not been logged. +set @@session.binlog_format=default; +drop temporary table if exists t9; + +--connect(con1,localhost,root,,) +set session binlog_format=default; +create temporary table t9 (i int); +--echo *** Must be no DROP logged for t9 when there was no CREATE, at disconnect too *** +--disconnect con1 + +--connection server_1 +--source include/show_binlog_events.inc + +# Clean up +drop table t2; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/create_or_replace2.test b/mysql-test/suite/rpl/t/create_or_replace2.test new file mode 100644 index 00000000..f0091db7 --- /dev/null +++ b/mysql-test/suite/rpl/t/create_or_replace2.test @@ -0,0 +1,42 @@ +--source include/have_innodb.inc +--source include/have_binlog_format_row_or_statement.inc +--source include/have_metadata_lock_info.inc +--source include/master-slave.inc + +--echo # +--echo # MDEV-6525 ; Problems with CREATE OR REPLACE under lock +--echo # + +CREATE TABLE t1 (a INT) ENGINE=InnoDB; +CREATE FUNCTION f1() RETURNS INT RETURN ( SELECT MAX(a) FROM t1 ); + +--connect (con1,localhost,root,,test) + +CREATE TEMPORARY TABLE tmp (b INT) ENGINE=InnoDB; +LOCK TABLE t1 WRITE; + +SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; + +CREATE OR REPLACE TABLE t1 LIKE tmp; +SHOW CREATE TABLE t1; + +--connection default +set session lock_wait_timeout=1; +--error 1205 +SELECT f1(); + +set session lock_wait_timeout=@@global.lock_wait_timeout; +--send SELECT f1() +--connection con1 +# This is here just in case, any timeout should be ok +--sleep 1 +unlock tables; +--connection default +--error 1054 +--reap +--disconnect con1 + +# Cleanup +drop function f1; +drop table t1; +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/create_or_replace_mix.cnf b/mysql-test/suite/rpl/t/create_or_replace_mix.cnf new file mode 100644 index 00000000..03d69b28 --- /dev/null +++ b/mysql-test/suite/rpl/t/create_or_replace_mix.cnf @@ -0,0 +1,9 @@ +!include suite/rpl/my.cnf + +[mysqld.1] +log-slave-updates +loose-innodb + +[mysqld.2] +log-slave-updates +loose-innodb diff --git a/mysql-test/suite/rpl/t/create_or_replace_mix.test b/mysql-test/suite/rpl/t/create_or_replace_mix.test new file mode 100644 index 00000000..0cabef15 --- /dev/null +++ b/mysql-test/suite/rpl/t/create_or_replace_mix.test @@ -0,0 +1,4 @@ +# Testing create or replace table in mixed mode. + +--source include/have_binlog_format_mixed.inc +--source create_or_replace.inc diff --git a/mysql-test/suite/rpl/t/create_or_replace_row.cnf b/mysql-test/suite/rpl/t/create_or_replace_row.cnf new file mode 100644 index 00000000..03d69b28 --- /dev/null +++ b/mysql-test/suite/rpl/t/create_or_replace_row.cnf @@ -0,0 +1,9 @@ +!include suite/rpl/my.cnf + +[mysqld.1] +log-slave-updates +loose-innodb + +[mysqld.2] +log-slave-updates +loose-innodb diff --git a/mysql-test/suite/rpl/t/create_or_replace_row.test b/mysql-test/suite/rpl/t/create_or_replace_row.test new file mode 100644 index 00000000..88dd8fd2 --- /dev/null +++ b/mysql-test/suite/rpl/t/create_or_replace_row.test @@ -0,0 +1,4 @@ +# Testing create or replace table in mixed mode. + +--source include/have_binlog_format_row.inc +--source create_or_replace.inc diff --git a/mysql-test/suite/rpl/t/create_or_replace_statement.cnf b/mysql-test/suite/rpl/t/create_or_replace_statement.cnf new file mode 100644 index 00000000..03d69b28 --- /dev/null +++ b/mysql-test/suite/rpl/t/create_or_replace_statement.cnf @@ -0,0 +1,9 @@ +!include suite/rpl/my.cnf + +[mysqld.1] +log-slave-updates +loose-innodb + +[mysqld.2] +log-slave-updates +loose-innodb diff --git a/mysql-test/suite/rpl/t/create_or_replace_statement.test b/mysql-test/suite/rpl/t/create_or_replace_statement.test new file mode 100644 index 00000000..2709e414 --- /dev/null +++ b/mysql-test/suite/rpl/t/create_or_replace_statement.test @@ -0,0 +1,4 @@ +# Testing create or replace table in mixed mode. + +--source include/have_binlog_format_statement.inc +--source create_or_replace.inc diff --git a/mysql-test/suite/rpl/t/create_select.cnf b/mysql-test/suite/rpl/t/create_select.cnf new file mode 100644 index 00000000..65a4396e --- /dev/null +++ b/mysql-test/suite/rpl/t/create_select.cnf @@ -0,0 +1,16 @@ +!include suite/rpl/my.cnf + +[mysqld.1] + +[mysqld.2] +log-slave-updates +binlog-checksum=CRC32 + +[mysqld.3] +log-slave-updates +binlog-checksum=CRC32 + +[ENV] +SERVER_MYPORT_3= @mysqld.3.port +SERVER_MYSOCK_3= @mysqld.3.socket + diff --git a/mysql-test/suite/rpl/t/create_select.test b/mysql-test/suite/rpl/t/create_select.test new file mode 100644 index 00000000..c1f8fc8f --- /dev/null +++ b/mysql-test/suite/rpl/t/create_select.test @@ -0,0 +1,37 @@ +--source include/have_innodb.inc + +--let $rpl_topology=1->2->3 +--source include/rpl_init.inc + +# +# Test of MDEV-8428 Mangled DML statements on 2nd level slave when enabling +# binlog checksums +# + +connection server_1; + +CREATE DATABASE test_8428; +USE test_8428; +CREATE TABLE t1(i INT) ENGINE=INNODB; +INSERT INTO t1 VALUES(1), (2), (3), (4), (5); +CREATE TABLE t2 AS SELECT * FROM t1; +CREATE TABLE t3 ENGINE=MyISAM AS SELECT * FROM t1; + +save_master_pos; +connection server_2; +sync_with_master; + +SHOW TABLES IN test_8428; + +save_master_pos; +connection server_3; +sync_with_master; + +SHOW TABLES IN test_8428; +SELECT * from test_8428.t1; + +# Cleanup +connection server_1; +DROP DATABASE test_8428; +--source include/rpl_end.inc +--echo # End of test diff --git a/mysql-test/suite/rpl/t/failed_create_view-6409.test b/mysql-test/suite/rpl/t/failed_create_view-6409.test new file mode 100644 index 00000000..5d96e6f8 --- /dev/null +++ b/mysql-test/suite/rpl/t/failed_create_view-6409.test @@ -0,0 +1,24 @@ +# +# MDEV-6409 CREATE VIEW replication problem if error occurs in mysql_register_view +# + +# +# +# verify that failed CREATE VIEW is not replicated + +create table v1 (a int); + +source include/master-slave.inc; + +connection master; +create table t1 (a int); +--error ER_TABLE_EXISTS_ERROR +create view v1 as select * from t1; +show tables; +sync_slave_with_master; +show tables; + +connection master; +drop table if exists t1, v1; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/grant_replication_slave.test b/mysql-test/suite/rpl/t/grant_replication_slave.test new file mode 100644 index 00000000..c5aca0a6 --- /dev/null +++ b/mysql-test/suite/rpl/t/grant_replication_slave.test @@ -0,0 +1,39 @@ +--echo # +--echo # MDEV-21743 Split up SUPER privilege to smaller privileges +--echo # + +# Checking that REPLICATION SLAVE is enough to start replication + +create user rpl@localhost; +grant replication slave on *.* to rpl@localhost; + +source include/master-slave.inc; +connection slave; +stop slave; +change master to master_user='rpl'; +connection master; + +create database mysqltest1; +create table mysqltest1.t1 (a int); +insert mysqltest1.t1 values (1),(2),(3); +select * from mysqltest1.t1; +flush tables; +create user foo@localhost; +grant select on *.* to foo@localhost; + +connection slave; +start slave; +connection master; +sync_slave_with_master; +select * from mysqltest1.t1; +show grants for foo@localhost; +connection master; +drop user foo@localhost; +drop database mysqltest1; +sync_slave_with_master; +stop slave; +change master to master_user='root'; +start slave; + +source include/rpl_end.inc; +drop user rpl@localhost; diff --git a/mysql-test/suite/rpl/t/ignore_table_autoinc-9737.test b/mysql-test/suite/rpl/t/ignore_table_autoinc-9737.test new file mode 100644 index 00000000..405d1a92 --- /dev/null +++ b/mysql-test/suite/rpl/t/ignore_table_autoinc-9737.test @@ -0,0 +1,35 @@ +# +# MDEV-9737 Duplicate error in replication with slave triggers and auto increment +# +source include/master-slave.inc; +call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT"); + + +create table t1(id int auto_increment primary key); +create table t2(id int auto_increment primary key); + +sync_slave_with_master; +create table slave_only(id int auto_increment primary key); +insert into slave_only values(NULL); +create trigger t1i after insert on t1 for each row insert into slave_only values(NULL); + +stop slave; +set global replicate_ignore_table="test.t2"; +start slave; + +connection master; +insert into t2 values(NULL); +insert into t1 values(NULL); + +sync_slave_with_master; + +drop table t1, t2, slave_only; +stop slave; +set global replicate_ignore_table=""; +start slave; + +connection master; +drop table t1, t2; + +source include/rpl_end.inc; + diff --git a/mysql-test/suite/rpl/t/kill_hard-6290.test b/mysql-test/suite/rpl/t/kill_hard-6290.test new file mode 100644 index 00000000..76242356 --- /dev/null +++ b/mysql-test/suite/rpl/t/kill_hard-6290.test @@ -0,0 +1,11 @@ +# +# MDEV-6290 Crash in KILL HARD QUERY USER x@y when slave threads are running +# + +# this test doesn't depend on the binlog format, no need to run it three times +--source include/have_binlog_format_mixed.inc + +--source include/master-slave.inc +--connection server_2 +kill user test2@nohost; +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/kill_race_condition.test b/mysql-test/suite/rpl/t/kill_race_condition.test new file mode 100644 index 00000000..25a7b18b --- /dev/null +++ b/mysql-test/suite/rpl/t/kill_race_condition.test @@ -0,0 +1,36 @@ +source include/have_debug_sync.inc; +source include/have_binlog_format_row.inc; +source include/master-slave.inc; + +connection master; +create table t1 (a int); +--sync_slave_with_master + +connection slave; +SET @saved_dbug = @@GLOBAL.debug_dbug; +set global debug_dbug='d,rows_log_event_before_open_table'; + +connection master; +insert t1 values (1),(2),(3); + +connection slave; +set debug_sync='now WAIT_FOR before_open_table'; +let $a=`select id from information_schema.processlist where state='debug sync point: now'`; +replace_result $a slave_sql_thread; +eval kill $a; +set debug_sync='now SIGNAL go_ahead_sql'; +--let $slave_sql_errno= 1927 +--source include/wait_for_slave_sql_error.inc +let $error= query_get_value(SHOW SLAVE STATUS, Last_SQL_Error, 1); +--echo Last_SQL_Error = $error +SET @@GLOBAL.debug_dbug = @saved_dbug; +set debug_sync='RESET'; +connection master; +drop table t1; + +connection slave; +--source include/start_slave.inc +let $error= query_get_value(SHOW SLAVE STATUS, Last_SQL_Error, 1); +--echo Last_SQL_Error = $error + +source include/rpl_end.inc; diff --git a/mysql-test/suite/rpl/t/last_insert_id.cnf b/mysql-test/suite/rpl/t/last_insert_id.cnf new file mode 100644 index 00000000..1c229e4a --- /dev/null +++ b/mysql-test/suite/rpl/t/last_insert_id.cnf @@ -0,0 +1,20 @@ +!include suite/rpl/my.cnf + +[mysqld.1] +log-slave-updates +loose-innodb + +[mysqld.2] +log-slave-updates +loose-innodb +replicate-ignore-table=db.t2 + +[mysqld.3] +log-slave-updates +loose-innodb + +[ENV] +SERVER_MYPORT_3= @mysqld.3.port +SERVER_MYSOCK_3= @mysqld.3.socket + + diff --git a/mysql-test/suite/rpl/t/last_insert_id.test b/mysql-test/suite/rpl/t/last_insert_id.test new file mode 100644 index 00000000..f23cca40 --- /dev/null +++ b/mysql-test/suite/rpl/t/last_insert_id.test @@ -0,0 +1,30 @@ +--source include/have_innodb.inc +--source include/have_binlog_format_mixed_or_statement.inc +--let $rpl_topology=1->2->3 +--source include/rpl_init.inc + +connection server_1; + +create table t1 (id int not null auto_increment primary key, i int) engine=InnoDB; +insert into t1 (i) values (-1); +insert into t1 (i) values (LAST_INSERT_ID()); +select * from t1; + +save_master_pos; + +connection server_2; + +sync_with_master; +select * from t1; +save_master_pos; + +connection server_3; + +sync_with_master; +select * from t1; + +connection server_1; +drop table t1; + +--source include/rpl_end.inc + diff --git a/mysql-test/suite/rpl/t/mdev_17588-slave.opt b/mysql-test/suite/rpl/t/mdev_17588-slave.opt new file mode 100644 index 00000000..d73dbeca --- /dev/null +++ b/mysql-test/suite/rpl/t/mdev_17588-slave.opt @@ -0,0 +1 @@ +--loose-disable-innodb --replicate-ignore-table=test.t3 diff --git a/mysql-test/suite/rpl/t/mdev_17588.test b/mysql-test/suite/rpl/t/mdev_17588.test new file mode 100644 index 00000000..44644158 --- /dev/null +++ b/mysql-test/suite/rpl/t/mdev_17588.test @@ -0,0 +1,44 @@ +--source include/master-slave.inc +--source include/have_innodb.inc + +--connection slave +--source include/stop_slave.inc +CHANGE MASTER TO master_use_gtid=slave_pos; +--source include/start_slave.inc + +--connection master +create table t1 (a int) engine=innodb; +create table t2 (a int); +create table t3 (a int) engine=innodb; +--save_master_pos + +--connection slave +# Using ER_UNKNOWN_STORAGE_ENGINE wont work +let $slave_sql_errno= 1286; +--source include/wait_for_slave_sql_error_and_skip.inc +--sync_with_master + +--let $assert_text= Status should be 'Slave has read all relay log...' +--let $assert_cond= "[SHOW SLAVE STATUS, Slave_SQL_Running_State, 1]" +#Like "Slave has read all relay log%" +--source include/rpl_assert.inc + +show tables; +show create table t2; +--error ER_NO_SUCH_TABLE +show create table t1; +--error ER_NO_SUCH_TABLE +show create table t3; + +--connection master +drop table if exists t1; +drop table if exists t2; +drop table if exists t3; +--source include/save_master_gtid.inc + +--connection slave +--source include/sync_with_master_gtid.inc + + +CALL mtr.add_suppression('Slave: Unknown storage engine .* Error_code: 1286'); +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/myisam_external_lock-slave.opt b/mysql-test/suite/rpl/t/myisam_external_lock-slave.opt new file mode 100644 index 00000000..db53e17d --- /dev/null +++ b/mysql-test/suite/rpl/t/myisam_external_lock-slave.opt @@ -0,0 +1,2 @@ +--log-slave-updates=0 +--skip_external_locking=0 diff --git a/mysql-test/suite/rpl/t/myisam_external_lock.test b/mysql-test/suite/rpl/t/myisam_external_lock.test new file mode 100644 index 00000000..14824fd8 --- /dev/null +++ b/mysql-test/suite/rpl/t/myisam_external_lock.test @@ -0,0 +1,24 @@ +--source include/have_binlog_format_row.inc +--source include/master-slave.inc + +# +# MDEV-6871 Multi-value insert on MyISAM table that makes slaves crash +# This only happens if external_lock is enabled +# + +drop table if exists t1; +CREATE TABLE `t1` (`col1` int(11) NOT NULL,`col2` int(11) NOT NULL, + PRIMARY KEY (`col1`,`col2`), + KEY `col2` (`col2`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1; +INSERT INTO `t1` VALUES (2775,974),(2775,975),(2775,976),(2778,977),(2778,978),(2782,979),(2790,986),(2790,1139),(2792,840),(2792,984),(2792,989),(2793,982),(2793,992),(2793,993),(2793,994),(2795,323),(2795,332),(2797,980),(2797,997),(2797,998),(2798,1103),(2798,1104),(2799,841),(2799,985),(2799,988),(2833,983),(2833,990),(2833,991),(2834,981),(2834,995),(2834,996),(2835,316),(2835,317),(3007,854),(3007,856),(3008,855),(3008,857),(3009,823),(3009,824),(3014,1),(3015,1),(3016,2),(3017,2),(3018,3),(3019,3),(3024,842),(3024,843),(3024,844),(3025,845),(3025,846),(3025,847),(3040,31),(3041,32),(3042,52),(3042,55),(3043,53),(3043,54),(3044,278),(3044,279),(3044,280),(3044,281),(3044,282),(3044,283),(3044,284),(3044,285),(3045,1),(3046,1),(3049,220),(3050,221),(3050,222),(3051,2),(3052,2),(3053,223),(3054,224),(3055,225),(3056,226),(3057,227),(3058,228),(3059,229),(3060,327),(3066,236),(3067,237),(3068,238),(3069,239),(3070,240),(3080,241),(3081,242),(3082,247),(3083,248),(3084,249),(3085,250),(3086,251),(3087,252),(3088,253),(3089,254),(3090,255),(3091,256),(3092,257),(3093,258),(3094,259),(3096,263),(3097,264),(3100,273),(3100,302),(3101,266),(3102,267),(3103,268),(3104,269),(3105,270),(3111,275),(3112,238),(3113,272),(3115,286),(3116,318),(3116,319),(3117,290),(3117,292),(3118,238),(3119,291),(3119,293),(3120,304),(3121,305),(3122,306),(3123,307),(3124,308),(3125,309),(3126,310),(3127,311),(3128,312),(3128,336),(3129,313),(3129,350),(3130,314),(3131,315),(3131,351),(3132,325),(3132,328),(3134,502),(3138,334),(3139,338),(3139,339),(3140,340),(3140,341),(3141,344),(3141,345),(3142,346),(3142,347),(3149,351),(3149,354),(3150,351),(3150,356),(3152,358),(3152,359),(3153,361),(3153,370),(3154,363),(3154,369),(3156,350),(3156,371),(3159,376),(3160,377),(3160,379),(3160,384),(3161,378),(3161,380),(3161,383),(3162,388),(3162,389),(3162,390),(3169,392),(3169,393),(3169,394),(3170,395),(3170,396),(3170,397),(3171,398),(3171,399),(3171,400),(3172,401),(3172,402),(3172,403),(3173,404),(3173,405),(3173,406),(3178,351),(3178,421),(3190,411),(3190,412),(3191,413),(3191,414),(3192,415),(3192,416),(3193,417),(3193,418),(3194,419),(3194,420),(3195,353),(3195,424),(3196,425),(3196,426),(3197,427),(3197,428),(3198,429),(3198,430),(3199,431),(3199,432),(3200,433),(3200,434),(3201,435),(3201,436),(3202,437),(3202,438),(3203,439),(3203,440),(3204,441),(3204,442),(3205,443),(3205,444),(3206,445),(3206,446),(3207,447),(3207,448),(3208,449),(3208,450),(3209,451),(3209,452),(3210,453),(3210,454),(3211,455),(3211,456),(3212,457),(3212,458),(3213,459),(3213,460),(3214,461),(3214,462),(3215,463),(3215,464),(3218,466),(3218,467),(3218,468),(3219,469),(3219,470),(3219,471),(3220,474),(3220,475),(3220,476),(3221,477),(3221,478),(3221,479),(3222,480),(3222,481),(3223,482),(3223,483),(3224,484),(3224,485),(3225,486),(3225,487),(3227,503),(3227,505),(3228,506),(3228,507),(3230,508),(3230,509),(3231,510),(3231,511),(3232,512),(3232,513),(3233,514),(3233,515),(3234,516),(3234,517),(3235,518),(3235,519),(3237,521),(3237,522),(3239,524),(3239,525),(3240,526),(3240,527),(3241,528),(3241,529),(3242,530),(3242,531),(3243,532),(3243,533),(3244,534),(3244,535),(3245,536),(3245,537),(3246,538),(3246,539),(3252,540),(3252,541),(3254,543),(3254,544),(3254,545),(3255,547),(3255,548),(3255,571),(3256,550),(3256,551),(3256,572),(3257,553),(3257,554),(3257,573),(3258,556),(3258,557),(3258,574),(3259,559),(3259,560),(3259,575),(3260,561),(3260,562),(3260,563),(3261,565),(3261,576),(3262,566),(3262,567),(3263,568),(3263,569),(3263,570),(3264,577),(3264,578),(3265,579),(3265,580),(3266,581),(3266,582),(3266,591),(3267,583),(3267,584),(3267,592),(3268,585),(3268,586),(3268,593),(3269,587),(3269,588),(3269,594),(3270,589),(3270,590),(3271,595),(3271,596),(3271,597),(3272,598),(3272,599),(3273,600),(3273,601),(3273,602),(3274,603),(3274,604),(3274,605),(3275,606),(3275,607),(3275,608),(3276,609),(3276,610),(3276,611),(3277,612),(3277,613),(3277,614),(3278,615),(3278,616),(3279,617),(3279,618),(3279,619),(3279,628),(3279,629),(3280,620),(3280,621),(3280,622),(3281,623),(3281,624),(3281,625),(3282,626),(3282,825),(3283,630),(3283,631),(3284,632),(3284,633),(3284,634),(3285,635),(3285,940),(3286,638),(3286,639),(3286,640),(3287,641),(3287,642),(3287,643),(3288,644),(3288,645),(3288,646),(3289,647),(3289,648),(3289,649),(3290,650),(3290,651),(3290,652),(3291,653),(3291,654),(3291,655),(3292,656),(3292,657),(3292,658),(3293,659),(3293,660),(3293,661),(3294,662),(3294,663),(3294,664),(3295,665),(3295,666),(3295,667),(3296,668),(3296,669),(3296,670),(3297,671),(3297,672),(3297,673),(3298,674),(3298,675),(3298,676),(3299,677),(3299,678),(3299,679),(3300,680),(3300,681),(3300,682),(3301,683),(3301,684),(3301,685),(3302,686),(3302,687),(3302,688),(3303,689),(3303,690),(3303,691),(3304,692),(3304,693),(3304,694),(3305,695),(3305,696),(3305,697),(3306,698),(3306,699),(3306,700),(3307,701),(3307,702),(3307,703),(3308,704),(3308,705),(3308,706),(3309,707),(3309,708),(3310,709),(3310,710),(3311,711),(3311,712),(3311,713),(3312,714),(3312,715),(3312,716),(3313,717),(3313,1167),(3314,720),(3314,721),(3314,722),(3315,723),(3315,724),(3315,725),(3316,726),(3316,727),(3316,728),(3317,729),(3317,730),(3317,731),(3318,732),(3318,733),(3318,734),(3319,735),(3319,736),(3319,737),(3320,738),(3320,739),(3320,740),(3321,741),(3321,742),(3322,743),(3322,744),(3323,745),(3323,746),(3323,747),(3324,748),(3324,749),(3324,750),(3325,751),(3325,752),(3325,753),(3326,754),(3326,755),(3327,756),(3327,757),(3328,758),(3328,789),(3329,761),(3329,790),(3330,762),(3330,763),(3331,768),(3331,785),(3331,786),(3332,769),(3332,783),(3332,784),(3335,766),(3336,767),(3343,770),(3343,771),(3344,772),(3344,773),(3345,774),(3345,775),(3347,776),(3347,777),(3347,987),(3348,778),(3348,779),(3349,780),(3372,781),(3372,782),(3373,787),(3373,788),(3376,791),(3376,792),(3377,793),(3377,794),(3378,799),(3378,800),(3379,801),(3379,802),(3380,795),(3380,796),(3381,797),(3381,798),(3383,805),(3384,806),(3384,807),(3385,808),(3385,809),(3386,810),(3386,811),(3387,812),(3387,814),(3388,815),(3388,816),(3391,817),(3391,818),(3391,819),(3392,820),(3392,821),(3392,822),(3393,826),(3393,827),(3394,828),(3394,829),(3395,830),(3395,831),(3396,834),(3396,835),(3397,832),(3397,833),(3398,836),(3398,837),(3399,838),(3399,839),(3410,850),(3410,851),(3411,852),(3411,853),(3412,848),(3412,849),(3419,860),(3419,951),(3420,859),(3420,861),(3422,862),(3422,863),(3423,864),(3423,865),(3424,866),(3424,867),(3424,872),(3424,873),(3425,868),(3425,869),(3425,874),(3425,875),(3426,878),(3426,879),(3427,876),(3427,877),(3428,880),(3432,884),(3432,885),(3432,886),(3434,887),(3434,888),(3434,889),(3441,894),(3441,895),(3442,896),(3442,897),(3444,904),(3445,905),(3449,906),(3449,907),(3450,908),(3450,909),(3453,910),(3458,915),(3458,916),(3459,917),(3459,918),(3463,919),(3463,920),(3485,929),(3486,930),(3487,931),(3488,932),(3489,933),(3493,2),(3494,2),(3501,934),(3502,936),(3503,938),(3504,939),(3505,941),(3506,942),(3507,943),(3508,944),(3509,945),(3510,946),(3511,947),(3512,948),(3514,949),(3514,950),(3515,953),(3516,954),(3517,955),(3518,956),(3519,957),(3520,958),(3521,959),(3527,960),(3527,965),(3528,961),(3528,962),(3529,963),(3529,964),(3530,966),(3530,967),(3531,968),(3531,969),(3535,970),(3535,971),(3536,972),(3536,973),(3540,999),(3540,1000),(3541,1001),(8888,9999); + +drop table t1; + +save_master_pos; +connection slave; +sync_with_master; + +connection master; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/mysql-wsrep#110-2.test b/mysql-test/suite/rpl/t/mysql-wsrep#110-2.test new file mode 100644 index 00000000..2b6d0791 --- /dev/null +++ b/mysql-test/suite/rpl/t/mysql-wsrep#110-2.test @@ -0,0 +1,44 @@ +# +# codership/mysql-wsrep/110 - Assertion `table_found' failed in unpack_row() with SAVEPOINT, trigger, error handler +# + +--source include/have_innodb.inc +--source include/have_binlog_format_row.inc +--source include/master-slave.inc + +CREATE TABLE t1 (f1 INTEGER PRIMARY KEY); +CREATE TABLE t2 (f1 INTEGER PRIMARY KEY); +CREATE TABLE t3 (f1 INTEGER PRIMARY KEY); + +CREATE TRIGGER tr1 AFTER INSERT ON t1 FOR EACH ROW CALL p1(NEW.f1); + +DELIMITER |; + +CREATE PROCEDURE p1 (IN x INT) +BEGIN + DECLARE EXIT HANDLER FOR SQLEXCEPTION + BEGIN + ROLLBACK TO event_logging; + INSERT t3 VALUES (x); + END; + SAVEPOINT event_logging; + + INSERT INTO t2 VALUES (x); + + RELEASE SAVEPOINT event_logging; +END| +DELIMITER ;| + +INSERT INTO t2 VALUES (1); +INSERT INTO t1 VALUES (1); + + +DROP TABLE t3; +DROP TABLE t2; +DROP TABLE t1; + +DROP PROCEDURE p1; + +sync_slave_with_master; +--source include/rpl_end.inc + diff --git a/mysql-test/suite/rpl/t/parallel_backup.test b/mysql-test/suite/rpl/t/parallel_backup.test new file mode 100644 index 00000000..6ed182c0 --- /dev/null +++ b/mysql-test/suite/rpl/t/parallel_backup.test @@ -0,0 +1,75 @@ +--source include/have_innodb.inc +# The test is not format specific, MIXED is required to optimize testing time +--source include/have_binlog_format_mixed.inc +--source include/master-slave.inc + +--echo # +--echo # MDEV-21953: deadlock between BACKUP STAGE BLOCK_COMMIT and parallel +--echo # replication +--echo # + +--connection master +CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE = innodb; + +--sync_slave_with_master +--source include/stop_slave.inc +SET @old_parallel_threads= @@GLOBAL.slave_parallel_threads; +SET @old_parallel_mode = @@GLOBAL.slave_parallel_mode; +SET @@global.slave_parallel_threads= 2; +SET @@global.slave_parallel_mode = 'optimistic'; + +--connection master +INSERT INTO t1 VALUES (1); +INSERT INTO t1 VALUES (2); +--save_master_pos + +# The plot: +# Block the 1st of two workers and, at waiting-for-prior-commit by the 2nd, +# issue BACKUP commands. +# BLOCK_COMMIT may hang so it is --send. +# Release the 1st worker to observe a deadlock unless its fixed. + +--connect (aux_slave,127.0.0.1,root,,test,$SLAVE_MYPORT,) +BEGIN; +# block the 1st worker and wait for the 2nd ready to commit +INSERT INTO t1 VALUES (1); + +--connection slave +--source include/start_slave.inc + +--connection aux_slave +--let $wait_condition= SELECT COUNT(*) > 0 FROM information_schema.processlist WHERE state = "Waiting for prior transaction to commit" +--source include/wait_condition.inc + +# While the 1st worker is locked out run backup +--connect (backup_slave,127.0.0.1,root,,test,$SLAVE_MYPORT,) +BACKUP STAGE START; +--send BACKUP STAGE BLOCK_COMMIT + +# release the 1st work +--connection aux_slave +--sleep 1 +ROLLBACK; + +--connection backup_slave +--reap +BACKUP STAGE END; + +--connection slave +--sync_with_master + +--let $diff_tables= master:t1,slave:t1 +--source include/diff_tables.inc + + +# Clean up. +--connection slave +--source include/stop_slave.inc +SET @@global.slave_parallel_threads= @old_parallel_threads; +SET @@global.slave_parallel_mode = @old_parallel_mode; +--source include/start_slave.inc + +--connection server_1 +DROP TABLE t1; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/password_expiration.test b/mysql-test/suite/rpl/t/password_expiration.test new file mode 100644 index 00000000..6934500c --- /dev/null +++ b/mysql-test/suite/rpl/t/password_expiration.test @@ -0,0 +1,53 @@ +# +# Test a slave connection is properly handled when the replication +# user has an expired password +# + +--source include/not_embedded.inc +--source include/have_binlog_format_mixed.inc +--source include/master-slave.inc + +--connection slave +--source include/stop_slave.inc + +--connection master +create user 'repl_user' password expire; +grant replication slave on *.* to repl_user; +flush privileges; +set global disconnect_on_expired_password=ON; + +--connection slave +--let $master_user= query_get_value(SHOW SLAVE STATUS, Master_User, 1) +CHANGE MASTER TO MASTER_USER= 'repl_user'; + +START SLAVE; +# ER_MUST_CHANGE_PASSWORD_LOGIN +--let $slave_io_errno= 1862 +--source include/wait_for_slave_io_error.inc + +# restart slave +--source include/stop_slave_sql.inc +RESET SLAVE; + +--connection master +# force sandbox mode for repl_user +set global disconnect_on_expired_password=OFF; + +--connection slave +START SLAVE; +# ER_MUST_CHANGE_PASSWORD +--let $slave_io_errno= 1820 +--source include/wait_for_slave_io_error.inc + +--connection master +DROP USER 'repl_user'; +set global disconnect_on_expired_password=default; + +--connection slave +--source include/stop_slave_sql.inc +eval CHANGE MASTER TO MASTER_USER='$master_user'; +RESET SLAVE; + +--let $rpl_only_running_threads= 1 +--source include/rpl_end.inc + diff --git a/mysql-test/suite/rpl/t/rename.test b/mysql-test/suite/rpl/t/rename.test new file mode 100644 index 00000000..ac499157 --- /dev/null +++ b/mysql-test/suite/rpl/t/rename.test @@ -0,0 +1,33 @@ +--source include/have_binlog_format_mixed.inc +--source include/master-slave.inc + +--echo # +--echo # MDEV-16229 Replication aborts with ER_VIEW_SELECT_TMPTABLE after +--echo # half-failed RENAME +--echo # + +CREATE TABLE t1 (a INT); +CREATE TEMPORARY TABLE t1 (b INT); +RENAME TABLE t1 TO tmp, tmp TO t1; +SHOW CREATE TABLE t1; +--error ER_VIEW_SELECT_TMPTABLE +CREATE VIEW v AS SELECT * FROM t1; + +RENAME TABLE t1 TO tmp, t1 TO t2; +SHOW CREATE TABLE tmp; +SHOW CREATE TABLE t2; +--error ER_VIEW_SELECT_TMPTABLE +CREATE VIEW v AS SELECT * FROM tmp; +CREATE VIEW v AS SELECT * FROM t2; + +--sync_slave_with_master + +# Cleanup + +--connection master + +DROP VIEW v; +DROP TABLE tmp; +DROP TABLE t2; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/replace.test b/mysql-test/suite/rpl/t/replace.test new file mode 100644 index 00000000..36afda0d --- /dev/null +++ b/mysql-test/suite/rpl/t/replace.test @@ -0,0 +1,24 @@ +# +# Test of REPLACE with replication +# + +source include/master-slave.inc; + +# +# Test of doing replace on unique key on table with auto_increment +# + +drop table if exists t1; +CREATE TABLE t1 (pr_id int(10) unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY, pr_page int(11) NOT NULL, pr_type varbinary(60) NOT NULL, test int, UNIQUE KEY pr_pagetype (pr_page,pr_type)) ENGINE=myisam AUTO_INCREMENT=136; +insert into t1 (pr_page, pr_type, test) values(1,"one",0),(2,"two",0); +select * from t1; +replace into t1 (pr_page, pr_type,test) values(1,"one",2); +select * from t1; +sync_slave_with_master; +connection slave; +select * from t1; +connection master; +drop table t1; + +# End of 5.5 tests +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_000010-slave.opt b/mysql-test/suite/rpl/t/rpl_000010-slave.opt new file mode 100644 index 00000000..cbd77ee2 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_000010-slave.opt @@ -0,0 +1 @@ +--debug-disconnect-slave-event-count=2 diff --git a/mysql-test/suite/rpl/t/rpl_000010.test b/mysql-test/suite/rpl/t/rpl_000010.test new file mode 100644 index 00000000..de6337dd --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_000010.test @@ -0,0 +1,16 @@ +# This tests the offset off by 22 mystery bug +# Must run slave with --disconnect-slave-event-count=1 --master-connect-retry=1 + +source include/master-slave.inc; + +create table t1 (n int not null auto_increment primary key); +insert into t1 values(NULL); +insert into t1 values(2); +sync_slave_with_master; +select n from t1; +connection master; +drop table t1; +sync_slave_with_master; + +# End of 4.1 tests +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_000011-slave.opt b/mysql-test/suite/rpl/t/rpl_000011-slave.opt new file mode 100644 index 00000000..7c3d2411 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_000011-slave.opt @@ -0,0 +1 @@ +--verbose=1 diff --git a/mysql-test/suite/rpl/t/rpl_000011.test b/mysql-test/suite/rpl/t/rpl_000011.test new file mode 100644 index 00000000..289b79f7 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_000011.test @@ -0,0 +1,34 @@ +# +# Test very simply slave replication (to ensure it works at all) +# In addition, test also: +# MDEV-5829 STOP SLAVE resets global status variables +# + +source include/master-slave.inc; +--connection slave +let $initial_com_insert= query_get_value(show global status like "Com_insert", Value, 1); +--connection master +create table t1 (n int); +insert into t1 values(1); +sync_slave_with_master; +let $current_com_insert= query_get_value(show global status like "Com_insert", Value, 1); +--let $delta_com_insert= `select $current_com_insert - $initial_com_insert from dual` +--echo # Com_insert = $delta_com_insert +stop slave; +let $current_com_insert= query_get_value(show global status like "Com_insert", Value, 1); +--let $delta_com_insert= `select $current_com_insert - $initial_com_insert from dual` +--echo # Com_insert = $delta_com_insert +--source include/wait_for_slave_to_stop.inc +start slave; +--source include/wait_for_slave_to_start.inc +connection master; +insert into t1 values(2); +#let slave catch up +sync_slave_with_master; +select * from t1; +connection master; +drop table t1; +sync_slave_with_master; + +# End of 4.1 tests +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_000013.test b/mysql-test/suite/rpl/t/rpl_000013.test new file mode 100644 index 00000000..9f1b0666 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_000013.test @@ -0,0 +1,55 @@ +# This test is to verify that DROP TEMPORARY TABLE +# is automatically binlogged and sent to slave +# when a temp table is dropped by disconnection +# of a master's conection. +# So it does not apply to row-based, where we neither need +# nor do this automatic binlogging. And if we run this test +# in row-based, it hangs waiting for an offset which is never +# reached (the "sync_with_master 1"), logically. + +--source include/have_binlog_format_mixed_or_statement.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 + +create table t2(n int); +create temporary table t1 (n int); +insert into t1 values(1),(2),(3); +--disable_warnings +insert into t2 select * from t1; +--enable_warnings +connection master1; +create temporary table t1 (n int); +insert into t1 values (4),(5); +--disable_warnings +insert into t2 select * from t1 as t10; +--enable_warnings +save_master_pos; +disconnect master; +connection slave; +#add 1 to catch drop table +sync_with_master 1; +connection master1; +insert into t2 values(6); +save_master_pos; +disconnect master1; +connection slave; +# same trick to go one more event +sync_with_master 1; +select * from t2; +show status like 'Slave_open_temp_tables'; +# +# Clean up +# +connect (master2,localhost,root,,); +connection master2; + +# We will get a warning for t1 as this is a temporary table that doesn't +# exist in this connection. + +drop table if exists t1,t2; + +--source include/rpl_end.inc +# End of 4.1 tests diff --git a/mysql-test/suite/rpl/t/rpl_000017.test b/mysql-test/suite/rpl/t/rpl_000017.test new file mode 100644 index 00000000..893117e6 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_000017.test @@ -0,0 +1,47 @@ +# ==== Purpose ==== +# +# Unknown. +# +# ==== Notes ==== +# +# This test uses the -slave.opt file to start the slave with +# --skip-slave-start. + +--source include/not_windows.inc + +--let $rpl_skip_start_slave= 1 +--source include/master-slave.inc + +--connection slave +--let $slave_datadir= `SELECT @@datadir` + +--remove_file $slave_datadir/master.info +--write_file $slave_datadir/master.info +master-bin.000001 +4 +127.0.0.1 +replicate +aaaaaaaaaaaaaaab +$MASTER_MYPORT +1 +0 +EOF + +connection master; +grant replication slave on *.* to replicate@localhost identified by 'aaaaaaaaaaaaaaab'; +grant replication slave on *.* to replicate@127.0.0.1 identified by 'aaaaaaaaaaaaaaab'; +connection slave; +--source include/start_slave.inc + +connection master; +create table t1(n int); +insert into t1 values(24); +sync_slave_with_master; +select * from t1; +connection master; +drop table t1; +delete from mysql.user where user="replicate"; + +# End of 4.1 tests +--source include/rpl_end.inc + diff --git a/mysql-test/suite/rpl/t/rpl_15867.test b/mysql-test/suite/rpl/t/rpl_15867.test new file mode 100644 index 00000000..6de39041 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_15867.test @@ -0,0 +1,11 @@ +--source include/master-slave.inc +CREATE TEMPORARY TABLE t (i INT); +CREATE TABLE t AS SELECT * FROM t; + +--sync_slave_with_master + +# Cleanup +--connection master +DROP TEMPORARY TABLE t; +DROP TABLE t; +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_15919-slave.opt b/mysql-test/suite/rpl/t/rpl_15919-slave.opt new file mode 100644 index 00000000..62ab6dad --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_15919-slave.opt @@ -0,0 +1 @@ +--lower_case_table_names=1 diff --git a/mysql-test/suite/rpl/t/rpl_15919.test b/mysql-test/suite/rpl/t/rpl_15919.test new file mode 100644 index 00000000..a5b25929 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_15919.test @@ -0,0 +1,18 @@ +--source include/have_case_sensitive_file_system.inc +--source include/have_innodb.inc +--source include/master-slave.inc + +--connection master +create table RPL(a int); +insert into RPL values(1); + +--sync_slave_with_master +select * from rpl; +insert into RPL values(3); +insert into rpl values(4); +select * from rpl; + +--connection master +drop table RPL; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_EE_err.test b/mysql-test/suite/rpl/t/rpl_EE_err.test new file mode 100644 index 00000000..b2ca3aac --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_EE_err.test @@ -0,0 +1,2 @@ +let $engine_type=myisam; +-- source include/rpl_EE_err.test diff --git a/mysql-test/suite/rpl/t/rpl_LD_INFILE.test b/mysql-test/suite/rpl/t/rpl_LD_INFILE.test new file mode 100644 index 00000000..0f02bdcc --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_LD_INFILE.test @@ -0,0 +1,39 @@ +############################################################################# +# Original Author: JBM # +# Original Date: Aug/18/2005 # +############################################################################# +# TEST: To test the LOAD DATA INFILE in rbr # +############################################################################# + +# Includes +-- source include/master-slave.inc + +# Begin clean up test section +--disable_warnings +connection master; +DROP TABLE IF EXISTS test.t1; +--enable_warnings + +# Section 1 test +CREATE TABLE test.t1 (a VARCHAR(255), PRIMARY KEY(a)); +LOAD DATA INFILE '../../std_data/words2.dat' INTO TABLE test.t1; +DELETE FROM test.t1 WHERE a = 'abashed'; +DELETE FROM test.t1; +LOAD DATA INFILE '../../std_data/words2.dat' INTO TABLE test.t1; + + +SELECT * FROM test.t1 ORDER BY a DESC; +save_master_pos; +sync_slave_with_master; +connection slave; +SELECT * FROM test.t1 ORDER BY a DESC; + +# Cleanup +#show binlog events; +connection master; +DROP TABLE test.t1; +sync_slave_with_master; + +# End of 5.0 test case + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_alter.test b/mysql-test/suite/rpl/t/rpl_alter.test new file mode 100644 index 00000000..8b8bcfb3 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_alter.test @@ -0,0 +1,71 @@ +source include/master-slave.inc; +create database mysqltest; + +create table mysqltest.t1 ( n int); +alter table mysqltest.t1 add m int; +insert into mysqltest.t1 values (1,2); +create table mysqltest.t2 (n int); +insert into mysqltest.t2 values (45); +rename table mysqltest.t2 to mysqltest.t3, mysqltest.t1 to mysqltest.t2; +sync_slave_with_master; +select * from mysqltest.t2; +select * from mysqltest.t3; +connection master; +drop database mysqltest; +sync_slave_with_master; + +# End of 4.1 tests + +connection master; +use test; + +--echo # +--echo # Test bug where ALTER TABLE MODIFY didn't replicate properly +--echo # + +create table t1 (a int unsigned primary key, b int); +show create table t1; +insert into t1 (a) values (1),((1<<32)-1); +select * from t1; +alter table t1 modify a bigint; +show create table t1; +select * from t1; +alter table t1 modify a int unsigned; +show create table t1; +select * from t1; +alter table t1 modify a bigint unsigned; +show create table t1; +select * from t1; +sync_slave_with_master; +use test; +select * from t1; +show create table t1; +connection master; +# +create table t2 (a int unsigned auto_increment primary key, b int); +show create table t2; +alter table t2 modify a bigint; +show create table t2; +alter table t2 modify a bigint auto_increment; +show create table t2; +drop table t1,t2; + +--echo # +--echo # MDEV-8432: Slave cannot replicate signed integer-type values +--echo # with high bit set to 1 +--echo # Test replication when we have int on master and bigint on slave +--echo # + +create table t1 (a int unsigned primary key, b int); +sync_slave_with_master; +SET GLOBAL SLAVE_TYPE_CONVERSIONS='ALL_NON_LOSSY'; +alter table t1 modify a bigint unsigned; +connection master; +insert into t1 (a) values (1),((1<<32)-1); +sync_slave_with_master; +select * from t1; +SET GLOBAL SLAVE_TYPE_CONVERSIONS=''; +connection master; +drop table t1; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_alter_db.test b/mysql-test/suite/rpl/t/rpl_alter_db.test new file mode 100644 index 00000000..f6f07825 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_alter_db.test @@ -0,0 +1,15 @@ +source include/master-slave.inc; + +--echo ==== Verify that alter database does not stop replication ==== + +create database temp_db; +use temp_db; # to be different from initial `test' db of mysqltest client +alter database collate latin1_bin; + +sync_slave_with_master; + +--echo ==== Clean up ==== +connection master; +drop database temp_db; +sync_slave_with_master; +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_alter_extra_persistent.test b/mysql-test/suite/rpl/t/rpl_alter_extra_persistent.test new file mode 100644 index 00000000..4e604787 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_alter_extra_persistent.test @@ -0,0 +1,106 @@ +--source include/have_binlog_format_row.inc +--source include/master-slave.inc + +--enable_connect_log +--connection master +create table t1(a int primary key); +insert into t1 values(1); +insert into t1 values(2); +insert into t1 values(3); +insert into t1 values(4); + +--sync_slave_with_master +select * from t1 order by a; +alter table t1 add column z1 int as(a+1) virtual, add column z2 int as (a+2) persistent; +select * from t1 order by a; + +--connection master +insert into t1 values(5); +insert into t1 values(6); + +--sync_slave_with_master +select * from t1 order by a; + + +--echo #UPDATE query + +--connection master +update t1 set a = a+10; +select * from t1 order by a; + +--sync_slave_with_master +select * from t1 order by a; + +--connection master +update t1 set a = a-10; +select * from t1 order by a; + +--sync_slave_with_master +select * from t1 order by a; + +--echo #DELETE quert +--connection master +delete from t1 where a > 2 and a < 4; +select * from t1 order by a; + +--sync_slave_with_master +select * from t1 order by a; + +--echo #REPLACE query +--connection master +replace into t1 values(1); +replace into t1 values(3); +replace into t1 values(1); + +--sync_slave_with_master +select * from t1 order by a; + +--echo #SELECT query +--connection master +select * from t1 where a > 2 and a < 4; + +--connection slave +select * from t1 where a > 2 and a < 4; + +--echo #UPDATE with SELECT query +--connection master +update t1 set a = a + 10 where a > 2 and a < 4; +select * from t1 order by a; + +--sync_slave_with_master +select * from t1 order by a; + +--connection master +update t1 set a = a - 10 where a = 13; +select * from t1 order by a; + +--sync_slave_with_master +select * from t1 order by a; + +--echo #Break Unique Constraint +alter table t1 add column z4 int as (a % 6) persistent unique; + +--connection master + +--echo #entering duplicate value for slave persistent column +insert into t1 values(7); +select * from t1 order by a; + +--connection slave +--let $slave_sql_errno= 1062 +--source include/wait_for_slave_sql_error.inc +select * from t1 order by a; +alter table t1 drop column z4; +start slave; + +--source include/wait_for_slave_sql_to_start.inc + +--connection master +--sync_slave_with_master +select * from t1 order by a; + +--connection master +select * from t1 order by a; +drop table t1; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_alter_instant.test b/mysql-test/suite/rpl/t/rpl_alter_instant.test new file mode 100644 index 00000000..260f7e92 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_alter_instant.test @@ -0,0 +1,50 @@ +source include/have_innodb.inc; +source include/master-slave.inc; + +use test; +create table t1 (id int primary key, c1 int default 10, c2 varchar(20) default 'holiday') engine = innodb; + +insert into t1 values(1, 12345, 'abcde'), (2, default, default), (3, 23456, 'xyzab'); + +set time_zone='+03:00'; +set timestamp = 1; +alter table t1 add column d1 timestamp not null default current_timestamp; + +select * from t1; +sync_slave_with_master; + +connection slave; +set time_zone='+03:00'; +select * from t1; + +connection master; +alter table t1 add column d2 timestamp not null default current_timestamp, ALGORITHM=copy; + +sync_slave_with_master; + +connection slave; +select * from t1; + +connection master; +drop table t1; + + +# datetime +create table t4 (id int primary key, c2 int); +insert into t4 values(1,1),(2,2),(3,3); +set timestamp = 1000; +alter table t4 add column (c3 datetime default current_timestamp(), c4 timestamp not null default current_timestamp()); +select * from t4; +alter table t4 add column c5 time not null default current_timestamp(); +alter table t4 add column c6 date not null default current_timestamp(); + +select * from t4; +sync_slave_with_master; + +connection slave; +select * from t4; + +connection master; +drop table t4; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_auto_increment-master.opt b/mysql-test/suite/rpl/t/rpl_auto_increment-master.opt new file mode 100644 index 00000000..a8a6af19 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_auto_increment-master.opt @@ -0,0 +1 @@ +--auto-increment-increment=10 --auto-increment-offset=2 diff --git a/mysql-test/suite/rpl/t/rpl_auto_increment-slave.opt b/mysql-test/suite/rpl/t/rpl_auto_increment-slave.opt new file mode 100644 index 00000000..79ed6f96 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_auto_increment-slave.opt @@ -0,0 +1 @@ +--replicate-ignore-table=test.t_ignored1 diff --git a/mysql-test/suite/rpl/t/rpl_auto_increment.test b/mysql-test/suite/rpl/t/rpl_auto_increment.test new file mode 100644 index 00000000..6d01fdb8 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_auto_increment.test @@ -0,0 +1,7 @@ +##################################### +# Wrapper for rpl_auto_increment.test# +##################################### +-- source include/have_innodb.inc +let $engine_type=innodb; +let $engine_type2=myisam; +-- source include/rpl_auto_increment.test diff --git a/mysql-test/suite/rpl/t/rpl_auto_increment_11932.test b/mysql-test/suite/rpl/t/rpl_auto_increment_11932.test new file mode 100644 index 00000000..1e5f9e53 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_auto_increment_11932.test @@ -0,0 +1,66 @@ +# +# Test of auto_increment +# BUG#11932 +# +# Bug reported that master and slave get out of sync after TRUNCATE +# TABLE. +# +# Test supplied by Are Casilla + +source include/master-slave.inc; +call mtr.add_suppression('Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT.'); +--disable_warnings +connection master; +drop database if exists test1; +--enable_warnings +create database test1; +use test1; + +CREATE TABLE `t1` ( + `id` int(10) unsigned NOT NULL auto_increment, + `fname` varchar(100) default NULL, + PRIMARY KEY (`id`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=2 ; + +INSERT INTO `t1` VALUES (1, 'blablabla'); + +CREATE TABLE `t2` ( + `id` int(10) NOT NULL auto_increment, + `comment` varchar(255) NOT NULL default '', + PRIMARY KEY (`id`) +) ENGINE=MyISAM AUTO_INCREMENT=3 ; + +INSERT INTO `t2` VALUES (1, 'testtest 1'); +INSERT INTO `t2` VALUES (2, 'test 2'); + +DELIMITER $; +CREATE PROCEDURE simpleproc3 () + NOT DETERMINISTIC + BEGIN + INSERT INTO t1 (fname) (SELECT t2.comment FROM t2 WHERE t2.id = '1'); + INSERT INTO t1 (fname) VALUES('test'); + END + $ +DELIMITER ;$ + +--disable_warnings +CALL simpleproc3(); +--enable_warnings + +select * from t2; + +TRUNCATE TABLE `t1`; +--disable_warnings +CALL simpleproc3(); +--enable_warnings + +select * from t1; + +sync_slave_with_master; + +use test1; +select * from t1; + +connection master; +drop database test1; +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_auto_increment_bug33029.test b/mysql-test/suite/rpl/t/rpl_auto_increment_bug33029.test new file mode 100644 index 00000000..6f7e0d80 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_auto_increment_bug33029.test @@ -0,0 +1,60 @@ +# BUG#33029 5.0 to 5.1 replication fails on dup key when inserting +# using a trig in SP + +# For all 5.0 up to 5.0.58 exclusive, and 5.1 up to 5.1.12 exclusive, +# if one statement in a SP generated AUTO_INCREMENT value by the top +# statement, all statements after it would be considered generated +# AUTO_INCREMENT value by the top statement, and a erroneous INSERT_ID +# value might be associated with these statement, which could cause +# duplicate entry error and stop the slave. + +# Test if the slave can replicate from such a buggy master + +# The bug33029-slave-relay-bin.000001 file is the +# slave-replay-bin.000003 file generated by run the +# rpl_auto_increment_bug33029.test with clean up statements at the end +# of the test case removed on a buggy 5.0 server + +--let $rpl_skip_start_slave= 1 +--source include/master-slave.inc + +--echo ==== Initialize ==== +--connection slave + +# The binlog we read does funny things with triggers and causes this warning. +--disable_query_log +CALL mtr.add_suppression('Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT'); +--enable_query_log + +# Need to restore this at the end; CHANGE MASTER modifies it (see the +# manual for CHANGE MASTER). +SET @old_relay_log_purge= @@global.relay_log_purge; + +# the relay log contains create t1, t2 tables and load data infile +--let $fake_relay_log = $MYSQL_TEST_DIR/std_data/bug33029-slave-relay-bin.000001 +--source include/setup_fake_relay_log.inc + +--echo ==== Test ==== +start slave sql_thread; +--let $slave_param= Exec_Master_Log_Pos +--let $slave_param_value= 3776 +--source include/wait_for_slave_param.inc + + +echo # Result on slave; +SELECT * FROM t1; +SELECT * FROM t2; + +--echo ==== Clean up ==== + +stop slave sql_thread; +--source include/cleanup_fake_relay_log.inc + +DROP TABLE t1, t2; +DROP PROCEDURE p1; +DROP PROCEDURE p2; +DROP FUNCTION f1; + +SET @@global.relay_log_purge= @old_relay_log_purge; +--let $rpl_only_running_threads= 1 +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_auto_increment_bug45679.test b/mysql-test/suite/rpl/t/rpl_auto_increment_bug45679.test new file mode 100644 index 00000000..32f08be7 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_auto_increment_bug45679.test @@ -0,0 +1,62 @@ +# Test of auto-increment. +# +# BUG#11754117-45670 +# Multipart primary key with the autoincrement part not first in it +# is replication unsafe. +# + +source include/have_binlog_format_mixed.inc; +source include/have_innodb.inc; +source include/master-slave.inc; + +call mtr.add_suppression('Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT.'); + +--connection master +create table tm (b int auto_increment, a int, primary key (a,b)) engine= myisam; +--error ER_WRONG_AUTO_KEY +create table ti (b int auto_increment, a int, primary key (a,b)) engine= innodb; +create table ti (b int auto_increment, a int, primary key (b,a)) engine= innodb; + +set @@binlog_format=statement; +--echo *** autoincrement field is not the first in PK warning must be there: *** +insert into tm set b=null, a=1; +show warnings; +--echo *** no warning when autoincrement is the first in PK +insert into ti set b=null, a=1; +show warnings; + +delimiter //; +create function multi_part_pk_with_autoinc (arg int) +returns int +begin + insert into tm set b=null, a=arg; + return arg; +end// +delimiter ;// + +select multi_part_pk_with_autoinc (3); +--echo *** autoincrement field is not the first in PK warning must be there: *** +show warnings; + +set @@binlog_format=mixed; +insert into tm set b=null, a=2; + +sync_slave_with_master; + +if (`select count(*) <> 3 from tm`) +{ + --echo Wrong result from SELECT on the slave side. + select * from tm; + --die +} + +# cleanup + +--connection master + +drop table tm, ti; +drop function multi_part_pk_with_autoinc; + +sync_slave_with_master; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_auto_increment_update_failure.test b/mysql-test/suite/rpl/t/rpl_auto_increment_update_failure.test new file mode 100644 index 00000000..82db8f08 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_auto_increment_update_failure.test @@ -0,0 +1,211 @@ +# +# Bug45677 +# This test verifies the following two properties: +# P1) insert/update in an autoinc column causes statement to +# be logged in row format if binlog_format=mixed. +# P2) if binlog_format=mixed, and a trigger or function contains +# two or more inserts/updates in a table that has an autoinc +# column, then the slave should not go out of sync, even if +# there are concurrent transactions. +# +# Property (P1) is tested by executing an insert and an update on +# a table that has an autoinc column, and verifying that these +# statements result in row events in the binlog. +# Property (P2) is tested by setting up the test scenario and +# verifying that the tables are identical on master and slave. +# + +source include/have_binlog_format_mixed.inc; +source include/have_innodb.inc; +source include/master-slave.inc; + +--echo # Test case1: INVOKES A TRIGGER with after insert action +let $trigger_action = after insert; +source include/rpl_auto_increment_invoke_trigger.test; + +--echo # Test case2: INVOKES A TRIGGER with before insert action +let $trigger_action = before insert; +source include/rpl_auto_increment_invoke_trigger.test; + +--echo # Test case3: INVOKES A TRIGGER with after update action +let $trigger_action = after update; +source include/rpl_auto_increment_invoke_trigger.test; + +--echo # Test case4: INVOKES A TRIGGER with before update action +let $trigger_action = before update; +source include/rpl_auto_increment_invoke_trigger.test; + +--echo # Test case5: INVOKES A TRIGGER with after delete action +let $trigger_action = after delete; +source include/rpl_auto_increment_invoke_trigger.test; + +--echo # Test case6: INVOKES A TRIGGER with before delete action +let $trigger_action = before delete; +source include/rpl_auto_increment_invoke_trigger.test; + +--echo # Test case7: CALLS A FUNCTION which INVOKES A TRIGGER with after insert action +let $insert_action = after insert; +source include/rpl_autoinc_func_invokes_trigger.test; + +--echo # Test case8: CALLS A FUNCTION which INVOKES A TRIGGER with before insert action +let $insert_action = before insert; +source include/rpl_autoinc_func_invokes_trigger.test; + +--echo # Test case9: INSERT DATA INTO VIEW WHICH INVOKES TRIGGERS with after insert action +let $insert_action = after insert; +source include/rpl_auto_increment_insert_view.test; + +--echo # Test case10: INSERT DATA INTO VIEW WHICH INVOKES TRIGGERS with before insert action +let $insert_action = before insert; +source include/rpl_auto_increment_insert_view.test; + +--echo # Test case11: INVOKES A FUNCTION TO INSERT TWO OR MORE VALUES INTO A TABLE WITH AUTOINC COLUMN +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; +delimiter //; +CREATE FUNCTION f1_two_inserts() RETURNS INTEGER +BEGIN + INSERT INTO t2(a) values(2); + INSERT INTO t2(a) values(2); + RETURN 1; +END// +delimiter ;// +begin; +insert into t1(a) values(f1_two_inserts()); + +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()); +commit; + +connection master; +--echo #Test result for INVOKES A FUNCTION TO INSERT TWO OR MORE VALUES on master +select * from t2 ORDER BY i1; + +sync_slave_with_master; +connection slave; +--echo #Test result for INVOKES A FUNCTION TO INSERT TWO OR MORE VALUES on slave +select * from t2 ORDER BY i1; + +connection master; +drop table t1; +drop table t2; +drop function f1_two_inserts; +sync_slave_with_master; + +--echo # Test case12: INVOKES A FUNCTION TO UPDATE TWO OR MORE VALUES OF A TABLE WITH AUTOINC COLUMN +connection master; +create table t1(a int) engine=innodb; +create table t2(i1 int not null auto_increment, a int, b int, primary key(i1)) engine=innodb; +delimiter //; +CREATE FUNCTION f1_two_updates() RETURNS INTEGER +BEGIN + update t2 set a = a + 5 where b = 1; + update t2 set a = a + 5 where b = 2; + update t2 set a = a + 5 where b = 3; + update t2 set a = a + 5 where b = 4; + RETURN 1; +END// +delimiter ;// + +connection master1; +#The default autocommit is set to 1, so the statement is auto committed +insert into t2(a,b) values(1,1); +insert into t2(a,b) values(2,2); +insert into t2(a,b) values(3,3); +insert into t2(a,b) values(4,4); +insert into t1(a) values(f1_two_updates()); + +connection master; +begin; +insert into t1(a) values(f1_two_updates()); +commit; + +connection master; +--echo #Test result for INVOKES A FUNCTION TO UPDATE TWO OR MORE VALUES on master +select * from t2 ORDER BY i1; + +sync_slave_with_master; +connection slave; +--echo #Test result for INVOKES A FUNCTION TO UPDATE TWO OR MORE VALUES on slave +select * from t2 ORDER BY i1; + +connection master; +drop table t1; +drop table t2; +drop function f1_two_updates; +sync_slave_with_master; + +--echo # Test case13: UPDATE MORE THAN ONE TABLES ON TOP-STATEMENT +connection master; +create table t1(i1 int not null auto_increment, a int, b int, primary key(i1)) engine=innodb; +create table t2(i1 int not null auto_increment, a int, b int, primary key(i1)) engine=innodb; +begin; +let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1); +insert into t1(a,b) values(1,1),(2,2); +insert into t2(a,b) values(1,1),(2,2); +update t1,t2 set t1.a=t1.a+5, t2.a=t2.a+5 where t1.b=t2.b; +insert into t1(a,b) values(3,3); +insert into t2(a,b) values(3,3); +commit; +--echo # To verify if it works fine when these statements are not be marked as unsafe +source include/show_binlog_events.inc; + +sync_slave_with_master; +--echo #Test if the results are consistent on master and slave +--echo #for 'UPDATE MORE THAN ONE TABLES ON TOP-STATEMENT' +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; + +--echo # Test case14: INSERT DATA INTO VIEW WHICH INVOLVED MORE THAN ONE TABLES +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; +let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1); +begin; +INSERT INTO t1(c1) VALUES (11), (12); +INSERT INTO t2(c2) VALUES (13), (14); + +CREATE VIEW v15 AS SELECT c1, c2 FROM t1, t2; + +INSERT INTO v15(c1) VALUES (15),(16); +INSERT INTO v15(c2) VALUES (17),(18); + +connection master1; +INSERT INTO v15(c1) VALUES (19),(20); +INSERT INTO v15(c2) VALUES (21),(22); + +connection master; +INSERT INTO v15(c1) VALUES (23), (24); +INSERT INTO v15(c2) VALUES (25), (26); +commit; +--echo # To verify if it works fine when these statements are not be marked as unsafe +source include/show_binlog_events.inc; + +sync_slave_with_master; +--echo #Test if the results are consistent on master and slave +--echo #for 'INSERT DATA INTO VIEW WHICH INVOLVED MORE THAN ONE TABLES' +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; +drop view v15; +sync_slave_with_master; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_autogen_query_multi_byte_char.test b/mysql-test/suite/rpl/t/rpl_autogen_query_multi_byte_char.test new file mode 100644 index 00000000..a93fcbac --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_autogen_query_multi_byte_char.test @@ -0,0 +1,87 @@ +############################################################################### +# Bug#21205695 DROP TABLE MAY CAUSE SLAVES TO BREAK +# +# Problem: +# ======== +# 1) Drop table queries are re-generated by server +# before writing the events(queries) into binlog +# for various reasons. If table name/db name contains +# a non regular characters (like latin characters), +# the generated query is wrong. Hence it breaks the +# replication. +# 2) In the edge case, when table name contains +# 64 latin characters (latin takes 2 bytes), server is +# throwing an assert (M_TBLLEN < 128) +# +# 3) In the edge case, when db name contains 64 latin +# characters, binlog contents are interpreted wrongly +# which is leading to replication issues. +# +############################################################################### + +--source include/not_windows.inc +--source include/master-slave.inc + +--let iter=1 +# Change iteration to 4 after fixing Bug #22280214 +while ($iter <= 2) +{ + --connection master + if ($iter == 1) + { + --echo Test case 1:- table name with one character latin name. + --let $tblname= REPEAT(CHAR(131),1) + } + if ($iter == 2) + { + --echo Test case 2:- table name and database names with one character latin name. + --let $tblname= REPEAT(CHAR(131),1),"`.`",REPEAT(CHAR(131),1) + --eval SET @s:=CONCAT("CREATE DATABASE `",REPEAT(CHAR(131),1),"`") + PREPARE STMT FROM @s; EXECUTE stmt; + } + # After fixing Bug #22280214 DATADIR LOCATION IS LIMITING + # IDENTIFIER MAX LENGTH, the following two tests (iter 3 and 4) can be + # uncommented. + #if ($iter == 3) + #{ + # --echo Test case 3:- table name and database names with 64 latin characters name. + # --let $tblname= REPEAT(CHAR(131),64),"`.`", REPEAT(CHAR(131),64) + # --eval SET @s:=CONCAT("CREATE DATABASE `",REPEAT(CHAR(131),64),"`") + # PREPARE STMT FROM @s; EXECUTE stmt; + #} + #if ($iter == 4) + #{ + # --echo Test case 4:- table name and database names with 64 Euro(€) characters. + # --let $tblname= REPEAT(CHAR(226,130,172),64),"`.`", REPEAT(CHAR(226,130,172),64) + # --eval SET @s:=CONCAT("CREATE DATABASE `",REPEAT(CHAR(226,130,172),64),"`") + # PREPARE STMT FROM @s; EXECUTE stmt; + #} + --eval SET @s:=CONCAT("CREATE TABLE `",$tblname,"` (a INT)") + PREPARE STMT FROM @s; EXECUTE stmt; + --eval SET @s:=CONCAT("INSERT INTO `",$tblname,"` VALUES (1)") + PREPARE STMT FROM @s; EXECUTE stmt; + --eval SET @s:=CONCAT("DROP TABLE `",$tblname, "`") + PREPARE STMT FROM @s; EXECUTE stmt; + if ($iter == 2) + { + --eval SET @s:=CONCAT("DROP DATABASE `",REPEAT(CHAR(131),1),"`") + PREPARE STMT FROM @s; EXECUTE stmt; + } + # After fixing Bug #22280214 DATADIR LOCATION IS LIMITING + # IDENTIFIER MAX LENGTH, the following two tests (iter 3 and 4) can be + # uncommented. + #if ($iter == 3) + #{ + # --eval SET @s:=CONCAT("DROP DATABASE `",REPEAT(CHAR(131),64),"`") + # PREPARE STMT FROM @s; EXECUTE stmt; + #} + #if ($iter == 4) + #{ + # --eval SET @s:=CONCAT("DROP DATABASE `",REPEAT(CHAR(226,130,172),64),"`") + # PREPARE STMT FROM @s; EXECUTE stmt; + #} + --sync_slave_with_master + --inc $iter +} + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_begin_commit_rollback-master.opt b/mysql-test/suite/rpl/t/rpl_begin_commit_rollback-master.opt new file mode 100644 index 00000000..a8de78ed --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_begin_commit_rollback-master.opt @@ -0,0 +1 @@ +--loose-innodb --binlog-ignore-db=db2 diff --git a/mysql-test/suite/rpl/t/rpl_begin_commit_rollback-slave.opt b/mysql-test/suite/rpl/t/rpl_begin_commit_rollback-slave.opt new file mode 100644 index 00000000..264b1728 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_begin_commit_rollback-slave.opt @@ -0,0 +1 @@ +--loose-innodb --replicate-do-db=db1 diff --git a/mysql-test/suite/rpl/t/rpl_begin_commit_rollback.test b/mysql-test/suite/rpl/t/rpl_begin_commit_rollback.test new file mode 100644 index 00000000..659f074e --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_begin_commit_rollback.test @@ -0,0 +1,173 @@ +source include/have_innodb.inc; +source include/have_binlog_format_statement.inc; +source include/master-slave.inc; + +connection slave; +call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT"); + +connection master; +call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT"); + +SET @@session.binlog_direct_non_transactional_updates= FALSE; + +disable_warnings; +DROP DATABASE IF EXISTS db1; +DROP DATABASE IF EXISTS db2; +enable_warnings; + +CREATE DATABASE db1; +CREATE DATABASE db2; + +use db1; + +CREATE TABLE db1.t1 (a INT) ENGINE=InnoDB; +CREATE TABLE db1.t2 (s CHAR(255)) ENGINE=MyISAM; + +sync_slave_with_master; +source include/stop_slave.inc; +connection master; + +DELIMITER //; +CREATE PROCEDURE db1.p1 () +BEGIN + INSERT INTO t1 VALUES (1); + INSERT INTO t1 VALUES (2); + INSERT INTO t1 VALUES (3); + INSERT INTO t1 VALUES (4); + INSERT INTO t1 VALUES (5); +END// + +CREATE PROCEDURE db1.p2 () +BEGIN + INSERT INTO t1 VALUES (6); + INSERT INTO t1 VALUES (7); + INSERT INTO t1 VALUES (8); + INSERT INTO t1 VALUES (9); + INSERT INTO t1 VALUES (10); + INSERT INTO t2 VALUES ('executed db1.p2()'); +END// +DELIMITER ;// + +INSERT INTO db1.t2 VALUES ('before call db1.p1()'); + +# Note: the master_log_pos is set to be the position of the BEGIN + 1, +# so before fix of BUG#43263 if the BEGIN is ignored, then all the +# INSERTS in p1 will be replicated in AUTOCOMMIT=1 mode and the slave +# SQL thread will stop right before the first INSERT. After fix of +# BUG#43263, BEGIN will not be ignored by the replication db rules, +# and then the whole transaction will be executed before slave SQL +# stop. +let $master_pos= query_get_value(SHOW MASTER STATUS, Position, 1); +let $master_pos= `SELECT $master_pos + 1`; + +use test; +BEGIN; +CALL db1.p1(); +COMMIT; + +# The position where the following START SLAVE UNTIL will stop at +let $master_end_trans_pos= query_get_value(SHOW MASTER STATUS, Position, 1); + +INSERT INTO db1.t2 VALUES ('after call db1.p1()'); +SELECT * FROM db1.t1; +SELECT * FROM db1.t2; + +connection slave; + +replace_result $master_pos MASTER_POS; +eval start slave until master_log_file='master-bin.000001', master_log_pos=$master_pos; +source include/wait_for_slave_sql_to_stop.inc; +let $slave_sql_stop_pos= query_get_value(SHOW SLAVE STATUS, Exec_Master_Log_Pos, 1); +let $result= query_get_value(SELECT $slave_sql_stop_pos - $master_end_trans_pos as result, result, 1); + +--echo # +--echo # If we got non-zero here, then we're suffering BUG#43263 +--echo # +eval SELECT $result as 'Must be 0'; +SELECT * from db1.t1; +SELECT * from db1.t2; + +connection master; + +INSERT INTO db1.t2 VALUES ('before call db1.p2()'); + +# See comments above. +let $master_pos= query_get_value(SHOW MASTER STATUS, Position, 1); +let $master_pos= `SELECT $master_pos + 1`; + +BEGIN; +CALL db1.p2(); +disable_warnings; +ROLLBACK; +enable_warnings; +let $master_end_trans_pos= query_get_value(SHOW MASTER STATUS, Position, 1); + +INSERT INTO db1.t2 VALUES ('after call db1.p2()'); +SELECT * FROM db1.t1; +SELECT * FROM db1.t2; + +connection slave; + +replace_result $master_pos MASTER_POS; +eval start slave until master_log_file='master-bin.000001', master_log_pos=$master_pos; +source include/wait_for_slave_sql_to_stop.inc; + +let $slave_sql_stop_pos= query_get_value(SHOW SLAVE STATUS, Exec_Master_Log_Pos, 1); +let $result= query_get_value(SELECT $slave_sql_stop_pos - $master_end_trans_pos as result, result, 1); + +--echo # +--echo # If we got non-zero here, then we're suffering BUG#43263 +--echo # +eval SELECT $result as 'Must be 0'; +SELECT * from db1.t1; +SELECT * from db1.t2; + +START SLAVE; +source include/wait_for_slave_sql_to_start.inc; + +--echo # +--echo # SAVEPOINT and ROLLBACK TO have the same problem in BUG#43263 +--echo # This was reported by BUG#50407 +connection master; +let $binlog_start=query_get_value(SHOW MASTER STATUS, Position, 1); + +BEGIN; +INSERT INTO db1.t1 VALUES(20); + +--echo # +--echo # Verify whether this statement is binlogged correctly +/*comment*/ SAVEPOINT has_comment; +USE db1; +INSERT INTO db1.t1 VALUES(30); +INSERT INTO db1.t2 VALUES("in savepoint has_comment"); +USE db2; +SavePoint mixed_cases; +USE db1; +INSERT INTO db1.t2 VALUES("in savepoint mixed_cases"); +INSERT INTO db1.t1 VALUES(40); +USE db2; +ROLLBACK TO mixed_cases; +ROLLBACK TO has_comment; +USE db1; +INSERT INTO db1.t2 VALUES("after rollback to"); +INSERT INTO db1.t1 VALUES(50); +USE db2; +COMMIT; +source include/show_binlog_events.inc; +sync_slave_with_master; + +--echo # +--echo # Verify INSERT statements in savepoints are executed, for MyISAM table +--echo # is not effected by ROLLBACK TO +SELECT * FROM db1.t2 WHERE s LIKE '% savepoint %'; +--echo # +--echo # Verify INSERT statements on the Innodb table are rolled back; +SELECT * FROM db1.t1 WHERE a IN (30, 40); + +--echo # +--echo # Clean up +--echo # +connection master; +DROP DATABASE db1; +DROP DATABASE db2; +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_binlog_compress.test b/mysql-test/suite/rpl/t/rpl_binlog_compress.test new file mode 100644 index 00000000..ef1e4508 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_binlog_compress.test @@ -0,0 +1,61 @@ +# +# Test of compressed binlog with replication +# + +source include/master-slave.inc; + +set @old_log_bin_compress=@@log_bin_compress; +set @old_log_bin_compress_min_len=@@log_bin_compress_min_len; +set @old_binlog_format=@@binlog_format; +set @old_binlog_row_image=@@binlog_row_image; + +set global log_bin_compress=on; +set global log_bin_compress_min_len=10; + +drop table if exists t1; +CREATE TABLE t1 (pr_id int(10) unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY, pr_page int(11) NOT NULL, pr_type varbinary(60) NOT NULL, test int, UNIQUE KEY pr_pagetype (pr_page,pr_type)) ENGINE=myisam AUTO_INCREMENT=136; + +set binlog_format=statement; +insert into t1 (pr_page, pr_type, test) values(1,"one",0),(2,"two",0); +replace into t1 (pr_page, pr_type,test) values(1,"one",2); +update t1 set test=test+1 where pr_page > 1; +delete from t1 where test=1; + +select * from t1; +sync_slave_with_master; +connection slave; +select * from t1; +connection master; + + +set binlog_format=row; +insert into t1 (pr_page, pr_type, test) values(3,"three",0),(4,"four",4),(5, "five", 0); +replace into t1 (pr_page, pr_type,test) values(3,"one",2); +update t1 set test=test+1 where pr_page > 3; +delete from t1 where test=1; + +select * from t1; +sync_slave_with_master; +connection slave; +select * from t1; +connection master; + + +set binlog_row_image=minimal; +insert into t1 (pr_page, pr_type, test) values(6,"six",0),(7,"seven",7),(8, "eight", 0); +replace into t1 (pr_page, pr_type,test) values(6,"six",2); +update t1 set test=test+1 where pr_page > 6; +delete from t1 where test=1; + +select * from t1; +sync_slave_with_master; +connection slave; +select * from t1; +connection master; +drop table t1; + +set global log_bin_compress=@old_log_bin_compress; +set global log_bin_compress_min_len=@old_log_bin_compress_min_len; +set binlog_format=@old_binlog_format; +set binlog_row_image=@old_binlog_row_image; +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_binlog_corruption.test b/mysql-test/suite/rpl/t/rpl_binlog_corruption.test new file mode 100644 index 00000000..66b0c80f --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_binlog_corruption.test @@ -0,0 +1,50 @@ +# ==== Purpose ==== +# +# Verify that the slave stops gracefully when reading a relay log with +# corrupted data. +# +# ==== Implementation ==== +# +# Setup "fake replication" where the slave only starts the SQL thread, +# not the IO thread, and reads from an existing relay log that has +# been prepared so that it contains the error. This requires some +# extra server options: see the -master.opt file. +# +# ==== Related bugs ==== +# +# BUG#31793: log event corruption causes crash +# BUG#40482: server/mysqlbinlog crashes when reading invalid Incident_log_event + +--source include/master-slave.inc + +# BUG#40482 only manifested itself in debug-compiled binaries. +-- source include/have_debug.inc + +--connection slave +call mtr.add_suppression('Found invalid event in binary log'); +call mtr.add_suppression('Slave SQL.*Relay log read failure: Could not parse relay log event entry.* 1594'); + +# +# BUG#40482: server/mysqlbinlog crashes when reading invalid Incident_log_event +# +# The relay log contains an Incident_log_event with a non-existing +# incident number. + +--echo ==== Initialize ==== +--source include/stop_slave.inc +RESET SLAVE; + +let $fake_relay_log= $MYSQL_TEST_DIR/std_data/bug40482-bin.000001; +source include/setup_fake_relay_log.inc; + +--echo ==== Test ==== +START SLAVE SQL_THREAD; +let $slave_sql_errno= 1594; # ER_SLAVE_RELAY_LOG_READ_FAILURE +source include/wait_for_slave_sql_error.inc; +let $error= query_get_value(SHOW SLAVE STATUS, Last_SQL_Error, 1); +--echo Last_SQL_Error = $error + +--echo ==== Clean up ==== +source include/cleanup_fake_relay_log.inc; +--let $rpl_only_running_threads= 1 +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_binlog_dump_slave_gtid_state_info.test b/mysql-test/suite/rpl/t/rpl_binlog_dump_slave_gtid_state_info.test new file mode 100644 index 00000000..f26e9565 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_binlog_dump_slave_gtid_state_info.test @@ -0,0 +1,121 @@ +# ==== Purpose ==== +# +# Test verifies that Start binlog_dump message will report GTID position +# requested by slave when log_warnings > 1. +# +# ==== Implementation ==== +# +# Steps: +# 0 - Have LOG_WARNINGS=2 +# 1 - On a fresh slave server which has not replicated any GTIDs execute +# "CHANGE MASTER TO MASTER_USE_GTID=current_pos;" command. Start the +# slave. +# 2 - In Master error log verify that pattern "using_gtid(1), gtid('')" is +# present. +# 3 - On slave server do STOP SLAVE and execute "CHANGE MASTER TO +# MASTER_USE_GTID=no;" command. Start the slave threads. +# 4 - In Master error log verify that pattern "using_gtid(0), gtid('')" is +# present. +# 5- Execute a DDL and DML on master server. This will generated two GTIDs +# on the master server ('0-1-2'). Sync the slave server with master. +# 6 - On slave do STOP SLAVE and execute "CHANGE MASTER TO +# MASTER_USE_GTID=slave_pos;" command. Start slave threads. +# 7 - In Master error verify that pattern "using_gtid(1), gtid('0-1-2')" is +# present. +# 8 - On Master change domain ID to 10 and execute a DML operation. It will +# generate a GTID 10-1-1. +# 9 - On slave do STOP SLAVE and execute "CHANGE MASTER TO +# MASTER_USE_GTID=slave_pos;" command. Start slave threads. +# 10 -In Master error verify that pattern "using_gtid(1), +# gtid('0-1-2,10-1-1')" is present. +# +# ==== References ==== +# +# MDEV-20428: "Start binlog_dump" message doesn't indicate GTID position +# + +--source include/have_binlog_format_mixed.inc +--source include/have_innodb.inc +--source include/master-slave.inc + +--connection master +SET GLOBAL LOG_WARNINGS=2; + +--connection slave +--source include/stop_slave.inc +CHANGE MASTER TO MASTER_USE_GTID=current_pos; +--source include/start_slave.inc + +--connection master +# Check error log for correct messages. +let $log_error_= `SELECT @@GLOBAL.log_error`; +if(!$log_error_) +{ + # MySQL Server on windows is started with --console and thus + # does not know the location of its .err log, use default location + let $log_error_ = $MYSQLTEST_VARDIR/log/mysqld.1.err; +} +--echo "Test Case 1: Start binlog_dump to slave_server(#), pos(master-bin.000001, ###), using_gtid(1), gtid('')" +--let SEARCH_FILE=$log_error_ +--let SEARCH_RANGE=-50000 +--let SEARCH_PATTERN=using_gtid\(1\), gtid\(\'\'\).* +--source include/search_pattern_in_file.inc + +--connection slave +--source include/stop_slave.inc +CHANGE MASTER TO MASTER_USE_GTID=no; +--source include/start_slave.inc + +--connection master +--echo "Test Case 2: Start binlog_dump to slave_server(#), pos(master-bin.000001, ###), using_gtid(0), gtid('')" +--let SEARCH_FILE=$log_error_ +--let SEARCH_RANGE=-50000 +--let SEARCH_PATTERN=using_gtid\(0\), gtid\(\'\'\).* +--source include/search_pattern_in_file.inc +CREATE TABLE t (f INT) ENGINE=INNODB; +INSERT INTO t VALUES(10); +save_master_pos; + +--connection slave +sync_with_master; + +--connection slave +--source include/stop_slave.inc +CHANGE MASTER TO MASTER_USE_GTID=slave_pos; +--source include/start_slave.inc + +--connection master +--echo "Test Case 3: Start binlog_dump to slave_server(#), pos(master-bin.000001, ###), using_gtid(1), gtid('0-1-2')" +--let SEARCH_FILE=$log_error_ +--let SEARCH_RANGE=-50000 +--let SEARCH_PATTERN=using_gtid\(1\), gtid\(\'0-1-2\'\).* +--source include/search_pattern_in_file.inc +SET @@SESSION.gtid_domain_id=10; +INSERT INTO t VALUES(20); +save_master_pos; + +--connection slave +sync_with_master; + +--connection slave +--source include/stop_slave.inc +CHANGE MASTER TO MASTER_USE_GTID=slave_pos; +--source include/start_slave.inc + +--connection master +--echo "Test Case 4: Start binlog_dump to slave_server(#), pos(master-bin.000001, ###), using_gtid(1), gtid('0-1-2,10-1-1')" +--let SEARCH_FILE=$log_error_ +--let SEARCH_RANGE=-50000 +--let SEARCH_PATTERN=using_gtid\(1\), gtid\(\'0-1-2,10-1-1\'\).* +--source include/search_pattern_in_file.inc + +--echo "===== Clean up =====" +--connection slave +--source include/stop_slave.inc +CHANGE MASTER TO MASTER_USE_GTID=no; +--source include/start_slave.inc + +--connection master +DROP TABLE t; +SET GLOBAL LOG_WARNINGS=default; +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_binlog_dup_entry.test b/mysql-test/suite/rpl/t/rpl_binlog_dup_entry.test new file mode 100644 index 00000000..869c715f --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_binlog_dup_entry.test @@ -0,0 +1,72 @@ +# ==== Purpose ==== +# +# Test verifies that there are no duplicate entries in binlog (i.e a safe +# statement which follows an unsafe statement gets logged in both row format +# and statement format resulting in duplicate entry) when binlog-format=MIXED +# and LOCK TABLES are enabled. +# +# ==== Implementation ==== +# +# Steps: +# 1 - Create three tables t1,t2 and t3 with AUTO_INCREMENT on. +# 2 - Create a trigger on table t3, so that trigger execution results in +# unsafe statement. Note query that modifies autoinc column in +# sub-statement can make the master and slave inconsistent. Hence they +# are logged in row format. +# 3 - Lock tables t1,t2 and t3. +# 4 - Execute an unsafe update which modifies tables t1 and t3. But since t2 +# table is also locked its table map event also gets written into the +# binary log during the execution of update. +# 5 - Execute a safe DML operation using table 't2' and verify that master +# doesn't report any assert. +# 6 - Ensure that slave is in sync with master and data is consistent. +# +# ==== References ==== +# +# MDEV-19158: MariaDB 10.2.22 is writing duplicate entries into binary log + +--source include/have_binlog_format_mixed.inc +--source include/master-slave.inc + +CREATE TABLE t1 (id mediumint(8) unsigned NOT NULL AUTO_INCREMENT, someLabel varchar(30) NOT NULL, flag tinyint(1) NOT NULL DEFAULT 0, PRIMARY KEY (id)) Engine=MyISAM; +CREATE TABLE t2 (id mediumint(8) unsigned NOT NULL AUTO_INCREMENT, data varchar(30) NOT NULL, status tinyint(1) NOT NULL, PRIMARY KEY (id)) Engine=MyISAM; +CREATE TABLE t3 (id mediumint(8) unsigned NOT NULL AUTO_INCREMENT, t1id mediumint(8) unsigned NOT NULL, flag tinyint(1) NOT NULL DEFAULT 0, status tinyint(1) NOT NULL DEFAULT 0, PRIMARY KEY (id)) Engine=MyISAM; + +INSERT INTO t1 ( id, someLabel, flag ) VALUES ( 1, 'ABC', 0 ); + +DELIMITER |; + +CREATE OR REPLACE TRIGGER doNothing +BEFORE UPDATE ON t1 +FOR EACH ROW + BEGIN + IF + new.someLabel != old.someLabel + THEN + UPDATE t3 SET t3.flag = 0; + END IF; + END| + +DELIMITER ;| + +FLUSH LOGS; + +LOCK TABLES t1 WRITE, t2 WRITE; +INSERT INTO t2 (data, status) VALUES ('1', 4); +UPDATE t1 SET flag = 1 WHERE id = 1; +INSERT INTO t2 (data, status) VALUES ('2', 4); +UNLOCK TABLES; + +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 +let $diff_tables= master:t3, slave:t3; +--source include/diff_tables.inc + +--connection master +DROP TABLE t1, t2, t3; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_binlog_errors-master.opt b/mysql-test/suite/rpl/t/rpl_binlog_errors-master.opt new file mode 100644 index 00000000..f8e46a44 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_binlog_errors-master.opt @@ -0,0 +1 @@ +--max_binlog_size=4096 diff --git a/mysql-test/suite/rpl/t/rpl_binlog_errors.test b/mysql-test/suite/rpl/t/rpl_binlog_errors.test new file mode 100644 index 00000000..30faaf79 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_binlog_errors.test @@ -0,0 +1 @@ +--source include/rpl_binlog_errors.inc diff --git a/mysql-test/suite/rpl/t/rpl_binlog_grant.test b/mysql-test/suite/rpl/t/rpl_binlog_grant.test new file mode 100644 index 00000000..f8513021 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_binlog_grant.test @@ -0,0 +1,42 @@ +-- source include/have_innodb.inc +-- source include/not_embedded.inc +-- source include/have_binlog_format_mixed_or_statement.inc +source include/master-slave.inc; + +let $VERSION=`select version()`; + +# Bug #21975: grant/revoke statements in transaction +# used to disappear from binlog upon rallback. +# Now GRANT/REVOKE do implicitly commit +# transaction + +create database d1; +use d1; +create table t (s1 int) engine=innodb; +set @@autocommit=0; +start transaction; +insert into t values (1); +create user x@y; +grant select on t to x@y; +let $wait_binlog_event= grant select; +source include/wait_for_binlog_event.inc; +# +# There is no active transaction here +# +rollback; +show grants for x@y; +start transaction; +insert into t values (2); +revoke select on t from x@y; +let $wait_binlog_event= revoke select; +source include/wait_for_binlog_event.inc; +# +# There is no active transaction here +# +commit; +select * from t; +show grants for x@y; +drop user x@y; +drop database d1; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_binlog_index.test b/mysql-test/suite/rpl/t/rpl_binlog_index.test new file mode 100644 index 00000000..95c49c3d --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_binlog_index.test @@ -0,0 +1,217 @@ +# ==== Purpose ==== +# +# Test that server can work fine after moving binlog or relay log +# files to another directory and setting binlog or relay log paths to +# the new path. +# +# ==== Method ==== +# +# Start replication, and then shutdown the master, move the binary +# logs and the log index file to a another directory and then restart +# the server with option to set the new binlog directory. After master +# restarted successfully, do the similar on slave to check the relay +# log of slave. +# +# ==== Reference ==== +# +# BUG#12133 master.index file keeps mysqld from starting if bin log has been moved +# BUG#42576 Relay logs in relay-log.info&localhost-relay-bin.index not processed after move + +source include/master-slave.inc; +# There is no need to run this test case on all binlog format +source include/have_binlog_format_row.inc; + +# Since this test relies heavily on filesystem operations (like +# moving files around, backslashes and so forth) we avoid messing +# around with windows access violations for not cluttering the +# test case any further. It is prepared to support windows, but +# it is not 100% compliant. +--source include/not_windows.inc + +connection master; +--let $master_datadir= `select @@datadir` +connection slave; +--let $slave_datadir= `select @@datadir` +connection master; +--let $dirname= `select uuid()` +--let $tmpdir= $MYSQLTEST_VARDIR/tmp/$dirname +--mkdir $tmpdir + +CREATE TABLE t1 (a INT); +# flush to generate one more binlog file. +FLUSH BINARY LOGS; +INSERT INTO t1 VALUES (1); + +sync_slave_with_master; +--source include/stop_slave.inc +# +# Test on master +# +connection master; +--echo # Shutdown master +--let $rpl_server_number=1 +source include/rpl_stop_server.inc; + +--echo # Move the master binlog files and the index file to a new place +--move_file $master_datadir/master-bin.000001 $tmpdir/master-bin.000001 +--move_file $master_datadir/master-bin.000002 $tmpdir/master-bin.000002 +--move_file $master_datadir/master-bin.index $tmpdir/master-bin.index + +--echo # Restart master with log-bin option set to the new path +--let $rpl_server_parameters=--log-bin=$tmpdir/master-bin --log-bin-index=$tmpdir/master-bin +--let $keep_include_silent=1 +source include/rpl_start_server.inc; +--let $keep_include_silent=0 + +--echo # Master has restarted successfully +--connection slave +--source include/start_slave.inc +--connection master +# +# Test master can handle old format with directory path in index file +# +--let $is_windows= `select convert(@@version_compile_os using latin1) in ('Win32', 'Win64', 'Windows')` + +# write_var_to_file.inc will call SELECT INTO DUMPFILE, which has to be +# done before shutdown the server +--echo # Create the master-bin.index file with the old format +--let $write_to_file= $master_datadir/master-bin.index +if ($is_windows) +{ + --let $write_var= .\\\\master-bin.000001\n.\\\\master-bin.000002\n.\\\\master-bin.000003\n +} +if (!$is_windows) +{ + --let $write_var= ./master-bin.000001\n./master-bin.000002\n./master-bin.000003\n +} +--disable_query_log +source include/write_var_to_file.inc; +--enable_query_log +--sync_slave_with_master +--source include/stop_slave.inc + +--connection master +--echo # Shutdown master +--let $rpl_server_number=1 +source include/rpl_stop_server.inc; + +--echo # Move back the master binlog files +--move_file $tmpdir/master-bin.000001 $master_datadir/master-bin.000001 +--move_file $tmpdir/master-bin.000002 $master_datadir/master-bin.000002 +--move_file $tmpdir/master-bin.000003 $master_datadir/master-bin.000003 + +--echo # Remove the unneeded master-bin.index file +--remove_file $tmpdir/master-bin.index + +--echo # Restart master with log-bin option set to default +--let $rpl_server_parameters=--log-bin=$master_datadir/master-bin --log-bin-index=$master_datadir/master-bin +--let $keep_include_silent=1 +source include/rpl_start_server.inc; +--let $keep_include_silent=0 + +--echo # Master has restarted successfully +--connection slave +--source include/start_slave.inc + +--connection master +--sync_slave_with_master +--echo # stop slave +--source include/stop_slave.inc +--let $rpl_server_number= 2 +--source include/rpl_stop_server.inc + +# switch to master because the slave has been shutdown +# and relocate_binlogs requires a running server to do +# SQL operations +--connection master + +--let $relocate_disable_query_log= 1 +--let $relocate_is_windows= $is_windows +--let $relocate_from=$slave_datadir +--let $relocate_into=$tmpdir + +--echo # relocate binlogs +--let $relocate_index_file=$slave_datadir/slave-bin.index +--source include/relocate_binlogs.inc + +--echo # relocate relay logs +--let $relocate_index_file=$slave_datadir/slave-relay-bin.index +--source include/relocate_binlogs.inc + +--echo # Restart slave with options log-bin, relay-log set to the new paths +--let $rpl_server_parameters=--log-bin=$tmpdir/slave-bin --relay-log=$tmpdir/slave-relay-bin --relay-log-index=$tmpdir/slave-relay-bin.index +--let $keep_include_silent=1 +--let $rpl_server_number= 2 +source include/rpl_start_server.inc; +--let $keep_include_silent=0 + +--connection slave + +--echo # Slave server has restarted successfully +--source include/start_slave.inc +--source include/stop_slave.inc + +connection master; +FLUSH LOGS; +INSERT INTO t1 VALUES (2); +INSERT INTO t1 VALUES (2); +INSERT INTO t1 VALUES (2); +INSERT INTO t1 VALUES (2); + +FLUSH LOGS; + +connection slave; +FLUSH LOGS; +--source include/start_slave.inc +connection master; +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/stop_slave.inc +--let $rpl_server_number= 2 +--source include/rpl_stop_server.inc + +--connection master + +--let $relocate_from=$tmpdir +--let $relocate_into=$slave_datadir +--let $relocate_recreate_index= 1 + +# binlogs +--let $relocate_index_file=$tmpdir/slave-bin.index +--source include/relocate_binlogs.inc + +# relay logs + +# since the complete fix for the relocation of logs is +# done in BUG#13428851 it does not help here to try +# to start the slave as it would fail (relay-log.info is +# tainted with the full path in the RELAY_LOG_FILE position). +# Instead, we reset the slave and let the test clean up. +--let $relocate_fix_relay_log_info= $slave_datadir/relay-log.info +--let $relocate_index_file=$tmpdir/slave-relay-bin.index +--source include/relocate_binlogs.inc + +--echo # remove tmpdir +--remove_files_wildcard $tmpdir * +--rmdir $tmpdir + +--echo # restarted with previous slave settings +--let $rpl_server_parameters=--log-bin=$slave_datadir/slave-bin --relay-log=$slave_datadir/slave-relay-bin --relay-log-index=$slave_datadir/slave-relay-bin.index +--let $keep_include_silent=1 +--let $rpl_server_number= 2 +--source include/rpl_start_server.inc +--let $keep_include_silent=0 + +--connection slave + +# The slave will restart if we have fixed the relay-log.info +# correctly +--source include/start_slave.inc + +--connection master +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_binlog_rollback_cleanup.test b/mysql-test/suite/rpl/t/rpl_binlog_rollback_cleanup.test new file mode 100644 index 00000000..ed4d713f --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_binlog_rollback_cleanup.test @@ -0,0 +1,46 @@ +# ==== Purpose ==== +# +# Test verifies that when flushing an event to binary log fails the transaction +# is successfully rolled back and following COMMIT command doesn't report any +# assert. +# +# ==== Implementation ==== +# +# Steps: +# 0 - SET max_binlog_cache_size=64K +# 1 - Create an Innodb table and insert required amount of data. Execute an +# UPDATE operation which generates a big update event whose size exceeds +# max_binlog_cache_size. +# 2 - Wait for error 1197. Execute COMMIT command. +# 3 - COMMIT should be successful. +# +# ==== References ==== +# +# MDEV-18514: Assertion `!writer.checksum_len || writer.remains == 0' failed +# +--source include/have_innodb.inc +--source include/have_binlog_format_row.inc +--source include/master-slave.inc +--connection master +let $old_max_binlog_cache_size= query_get_value(SHOW VARIABLES LIKE "max_binlog_cache_size", Value, 1); +SET GLOBAL max_binlog_cache_size = 65536; +CREATE TABLE t1(a INT PRIMARY KEY, data VARCHAR(30000)) ENGINE=INNODB; +let $data = `select concat('"', repeat('a',6000), '"')`; +let $data1 = `select concat('"', repeat('b',6000), '"')`; +--disable_query_log +eval INSERT INTO t1 (a, data) VALUES (1, CONCAT($data, $data)); +eval INSERT INTO t1 (a, data) VALUES (2, CONCAT($data, $data)); +eval INSERT INTO t1 (a, data) VALUES (3, CONCAT($data, $data)); +eval INSERT INTO t1 (a, data) VALUES (4, CONCAT($data, $data)); +eval INSERT INTO t1 (a, data) VALUES (5, CONCAT($data, $data)); +START TRANSACTION; +--error ER_TRANS_CACHE_FULL +eval UPDATE t1 SET data=$data1; +COMMIT; +--enable_query_log + +--replace_result $old_max_binlog_cache_size ORIGINAL_VALUE +--eval SET GLOBAL max_binlog_cache_size= $old_max_binlog_cache_size +DROP TABLE t1; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_bit.test b/mysql-test/suite/rpl/t/rpl_bit.test new file mode 100644 index 00000000..305a2abc --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_bit.test @@ -0,0 +1,92 @@ +############################################################################# +# Original Author: JBM # +# Original Date: Sept/15/2005 # +############################################################################# +# Test: To test the replication of the bit field # +############################################################################# +# Change Author: JBM +# Change Date: 2006-01-16 +########## + +-- source include/master-slave.inc + + +# Begin clean up test section +connection master; +--disable_warnings +DROP TABLE IF EXISTS test.t1; +--enable_warnings +# End of cleanup + +# Begin test section 1 + +CREATE TABLE test.t1 ( + dummyKey INTEGER NOT NULL, + f01 TINYINT, + f10 TINYINT, + f12 TINYINT, + f15 TINYINT, + f16 TINYINT, + f7 TINYINT, + f9 TINYINT, + f29 TINYINT, + f0 TINYINT, + fA1 TINYINT, + C32 TINYINT, + A42 TINYINT, + CA3 TINYINT, + A044 TINYINT, + f001 TINYINT, + A3002 TINYINT, + fC003 TINYINT, + CA300 TINYINT, + A305 TINYINT, + CA321 TINYINT, + r001 TINYINT, + bit1 BIT(6), + bit2 BIT(6), + bit3 BIT(6), + State1 TINYINT, + State2 TINYINT, + State3 TINYINT, + State4 TINYINT, + SubState TINYINT, + gState TINYINT, + oSupp TINYINT, + tSupp TINYINT, + sSuppD TINYINT, + mSuppf TINYINT, + GSuppDf TINYINT, + VNotSupp TINYINT, + x034 TINYINT, +PRIMARY KEY USING HASH (dummyKey) ); + +LOCK TABLES test.t1 WRITE; +INSERT INTO test.t1 VALUES (6,1,1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,b'111111',b'111110',b'110101',4,5,5,5,5,5,5,5,5,5,3,2,1); +INSERT INTO test.t1 VALUES (1,1,1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,b'111111',b'000000',b'100100',4,5,5,5,5,5,5,5,5,5,3,2,1); +INSERT INTO test.t1 VALUES (2,1,1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,b'000000',b'101010',b'010101',4,5,5,5,5,5,5,5,5,5,3,2,1); +INSERT INTO test.t1 VALUES (3,1,1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,b'101010',b'111111',b'000000',4,5,5,5,5,5,5,5,5,5,3,2,1); +INSERT INTO test.t1 VALUES (4,1,1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,4,5,5,5,5,5,5,5,5,5,3,2,1); +INSERT INTO test.t1 VALUES (5,1,1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,4,5,5,5,5,5,5,5,5,5,3,2,1); +INSERT INTO test.t1 VALUES (7,1,1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,4,5,5,5,5,5,5,5,5,5,3,2,1); +INSERT INTO test.t1 VALUES (8,1,1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,4,5,5,5,5,5,5,5,5,5,3,2,1); +UNLOCK TABLES; + + +SELECT oSupp, sSuppD, GSuppDf, VNotSupp, x034 FROM test.t1; +SELECT hex(bit1) FROM test.t1 ORDER BY bit1; +SELECT hex(bit2) from test.t1 ORDER BY bit2; +SELECT hex(bit3) from test.t1 ORDER BY bit3; +sync_slave_with_master; + +SELECT oSupp, sSuppD, GSuppDf, VNotSupp, x034 FROM test.t1; +SELECT hex(bit1) FROM test.t1 ORDER BY bit1; +SELECT hex(bit2) from test.t1 ORDER BY bit2; +SELECT hex(bit3) from test.t1 ORDER BY bit3; + +connection master; +DROP TABLE IF EXISTS test.t1; +sync_slave_with_master; + +# End of 5.0 test case +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_bit_npk.test b/mysql-test/suite/rpl/t/rpl_bit_npk.test new file mode 100644 index 00000000..d65ef66a --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_bit_npk.test @@ -0,0 +1,113 @@ +############################################################################# +# Original Author: JBM # +# Original Date: Sept/15/2005 # +############################################################################# +# Test: To test the replication of the bit field # +############################################################################# + +-- source include/master-slave.inc + + +# Begin clean up test section +connection master; +--disable_warnings +DROP TABLE IF EXISTS test.t1; +--enable_warnings +# End of cleanup + +# Begin test section 1 + +CREATE TABLE test.t1 ( + dummyKey INTEGER NOT NULL, + f01 TINYINT, + f10 TINYINT, + f12 TINYINT, + f15 TINYINT, + f16 TINYINT, + f7 TINYINT, + f9 TINYINT, + f29 TINYINT, + f0 TINYINT, + fA1 TINYINT, + C32 TINYINT, + A42 TINYINT, + CA3 TINYINT, + A044 TINYINT, + f001 TINYINT, + A3002 TINYINT, + fC003 TINYINT, + CA300 TINYINT, + A305 TINYINT, + CA321 TINYINT, + r001 TINYINT, + bit1 BIT(6), + bit2 BIT(6), + bit3 BIT(6), + State1 TINYINT, + State2 TINYINT, + State3 TINYINT, + State4 TINYINT, + SubState TINYINT, + gState TINYINT, + oSupp TINYINT, + tSupp TINYINT, + sSuppD TINYINT, + mSuppf TINYINT, + GSuppDf TINYINT, + VNotSupp TINYINT, + x034 TINYINT); + +LOCK TABLES test.t1 WRITE; +INSERT INTO test.t1 VALUES (6,1,1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,b'111111',b'111110',b'110101',4,5,5,5,5,5,5,5,5,5,3,NULL,1); +INSERT INTO test.t1 VALUES (1,1,1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,b'111111',b'000000',b'100100',4,5,5,5,5,5,5,5,5,5,3,2,1); +INSERT INTO test.t1 VALUES (2,1,1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,b'000000',b'101010',b'010101',4,5,5,5,5,5,5,5,5,5,3,2,1); +INSERT INTO test.t1 VALUES (3,1,1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,b'101010',b'111111',b'000000',4,5,5,5,5,5,5,5,5,5,3,2,1); +INSERT INTO test.t1 VALUES (4,1,1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,b'0',1,1,4,5,5,5,5,5,5,5,5,5,3,2,1); +INSERT INTO test.t1 VALUES (5,1,1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,4,5,5,5,5,5,5,5,5,5,3,2,1); +INSERT INTO test.t1 VALUES (7,1,1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,4,5,5,5,5,5,5,5,5,5,3,2,1); +INSERT INTO test.t1 VALUES (8,1,1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,4,5,5,5,5,5,5,5,5,5,3,2,1); +UNLOCK TABLES; + +UPDATE test.t1 set x034 = 50 where bit3 = b'000000'; +UPDATE test.t1 set VNotSupp = 33 where bit1 = b'0'; +SELECT oSupp, sSuppD, GSuppDf, VNotSupp, x034 + FROM test.t1 + ORDER BY oSupp, sSuppD, GSuppDf, VNotSupp, x034; +SELECT hex(bit1) from test.t1 ORDER BY bit1; +SELECT hex(bit2) from test.t1 ORDER BY bit2; +SELECT hex(bit3) from test.t1 ORDER BY bit3; +sync_slave_with_master; + +SELECT oSupp, sSuppD, GSuppDf, VNotSupp, x034 + FROM test.t1 + ORDER BY oSupp, sSuppD, GSuppDf, VNotSupp, x034; +SELECT hex(bit1) from test.t1 ORDER BY bit1; +SELECT hex(bit2) from test.t1 ORDER BY bit2; +SELECT hex(bit3) from test.t1 ORDER BY bit3; + +connection master; +CREATE TABLE test.t2 (a INT, b BIT(1)); +INSERT INTO test.t2 VALUES (1, b'0'); +INSERT INTO test.t2 VALUES (1, b'1'); +UPDATE test.t2 SET a = 2 WHERE b = b'1'; + +CREATE TABLE test.t3 (a INT, b INT); +INSERT INTO test.t3 VALUES (1, NULL); +INSERT INTO test.t3 VALUES (1, 0); +UPDATE test.t3 SET a = 2 WHERE b = 0; + +SELECT a, hex(b) FROM test.t2 ORDER BY a,b; +SELECT * FROM test.t3 ORDER BY a,b; +sync_slave_with_master; + +SELECT a, hex(b) FROM test.t2 ORDER BY a,b; +SELECT * FROM test.t3 ORDER BY a,b; + +connection master; +DROP TABLE IF EXISTS test.t1; +DROP TABLE IF EXISTS test.t2; +DROP TABLE IF EXISTS test.t3; +sync_slave_with_master; + +# End of 5.0 test case +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_blackhole.test b/mysql-test/suite/rpl/t/rpl_blackhole.test new file mode 100644 index 00000000..927f0d80 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_blackhole.test @@ -0,0 +1,25 @@ +# 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). + +source include/have_blackhole.inc; +source include/master-slave.inc; + +call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT"); + +source include/rpl_blackhole_basic.test; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_blackhole_row_annotate-master.opt b/mysql-test/suite/rpl/t/rpl_blackhole_row_annotate-master.opt new file mode 100644 index 00000000..91302791 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_blackhole_row_annotate-master.opt @@ -0,0 +1 @@ +--binlog_annotate_row_events --timezone=GMT-3 diff --git a/mysql-test/suite/rpl/t/rpl_blackhole_row_annotate-slave.opt b/mysql-test/suite/rpl/t/rpl_blackhole_row_annotate-slave.opt new file mode 100644 index 00000000..7ac6a84f --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_blackhole_row_annotate-slave.opt @@ -0,0 +1 @@ +--binlog_annotate_row_events --replicate_annotate_row_events diff --git a/mysql-test/suite/rpl/t/rpl_blackhole_row_annotate.test b/mysql-test/suite/rpl/t/rpl_blackhole_row_annotate.test new file mode 100644 index 00000000..afc8e257 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_blackhole_row_annotate.test @@ -0,0 +1,49 @@ +# ==== Purpose ==== +# +# Test verifies that when "replicate_annotate_row_events" are enabled on slave +# the DML operations on blackhole engine will be successful. It also ensures +# that Annotate events are logged into slave's binary log. +# +# ==== Implementation ==== +# +# Steps: +# 0 - Enable "replicate_annotate_row_events" on slave and do DML operations +# on master. +# 1 - Slave server will successfully apply the DML operations and it is in +# sync with master. +# 2 - Verify that the "show binlog events" prints all annotate events. +# 3 - Stream the slave's binary log using "mysqlbinlog" tool and verify +# that the Annotate events are being displayed. +# +# ==== References ==== +# +# MDEV-11094: Blackhole table updates on slave fail when row annotation is +# enabled + +source include/have_blackhole.inc; +source include/have_binlog_format_row.inc; +source include/binlog_start_pos.inc; +source include/master-slave.inc; + +SET timestamp=1000000000; +RESET MASTER; +connection slave; +SET timestamp=1000000000; +RESET MASTER; + +connection master; +source include/rpl_blackhole_basic.test; + +# Verify on slave. +connection slave; +FLUSH LOGS; +--replace_column 2 # 5 # +--replace_result $binlog_start_pos +--replace_regex /table_id: [0-9]+/table_id: #/ /\/\* xid=.* \*\//\/* xid= *\// +--eval show binlog events in 'slave-bin.000001' from $binlog_start_pos + +let $MYSQLD_DATADIR= `select @@datadir`; +--replace_regex /server id [0-9]*/server id #/ /server v [^ ]*/server v #.##.##/ /exec_time=[0-9]*/exec_time=#/ /thread_id=[0-9]*/thread_id=#/ /table id [0-9]*/table id #/ /mapped to number [0-9]*/mapped to number #/ /end_log_pos [0-9]*/end_log_pos #/ /# at [0-9]*/# at #/ /CRC32 0x[0-9a-f]*/CRC32 XXX/ +--exec $MYSQL_BINLOG --base64-output=decode-rows $MYSQLD_DATADIR/slave-bin.000001 + +source include/rpl_end.inc; diff --git a/mysql-test/suite/rpl/t/rpl_bug26395.test b/mysql-test/suite/rpl/t/rpl_bug26395.test new file mode 100644 index 00000000..0c1b2a7a --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_bug26395.test @@ -0,0 +1,93 @@ +# ==== Purpose ==== +# +# Tests that an autocommitted XA transaction where the master crashes +# just before writing the XID log event is executed correctly. The +# master rolls back, so the slave should not execute statement. +# +# ==== Method ==== +# +# We want master to be alive so that it can replicate the statement to +# the slave. So in the test case, we must not crash the +# master. Instead, we fake the crash by just not writing the XID event +# to the binlog. This is done by the @@debug_dbug='d,do_not_write_xid' +# flag. This, in turn, requires us to do 'source +# include/have_debug.inc' +# +# So, unlike if the master had crashed, the master *will* execute the +# statement. But the slave should not execute it. Hence, after the +# test is executed, the expected result on master is a table with one +# row, and on slave a table with no rows. +# +# To simulate the slave correctly, we wait until everything up to but +# not including the XID is replicated. This has to be done with +# include/sync_slave_io_with_master.inc, not sync_slave_with_master, +# since the latter waits until the slave *SQL* thread has caught up +# with the master's position, which it will never do. +# +# +# ==== Related bugs ==== +# +# BUG#26395: if crash during autocommit update to transactional table on master, slave fails + +source include/have_innodb.inc; +# have_debug is needed since we use the @@debug variable on master +source include/have_debug.inc; +source include/master-slave.inc; + + +--echo ==== Initialize ==== + +--connection master + +CREATE TABLE tinnodb (a INT) ENGINE = INNODB; +SHOW CREATE TABLE tinnodb; + +# do_not_write_xid stops the master from writing an XID event. +set @old_debug= @@debug; +set @@debug_dbug= 'd,do_not_write_xid'; + + +--echo ==== Test ==== + +# Save the position up to which the slave SQL thread should execute. +save_master_pos; + +# Execute query and check that the row made it to the table. +INSERT INTO tinnodb VALUES (1); +SELECT * FROM tinnodb ORDER BY a; + +# Sync slave's IO thread. +--echo [on slave] +source include/sync_slave_io_with_master.inc; + +# Sync slave's SQL thread. +sync_with_master 0; + + +--echo ==== Verify results on slave ==== + +source include/stop_slave.inc; +let $tmp= query_get_value("SHOW SLAVE STATUS", Slave_IO_State, 1); +eval SELECT "$tmp" AS Slave_IO_State; +let $tmp= query_get_value("SHOW SLAVE STATUS", Last_SQL_Error, 1); +eval SELECT "$tmp" AS Last_SQL_Error; +let $tmp= query_get_value("SHOW SLAVE STATUS", Last_IO_Error, 1); +eval SELECT "$tmp" AS Last_IO_Error; +SELECT * FROM tinnodb ORDER BY a; + + +--echo ==== Clean up ==== + +# Easiest to clean up master and slave separately, without +# replication, since master and slave are out of sync. + +connection master; +DROP TABLE tinnodb; +set @@debug_dbug= @old_debug; + +connection slave; +DROP TABLE tinnodb; + +# Warning: do not add more tests here. The binlog is in a bad state. +--let $rpl_only_running_threads= 1 +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_bug31076.test b/mysql-test/suite/rpl/t/rpl_bug31076.test new file mode 100644 index 00000000..4e9517fb --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_bug31076.test @@ -0,0 +1,146 @@ +source include/have_binlog_format_mixed_or_row.inc; +source include/master-slave.inc; + +SET @saved_slave_type_conversions = @@slave_type_conversions; +SET GLOBAL SLAVE_TYPE_CONVERSIONS = 'ALL_NON_LOSSY'; + +CREATE DATABASE track; +USE track; + +CREATE TABLE `visits` ( + `visits_id` int(11) unsigned NOT NULL AUTO_INCREMENT, + `myid` varchar(32) NOT NULL DEFAULT '', + `src` varchar(64) NOT NULL DEFAULT '', + `ip` int(10) unsigned NOT NULL DEFAULT '0', + `cc` char(2) NOT NULL DEFAULT '', + `org` varchar(80) DEFAULT NULL, + `ref` varchar(255) NOT NULL DEFAULT '', + `time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + `host` varchar(30) NOT NULL DEFAULT '', + `entry` varchar(255) NOT NULL DEFAULT '', + `visit_exit` varchar(255) NOT NULL DEFAULT '', + `user_id` int(11) unsigned NOT NULL DEFAULT '0', + `visit_start` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + PRIMARY KEY (`visits_id`), + KEY `ip` (`ip`), + KEY `time` (`time`), + KEY `user_id` (`user_id`) +) ENGINE=MyISAM AUTO_INCREMENT=21293381 DEFAULT CHARSET=latin1; + +CREATE TABLE `visits_events` ( + `event_id` mediumint(8) unsigned NOT NULL DEFAULT '0', + `visit_id` int(11) unsigned NOT NULL DEFAULT '0', + `timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `src` varchar(64) NOT NULL DEFAULT '', + `data` varchar(255) NOT NULL DEFAULT '', + `visits_events_id` int(11) unsigned NOT NULL AUTO_INCREMENT, + PRIMARY KEY (`visits_events_id`), + KEY `event_id` (`event_id`), + KEY `visit_id` (`visit_id`), + KEY `data` (`data`) +) ENGINE=MyISAM AUTO_INCREMENT=33900731 DEFAULT CHARSET=latin1; + +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/; +/*!40019 SET @@session.max_insert_delayed_threads=0*/; +/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; +--delimiter /*!*/; + +# at 4 (0x4) +#071204 14:29:31 server id 1 end_log_pos 106 +# Position Timestamp Type Master ID Size Master Pos Flags +# 4 3b 56 55 47 0f 01 00 00 00 66 00 00 00 6a 00 00 00 00 00 +# 17 04 00 35 2e 31 2e 32 33 2d 72 63 2d 64 65 62 75 |..5.1.23.rc.debu| +# 27 67 2d 6c 6f 67 00 00 00 00 00 00 00 00 00 00 00 |g.log...........| +# 37 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +# 47 00 00 00 00 3b 56 55 47 13 38 0d 00 08 00 12 00 |.....VUG.8......| +# 57 04 04 04 04 12 00 00 53 00 04 1a 08 00 00 00 08 |.......S........| +# 67 08 08 02 |...| +# Start: binlog v 4, server v 5.1.23-rc-debug-log created 071204 14:29:31 at startup + +BINLOG ' +O1ZVRw8BAAAAZgAAAGoAAAAAAAQANS4xLjIzLXJjLWRlYnVnLWxvZwAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAA7VlVHEzgNAAgAEgAEBAQEEgAAUwAEGggAAAAICAgC +'/*!*/; + +# at 164170623 +# at 164170679 +#7918 3:59:2 server id 436 end_log_pos 164170679 +# 9c90b7f 06 4d ef 46 13 b4 01 00 00 38 00 00 00 b7 0b c9 |.M.F.....8......| +# 9c90b8f 09 00 00 99 57 17 02 00 00 00 00 05 74 72 61 63 |....W.......trac| +# 9c90b9f 6b 00 0d 76 69 |k..vi| +# Table_map: `track`.`visits_events` mapped to number 35084185 +#7918 3:59:2 server id 436 end_log_pos 164170769 +# 9c90bb7 06 4d ef 46 17 b4 01 00 00 5a 00 00 00 11 0c c9 |.M.F.....Z......| +# 9c90bc7 09 10 00 99 57 17 02 00 00 01 00 06 ff c0 20 4e |....W..........N| +# 9c90bd7 00 be f5 43 01 06 4d ef 46 00 2b 44 6f 77 6e 6c |...C..M.F..Downl| +# 9c90be7 6f 61 64 73 2f 4d 79 53 51 4c 2d 34 2e 31 2f 6d |oads.MySQL.4.1.m| +# 9c90bf7 79 73 71 6c 2d 34 2e |ysql.4.| +# Write_rows: table id 35084185 flags: STMT_END_F + +BINLOG ' +Bk3vRhO0AQAAOAAAALcLyQkAAJlXFwIAAAAABXRyYWNrAA12aXNpdHNfZXZlbnRzAAYJAwcPDwM= +Bk3vRhe0AQAAWgAAABEMyQkQAJlXFwIAAAEABv/AIE4AvvVDAQZN70YAK0Rvd25sb2Fkcy9NeVNR +TC00LjEvbXlzcWwtNC4xLjEyYS13aW4zMi56aXBPaAIC +'/*!*/; +# at 164170769 +#7918 3:59:2 server id 436 end_log_pos 164170797 +# 9c90c11 06 4d ef 46 05 b4 01 00 00 |.M.F.....| +# Intvar +SET INSERT_ID=21231039/*!*/; +# at 164170797 +#7918 3:59:2 server id 436 end_log_pos 164171293 +# 9c90c2d 06 4d ef 46 02 b4 01 00 00 f0 01 00 00 1d 0e c9 |.M.F............| +# 9c90c3d 09 10 00 28 80 af 01 00 00 00 00 05 00 00 1f 00 |................| +# 9c90c4d 00 00 40 00 00 01 00 00 00 00 00 00 00 00 06 03 |................| +# 9c90c5d 73 74 64 04 08 00 08 00 08 00 05 03 55 54 43 74 |std.........UTCt| +# 9c90c6d 72 61 63 6b 00 49 4e 53 45 52 54 20 49 4e 54 4f |rack.INSERT.INTO| +# 9c90c7d 20 76 69 73 69 74 73 20 28 6d 79 69 64 2c 20 75 |.visits..myid..u| +# 9c90c8d 73 65 72 5f 69 64 2c 20 73 72 63 2c 20 69 70 2c |ser.id..src..ip.| +# 9c90c9d 20 63 63 2c 20 6f 72 67 2c 20 72 65 66 2c 20 74 |.cc..org..ref..t| +# 9c90cad 69 6d 65 2c 20 68 6f 73 74 2c 20 65 6e 74 72 79 |ime..host..entry| +# 9c90cbd 2c 20 76 69 73 69 74 5f 65 78 69 74 2c 20 76 69 |..visit.exit..vi| +# 9c90ccd 73 69 74 5f 73 74 61 72 74 29 0a 09 09 09 56 41 |sit.start.....VA| +# 9c90cdd 4c 55 45 53 20 28 27 33 6d 33 6c 34 72 68 73 36 |LUES...3m3l4rhs6| +# 9c90ced 64 6f 30 73 66 35 70 31 69 39 6c 72 39 34 67 39 |do0sf5p1i9lr94g9| +# 9c90cfd 32 38 61 32 37 32 76 27 2c 20 27 27 2c 20 27 27 |28a272v.........| +# 9c90d0d 2c 20 49 4e 45 54 5f 41 54 4f 4e 28 27 37 31 2e |..INET.ATON..71.| +# 9c90d1d 31 31 38 2e 31 32 34 2e 39 38 27 29 2c 20 27 27 |118.124.98......| +# 9c90d2d 2c 20 27 27 2c 20 27 68 74 74 70 3a 2f 2f 64 65 |.......http...de| +# 9c90d3d 76 2e 6d 79 73 71 6c 2e 63 6f 6d 2f 64 6f 77 6e |v.mysql.com.down| +# 9c90d4d 6c 6f 61 64 73 2f 63 6f 6e 6e 65 63 74 6f 72 2f |loads.connector.| +# 9c90d5d 6a 2f 33 2e 30 2e 68 74 6d 6c 27 2c 20 4e 55 4c |j.3.0.html...NUL| +# 9c90d6d 4c 2c 20 27 64 65 76 2e 6d 79 73 71 6c 2e 63 6f |L...dev.mysql.co| +# 9c90d7d 6d 27 2c 20 27 2f 67 65 74 2f 44 6f 77 6e 6c 6f |m.....get.Downlo| +# 9c90d8d 61 64 73 2f 43 6f 6e 6e 65 63 74 6f 72 2d 4a 2f |ads.Connector.J.| +# 9c90d9d 6d 79 73 71 6c 2d 63 6f 6e 6e 65 63 74 6f 72 2d |mysql.connector.| +# 9c90dad 6a 61 76 61 2d 33 2e 30 2e 31 37 2d 67 61 2e 7a |java.3.0.17.ga.z| +# 9c90dbd 69 70 2f 66 72 6f 6d 2f 70 69 63 6b 27 2c 20 27 |ip.from.pick....| +# 9c90dcd 2f 67 65 74 2f 44 6f 77 6e 6c 6f 61 64 73 2f 43 |.get.Downloads.C| +# 9c90ddd 6f 6e 6e 65 63 74 6f 72 2d 4a 2f 6d 79 73 71 6c |onnector.J.mysql| +# 9c90ded 2d 63 6f 6e 6e 65 63 74 6f 72 2d 6a 61 76 61 2d |.connector.java.| +# 9c90dfd 33 2e 30 2e 31 37 2d 67 61 2e 7a 69 70 |3.0.17.ga.zip| +# Query thread_id=28278824 exec_time=0 error_code=0 +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/; +use track/*!*/; +SET TIMESTAMP=1190087942/*!*/; +SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1/*!*/; +SET @@session.sql_mode=0/*!*/; +SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/; +SET @@session.time_zone='UTC'/*!*/; +INSERT INTO visits (myid, user_id, src, ip, cc, org, ref, time, host, entry, visit_exit, visit_start) +VALUES ('3m3l4rhs6do0sf5p1i9lr94g928a272v', '', '', INET_ATON('71.118.124.98'), '', '', 'http://dev.mysql.com/downloads/connector/j/3.0.html', NULL, 'dev.mysql.com', '/get/Downloads/Connector-J/mysql-connector-java-3.0.17-ga.zip/from/pick', '/get/Downloads/Connector-J/mysql-connector-java-3.0.17-ga.zip/from/pick', NOW())/*!*/; +# at 164171293 + +--delimiter ; + +SELECT * FROM visits; +SELECT * FROM visits_events; + +SET GLOBAL SLAVE_TYPE_CONVERSIONS = @saved_slave_type_conversions; + +# Cleanup +DROP DATABASE track; +sync_slave_with_master; + +--echo End of 5.1 tests +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_bug33931.test b/mysql-test/suite/rpl/t/rpl_bug33931.test new file mode 100644 index 00000000..0b2cbb63 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_bug33931.test @@ -0,0 +1,49 @@ +# Test for +# Bug #33931 assertion at write_ignored_events_info_to_relay_log if init_slave_thread() fails +# Bug #33932 assertion at handle_slave_sql if init_slave_thread() fails + +source include/have_debug.inc; +source include/master-slave.inc; + +connection slave; + +# Add suppression for expected warnings in slaves error log +call mtr.add_suppression("Failed during slave I/O thread initialization"); +call mtr.add_suppression("Slave SQL.*Failed during slave thread initialization.* 1593"); + +--source include/stop_slave.inc +reset slave; + +# Set debug flags on slave to force errors to occur +SET @saved_dbug = @@GLOBAL.debug_dbug; +SET GLOBAL debug_dbug="d,simulate_io_slave_error_on_init,simulate_sql_slave_error_on_init"; + +--disable_query_log +eval CHANGE MASTER TO MASTER_USER='root', + MASTER_CONNECT_RETRY=1, + MASTER_HOST='127.0.0.1', + MASTER_PORT=$MASTER_MYPORT; +--enable_query_log + +start slave; + +# +# slave is going to stop because of emulated failures +# but there won't be any crashes nor asserts hit. +# + +# 1593 = ER_SLAVE_FATAL_ERROR +--let $slave_sql_errno= 1593 +--let $show_slave_sql_error= 1 +--source include/wait_for_slave_sql_error.inc + +# +# Cleanup +# +SET @@GLOBAL.debug_dbug = @saved_dbug; + +# Clear Last_SQL_Error +RESET SLAVE; + +--let $rpl_only_running_threads= 1 +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_bug37426.test b/mysql-test/suite/rpl/t/rpl_bug37426.test new file mode 100644 index 00000000..18e80a5f --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_bug37426.test @@ -0,0 +1,22 @@ +############################################################# +# Purpose: Test for BUG#37426 +# RBR breaks for CHAR() UTF8 fields > 85 chars +############################################################# + +source include/have_binlog_format_row.inc; +source include/master-slave.inc; + +connection master; +CREATE TABLE char128_utf8 (i1 INT NOT NULL, c CHAR(128) CHARACTER SET utf8 NOT NULL, i2 INT NOT NULL); +INSERT INTO char128_utf8 VALUES ( 1, "123", 1 ); + +SELECT * FROM char128_utf8; +sync_slave_with_master; + +SELECT * FROM char128_utf8; + +# Clean up +connection master; +DROP TABLE char128_utf8; +sync_slave_with_master; +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_bug38694-slave.opt b/mysql-test/suite/rpl/t/rpl_bug38694-slave.opt new file mode 100644 index 00000000..b457a7eb --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_bug38694-slave.opt @@ -0,0 +1 @@ +--loose-debug-dbug=d,simulate_slave_delay_at_terminate_bug38694 diff --git a/mysql-test/suite/rpl/t/rpl_bug38694.test b/mysql-test/suite/rpl/t/rpl_bug38694.test new file mode 100644 index 00000000..57d7dde0 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_bug38694.test @@ -0,0 +1,13 @@ +# Testing replication threads stopping concurrency issue +# at the server shutdown +# Related bugs: bug#38694, bug#29968, bug#25306 +# The test checks if a delay at the termination phase of slave threads +# DBUG_EXECUTE_IF("simulate_slave_delay_at_terminate_bug38694", sleep(5);); +# could cause any issue. + +source include/master-slave.inc; + +call mtr.add_suppression("Aborted connection"); + +# End of tests +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_bug41902.test b/mysql-test/suite/rpl/t/rpl_bug41902.test new file mode 100644 index 00000000..bb6c5725 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_bug41902.test @@ -0,0 +1,67 @@ +# Test for Bug #41902 MYSQL_BIN_LOG::reset_logs() doesn't call my_error() +# in face of an error +# + +source include/have_debug.inc; +source include/master-slave.inc; + +# +# test checks that +# a. there is no crash when find_log_pos() returns with an error +# that tests expect to receive; +# b. in the case of multiple error messages the first error message is +# reported to the user and others are available as warnings. +# + +connection slave; +stop slave; +SET @saved_dbug = @@GLOBAL.debug_dbug; +SET @@debug_dbug="d,simulate_find_log_pos_error"; + +--error ER_UNKNOWN_TARGET_BINLOG +reset slave; +show warnings; + +SET @@debug_dbug=""; +reset slave; +change master to master_host='dummy'; + +SET @@debug_dbug="d,simulate_find_log_pos_error"; + +--error ER_UNKNOWN_TARGET_BINLOG +change master to master_host='dummy'; + +SET @@debug_dbug=""; +reset slave; +change master to master_host='dummy'; + +connection master; +SET @saved_dbug_m = @@global.debug_dbug; +SET @@debug_dbug="d,simulate_find_log_pos_error"; +--error ER_UNKNOWN_TARGET_BINLOG +reset master; + +SET @@debug_dbug=""; +reset master; + +SET @@debug_dbug="d,simulate_find_log_pos_error"; +--error ER_UNKNOWN_TARGET_BINLOG +purge binary logs to 'master-bin.000001'; + +SET @@debug_dbug=""; +purge binary logs to 'master-bin.000001'; + +--disable_query_log +call mtr.add_suppression("Failed to locate old binlog or relay log files"); +call mtr.add_suppression("MYSQL_BIN_LOG::purge_logs was called with file ..master-bin.000001 not listed in the index"); +set @@global.debug_dbug = @saved_dbug_m; +connection slave; +call mtr.add_suppression("Failed to locate old binlog or relay log files"); +call mtr.add_suppression("MYSQL_BIN_LOG::purge_logs was called with file ..master-bin.000001 not listed in the index"); +--enable_query_log +SET @@GLOBAL.debug_dbug = @saved_dbug; + +--echo ==== clean up ==== +CHANGE MASTER TO MASTER_HOST = '127.0.0.1'; +--let $rpl_only_running_threads= 1 +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_cant_read_event_incident.test b/mysql-test/suite/rpl/t/rpl_cant_read_event_incident.test new file mode 100644 index 00000000..573c1d11 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_cant_read_event_incident.test @@ -0,0 +1 @@ +--source include/rpl_cant_read_event_incident.inc diff --git a/mysql-test/suite/rpl/t/rpl_change_master.test b/mysql-test/suite/rpl/t/rpl_change_master.test new file mode 100644 index 00000000..9ab49a58 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_change_master.test @@ -0,0 +1,111 @@ +# Verify that after CHANGE MASTER, replication (I/O thread and SQL +# thread) restart from where SQL thread left, not from where +# I/O thread left (some old bug fixed in 4.0.17) + +source include/master-slave.inc; +call mtr.add_suppression("Slave I/O: The slave I/O thread stops because a fatal error is encountered when it tried to SET @master_binlog_checksum"); + +connection master; +# Make SQL slave thread advance a bit +create table t1(n int); +sync_slave_with_master; +select * from t1; +# Now stop it and make I/O slave thread be ahead +stop slave sql_thread; +connection master; +insert into t1 values(1); +insert into t1 values(2); +save_master_pos; +let $slave_param= Read_Master_Log_Pos; +let $slave_param_value= query_get_value(SHOW MASTER STATUS, Position, 1); +connection slave; +source include/wait_for_slave_param.inc; +source include/stop_slave.inc; + +let $read_pos= query_get_value(SHOW SLAVE STATUS, Read_Master_Log_Pos, 1); +let $exec_pos= query_get_value(SHOW SLAVE STATUS, Exec_Master_Log_Pos, 1); +if ($read_pos == $exec_pos) +{ + source include/show_rpl_debug_info.inc; + echo 'Read_Master_Log_Pos: $read_pos' == 'Exec_Master_Log_Pos: $exec_pos'; + die Failed because Read_Master_Log_Pos is equal to Exec_Master_Log_Pos; +} +change master to master_user='root'; +let $read_pos= query_get_value(SHOW SLAVE STATUS, Read_Master_Log_Pos, 1); +let $exec_pos= query_get_value(SHOW SLAVE STATUS, Exec_Master_Log_Pos, 1); +if ($read_pos != $exec_pos) +{ + source include/show_rpl_debug_info.inc; + echo 'Read_Master_Log_Pos: $read_pos' <> 'Exec_Master_Log_Pos: $exec_pos'; + die Failed because Read_Master_Log_Pos is not equal to Exec_Master_Log_Pos; +} + +start slave; +sync_with_master; +select * from t1; +connection master; +drop table t1; +sync_slave_with_master; + +# End of 4.1 tests + +# +# BUG#12190 CHANGE MASTER has differ path requiremts on MASTER_LOG_FILE and RELAY_LOG_FILE +# + +if ($bug_59037_is_fixed == 'true') { +--source include/rpl_reset.inc + +connection master; +create table t1 (a int); +insert into t1 values (1); +flush logs; +insert into t1 values (2); + +# Note: the master positon saved by this will also be used by the +# 'sync_with_master' below. +sync_slave_with_master; + +# Check if the table t1 and t2 are identical on master and slave; +let $diff_tables= master:t1,slave:t1 +source include/diff_tables.inc; + +connection slave; +source include/stop_slave.inc; +delete from t1 where a=2; + +# start replication from the second insert, after fix of BUG#12190, +# relay_log_file does not use absolute path, only the filename is +# required +# +# Note: the follow change master will automatically reset +# relay_log_purge to false, save the old value to restore +let $relay_log_purge= `select @@global.relay_log_purge`; +CHANGE MASTER TO relay_log_file='slave-relay-bin.000005', relay_log_pos=4; +start slave sql_thread; +source include/wait_for_slave_sql_to_start.inc; + +# Sync to the same position saved by the 'sync_slave_with_master' above. +sync_with_master; + +# Check if the table t1 and t2 are identical on master and slave; +let $diff_tables= master:t1,slave:t1 +source include/diff_tables.inc; + +# clean up +connection slave; +start slave io_thread; +source include/wait_for_slave_io_to_start.inc; +eval set global relay_log_purge=$relay_log_purge; +connection master; +drop table t1; +} + +--connection master +# MDEV-22741: *SAN: ERROR: AddressSanitizer: use-after-poison on address in +# instrings/strmake.c:36 from change_master (on optimized builds) +CHANGE MASTER TO MASTER_USER='root', MASTER_SSL=0, MASTER_SSL_CA='', MASTER_SSL_CERT='', + MASTER_SSL_KEY='', MASTER_SSL_CRL='', MASTER_SSL_CRLPATH=''; +CHANGE MASTER TO MASTER_USER='root', MASTER_PASSWORD='', MASTER_SSL=0; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_charset.test b/mysql-test/suite/rpl/t/rpl_charset.test new file mode 100644 index 00000000..31ea2bc8 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_charset.test @@ -0,0 +1,2 @@ +let $engine_type=myisam; +source include/rpl_charset.test; diff --git a/mysql-test/suite/rpl/t/rpl_charset_sjis.test b/mysql-test/suite/rpl/t/rpl_charset_sjis.test new file mode 100644 index 00000000..af4e8ff5 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_charset_sjis.test @@ -0,0 +1,54 @@ +source include/have_sjis.inc; +source include/master-slave.inc; + +--disable_warnings +drop table if exists t1; +drop procedure if exists p1; +--enable_warnings +create table t1 (a varchar(255) character set sjis); +create procedure p1 (in a varchar(255) character set sjis) insert into t1 values (a); + +SET NAMES binary; +CALL p1 ('–\\'); +select hex(a) from t1 ; +sync_slave_with_master; +connection slave; +select hex(a) from t1; +connection master; +drop table t1; +drop procedure p1; +sync_slave_with_master; +connection master; + +# End of 5.0 tests + +--echo # +--echo # Start of 5.5 tests +--echo # + +--echo # +--echo # Bug#MDEV-4489 Replication of big5, cp932, gbk, sjis strings makes wrong values on slave +--echo # + +connection master; +SET NAMES sjis; +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (0x31),(X'31'),('1'); +PREPARE stmt FROM 'INSERT INTO t1 (a) VALUES (?)'; +SET @a='1'; +EXECUTE stmt USING @a; +DROP PREPARE stmt; +SELECT * FROM t1; +sync_slave_with_master; +connection slave; +SELECT * FROM t1; +connection master; +DROP TABLE t1; +sync_slave_with_master; +connection master; + +--echo # +--echo # End of 5.5 tests +--echo # + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_checksum-master.opt b/mysql-test/suite/rpl/t/rpl_checksum-master.opt new file mode 100644 index 00000000..a6e99a9f --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_checksum-master.opt @@ -0,0 +1 @@ +--binlog-checksum=CRC32 diff --git a/mysql-test/suite/rpl/t/rpl_checksum.test b/mysql-test/suite/rpl/t/rpl_checksum.test new file mode 100644 index 00000000..0edf8fda --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_checksum.test @@ -0,0 +1 @@ +--source include/rpl_checksum.inc diff --git a/mysql-test/suite/rpl/t/rpl_checksum_cache.test b/mysql-test/suite/rpl/t/rpl_checksum_cache.test new file mode 100644 index 00000000..59b338d2 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_checksum_cache.test @@ -0,0 +1 @@ +--source include/rpl_checksum_cache.inc diff --git a/mysql-test/suite/rpl/t/rpl_circular_for_4_hosts.cnf b/mysql-test/suite/rpl/t/rpl_circular_for_4_hosts.cnf new file mode 100644 index 00000000..3ff94e45 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_circular_for_4_hosts.cnf @@ -0,0 +1,24 @@ +!include ../my.cnf + +[mysqld.1] +log-slave-updates +loose-innodb + +[mysqld.2] +log-slave-updates +loose-innodb + +[mysqld.3] +log-slave-updates +loose-innodb + +[mysqld.4] +log-slave-updates +loose-innodb + +[ENV] +SERVER_MYPORT_3= @mysqld.3.port +SERVER_MYSOCK_3= @mysqld.3.socket + +SERVER_MYPORT_4= @mysqld.4.port +SERVER_MYSOCK_4= @mysqld.4.socket diff --git a/mysql-test/suite/rpl/t/rpl_circular_for_4_hosts.test b/mysql-test/suite/rpl/t/rpl_circular_for_4_hosts.test new file mode 100644 index 00000000..8d610a87 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_circular_for_4_hosts.test @@ -0,0 +1,336 @@ +# ==== Purpose ==== +# +# Setup: circular replication on four hosts, i.e., topology +# server_1 -> server_2 -> server_3 -> server_4 -> server_1 +# +# Tested properties: +# - Correctly configured autoinc works. +# - Manual failover works. +# +# ==== Related bugs and worklogs ==== +# +# WL#3754 +# BUG#49978 + +--source include/have_innodb.inc + +# Use wait_for_slave_to_(start|stop) for current connections +let $keep_connection= 1; + +# Set up circular ring and new names for servers +--echo *** Set up circular replication on four servers *** +--let $rpl_topology= 1->2->3->4->1 +--source include/rpl_init.inc +--echo + +#set auto inc variables at each server +--let $_rpl_server= $rpl_server_count +while ($_rpl_server) +{ + connection server_$_rpl_server; + eval SET auto_increment_increment= $rpl_server_count; + eval SET auto_increment_offset= $_rpl_server; + + --dec $_rpl_server +} + +# Preparing data. +--echo *** Preparing data *** +--connection server_1 +CREATE TABLE t1 (a INT NOT NULL AUTO_INCREMENT, b VARCHAR(100), c INT NOT NULL, PRIMARY KEY(a)) ENGINE=MyISAM; +CREATE TABLE t2 (a INT NOT NULL AUTO_INCREMENT, b VARCHAR(100), c INT NOT NULL, PRIMARY KEY(a)) ENGINE=InnoDB; +--source include/rpl_sync.inc +--connection server_4 +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"); +--echo + +# +# Testing +# + +--echo *** Testing schema A->B->C->D->A *** +--echo +# insert data via all hosts +--connection server_1 +INSERT INTO t1(b,c) VALUES('A',1); +--sync_slave_with_master server_2 +INSERT INTO t1(b,c) VALUES('B',1); +--sync_slave_with_master server_3 +INSERT INTO t1(b,c) VALUES('C',1); +--sync_slave_with_master server_4 +INSERT INTO t1(b,c) VALUES('D',1); + +--source include/rpl_sync.inc + +--connection server_1 +SELECT 'Master A',a,b FROM t1 WHERE c = 1 ORDER BY a,b; +--connection server_2 +SELECT 'Master B',a,b FROM t1 WHERE c = 1 ORDER BY a,b; +--connection server_3 +SELECT 'Master C',a,b FROM t1 WHERE c = 1 ORDER BY a,b; +--connection server_4 +SELECT 'Master D',a,b FROM t1 WHERE c = 1 ORDER BY a,b; +--echo + +--echo *** Testing schema A->B->D->A if C has failure *** +--echo +--echo * Do failure for C and then make new connection B->D * + +# Note: server_N has auto_increment_offset=N. Below, we insert value 6 +# in the autoinc column on server_3 (and prevent it from replicating +# further using SQL_SLAVE_SKIP_COUNTER on server_4). Due to the +# auto_increment_offset setting, the autoinc value 6 is normally +# generated on server_2. When we later insert a row on server_2, we +# thus cause a duplicate key error on server_3. + +# Do not replicate next event from C +--connection server_4 +STOP SLAVE; +SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1; +source include/start_slave.inc; +--connection server_3 +INSERT INTO t1 VALUES(6,'C',2); +--sync_slave_with_master server_4 + +--connection server_2 +INSERT INTO t1(b,c) VALUES('B',2); +# Wait while C will stop. +--connection server_3 +# 1062 = ER_DUP_ENTRY +call mtr.add_suppression("Slave SQL.*Duplicate entry .6. for key .PRIMARY.* error.* 1062"); +--let $slave_sql_errno= 1062 +--source include/wait_for_slave_sql_error.inc +--connection server_1 +INSERT INTO t1(b,c) VALUES('A',2); +--connection server_4 +INSERT INTO t1(b,c) VALUES('D',2); + + +# Sync all servers except C +--connection server_2 +let $wait_condition= SELECT COUNT(*)=3 FROM t1 WHERE a > 4; +--let $server_connection= server_1 +--source include/wait_condition.inc + +--echo +--echo * Data on servers (C failed) * +# Masters C,D shouldn't have correct data +--connection server_1 +SELECT 'Master A',a,b FROM t1 WHERE c = 2 ORDER BY a,b; +--connection server_2 +SELECT 'Master B',a,b FROM t1 WHERE c = 2 ORDER BY a,b; +--connection server_3 +SELECT 'Master C',a,b FROM t1 WHERE c = 2 ORDER BY a,b; +--connection server_4 +SELECT 'Master D',a,b FROM t1 WHERE c = 2 ORDER BY a,b; +--echo + +--echo * Reconfigure replication to schema A->B->D->A * +# Exclude Master C +--connection server_3 +--source include/stop_slave_io.inc +--let $pos_c= query_get_value(SHOW SLAVE STATUS, Exec_Master_Log_Pos, 1) +--let $file_c= query_get_value(SHOW SLAVE STATUS, Master_Log_File, 1) + +--connection server_4 +--source include/stop_slave.inc + +--let $rpl_topology= 1->2->4->1,2->3 +--let $rpl_master_log_file= 4:$file_c +--let $rpl_master_log_pos= 4:$pos_c +--source include/rpl_change_topology.inc + +#--replace_result $SERVER_MYPORT_2 SERVER_MYPORT_2 $file_c LOG_FILE $pos_c LOG_POS +#--eval CHANGE MASTER TO master_host='127.0.0.1',master_port=$SERVER_MYPORT_2,master_user='root',master_log_file='$file_c',master_log_pos=$pos_c +source include/start_slave.inc; +--connection server_2 +--sync_slave_with_master server_4 +--sync_slave_with_master server_1 +--echo + +--echo * Check data inserted before failure * +--connection server_1 +SELECT 'Master A',a,b FROM t1 WHERE c = 2 ORDER BY a,b; +--connection server_2 +SELECT 'Master B',a,b FROM t1 WHERE c = 2 ORDER BY a,b; +--connection server_3 +SELECT 'Master C',a,b FROM t1 WHERE c = 2 ORDER BY a,b; +--connection server_4 +SELECT 'Master D',a,b FROM t1 WHERE c = 2 ORDER BY a,b; +--echo + +--echo * Check data inserted after failure * +--connection server_1 +INSERT INTO t1(b,c) VALUES('A',3); +--connection server_2 +INSERT INTO t1(b,c) VALUES('B',3); +--connection server_4 +INSERT INTO t1(b,c) VALUES('D',3); +connection server_1; + +--let $rpl_only_running_threads= 1 +--source include/rpl_sync.inc + +--connection server_1 +SELECT 'Master A',a,b FROM t1 WHERE c = 3 ORDER BY a,b; +--connection server_2 +SELECT 'Master B',a,b FROM t1 WHERE c = 3 ORDER BY a,b; +--connection server_3 +SELECT 'Master C',a,b FROM t1 WHERE c = 3 ORDER BY a,b; +--connection server_4 +SELECT 'Master D',a,b FROM t1 WHERE c = 3 ORDER BY a,b; +--connection server_1 +--echo + +--echo *** Testing restoring scheme A->B->C->D->A after failure *** +--echo +# Master D will ignore a next event from C so that event will not be +# distributed to other servers +--echo * Remove wrong event from C and restore B->C->D * +--connection server_4 +source include/stop_slave.inc; +--connection server_3 +DELETE FROM t1 WHERE a = 6; +--source include/start_slave.inc +--connection server_2 +--sync_slave_with_master server_3 +RESET MASTER; +--let $file_d= query_get_value(SHOW MASTER STATUS, File, 1) +--let $pos_d= query_get_value(SHOW MASTER STATUS, Position, 1) +--connection server_4 +RESET SLAVE; +--let $rpl_topology= 1->2->3->4->1 +--let $rpl_master_log_file= 4:$file_d +--let $rpl_master_log_pos= 4:$pos_d +--source include/rpl_change_topology.inc +#--replace_result $SERVER_MYPORT_3 SERVER_MYPORT_3 $file_d LOG_FILE $pos_d LOG_POS +#--eval CHANGE MASTER TO master_host='127.0.0.1',master_port=$SERVER_MYPORT_3,master_user='root',master_log_file='$file_d',master_log_pos=$pos_d +--source include/start_slave.inc +--connection server_3 +--sync_slave_with_master server_4 +--source include/rpl_sync.inc + +--echo +--echo * Check data inserted before restoring schema A->B->C->D->A * +--connection server_1 +SELECT 'Master A',a,b FROM t1 WHERE c IN (2,3) ORDER BY a,b; +--sync_slave_with_master server_2 +SELECT 'Master B',a,b FROM t1 WHERE c IN (2,3) ORDER BY a,b; +--sync_slave_with_master server_3 +SELECT 'Master C',a,b FROM t1 WHERE c IN (2,3) ORDER BY a,b; +--sync_slave_with_master server_4 +SELECT 'Master D',a,b FROM t1 WHERE c IN (2,3) ORDER BY a,b; +--sync_slave_with_master server_1 +--echo + +--echo * Check data inserted after restoring schema A->B->C->D->A * +--connection server_1 +INSERT INTO t1(b,c) VALUES('A',4); +--connection server_2 +INSERT INTO t1(b,c) VALUES('B',4); +--connection server_3 +INSERT INTO t1(b,c) VALUES('C',4); +--connection server_4 +INSERT INTO t1(b,c) VALUES('D',4); +--connection server_1 + +--source include/rpl_sync.inc + +--connection server_1 +SELECT 'Master A',a,b FROM t1 WHERE c = 4 ORDER BY a,b; +--connection server_2 +SELECT 'Master B',a,b FROM t1 WHERE c = 4 ORDER BY a,b; +--connection server_3 +SELECT 'Master C',a,b FROM t1 WHERE c = 4 ORDER BY a,b; +--connection server_4 +SELECT 'Master D',a,b FROM t1 WHERE c = 4 ORDER BY a,b; +--connection server_1 +--echo + +--echo * Transactions with commits * +# Testing mixing of transactions and regular inserts +--connection server_1 +BEGIN; +--connection server_3 +BEGIN; +let $counter= 100; +--connection server_1 +--disable_query_log +while ($counter) { + --connection server_1 + INSERT INTO t2(b,c) VALUES('A',1); + --connection server_2 + INSERT INTO t2(b,c) VALUES('B',1); + --connection server_3 + INSERT INTO t2(b,c) VALUES('C',1); + --connection server_4 + INSERT INTO t2(b,c) VALUES('D',1); + dec $counter; +} +--connection server_1 +COMMIT; +--connection server_3 +COMMIT; +--connection server_1 +--enable_query_log + +--source include/rpl_sync.inc + +--connection server_1 +SELECT 'Master A',b,COUNT(*) FROM t2 WHERE c = 1 GROUP BY b ORDER BY b; +--connection server_2 +SELECT 'Master B',b,COUNT(*) FROM t2 WHERE c = 1 GROUP BY b ORDER BY b; +--connection server_3 +SELECT 'Master C',b,COUNT(*) FROM t2 WHERE c = 1 GROUP BY b ORDER BY b; +--connection server_4 +SELECT 'Master D',b,COUNT(*) FROM t2 WHERE c = 1 GROUP BY b ORDER BY b; +--connection server_1 +--echo + +--echo * Transactions with rollbacks * +# Testing mixing of transactions with rollback and regular inserts +--connection server_1 +BEGIN; +--connection server_3 +BEGIN; +let $counter= 100; +--connection server_1 +--disable_query_log +while ($counter) { + --connection server_1 + INSERT INTO t2(b,c) VALUES('A',2); + --connection server_2 + INSERT INTO t2(b,c) VALUES('B',2); + --connection server_3 + INSERT INTO t2(b,c) VALUES('C',2); + --connection server_4 + INSERT INTO t2(b,c) VALUES('D',2); + dec $counter; +} +--connection server_1 +ROLLBACK; +--connection server_3 +ROLLBACK; +--connection server_1 +--enable_query_log + +--source include/rpl_sync.inc + +--connection server_1 +SELECT 'Master A',b,COUNT(*) FROM t2 WHERE c = 2 GROUP BY b ORDER BY b; +--connection server_2 +SELECT 'Master B',b,COUNT(*) FROM t2 WHERE c = 2 GROUP BY b ORDER BY b; +--connection server_3 +SELECT 'Master C',b,COUNT(*) FROM t2 WHERE c = 2 GROUP BY b ORDER BY b; +--connection server_4 +SELECT 'Master D',b,COUNT(*) FROM t2 WHERE c = 2 GROUP BY b ORDER BY b; +--connection server_1 + +--echo + +# Clean up +--echo *** Clean up *** +--connection server_1 +DROP TABLE t1,t2; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_colSize.test b/mysql-test/suite/rpl/t/rpl_colSize.test new file mode 100644 index 00000000..d6f817af --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_colSize.test @@ -0,0 +1,228 @@ +################################################################## +# rpl_colSize # +# # +# This test is designed to test the changes included in WL#3228. # +# The changes include the ability to replicate with the master # +# having columns that are smaller (shorter) than the slave. # +################################################################## + +-- source include/master-slave.inc + +--disable_warnings +DROP TABLE IF EXISTS t1; +--enable_warnings + +--echo **** Testing WL#3228 changes. **** +--echo *** Create "wider" table on slave *** +sync_slave_with_master; +STOP SLAVE; +--source include/wait_for_slave_to_stop.inc +RESET SLAVE; + +SET @saved_slave_type_conversions = @@slave_type_conversions; +SET GLOBAL SLAVE_TYPE_CONVERSIONS = 'ALL_NON_LOSSY'; + +eval CREATE TABLE t1 ( + a float (47), + b double (143,9), + c decimal (65,30), + d numeric (4,0), + e bit (32), + f char (21), + g varchar (1300), + h binary (33), + j varbinary (200), + k enum ('5','6','7', '8','9','0'), + l set ('1','2','3','4','5','6','7','8','9','0','11','12','13','14','15','16','17','18','19','21','22','23','24','25','26','27','28','29'), + m TINYBLOB, + n BLOB, + o MEDIUMBLOB, + p LONGBLOB, + q TINYTEXT, + r TEXT, + s MEDIUMTEXT, + t LONGTEXT +); + +--echo *** Create same table on master but with narrow columns *** +connection master; +eval CREATE TABLE t1 ( + a float (44), + b double (10,3), + c decimal (10,2), + d numeric (3,0), + e bit (16), + f char (10), + g varchar (100), + h binary (20), + j varbinary (20), + k enum ('5','6','7'), + l set ('1','2','3','4','5','6','7','8','9','0'), + m TINYBLOB, + n BLOB, + o MEDIUMBLOB, + p LONGBLOB, + q TINYTEXT, + r TEXT, + s MEDIUMTEXT, + t LONGTEXT +); + +RESET MASTER; + +--echo *** Start replication *** +connection slave; +START SLAVE; +--source include/wait_for_slave_to_start.inc + +--echo *** Insert data on master and display it. *** +connection master; + +INSERT INTO t1 () VALUES ( + 17.567, + 2.123, + 10.20, + 125, + hex(64), + 'TEST', + 'This is a test', + 'binary data', + 'more binary data', + '6', + '7', + "blob 1", + "blob 2", + "blob 3", + "blob 4", + "text 1", + "text 2", + "text 3", + "text 4"); + +# Replace values in columns that display differently between SBR & RBR +--replace_column 5 # 8 # +SELECT * FROM t1 ORDER BY a; + +--echo *** Select data from slave to compare *** +sync_slave_with_master; +connection slave; + +# Replace values in columns that display differently between SBR & RBR +--replace_column 5 # 8 # +SELECT * FROM t1 ORDER BY a; + +# Test boundary limits of varchar and char fields +# Master/Slave +# <256/<256 with m < s, m > s, and m == s <-- col a +# >255/<256 with m < s, m > s, and m == s <-- error will be caught in BUG#22086 +# <256/>255 with m < s, m > s, and m == s <-- col b +# >255/>255 with m < s, m > s, and m == s <-- col c +# +# Test boundary limits of CHAR fields +# Master/Slave +# <256/<256 with m < s, m > s, and m == s <-- col d +# >255/<256 with m < s, m > s, and m == s <-- error char limited to 255 chars +# <256/>255 with m < s, m > s, and m == s <-- error char limited to 255 chars +# >255/>255 with m < s, m > s, and m == s <-- error char limited to 255 chars + +connection master; +DROP TABLE t1; + +--echo Create varchar table on master +CREATE TABLE t1 ( + a VARCHAR(50), + b VARCHAR(100), + c VARCHAR(300), + d CHAR(5) +); + +sync_slave_with_master slave; + +--echo Alter varchar table on slave +ALTER TABLE t1 CHANGE COLUMN a a VARCHAR(100); +ALTER TABLE t1 CHANGE COLUMN b b VARCHAR(400); +ALTER TABLE t1 CHANGE COLUMN c c VARCHAR(500); +ALTER TABLE t1 CHANGE COLUMN d d CHAR(100); + +connection master; + +--echo Insert some values and select them on master +INSERT INTO t1 VALUES ("This is a test of col a.", + "This is another test of col b.", + "This is a test of the large col c.", + "Col d"); +SELECT * FROM t1; +--replace_result default DEFAULT +SHOW CREATE TABLE t1; + +sync_slave_with_master slave; + +--echo Insert some values and select them on slave +SELECT * FROM t1; +--replace_result default DEFAULT +SHOW CREATE TABLE t1; + + +# Test boundary limits of bit fields +# m < s, m % 8 != 0, and s % 8 == 0 col a +# m < s, m % 8 == 0, and s % 8 != 0 col b +# m < s, m % 8 != 0, and s % 8 != 0 col c +# m > s, m % 8 != 0, and s % 8 == 0 <-- error will be caught in BUG#22086 +# m > s, m % 8 == 0, and s % 8 != 0 <-- error will be caught in BUG#22086 +# m > s, m % 8 != 0, and s % 8 != 0 <-- error will be caught in BUG#22086 + +connection master; +DROP TABLE t1; + +--echo Create bit table on master +CREATE TABLE t1 ( + a BIT(7), + b BIT(8), + c BIT(21), + d BIT(11), + e BIT(11) +); + +sync_slave_with_master slave; + +--echo Create bit table on slave +DROP TABLE t1; +CREATE TABLE t1 ( + a BIT(16), + b BIT(22), + c BIT(54), + d BIT(25), + e BIT(13) +); + +connection master; + +--echo Insert some values and select them on master +INSERT INTO t1 VALUES ( + b'1010101', + b'10101011', + b'101010110101010101111', + b'10101010101', + b'10101011111' + ); + +SELECT BIN(a), BIN(b), BIN(c), BIN(d), BIN(e) FROM t1; +--replace_result default DEFAULT +SHOW CREATE TABLE t1; + +sync_slave_with_master slave; + +--echo Insert some values and select them on master +SELECT BIN(a), BIN(b), BIN(c), BIN(d), BIN(e) FROM t1; +--replace_result default DEFAULT +SHOW CREATE TABLE t1; + +--echo *** Cleanup *** +connection master; +DROP TABLE t1; +sync_slave_with_master; + +SET GLOBAL SLAVE_TYPE_CONVERSIONS = @saved_slave_type_conversions; + +# END 5.1 Test Case +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_commit_after_flush.test b/mysql-test/suite/rpl/t/rpl_commit_after_flush.test new file mode 100644 index 00000000..5d547908 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_commit_after_flush.test @@ -0,0 +1,5 @@ +-- source include/have_innodb.inc +-- source include/master-slave.inc +let $engine_type=innodb; +-- source include/rpl_commit_after_flush.test +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_concurrency_error-master.opt b/mysql-test/suite/rpl/t/rpl_concurrency_error-master.opt new file mode 100644 index 00000000..3f82baff --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_concurrency_error-master.opt @@ -0,0 +1 @@ +--loose-innodb-lock-wait-timeout=1 diff --git a/mysql-test/suite/rpl/t/rpl_concurrency_error.test b/mysql-test/suite/rpl/t/rpl_concurrency_error.test new file mode 100644 index 00000000..72179ef2 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_concurrency_error.test @@ -0,0 +1,150 @@ +############################################################################### +#BUG#44581 Slave stops when transaction with non-transactional table gets +#lock wait timeout +# +# In STMT and MIXED modes, a statement that changes both non-transactional and +# transactional tables must be written to the binary log whenever there are +# changes to non-transactional tables. This means that the statement gets into +# the # binary log even when the changes to the transactional tables fail. In +# particular, in the presence of a failure such statement is annotated with the +# error number and wrapped in a begin/rollback. On the slave, while applying +# the statement, it is expected the same failure and the rollback prevents the +# transactional changes to be persisted. + +# This test aims to verify if a statement that updates both transactional and +# non-transacitonal tables and fails due to concurrency problems is correctly +# processed by the slave in the sense that the statements get into the binary +# log, the error is ignored and only the non-transactional tables are changed. +############################################################################### + +--source include/have_innodb.inc +--source include/have_binlog_format_statement.inc +--source include/master-slave.inc + +call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT"); + +--echo ######################################################################## +--echo # Environment +--echo ######################################################################## +connection master; + +CREATE TABLE t (i INT, PRIMARY KEY(i), f CHAR(8)) engine = Innodb; +CREATE TABLE n (d DATETIME, f CHAR(32)) engine = MyIsam; + +DELIMITER |; +CREATE TRIGGER tr AFTER UPDATE ON t FOR EACH ROW +BEGIN + INSERT INTO n VALUES ( now(), concat( 'updated t: ', old.f, ' -> ', new.f ) ); +END | +DELIMITER ;| + +INSERT INTO t VALUES (4,'black'), (2,'red'), (3,'yelow'), (1,'cyan'); + +connect (conn1, 127.0.0.1,root,,); +connect (conn2, 127.0.0.1,root,,); + +--echo ######################################################################## +--echo # Testing ER_LOCK_WAIT_TIMEOUT +--echo ######################################################################## + +let $type=2; + +while ($type) +{ + let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1); + connection conn1; + if ($type == 2) + { + SET AUTOCOMMIT = 1; + BEGIN; + } + if ($type == 1) + { + SET AUTOCOMMIT = 0; + } + eval UPDATE t SET f = 'yellow $type' WHERE i = 3; + + connection conn2; + if ($type == 2) + { + SET AUTOCOMMIT = 1; + BEGIN; + } + if ($type == 1) + { + SET AUTOCOMMIT = 0; + } + --error ER_LOCK_WAIT_TIMEOUT + eval UPDATE IGNORE t SET f = 'magenta $type' WHERE f = 'red'; + eval INSERT INTO t VALUES (5 + ($type * 10),"brown"); + INSERT INTO n VALUES (now(),"brown"); + + connection conn1; + COMMIT; + + connection conn2; + ROLLBACK; + --source include/show_binlog_events.inc + + let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1); + connection conn1; + if ($type == 2) + { + SET AUTOCOMMIT = 1; + BEGIN; + } + if ($type == 1) + { + SET AUTOCOMMIT = 0; + } + eval UPDATE t SET f = 'gray $type' WHERE i = 3; + + connection conn2; + if ($type == 2) + { + SET AUTOCOMMIT = 1; + BEGIN; + } + if ($type == 1) + { + SET AUTOCOMMIT = 0; + } + --error ER_LOCK_WAIT_TIMEOUT + eval UPDATE IGNORE t SET f = 'dark blue $type' WHERE f = 'red'; + eval INSERT INTO t VALUES (6 + ($type * 10),"brown"); + INSERT INTO n VALUES (now(),"brown"); + + connection conn1; + COMMIT; + + connection conn2; + COMMIT; + --source include/show_binlog_events.inc + + dec $type; +} + +connection master; +sync_slave_with_master; + +let $rpl_diff_statement= SELECT * FROM t order by i; +source include/rpl_diff.inc; + +let $rpl_diff_statement= SELECT * FROM n order by d, f; +source include/rpl_diff.inc; + +--echo ######################################################################## +--echo # Cleanup +--echo ######################################################################## + +connection master; +DROP TRIGGER tr; +DROP TABLE t; +DROP TABLE n; + +sync_slave_with_master; + +connection master; +disconnect conn1; +disconnect conn2; +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_conditional_comments.test b/mysql-test/suite/rpl/t/rpl_conditional_comments.test new file mode 100644 index 00000000..6e4ec874 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_conditional_comments.test @@ -0,0 +1,84 @@ +############################################################################### +# After the patch for BUG#49124: +# - Use ' ' instead of '!' in the conditional comments which are not applied on +# master. So they become common comments and will not be applied on slave. +# +# - Example: +# 'INSERT INTO t1 VALUES (1) /*!10000, (2)*/ /*!999999 ,(3)*/ +# will be binlogged as +# 'INSERT INTO t1 VALUES (1) /*!10000, (2)*/ /* 99999 ,(3)*/'. +############################################################################### +source include/have_binlog_format_statement.inc; +source include/master-slave.inc; + +CREATE TABLE t1(c1 INT); +source include/show_binlog_events.inc; +let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1); + +--echo +--echo # Case 1: +--echo # ------------------------------------------------------------------ +--echo # In a statement, some CCs are applied while others are not. The CCs +--echo # which are not applied on master will be binlogged as common comments. + +/*!999999 --- */INSERT /*!INTO*/ /*!10000 t1 */ VALUES(10) /*!999999 ,(11)*/; + +source include/show_binlog_events.inc; +let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1); +sync_slave_with_master; +--let $diff_tables= master:t1,slave:t1 +--source include/diff_tables.inc + +--echo +--echo # Case 2: +--echo # ----------------------------------------------------------------- +--echo # Verify whether it can be binlogged correctly when executing prepared +--echo # statement. +--connection master +PREPARE stmt FROM 'INSERT INTO /*!999999 blabla*/ t1 VALUES(60) /*!999999 ,(61)*/'; +EXECUTE stmt; +DROP TABLE t1; +CREATE TABLE t1(c1 INT); +EXECUTE stmt; + +sync_slave_with_master; +--let $diff_tables= master:t1,slave:t1 +--source include/diff_tables.inc + +--connection master +--echo +SET @value=62; +PREPARE stmt FROM 'INSERT INTO /*!999999 blabla */ t1 VALUES(?) /*!999999 ,(63)*/'; +EXECUTE stmt USING @value; +DROP TABLE t1; +CREATE TABLE t1(c1 INT); +EXECUTE stmt USING @value; + +source include/show_binlog_events.inc; +let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1); + +sync_slave_with_master; +--let $diff_tables= master:t1,slave:t1 +--source include/diff_tables.inc + +--echo +--echo # Case 3: +--echo # ----------------------------------------------------------------- +--echo # Verify it can restore the '!', if the it is an uncomplete conditional +--echo # comments +--connection master +--error 1064 +SELECT c1 FROM /*!999999 t1 WHEREN; #*/ + +# +# Bug#28388217 - SERVER CAN FAIL WHILE REPLICATING CONDITIONAL COMMENTS +# +insert t1 values (/*!50505 1 /* foo */ */ + 2); +insert t1 values (/*!999999 10 /* foo */ */ + 20); +source include/show_binlog_events.inc; +sync_slave_with_master; +select * from t1; +connection master; + +DROP TABLE t1; +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_connection.test b/mysql-test/suite/rpl/t/rpl_connection.test new file mode 100644 index 00000000..31024006 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_connection.test @@ -0,0 +1,24 @@ +--source include/not_embedded.inc +--source include/have_binlog_format_mixed.inc +--source include/master-slave.inc + +# +# BUG#13427949: CHANGE MASTER TO USER='' (EMPTY USER) CAUSES ERRORS ON VALGRING +# + +--connection slave +call mtr.add_suppression(".*Invalid .* username when attempting to connect to the master server.*"); + + +# Assert that we disallow empty users and that no problem +--source include/stop_slave.inc +CHANGE MASTER TO MASTER_USER= '', MASTER_PASSWORD= ''; +START SLAVE; +--let $slave_io_errno= 1045, 1593 +--source include/wait_for_slave_io_error.inc +--source include/stop_slave.inc + +CHANGE MASTER TO MASTER_USER= 'root', MASTER_PASSWORD= ''; +START SLAVE; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_corruption-master.opt b/mysql-test/suite/rpl/t/rpl_corruption-master.opt new file mode 100644 index 00000000..2612c17a --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_corruption-master.opt @@ -0,0 +1 @@ +--binlog-checksum=CRC32 --master-verify-checksum=1 diff --git a/mysql-test/suite/rpl/t/rpl_corruption-slave.opt b/mysql-test/suite/rpl/t/rpl_corruption-slave.opt new file mode 100644 index 00000000..b32a5240 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_corruption-slave.opt @@ -0,0 +1 @@ +--binlog-checksum=CRC32 --slave-sql-verify-checksum=1 diff --git a/mysql-test/suite/rpl/t/rpl_corruption.test b/mysql-test/suite/rpl/t/rpl_corruption.test new file mode 100644 index 00000000..e51d1c65 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_corruption.test @@ -0,0 +1 @@ +--source include/rpl_corruption.inc diff --git a/mysql-test/suite/rpl/t/rpl_create_database-master.opt b/mysql-test/suite/rpl/t/rpl_create_database-master.opt new file mode 100644 index 00000000..85660a17 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_create_database-master.opt @@ -0,0 +1 @@ +--binlog-do-db=mysqltest_sisyfos --binlog-do-db=mysqltest_prometheus diff --git a/mysql-test/suite/rpl/t/rpl_create_database-slave.opt b/mysql-test/suite/rpl/t/rpl_create_database-slave.opt new file mode 100644 index 00000000..96d630c9 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_create_database-slave.opt @@ -0,0 +1 @@ +--replicate-do-db=mysqltest_sisyfos --replicate-do-db=mysqltest_prometheus diff --git a/mysql-test/suite/rpl/t/rpl_create_database.test b/mysql-test/suite/rpl/t/rpl_create_database.test new file mode 100644 index 00000000..5eac3de0 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_create_database.test @@ -0,0 +1,73 @@ +# +# Tests for replication of statements that manipulate databases. +# +# For this test file, we have a number of databases. All databases +# with "greek" names will be replicated on the slave, while other names +# (e.g., american) will not be replicated. +# + +source include/master-slave.inc; + +# Bug#6391 (binlog-do-db rules ignored) +# In this case, 'mysqltest_bob' should not be replicated to the slave. +--disable_warnings +DROP DATABASE IF EXISTS mysqltest_prometheus; +DROP DATABASE IF EXISTS mysqltest_sisyfos; +DROP DATABASE IF EXISTS mysqltest_bob; +sync_slave_with_master; +# This database is not replicated +DROP DATABASE IF EXISTS mysqltest_bob; +--enable_warnings + +connection master; +CREATE DATABASE mysqltest_prometheus; +CREATE DATABASE mysqltest_sisyfos; +CREATE DATABASE mysqltest_bob; + +USE mysqltest_sisyfos; +# These should be replicated +CREATE TABLE t1 (b int); +INSERT INTO t1 VALUES(1); + +USE mysqltest_bob; +# These should *not* be replicated +CREATE TABLE t2 (b int); +INSERT INTO t2 VALUES(2); + +# Current database is now 'mysqltest_bob' +# The following should be replicated +ALTER DATABASE mysqltest_sisyfos CHARACTER SET latin1; + +USE mysqltest_sisyfos; +# The following should *not* be replicated +ALTER DATABASE mysqltest_bob CHARACTER SET latin1; + +SHOW DATABASES LIKE 'mysql%'; +sync_slave_with_master; +SHOW DATABASES LIKE 'mysql%'; + +connection master; +DROP DATABASE IF EXISTS mysqltest_sisyfos; +USE mysqltest_prometheus; +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1); +CREATE DATABASE mysqltest_sisyfos; +USE mysqltest_sisyfos; +CREATE TABLE t2 (a INT); +let $VERSION=`select version()`; +SHOW DATABASES LIKE 'mysql%'; +sync_slave_with_master; +SHOW DATABASES LIKE 'mysql%'; +USE mysqltest_prometheus; +SHOW TABLES; +USE mysqltest_sisyfos; +SHOW TABLES; + +connection master; +DROP DATABASE IF EXISTS mysqltest_prometheus; +DROP DATABASE IF EXISTS mysqltest_sisyfos; +DROP DATABASE IF EXISTS mysqltest_bob; +sync_slave_with_master; + +# End of 4.1 tests +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_create_drop_db.test b/mysql-test/suite/rpl/t/rpl_create_drop_db.test new file mode 100644 index 00000000..04721c9c --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_create_drop_db.test @@ -0,0 +1,33 @@ +--source include/master-slave.inc + +connection master; + +CREATE DATABASE db1; +CREATE DATABASE IF NOT EXISTS db1; +CREATE OR REPLACE DATABASE db2; +CREATE OR REPLACE DATABASE db1; +sync_slave_with_master; + +SHOW DATABASES LIKE 'db%'; + +connection master; +--error ER_DB_CREATE_EXISTS +CREATE DATABASE db1; + +--error ER_DB_DROP_EXISTS +DROP DATABASE db3; + +CREATE DATABASE IF NOT EXISTS db3; +sync_slave_with_master; + +SHOW DATABASES LIKE 'db%'; + +connection master; +DROP DATABASE db1; +DROP DATABASE db2; +DROP DATABASE IF EXISTS db3; +sync_slave_with_master; + +SHOW DATABASES LIKE 'db%'; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_create_drop_event.test b/mysql-test/suite/rpl/t/rpl_create_drop_event.test new file mode 100644 index 00000000..96a7e82d --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_create_drop_event.test @@ -0,0 +1,27 @@ +--source include/master-slave.inc + +connection master; +SET GLOBAL event_scheduler=off; + +CREATE TABLE t1 (a INT); +CREATE EVENT ev1 ON SCHEDULE EVERY 1 SECOND DO INSERT INTO t1 VALUES (10); +--error ER_EVENT_ALREADY_EXISTS +CREATE EVENT ev1 ON SCHEDULE EVERY 1 SECOND DO INSERT INTO t1 VALUES (11); +CREATE OR REPLACE EVENT ev1 ON SCHEDULE EVERY 1 SECOND DO INSERT INTO t1 VALUES (11); +SELECT EVENT_NAME,STATUS,EVENT_DEFINITION FROM INFORMATION_SCHEMA.EVENTS; + +SET GLOBAL event_scheduler=on; +let $wait_condition= SELECT count(*)>0 FROM t1; +--source include/wait_condition.inc +SET GLOBAL event_scheduler=off; +SELECT DISTINCT a FROM t1; +DELETE FROM t1; + +--echo # Syncing slave with master +sync_slave_with_master; +SELECT EVENT_NAME,STATUS,EVENT_DEFINITION FROM INFORMATION_SCHEMA.EVENTS; +connection master; +DROP TABLE t1; +DROP EVENT ev1; +sync_slave_with_master; +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_create_drop_function.test b/mysql-test/suite/rpl/t/rpl_create_drop_function.test new file mode 100644 index 00000000..5ae0b765 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_create_drop_function.test @@ -0,0 +1,54 @@ +--source include/master-slave.inc + +connection master; + +CREATE FUNCTION hello (str CHAR(20)) RETURNS CHAR(50) DETERMINISTIC RETURN +CONCAT('Hello, ', str, '!'); + +--error ER_SP_ALREADY_EXISTS +CREATE FUNCTION hello (str CHAR(20)) RETURNS CHAR(50) DETERMINISTIC RETURN +CONCAT('Hello, ', str, '!'); + +sync_slave_with_master; + +SHOW CREATE FUNCTION hello; + +connection master; + +--error ER_WRONG_USAGE +CREATE OR REPLACE FUNCTION IF NOT EXISTS hello (str CHAR(20)) RETURNS CHAR(50) DETERMINISTIC RETURN +CONCAT('Hello, ', str, '!'); + +CREATE OR REPLACE FUNCTION hello (str CHAR(20)) RETURNS CHAR(50) DETERMINISTIC RETURN +CONCAT('Hello, ', str, '!'); + +SELECT hello('master'); +sync_slave_with_master; + +SELECT hello('slave'); + +connection master; +CREATE FUNCTION IF NOT EXISTS hello (str CHAR(20)) RETURNS CHAR(50) DETERMINISTIC RETURN +CONCAT('Hello, ', str, '!'); + +CREATE OR REPLACE FUNCTION bye (str CHAR(20)) RETURNS CHAR(50) DETERMINISTIC RETURN +CONCAT('Bye, ', str, '!'); + +SELECT hello('master'); +SELECT bye('master'); +sync_slave_with_master; + +SELECT hello('slave'); +SELECT bye('slave'); + +connection master; +DROP FUNCTION hello; +DROP FUNCTION IF EXISTS bye; +sync_slave_with_master; + +--error ER_SP_DOES_NOT_EXIST +DROP FUNCTION hello; + +DROP FUNCTION IF EXISTS bye; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_create_drop_index.test b/mysql-test/suite/rpl/t/rpl_create_drop_index.test new file mode 100644 index 00000000..f1b65349 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_create_drop_index.test @@ -0,0 +1,17 @@ +--source include/master-slave.inc + +connection master; + +CREATE TABLE t1 (a INT, b INT); +CREATE INDEX i1 ON t1 (a); +CREATE OR REPLACE INDEX i1 ON t1 (a, b); +sync_slave_with_master; + +SHOW CREATE TABLE t1; + +connection master; +SHOW CREATE TABLE t1; +DROP TABLE t1; +sync_slave_with_master; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_create_drop_procedure.test b/mysql-test/suite/rpl/t/rpl_create_drop_procedure.test new file mode 100644 index 00000000..6fb0313c --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_create_drop_procedure.test @@ -0,0 +1,81 @@ +--source include/master-slave.inc + +connection master; +CREATE TABLE t1 (id INT); +DELIMITER $$; +CREATE PROCEDURE proc1 (OUT cnt INT) BEGIN SELECT COUNT(*) INTO cnt FROM t1; END$$ +DELIMITER ;$$ +CALL proc1(@cnt); +SELECT @cnt; +INSERT INTO t1 VALUES (1), (2), (3); +CALL proc1(@cnt); +SELECT @cnt; + +--echo # Syncing with slave +sync_slave_with_master; + +CALL proc1(@cnt); +SELECT @cnt; + +connection master; +DELIMITER $$; +--error ER_SP_ALREADY_EXISTS +CREATE PROCEDURE proc1 (OUT cnt INT) BEGIN SELECT COUNT(*) INTO cnt FROM t1; END$$ + +CREATE PROCEDURE IF NOT EXISTS proc1 (OUT cnt INT) BEGIN SELECT COUNT(*) INTO cnt FROM t1; END$$ + +--error ER_WRONG_USAGE +CREATE OR REPLACE PROCEDURE IF NOT EXISTS proc1 (OUT cnt INT) BEGIN SELECT COUNT(*) INTO cnt FROM t1; END$$ + +CREATE OR REPLACE PROCEDURE proc1 (OUT cnt INT) BEGIN SELECT COUNT(*) INTO cnt FROM t1; END$$ +DELIMITER ;$$ + +--echo # Syncing with slave +sync_slave_with_master; + +CALL proc1(@cnt); +SELECT @cnt; + +connection master; +DROP PROCEDURE proc1; +DELIMITER $$; +CREATE PROCEDURE IF NOT EXISTS proc1 (OUT cnt INT) BEGIN SELECT COUNT(*) INTO cnt FROM t1; END$$ +DELIMITER ;$$ +INSERT INTO t1 VALUES (1), (2), (3); +CALL proc1(@cnt); +SELECT @cnt; + +--echo # Syncing with slave +sync_slave_with_master; + +CALL proc1(@cnt); +SELECT @cnt; + +connection master; +DROP PROCEDURE proc1; +DELIMITER $$; +CREATE OR REPLACE PROCEDURE proc1 (OUT cnt INT) BEGIN SELECT COUNT(*) INTO cnt FROM t1; END$$ +DELIMITER ;$$ +INSERT INTO t1 VALUES (1), (2), (3); +CALL proc1(@cnt); +SELECT @cnt; + +--echo # Syncing with slave +sync_slave_with_master; + +CALL proc1(@cnt); +SELECT @cnt; + +connection master; +DROP TABLE IF EXISTS t1; +DROP PROCEDURE proc1; + +DROP PROCEDURE IF EXISTS proc2; + +--echo # Syncing with slave +sync_slave_with_master; + +--error ER_SP_DOES_NOT_EXIST +DROP PROCEDURE proc1; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_create_drop_role.test b/mysql-test/suite/rpl/t/rpl_create_drop_role.test new file mode 100644 index 00000000..7260b473 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_create_drop_role.test @@ -0,0 +1,48 @@ +--source include/master-slave.inc + +connection master; +CREATE ROLE role_1; +sync_slave_with_master; + +SELECT User FROM mysql.user WHERE is_role='Y' ORDER BY User; + +connection master; +CREATE ROLE IF NOT EXISTS role_1; +CREATE ROLE IF NOT EXISTS role_2; +sync_slave_with_master; + +SELECT User FROM mysql.user WHERE is_role='Y' ORDER BY User; + +connection master; + +--error ER_WRONG_USAGE +CREATE OR REPLACE ROLE IF NOT EXISTS role_3; + +CREATE OR REPLACE ROLE role_3; +CREATE OR REPLACE ROLE role_2; +sync_slave_with_master; + +SELECT User FROM mysql.user WHERE is_role='Y' ORDER BY User; + +connection master; +--error ER_CANNOT_USER +CREATE ROLE role_2; + +sync_slave_with_master; + +SELECT User FROM mysql.user WHERE is_role='Y' ORDER BY User; + +connection master; +DROP ROLE role_1; +DROP ROLE IF EXISTS role_2; +DROP ROLE IF EXISTS role_3; +DROP ROLE IF EXISTS role_4; + +--error ER_CANNOT_USER +DROP ROLE role_4; + +sync_slave_with_master; + +SELECT User FROM mysql.user WHERE is_role='Y' ORDER BY User; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_create_drop_trigger.test b/mysql-test/suite/rpl/t/rpl_create_drop_trigger.test new file mode 100644 index 00000000..568d4e22 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_create_drop_trigger.test @@ -0,0 +1,48 @@ +--source include/master-slave.inc + +--echo # Part 1 - initial creation +connection master; +CREATE DATABASE db1; +USE db1; +CREATE TABLE t1 (val INT); +CREATE TRIGGER val_sum BEFORE INSERT ON t1 FOR EACH ROW SET @sum = @sum + NEW.val + 1; +SET @sum=0; +INSERT INTO t1 VALUES (10), (20), (30); +SELECT ACTION_STATEMENT AS ACTION_STATEMENT_Master FROM INFORMATION_SCHEMA.TRIGGERS WHERE TRIGGER_NAME='val_sum'; +sync_slave_with_master; +SELECT ACTION_STATEMENT AS ACTION_STATEMENT_Slave FROM INFORMATION_SCHEMA.TRIGGERS WHERE TRIGGER_NAME='val_sum'; + +--echo # Part 2 - CREATE IF NOT EXISTS (on a existing trigger) +connection master; +CREATE TRIGGER IF NOT EXISTS val_sum AFTER INSERT ON t1 FOR EACH ROW SET @sum = @sum + NEW.val + 2; +SELECT ACTION_STATEMENT AS ACTION_STATEMENT_Master FROM INFORMATION_SCHEMA.TRIGGERS WHERE TRIGGER_NAME='val_sum'; +sync_slave_with_master; +SELECT ACTION_STATEMENT AS ACTION_STATEMENT_Slave FROM INFORMATION_SCHEMA.TRIGGERS WHERE TRIGGER_NAME='val_sum'; + +--echo # Part 3 - CREATE OR REPLACE (on a existing trigger) +connection master; +CREATE OR REPLACE TRIGGER val_sum BEFORE INSERT ON t1 FOR EACH ROW SET @sum = @sum + NEW.val + 3; +SELECT ACTION_STATEMENT AS ACTION_STATEMENT_Master FROM INFORMATION_SCHEMA.TRIGGERS WHERE TRIGGER_NAME='val_sum'; +sync_slave_with_master; +SELECT ACTION_STATEMENT AS ACTION_STATEMENT_Slave FROM INFORMATION_SCHEMA.TRIGGERS WHERE TRIGGER_NAME='val_sum'; + +--echo # Clearing up +connection master; +DROP TRIGGER val_sum; +DROP TABLE t1; +DROP TRIGGER IF EXISTS val_sum; + +--error ER_TRG_DOES_NOT_EXIST +DROP TRIGGER random_trigger; +DROP DATABASE db1; + +--error ER_NO_DB_ERROR +DROP TRIGGER IF EXISTS val_sum; + +--echo # Syncing slave with master +sync_slave_with_master; + +--error ER_TRG_DOES_NOT_EXIST +DROP TRIGGER val_sum; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_create_drop_udf.test b/mysql-test/suite/rpl/t/rpl_create_drop_udf.test new file mode 100644 index 00000000..af24cabd --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_create_drop_udf.test @@ -0,0 +1,56 @@ +--source include/have_udf.inc +--source include/master-slave.inc + +connection master; + +--replace_result $UDF_EXAMPLE_SO UDF_EXAMPLE_LIB +eval CREATE FUNCTION metaphon RETURNS STRING SONAME "$UDF_EXAMPLE_SO"; +SELECT metaphon('master'); + +--replace_result $UDF_EXAMPLE_SO UDF_EXAMPLE_LIB +--error ER_UDF_EXISTS +eval CREATE FUNCTION metaphon RETURNS INT SONAME "$UDF_EXAMPLE_SO"; + +sync_slave_with_master; + +SELECT metaphon('slave'); + +connection master; + +--replace_result $UDF_EXAMPLE_SO UDF_EXAMPLE_LIB +eval CREATE FUNCTION IF NOT EXISTS metaphon RETURNS STRING SONAME "$UDF_EXAMPLE_SO"; +DROP FUNCTION IF EXISTS random_function_name; +--replace_result $UDF_EXAMPLE_SO UDF_EXAMPLE_LIB +eval CREATE FUNCTION IF NOT EXISTS metaphon RETURNS STRING SONAME "$UDF_EXAMPLE_SO"; + +--replace_result $UDF_EXAMPLE_SO UDF_EXAMPLE_LIB +--error ER_WRONG_USAGE +eval CREATE OR REPLACE FUNCTION IF NOT EXISTS metaphon RETURNS STRING SONAME "$UDF_EXAMPLE_SO"; +sync_slave_with_master; + +SELECT metaphon('slave'); + +connection master; +DROP FUNCTION metaphon; + +--replace_result $UDF_EXAMPLE_SO UDF_EXAMPLE_LIB +eval CREATE OR REPLACE FUNCTION metaphon RETURNS STRING SONAME "$UDF_EXAMPLE_SO"; + +--replace_result $UDF_EXAMPLE_SO UDF_EXAMPLE_LIB +--error ER_UDF_EXISTS +eval CREATE FUNCTION metaphon RETURNS STRING SONAME "$UDF_EXAMPLE_SO"; +sync_slave_with_master; + +SELECT metaphon('slave'); + +connection master; +DROP FUNCTION metaphon; +DROP FUNCTION IF EXISTS metaphon; +sync_slave_with_master; + +--error ER_SP_DOES_NOT_EXIST +DROP FUNCTION metaphon; + +DROP FUNCTION IF EXISTS metaphon; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_create_drop_user.test b/mysql-test/suite/rpl/t/rpl_create_drop_user.test new file mode 100644 index 00000000..c5f193a0 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_create_drop_user.test @@ -0,0 +1,57 @@ +--source include/master-slave.inc + +connection master; +CREATE USER u1@localhost IDENTIFIED BY 'abcdefghijk'; +connect (user_a, localhost, u1,'abcdefghijk',); +connection user_a; +SELECT CURRENT_USER; +disconnect user_a; + +connection master; +CREATE USER IF NOT EXISTS u2@localhost; +connect (user_a, localhost, u2,,); +connection user_a; +SELECT CURRENT_USER; +disconnect user_a; + +connection master; +--sorted_result +SELECT user,password,plugin,authentication_string FROM mysql.user WHERE user LIKE 'u%' ; +sync_slave_with_master; +--sorted_result +SELECT user,password,plugin,authentication_string FROM mysql.user WHERE user LIKE 'u%' ; + +connection master; +CREATE OR REPLACE USER u1@localhost IDENTIFIED BY 'abcdefghijk2'; +connect (user_a, localhost, u1,'abcdefghijk2',); +connection user_a; +SELECT CURRENT_USER; +disconnect user_a; +connection master; +--sorted_result +SELECT user,password,plugin,authentication_string FROM mysql.user WHERE user LIKE 'u%' ; +sync_slave_with_master; +--sorted_result +SELECT user,password,plugin,authentication_string FROM mysql.user WHERE user LIKE 'u%' ; + +connection master; +--error ER_CANNOT_USER +CREATE USER u1@localhost; + +--error ER_CANNOT_USER +DROP USER u3@localhost; + +sync_slave_with_master; +--sorted_result +SELECT user,password,plugin,authentication_string FROM mysql.user WHERE user LIKE 'u%' ; + +connection master; +DROP USER IF EXISTS u1@localhost; +DROP USER u2@localhost; +DROP USER IF EXISTS u3@localhost; +sync_slave_with_master; + +--sorted_result +SELECT user,password,plugin,authentication_string FROM mysql.user WHERE user LIKE 'u%' ; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_create_drop_view.test b/mysql-test/suite/rpl/t/rpl_create_drop_view.test new file mode 100644 index 00000000..4abb3ffb --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_create_drop_view.test @@ -0,0 +1,56 @@ +--source include/master-slave.inc + +connection master; +CREATE TABLE t1(id INT); +CREATE VIEW v1 AS SELECT * FROM t1 WHERE id>10; +INSERT INTO t1 VALUES (5), (8), (10), (20), (30); +SELECT * FROM t1; +SELECT * FROM v1; + +--echo # Syncing slave with master +sync_slave_with_master; +SELECT * FROM t1; +SELECT * FROM v1; + +connection master; +--error ER_TABLE_EXISTS_ERROR +CREATE VIEW v1 AS SELECT * FROM t1 WHERE id>10; + +CREATE VIEW IF NOT EXISTS v1 AS SELECT * FROM t1 WHERE id>10; + +--error ER_WRONG_USAGE +CREATE OR REPLACE VIEW IF NOT EXISTS v1 AS SELECT * FROM t1 WHERE id>10; + +--echo # Syncing slave with master +sync_slave_with_master; +SELECT * FROM t1; +SELECT * FROM v1; + +connection master; +CREATE OR REPLACE VIEW v1 AS SELECT * FROM t1 WHERE id>10; +INSERT INTO t1 VALUES (50), (80), (3), (2), (40); +SELECT * FROM t1; +SELECT * FROM v1; + +--echo # Syncing slave with master +sync_slave_with_master; +SELECT * FROM t1; +SELECT * FROM v1; + +connection master; +RENAME TABLE v1 TO v2; +DROP VIEW v2; +DROP TABLE t1; + +--error ER_UNKNOWN_VIEW +DROP VIEW v1; + +DROP VIEW IF EXISTS v2; + +--echo # Syncing slave with master +sync_slave_with_master; + +--error ER_NO_SUCH_TABLE +SELECT * FROM v1; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_create_if_not_exists.test b/mysql-test/suite/rpl/t/rpl_create_if_not_exists.test new file mode 100644 index 00000000..b27250f9 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_create_if_not_exists.test @@ -0,0 +1,195 @@ +# BUG#45574: +# SP: CREATE DATABASE|TABLE IF NOT EXISTS not binlogged if routine exists. +# +# There is an inconsistency with DROP DATABASE|TABLE|EVENT IF EXISTS and +# CREATE DATABASE|TABLE|EVENT IF NOT EXISTS. DROP IF EXISTS statements are +# binlogged even if either the DB, TABLE or EVENT does not exist. In +# contrast, Only the CREATE EVENT IF NOT EXISTS is binlogged when the EVENT +# exists. +# +# This problem caused some of the tests to fail randomly on PB or PB2. +# +# Description: +# Fixed this bug by adding calls to write_bin_log in: +# mysql_create_db +# mysql_create_table_no_lock +# mysql_create_like_table +# create_table_from_items +# +# Test is implemented as follows: +# i) test each "CREATE IF NOT EXISTS" (DDL), found in MySQL 5.1 manual +# exclude CREATE TEMPORARY TABLE, on existent objects; +# +# Note: +# rpl_create_tmp_table_if_not_exists.test tests CREATE TEMPORARY TABLE cases. +# +# References: +# http://dev.mysql.com/doc/refman/5.1/en/sql-syntax-data-definition.html +# + +source include/master-slave.inc; +disable_warnings; +DROP DATABASE IF EXISTS mysqltest; + +CREATE DATABASE IF NOT EXISTS mysqltest; +USE mysqltest; +CREATE TABLE IF NOT EXISTS t(c1 int); +CREATE TABLE IF NOT EXISTS t1 LIKE t; +CREATE TABLE IF NOT EXISTS t2 SELECT * FROM t; +CREATE EVENT IF NOT EXISTS e +ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 HOUR +DO SELECT now(); +sync_slave_with_master; + +connection slave; +#DROP database from slave. +#The database and all tables can be recreated in slave +#if binlog of the second CREATE command is recorded and sent from master to slave. +DROP DATABASE mysqltest; + +connection master; +CREATE DATABASE IF NOT EXISTS mysqltest; +USE mysqltest; +CREATE TABLE IF NOT EXISTS t(c1 int); +CREATE TABLE IF NOT EXISTS t1 LIKE t; +# The following will not be logged because t2 existed and we will not +# put the data of SELECT into the binary log +CREATE TABLE IF NOT EXISTS t2 SELECT * FROM t; +CREATE EVENT IF NOT EXISTS e +ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 HOUR +DO SELECT now(); +sync_slave_with_master; + +connection slave; +SHOW TABLES in mysqltest; +#Execution time changes in each run. So we disregard it by calling replace_column. +replace_column 6 #; +SHOW EVENTS in mysqltest; + + +connection master; +DROP DATABASE IF EXISTS mysqltest; + +# +# BUG#47418 RBR fails, failure with mixup of base/temporary/view TABLE DDL +# +# Before the patch for this bug, 'CREATE TABLE IF NOT EXIST ... SELECT' +# statement was binlogged as a TEMPORARY table if the object existed as +# a temporary table. This was caused by that the temporary table was opened +# and the results of the 'SELECT' was inserted into the temporary table if +# a temporary table existed with the same name. +# +# After the patch for this bug, the base table is created and the results of +# the 'SELECT' are inserted into it, even though a temporary table exists with +# the same name, and the statement is still binlogged as a base table. +# + +echo -------------BUG#47418-------------; +connection master; +USE test; +DROP TABLE IF EXISTS t3; +--enable_warnings +CREATE TABLE t3(c1 INTEGER); +INSERT INTO t3 VALUES(33); + +CREATE TEMPORARY TABLE t1(c1 INTEGER); +CREATE TEMPORARY TABLE t2(c1 INTEGER); +INSERT INTO t1 VALUES(1); +INSERT INTO t2 VALUES(1); + +CREATE TABLE IF NOT EXISTS t1(c1 INTEGER) SELECT c1 FROM t3; +CREATE TABLE t2(c1 INTEGER) SELECT c1 FROM t3; + +# In these two statements, t1 and t2 are the temporary table. there is only +# value '1' in them. The records of t2 are not inserted into them. +SELECT * FROM t1; +SELECT * FROM t2; +sync_slave_with_master; + +# In these two statements, t1 and t2 are the base table. The records of t2 +# are inserted into it when CREATE TABLE ... SELECT was executed. +SELECT * FROM t1; +SELECT * FROM t2; + +connection master; +DROP TEMPORARY TABLE t1; +DROP TEMPORARY TABLE t2; +#In these two statements, t1 and t2 are the base table. +SELECT * FROM t1; +SELECT * FROM t2; + +DROP TABLE t1; +DROP TABLE t2; +DROP TABLE t3; + +--echo # WL#5370 +--echo # The behavior of statement 'CREATE TABLE SELECT IF NOT EXISTS' is changed. +--echo # After the worklog, it will insert nothing and the statement will not be +--echo # binlogged if the table already exists. +--echo # After the worklog, some bugs will disappear automotically. +--source include/rpl_reset.inc + +--echo +--echo # Case 1: BUG#47132 +connection master; +call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT.*"); + +CREATE TABLE t1 (id int); +CREATE TABLE t2 (id int); +INSERT INTO t1 VALUES (1), (1); +INSERT INTO t2 VALUES (2), (2); + +CREATE VIEW v1 AS SELECT id FROM t2; +--let binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1) +CREATE TABLE IF NOT EXISTS v1(a int, b int) SELECT id, id as di FROM t1; +--source include/show_binlog_events.inc + +SHOW CREATE TABLE v1; +SELECT * FROM t2; +SELECT * FROM v1; +DROP VIEW v1; + +# the warning only happens on SBR, so we disable it. +--disable_warnings +CREATE TEMPORARY TABLE tt1 AS SELECT id FROM t2; +--enable_warnings + +--let binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1) +CREATE TEMPORARY TABLE IF NOT EXISTS tt1(a int, b int) SELECT id, id FROM t1; +--source include/show_binlog_events.inc +SELECT * FROM t2; +SELECT * FROM tt1; +DROP TEMPORARY TABLE tt1; + +--echo +--echo # Case 1: BUG#47132 +--echo # RBR breaks on CREATE TABLE IF EXISTS AS SELECT +CREATE VIEW v1 AS SELECT 1 as a; +--let binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1) +CREATE TABLE IF NOT EXISTS v1 SELECT 2 as a; +--source include/show_binlog_events.inc +sync_slave_with_master; + +connection master; +DROP VIEW v1; + +DROP TABLE t1, t2; + + +--echo # +--echo # Test case which has failed on assertion after refactoring which was +--echo # made as part of fix for bug #27480 "Extend CREATE TEMPORARY TABLES +--echo # privilege to allow temp table operations". +--echo # +CREATE TEMPORARY TABLE t1 (id int); +CREATE TABLE IF NOT EXISTS t2 LIKE t1; +--echo # The below statement should succeed with warning and +--echo # should not crash due to failing assertion. +CREATE TABLE IF NOT EXISTS t2 LIKE t1; +--echo # Clean-up. +DROP TABLE t1, t2; +sync_slave_with_master; +connection master; + + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_create_or_replace_fail.test b/mysql-test/suite/rpl/t/rpl_create_or_replace_fail.test new file mode 100644 index 00000000..8624d3c9 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_create_or_replace_fail.test @@ -0,0 +1,56 @@ +# ==== Purpose ==== +# +# Test verifies that failed CREATE OR REPLACE TEMPORARY TABLE statement which +# dropped the table but failed at a later stage of creation of temporary table +# is written to binarylog in row based replication. +# +# ==== Implementation ==== +# +# Steps: +# 0 - Have mixed based replication mode. +# 1 - Create a temporary table. It will be replicated as mixed replication +# mode is in use. +# 2 - Execute an unsafe statement which will switch current statement +# binlog format to 'ROW'. i.e If binlog_format=MIXED, there are open +# temporary tables, and an unsafe statement is executed, then subsequent +# statements are logged in row format. +# 3 - Execute a CREATE OR REPLACE TEMPORARY TABLE statement which tries to +# create partitions on temporary table. Since it is not supported it will +# fail. +# 4 - Check the binary log output to ensure that the failed statement is +# written to the binary log. +# 5 - Slave should be up and running and in sync with master. +# +# ==== References ==== +# +# MDEV-18930: Failed CREATE OR REPLACE TEMPORARY not written into binary log +# makes data on master and slave diverge +# + +--source include/have_partition.inc +--source include/have_binlog_format_mixed.inc +--source include/master-slave.inc + +CREATE TEMPORARY TABLE t1 (a INT NOT NULL); + +# Execute an unsafe statement which switches replication mode internally from +# "STATEMENT" to "ROW". +--error ER_NO_SUCH_TABLE +LOAD DATA INFILE 'x' INTO TABLE x; + +--error ER_FEATURE_NOT_SUPPORTED_WITH_PARTITIONING +CREATE OR REPLACE TEMPORARY TABLE t1 (x INT) PARTITION BY HASH(x); + +--echo "************** DROP TEMPORARY TABLE Should be present in Binary log **************" +--source include/show_binlog_events.inc + +CREATE TABLE t1 (b INT); +INSERT INTO t1 VALUES (NULL); +--sync_slave_with_master + +# Cleanup +--connection master +DROP TABLE t1; + +--source include/rpl_end.inc + diff --git a/mysql-test/suite/rpl/t/rpl_create_tmp_table_if_not_exists.test b/mysql-test/suite/rpl/t/rpl_create_tmp_table_if_not_exists.test new file mode 100644 index 00000000..3107fdfa --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_create_tmp_table_if_not_exists.test @@ -0,0 +1,45 @@ +# BUG#45574: +# SP: CREATE DATABASE|TABLE IF NOT EXISTS not binlogged if routine exists. +# +# There is an inconsistency with DROP DATABASE|TABLE|EVENT IF EXISTS and +# CREATE DATABASE|TABLE|EVENT IF NOT EXISTS. DROP IF EXISTS statements are +# binlogged even if either the DB, TABLE or EVENT does not exist. In +# contrast, Only the CREATE EVENT IF NOT EXISTS is binlogged when the EVENT +# exists. +# +# This problem caused some of the tests to fail randomly on PB or PB2. +# +# Test is implemented as follows: +# +# i) test each "CREATE TEMPORARY TABLE IF EXISTS" (DDL), found in MySQL +# 5.1 manual, on existent objects; +# ii) show binlog events; +# +# Note: +# rpl_create_if_not_exists.test tests other cases. +# +# References: +# http://dev.mysql.com/doc/refman/5.1/en/sql-syntax-data-definition.html +# + +#CREATE TEMPORARY TABLE statements are not binlogged in row mode, +#So it must be test by itself. +source include/have_binlog_format_mixed_or_statement.inc; +source include/master-slave.inc; +disable_warnings; + +DROP DATABASE IF EXISTS mysqltest; + +CREATE TEMPORARY TABLE IF NOT EXISTS tmp(c1 int); +CREATE TEMPORARY TABLE IF NOT EXISTS tmp(c1 int); +CREATE TEMPORARY TABLE IF NOT EXISTS tmp1 LIKE tmp; +CREATE TEMPORARY TABLE IF NOT EXISTS tmp1 LIKE tmp; +CREATE TEMPORARY TABLE IF NOT EXISTS tmp2 SELECT * FROM tmp; +CREATE TEMPORARY TABLE IF NOT EXISTS tmp2 SELECT * FROM tmp; +source include/show_binlog_events.inc; + +DROP TEMPORARY TABLE tmp; +DROP TEMPORARY TABLE tmp1; +DROP TEMPORARY TABLE tmp2; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_create_xa_prepared.inc b/mysql-test/suite/rpl/t/rpl_create_xa_prepared.inc new file mode 100644 index 00000000..b823ebf6 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_create_xa_prepared.inc @@ -0,0 +1,9 @@ +# param $xid to name xa and take part in the connection name +# param $query to execute as the xa body +# param $db_ign the default database + +--connect (master_$xid, 127.0.0.1,root,,$db,$MASTER_MYPORT,) +--eval xa start '$xid' +--eval $query +--eval xa end '$xid' +--eval xa prepare '$xid'; diff --git a/mysql-test/suite/rpl/t/rpl_critical_errors.test b/mysql-test/suite/rpl/t/rpl_critical_errors.test new file mode 100644 index 00000000..bc0d7096 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_critical_errors.test @@ -0,0 +1,66 @@ +# Test for BUG#26551 +# + +# This test is unfortunately very fragile and very dependent on the +# load of the computer. The test is therefore disabled normally. It is +# entered here to demonstrate how to check that the bug is actually +# solved. + +--echo Turn on parsing to run this test + +disable_parsing; + +source include/master-slave.inc; + +connection master; +CREATE TABLE t1 (data LONGBLOB) ENGINE=MYISAM; +CREATE TABLE t2 (data LONGBLOB) ENGINE=MYISAM; + +INSERT INTO t1 (data) VALUES (repeat('a',1024*1024)); +INSERT INTO t1 SELECT * FROM t1; +INSERT INTO t1 SELECT * FROM t1; +INSERT INTO t1 SELECT * FROM t1; +INSERT INTO t1 SELECT * FROM t1; +INSERT INTO t1 SELECT * FROM t1; +INSERT INTO t1 SELECT * FROM t1; +INSERT INTO t1 SELECT * FROM t1; +INSERT INTO t1 SELECT * FROM t1; +sync_slave_with_master; + +connection master; +send INSERT INTO t2 SELECT * FROM t1; + +connection master1; + +# This sleep is picked so that the query above has started to insert +# some rows into t2. If it hasn't the slave will not stop below. +let $wait_condition= SELECT COUNT(*) > 1000 FROM t1; +--source include/wait_condition.inc + +# SHOW PROCESSLIST; + +# Code for the 5.1 server to get the thread id of the thread executing +# the query above. +# +#SET @id = 0; +#SELECT id INTO @id +# FROM information_schema.processlist +# WHERE info LIKE 'INSERT INTO t2%'; + +# This is the connection that is executing the INSERT INTO t2... +KILL QUERY 2; + +connection slave; + +# Here the slave will only stop if the query above actually started +# inserting some rows into t2. Otherwise, it will hang forever. ... and there +# the error code should be 1317 (ER_QUERY_INTERRUPTED) +--let $slave_sql_errno= 1317 +--let $show_slave_sql_error= 1 +--source include/wait_for_slave_sql_error.inc + +# The following should be 0 +SELECT COUNT(*) FROM t2; + +--source include/rpl_end.inc +enable_parsing; diff --git a/mysql-test/suite/rpl/t/rpl_cross_version-master.opt b/mysql-test/suite/rpl/t/rpl_cross_version-master.opt new file mode 100644 index 00000000..815a8f81 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_cross_version-master.opt @@ -0,0 +1 @@ +--replicate-same-server-id --relay-log=slave-relay-bin diff --git a/mysql-test/suite/rpl/t/rpl_cross_version.test b/mysql-test/suite/rpl/t/rpl_cross_version.test new file mode 100644 index 00000000..94c9f043 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_cross_version.test @@ -0,0 +1,48 @@ +# ==== Purpose ==== +# +# Verify cross-version replication from an old master to the up-to-date slave +# +# ==== Implementation ==== +# +# Feed to the slave server a binlog recorded on an old version master +# via setting up slave-to-slave replication. The latter is done by means of +# the opt file and include/setup_fake_relay_log.inc. +# The master's binlog is treated as a relay log that the SQL thread executes. +# + +--source include/master-slave.inc + +# +# Bug#31240 load data infile replication between (4.0 or 4.1) and 5.1 fails +# + +--echo ==== Initialize ==== +--connection slave + +--disable_query_log +# The binlog contains the function RAND which is unsafe. +CALL mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT"); +--enable_query_log + +--source include/stop_slave.inc +RESET SLAVE; + +# the relay log contains create t1, t3 tables and load data infile +--let $fake_relay_log = $MYSQL_TEST_DIR/suite/binlog/std_data/binlog_old_version_4_1.000001 +--source include/setup_fake_relay_log.inc + +--echo ==== Test ==== +start slave sql_thread; +--let $slave_param = Exec_Master_Log_Pos +# end_log_pos of the last event of the relay log +--let $slave_param_value = 149436 +--source include/wait_for_slave_param.inc +--echo ==== a prove that the fake has been processed successfully ==== +SELECT COUNT(*) - 17920 as zero FROM t3; + +--echo ==== Clean up ==== +--source include/stop_slave_sql.inc +--source include/cleanup_fake_relay_log.inc +drop table t1, t3; +--let $rpl_only_running_threads= 1 +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_ctype_latin1.test b/mysql-test/suite/rpl/t/rpl_ctype_latin1.test new file mode 100644 index 00000000..a8525421 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_ctype_latin1.test @@ -0,0 +1,44 @@ +--source include/have_lowercase0.inc +--disable_warnings +--source include/master-slave.inc +--enable_warnings + +--echo # +--echo # Start of 10.2 tests +--echo # + + +--echo # +--echo # MDEV-14249 Wrong character set info of Query_log_event and the query in Query_log_event constructed by different charsets cause error when slave apply the event. +--echo # + +# +# The below tests uses a sequence of bytes 0xD191, +# which in a utf8 console looks like Ñ‘ (CYRILIC SMALL LETTER YO). +# Don't be mislead. This sequence is used in latin1 context and +# represents a sequence of two characters: +# U+00D1 CAPITAL LATIN LETTER N WITH TILDE (_latin1 0xD1) +# U+2018 LEFT SINGLE QUOTATION MARK (_latin1 0x91) +# + +SET NAMES latin1; +CREATE TABLE `tÑ‘` (`tÑ‘` INT); +CREATE VIEW `vÑ‘` AS SELECT 'vÑ‘'; +CREATE PROCEDURE `pÑ‘`() SELECT 'pÑ‘'; + +select hex(table_name) from information_schema.tables where table_schema="test" and table_name like "t%"; +select hex(table_name) from information_schema.tables where table_schema="test" and table_name like "v%"; + +--sync_slave_with_master +select hex(table_name) from information_schema.tables where table_schema="test" and table_name like "t%"; +select hex(table_name) from information_schema.tables where table_schema="test" and table_name like "v%"; +--replace_column 5 ts 6 ts +SHOW PROCEDURE STATUS LIKE 'p%'; + +--connection master +DROP TABLE `tÑ‘`; +DROP VIEW `vÑ‘`; +DROP PROCEDURE `pÑ‘`; +--sync_slave_with_master + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_current_user.cnf b/mysql-test/suite/rpl/t/rpl_current_user.cnf new file mode 100644 index 00000000..58b605ad --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_current_user.cnf @@ -0,0 +1,8 @@ +!include ../my.cnf + +[mysqld.3] +log-slave-updates + +[ENV] +SERVER_MYPORT_3= @mysqld.3.port +SERVER_MYSOCK_3= @mysqld.3.socket diff --git a/mysql-test/suite/rpl/t/rpl_current_user.test b/mysql-test/suite/rpl/t/rpl_current_user.test new file mode 100644 index 00000000..391606e3 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_current_user.test @@ -0,0 +1,225 @@ +############################################################################## +# BUG#48321 CURRENT_USER() incorrectly replicated for DROP/RENAME USER, +# REVOKE, GRANT, ALTER EVENT +# +# Calling CURRENT_USER() results into inconsistency between slave and master, +# as the slave SQL thread has different user with common users. +# +# After the patch for bug#48321, session's user will be written into query log +# event if CURRENT_USER() is called in 'DROP/RENAME USER', 'REVOKE', 'GRANT', +# 'ALTER EVENT'. +# +############################################################################## + +source include/have_binlog_format_statement.inc; + +--let $rpl_topology= 1->2->3 +--source include/rpl_init.inc + +--let $rpl_connection_name= master +--let $rpl_server_number= 1 +--source include/rpl_connect.inc + +--let $rpl_connection_name= slave +--let $rpl_server_number= 2 +--source include/rpl_connect.inc + +--disable_query_log +--connection server_1 +call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT.*"); +--connection server_2 +call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT.*"); +--connection server_3 +call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT.*"); +--enable_query_log + +--connection master + +CREATE TABLE t1(c1 char(100)); +CREATE VIEW test.v_user AS SELECT * FROM mysql.user WHERE User LIKE 'bug48321%'; +CREATE VIEW test.v_tables_priv AS SELECT * FROM mysql.tables_priv WHERE User LIKE 'bug48321%'; +CREATE VIEW test.v_procs_priv AS SELECT * FROM mysql.procs_priv WHERE User LIKE 'bug48321%'; +CREATE VIEW test.v_event AS SELECT definer FROM mysql.event WHERE name = 'e1'; +CREATE PROCEDURE p1() SELECT 1; +--echo # bug48321_1-01234 has the max length(16) of user. +CREATE USER 'bug48321_1-01234'@'localhost'; +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1-01234'@'localhost' WITH GRANT OPTION; + +--echo +--echo # Test the max lengths of user and host names +--echo # the user name is too long +--error ER_WRONG_STRING_LENGTH +GRANT CREATE USER ON *.* TO '012345678901234567890123456789012345678901234567890123456789012345678901234567890'@'fakehost'; +--echo # the host name is too long +--error ER_WRONG_STRING_LENGTH +GRANT CREATE USER ON *.* TO 'fakename'@'0123456789012345678901234567890123456789012345678901234567890'; + +--echo +--echo # User 'bug48321_1-01234' connects to master by conn1 +connect (conn1, 127.0.0.1, 'bug48321_1-01234'@'localhost',,); +connection conn1; +--echo # Verify 'REVOKE ALL' statement +REVOKE ALL PRIVILEGES, GRANT OPTION FROM CURRENT_USER(); +--source include/rpl_sync.inc +let $diff_tables= server_1:v_user, server_2:v_user, server_3:v_user; +source include/diff_tables.inc; + +--echo +--echo # Verify 'GRANT ... ON TABLE ...' statement +GRANT CREATE, INSERT, SELECT ON TABLE test.t1 TO CURRENT_USER(); +--source include/rpl_sync.inc +let $diff_tables= server_1:v_tables_priv, server_2:v_tables_priv, server_3:v_tables_priv; +source include/diff_tables.inc; + +--echo +--echo # Verify 'GRANT ... ON PROCEDURE...' statement +GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO CURRENT_USER(); +--source include/rpl_sync.inc +let $diff_tables= server_1:v_procs_priv, server_2:v_procs_priv, server_3:v_procs_priv; +source include/diff_tables.inc; + +--echo +--echo # Verify 'GRANT ... ON *.* ...' statement +GRANT ALL PRIVILEGES ON *.* TO CURRENT_USER() WITH GRANT OPTION; +--source include/rpl_sync.inc +let $diff_tables= server_1:v_procs_priv, server_2:v_procs_priv, server_3:v_procs_priv; +source include/diff_tables.inc; + +--echo +--echo # Verify 'REVOKE ... ON TABLE ...' statement +REVOKE CREATE, INSERT, SELECT ON TABLE t1 FROM CURRENT_USER(); +--source include/rpl_sync.inc +let $diff_tables= server_1:v_tables_priv, server_2:v_tables_priv, server_3:v_tables_priv; +source include/diff_tables.inc; + +--echo +--echo # Verify 'REVOKE ... ON PROCEDURE...' statement +REVOKE ALTER ROUTINE, EXECUTE ON PROCEDURE p1 FROM CURRENT_USER(); +--source include/rpl_sync.inc +let $diff_tables= server_1:v_procs_priv, server_2:v_procs_priv, server_3:v_procs_priv; +source include/diff_tables.inc; + +--echo +--echo # Verify 'REVOKE ... ON *.* ...' statement +REVOKE ALL PRIVILEGES ON *.* FROM CURRENT_USER(); +--source include/rpl_sync.inc +let $diff_tables= server_1:v_user, server_2:v_user, server_3:v_user; +source include/diff_tables.inc; + +--echo +--echo # Verify 'GRANT ...' statement in the procedure +CREATE PROCEDURE my_grant() + GRANT CREATE, INSERT, SELECT ON TABLE test.t1 TO CURRENT_USER(); +call my_grant; +--source include/rpl_sync.inc +let $diff_tables= server_1:v_tables_priv, server_2:v_tables_priv, server_3:v_tables_priv; +source include/diff_tables.inc; + +--echo +--echo # Verify 'REVOKE ... ON TABLE ...' statement in the procedure +CREATE PROCEDURE my_revoke() + REVOKE CREATE, INSERT, SELECT ON TABLE t1 FROM CURRENT_USER(); +call my_revoke; +--source include/rpl_sync.inc +let $diff_tables= server_1:v_tables_priv, server_2:v_tables_priv, server_3:v_tables_priv; +source include/diff_tables.inc; + +--echo +--echo # Verify 'RENAME USER ...' statement +RENAME USER CURRENT_USER TO 'bug48321_2'@'localhost'; +--source include/rpl_sync.inc +let $diff_tables= server_1:v_user, server_2:v_user, server_3:v_user; +source include/diff_tables.inc; + +disconnect conn1; + +--echo +--echo # Verify 'DROP USER ...' statement +connection master; +GRANT CREATE USER ON *.* TO 'bug48321_2'@'localhost'; +connect (conn1, 127.0.0.1, 'bug48321_2'@'localhost',,); +connection conn1; +DROP USER CURRENT_USER(); +--source include/rpl_sync.inc +let $diff_tables= server_1:v_user, server_2:v_user, server_3:v_user; +source include/diff_tables.inc; + +--echo +--echo # Verify 'ALTER EVENT...' statement +connection master; +CREATE EVENT e1 ON SCHEDULE EVERY 1 DAY DO SELECT * FROM t1; + +--echo # Explicitly assign CURRENT_USER() to definer +ALTER DEFINER=CURRENT_USER() EVENT e1 ENABLE; +--source include/rpl_sync.inc +let $diff_tables= server_1:v_event, server_2:v_event, server_3:v_event; +source include/diff_tables.inc; + +--echo +--echo # Session user will be set as definer, if the statement does not assign +--echo # a definer +ALTER EVENT e1 ENABLE; +--source include/rpl_sync.inc +let $diff_tables= server_1:v_event, server_2:v_event, server_3:v_event; +source include/diff_tables.inc; + +--echo +--echo # Verify that this patch does not affect the calling of CURRENT_USER() +--echo # in the other statements +connection master; +INSERT INTO t1 VALUES(CURRENT_USER()), ('1234'); +SELECT * FROM t1; +sync_slave_with_master; +SELECT * FROM t1; +sync_slave_with_master server_3; +SELECT * FROM t1; + +connection master; +UPDATE t1 SET c1=CURRENT_USER() WHERE c1='1234'; +SELECT * FROM t1; +sync_slave_with_master; +SELECT * FROM t1; +sync_slave_with_master server_3; +SELECT * FROM t1; + +connection master; +DELETE FROM t1 WHERE c1=CURRENT_USER(); +SELECT * FROM t1; +sync_slave_with_master; +SELECT * FROM t1; +sync_slave_with_master server_3; +SELECT * FROM t1; + +connection master; +CREATE TABLE t2(c1 char(100)); + +DELIMITER |; +CREATE FUNCTION my_user() RETURNS VARCHAR(64) + SQL SECURITY INVOKER +BEGIN + INSERT INTO t2 VALUES(CURRENT_USER()); + RETURN CURRENT_USER(); +END | +DELIMITER ;| + +INSERT INTO t1 VALUES(my_user()); +SELECT * FROM t1; +SELECT * FROM t2; +sync_slave_with_master; +SELECT * FROM t1; +SELECT * FROM t2; +sync_slave_with_master server_3; +SELECT * FROM t1; +SELECT * FROM t2; + +--echo +--echo # END +connection master; +DROP TABLE t1, t2; +DROP VIEW v_user, v_tables_priv, v_procs_priv, v_event; +DROP PROCEDURE p1; +DROP PROCEDURE my_grant; +DROP PROCEDURE my_revoke; +DROP FUNCTION my_user; +DROP EVENT e1; +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_ddl-slave.opt b/mysql-test/suite/rpl/t/rpl_ddl-slave.opt new file mode 100644 index 00000000..21356507 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_ddl-slave.opt @@ -0,0 +1 @@ +--loose-skip-innodb diff --git a/mysql-test/suite/rpl/t/rpl_ddl.test b/mysql-test/suite/rpl/t/rpl_ddl.test new file mode 100644 index 00000000..b11a6927 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_ddl.test @@ -0,0 +1,32 @@ +######################## rpl_ddl.test ######################## +# # +# DDL statements (sometimes with implicit COMMIT) executed # +# by the master and it's propagation into the slave # +# # +############################################################## + +# +# NOTE, PLEASE BE CAREFUL, WHEN MODIFYING THE TESTS !! +# +# 1. !All! objects to be dropped, renamed, altered ... must be created +# in AUTOCOMMIT= 1 mode before AUTOCOMMIT is set to 0 and the test +# sequences start. +# +# 2. Never use a test object, which was direct or indirect affected by a +# preceding test sequence again. +# Except table d1.t1 where ONLY DML is allowed. +# +# If one preceding test sequence hits a (sometimes not good 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.. +# +--source include/have_innodb.inc +--source include/master-slave.inc +let $engine_type= InnoDB; +let $temp_engine_type= MEMORY; +let $show_binlog = 0; +let $manipulate = 0; +-- source include/rpl_ddl.test +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_deadlock_innodb-slave.opt b/mysql-test/suite/rpl/t/rpl_deadlock_innodb-slave.opt new file mode 100644 index 00000000..f516b1b7 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_deadlock_innodb-slave.opt @@ -0,0 +1 @@ +--loose-innodb-lock-wait-timeout=4 --slave-transaction-retries=2 --max-relay-log-size=4096 diff --git a/mysql-test/suite/rpl/t/rpl_deadlock_innodb.test b/mysql-test/suite/rpl/t/rpl_deadlock_innodb.test new file mode 100644 index 00000000..e2311cb0 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_deadlock_innodb.test @@ -0,0 +1,4 @@ +-- source include/have_innodb.inc +-- source include/long_test.inc +let $engine_type=innodb; +-- source include/rpl_deadlock.test diff --git a/mysql-test/suite/rpl/t/rpl_default.test b/mysql-test/suite/rpl/t/rpl_default.test new file mode 100644 index 00000000..9adf15c9 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_default.test @@ -0,0 +1,29 @@ +# +# Test of replicating default values +# As the table is using non deterministic functions, replication must +# switch to binlog format. +# + +-- source include/have_binlog_format_mixed_or_row.inc +-- source include/master-slave.inc + +connection master; + +create table t1 (a int DEFAULT (1+1), b bigint default uuid_short(), u blob default user()); +insert into t1 (a) values(1); + +let $b=query_get_value(select * from t1, b, 1); +let $u=query_get_value(select * from t1, u, 1); + +sync_slave_with_master; +connection slave; + +show create table t1; +--disable_query_log +eval select a,"$b"=b as uuid,"$u"=u as user from t1; +--enable_query_log +connection master; + +drop table t1; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_delayed_slave.combinations b/mysql-test/suite/rpl/t/rpl_delayed_slave.combinations new file mode 100644 index 00000000..bac7cb33 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_delayed_slave.combinations @@ -0,0 +1,4 @@ +[nonparallel] + +[parallel] +--slave-parallel-threads=10 diff --git a/mysql-test/suite/rpl/t/rpl_delayed_slave.test b/mysql-test/suite/rpl/t/rpl_delayed_slave.test new file mode 100644 index 00000000..7dd7b9cf --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_delayed_slave.test @@ -0,0 +1,424 @@ +# ==== Purpose ==== +# +# Test the time-delayed replication feature, i.e., +# CHANGE MASTER TO MASTER_DELAY=X: +# +# - Verify that slave has executed the events after but not before the +# delay timeout. +# +# - Verify that delay is correct when slave is already lagging +# due to slow queries. +# +# - Verify that Seconds_Behind_Master is greater than or equal to the +# delay if the slave still has unprocessed events in the relay log +# and more time than the delay has elapsed since the last event was +# executed on the master. +# +# - Verify that STOP SLAVE works instantly even during a delay, and +# that it does not cause the waited-for event to be executed too +# early on slave. +# +# - Verify that changing back to no delay works. +# +# - Verify that RESET SLAVE sets the delay to 0. +# +# - Verify that setting a bad value for the delay gives an error. +# +# ==== Implementation ==== +# +# We run the slave with 10 seconds lag. +# +# In general, to test that a query has not been executed by the slave +# before this time, we wait until the slave IO thread has received the +# event, and then 5 seconds more, and check that the table has not +# been updated. To test that a query has been executed after this +# time, we wait 10 seconds more. +# +# To simulate that the slave lags due to slow queries, we invoke a +# stored function that executes SLEEP if @@gloval.server_id==2. This +# requires that we run with binlog_format=STATEMENT. +# +# ==== Related Bugs and Worklogs ==== +# +# WL#344: Time-delayed replication +# BUG#28760: Simulating a replication lag +# [duplicate] BUG#22072: configurable delayed replication +# [duplicate] BUG#21639: Add Replication Delay parameter +# BUG#56442: Slave executes delayed statements when STOP SLAVE is issued +# +# ==== Issues with this Test Case ==== +# +# The test is inherently timing-sensitive (i.e., contains races) and +# is likely to fail sporadically on a loaded host. +# +# The test takes a long time; it sleeps for around 20*10 seconds. + +--source include/big_test.inc +--source include/not_valgrind.inc +--source include/master-slave.inc +# Needed so that sleeps get executed in the slave SQL thread. +--source include/have_binlog_format_statement.inc + + +call mtr.add_suppression("Unsafe statement written to the binary log using statement format"); +--connection slave +call mtr.add_suppression("Unsafe statement written to the binary log using statement format"); +--connection master + + +# We assume that any simple operation takes zero time, with an error +# margin of $time1 seconds. Hence, if we run with a delay of $time2 +# seconds, we expect that: +# - If we execute a query on master and wait $time1 seconds, then the +# query has been copied to slave but not yet executed. +# - If we execute a query on master and wait $time3 seconds, then the +# query has been executed. +--let $time1= 10 +if (`SELECT '$max_query_execution_time' > 0`) { + --let $time1= $max_query_execution_time +} +--let $time2= `SELECT 2 * $time1` +--let $time3= `SELECT 3 * $time1` + + +--echo [on master] +CREATE TABLE t1 (a VARCHAR(100), b INT); +INSERT INTO t1 VALUES ("zero", 0); + + +--echo ==== Normal setup ==== + +--echo [on slave] +--sync_slave_with_master + +--source include/stop_slave.inc + +--echo # CHANGE MASTER TO MASTER_DELAY = 2*T +--disable_query_log +eval CHANGE MASTER TO MASTER_DELAY = $time2; +--enable_query_log + +--source include/start_slave.inc + +--let $assert_text= SHOW SLAVE STATUS should return the same delay that we set with CHANGE MASTER +--let $assert_cond= [SHOW SLAVE STATUS, SQL_Delay, 1] = $time2 +--source include/rpl_assert.inc + +--echo [on master] +--connection master +INSERT INTO t1 VALUES ('normal setup', 1); + +--let $query_number= 1 +--source include/delayed_slave_wait_on_query.inc + + +--echo ==== Slave lags "naturally" after master ==== + +--echo [on master] +--connection master + +--disable_query_log +--echo # CREATE FUNCTION delay_on_slave(time_units INT) RETURNS INT BEGIN IF @@GLOBAL.server_id = 2 THEN RETURN SLEEP(time_units * T); ELSE RETURN 0; END IF; END +--eval CREATE FUNCTION delay_on_slave(time_units INT) RETURNS INT BEGIN IF @@GLOBAL.server_id = 2 THEN RETURN SLEEP(time_units * $time1); ELSE RETURN 0; END IF; END +--enable_query_log + +INSERT INTO t1 SELECT delay_on_slave(3), 2; + +--save_master_pos +INSERT INTO t1 VALUES ('slave is already lagging: this statement should execute immediately', 3); +INSERT INTO t1 SELECT delay_on_slave(2), 4; + +--echo [on slave] +--source include/sync_slave_io_with_master.inc +--echo # sleep 1*T +--sleep $time1 + +--let $assert_text= No query executed +--let $assert_cond= MAX(b) = 1 FROM t1 +--source include/rpl_assert.inc + +--let $assert_text= Status should be 'Waiting until MASTER_DELAY...' +--let $assert_cond= "[SHOW SLAVE STATUS, Slave_SQL_Running_State, 1]" LIKE "Waiting until MASTER_DELAY%" +--source include/rpl_assert.inc + +--echo # wait for first query to execute +--sync_with_master + +--echo # sleep 1*T +--sleep $time1 + +--let $assert_text= Second query executed +--let $assert_cond= MAX(b) = 3 FROM t1 +--source include/rpl_assert.inc + +let $parallel= `SELECT @@GLOBAL.slave_parallel_threads`; +if (!$parallel) +{ + let $assert_text= Status should be executing third query (i.e., 'User sleep'); + let $assert_cond= "[SHOW SLAVE STATUS, Slave_SQL_Running_State, 1]" = "User sleep"; + source include/rpl_assert.inc; +} + +--echo # sleep 2*T +--sleep $time2 + +--let $assert_text= Third query executed +--let $assert_cond= MAX(b) = 4 FROM t1 +--source include/rpl_assert.inc + +--let $assert_text= Status should be 'Has read all relay log...' +--let $assert_cond= "[SHOW SLAVE STATUS, Slave_SQL_Running_State, 1]" LIKE "Slave has read all relay log%" +--source include/rpl_assert.inc + + +--echo ==== Seconds_Behind_Master ==== + +--echo # Bring slave to sync. +--source include/stop_slave.inc +CHANGE MASTER TO MASTER_DELAY = 0; +--source include/start_slave.inc + +--connection master +INSERT INTO t1 VALUES ('Syncing slave', 5); +--sync_slave_with_master + +--source include/stop_slave.inc +--echo # CHANGE MASTER TO MASTER_DELAY = 2*T +--disable_query_log +eval CHANGE MASTER TO MASTER_DELAY = $time2; +--enable_query_log +--source include/start_slave.inc + +--connection master +INSERT INTO t1 VALUES (delay_on_slave(1), 6); +--save_master_pos +--connection slave + +--echo # sleep 1*T +--sleep $time1 + +--let $assert_cond= [SHOW SLAVE STATUS, Seconds_Behind_Master, 1] >= 0 AND <1> < $time2 +--let $assert_text= Seconds_Behind_Master should be between 0 and the 2*T +--source include/rpl_assert.inc + +--echo # sleep 1*T +--sleep $time1 + +--let $assert_cond= [SHOW SLAVE STATUS, Seconds_Behind_Master, 1] >= $time2 +--let $assert_text= Seconds_Behind_Master should be at least 2*T +--source include/rpl_assert.inc + +--sync_with_master + + +--echo ==== STOP SLAVE / START SLAVE + DML ==== + +# Set up a longer delay. +--source include/stop_slave.inc + +--echo # CHANGE MASTER TO MASTER_DELAY = 3*T +--disable_query_log +eval CHANGE MASTER TO MASTER_DELAY = $time3; +--enable_query_log + +--source include/start_slave.inc + +--echo [on master] +--connection master +INSERT INTO t1 VALUES ('stop slave and start slave: DML', 7); + +--echo [on slave] +--connection slave +--echo # sleep 1*T +--sleep $time1 +--let $timestamp_before_stop= `SELECT UNIX_TIMESTAMP()` +--let $relay_log_pos_before_stop= query_get_value(SHOW SLAVE STATUS, Relay_Log_Pos, 1) +--source include/stop_slave.inc + +--let $assert_text= STOP SLAVE should finish quickly, not wait for the ongoing sleep to finish +--let $assert_cond= UNIX_TIMESTAMP() - $timestamp_before_stop < $time1 +--source include/rpl_assert.inc + +--let $assert_text= SQL thread position should not increase after STOP SLAVE +--let $assert_cond= [SHOW SLAVE STATUS, Relay_Log_Pos, 1] = $relay_log_pos_before_stop +--source include/rpl_assert.inc + +--let $assert_text= Query should not be executed after STOP SLAVE +--let $assert_cond= MAX(b) = 6 FROM t1 +--source include/rpl_assert.inc + +--let $assert_text= Status should be '' after STOP SLAVE +--let $assert_cond= "[SHOW SLAVE STATUS, Slave_SQL_Running_State, 1]" = "" +--source include/rpl_assert.inc + +--source include/start_slave.inc + +--let $assert_text= START SLAVE should finish quickly +--let $assert_cond= UNIX_TIMESTAMP() - $timestamp_before_stop < $time1 +--source include/rpl_assert.inc + +--let $query_number= 7 +--source include/delayed_slave_wait_on_query.inc + + +--echo ==== STOP SLAVE / START SLAVE + DDL ==== + +--echo This verifies BUG#56442 + +--echo [on master] +--connection master +CREATE TABLE t_check_dml_not_executed_prematurely (a INT); +--source include/save_master_pos.inc + +--echo [on slave] +--connection slave +--echo # sleep 1*T +--sleep $time1 + +--let $timestamp_before_stop= `SELECT UNIX_TIMESTAMP()` +--let $relay_log_pos_before_stop= query_get_value(SHOW SLAVE STATUS, Relay_Log_Pos, 1) +--source include/stop_slave.inc + +--let $assert_text= STOP SLAVE should finish quickly, not wait for the ongoing sleep to finish +--let $assert_cond= UNIX_TIMESTAMP() - $timestamp_before_stop < $time1 +--source include/rpl_assert.inc + +--let $assert_text= SQL thread position should not increase after STOP SLAVE +--let $assert_cond= [SHOW SLAVE STATUS, Relay_Log_Pos, 1] = $relay_log_pos_before_stop +--source include/rpl_assert.inc + +--let $assert_text= Query should not be executed after STOP SLAVE +--let $assert_cond= COUNT(*) = 0 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = "t_check_dml_not_executed_prematurely" +--source include/rpl_assert.inc + +--let $assert_text= Status should be '' after STOP SLAVE +--let $assert_cond= "[SHOW SLAVE STATUS, Slave_SQL_Running_State, 1]" = "" +--source include/rpl_assert.inc + +--source include/start_slave.inc + +--let $assert_text= START SLAVE should finish quickly +--let $assert_cond= UNIX_TIMESTAMP() - $timestamp_before_stop < $time1 +--source include/rpl_assert.inc + +--echo # sleep 1*T +--sleep $time1 + +--let $assert_text= DDL Query should not be executed after START SLAVE +--let $assert_cond= COUNT(*) = 0 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = "t_check_dml_not_executed_prematurely" +--source include/rpl_assert.inc + +--let $assert_text= Status should be 'Waiting until MASTER_DELAY...' +--let $assert_cond= "[SHOW SLAVE STATUS, Slave_SQL_Running_State, 1]" LIKE "Waiting until MASTER_DELAY%" +--source include/rpl_assert.inc + +--echo # sleep 1*T +--sleep $time1 + +--echo # sync with master (with timeout 1*T) +--source include/sync_with_master.inc + +--let $assert_text= DDL Query should be executed +--let $assert_cond= COUNT(*) = 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = "t_check_dml_not_executed_prematurely" +--source include/rpl_assert.inc + +--let $assert_text= Status should be 'Has read all relay log...' +--let $assert_cond= "[SHOW SLAVE STATUS, Slave_SQL_Running_State, 1]" LIKE "Slave has read all relay log%" +--source include/rpl_assert.inc + +--source include/check_slave_is_running.inc + + +--echo ==== Change back to no delay ==== + +--echo [on slave] +--connection slave +--source include/stop_slave.inc +CHANGE MASTER TO MASTER_DELAY = 0; + +--let $assert_text= Delay should be 0 when we set it to 0 +--let $assert_cond= [SHOW SLAVE STATUS, SQL_Delay, 1] = 0 +--source include/rpl_assert.inc + +--source include/start_slave.inc + +--echo [on master] +--connection master +INSERT INTO t1 VALUES ('change back to no delay', 8); + +--echo [on slave] +--source include/sync_slave_io_with_master.inc +--echo # sleep 1*T +--sleep $time1 + +--let $assert_text= Query should be executed +--let $assert_cond= MAX(b) = 8 FROM t1 +--source include/rpl_assert.inc + +--let $assert_text= Status should be 'Slave has read all relay log...' +--let $assert_cond= "[SHOW SLAVE STATUS, Slave_SQL_Running_State, 1]" Like "Slave has read all relay log%" +--source include/rpl_assert.inc + + +--echo ==== Reset delay with RESET SLAVE ==== + +--source include/stop_slave.inc +CHANGE MASTER TO MASTER_DELAY = 71; +--source include/start_slave.inc + +--let $assert_text= Delay should be 71 when we set it to 71 +--let $assert_cond= [SHOW SLAVE STATUS, SQL_Delay, 1] = 71 +--source include/rpl_assert.inc + +--source include/stop_slave.inc +RESET SLAVE; +--echo [on master] +--connection master +RESET MASTER; +--echo [on slave] +--connection slave +--source include/start_slave.inc + +--let $assert_text= Delay should be 0 after RESET SLAVE +--let $assert_cond= [SHOW SLAVE STATUS, SQL_Delay, 1] = 0 +--source include/rpl_assert.inc + + +--echo ==== Set an invalid value for the delay ==== + +--source include/stop_slave.inc + +--echo # Expect error for setting negative delay +--error ER_PARSE_ERROR +CHANGE MASTER TO MASTER_DELAY = -1; + +--echo # Expect that it's ok to set delay of 2^31-1 +CHANGE MASTER TO MASTER_DELAY = 2147483647; +--echo # Expect error for setting delay between 2^31 and 2^32-1 +--error ER_MASTER_DELAY_VALUE_OUT_OF_RANGE +CHANGE MASTER TO MASTER_DELAY = 2147483648; + +--echo # Expect error for setting delay to nonsense +--error ER_PARSE_ERROR +CHANGE MASTER TO MASTER_DELAY = blah; + +# todo: CHANGE MASTER TO MASTER_DELAY = 999999999999999999999999999 +# should give error + +CHANGE MASTER TO MASTER_DELAY = 0; +--source include/start_slave.inc + + +--echo ==== Clean up ==== + +--echo [on master] +--connection master +DROP TABLE t1, t_check_dml_not_executed_prematurely; +DROP FUNCTION delay_on_slave; + +--echo [on slave] +--sync_slave_with_master +SELECT @@GLOBAL.slave_parallel_mode; +SELECT @@GLOBAL.slave_parallel_threads; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_delayed_slave2.test b/mysql-test/suite/rpl/t/rpl_delayed_slave2.test new file mode 100644 index 00000000..68e8f8e1 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_delayed_slave2.test @@ -0,0 +1,65 @@ +--source include/have_innodb.inc +--source include/master-slave.inc + +# This test file tests delayed slave for parallel replication (and GTID). +# Uses a different approach from rpl_delayed_slave.test, setting @@timestamp +# to simulate events logged on master at different times. + +--connection master +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +CREATE TABLE t1 (a INT PRIMARY KEY, b VARCHAR(100)); +INSERT INTO t1 VALUES (1, "a"); +--save_master_pos + +--connection slave +--sync_with_master +--source include/stop_slave.inc +CHANGE MASTER TO master_use_gtid=slave_pos; +SET @old_mode= @@GLOBAL.slave_parallel_mode; +SET GLOBAL slave_parallel_mode=optimistic; +SET @old_threads= @@GLOBAL.slave_parallel_threads; +SET GLOBAL slave_parallel_threads=10; + +--connection master +INSERT INTO t1 VALUES (2, "b"); +INSERT INTO t1 VALUES (3, "b"); +INSERT INTO t1 VALUES (4, "b"); +--let $gtid1= `SELECT @@gtid_binlog_pos` +# Simulate an event a days in the future, for delayed slave to wait on. +SET timestamp= @@timestamp + 24*60*60; +INSERT INTO t1 VALUES (5, "c"); +INSERT INTO t1 VALUES (6, "c"); +SET timestamp= 0; +--let $gtid2= `SELECT @@gtid_binlog_pos` +--source include/save_master_gtid.inc + +--connection slave +CHANGE MASTER TO master_delay=1; +--source include/start_slave.inc +--replace_result $gtid1 GTID1 +# First sync halfways, to avoid timing-dependent test failures. +eval SELECT MASTER_GTID_WAIT('$gtid1'); +# Try to sync up, should timeout because slave is waiting for one day. +--replace_result $gtid2 GTID2 +eval SELECT MASTER_GTID_WAIT('$gtid2', 2); + +# Check that we can stop slave while delaying. +--source include/stop_slave.inc +SELECT * FROM t1 ORDER BY a; +CHANGE MASTER TO master_delay=0; +--source include/start_slave.inc +--source include/sync_with_master_gtid.inc +SELECT * FROM t1 ORDER BY a; + + +--connection slave +--source include/stop_slave.inc +CHANGE MASTER TO master_use_gtid=no, master_delay=0; +SET GLOBAL slave_parallel_mode=@old_mode; +SET GLOBAL slave_parallel_threads=@old_threads; +--source include/start_slave.inc + +--connection master +DROP TABLE t1; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_delete_no_where.test b/mysql-test/suite/rpl/t/rpl_delete_no_where.test new file mode 100644 index 00000000..c07649cb --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_delete_no_where.test @@ -0,0 +1,4 @@ +-- source include/master-slave.inc +let $engine_type=myisam; +-- source include/rpl_delete_no_where.test +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_do_grant.test b/mysql-test/suite/rpl/t/rpl_do_grant.test new file mode 100644 index 00000000..1350585f --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_do_grant.test @@ -0,0 +1,350 @@ +# Works in statement-based and row-based binlogging. +# Test that GRANT and other user management commands are replicated to the slave + +-- source include/master-slave.inc + +# test replication of GRANT +connection master; +create user rpl_do_grant@localhost; +grant select on *.* to rpl_do_grant@localhost; +grant drop on test.* to rpl_do_grant@localhost; +sync_slave_with_master; +show grants for rpl_do_grant@localhost; + +# test replication of SET PASSWORD +connection master; +set password for rpl_do_grant@localhost=password("does it work?"); +sync_slave_with_master; +select authentication_string<>'' from mysql.user where user='rpl_do_grant'; + +# +# Bug#24158 SET PASSWORD in binary log fails under ANSI_QUOTES +# +connection master; +update mysql.global_priv set priv=json_remove(priv, '$.authentication_string') where user='rpl_do_grant'; +flush privileges; +select authentication_string<>'' from mysql.user where user='rpl_do_grant'; +set sql_mode='ANSI_QUOTES'; +set password for rpl_do_grant@localhost=password('does it work?'); +set sql_mode=''; +sync_slave_with_master; +select authentication_string<>'' from mysql.user where user='rpl_do_grant'; + +# clear what we have done, to not influence other tests. +connection master; +drop user rpl_do_grant@localhost; +sync_slave_with_master; + +# End of 4.1 tests + +connection master; +--error 1141 +show grants for rpl_do_grant@localhost; +connection slave; +--error 1141 +show grants for rpl_do_grant@localhost; + +connection master; +create user rpl_do_grant@localhost; +show grants for rpl_do_grant@localhost; +--error 1141 +show grants for rpl_do_grant2@localhost; +sync_slave_with_master; +show grants for rpl_do_grant@localhost; +--error 1141 +show grants for rpl_do_grant2@localhost; + +connection master; +rename user rpl_do_grant@localhost to rpl_do_grant2@localhost; +show grants for rpl_do_grant2@localhost; +sync_slave_with_master; +show grants for rpl_do_grant2@localhost; + +connection master; +grant DELETE,INSERT on mysqltest1.* to rpl_do_grant2@localhost; +show grants for rpl_do_grant2@localhost; +sync_slave_with_master; +show grants for rpl_do_grant2@localhost; + +connection master; +revoke DELETE on mysqltest1.* from rpl_do_grant2@localhost; +show grants for rpl_do_grant2@localhost; +sync_slave_with_master; +show grants for rpl_do_grant2@localhost; + +connection master; +revoke all privileges, grant option from rpl_do_grant2@localhost; +show grants for rpl_do_grant2@localhost; +sync_slave_with_master; +show grants for rpl_do_grant2@localhost; + +connection master; +drop user rpl_do_grant2@localhost; +--error 1141 +show grants for rpl_do_grant2@localhost; +sync_slave_with_master; +--error 1141 +show grants for rpl_do_grant2@localhost; + +##################################################### +# Purpose +# Test whether mysql.procs_priv get replicated +# Related bugs: +# BUG42217 mysql.procs_priv does not get replicated +##################################################### +connection master; +call mtr.add_suppression("Slave: Operation DROP USER failed for 'create_rout_db'@'localhost' error.* 1396"); +sync_slave_with_master; +connection master; + +--disable_warnings +DROP DATABASE IF EXISTS bug42217_db; +--enable_warnings +CREATE DATABASE bug42217_db; + +GRANT CREATE ROUTINE ON bug42217_db.* TO 'create_rout_db'@'localhost' + IDENTIFIED BY 'create_rout_db' WITH GRANT OPTION; + +-- sync_slave_with_master +-- connection master + +connect (create_rout_db_master, localhost, create_rout_db, create_rout_db, bug42217_db,$MASTER_MYPORT,); +connect (create_rout_db_slave, localhost, create_rout_db, create_rout_db, bug42217_db, $SLAVE_MYPORT,); + +connection create_rout_db_master; + + +USE bug42217_db; + +DELIMITER //; +CREATE FUNCTION upgrade_del_func() RETURNS CHAR(30) +BEGIN + RETURN "INSIDE upgrade_del_func()"; +END// + +DELIMITER ;// + +connection master; + +USE bug42217_db; +--replace_column 8 # +SELECT * FROM mysql.procs_priv; +SELECT upgrade_del_func(); + +sync_slave_with_master; +--replace_column 8 # +SELECT * FROM mysql.procs_priv; +SHOW GRANTS FOR 'create_rout_db'@'localhost'; + +USE bug42217_db; +SHOW CREATE FUNCTION upgrade_del_func; +SELECT upgrade_del_func(); + +--echo "Check whether the definer user will be able to execute the replicated routine on slave" +connection create_rout_db_slave; +USE bug42217_db; +SHOW CREATE FUNCTION upgrade_del_func; +SELECT upgrade_del_func(); + +connection slave; +DELETE FROM mysql.procs_priv; +FLUSH PRIVILEGES; +USE bug42217_db; +--echo "Can't execute the replicated routine on slave like before after procs privilege is deleted " +--error 1370 +SELECT upgrade_del_func(); + +--echo "Test the user who creates a function on master doesn't exist on slave." +--echo "Hence SQL thread ACL_GLOBAL privilege jumps in and no mysql.procs_priv is inserted" +DROP USER 'create_rout_db'@'localhost'; + +connection create_rout_db_master; +DELIMITER //; +CREATE FUNCTION upgrade_alter_func() RETURNS CHAR(30) +BEGIN + RETURN "INSIDE upgrade_alter_func()"; +END// +DELIMITER ;// + +connection master; +SELECT upgrade_alter_func(); + +sync_slave_with_master; +SHOW CREATE FUNCTION upgrade_alter_func; +--echo "Should no privilege record for upgrade_alter_func in mysql.procs_priv" +--replace_column 8 # +SELECT * FROM mysql.procs_priv; +--error 1449 +SELECT upgrade_alter_func(); + +###### CLEAN UP SECTION ############## +disconnect create_rout_db_master; +disconnect create_rout_db_slave; +connection master; +USE bug42217_db; +DROP FUNCTION upgrade_del_func; +DROP FUNCTION upgrade_alter_func; +DROP DATABASE bug42217_db; +-- sync_slave_with_master +-- connection master + +# user was already dropped in the slave before +# so we should not replicate this statement. +SET SQL_LOG_BIN= 0; +DROP USER 'create_rout_db'@'localhost'; +SET SQL_LOG_BIN= 1; + +# finish entire clean up (remove binlogs) +# so that we leave a pristine environment for the +# following tests +--let $rpl_only_running_threads= 1 +-- source include/rpl_reset.inc +USE test; + +# BUG#49119: Master crashes when executing 'REVOKE ... ON +# {PROCEDURE|FUNCTION} FROM ...' +# +# The tests are divided into two test cases: +# +# i) a test case that mimics the one in the bug report. +# +# - We show that, despite the fact, that a revoke command fails +# when binlogging is active, the master will not hit an +# assertion. +# +# ii) a test case that partially succeeds on the master will also +# partially succeed on the slave. +# +# - The revoke statement that partially succeeds tries to revoke +# an EXECUTE grant for two users, and only one of the user has +# the specific grant. This will cause mysql to drop one of the +# grants and report error for the statement. The slave should +# also drop the grants that the master succeed and the SQL +# thread should not stop on statement failure. + +-- echo ######## BUG#49119 ####### +-- echo ### i) test case from the 'how to repeat section' + +-- connection master + +CREATE TABLE t1(c1 INT); +DELIMITER |; +CREATE PROCEDURE p1() SELECT * FROM t1 | +DELIMITER ;| +-- error ER_NONEXISTING_PROC_GRANT +REVOKE EXECUTE ON PROCEDURE p1 FROM 'root'@'localhost'; + +-- sync_slave_with_master + +-- connection master +DROP TABLE t1; +DROP PROCEDURE p1; + +-- sync_slave_with_master + +-- echo ### ii) Test case in which REVOKE partially succeeds + +-- connection master +-- source include/rpl_reset.inc +-- connection master + +CREATE TABLE t1(c1 INT); +DELIMITER |; +CREATE PROCEDURE p1() SELECT * FROM t1 | +DELIMITER ;| + +CREATE USER 'user49119'@'localhost'; +GRANT EXECUTE ON PROCEDURE p1 TO 'user49119'@'localhost'; + +-- echo ############################################################## +-- echo ### Showing grants for both users: root and user49119 (master) +SHOW GRANTS FOR 'user49119'@'localhost'; +SHOW GRANTS FOR CURRENT_USER; +-- echo ############################################################## + +-- sync_slave_with_master + +-- echo ############################################################## +-- echo ### Showing grants for both users: root and user49119 (master) +SHOW GRANTS FOR 'user49119'@'localhost'; +SHOW GRANTS FOR CURRENT_USER; +-- echo ############################################################## + +-- connection master + +-- echo ## This statement will make the revoke fail because root has no +-- echo ## execute grant. However, it will still revoke the grant for +-- echo ## user49119. +-- error ER_NONEXISTING_PROC_GRANT +REVOKE EXECUTE ON PROCEDURE p1 FROM 'user49119'@'localhost', 'root'@'localhost'; + +-- echo ############################################################## +-- echo ### Showing grants for both users: root and user49119 (master) +-- echo ### after revoke statement failure +SHOW GRANTS FOR 'user49119'@'localhost'; +SHOW GRANTS FOR CURRENT_USER; +-- echo ############################################################## + +-- sync_slave_with_master + +-- echo ############################################################# +-- echo ### Showing grants for both users: root and user49119 (slave) +-- echo ### after revoke statement failure (should match +SHOW GRANTS FOR 'user49119'@'localhost'; +SHOW GRANTS FOR CURRENT_USER; +-- echo ############################################################## + +-- connection master +DROP TABLE t1; +DROP PROCEDURE p1; +DROP USER 'user49119'@'localhost'; + +-- sync_slave_with_master + +# +# Bug #51987 revoke privileges logs wrong error code +# + +-- source include/rpl_reset.inc +-- connection master + +grant all on *.* to foo@"1.2.3.4"; +-- error ER_REVOKE_GRANTS +revoke all privileges, grant option from "foo"; + +## assertion: revoke is logged +-- source include/show_binlog_events.inc + +-- sync_slave_with_master + +## assertion: slave replicates revoke and does not fail because master +## logged revoke with correct expected error code +--source include/check_slave_no_error.inc + +-- connection master +DROP USER foo@"1.2.3.4"; +-- sync_slave_with_master + +--echo +--echo # Bug#27606 GRANT statement should be replicated with DEFINER information +--source include/rpl_reset.inc +--connection master +GRANT SELECT, INSERT ON mysql.user TO user_bug27606@localhost; + +SELECT Grantor FROM mysql.tables_priv WHERE User='user_bug27606'; +sync_slave_with_master; +SELECT Grantor FROM mysql.tables_priv WHERE User='user_bug27606'; + +--connection master +REVOKE SELECT ON mysql.user FROM user_bug27606@localhost; +SELECT Grantor FROM mysql.tables_priv WHERE User='user_bug27606'; +sync_slave_with_master; +SELECT Grantor FROM mysql.tables_priv WHERE User='user_bug27606'; + +--connection master +DROP USER user_bug27606@localhost; +select priv into @root_priv from mysql.global_priv where user='root' and host='127.0.0.1'; +update mysql.global_priv set priv=@root_priv where user='root' and host='localhost'; + + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_domain_id_filter.test b/mysql-test/suite/rpl/t/rpl_domain_id_filter.test new file mode 100644 index 00000000..2b8ac17c --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_domain_id_filter.test @@ -0,0 +1,400 @@ +--source include/have_innodb.inc +--source include/master-slave.inc + +# +# Test for DO_DOMAIN_IDS=(M1, M2, ..) and IGNORE_DOMAIN_IDS=(N1, N2, ..) +# + +connection slave; +call mtr.add_suppression("Both DO_DOMAIN_IDS & IGNORE_DOMAIN_IDS lists can't be non-empty at the same time"); +call mtr.add_suppression("DO_DOMAIN_IDS or IGNORE_DOMAIN_IDS lists can't be non-empty in non-GTID mode.*"); + +connection master; +SET @@session.gtid_domain_id= 1; +SELECT @@session.gtid_domain_id; +CREATE TABLE t1(i INT) ENGINE=INNODB; +INSERT INTO t1 VALUES(1); +SELECT * FROM t1; +--source include/save_master_gtid.inc + +connection slave; +--source include/sync_with_master_gtid.inc +##### Case 0 : When both DO_DOMAIN_IDS and IGNORE_DOMAIN_IDS are empty. +SELECT * FROM t1; + +##### Case 1: When DO_DOMAIN_IDS is non-empty. +--source include/stop_slave.inc +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); +--echo DO_DOMAIN_IDS (BEFORE) : $do_domain_ids_before +--echo IGNORE_DOMAIN_IDS (BEFORE) : $ignore_domain_ids_before + +# Replicate events belonging to "domain_id 1". +CHANGE MASTER TO DO_DOMAIN_IDS=(1), MASTER_USE_GTID=slave_pos; +--source include/start_slave.inc + +let $do_domain_ids_after= query_get_value(SHOW SLAVE STATUS, Replicate_Do_Domain_Ids, 1); +let $ignore_domain_ids_after= query_get_value(SHOW SLAVE STATUS, Replicate_Ignore_Domain_Ids, 1); +--echo DO_DOMAIN_IDS (AFTER) : $do_domain_ids_after +--echo IGNORE_DOMAIN_IDS (AFTER) : $ignore_domain_ids_after + +connection master; +# Lets change the session domain_id to 2(not in DO_DOMAIN_IDS). +SET @@session.gtid_domain_id= 2; +# Should get filtered out on slave. +INSERT INTO t1 VALUES(2); +# Change it back to 1 (in DO_DOMAIN_IDS). +SET @@session.gtid_domain_id= 1; +# Should get applied on slave. +INSERT INTO t1 VALUES(3); + +SELECT * FROM t1; +--source include/save_master_gtid.inc + +connection slave; +--source include/sync_with_master_gtid.inc +SELECT * FROM t1; + +##### Case 2: When IGNORE_DOMAIN_IDS is non-empty. +--source include/stop_slave.inc +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); +--echo DO_DOMAIN_IDS (BEFORE) : $do_domain_ids_before +--echo IGNORE_DOMAIN_IDS (BEFORE) : $ignore_domain_ids_before + +# Ignore events belonging to "domain_id 1". +CHANGE MASTER TO DO_DOMAIN_IDS=(), IGNORE_DOMAIN_IDS=(1), MASTER_USE_GTID=slave_pos; +--source include/start_slave.inc + +let $do_domain_ids_after= query_get_value(SHOW SLAVE STATUS, Replicate_Do_Domain_Ids, 1); +let $ignore_domain_ids_after= query_get_value(SHOW SLAVE STATUS, Replicate_Ignore_Domain_Ids, 1); +--echo DO_DOMAIN_IDS (AFTER) : $do_domain_ids_after +--echo IGNORE_DOMAIN_IDS (AFTER) : $ignore_domain_ids_after + +connection master; +# @@session.gtid_domain_id = 1 (in IGNORE_DOMAIN_IDS) +SELECT @@session.gtid_domain_id; +# Should get filtered out on slave. +INSERT INTO t1 VALUES(4); +# Change it to 2 (not in IGNORE_DOMAIN_IDS). +SET @@session.gtid_domain_id= 2; +# Should get applied on slave. +INSERT INTO t1 VALUES(5); + +SELECT * FROM t1; +--source include/save_master_gtid.inc + +connection slave; +--source include/sync_with_master_gtid.inc +SELECT * FROM t1; + +##### Case 3: When both DO_DOMAIN_IDS and IGNORE_DOMAIN_IDS are non-empty + +--source include/stop_slave.inc +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); +--echo DO_DOMAIN_IDS (BEFORE) : $do_domain_ids_before +--echo IGNORE_DOMAIN_IDS (BEFORE) : $ignore_domain_ids_before + +--error ER_MASTER_INFO +CHANGE MASTER TO DO_DOMAIN_IDS=(1), IGNORE_DOMAIN_IDS=(2), MASTER_USE_GTID=slave_pos; + +let $do_domain_ids_after= query_get_value(SHOW SLAVE STATUS, Replicate_Do_Domain_Ids, 1); +let $ignore_domain_ids_after= query_get_value(SHOW SLAVE STATUS, Replicate_Ignore_Domain_Ids, 1); +--echo DO_DOMAIN_IDS (AFTER) : $do_domain_ids_after +--echo IGNORE_DOMAIN_IDS (AFTER) : $ignore_domain_ids_after + +##### Case 4: Multiple domain ids. + +--source include/stop_slave.inc +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); +--echo DO_DOMAIN_IDS (BEFORE) : $do_domain_ids_before +--echo IGNORE_DOMAIN_IDS (BEFORE) : $ignore_domain_ids_before + +# Replicate events belonging to "domain_id 1". +CHANGE MASTER TO DO_DOMAIN_IDS=(4,4,5,1,7,7,7,1,1,2,6,8,1,4,5,5,9,3), IGNORE_DOMAIN_IDS=(), MASTER_USE_GTID=slave_pos; +--source include/start_slave.inc + +let $do_domain_ids_after= query_get_value(SHOW SLAVE STATUS, Replicate_Do_Domain_Ids, 1); +let $ignore_domain_ids_after= query_get_value(SHOW SLAVE STATUS, Replicate_Ignore_Domain_Ids, 1); +--echo DO_DOMAIN_IDS (AFTER) : $do_domain_ids_after +--echo IGNORE_DOMAIN_IDS (AFTER) : $ignore_domain_ids_after + +connection master; +# @@session.gtid_domain_id = 1 (in DO_DOMAIN_IDS) +SELECT @@session.gtid_domain_id; +# Should get applied on slave. +INSERT INTO t1 VALUES(8); +# Change it to 7 (in DO_DOMAIN_IDS). +SET @@session.gtid_domain_id= 7; +# Should get applied on slave. +INSERT INTO t1 VALUES(9); +# Change it to 10 (no in DO_DOMAIN_IDS). +SET @@session.gtid_domain_id= 10; +# Following should get filtered out on slave. +INSERT INTO t1 VALUES(10); +INSERT INTO t1 VALUES(11); +START TRANSACTION; +INSERT INTO t1 VALUES(12); +INSERT INTO t1 VALUES(13); +COMMIT; +INSERT INTO t1 VALUES(14); +INSERT INTO t1 VALUES(15); +--source include/save_master_gtid.inc + +connection slave; +--source include/sync_with_master_gtid.inc +SELECT * FROM t1; + +##### Case 5: Seconds_Behind_Master +connection slave; +--echo # Seconds_Behind_Master should be zero here because the slave is fully caught up and idle. +--let $status_items= Seconds_Behind_Master +--source include/show_slave_status.inc + +##### Case 6: Stop slave before a transaction (involving MyISAM and InnoDB +# table) being filtered commits. + +connection slave; +--source include/stop_slave.inc +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); +--echo DO_DOMAIN_IDS (BEFORE) : $do_domain_ids_before +--echo IGNORE_DOMAIN_IDS (BEFORE) : $ignore_domain_ids_before + +# IGNORE_DOMAIN_IDS=(1) +CHANGE MASTER TO DO_DOMAIN_IDS=(), IGNORE_DOMAIN_IDS=(1), MASTER_USE_GTID=slave_pos; +--source include/start_slave.inc + +let $do_domain_ids_after= query_get_value(SHOW SLAVE STATUS, Replicate_Do_Domain_Ids, 1); +let $ignore_domain_ids_after= query_get_value(SHOW SLAVE STATUS, Replicate_Ignore_Domain_Ids, 1); +--echo DO_DOMAIN_IDS (AFTER) : $do_domain_ids_after +--echo IGNORE_DOMAIN_IDS (AFTER) : $ignore_domain_ids_after + +connection master; +# following statements should not get filtered. +SET @@session.gtid_domain_id=2; +CREATE TABLE t2(i int) ENGINE=MYISAM; +CREATE TABLE t3(i int) ENGINE=INNODB; + +SET @@session.gtid_domain_id=1; +BEGIN; +INSERT INTO t2 VALUES(1); +INSERT INTO t3 VALUES(1); + +# Now switch to slave to stop replication. +connection slave; +--source include/stop_slave.inc +--source include/wait_for_slave_to_stop.inc + +# Back to master to finish the transaction. +connection master; +INSERT INTO t2 VALUES(2); +INSERT INTO t3 VALUES(2); +COMMIT; +--source include/save_master_gtid.inc + +# On slave to start replication. +connection slave; +--source include/start_slave.inc +--source include/sync_with_master_gtid.inc + +SELECT * FROM t2; +SELECT * FROM t3; + +##### Case 7: Stop slave before a transaction (involving MyISAM and InnoDB +# table) being filtered commits and start it back with filtering +# disabled. + +connection master; +SET @@session.gtid_domain_id=1; +BEGIN; +INSERT INTO t2 VALUES(3); +INSERT INTO t3 VALUES(3); +--source include/save_master_gtid.inc + +connection slave; +--source include/sync_with_master_gtid.inc +--source include/stop_slave.inc +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); +--echo DO_DOMAIN_IDS (BEFORE) : $do_domain_ids_before +--echo IGNORE_DOMAIN_IDS (BEFORE) : $ignore_domain_ids_before + +# Clear IGNORE_DOMAIN_IDS +CHANGE MASTER TO DO_DOMAIN_IDS=(), IGNORE_DOMAIN_IDS=(), MASTER_USE_GTID=slave_pos; +--source include/start_slave.inc + +let $do_domain_ids_after= query_get_value(SHOW SLAVE STATUS, Replicate_Do_Domain_Ids, 1); +let $ignore_domain_ids_after= query_get_value(SHOW SLAVE STATUS, Replicate_Ignore_Domain_Ids, 1); +--echo DO_DOMAIN_IDS (AFTER) : $do_domain_ids_after +--echo IGNORE_DOMAIN_IDS (AFTER) : $ignore_domain_ids_after + +connection master; +INSERT INTO t2 VALUES(4); +INSERT INTO t3 VALUES(4); +COMMIT; +--source include/save_master_gtid.inc + +connection slave; +--source include/sync_with_master_gtid.inc +SELECT * FROM t2; +SELECT * FROM t3; + +##### Case 8: Stop slave into the middle of a transaction and start it back +# with filtering enabled. + +connection master; +SET @@session.gtid_domain_id=1; +BEGIN; +INSERT INTO t2 VALUES(5); +INSERT INTO t3 VALUES(5); +--source include/save_master_gtid.inc + +connection slave; +--source include/sync_with_master_gtid.inc +--source include/stop_slave.inc +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); +--echo DO_DOMAIN_IDS (BEFORE) : $do_domain_ids_before +--echo IGNORE_DOMAIN_IDS (BEFORE) : $ignore_domain_ids_before + +# IGNORE_DOMAIN_IDS(1) +CHANGE MASTER TO DO_DOMAIN_IDS=(), IGNORE_DOMAIN_IDS=(1), MASTER_USE_GTID=slave_pos; +--source include/start_slave.inc + +let $do_domain_ids_after= query_get_value(SHOW SLAVE STATUS, Replicate_Do_Domain_Ids, 1); +let $ignore_domain_ids_after= query_get_value(SHOW SLAVE STATUS, Replicate_Ignore_Domain_Ids, 1); +--echo DO_DOMAIN_IDS (AFTER) : $do_domain_ids_after +--echo IGNORE_DOMAIN_IDS (AFTER) : $ignore_domain_ids_after + +connection master; +INSERT INTO t2 VALUES(6); +INSERT INTO t3 VALUES(6); +COMMIT; +--source include/save_master_gtid.inc + +connection slave; +--source include/sync_with_master_gtid.inc +SELECT * FROM t2; +SELECT * FROM t3; + +##### Case 9: Initially filter out events belonging to domain_id=2 and then +# remove the rule to check if event are not being filtered out. + +connection slave; +--source include/stop_slave.inc +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); +--echo DO_DOMAIN_IDS (BEFORE) : $do_domain_ids_before +--echo IGNORE_DOMAIN_IDS (BEFORE) : $ignore_domain_ids_before + +# IGNORE_DOMAIN_IDS(2) +CHANGE MASTER TO IGNORE_DOMAIN_IDS=(2), MASTER_USE_GTID=slave_pos; +--source include/start_slave.inc + +let $do_domain_ids_after= query_get_value(SHOW SLAVE STATUS, Replicate_Do_Domain_Ids, 1); +let $ignore_domain_ids_after= query_get_value(SHOW SLAVE STATUS, Replicate_Ignore_Domain_Ids, 1); +--echo DO_DOMAIN_IDS (AFTER) : $do_domain_ids_after +--echo IGNORE_DOMAIN_IDS (AFTER) : $ignore_domain_ids_after + +connection master; +SET @@session.gtid_domain_id=2; +BEGIN; +INSERT INTO t2 VALUES(7); +INSERT INTO t3 VALUES(7); +COMMIT; +--source include/save_master_gtid.inc + +# Clear the filter +connection slave; +--source include/sync_with_master_gtid.inc +--source include/stop_slave.inc +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); +--echo DO_DOMAIN_IDS (BEFORE) : $do_domain_ids_before +--echo IGNORE_DOMAIN_IDS (BEFORE) : $ignore_domain_ids_before + +# IGNORE_DOMAIN_IDS() +CHANGE MASTER TO IGNORE_DOMAIN_IDS=(), MASTER_USE_GTID=slave_pos; +--source include/start_slave.inc + +let $do_domain_ids_after= query_get_value(SHOW SLAVE STATUS, Replicate_Do_Domain_Ids, 1); +let $ignore_domain_ids_after= query_get_value(SHOW SLAVE STATUS, Replicate_Ignore_Domain_Ids, 1); +--echo DO_DOMAIN_IDS (AFTER) : $do_domain_ids_after +--echo IGNORE_DOMAIN_IDS (AFTER) : $ignore_domain_ids_after + +connection master; +SET @@session.gtid_domain_id=2; +BEGIN; +INSERT INTO t2 VALUES(8); +INSERT INTO t3 VALUES(8); +COMMIT; +--source include/save_master_gtid.inc + +connection slave; +--source include/sync_with_master_gtid.inc +SELECT * FROM t2; +SELECT * FROM t3; + +##### Case 10: Test CHANGE MASTER with various "incompatible" combinations. +connection slave; +--source include/stop_slave.inc + +# 10a: Both DO_DOMAIN_IDS & IGNORE_DOMAIN_IDS can't be non-empty at the same +# time. + +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); +--echo DO_DOMAIN_IDS (BEFORE) : $do_domain_ids_before +--echo IGNORE_DOMAIN_IDS (BEFORE) : $ignore_domain_ids_before + +--error ER_MASTER_INFO +CHANGE MASTER TO DO_DOMAIN_IDS=(1), IGNORE_DOMAIN_IDS=(1), MASTER_USE_GTID=SLAVE_POS; +CHANGE MASTER TO DO_DOMAIN_IDS=(1), MASTER_USE_GTID=SLAVE_POS; +--error ER_MASTER_INFO +CHANGE MASTER TO IGNORE_DOMAIN_IDS=(1), MASTER_USE_GTID=SLAVE_POS; +CHANGE MASTER TO DO_DOMAIN_IDS=(), IGNORE_DOMAIN_IDS=(1), MASTER_USE_GTID=SLAVE_POS; +--error ER_MASTER_INFO +CHANGE MASTER TO DO_DOMAIN_IDS=(1), MASTER_USE_GTID=SLAVE_POS; + +# 10b: Neither DO_DOMAIN_IDS nor IGNORE_DOMAIN_IDS can be set when +# MASTER_USE_GTID=NO + +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); +--echo DO_DOMAIN_IDS (BEFORE) : $do_domain_ids_before +--echo IGNORE_DOMAIN_IDS (BEFORE) : $ignore_domain_ids_before + +# MASTER_USE_GTID can't be set to NO when either of IGNORE_DOMAIN_IDS or +# DO_DOMAIN_IDS is non-empty. +--error ER_MASTER_INFO +CHANGE MASTER TO MASTER_USE_GTID=NO; +CHANGE MASTER TO DO_DOMAIN_IDS=(), IGNORE_DOMAIN_IDS=(), MASTER_USE_GTID=NO; +--error ER_MASTER_INFO +CHANGE MASTER TO DO_DOMAIN_IDS=(1), MASTER_USE_GTID=NO; +--error ER_MASTER_INFO +CHANGE MASTER TO IGNORE_DOMAIN_IDS=(1), MASTER_USE_GTID=NO; + +let $do_domain_ids_after= query_get_value(SHOW SLAVE STATUS, Replicate_Do_Domain_Ids, 1); +let $ignore_domain_ids_after= query_get_value(SHOW SLAVE STATUS, Replicate_Ignore_Domain_Ids, 1); +--echo DO_DOMAIN_IDS (AFTER) : $do_domain_ids_after +--echo IGNORE_DOMAIN_IDS (AFTER) : $ignore_domain_ids_after + +CHANGE MASTER TO IGNORE_DOMAIN_IDS=(1), DO_DOMAIN_IDS=(), MASTER_USE_GTID=SLAVE_POS; +--source include/start_slave.inc + +# Cleanup +connection master; +SET @@session.gtid_domain_id=2; +DROP TABLE t1, t2, t3; +--source include/save_master_gtid.inc + +connection slave; +--source include/sync_with_master_gtid.inc +--source include/stop_slave.inc +CHANGE MASTER TO DO_DOMAIN_IDS=(), IGNORE_DOMAIN_IDS=(); +--source include/start_slave.inc + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_domain_id_filter_io_crash.test b/mysql-test/suite/rpl/t/rpl_domain_id_filter_io_crash.test new file mode 100644 index 00000000..a949da0c --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_domain_id_filter_io_crash.test @@ -0,0 +1,384 @@ +--source include/have_debug.inc +--source include/have_innodb.inc +--source include/master-slave.inc + +connection master; +SET @@session.gtid_domain_id= 1; +SELECT @@session.gtid_domain_id; +CREATE TABLE t1(i INT) ENGINE=INNODB; +INSERT INTO t1 VALUES(1); +SELECT * FROM t1; +sync_slave_with_master; + +connection slave; + +call mtr.add_suppression("Slave I/O: Relay log write failure: could not queue event from master.*"); + +--echo # Case 0 : Start slave with IGNORE_DOMAIN_IDS=(), then restart +--echo # replication with IGNORE_DOMAIN_IDS=() after IO thread is +--echo # killed due to DBUG_EXECUTE_IF("+d,kill_slave_io_before_commit"). + +SELECT * FROM t1; + +--source include/stop_slave.inc +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); +--echo DO_DOMAIN_IDS (BEFORE) : $do_domain_ids_before +--echo IGNORE_DOMAIN_IDS (BEFORE) : $ignore_domain_ids_before + +CHANGE MASTER TO IGNORE_DOMAIN_IDS=(), MASTER_USE_GTID=slave_pos; +--source include/start_slave.inc +sync_with_master; + +let $do_domain_ids_after= query_get_value(SHOW SLAVE STATUS, Replicate_Do_Domain_Ids, 1); +let $ignore_domain_ids_after= query_get_value(SHOW SLAVE STATUS, Replicate_Ignore_Domain_Ids, 1); +--echo DO_DOMAIN_IDS (AFTER) : $do_domain_ids_after +--echo IGNORE_DOMAIN_IDS (AFTER) : $ignore_domain_ids_after + +SET @saved_dbug = @@GLOBAL.debug_dbug; +SET @@global.debug_dbug="d,kill_slave_io_before_commit"; + +connection master; + +START TRANSACTION; +INSERT INTO t1 VALUES(2); +INSERT INTO t1 VALUES(3); +COMMIT; +save_master_pos; +SELECT * FROM t1; + +connection slave; +--let $slave_io_errno= 1595 +--source include/wait_for_slave_io_error.inc +SELECT * FROM t1; +SET @@global.debug_dbug=@saved_dbug; + +START SLAVE io_thread; +--source include/wait_for_slave_io_to_start.inc +sync_with_master; +SELECT * FROM t1; + +--echo # Case 1 : Start slave with IGNORE_DOMAIN_IDS=(1), then restart +--echo # replication with IGNORE_DOMAIN_IDS=(1) after IO thread is +--echo # killed due to DBUG_EXECUTE_IF("+d,kill_slave_io_before_commit"). + +--source include/stop_slave.inc +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); +--echo DO_DOMAIN_IDS (BEFORE) : $do_domain_ids_before +--echo IGNORE_DOMAIN_IDS (BEFORE) : $ignore_domain_ids_before + +CHANGE MASTER TO IGNORE_DOMAIN_IDS=(1), MASTER_USE_GTID=slave_pos; +--source include/start_slave.inc +sync_with_master; + +let $do_domain_ids_after= query_get_value(SHOW SLAVE STATUS, Replicate_Do_Domain_Ids, 1); +let $ignore_domain_ids_after= query_get_value(SHOW SLAVE STATUS, Replicate_Ignore_Domain_Ids, 1); +--echo DO_DOMAIN_IDS (AFTER) : $do_domain_ids_after +--echo IGNORE_DOMAIN_IDS (AFTER) : $ignore_domain_ids_after + +SET @@global.debug_dbug="d,kill_slave_io_before_commit"; + +connection master; + +START TRANSACTION; +INSERT INTO t1 VALUES(4); +INSERT INTO t1 VALUES(5); +COMMIT; + +save_master_pos; +SELECT * FROM t1; + +connection slave; +--let $slave_io_errno= 1595 +--source include/wait_for_slave_io_error.inc +SELECT * FROM t1; +SET @@global.debug_dbug=@saved_dbug; + +START SLAVE io_thread; +--source include/wait_for_slave_io_to_start.inc +sync_with_master; +SELECT * FROM t1; + +--echo # Case 2 : Start slave with IGNORE_DOMAIN_IDS=(), then restart +--echo # replication with IGNORE_DOMAIN_IDS=(1) after IO thread is +--echo # killed due to DBUG_EXECUTE_IF("+d,kill_slave_io_before_commit"). + +--source include/stop_slave.inc +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); +--echo DO_DOMAIN_IDS (BEFORE) : $do_domain_ids_before +--echo IGNORE_DOMAIN_IDS (BEFORE) : $ignore_domain_ids_before + +CHANGE MASTER TO IGNORE_DOMAIN_IDS=(), MASTER_USE_GTID=slave_pos; +--source include/start_slave.inc +sync_with_master; + +let $do_domain_ids_after= query_get_value(SHOW SLAVE STATUS, Replicate_Do_Domain_Ids, 1); +let $ignore_domain_ids_after= query_get_value(SHOW SLAVE STATUS, Replicate_Ignore_Domain_Ids, 1); +--echo DO_DOMAIN_IDS (AFTER) : $do_domain_ids_after +--echo IGNORE_DOMAIN_IDS (AFTER) : $ignore_domain_ids_after + +SET @@global.debug_dbug="d,kill_slave_io_before_commit"; + +connection master; + +START TRANSACTION; +INSERT INTO t1 VALUES(6); +INSERT INTO t1 VALUES(7); +COMMIT; # IO thread gets killed here. + +START TRANSACTION; +INSERT INTO t1 VALUES(8); +INSERT INTO t1 VALUES(9); +COMMIT; + +SET @@session.gtid_domain_id= 2; + +START TRANSACTION; +INSERT INTO t1 VALUES(10); +INSERT INTO t1 VALUES(11); +COMMIT; + +save_master_pos; +SELECT * FROM t1; + +connection slave; +--let $slave_io_errno= 1595 +--source include/wait_for_slave_io_error.inc +SELECT * FROM t1; + +SET @@global.debug_dbug=@saved_dbug; + +--source include/stop_slave.inc +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); +--echo DO_DOMAIN_IDS (BEFORE) : $do_domain_ids_before +--echo IGNORE_DOMAIN_IDS (BEFORE) : $ignore_domain_ids_before + +CHANGE MASTER TO IGNORE_DOMAIN_IDS=(1), MASTER_USE_GTID=slave_pos; +--source include/start_slave.inc +sync_with_master; + +let $do_domain_ids_after= query_get_value(SHOW SLAVE STATUS, Replicate_Do_Domain_Ids, 1); +let $ignore_domain_ids_after= query_get_value(SHOW SLAVE STATUS, Replicate_Ignore_Domain_Ids, 1); +--echo DO_DOMAIN_IDS (AFTER) : $do_domain_ids_after +--echo IGNORE_DOMAIN_IDS (AFTER) : $ignore_domain_ids_after + +SELECT * FROM t1; + +--echo # Case 3 : Start slave with IGNORE_DOMAIN_IDS=(1), then restart +--echo # replication with IGNORE_DOMAIN_IDS=() after IO thread is +--echo # killed due to DBUG_EXECUTE_IF("+d,kill_slave_io_before_commit"). + +--source include/stop_slave.inc +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); +--echo DO_DOMAIN_IDS (BEFORE) : $do_domain_ids_before +--echo IGNORE_DOMAIN_IDS (BEFORE) : $ignore_domain_ids_before + +CHANGE MASTER TO IGNORE_DOMAIN_IDS=(1), MASTER_USE_GTID=slave_pos; +--source include/start_slave.inc +sync_with_master; + +let $do_domain_ids_after= query_get_value(SHOW SLAVE STATUS, Replicate_Do_Domain_Ids, 1); +let $ignore_domain_ids_after= query_get_value(SHOW SLAVE STATUS, Replicate_Ignore_Domain_Ids, 1); +--echo DO_DOMAIN_IDS (AFTER) : $do_domain_ids_after +--echo IGNORE_DOMAIN_IDS (AFTER) : $ignore_domain_ids_after + +SET @@global.debug_dbug="d,kill_slave_io_before_commit"; + +connection master; + +SET @@session.gtid_domain_id= 1; + +START TRANSACTION; +INSERT INTO t1 VALUES(12); +INSERT INTO t1 VALUES(13); +COMMIT; # IO thread gets killed here. + +START TRANSACTION; +INSERT INTO t1 VALUES(14); +INSERT INTO t1 VALUES(15); +COMMIT; + +SET @@session.gtid_domain_id= 2; +START TRANSACTION; +INSERT INTO t1 VALUES(16); +INSERT INTO t1 VALUES(17); +COMMIT; + +save_master_pos; +SELECT * FROM t1; + +connection slave; +--let $slave_io_errno= 1595 +--source include/wait_for_slave_io_error.inc +SELECT * FROM t1; + +SET @@global.debug_dbug=@saved_dbug; + +--source include/stop_slave.inc +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); +--echo DO_DOMAIN_IDS (BEFORE) : $do_domain_ids_before +--echo IGNORE_DOMAIN_IDS (BEFORE) : $ignore_domain_ids_before + +CHANGE MASTER TO IGNORE_DOMAIN_IDS=(), MASTER_USE_GTID=slave_pos; +--source include/start_slave.inc +sync_with_master; + +let $do_domain_ids_after= query_get_value(SHOW SLAVE STATUS, Replicate_Do_Domain_Ids, 1); +let $ignore_domain_ids_after= query_get_value(SHOW SLAVE STATUS, Replicate_Ignore_Domain_Ids, 1); +--echo DO_DOMAIN_IDS (AFTER) : $do_domain_ids_after +--echo IGNORE_DOMAIN_IDS (AFTER) : $ignore_domain_ids_after + +SELECT * FROM t1; + +--echo # Case 4 : Start slave with IGNORE_DOMAIN_IDS=(1), then restart +--echo # replication with IGNORE_DOMAIN_IDS=() after IO thread is +--echo # killed due to DBUG_EXECUTE_IF("+d,kill_slave_io_after_2_events"). + +--source include/stop_slave.inc +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); +--echo DO_DOMAIN_IDS (BEFORE) : $do_domain_ids_before +--echo IGNORE_DOMAIN_IDS (BEFORE) : $ignore_domain_ids_before + +CHANGE MASTER TO IGNORE_DOMAIN_IDS=(1), MASTER_USE_GTID=slave_pos; +--source include/start_slave.inc +sync_with_master; + +let $do_domain_ids_after= query_get_value(SHOW SLAVE STATUS, Replicate_Do_Domain_Ids, 1); +let $ignore_domain_ids_after= query_get_value(SHOW SLAVE STATUS, Replicate_Ignore_Domain_Ids, 1); +--echo DO_DOMAIN_IDS (AFTER) : $do_domain_ids_after +--echo IGNORE_DOMAIN_IDS (AFTER) : $ignore_domain_ids_after + +SET @@global.debug_dbug="d,kill_slave_io_after_2_events"; + +connection master; + +SET @@session.gtid_domain_id= 1; + +START TRANSACTION; +INSERT INTO t1 VALUES(18); +INSERT INTO t1 VALUES(19); # IO thread gets killed here. +COMMIT; + +START TRANSACTION; +INSERT INTO t1 VALUES(20); +INSERT INTO t1 VALUES(21); +COMMIT; + +SET @@session.gtid_domain_id= 2; +START TRANSACTION; +INSERT INTO t1 VALUES(22); +INSERT INTO t1 VALUES(23); +COMMIT; + +save_master_pos; +SELECT * FROM t1; + +connection slave; +--let $slave_io_errno= 1595 +--source include/wait_for_slave_io_error.inc +SELECT * FROM t1; + +SET @@global.debug_dbug=@saved_dbug; + +--source include/stop_slave.inc +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); +--echo DO_DOMAIN_IDS (BEFORE) : $do_domain_ids_before +--echo IGNORE_DOMAIN_IDS (BEFORE) : $ignore_domain_ids_before + +CHANGE MASTER TO IGNORE_DOMAIN_IDS=(), MASTER_USE_GTID=slave_pos; +--source include/start_slave.inc +sync_with_master; + +let $do_domain_ids_after= query_get_value(SHOW SLAVE STATUS, Replicate_Do_Domain_Ids, 1); +let $ignore_domain_ids_after= query_get_value(SHOW SLAVE STATUS, Replicate_Ignore_Domain_Ids, 1); +--echo DO_DOMAIN_IDS (AFTER) : $do_domain_ids_after +--echo IGNORE_DOMAIN_IDS (AFTER) : $ignore_domain_ids_after + +SELECT * FROM t1; + +--echo # Case 5 : Start slave with IGNORE_DOMAIN_IDS=(), then restart +--echo # replication with IGNORE_DOMAIN_IDS=(1) after IO thread is +--echo # killed due to DBUG_EXECUTE_IF("+d,kill_slave_io_after_2_events"). + +--source include/stop_slave.inc +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); +--echo DO_DOMAIN_IDS (BEFORE) : $do_domain_ids_before +--echo IGNORE_DOMAIN_IDS (BEFORE) : $ignore_domain_ids_before + +CHANGE MASTER TO IGNORE_DOMAIN_IDS=(), MASTER_USE_GTID=slave_pos; +--source include/start_slave.inc +sync_with_master; + +let $do_domain_ids_after= query_get_value(SHOW SLAVE STATUS, Replicate_Do_Domain_Ids, 1); +let $ignore_domain_ids_after= query_get_value(SHOW SLAVE STATUS, Replicate_Ignore_Domain_Ids, 1); +--echo DO_DOMAIN_IDS (AFTER) : $do_domain_ids_after +--echo IGNORE_DOMAIN_IDS (AFTER) : $ignore_domain_ids_after + +SET @@global.debug_dbug="d,kill_slave_io_after_2_events"; + +connection master; + +SET @@session.gtid_domain_id= 1; + +START TRANSACTION; +INSERT INTO t1 VALUES(24); +INSERT INTO t1 VALUES(25); # IO thread gets killed here. +COMMIT; + +START TRANSACTION; +INSERT INTO t1 VALUES(26); +INSERT INTO t1 VALUES(27); +COMMIT; + +SET @@session.gtid_domain_id= 2; +START TRANSACTION; +INSERT INTO t1 VALUES(28); +INSERT INTO t1 VALUES(29); +COMMIT; + +save_master_pos; +SELECT * FROM t1; + +connection slave; +--let $slave_io_errno= 1595 +--source include/wait_for_slave_io_error.inc +SELECT * FROM t1; + +SET @@global.debug_dbug=@saved_dbug; + +--source include/stop_slave.inc +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); +--echo DO_DOMAIN_IDS (BEFORE) : $do_domain_ids_before +--echo IGNORE_DOMAIN_IDS (BEFORE) : $ignore_domain_ids_before + +CHANGE MASTER TO IGNORE_DOMAIN_IDS=(1), MASTER_USE_GTID=slave_pos; +--source include/start_slave.inc +sync_with_master; + +let $do_domain_ids_after= query_get_value(SHOW SLAVE STATUS, Replicate_Do_Domain_Ids, 1); +let $ignore_domain_ids_after= query_get_value(SHOW SLAVE STATUS, Replicate_Ignore_Domain_Ids, 1); +--echo DO_DOMAIN_IDS (AFTER) : $do_domain_ids_after +--echo IGNORE_DOMAIN_IDS (AFTER) : $ignore_domain_ids_after + +SELECT * FROM t1; + +# Cleanup +connection master; +DROP TABLE t1; +sync_slave_with_master; + +connection slave; +--source include/stop_slave.inc +CHANGE MASTER TO DO_DOMAIN_IDS=(), IGNORE_DOMAIN_IDS=(); +--source include/start_slave.inc +SET @@GLOBAL.debug_dbug = @saved_dbug; +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_domain_id_filter_master_crash.test b/mysql-test/suite/rpl/t/rpl_domain_id_filter_master_crash.test new file mode 100644 index 00000000..6dafab19 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_domain_id_filter_master_crash.test @@ -0,0 +1,87 @@ +--source include/have_innodb.inc +--source include/have_debug.inc +# Valgrind does not work well with test that crashes the server +--source include/not_valgrind.inc +--source include/master-slave.inc + +connection master; + +call mtr.add_suppression("mysqld: Table '.*gtid_slave_pos' is marked as crashed and should be repaired"); +call mtr.add_suppression("Checking table: './mysql/gtid_slave_pos'"); +call mtr.add_suppression("mysql.gtid_slave_pos: 1 client is using or hasn't closed the table properly"); +SET @@session.gtid_domain_id= 0; + +create table ti (a int auto_increment primary key) engine=innodb; +create table tm (a int auto_increment primary key) engine=myisam; + +insert into ti set a=null; +insert into tm set a=null; + +save_master_pos; + +connection slave; +sync_with_master; +--source include/stop_slave.inc + +select * from ti; +select * from tm; + +connection master; +SET @@session.gtid_domain_id= 1; + +begin; +insert into ti set a=null; +insert into tm set a=null; +commit; + +SET @@session.gtid_domain_id= 0; +insert into ti set a=null; +insert into tm set a=null; + +set @@global.debug_dbug="+d,crash_before_send_xid"; +--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect + +connection slave; +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); +--echo DO_DOMAIN_IDS (BEFORE) : $do_domain_ids_before +--echo IGNORE_DOMAIN_IDS (BEFORE) : $ignore_domain_ids_before + +# IGNORE_DOMAIN_IDS=(1) +CHANGE MASTER TO IGNORE_DOMAIN_IDS=(1), MASTER_USE_GTID=slave_pos; +--source include/start_slave.inc + +let $do_domain_ids_after= query_get_value(SHOW SLAVE STATUS, Replicate_Do_Domain_Ids, 1); +let $ignore_domain_ids_after= query_get_value(SHOW SLAVE STATUS, Replicate_Ignore_Domain_Ids, 1); +--echo DO_DOMAIN_IDS (AFTER) : $do_domain_ids_after +--echo IGNORE_DOMAIN_IDS (AFTER) : $ignore_domain_ids_after + +connection master; +--source include/wait_until_disconnected.inc +--enable_reconnect +--let $rpl_server_number=1 +--source include/rpl_start_server.inc +#--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--source include/wait_until_connected_again.inc +--echo # Master has restarted successfully +save_master_pos; + +--connection slave +--source include/stop_slave.inc +--source include/start_slave.inc +sync_with_master; +select * from ti; +select * from tm; + +# Cleanup +--connection master +drop table ti; +drop table tm; +sync_slave_with_master; + +--connection slave +--source include/stop_slave.inc +CHANGE MASTER TO DO_DOMAIN_IDS=(), IGNORE_DOMAIN_IDS=(), MASTER_USE_GTID=NO; +--source include/start_slave.inc + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_domain_id_filter_parallel.test b/mysql-test/suite/rpl/t/rpl_domain_id_filter_parallel.test new file mode 100644 index 00000000..902f6b52 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_domain_id_filter_parallel.test @@ -0,0 +1,196 @@ +--source include/have_innodb.inc +--source include/have_debug.inc +--source include/have_debug_sync.inc +--let $rpl_topology=1->2 +--source include/rpl_init.inc + +--connection server_2 +SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads; +--source include/stop_slave.inc +SET GLOBAL slave_parallel_threads=10; + +##### Case 0 : When both DO_DOMAIN_IDS and IGNORE_DOMAIN_IDS are empty. + +--connection server_2 +CHANGE MASTER TO master_use_gtid=slave_pos, DO_DOMAIN_IDS=(), IGNORE_DOMAIN_IDS=(); +--source include/start_slave.inc + +--connection server_1 +SELECT @@session.gtid_domain_id; +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +CREATE TABLE t1 (a int PRIMARY KEY) ENGINE=MyISAM; +CREATE TABLE t2 (a int PRIMARY KEY) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1); +INSERT INTO t2 VALUES (1); +--save_master_pos + +--connection server_2 +--sync_with_master + +# Block the table t1 to simulate a replicated query taking a long time. +--connect (con_temp1,127.0.0.1,root,,test,$SERVER_MYPORT_2,) +LOCK TABLE t1 WRITE; + +--connection server_1 +SET @@session.gtid_domain_id=1; +# This query will be blocked on the slave until UNLOCK TABLES. +INSERT INTO t1 VALUES (2); +SET @@session.gtid_domain_id=0; +# These t2 queries can be replicated in parallel with the prior t1 query, as +# they are in a separate replication domain. +INSERT INTO t2 VALUES (2); +INSERT INTO t2 VALUES (3); +BEGIN; +INSERT INTO t2 VALUES (4); +INSERT INTO t2 VALUES (5); +COMMIT; +INSERT INTO t2 VALUES (6); + +--connection server_2 +--let $wait_condition= SELECT COUNT(*) = 6 FROM t2 +--source include/wait_condition.inc + +SELECT * FROM t2 ORDER by a; + +--connection con_temp1 +SELECT * FROM t1; +UNLOCK TABLES; + +--connection server_2 +--let $wait_condition= SELECT COUNT(*) = 2 FROM t1 +--source include/wait_condition.inc + +SELECT * FROM t1 ORDER BY a; + +##### Case 1 : When DO_DOMAIN_IDS=(1) + +--connection server_2 +--source include/stop_slave.inc +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); +--echo DO_DOMAIN_IDS (BEFORE) : $do_domain_ids_before +--echo IGNORE_DOMAIN_IDS (BEFORE) : $ignore_domain_ids_before + +# Replicate events belonging to "domain_id 1". +CHANGE MASTER TO DO_DOMAIN_IDS=(1), MASTER_USE_GTID=slave_pos; +--source include/start_slave.inc +sync_with_master; + +let $do_domain_ids_after= query_get_value(SHOW SLAVE STATUS, Replicate_Do_Domain_Ids, 1); +let $ignore_domain_ids_after= query_get_value(SHOW SLAVE STATUS, Replicate_Ignore_Domain_Ids, 1); +--echo DO_DOMAIN_IDS (AFTER) : $do_domain_ids_after +--echo IGNORE_DOMAIN_IDS (AFTER) : $ignore_domain_ids_after + +--connection server_2 +--sync_with_master + +# Block the table t1 to simulate a replicated query taking a long time. +--connection con_temp1 +LOCK TABLE t1 WRITE; + +--connection server_1 +SET @@session.gtid_domain_id=0; +# This query will be blocked on the slave until UNLOCK TABLES. +# But, since DO_DOMAIN_IDS=(1), it will be filtered out on slave. +INSERT INTO t1 VALUES (3); + +SET @@session.gtid_domain_id=1; +# These t2 queries can be replicated in parallel with the prior t1 query, as +# they are in a separate replication domain. +INSERT INTO t2 VALUES (7); +INSERT INTO t2 VALUES (8); +BEGIN; +INSERT INTO t2 VALUES (9); +INSERT INTO t2 VALUES (10); +COMMIT; +INSERT INTO t2 VALUES (11); + +--connection server_2 +--let $wait_condition= SELECT COUNT(*) = 11 FROM t2 +--source include/wait_condition.inc + +SELECT * FROM t2 ORDER by a; + +--connection con_temp1 +SELECT * FROM t1; +UNLOCK TABLES; + +--connection server_2 +--let $wait_condition= SELECT COUNT(*) = 2 FROM t1 +--source include/wait_condition.inc + +SELECT * FROM t1 ORDER BY a; + +##### Case 2 : When IGNORE_DOMAIN_IDS=(1) + +--connection server_2 +--source include/stop_slave.inc +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); +--echo DO_DOMAIN_IDS (BEFORE) : $do_domain_ids_before +--echo IGNORE_DOMAIN_IDS (BEFORE) : $ignore_domain_ids_before + +# Replicate events belonging to "domain_id 1". +CHANGE MASTER TO DO_DOMAIN_IDS=(), IGNORE_DOMAIN_IDS=(1), MASTER_USE_GTID=slave_pos; +--source include/start_slave.inc +sync_with_master; + +let $do_domain_ids_after= query_get_value(SHOW SLAVE STATUS, Replicate_Do_Domain_Ids, 1); +let $ignore_domain_ids_after= query_get_value(SHOW SLAVE STATUS, Replicate_Ignore_Domain_Ids, 1); +--echo DO_DOMAIN_IDS (AFTER) : $do_domain_ids_after +--echo IGNORE_DOMAIN_IDS (AFTER) : $ignore_domain_ids_after + +--connection server_2 +--sync_with_master + +# Block the table t1 to simulate a replicated query taking a long time. +--connection con_temp1 +LOCK TABLE t1 WRITE; + +--connection server_1 +SET @@session.gtid_domain_id=1; +# This query will be blocked on the slave until UNLOCK TABLES. However, since +# IGNORE_DOMAIN_IDS=(1), it will be filtered out on slave. +INSERT INTO t1 VALUES (4); +SET @@session.gtid_domain_id=0; +# These t2 queries can be replicated in parallel with the prior t1 query, as +# they are in a separate replication domain. +INSERT INTO t2 VALUES (12); +INSERT INTO t2 VALUES (13); +BEGIN; +INSERT INTO t2 VALUES (14); +INSERT INTO t2 VALUES (15); +COMMIT; +INSERT INTO t2 VALUES (16); + +--connection server_2 +--let $wait_condition= SELECT COUNT(*) = 16 FROM t2 +--source include/wait_condition.inc + +SELECT * FROM t2 ORDER by a; + +--connection con_temp1 +SELECT * FROM t1; +UNLOCK TABLES; + +--connection server_2 +--let $wait_condition= SELECT COUNT(*) = 2 FROM t1 +--source include/wait_condition.inc + +SELECT * FROM t1 ORDER BY a; +SELECT * FROM t2; + +--echo # Restore original settings. +--connection server_1 +SET @@session.gtid_domain_id=0; +DROP TABLE t1, t2; +--save_master_pos + +--connection server_2 +--sync_with_master +--source include/stop_slave.inc +SET GLOBAL slave_parallel_threads= @old_parallel_threads; +CHANGE MASTER TO DO_DOMAIN_IDS=(), IGNORE_DOMAIN_IDS=(); +--source include/start_slave.inc + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_domain_id_filter_restart.test b/mysql-test/suite/rpl/t/rpl_domain_id_filter_restart.test new file mode 100644 index 00000000..8083b8f2 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_domain_id_filter_restart.test @@ -0,0 +1,73 @@ +--source include/master-slave.inc + +# +# Test for domain-id based filter on slave restart in GTID-mode. +# + + +connection slave; + +source include/stop_slave.inc; +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); +--echo DO_DOMAIN_IDS (BEFORE) : $do_domain_ids_before +--echo IGNORE_DOMAIN_IDS (BEFORE) : $ignore_domain_ids_before + +# Ignore events belonging to "domain_id 1". +CHANGE MASTER TO IGNORE_DOMAIN_IDS=(1), MASTER_USE_GTID=slave_pos; +source include/start_slave.inc; + +let $do_domain_ids_after= query_get_value(SHOW SLAVE STATUS, Replicate_Do_Domain_Ids, 1); +let $ignore_domain_ids_after= query_get_value(SHOW SLAVE STATUS, Replicate_Ignore_Domain_Ids, 1); +--echo DO_DOMAIN_IDS (AFTER) : $do_domain_ids_after +--echo IGNORE_DOMAIN_IDS (AFTER) : $ignore_domain_ids_after + +connection master; +SET @@session.gtid_domain_id= 0; +CREATE TABLE t1(i INT); +CREATE TABLE t2(i INT); + +INSERT INTO t1 VALUES(1); +SELECT * FROM t1; + +SET @@session.gtid_domain_id= 1; +# the following will get filtered out. +INSERT INTO t2 VALUES(1); +SELECT * FROM t2; + +sync_slave_with_master; + +connection slave; +SELECT * FROM t1; +SELECT * FROM t2; + +# restart the slave +--let $rpl_server_number= 2 +--source include/rpl_restart_server.inc + +# Replicate_Do_Domain_Ids/Replicate_Ignore_Domain_Ids should reinitialize +# properly on restart. +connection slave; +let $do_domain_ids_after= query_get_value(SHOW SLAVE STATUS, Replicate_Do_Domain_Ids, 1); +let $ignore_domain_ids_after= query_get_value(SHOW SLAVE STATUS, Replicate_Ignore_Domain_Ids, 1); +--echo DO_DOMAIN_IDS (AFTER RESTART) : $do_domain_ids_after +--echo IGNORE_DOMAIN_IDS (AFTER RESTART) : $ignore_domain_ids_after + +# Now, lets clear IGNORE_DOMAIN_IDS. +CHANGE MASTER TO IGNORE_DOMAIN_IDS=(); +--source include/start_slave.inc + +let $do_domain_ids_after= query_get_value(SHOW SLAVE STATUS, Replicate_Do_Domain_Ids, 1); +let $ignore_domain_ids_after= query_get_value(SHOW SLAVE STATUS, Replicate_Ignore_Domain_Ids, 1); +--echo DO_DOMAIN_IDS (AFTER) : $do_domain_ids_after +--echo IGNORE_DOMAIN_IDS (AFTER) : $ignore_domain_ids_after + +SELECT * FROM t1; +SELECT * FROM t2; + +connection master; +SET @@session.gtid_domain_id= 0; +DROP TABLE t1, t2; +sync_slave_with_master; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_drop.test b/mysql-test/suite/rpl/t/rpl_drop.test new file mode 100644 index 00000000..7b887334 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_drop.test @@ -0,0 +1,12 @@ +# Testcase for BUG#4552 (DROP on two tables, one of which does not +# exist, must be binlogged with a non-zero error code) +source include/master-slave.inc; + +create table t1 (a int); +--error 1051 +drop table t1, t2; +--sync_slave_with_master + +# End of 4.1 tests + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_drop_db.test b/mysql-test/suite/rpl/t/rpl_drop_db.test new file mode 100644 index 00000000..372afaa6 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_drop_db.test @@ -0,0 +1,62 @@ +# test case for BUG#4680 -- if there are extra files in the db directory +# dropping the db on the master causes replication problems + +-- source include/master-slave.inc +connection master; + +--disable_warnings +drop database if exists mysqltest1; +--enable_warnings +create database mysqltest1; +create table mysqltest1.t1 (n int); +insert into mysqltest1.t1 values (1); +select * from mysqltest1.t1 into outfile 'mysqltest1/f1.txt'; +create table mysqltest1.t2 (n int); +create table mysqltest1.t3 (n int); +--replace_result \\ / 66 39 93 39 17 39 247 39 41 39 "File exists" "Directory not empty" +--error ER_DB_DROP_RMDIR +drop database mysqltest1; +use mysqltest1; +show tables; + +# test the branch of the code that deals with the query buffer overflow + +--disable_query_log +let $1=50; +while ($1) +{ + eval create table mysqltest1.mysqltest_long_table_name$1 (n int); + dec $1; +} +--enable_query_log + +--replace_result \\ / 66 39 93 39 17 39 247 39 41 39 "File exists" "Directory not empty" +--error ER_DB_DROP_RMDIR +drop database mysqltest1; +use mysqltest1; +show tables; +use test; +create table t1 (n int); +insert into t1 values (1234); +sync_slave_with_master; + +connection slave; +use mysqltest1; +show tables; +use test; +select * from t1; + +#cleanup +connection master; + +# Remove the "extra" file created above +let $MYSQLD_DATADIR= `select @@datadir`; +remove_file $MYSQLD_DATADIR/mysqltest1/f1.txt; + +use test; +drop table t1; +drop database mysqltest1; + +sync_slave_with_master; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_drop_db_fail.test b/mysql-test/suite/rpl/t/rpl_drop_db_fail.test new file mode 100644 index 00000000..c13bae1c --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_drop_db_fail.test @@ -0,0 +1,34 @@ +############################################################################### +# Bug#20041860: SLAVE ERROR WHEN DROP DATABASE +# +# Test: +# ===== +# Create two databases such that one database has a dependency over the other +# database and try to drop the database which has a dependency. This should +# not cause slave to break. +############################################################################### +--source include/have_innodb.inc +--source include/master-slave.inc + +connection master; +CREATE DATABASE IF NOT EXISTS db1; +CREATE DATABASE IF NOT EXISTS db2; + +use db1; +CREATE TABLE a(id INT); +CREATE VIEW v AS SELECT * FROM a; +CREATE TABLE table_father(id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(20)) ENGINE=INNODB; +--sync_slave_with_master + +connection master; +use db2; +CREATE TABLE table_child(id INT PRIMARY KEY, info VARCHAR(20), father_id INT) ENGINE=INNODB; +ALTER TABLE table_child ADD CONSTRAINT aaa FOREIGN KEY (father_id) REFERENCES db1.table_father(id); + +--error ER_ROW_IS_REFERENCED_2 +DROP DATABASE db1; +DROP DATABASE db2; +--sync_slave_with_master +--connection master +DROP DATABASE db1; +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_drop_temp-slave.opt b/mysql-test/suite/rpl/t/rpl_drop_temp-slave.opt new file mode 100644 index 00000000..2f9244c6 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_drop_temp-slave.opt @@ -0,0 +1,2 @@ +--replicate-ignore-table=mysqltest.t2 + diff --git a/mysql-test/suite/rpl/t/rpl_drop_temp.test b/mysql-test/suite/rpl/t/rpl_drop_temp.test new file mode 100644 index 00000000..7158e2a8 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_drop_temp.test @@ -0,0 +1,94 @@ +############################################## +# Change Author: JBM +# Change Date: 2006-02-07 +# Change: Added ENGINE=MyISAM +############################################## +source include/have_binlog_format_mixed_or_statement.inc; +source include/master-slave.inc; + +--disable_warnings +create database if not exists mysqltest; +--enable_warnings + +connect (con_temp,127.0.0.1,root,,test,$MASTER_MYPORT,); + +connection con_temp; +use mysqltest; +create temporary table mysqltest.t1 (n int)ENGINE=MyISAM; +create temporary table mysqltest.t2 (n int)ENGINE=MyISAM; + +disconnect con_temp; +--source include/wait_until_disconnected.inc + +connection master; +-- let $wait_binlog_event= DROP +-- source include/wait_for_binlog_event.inc +sync_slave_with_master; + +connection slave; +show status like 'Slave_open_temp_tables'; +# Cleanup +connection master; +drop database mysqltest; +sync_slave_with_master; + +# +# Bug#49137 +# This test verifies if DROP MULTI TEMPORARY TABLE +# will cause different errors on master and slave, +# when one or more of these tables do not exist. +# + +connection master; +DROP TEMPORARY TABLE IF EXISTS tmp1; +CREATE TEMPORARY TABLE t1 ( a int ); +--error 1051 +DROP TEMPORARY TABLE t1, t2; +--error 1051 +DROP TEMPORARY TABLE tmp2; +sync_slave_with_master; + +connection slave; +stop slave; +wait_for_slave_to_stop; + +connection master; +CREATE TEMPORARY TABLE tmp3 (a int); +DROP TEMPORARY TABLE tmp3; + +connection slave; +SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1; +START SLAVE; + +connection master; +sync_slave_with_master; + + +# +# BUG#54842: DROP TEMPORARY TABLE not binlogged after manual switching binlog format to ROW +# + +--source include/rpl_reset.inc +--connection master + +CREATE TABLE t1 ( i INT ); +--sync_slave_with_master +SHOW STATUS LIKE 'Slave_open_temp_tables'; + +--connect(con1,localhost,root,,) +CREATE TEMPORARY TABLE ttmp1 ( i INT ); +SET SESSION binlog_format=ROW; +--disconnect con1 + +-- connection master +--let $wait_binlog_event= DROP +--source include/wait_for_binlog_event.inc +--sync_slave_with_master +SHOW STATUS LIKE 'Slave_open_temp_tables'; + +--connection master +--source include/show_binlog_events.inc +DROP TABLE t1; + +# End of 4.1 tests +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_drop_temp_table_invalid_lex.test b/mysql-test/suite/rpl/t/rpl_drop_temp_table_invalid_lex.test new file mode 100644 index 00000000..475afef1 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_drop_temp_table_invalid_lex.test @@ -0,0 +1,41 @@ +# ==== Purpose ==== +# +# Test verifies that no ASAN issues are reported at the time of writing DROP +# TEMPORARY TABLE statements to binary log as part of session cleanup. +# +# ==== Implementation ==== +# +# Steps: +# 1 - Create a new connection named 'con1'. +# 2 - Create a temporary table named 'tmp' as part of connection 'con1'. +# 3 - Try to disconnect the current session when a CREATE .. SELECT +# statement is in the middle of execution. +# 4 - Observe that no ASAN issue is reported. +# +# ==== References ==== +# +# MDEV-19716: ASAN use-after-poison in Query_log_event::Query_log_event / +# THD::log_events_and_free_tmp_shares + +--source include/have_binlog_format_mixed_or_statement.inc +--source include/master-slave.inc + +--connect (con1,localhost,root,,) +CREATE TEMPORARY TABLE tmp (a INT); + +--send CREATE TABLE non_existing_db.t SELECT 1 AS b +--disconnect con1 +--source include/wait_until_disconnected.inc + +--connection master +--let $wait_binlog_event= DROP +--source include/wait_for_binlog_event.inc +sync_slave_with_master; + +--connection slave +--let $open_temp_tbl_count=query_get_value(show status like 'Slave_open_temp_tables', Value, 1) +--let $assert_cond= "open_temp_tbl_count" = 0 +--let $assert_text= "Slave_open_temp_tables count should be 0" +--source include/assert.inc + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_drop_view.test b/mysql-test/suite/rpl/t/rpl_drop_view.test new file mode 100644 index 00000000..1893dd21 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_drop_view.test @@ -0,0 +1,35 @@ +# test case for bug#30998 +# Drop View breaks replication if view does not exist +# + +source include/master-slave.inc; +--disable_warnings +drop table if exists t1, t2; +drop view if exists v1, v2, v3, not_exist_view; +--enable_warnings +create table t1 (a int); +create table t2 (b int); +create table t3 (c int); +create view v1 as select * from t1; +create view v2 as select * from t2; +create view v3 as select * from t3; +--error ER_UNKNOWN_VIEW +drop view not_exist_view; +--error ER_UNKNOWN_VIEW +drop view v1, not_exist_view; +--error 1146 +select * from v1; +drop view v2, v3; +sync_slave_with_master; +--error 1146 +select * from v1; +--error 1146 +select * from v2; +--error 1146 +select * from v3; + +--echo ==== clean up ==== +connection master; +drop table t1, t2, t3; +sync_slave_with_master; +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_dual_pos_advance.test b/mysql-test/suite/rpl/t/rpl_dual_pos_advance.test new file mode 100644 index 00000000..618576f5 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_dual_pos_advance.test @@ -0,0 +1,97 @@ +# This test checks that in a dual-head setup +# A->B->A, where A has --log-slave-updates (why would it? +# assume that there is a C as slave of A), +# then the Exec_master_log_pos of SHOW SLAVE STATUS does +# not stay too low on B(BUG#13023 due to events ignored because +# of their server id). +# It also will test BUG#13861. + +source include/have_innodb.inc; + +--let $rpl_topology= 1->2->1 +--source include/rpl_init.inc + +# now we test it + +connection server_2; + +create table t1 (n int); +let $master_log_file= query_get_value(SHOW MASTER STATUS, File, 1); +let $master_log_pos_1= query_get_value(SHOW MASTER STATUS, Position, 1); +let $master_log_pos_1= `SELECT $master_log_pos_1 + 3`; + +--sync_slave_with_master server_1 + +# +# BUG#13861 - START SLAVE UNTIL may stop 1 evnt too late if +# log-slave-updates and circul repl +# +source include/stop_slave.inc; + +create table t2 (n int); # create one ignored event + +--sync_slave_with_master server_2 + +show tables; + +create table t3 (n int) engine=innodb; +let $master_log_pos_2= query_get_value(SHOW MASTER STATUS, Position, 1); +let $master_log_pos_2= `SELECT $master_log_pos_2 + 5`; +set @a=1; +insert into t3 values(@a); +let $master_log_pos_3= query_get_value(SHOW MASTER STATUS, Position, 1); +let $master_log_pos_3= `SELECT $master_log_pos_3 + 5`; +begin; +insert into t3 values(2); +insert into t3 values(3); +commit; +insert into t3 values(4); + + +connection server_1; + +# bug is that START SLAVE UNTIL may stop too late, we test that by +# asking it to stop before creation of t3. + +--replace_result $master_log_file MASTER_LOG_FILE $master_log_pos_1 MASTER_LOG_POS +eval start slave until master_log_file="$master_log_file",master_log_pos=$master_log_pos_1; +--source include/wait_for_slave_sql_to_stop.inc + +# then BUG#13861 causes t3 to show up below (because stopped too +# late). + +show tables; + +# ensure that we do not break set @a=1; insert into t3 values(@a); +--replace_result $master_log_file MASTER_LOG_FILE $master_log_pos_2 MASTER_LOG_POS +eval start slave until master_log_file="$master_log_file",master_log_pos=$master_log_pos_2; +--source include/wait_for_slave_sql_to_stop.inc +select * from t3; + +# ensure that we do not break transaction +--replace_result $master_log_file MASTER_LOG_FILE $master_log_pos_3 MASTER_LOG_POS +eval start slave until master_log_file="$master_log_file",master_log_pos=$master_log_pos_3; +--source include/wait_for_slave_sql_to_stop.inc +select * from t3; + +source include/start_slave.inc; + +# BUG#13023 is that Exec_master_log_pos may stay too low "forever": + +connection server_1; + +create table t4 (n int); # create 3 ignored events +create table t5 (n int); +create table t6 (n int); + +--sync_slave_with_master server_2 + +# then BUG#13023 caused hang below ("master" looks behind, while it's +# not in terms of updates done). +--sync_slave_with_master server_1 + +show tables; + +# cleanup +drop table t1, t2, t3, t4, t5, t6; +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_dump_request_retry_warning.test b/mysql-test/suite/rpl/t/rpl_dump_request_retry_warning.test new file mode 100644 index 00000000..d750d44a --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_dump_request_retry_warning.test @@ -0,0 +1,60 @@ +# ==== Purpose ==== +# +# Test verifies that, due to a temporary network error, if request dump +# command specific packet write operation fails then the write error gets +# handled appropriately. Further retry will be initiated with appropriate +# slave registration on master. This will ensure that master has all the +# details of slave and no warnings are reported on the master side. +# +# ==== Implementation ==== +# +# Steps: +# 0 - Skip the slave start. +# 1 - Enable debug simulation which will simulate packet write error during +# dump request command execution. +# 2 - Start the slave. Observe that slave is able to reconnect post +# temporary network write error. +# +# ==== References ==== +# +# MDEV-14203: rpl.rpl_extra_col_master_myisam, +# rpl.rpl_slave_load_tmpdir_not_exist failed in buildbot with a +# warning +# +# MDEV-13258: rpl.rpl_skip_replication, rpl.rpl_set_statement_default_master +# failed in buildbot +# + +--source include/have_debug.inc +--source include/have_debug_sync.inc +--let $rpl_skip_start_slave=1 +--source include/master-slave.inc + +# Do an insert on master +CREATE TABLE t1(a int); +INSERT INTO t1 VALUES(1); + +# Add a debug point and start the slave so that dump request fails. +connection slave; +SET @saved_dbug = @@GLOBAL.debug_dbug; +SET @@global.debug_dbug= 'd,simulate_error_on_packet_write'; + +START SLAVE; +SET DEBUG_SYNC= 'now WAIT_FOR parked'; +SET @@GLOBAL.debug_dbug = @saved_dbug; +SET DEBUG_SYNC= 'now SIGNAL continue'; +SET DEBUG_SYNC= 'RESET'; + +--source include/wait_for_slave_io_to_start.inc +--source include/wait_for_slave_sql_to_start.inc + +# Sync the slave and verify that slave has caught up with the master. +connection master; +--source include/sync_slave_sql_with_master.inc +SELECT * FROM t1; + +# Cleanup +connection master; +DROP TABLE t1; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_empty_master_host.test b/mysql-test/suite/rpl/t/rpl_empty_master_host.test new file mode 100644 index 00000000..0fc2d11a --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_empty_master_host.test @@ -0,0 +1,53 @@ +# +# BUG +# --- +# BUG#28796: CHANGE MASTER TO MASTER_HOST="" leads to invalid master.info +# +# Description +# ----------- +# +# This test aims at: +# i) verifying that an error is thrown when setting MASTER_HOST='' +# ii) no error is thrown when setting non empty MASTER_HOST +# iii) replication works after setting a correct host name/ip +# +# Implementation is performed by feeding different values (according +# to i), ii) and iii) ) to CHANGE MASTER TO MASTER_HOST= x and checking +# along the way if error/no error is thrown and/or if replication starts +# working when expected. + +--source include/have_binlog_format_mixed.inc +--source include/master-slave.inc + +connection slave; +STOP SLAVE; +--source include/wait_for_slave_to_stop.inc + +let $master_host= query_get_value(SHOW SLAVE STATUS, Master_Host, 1); +--echo Master_Host = '$master_host' (expected '127.0.0.1') + +# attempt to change to an empty master host should +# result in error ER_WRONG_ARGUMENTS: "Incorrect arguments to ..." +error ER_WRONG_ARGUMENTS; +CHANGE MASTER TO MASTER_HOST=""; + +# show slave status still holds previous information +let $master_host= query_get_value(SHOW SLAVE STATUS, Master_Host, 1); +--echo Master_Host = '$master_host' (expected '127.0.0.1') + +# changing master to other than empty master host succeeds +CHANGE MASTER TO MASTER_HOST="foo"; + +# show slave status should hold "foo" as master host +let $master_host= query_get_value(SHOW SLAVE STATUS, Master_Host, 1); +--echo Master_Host = '$master_host' (expected 'foo') + +# changing back to localhost +CHANGE MASTER TO MASTER_HOST="127.0.0.1"; +let $master_host= query_get_value(SHOW SLAVE STATUS, Master_Host, 1); +--echo Master_Host = '$master_host' (expected '127.0.0.1') + +# start slave must succeed. +START SLAVE; +--source include/wait_for_slave_to_start.inc +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_err_ignoredtable-slave.opt b/mysql-test/suite/rpl/t/rpl_err_ignoredtable-slave.opt new file mode 100644 index 00000000..cb49119b --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_err_ignoredtable-slave.opt @@ -0,0 +1 @@ +--replicate-ignore-table=test.t1 --replicate-ignore-table=test.t2 --replicate-ignore-table=test.t3 diff --git a/mysql-test/suite/rpl/t/rpl_err_ignoredtable.test b/mysql-test/suite/rpl/t/rpl_err_ignoredtable.test new file mode 100644 index 00000000..9aee3582 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_err_ignoredtable.test @@ -0,0 +1,70 @@ +# Test for +# Bug #797: If a query is ignored on slave (replicate-ignore-table) the slave +# still checks that it has the same error as on the master. +########################################################################## + +-- 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 + +connection master; +create table t1 (a int primary key); +create table t4 (a int primary key); +# generate an error that goes to the binlog +--error 1022, ER_DUP_ENTRY +insert into t1 values (1),(1); +insert into t4 values (1),(2); +# as the t1 table is ignored on the slave, the slave should be able to sync +sync_slave_with_master; +# check that the table has been ignored, because otherwise the test is nonsense +show tables like 't1'; +show tables like 't4'; +SELECT * FROM test.t4 ORDER BY a; +connection master; +drop table t1; +sync_slave_with_master; + +# Now test that even critical errors (connection killed) +# are ignored if rules allow it. +# The "kill" idea was copied from rpl000001.test. + +connection master1; +select get_lock('crash_lock%20C', 10); + +connection master; +create table t2 (a int primary key); +insert into t2 values(1); +create table t3 (id int); +insert into t3 values(connection_id()); +send update t2 set a = a + 1 + get_lock('crash_lock%20C', 10); + +connection master1; +let $wait_condition= SELECT count(*) > 0 FROM information_schema.processlist WHERE info LIKE 'update%' AND state='User lock'; +source include/wait_condition.inc; +select (@id := id) - id from t3; +kill @id; +let $id= `SELECT @id`; +let $wait_condition= SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE ID = $id; +source include/wait_condition.inc; +drop table t2,t3; +insert into t4 values (3),(4); +connection master; +# The get_lock function causes warning for unsafe statement. +--disable_warnings +--error 0,1317,2013 +reap; +--enable_warnings +connection master1; +sync_slave_with_master; +SELECT * FROM test.t4 ORDER BY a; + +connection master1; +DROP TABLE test.t4; +sync_slave_with_master; +# End of 4.1 tests +# Adding comment for force manual merge 5.0 -> wl1012. delete me if needed + + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_events.test b/mysql-test/suite/rpl/t/rpl_events.test new file mode 100644 index 00000000..3e73fc7a --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_events.test @@ -0,0 +1,244 @@ +################################################################## +# Author: Giuseppe # +# Date: 2006-12-20 # +# Purpose: To test that event effects are replicated. # +################################################################## + +--source include/master-slave.inc + +SET @old_event_scheduler = @@global.event_scheduler; +set global event_scheduler=1; + +# first, we need a table to record something from an event + +eval CREATE TABLE `t1` ( + `id` INT(10) UNSIGNED NOT NULL, + `c` VARCHAR(50) NOT NULL, + `ts` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (`id`) +) DEFAULT CHARSET=utf8; + +INSERT INTO t1 (id, c) VALUES (1, 'manually'); + +# We create the event so that it inserts exactly 1 row in the table +# A recuring event is used so that we can be sure the event will +# fire regardless of timing delays on the server. Otherwise, it is +# possible for the event to timeout before it has inserted a row. +--echo "Creating event test.justonce on the master" +CREATE EVENT test.justonce ON SCHEDULE EVERY 2 SECOND DO + INSERT IGNORE INTO t1 (id, c) VALUES (2, 'from justonce'); + +# Show the event is alive and present on master +--echo "Checking event is active on master" +SELECT db, name, status, originator FROM mysql.event WHERE db = 'test' AND name = 'justonce'; + +# Wait until event has fired. We know this because t1 will contain +# the row from the event. +let $wait_condition= + SELECT COUNT(*) = 1 FROM t1 WHERE c = 'from justonce'; +--source include/wait_condition.inc + +# check that table t1 contains something +--echo "Checking event data on the master" +let $events_done=`SELECT count(*) FROM t1 id`; +--disable_query_log +eval SELECT $events_done > 0 as ONE; +--enable_query_log + +sync_slave_with_master; + +--echo "Checking event data on the slave" +--disable_query_log +eval SELECT count(*) - $events_done as ZERO FROM t1 id; +--enable_query_log + +--echo "Checking event is inactive on slave" +SELECT db, name, status, originator FROM mysql.event WHERE db = 'test' AND name = 'justonce'; + +# Create an event on the slave and check to see what the originator is. +--echo "Dropping event test.slave_once on the slave" +--disable_warnings +DROP EVENT IF EXISTS test.slave_once; +--enable_warnings + +# Create an event on slave and check its state. An event shouldn't be executed +# so set start time in 1 hour. +CREATE EVENT test.slave_once ON SCHEDULE EVERY 5 MINUTE STARTS CURRENT_TIMESTAMP + INTERVAL 1 HOUR DO + INSERT IGNORE INTO t1(id, c) VALUES (3, 'from slave_once'); + +--echo "Checking event status on the slave for originator value = slave's server_id" +SELECT db, name, status, originator FROM mysql.event WHERE db = 'test' AND name = 'slave_once'; + +--echo "Dropping event test.slave_once on the slave" +--disable_warnings +DROP EVENT IF EXISTS test.slave_once; +--enable_warnings + +connection master; + +# BUG#20384 - disable events on slave +--echo "Dropping event test.justonce on the master" +--disable_warnings +DROP EVENT IF EXISTS test.justonce; +--enable_warnings + +# Create an event on master and check its state on slave. An event shouldn't be executed +# so set start time in 1 hour. Check that changes of event statement replicated to slave + +--echo "Creating event test.er on the master" +CREATE EVENT test.er ON SCHEDULE EVERY 3 SECOND STARTS CURRENT_TIMESTAMP + INTERVAL 1 HOUR DO + INSERT IGNORE INTO t1(id, c) VALUES (4, 'from er'); + +--echo "Checking event status on the master" +SELECT db, name, status, originator, body FROM mysql.event WHERE db = 'test' AND name = 'er'; + +sync_slave_with_master; + +--echo "Checking event status on the slave" +SELECT db, name, status, originator, body FROM mysql.event WHERE db = 'test' AND name = 'er'; + +connection master; +--echo "Altering event test.er on the master" +ALTER EVENT test.er ON SCHEDULE EVERY 5 SECOND STARTS CURRENT_TIMESTAMP + INTERVAL 1 HOUR DO + INSERT IGNORE INTO t1(id, c) VALUES (5, 'from alter er'); + +--echo "Checking event status on the master" +SELECT db, name, status, originator, body FROM mysql.event WHERE db = 'test' AND name = 'er'; + +sync_slave_with_master; + +--echo "Checking event status on the slave" +SELECT db, name, status, originator, body FROM mysql.event WHERE db = 'test' AND name = 'er'; + +connection master; +--echo "Dropping event test.er on the master" +DROP EVENT test.er; + +--echo "Checking event status on the master" +SELECT db, name, status, originator FROM mysql.event WHERE db = 'test'; + +--disable_info + +sync_slave_with_master; + +--echo "Checking event status on the slave" +SELECT db, name, status, originator FROM mysql.event WHERE db = 'test'; + +# test the DISABLE ON SLAVE for setting event SLAVESIDE_DISABLED as status +# on CREATE EVENT + +# Create an event on slave and check its status. An event shouldn't be executed +# so set start time in 1 hour. + +--echo "Creating event test.slave_terminate on the slave" +CREATE EVENT test.slave_terminate ON SCHEDULE EVERY 3 SECOND STARTS CURRENT_TIMESTAMP + INTERVAL 1 HOUR DO + INSERT IGNORE INTO t1(id, c) VALUES (6, 'from slave_terminate'); + +--echo "Checking event status on the slave" +SELECT db, name, status, originator FROM mysql.event WHERE db = 'test' AND name = 'slave_terminate'; + +--echo "Dropping event test.slave_terminate on the slave" +DROP EVENT test.slave_terminate; + +--echo "Creating event test.slave_terminate with DISABLE ON SLAVE on the slave" +CREATE EVENT test.slave_terminate ON SCHEDULE EVERY 3 SECOND DISABLE ON SLAVE DO + INSERT IGNORE INTO t1(c) VALUES (7, 'from slave_terminate'); + +--echo "Checking event status on the slave" +SELECT db, name, status, originator FROM mysql.event WHERE db = 'test' AND name = 'slave_terminate'; + +--echo "Dropping event test.slave_terminate on the slave" +DROP EVENT test.slave_terminate; + +--echo "Cleanup" + +connection master; +DROP TABLE t1; +sync_slave_with_master; +connection master; + +# +# Bug #28953 Using events in a replication let the slave crash. +# + +CREATE TABLE t28953 (a INT); + +DELIMITER |; +CREATE EVENT event1 ON SCHEDULE EVERY 1 YEAR +DO BEGIN + select * from t28953; +END;| +DELIMITER ;| + +ALTER EVENT event1 RENAME TO event2; + +sync_slave_with_master; + +connection master; + +DROP EVENT event2; + +# +# BUG#44331 +# This test verifies if the definer is consistent between master and slave, +# when the event is created without the DEFINER clause set explicitly or the +# DEFINER is set to CURRENT_USER +# +CREATE TABLE test.t1(details CHAR(30)); + +CREATE EVENT /*!50000 event44331_1 */ + ON SCHEDULE AT CURRENT_TIMESTAMP + ON COMPLETION PRESERVE DISABLE + DO INSERT INTO test.t1 VALUES('event event44331_1 fired - no definer'); + +CREATE DEFINER=CURRENT_USER /*!50000 EVENT event44331_2 */ + ON SCHEDULE AT CURRENT_TIMESTAMP + ON COMPLETION PRESERVE DISABLE + DO INSERT INTO test.t1 VALUES('event event44331_2 fired - DEFINER=CURRENT_USER'); + +CREATE DEFINER=CURRENT_USER() EVENT event44331_3 + ON SCHEDULE AT CURRENT_TIMESTAMP + ON COMPLETION PRESERVE DISABLE + DO INSERT INTO test.t1 VALUES('event event44331_3 fired - DEFINER=CURRENT_USER() function'); + +DELIMITER |; +CREATE /*!50000 DEFINER='user44331' */ EVENT event44331_4 + ON SCHEDULE AT CURRENT_TIMESTAMP + ON COMPLETION PRESERVE DISABLE + DO INSERT INTO test.t1 VALUES('event event44331_4 fired - DEFINER=user1'); +# Test for bug#50095 Multi-statement including CREATE EVENT causes rotten +# binlog entry + SELECT 'ABC'; + SELECT '123'| +DELIMITER ;| + +select EVENT_SCHEMA, EVENT_NAME, DEFINER from information_schema.events + where EVENT_NAME='event44331_1'; +select EVENT_SCHEMA, EVENT_NAME, DEFINER from information_schema.events + where EVENT_NAME='event44331_2'; +select EVENT_SCHEMA, EVENT_NAME, DEFINER from information_schema.events + where EVENT_NAME='event44331_3'; +select EVENT_SCHEMA, EVENT_NAME, DEFINER from information_schema.events + where EVENT_NAME='event44331_4'; + +sync_slave_with_master; +connection slave; +select EVENT_SCHEMA, EVENT_NAME, DEFINER from information_schema.events + where EVENT_NAME='event44331_1'; +select EVENT_SCHEMA, EVENT_NAME, DEFINER from information_schema.events + where EVENT_NAME='event44331_2'; +select EVENT_SCHEMA, EVENT_NAME, DEFINER from information_schema.events + where EVENT_NAME='event44331_3'; +select EVENT_SCHEMA, EVENT_NAME, DEFINER from information_schema.events + where EVENT_NAME='event44331_4'; + +connection master; +SET @@global.event_scheduler= @old_event_scheduler; +DROP TABLE t28953; +DROP TABLE t1; +DROP EVENT event44331_1; +DROP EVENT event44331_2; +DROP EVENT event44331_3; +DROP EVENT event44331_4; +sync_slave_with_master; +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_extra_col_master_innodb.test b/mysql-test/suite/rpl/t/rpl_extra_col_master_innodb.test new file mode 100644 index 00000000..63ae0fce --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_extra_col_master_innodb.test @@ -0,0 +1,11 @@ +############################################################# +# Purpose: To test having extra columns on the master WL#3915 +############################################################# +-- source include/have_binlog_format_row.inc +-- source include/have_innodb.inc +-- source include/master-slave.inc + +let $engine_type = 'InnoDB'; +--source include/rpl_extra_col_master.test + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_extra_col_master_myisam.test b/mysql-test/suite/rpl/t/rpl_extra_col_master_myisam.test new file mode 100644 index 00000000..72a35992 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_extra_col_master_myisam.test @@ -0,0 +1,10 @@ +############################################################# +# Purpose: To test having extra columns on the master WL#3915 +############################################################# +-- source include/have_binlog_format_row.inc +-- source include/master-slave.inc + +let $engine_type = 'MyISAM'; +--source include/rpl_extra_col_master.test + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_extra_col_slave_innodb.test b/mysql-test/suite/rpl/t/rpl_extra_col_slave_innodb.test new file mode 100644 index 00000000..e16e1dba --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_extra_col_slave_innodb.test @@ -0,0 +1,7 @@ +-- source include/have_binlog_format_row.inc +-- source include/have_innodb.inc +-- source include/master-slave.inc + +let $engine_type = 'InnoDB'; +-- source include/rpl_extra_col_slave.test +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_extra_col_slave_myisam.test b/mysql-test/suite/rpl/t/rpl_extra_col_slave_myisam.test new file mode 100644 index 00000000..f1e9fa24 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_extra_col_slave_myisam.test @@ -0,0 +1,6 @@ +-- source include/have_binlog_format_row.inc +-- source include/master-slave.inc + +let $engine_type = 'MyISAM'; +-- source include/rpl_extra_col_slave.test +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_fail_register.test b/mysql-test/suite/rpl/t/rpl_fail_register.test new file mode 100644 index 00000000..d95a5c5f --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_fail_register.test @@ -0,0 +1,33 @@ +source include/have_debug.inc; +source include/have_binlog_format_mixed.inc; +source include/master-slave.inc; + +connection slave; + +set @old_dbug=@@global.debug_dbug; +set global debug_dbug='d,fail_com_register_slave'; + +stop slave; +reset slave; +source include/wait_for_slave_to_stop.inc; +start slave; +stop slave; +source include/wait_for_slave_to_stop.inc; +set global debug_dbug=@old_dbug; + +connection master; + +let $id=`SELECT id from information_schema.processlist where command='Binlog Dump'`; + +if ($id) { + replace_result $id DUMP_THREAD; + eval kill $id; + let $wait_condition= SELECT count(*)=0 from information_schema.processlist where command='Killed'; + source include/wait_condition.inc; +} + +show slave hosts; + +connection slave; +start slave; +source include/rpl_end.inc; diff --git a/mysql-test/suite/rpl/t/rpl_failed_drop_tbl_binlog.opt b/mysql-test/suite/rpl/t/rpl_failed_drop_tbl_binlog.opt new file mode 100644 index 00000000..14fe8f7b --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_failed_drop_tbl_binlog.opt @@ -0,0 +1 @@ +--loose-innodb-adaptive-hash-index diff --git a/mysql-test/suite/rpl/t/rpl_failed_optimize.test b/mysql-test/suite/rpl/t/rpl_failed_optimize.test new file mode 100644 index 00000000..a65c19cb --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_failed_optimize.test @@ -0,0 +1,3 @@ +-- source include/have_innodb.inc +let $engine_type=InnoDB; +-- source include/rpl_failed_optimize.test diff --git a/mysql-test/suite/rpl/t/rpl_filter_dbs_dynamic.test b/mysql-test/suite/rpl/t/rpl_filter_dbs_dynamic.test new file mode 100644 index 00000000..05590a0a --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_filter_dbs_dynamic.test @@ -0,0 +1,63 @@ +# +# Test if dynamic replication database filter rules are properly evaluated. +# + +source include/have_binlog_format_statement.inc; +source include/master-slave.inc; + +connection slave; +--error ER_SLAVE_MUST_STOP +SET @@GLOBAL.replicate_do_db="db1"; +--error ER_SLAVE_MUST_STOP +SET @@GLOBAL.replicate_ignore_db="db2"; + +connection slave; +source include/stop_slave.inc; +SET @@GLOBAL.replicate_do_db="db1"; +SET @@GLOBAL.replicate_ignore_db="db2"; +source include/start_slave.inc; +connection master; + +CREATE DATABASE db1; +CREATE DATABASE db2; +CREATE DATABASE db3; + +# db is mentioned in do-db rules +USE db1; +CREATE TABLE t1 (a INT); + +# db is mentioned in ignore-db rules +USE db2; +CREATE TABLE t2 (a INT); + +# db is not mentioned in do-db or ignore-db rules +USE db3; +CREATE TABLE t3 (a INT); + +USE db1; +INSERT INTO t1 VALUES (1); + +USE db2; +INSERT INTO t2 VALUES (2); + +USE db3; +INSERT INTO t3 VALUES (3); + +# Only db1 should be replicated to slave +sync_slave_with_master; +echo [on slave]; +SHOW DATABASES LIKE 'db%'; +SHOW TABLES IN db1 LIKE 't%'; + +connection master; + +# Clean up +connection master; +DROP DATABASE IF EXISTS db1; +DROP DATABASE IF EXISTS db2; +DROP DATABASE IF EXISTS db3; +--source include/rpl_end.inc + +connection slave; +SET @@GLOBAL.replicate_do_db=""; +SET @@GLOBAL.replicate_ignore_db=""; diff --git a/mysql-test/suite/rpl/t/rpl_filter_tables_dynamic.test b/mysql-test/suite/rpl/t/rpl_filter_tables_dynamic.test new file mode 100644 index 00000000..529613b3 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_filter_tables_dynamic.test @@ -0,0 +1,217 @@ +# Test evaluation of replication table filter rules +# +# ==== Purpose ==== +# +# Test if dynamic replication table filter rules are properly evaluated +# when some of the tables referenced by the multiple-table update do not +# exist on slave. +# +# ==== Method ==== +# +# Master creates tables t1, t2, t3, t4, t5, t6, t7, t8, t9 and the +# slave is started with the following replication table filter rules: +# +# SET @@GLOBAL.replicate_do_table="test.t1,test.t2,test.t3"; +# +# and +# +# SET @@GLOBAL.replicate_ignore_table="test.t4,test.t5,test.t6"; +# +# So the slave only replicate changes to tables t1, t2 and t3 and only +# these tables exist on slave. +# +# From now on, tables t1, t2, and t3 are referenced as do tables, +# tables t4, t5, t6 are referenced as ignore tables, and tables t7, +# t8, t9 are referenced as other tables. +# +# All multi-table update tests reference tables that are not do +# tables, which do not exist on slave. And the following situations +# of multi-table update will be tested: +# +# 1. Do tables are not referenced at all +# 2. Do tables are not referenced for update +# 3. Ignore tables are referenced for update before do tables +# 4. Only do tables are referenced for update +# 5. Do tables and other tables are referenced for update +# 6. Do tables are referenced for update before ignore tables +# +# For 1, 2 and 3, the statement should be ignored by slave, for 4, 5 +# and 6 the statement should be accepted by slave and cause an error +# because of non-exist tables. +# + +source include/have_binlog_format_statement.inc; +source include/master-slave.inc; + +connection slave; +--error ER_SLAVE_MUST_STOP +SET @@GLOBAL.replicate_do_table="test.t1,test.t2,test.t3"; +--error ER_SLAVE_MUST_STOP +SET @@GLOBAL.replicate_ignore_table="test.t4,test.t5,test.t6"; + +connection slave; +source include/stop_slave.inc; +SET @@GLOBAL.replicate_do_table=""; +SET @@GLOBAL.replicate_ignore_table=""; +SET @@GLOBAL.replicate_do_table="test.t1,test.t2,test.t3"; +SET @@GLOBAL.replicate_ignore_table="test.t4,test.t5,test.t6"; +source include/start_slave.inc; +connection master; + +# These tables are mentioned in do-table rules +CREATE TABLE t1 (id int, a int); +CREATE TABLE t2 (id int, b int); +CREATE TABLE t3 (id int, c int); + +# These tables are mentioned in ignore-table rules +CREATE TABLE t4 (id int, d int); +CREATE TABLE t5 (id int, e int); +CREATE TABLE t6 (id int, f int); + +# These tables are not mentioned in do-table or ignore-table rules +CREATE TABLE t7 (id int, g int); +CREATE TABLE t8 (id int, h int); +CREATE TABLE t9 (id int, i int); + +INSERT INTO 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); + +INSERT INTO t4 VALUES (1, 1), (2, 2), (3, 3); +INSERT INTO t5 VALUES (1, 1), (2, 2), (3, 3); +INSERT INTO t6 VALUES (1, 1), (2, 2), (3, 3); + +INSERT INTO t7 VALUES (1, 1), (2, 2), (3, 3); +INSERT INTO t8 VALUES (1, 1), (2, 2), (3, 3); +INSERT INTO t9 VALUES (1, 1), (2, 2), (3, 3); + +# Only t1, t2, t3 should be replicated to slave +sync_slave_with_master; +SHOW TABLES LIKE 't%'; + +connection master; + +# +# Do tables are not referenced, these statements should be ignored by +# slave. +# +UPDATE t7 LEFT JOIN t4 ON (t4.id=t7.id) SET d=0, g=0 where t7.id=1; +UPDATE t7 LEFT JOIN (t4, t5, t6) ON (t7.id=t4.id and t7.id=t5.id and t7.id=t6.id) SET d=0, e=0, f=0, g=0 where t7.id=1; +UPDATE t4 LEFT JOIN (t7, t8, t9) ON (t4.id=t7.id and t4.id=t8.id and t4.id=t9.id) SET d=0, g=0, h=0, i=0 where t4.id=1; +UPDATE t7 LEFT JOIN (t8, t9) ON (t7.id=t8.id and t7.id=t9.id) SET g=0, h=0, i=0 where t7.id=1; + +# +# Do tables are not referenced for update, these statements should be +# ignored by slave. +# +UPDATE t1 LEFT JOIN t4 ON (t1.id=t4.id) SET d=0 where t1.id=1; +UPDATE t1 LEFT JOIN t7 ON (t1.id=t7.id) SET g=0 where t1.id=1; +UPDATE t1 LEFT JOIN (t4, t5, t6) ON (t1.id=t4.id and t1.id=t5.id and t1.id=t6.id) SET d=0, e=0, f=0 where t1.id=1; +UPDATE t1 LEFT JOIN (t4, t5, t8) ON (t1.id=t4.id and t1.id=t5.id and t1.id=t8.id) SET d=0, e=0, h=0 where t1.id=1; +UPDATE t1 LEFT JOIN (t7, t8, t5) ON (t1.id=t7.id and t1.id=t8.id and t1.id=t5.id) SET g=0, h=0, e=0 where t1.id=1; +UPDATE t1 LEFT JOIN (t2, t3, t5) ON (t1.id=t2.id and t1.id=t3.id and t1.id=t5.id) SET e=0 where t1.id=1; + +# +# Ignore tables are referenced for update before do tables, these +# statements should be ignore by slave. +# +UPDATE t4 LEFT JOIN t1 ON (t1.id=t4.id) SET a=0, d=0 where t4.id=1; +UPDATE t4 LEFT JOIN (t1, t7) ON (t4.id=t1.id and t7.id=t4.id) SET a = 0, d=0, g=0 where t4.id=1; +UPDATE t4 LEFT JOIN (t1, t2, t3) ON (t1.id=t4.id and t2.id=t4.id and t3.id=t4.id) SET a=0, b=0, c=0, d=0 where t4.id=1; +UPDATE t4 LEFT JOIN (t1, t2, t5) ON (t1.id=t4.id and t2.id=t4.id and t5.id=t4.id) SET a=0, b=0, e=0, d=0 where t4.id=1; +UPDATE t4 LEFT JOIN (t1, t6, t7) ON (t4.id=t1.id and t4.id=t6.id and t4.id=t7.id) SET a=0, d=0, f=0, g=0 where t4.id=1; +UPDATE t7 LEFT JOIN (t4, t1, t2) ON (t7.id=t4.id and t7.id=t1.id and t7.id=t2.id) SET a=0, b=0, d=0, g=0 where t7.id=1; +UPDATE t7 LEFT JOIN (t8, t4, t1) ON (t7.id=t8.id and t7.id=t4.id and t7.id=t1.id) SET a=0, d=0, g=0, h=0 where t7.id=1; + +# Sync slave to make sure all above statements are correctly ignored, +# if any of the above statement are not ignored, it would cause error +# and stop slave sql thread. +sync_slave_with_master; +connection slave; +call mtr.add_suppression("Slave SQL.*Error .Table .test.t[47]. doesn.t exist. on query.* error.* 1146"); +connection master; + +# Parameters for include/wait_for_slave_sql_error_and_skip.inc: +# Ask it to show SQL error message. +let $show_slave_sql_error= 1; +# The expected error will always be 1146 (ER_NO_SUCH_TABLE). +let $slave_sql_errno= 1146; + +# +# Only do tables are referenced for update, these statements should +# cause error on slave +# +UPDATE t1 LEFT JOIN t4 ON (t1.id=t4.id) SET a=0 where t1.id=1; +source include/wait_for_slave_sql_error_and_skip.inc; + +UPDATE t1 LEFT JOIN (t4, t7) ON (t1.id=t4.id and t1.id=t7.id) SET a=0 where t1.id=1; +source include/wait_for_slave_sql_error_and_skip.inc; + +UPDATE t1 LEFT JOIN (t2, t4, t7) ON (t1.id=t2.id and t1.id=t4.id and t1.id=t7.id) SET a=0, b=0 where t1.id=1; +source include/wait_for_slave_sql_error_and_skip.inc; + +UPDATE t1 LEFT JOIN (t2, t3, t7) ON (t1.id=t2.id and t1.id=t3.id and t1.id=t7.id) SET a=0, b=0, c=0 where t1.id=1; +source include/wait_for_slave_sql_error_and_skip.inc; + +# +# Do tables and other tables are referenced for update, these +# statements should cause error on slave +# +UPDATE t1 LEFT JOIN t7 ON (t1.id=t7.id) SET a=0, g=0 where t1.id=1; +source include/wait_for_slave_sql_error_and_skip.inc; + +UPDATE t7 LEFT JOIN t1 ON (t1.id=t7.id) SET a=0, g=0 where t7.id=1; +source include/wait_for_slave_sql_error_and_skip.inc; + +UPDATE t1 LEFT JOIN (t4, t5, t7) ON (t1.id=t4.id and t1.id=t5.id and t1.id=t7.id) SET a=0, g=0 where t1.id=1; +source include/wait_for_slave_sql_error_and_skip.inc; + +UPDATE t1 LEFT JOIN (t4, t7, t8) ON (t1.id=t4.id and t1.id=t7.id and t1.id=t8.id) SET a=0, g=0 where t1.id=1; +source include/wait_for_slave_sql_error_and_skip.inc; + +UPDATE t1 LEFT JOIN (t7, t8, t9) ON (t1.id=t7.id and t1.id=t8.id and t1.id=t9.id) SET a=0, g=0, h=0, i=0 where t1.id=1; +source include/wait_for_slave_sql_error_and_skip.inc; + +UPDATE t7 LEFT JOIN (t1, t2, t3) ON (t7.id=t1.id and t7.id=t2.id and t7.id=t3.id) SET g=0, a=0, b=0, c=0 where t7.id=1; +source include/wait_for_slave_sql_error_and_skip.inc; + +UPDATE t7 LEFT JOIN (t4, t5, t3) ON (t7.id=t4.id and t7.id=t5.id and t7.id=t3.id) SET g=0, c=0 where t7.id=1; +source include/wait_for_slave_sql_error_and_skip.inc; + +UPDATE t7 LEFT JOIN (t8, t9, t3) ON (t7.id=t8.id and t7.id=t9.id and t7.id=t3.id) SET g=0, h=0, i=0, c=0 where t7.id=1; +source include/wait_for_slave_sql_error_and_skip.inc; + +# +# Do tables are referenced for update before ignore tables +# +UPDATE t1 LEFT JOIN t4 ON (t1.id=t4.id) SET a=0, d=0 where t1.id=1; +source include/wait_for_slave_sql_error_and_skip.inc; + +UPDATE t1 LEFT JOIN (t4, t5, t6) ON (t1.id=t4.id and t1.id=t5.id and t1.id=t6.id) SET a=0, d=0, e=0, f=0 where t1.id=1; +source include/wait_for_slave_sql_error_and_skip.inc; + +UPDATE t4 LEFT JOIN (t1, t5, t6) ON (t4.id=t1.id and t4.id=t5.id and t4.id=t6.id) SET a=0, e=0, f=0 where t4.id=1; +source include/wait_for_slave_sql_error_and_skip.inc; + +UPDATE t7 LEFT JOIN (t1, t4, t2) ON (t7.id=t1.id and t7.id=t4.id and t7.id=t2.id) SET a=0, b=0, d=0, g=0 where t7.id=1; +source include/wait_for_slave_sql_error_and_skip.inc; + +sync_slave_with_master; +echo [on slave]; + +# We should only have tables t1, t2, t3 on slave +show tables like 't%'; + +# The rows in these tables should remain untouched +SELECT * FROM t1; +SELECT * FROM t2; +SELECT * FROM t3; + +# Clean up +connection master; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +--source include/rpl_end.inc + +connection slave; +SET @@GLOBAL.replicate_do_table=""; +SET @@GLOBAL.replicate_ignore_table=""; diff --git a/mysql-test/suite/rpl/t/rpl_filter_tables_not_exist-slave.opt b/mysql-test/suite/rpl/t/rpl_filter_tables_not_exist-slave.opt new file mode 100644 index 00000000..42acd3ea --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_filter_tables_not_exist-slave.opt @@ -0,0 +1 @@ +--replicate-do-table=test.t1 --replicate-do-table=test.t2 --replicate-do-table=test.t3 --replicate-ignore-table=test.t4 --replicate-ignore-table=test.t5 --replicate-ignore-table=test.t6 diff --git a/mysql-test/suite/rpl/t/rpl_filter_tables_not_exist.test b/mysql-test/suite/rpl/t/rpl_filter_tables_not_exist.test new file mode 100644 index 00000000..ee6daac7 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_filter_tables_not_exist.test @@ -0,0 +1,267 @@ +# Test evaluation of replication table filter rules +# +# ==== Purpose ==== +# +# Test if replication table filter rules are properly evaluated when +# some of the tables referenced by the multiple-table update do not +# exist on slave. +# +# ==== Method ==== +# +# Master creates tables t1, t2, t3, t4, t5, t6, t7, t8, t9 and the +# slave is started with the following replication table filter rules: +# +# --replicate-do-table=t1 +# --replicate-do-table=t2 +# --replicate-do-table=t3 +# +# and +# +# --replicate-ignore-table=t4 +# --replicate-ignore-table=t5 +# --replicate-ignore-table=t6 +# +# So the slave only replicate changes to tables t1, t2 and t3 and only +# these tables exist on slave. +# +# From now on, tables t1, t2, and t3 are referenced as do tables, +# tables t4, t5, t6 are referenced as ignore tables, and tables t7, +# t8, t9 are referenced as other tables. +# +# All multi-table update tests reference tables that are not do +# tables, which do not exist on slave. And the following situations +# of multi-table update will be tested: +# +# 1. Do tables are not referenced at all +# 2. Do tables are not referenced for update +# 3. Ignore tables are referenced for update before do tables +# 4. Only do tables are referenced for update +# 5. Do tables and other tables are referenced for update +# 6. Do tables are referenced for update before ignore tables +# +# For 1, 2 and 3, the statement should be ignored by slave, for 4, 5 +# and 6 the statement should be accepted by slave and cause an error +# because of non-exist tables. +# +# ==== Related bugs ==== +# +# BUG#37051 Replication rules not evaluated correctly + + +source include/have_binlog_format_statement.inc; +source include/master-slave.inc; + +# These tables are mentioned in do-table rules +CREATE TABLE t1 (id int, a int); +CREATE TABLE t2 (id int, b int); +CREATE TABLE t3 (id int, c int); + +# These tables are mentioned in ignore-table rules +CREATE TABLE t4 (id int, d int); +CREATE TABLE t5 (id int, e int); +CREATE TABLE t6 (id int, f int); + +# These tables are not mentioned in do-table or ignore-table rules +CREATE TABLE t7 (id int, g int); +CREATE TABLE t8 (id int, h int); +CREATE TABLE t9 (id int, i int); + +INSERT INTO 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); + +INSERT INTO t4 VALUES (1, 1), (2, 2), (3, 3); +INSERT INTO t5 VALUES (1, 1), (2, 2), (3, 3); +INSERT INTO t6 VALUES (1, 1), (2, 2), (3, 3); + +INSERT INTO t7 VALUES (1, 1), (2, 2), (3, 3); +INSERT INTO t8 VALUES (1, 1), (2, 2), (3, 3); +INSERT INTO t9 VALUES (1, 1), (2, 2), (3, 3); + +# Only t1, t2, t3 should be replicated to slave +sync_slave_with_master; +SHOW TABLES LIKE 't%'; + +connection master; + +# +# Do tables are not referenced, these statements should be ignored by +# slave. +# +UPDATE t7 LEFT JOIN t4 ON (t4.id=t7.id) SET d=0, g=0 where t7.id=1; +UPDATE t7 LEFT JOIN (t4, t5, t6) ON (t7.id=t4.id and t7.id=t5.id and t7.id=t6.id) SET d=0, e=0, f=0, g=0 where t7.id=1; +UPDATE t4 LEFT JOIN (t7, t8, t9) ON (t4.id=t7.id and t4.id=t8.id and t4.id=t9.id) SET d=0, g=0, h=0, i=0 where t4.id=1; +UPDATE t7 LEFT JOIN (t8, t9) ON (t7.id=t8.id and t7.id=t9.id) SET g=0, h=0, i=0 where t7.id=1; + +# +# Do tables are not referenced for update, these statements should be +# ignored by slave. +# +UPDATE t1 LEFT JOIN t4 ON (t1.id=t4.id) SET d=0 where t1.id=1; +UPDATE t1 LEFT JOIN t7 ON (t1.id=t7.id) SET g=0 where t1.id=1; +UPDATE t1 LEFT JOIN (t4, t5, t6) ON (t1.id=t4.id and t1.id=t5.id and t1.id=t6.id) SET d=0, e=0, f=0 where t1.id=1; +UPDATE t1 LEFT JOIN (t4, t5, t8) ON (t1.id=t4.id and t1.id=t5.id and t1.id=t8.id) SET d=0, e=0, h=0 where t1.id=1; +UPDATE t1 LEFT JOIN (t7, t8, t5) ON (t1.id=t7.id and t1.id=t8.id and t1.id=t5.id) SET g=0, h=0, e=0 where t1.id=1; +UPDATE t1 LEFT JOIN (t2, t3, t5) ON (t1.id=t2.id and t1.id=t3.id and t1.id=t5.id) SET e=0 where t1.id=1; + +# +# Ignore tables are referenced for update before do tables, these +# statements should be ignore by slave. +# +UPDATE t4 LEFT JOIN t1 ON (t1.id=t4.id) SET a=0, d=0 where t4.id=1; +UPDATE t4 LEFT JOIN (t1, t7) ON (t4.id=t1.id and t7.id=t4.id) SET a = 0, d=0, g=0 where t4.id=1; +UPDATE t4 LEFT JOIN (t1, t2, t3) ON (t1.id=t4.id and t2.id=t4.id and t3.id=t4.id) SET a=0, b=0, c=0, d=0 where t4.id=1; +UPDATE t4 LEFT JOIN (t1, t2, t5) ON (t1.id=t4.id and t2.id=t4.id and t5.id=t4.id) SET a=0, b=0, e=0, d=0 where t4.id=1; +UPDATE t4 LEFT JOIN (t1, t6, t7) ON (t4.id=t1.id and t4.id=t6.id and t4.id=t7.id) SET a=0, d=0, f=0, g=0 where t4.id=1; +UPDATE t7 LEFT JOIN (t4, t1, t2) ON (t7.id=t4.id and t7.id=t1.id and t7.id=t2.id) SET a=0, b=0, d=0, g=0 where t7.id=1; +UPDATE t7 LEFT JOIN (t8, t4, t1) ON (t7.id=t8.id and t7.id=t4.id and t7.id=t1.id) SET a=0, d=0, g=0, h=0 where t7.id=1; + +# Sync slave to make sure all above statements are correctly ignored, +# if any of the above statement are not ignored, it would cause error +# and stop slave sql thread. +sync_slave_with_master; +connection slave; +call mtr.add_suppression("Slave SQL.*Error .Table .test.t[47]. doesn.t exist. on query.* error.* 1146"); +connection master; + +# Parameters for include/wait_for_slave_sql_error_and_skip.inc: +# Ask it to show SQL error message. +let $show_slave_sql_error= 1; +# The expected error will always be 1146 (ER_NO_SUCH_TABLE). +let $slave_sql_errno= 1146; + +# +# Only do tables are referenced for update, these statements should +# cause error on slave +# +UPDATE t1 LEFT JOIN t4 ON (t1.id=t4.id) SET a=0 where t1.id=1; +source include/wait_for_slave_sql_error_and_skip.inc; + +UPDATE t1 LEFT JOIN (t4, t7) ON (t1.id=t4.id and t1.id=t7.id) SET a=0 where t1.id=1; +source include/wait_for_slave_sql_error_and_skip.inc; + +UPDATE t1 LEFT JOIN (t2, t4, t7) ON (t1.id=t2.id and t1.id=t4.id and t1.id=t7.id) SET a=0, b=0 where t1.id=1; +source include/wait_for_slave_sql_error_and_skip.inc; + +UPDATE t1 LEFT JOIN (t2, t3, t7) ON (t1.id=t2.id and t1.id=t3.id and t1.id=t7.id) SET a=0, b=0, c=0 where t1.id=1; +source include/wait_for_slave_sql_error_and_skip.inc; + +# +# Do tables and other tables are referenced for update, these +# statements should cause error on slave +# +UPDATE t1 LEFT JOIN t7 ON (t1.id=t7.id) SET a=0, g=0 where t1.id=1; +source include/wait_for_slave_sql_error_and_skip.inc; + +UPDATE t7 LEFT JOIN t1 ON (t1.id=t7.id) SET a=0, g=0 where t7.id=1; +source include/wait_for_slave_sql_error_and_skip.inc; + +UPDATE t1 LEFT JOIN (t4, t5, t7) ON (t1.id=t4.id and t1.id=t5.id and t1.id=t7.id) SET a=0, g=0 where t1.id=1; +source include/wait_for_slave_sql_error_and_skip.inc; + +UPDATE t1 LEFT JOIN (t4, t7, t8) ON (t1.id=t4.id and t1.id=t7.id and t1.id=t8.id) SET a=0, g=0 where t1.id=1; +source include/wait_for_slave_sql_error_and_skip.inc; + +UPDATE t1 LEFT JOIN (t7, t8, t9) ON (t1.id=t7.id and t1.id=t8.id and t1.id=t9.id) SET a=0, g=0, h=0, i=0 where t1.id=1; +source include/wait_for_slave_sql_error_and_skip.inc; + +UPDATE t7 LEFT JOIN (t1, t2, t3) ON (t7.id=t1.id and t7.id=t2.id and t7.id=t3.id) SET g=0, a=0, b=0, c=0 where t7.id=1; +source include/wait_for_slave_sql_error_and_skip.inc; + +UPDATE t7 LEFT JOIN (t4, t5, t3) ON (t7.id=t4.id and t7.id=t5.id and t7.id=t3.id) SET g=0, c=0 where t7.id=1; +source include/wait_for_slave_sql_error_and_skip.inc; + +UPDATE t7 LEFT JOIN (t8, t9, t3) ON (t7.id=t8.id and t7.id=t9.id and t7.id=t3.id) SET g=0, h=0, i=0, c=0 where t7.id=1; +source include/wait_for_slave_sql_error_and_skip.inc; + +# +# Do tables are referenced for update before ignore tables +# +UPDATE t1 LEFT JOIN t4 ON (t1.id=t4.id) SET a=0, d=0 where t1.id=1; +source include/wait_for_slave_sql_error_and_skip.inc; + +UPDATE t1 LEFT JOIN (t4, t5, t6) ON (t1.id=t4.id and t1.id=t5.id and t1.id=t6.id) SET a=0, d=0, e=0, f=0 where t1.id=1; +source include/wait_for_slave_sql_error_and_skip.inc; + +UPDATE t4 LEFT JOIN (t1, t5, t6) ON (t4.id=t1.id and t4.id=t5.id and t4.id=t6.id) SET a=0, e=0, f=0 where t4.id=1; +source include/wait_for_slave_sql_error_and_skip.inc; + +UPDATE t7 LEFT JOIN (t1, t4, t2) ON (t7.id=t1.id and t7.id=t4.id and t7.id=t2.id) SET a=0, b=0, d=0, g=0 where t7.id=1; +source include/wait_for_slave_sql_error_and_skip.inc; + +sync_slave_with_master; +echo [on slave]; + +# We should only have tables t1, t2, t3 on slave +show tables like 't%'; + +# The rows in these tables should remain untouched +SELECT * FROM t1; +SELECT * FROM t2; +SELECT * FROM t3; + +# Clean up +connection master; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; + +--sync_slave_with_master + +# +# BUG#11754117 - 45670: INTVAR_EVENTS FOR FILTERED-OUT QUERY_LOG_EVENTS ARE EXECUTED +# Int-, Rand- and User- var events accompaning a filtered out Query-log-event should +# be filtered as well. +# +connection master; +# Although RAND() is from 0 to 1.0, DECIMAL(M,D), requires that M must be >= D. +CREATE TABLE test.t5 (a INT AUTO_INCREMENT PRIMARY KEY, b DECIMAL(20,20), c INT); # ignored on slave +CREATE TABLE test.t1 (a INT); # accepted on slave +INSERT INTO test.t1 VALUES(1); + +--sync_slave_with_master +call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT"); +# Although RAND() is from 0 to 1.0, DECIMAL(M,D), requires that M must be >= D. +CREATE TABLE test.t_slave (a INT AUTO_INCREMENT PRIMARY KEY, b DECIMAL(20,20), c INT); +CREATE TRIGGER t1_update AFTER UPDATE ON test.t1 FOR EACH ROW + INSERT INTO test.t_slave VALUES(NULL, RAND(), @c); + +connection master; +SET INSERT_ID=2; +SET @c=2; +SET @@rand_seed1=10000000, @@rand_seed2=1000000; +INSERT INTO t5 VALUES (NULL, RAND(), @c); # to be ignored +SELECT b into @b FROM test.t5; +--let $b_master=`select @b` +UPDATE test.t1 SET a=2; # to run trigger on slave + +--sync_slave_with_master + +# The proof: +SELECT a AS 'ONE' into @a FROM test.t_slave; +SELECT c AS 'NULL' into @c FROM test.t_slave; + +let $count= 1; +let $table= test.t_slave; +source include/wait_until_rows_count.inc; + +if (`SELECT @a != 2 and @c != NULL`) +{ + SELECT * FROM test.t_slave; + --die Intvar or user var from replication events unexpetedly escaped out to screw a following query applying context. +} + +SELECT b into @b FROM test.t_slave; +--let $b_slave=`select @b` + +--let $assert_text= Random values from master and slave must be different +--let $assert_cond= $b_master != $b_slave +--source include/assert.inc + +# cleanup BUG#11754117 +connection master; +drop table test.t5; +drop table test.t1; + +--sync_slave_with_master +drop table test.t_slave; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_filter_wild_tables_dynamic.test b/mysql-test/suite/rpl/t/rpl_filter_wild_tables_dynamic.test new file mode 100644 index 00000000..657a95ce --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_filter_wild_tables_dynamic.test @@ -0,0 +1,49 @@ +# +# Test if dynamic replication wild table filter rules are properly evaluated. +# + +source include/have_binlog_format_statement.inc; +source include/master-slave.inc; + +connection slave; +--error ER_SLAVE_MUST_STOP +SET @@GLOBAL.replicate_wild_do_table="test.a%"; +--error ER_SLAVE_MUST_STOP +SET @@GLOBAL.replicate_wild_ignore_table="test.b%"; + +connection slave; +source include/stop_slave.inc; +SET @@GLOBAL.replicate_wild_do_table=""; +SET @@GLOBAL.replicate_wild_ignore_table=""; +SET @@GLOBAL.replicate_wild_do_table="test.a%"; +SET @@GLOBAL.replicate_wild_ignore_table="test.b%"; +source include/start_slave.inc; +connection master; + +# Table is mentioned in wild-do-table rules +CREATE TABLE a1 (a INT); + +# Table is mentioned in wild-ignore-table rules +CREATE TABLE b1 (a INT); + +# Table is not mentioned in wild-do-table or wild-ignore-table rules +CREATE TABLE c1 (a INT); + +INSERT INTO a1 VALUES (1); +INSERT INTO b1 VALUES (2); +INSERT INTO c1 VALUES (3); + +# Only a1 should be replicated to slave +sync_slave_with_master; +SHOW TABLES LIKE '%1'; + +connection master; + +# Clean up +connection master; +DROP TABLE IF EXISTS a1,b1,c1; +--source include/rpl_end.inc + +connection slave; +SET @@GLOBAL.replicate_wild_do_table=""; +SET @@GLOBAL.replicate_wild_ignore_table=""; diff --git a/mysql-test/suite/rpl/t/rpl_flush_logs-master.opt b/mysql-test/suite/rpl/t/rpl_flush_logs-master.opt new file mode 100644 index 00000000..36eab1d6 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_flush_logs-master.opt @@ -0,0 +1 @@ +--log-error=$MYSQLTEST_VARDIR/tmp/master_log.err diff --git a/mysql-test/suite/rpl/t/rpl_flush_logs.test b/mysql-test/suite/rpl/t/rpl_flush_logs.test new file mode 100644 index 00000000..6dad588f --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_flush_logs.test @@ -0,0 +1,141 @@ +# +# WL#5124 +# This test verifies if the 'flush individual logs' statement +# works fine. +# + +--source include/have_binlog_format_statement.inc +--source include/master-slave.inc +connection master; + +# Test 'flush error logs' statement. + +--echo # Test if support 'flush error logs' statement. +flush error logs; + +file_exists $MYSQLTEST_VARDIR/tmp/master_log.err; + +--echo # Make sure binary logs was not be flushed +--echo # after execute 'flush error logs' statement. +--error 1 +file_exists $MYSQLTEST_VARDIR/mysqld.1/data/master-bin.000002; + +sync_slave_with_master; +--echo # Make sure relay logs was not be flushed +--echo # after execute 'flush error logs' statement. +--error 1 +file_exists $MYSQLTEST_VARDIR/mysqld.2/data/slave-relay-bin.000003; + +connection master; +--echo # Test if support 'flush relay logs' statement. +flush relay logs; + +sync_slave_with_master; +--echo # Check the 'slave-relay-bin.000003' file is not created +--echo # after executed 'flush relay logs' statement. +--error 1 +file_exists $MYSQLTEST_VARDIR/mysqld.2/data/slave-relay-bin.000003; + +connection master; +--echo # Make sure binary logs was not be flushed +--echo # after execute 'flush relay logs' statement. +--error 1 +file_exists $MYSQLTEST_VARDIR/mysqld.1/data/master-bin.000002; + + +# Test 'flush slow logs' statement. +--echo # Test if support 'flush slow logs' statement. +flush slow logs; + +--echo # Make sure binary logs was not be flushed +--echo # after execute 'flush slow logs' statement. +--error 1 +file_exists $MYSQLTEST_VARDIR/mysqld.1/data/master-bin.000002; + + +# Test 'flush general logs' statement. +--echo # Test if support 'flush general logs' statement. +flush general logs; + +--echo # Make sure binary logs was not be flushed +--echo # after execute 'flush general logs' statement. +--error 1 +file_exists $MYSQLTEST_VARDIR/mysqld.1/data/master-bin.000002; + + +# Test 'flush engine logs' statement. +--echo # Test if support 'flush engine logs' statement. +flush engine logs; + +--echo # Make sure binary logs was not be flushed +--echo # after execute 'flush engine logs' statement. +--error 1 +file_exists $MYSQLTEST_VARDIR/mysqld.1/data/master-bin.000002; + + +# Test 'flush binary logs' statement. +--echo # Make sure the 'master-bin.000002' file does not +--echo # exist before execute 'flush binary logs' statement. +--error 1 +file_exists $MYSQLTEST_VARDIR/mysqld.1/data/master-bin.000002; + +--echo # Test if support 'flush binary logs' statement. +flush binary logs; + +--echo # Check the 'master-bin.000002' file is created +--echo # after executed 'flush binary logs' statement. +file_exists $MYSQLTEST_VARDIR/mysqld.1/data/master-bin.000002; +file_exists $MYSQLTEST_VARDIR/mysqld.1/data/master-bin.000001; + + +# Test 'flush error logs, relay logs' statement +sync_slave_with_master; +--echo # Make sure the 'slave-relay-bin.000005' file does not exist +--echo # exist before execute 'flush error logs, relay logs' statement. +--error 1 +file_exists $MYSQLTEST_VARDIR/mysqld.2/data/slave-relay-bin.000005; + +connection master; + +--echo # Test if support to combine all kinds of logs into one statement. +flush error logs, relay logs; + +file_exists $MYSQLTEST_VARDIR/tmp/master_log.err; + +--echo # Make sure binary logs was not be flushed +--echo # after execute 'flush error logs, relay logs' statement. +--error 1 +file_exists $MYSQLTEST_VARDIR/mysqld.1/data/master-bin.000003; + +sync_slave_with_master; +--echo # Check the 'slave-relay-bin.000004' file is created after +--echo # execute 'flush error logs, relay logs' statement. +file_exists $MYSQLTEST_VARDIR/mysqld.2/data/slave-relay-bin.000004; + +# Test 'flush logs' statement +--echo # Make sure the 'slave-relay-bin.000005' and 'slave-relay-bin.000006' +--echo # files do not exist before execute 'flush error logs, relay logs' +--echo # statement. +--error 1 +file_exists $MYSQLTEST_VARDIR/mysqld.2/data/slave-relay-bin.000005; +--error 1 +file_exists $MYSQLTEST_VARDIR/mysqld.2/data/slave-relay-bin.000006; + +connection master; + +--echo # Test if 'flush logs' statement works fine and flush all the logs. +flush logs; + +file_exists $MYSQLTEST_VARDIR/tmp/master_log.err; + +--echo # Check 'master-bin.000003' is created +--echo # after execute 'flush logs' statement. +file_exists $MYSQLTEST_VARDIR/mysqld.1/data/master-bin.000003; + +sync_slave_with_master; +--echo # Check the 'slave-relay-bin.000005' and 'slave-relay-bin.000006' +--echo # files are created after execute 'flush logs' statement. +file_exists $MYSQLTEST_VARDIR/mysqld.2/data/slave-relay-bin.000005; +file_exists $MYSQLTEST_VARDIR/mysqld.2/data/slave-relay-bin.000006; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_flushlog_loop-master.opt b/mysql-test/suite/rpl/t/rpl_flushlog_loop-master.opt new file mode 100644 index 00000000..3b5d41d4 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_flushlog_loop-master.opt @@ -0,0 +1 @@ +--max_binlog_size=1M diff --git a/mysql-test/suite/rpl/t/rpl_flushlog_loop-slave.opt b/mysql-test/suite/rpl/t/rpl_flushlog_loop-slave.opt new file mode 100644 index 00000000..3b5d41d4 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_flushlog_loop-slave.opt @@ -0,0 +1 @@ +--max_binlog_size=1M diff --git a/mysql-test/suite/rpl/t/rpl_flushlog_loop.test b/mysql-test/suite/rpl/t/rpl_flushlog_loop.test new file mode 100644 index 00000000..d5d362ba --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_flushlog_loop.test @@ -0,0 +1,46 @@ +# Testing if "flush logs" command bouncing resulting in logs created in a loop +# in case of bi-directional replication +--let $rpl_topology= 1->2->1 +--source include/rpl_init.inc + +let $MYSQLD_DATADIR= `select @@datadir`; +--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR/ +show variables like 'relay_log%'; + +# +# Flush logs of slave +# +# Create full loop by following way: +# 1. Insert into t1 on master (1st). +# 2. Insert into t1 on slave (2nd) when the event (1st) for t1 replicated. +# 3. Master waits until the event (2nd) for t1 will be replicated. + +CREATE TABLE t1 (a INT KEY) ENGINE= MyISAM; +let $wait_binlog_event= CREATE TABLE t1; +--source include/wait_for_binlog_event.inc +sync_slave_with_master server_2; + +connection server_1; +INSERT INTO t1 VALUE(1); +FLUSH LOGS; +sync_slave_with_master server_2; + +INSERT INTO t1 VALUE(2); +let $slave_param_value= query_get_value(SHOW MASTER STATUS, Position, 1); +sync_slave_with_master server_1; + +# +# Check that the master server's slave threads are still running and show +# Relay_Log_File +# +--source include/check_slave_is_running.inc +--let status_items= Relay_Log_File +--source include/show_slave_status.inc + +--disable_query_log +connection server_1; +DROP TABLE t1; +sync_slave_with_master server_2; +--enable_query_log + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_foreign_key_innodb.test b/mysql-test/suite/rpl/t/rpl_foreign_key_innodb.test new file mode 100644 index 00000000..2c4af75e --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_foreign_key_innodb.test @@ -0,0 +1,78 @@ +-- source include/have_innodb.inc + +# Check the replication of the FOREIGN_KEY_CHECKS variable. + +-- source include/master-slave.inc + +CREATE TABLE t1 (a INT AUTO_INCREMENT KEY) ENGINE=INNODB; +CREATE TABLE t2 (b INT AUTO_INCREMENT KEY, c INT, FOREIGN KEY(b) REFERENCES t1(a)) ENGINE=INNODB; + +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; +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; +SET TIMESTAMP=1000000000; +CREATE TABLE t3 ( a INT UNIQUE ); +SET FOREIGN_KEY_CHECKS=0; +--error ER_DUP_ENTRY +INSERT INTO t3 VALUES (1),(1); +sync_slave_with_master; + +connection master; +SET FOREIGN_KEY_CHECKS=0; +DROP TABLE IF EXISTS t1,t2,t3; +SET FOREIGN_KEY_CHECKS=1; +sync_slave_with_master; + +# +# Bug #32468 delete rows event on a table with foreign key constraint fails +# + +connection master; + +create table t1 (b int primary key) engine = INNODB; +create table t2 (a int primary key, b int, foreign key (b) references t1(b)) engine = INNODB; + +insert into t1 set b=1; +insert into t2 set a=1, b=1; + +set foreign_key_checks=0; +delete from t1; + +--echo must sync w/o a problem (could not with the buggy code) +sync_slave_with_master; +select count(*) from t1 /* must be zero */; + + +# cleanup for bug#32468 + +connection master; +drop table t2,t1; +set foreign_key_checks=1; + +--echo # +--echo # MDEV-25530 Error 1451 on slave: Cannot delete or update a parent row: a foreign key constraint fails +--echo # + +create table t1 (id int primary key)engine=innodb; +create table t2 (id int not null primary key auto_increment, + id2 int default null, key f1 (id2), + constraint f1 foreign key (id2) references t1 (id) on delete cascade) engine=innodb; +error ER_ROW_IS_REFERENCED_2; +drop table t1,t2; +sync_slave_with_master; +show tables; +connection master; +drop table t1; +sync_slave_with_master; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_free_items-slave.opt b/mysql-test/suite/rpl/t/rpl_free_items-slave.opt new file mode 100644 index 00000000..b828d03f --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_free_items-slave.opt @@ -0,0 +1 @@ +--replicate-wild-ignore-table=test.% diff --git a/mysql-test/suite/rpl/t/rpl_free_items.test b/mysql-test/suite/rpl/t/rpl_free_items.test new file mode 100644 index 00000000..581409cf --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_free_items.test @@ -0,0 +1,23 @@ +source include/master-slave.inc; +create table t1 (a int); +create table t2 (a int); +disable_query_log; +SET @query="INSERT INTO t2 SELECT * FROM t1 WHERE a REGEXP \"0\""; +let $1 = 2000; +while ($1) +{ + eval SET @query=concat(@query, " OR a REGEXP '$1'"); + dec $1; +} +let $1=`select @query`; +eval $1; +enable_query_log; +# I have seen the slave crash either now or at shutdown +sync_slave_with_master; +connection master; +drop table t1; +drop table t2; +sync_slave_with_master; + +# End of 4.1 tests +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_function_defaults.test b/mysql-test/suite/rpl/t/rpl_function_defaults.test new file mode 100644 index 00000000..f2413299 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_function_defaults.test @@ -0,0 +1,86 @@ +--echo # +--echo # Test of function defaults on replicated tables. +--echo # + +source include/master-slave.inc; + +connection master; +SET TIME_ZONE="+10:30"; +SET TIMESTAMP=123456.789123; +SELECT CURRENT_TIMESTAMP; + +connection slave; +SET TIME_ZONE="+00:00"; +SET TIMESTAMP=987654321.123456; +SELECT CURRENT_TIMESTAMP; + +connection master; +CREATE TABLE t1 ( + a TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + b TIMESTAMP(1) NOT NULL DEFAULT CURRENT_TIMESTAMP(1), + c TIMESTAMP(2) NOT NULL DEFAULT CURRENT_TIMESTAMP(2), + d TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), + e TIMESTAMP(4) NOT NULL DEFAULT CURRENT_TIMESTAMP(4), + f TIMESTAMP(5) NOT NULL DEFAULT CURRENT_TIMESTAMP(5), + g TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6), + h DATETIME DEFAULT CURRENT_TIMESTAMP, + i DATETIME(1) DEFAULT CURRENT_TIMESTAMP(1), + j DATETIME(2) DEFAULT CURRENT_TIMESTAMP(2), + k DATETIME(3) DEFAULT CURRENT_TIMESTAMP(3), + l DATETIME(4) DEFAULT CURRENT_TIMESTAMP(4), + m DATETIME(5) DEFAULT CURRENT_TIMESTAMP(5), + n DATETIME(6) DEFAULT CURRENT_TIMESTAMP(6), + o INT +); + +INSERT INTO t1 ( o ) VALUES ( 1 ); + +CREATE TABLE t2 ( + a TIMESTAMP NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP, + b TIMESTAMP(1) NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP(1), + c TIMESTAMP(2) NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP(2), + d TIMESTAMP(3) NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP(3), + e TIMESTAMP(4) NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP(4), + f TIMESTAMP(5) NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP(5), + g TIMESTAMP(6) NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP(6), + h DATETIME ON UPDATE CURRENT_TIMESTAMP, + i DATETIME(1) ON UPDATE CURRENT_TIMESTAMP(1), + j DATETIME(2) ON UPDATE CURRENT_TIMESTAMP(2), + k DATETIME(3) ON UPDATE CURRENT_TIMESTAMP(3), + l DATETIME(4) ON UPDATE CURRENT_TIMESTAMP(4), + m DATETIME(5) ON UPDATE CURRENT_TIMESTAMP(5), + n DATETIME(6) ON UPDATE CURRENT_TIMESTAMP(6), + o INT +); + +INSERT INTO t2 ( o ) VALUES ( 1 ); + +--echo sync_slave_with_master +sync_slave_with_master; + +connection slave; + +query_vertical SELECT * FROM t1; +query_vertical SELECT * FROM t2; + +connection master; + +SET TIMESTAMP=1234567890.123456; +SELECT CURRENT_TIMESTAMP; + +UPDATE t1 SET o = 2; +UPDATE t2 SET o = 2; + +--echo sync_slave_with_master +sync_slave_with_master; + +connection slave; + +query_vertical SELECT * FROM t1; +query_vertical SELECT * FROM t2; + +connection master; + +DROP TABLE t1, t2; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_geometry.test b/mysql-test/suite/rpl/t/rpl_geometry.test new file mode 100644 index 00000000..415732a0 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_geometry.test @@ -0,0 +1,26 @@ +source include/have_binlog_format_row.inc; +source include/master-slave.inc; + +# +# Bug#48776, Bug#43784 +# +create table t1(a varchar(100), + b multipoint not null, + c varchar(256)); + +insert into t1 set + a='hello', + b=geomfromtext('multipoint(1 1)'), + c='geometry'; + +create table t2 (a int(11) not null auto_increment primary key, + b geometrycollection default null, + c decimal(10,0)); + +insert into t2(c) values (null); + +sync_slave_with_master; + +connection master; +drop table t1, t2; +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_get_lock.test b/mysql-test/suite/rpl/t/rpl_get_lock.test new file mode 100644 index 00000000..b5c08858 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_get_lock.test @@ -0,0 +1,47 @@ +source include/master-slave.inc; + +CALL mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT"); + +create table t1(n int); +# Use of get_lock gives a warning for unsafeness if binlog_format=statement +--disable_warnings +insert into t1 values(get_lock("lock",2)); +--enable_warnings +dirty_close master; +connection master1; +select get_lock("lock",2); + +select release_lock("lock"); +#ignore +disable_query_log; +let $1=2000; +while ($1) +{ + do get_lock("lock",2); + do release_lock("lock"); + dec $1; +} +enable_query_log; +sync_slave_with_master; +select get_lock("lock",3); +select * from t1; +# There is no point in testing REPLICATIION of the IS_*_LOCK +# functions; slave does not run with the same concurrency context as +# master (generally in slave we can't know that on master this lock +# was already held by another connection and so that the the +# get_lock() we're replicating timed out on master hence returned 0, +# or that the is_free_lock() we're playing returned 0 etc. +# But here all we do is test these functions outside of replication. +select is_free_lock("lock"), is_used_lock("lock") = connection_id(); +explain extended select is_free_lock("lock"), is_used_lock("lock"); +# Check lock functions +select is_free_lock("lock2"); +select is_free_lock(NULL); +connection master1; +drop table t1; +sync_slave_with_master; + + +--source include/rpl_end.inc + +# End of 4.1 tests diff --git a/mysql-test/suite/rpl/t/rpl_get_master_version_and_clock-slave.opt b/mysql-test/suite/rpl/t/rpl_get_master_version_and_clock-slave.opt new file mode 100644 index 00000000..f9aa8c03 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_get_master_version_and_clock-slave.opt @@ -0,0 +1 @@ +--master-retry-count=60 diff --git a/mysql-test/suite/rpl/t/rpl_get_master_version_and_clock.test b/mysql-test/suite/rpl/t/rpl_get_master_version_and_clock.test new file mode 100644 index 00000000..02665c70 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_get_master_version_and_clock.test @@ -0,0 +1,50 @@ +# +# BUG#45214 +# This test verifies if the slave I/O tread tries to reconnect to +# master when it tries to get the values of the UNIX_TIMESTAMP, SERVER_ID, +# COLLATION_SERVER and TIME_ZONE from master under network disconnection. +# The COLLATION_SERVER and TIME_ZONE are got only on master server version 4. +# So they can't be verified by test case here. +# Finish the following tests by calling its common test script: +# include/rpl_get_master_version_and_clock.test. + +source include/have_debug.inc; +source include/have_debug_sync.inc; +source include/master-slave.inc; + +# +# The test is not supposed to have any binglog affairs. +# Hence it's enough it to run only with one binlog format +# +source include/have_binlog_format_mixed.inc; + +connection slave; + +call mtr.add_suppression("Slave I/O: Master command COM_REGISTER_SLAVE failed: .*"); +call mtr.add_suppression("Slave I/O: .* failed with error: Lost connection to MySQL server at 'reading initial communication packet'"); +call mtr.add_suppression("Fatal error: The slave I/O thread stops because master and slave have equal MySQL server ids; .*"); +call mtr.add_suppression("Slave I/O thread .* register on master"); + +#Test case 1: Try to get the value of the UNIX_TIMESTAMP from master under network disconnection +SET @saved_dbug = @@GLOBAL.debug_dbug; + +# set up two parameters to pass into include/rpl_get_master_version_and_clock +let $dbug_sync_point= 'debug_lock.before_get_UNIX_TIMESTAMP'; +let $debug_sync_action= 'now SIGNAL signal.get_unix_timestamp'; +source include/rpl_get_master_version_and_clock.test; + +#Test case 2: Try to get the value of the SERVER_ID from master under network disconnection +connection slave; + +let $dbug_sync_point= 'debug_lock.before_get_SERVER_ID'; +let $debug_sync_action= 'now SIGNAL signal.get_server_id'; +source include/rpl_get_master_version_and_clock.test; + + +# cleanup +SET @@GLOBAL.debug_dbug = @saved_dbug; +# is not really necessary but avoids mtr post-run env check warnings +SET DEBUG_SYNC= 'RESET'; + +# End of tests +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_grant.test b/mysql-test/suite/rpl/t/rpl_grant.test new file mode 100644 index 00000000..02206453 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_grant.test @@ -0,0 +1,37 @@ +# Tests of grants and users + +source include/not_embedded.inc; +source include/master-slave.inc; + +connection master; + +CREATE USER dummy@localhost; +CREATE USER dummy1@localhost, dummy2@localhost; + +SELECT user, host FROM mysql.user WHERE user like 'dummy%'; +SELECT COUNT(*) FROM mysql.user WHERE user like 'dummy%'; +sync_slave_with_master; +--echo **** On Slave **** +SELECT user,host FROM mysql.user WHERE user like 'dummy%'; +SELECT COUNT(*) FROM mysql.user WHERE user like 'dummy%'; + +connection master; + +# No user exists +error ER_CANNOT_USER; +DROP USER nonexisting@localhost; + +# At least one user exists, but not all +error ER_CANNOT_USER; +DROP USER nonexisting@localhost, dummy@localhost; + +# All users exist +DROP USER dummy1@localhost, dummy2@localhost; + +SELECT user, host FROM mysql.user WHERE user like 'dummy%'; +SELECT COUNT(*) FROM mysql.user WHERE user like 'dummy%'; +sync_slave_with_master; +SELECT user,host FROM mysql.user WHERE user like 'dummy%'; +SELECT COUNT(*) FROM mysql.user WHERE user like 'dummy%'; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_gtid_basic.cnf b/mysql-test/suite/rpl/t/rpl_gtid_basic.cnf new file mode 100644 index 00000000..3ff94e45 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_gtid_basic.cnf @@ -0,0 +1,24 @@ +!include ../my.cnf + +[mysqld.1] +log-slave-updates +loose-innodb + +[mysqld.2] +log-slave-updates +loose-innodb + +[mysqld.3] +log-slave-updates +loose-innodb + +[mysqld.4] +log-slave-updates +loose-innodb + +[ENV] +SERVER_MYPORT_3= @mysqld.3.port +SERVER_MYSOCK_3= @mysqld.3.socket + +SERVER_MYPORT_4= @mysqld.4.port +SERVER_MYSOCK_4= @mysqld.4.socket diff --git a/mysql-test/suite/rpl/t/rpl_gtid_basic.test b/mysql-test/suite/rpl/t/rpl_gtid_basic.test new file mode 100644 index 00000000..004003ea --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_gtid_basic.test @@ -0,0 +1,36 @@ +--source include/rpl_gtid_basic.inc + +--echo # +--echo # Start of 10.2 tests +--echo # + +--echo # +--echo # MDEV-10134 Add full support for DEFAULT +--echo # + +--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED +CREATE TABLE t1 (a VARCHAR(100) DEFAULT BINLOG_GTID_POS("master-bin.000001", 600)); + +--echo # +--echo # End of 10.2 tests +--echo # + + +--echo # +--echo # Start of 10.3 tests +--echo # + +--echo # +--echo # MDEV-13967 Parameter data type control for Item_long_func +--echo # + +--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION +SELECT MASTER_GTID_WAIT(ROW(1,1),'str'); + +--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION +SELECT MASTER_GTID_WAIT('str',ROW(1,1)); + + +--echo # +--echo # End of 10.3 tests +--echo # diff --git a/mysql-test/suite/rpl/t/rpl_gtid_crash-master.opt b/mysql-test/suite/rpl/t/rpl_gtid_crash-master.opt new file mode 100644 index 00000000..590d44a6 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_gtid_crash-master.opt @@ -0,0 +1 @@ +--loose-skip-stack-trace --skip-core-file diff --git a/mysql-test/suite/rpl/t/rpl_gtid_crash-slave.opt b/mysql-test/suite/rpl/t/rpl_gtid_crash-slave.opt new file mode 100644 index 00000000..69c1a64e --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_gtid_crash-slave.opt @@ -0,0 +1 @@ +--master-retry-count=100 diff --git a/mysql-test/suite/rpl/t/rpl_gtid_crash.test b/mysql-test/suite/rpl/t/rpl_gtid_crash.test new file mode 100644 index 00000000..d0af69a6 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_gtid_crash.test @@ -0,0 +1,668 @@ +--source include/have_innodb.inc +--source include/have_debug.inc +# Valgrind does not work well with test that crashes the server +--source include/not_valgrind.inc + +--let $rpl_topology=1->2 +--source include/rpl_init.inc + +--echo *** Test crashing master, causing slave IO thread to reconnect while SQL thread is running *** + +--connection server_1 +call mtr.add_suppression("Checking table:"); +call mtr.add_suppression("client is using or hasn't closed the table properly"); +call mtr.add_suppression("Table .* is marked as crashed and should be repaired"); +flush tables; + +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +CREATE TABLE t1 (a INT PRIMARY KEY, b INT) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1, 0); +--save_master_pos + +--connection server_2 +--sync_with_master +SET sql_log_bin=0; +call mtr.add_suppression('Master command COM_REGISTER_SLAVE failed: failed registering on master, reconnecting to try again'); +SET sql_log_bin=1; +--source include/stop_slave.inc +--replace_result $MASTER_MYPORT MASTER_PORT +eval CHANGE MASTER TO master_host = '127.0.0.1', master_port = $MASTER_MYPORT, + MASTER_USE_GTID=CURRENT_POS; + +--connection server_1 +INSERT INTO t1 VALUES (2,1); +INSERT INTO t1 VALUES (3,1); + +--connection server_2 +--source include/start_slave.inc + +--connection server_1 + +--write_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +wait-rpl_gtid_crash.test +EOF + +let $1=200; +--disable_query_log +while ($1) +{ + eval INSERT INTO t1 VALUES ($1 + 10, 2); + dec $1; +} +--enable_query_log +--source include/save_master_gtid.inc + +SET SESSION debug_dbug="+d,crash_dispatch_command_before"; +--error 2006,2013 +SELECT 1; +--source include/wait_until_disconnected.inc + +--append_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +restart-rpl_gtid_crash.test +EOF + +--enable_reconnect +--source include/wait_until_connected_again.inc + +--connection server_2 +--source include/sync_with_master_gtid.inc + +--connection server_1 +INSERT INTO t1 VALUES (1000, 3); +--source include/save_master_gtid.inc + +--connection server_2 +--source include/sync_with_master_gtid.inc + +--connection server_1 +DROP TABLE t1; +--save_master_pos + +--echo *** Test crashing the master mysqld and check that binlog state is recovered. *** +--connection server_2 +--sync_with_master +--source include/stop_slave.inc +RESET MASTER; +SET GLOBAL gtid_slave_pos=''; + +--connection server_1 +RESET MASTER; +--replace_column 2 # 4 # 5 # +SHOW BINLOG EVENTS IN 'master-bin.000001' LIMIT 1,1; +CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB; + +--connection server_2 +--source include/start_slave.inc + +--connection server_1 +SET gtid_domain_id= 1; +INSERT INTO t1 VALUES (1); +INSERT INTO t1 VALUES (2); +FLUSH LOGS; +SET gtid_domain_id= 2; +INSERT INTO t1 VALUES (3); +FLUSH LOGS; +--source include/show_binary_logs.inc +--replace_column 2 # 4 # 5 # 6 # +SHOW BINLOG EVENTS IN 'master-bin.000003' LIMIT 1,1; + +--write_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +wait +EOF + +SET SESSION debug_dbug="+d,crash_dispatch_command_before"; +--error 2006,2013 +SELECT 1; +--source include/wait_until_disconnected.inc + +--append_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +restart +EOF + +--enable_reconnect +--source include/wait_until_connected_again.inc + +--source include/show_binary_logs.inc +--replace_column 2 # 4 # 5 # 6 # +SHOW BINLOG EVENTS IN 'master-bin.000004' LIMIT 1,1; +--save_master_pos + +--connection server_2 +--sync_with_master +SELECT * FROM t1 ORDER BY a; + + +--echo *** Test crashing slave at various points and check that it recovers crash-safe. *** + +# Crash the slave just before updating mysql.gtid_slave_pos table. +--source include/stop_slave.inc +--write_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect +wait +EOF +# We do not have to save @@GLOBAL.debug_dbug, it is reset when slave crashes. +SET GLOBAL debug_dbug="+d,inject_crash_before_write_rpl_slave_state"; +START SLAVE; + +--connection server_1 +INSERT INTO t1 VALUES (4); +--source include/save_master_gtid.inc + +--connection server_2 +--source include/wait_until_disconnected.inc + +--append_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect +restart: --skip-slave-start=0 +EOF + +--enable_reconnect +--source include/wait_until_connected_again.inc + +--source include/sync_with_master_gtid.inc + +# Crash the slave just before committing. +--source include/stop_slave.inc +--write_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect +wait +EOF +START SLAVE; +--error 0,2006,2013 +SET GLOBAL debug_dbug="+d,crash_commit_before"; + +--connection server_1 +INSERT INTO t1 VALUES (5); +--source include/save_master_gtid.inc + +--connection server_2 +--source include/wait_until_disconnected.inc + +--append_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect +restart: --skip-slave-start=0 +EOF + +--enable_reconnect +--source include/wait_until_connected_again.inc + +--source include/sync_with_master_gtid.inc + +# Crash the slave just after committing. +--source include/stop_slave.inc +--write_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect +wait +EOF +START SLAVE; +--error 0,2006,2013 +SET GLOBAL debug_dbug="+d,crash_commit_after"; + +--connection server_1 +INSERT INTO t1 VALUES (6); +--source include/save_master_gtid.inc + +--connection server_2 +--source include/wait_until_disconnected.inc + +--append_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect +restart: --skip-slave-start=0 +EOF + +--enable_reconnect +--source include/wait_until_connected_again.inc + +--source include/sync_with_master_gtid.inc + +# Crash the slave just before updating relay-log.info +--source include/stop_slave.inc +--write_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect +wait +EOF +SET GLOBAL debug_dbug="+d,inject_crash_before_flush_rli"; +--error 0,2006,2013 +START SLAVE; + +--connection server_1 +INSERT INTO t1 VALUES (7); +--source include/save_master_gtid.inc + +--connection server_2 +--source include/wait_until_disconnected.inc + +--append_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect +restart: --skip-slave-start=0 +EOF + +--enable_reconnect +--source include/wait_until_connected_again.inc + +--source include/sync_with_master_gtid.inc + +# Crash the slave just after updating relay-log.info +--source include/stop_slave.inc +--write_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect +wait +EOF +SET GLOBAL debug_dbug="+d,inject_crash_after_flush_rli"; +--error 0,2006,2013 +START SLAVE; + +--connection server_1 +INSERT INTO t1 VALUES (8); +--source include/save_master_gtid.inc + +--connection server_2 +--source include/wait_until_disconnected.inc + +--append_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect +restart: --skip-slave-start=0 +EOF + +--enable_reconnect +--source include/wait_until_connected_again.inc + +--source include/sync_with_master_gtid.inc + + +# Check that everything was replicated correctly. +SELECT * FROM t1 ORDER BY a; + + +--echo *** MDEV-4725: Incorrect recovery when crash in the middle of writing an event group *** + +--connection server_2 +--write_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect +wait +EOF + +--let $old_gtid_strict= `SELECT @@gtid_strict_mode` +SET GLOBAL debug_dbug="+d,crash_before_writing_xid"; + +--connection server_1 +INSERT INTO t1 VALUES (9), (10); +--let $saved_gtid=`SELECT @@last_gtid` +--save_master_pos + +--connection server_2 +--source include/wait_until_disconnected.inc + +# The bug was that during crash recovery we would update the binlog state +# with the GTID of the half-written event group at the end of the slaves +# binlog, even though this event group was not committed. +# We restart the server with gtid_strict_mode; this way, we get an error +# about duplicate gtid when the slave re-executes the event group, if the +# binlog crash recovery is incorrect. +--append_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect +restart: --gtid_strict_mode=1 +EOF + +--enable_reconnect +--source include/wait_until_connected_again.inc + +SHOW VARIABLES like 'gtid_strict_mode'; +--source include/start_slave.inc +--sync_with_master +--disable_query_log +eval SET GLOBAL gtid_strict_mode= $old_gtid_strict; +--enable_query_log + + +--echo *** MDEV-6462: Incorrect recovery on a slave reconnecting to crashed master *** + +--connection server_1 +set sql_log_bin= 0; +call mtr.add_suppression("Error writing file 'master-bin'"); +set sql_log_bin= 1; +--connection server_2 +set sql_log_bin= 0; +call mtr.add_suppression("The server_id of master server changed in the middle of GTID"); +call mtr.add_suppression("Unexpected change of master binlog file name in the middle of GTID"); +set sql_log_bin= 1; + +--connection server_1 +--write_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +wait +EOF + +SET GLOBAL debug_dbug="+d,inject_error_writing_xid"; +BEGIN; +INSERT INTO t1 VALUES (11); +--error ER_ERROR_ON_WRITE +COMMIT; +SET GLOBAL debug_dbug="+d,crash_dispatch_command_before"; +--error 2006,2013 +COMMIT; + +--source include/wait_until_disconnected.inc + +# Simulate that we reconnect to a different server (new server_id). +--append_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +restart: --server-id=3 +EOF + +--enable_reconnect +--source include/wait_until_connected_again.inc + +SELECT @@GLOBAL.server_id; +SELECT * from t1 WHERE a > 10 ORDER BY a; +--disable_query_log +eval SELECT IF(INSTR(@@gtid_binlog_pos, '$saved_gtid'), "Binlog pos ok", CONCAT("Unexpected binlog pos: ", @@gtid_binlog_pos, "; does not contain the GTID $saved_gtid.")) AS gtid_check; +--enable_query_log + +--echo # Wait 30 seconds for SQL thread to catch up with IO thread +--connection server_2 +--let $wait_timeout= 300 +while ($wait_timeout != 0) +{ + --let $read_log_pos= query_get_value('SHOW SLAVE STATUS', Read_Master_Log_Pos, 1) + --let $exec_log_pos= query_get_value('SHOW SLAVE STATUS', Exec_Master_Log_Pos, 1) + if ($read_log_pos == $exec_log_pos) + { + --let $wait_timeout= 0 + } + if ($read_log_pos != $exec_log_pos) + { + --sleep 0.1 + --dec $wait_timeout + } +} +if ($read_log_pos != $exec_log_pos) +{ + --die Timeout wait for SQL thread to catch up with IO thread +} + +SELECT * from t1 WHERE a > 10 ORDER BY a; +--disable_query_log +eval SELECT IF(INSTR(@@gtid_binlog_pos, '$saved_gtid'), "Binlog pos ok", CONCAT("Unexpected binlog pos: ", @@gtid_binlog_pos, "; does not contain the GTID $saved_gtid.")) AS gtid_check; +eval SELECT IF(INSTR(@@gtid_slave_pos, '$saved_gtid'), "Slave pos ok", CONCAT("Unexpected slave pos: ", @@gtid_slave_pos, "; does not contain the GTID $saved_gtid.")) AS gtid_check; +eval SELECT IF(INSTR(@@gtid_current_pos, '$saved_gtid'), "Current pos ok", CONCAT("Unexpected current pos: ", @@gtid_current_pos, "; does not contain the GTID $saved_gtid.")) AS gtid_check; +--enable_query_log + +--echo # Repeat this with additional transactions on the master + +--connection server_1 +--write_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +wait +EOF + +SET GLOBAL debug_dbug="+d,inject_error_writing_xid"; +BEGIN; +INSERT INTO t1 VALUES (12); +--error ER_ERROR_ON_WRITE +COMMIT; +SET GLOBAL debug_dbug="+d,crash_dispatch_command_before"; +--error 2006,2013 +COMMIT; + +--source include/wait_until_disconnected.inc + +# Simulate that we reconnect to a different server (new server_id). +--append_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +restart: --server-id=1 +EOF + +--enable_reconnect +--source include/wait_until_connected_again.inc + +SELECT @@GLOBAL.server_id; +INSERT INTO t1 VALUES (13); +INSERT INTO t1 VALUES (14); +--let $saved_gtid=`SELECT @@last_gtid` +SELECT * from t1 WHERE a > 10 ORDER BY a; +--source include/save_master_gtid.inc + +--connection server_2 +--source include/sync_with_master_gtid.inc +SELECT * from t1 WHERE a > 10 ORDER BY a; + +--connection server_1 +--write_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +wait +EOF + +SET GLOBAL debug_dbug="+d,inject_error_writing_xid"; +BEGIN; +INSERT INTO t1 VALUES (21); +--error ER_ERROR_ON_WRITE +COMMIT; +SET GLOBAL debug_dbug="+d,crash_dispatch_command_before"; +--error 2006,2013 +COMMIT; + +--source include/wait_until_disconnected.inc + +# Simulate that we reconnect to the same server (same server_id). +--append_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +restart +EOF + +--enable_reconnect +--source include/wait_until_connected_again.inc + +SELECT @@GLOBAL.server_id; +SELECT * from t1 WHERE a > 10 ORDER BY a; +--disable_query_log +eval SELECT IF(INSTR(@@gtid_binlog_pos, '$saved_gtid'), "Binlog pos ok", CONCAT("Unexpected binlog pos: ", @@gtid_binlog_pos, "; does not contain the GTID $saved_gtid.")) AS gtid_check; +eval SELECT IF(INSTR(@@gtid_current_pos, '$saved_gtid'), "Current pos ok", CONCAT("Unexpected current pos: ", @@gtid_current_pos, "; does not contain the GTID $saved_gtid.")) AS gtid_check; +--enable_query_log + +--echo # Wait 30 seconds for SQL thread to catch up with IO thread +--connection server_2 +--let $wait_timeout= 300 +while ($wait_timeout != 0) +{ + --let $read_log_pos= query_get_value('SHOW SLAVE STATUS', Read_Master_Log_Pos, 1) + --let $exec_log_pos= query_get_value('SHOW SLAVE STATUS', Exec_Master_Log_Pos, 1) + if ($read_log_pos == $exec_log_pos) + { + --let $wait_timeout= 0 + } + if ($read_log_pos != $exec_log_pos) + { + --sleep 0.1 + --dec $wait_timeout + } +} +if ($read_log_pos != $exec_log_pos) +{ + --die Timeout wait for SQL thread to catch up with IO thread +} + +SELECT * from t1 WHERE a > 10 ORDER BY a; +--disable_query_log +eval SELECT IF(INSTR(@@gtid_binlog_pos, '$saved_gtid'), "Binlog pos ok", CONCAT("Unexpected binlog pos: ", @@gtid_binlog_pos, "; does not contain the GTID $saved_gtid.")) AS gtid_check; +eval SELECT IF(INSTR(@@gtid_slave_pos, '$saved_gtid'), "Slave pos ok", CONCAT("Unexpected slave pos: ", @@gtid_slave_pos, "; does not contain the GTID $saved_gtid.")) AS gtid_check; +eval SELECT IF(INSTR(@@gtid_current_pos, '$saved_gtid'), "Current pos ok", CONCAT("Unexpected current pos: ", @@gtid_current_pos, "; does not contain the GTID $saved_gtid.")) AS gtid_check; +--enable_query_log + +--echo # Repeat this with additional transactions on the master + +--connection server_1 +--write_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +wait +EOF + +SET GLOBAL debug_dbug="+d,inject_error_writing_xid"; +BEGIN; +INSERT INTO t1 VALUES (22); +--error ER_ERROR_ON_WRITE +COMMIT; +SET GLOBAL debug_dbug="+d,crash_dispatch_command_before"; +--error 2006,2013 +COMMIT; + +--source include/wait_until_disconnected.inc + +--append_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +restart +EOF + +--enable_reconnect +--source include/wait_until_connected_again.inc + +INSERT INTO t1 VALUES (23); +INSERT INTO t1 VALUES (24); +--let $saved_gtid=`SELECT @@last_gtid` +SELECT * from t1 WHERE a > 10 ORDER BY a; +--source include/save_master_gtid.inc + +--connection server_2 +--source include/sync_with_master_gtid.inc +SELECT * from t1 WHERE a > 10 ORDER BY a; + +--echo # Repeat this with slave restart + +--connection server_1 +--write_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +wait +EOF + +SET GLOBAL debug_dbug="+d,inject_error_writing_xid"; +BEGIN; +INSERT INTO t1 VALUES (25); +--error ER_ERROR_ON_WRITE +COMMIT; +SET GLOBAL debug_dbug="+d,crash_dispatch_command_before"; +--error 2006,2013 +COMMIT; + +--source include/wait_until_disconnected.inc + +--append_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +restart +EOF + +--connection server_1 +--enable_reconnect +--source include/wait_until_connected_again.inc + +--connection server_2 +--echo # Wait 30 seconds for IO thread to connect and SQL thread to catch up +--echo # with IO thread. +--let $wait_timeout= 300 +while ($wait_timeout != 0) +{ + --let $connected=`SELECT COUNT(*) > 0 FROM information_schema.processlist WHERE State = 'Waiting for master to send event'` + if ($connected) + { + --let $read_log_pos= query_get_value('SHOW SLAVE STATUS', Read_Master_Log_Pos, 1) + --let $exec_log_pos= query_get_value('SHOW SLAVE STATUS', Exec_Master_Log_Pos, 1) + if ($read_log_pos == $exec_log_pos) + { + --let $wait_timeout= 0 + } + if ($read_log_pos != $exec_log_pos) + { + --sleep 0.1 + --dec $wait_timeout + } + } + if (!$connected) + { + --sleep 0.1 + --dec $wait_timeout + } +} +if (`SELECT NOT $connected OR $read_log_pos != $exec_log_pos`) +{ + --die Timeout wait for IO thread to connect and SQL thread to catch up with IO thread +} + +--source include/stop_slave.inc + +--connection server_1 +--disable_query_log +eval SELECT IF(INSTR(@@gtid_binlog_pos, '$saved_gtid'), "Binlog pos ok", CONCAT("Unexpected binlog pos: ", @@gtid_binlog_pos, "; does not contain the GTID $saved_gtid.")) AS gtid_check; +eval SELECT IF(INSTR(@@gtid_current_pos, '$saved_gtid'), "Current pos ok", CONCAT("Unexpected current pos: ", @@gtid_current_pos, "; does not contain the GTID $saved_gtid.")) AS gtid_check; +--enable_query_log +INSERT INTO t1 VALUES (26); +INSERT INTO t1 VALUES (27); +SELECT * from t1 WHERE a > 10 ORDER BY a; +--source include/save_master_gtid.inc + +--connection server_2 +--disable_query_log +eval SELECT IF(INSTR(@@gtid_binlog_pos, '$saved_gtid'), "Binlog pos ok", CONCAT("Unexpected binlog pos: ", @@gtid_binlog_pos, "; does not contain the GTID $saved_gtid.")) AS gtid_check; +eval SELECT IF(INSTR(@@gtid_slave_pos, '$saved_gtid'), "Slave pos ok", CONCAT("Unexpected slave pos: ", @@gtid_slave_pos, "; does not contain the GTID $saved_gtid.")) AS gtid_check; +eval SELECT IF(INSTR(@@gtid_current_pos, '$saved_gtid'), "Current pos ok", CONCAT("Unexpected current pos: ", @@gtid_current_pos, "; does not contain the GTID $saved_gtid.")) AS gtid_check; +--enable_query_log +--source include/start_slave.inc +--source include/sync_with_master_gtid.inc +SELECT * from t1 WHERE a > 10 ORDER BY a; + + +--echo *** MDEV-6391: GTID binlog state not recovered if mariadb-bin.state is removed *** + +--connection server_2 +--source include/stop_slave.inc + +# Do some misc. transactions, stop the master, drop the master-bin.state file. +# Start the master back up, check that binlog state is correct. + +--connection server_1 + +INSERT INTO t1 VALUES (30); +SET @old_server_id= @@server_id; +SET @old_domain_id= @@gtid_domain_id; + +SET SESSION server_id= 10; +INSERT INTO t1 VALUES (31); +INSERT INTO t1 VALUES (32); +SET SESSION gtid_domain_id= 1; +SET SESSION server_id=11; +INSERT INTO t1 VALUES (33); +SET SESSION gtid_domain_id= 2; +INSERT INTO t1 VALUES (34); +SET SESSION server_id= 10; +INSERT INTO t1 VALUES (35); +INSERT INTO t1 VALUES (36); +SET SESSION gtid_domain_id= 0; +SET SESSION server_id= 12; +INSERT INTO t1 VALUES (37); +SET SESSION gtid_domain_id= @old_domain_id; +SET SESSION server_id= @old_server_id; +INSERT INTO t1 VALUES (38); +INSERT INTO t1 VALUES (39); +SELECT * FROM t1 WHERE a >= 30 ORDER BY a; +--source include/save_master_gtid.inc + +--let OLD_STATE= `SELECT @@gtid_binlog_state` + +--let $datadir= `SELECT @@datadir` + +--write_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +wait +EOF +shutdown_server; +--source include/wait_until_disconnected.inc + +--remove_file $datadir/master-bin.state + +--append_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +restart +EOF +--enable_reconnect +--source include/wait_until_connected_again.inc + +--let NEW_STATE= `SELECT @@gtid_binlog_state` + +--perl +my $old= $ENV{'OLD_STATE'}; +my $new= $ENV{'NEW_STATE'}; +# Make them order-independent, for easy comparison. +$old= join(",", sort(split(",", $old))); +$new= join(",", sort(split(",", $new))); +die "ERROR: new binlog state '$new' differs from old '$old'\n" + unless $old eq $new; +EOF + +--connection server_2 +--source include/start_slave.inc +--source include/sync_with_master_gtid.inc +SELECT * FROM t1 WHERE a >= 30 ORDER BY a; + + +--connection server_1 +DROP TABLE t1; + +--connection default +--enable_reconnect +--source include/wait_until_connected_again.inc + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_gtid_crash_myisam-master.opt b/mysql-test/suite/rpl/t/rpl_gtid_crash_myisam-master.opt new file mode 100644 index 00000000..16d8af5b --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_gtid_crash_myisam-master.opt @@ -0,0 +1 @@ +--loose-skip-stack-trace --skip-core-file --skip-innodb diff --git a/mysql-test/suite/rpl/t/rpl_gtid_crash_myisam.test b/mysql-test/suite/rpl/t/rpl_gtid_crash_myisam.test new file mode 100644 index 00000000..faf388f5 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_gtid_crash_myisam.test @@ -0,0 +1,64 @@ +--source include/have_debug.inc +# Valgrind does not work well with test that crashes the server +--source include/not_valgrind.inc + +--let $rpl_topology=1->2 +--source include/rpl_init.inc + +--echo *** Test crashing master with InnoDB disabled, the binlog gtid state should still be correctly recovered. *** + +--connection server_1 +CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=MyISAM; +--save_master_pos + +--connection server_2 +--sync_with_master +--source include/stop_slave.inc +CHANGE MASTER TO master_use_gtid=slave_pos; +--source include/start_slave.inc + +--connection server_1 +INSERT INTO t1 VALUES (1); +INSERT INTO t1 VALUES (2); +--save_master_pos + +--connection server_2 +--sync_with_master +SELECT * FROM t1 ORDER BY a; + +--connection server_1 + +--write_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +wait +EOF + +FLUSH TABLES; +SET SESSION debug_dbug="+d,crash_dispatch_command_before"; +--error 2006,2013 +SELECT 1; + +--source include/wait_until_disconnected.inc + +--append_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +restart-rpl_gtid_crash.test +EOF + +--connection server_1 +--enable_reconnect +--source include/wait_until_connected_again.inc + +INSERT INTO t1 VALUES (3); +--save_master_pos + +--connection server_2 +--sync_with_master +SELECT * FROM t1 ORDER BY a; + +--connection server_1 +DROP TABLE t1; + +--connection default +--enable_reconnect +--source include/wait_until_connected_again.inc + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_gtid_delete_domain.test b/mysql-test/suite/rpl/t/rpl_gtid_delete_domain.test new file mode 100644 index 00000000..5537b6fb --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_gtid_delete_domain.test @@ -0,0 +1,101 @@ +# In case master's gtid binlog state is divergent from the slave's gtid_slave_pos +# slave may not be able to connect. +# For instance when slave is more updated in some of domains, see +# MDEV-12012 as example, the master's state may require adjustment. +# In a specific case of an "old" divergent domain, that is there +# won't be no more event groups from it generated, the states can be +# made compatible with wiping the problematic domain away. After that slave +# becomes connectable. +# +# Notice that the slave applied gtid state is not really required to +# be similarly cleaned in order for replication to flow. +# However this could lead to an expected error when the master +# resumes binlogging of such domain which the test demonstrate. + +--source include/master-slave.inc + +--connection master +# enforce the default domain_id binlogging explicitly +SET @@SESSION.gtid_domain_id=0; +CREATE TABLE t (a INT); +--sync_slave_with_master + +--connection slave +call mtr.add_suppression("connecting slave requested to start from.*which is not in the master's binlog"); + +--source include/stop_slave.inc +CHANGE MASTER TO master_use_gtid=slave_pos; + +--connection master +# create extra gtid domains for binlog state +--let $extra_domain_id=11 +--let $extra_domain_server_id=111 +--let $extra_gtid_seq_no=1 +--eval SET @@SESSION.gtid_domain_id=$extra_domain_id +--eval SET @@SESSION.server_id=$extra_domain_server_id +--eval SET @@SESSION.gtid_seq_no=$extra_gtid_seq_no +INSERT INTO t SET a=1; + +# +# Set up the slave replication state as if slave knows more events from the extra +# domain. +# +--connection slave +SET @save.gtid_slave_pos=@@global.gtid_slave_pos; +--eval SET @@global.gtid_slave_pos=concat(@@global.gtid_slave_pos, ",", $extra_domain_id, "-", $extra_domain_server_id, "-", $extra_gtid_seq_no + 1) + +# unsuccessful attempt to start slave +START SLAVE IO_THREAD; +--let $slave_io_errno=1236 +--source include/wait_for_slave_io_error.inc + +--connection master +# adjust the master binlog state +FLUSH BINARY LOGS; +--let $purge_to_binlog= query_get_value(SHOW MASTER STATUS, File, 1) +--let $purge_binlogs_to=$purge_to_binlog +--source include/wait_for_purge.inc + +# with final removal of the extra domain +--eval FLUSH BINARY LOGS DELETE_DOMAIN_ID=($extra_domain_id) +SELECT @@global.gtid_binlog_pos, @@global.gtid_binlog_state; + +--connection slave +SELECT @@global.gtid_slave_pos; +# start the slave sucessfully +--let rpl_debug=1 +--source include/start_slave.inc +--let rpl_debug=0 + +--connection master +# but the following gtid from the *extra* domain will break replication +INSERT INTO t SET a=1; + +# take note of the slave io thread error due to being dismissed +# extra domain at connection to master which tried becoming active; +# slave is to stop. +--connection slave +--let $errno=1236 +--source include/wait_for_slave_io_error.inc + +# let's apply the very same medicine +--connection master +FLUSH BINARY LOGS; +--let $purge_to_binlog= query_get_value(SHOW MASTER STATUS, File, 1) +--eval PURGE BINARY LOGS TO '$purge_to_binlog'; +# with final removal of the extra domain +--eval FLUSH BINARY LOGS DELETE_DOMAIN_ID=($extra_domain_id) + +--connection slave +--source include/start_slave.inc + +# +# cleanup +# +--connection master +SET @@SESSION.gtid_domain_id=0; +DROP TABLE t; + +sync_slave_with_master; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_gtid_errorhandling.test b/mysql-test/suite/rpl/t/rpl_gtid_errorhandling.test new file mode 100644 index 00000000..c02e2670 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_gtid_errorhandling.test @@ -0,0 +1,290 @@ +--source include/have_innodb.inc +--source include/have_debug.inc +--source include/master-slave.inc + +--echo *** Test that we check against incorrect table definition for mysql.gtid_slave_pos *** +--connection master +CREATE TABLE t1(a INT PRIMARY KEY) ENGINE=InnoDB; +--sync_slave_with_master + +--connection slave +--source include/stop_slave.inc +ALTER TABLE mysql.gtid_slave_pos CHANGE seq_no seq_no VARCHAR(20); +START SLAVE; + +--connection master +INSERT INTO t1 VALUES (1); + +--connection slave +CALL mtr.add_suppression("Slave: Failed to open mysql.gtid_slave_pos"); +--let $slave_sql_errno=1944 +--source include/wait_for_slave_sql_error.inc + +--source include/stop_slave.inc +ALTER TABLE mysql.gtid_slave_pos CHANGE seq_no seq_no BIGINT UNSIGNED NOT NULL; +ALTER TABLE mysql.gtid_slave_pos DROP PRIMARY KEY; +ALTER TABLE mysql.gtid_slave_pos ADD PRIMARY KEY (sub_id, domain_id); +START SLAVE; +--let $slave_sql_errno=1944 +--source include/wait_for_slave_sql_error.inc + +--source include/stop_slave.inc +ALTER TABLE mysql.gtid_slave_pos DROP PRIMARY KEY; +START SLAVE; +--let $slave_sql_errno=1944 +--source include/wait_for_slave_sql_error.inc + +--source include/stop_slave.inc +ALTER TABLE mysql.gtid_slave_pos ADD PRIMARY KEY (sub_id); +START SLAVE; +--let $slave_sql_errno=1944 +--source include/wait_for_slave_sql_error.inc + +--source include/stop_slave.inc +ALTER TABLE mysql.gtid_slave_pos DROP PRIMARY KEY; +ALTER TABLE mysql.gtid_slave_pos ADD PRIMARY KEY (domain_id, sub_id); +--source include/start_slave.inc + +--connection master +--sync_slave_with_master + +--connection slave +SELECT * FROM t1; + + +--echo *** Test that setting @@gtid_domain_id or @@gtid_seq_no is not allowed inside a transaction. *** +BEGIN; +INSERT INTO t1 VALUES (100); +--error ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_GTID_DOMAIN_ID_SEQ_NO +SET SESSION gtid_domain_id= 100; +--error ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_GTID_DOMAIN_ID_SEQ_NO +SET SESSION gtid_seq_no= 100; +SET @old_domain= @@GLOBAL.gtid_domain_id; +SET GLOBAL gtid_domain_id= 100; +SELECT @@SESSION.gtid_domain_id; +SET GLOBAL gtid_domain_id= @old_domain; +INSERT INTO t1 VALUES (101); +SELECT * FROM t1 ORDER BY a; +ROLLBACK; +SELECT * FROM t1 ORDER BY a; + + +--echo *** Test requesting an explicit GTID position that conflicts with newer GTIDs of our own in the binlog. *** +--connection slave +--source include/stop_slave.inc + +--connection master +RESET MASTER; +# This insert will be GTID 0-1-1 +INSERT INTO t1 VALUES (2); +# And this will be GTID 0-1-2 +INSERT INTO t1 VALUES (4); +--source include/save_master_gtid.inc + +--connection slave +SET sql_log_bin = 0; +INSERT INTO t1 VALUES (2); +SET sql_log_bin = 1; +INSERT INTO t1 VALUES (3); + +CHANGE MASTER TO master_use_gtid=current_pos; +# Most not change @@GLOBAL.gtid_slave_pos in the middle of a transaction. +BEGIN; +--error ER_CANT_DO_THIS_DURING_AN_TRANSACTION +SET GLOBAL gtid_slave_pos = "100-100-100"; +INSERT INTO t1 VALUES (100); +--error ER_CANT_DO_THIS_DURING_AN_TRANSACTION +SET GLOBAL gtid_slave_pos = "100-100-100"; +ROLLBACK; + +# In gtid non-strict mode, we get warnings for setting @@gtid_slave_pos back +# to earlier than what is in the binlog. In strict mode, we get an error. +SET GLOBAL gtid_strict_mode= 1; +--error ER_MASTER_GTID_POS_CONFLICTS_WITH_BINLOG +SET GLOBAL gtid_slave_pos = "0-1-1"; +--error ER_MASTER_GTID_POS_MISSING_DOMAIN +SET GLOBAL gtid_slave_pos = ""; +SET GLOBAL gtid_strict_mode= 0; +SET GLOBAL gtid_slave_pos = "0-1-1"; +SET GLOBAL gtid_slave_pos = ""; +RESET MASTER; +SET GLOBAL gtid_slave_pos = "0-1-1"; + +START SLAVE; +--source include/sync_with_master_gtid.inc +SELECT * FROM t1 ORDER BY a; + +--echo *** MDEV-4688: Empty value of @@GLOBAL.gtid_slave_pos *** +# The problem was that record_gtid() deleted too much of the in-memory state, +# leaving the state empty until after commit when we add the newly committed +# GTID. Test this by forcing an error after the delete of the old data but +# before the add of new data. + +--source include/stop_slave.inc + +--connection master +# This will be GTID 0-1-3 +INSERT INTO t1 VALUES (5); +--source include/save_master_gtid.inc + +--connection slave +SET @old_dbug= @@GLOBAL.debug_dbug; +SET GLOBAL debug_dbug="+d,dummy_disable_default_dbug_output"; +SET GLOBAL debug_dbug="+d,gtid_fail_after_record_gtid"; +SET sql_log_bin=0; +CALL mtr.add_suppression('Got error 131 "Command not supported by the engine" during COMMIT'); +SET sql_log_bin=1; +START SLAVE; +--let $slave_sql_errno= 1180 +--source include/wait_for_slave_sql_error.inc +# The bug was that @@GLOBAL.gtid_slave_pos was empty here. +SELECT @@GLOBAL.gtid_slave_pos; +SELECT * FROM t1 ORDER BY a; +SET GLOBAL debug_dbug= @old_dbug; +START SLAVE SQL_THREAD; +--source include/sync_with_master_gtid.inc +SELECT * FROM t1 ORDER BY a; + + +--echo *** Test slave requesting a GTID that is not present in the master's binlog *** +--source include/stop_slave.inc +SET GLOBAL gtid_slave_pos = "0-1-4"; +START SLAVE; + +SET sql_log_bin=0; +CALL mtr.add_suppression("Got fatal error .* from master when reading data from binary log: 'Error: connecting slave requested to start from GTID .*, which is not in the master's binlog'"); +SET sql_log_bin=1; +--let $slave_io_errno= 1236 +--source include/wait_for_slave_io_error.inc +--let $status_items= Slave_IO_State, Last_IO_Errno, Last_IO_Error, Using_Gtid +--source include/show_slave_status.inc + +--let $rpl_only_running_threads= 1 +--source include/stop_slave.inc +SET GLOBAL gtid_slave_pos = "0-1-3"; +START SLAVE; +--source include/wait_for_slave_to_start.inc + +--connection master +INSERT INTO t1 VALUES (6); +--source include/save_master_gtid.inc + +--connection slave +--source include/sync_with_master_gtid.inc +SELECT * FROM t1 ORDER BY a; + + +--echo *** MDEV-4278: Slave does not detect that master is not GTID-aware *** + +--connection slave +--source include/stop_slave.inc + +--connection master +SET @old_dbug= @@global.DEBUG_DBUG; +SET GLOBAL debug_dbug="+d,simulate_non_gtid_aware_master"; + +--connection slave +START SLAVE; +--let $slave_io_errno= 1233 +--source include/wait_for_slave_io_error.inc + +--connection master +SET GLOBAL debug_dbug= @old_dbug; +INSERT INTO t1 VALUES (7); +--save_master_pos + +--connection slave +START SLAVE; +--sync_with_master +SET sql_log_bin=0; +CALL mtr.add_suppression("The slave I/O thread stops because master does not support MariaDB global transaction id"); +SET sql_log_bin=1; + + +--echo *** Test error during record_gtid() (non-xid cases) *** + +--connection slave +--source include/stop_slave.inc + +--connection master +CREATE TABLE t2 (a INT) ENGINE=MyISAM; +INSERT INTO t2 VALUES (1); +--save_master_pos + +--connection slave +SET @old_dbug= @@global.DEBUG_DBUG; +SET GLOBAL debug_dbug="+d,gtid_inject_record_gtid"; + +START SLAVE; +--let $slave_sql_errno= 1942 +--source include/wait_for_slave_sql_error.inc + +SET GLOBAL debug_dbug= @old_dbug; + +START SLAVE SQL_THREAD; +--sync_with_master + +SELECT * FROM t2; +SET sql_log_bin=0; +CALL mtr.add_suppression("Slave: Could not update replication slave gtid state"); +SET sql_log_bin=1; + + +--echo *** MDEV-4906: When event apply fails, next SQL thread start erroneously commits the failing GTID to gtid_slave_pos *** + +--connection slave +--source include/stop_slave.inc +SET sql_log_bin=0; +DELETE FROM t2; +SET sql_log_bin=1; +SET @old_format=@@binlog_format; +SET GLOBAL binlog_format='row'; +--source include/start_slave.inc + +--connection master +SET @old_format=@@binlog_format; +SET binlog_format='row'; +--let $gtid_pos1=`SELECT @@GLOBAL.gtid_binlog_pos` +DELETE FROM t2; +SET binlog_format=@old_format; +--save_master_pos + +--connection slave +--let $slave_sql_errno= 1032 +--source include/wait_for_slave_sql_error.inc +# Disable query to avoid result file update if precise GTID value changes. +--disable_query_log +SET @x=@@GLOBAL.gtid_slave_pos; +eval SELECT IF(@x='$gtid_pos1', "OK", CONCAT("ERROR: expected $gtid_pos1 got ", @x)) AS result; +--enable_query_log + +# The bug was that upon restarting the SQL thread, the GTID for the +# failing event group was not cleared, so we would update it in the +# gtid_slave_pos as part of the first rotate event, corrupting the +# replication. +STOP SLAVE IO_THREAD; +START SLAVE; +--let $slave_sql_errno= 1032 +--source include/wait_for_slave_sql_error.inc +# Disable query to avoid result file update if precise GTID value changes. +--disable_query_log +SET @x=@@GLOBAL.gtid_slave_pos; +eval SELECT IF(@x='$gtid_pos1', "OK", CONCAT("ERROR: expected $gtid_pos1 got ", @x)) AS result; +--enable_query_log + +STOP SLAVE IO_THREAD; +SET sql_log_bin=0; +INSERT INTO t2 VALUES (1); +CALL mtr.add_suppression("Slave: Can't find record in 't2' Error_code: 1032"); +SET sql_log_bin=1; +--source include/start_slave.inc +--sync_with_master +SET GLOBAL binlog_format=@old_format; + +--connection master +DROP TABLE t1; +DROP TABLE t2; + +call mtr.add_suppression("Can't find record in 't2'"); + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_gtid_errorlog.test b/mysql-test/suite/rpl/t/rpl_gtid_errorlog.test new file mode 100644 index 00000000..ea321062 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_gtid_errorlog.test @@ -0,0 +1,85 @@ +--source include/have_debug.inc +--source include/master-slave.inc + +connection master; +SET GLOBAL BINLOG_CHECKSUM=NONE; +connection slave; +SET GLOBAL BINLOG_CHECKSUM=NONE; + +--echo *** Test MDEV-6120, output of current GTID when a replication error is logged to the errorlog *** +--connection master +CREATE TABLE t1(a INT PRIMARY KEY); +--sync_slave_with_master + +--connection slave +--source include/stop_slave.inc +CHANGE MASTER TO master_use_gtid=slave_pos; + +--connection master +INSERT INTO t1 VALUES (1); +SET gtid_seq_no=100; +INSERT INTO t1 VALUES (2); +INSERT INTO t1 VALUES (3); +INSERT INTO t1 VALUES (4); +--save_master_pos + +--connection slave +SET sql_log_bin=0; +INSERT INTO t1 VALUES (2); +SET sql_log_bin=1; + +START SLAVE; +--let $slave_sql_errno=1062 +--source include/wait_for_slave_sql_error.inc + +--source include/stop_slave.inc +# Skip the problem event from the master. +SET GLOBAL gtid_slave_pos= "0-1-100"; +--source include/start_slave.inc +--sync_with_master + +SELECT * FROM t1 ORDER BY a; + +--connection master + +SET @dbug_save= @@debug_dbug; +SET debug_dbug= '+d,incident_database_resync_on_replace'; +REPLACE INTO t1 VALUES (5); +SET debug_dbug= @dbug_save; +--save_master_pos + +--connection slave +--let $slave_sql_errno=1590 +--source include/wait_for_slave_sql_error.inc +--source include/stop_slave.inc +SET sql_slave_skip_counter=1; +--source include/start_slave.inc +--sync_with_master + +SELECT * FROM t1 ORDER BY a; + + +# Check error log for correct messages. +let $log_error_= `SELECT @@GLOBAL.log_error`; +if(!$log_error_) +{ + # MySQL Server on windows is started with --console and thus + # does not know the location of its .err log, use default location + let $log_error_ = $MYSQLTEST_VARDIR/log/mysqld.2.err; +} +--let SEARCH_FILE=$log_error_ +--let SEARCH_PATTERN=Slave SQL: Error 'Duplicate entry .* on query\. .*Query: '.*', Gtid 0-1-100, Internal MariaDB error code:|Slave SQL: Could not execute Write_rows.*table test.t1; Duplicate entry.*, Gtid 0-1-100, Internal MariaDB error +--source include/search_pattern_in_file.inc +--let SEARCH_PATTERN=Slave SQL: The incident LOST_EVENTS occurred on the master\. Message: , Internal MariaDB error code: 1590 +--source include/search_pattern_in_file.inc + + +--connection master +DROP TABLE t1; + +connection master; +SET GLOBAL BINLOG_CHECKSUM=default; +connection slave; +SET GLOBAL BINLOG_CHECKSUM=default; +connection master; +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_gtid_excess_initial_delay.test b/mysql-test/suite/rpl/t/rpl_gtid_excess_initial_delay.test new file mode 100644 index 00000000..d840b67e --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_gtid_excess_initial_delay.test @@ -0,0 +1,58 @@ +# ==== Purpose ==== +# +# Test verifies that when "Master_Delay" is specified on slave with GTIDS there +# will not be any extra delay initially. +# +# ==== Implementation ==== +# +# Steps: +# 0 - Stop the slave and execute CHANGE MASTER command with +# master_use_gtid= curren_pos and master_delay= 10 +# 1 - On slave introduce a sleep of 15 seconds and check that the +# Seconds_Behind_Master is within specified master_delay limit. It should +# not be more that "10" seconds. +# +# ==== References ==== +# +# MDEV-13895: GTID and Master_Delay causes excessive initial delay + +--source include/have_binlog_format_mixed.inc +--source include/master-slave.inc + +CREATE TABLE t1 (i INT); +--sync_slave_with_master + +--source include/stop_slave.inc +CHANGE MASTER TO MASTER_USE_GTID= current_pos, MASTER_DELAY= 10; +--source include/start_slave.inc + +--connection master +INSERT INTO t1 VALUES (1); +--source include/sync_slave_io_with_master.inc + +--connection slave +--let $actual_delay= query_get_value(SHOW SLAVE STATUS, SQL_Delay, 1) +--let $sleep_time= `SELECT 5 + $actual_delay` +--echo "Sleeping for $sleep_time" +--sleep $sleep_time + +--let $assert_cond= [SHOW SLAVE STATUS, Seconds_Behind_Master, 1] <= 10 +--let $assert_text= Seconds_Behind_Master should be less than MASTER_DELAY +--source include/rpl_assert.inc + +# The row should be available in table after master_delay=20 seconds. +--let $assert_text= One row shoule be found in table t1. +--let $assert_cond= COUNT(*) = 1 FROM t1 +--source include/rpl_assert.inc + +--echo "======= Clean up ========" +STOP SLAVE; +CHANGE MASTER TO MASTER_USE_GTID=no, MASTER_DELAY=0; +START SLAVE; + +--connection master +DROP TABLE t1; +--sync_slave_with_master + +--connection master +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_gtid_ignored.test b/mysql-test/suite/rpl/t/rpl_gtid_ignored.test new file mode 100644 index 00000000..3c1324b2 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_gtid_ignored.test @@ -0,0 +1,141 @@ +--source include/have_innodb.inc +--source include/have_debug.inc +--source include/have_debug_sync.inc + +--let $rpl_topology=1->2 +--source include/rpl_init.inc + +--connection server_1 +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; + +SET @old_gtid_strict_mode= @@GLOBAL.gtid_strict_mode; +SET GLOBAL gtid_strict_mode= 1; + +--connection server_2 +--source include/stop_slave.inc +SET @old_gtid_strict_mode= @@GLOBAL.gtid_strict_mode; +SET GLOBAL gtid_strict_mode=1; +CHANGE MASTER TO master_use_gtid=slave_pos; +--source include/start_slave.inc + +--connection server_1 +CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1); +--save_master_pos + +--connection server_2 +--sync_with_master + +--echo **** MDEV-4488: GTID position should be updated for events that are ignored due to server id *** +--source include/stop_slave.inc +CHANGE MASTER TO ignore_server_ids=(1); +--source include/start_slave.inc + +--connection server_1 +# These inserts should be ignored (not applied) on the slave, but the +# gtid_slave_pos should still be updated. +INSERT INTO t1 VALUES (2); +INSERT INTO t1 VALUES (3); +--save_master_pos +--let gtid_pos=`SELECT @@GLOBAL.gtid_binlog_pos` + +--connection server_2 +--sync_with_master +--let $wait_condition= SELECT @@GLOBAL.gtid_slave_pos = '$gtid_pos' +--source include/wait_condition.inc +--disable_query_log +eval SELECT IF(@@GLOBAL.gtid_slave_pos = '$gtid_pos', 'OK', CONCAT("ERROR: Expected $gtid_pos got ", @@GLOBAL.gtid_slave_pos)) AS RESULT; +--enable_query_log + +SELECT * FROM t1 ORDER BY a; + +--source include/stop_slave.inc +CHANGE MASTER TO ignore_server_ids=(); +--source include/start_slave.inc +--sync_with_master +--disable_query_log +eval SELECT IF(@@GLOBAL.gtid_slave_pos = '$gtid_pos', 'OK', CONCAT("ERROR: Expected $gtid_pos got ", @@GLOBAL.gtid_slave_pos)) AS RESULT; +--enable_query_log + +SELECT * FROM t1 ORDER BY a; + +--connection server_1 +INSERT INTO t1 VALUES (4); +INSERT INTO t1 VALUES (5); +--let gtid_pos=`SELECT @@GLOBAL.gtid_binlog_pos` +--save_master_pos + +--connection server_2 +--sync_with_master +--disable_query_log +eval SELECT IF(@@GLOBAL.gtid_slave_pos = '$gtid_pos', 'OK', CONCAT("ERROR: Expected $gtid_pos got ", @@GLOBAL.gtid_slave_pos)) AS RESULT; +SELECT * FROM t1 ORDER BY a; +--enable_query_log + + +--echo *** Test the same thing when IO thread exits before SQL thread reaches end of log. *** +--connection server_2 +--source include/stop_slave.inc +SET @old_dbug= @@GLOBAL.debug_dbug; +SET GLOBAL debug_dbug= "+d,inject_slave_sql_before_apply_event"; +CHANGE MASTER TO ignore_server_ids=(1); +--source include/start_slave.inc + +--connection server_1 +INSERT INTO t1 VALUES (6); +INSERT INTO t1 VALUES (7); +--let $master_pos= query_get_value(SHOW MASTER STATUS, Position, 1) +--let gtid_pos=`SELECT @@GLOBAL.gtid_binlog_pos` +--save_master_pos + +--connection server_2 +# Wait for IO thread to have read all events from master, and for SQL thread to +# sit in the debug_sync point. + +--let $slave_param= Read_Master_Log_Pos +--let $slave_param_value= $master_pos +--source include/wait_for_slave_param.inc + +# Now stop the IO thread, and let the SQL thread continue. The IO thread +# should write a Gtid_list event that the SQL thread can use to update the +# gtid_slave_pos with the GTIDs of the skipped events. +STOP SLAVE IO_THREAD; +SET debug_sync = "now SIGNAL continue"; + +--sync_with_master +--let $wait_condition= SELECT @@GLOBAL.gtid_slave_pos = '$gtid_pos' +--source include/wait_condition.inc +--disable_query_log +eval SELECT IF(@@GLOBAL.gtid_slave_pos = '$gtid_pos', 'OK', CONCAT("ERROR: Expected $gtid_pos got ", @@GLOBAL.gtid_slave_pos)) AS RESULT; +--let $slave_pos= query_get_value(SHOW SLAVE STATUS, Exec_Master_Log_Pos, 1) +eval SELECT IF('$slave_pos' = '$master_pos', 'OK', "ERROR: Expected $master_pos got $slave_pos") AS RESULT; +--enable_query_log + + +--source include/stop_slave.inc +CHANGE MASTER TO ignore_server_ids=(); +SET GLOBAL debug_dbug= @old_dbug; +--source include/start_slave.inc + +--connection server_1 +INSERT INTO t1 VALUES (8); +INSERT INTO t1 VALUES (9); +--save_master_pos + +--connection server_2 +--sync_with_master +SELECT * FROM t1 ORDER BY a; + +# Clean up. +--connection server_1 +DROP TABLE t1; +ALTER TABLE mysql.gtid_slave_pos ENGINE=Aria; +SET GLOBAL gtid_strict_mode= @old_gtid_strict_mode; +SET debug_sync = "reset"; + +--connection server_2 +SET GLOBAL gtid_strict_mode= @old_gtid_strict_mode; +SET debug_sync = "reset"; + +--source include/rpl_end.inc + diff --git a/mysql-test/suite/rpl/t/rpl_gtid_master_promote.cnf b/mysql-test/suite/rpl/t/rpl_gtid_master_promote.cnf new file mode 100644 index 00000000..4eafa897 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_gtid_master_promote.cnf @@ -0,0 +1,35 @@ +!include ../my.cnf + +[mysqld.1] +log-slave-updates +loose-innodb + +[mysqld.2] +log-slave-updates +skip-slave-start +loose-innodb + +[mysqld.3] +log-slave-updates +skip-slave-start +loose-innodb + +[mysqld.4] +log-slave-updates +skip-slave-start +loose-innodb + +[mysqld.5] +log-slave-updates +skip-slave-start +loose-innodb + +[ENV] +SERVER_MYPORT_3= @mysqld.3.port +SERVER_MYSOCK_3= @mysqld.3.socket + +SERVER_MYPORT_4= @mysqld.4.port +SERVER_MYSOCK_4= @mysqld.4.socket + +SERVER_MYPORT_5= @mysqld.5.port +SERVER_MYSOCK_5= @mysqld.5.socket diff --git a/mysql-test/suite/rpl/t/rpl_gtid_master_promote.test b/mysql-test/suite/rpl/t/rpl_gtid_master_promote.test new file mode 100644 index 00000000..bd5343d7 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_gtid_master_promote.test @@ -0,0 +1,270 @@ +--source include/have_innodb.inc +--let $rpl_topology=1->2, 1->3, 1->4, 1->5 +--source include/rpl_init.inc + +# Set up a topology with one master and 4 slaves. +# +# Replicate some events leaving the four slaves at different points +# in different domains. +# +# Then promote one slave as new master, bringing it ahead of all others +# using START SLAVE UNTIL master_gtid_pos. + +--connection server_1 +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +CREATE TABLE t4 (a INT, b INT, PRIMARY KEY (a,b)) Engine=InnoDB; + +# Function to extract one GTID from a list. +delimiter |; +CREATE FUNCTION extract_gtid(d VARCHAR(100), s VARCHAR(100)) + RETURNS VARCHAR(100) DETERMINISTIC +BEGIN + SET s= CONCAT(",", s, ","); + SET s= SUBSTR(s FROM LOCATE(CONCAT(",", d, "-"), s) + 1); + SET s= SUBSTR(s FROM 1 FOR LOCATE(",", s) - 1); + RETURN s; +END| +delimiter ;| + +--save_master_pos + +--connection server_2 +--sync_with_master +--source include/stop_slave.inc +CHANGE MASTER TO master_use_gtid=current_pos; + +--connection server_3 +--sync_with_master +--source include/stop_slave.inc +CHANGE MASTER TO master_use_gtid=current_pos; + +--connection server_4 +--sync_with_master +--source include/stop_slave.inc +CHANGE MASTER TO master_use_gtid=current_pos; + +--connection server_5 +--sync_with_master +--source include/stop_slave.inc +CHANGE MASTER TO master_use_gtid=current_pos; + + +# Create three separate replication streams on master server_1. +# +# Then use START SLAVE UNTIL to get the different streams interleaved +# differently spread over multiple binlogs on the different slaves, to +# test that new master promotion is able to deal with this. + +--connection server_1 + +SET gtid_domain_id= 1; +CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB; +--let $d1_begin= `SELECT extract_gtid("1", @@GLOBAL.gtid_binlog_pos)` +INSERT INTO t1 VALUES (1); +INSERT INTO t1 VALUES (2); +INSERT INTO t4 VALUES (1, 1); +--let $d1_mid= `SELECT extract_gtid("1", @@GLOBAL.gtid_binlog_pos)` +INSERT INTO t1 VALUES (3); +INSERT INTO t1 VALUES (4); +INSERT INTO t4 VALUES (1, 3); +--let $d1_end= `SELECT extract_gtid("1", @@GLOBAL.gtid_binlog_pos)` + +SET gtid_domain_id= 2; +CREATE TABLE t2 (a INT PRIMARY KEY) ENGINE=InnoDB; +--let $d2_begin= `SELECT extract_gtid("2", @@GLOBAL.gtid_binlog_pos)` +INSERT INTO t2 VALUES (1); +INSERT INTO t2 VALUES (2); +INSERT INTO t4 VALUES (2, 1); +--let $d2_mid= `SELECT extract_gtid("2", @@GLOBAL.gtid_binlog_pos)` +INSERT INTO t2 VALUES (3); +INSERT INTO t2 VALUES (4); +INSERT INTO t4 VALUES (2, 3); +--let $d2_end= `SELECT extract_gtid("2", @@GLOBAL.gtid_binlog_pos)` + +SET gtid_domain_id= 3; +CREATE TABLE t3 (a INT PRIMARY KEY) ENGINE=InnoDB; +--let $d3_begin= `SELECT extract_gtid("3", @@GLOBAL.gtid_binlog_pos)` +INSERT INTO t3 VALUES (1); +INSERT INTO t3 VALUES (2); +INSERT INTO t4 VALUES (3, 1); +--let $d3_mid= `SELECT extract_gtid("3", @@GLOBAL.gtid_binlog_pos)` +INSERT INTO t3 VALUES (3); +INSERT INTO t3 VALUES (4); +INSERT INTO t4 VALUES (3, 3); +--let $d3_end= `SELECT extract_gtid("3", @@GLOBAL.gtid_binlog_pos)` + + +# Slave server_2 (that will be promoted to master) is in the middle +# of each stream. +--connection server_2 +eval START SLAVE UNTIL master_gtid_pos= "$d1_mid,$d2_mid,$d3_mid"; + +# The remaining slaves sit at different points each in different domains. +--connection server_3 +eval START SLAVE UNTIL master_gtid_pos= "$d1_begin,$d2_mid,$d3_end"; +--connection server_4 +eval START SLAVE UNTIL master_gtid_pos= "$d2_begin,$d3_mid,$d1_end"; +--connection server_5 +eval START SLAVE UNTIL master_gtid_pos= "$d3_begin,$d1_mid,$d2_end"; +--connection server_2 +--source include/wait_for_slave_to_stop.inc +SELECT * FROM t1 ORDER BY a; +SELECT * FROM t2 ORDER BY a; +SELECT * FROM t3 ORDER BY a; +SELECT * FROM t4 ORDER BY a,b; +--connection server_3 +--source include/wait_for_slave_to_stop.inc +SELECT * FROM t1 ORDER BY a; +SELECT * FROM t2 ORDER BY a; +SELECT * FROM t3 ORDER BY a; +SELECT * FROM t4 ORDER BY a,b; +--connection server_4 +--source include/wait_for_slave_to_stop.inc +SELECT * FROM t1 ORDER BY a; +SELECT * FROM t2 ORDER BY a; +SELECT * FROM t3 ORDER BY a; +SELECT * FROM t4 ORDER BY a,b; +--connection server_5 +--source include/wait_for_slave_to_stop.inc +SELECT * FROM t1 ORDER BY a; +SELECT * FROM t2 ORDER BY a; +SELECT * FROM t3 ORDER BY a; +SELECT * FROM t4 ORDER BY a,b; + + +--echo *** Now replicate all extra changes from 3,4,5 to 2, in preparation for making 2 the new master. *** + +--connection server_3 +--let $server3_pos= `SELECT @@GLOBAL.gtid_slave_pos` +--connection server_2 +--replace_result $SERVER_MYPORT_3 SERVER_MYPORT_3 +eval CHANGE MASTER TO master_host = '127.0.0.1', master_port = $SERVER_MYPORT_3; +--replace_result $server3_pos SERVER3_POS +eval START SLAVE UNTIL master_gtid_pos = "$server3_pos"; +--source include/wait_for_slave_to_stop.inc +SELECT * FROM t1 ORDER BY a; +SELECT * FROM t2 ORDER BY a; +SELECT * FROM t3 ORDER BY a; +SELECT * FROM t4 ORDER BY a,b; + +--connection server_4 +--let $server4_pos= `SELECT @@GLOBAL.gtid_slave_pos` +--connection server_2 +--replace_result $SERVER_MYPORT_4 SERVER_MYPORT_4 +eval CHANGE MASTER TO master_host = '127.0.0.1', master_port = $SERVER_MYPORT_4; +--replace_result $server4_pos SERVER4_POS +eval START SLAVE UNTIL master_gtid_pos = "$server4_pos"; +--source include/wait_for_slave_to_stop.inc +SELECT * FROM t1 ORDER BY a; +SELECT * FROM t2 ORDER BY a; +SELECT * FROM t3 ORDER BY a; +SELECT * FROM t4 ORDER BY a,b; + +--connection server_5 +--let $server5_pos= `SELECT @@GLOBAL.gtid_slave_pos` +--connection server_2 +--replace_result $SERVER_MYPORT_5 SERVER_MYPORT_5 +eval CHANGE MASTER TO master_host = '127.0.0.1', master_port = $SERVER_MYPORT_5; +--replace_result $server5_pos SERVER5_POS +eval START SLAVE UNTIL master_gtid_pos = "$server5_pos"; +--source include/wait_for_slave_to_stop.inc +SELECT * FROM t1 ORDER BY a; +SELECT * FROM t2 ORDER BY a; +SELECT * FROM t3 ORDER BY a; +SELECT * FROM t4 ORDER BY a,b; + +--echo *** Now make 2 master and point 3,4,5 to the new master 2 +--connection server_2 +SET gtid_domain_id= 1; +INSERT INTO t1 values (5); +INSERT INTO t4 values (1,5); +SET gtid_domain_id= 2; +INSERT INTO t2 values (5); +INSERT INTO t4 values (2,5); +SET gtid_domain_id= 3; +INSERT INTO t3 values (5); +INSERT INTO t4 values (3,5); + +--connection server_3 +--replace_result $SERVER_MYPORT_2 SERVER_MYPORT_2 +eval CHANGE MASTER TO master_host = '127.0.0.1', master_port = $SERVER_MYPORT_2; +--source include/start_slave.inc +--connection server_4 +--replace_result $SERVER_MYPORT_2 SERVER_MYPORT_2 +eval CHANGE MASTER TO master_host = '127.0.0.1', master_port = $SERVER_MYPORT_2; +--source include/start_slave.inc +--connection server_5 +--replace_result $SERVER_MYPORT_2 SERVER_MYPORT_2 +eval CHANGE MASTER TO master_host = '127.0.0.1', master_port = $SERVER_MYPORT_2; +--source include/start_slave.inc + +--connection server_2 +--save_master_pos + +--connection server_3 +--sync_with_master +SELECT * FROM t1 ORDER BY a; +SELECT * FROM t2 ORDER BY a; +SELECT * FROM t3 ORDER BY a; +SELECT * FROM t4 ORDER BY a,b; +--connection server_5 +--sync_with_master +SELECT * FROM t1 ORDER BY a; +SELECT * FROM t2 ORDER BY a; +SELECT * FROM t3 ORDER BY a; +SELECT * FROM t4 ORDER BY a,b; +--connection server_5 +--sync_with_master +SELECT * FROM t1 ORDER BY a; +SELECT * FROM t2 ORDER BY a; +SELECT * FROM t3 ORDER BY a; +SELECT * FROM t4 ORDER BY a,b; + + +--echo *** Now let the old master join up as slave. *** +--connection server_1 +--replace_result $SERVER_MYPORT_2 SERVER_MYPORT_2 +eval CHANGE MASTER TO master_host = '127.0.0.1', master_port = $SERVER_MYPORT_2, + master_user = "root", master_use_gtid = current_pos; +--source include/start_slave.inc +--sync_with_master +SELECT * FROM t1 ORDER BY a; +SELECT * FROM t2 ORDER BY a; +SELECT * FROM t3 ORDER BY a; +SELECT * FROM t4 ORDER BY a,b; + + +--echo *** Finally move things back and clean up. *** +--connection server_1 +--source include/stop_slave.inc +RESET SLAVE ALL; + +--connection server_2 +--replace_result $SERVER_MYPORT_1 SERVER_MYPORT_1 +eval CHANGE MASTER TO master_host = '127.0.0.1', master_port = $SERVER_MYPORT_1; +--source include/start_slave.inc +--connection server_3 +--source include/stop_slave.inc +--replace_result $SERVER_MYPORT_1 SERVER_MYPORT_1 +eval CHANGE MASTER TO master_host = '127.0.0.1', master_port = $SERVER_MYPORT_1; +--source include/start_slave.inc +--connection server_4 +--source include/stop_slave.inc +--replace_result $SERVER_MYPORT_1 SERVER_MYPORT_1 +eval CHANGE MASTER TO master_host = '127.0.0.1', master_port = $SERVER_MYPORT_1; +--source include/start_slave.inc +--connection server_5 +--source include/stop_slave.inc +--replace_result $SERVER_MYPORT_1 SERVER_MYPORT_1 +eval CHANGE MASTER TO master_host = '127.0.0.1', master_port = $SERVER_MYPORT_1; +--source include/start_slave.inc + +--connection server_1 +SET gtid_domain_id = 0; +DROP TABLE t1; +DROP TABLE t2; +DROP TABLE t3; +DROP TABLE t4; +DROP FUNCTION extract_gtid; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_gtid_mdev4473.cnf b/mysql-test/suite/rpl/t/rpl_gtid_mdev4473.cnf new file mode 100644 index 00000000..4fe90e6a --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_gtid_mdev4473.cnf @@ -0,0 +1,18 @@ +!include ../my.cnf + +[mysqld.1] +log-slave-updates +loose-innodb + +[mysqld.2] +log-slave-updates +loose-innodb + +[mysqld.3] +log-slave-updates +loose-innodb + +[ENV] +SERVER_MYPORT_3= @mysqld.3.port +SERVER_MYSOCK_3= @mysqld.3.socket + diff --git a/mysql-test/suite/rpl/t/rpl_gtid_mdev4473.test b/mysql-test/suite/rpl/t/rpl_gtid_mdev4473.test new file mode 100644 index 00000000..01259eb5 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_gtid_mdev4473.test @@ -0,0 +1,72 @@ +--source include/have_innodb.inc +--source include/have_binlog_format_mixed.inc + +--let $rpl_topology=1->2,1->3 +--source include/rpl_init.inc + +connection server_1; +create table t1 (n int); +insert into t1 values (1); +insert into t1 values (2); +save_master_pos; + +connection server_3; +sync_with_master; +source include/stop_slave.inc; +source include/wait_for_slave_to_stop.inc; + +connection server_2; +sync_with_master; +source include/stop_slave.inc; +source include/wait_for_slave_to_stop.inc; +reset slave all; + +connection server_1; +--replace_result $SERVER_MYPORT_2 SERVER_MYPORT_2 +eval CHANGE MASTER TO master_host = '127.0.0.1', master_port = $SERVER_MYPORT_2, + master_user='root', MASTER_USE_GTID=CURRENT_POS; +source include/start_slave.inc; +source include/wait_for_slave_to_start.inc; + +connection server_2; +flush logs; +insert into t1 values (3); +insert into t1 values (4); +flush logs; +save_master_pos; + +connection server_3; +--replace_result $SERVER_MYPORT_2 SERVER_MYPORT_2 +eval CHANGE MASTER TO master_host = '127.0.0.1', master_port = $SERVER_MYPORT_2, + MASTER_USE_GTID=CURRENT_POS; +source include/start_slave.inc; +sync_with_master; + +select * from t1 order by n; +source include/show_binary_logs.inc; +let $binlog_file=LAST; +source include/show_binlog_events.inc; + +connection server_1; +--sync_with_master +source include/stop_slave.inc; +source include/wait_for_slave_to_stop.inc; +reset slave all; + +connection server_2; +--replace_result $SERVER_MYPORT_1 SERVER_MYPORT_1 +eval CHANGE MASTER TO master_host = '127.0.0.1', master_port = $SERVER_MYPORT_1, + master_user = 'root', MASTER_USE_GTID=CURRENT_POS; +source include/start_slave.inc; + +connection server_3; +source include/stop_slave.inc; +--replace_result $SERVER_MYPORT_1 SERVER_MYPORT_1 +eval CHANGE MASTER TO master_host = '127.0.0.1', master_port = $SERVER_MYPORT_1, + MASTER_USE_GTID=CURRENT_POS; +source include/start_slave.inc; + +connection server_1; +drop table t1; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_gtid_mdev4474.cnf b/mysql-test/suite/rpl/t/rpl_gtid_mdev4474.cnf new file mode 100644 index 00000000..2b9e70c5 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_gtid_mdev4474.cnf @@ -0,0 +1,11 @@ +!include suite/rpl/rpl_1slave_base.cnf +!include include/default_client.cnf + + +[mysqld.1] +log-slave-updates +loose-innodb + +[mysqld.2] +log-slave-updates +loose-innodb diff --git a/mysql-test/suite/rpl/t/rpl_gtid_mdev4474.test b/mysql-test/suite/rpl/t/rpl_gtid_mdev4474.test new file mode 100644 index 00000000..064f7b8a --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_gtid_mdev4474.test @@ -0,0 +1,72 @@ +--source include/have_innodb.inc +--source include/have_binlog_format_mixed_or_statement.inc +--let $rpl_topology=1->2->1 +--source include/rpl_init.inc + +--echo # +--echo # For now we'll only have 1->2 running + +--echo # +--echo # Server 1 +--echo # Stop replication 2->1 +--connection server_1 +--source include/stop_slave.inc + +--echo # +--echo # Server 2 +--echo # Use GTID for replication 1->2 +--connection server_2 +--source include/stop_slave.inc +change master to master_use_gtid=slave_pos; +--source include/start_slave.inc + +--echo # +--echo # Create some 0-1-* and 0-2-* events in binlog of server 2 + +--connection server_1 +create table t1 (i int) engine=InnoDB; +insert into t1 values (1); +--save_master_pos + +--connection server_2 +--sync_with_master +create table t2 (i int) engine=InnoDB; +--save_master_pos + +--connection server_1 +insert into t1 values (2); +--save_master_pos + +--connection server_2 +--sync_with_master +insert into t2 values (1); +--save_master_pos + +--echo # +--echo # All events are present in the binlog of server 2 + +--source include/show_binlog_events.inc + +--echo # +--echo # Server 1 +--echo # Start replication 2->1 using GTID, + +--connection server_1 +change master to master_use_gtid=slave_pos; +--source include/start_slave.inc +--sync_with_master + +select * from t1 order by i; +select * from t2 order by i; + +--connection server_2 +select * from t1 order by i; +select * from t2 order by i; + +--connection server_1 +drop table t1; + +--connection server_2 +drop table t2; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_gtid_mdev4484.test b/mysql-test/suite/rpl/t/rpl_gtid_mdev4484.test new file mode 100644 index 00000000..5c17653d --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_gtid_mdev4484.test @@ -0,0 +1,106 @@ +--source include/have_innodb.inc +--source include/have_debug.inc +--source include/master-slave.inc + +--connection slave +--source include/stop_slave.inc +# Since we inject an error updating mysql.gtid_slave_pos, we will get different +# output depending on whether it is InnoDB or MyISAM (roll back or no roll +# back). So fix it to make sure we are consistent, in case an earlier test case +# left it as InnoDB. +SET sql_log_bin=0; +ALTER TABLE mysql.gtid_slave_pos ENGINE=Aria; +SET sql_log_bin=1; +--source include/start_slave.inc + +--connection master +CREATE TABLE t1 (i int) ENGINE=InnoDB; + +--sync_slave_with_master + +--echo *** MDEV-4484, incorrect error handling when entries in gtid_slave_pos not found. *** +TRUNCATE TABLE mysql.gtid_slave_pos; + +--connection master +INSERT INTO t1 VALUES (1); +--sync_slave_with_master + +# Inject an artificial error deleting entries, and check that the error handling code works. +--connection slave +--source include/stop_slave.inc +SET @old_gtid_cleanup_batch_size= @@GLOBAL.gtid_cleanup_batch_size; +SET GLOBAL gtid_cleanup_batch_size= 2; +SET @old_dbug= @@GLOBAL.debug_dbug; +SET GLOBAL debug_dbug="+d,gtid_slave_pos_simulate_failed_delete"; +SET sql_log_bin= 0; +CALL mtr.add_suppression(" Error deleting old GTID row"); +SET sql_log_bin= 1; +--source include/start_slave.inc + +--connection master +--disable_query_log +let $i = 20; +while ($i) { + eval INSERT INTO t1 VALUES ($i+10); + dec $i; +} +--enable_query_log +--save_master_pos + +--connection slave +--sync_with_master + +# Now wait for the slave background thread to try to delete old rows and +# hit the error injection. +--let _TEST_MYSQLD_ERROR_LOG=$MYSQLTEST_VARDIR/log/mysqld.2.err +--perl + open F, '<', $ENV{'_TEST_MYSQLD_ERROR_LOG'} or die; + outer: while (1) { + inner: while () { + last outer if / Error deleting old GTID row/; + } + # Easy way to do sub-second sleep without extra modules. + select(undef, undef, undef, 0.1); + } +EOF + +# Since we injected error in the cleanup code, the rows should remain in +# mysql.gtid_slave_pos. Check that we have at least 20 (more robust against +# non-deterministic cleanup and future changes than checking for exact number). +SELECT COUNT(*), MAX(seq_no) INTO @pre_count, @pre_max_seq_no + FROM mysql.gtid_slave_pos; +SELECT IF(@pre_count >= 20, "OK", CONCAT("Error: too few rows seen while errors injected: ", @pre_count)); +SET GLOBAL debug_dbug= @old_dbug; + +--connection master +--disable_query_log +let $i = 20; +while ($i) { + eval INSERT INTO t1 VALUES ($i+40); + dec $i; +} +--enable_query_log +--sync_slave_with_master + +--connection slave +# Now check that 1) rows are being deleted again after removing error +# injection, and 2) old rows are left that failed their delete while errors +# where injected (again compensating for non-deterministic deletion). +# Deletion is async and slightly non-deterministic, so we wait for at +# least 10 of the 20 new rows to be deleted. +let $wait_condition= + SELECT COUNT(*) <= 20-10 + FROM mysql.gtid_slave_pos + WHERE seq_no > @pre_max_seq_no; +--source include/wait_condition.inc +SELECT IF(COUNT(*) >= 1, "OK", CONCAT("Error: too few rows seen after errors no longer injected: ", COUNT(*))) + FROM mysql.gtid_slave_pos + WHERE seq_no <= @pre_max_seq_no; + +# Clean up +--connection master +DROP TABLE t1; +--connection slave +SET GLOBAL gtid_cleanup_batch_size= @old_gtid_cleanup_batch_size; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_gtid_mdev4485.cnf b/mysql-test/suite/rpl/t/rpl_gtid_mdev4485.cnf new file mode 100644 index 00000000..fccef215 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_gtid_mdev4485.cnf @@ -0,0 +1,18 @@ +!include suite/rpl/rpl_1slave_base.cnf +!include include/default_client.cnf + +[mysqld.1] +log-slave-updates +gtid-domain-id=1 + +[mysqld.2] +log-slave-updates +gtid-domain-id=2 + +[mysqld.3] +log-slave-updates +gtid-domain-id=3 + +[ENV] +SERVER_MYPORT_3= @mysqld.3.port +SERVER_MYSOCK_3= @mysqld.3.socket diff --git a/mysql-test/suite/rpl/t/rpl_gtid_mdev4485.test b/mysql-test/suite/rpl/t/rpl_gtid_mdev4485.test new file mode 100644 index 00000000..6c37ceaf --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_gtid_mdev4485.test @@ -0,0 +1,41 @@ +--let $rpl_topology= 1->3 +--source include/rpl_init.inc + +--echo *** MDEV-4485. Master did not allow slave to connect from the very start (empty GTID pos) if GTIDs from other multi_source master was present *** + +--connection server_1 +create table t1 (i int); + +--connection server_2 +create table t2 (i int); + +--connection server_3 + +set default_master_connection = 'm2'; +--replace_result $SERVER_MYPORT_2 SERVER_MYPORT_2 +eval change master to master_host='127.0.0.1', master_port=$SERVER_MYPORT_2, master_user='root', master_use_gtid=slave_pos; +--source include/start_slave.inc + +--connection server_2 +insert into t2 values (1); +--save_master_pos + +--connection server_3 +--sync_with_master 0,'m2' + +--connection server_1 +drop table t1; + +--connection server_2 +drop table t2; +--save_master_pos + +--connection server_3 +--sync_with_master 0,'m2' +set default_master_connection = 'm2'; +--source include/stop_slave.inc +RESET SLAVE ALL; +set default_master_connection = ''; + +--connection server_1 +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_gtid_mdev4820.test b/mysql-test/suite/rpl/t/rpl_gtid_mdev4820.test new file mode 100644 index 00000000..7f4d851f --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_gtid_mdev4820.test @@ -0,0 +1,118 @@ +--let $rpl_topology=1->2 +--source include/rpl_init.inc + +--connection server_2 +--source include/stop_slave.inc +SET @slave_old_strict= @@GLOBAL.gtid_strict_mode; +SET GLOBAL gtid_strict_mode= 1; +CHANGE MASTER TO master_use_gtid=slave_pos; +--source include/start_slave.inc + +--connection server_1 +SET @master_old_strict= @@GLOBAL.gtid_strict_mode; +SET GLOBAL gtid_strict_mode= 1; +CREATE TABLE t1 (a INT PRIMARY KEY); +INSERT INTO t1 VALUES (1); +--save_master_pos + +--connection server_2 +--sync_with_master +SELECT * FROM t1 ORDER BY a; + +--source include/stop_slave.inc + +--connection server_1 +INSERT INTO t1 VALUES (2); +INSERT INTO t1 VALUES (3); +--let $old_gtid_pos= `SELECT @@GLOBAL.gtid_current_pos` +RESET MASTER; +--replace_result $old_gtid_pos OLD_GTID_POS +eval SET GLOBAL gtid_slave_pos= '$old_gtid_pos'; + +--connection server_2 +--source include/start_slave.inc + +--connection server_1 +INSERT INTO t1 VALUES (4); +--source include/save_master_gtid.inc + +--connection server_2 +SET sql_log_bin= 0; +CALL mtr.add_suppression("The binlog on the master is missing the GTID"); +SET sql_log_bin= 1; +--let $slave_io_errno=1236 +--source include/wait_for_slave_io_error.inc + +STOP SLAVE SQL_THREAD; +--replace_result $old_gtid_pos OLD_GTID_POS +eval SET GLOBAL gtid_slave_pos= '$old_gtid_pos'; + +--source include/start_slave.inc +--source include/sync_with_master_gtid.inc +SELECT * FROM t1 ORDER BY a; + +--source include/stop_slave.inc +RESET SLAVE ALL; +RESET MASTER; +SET GLOBAL gtid_slave_pos= '0-2-10'; + +--connection server_1 +--replace_result $SERVER_MYPORT_2 SERVER_MYPORT_2 +eval CHANGE MASTER TO master_host = '127.0.0.1', master_port = $SERVER_MYPORT_2, + master_user= 'root', master_use_gtid=CURRENT_POS; +START SLAVE; + +--connection server_2 +INSERT INTO t1 VALUES (11); +--save_master_pos + +--connection server_1 +SET sql_log_bin= 0; +CALL mtr.add_suppression("which is not in the master's binlog. Since the master's binlog contains GTIDs with higher sequence numbers, it probably means that the slave has diverged"); +SET sql_log_bin= 1; +--let $slave_io_errno=1236 +--source include/wait_for_slave_io_error.inc + +--connection server_1 +STOP SLAVE SQL_THREAD; +SET GLOBAL gtid_slave_pos= '0-2-10'; +SET GLOBAL gtid_strict_mode= 0; +--source include/start_slave.inc +--sync_with_master +SELECT * FROM t1 ORDER BY a; + +--source include/stop_slave.inc +RESET SLAVE ALL; +--let $old_gtid_pos= `SELECT @@GLOBAL.gtid_current_pos` +INSERT INTO t1 VALUES (12); +--save_master_pos + +--connection server_2 +INSERT INTO t1 VALUES (22); +--replace_result $SERVER_MYPORT_1 SERVER_MYPORT_1 +eval CHANGE MASTER TO master_host = '127.0.0.1', master_port = $SERVER_MYPORT_1, + master_user= 'root', master_use_gtid=CURRENT_POS; +START SLAVE; +SET sql_log_bin= 0; +CALL mtr.add_suppression("which is not in the master's binlog. Since the master's binlog contains GTIDs with higher sequence numbers, it probably means that the slave has diverged"); +SET sql_log_bin= 1; +--let $slave_io_errno=1236 +--source include/wait_for_slave_io_error.inc +STOP SLAVE SQL_THREAD; +SET GLOBAL gtid_strict_mode= 0; +CHANGE MASTER TO master_use_gtid=SLAVE_POS; +--replace_result $old_gtid_pos OLD_GTID_POS +eval SET GLOBAL gtid_slave_pos= '$old_gtid_pos'; +--source include/start_slave.inc +--sync_with_master +SELECT * FROM t1 ORDER BY a; + +# Clean up. +--connection server_2 +SET GLOBAL gtid_strict_mode= @slave_old_strict; + +--connection server_1 +DROP TABLE t1; +SET GLOBAL gtid_strict_mode= @master_old_strict; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_gtid_mdev9033.cnf b/mysql-test/suite/rpl/t/rpl_gtid_mdev9033.cnf new file mode 100644 index 00000000..80b66498 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_gtid_mdev9033.cnf @@ -0,0 +1,20 @@ +!include ../my.cnf + +[mysqld.1] +log-slave-updates +loose-innodb +gtid_domain_id=1 + +[mysqld.2] +log-slave-updates +loose-innodb +gtid_domain_id=2 + +[mysqld.3] +log-slave-updates +loose-innodb +gtid_domain_id=3 + +[ENV] +SERVER_MYPORT_3= @mysqld.3.port +SERVER_MYSOCK_3= @mysqld.3.socket diff --git a/mysql-test/suite/rpl/t/rpl_gtid_mdev9033.test b/mysql-test/suite/rpl/t/rpl_gtid_mdev9033.test new file mode 100644 index 00000000..f8e8642a --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_gtid_mdev9033.test @@ -0,0 +1,72 @@ +--source include/have_innodb.inc +--let $rpl_topology=1->2->3 +--source include/rpl_init.inc + +--connection server_2 +--source include/stop_slave.inc +eval CHANGE MASTER TO + MASTER_USE_GTID = SLAVE_POS, IGNORE_DOMAIN_IDS = (2,3); +START SLAVE; + +--connection server_3 +--source include/stop_slave.inc +eval CHANGE MASTER TO + MASTER_USE_GTID = SLAVE_POS, IGNORE_DOMAIN_IDS = (2,3); +START SLAVE; + +connection server_1; + +CREATE TABLE t1 (a INT PRIMARY KEY, b VARCHAR(10)) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1, "m1"); +INSERT INTO t1 VALUES (2, "m2"), (3, "m3"), (4, "m4"); + +SET @@session.gtid_domain_id=2; +--echo # The following should get filetered on slave. +CREATE TABLE t2 (a INT PRIMARY KEY, b VARCHAR(10)) ENGINE=InnoDB; +INSERT INTO t2 VALUES (1, "m1"); +INSERT INTO t2 VALUES (2, "m2"), (3, "m3"), (4, "m4"); + +--source include/save_master_gtid.inc + +connection server_2; +--source include/sync_with_master_gtid.inc + +SELECT * FROM t1 ORDER BY a; +--echo # Only 't1' should have replicated to slaves. +SHOW TABLES; + +--source include/save_master_gtid.inc + +connection server_3; +--source include/sync_with_master_gtid.inc + +SELECT * FROM t1 ORDER BY a; +--echo # Only 't1' should have replicated to slaves. +SHOW TABLES; + +--echo # Cleanup +--connection server_1 +SET @@session.gtid_domain_id=1; +DROP TABLE t1; +SET @@session.gtid_domain_id=2; +DROP TABLE t2; + +--source include/save_master_gtid.inc + +--connection server_2 +--source include/sync_with_master_gtid.inc + +--source include/save_master_gtid.inc + +--connection server_3 +--source include/sync_with_master_gtid.inc + +--connection server_2 +STOP SLAVE; +CHANGE MASTER TO MASTER_USE_GTID = NO, IGNORE_DOMAIN_IDS = (); + +--connection server_3 +STOP SLAVE; +CHANGE MASTER TO MASTER_USE_GTID = NO, IGNORE_DOMAIN_IDS = (); + +--echo # End of test. diff --git a/mysql-test/suite/rpl/t/rpl_gtid_misc.test b/mysql-test/suite/rpl/t/rpl_gtid_misc.test new file mode 100644 index 00000000..66d98ec8 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_gtid_misc.test @@ -0,0 +1,50 @@ +--source include/master-slave.inc + +--echo *** MDEV-6403: Temporary tables lost at STOP SLAVE in GTID mode if master has not rotated binlog since restart *** + +--connection master +CREATE TABLE t1 (a INT PRIMARY KEY); +--sync_slave_with_master + +--connection slave +--source include/stop_slave.inc +# Inject a duplicate key error that will make the slave stop in the middle of +# a sequence of transactions that use a temporary table. +SET sql_log_bin= 0; +INSERT INTO t1 VALUES (1); +SET sql_log_bin= 1; +CHANGE MASTER TO master_use_gtid= current_pos; + +--connection master + +# Make some queries that use a temporary table. +CREATE TEMPORARY TABLE t2 LIKE t1; +INSERT INTO t2 VALUE (1); +INSERT INTO t1 SELECT * FROM t2; +DROP TEMPORARY TABLE t2; +--save_master_pos + +--connection slave +START SLAVE; +--let $slave_sql_errno=1062 +--source include/wait_for_slave_sql_error.inc + +# Restart the slave. +# The bug was that the IO thread would receive again the restart +# format_description event at the start of the master's binlog, and this +# event would cause the SQL thread to discard all active temporary tables. + +STOP SLAVE IO_THREAD; + +SET sql_log_bin= 0; +DELETE FROM t1 WHERE a=1; +SET sql_log_bin= 1; + +--source include/start_slave.inc +--sync_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/t/rpl_gtid_nobinlog.cnf b/mysql-test/suite/rpl/t/rpl_gtid_nobinlog.cnf new file mode 100644 index 00000000..0ea0d951 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_gtid_nobinlog.cnf @@ -0,0 +1,9 @@ +!include ../my.cnf + +[mysqld.1] +log-slave-updates=0 +loose-innodb + +[mysqld.2] +log-slave-updates=0 +loose-innodb diff --git a/mysql-test/suite/rpl/t/rpl_gtid_nobinlog.test b/mysql-test/suite/rpl/t/rpl_gtid_nobinlog.test new file mode 100644 index 00000000..a5caebf0 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_gtid_nobinlog.test @@ -0,0 +1,66 @@ +--let $rpl_topology=1->2 +--source include/rpl_init.inc +--source include/have_binlog_format_statement.inc + +--connection server_1 +SET @old_strict= @@GLOBAL.gtid_strict_mode; +SET GLOBAL gtid_strict_mode= 1; +select @@global.log_slave_updates; + +CREATE TABLE t1 (a INT PRIMARY KEY, b INT); +INSERT INTO t1 VALUES (1, 1); +INSERT INTO t1 VALUES (2, 1); +--save_master_pos + +--connection server_2 +SET @old_strict= @@GLOBAL.gtid_strict_mode; +SET GLOBAL gtid_strict_mode= 1; +select @@global.log_slave_updates; + +--sync_with_master +SELECT * FROM t1 ORDER BY a; + +--source include/stop_slave.inc + +--connection server_1 +--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 = current_pos; +START SLAVE; +--source include/wait_for_slave_to_start.inc + +--connection server_2 +INSERT INTO t1 VALUES (3, 2); +INSERT INTO t1 VALUES (4, 2); +--source include/save_master_gtid.inc + +--source include/show_binlog_events.inc + +--connection server_1 +--source include/sync_with_master_gtid.inc + +SELECT * FROM t1 ORDER BY a; + +--source include/stop_slave.inc +RESET SLAVE; +INSERT INTO t1 VALUES (5, 1); +INSERT INTO t1 VALUES (6, 1); +--source include/save_master_gtid.inc + +--connection server_2 +--replace_result $MASTER_MYPORT MASTER_PORT +eval CHANGE MASTER TO master_host = '127.0.0.1', master_port = $MASTER_MYPORT, + master_use_gtid = current_pos; +START SLAVE; +--source include/sync_with_master_gtid.inc + +SELECT * FROM t1 ORDER BY a; + +# Cleanup. +SET GLOBAL gtid_strict_mode= @old_strict; + +--connection server_1 +SET GLOBAL gtid_strict_mode= @old_strict; +DROP TABLE t1; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_gtid_reconnect.test b/mysql-test/suite/rpl/t/rpl_gtid_reconnect.test new file mode 100644 index 00000000..bc28ebdd --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_gtid_reconnect.test @@ -0,0 +1,206 @@ +--let $rpl_topology=1->2 +--source include/rpl_init.inc +--source include/have_innodb.inc +--source include/have_debug.inc + + +--connection server_2 +--source include/stop_slave.inc +CHANGE MASTER TO master_use_gtid= current_pos; +--source include/start_slave.inc + +--connection server_1 +CREATE TABLE t1 (a INT); +FLUSH LOGS; +--save_master_pos + +--connection server_2 +--sync_with_master + + +# Prepare a string of events and have the slave replicate all of it. +--connection server_1 +SET gtid_domain_id=10; +INSERT INTO t1 VALUES (1); +INSERT INTO t1 VALUES (2); +SET gtid_seq_no=100; +INSERT INTO t1 VALUES (3); +INSERT INTO t1 VALUES (4); +INSERT INTO t1 VALUES (5); +--save_master_pos + +--connection server_2 +--sync_with_master +--source include/stop_slave.inc +SELECT * FROM t1 ORDER BY a; + +# Now start the slave again, but force a reconnect. There was a bug that this +# reconnect would cause duplicate events. + +--connection server_1 +# Make sure to get rid of any old binlog dump thread so it does not +# interfere with our DBUG error injection. +--source include/kill_binlog_dump_threads.inc +INSERT INTO t1 VALUES (10); +SET @old_debug= @@GLOBAL.debug_dbug; +SET GLOBAL debug_dbug="+d,dummy_disable_default_dbug_output"; +SET GLOBAL debug_dbug="+d,gtid_force_reconnect_at_10_1_100"; +--save_master_pos + +--connection server_2 +--source include/start_slave.inc +--sync_with_master +SELECT * FROM t1 ORDER BY a; + +--source include/stop_slave.inc +TRUNCATE t1; +RESET MASTER; +SET GLOBAL gtid_slave_pos= ""; + +--connection server_1 +SET GLOBAL debug_dbug= @old_debug; +TRUNCATE t1; +RESET MASTER; + +# A1 B1 A2 B2 A3 B3, slave reached A1 and B3 and stopped. Slave starts, +# reconnects at A2. There was a bug that B2 would be duplicated. + +SET gtid_domain_id=10; +SET gtid_seq_no=50; +INSERT INTO t1 VALUES (1); +SET gtid_domain_id=11; +INSERT INTO t1 VALUES (11); +SET gtid_domain_id=10; +SET gtid_seq_no=100; +INSERT INTO t1 VALUES (2); +SET gtid_domain_id=11; +INSERT INTO t1 VALUES (12); +SET gtid_domain_id=10; +INSERT INTO t1 VALUES (3); +SET gtid_domain_id=11; +SET gtid_seq_no=200; +INSERT INTO t1 VALUES (13); + +--connection server_2 +START SLAVE UNTIL master_gtid_pos="10-1-50,11-1-200"; +--source include/wait_for_slave_to_stop.inc +SELECT * FROM t1 ORDER BY a; + +--connection server_1 +--source include/kill_binlog_dump_threads.inc +INSERT INTO t1 VALUES (20); +SET GLOBAL debug_dbug="+d,dummy_disable_default_dbug_output"; +SET GLOBAL debug_dbug="+d,gtid_force_reconnect_at_10_1_100"; +--save_master_pos + +--connection server_2 +--source include/start_slave.inc +--sync_with_master +SELECT * FROM t1 ORDER BY a; + +--source include/stop_slave.inc +TRUNCATE t1; +RESET MASTER; +SET GLOBAL gtid_slave_pos= ""; + +--connection server_1 +SET GLOBAL debug_dbug= @old_debug; +TRUNCATE t1; +RESET MASTER; + +# A1 B1 A2 B2 A3 B3. START SLAVE UNTIL A1,B3, gets reconnect at B2. +# There was a bug that the UNTIL would be ignored, and A2 would be lost. + +--source include/kill_binlog_dump_threads.inc +SET gtid_domain_id= 9; +SET gtid_seq_no= 50; +INSERT INTO t1 VALUES (1); +SET gtid_domain_id= 10; +INSERT INTO t1 VALUES (11); +SET gtid_domain_id= 9; +INSERT INTO t1 VALUES (2); +SET gtid_domain_id= 10; +SET gtid_seq_no= 100; +INSERT INTO t1 VALUES (12); +SET gtid_domain_id= 9; +INSERT INTO t1 VALUES (3); +SET gtid_domain_id= 10; +SET gtid_seq_no= 200; +INSERT INTO t1 VALUES (13); +SET gtid_domain_id= 10; + +SET GLOBAL debug_dbug="+d,dummy_disable_default_dbug_output"; +SET GLOBAL debug_dbug="+d,gtid_force_reconnect_at_10_1_100"; + +--connection server_2 +START SLAVE UNTIL master_gtid_pos="9-1-50,10-1-200"; +--source include/wait_for_slave_to_stop.inc +SELECT * FROM t1 ORDER BY a; + +--connection server_1 +SET GLOBAL debug_dbug= @old_debug; +INSERT INTO t1 VALUES (20); +--save_master_pos + +--connection server_2 +--source include/start_slave.inc +--sync_with_master +SELECT * FROM t1 ORDER BY a; + + +--echo *** Test when slave IO thread needs to reconnect in the middle of an event group. *** +--connection server_2 +--source include/stop_slave.inc + +TRUNCATE t1; +RESET MASTER; +SET GLOBAL gtid_slave_pos= ""; + +--connection server_1 +SET GLOBAL debug_dbug= @old_debug; +TRUNCATE t1; +RESET MASTER; + +--source include/kill_binlog_dump_threads.inc +SET GLOBAL debug_dbug="+d,dummy_disable_default_dbug_output"; +SET GLOBAL debug_dbug="+d,binlog_force_reconnect_after_22_events"; + +# 4 events for FD, fake rotate, gtid list, binlog checkpoint. +# 2 events for GTID, create table +CREATE TABLE t2 (a INT PRIMARY KEY) ENGINE=InnoDB; +# 3 events for BEGIN/query/COMMIT +INSERT INTO t2 VALUES (1); +# 4 events for BEGIN/query/query/COMMIT +BEGIN; +INSERT INTO t2 VALUES (10); +INSERT INTO t2 VALUES (11); +COMMIT; +# So this event group starts after 4+2+4+3=13 events. Or 16 in row-based. +BEGIN; +INSERT INTO t2 VALUES (20); +INSERT INTO t2 VALUES (21); +INSERT INTO t2 VALUES (22); +INSERT INTO t2 VALUES (23); +INSERT INTO t2 VALUES (24); +INSERT INTO t2 VALUES (25); +INSERT INTO t2 VALUES (26); +INSERT INTO t2 VALUES (27); +INSERT INTO t2 VALUES (28); +INSERT INTO t2 VALUES (29); +COMMIT; +--save_master_pos + +--connection server_2 +--source include/start_slave.inc +--sync_with_master +SELECT * FROM t2 ORDER BY a; + +--connection server_1 +SET GLOBAL debug_dbug= @old_debug; + + +# Clean up. +--connection server_1 +DROP TABLE t1, t2; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_gtid_sort.test b/mysql-test/suite/rpl/t/rpl_gtid_sort.test new file mode 100644 index 00000000..dc3b18aa --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_gtid_sort.test @@ -0,0 +1,77 @@ +--source include/have_innodb.inc +--let $rpl_topology=1->2 +--source include/rpl_init.inc + +--echo *** Test connecting with empty GTID state to start from very beginning of binlog *** +--connection server_2 +--source include/stop_slave.inc +RESET MASTER; +RESET SLAVE; +SHOW VARIABLES LIKE 'gtid_binlog_pos'; +SHOW VARIABLES LIKE 'gtid_current_pos'; +SHOW VARIABLES LIKE 'gtid_slave_pos'; +SHOW VARIABLES LIKE 'gtid_binlog_state'; + +--connection server_1 +RESET MASTER; +FLUSH LOGS; +CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB; +SET @@SESSION.gtid_domain_id=1; +INSERT INTO t1 VALUES(1); + +SET @@SESSION.gtid_domain_id=99999; +INSERT INTO t1 VALUES(3); + +SET @@SESSION.gtid_domain_id=10; +INSERT INTO t1 VALUES(4); + +SET @@SESSION.gtid_domain_id=100; +INSERT INTO t1 VALUES(5); + +SET @@SESSION.gtid_domain_id=2147483648; # 0x80000000 +INSERT INTO t1 VALUES(6); + +SET @@SESSION.gtid_domain_id=4294967295; # 0xFFFFFFFF +INSERT INTO t1 VALUES(7); + +SHOW VARIABLES LIKE 'gtid_binlog_pos'; +SHOW VARIABLES LIKE 'gtid_current_pos'; +SHOW VARIABLES LIKE 'gtid_slave_pos'; +SHOW VARIABLES LIKE 'gtid_binlog_state'; +--save_master_pos + +--connection server_2 +SHOW VARIABLES LIKE 'gtid_binlog_pos'; +SHOW VARIABLES LIKE 'gtid_current_pos'; +SHOW VARIABLES LIKE 'gtid_slave_pos'; +SHOW VARIABLES LIKE 'gtid_binlog_state'; +--replace_result $MASTER_MYPORT MASTER_PORT +eval CHANGE MASTER TO master_host = '127.0.0.1', master_port = $MASTER_MYPORT, + MASTER_USE_GTID=CURRENT_POS; +--source include/start_slave.inc +--sync_with_master +SHOW VARIABLES LIKE 'gtid_binlog_pos'; +SHOW VARIABLES LIKE 'gtid_current_pos'; +SHOW VARIABLES LIKE 'gtid_slave_pos'; +SHOW VARIABLES LIKE 'gtid_binlog_state'; +SELECT * FROM t1; + +SET @@SESSION.gtid_domain_id=1000; +INSERT INTO t1 VALUES(8); + +SET @@SESSION.gtid_domain_id=89; +INSERT INTO t1 VALUES(9); + +SET @@SESSION.gtid_domain_id=10100000; +INSERT INTO t1 VALUES(10); + +SHOW VARIABLES LIKE 'gtid_binlog_pos'; +SHOW VARIABLES LIKE 'gtid_current_pos'; +SHOW VARIABLES LIKE 'gtid_slave_pos'; +SHOW VARIABLES LIKE 'gtid_binlog_state'; + +# Clean up. +--connection server_1 +DROP TABLE t1; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_gtid_startpos.test b/mysql-test/suite/rpl/t/rpl_gtid_startpos.test new file mode 100644 index 00000000..100d75a8 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_gtid_startpos.test @@ -0,0 +1,358 @@ +--source include/have_innodb.inc +--let $rpl_topology=1->2 +--source include/rpl_init.inc + +--echo *** Test connecting with empty GTID state to start from very beginning of binlog *** +--connection server_2 +--source include/stop_slave.inc +RESET MASTER; +RESET SLAVE; + +--connection server_1 +RESET MASTER; +# Create an empty binlog file, to check that empty binlog state is handled correctly. +FLUSH LOGS; +CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB; +--save_master_pos + +--connection server_2 +SET GLOBAL gtid_slave_pos=""; +--replace_result $MASTER_MYPORT MASTER_PORT +eval CHANGE MASTER TO master_host = '127.0.0.1', master_port = $MASTER_MYPORT, + MASTER_USE_GTID=CURRENT_POS; +--source include/start_slave.inc +--sync_with_master +SELECT * FROM t1; + +--connection server_1 +INSERT INTO t1 VALUES (1); +--save_master_pos + +--connection server_2 +--sync_with_master +SELECT * FROM t1; +--source include/stop_slave.inc + +--echo *** Test that master gives error when slave asks for empty gtid pos and binlog files have been purged. *** +--connection server_1 +FLUSH LOGS; +INSERT INTO t1 VALUES (2); +--save_master_pos +--let $purge_binlogs_to=master-bin.000003 +--source include/wait_for_purge.inc +--source include/show_binary_logs.inc + +--connection server_2 +SET GLOBAL gtid_slave_pos=""; +--replace_result $MASTER_MYPORT MASTER_PORT +eval CHANGE MASTER TO master_host = '127.0.0.1', master_port = $MASTER_MYPORT, + MASTER_USE_GTID=CURRENT_POS; +START SLAVE; +--let $slave_io_errno= 1236 +--source include/wait_for_slave_io_error.inc +--source include/stop_slave.inc + +--replace_result $MASTER_MYPORT MASTER_PORT +eval CHANGE MASTER TO master_host = '127.0.0.1', master_port = $MASTER_MYPORT, + MASTER_LOG_FILE="master-bin.000003", MASTER_LOG_POS=4; +--source include/start_slave.inc +--sync_with_master +SELECT * FROM t1 ORDER BY a; +SET sql_log_bin=0; +call mtr.add_suppression('Could not find GTID state requested by slave in any binlog files'); +SET sql_log_bin=1; + +--echo *** Test that we give warning when explict @@gtid_slave_pos=xxx that conflicts with what is in our binary log *** +--source include/stop_slave.inc + +--connection server_1 +INSERT INTO t1 VALUES(3); +--source include/save_master_gtid.inc + +--connection server_2 +SET GLOBAL gtid_slave_pos='0-1-3'; +--replace_result $MASTER_MYPORT MASTER_PORT +eval CHANGE MASTER TO master_host = '127.0.0.1', master_port = $MASTER_MYPORT, + MASTER_USE_GTID=CURRENT_POS; +--source include/start_slave.inc +--source include/sync_with_master_gtid.inc +SELECT * FROM t1 ORDER by a; +--source include/stop_slave.inc + +--connection server_1 +INSERT INTO t1 VALUES (4); +--source include/save_master_gtid.inc + +--connection server_2 +# Now add some local transactions that conflict with the GTID position +# being set for @@gtid_slave_pos. +INSERT INTO t1 VALUES (10); +DELETE FROM t1 WHERE a=10; +SET GLOBAL gtid_slave_pos='0-1-4'; + +# Try again after RESET MASTER to remove the conflicting binlog. +RESET MASTER; +SET GLOBAL gtid_slave_pos='0-1-4'; +START SLAVE; +--source include/sync_with_master_gtid.inc +SELECT * FROM t1 ORDER by a; + +--connection server_1 +DROP TABLE t1; +--save_master_pos + +--connection server_2 +--sync_with_master + + +--echo *** MDEV-4275: I/O thread restart duplicates events in relay log *** + +--connection server_2 +--source include/stop_slave.inc +RESET SLAVE ALL; +RESET MASTER; + +--connection server_1 +RESET MASTER; + +--connection server_2 +SET GLOBAL gtid_slave_pos=''; +--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=current_pos; +--source include/start_slave.inc + +--connection server_1 +CREATE TABLE t1 (a INT PRIMARY KEY); +INSERT INTO t1 VALUES (1); +--save_master_pos + +--connection server_2 +--sync_with_master +SELECT * FROM t1; + +--source include/stop_slave_io.inc +START SLAVE IO_THREAD; +--source include/wait_for_slave_io_to_start.inc + +--connection server_1 +INSERT INTO t1 VALUES (2); +--save_master_pos + +--connection server_2 +--sync_with_master + +SELECT * FROM t1 ORDER BY a; + + +--echo *** MDEV-4329: GTID_SLAVE_POS='' is not checked for conflicts with binlog *** + +# Test starting the slave completely from scratch, deleting all tables and +# replicating from the start of the master's binlog. This requires RESET +# MASTER is run on the slave to avoid old junk in the binlog. The bug was +# that the code did not catch the error of missing RESET MASTER when an +# empty GTID_SLAVE_POS='' was specified. + +--connection server_2 +--source include/stop_slave.inc +DROP TABLE t1; +RESET SLAVE; +SET GLOBAL gtid_slave_pos=""; +RESET MASTER; +SET GLOBAL gtid_slave_pos=""; + +--source include/start_slave.inc +--sync_with_master +SELECT * FROM t1 ORDER BY a; + + +# Same thing, but this time using SQL_LOG_BIN=0 to avoid polluting the +# slave binlog. + +--connection server_2 +--source include/stop_slave.inc +SET SQL_LOG_BIN=0; +DROP TABLE t1; +SET SQL_LOG_BIN=1; +RESET SLAVE; +SET GLOBAL gtid_slave_pos=""; +# Ensure that the slave fails because of missing table to be dropped +SET @save_slave_ddl_exec_mode=@@global.slave_ddl_exec_mode; +SET GLOBAL slave_ddl_exec_mode=STRICT; + +--source include/start_slave.inc +--sync_with_master +SELECT * FROM t1 ORDER BY a; + +--echo *** Test that RESET SLAVE clears the Using_Gtid flag. *** +--source include/stop_slave.inc +RESET SLAVE; +--let $status_items= Using_Gtid +--source include/show_slave_status.inc + +# Starting the slave now reverts to old-style position which defaults to +# the first non-purged binlog file on the master. +# This should give error due to table already existing. +START SLAVE; +--let $slave_sql_errno= 1050 +--source include/wait_for_slave_sql_error.inc + +# Going back to using GTID should fix things. +STOP SLAVE IO_THREAD; +CHANGE MASTER TO MASTER_USE_GTID=CURRENT_POS; +--source include/start_slave.inc + +--connection server_1 +INSERT INTO t1 VALUES(3); +--source include/save_master_gtid.inc + +--connection server_2 +--source include/sync_with_master_gtid.inc +SELECT * FROM t1 ORDER BY a; +SET SQL_LOG_BIN=0; +call mtr.add_suppression("Slave: Table 't1' already exists error.* 1050"); +SET SQL_LOG_BIN=1; + + +--echo *** Test reconnecting slave with GTID after purge logs on master. *** + +--connection server_1 +FLUSH LOGS; +INSERT INTO t1 VALUES (4); +--source include/save_master_gtid.inc + +--connection server_2 +--source include/sync_with_master_gtid.inc +--source include/stop_slave.inc + +--connection server_1 +FLUSH LOGS; +FLUSH LOGS; +--let $purge_binlogs_to=master-bin.000004 +--source include/wait_for_purge.inc +--source include/show_binary_logs.inc +INSERT INTO t1 VALUES (5); +--source include/save_master_gtid.inc + +--connection server_2 +--replace_result $MASTER_MYPORT MASTER_PORT +eval CHANGE MASTER TO master_host = '127.0.0.1', master_port = $MASTER_MYPORT; +--source include/start_slave.inc +--source include/sync_with_master_gtid.inc +SELECT * FROM t1 ORDER BY a; + + +--echo *** Test modifying binlog on slave and the effect on GTID state. *** + +--connection server_2 +--source include/stop_slave.inc +RESET MASTER; +SET GLOBAL gtid_slave_pos=""; + +--connection server_1 +RESET MASTER; +TRUNCATE TABLE t1; +INSERT INTO t1 VALUES (10); # Will be GTID 0-1-2 +--source include/save_master_gtid.inc + +--connection server_2 +--source include/start_slave.inc +--source include/sync_with_master_gtid.inc + +SELECT * FROM t1; +--let $value= query_get_value(SHOW SLAVE STATUS, "Using_Gtid", 1) +eval SELECT '$value' AS Using_Gtid; +--let $value= query_get_value(SHOW ALL SLAVES STATUS, "Gtid_Slave_Pos", 1) +eval SELECT '$value' AS Gtid_Slave_Pos; + +UPDATE t1 SET a=9 WHERE a=10; +UPDATE t1 SET a=10 WHERE a=9; + +--let $value= query_get_value(SHOW ALL SLAVES STATUS, "Gtid_Slave_Pos", 1) +eval SELECT '$value' AS Gtid_Slave_Pos; + +--source include/stop_slave.inc +SET GLOBAL gtid_slave_pos='0-1-2'; +RESET MASTER; +--let $value= query_get_value(SHOW ALL SLAVES STATUS, "Gtid_Slave_Pos", 1) +eval SELECT '$value' AS Gtid_Slave_Pos; +SET GLOBAL gtid_slave_pos='0-1-2'; +--source include/start_slave.inc +--let $value= query_get_value(SHOW ALL SLAVES STATUS, "Gtid_Slave_Pos", 1) +eval SELECT '$value' AS Gtid_Slave_Pos; + + +--echo *** MDEV-4483: Slave loses traditional master coordinates immediately on CHANGE MASTER TO MASTER_USE_GTID = 1 *** +--connection server_2 +--source include/stop_slave.inc +DROP TABLE t1; +RESET SLAVE ALL; +RESET MASTER; +SET GLOBAL gtid_slave_pos= ""; + +# Set up old-style replication. The bug was that CHANGE MASTER would clear +# out the old-style binlog/relaylog coordinates when it should not. + +--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=no, master_log_file="", master_log_pos= 4; + +--connection server_1 +DROP TABLE t1; +RESET MASTER; + +CREATE TABLE t1 (a INT PRIMARY KEY); +--save_master_pos + +--connection server_2 +--source include/start_slave.inc +--sync_with_master + +--source include/stop_slave.inc + +--connection server_1 +INSERT INTO t1 VALUES (1); +--let $log_file1= query_get_value(SHOW MASTER STATUS, "File", 1) +--let $log_pos1= query_get_value(SHOW MASTER STATUS, "Position", 1) +INSERT INTO t1 VALUES (2); +--let $log_file2= query_get_value(SHOW MASTER STATUS, "File", 1) +--let $log_pos2= query_get_value(SHOW MASTER STATUS, "Position", 1) +--save_master_pos + +--connection server_2 +# Get the slave to a point where the IO thread has fetched one event ahead +# of the SQL thread (we want to test that CHANGE MASTER does not mess with +# existing relay logs). +--replace_result $log_file1 LOG_FILE1 $log_pos1 LOG_POS1 +eval START SLAVE UNTIL master_log_file='$log_file1', master_log_pos=$log_pos1; +--source include/wait_for_slave_sql_to_stop.inc +SELECT * FROM t1; +--let $slave_param= Read_Master_Log_Pos +--let $slave_param_value= $log_pos2 +--source include/wait_for_slave_param.inc +--source include/stop_slave_io.inc + +# Test that we can change to GTID and back without loosing our +# old-style slave position. +CHANGE MASTER TO master_use_gtid=slave_pos; +# Unknown GTID, so slave will fail to connect. +SET GLOBAL gtid_slave_pos="0-42-42"; +SET sql_log_bin=0; +call mtr.add_suppression("Error: connecting slave requested to start from GTID"); +SET sql_log_bin=1; +START SLAVE; +--let $slave_io_errno= 1236 +--source include/wait_for_slave_io_error.inc +STOP SLAVE SQL_THREAD; +--source include/wait_for_slave_sql_to_stop.inc +CHANGE MASTER TO master_use_gtid=no; + +--source include/start_slave.inc +--sync_with_master +SELECT * FROM t1 ORDER BY a; + +# Clean up. +--connection server_1 +DROP TABLE t1; +--connection server_2 +set @@global.slave_ddl_exec_mode=@save_slave_ddl_exec_mode; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_gtid_stop_start.cnf b/mysql-test/suite/rpl/t/rpl_gtid_stop_start.cnf new file mode 100644 index 00000000..c7247a80 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_gtid_stop_start.cnf @@ -0,0 +1,5 @@ +!include ../my.cnf + +[mysqld.2] +# Needed because depending on load on test machine the master restart can take long. +master_retry_count = 120 diff --git a/mysql-test/suite/rpl/t/rpl_gtid_stop_start.test b/mysql-test/suite/rpl/t/rpl_gtid_stop_start.test new file mode 100644 index 00000000..fd4cdf71 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_gtid_stop_start.test @@ -0,0 +1,351 @@ +--let $rpl_topology=1->2 +--source include/rpl_init.inc +--source include/have_innodb.inc + +--echo *** Test normal shutdown/restart of slave server configured as a GTID slave. *** + +--connection server_1 +CREATE TABLE t1 (a INT PRIMARY KEY); +INSERT INTO t1 VALUES (1); +--save_master_pos + +--connection server_2 +--sync_with_master +--source include/stop_slave.inc + +--let $status_items= Master_Log_File,Using_Gtid +--source include/show_slave_status.inc + +CHANGE MASTER TO master_use_gtid=current_pos; + +# Now try to restart the slave mysqld server without starting the slave first +# threads after the CHANGE MASTER. +# When the slave restarts, it should reconnect using GTID. +# We test that it really uses GTID by purging on the master the +# old binlog the slave would need if connecting with old style +# file name/offset. + +--write_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect +wait +EOF +FLUSH LOGS; +--shutdown_server +--source include/wait_until_disconnected.inc + +--connection server_1 +FLUSH LOGS; +--let $purge_binlogs_to=master-bin.000002 +--source include/wait_for_purge.inc +--source include/show_binary_logs.inc +INSERT INTO t1 VALUES (2); +FLUSH LOGS; +INSERT INTO t1 VALUES (3); +--source include/save_master_gtid.inc +--source include/show_binary_logs.inc + +# Let the slave mysqld server start again. +--append_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect +restart: --skip-slave-start=0 +EOF + +--connection server_2 +--enable_reconnect +--source include/wait_until_connected_again.inc + +--source include/sync_with_master_gtid.inc +SELECT * FROM t1 ORDER BY a; + + +--echo *** Test normal shutdown/restart of master server, check binlog state is preserved. *** + +--connection server_1 +SET SESSION gtid_domain_id= 1; +INSERT INTO t1 VALUES (4); +--replace_column 2 # 4 # 5 # +SHOW BINLOG EVENTS IN 'master-bin.000003' LIMIT 1,1; +FLUSH LOGS; +--replace_column 2 # 4 # 5 # 6 # +SHOW BINLOG EVENTS IN 'master-bin.000004' LIMIT 1,1; + +--write_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +wait +EOF +--shutdown_server +--source include/wait_until_disconnected.inc + +--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 + +--replace_column 2 # 4 # 5 # 6 # +SHOW BINLOG EVENTS IN 'master-bin.000005' LIMIT 1,1; +--source include/show_binary_logs.inc + +INSERT INTO t1 VALUES(5); +--source include/save_master_gtid.inc + +--connection server_2 +--source include/sync_with_master_gtid.inc +FLUSH NO_WRITE_TO_BINLOG TABLES; +SELECT * FROM t1 ORDER BY a; + +--echo *** Test that @@gtid_slave_pos and @@gtid_current_pos are correctly loaded even if slave threads have not started. *** +--let $slave_pos1= `SELECT @@GLOBAL.gtid_slave_pos` +--let $current_pos1= `SELECT @@GLOBAL.gtid_current_pos` + +--write_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect +wait +EOF +--shutdown_server +--source include/wait_until_disconnected.inc + +--append_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect +restart: --skip-slave-start=1 --skip-log-bin +EOF +--enable_reconnect +--source include/wait_until_connected_again.inc +--disable_query_log +eval SET @slave_pos1= "$slave_pos1"; +eval SET @current_pos1= "$current_pos1"; +--enable_query_log +SET @slave_pos2= @@GLOBAL.gtid_slave_pos; +SET @current_pos2= @@GLOBAL.gtid_current_pos; +SELECT IF(@slave_pos1=@slave_pos2, "OK", CONCAT(@slave_pos1, " != ", @slave_pos2)); +SELECT IF(@current_pos1=@current_pos2, "OK", CONCAT(@current_pos1, " != ", @current_pos2)); + +--connection server_1 +INSERT INTO t1 VALUES (6); +--save_master_pos + +--connection server_2 +--source include/start_slave.inc +--sync_with_master +SELECT * FROM t1 ORDER BY a; + + +--echo *** MDEV-4490: Old-style master position points at the last GTID event after slave restart *** + +--connection server_1 +INSERT INTO t1 VALUES (7); +--save_master_pos + +--connection server_2 +--sync_with_master +FLUSH NO_WRITE_TO_BINLOG TABLES; +SELECT * FROM t1 ORDER BY a; + +# Now we restart the slave server. When it restarts, there is nothing new +# to replicate. Check that the position is nevertheless updated and +# MASTER_POS_WAIT() works correctly and detects that we are up-to-date. + +--write_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect +wait +EOF +--shutdown_server +--source include/wait_until_disconnected.inc + +--append_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect +restart: --skip-slave-start=0 +EOF +--enable_reconnect +--source include/wait_until_connected_again.inc + +--source include/wait_for_slave_to_start.inc + +--connection server_1 +--save_master_pos + +--connection server_2 +--sync_with_master +SELECT * FROM t1 ORDER BY a; + + +--echo *** MDEV-4486: Allow to start old-style replication even if mysql.gtid_slave_pos is unavailable + +--connection server_2 +--source include/stop_slave.inc +CHANGE MASTER TO master_use_gtid= no; +--source include/start_slave.inc + +--connection server_1 +INSERT INTO t1 VALUES (8); +--save_master_pos + +--connection server_2 +--sync_with_master +FLUSH NO_WRITE_TO_BINLOG TABLES; +SELECT * FROM t1 ORDER BY a; +--source include/stop_slave.inc + +SET sql_log_bin= 0; +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +SET sql_log_bin= 1; + +--write_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect +wait +EOF +--shutdown_server +--source include/wait_until_disconnected.inc + +--append_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect +restart: --skip-slave-start=1 --skip-innodb +EOF +--enable_reconnect +--source include/wait_until_connected_again.inc + +--error ER_UNKNOWN_STORAGE_ENGINE +SELECT * FROM mysql.gtid_slave_pos; +SET sql_log_bin=0; +call mtr.add_suppression("Failed to load slave replication state from table"); +call mtr.add_suppression("Unable to load replication GTID slave state"); +SET sql_log_bin=1; + +--source include/start_slave.inc +--connection server_1 +INSERT INTO t1 VALUES (9); +--save_master_pos + +--connection server_2 +--sync_with_master +FLUSH NO_WRITE_TO_BINLOG TABLES; +SELECT * FROM t1 ORDER BY a; + +# Put things back as they were. +--write_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect +wait +EOF +--shutdown_server +--source include/wait_until_disconnected.inc + +--append_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect +restart: +EOF +--enable_reconnect +--source include/wait_until_connected_again.inc +SET sql_log_bin= 0; +ALTER TABLE mysql.gtid_slave_pos ENGINE=Aria; +SET sql_log_bin= 1; +# Do a second restart to get the mysql.gtid_slave_pos table loaded with +# the right engine. +--write_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect +wait +EOF +--shutdown_server +--source include/wait_until_disconnected.inc + +--append_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect +restart: +EOF +--enable_reconnect +--source include/wait_until_connected_again.inc + +--source include/start_slave.inc + +--connection server_1 +INSERT INTO t1 VALUES (10); +--save_master_pos + +--connection server_2 +--sync_with_master +--source include/stop_slave.inc +CHANGE MASTER TO master_use_gtid= slave_pos; +--source include/start_slave.inc + +--echo *** MDEV-4692: mysql.gtid_slave_pos accumulates values for a domain *** +SELECT domain_id, COUNT(*) FROM mysql.gtid_slave_pos GROUP BY domain_id; + +--connection server_1 +INSERT INTO t1 VALUES (11); +--save_master_pos + +--connection server_2 +--sync_with_master +FLUSH NO_WRITE_TO_BINLOG TABLES; +SELECT domain_id, COUNT(*) FROM mysql.gtid_slave_pos GROUP BY domain_id; + +--write_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect +wait +EOF +--shutdown_server +--source include/wait_until_disconnected.inc + +--append_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect +restart: +EOF +--enable_reconnect +--source include/wait_until_connected_again.inc +--source include/start_slave.inc + +--connection server_1 +INSERT INTO t1 VALUES (12); +INSERT INTO t1 VALUES (13); +--save_master_pos + +--connection server_2 +--sync_with_master +FLUSH NO_WRITE_TO_BINLOG TABLES; +SELECT domain_id, COUNT(*) FROM mysql.gtid_slave_pos GROUP BY domain_id; + + +--echo *** MDEV-4650: show variables; ERROR 1946 (HY000): Failed to load replication slave GTID position *** + +--connection server_2 +SET sql_log_bin=0; +--let $old_pos= `SELECT @@GLOBAL.gtid_slave_pos` +RENAME TABLE mysql.gtid_slave_pos TO mysql.old_gtid_slave_pos; +SET sql_log_bin=1; + +--write_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect +wait +EOF +--shutdown_server +--source include/wait_until_disconnected.inc + +# Let the slave mysqld server start again. +--append_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect +restart +EOF + +--enable_reconnect +--source include/wait_until_connected_again.inc + +--disable_result_log +SHOW VARIABLES; +--enable_result_log +SHOW VARIABLES LIKE 'gtid_slave_pos'; +--error ER_CANNOT_LOAD_SLAVE_GTID_STATE,ER_NO_SUCH_TABLE +SET GLOBAL gtid_slave_pos = '0-1-2'; +SHOW WARNINGS; + +# Restore things. + +SET sql_log_bin=0; +RENAME TABLE mysql.old_gtid_slave_pos TO mysql.gtid_slave_pos; +CALL mtr.add_suppression("Failed to load slave replication state from table mysql.gtid_slave_pos"); +SET sql_log_bin=1; + +SHOW VARIABLES LIKE 'gtid_slave_pos'; +SET GLOBAL gtid_slave_pos = '0-1-2'; +SHOW VARIABLES LIKE 'gtid_slave_pos'; + +# Don't let .result file depend on old state of gtid_slave_pos +--disable_query_log +--disable_result_log +eval SET GLOBAL gtid_slave_pos = '$old_pos'; +--enable_query_log +--enable_result_log + +--source include/start_slave.inc + + +--connection server_1 +DROP TABLE t1; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_gtid_strict.test b/mysql-test/suite/rpl/t/rpl_gtid_strict.test new file mode 100644 index 00000000..56ebba82 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_gtid_strict.test @@ -0,0 +1,179 @@ +--source include/have_debug.inc +--source include/have_innodb.inc +--source include/have_binlog_format_statement.inc +--let $rpl_topology=1->2 +--source include/rpl_init.inc + +--connection server_1 +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +SET sql_log_bin= 0; +call mtr.add_suppression("Error writing file .*errno: 1950"); + +SET sql_log_bin= 1; + +SET @old_gtid_strict_mode= @@GLOBAL.gtid_strict_mode; +SET GLOBAL gtid_strict_mode= 1; +--connection server_2 +--source include/stop_slave.inc +SET @old_gtid_strict_mode= @@GLOBAL.gtid_strict_mode; +SET GLOBAL gtid_strict_mode=1; +CHANGE MASTER TO master_use_gtid=slave_pos; +--source include/start_slave.inc + +--connection server_1 +CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1); + +--source include/show_binlog_events.inc + +SET server_id= 3; +--error ER_GTID_STRICT_OUT_OF_ORDER +SET gtid_seq_no= 3; +SET @old_dbug = @@session.debug_dbug; +SET SESSION debug_dbug="d,ignore_set_gtid_seq_no_check"; +SET gtid_seq_no= 3; +SET SESSION debug_dbug=@old_dbug; +--error ER_GTID_STRICT_OUT_OF_ORDER +INSERT INTO t1 VALUES (2); + +--error ER_GTID_STRICT_OUT_OF_ORDER +SET gtid_seq_no= 2; +SET SESSION debug_dbug="d,ignore_set_gtid_seq_no_check"; +SET gtid_seq_no= 2; +SET SESSION debug_dbug=@old_dbug; +--error ER_GTID_STRICT_OUT_OF_ORDER +INSERT INTO t1 VALUES (3); +SET server_id= 1; +SET gtid_seq_no= 4; +INSERT INTO t1 VALUES (4); +SELECT * FROM t1 ORDER BY 1; +--source include/show_binlog_events.inc + +--echo *** Test non-transactional GTID error (cannot be rolled back). *** +SET server_id= 3; +--error ER_GTID_STRICT_OUT_OF_ORDER +SET gtid_seq_no= 1; +SET SESSION debug_dbug="d,ignore_set_gtid_seq_no_check"; +SET gtid_seq_no= 1; +SET SESSION debug_dbug=@old_dbug; +--error ER_GTID_STRICT_OUT_OF_ORDER +CREATE TABLE t2 (a INT PRIMARY KEY) ENGINE=MyISAM; +# The table is still created, DDL cannot be rolled back. +# Fix it up for replication. +SET sql_log_bin= 0; +DROP TABLE t2; +SET sql_log_bin= 1; +CREATE TABLE t2 (a INT PRIMARY KEY) ENGINE=MyISAM; + +--error ER_GTID_STRICT_OUT_OF_ORDER +SET gtid_seq_no= 1; +SET SESSION debug_dbug="d,ignore_set_gtid_seq_no_check"; +SET gtid_seq_no= 1; +SET SESSION debug_dbug=@old_dbug; +--error ER_GTID_STRICT_OUT_OF_ORDER +INSERT INTO t2 VALUES (1); +# The value is still inserted, cannot be rolled back. +SET server_id= 1; +SET gtid_seq_no= 6; +INSERT INTO t2 VALUES (2); +SELECT * FROM t2 ORDER BY a; +--source include/show_binlog_events.inc + + +--echo *** Test that slave stops if it tries to apply a GTID that would create out-of-order binlog GTID sequence numbers. *** + +--save_master_pos +--connection server_2 +--sync_with_master + +SELECT * FROM t1 ORDER BY a; +SELECT * FROM t2 ORDER BY a; +SET sql_log_bin= 0; +call mtr.add_suppression("An attempt was made to binlog GTID .* which would create an out-of-order sequence number with existing GTID .*, and gtid strict mode is enabled"); +call mtr.add_suppression("The binlog on the master is missing the GTID [-0-9]+ requested by the slave"); +SET sql_log_bin= 1; + +# Create some out-of-order stuff on slave. +INSERT INTO t1 VALUES (5); + +--connection server_1 +INSERT INTO t1 VALUES (6); +--save_master_pos + +--connection server_2 +--let $slave_sql_errno=1950 +--source include/wait_for_slave_sql_error.inc +STOP SLAVE IO_THREAD; +SET GLOBAL gtid_strict_mode=0; +--source include/start_slave.inc +--sync_with_master +SET GLOBAL gtid_strict_mode=1; +SELECT * FROM t1 ORDER BY a; + +INSERT INTO t1 VALUES (7); +--connection server_1 +CREATE TABLE t3 (a INT PRIMARY KEY); +--save_master_pos + +--connection server_2 +--let $slave_sql_errno=1950 +--source include/wait_for_slave_sql_error.inc +--error ER_NO_SUCH_TABLE +--query_vertical SHOW CREATE TABLE t3 +STOP SLAVE IO_THREAD; +SET GLOBAL gtid_strict_mode=0; +--source include/start_slave.inc +--sync_with_master +SET GLOBAL gtid_strict_mode=1; +--query_vertical SHOW CREATE TABLE t3 + +INSERT INTO t1 VALUES (8); +--connection server_1 +INSERT INTO t2 VALUES (3); +--save_master_pos + +--connection server_2 +--let $slave_sql_errno=1950 +--source include/wait_for_slave_sql_error.inc +SELECT * FROM t2 ORDER BY a; +STOP SLAVE IO_THREAD; +SET GLOBAL gtid_strict_mode=0; +--source include/start_slave.inc +--sync_with_master +SET GLOBAL gtid_strict_mode=1; +SELECT * FROM t2 ORDER BY a; + + +--echo *** Check slave requests starting from a hole on the master. *** +--connection server_2 +--source include/stop_slave.inc + +--connection server_1 +INSERT INTO t1 VALUES (10); +SET gtid_seq_no= 100; +INSERT INTO t1 VALUES (11); +INSERT INTO t1 VALUES (12); +--save_master_pos + +--connection server_2 +SET GLOBAL gtid_slave_pos= "0-1-50"; +START SLAVE; +--let $slave_io_errno=1236 +--source include/wait_for_slave_io_error.inc +STOP SLAVE SQL_THREAD; +SET GLOBAL gtid_strict_mode= 0; +--source include/start_slave.inc +--sync_with_master + +SELECT * FROM t1 ORDER BY a; +SET GLOBAL gtid_strict_mode= 1; + + +# Clean up. +--connection server_1 +DROP TABLE t1, t2, t3; +SET GLOBAL gtid_strict_mode= @old_gtid_strict_mode; +--connection server_2 +SET GLOBAL gtid_strict_mode= @old_gtid_strict_mode; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_gtid_until.test b/mysql-test/suite/rpl/t/rpl_gtid_until.test new file mode 100644 index 00000000..aa05ecf7 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_gtid_until.test @@ -0,0 +1,248 @@ +--source include/have_innodb.inc +--let $rpl_topology=1->2 +--source include/rpl_init.inc + +--connection server_1 +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +# Function to extract one GTID from a list. +delimiter |; +CREATE FUNCTION extract_gtid(d VARCHAR(100), s VARCHAR(100)) + RETURNS VARCHAR(100) DETERMINISTIC +BEGIN + SET s= CONCAT(",", s, ","); + SET s= SUBSTR(s FROM LOCATE(CONCAT(",", d, "-"), s) + 1); + SET s= SUBSTR(s FROM 1 FOR LOCATE(",", s) - 1); + RETURN s; +END| +delimiter ;| +--save_master_pos + +--connection server_2 +--sync_with_master +# Restart SQL thread to pick up ALTER TABLE of mysql.gtid_slave_pos. +--source include/stop_slave.inc +--source include/start_slave.inc + +# Both replication threads must be stopped for UNTIL master_gtid_pos. +--error ER_SLAVE_WAS_RUNNING +START SLAVE UNTIL master_gtid_pos = ""; +--source include/stop_slave_io.inc +--error ER_SLAVE_WAS_RUNNING +START SLAVE UNTIL master_gtid_pos = ""; +START SLAVE IO_THREAD; +--source include/wait_for_slave_io_to_start.inc +--source include/stop_slave_sql.inc +--error ER_SLAVE_WAS_RUNNING +START SLAVE UNTIL master_gtid_pos = ""; +--source include/stop_slave_io.inc +# UNTIL master_gtid_pos only valid if GTID is used. + +--error ER_UNTIL_REQUIRES_USING_GTID +START SLAVE UNTIL master_gtid_pos = ""; + +CHANGE MASTER TO master_use_gtid=current_pos; + +--connection server_1 +CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB; +INSERT INTO t1 VALUES(1); +--let $gtid_pos=`SELECT @@GLOBAL.gtid_binlog_pos` +INSERT INTO t1 VALUES(2); + +--connection server_2 + +# Test various incorrect syntax for UNTIL master_gtid_pos. +--error ER_DUPLICATE_GTID_DOMAIN +START SLAVE UNTIL master_gtid_pos = "0-1-100,1-1-100,2-2-200,1-3-100,4-4-400"; +--error ER_PARSE_ERROR +START SLAVE UNTIL master_log_file = "master-bin.000001", master_log_pos = 4, master_gtid_pos = ""; +--error ER_BAD_SLAVE_UNTIL_COND +START SLAVE IO_THREAD UNTIL master_gtid_pos = ""; +--error ER_BAD_SLAVE_UNTIL_COND +START SLAVE SQL_THREAD UNTIL master_gtid_pos = ""; + +eval START SLAVE UNTIL master_gtid_pos = '$gtid_pos'; + +--source include/wait_for_slave_to_stop.inc +SELECT * FROM t1; + +--source include/start_slave.inc + +--connection server_1 +--save_master_pos + +--connection server_2 +--sync_with_master +SELECT * FROM t1 ORDER BY a; + +# Test showing the UNTIL condition in SHOW SLAVE STATUS. +--source include/stop_slave.inc +START SLAVE UNTIL master_gtid_pos = "1-10-100,2-20-200,0-1-300"; +--source include/wait_for_slave_to_start.inc +--let $status_items= Using_Gtid,Until_Condition +--source include/show_slave_status.inc + +# Clear the UNTIL condition. +# Note that we need to wait for a transaction to get through from the master. +# Otherwise the IO thread may still be in get_master_version_and_clock() +# (wait_for_slave_to_start.inc returns as soon as the IO thread is connected), +# and we can get test failures from warnings in the log about IO thread being +# killed in the middle of setting @@gtid_strict_mode or similar (MDEV-7940). +--connection server_1 +INSERT INTO t1 VALUES (3); +DELETE FROM t1 WHERE a=3; +--save_master_pos + +--connection server_2 +--sync_with_master +--source include/stop_slave.inc + + +--echo *** Test UNTIL condition in an earlier binlog than the start GTID. *** +--connection server_2 + +--connection server_1 +SET gtid_domain_id = 1; +INSERT INTO t1 VALUES (3); +SET gtid_domain_id = 2; +CREATE TABLE t2 (a INT); +INSERT INTO t2 VALUES (3); +--let $d1_point1= `SELECT extract_gtid("1", @@GLOBAL.gtid_binlog_pos)` +--let $d2_point1= `SELECT extract_gtid("2", @@GLOBAL.gtid_binlog_pos)` +FLUSH LOGS; +SET gtid_domain_id = 1; +INSERT INTO t1 VALUES (4); +SET gtid_domain_id = 2; +INSERT INTO t2 VALUES (4); +FLUSH LOGS; +SET gtid_domain_id = 1; +INSERT INTO t1 VALUES (5); +--let $d1_point2= `SELECT extract_gtid("1", @@GLOBAL.gtid_binlog_pos)` +--let $d2_point2= `SELECT extract_gtid("2", @@GLOBAL.gtid_binlog_pos)` +SET gtid_domain_id = 2; +INSERT INTO t2 VALUES (5); +FLUSH LOGS; +SET gtid_domain_id = 1; +INSERT INTO t1 VALUES (6); +--let $d1_point3= `SELECT extract_gtid("1", @@GLOBAL.gtid_binlog_pos)` +--let $d2_point3= `SELECT extract_gtid("2", @@GLOBAL.gtid_binlog_pos)` +SET gtid_domain_id = 2; +INSERT INTO t2 VALUES (6); +SET gtid_domain_id = 0; +--source include/show_binary_logs.inc +--save_master_pos + +--connection server_2 +# Let the slave reach an middle point in domain 1 and a late point in domain 2. +eval START SLAVE UNTIL master_gtid_pos='$d1_point2,$d2_point3'; +--source include/wait_for_slave_to_stop.inc +SELECT * FROM t1 ORDER BY a; +SELECT * FROM t2 ORDER BY a; +# Now test starting at a middle point in the binlogs when the stop position in +# one domain (domain 2) is early. +eval START SLAVE UNTIL master_gtid_pos='$d1_point3,$d2_point1'; +--source include/wait_for_slave_to_stop.inc +SELECT * FROM t1 ORDER BY a; +SELECT * FROM t2 ORDER BY a; +# Test that one UNTIL domain empty means stop that domain immediately. +eval START SLAVE UNTIL master_gtid_pos='$d1_point2'; +--source include/wait_for_slave_to_stop.inc +SELECT * FROM t1 ORDER BY a; +SELECT * FROM t2 ORDER BY a; + +--source include/start_slave.inc +--sync_with_master +SELECT * FROM t1 ORDER BY a; +SELECT * FROM t2 ORDER BY a; + +--echo *** Test when the UNTIL position is right at the end of the binlog file prior to the starting position *** + +--connection server_2 +--source include/stop_slave.inc + +--connection server_1 +FLUSH LOGS; +SET gtid_domain_id = 1; +INSERT INTO t1 VALUES (7); +SET gtid_domain_id = 0; +--save_master_pos + +--connection server_2 +eval START SLAVE UNTIL master_gtid_pos='$d1_point3'; +--source include/wait_for_slave_to_stop.inc +# This should not show row 7, as we requested stop just before it. +SELECT * FROM t1 ORDER BY a; +--source include/start_slave.inc +--sync_with_master +SELECT * FROM t1 ORDER BY a; + + +--echo *** Test when UNTIL condition is after a stand-alone event (not a transaction). *** + +--connection server_2 +--source include/stop_slave.inc + +--connection server_1 +CREATE TABLE t3 (a INT); +--let $until_condition=`SELECT @@GLOBAL.gtid_binlog_pos` +DROP TABLE t3; +--save_master_pos + +--connection server_2 +--replace_result $until_condition UNTIL_CONDITION +eval START SLAVE UNTIL master_gtid_pos='$until_condition'; +--source include/wait_for_slave_to_stop.inc +SHOW CREATE TABLE t3; +--source include/start_slave.inc +--sync_with_master + +--echo *** Test UNTIL condition that has not yet been logged. *** + +--connection server_2 +--source include/stop_slave.inc +RESET SLAVE ALL; +RESET MASTER; +SET GLOBAL gtid_slave_pos=''; + +--connection server_1 +# Do it once to compute the right GTID, then throw it away and do it again +# for the actual test. +RESET MASTER; +INSERT INTO t1 VALUES (10); +INSERT INTO t1 VALUES (11); +--let $until_condition=`SELECT @@GLOBAL.gtid_binlog_pos` +INSERT INTO t1 VALUES (12); +DELETE FROM t1 WHERE a >= 10; + +RESET MASTER; +INSERT INTO t1 VALUES (10); + +--connection server_2 +--replace_result $SERVER_MYPORT_1 SERVER_MYPORT_1 +eval CHANGE MASTER TO master_host = '127.0.0.1', master_port = $SERVER_MYPORT_1, + master_user = "root", master_use_gtid = current_pos; +eval START SLAVE UNTIL master_gtid_pos = '$until_condition'; +--source include/wait_for_slave_to_start.inc + +--connection server_1 +INSERT INTO t1 VALUES (11); +INSERT INTO t1 VALUES (12); +--save_master_pos + +--connection server_2 +# This then should wait until it gets the row (11) and then stop, not +# yet having the row (12). +--source include/wait_for_slave_to_stop.inc +SELECT * FROM t1 ORDER BY a; +--source include/start_slave.inc +--sync_with_master +# And now the row (12) should be there. +SELECT * FROM t1 ORDER BY a; + + +# Clean up. +--connection server_1 +DROP TABLE t1; +DROP TABLE t2; +DROP FUNCTION extract_gtid; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_heartbeat.test b/mysql-test/suite/rpl/t/rpl_heartbeat.test new file mode 100644 index 00000000..77c05a60 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_heartbeat.test @@ -0,0 +1,172 @@ +# Testing master to slave heartbeat protocol +# +# Including: +# - user interface, grammar, checking the range and warnings about +# unreasonable values for the heartbeat period; +# - no rotation of relay log if heartbeat is less that slave_net_timeout +# - SHOW STATUS like 'Slave_received_heartbeats' action +# - SHOW STATUS like 'Slave_heartbeat_period' report + +-- source include/have_log_bin.inc + +connect (master,localhost,root,,test,$MASTER_MYPORT,$MASTER_MYSOCK); +connect (slave,localhost,root,,test,$SLAVE_MYPORT,$SLAVE_MYSOCK); + +connection master; +reset master; + +connection slave; +set @restore_slave_net_timeout= @@global.slave_net_timeout; +--disable_warnings +set @@global.slave_net_timeout= 10; +--enable_warnings + +### +### Checking the range +### + +# +# default period slave_net_timeout/2 +# +--replace_result $MASTER_MYPORT MASTER_PORT +eval change master to master_host='127.0.0.1',master_port=$MASTER_MYPORT, master_user='root'; +--query_vertical show status like 'Slave_heartbeat_period'; + +# +# the max for the period is ULONG_MAX/1000; an attempt to exceed it is denied +# +--replace_result $MASTER_MYPORT MASTER_PORT +--error ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE +eval change master to master_host='127.0.0.1',master_port=$MASTER_MYPORT, master_user='root', master_heartbeat_period= 4294968; +--query_vertical show status like 'Slave_heartbeat_period'; + +# +# the min value for the period is 1 millisecond an attempt to assign a +# lesser will be warned with treating the value as zero +# +connection slave; +--replace_result $MASTER_MYPORT MASTER_PORT +### 5.1 mtr does not have --warning ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE +eval change master to master_host='127.0.0.1',master_port=$MASTER_MYPORT, master_user='root', master_heartbeat_period= 0.0009999; +--query_vertical show status like 'Slave_heartbeat_period'; + +# +# the actual max and min must be accepted +# +--replace_result $MASTER_MYPORT MASTER_PORT +eval change master to master_host='127.0.0.1',master_port=$MASTER_MYPORT, master_user='root', master_heartbeat_period= 4294967; +--query_vertical show status like 'Slave_heartbeat_period'; + +--replace_result $MASTER_MYPORT MASTER_PORT +eval change master to master_host='127.0.0.1',master_port=$MASTER_MYPORT, master_user='root', master_heartbeat_period= 0.001; +--query_vertical show status like 'Slave_heartbeat_period'; + +reset slave; + +# +# A warning if period greater than slave_net_timeout +# +set @@global.slave_net_timeout= 5; +--replace_result $MASTER_MYPORT MASTER_PORT +eval change master to master_host='127.0.0.1',master_port=$MASTER_MYPORT, master_user='root', master_heartbeat_period= 5.001; +--query_vertical show status like 'Slave_heartbeat_period'; + +reset slave; + +# +# A warning if slave_net_timeout is set to less than the current HB period +# +set @@global.slave_net_timeout= 5; +--replace_result $MASTER_MYPORT MASTER_PORT +eval change master to master_host='127.0.0.1',master_port=$MASTER_MYPORT, master_user='root', master_heartbeat_period= 4; +--query_vertical show status like 'Slave_heartbeat_period'; +set @@global.slave_net_timeout= 3 /* must be a warning */; + +reset slave; + + +### +### checking no rotation +### + +connection master; +--disable_warnings +drop table if exists t1; +--enable_warnings +# +# Even though master_heartbeat_period= 0.5 is 20 times less than +# @@global.slave_net_timeout= 10 in some circumstances master will +# not be able to send any heartbeat during the slave's net timeout +# and slave's relay log will rotate. +# The probability for such a scenario is pretty small so the following +# part is almost deterministic. +# + +connection slave; +set @@global.slave_net_timeout= 10; +--replace_result $MASTER_MYPORT MASTER_PORT +# no error this time but rather a warning +eval change master to master_host='127.0.0.1',master_port=$MASTER_MYPORT, master_user='root', master_heartbeat_period= 0.5; +--query_vertical show status like 'Slave_heartbeat_period'; + +start slave; + +connection master; +create table t1 (f1 int); + +#connection slave; +sync_slave_with_master; +let $slave_param= Relay_Log_File; +let $slave_param_value= query_get_value(SHOW SLAVE STATUS, Relay_Log_File, 1); + +# there is an explicit sleep lasting longer than slave_net_timeout +# to ensure that nothing will come to slave from master for that period. +# That would cause reconnecting and relaylog rotation w/o the fix i.e +# without a heartbeat received. + +real_sleep 15; + +# check (compare with the previous show's results) that no rotation happened +source include/check_slave_param.inc; + +### +### SHOW STATUS like 'Slave_heartbeat_period' and 'Slave_received_heartbeats' +### + +--query_vertical show status like 'Slave_heartbeat_period'; + +# +# proof that there has been received at least one heartbeat; +# The exact number of received heartbeat is an indeterministic value +# and therefore it's not recorded into results. +# + +let $slave_wait_param_counter= 300; +let $slave_value= query_get_value("SHOW STATUS like 'Slave_received_heartbeats'", Value, 1); +# Checking the fact that at least one heartbeat is received +while (!$slave_value) +{ + dec $slave_wait_param_counter; + if (!$slave_wait_param_counter) + { + --echo ERROR: failed while waiting for slave parameter $slave_param: $slave_param_value + query_vertical show slave status; + SHOW STATUS like 'Slave_received_heartbeats'; + exit; + } + sleep 0.1; + let $slave_value= query_get_value("SHOW STATUS like 'Slave_received_heartbeats'", Value, 1); +} +--echo A heartbeat has been received by the slave +# cleanup + +connection master; +drop table t1; + +#connection slave; +sync_slave_with_master; +set @@global.slave_net_timeout= @restore_slave_net_timeout; + +--source include/stop_slave.inc + +--echo End of tests diff --git a/mysql-test/suite/rpl/t/rpl_heartbeat_2slaves.cnf b/mysql-test/suite/rpl/t/rpl_heartbeat_2slaves.cnf new file mode 100644 index 00000000..f24de9ab --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_heartbeat_2slaves.cnf @@ -0,0 +1,12 @@ +!include ../my.cnf + +[mysqld.1] +log-slave-updates + +[mysqld.2] +log-slave-updates + +[mysqld.3] + +[ENV] +SERVER_MYPORT_3= @mysqld.3.port diff --git a/mysql-test/suite/rpl/t/rpl_heartbeat_2slaves.test b/mysql-test/suite/rpl/t/rpl_heartbeat_2slaves.test new file mode 100644 index 00000000..e0fdf668 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_heartbeat_2slaves.test @@ -0,0 +1,124 @@ +############################################################# +# Author: Serge Kozlov +# Date: 02/19/2009 +# Purpose: Testing heartbeat for schema +# 1 master and 2 slaves +############################################################# +--let $rpl_topology= 1->2,1->3 +--source include/rpl_init.inc + +--let $rpl_connection_name= master +--let $rpl_server_number= 1 +--source include/rpl_connect.inc + +--let $rpl_connection_name= slave_1 +--let $rpl_server_number= 2 +--source include/rpl_connect.inc + +--let $rpl_connection_name= slave_2 +--let $rpl_server_number= 3 +--source include/rpl_connect.inc + +# +# Set different heartbeat periods for slaves +# +--connection slave_1 +--source include/stop_slave.inc +CHANGE MASTER TO MASTER_HEARTBEAT_PERIOD = 0.1; +--source include/start_slave.inc +--connection slave_2 +--source include/stop_slave.inc +CHANGE MASTER TO MASTER_HEARTBEAT_PERIOD = 1; +--source include/start_slave.inc + +# +# Testing heartbeat for one master and two slaves +# + +# Check that heartbeat events sent to both slaves with correct periods +--connection slave_1 +let $status_var= slave_received_heartbeats; +let $status_var_value= query_get_value(SHOW STATUS LIKE 'slave_received_heartbeats', Value, 1); +let $status_var_comparsion= >; +--source include/wait_for_status_var.inc +--echo Slave has received heartbeat event +--connection slave_2 +let $status_var= slave_received_heartbeats; +let $status_var_value= query_get_value(SHOW STATUS LIKE 'slave_received_heartbeats', Value, 1); +let $status_var_comparsion= >; +--source include/wait_for_status_var.inc +--let $assert_cond= [slave_1:SHOW STATUS LIKE "slave_received_heartbeats", Value, 1] > [slave_2:SHOW STATUS LIKE "slave_received_heartbeats", Value, 1] +--let $assert_text= slave_1 should have received more heartbeats than slave_2 +--source include/assert.inc +--echo + +# Create topology master->slave_2->slave_1 and check that slave_1 +# receives heartbeat while slave_2 gets data. + +# slave_2 was started w/o --log-slave-updates because slave_2 should +# not send data from master to slave_1 + +--source include/rpl_stop_slaves.inc +--let $rpl_topology= 1->3->2 +--source include/rpl_change_topology.inc +--source include/rpl_start_slaves.inc +--connection slave_1 +--source include/stop_slave.inc +CHANGE MASTER TO MASTER_HEARTBEAT_PERIOD=0.1; +--source include/start_slave.inc + +# Check heartbeat for new replication channel slave_2->slave +let $status_var= slave_received_heartbeats; +let $status_var_value= query_get_value(SHOW STATUS LIKE 'slave_received_heartbeats', Value, 1); +let $status_var_comparsion= >; +--source include/wait_for_status_var.inc +--echo slave_1 has received heartbeat event +--connection master +CREATE TABLE t1 (a INT PRIMARY KEY, b VARCHAR(10), c LONGTEXT); +INSERT INTO t1 VALUES (1, 'on master', ''); +SHOW TABLES; +--sync_slave_with_master slave_2 +SHOW TABLES; +let $slave_2_pos_before= query_get_value(SHOW SLAVE STATUS, Read_Master_Log_Pos, 1); +--sync_slave_with_master slave_1 +SHOW TABLES; +--connection master +--echo creating updates on master and send to slave_2 during 5 second +# Generate events on master and send to slave_2 during 5 second +let $i= 1; +let $j= 1; +let $k= 1; +--disable_query_log +while ($i) { + eval SET @c_text=REPEAT('1234567890', $j); + eval UPDATE t1 SET a=$j, c=@c_text; + --connection slave_2 + let $slave_2_pos= query_get_value(SHOW SLAVE STATUS, Read_Master_Log_Pos, 1); + if (`SELECT ($k*($slave_2_pos - $slave_2_pos_before)) > 0`) { + --connection slave_1 + let $slave_1_rcvd_heartbeats_before= query_get_value(SHOW STATUS LIKE 'slave_received_heartbeats', Value, 1); + let $k= 0; + let $time_before = `SELECT NOW()`; + } + if (`SELECT ((1-$k)*TIMESTAMPDIFF(SECOND,'$time_before',NOW())) > 5`) { + let $i= 0; + } + --connection master + inc $j; + sleep 0.1; +} +--enable_query_log +--connection slave_1 +--let $assert_cond= [SHOW STATUS LIKE "slave_received_heartbeats", Value, 1] > $slave_1_rcvd_heartbeats_before +--let $assert_text= slave_1 should have received heartbeats +--source include/assert.inc +--echo + +# +# Clean up +# +--echo *** Clean up *** +--connection master +DROP TABLE t1; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_heartbeat_basic.cnf b/mysql-test/suite/rpl/t/rpl_heartbeat_basic.cnf new file mode 100644 index 00000000..a4a291bc --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_heartbeat_basic.cnf @@ -0,0 +1,7 @@ +!include ../my.cnf + +[mysqld.1] +log-slave-updates + +[mysqld.2] +log-slave-updates diff --git a/mysql-test/suite/rpl/t/rpl_heartbeat_basic.test b/mysql-test/suite/rpl/t/rpl_heartbeat_basic.test new file mode 100644 index 00000000..f12c5921 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_heartbeat_basic.test @@ -0,0 +1,565 @@ +############################################################# +# Author: Serge Kozlov +# Date: 02/19/2009 +# Purpose: Testing basic functionality of heartbeat. +# Description: +# * Testing different values for slave_heartbeat_period. +# * How to affect various statements to slave_heartbeat_period +# * Various states of slave and heartbeat +# * Various states of master and heartbeat +# * Circular replication +############################################################# +--source include/master-slave.inc +# +# The test runs long and does not have any specifics to +# binlog_format. It is chosen therefore to run with MIXED mode +# in order to not slow down much `make test'. +# +--source include/have_binlog_format_mixed.inc +--echo + +# Set number of retries to connect to master +let $connect_retry= 20; + +--echo *** Preparing *** +--connection slave +--source include/stop_slave.inc +RESET SLAVE; +SET @restore_slave_net_timeout=@@global.slave_net_timeout; +let $slave_heartbeat_timeout= query_get_value(SHOW GLOBAL STATUS LIKE 'slave_heartbeat_period', Value, 1); +--disable_query_log +eval SET @restore_slave_heartbeat_timeout=$slave_heartbeat_timeout; +--enable_query_log + +--connection master +RESET MASTER; +SET @restore_slave_net_timeout=@@global.slave_net_timeout; +--echo + +# +# Test slave_heartbeat_period +# + +--connection slave + +# Default value of slave_heartbeat_timeout = slave_net_timeout/2 +--echo *** Default value *** +--replace_result $MASTER_MYPORT MASTER_PORT +eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=$MASTER_MYPORT, MASTER_USER='root'; +let $slave_net_timeout= query_get_value(SHOW VARIABLES LIKE 'slave_net_timeout', Value, 1); +let $slave_heartbeat_timeout= query_get_value(SHOW GLOBAL STATUS LIKE 'slave_heartbeat_period', Value, 1); +let $result= query_get_value(SELECT $slave_net_timeout/$slave_heartbeat_timeout AS Result, Result, 1); +--echo slave_net_timeout/slave_heartbeat_timeout=$result +RESET SLAVE; +--echo + +# Reset slave set slave_heartbeat_timeout = slave_net_timeout/2 +--echo *** Reset slave affect *** +--disable_warnings +SET @@global.slave_net_timeout=30; +--enable_warnings +--replace_result $MASTER_MYPORT MASTER_PORT +eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=$MASTER_MYPORT, MASTER_USER='root', MASTER_CONNECT_RETRY=$connect_retry, MASTER_HEARTBEAT_PERIOD=5; +RESET SLAVE; +SHOW GLOBAL STATUS LIKE 'slave_heartbeat_period'; +--echo + +# Check default value of slave_heartbeat_timeout if slave_net_timeout is changed +--echo *** Default value if slave_net_timeout changed *** +--disable_warnings +SET @@global.slave_net_timeout=50; +--enable_warnings +--replace_result $MASTER_MYPORT MASTER_PORT +eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=$MASTER_MYPORT, MASTER_USER='root', MASTER_CONNECT_RETRY=$connect_retry; +SHOW GLOBAL STATUS LIKE 'slave_heartbeat_period'; +SET @@global.slave_net_timeout=@restore_slave_net_timeout; +RESET SLAVE; +--echo + +# Set slave_net_timeout less than current value of slave_heartbeat_period +--echo *** Warning if updated slave_net_timeout < slave_heartbeat_timeout *** +let $slave_heartbeat_timeout= query_get_value(SHOW GLOBAL STATUS LIKE 'slave_heartbeat_period', Value, 1); +--replace_result $slave_heartbeat_timeout SLAVE_HEARTBEAT_TIMEOUT +eval SET @@global.slave_net_timeout=FLOOR($slave_heartbeat_timeout)-1; +SET @@global.slave_net_timeout=@restore_slave_net_timeout; +RESET SLAVE; +--echo + +# Set value of slave_heartbeat_period greater than slave_net_timeout +--echo *** Warning if updated slave_heartbeat_timeout > slave_net_timeout *** +let $slave_net_timeout= query_get_value(SHOW VARIABLES LIKE 'slave_net_timeout', Value, 1); +inc $slave_net_timeout; +--replace_result $MASTER_MYPORT MASTER_PORT $slave_net_timeout SLAVE_NET_TIMEOUT +eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=$MASTER_MYPORT, MASTER_USER='root', MASTER_CONNECT_RETRY=$connect_retry, MASTER_HEARTBEAT_PERIOD=$slave_net_timeout; +RESET SLAVE; +--echo + +# Changing of slave_net_timeout shouldn't affect to current value of slave_heartbeat_period +--echo *** CHANGE MASTER statement only updates slave_heartbeat_period *** +--disable_warnings +SET @@global.slave_net_timeout=20; +--enable_warnings +--replace_result $MASTER_MYPORT MASTER_PORT +eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=$MASTER_MYPORT, MASTER_USER='root', MASTER_CONNECT_RETRY=$connect_retry, MASTER_HEARTBEAT_PERIOD=5; +SHOW VARIABLES LIKE 'slave_net_timeout'; +SHOW GLOBAL STATUS LIKE 'slave_heartbeat_period'; +SET @@global.slave_net_timeout=2*@@global.slave_net_timeout; +SHOW VARIABLES LIKE 'slave_net_timeout'; +SHOW GLOBAL STATUS LIKE 'slave_heartbeat_period'; +SET @@global.slave_net_timeout=@restore_slave_net_timeout; +RESET SLAVE; +--echo + +# Master value of slave_net_timeout shouldn't affect to slave's slave_heartbeat_period +--echo *** Update slave_net_timeout on master *** +--connection master +--disable_warnings +SET @@global.slave_net_timeout=500; +--enable_warnings +--connection slave +SET @@global.slave_net_timeout=200; +RESET 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_CONNECT_RETRY=$connect_retry; +--source include/start_slave.inc +--connection master +--sync_slave_with_master +SHOW VARIABLES LIKE 'slave_net_timeout'; +SHOW GLOBAL STATUS LIKE 'slave_heartbeat_period'; +SET @@global.slave_net_timeout=@restore_slave_net_timeout; +--source include/stop_slave.inc +RESET SLAVE; +--connection master +SET @@global.slave_net_timeout=@restore_slave_net_timeout; +--echo + +# Start/stop slave shouldn't change slave_heartbeat_period +--echo *** Start/stop slave *** +--connection slave +--disable_warnings +SET @@global.slave_net_timeout=100; +--enable_warnings +--replace_result $MASTER_MYPORT MASTER_PORT +eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=$MASTER_MYPORT, MASTER_USER='root', MASTER_CONNECT_RETRY=$connect_retry, MASTER_HEARTBEAT_PERIOD=20; +--source include/start_slave.inc +--connection master +--sync_slave_with_master +SHOW GLOBAL STATUS LIKE 'slave_heartbeat_period'; +--source include/stop_slave.inc +SHOW GLOBAL STATUS LIKE 'slave_heartbeat_period'; +--echo + +# Reload slave shouldn't change slave_heartbeat_period +--echo *** Reload slave *** +--connection slave +--disable_warnings +SET @@global.slave_net_timeout=50; +--enable_warnings +--replace_result $MASTER_MYPORT MASTER_PORT +eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=$MASTER_MYPORT, MASTER_USER='root', MASTER_CONNECT_RETRY=$connect_retry, MASTER_HEARTBEAT_PERIOD=30; +--let $rpl_server_number= 2 +--source include/rpl_restart_server.inc +SHOW GLOBAL STATUS LIKE 'slave_heartbeat_period'; +SET @restore_slave_net_timeout=@@global.slave_net_timeout; +--echo + +# Disable heartbeat +--echo *** Disable heartbeat *** +--replace_result $MASTER_MYPORT MASTER_PORT +eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=$MASTER_MYPORT, MASTER_USER='root', MASTER_CONNECT_RETRY=$connect_retry, MASTER_HEARTBEAT_PERIOD=0; +SHOW GLOBAL STATUS LIKE 'slave_heartbeat_period'; +SHOW STATUS LIKE 'slave_received_heartbeats'; +--source include/start_slave.inc +--connection master +--sync_slave_with_master +--sleep 2 +SHOW GLOBAL STATUS LIKE 'slave_heartbeat_period'; +SHOW STATUS LIKE 'slave_received_heartbeats'; +--source include/stop_slave.inc +SHOW GLOBAL STATUS LIKE 'slave_heartbeat_period'; +SHOW STATUS LIKE 'slave_received_heartbeats'; +RESET SLAVE; +let $slave_heartbeat_timeout= query_get_value(SHOW GLOBAL STATUS LIKE 'slave_heartbeat_period', Value, 1); +--replace_result $slave_heartbeat_timeout SLAVE_HEARTBEAT_TIMEOUT +--eval SELECT $slave_heartbeat_timeout = 0 AS Result +--echo + +# +# Check limits for slave_heartbeat_timeout +# + +--echo *** Min slave_heartbeat_timeout *** +--replace_result $MASTER_MYPORT MASTER_PORT +eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=$MASTER_MYPORT, MASTER_USER='root', MASTER_CONNECT_RETRY=$connect_retry, MASTER_HEARTBEAT_PERIOD=0.001; +SHOW GLOBAL STATUS LIKE 'slave_heartbeat_period'; +RESET 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_CONNECT_RETRY=$connect_retry, MASTER_HEARTBEAT_PERIOD=0.0009; +SHOW GLOBAL STATUS LIKE 'slave_heartbeat_period'; +RESET SLAVE; +--echo + +--echo *** Max slave_heartbeat_timeout *** +--replace_result $MASTER_MYPORT MASTER_PORT +eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=$MASTER_MYPORT, MASTER_USER='root', MASTER_CONNECT_RETRY=$connect_retry, MASTER_HEARTBEAT_PERIOD=4294967; +SHOW GLOBAL STATUS LIKE 'slave_heartbeat_period'; +RESET SLAVE; +--replace_result $MASTER_MYPORT MASTER_PORT +--error ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE +eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=$MASTER_MYPORT, MASTER_USER='root', MASTER_CONNECT_RETRY=$connect_retry, MASTER_HEARTBEAT_PERIOD=4294968; +RESET SLAVE; +# Check double size of max allowed value for master_heartbeat_period +--replace_result $MASTER_MYPORT MASTER_PORT +--error ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE +eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=$MASTER_MYPORT, MASTER_USER='root', MASTER_CONNECT_RETRY=$connect_retry, MASTER_HEARTBEAT_PERIOD=8589935; +RESET SLAVE; +# Check 2^32 +--replace_result $MASTER_MYPORT MASTER_PORT +--error ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE +eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=$MASTER_MYPORT, MASTER_USER='root', MASTER_CONNECT_RETRY=$connect_retry, MASTER_HEARTBEAT_PERIOD=4294967296; +RESET SLAVE; +--echo + +--echo *** Misc incorrect values *** +--replace_result $MASTER_MYPORT MASTER_PORT +--error ER_PARSE_ERROR +eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=$MASTER_MYPORT, MASTER_USER='root', MASTER_CONNECT_RETRY=$connect_retry, MASTER_HEARTBEAT_PERIOD='-1'; +RESET SLAVE; +--replace_result $MASTER_MYPORT MASTER_PORT +--error ER_PARSE_ERROR +eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=$MASTER_MYPORT, MASTER_USER='root', MASTER_CONNECT_RETRY=$connect_retry, MASTER_HEARTBEAT_PERIOD='123abc'; +RESET SLAVE; +--replace_result $MASTER_MYPORT MASTER_PORT +--error ER_PARSE_ERROR +eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=$MASTER_MYPORT, MASTER_USER='root', MASTER_CONNECT_RETRY=$connect_retry, MASTER_HEARTBEAT_PERIOD=''; +RESET SLAVE; +--echo + +# +# Testing heartbeat +# + +# Check received heartbeat events for running slave +--echo *** Running 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_CONNECT_RETRY=$connect_retry, MASTER_HEARTBEAT_PERIOD=0.1; +--source include/start_slave.inc +--connection master +--sync_slave_with_master +let $status_var_value= query_get_value(SHOW STATUS LIKE 'slave_received_heartbeats', Value, 1); +let $status_var= slave_received_heartbeats; +let $status_var_comparsion= >; +--source include/wait_for_status_var.inc +--echo Heartbeat event received +--echo + +# Check received heartbeat events for stopped slave +--echo *** Stopped slave *** +--source include/stop_slave.inc +let $rcvd_heartbeats_before= query_get_value(SHOW STATUS LIKE 'slave_received_heartbeats', Value, 1); +sleep 2; +let $rcvd_heartbeats_after= query_get_value(SHOW STATUS LIKE 'slave_received_heartbeats', Value, 1); +let $result= query_get_value(SELECT ($rcvd_heartbeats_after - $rcvd_heartbeats_before) AS Result, Result, 1); +--echo Number of received heartbeat events while slave stopped: $result +--echo + +# Check received heartbeat events for started slave +--echo *** Started slave *** +--source include/start_slave.inc +let $status_var_value= query_get_value(SHOW STATUS LIKE 'slave_received_heartbeats', Value, 1); +--source include/wait_for_status_var.inc +--echo Heartbeat event received +--echo + +# Check received heartbeat events for stopped IO thread +--echo *** Stopped IO thread *** +--source include/stop_slave_io.inc +let $rcvd_heartbeats_before= query_get_value(SHOW STATUS LIKE 'slave_received_heartbeats', Value, 1); +sleep 2; +let $rcvd_heartbeats_after= query_get_value(SHOW STATUS LIKE 'slave_received_heartbeats', Value, 1); +let $result= query_get_value(SELECT ($rcvd_heartbeats_after - $rcvd_heartbeats_before) AS Result, Result, 1); +--echo Number of received heartbeat events while io thread stopped: $result +--echo + +# Check received heartbeat events for started IO thread +--echo *** Started IO thread *** +START SLAVE IO_THREAD; +--source include/wait_for_slave_io_to_start.inc +let $status_var_value= query_get_value(SHOW STATUS LIKE 'slave_received_heartbeats', Value, 1); +--source include/wait_for_status_var.inc +--echo Heartbeat event received +--echo + +# Check received heartbeat events for stopped SQL thread +--echo *** Stopped SQL thread *** +--source include/stop_slave_sql.inc +let $rcvd_heartbeats_before= query_get_value(SHOW STATUS LIKE 'slave_received_heartbeats', Value, 1); +sleep 2; +let $rcvd_heartbeats_after= query_get_value(SHOW STATUS LIKE 'slave_received_heartbeats', Value, 1); +let $result= query_get_value(SELECT ($rcvd_heartbeats_after - $rcvd_heartbeats_before) > 0 AS Result, Result, 1); +--echo Heartbeat events are received while sql thread stopped (1 means 'yes'): $result +--echo + +# Check received heartbeat events for started SQL thread +--echo *** Started SQL thread *** +START SLAVE SQL_THREAD; +--source include/wait_for_slave_sql_to_start.inc +let $status_var_value= query_get_value(SHOW STATUS LIKE 'slave_received_heartbeats', Value, 1); +--source include/wait_for_status_var.inc +--echo Heartbeat event received +--echo + +# Check received heartbeat event for stopped SQL thread by error +--echo *** Stopped SQL thread by error *** +--connection master +CREATE TABLE t1 (a INT PRIMARY KEY, b VARCHAR(10), c LONGTEXT); +--sync_slave_with_master +INSERT INTO t1 VALUES (1, 'on slave', NULL); +--connection master +INSERT INTO t1 VALUES (1, 'on master', NULL); +--connection slave +call mtr.add_suppression("Slave SQL.*Duplicate entry .1. for key .PRIMARY.. on query.* error.* 1062"); +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"); +let $slave_errno= ER_DUP_ENTRY +--source include/wait_for_slave_sql_error.inc +let $rcvd_heartbeats_before= query_get_value(SHOW STATUS LIKE 'slave_received_heartbeats', Value, 1); +sleep 4; +let $rcvd_heartbeats_after= query_get_value(SHOW STATUS LIKE 'slave_received_heartbeats', Value, 1); +let $result= query_get_value(SELECT ($rcvd_heartbeats_after - $rcvd_heartbeats_before) > 0 AS Result, Result, 1); +--echo Heartbeat events are received while sql thread stopped (1 means 'yes'): $result +--source include/stop_slave.inc +DROP TABLE t1; +--echo + +# Check received heartbeat events while master send events to slave +--echo *** Master send to slave *** +--connection master +# Create the event that will update table t1 every second +DELIMITER |; +CREATE EVENT e1 + ON SCHEDULE EVERY 1 SECOND + DO + BEGIN + UPDATE test.t1 SET a = a + 1 WHERE a < 10; + END| +DELIMITER ;| +--connection slave +RESET 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_CONNECT_RETRY=$connect_retry, MASTER_HEARTBEAT_PERIOD=5; +--source include/start_slave.inc +--connection master +# Enable scheduler +SET @@global.event_scheduler=1; + +--sync_slave_with_master +let $rcvd_heartbeats_before= query_get_value(SHOW STATUS LIKE 'slave_received_heartbeats', Value, 1); + +--connection master + +# Whether or not to send a heartbeat is decided on the master, based on +# whether the binlog was updated during the period or not. +# Even with the 1-second event, we cannot make the master to write binary +# logs (or execute SQL) in a timely manner. We can only check that they +# were executed in a timely manner, and if they were not, neutralize the +# heartbeat check on the slave. +# We will wait for 5 events, and keep checking 'Binlog_commits' on master. +# Time interval between consequent events will be measured. +# We can only expect that no heartbeats have been sent if the interval +# between events never exceeded MASTER_HEARTBEAT_PERIOD. +# If it has exceeded the value at least once, the slave can legitimately +# receive a heartbeat (but we cannot require it, because the delay +# could have occurred somewhere else, e.g. upon checking the status). +# So, if the delay is detected, we will signal slave to ignore possible +# heartbeats. + +let $possible_heartbeats= 0; +let $commits_to_wait= 5; +while ($commits_to_wait) +{ + let $tm= `SELECT UNIX_TIMESTAMP(NOW(3))`; + let $binlog_commits= query_get_value(SHOW STATUS LIKE 'Binlog_commits', Value, 1); + let $wait_condition= SELECT VARIABLE_VALUE > $binlog_commits FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME= 'BINLOG_COMMITS'; + --source include/wait_condition.inc + dec $commits_to_wait; + if (`SELECT UNIX_TIMESTAMP(NOW(3)) > $tm + 5`) + { + let $possible_heartbeats= 1; + let $commits_to_wait= 0; + } +} + +--connection slave +let $rcvd_heartbeats_after= query_get_value(SHOW STATUS LIKE 'slave_received_heartbeats', Value, 1); +let $result= `SELECT CASE WHEN $possible_heartbeats THEN 'TRUE' WHEN $rcvd_heartbeats_after - $rcvd_heartbeats_before > 0 THEN 'FALSE' ELSE 'TRUE' END`; +--echo Received heartbeats meet expectations: $result +--connection master +DELETE FROM t1; +DROP EVENT e1; +--sync_slave_with_master +--echo + +# Check received heartbeat events while logs flushed on slave +--echo *** Flush logs on slave *** +STOP SLAVE; +RESET SLAVE; +DROP TABLE t1; +--connection master +DROP TABLE t1; +RESET MASTER; +--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_CONNECT_RETRY=$connect_retry, MASTER_HEARTBEAT_PERIOD=0.5; +let $slave_param_comparison= =; +--source include/start_slave.inc +let $rcvd_heartbeats_before= query_get_value(SHOW STATUS LIKE 'slave_received_heartbeats', Value, 1); +# Flush logs every 0.1 second during 5 sec +--disable_query_log +let $i=100; +while ($i) { + FLUSH LOGS; + dec $i; + sleep 0.1; +} +--enable_query_log +let $rcvd_heartbeats_after= query_get_value(SHOW STATUS LIKE 'slave_received_heartbeats', Value, 1); +let $result= query_get_value(SELECT ($rcvd_heartbeats_after - $rcvd_heartbeats_before) > 0 AS Result, Result, 1); +--echo Heartbeat events are received while rotation of relay logs (1 means 'yes'): $result +--echo + +# Use compressed protocol between master and slave +--echo *** Compressed protocol *** +--connection master +SET @@global.slave_compressed_protocol=1; +--connection slave +--source include/stop_slave.inc +RESET SLAVE; +SET @@global.slave_compressed_protocol=1; +--replace_result $MASTER_MYPORT MASTER_PORT +eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=$MASTER_MYPORT, MASTER_USER='root', MASTER_CONNECT_RETRY=$connect_retry, MASTER_HEARTBEAT_PERIOD=0.1; +--source include/start_slave.inc +let $status_var_value= query_get_value(SHOW STATUS LIKE 'slave_received_heartbeats', Value, 1); +let $status_var= slave_received_heartbeats; +let $status_var_comparsion= >; +--source include/wait_for_status_var.inc +--echo Heartbeat event received +SET @@global.slave_compressed_protocol=0; +--connection master +SET @@global.slave_compressed_protocol=0; +--echo + + +# Check received heartbeat events after reset of master +--echo *** Reset master *** +--connection slave +STOP SLAVE; +RESET 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_CONNECT_RETRY=$connect_retry, MASTER_HEARTBEAT_PERIOD=0.1; +--source include/start_slave.inc +let $rcvd_heartbeats_before= query_get_value(SHOW STATUS LIKE 'slave_received_heartbeats', Value, 1); +--connection master +RESET MASTER; +--enable_query_log +--sync_slave_with_master +--sleep 2 +let $rcvd_heartbeats_after= query_get_value(SHOW STATUS LIKE 'slave_received_heartbeats', Value, 1); +let $result= query_get_value(SELECT ($rcvd_heartbeats_after - $rcvd_heartbeats_before) > 0 AS Result, Result, 1); +--echo Heartbeat events are received after reset of master (1 means 'yes'): $result +--echo + +# Reloaded master should restore heartbeat +--echo *** Reload master *** +--connection slave +STOP SLAVE; +RESET 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_CONNECT_RETRY=$connect_retry, MASTER_HEARTBEAT_PERIOD=0.1; +--source include/start_slave.inc +# Wait until slave_received_heartbeats will be incremented +let $status_var_value= query_get_value(SHOW STATUS LIKE 'slave_received_heartbeats', Value, 1); +let $status_var= slave_received_heartbeats; +let $status_var_comparsion= >; +--source include/wait_for_status_var.inc +--echo Heartbeat event received +--let $rpl_server_number= 1 +--source include/rpl_restart_server.inc +# make sure IO thread has re-connected +# due to slow valgrind env the following wait_for_status may time out +--let $rpl_allow_error= 1 +--source include/wait_for_slave_io_to_start.inc +# Wait until slave_received_heartbeats will be incremented +let $status_var_value= query_get_value(SHOW STATUS LIKE 'slave_received_heartbeats', Value, 1); +let $status_var= slave_received_heartbeats; +let $status_var_comparsion= >; +--source include/wait_for_status_var.inc +--echo Heartbeat event received +--echo + +# Circular replication: demonstrating bidirectional hearbeat flow +--echo *** Circular replication *** +# Configure circular replication +--source include/rpl_reset.inc +--source include/stop_slave.inc +--let $rpl_topology= 1->2->1 +--source include/rpl_change_topology.inc + +#--connection slave +#--source include/stop_slave.inc +#let $slave_binlog= query_get_value(SHOW MASTER STATUS, File, 1); +--connection master +#--replace_result $SLAVE_MYPORT SLAVE_PORT $slave_binlog SLAVE_BINLOG +#eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=$SLAVE_MYPORT, MASTER_USER='root', MASTER_CONNECT_RETRY=$connect_retry, MASTER_HEARTBEAT_PERIOD=1, MASTER_LOG_FILE='$slave_binlog'; + +# BUG#12403008 RPL_HEARTBEAT_BASIC FAILS SPORADICALLY ON PUSHBUILD +# MASTER_HEARTBEAT_PERIOD had the default value (slave_net_timeout/2) +# so wait on "Heartbeat event received on master", that only waits for +# 1 minute, sometimes timeout before heartbeat arrives. +CHANGE MASTER TO MASTER_HEARTBEAT_PERIOD=1; +--source include/start_slave.inc + +# Insert data on master and on slave and make sure that it replicated for both directions +CREATE TABLE t1 (a INT PRIMARY KEY, b VARCHAR(10)); +INSERT INTO t1 VALUES(1, 'on master'); +--save_master_pos +--connection slave +## set slave period 1/10 of master's +CHANGE MASTER TO MASTER_HEARTBEAT_PERIOD=0.1; +--source include/start_slave.inc +--sync_with_master +INSERT INTO t1 VALUES(2, 'on slave'); +--sync_slave_with_master master +SELECT * FROM t1 ORDER BY a; +let $master_rcvd_heartbeats_before= query_get_value(SHOW STATUS LIKE 'slave_received_heartbeats', Value, 1); +--connection slave +SELECT * FROM t1 ORDER BY a; + +# Wait for heartbeat event on master +--connection master +let $status_var= slave_received_heartbeats; +let $status_var_value= query_get_value(SHOW STATUS LIKE 'slave_received_heartbeats', Value, 1); +let $status_var_comparsion= >; +--source include/wait_for_status_var.inc +--echo Heartbeat event received on master + +# Wait heartbeat events on slave +--connection slave +let $status_var= slave_received_heartbeats; +let $status_var_value= query_get_value(SHOW STATUS LIKE 'slave_received_heartbeats', Value, 1); +let $status_var_comparsion= >; +--source include/wait_for_status_var.inc +--echo Heartbeat event received on slave +let $slave_rcvd_heartbeats= query_get_value(SHOW STATUS LIKE 'slave_received_heartbeats', Value, 1); + +# +# Clean up and restore system variables +# +--echo *** Clean up *** +--connection master +#--source include/stop_slave.inc +DROP TABLE t1; +--sync_slave_with_master +SET @@global.slave_net_timeout=@restore_slave_net_timeout; + +#--let $rpl_only_running_threads= 1 +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_heartbeat_debug.test b/mysql-test/suite/rpl/t/rpl_heartbeat_debug.test new file mode 100644 index 00000000..bd66a249 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_heartbeat_debug.test @@ -0,0 +1,52 @@ +# Testing master to slave heartbeat protocol, test cases that need debug build. + +--source include/have_debug.inc +--source include/master-slave.inc + +connection slave; +--source include/stop_slave.inc +set @restore_slave_net_timeout= @@global.slave_net_timeout; +--disable_warnings +set @@global.slave_net_timeout= 10; +--enable_warnings + +### +### Checking the range +### + +# +# default period slave_net_timeout/2 +# +--query_vertical show status like 'Slave_heartbeat_period'; +SET @saved_dbug= @@GLOBAL.debug_dbug; +SET GLOBAL debug_dbug="+d,simulate_slave_heartbeat_network_error"; +CALL mtr.add_suppression('SET @master_heartbeat_period to master failed with error'); +CALL mtr.add_suppression('Master command COM_REGISTER_SLAVE failed: failed registering on master, reconnecting to try again'); +--source include/start_slave.inc + + +connection master; +--disable_warnings +drop table if exists t1; +--enable_warnings + +CREATE TABLE t1 (a INT PRIMARY KEY); +INSERT INTO t1 VALUES (1); + +sync_slave_with_master; + +--connection slave +SELECT * FROM t1; + +connection master; +drop table t1; + +connection slave; +--source include/stop_slave.inc +--disable_warnings +SET GLOBAL debug_dbug=@saved_dbug; +set @@global.slave_net_timeout= @restore_slave_net_timeout; +--enable_warnings +--source include/start_slave.inc + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_heartbeat_ssl.test b/mysql-test/suite/rpl/t/rpl_heartbeat_ssl.test new file mode 100644 index 00000000..810db4cc --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_heartbeat_ssl.test @@ -0,0 +1,56 @@ +############################################################# +# Author: Serge Kozlov +# Date: 02/19/2009 +# Purpose: Testing basic functionality of heartbeat over SSL +############################################################# +--source include/have_ssl_communication.inc +--source include/master-slave.inc +--echo + +# +# Testing heartbeat over SSL +# + +# Heartbeat over SSL +--echo *** Heartbeat over SSL *** +--connection master +let $master_binlog= query_get_value(SHOW MASTER STATUS, File, 1); +--connection slave +--source include/stop_slave.inc +RESET SLAVE; +# Connect to master with SSL +--replace_result $MASTER_MYPORT MASTER_PORT $MYSQL_TEST_DIR MYSQL_TEST_DIR $master_binlog MASTER_BINLOG +eval CHANGE MASTER TO + MASTER_HOST='127.0.0.1', + MASTER_PORT=$MASTER_MYPORT, + MASTER_USER='root', + MASTER_HEARTBEAT_PERIOD=0.1, + MASTER_LOG_FILE='$master_binlog', + MASTER_SSL=1, + MASTER_SSL_CA='$MYSQL_TEST_DIR/std_data/cacert.pem', + MASTER_SSL_CERT='$MYSQL_TEST_DIR/std_data/client-cert.pem', + MASTER_SSL_KEY='$MYSQL_TEST_DIR/std_data/client-key.pem'; +--source include/start_slave.inc +# Check SSL state of slave +let $slave_ssl_status= query_get_value(SHOW SLAVE STATUS, Master_SSL_Allowed, 1); +--echo Master_SSL_Allowed: $slave_ssl_status +# Wait until hearbeat event will received +let $status_var_value= query_get_value(SHOW STATUS LIKE 'slave_received_heartbeats', Value, 1); +let $status_var= slave_received_heartbeats; +let $status_var_comparsion= >; +--source include/wait_for_status_var.inc +--echo Heartbeat event has received +--echo + +# +# Clean up +# +--echo *** Clean up *** +--source include/stop_slave.inc +CHANGE MASTER TO + MASTER_SSL=0, + MASTER_SSL_CA='', + MASTER_SSL_CERT='', + MASTER_SSL_KEY=''; +--let $rpl_only_running_threads= 1 +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_hrtime.test b/mysql-test/suite/rpl/t/rpl_hrtime.test new file mode 100644 index 00000000..98b08abe --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_hrtime.test @@ -0,0 +1,7 @@ +--source include/have_binlog_format_mixed_or_statement.inc + +--source suite/rpl/include/hrtime.inc + +let $MYSQLD_DATADIR= `select @@datadir`; +--exec $MYSQL_BINLOG --short-form $MYSQLD_DATADIR/master-bin.000001 + diff --git a/mysql-test/suite/rpl/t/rpl_hrtime_row.test b/mysql-test/suite/rpl/t/rpl_hrtime_row.test new file mode 100644 index 00000000..e1d49f53 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_hrtime_row.test @@ -0,0 +1,3 @@ +--source include/have_binlog_format_row.inc +--source suite/rpl/include/hrtime.inc + diff --git a/mysql-test/suite/rpl/t/rpl_idempotency.test b/mysql-test/suite/rpl/t/rpl_idempotency.test new file mode 100644 index 00000000..12dec236 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_idempotency.test @@ -0,0 +1,107 @@ +# Testing various forms of idempotency for replication that should +# work the same way under statement based as under row based. + +source include/master-slave.inc; + +# Add suppression for expected warning(s) in slaves error log +call mtr.add_suppression("Slave SQL.*Can.t find record in .t[12].* error.* 1032"); +call mtr.add_suppression("Slave SQL.*Cannot delete or update a parent row: a foreign key constraint fails .* error.* 1451"); +call mtr.add_suppression("Slave SQL.*Cannot add or update a child row: a foreign key constraint fails .* error.* 1452"); +call mtr.add_suppression("Slave SQL.*Could not execute Write_rows event on table test.* Duplicate entry .1. for key .PRIMARY.* error.* 1062"); +call mtr.add_suppression("Can't find record in 't1'"); +call mtr.add_suppression("Can't find record in 't2'"); + +connection master; +CREATE TABLE t1 (a INT PRIMARY KEY); +CREATE TABLE t2 (a INT); +INSERT INTO t1 VALUES (-1),(-2),(-3); +INSERT INTO t2 VALUES (-1),(-2),(-3); +sync_slave_with_master; + +SET @old_slave_exec_mode= @@global.slave_exec_mode; +SET @@global.slave_exec_mode= IDEMPOTENT; + +# A delete for a row that does not exist, the statement is +# deliberately written to be idempotent for statement-based +# replication as well. We test this towards both a table with a +# primary key and without a primary key. + +connection slave; +DELETE FROM t1 WHERE a = -2; +DELETE FROM t2 WHERE a = -2; +connection master; +DELETE FROM t1 WHERE a = -2; +DELETE FROM t2 WHERE a = -2; +SELECT * FROM t1 ORDER BY a; +SELECT * FROM t2 ORDER BY a; +sync_slave_with_master; +SELECT * FROM t1 ORDER BY a; +SELECT * FROM t2 ORDER BY a; +--source include/check_slave_no_error.inc + +# An insert of a row that already exists. Since we are replacing the +# row if it already exists, the most apropriate representation is +# INSERT IGNORE. We only test this towards a table with a primary key, +# since the other case does not make sense. + +INSERT IGNORE INTO t1 VALUES (-2); +connection master; +INSERT IGNORE INTO t1 VALUES (-2); +SELECT * FROM t1 ORDER BY a; +sync_slave_with_master; +SELECT * FROM t1 ORDER BY a; +--source include/check_slave_no_error.inc + + +# BUG#19958: RBR idempotency issue for UPDATE and DELETE + +# Statement-based and row-based replication have different behaviour +# when updating a row with an explicit WHERE-clause that matches +# exactly one row (or no row at all). For statement-based replication, +# the statement is idempotent since the first time it is executed, it +# will update exactly one row, and the second time it will not update +# any row at all. This was not the case for row-based replication, so +# we test under both row-based and statement-based replication both +# for tables with and without primary keys. + +connection slave; +UPDATE t1 SET a = 1 WHERE a = -1; +UPDATE t2 SET a = 1 WHERE a = -1; +connection master; +UPDATE t1 SET a = 1 WHERE a = -1; +UPDATE t2 SET a = 1 WHERE a = -1; +SELECT * FROM t1 ORDER BY a; +SELECT * FROM t2 ORDER BY a; +sync_slave_with_master; +SELECT * FROM t1 ORDER BY a; +SELECT * FROM t2 ORDER BY a; +--source include/check_slave_no_error.inc + +connection slave; +drop table t1, t2; + +connection master; +DROP TABLE t1, t2; +sync_slave_with_master; +--source include/check_slave_no_error.inc +create database d; +create database e; + +connection master; +create database d; +create database if not exists e; + +sync_slave_with_master; +--source include/check_slave_no_error.inc +drop database d; +drop database e; + +connection master; +drop database d; +drop database if exists e; +sync_slave_with_master; +--source include/check_slave_no_error.inc + +SET @@global.slave_exec_mode= @old_slave_exec_mode; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_ignore_grant-slave.opt b/mysql-test/suite/rpl/t/rpl_ignore_grant-slave.opt new file mode 100644 index 00000000..e931bfbd --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_ignore_grant-slave.opt @@ -0,0 +1 @@ +--replicate-wild-ignore-table=mysql.% diff --git a/mysql-test/suite/rpl/t/rpl_ignore_grant.test b/mysql-test/suite/rpl/t/rpl_ignore_grant.test new file mode 100644 index 00000000..58457c14 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_ignore_grant.test @@ -0,0 +1,55 @@ +# Test that GRANT is not replicated to the slave +# when --replicate-wild-ignore-table=mysql.% +# In BUG#980, this test would _randomly_ fail. + +source include/master-slave.inc; + +# do not be influenced by other tests. +connection master; +set sql_mode=""; +delete from mysql.user where user=_binary'rpl_ignore_grant'; +delete from mysql.db where user=_binary'rpl_ignore_grant'; +flush privileges; +--sync_slave_with_master +set sql_mode=""; +# as these DELETE were not replicated, we need to do them manually on the +# slave. +delete from mysql.user where user=_binary'rpl_ignore_grant'; +delete from mysql.db where user=_binary'rpl_ignore_grant'; +flush privileges; + +# test non-replication of GRANT +connection master; +grant select on *.* to rpl_ignore_grant@localhost; +grant drop on test.* to rpl_ignore_grant@localhost; +show grants for rpl_ignore_grant@localhost; +--sync_slave_with_master +--error 1141 #("no such grant for user") +show grants for rpl_ignore_grant@localhost; +# check it another way +select count(*) from mysql.user where user=_binary'rpl_ignore_grant'; +select count(*) from mysql.db where user=_binary'rpl_ignore_grant'; + +# test non-replication of SET PASSWORD +# first force creation of the user on slave (because as the user does not exist +# on slave, the SET PASSWORD may be replicated but silently do nothing; this is +# not what we want; we want it to be not-replicated). +grant select on *.* to rpl_ignore_grant@localhost; +connection master; +set password for rpl_ignore_grant@localhost=password("does it work?"); +--sync_slave_with_master +select password<>_binary'' from mysql.user where user=_binary'rpl_ignore_grant'; + +# clear what we have done, to not influence other tests. +connection master; +delete from mysql.user where user=_binary'rpl_ignore_grant'; +delete from mysql.db where user=_binary'rpl_ignore_grant'; +flush privileges; +--sync_slave_with_master +delete from mysql.user where user=_binary'rpl_ignore_grant'; +delete from mysql.db where user=_binary'rpl_ignore_grant'; +flush privileges; + +connection master; +# End of 4.1 tests +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_ignore_revoke-slave.opt b/mysql-test/suite/rpl/t/rpl_ignore_revoke-slave.opt new file mode 100644 index 00000000..e931bfbd --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_ignore_revoke-slave.opt @@ -0,0 +1 @@ +--replicate-wild-ignore-table=mysql.% diff --git a/mysql-test/suite/rpl/t/rpl_ignore_revoke.test b/mysql-test/suite/rpl/t/rpl_ignore_revoke.test new file mode 100644 index 00000000..db20e807 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_ignore_revoke.test @@ -0,0 +1,52 @@ +# test verifies that REVOKE must not be replicated when +# slave server starts with --replicate-wild-ignore-table=mysql.% +# the option is set in rpl_ignore_revoke-slave.opt +# The first part of BUG#9483 for GRANT is checked by +# existed specific rpl_ignore_grant test case (BUG#980) + + +source include/master-slave.inc; + +### CLEAN-UP: create an account and manually duplicate it on the slave + +connection master; +grant select on *.* to 'user_foo'@'%' identified by 'user_foopass'; +revoke select on *.* from 'user_foo'@'%'; +select select_priv from mysql.user where user='user_foo' /* master:must be N */; + +sync_slave_with_master; +#connection slave; +grant select on *.* to 'user_foo'@'%' identified by 'user_foopass'; +revoke select on *.* from 'user_foo'@'%'; +select select_priv from mysql.user where user='user_foo' /* slave:must be N */; + + +### TEST + +#connection slave; +grant select on *.* to 'user_foo'@'%' identified by 'user_foopass'; +select select_priv from mysql.user where user='user_foo' /* slave:must be Y */; + +connection master; +revoke select on *.* from 'user_foo'; +select select_priv from mysql.user where user='user_foo' /* master:must be N */; + +sync_slave_with_master; +#connection slave; +select select_priv from mysql.user where user='user_foo' /* slave:must get Y */; + +### CLEAN-UP + +connection slave; +--disable_abort_on_error +revoke select on *.* FROM 'user_foo'; +--enable_abort_on_error + +connection master; +delete from mysql.user where user="user_foo"; +sync_slave_with_master; + +# Since changes to mysql.* are ignored, the revoke need to +# be done on slave as well +delete from mysql.user where user="user_foo"; +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_ignore_table-slave.opt b/mysql-test/suite/rpl/t/rpl_ignore_table-slave.opt new file mode 100644 index 00000000..3aabbb2e --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_ignore_table-slave.opt @@ -0,0 +1 @@ +--replicate-ignore-table=test.t1 --replicate-ignore-table=test.t2 --replicate-ignore-table=test.t3 --replicate-wild-ignore-table=%.tmptbl% diff --git a/mysql-test/suite/rpl/t/rpl_ignore_table.test b/mysql-test/suite/rpl/t/rpl_ignore_table.test new file mode 100644 index 00000000..19797b89 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_ignore_table.test @@ -0,0 +1,198 @@ +let collation=utf8_unicode_ci; +source include/have_collation.inc; +source include/master-slave.inc; + +call mtr.add_suppression("Can't find record in 't.'"); +call mtr.add_suppression("Can't find record in 'global_priv'"); +call mtr.add_suppression("Can't find record in 'tables_priv'"); + +# +# BUG#16487 +# +# Requirement: +# Multi-updates on ignored tables should not fail even if the slave does +# not have the ignored tables. +# +# Note table t1, t2, and t3 are ignored in the option file to this test. +# + +--echo **** Test case for BUG#16487 **** +connection master; +CREATE TABLE test.t4 (a int); +CREATE TABLE test.t1 (a int); + +# Expect: The row must *not* by updated on slave, since t1 is ignored +UPDATE test.t4 NATURAL JOIN test.t1 SET t1.a=5; + +sync_slave_with_master; +SELECT * FROM t4; + +# Cleanup +connection master; +DROP TABLE t1; +DROP TABLE t4; + +sync_slave_with_master; + + +# +# Bug#25482 GRANT statements are not replicated if +# you use "replicate-ignore-table" +# + +--echo **** Test case for BUG#25482 **** +--echo **** Adding GRANTS on master **** + +connection master; +create table test.t1(a int); +create table test.t4(a int); + +set sql_mode=""; +# Simple user that should not replicate +GRANT SELECT ON test.t1 TO mysqltest1@localhost; + +# Partial replicate +GRANT INSERT ON test.t4 TO mysqltest2@localhost; +GRANT select, update, insert, references on t1 + to mysqltest2@localhost; + +# Partial replicate 2 +GRANT SELECT ON test.* TO mysqltest3@localhost; +GRANT INSERT ON test.t4 TO mysqltest3@localhost; +GRANT select(a), update(a), insert(a), references(a) on t4 + to mysqltest3@localhost; + +# Create another database and table +create database mysqltest2; +create table mysqltest2.t2 (id int); +# Create a grant that should replicate +GRANT SELECT ON mysqltest2.t2 TO mysqltest4@localhost IDENTIFIED BY 'pass'; + +# Create a grant manually +insert into mysql.global_priv (user, host) values ("mysqltest5", "somehost"); + +# Partial replicate 3 with *.* +GRANT SELECT ON *.* TO mysqltest6@localhost; +GRANT INSERT ON *.* TO mysqltest6@localhost; +GRANT INSERT ON test.* TO mysqltest6@localhost; +GRANT INSERT ON test.t1 TO mysqltest6@localhost; + +--sorted_result +show grants for mysqltest1@localhost; +--sorted_result +show grants for mysqltest2@localhost; +--sorted_result +show grants for mysqltest3@localhost; +--sorted_result +show grants for mysqltest4@localhost; +--sorted_result +show grants for mysqltest6@localhost; + +flush privileges; +show grants for mysqltest5@somehost; + +set sql_mode=""; +sync_slave_with_master; + +--echo **** Checking grants on slave **** + +# Check that grants are replicated to slave +--sorted_result +show grants for mysqltest2@localhost; +--sorted_result +show grants for mysqltest3@localhost; +--sorted_result +show grants for mysqltest4@localhost; +--sorted_result +show grants for mysqltest5@somehost; +--sorted_result +show grants for mysqltest6@localhost; + +# mysqltest1 should not be on slave +--error 1141 +show grants for mysqltest1@localhost; + +--echo **** Revoking grants on master **** +connection master; +REVOKE SELECT ON test.t1 FROM mysqltest1@localhost; +REVOKE SELECT ON mysqltest2.t2 FROM mysqltest4@localhost; +REVOKE select(a) on t4 + from mysqltest3@localhost; + +--sorted_result +show grants for mysqltest1@localhost; +--sorted_result +show grants for mysqltest3@localhost; +--sorted_result +show grants for mysqltest4@localhost; + +sync_slave_with_master; + +--echo **** Checking grants on slave **** + +# mysqltest1 should not be on slave +--error 1141 +show grants for mysqltest1@localhost; +show grants for mysqltest3@localhost; +show grants for mysqltest4@localhost; + +# Cleanup +# connection slave; +# BUG31552 changes idempotency is not default any longer +# In order the following `delete from mysql.user', +# where mysqltest1 does not exist on slave, +# to succeed on slave the mode is temporarily changed +set global slave_exec_mode='IDEMPOTENT'; +call mtr.add_suppression("Slave SQL.*Could not execute Delete_rows event on table mysql.* error.* 1032"); + +connection master; +drop table t1, mysqltest2.t2; +drop table t4; +drop database mysqltest2; +delete from mysql.user where user like "mysqltest%"; +delete from mysql.db where user like "mysqltest%"; +# +# BUG 27606 causes failure to replicate this statement +# move it to slave instead +#delete from mysql.tables_priv where user like "mysqltest%"; +delete from mysql.columns_priv where user like "mysqltest%"; + +sync_slave_with_master; +# bug#31552: do not restore the mode here but later in order +# to succeed with yet the following delete from mysql.tables_priv + +#BUG27606 +delete from mysql.tables_priv where user like "mysqltest%"; + +connection master; + +#BUG27606 +delete from mysql.tables_priv where user like "mysqltest%"; + +# +# bug#22877 replication character sets get out of sync +# using replicate-wild-ignore-table +# +connection master; +--disable_warnings +DROP TABLE IF EXISTS t5; +--enable_warnings +CREATE TABLE t5 ( + word varchar(50) collate utf8_unicode_ci NOT NULL default '' +) DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; +SET @@session.character_set_client=33,@@session.collation_connection=192; +CREATE TEMPORARY TABLE tmptbl504451f4258$1 (id INT NOT NULL) ENGINE=MEMORY; +INSERT INTO t5 (word) VALUES ('TEST’'); +SELECT HEX(word) FROM t5; +sync_slave_with_master; +set @@global.slave_exec_mode= default; # bug#31552 comments above +connection slave; +SELECT HEX(word) FROM t5; +--error 1146 +SELECT * FROM tmptbl504451f4258$1; +connection master; +DROP TABLE t5; +flush privileges; +sync_slave_with_master; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_ignore_table_update-slave.opt b/mysql-test/suite/rpl/t/rpl_ignore_table_update-slave.opt new file mode 100644 index 00000000..177f89e0 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_ignore_table_update-slave.opt @@ -0,0 +1 @@ +--replicate-ignore-table=test.mysqltest_foo diff --git a/mysql-test/suite/rpl/t/rpl_ignore_table_update.test b/mysql-test/suite/rpl/t/rpl_ignore_table_update.test new file mode 100644 index 00000000..6591dbbc --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_ignore_table_update.test @@ -0,0 +1,35 @@ +# This one assumes we are ignoring updates on table mysqltest_foo, but doing +# the ones on all other tables + +source include/master-slave.inc; +connection slave; + +# +# For this test we must be in the test database +# +use test; + +--disable_warnings +drop table if exists mysqltest_foo; +drop table if exists mysqltest_bar; +--enable_warnings + +create table mysqltest_foo (n int); +insert into mysqltest_foo values(4); +connection master; +use test; +create table mysqltest_foo (n int); +insert into mysqltest_foo values(5); +create table mysqltest_bar (m int); +insert into mysqltest_bar values(15); +create table t1 (k int); +insert into t1 values(55); +--sync_slave_with_master +select mysqltest_foo.n,mysqltest_bar.m,t1.k from mysqltest_foo,mysqltest_bar,t1; +connection master; +drop table mysqltest_foo,mysqltest_bar,t1; +--sync_slave_with_master +drop table mysqltest_foo,mysqltest_bar,t1; + +# End of 4.1 tests +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_incident.test b/mysql-test/suite/rpl/t/rpl_incident.test new file mode 100644 index 00000000..4bb6477c --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_incident.test @@ -0,0 +1 @@ +--source include/rpl_incident.inc diff --git a/mysql-test/suite/rpl/t/rpl_incompatible_heartbeat.test b/mysql-test/suite/rpl/t/rpl_incompatible_heartbeat.test new file mode 100644 index 00000000..104debe7 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_incompatible_heartbeat.test @@ -0,0 +1,44 @@ +# ==== Purpose ==== +# +# Test verifies that slave IO thread can process heartbeat events with log_pos +# values higher than UINT32_MAX. +# +# ==== Implementation ==== +# +# Steps: +# 0 - Stop slave threads. Configure a small master_heartbeat_period. +# 1 - Using debug points, simulate a huge binlog offset higher than +# UINT32_MAX on master. +# 2 - Start the slave and observe that slave IO thread is able to process +# the offset received through heartbeat event. +# +# ==== References ==== +# +# MDEV-16146: MariaDB slave stops with incompatible heartbeat +# +--source include/have_debug.inc +--source include/have_innodb.inc +--source include/have_binlog_format_mixed.inc +# Test simulates binarylog offsets higher than UINT32_MAX +--source include/have_64bit.inc +--source include/master-slave.inc + +--connection master +SET @saved_dbug = @@GLOBAL.debug_dbug; +SET @@global.debug_dbug= 'd,simulate_pos_4G'; + +--connection slave +--source include/stop_slave.inc +CHANGE MASTER TO MASTER_HEARTBEAT_PERIOD=0.001; +--source include/start_slave.inc + +--connection master +sleep 1; +SET @@GLOBAL.debug_dbug = @saved_dbug; +--sync_slave_with_master + +--connection master +CREATE TABLE t (f INT) ENGINE=INNODB; +INSERT INTO t VALUES (10); +DROP TABLE t; +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_init_slave-slave.opt b/mysql-test/suite/rpl/t/rpl_init_slave-slave.opt new file mode 100644 index 00000000..337e8a60 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_init_slave-slave.opt @@ -0,0 +1 @@ +--init-slave="set global max_connections=500" diff --git a/mysql-test/suite/rpl/t/rpl_init_slave.test b/mysql-test/suite/rpl/t/rpl_init_slave.test new file mode 100644 index 00000000..1803b146 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_init_slave.test @@ -0,0 +1,34 @@ +source include/master-slave.inc; + +# +# Test of init_slave variable +# + +set global max_connections=151; + +connection slave; +source include/stop_slave.inc; +source include/start_slave.inc; + +connection master; +sync_slave_with_master; +show variables like 'init_slave'; +show variables like 'max_connections'; +reset master; +connection master; +show variables like 'init_slave'; +show variables like 'max_connections'; +sync_slave_with_master; +# Save variable value +set @my_global_init_connect= @@global.init_connect; +set global init_connect="set @c=1"; +show variables like 'init_connect'; +connection master; +sync_slave_with_master; + +# Restore changed global variable +set global init_connect= @my_global_init_connect; +set global max_connections= default; + +# End of 4.1 tests +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_init_slave_errors.test b/mysql-test/suite/rpl/t/rpl_init_slave_errors.test new file mode 100644 index 00000000..6f6ab7e8 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_init_slave_errors.test @@ -0,0 +1 @@ +--source include/rpl_init_slave_errors.inc diff --git a/mysql-test/suite/rpl/t/rpl_innodb-master.opt b/mysql-test/suite/rpl/t/rpl_innodb-master.opt new file mode 100644 index 00000000..e27ee9b2 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_innodb-master.opt @@ -0,0 +1 @@ +--loose-innodb-autoinc-lock-mode=0 diff --git a/mysql-test/suite/rpl/t/rpl_innodb_bug28430-master.opt b/mysql-test/suite/rpl/t/rpl_innodb_bug28430-master.opt new file mode 100644 index 00000000..e27ee9b2 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_innodb_bug28430-master.opt @@ -0,0 +1 @@ +--loose-innodb-autoinc-lock-mode=0 diff --git a/mysql-test/suite/rpl/t/rpl_innodb_bug28430-slave.opt b/mysql-test/suite/rpl/t/rpl_innodb_bug28430-slave.opt new file mode 100644 index 00000000..e27ee9b2 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_innodb_bug28430-slave.opt @@ -0,0 +1 @@ +--loose-innodb-autoinc-lock-mode=0 diff --git a/mysql-test/suite/rpl/t/rpl_innodb_bug28430.test b/mysql-test/suite/rpl/t/rpl_innodb_bug28430.test new file mode 100644 index 00000000..12698263 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_innodb_bug28430.test @@ -0,0 +1,163 @@ +--source include/big_test.inc +--source include/have_innodb.inc +--source include/have_partition.inc +--source include/have_binlog_format_mixed_or_row.inc +--source include/master-slave.inc + +# Set the default connection to 'master' + +--vertical_results + +let $engine_type= 'innodb'; + +######## Creat Table Section ######### +use test; + +eval CREATE TABLE test.regular_tbl(id MEDIUMINT NOT NULL AUTO_INCREMENT, + dt TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON + UPDATE CURRENT_TIMESTAMP, user CHAR(255), uuidf LONGBLOB, + fkid MEDIUMINT, filler VARCHAR(255), + PRIMARY KEY(id)) ENGINE=$engine_type; + +eval CREATE TABLE test.bykey_tbl(id MEDIUMINT NOT NULL AUTO_INCREMENT, + dt TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE + CURRENT_TIMESTAMP, user CHAR(255), uuidf LONGBLOB, + fkid MEDIUMINT, filler VARCHAR(255), + PRIMARY KEY(id)) ENGINE=$engine_type + PARTITION BY KEY(id) partitions 5; + +eval CREATE TABLE test.byrange_tbl(id MEDIUMINT NOT NULL AUTO_INCREMENT, + dt TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE + CURRENT_TIMESTAMP, user CHAR(255), uuidf LONGBLOB, + fkid MEDIUMINT, filler VARCHAR(255), + PRIMARY KEY(id)) ENGINE=$engine_type + PARTITION BY RANGE(id) + SUBPARTITION BY hash(id) subpartitions 2 + (PARTITION pa1 values less than (10), + PARTITION pa2 values less than (20), + PARTITION pa3 values less than (30), + PARTITION pa4 values less than (40), + PARTITION pa5 values less than (50), + PARTITION pa6 values less than (60), + PARTITION pa7 values less than (70), + PARTITION pa8 values less than (80), + PARTITION pa9 values less than (90), + PARTITION pa10 values less than (100), + PARTITION pa11 values less than MAXVALUE); + +######## Create SPs, Functions, Views and Triggers Section ############## + +delimiter |; +CREATE PROCEDURE test.proc_norm() +BEGIN + DECLARE ins_count INT DEFAULT 1000; + DECLARE del_count INT; + DECLARE cur_user VARCHAR(255); + DECLARE local_uuid VARCHAR(255); + DECLARE local_time TIMESTAMP; + + SET local_time= NOW(); + SET cur_user= CURRENT_USER(); + SET local_uuid= UUID(); + + WHILE ins_count > 0 DO + INSERT INTO test.regular_tbl VALUES (NULL, NOW(), USER() , UUID(), + ins_count,'Going to test MBR for MySQL'); + SET ins_count = ins_count - 1; + END WHILE; + + SELECT MAX(id) FROM test.regular_tbl INTO del_count; + WHILE del_count > 0 DO + DELETE FROM test.regular_tbl WHERE id = del_count; + SET del_count = del_count - 2; + END WHILE; +END| + +CREATE PROCEDURE test.proc_bykey() +BEGIN + DECLARE ins_count INT DEFAULT 1000; + DECLARE del_count INT; + DECLARE cur_user VARCHAR(255); + DECLARE local_uuid VARCHAR(255); + DECLARE local_time TIMESTAMP; + + SET local_time= NOW(); + SET cur_user= CURRENT_USER(); + SET local_uuid= UUID(); + + WHILE ins_count > 0 DO + INSERT INTO test.bykey_tbl VALUES (NULL, NOW(), USER() , UUID(), + ins_count,'Going to test MBR for MySQL'); + SET ins_count = ins_count - 1; + END WHILE; + + SELECT MAX(id) FROM test.bykey_tbl INTO del_count; + WHILE del_count > 0 DO + DELETE FROM test.bykey_tbl WHERE id = del_count; + SET del_count = del_count - 2; + END WHILE; +END| + +CREATE PROCEDURE test.proc_byrange() +BEGIN + DECLARE ins_count INT DEFAULT 1000; + DECLARE del_count INT; + DECLARE cur_user VARCHAR(255); + DECLARE local_uuid VARCHAR(255); + DECLARE local_time TIMESTAMP; + + SET local_time= NOW(); + SET cur_user = CURRENT_USER(); + SET local_uuid=UUID(); + + WHILE ins_count > 0 DO + INSERT INTO test.byrange_tbl VALUES (NULL, NOW(), USER(), UUID(), + ins_count,'Going to test MBR for MySQL'); + SET ins_count = ins_count - 1; + END WHILE; + + SELECT MAX(id) FROM test.byrange_tbl INTO del_count; + WHILE del_count > 0 DO + DELETE FROM test.byrange_tbl WHERE id = del_count; + SET del_count = del_count - 2; + END WHILE; +END| + +delimiter ;| + +############ Finish Setup Section ################### + + +############ Test Section ################### + +begin; +CALL test.proc_norm(); +commit; +SELECT count(*) as "Master regular" FROM test.regular_tbl; +begin; +CALL test.proc_bykey(); +commit; +SELECT count(*) as "Master bykey" FROM test.bykey_tbl; +begin; +CALL test.proc_byrange(); +commit; +SELECT count(*) as "Master byrange" FROM test.byrange_tbl; + +--sync_slave_with_master +connection slave; +show create table test.byrange_tbl; +SELECT count(*) "Slave norm" FROM test.regular_tbl; +SELECT count(*) "Slave bykey" FROM test.bykey_tbl; +SELECT count(*) "Slave byrange" FROM test.byrange_tbl; + +###### CLEAN UP SECTION ############## + +connection master; +DROP PROCEDURE test.proc_norm; +DROP PROCEDURE test.proc_bykey; +DROP PROCEDURE test.proc_byrange; +DROP TABLE test.regular_tbl; +DROP TABLE test.bykey_tbl; +DROP TABLE test.byrange_tbl; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_innodb_bug30888.opt b/mysql-test/suite/rpl/t/rpl_innodb_bug30888.opt new file mode 100644 index 00000000..e6685732 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_innodb_bug30888.opt @@ -0,0 +1 @@ +--innodb-flush-log-at-trx-commit=2 diff --git a/mysql-test/suite/rpl/t/rpl_innodb_bug30888.test b/mysql-test/suite/rpl/t/rpl_innodb_bug30888.test new file mode 100644 index 00000000..9bfce618 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_innodb_bug30888.test @@ -0,0 +1,66 @@ +--source include/have_innodb.inc +--source include/have_binlog_format_mixed_or_row.inc +--source include/master-slave.inc + +# Set the default connection to 'master' + +--vertical_results + +#let $engine_type= 'myisam'; +let $engine_type= 'innodb'; + +######## Creat Table Section ######### +use test; + +eval CREATE TABLE test.regular_tbl(id MEDIUMINT NOT NULL AUTO_INCREMENT, + dt TIMESTAMP, user CHAR(255), uuidf LONGBLOB, + fkid MEDIUMINT, filler VARCHAR(255), + PRIMARY KEY(id)) ENGINE=$engine_type; + +######## Create SPs, Functions, Views and Triggers Section ############## + +delimiter |; +CREATE PROCEDURE test.proc_norm() +BEGIN + DECLARE ins_count INT DEFAULT 1000; + DECLARE del_count INT; + DECLARE cur_user VARCHAR(255); + DECLARE local_uuid VARCHAR(255); + DECLARE local_time TIMESTAMP; + + SET local_time= NOW(); + SET cur_user= CURRENT_USER(); + SET local_uuid= UUID(); + + WHILE ins_count > 0 DO + INSERT INTO test.regular_tbl VALUES (NULL, NOW(), USER() , UUID(), + ins_count,'Going to test MBR for MySQL'); + SET ins_count = ins_count - 1; + END WHILE; + + SELECT MAX(id) FROM test.regular_tbl INTO del_count; + WHILE del_count > 0 DO + DELETE FROM test.regular_tbl WHERE id = del_count; + SET del_count = del_count - 2; + END WHILE; +END| + +delimiter ;| + +############ Finish Setup Section ################### + + +############ Test Section ################### + +CALL test.proc_norm(); + +--sync_slave_with_master + +###### CLEAN UP SECTION ############## + +connection master; +DROP PROCEDURE test.proc_norm; +DROP TABLE test.regular_tbl; + +--source include/rpl_end.inc + diff --git a/mysql-test/suite/rpl/t/rpl_innodb_bug68220.test b/mysql-test/suite/rpl/t/rpl_innodb_bug68220.test new file mode 100644 index 00000000..1e4f40a0 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_innodb_bug68220.test @@ -0,0 +1,53 @@ +--source include/have_innodb.inc +--source include/have_binlog_format_row.inc +--source include/master-slave.inc + +# +# Bug#68220: innodb_rows_updated is misleading on slave when *info_repository=TABLE +# + +# created all the base variables at the beginning at the test +--connection master +select variable_value into @master_rows_read from information_schema.global_status where variable_name = 'innodb_rows_read'; +select variable_value into @master_rows_updated from information_schema.global_status where variable_name = 'innodb_rows_updated'; +select variable_value into @master_rows_deleted from information_schema.global_status where variable_name = 'innodb_rows_deleted'; +select variable_value into @master_rows_inserted from information_schema.global_status where variable_name = 'innodb_rows_inserted'; +select variable_value into @master_system_rows_read from information_schema.global_status where variable_name = 'innodb_system_rows_read'; +select variable_value into @master_system_rows_updated from information_schema.global_status where variable_name = 'innodb_system_rows_updated'; +select variable_value into @master_system_rows_deleted from information_schema.global_status where variable_name = 'innodb_system_rows_deleted'; +select variable_value into @master_system_rows_inserted from information_schema.global_status where variable_name = 'innodb_system_rows_inserted'; + +--connection slave +select variable_value into @slave_rows_read from information_schema.global_status where variable_name = 'innodb_rows_read'; +select variable_value into @slave_rows_updated from information_schema.global_status where variable_name = 'innodb_rows_updated'; +select variable_value into @slave_rows_deleted from information_schema.global_status where variable_name = 'innodb_rows_deleted'; +select variable_value into @slave_rows_inserted from information_schema.global_status where variable_name = 'innodb_rows_inserted'; +select variable_value into @slave_system_rows_read from information_schema.global_status where variable_name = 'innodb_system_rows_read'; +select variable_value into @slave_system_rows_updated from information_schema.global_status where variable_name = 'innodb_system_rows_updated'; +select variable_value into @slave_system_rows_deleted from information_schema.global_status where variable_name = 'innodb_system_rows_deleted'; +select variable_value into @slave_system_rows_inserted from information_schema.global_status where variable_name = 'innodb_system_rows_inserted'; + +--connection master +CREATE DATABASE testdb; +USE testdb; +CREATE TABLE testdb.t1 (i int NOT NULL PRIMARY KEY) ENGINE=InnoDB; + +# insert a row and show counters on master and slave +INSERT INTO testdb.t1 VALUES (1); +--source suite/rpl/include/rpl_innodb_rows_counters.inc + +# update the row and show counters on master and slave +UPDATE t1 SET i=2 WHERE i=1; +--sync_slave_with_master +--source suite/rpl/include/rpl_innodb_rows_counters.inc + +# delete the row and show counters on master and slave +DELETE FROM t1 WHERE i=2; +--source suite/rpl/include/rpl_innodb_rows_counters.inc + +# clean the test +DROP TABLE t1; +DROP DATABASE testdb; +--sync_slave_with_master + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_innodb_mixed_ddl.test b/mysql-test/suite/rpl/t/rpl_innodb_mixed_ddl.test new file mode 100644 index 00000000..5147e67c --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_innodb_mixed_ddl.test @@ -0,0 +1,9 @@ +######################################### +# 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/have_binlog_format_mixed.inc +--source include/have_innodb.inc +let $engine_type= innodb; +--source suite/rpl/include/rpl_mixed_ddl.inc diff --git a/mysql-test/suite/rpl/t/rpl_innodb_mixed_dml.test b/mysql-test/suite/rpl/t/rpl_innodb_mixed_dml.test new file mode 100644 index 00000000..d04ced0f --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_innodb_mixed_dml.test @@ -0,0 +1,9 @@ +######################################### +# 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/have_binlog_format_mixed.inc +--source include/have_innodb.inc +let $engine_type= innodb; +--source suite/rpl/include/rpl_mixed_dml.inc diff --git a/mysql-test/suite/rpl/t/rpl_insert.test b/mysql-test/suite/rpl/t/rpl_insert.test new file mode 100644 index 00000000..48814508 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_insert.test @@ -0,0 +1,45 @@ +--echo # +--echo # Bug#20821: INSERT DELAYED fails to write some rows to binlog +--echo # + +--source include/not_embedded.inc +--source include/not_windows.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; + +--disable_warnings +CREATE SCHEMA IF NOT EXISTS mysqlslap; +USE mysqlslap; +--enable_warnings + +CREATE TABLE t1 (id INT, name VARCHAR(64)) ENGINE=MyISAM; + +sync_slave_with_master; +connection master; + +let $query = "INSERT DELAYED INTO t1 VALUES (1, 'Dr. No'), (2, 'From Russia With Love'), (3, 'Goldfinger'), (4, 'Thunderball'), (5, 'You Only Live Twice')"; +--exec $MYSQL_SLAP --silent --concurrency=5 --iterations=200 --query=$query --delimiter=";" + +# Wait until all the 5000 inserts has been inserted into the table +let $wait_condition= SELECT COUNT(*) = 5000 FROM mysqlslap.t1; +source include/wait_condition.inc; +SELECT COUNT(*) FROM mysqlslap.t1; + +connection slave; +# Wait until all the 5000 inserts has been inserted into the table +let $wait_condition= SELECT COUNT(*) = 5000 FROM mysqlslap.t1; +source include/wait_condition.inc; +SELECT COUNT(*) FROM mysqlslap.t1; + +--echo # +--echo # Cleanup +--echo # + +connection master; +USE test; +DROP SCHEMA mysqlslap; +sync_slave_with_master; +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_insert_delayed.test b/mysql-test/suite/rpl/t/rpl_insert_delayed.test new file mode 100644 index 00000000..6a88899f --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_insert_delayed.test @@ -0,0 +1,5 @@ +--source include/not_embedded.inc +--source include/not_windows.inc +--source include/master-slave.inc +--source include/rpl_insert_delayed.test +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_insert_id.test b/mysql-test/suite/rpl/t/rpl_insert_id.test new file mode 100644 index 00000000..c9d84049 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_insert_id.test @@ -0,0 +1,6 @@ +################################# +# Wrapper for rpl_insert_id.test# +################################# +-- source include/have_innodb.inc +let $engine_type=myisam; +-- source include/rpl_insert_id.test diff --git a/mysql-test/suite/rpl/t/rpl_insert_id_pk.test b/mysql-test/suite/rpl/t/rpl_insert_id_pk.test new file mode 100644 index 00000000..d9ba2a2b --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_insert_id_pk.test @@ -0,0 +1,6 @@ +################################# +# Wrapper for rpl_insert_id.test# +################################# +-- source include/have_innodb.inc +let $engine_type=innodb; +-- source include/rpl_insert_id_pk.test diff --git a/mysql-test/suite/rpl/t/rpl_insert_ignore.test b/mysql-test/suite/rpl/t/rpl_insert_ignore.test new file mode 100644 index 00000000..2940ad16 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_insert_ignore.test @@ -0,0 +1,15 @@ +##################################### +# Wrapper for rpl_insert_ignore.test# +##################################### +-- source include/have_innodb.inc +-- source include/master-slave.inc + +call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT"); + +-- let $engine_type=innodb +-- source include/rpl_insert_ignore.test + +-- let $engine_type=myisam +-- source include/rpl_insert_ignore.test + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_invoked_features-master.opt b/mysql-test/suite/rpl/t/rpl_invoked_features-master.opt new file mode 100644 index 00000000..96f0ce3f --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_invoked_features-master.opt @@ -0,0 +1 @@ +--default-storage-engine=MyISAM diff --git a/mysql-test/suite/rpl/t/rpl_invoked_features.test b/mysql-test/suite/rpl/t/rpl_invoked_features.test new file mode 100644 index 00000000..91391cf8 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_invoked_features.test @@ -0,0 +1,311 @@ +######################################### +# Author: Serge Kozlov skozlov@mysql.com +# Date: 04/25/2007 +# Purpose: Testing Invocation and Invoked +# Features for Replication. +######################################### + +--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; + +# --disable_warnings/--enable_warnings added before/after query +# if one uses UUID() function because we need to avoid warnings +# for STATEMENT binlog format + +# Non-transactional engine +--let $engine_type= myisam + +# Transactional engine +--let $engine_type2= innodb + + +# +# Clean up +# + +USE test; +--disable_warnings +DROP VIEW IF EXISTS v1,v11; +DROP TABLE IF EXISTS t1,t2,t3,t11,t12,t13; +DROP PROCEDURE IF EXISTS p1; +DROP PROCEDURE IF EXISTS p11; +DROP FUNCTION IF EXISTS f1; +DROP FUNCTION IF EXISTS f2; +DROP EVENT IF EXISTS e1; +DROP EVENT IF EXISTS e11; +--enable_warnings + + +# +# Prepare objects (tables etc) +# + +# Create tables + +--echo +eval CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY, b INT, c VARCHAR(64)) ENGINE=$engine_type; +INSERT INTO t1 VALUES (1,1,'1'); +--disable_warnings +INSERT INTO t1 VALUES (2,2,UUID()); +--enable_warnings +eval CREATE TABLE t2 (a INT UNIQUE, b INT, c VARCHAR(64)) ENGINE=$engine_type; +INSERT INTO t2 VALUES (1,1,'1'); +--disable_warnings +INSERT INTO t2 VALUES (2,2,UUID()); +--enable_warnings + +eval CREATE TABLE t11 (a INT NOT NULL PRIMARY KEY, b INT, c VARCHAR(64)) ENGINE=$engine_type2; +INSERT INTO t11 VALUES (1,1,'1'); +--disable_warnings +INSERT INTO t11 VALUES (2,2,UUID()); +--enable_warnings +eval CREATE TABLE t12 (a INT UNIQUE, b INT, c VARCHAR(64)) ENGINE=$engine_type2; +INSERT INTO t12 VALUES (1,1,'1'); +--disable_warnings +INSERT INTO t12 VALUES (2,2,UUID()); +--enable_warnings + +# Create invoked features +--echo +# Create view for tables t1,t11 +CREATE VIEW v1 AS SELECT * FROM t1; +CREATE VIEW v11 AS SELECT * FROM t11; + +# Create triggers for t1,t11 +DELIMITER |; + +CREATE TRIGGER t1_tr1 BEFORE INSERT ON t1 FOR EACH ROW +BEGIN + INSERT INTO t2 VALUES (NEW.a, NEW.b, NEW.c); + INSERT INTO t3 VALUES (NEW.a, NEW.b, NEW.c); +END| + +CREATE TRIGGER t1_tr2 BEFORE UPDATE ON t1 FOR EACH ROW +BEGIN + UPDATE t2 SET c = ''; + UPDATE t3 SET c = ''; +END| + +CREATE TRIGGER t11_tr1 BEFORE INSERT ON t11 FOR EACH ROW +BEGIN + INSERT INTO t12 VALUES (NEW.a, NEW.b, NEW.c); + INSERT INTO t13 VALUES (NEW.a, NEW.b, NEW.c); +END| + +CREATE TRIGGER t11_tr2 BEFORE UPDATE ON t11 FOR EACH ROW +BEGIN + UPDATE t12 SET c = ''; + UPDATE t13 SET c = ''; +END| + +# Create events which will run every 1 sec +CREATE EVENT e1 ON SCHEDULE EVERY 1 SECOND DISABLE DO +BEGIN + ALTER EVENT e1 DISABLE; + CALL p1(10, ''); +END| + +CREATE EVENT e11 ON SCHEDULE EVERY 1 SECOND DISABLE DO +BEGIN + ALTER EVENT e11 DISABLE; + CALL p11(10, ''); +END| + +# Create functions and procedures used for events +CREATE FUNCTION f1 (x INT) RETURNS VARCHAR(64) +BEGIN + IF x > 5 THEN + RETURN UUID(); + END IF; + RETURN ''; +END| + +CREATE FUNCTION f2 (x INT) RETURNS VARCHAR(64) +BEGIN + RETURN f1(x); +END| + +CREATE PROCEDURE p1 (IN x INT, IN y VARCHAR(64)) +BEGIN + INSERT IGNORE INTO t1 VALUES (x,x,y); +END| + +CREATE PROCEDURE p11 (IN x INT, IN y VARCHAR(64)) +BEGIN + INSERT IGNORE INTO t11 VALUES (x,x,y); +END| + +DELIMITER ;| + + +# +# Start test case +# + +# Do some actions for non-transactional tables +--echo +CREATE TABLE t3 SELECT * FROM v1; +INSERT INTO t1 VALUES (3,3,''); +UPDATE t1 SET c='2' WHERE a = 1; +--disable_warnings +INSERT INTO t1 VALUES(4,4,f1(4)); +--enable_warnings +INSERT INTO t1 VALUES (100,100,''); +--disable_warnings +CALL p1(5, UUID()); +--enable_warnings +INSERT INTO t1 VALUES (101,101,''); +--disable_warnings +INSERT INTO t1 VALUES(6,6,f1(6)); +--enable_warnings +INSERT INTO t1 VALUES (102,102,''); +--disable_warnings +INSERT INTO t1 VALUES(7,7,f2(7)); +--enable_warnings +INSERT INTO t1 VALUES (103,103,''); + +# Do some actions for transactional tables +--echo +--disable_warnings +CREATE TABLE t13 SELECT * FROM v11; +INSERT INTO t11 VALUES (3,3,''); +UPDATE t11 SET c='2' WHERE a = 1; +INSERT INTO t11 VALUES(4,4,f1(4)); +INSERT INTO t11 VALUES (100,100,''); +CALL p11(5, UUID()); +INSERT INTO t11 VALUES (101,101,''); +INSERT INTO t11 VALUES(6,6,f1(6)); +INSERT INTO t11 VALUES (102,102,''); +INSERT INTO t11 VALUES(7,7,f2(7)); +INSERT INTO t11 VALUES (103,103,''); +--enable_warnings + +# Scheduler is on +--echo +# Temporally events fire sequentally due Bug#29020. +SET GLOBAL EVENT_SCHEDULER = on; +# Wait while events will executed +ALTER EVENT e1 ENABLE; +let $wait_condition= SELECT COUNT(*) = 1 FROM t1 WHERE t1.a = 10; +--source include/wait_condition.inc +ALTER EVENT e11 ENABLE; +let $wait_condition= SELECT COUNT(*) = 1 FROM t11 WHERE t11.a = 10; +--source include/wait_condition.inc +SET GLOBAL EVENT_SCHEDULER = off; + +# Check original objects +--echo +--sorted_result +SHOW TABLES LIKE 't%'; +--sorted_result +SELECT table_name FROM information_schema.views WHERE table_schema='test'; +--sorted_result +SELECT trigger_name, event_manipulation, event_object_table FROM information_schema.triggers WHERE trigger_schema='test'; +--sorted_result +SELECT routine_type, routine_name FROM information_schema.routines WHERE routine_schema='test'; +--sorted_result +SELECT event_name, status FROM information_schema.events WHERE event_schema='test'; + +# Check original data +--echo +SELECT COUNT(*) FROM t1; +SELECT a,b FROM t1 ORDER BY a; +SELECT COUNT(*) FROM t2; +SELECT a,b FROM t2 ORDER BY a; +SELECT COUNT(*) FROM t3; +SELECT a,b FROM t3 ORDER BY a; +SELECT a,b FROM v1 ORDER BY a; +SELECT COUNT(*) FROM t11; +SELECT a,b FROM t11 ORDER BY a; +SELECT COUNT(*) FROM t12; +SELECT a,b FROM t12 ORDER BY a; +SELECT COUNT(*) FROM t13; +SELECT a,b FROM t13 ORDER BY a; +SELECT a,b FROM v11 ORDER BY a; + +--sync_slave_with_master slave + +# Check replicated objects +--echo +--sorted_result +SHOW TABLES LIKE 't%'; +--sorted_result +SELECT table_name FROM information_schema.views WHERE table_schema='test'; +--sorted_result +SELECT trigger_name, event_manipulation, event_object_table FROM information_schema.triggers WHERE trigger_schema='test'; +--sorted_result +SELECT routine_type, routine_name FROM information_schema.routines WHERE routine_schema='test'; +--sorted_result +SELECT event_name, status FROM information_schema.events WHERE event_schema='test'; + +# Check replicated data +--echo +SELECT COUNT(*) FROM t1; +SELECT a,b FROM t1 ORDER BY a; +SELECT COUNT(*) FROM t2; +SELECT a,b FROM t2 ORDER BY a; +SELECT COUNT(*) FROM t3; +SELECT a,b FROM t3 ORDER BY a; +SELECT a,b FROM v1 ORDER BY a; +SELECT COUNT(*) FROM t11; +SELECT a,b FROM t11 ORDER BY a; +SELECT COUNT(*) FROM t12; +SELECT a,b FROM t12 ORDER BY a; +SELECT COUNT(*) FROM t13; +SELECT a,b FROM t13 ORDER BY a; +SELECT a,b FROM v11 ORDER BY a; + +# Remove UUID() before comparing and sort tables + +--connection master +--echo +UPDATE t1 SET c=''; +UPDATE t2 SET c=''; +UPDATE t3 SET c=''; +--disable_warnings +UPDATE t11 SET c=''; +--enable_warnings +UPDATE t12 SET c=''; +UPDATE t13 SET c=''; + +ALTER TABLE t3 ORDER BY a; +ALTER TABLE t13 ORDER BY a; + +--sync_slave_with_master slave + +# Compare a data from master and slave +--echo +--exec $MYSQL_DUMP --compact --order-by-primary --skip-extended-insert --no-create-info test > $MYSQLTEST_VARDIR/tmp/rpl_invoked_features_master.sql +--exec $MYSQL_DUMP_SLAVE --compact --order-by-primary --skip-extended-insert --no-create-info test > $MYSQLTEST_VARDIR/tmp/rpl_invoked_features_slave.sql +--diff_files $MYSQLTEST_VARDIR/tmp/rpl_invoked_features_master.sql $MYSQLTEST_VARDIR/tmp/rpl_invoked_features_slave.sql + + +# +# Clean up +# + +# Remove dumps +--echo +--remove_file $MYSQLTEST_VARDIR/tmp/rpl_invoked_features_master.sql +--remove_file $MYSQLTEST_VARDIR/tmp/rpl_invoked_features_slave.sql + +# Remove tables,views,procedures,functions +--connection master +--echo +DROP VIEW IF EXISTS v1,v11; +DROP TABLE IF EXISTS t1,t2,t3,t11,t12,t13; +DROP PROCEDURE IF EXISTS p1; +DROP PROCEDURE IF EXISTS p11; +DROP FUNCTION IF EXISTS f1; +DROP FUNCTION IF EXISTS f2; +DROP EVENT IF EXISTS e1; +DROP EVENT IF EXISTS e11; + +--sync_slave_with_master slave + +# End 5.1 test case +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_ip_mix.cnf b/mysql-test/suite/rpl/t/rpl_ip_mix.cnf new file mode 100644 index 00000000..00e2637d --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_ip_mix.cnf @@ -0,0 +1,56 @@ +# Use default setting for mysqld processes +!include include/default_mysqld.cnf +!include include/default_client.cnf + +[mysqld.1] + +# Run the master.sh script before starting this process +#!run-master-sh + +log-bin= master-bin + +loose-innodb + +skip-name-resolve +bind-address= :: + + +[mysqld.2] +# Run the slave.sh script before starting this process +#!run-slave-sh + +# Append -slave.opt file to the list of argument used when +# starting the mysqld +#!use-slave-opt + +log-bin= slave-bin +relay-log= slave-relay-bin + +init-rpl-role= slave +log-slave-updates +master-retry-count= 10 + +# Values reported by slave when it connect to master +# and shows up in SHOW SLAVE STATUS; +report-host= localhost +report-port= @mysqld.2.port +report-user= root + +skip-slave-start +skip-name-resolve +bind-address= 0.0.0.0 + +# Directory where slaves find the dumps generated by "load data" +# on the server. The path need to have constant length otherwise +# test results will vary, thus a relative path is used. +slave-load-tmpdir= ../../tmp + +loose-innodb + +[ENV] +MASTER_MYPORT= @mysqld.1.port +MASTER_MYSOCK= @mysqld.1.socket + +SLAVE_MYPORT= @mysqld.2.port +SLAVE_MYSOCK= @mysqld.2.socket + diff --git a/mysql-test/suite/rpl/t/rpl_ip_mix.test b/mysql-test/suite/rpl/t/rpl_ip_mix.test new file mode 100644 index 00000000..63c5fa92 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_ip_mix.test @@ -0,0 +1,48 @@ +# Test of ipv6 format, especially "change master host=..." +# Options: --skip-name-resolve, master: --bind-address=::, slave: --bind-address=0.0.0.0 +# (see corresponding cnf file) +# +--source include/check_ipv6.inc +--source include/have_log_bin.inc + +let $IPv6= ::1; +--echo #################### IP: $IPv6 ########################### +--source include/rpl_ip_mix.inc + +let $IPv6= ::1/128; +#--echo #################### IP: $IPv6 ########################### +#--source include/rpl_ip_mix.inc + +let $IPv6= 0000:0000:0000:0000:0000:0000:0000:0001; +--echo #################### IP: $IPv6 ########################### +--source include/rpl_ip_mix.inc + +let $IPv6= 0:0:0:0:0:0:0:1; +--echo #################### IP: $IPv6 ########################### +--source include/rpl_ip_mix.inc + +let $IPv6= ::1; +--echo #################### IP: $IPv6 mix ####################### +connect (master,$IPv6,root,,test,$MASTER_MYPORT); +connect (slave,127.0.0.1,root,,test,$SLAVE_MYPORT); +connection master; +reset master; +source include/show_master_status.inc; +connection slave; +reset slave; +let $master_host= query_get_value(SHOW SLAVE STATUS, Master_Host, 1); +--echo Master-Host: $master_host +eval change master to master_host='$IPv6'; +let $master_host= query_get_value(SHOW SLAVE STATUS, Master_Host, 1); +--echo Master-Host: $master_host +eval change master to master_host='127.0.0.1'; +let $master_host= query_get_value(SHOW SLAVE STATUS, Master_Host, 1); +--echo Master-Host: $master_host +eval change master to master_host='0:0:0:0:0:0:0:1'; +let $master_host= query_get_value(SHOW SLAVE STATUS, Master_Host, 1); +--echo Master-Host: $master_host + +# clean up +CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_USER='root'; +--connection slave +reset slave all; diff --git a/mysql-test/suite/rpl/t/rpl_ip_mix2.cnf b/mysql-test/suite/rpl/t/rpl_ip_mix2.cnf new file mode 100644 index 00000000..306df437 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_ip_mix2.cnf @@ -0,0 +1,56 @@ +# Use default setting for mysqld processes +!include include/default_mysqld.cnf +!include include/default_client.cnf + +[mysqld.1] + +# Run the master.sh script before starting this process +#!run-master-sh + +log-bin= master-bin + +loose-innodb + +skip-name-resolve +bind-address= 0.0.0.0 + + +[mysqld.2] +# Run the slave.sh script before starting this process +#!run-slave-sh + +# Append -slave.opt file to the list of argument used when +# starting the mysqld +#!use-slave-opt + +log-bin= slave-bin +relay-log= slave-relay-bin + +init-rpl-role= slave +log-slave-updates +master-retry-count= 10 + +# Values reported by slave when it connect to master +# and shows up in SHOW SLAVE STATUS; +report-host= localhost +report-port= @mysqld.2.port +report-user= root + +skip-slave-start +skip-name-resolve +bind-address= :: + +# Directory where slaves find the dumps generated by "load data" +# on the server. The path need to have constant length otherwise +# test results will vary, thus a relative path is used. +slave-load-tmpdir= ../../tmp + +loose-innodb + +[ENV] +MASTER_MYPORT= @mysqld.1.port +MASTER_MYSOCK= @mysqld.1.socket + +SLAVE_MYPORT= @mysqld.2.port +SLAVE_MYSOCK= @mysqld.2.socket + diff --git a/mysql-test/suite/rpl/t/rpl_ip_mix2.test b/mysql-test/suite/rpl/t/rpl_ip_mix2.test new file mode 100644 index 00000000..3fff54e5 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_ip_mix2.test @@ -0,0 +1,49 @@ +# Test of ipv6 format, especially "change master host=..." +# Options: --skip-name-resolve, master: --bind-address=0.0.0.0, slave: --bind-address=:: +# (see corresponding cnf file) +# +--source include/check_ipv6.inc +--source include/have_log_bin.inc + +let $IPv6= ::1; +--echo #################### IP: $IPv6 ########################### +--source include/rpl_ip_mix2.inc + +let $IPv6= ::1/128; +#--echo #################### IP: $IPv6 ########################### +#--source include/rpl_ip_mix2.inc + +let $IPv6= 0000:0000:0000:0000:0000:0000:0000:0001; +--echo #################### IP: $IPv6 ########################### +--source include/rpl_ip_mix2.inc + +let $IPv6= 0:0:0:0:0:0:0:1; +--echo #################### IP: $IPv6 ########################### +--source include/rpl_ip_mix2.inc + +let $IPv6= ::1; +--echo #################### IP: $IPv6 mix ####################### +connect (master,127.0.0.1,root,,test,$MASTER_MYPORT); +connect (slave,$IPv6,root,,test,$SLAVE_MYPORT); +connection master; +reset master; +source include/show_master_status.inc; +save_master_pos; +connection slave; +reset slave; +let $master_host= query_get_value(SHOW SLAVE STATUS, Master_Host, 1); +--echo Master-Host: $master_host +eval change master to master_host='$IPv6'; +let $master_host= query_get_value(SHOW SLAVE STATUS, Master_Host, 1); +--echo Master-Host: $master_host +eval change master to master_host='127.0.0.1'; +let $master_host= query_get_value(SHOW SLAVE STATUS, Master_Host, 1); +--echo Master-Host: $master_host +eval change master to master_host='0:0:0:0:0:0:0:1'; +let $master_host= query_get_value(SHOW SLAVE STATUS, Master_Host, 1); +--echo Master-Host: $master_host + +# clean up +CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_USER='root'; +connection slave; +reset slave all; diff --git a/mysql-test/suite/rpl/t/rpl_ipv4_as_ipv6.cnf b/mysql-test/suite/rpl/t/rpl_ipv4_as_ipv6.cnf new file mode 100644 index 00000000..b646a408 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_ipv4_as_ipv6.cnf @@ -0,0 +1,56 @@ +# Use default setting for mysqld processes +!include include/default_mysqld.cnf +!include include/default_client.cnf + +[mysqld.1] + +# Run the master.sh script before starting this process +#!run-master-sh + +log-bin= master-bin + +loose-innodb + +skip-name-resolve +bind-address= 0.0.0.0 + + +[mysqld.2] +# Run the slave.sh script before starting this process +#!run-slave-sh + +# Append -slave.opt file to the list of argument used when +# starting the mysqld +#!use-slave-opt + +log-bin= slave-bin +relay-log= slave-relay-bin + +init-rpl-role= slave +log-slave-updates +master-retry-count= 10 + +# Values reported by slave when it connect to master +# and shows up in SHOW SLAVE STATUS; +report-host= localhost +report-port= @mysqld.2.port +report-user= root + +skip-slave-start +skip-name-resolve +bind-address= 0.0.0.0 + +# Directory where slaves find the dumps generated by "load data" +# on the server. The path need to have constant length otherwise +# test results will vary, thus a relative path is used. +slave-load-tmpdir= ../../tmp + +loose-innodb + +[ENV] +MASTER_MYPORT= @mysqld.1.port +MASTER_MYSOCK= @mysqld.1.socket + +SLAVE_MYPORT= @mysqld.2.port +SLAVE_MYSOCK= @mysqld.2.socket + diff --git a/mysql-test/suite/rpl/t/rpl_ipv4_as_ipv6.test b/mysql-test/suite/rpl/t/rpl_ipv4_as_ipv6.test new file mode 100644 index 00000000..d17b32c3 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_ipv4_as_ipv6.test @@ -0,0 +1,63 @@ +# Test of ipv4 (127.0.0.1) in ipv6 format, especially "change master host=..." +# Options: --skip-name-resolve, --bind-address=0.0.0.0 (see corresponding cnf file) +# for master and slave +# +--source include/have_ipv4_mapped.inc +--source include/have_log_bin.inc + +let $IPv6= 127.0.0.1; +--echo #################### IP: $IPv6 ########################### +--source include/rpl_ipv6.inc + +let $IPv6= 0:0:0:0:0:FFFF:127.0.0.1; +--echo #################### IP: $IPv6 ########################### +--source include/rpl_ipv6.inc + +let $IPv6= 0000:0000:0000:0000:0000:FFFF:127.0.0.1; +--echo #################### IP: $IPv6 ########################### +--source include/rpl_ipv6.inc + +let $IPv6= 0:0000:0000:0:0000:FFFF:127.0.0.1; +--echo #################### IP: $IPv6 ########################### +--source include/rpl_ipv6.inc + +let $IPv6= 0::0000:FFFF:127.0.0.1; +--echo #################### IP: $IPv6 ########################### +--source include/rpl_ipv6.inc + +#let $IPv6= 0:0:0:0:0:FFFF:127.0.0.1/96; +#--echo #################### IP: $IPv6 ########################### +#--source include/rpl_ipv6.inc + +let $IPv6= ::FFFF:127.0.0.1; +--echo #################### IP: $IPv6 ########################### +--source include/rpl_ipv6.inc + +#let $IPv6= ::FFFF:127.0.0.1/96; +#--echo #################### IP: $IPv6 ########################### +#--source include/rpl_ipv6.inc + +let $IPv6= ::FFFF:127.0.0.1; +--echo #################### IP: $IPv6 ########################### +connect (master,127.0.0.1,root,,test,$MASTER_MYPORT); +connect (slave,127.0.0.1,root,,test,$SLAVE_MYPORT); +connection master; +reset master; +source include/show_master_status.inc; +save_master_pos; +connection slave; +reset slave; +let $master_host= query_get_value(SHOW SLAVE STATUS, Master_Host, 1); +--echo Master-Host: $master_host +eval change master to master_host='$IPv6'; +let $master_host= query_get_value(SHOW SLAVE STATUS, Master_Host, 1); +--echo Master-Host: $master_host +eval change master to master_host='127.0.0.1'; +let $master_host= query_get_value(SHOW SLAVE STATUS, Master_Host, 1); +--echo Master-Host: $master_host +eval change master to master_host='0:0000:0000:0:0000:FFFF:127.0.0.1'; +let $master_host= query_get_value(SHOW SLAVE STATUS, Master_Host, 1); +--echo Master-Host: $master_host + +# clean up +CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_USER='root'; diff --git a/mysql-test/suite/rpl/t/rpl_ipv6.cnf b/mysql-test/suite/rpl/t/rpl_ipv6.cnf new file mode 100644 index 00000000..c657e7c5 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_ipv6.cnf @@ -0,0 +1,56 @@ +# Use default setting for mysqld processes +!include include/default_mysqld.cnf +!include include/default_client.cnf + +[mysqld.1] + +# Run the master.sh script before starting this process +#!run-master-sh + +log-bin= master-bin + +loose-innodb + +skip-name-resolve +bind-address= :: + + +[mysqld.2] +# Run the slave.sh script before starting this process +#!run-slave-sh + +# Append -slave.opt file to the list of argument used when +# starting the mysqld +#!use-slave-opt + +log-bin= slave-bin +relay-log= slave-relay-bin + +init-rpl-role= slave +log-slave-updates +master-retry-count= 10 + +# Values reported by slave when it connect to master +# and shows up in SHOW SLAVE STATUS; +report-host= localhost +report-port= @mysqld.2.port +report-user= root + +skip-slave-start +skip-name-resolve +bind-address= :: + +# Directory where slaves find the dumps generated by "load data" +# on the server. The path need to have constant length otherwise +# test results will vary, thus a relative path is used. +slave-load-tmpdir= ../../tmp + +loose-innodb + +[ENV] +MASTER_MYPORT= @mysqld.1.port +MASTER_MYSOCK= @mysqld.1.socket + +SLAVE_MYPORT= @mysqld.2.port +SLAVE_MYSOCK= @mysqld.2.socket + diff --git a/mysql-test/suite/rpl/t/rpl_ipv6.test b/mysql-test/suite/rpl/t/rpl_ipv6.test new file mode 100644 index 00000000..f3795832 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_ipv6.test @@ -0,0 +1,49 @@ +# Test of ipv6 format, especially "change master host=..." +# Options: --skip-name-resolve, --bind-address=:: (see corresponding cnf file) +# for master and slave. +# +--source include/check_ipv6.inc +# Can't be tested with windows due to mixed format like 0::0000:FFFF:127.0.0.1 +--source include/not_windows.inc +--source include/have_log_bin.inc + +let $IPv6= ::1; +--echo #################### IP: $IPv6 ########################### +--source include/rpl_ipv6.inc + +let $IPv6= ::1/128; +#--echo #################### IP: $IPv6 ########################### +#--source include/rpl_ipv6.inc + +let $IPv6= 0000:0000:0000:0000:0000:0000:0000:0001; +--echo #################### IP: $IPv6 ########################### +--source include/rpl_ipv6.inc + +let $IPv6= 0:0:0:0:0:0:0:1; +--echo #################### IP: $IPv6 ########################### +--source include/rpl_ipv6.inc + +let $IPv6= ::1; +--echo #################### IP: $IPv6 mix ####################### +connect (master,127.0.0.1,root,,test,$MASTER_MYPORT); +connect (slave,127.0.0.1,root,,test,$SLAVE_MYPORT); +connection master; +reset master; +source include/show_master_status.inc; +save_master_pos; +connection slave; +reset slave; +let $master_host= query_get_value(SHOW SLAVE STATUS, Master_Host, 1); +--echo Master-Host: $master_host +eval change master to master_host='$IPv6'; +let $master_host= query_get_value(SHOW SLAVE STATUS, Master_Host, 1); +--echo Master-Host: $master_host +eval change master to master_host='127.0.0.1'; +let $master_host= query_get_value(SHOW SLAVE STATUS, Master_Host, 1); +--echo Master-Host: $master_host +eval change master to master_host='0:0:0:0:0:0:0:1'; +let $master_host= query_get_value(SHOW SLAVE STATUS, Master_Host, 1); +--echo Master-Host: $master_host + +# clean up +CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_USER='root'; diff --git a/mysql-test/suite/rpl/t/rpl_killed_ddl-master.opt b/mysql-test/suite/rpl/t/rpl_killed_ddl-master.opt new file mode 100644 index 00000000..dcc136e1 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_killed_ddl-master.opt @@ -0,0 +1 @@ +--loose-debug-dbug=d,debug_lock_before_query_log_event diff --git a/mysql-test/suite/rpl/t/rpl_killed_ddl.test b/mysql-test/suite/rpl/t/rpl_killed_ddl.test new file mode 100644 index 00000000..6415b3e8 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_killed_ddl.test @@ -0,0 +1,349 @@ +# ==== Purpose ==== +# +# This test check if DDL statements are correctly binlogged when the +# thread is killed +# +# ==== Method ==== +# +# Start a DDL query and kill it, check if the error code of the binlog +# event is correct. +# +# DDL statements tested: +# CREATE/ALTER/RENAME/DROP DATABASE +# CREATE/ALTER/DROP EVENT +# CREATE/ALTER/DROP FUNCTION +# CREATE/ALTER/DROP PROCEDURE +# CREATE/ALTER/DROP SERVER +# CREATE/ALTER/RENAME/DROP TABLE +# CREATE/DROP TRIGGER +# CREATE/ALTER/DROP VIEW +# +# ==== Bugs ===== +# +# BUG#37145 +# +# ==== TODO ==== +# +# There are some part of the test are temporarily disabled because of +# the following bugs, please enable then once they get fixed: +# - BUG#22473427 +# - Bug#22587377 + +# Temporarily disabled on Windows due to bug #47638 +--source include/not_windows.inc + +source include/have_debug.inc; +source include/master-slave.inc; + +# Use the DBUG_SYNC_POINT to make sure the thread running the DDL is +# waiting before creating the query log event + +let $debug_lock= "debug_lock.before_query_log_event"; + +######## INITIALIZATION ######## + +disable_warnings; +DROP DATABASE IF EXISTS d1; +DROP DATABASE IF EXISTS d2; +DROP DATABASE IF EXISTS d3; +DROP DATABASE IF EXISTS d4; +DROP EVENT IF EXISTS e1; +DROP EVENT IF EXISTS e2; +DROP EVENT IF EXISTS e3; +DROP EVENT IF EXISTS e4; +DROP FUNCTION IF EXISTS f1; +DROP FUNCTION IF EXISTS f2; +DROP FUNCTION IF EXISTS f3; +DROP FUNCTION IF EXISTS f4; +DROP SERVER IF EXISTS s1; +DROP SERVER IF EXISTS s2; +DROP SERVER IF EXISTS s3; +DROP SERVER IF EXISTS s4; +DROP TABLE IF EXISTS t1; +DROP TABLE IF EXISTS t2; +DROP TABLE IF EXISTS t3; +DROP TABLE IF EXISTS t4; +DROP PROCEDURE IF EXISTS p1; +DROP PROCEDURE IF EXISTS p2; +DROP PROCEDURE IF EXISTS p3; +DROP PROCEDURE IF EXISTS p4; +DROP TRIGGER IF EXISTS tr1; +DROP TRIGGER IF EXISTS tr2; +DROP TRIGGER IF EXISTS tr3; +DROP TRIGGER IF EXISTS tr4; +enable_warnings; + +CREATE DATABASE d1; + +CREATE EVENT e1 + ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 DAY + DO INSERT INTO test.t1 VALUES (1); + +CREATE FUNCTION f1 () RETURNS INT DETERMINISTIC + RETURN 1; + +DELIMITER //; +CREATE PROCEDURE p1 (OUT rows_cnt INT) + BEGIN + SELECT COUNT(*) INTO rows_cnt FROM t1; + END; + // +DELIMITER ;// + +CREATE SERVER s1 +FOREIGN DATA WRAPPER mysql +OPTIONS (USER 'user1', HOST '192.168.1.106', DATABASE 'test'); + +CREATE TABLE t1 (a int); +CREATE TABLE t3 (a int); + +DELIMITER //; +CREATE TRIGGER tr1 BEFORE INSERT ON t1 + FOR EACH ROW BEGIN + DELETE FROM t4 WHERE a=NEW.a; + END; + // +DELIMITER ;// + +CREATE INDEX i1 ON t1 (a); + +CREATE VIEW v1 AS SELECT a FROM t1 WHERE a < 100; + +sync_slave_with_master; + +connection master1; +let $connection_name= master1; +let $connection_id= `SELECT CONNECTION_ID()`; + +connection master; + +# This will block the execution of a statement at the DBUG_SYNC_POINT +# with given lock name +if ($debug_lock) +{ + disable_query_log; + disable_result_log; + eval SELECT IS_FREE_LOCK($debug_lock); + eval SELECT GET_LOCK($debug_lock, 10); + eval SELECT IS_FREE_LOCK($debug_lock); + enable_query_log; + enable_result_log; +} + +######## START TEST ######## + +connection master1; + +disable_warnings; + +######## DATABASE ######## + +let $rpl_diff_statement= SELECT schema_name FROM information_schema.schemata + WHERE schema_name LIKE \'d%\' ORDER BY schema_name; + +send CREATE DATABASE d2; +source include/kill_query_and_diff_master_slave.inc; + +send ALTER DATABASE d1 + DEFAULT CHARACTER SET = 'utf8'; +source include/kill_query_and_diff_master_slave.inc; + +send DROP DATABASE d1; +source include/kill_query_and_diff_master_slave.inc; + +send DROP DATABASE IF EXISTS d2; +source include/kill_query_and_diff_master_slave.inc; + +######## EVENT ######## + +let $rpl_diff_statement= SELECT event_name, event_body, execute_at + FROM information_schema.events where event_name like \'e%\' + ORDER BY event_name; + +send CREATE EVENT e2 + ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 DAY + DO INSERT INTO test.t1 VALUES (2); +source include/kill_query_and_diff_master_slave.inc; + +# Temporarily disabled,see Bug#22587377-RPL.RPL_KILLED_DDL +# FAILS SPORADICALLY ON PB2 IN 5.5 AND 5.6 +#send ALTER EVENT e1 +# ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 2 DAY; +#source include/kill_query_and_diff_master_slave.inc; + +send DROP EVENT e1; +source include/kill_query_and_diff_master_slave.inc; + +send DROP EVENT IF EXISTS e2; +source include/kill_query_and_diff_master_slave.inc; + +######## FUNCTION ######## + +--let $rpl_diff_statement= SHOW FUNCTION STATUS LIKE \'f%\' + +send CREATE FUNCTION f2 () RETURNS INT DETERMINISTIC + RETURN 1; +source include/kill_query_and_diff_master_slave.inc; + +send ALTER FUNCTION f1 SQL SECURITY INVOKER; +source include/kill_query_and_diff_master_slave.inc; + +# function f1 probably does not exist because the ALTER query was +# killed +send DROP FUNCTION f1; +source include/kill_query_and_diff_master_slave.inc; + +# function f2 probably does not exist because the CREATE query was +# killed +send DROP FUNCTION IF EXISTS f2; +source include/kill_query_and_diff_master_slave.inc; + +######## PROCEDURE ######## + +--let $rpl_diff_statement= SHOW PROCEDURE STATUS LIKE \'p%\' + +DELIMITER //; +send CREATE PROCEDURE p2 (OUT rows_cnt INT) + BEGIN + SELECT COUNT(*) INTO rows_cnt FROM t2; + END; + // +DELIMITER ;// +source include/kill_query_and_diff_master_slave.inc; + +send ALTER PROCEDURE p1 SQL SECURITY INVOKER COMMENT 'return rows_cnt of table t1'; +source include/kill_query_and_diff_master_slave.inc; + +send DROP PROCEDURE p1; +source include/kill_query_and_diff_master_slave.inc; + +send DROP PROCEDURE IF EXISTS p2; +source include/kill_query_and_diff_master_slave.inc; + +######## TABLE ######## + +--let $rpl_diff_statement= SHOW TABLES LIKE \'t%\' + +send CREATE TABLE t2 (b int); +source include/kill_query_and_diff_master_slave.inc; + +send ALTER TABLE t1 ADD (d int); +source include/kill_query_and_diff_master_slave.inc; + +send RENAME TABLE t3 TO t4; +source include/kill_query_and_diff_master_slave.inc; + +######## INDEX ######## + +--let $rpl_diff_statement= SHOW INDEX FROM t1 + +send CREATE INDEX i2 on t1 (a); +source include/kill_query_and_diff_master_slave.inc; + +send DROP INDEX i1 on t1; +source include/kill_query_and_diff_master_slave.inc; + + +######## SERVER ######## + +# Temporarily disabled, see Bug #22473427 - DROP SERVER FAILS +# AFTER ALTER SERVER+KILL QUERY + +# --let $rpl_diff_statement= SELECT * FROM mysql.servers WHERE Server_name like \'s%\' + +# send CREATE SERVER s2 +# FOREIGN DATA WRAPPER mysql +# OPTIONS (USER 'user2', HOST '192.168.1.108', DATABASE 'test'); +# source include/kill_query_and_diff_master_slave.inc; + +# send ALTER SERVER s1 +# OPTIONS (DATABASE 'test1'); +# source include/kill_query_and_diff_master_slave.inc; + +# send DROP SERVER s1; +# source include/kill_query_and_diff_master_slave.inc; + +# send DROP SERVER IF EXIST s1; +# source include/kill_query_and_diff_master_slave.inc; + +######## TRIGGER ######## + +# Make sure table t4 exists +connection master; +CREATE TABLE IF NOT EXISTS t4 (a int); +connection master1; + +--let $rpl_diff_statement= SHOW TRIGGERS LIKE \'v%\' + +DELIMITER //; +send CREATE TRIGGER tr2 BEFORE INSERT ON t4 + FOR EACH ROW BEGIN + DELETE FROM t1 WHERE a=NEW.a; + END; + // +DELIMITER ;// +source include/kill_query_and_diff_master_slave.inc; + +send DROP TRIGGER tr1; +source include/kill_query_and_diff_master_slave.inc; + +send DROP TRIGGER IF EXISTS tr2; +source include/kill_query_and_diff_master_slave.inc; + +######## VIEW ######## + +--let $rpl_diff_statement= SHOW TABLES LIKE \'v%\' + +send CREATE VIEW v2 AS SELECT a FROM t1 WHERE a > 100; +source include/kill_query_and_diff_master_slave.inc; + +send DROP VIEW v1; +source include/kill_query_and_diff_master_slave.inc; + +send DROP VIEW IF EXISTS v2; +source include/kill_query_and_diff_master_slave.inc; + +######## DROP TABLE ######## + +--let $rpl_diff_statement= SHOW TABLES LIKE \'t%\' + +send DROP TABLE t1; +source include/kill_query_and_diff_master_slave.inc; + +send DROP TABLE IF EXISTS t2; +source include/kill_query_and_diff_master_slave.inc; + +######## CLEAN UP ######## + +connection master; + +# The DROP statements above are killed during the process, so they +# does not make sure the objects are dropped. + +disable_warnings; +DROP DATABASE IF EXISTS d1; +DROP DATABASE IF EXISTS d2; +DROP DATABASE IF EXISTS d3; +DROP DATABASE IF EXISTS d4; +DROP EVENT IF EXISTS e1; +DROP EVENT IF EXISTS e2; +DROP EVENT IF EXISTS e3; +DROP EVENT IF EXISTS e4; +DROP FUNCTION IF EXISTS f1; +DROP FUNCTION IF EXISTS f2; +DROP FUNCTION IF EXISTS f3; +DROP FUNCTION IF EXISTS f4; +DROP SERVER IF EXISTS s1; +DROP SERVER IF EXISTS s2; +DROP SERVER IF EXISTS s3; +DROP SERVER IF EXISTS s4; +DROP TABLE IF EXISTS t1; +DROP TABLE IF EXISTS t2; +DROP TABLE IF EXISTS t3; +DROP TABLE IF EXISTS t4; +DROP PROCEDURE IF EXISTS p1; +DROP PROCEDURE IF EXISTS p2; +DROP PROCEDURE IF EXISTS p3; +DROP PROCEDURE IF EXISTS p4; +enable_warnings; +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_known_bugs_detection-master.opt b/mysql-test/suite/rpl/t/rpl_known_bugs_detection-master.opt new file mode 100644 index 00000000..d4ba386a --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_known_bugs_detection-master.opt @@ -0,0 +1 @@ +--loose-debug=d,pretend_version_50034_in_binlog diff --git a/mysql-test/suite/rpl/t/rpl_known_bugs_detection.test b/mysql-test/suite/rpl/t/rpl_known_bugs_detection.test new file mode 100644 index 00000000..5ea056d5 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_known_bugs_detection.test @@ -0,0 +1,76 @@ +# Test to see if slave can detect certain known bugs present +# on the master, and appropriately decides to stop +# (assuming the bug is fixed in the slave, slave cannot of course +# imitate the bug, so it has to stop). + +call mtr.add_suppression("Unsafe statement written to the binary log using statement format"); + +source include/have_debug.inc; +# because of pretend_version_50034_in_binlog the test can't run with checksum +source include/have_binlog_checksum_off.inc; + +# Currently only statement-based-specific bugs are here +-- source include/have_binlog_format_statement.inc + +source include/master-slave.inc; + +# testcase with INSERT SELECT +connection master; +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) +); +CREATE TABLE t2 ( + field_a int(10) unsigned NOT NULL, + field_b varchar(255) NOT NULL, + field_c varchar(255) NOT NULL +); +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'); +sync_slave_with_master; +connection master; +# Updating table t1 based on values from table t2 +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; +# Inserting new record into t2 +INSERT INTO t2 (field_a, field_b, field_c) VALUES (6, 'f', '6f'); +# Updating t1 again +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; +SELECT * FROM t1; +connection slave; + +# show the error message +#1105 = ER_UNKNOWN_ERROR +--let $slave_sql_errno= 1105 +--let $show_slave_sql_error= 1 +--source include/wait_for_slave_sql_error.inc + +# show that it was not replicated +SELECT * FROM t1; +connection master; + +# clean up +drop table t1, t2; +connection slave; +drop table t1, t2; +# clear error message in sql thread +--source include/stop_slave_io.inc +RESET SLAVE; + +# End of 5.0 tests +--let $rpl_only_running_threads= 1 +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_lcase_tblnames_rewrite_db-slave.opt b/mysql-test/suite/rpl/t/rpl_lcase_tblnames_rewrite_db-slave.opt new file mode 100644 index 00000000..0031a57a --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_lcase_tblnames_rewrite_db-slave.opt @@ -0,0 +1 @@ +--lower-case-table-names=1 "--replicate-rewrite-db=b37656->bug37656" diff --git a/mysql-test/suite/rpl/t/rpl_lcase_tblnames_rewrite_db.test b/mysql-test/suite/rpl/t/rpl_lcase_tblnames_rewrite_db.test new file mode 100644 index 00000000..9c804d82 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_lcase_tblnames_rewrite_db.test @@ -0,0 +1,60 @@ +# BUG#37656 +# +# DESCRIPTION +# +# +# This test case is tests whether replication works properly when +# slave is configured with --lower-case-table-names=1 and replication +# rewrite rules are in effect. +# +# It checks four issues: +# +# (i) master contains capitalized table name +# +# (ii) slave contains lowered case table name +# +# (iii) master and slave tables do not differ +# +-- source include/master-slave.inc +-- source include/not_windows.inc + +SET SQL_LOG_BIN=0; +CREATE DATABASE B37656; +SET SQL_LOG_BIN=1; + +-- connection slave +CREATE DATABASE BUG37656; + +-- echo ### action: show that database on slave is created in lowercase +SHOW DATABASES LIKE '%37656'; + +-- connection master +USE B37656; +CREATE TABLE T1 (a int); +INSERT INTO T1 VALUES (1); + +-- echo ### assertion: master contains capitalized case table +SHOW TABLES; + +-- sync_slave_with_master + +use bug37656; + +-- echo ### assertion: slave contains lowered case table +SHOW TABLES; + +-- echo ### assertion: master and slave tables do not differ +let $diff_tables= master:B37656.T1, slave:bug37656.t1; + +-- source include/diff_tables.inc + +-- connection master +SET SQL_LOG_BIN=0; +DROP DATABASE B37656; +SET SQL_LOG_BIN=1; +SHOW DATABASES LIKE '%37656'; + +-- connection slave +DROP DATABASE BUG37656; +SHOW DATABASES LIKE '%37656'; +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_loaddata.test b/mysql-test/suite/rpl/t/rpl_loaddata.test new file mode 100644 index 00000000..9f0ba95a --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_loaddata.test @@ -0,0 +1,4 @@ +-- source include/have_binlog_format_statement.inc + +let $engine_type=MyISAM; +-- source include/rpl_loaddata.test diff --git a/mysql-test/suite/rpl/t/rpl_loaddata_charset.test b/mysql-test/suite/rpl/t/rpl_loaddata_charset.test new file mode 100644 index 00000000..bb87ee95 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_loaddata_charset.test @@ -0,0 +1,49 @@ +# +# Check LOAD DATA + character sets + replication +# +source include/master-slave.inc; + +# +# Bug#15126 character_set_database is not replicated +# (LOAD DATA INFILE need it) +# +connection master; +create table t1 (a varchar(10) character set utf8); +load data infile '../../std_data/loaddata6.dat' into table t1; +set @@character_set_database=koi8r; +load data infile '../../std_data/loaddata6.dat' into table t1; +set @@character_set_database=DEFAULT; +load data infile '../../std_data/loaddata6.dat' into table t1; +load data infile '../../std_data/loaddata6.dat' into table t1; +load data infile '../../std_data/loaddata6.dat' into table t1; +set @@character_set_database=koi8r; +load data infile '../../std_data/loaddata6.dat' into table t1; +set @@character_set_database=DEFAULT; +load data infile '../../std_data/loaddata6.dat' into table t1 character set koi8r; + +select hex(a) from t1; + +sync_slave_with_master; + +select hex(a) from t1; +connection master; +drop table t1; +sync_slave_with_master; + +# +# Bug#45516 +# When slave SQL thread executing LOAD DATA command, the +# thd->variables.collation_database was not set properly to the default +# database charset +# + +echo -------------test bug#45516------------------; + +# LOAD DATA INFILE +let $LOAD_LOCAL=1; +source include/rpl_loaddata_charset.inc; + +# LOAD DATA LOCAL INFILE +let $LOAD_LOCAL=0; +source include/rpl_loaddata_charset.inc; +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_loaddata_fatal-slave.opt b/mysql-test/suite/rpl/t/rpl_loaddata_fatal-slave.opt new file mode 100644 index 00000000..9c846c79 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_loaddata_fatal-slave.opt @@ -0,0 +1 @@ +--loose-debug=+d,LOAD_DATA_INFILE_has_fatal_error diff --git a/mysql-test/suite/rpl/t/rpl_loaddata_fatal.test b/mysql-test/suite/rpl/t/rpl_loaddata_fatal.test new file mode 100644 index 00000000..4e87d6de --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_loaddata_fatal.test @@ -0,0 +1,27 @@ +source include/have_binlog_format_statement.inc; +source include/have_debug.inc; +source include/master-slave.inc; + +# We do this little stunt to make sure that the slave has started +# before we stop it again. +connection master; +CREATE TABLE t1 (a INT, b INT); +INSERT INTO t1 VALUES (1,10); +sync_slave_with_master; + +# Now we feed it a load data infile, which should make it stop with a +# fatal error. +connection master; +LOAD DATA INFILE '../../std_data/rpl_loaddata.dat' INTO TABLE t1; + +connection slave; +call mtr.add_suppression("Slave SQL.*Fatal error: Not enough memory, error.* 1593"); +let $slave_sql_errno= 1593; +let $show_slave_sql_error= 1; +source include/wait_for_slave_sql_error_and_skip.inc; + +connection master; +DROP TABLE t1; +sync_slave_with_master; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_loaddata_m-master.opt b/mysql-test/suite/rpl/t/rpl_loaddata_m-master.opt new file mode 100644 index 00000000..9d4a8f0b --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_loaddata_m-master.opt @@ -0,0 +1 @@ +--binlog_ignore_db=test diff --git a/mysql-test/suite/rpl/t/rpl_loaddata_m.test b/mysql-test/suite/rpl/t/rpl_loaddata_m.test new file mode 100644 index 00000000..b9dffa3f --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_loaddata_m.test @@ -0,0 +1,51 @@ +# See if the master logs LOAD DATA INFILE correctly when binlog_*_db rules +# exist. +# This is for BUG#1100 (LOAD DATA INFILE was half-logged). +###################################################### +# Change Author: JBM +# Change Date: 2005-12-22 +# Change: Test rewritten to remove show binlog events +# and to test the option better + Cleanup +###################################################### +-- source include/master-slave.inc + +--disable_warnings +drop database if exists mysqltest; +--enable_warnings + +connection master; +# 'test' database should be ignored by the slave +USE test; +CREATE TABLE t1(a INT, b INT, UNIQUE(b)); +LOAD DATA INFILE '../../std_data/rpl_loaddata.dat' INTO TABLE test.t1; +SELECT COUNT(*) FROM test.t1; + +# 'mysqltest' database should NOT be ignored by the slave +CREATE DATABASE mysqltest; +USE mysqltest; +CREATE TABLE t1(a INT, b INT, UNIQUE(b)); +LOAD DATA INFILE '../../std_data/rpl_loaddata.dat' INTO TABLE mysqltest.t1; +SELECT COUNT(*) FROM mysqltest.t1; + +# Now lets check the slave to see what we have :-) +sync_slave_with_master; + +SHOW DATABASES; + +USE test; +SHOW TABLES; + +USE mysqltest; +SHOW TABLES; +SELECT COUNT(*) FROM mysqltest.t1; + +#show binlog events; + +# Cleanup +connection master; +DROP DATABASE mysqltest; +DROP TABLE IF EXISTS test.t1; +sync_slave_with_master; + +# End of test +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_loaddata_map-master.opt b/mysql-test/suite/rpl/t/rpl_loaddata_map-master.opt new file mode 100644 index 00000000..5fdeb855 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_loaddata_map-master.opt @@ -0,0 +1 @@ +--read_buffer_size=12K --max_allowed_packet=8K --net-buffer-length=8K diff --git a/mysql-test/suite/rpl/t/rpl_loaddata_map-slave.opt b/mysql-test/suite/rpl/t/rpl_loaddata_map-slave.opt new file mode 100644 index 00000000..7d404fae --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_loaddata_map-slave.opt @@ -0,0 +1 @@ +--max_allowed_packet=8K --net-buffer-length=8K diff --git a/mysql-test/suite/rpl/t/rpl_loaddata_map.test b/mysql-test/suite/rpl/t/rpl_loaddata_map.test new file mode 100644 index 00000000..655bcc39 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_loaddata_map.test @@ -0,0 +1,72 @@ +# ==== Purpose ==== +# +# check replication of load data with the server parameters subjected to +# read_buffer_size > max_allowed_packet +# +# ==== Implementation ==== +# +# Insert many rows into t1, write t1 to file. +# Load the file into t2. +# See that t2 came out as expected on slave. +# +# ==== Related Bugs ==== +# +# BUG#30435 loading large LOAD DATA INFILE breaks slave with +# read_buffer_size set on master +# BUG#33413 show binlog events fails if binlog has event size of close +# to max_allowed_packet + +source include/have_binlog_format_statement.inc; +source include/master-slave.inc; + + +--echo ==== Create a big file ==== + +# We turn off binlogging to avoid too much noise in the binlog. t1 is +# just an auxiliary construction anyways, it is not needed on the +# slave. + +--disable_query_log +SET @@sql_log_bin= 0; + +let $rows= 5000; +create table t1 (id int not null primary key auto_increment); + +while($rows) +{ + eval insert into t1 values (null); + dec $rows; +} +eval select * into outfile '$MYSQLTEST_VARDIR/tmp/bug30435_5k.txt' from t1; + +DROP TABLE t1; +SET @@sql_log_bin= 1; +--enable_query_log + + +--echo ==== Load our big file into a table ==== +create table t2 (id int not null primary key auto_increment); + +select @@session.read_buffer_size - @@session.max_allowed_packet > 0 ; + +--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +eval load data infile '$MYSQLTEST_VARDIR/tmp/bug30435_5k.txt' into table t2; +select count(*) from t2 /* 5 000 */; + +# the binlog will show fragmented Append_block events +source include/show_binlog_events.inc; + + +--echo ==== Verify results on slave ==== + +sync_slave_with_master; +select count(*) from t2 /* 5 000 */; + + +--echo ==== Clean up ==== + +connection master; +drop table t2; +sync_slave_with_master; +remove_file $MYSQLTEST_VARDIR/tmp/bug30435_5k.txt; +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_loaddata_s-slave.opt b/mysql-test/suite/rpl/t/rpl_loaddata_s-slave.opt new file mode 100644 index 00000000..9d4a8f0b --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_loaddata_s-slave.opt @@ -0,0 +1 @@ +--binlog_ignore_db=test diff --git a/mysql-test/suite/rpl/t/rpl_loaddata_s.test b/mysql-test/suite/rpl/t/rpl_loaddata_s.test new file mode 100644 index 00000000..21167968 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_loaddata_s.test @@ -0,0 +1,27 @@ +# See if the slave logs (in its own binlog, with --log-slave-updates) a +# replicated LOAD DATA INFILE correctly when it has binlog_*_db rules. +# This is for BUG#1100 (LOAD DATA INFILE was half-logged). + +-- source include/have_binlog_format_mixed_or_statement.inc +-- source include/master-slave.inc + +connection slave; +# Not sure why we connect to slave and then try to reset master, but I will leave it [JBM] +reset master; + +connection master; +# 'test' is the current database +create table test.t1(a int, b int, unique(b)); +load data infile '../../std_data/rpl_loaddata.dat' into table test.t1; + +# Test logging on slave; + +sync_slave_with_master; +select count(*) from test.t1; # check that LOAD was replicated +source include/show_binlog_events.inc; + +# Cleanup +connection master; +drop table test.t1; +sync_slave_with_master; +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_loaddata_simple.test b/mysql-test/suite/rpl/t/rpl_loaddata_simple.test new file mode 100644 index 00000000..a09d3fee --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_loaddata_simple.test @@ -0,0 +1,15 @@ +--source include/master-slave.inc + +CREATE TABLE t1 (word CHAR(20) NOT NULL); +LOAD DATA INFILE '../../std_data/words.dat' INTO TABLE t1; +SELECT * FROM t1 ORDER BY word; +sync_slave_with_master; + +# Check +SELECT * FROM t1 ORDER BY word; + +# Cleanup +connection master; +drop table t1; +sync_slave_with_master; +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_loaddata_symlink-master.opt b/mysql-test/suite/rpl/t/rpl_loaddata_symlink-master.opt new file mode 100644 index 00000000..719832a2 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_loaddata_symlink-master.opt @@ -0,0 +1 @@ +--secure-file-priv=$MYSQLTEST_VARDIR/std_data_master_link diff --git a/mysql-test/suite/rpl/t/rpl_loaddata_symlink-master.sh b/mysql-test/suite/rpl/t/rpl_loaddata_symlink-master.sh new file mode 100644 index 00000000..e5bb3e61 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_loaddata_symlink-master.sh @@ -0,0 +1,2 @@ +rm -f $MYSQLTEST_VARDIR/std_data_master_link +ln -s $MYSQLTEST_VARDIR/std_data $MYSQLTEST_VARDIR/std_data_master_link diff --git a/mysql-test/suite/rpl/t/rpl_loaddata_symlink-slave.opt b/mysql-test/suite/rpl/t/rpl_loaddata_symlink-slave.opt new file mode 100644 index 00000000..a112e81a --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_loaddata_symlink-slave.opt @@ -0,0 +1 @@ +--slave-load-tmpdir=$MYSQLTEST_VARDIR/std_data_slave_link diff --git a/mysql-test/suite/rpl/t/rpl_loaddata_symlink-slave.sh b/mysql-test/suite/rpl/t/rpl_loaddata_symlink-slave.sh new file mode 100644 index 00000000..7a0c0bb3 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_loaddata_symlink-slave.sh @@ -0,0 +1,2 @@ +rm -f $MYSQLTEST_VARDIR/std_data_slave_link +ln -s $MYSQLTEST_VARDIR/std_data $MYSQLTEST_VARDIR/std_data_slave_link diff --git a/mysql-test/suite/rpl/t/rpl_loaddata_symlink.test b/mysql-test/suite/rpl/t/rpl_loaddata_symlink.test new file mode 100644 index 00000000..e5ee400d --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_loaddata_symlink.test @@ -0,0 +1,22 @@ +# +# BUG#43913 +# This test verifies if loading data infile will work fine +# if the path of the load data file is a symbolic link. +# +--source include/not_windows.inc +--source include/have_binlog_format_statement.inc +--source include/master-slave.inc + +create table t1(a int not null auto_increment, b int, primary key(a) ); +load data infile '../../std_data/rpl_loaddata.dat' into table t1; +select * from t1; + +sync_slave_with_master; +connection slave; +select * from t1; + +connection master; +drop table t1; +sync_slave_with_master; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_loaddatalocal.test b/mysql-test/suite/rpl/t/rpl_loaddatalocal.test new file mode 100644 index 00000000..71204146 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_loaddatalocal.test @@ -0,0 +1 @@ +--source include/rpl_loaddata_local.inc diff --git a/mysql-test/suite/rpl/t/rpl_loadfile.test b/mysql-test/suite/rpl/t/rpl_loadfile.test new file mode 100644 index 00000000..10fecf1f --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_loadfile.test @@ -0,0 +1 @@ +--source include/rpl_loadfile.inc diff --git a/mysql-test/suite/rpl/t/rpl_locale.test b/mysql-test/suite/rpl/t/rpl_locale.test new file mode 100644 index 00000000..0d6692dd --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_locale.test @@ -0,0 +1,25 @@ +# Replication of locale variables + +source include/master-slave.inc; + +# +# Bug#22645 LC_TIME_NAMES: Statement not replicated +# +connection master; +create table t1 (s1 char(10)); +set lc_time_names= 'de_DE'; +insert into t1 values (date_format('2001-01-01','%W')); +set lc_time_names= 'en_US'; +insert into t1 values (date_format('2001-01-01','%W')); +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 + + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_log_pos.test b/mysql-test/suite/rpl/t/rpl_log_pos.test new file mode 100644 index 00000000..4f63cd32 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_log_pos.test @@ -0,0 +1,57 @@ +########## +# Change Author: JBM +# Change Date: 2006-01-16 +########## + +# +# Testing of setting slave to wrong log position with master_log_pos +# + +# Passes with rbr no problem, removed statement include [jbm] + +source include/master-slave.inc; + +# +# Add an event to get some information into the log we can try to parse +# +let $read_pos= query_get_value(SHOW MASTER STATUS, Position, 1); +create table if not exists t1 (n int); +drop table t1; + +call mtr.add_suppression ("Slave I/O: Got fatal error 1236 from master when reading data from binary"); +call mtr.add_suppression ("Error in Log_event::read_log_event"); +source include/show_master_status.inc; +sync_slave_with_master; +source include/stop_slave.inc; + +let $wrong_log_pos= `SELECT $read_pos+2`; +--replace_result $wrong_log_pos MASTER_LOG_POS +eval change master to master_log_pos=$wrong_log_pos; +start slave; +let $slave_io_errno= 1236; +--let $show_slave_io_error= 1 +# Mask line numbers +--let $slave_io_error_replace= / at [0-9]*/ at XXX/ +source include/wait_for_slave_io_error.inc; +source include/stop_slave_sql.inc; +--enable_warnings + +connection master; +source include/show_master_status.inc; +create table if not exists t1 (n int); +drop table if exists t1; +create table t1 (n int); +insert into t1 values (1),(2),(3); +save_master_pos; +connection slave; +--replace_result 4 MASTER_LOG_POS +change master to master_log_pos=4; +start slave; +sync_with_master; +select * from t1 ORDER BY n; +connection master; +drop table t1; +sync_slave_with_master; + +--echo End of 5.0 tests +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_lost_events_on_rotate.test b/mysql-test/suite/rpl/t/rpl_lost_events_on_rotate.test new file mode 100644 index 00000000..3a4a24e1 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_lost_events_on_rotate.test @@ -0,0 +1,51 @@ +# +# Whenever the mysql_binlog_send method (dump thread) reaches the +# end of file when reading events from the binlog, before checking +# if it should wait for more events, there was a test to check if +# the file being read was still active, i.e, it was the last known +# binlog. However, it was possible that something was written to +# the binary log and then a rotation would happen, after EOF was +# detected and before the check for active was performed. In this +# case, the end of the binary log would not be read by the dump +# thread, and this would cause the slave to lose updates. +# +# This test verifies that the problem has been fixed. It waits +# during this window while forcing a rotation in the binlog. +# +--source include/have_debug.inc +--source include/master-slave.inc + +--connection master + +SET @debug_saved= @@GLOBAL.DEBUG_DBUG; + +CREATE TABLE t (i INT); + +# When reaching the EOF the dump thread will wait before deciding if +# it should move to a new binlong file. +SET GLOBAL DEBUG_DBUG= "d,wait_after_binlog_EOF"; + +INSERT INTO t VALUES (1); + +--sleep 1 + +# A insert and a rotate happens before the decision +INSERT INTO t VALUES (2); +FLUSH LOGS; + +SET DEBUG_SYNC= 'now SIGNAL signal.rotate_finished'; + +--sync_slave_with_master + +# All the rows should be sent to the slave. +--let $diff_tables=master:t,slave:t +--source include/diff_tables.inc + +##Clean up +--connection master + +SET @@GLOBAL.DEBUG_DBUG= @debug_saved; +SET DEBUG_SYNC= 'RESET'; + +DROP TABLE t; +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_manual_change_index_file.test b/mysql-test/suite/rpl/t/rpl_manual_change_index_file.test new file mode 100644 index 00000000..1c087c55 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_manual_change_index_file.test @@ -0,0 +1,108 @@ +source include/master-slave.inc; + +# +# BUG#28421 Infinite loop on slave relay logs +# +# That, manually deleteing one or more entries from 'master-bin.index', will +# cause master infinitely loop to send one binlog file. +# +# Manually changing index file is a illegal action, so when this happen, we +# send a fatal error to slave and close the dump session. + +FLUSH LOGS; +# Now, 2 entries in index file. +# ./master-bin.000001 +# ./master-bin.000002 + +CREATE TABLE t1(c1 INT); +# Now, the current dump file(master-bin.000002) is the second line of index +# file +sync_slave_with_master; +# Now, all events has been replicate to slave. As current dump file +# (master-bin.000002) is the last binlog file, so master is waiting for new +# events. + +connection master; +# Delete './master-bin.000001' from index file. +let $MYSQLD_DATADIR= `SELECT @@DATADIR`; +let TRUNCATE_FILE= $MYSQLD_DATADIR/master-bin.index; +source include/truncate_file.inc; + +if (`SELECT CONVERT(@@VERSION_COMPILE_OS USING latin1) NOT IN ('Win32', 'Win64', 'Windows')`) +{ +append_file $MYSQLD_DATADIR/master-bin.index; +./master-bin.000002 +EOF +sleep 0.00000001; +} + +if (`SELECT CONVERT(@@VERSION_COMPILE_OS USING latin1) IN ('Win32', 'Win64', 'Windows')`) +{ +append_file $MYSQLD_DATADIR/master-bin.index; +.\master-bin.000002 +EOF +sleep 0.00000001; +} + +# Now, only 1 entry in index file. ./master-bin.000002 + +# Generate master-bin.000003, but it is in the second line. +FLUSH LOGS; +# Now, 2 entries in index file. +# ./master-bin.000002 +# ./master-bin.000003 + +# Now, master know that new binlog file(master-bin.000003) has been generated. +# It expects that the new binlog file is in third line of index file, but +# there is no third line in index file. It is so strange that master sends an +# error to slave. +call mtr.add_suppression('Got fatal error 1236 from master when reading data from binary log: .*could not find next log'); +connection slave; +# 1236 = ER_MASTER_FATAL_ERROR_READING_BINLOG +--let $slave_io_errno= 1236 +--let $show_slave_io_error= 1 +# Mask line numbers +--let $slave_io_error_replace= / at [0-9]*/ at XXX/ +--source include/wait_for_slave_io_error.inc + +connection master; + +source include/truncate_file.inc; + +if (`SELECT CONVERT(@@VERSION_COMPILE_OS USING latin1) NOT IN ('Win32', 'Win64', 'Windows')`) +{ +append_file $MYSQLD_DATADIR/master-bin.index; +./master-bin.000001 +./master-bin.000002 +./master-bin.000003 +EOF +sleep 0.00000001; +} + +if (`SELECT CONVERT(@@VERSION_COMPILE_OS USING latin1) IN ('Win32', 'Win64', 'Windows')`) +{ +append_file $MYSQLD_DATADIR/master-bin.index; +.\master-bin.000001 +.\master-bin.000002 +.\master-bin.000003 +EOF +sleep 0.00000001; +} + +CREATE TABLE t2(c1 INT); +FLUSH LOGS; +CREATE TABLE t3(c1 INT); +FLUSH LOGS; +CREATE TABLE t4(c1 INT); + +connection slave; +START SLAVE IO_THREAD; +source include/wait_for_slave_io_to_start.inc; + +connection master; +sync_slave_with_master; +SHOW TABLES; + +connection master; +DROP TABLE t1, t2, t3, t4; +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_many_optimize.test b/mysql-test/suite/rpl/t/rpl_many_optimize.test new file mode 100644 index 00000000..d5e9f69b --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_many_optimize.test @@ -0,0 +1,23 @@ +# Test for BUG#7658 "optimize crashes slave thread (1 in 1000)]" + +source include/master-slave.inc; + +create table t1 (a int not null auto_increment primary key, b int, key(b)); +INSERT INTO t1 (a) VALUES (1),(2); +# Now many OPTIMIZE to test if we crash (BUG#7658) +let $1=300; +disable_query_log; +disable_result_log; +while ($1) +{ + eval OPTIMIZE TABLE t1; + dec $1; +} +enable_result_log; +enable_query_log; +drop table t1; +# Bug was that slave segfaulted after ~ a hundred of OPTIMIZE (or ANALYZE) +sync_slave_with_master; + +# End of 4.1 tests +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_mariadb_slave_capability.test b/mysql-test/suite/rpl/t/rpl_mariadb_slave_capability.test new file mode 100644 index 00000000..046a65f7 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_mariadb_slave_capability.test @@ -0,0 +1,158 @@ +--source include/have_debug.inc +--source include/have_debug_sync.inc +--source include/have_binlog_format_row.inc +--source include/have_innodb.inc +--source include/master-slave.inc + +connection master; +set @old_master_binlog_checksum= @@global.binlog_checksum; + +# MDEV-4475: Cannot replicate to old server when binlog contains +# empty Gtid_list event +# +# Test this by binlog rotation before we log any GTIDs. +connection slave; +--source include/stop_slave.inc +--echo # Test slave with no capability gets dummy event, which is ignored. +set @old_dbug= @@global.debug_dbug; +SET @@global.debug_dbug='+d,simulate_slave_capability_none'; +--source include/start_slave.inc + +connection master; +FLUSH LOGS; +CREATE TABLE t1 (a INT PRIMARY KEY); +INSERT INTO t1 VALUES (0); +sync_slave_with_master; + +connection master; +# Add a dummy event just to have something to sync_slave_with_master on. +# Otherwise we occasionally get different $relaylog_start, depending on +# whether Format_description_log_event was written to relay log or not +# at the time of SHOW SLAVE STATUS. +ALTER TABLE t1 ORDER BY a; +sync_slave_with_master; +connection slave; +let $relaylog_start= query_get_value(SHOW SLAVE STATUS, Relay_Log_Pos, 1); + +connection master; +SET SESSION binlog_annotate_row_events = ON; +let $binlog_file= query_get_value(SHOW MASTER STATUS, File, 1); +let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1); +# A short event, to test when we need to use user_var_event for dummy event. +DELETE FROM t1; +INSERT INTO t1 /* A comment just to make the annotate event sufficiently long that the dummy event will need to get padded with spaces so that we can test that this works */ VALUES(1); +let $binlog_limit= 0, 10; +--source include/show_binlog_events.inc +sync_slave_with_master; +connection slave; + +SELECT * FROM t1; +let $binlog_file= query_get_value(SHOW SLAVE STATUS, Relay_Log_File, 1); +let $binlog_start= $relaylog_start; +let $binlog_limit=0,10; +--source include/show_relaylog_events.inc +set @@global.debug_dbug= @old_dbug; + +--echo # Test dummy event is checksummed correctly. + +connection master; +set @@global.binlog_checksum = CRC32; +--source include/wait_for_binlog_checkpoint.inc +TRUNCATE t1; +let $binlog_file= query_get_value(SHOW MASTER STATUS, File, 1); +let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1); +INSERT INTO t1 VALUES(2); +let $binlog_limit= 0, 5; +--source include/show_binlog_events.inc +sync_slave_with_master; +connection slave; + +SELECT * FROM t1; +let $binlog_file= query_get_value(SHOW SLAVE STATUS, Relay_Log_File, 1); +let $binlog_start= 0; +let $binlog_limit=7,5; +--source include/show_relaylog_events.inc + + +--echo *** MDEV-5754: MySQL 5.5 slaves cannot replicate from MariaDB 10.0 *** + +# The problem was that for a group commit, we get commit id into the +# GTID event, and there was a bug in the code that replaces GTID with +# dummy that failed when commit id was present. +# +# So setup a group commit in InnoDB. + +--connection master +CREATE TABLE t2 (a INT PRIMARY KEY) ENGINE=InnoDB; +let $binlog_file= query_get_value(SHOW MASTER STATUS, File, 1); +let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1); + +--connect (con1,127.0.0.1,root,,test,$SERVER_MYPORT_1,) +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued1 WAIT_FOR master_cont1'; +send INSERT INTO t2 VALUES (1); + +--connection master +SET debug_sync='now WAIT_FOR master_queued1'; + +--connect (con2,127.0.0.1,root,,test,$SERVER_MYPORT_1,) +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued2'; +send INSERT INTO t2 VALUES (2); + +--connection master +SET debug_sync='now WAIT_FOR master_queued2'; +SET debug_sync='now SIGNAL master_cont1'; + +--connection con1 +REAP; +SET debug_sync='RESET'; +--connection con2 +REAP; +SET debug_sync='RESET'; +--connection master +SET debug_sync='RESET'; +let $binlog_limit= 0, 10; +--source include/show_binlog_events.inc +--save_master_pos + +--connection slave +--sync_with_master +SELECT * FROM t2 ORDER BY a; + + +--echo # Test that slave which cannot tolerate holes in binlog stream but +--echo # knows the event does not get dummy event + +--source include/stop_slave.inc +SET @@global.debug_dbug='+d,simulate_slave_capability_old_53'; +--source include/start_slave.inc +connection master; +ALTER TABLE t1 ORDER BY a; +sync_slave_with_master; +connection slave; +let $relaylog_start= query_get_value(SHOW SLAVE STATUS, Relay_Log_Pos, 1); + +connection master; +let $binlog_file= query_get_value(SHOW MASTER STATUS, File, 1); +let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1); +UPDATE t1 SET a = 3; +let $binlog_limit= 0, 5; +--source include/show_binlog_events.inc +sync_slave_with_master; +connection slave; + +SELECT * FROM t1; +let $binlog_file= query_get_value(SHOW SLAVE STATUS, Relay_Log_File, 1); +let $binlog_start= $relaylog_start; +let $binlog_limit=0,5; +--source include/show_relaylog_events.inc + +select @@global.log_slave_updates; +select @@global.replicate_annotate_row_events; + +--echo Clean up. +connection master; +set @@global.binlog_checksum = @old_master_binlog_checksum; +DROP TABLE t1, t2; +sync_slave_with_master; +set @@global.debug_dbug= @old_dbug; +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_mark_optimize_tbl_ddl.test b/mysql-test/suite/rpl/t/rpl_mark_optimize_tbl_ddl.test new file mode 100644 index 00000000..6d66e3fd --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_mark_optimize_tbl_ddl.test @@ -0,0 +1,142 @@ +# ==== Purpose ==== +# +# Test verifies that there is no deadlock or assertion in +# slave_parallel_mode=optimistic configuration while applying admin command +# like 'OPTIMIZE TABLE', 'REPAIR TABLE' and 'ANALYZE TABLE'. +# +# ==== Implementation ==== +# +# Steps: +# 0 - Create a table, execute OPTIMIZE TABLE command on the table followed +# by some DMLS. +# 1 - No assert should happen on slave server. +# 2 - Assert that 'OPTIMIZE TABLE', 'REPAIR TABLE' and 'ANALYZE TABLE' are +# marked as 'DDL' in the binary log. +# +# ==== References ==== +# +# MDEV-17515: GTID Replication in optimistic mode deadlock +# +--source include/have_partition.inc +--source include/have_innodb.inc +--let $rpl_topology=1->2 +--source include/rpl_init.inc + +--connection server_1 +FLUSH TABLES; +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; + +--connection server_2 +SET @save_slave_parallel_threads= @@GLOBAL.slave_parallel_threads; +SET @save_slave_parallel_mode= @@GLOBAL.slave_parallel_mode; +--source include/stop_slave.inc +SET GLOBAL slave_parallel_threads=2; +SET GLOBAL slave_parallel_mode=optimistic; +--source include/start_slave.inc + +--connection server_1 +CREATE TABLE t1(a INT) ENGINE=INNODB; +OPTIMIZE TABLE t1; +INSERT INTO t1 VALUES(1); +INSERT INTO t1 SELECT 1+a FROM t1; +INSERT INTO t1 SELECT 2+a FROM t1; +--save_master_pos + +--connection server_2 +--sync_with_master + +--echo # +--echo # Verify that following admin commands are marked as ddl +--echo # 'OPTIMIZE TABLE', 'REPAIR TABLE' and 'ANALYZE TABLE' +--echo # +--connection server_1 + +OPTIMIZE TABLE t1; +--let optimize_gtid= `SELECT @@GLOBAL.gtid_binlog_pos` + +REPAIR TABLE t1; +--let repair_gtid= `SELECT @@GLOBAL.gtid_binlog_pos` + +ANALYZE TABLE t1; +--let analyze_gtid= `SELECT @@GLOBAL.gtid_binlog_pos` + +let $binlog_file= query_get_value(SHOW MASTER STATUS, File, 1); +FLUSH LOGS; + +--let $MYSQLD_DATADIR= `select @@datadir` +--exec $MYSQL_BINLOG $MYSQLD_DATADIR/$binlog_file > $MYSQLTEST_VARDIR/tmp/mysqlbinlog.out + +--let SEARCH_PATTERN= GTID $optimize_gtid ddl +--let SEARCH_FILE= $MYSQLTEST_VARDIR/tmp/mysqlbinlog.out +--source include/search_pattern_in_file.inc + +--let SEARCH_PATTERN= GTID $repair_gtid ddl +--let SEARCH_FILE= $MYSQLTEST_VARDIR/tmp/mysqlbinlog.out +--source include/search_pattern_in_file.inc + +--let SEARCH_PATTERN= GTID $analyze_gtid ddl +--let SEARCH_FILE= $MYSQLTEST_VARDIR/tmp/mysqlbinlog.out +--source include/search_pattern_in_file.inc + +--echo # +--echo # Clean up +--echo # +DROP TABLE t1; +--remove_file $MYSQLTEST_VARDIR/tmp/mysqlbinlog.out +--save_master_pos + +--connection server_2 +--sync_with_master +FLUSH LOGS; + +--echo # +--echo # Check that ALTER TABLE commands with ANALYZE, OPTIMIZE and REPAIR on +--echo # partitions will be marked as DDL in binary log. +--echo # +--connection server_1 +CREATE TABLE t1(id INT) PARTITION BY RANGE (id) (PARTITION p0 VALUES LESS THAN (100), + PARTITION pmax VALUES LESS THAN (MAXVALUE)); +INSERT INTO t1 VALUES (1), (10), (100), (1000); + +ALTER TABLE t1 ANALYZE PARTITION p0; +--let analyze_gtid= `SELECT @@GLOBAL.gtid_binlog_pos` + +ALTER TABLE t1 OPTIMIZE PARTITION p0; +--let optimize_gtid= `SELECT @@GLOBAL.gtid_binlog_pos` + +ALTER TABLE t1 REPAIR PARTITION p0; +--let repair_gtid= `SELECT @@GLOBAL.gtid_binlog_pos` + +let $binlog_file= query_get_value(SHOW MASTER STATUS, File, 1); +FLUSH LOGS; + +--exec $MYSQL_BINLOG $MYSQLD_DATADIR/$binlog_file > $MYSQLTEST_VARDIR/tmp/mysqlbinlog.out + +--let SEARCH_PATTERN= GTID $analyze_gtid ddl +--let SEARCH_FILE= $MYSQLTEST_VARDIR/tmp/mysqlbinlog.out +--source include/search_pattern_in_file.inc + +--let SEARCH_PATTERN= GTID $optimize_gtid ddl +--let SEARCH_FILE= $MYSQLTEST_VARDIR/tmp/mysqlbinlog.out +--source include/search_pattern_in_file.inc + +--let SEARCH_PATTERN= GTID $repair_gtid ddl +--let SEARCH_FILE= $MYSQLTEST_VARDIR/tmp/mysqlbinlog.out +--source include/search_pattern_in_file.inc + +--echo # +--echo # Clean up +--echo # +DROP TABLE t1; +--remove_file $MYSQLTEST_VARDIR/tmp/mysqlbinlog.out +--save_master_pos + +--connection server_2 +--sync_with_master + +--source include/stop_slave.inc +SET GLOBAL slave_parallel_threads= @save_slave_parallel_threads; +SET GLOBAL slave_parallel_mode= @save_slave_parallel_mode; +--source include/start_slave.inc + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_master_pos_wait.test b/mysql-test/suite/rpl/t/rpl_master_pos_wait.test new file mode 100644 index 00000000..437d8412 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_master_pos_wait.test @@ -0,0 +1,79 @@ +# See if master_pos_wait(,,timeout) +# Terminates with "timeout expired" (-1) +source include/master-slave.inc; +sync_slave_with_master; +# Ask for a master log that has certainly not been reached yet +# timeout= 2 seconds +select master_pos_wait('master-bin.999999',0,2); +explain extended select master_pos_wait('master-bin.999999',0,2); +# Testcase for bug 651 (master_pos_wait() hangs if slave idle and STOP SLAVE). +send select master_pos_wait('master-bin.999999',0); +connection slave1; +stop slave sql_thread; +--source include/wait_for_slave_sql_to_stop.inc +connection slave; +reap; + +# +# bug#26622 MASTER_POS_WAIT does not work as documented +# + +connection master; +echo "*** must be empty ***"; +query_vertical show slave status; + +echo "*** must be NULL ***"; +select master_pos_wait('foo', 98); + +# End of 4.1 tests + + +--echo *** MDEV-7130: MASTER_POS_WAIT(log_name,log_pos,timeout,"connection_name") hangs, does not respect the timeout *** + +--connection slave +--source include/stop_slave.inc +reset slave all; +--replace_result $MASTER_MYPORT MASTER_MYPORT +eval change master 'my_slave' to master_port=$MASTER_MYPORT, master_host='127.0.0.1', master_user='root'; +set default_master_connection = 'my_slave'; +--source include/start_slave.inc + +--echo # Call without connection name -- works (expected -1) +select master_pos_wait('master-bin.000001',1000000,1); + +set default_master_connection = ''; + +--echo # Call for non-existing anonymous connection -- works (expected NULL) +select master_pos_wait('master-bin.000001',1000000,1); + +--echo # Call with a valid connection name -- hangs before MDEV-7130 fix (expected -1) +select master_pos_wait('master-bin.000001',1000000,1,"my_slave"); + +STOP SLAVE 'my_slave'; +RESET SLAVE 'my_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'; + +# End of 10.0 tests + +--echo # +--echo # Start of 10.3 tests +--echo # + +--echo # +--echo # MDEV-13965 Parameter data type control for Item_longlong_func +--echo # + +--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION +SELECT MASTER_POS_WAIT('x',1,ROW(1,1)); +--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION +SELECT MASTER_POS_WAIT('x',1,1,ROW(1,1)); + +--echo # +--echo # End of 10.3 tests +--echo # + + +--let $rpl_only_running_threads= 1 +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_mdev-11092.opt b/mysql-test/suite/rpl/t/rpl_mdev-11092.opt new file mode 100644 index 00000000..7f1d270d --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_mdev-11092.opt @@ -0,0 +1 @@ +--binlog_checksum=1 --binlog-annotate-row-events=1 diff --git a/mysql-test/suite/rpl/t/rpl_mdev-11092.test b/mysql-test/suite/rpl/t/rpl_mdev-11092.test new file mode 100644 index 00000000..782d2480 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_mdev-11092.test @@ -0,0 +1,53 @@ +--source include/have_innodb.inc +--source include/not_embedded.inc +--source include/not_windows.inc +--source include/have_binlog_format_row.inc +--source include/master-slave.inc + +######################################################################################## +call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT"); +call mtr.add_suppression("Slave SQL: The incident LOST_EVENTS occurred on the master. .*"); + +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=MYISAM; + +let $data = `select concat('"', repeat('a',2000), '"')`; + +connection master; + +--disable_query_log +--error ER_BINLOG_ROW_LOGGING_FAILED +eval INSERT INTO t1 (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 + +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 + +DROP TABLE t1; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_mdev10863.test b/mysql-test/suite/rpl/t/rpl_mdev10863.test new file mode 100644 index 00000000..73062df8 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_mdev10863.test @@ -0,0 +1,105 @@ +--source include/have_innodb.inc +--let $rpl_topology=1->2 +--source include/rpl_init.inc + +# Test various aspects of parallel replication. + +--connection server_2 +SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads; +--source include/stop_slave.inc +SET GLOBAL slave_parallel_threads=10; +SET @old_max_relay= @@GLOBAL.max_relay_log_size; +SET GLOBAL max_relay_log_size = 4096; +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 t1 (a int PRIMARY KEY, b VARCHAR(100)) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1, "a"); +--save_master_pos + +--connection server_2 +--sync_with_master + +--echo *** Create a long transaction that will span a relay log file. *** +--connection server_1 + +# Add some transactions in separate domains, that will cause the need to +# have a multi-valued restart position in the relay log for the SQL thread. +SET @old_domain= @@gtid_domain_id; +SET gtid_domain_id=10; +INSERT INTO t1 VALUES (10000, "domain 10"); +SET gtid_domain_id=20; +INSERT INTO t1 VALUES (20000, "domain 20"); +SET gtid_domain_id=@old_domain; + +BEGIN; +--echo [lots of inserts omitted] +--disable_query_log +--let $count = 500 +while ($count) { + eval INSERT INTO t1 VALUES (1000+$count, REPEAT("hulubulu??!?", 8)); + dec $count; +} +--enable_query_log +COMMIT; + +--save_master_pos + +--connection server_2 +--sync_with_master + +--connection server_1 +# Now do another one, to make the inuse_relaylog proceed to somewhere inside +# the first large transaction. + +BEGIN; +--echo [lots of inserts omitted] +--disable_query_log +--let $count = 500 +while ($count) { + eval INSERT INTO t1 VALUES (2000+$count, REPEAT("hulubulu??!?", 8)); + dec $count; +} +--enable_query_log +COMMIT; + +--save_master_pos + +--connection server_2 +--sync_with_master + + +# Stop and restart the SQL thread only. +# The bug was that the SQL thread would restart at the start +# of a relay log file, which could be in the middle of an event group. +# This way, part of that event group could be wrongly re-applied. + +--source include/stop_slave_sql.inc +START SLAVE SQL_THREAD; +--source include/wait_for_slave_to_start.inc + + +--connection server_1 +INSERT INTO t1 VALUES (100000, "More stuffs."); +INSERT INTO t1 VALUES (100001, "And even more"); +--save_master_pos + +--connection server_2 +--sync_with_master +SELECT * FROM t1 WHERE a >= 100000 ORDER BY a; + + +# Clean up. +--connection server_2 +--source include/stop_slave.inc +SET GLOBAL slave_parallel_threads=@old_parallel_threads; +SET GLOBAL max_relay_log_size= @old_max_relay; +--source include/start_slave.inc + +--connection server_1 +ALTER TABLE mysql.gtid_slave_pos ENGINE=Aria; +DROP TABLE t1; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_mdev12179.test b/mysql-test/suite/rpl/t/rpl_mdev12179.test new file mode 100644 index 00000000..e3caccde --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_mdev12179.test @@ -0,0 +1,316 @@ +--source include/have_innodb.inc +--let $rpl_topology=1->2 +--source include/rpl_init.inc + +--connection server_2 +call mtr.add_suppression("The automatically created table.*name may not be entirely in lowercase"); + +--error ER_SLAVE_MUST_STOP +SET GLOBAL gtid_pos_auto_engines="innodb"; +--source include/stop_slave.inc +CHANGE MASTER TO master_use_gtid=slave_pos; + +# Test the @@gtid_pos_auto_engines sysvar. +SELECT @@gtid_pos_auto_engines; +--error ER_INCORRECT_GLOBAL_LOCAL_VAR +SELECT @@SESSION.gtid_pos_auto_engines; +--error ER_WRONG_VALUE_FOR_VAR +SET GLOBAL gtid_pos_auto_engines= NULL; +SET GLOBAL gtid_pos_auto_engines="innodb"; +SELECT @@gtid_pos_auto_engines; +SET GLOBAL gtid_pos_auto_engines="myisam,innodb"; +SELECT @@gtid_pos_auto_engines; +SET GLOBAL gtid_pos_auto_engines="innodb,myisam"; +SELECT @@gtid_pos_auto_engines; +SET GLOBAL gtid_pos_auto_engines="innodb,innodb,myisam,innodb,myisam,myisam,innodb"; +SELECT @@gtid_pos_auto_engines; +SET GLOBAL gtid_pos_auto_engines=DEFAULT; +SELECT @@gtid_pos_auto_engines; +SET GLOBAL gtid_pos_auto_engines=""; +SELECT @@gtid_pos_auto_engines; + +--source include/start_slave.inc + +--connection server_1 +CREATE TABLE t1 (a INT PRIMARY KEY); +INSERT INTO t1 VALUES (1); +SELECT * FROM t1 ORDER BY a; +--save_master_pos + +--connection server_2 +--sync_with_master +SELECT * FROM t1 ORDER BY a; +--source include/stop_slave.inc +SET sql_log_bin=0; +# Reset storage engine for mysql.gtid_slave_pos in case an earlier test +# might have changed it to InnoDB. +ALTER TABLE mysql.gtid_slave_pos ENGINE=Aria; +CREATE TABLE mysql.gtid_slave_pos_innodb LIKE mysql.gtid_slave_pos; +ALTER TABLE mysql.gtid_slave_pos_innodb ENGINE=InnoDB; +INSERT INTO mysql.gtid_slave_pos_innodb SELECT * FROM mysql.gtid_slave_pos; +TRUNCATE mysql.gtid_slave_pos; +SET sql_log_bin=1; + +# Restart the slave mysqld server, and verify that the GTID position is +# read correctly from the new mysql.gtid_slave_pos_innodb table. + +--write_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect +wait +EOF +--shutdown_server +--source include/wait_until_disconnected.inc + +--connection server_1 +INSERT INTO t1 VALUES (2); +INSERT INTO t1 VALUES (3); +SELECT * FROM t1 ORDER BY a; +--source include/save_master_gtid.inc + +# Let the slave mysqld server start again. +# As we are restarting, also take the opportunity to test --gtid-pos-auto-engines +--echo *** Restart server with --gtid-pos-auto-engines=innodb,myisam *** +--append_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect +restart: --skip-slave-start=0 --gtid-pos-auto-engines=innodb,myisam +EOF + +--connection server_2 +--enable_reconnect +--source include/wait_until_connected_again.inc + +--source include/sync_with_master_gtid.inc +SELECT * FROM t1 ORDER BY a; + +--echo *** Verify no new gtid_slave_pos* tables are created *** +SELECT table_name, engine FROM information_schema.tables + WHERE table_schema='mysql' AND table_name LIKE 'gtid_slave_pos%' + ORDER BY table_name; + +SELECT @@gtid_pos_auto_engines; +--source include/stop_slave.inc +SET sql_log_bin=0; +INSERT INTO mysql.gtid_slave_pos_innodb SELECT * FROM mysql.gtid_slave_pos; +DROP TABLE mysql.gtid_slave_pos; +RENAME TABLE mysql.gtid_slave_pos_innodb TO mysql.gtid_slave_pos; +SET sql_log_bin=1; + +--write_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect +wait +EOF +--shutdown_server +--source include/wait_until_disconnected.inc + +--connection server_1 +CREATE TABLE t2 (a INT PRIMARY KEY) ENGINE=InnoDB; +INSERT INTO t1 VALUES (4); +INSERT INTO t2 VALUES (1); +SELECT * FROM t1 ORDER BY a; +SELECT * FROM t2 ORDER BY a; +--source include/save_master_gtid.inc + +--echo *** Restart server with --gtid-pos-auto-engines=myisam,innodb *** +--append_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect +restart: --skip-slave-start=0 --gtid-pos-auto-engines=myisam,innodb +EOF + +--connection server_2 +--enable_reconnect +--source include/wait_until_connected_again.inc + +--source include/sync_with_master_gtid.inc +SELECT * FROM t1 ORDER BY a; +SELECT * FROM t2 ORDER BY a; + +--echo *** Verify that no new gtid_slave_pos* tables are auto-created *** +SELECT table_name, engine FROM information_schema.tables + WHERE table_schema='mysql' AND table_name LIKE 'gtid_slave_pos%' + ORDER BY table_name; + + +--source include/stop_slave.inc +SET sql_log_bin=0; +ALTER TABLE mysql.gtid_slave_pos ENGINE=Aria; +SET sql_log_bin=1; + +--write_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect +wait +EOF +--shutdown_server +--source include/wait_until_disconnected.inc + +--connection server_1 +INSERT INTO t1 VALUES (5); +INSERT INTO t2 VALUES (2); +SELECT * FROM t1 ORDER BY a; +SELECT * FROM t2 ORDER BY a; +--source include/save_master_gtid.inc + +--append_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect +--echo *** Restart server with --gtid-pos-auto-engines=innodb *** +restart: --skip-slave-start=0 --gtid-pos-auto-engines=innodb +EOF + +--connection server_2 +--enable_reconnect +--source include/wait_until_connected_again.inc + +--source include/sync_with_master_gtid.inc +SELECT * FROM t1 ORDER BY a; +SELECT * FROM t2 ORDER BY a; + +--echo *** Verify that mysql.gtid_slave_pos_InnoDB is auto-created *** +# Note, the create happens asynchronously, so wait for it. +let $wait_condition= + SELECT EXISTS (SELECT * FROM information_schema.tables + WHERE table_schema='mysql' AND table_name='gtid_slave_pos_InnoDB'); +--source include/wait_condition.inc +# MDEV-15373 lowercases 'table_name' to satisfy --lower-case-table-names options +SELECT lower(table_name), engine FROM information_schema.tables + WHERE table_schema='mysql' AND table_name LIKE 'gtid_slave_pos%' + ORDER BY table_name; + + +--source include/stop_slave.inc +SET sql_log_bin=0; +INSERT INTO mysql.gtid_slave_pos SELECT * FROM mysql.gtid_slave_pos_InnoDB; +DROP TABLE mysql.gtid_slave_pos_InnoDB; +SET sql_log_bin=1; + +--write_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect +wait +EOF +--shutdown_server +--source include/wait_until_disconnected.inc + +--connection server_1 +INSERT INTO t1 VALUES (6); +INSERT INTO t2 VALUES (3); +SELECT * FROM t1 ORDER BY a; +SELECT * FROM t2 ORDER BY a; +--source include/save_master_gtid.inc + +--echo *** Restart server without --gtid-pos-auto-engines *** +--append_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect +restart: --skip-slave-start=0 +EOF + +--connection server_2 +--enable_reconnect +--source include/wait_until_connected_again.inc + +--source include/sync_with_master_gtid.inc +SELECT * FROM t1 ORDER BY a; +SELECT * FROM t2 ORDER BY a; + +--echo *** Verify that no mysql.gtid_slave_pos* table is auto-created *** +SELECT table_name, engine FROM information_schema.tables + WHERE table_schema='mysql' AND table_name LIKE 'gtid_slave_pos%' + ORDER BY table_name; +SELECT domain_id, max(seq_no) FROM mysql.gtid_slave_pos GROUP BY domain_id; + +--source include/stop_slave.inc +SET GLOBAL gtid_pos_auto_engines="innodb"; +--source include/start_slave.inc + +--connection server_1 +INSERT INTO t1 VALUES (7); +INSERT INTO t2 VALUES (4); +SELECT * FROM t1 ORDER BY a; +SELECT * FROM t2 ORDER BY a; +--source include/save_master_gtid.inc + +--connection server_2 +--source include/sync_with_master_gtid.inc +SELECT * FROM t1 ORDER BY a; +SELECT * FROM t2 ORDER BY a; + +--echo *** Verify that mysql.gtid_slave_pos_InnoDB is auto-created *** +let $wait_condition= + SELECT EXISTS (SELECT * FROM information_schema.tables + WHERE table_schema='mysql' AND table_name='gtid_slave_pos_InnoDB'); +--source include/wait_condition.inc +SELECT lower(table_name), engine FROM information_schema.tables + WHERE table_schema='mysql' AND table_name LIKE 'gtid_slave_pos%' + ORDER BY table_name; +SELECT domain_id, max(seq_no) FROM mysql.gtid_slave_pos GROUP BY domain_id; + +# Check that the auto-created InnoDB table starts being used without +# needing slave restart. The auto-create happens asynchronously, so it +# is non-deterministic when it will start being used. But we can wait +# for it to happen. + +--let $count=300 +--let $done=0 +--let $old_silent= $keep_include_silent +--let $keep_include_silent= 1 +--disable_query_log +while (!$done) +{ + --connection server_1 + INSERT INTO t2(a) SELECT 1+MAX(a) FROM t2; + --source include/save_master_gtid.inc + + --connection server_2 + --source include/sync_with_master_gtid.inc + --let $done=`SELECT COUNT(*) > 0 FROM mysql.gtid_slave_pos_InnoDB` + if (!$done) + { + dec $count; + if (!$count) + { + SELECT * FROM mysql.gtid_slave_pos_InnoDB; + --die Timeout waiting for mysql.gtid_slave_pos_InnoDB to be used + } + real_sleep 0.1; + } +} +--enable_query_log +--let $keep_include_silent=$old_silent +# Note that at this point, the contents of table t2, as well as the GTID +# position, is non-deterministic. + +# MDEV-15373 engine gtid_slave_pos table name disobeys lower-case-table-names +# This snippet verifies that engine gtid_slave_pos table is found, +# its data are up-to-date. +--write_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect +wait +EOF +--connection server_2 +--shutdown_server +--source include/wait_until_disconnected.inc + +--echo *** Restart the slave server to prove 'gtid_slave_pos_innodb' autodiscovery *** +--append_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect +restart: --skip-slave-start=0 +EOF + +--connection server_2 +--enable_reconnect +--source include/wait_until_connected_again.inc +SELECT max(seq_no) FROM mysql.gtid_slave_pos_InnoDB into @seq_no; + +--connection server_1 +INSERT INTO t2(a) SELECT 1+MAX(a) FROM t2; +--source include/save_master_gtid.inc + +--connection server_2 +--source include/sync_with_master_gtid.inc +if (`SELECT max(seq_no) <> @seq_no + 1 FROM mysql.gtid_slave_pos_InnoDB`) +{ + SELECT * FROM mysql.gtid_slave_pos_InnoDB; + --die Inconsistent table +} +# +# end of MDEV-15373 + +#--connection server_2 +--source include/stop_slave.inc +SET GLOBAL gtid_pos_auto_engines=""; +SET sql_log_bin=0; +DROP TABLE mysql.gtid_slave_pos_InnoDB; +SET sql_log_bin=1; +--source include/start_slave.inc + +--connection server_1 +DROP TABLE t1, t2; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_mdev359.test b/mysql-test/suite/rpl/t/rpl_mdev359.test new file mode 100644 index 00000000..5b02ecd7 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_mdev359.test @@ -0,0 +1,31 @@ +--source include/not_embedded.inc +--source include/have_debug_sync.inc +--source include/have_binlog_format_mixed_or_statement.inc +--source include/master-slave.inc + +# MDEV-359: There was a server crash when the code first checks if semisync +# is enabled without lock, then if so takes the lock and tests again. +# If semisync was disabled in-between the first and the second test, an +# assert was incorrectly made that referenced a NULL pointer. +# +# This tests uses debug_sync to pause one thread at the critical point in +# the code, disable the semisync, and then continue the paused thread. + +CREATE TABLE t1 (a INT) ENGINE=MyISAM; +SET GLOBAL rpl_semi_sync_master_enabled = ON; +--connection master1 +SET DEBUG_SYNC = "rpl_semisync_master_commit_trx_before_lock SIGNAL m1_ready WAIT_FOR m1_cont"; +--send +INSERT INTO t1 SELECT * FROM t1; +--connection master +SET DEBUG_SYNC= "now WAIT_FOR m1_ready"; +SET GLOBAL rpl_semi_sync_master_enabled = OFF; +SET DEBUG_SYNC= "now SIGNAL m1_cont"; +--connection master1 +--reap + +connection master; +DROP TABLE t1; +SET DEBUG_SYNC= "RESET"; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_mdev382.test b/mysql-test/suite/rpl/t/rpl_mdev382.test new file mode 100644 index 00000000..093b7b92 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_mdev382.test @@ -0,0 +1,264 @@ +--source include/have_innodb.inc +--source include/have_binlog_format_statement.inc +--source include/master-slave.inc +--source include/not_windows.inc #unix shell escaping used for mysqlbinlog + +# MDEV-382: multiple SQL injections in replication code. + +# Test previous SQL injection attack against binlog for SAVEPOINT statement. +# The test would cause syntax error on slave due to improper quoting of +# the savepoint name. +connection master; +create table t1 (a int primary key) engine=innodb; +create table t2 (a int primary key) engine=myisam; + +begin; +insert into t1 values (1); +SET sql_mode = 'ANSI_QUOTES'; +savepoint `a``; create database couldbebadthingshere; savepoint ``dummy`; +insert into t1 values (2); +insert into t2 values (1); +SET sql_mode = ''; +rollback to savepoint `a``; create database couldbebadthingshere; savepoint ``dummy`; +insert into t1 values (3); +commit; + +--source include/show_binlog_events2.inc + +# This failed due to syntax error in query when the bug was not fixed. +sync_slave_with_master; +connection slave; + +# Test some more combinations of ANSI_QUOTES and sql_quote_show_create +connection master; +let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1); +BEGIN; +insert into t1 values(10); +set sql_mode = 'ANSI_QUOTES'; +set sql_quote_show_create = 1; +savepoint a; +insert into t1 values(11); +savepoint "a""a"; +insert into t1 values(12); +set sql_quote_show_create = 0; +savepoint b; +insert into t1 values(13); +savepoint "b""b"; +insert into t1 values(14); +set sql_mode = ''; +set sql_quote_show_create = 1; +savepoint c; +insert into t1 values(15); +savepoint `c``c`; +insert into t1 values(16); +set sql_quote_show_create = 0; +savepoint d; +insert into t1 values(17); +savepoint `d``d`; +insert into t1 values(18); +COMMIT; +set sql_quote_show_create = 1; + +--source include/show_binlog_events2.inc + +--echo *** Test correct USE statement in SHOW BINLOG EVENTS *** +connection master; +let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1); +set sql_mode = 'ANSI_QUOTES'; +CREATE DATABASE "db1`; select 'oops!'"; +use "db1`; select 'oops!'"; +CREATE TABLE t1 (a INT PRIMARY KEY) engine=MyISAM; +INSERT INTO t1 VALUES (1); +set sql_mode = ''; +INSERT INTO t1 VALUES (2); +set sql_mode = 'ANSI_QUOTES'; +--source include/show_binlog_events2.inc +set sql_mode = ''; +set sql_quote_show_create = 0; +--source include/show_binlog_events2.inc +set sql_quote_show_create = 1; +--source include/show_binlog_events2.inc +DROP TABLE t1; + +use test; + +--echo ***Test LOAD DATA INFILE with various identifiers that need correct quoting *** + +--let $load_file= $MYSQLTEST_VARDIR/tmp/f'le.txt +--write_file $load_file +'fo\\o','bar' +EOF + +use `db1``; select 'oops!'`; +let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1); +set timestamp=1000000000; +CREATE TABLE `t``1` (`a``1` VARCHAR(4) PRIMARY KEY, `b``2` VARCHAR(3), + `c``3` VARCHAR(7)); +--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +eval LOAD DATA INFILE '$MYSQLTEST_VARDIR/tmp/f''le.txt' INTO TABLE `t``1` + FIELDS TERMINATED BY ',' ESCAPED BY '\\\\' ENCLOSED BY '''' + LINES TERMINATED BY '\\n' + (`a``1`, @`b```) SET `b``2` = @`b```, `c``3` = concat('|', "b""a'z", "!"); + +SELECT * FROM `t``1`; +# Also test when code prefixes table name with database. +truncate `t``1`; +use test; +--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +eval LOAD DATA INFILE '$MYSQLTEST_VARDIR/tmp/f''le.txt' + INTO TABLE `db1``; select 'oops!'`.`t``1` + FIELDS TERMINATED BY ',' ESCAPED BY '\\\\' ENCLOSED BY '''' + LINES TERMINATED BY '\\n' + (`a``1`, `b``2`) SET `c``3` = concat('|', "b""a'z", "!"); +SELECT * FROM `db1``; select 'oops!'`.`t``1`; +let $pos2= query_get_value(SHOW MASTER STATUS, Position, 1); + +--source include/show_binlog_events2.inc +let $MYSQLD_DATADIR= `select @@datadir`; +--replace_regex /LOCAL INFILE '.*SQL_LOAD.*' INTO/LOCAL INFILE '' INTO/ +--exec $MYSQL_BINLOG --short-form --start-position=$binlog_start --stop-position=$pos2 $MYSQLD_DATADIR/master-bin.000001 + +sync_slave_with_master; +connection slave; +SELECT * FROM `db1``; select 'oops!'`.`t``1`; +connection master; + +DROP TABLE `db1``; select 'oops!'`.`t``1`; +--remove_file $load_file + +connection master; +drop table t1,t2; + + +--echo *** Test truncation of long SET expression in LOAD DATA *** +CREATE TABLE t1 (a INT PRIMARY KEY, b VARCHAR(1000)); +--let $load_file= $MYSQLTEST_VARDIR/tmp/file.txt +--write_file $load_file +1,X +2,A +EOF + +let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1); +# The bug was that the SET expression was truncated to 256 bytes, so test with +# an expression longer than that. +--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +eval LOAD DATA INFILE '$load_file' INTO TABLE t1 + FIELDS TERMINATED BY ',' + (a, @b) SET b = CONCAT(@b, '| 123456789A123456789B123456789C123456789D123456789E123456789F123456789G123456789H123456789I123456789J123456789K123456789L123456789M123456789N123456789O123456789P123456789Q123456789R123456789123456789T123456789U123456789V123456789W123456789X123456789Y123456789Z123456789|', @b); + +SELECT * FROM t1 ORDER BY a; +--source include/show_binlog_events2.inc + +sync_slave_with_master; +connection slave; +SELECT * FROM t1 ORDER BY a; + +connection master; +--remove_file $load_file +DROP TABLE t1; + + +--echo *** Test user variables whose names require correct quoting *** +use `db1``; select 'oops!'`; +let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1); +CREATE TABLE t1 (a1 BIGINT PRIMARY KEY, a2 BIGINT, a3 BIGINT, a4 BIGINT UNSIGNED, b DOUBLE, c DECIMAL(65,10), d VARCHAR(100)); +INSERT INTO t1 VALUES (-9223372036854775808,42,9223372036854775807,18446744073709551615,-1234560123456789e110, -1234501234567890123456789012345678901234567890123456789.0123456789, REPEAT("x", 100)); +SELECT @`a``1`:=a1, @`a``2`:=a2, @`a``3`:=a3, @`a``4`:=a4, @`b```:=b, @```c`:=c, @```d```:=d FROM t1; +INSERT INTO t1 VALUES (@`a``1`+1, @`a``2`*100, @`a``3`-1, @`a``4`-1, @`b```/2, @```c`, substr(@```d```, 2, 98)); +let $pos2= query_get_value(SHOW MASTER STATUS, Position, 1); + +--source include/show_binlog_events2.inc + +--exec $MYSQL_BINLOG --short-form --start-position=$binlog_start --stop-position=$pos2 $MYSQLD_DATADIR/master-bin.000001 + +sync_slave_with_master; +connection slave; +SELECT * FROM `db1``; select 'oops!'`.t1 ORDER BY a1; + +connection master; +DROP TABLE t1; + +--echo *** Test correct quoting in foreign key error message *** +use `db1``; select 'oops!'`; +CREATE TABLE `t``1` ( `a``` INT PRIMARY KEY) ENGINE=innodb; +CREATE TABLE `t``2` ( `b``` INT PRIMARY KEY, `c``` INT NOT NULL, + FOREIGN KEY fk (`c```) REFERENCES `t``1`(`a```)) ENGINE=innodb; +--error ER_TRUNCATE_ILLEGAL_FK +TRUNCATE `t``1`; +DROP TABLE `t``2`; +DROP TABLE `t``1`; + + +--echo *** Test correct quoting of DELETE FROM statement binlogged for HEAP table that is emptied due to server restart + +# Let's keep the slave stopped during master restart, to avoid any potential +# races between slave reconnect and master restart. +connection slave; +--source include/stop_slave.inc + +connection master; +CREATE TABLE `db1``; select 'oops!'`.`t``1` (`a``` INT PRIMARY KEY) ENGINE=heap; +INSERT INTO `db1``; select 'oops!'`.`t``1` VALUES (1), (2), (5); +SELECT * FROM `db1``; select 'oops!'`.`t``1` ORDER BY 1; + +# Restart the master mysqld. +# This will cause an implicit truncation of the memory-based table, which will +# cause logging of an explicit DELETE FROM to binlog. +--write_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +wait-rpl_mdev382.test +EOF + +--shutdown_server + +--append_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +restart-rpl_mdev382.test +EOF + +connection default; +--enable_reconnect +--source include/wait_until_connected_again.inc +# rpl_end.inc needs to use the connection server_1 +connection server_1; +--enable_reconnect +--source include/wait_until_connected_again.inc +connection master; +--enable_reconnect +--source include/wait_until_connected_again.inc +set timestamp=1000000000; + +--echo # The table should be empty on the master. +let $binlog_file= master-bin.000002; +let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1); +SELECT * FROM `db1``; select 'oops!'`.`t``1`; + +--echo # The DELETE statement should be correctly quoted +--source include/show_binlog_events2.inc + +connection slave; +--source include/start_slave.inc + +connection master; +sync_slave_with_master; +connection slave; +--echo # The table should be empty on the slave also. +SELECT * FROM `db1``; select 'oops!'`.`t``1`; + +connection master; +DROP TABLE `db1``; select 'oops!'`.`t``1`; +sync_slave_with_master; + + +connection master; +use test; +DROP DATABASE `db1``; select 'oops!'`; + +--echo *** Test correct quoting of mysqlbinlog --rewrite-db option *** +CREATE TABLE t1 (a INT PRIMARY KEY); +let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1); +INSERT INTO t1 VALUES(1); +--source include/show_binlog_events2.inc +let $pos2= query_get_value(SHOW MASTER STATUS, Position, 1); +--exec $MYSQL_BINLOG --short-form --start-position=$binlog_start --stop-position=$pos2 --rewrite-db='test->ts`et' $MYSQLD_DATADIR/master-bin.000002 +DROP TABLE t1; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_mdev6020.test b/mysql-test/suite/rpl/t/rpl_mdev6020.test new file mode 100644 index 00000000..ec3fd92f --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_mdev6020.test @@ -0,0 +1,69 @@ +--source include/have_innodb.inc +--source include/have_partition.inc +--source include/have_binlog_format_mixed_or_row.inc +--source include/master-slave.inc +--connection slave +--source include/stop_slave.inc + +--connection master +--let $datadir= `SELECT @@datadir` + +--let $rpl_server_number= 1 +--source include/rpl_stop_server.inc + +--remove_file $datadir/master-bin.000001 +--remove_file $datadir/master-bin.state +--copy_file $MYSQL_TEST_DIR/std_data/mdev6020-mysql-bin.000001 $datadir/master-bin.000001 + +--let $rpl_server_number= 1 +--source include/rpl_start_server.inc + +--source include/wait_until_connected_again.inc + +--connection slave +SET SQL_LOG_BIN=0; +ALTER TABLE mysql.gtid_slave_pos ENGINE = InnoDB; +SET SQL_LOG_BIN=1; +SET @old_engine= @@GLOBAL.default_storage_engine; +SET GLOBAL default_storage_engine=InnoDB; +SET @old_parallel= @@GLOBAL.slave_parallel_threads; +SET GLOBAL slave_parallel_threads=12; +--replace_result $SERVER_MYPORT_1 SERVER_MYPORT_1 +eval CHANGE MASTER TO master_host='127.0.0.1', master_port=$SERVER_MYPORT_1, master_user='root', master_log_file='master-bin.000001', master_log_pos=4; +--source include/start_slave.inc + +--connection master +SET SQL_LOG_BIN=0; +ALTER TABLE mysql.gtid_slave_pos ENGINE = InnoDB; +SET SQL_LOG_BIN=1; +--save_master_pos + +--connection slave +--sync_with_master + +SELECT @@gtid_slave_pos; +CHECKSUM TABLE table0_int_autoinc, table0_key_pk_parts_2_int_autoinc, table100_int_autoinc, table100_key_pk_parts_2_int_autoinc, table10_int_autoinc, table10_key_pk_parts_2_int_autoinc, table1_int_autoinc, table1_key_pk_parts_2_int_autoinc, table2_int_autoinc, table2_key_pk_parts_2_int_autoinc; + +--source include/stop_slave.inc + + +SET GLOBAL default_storage_engine= @old_engine; +SET GLOBAL slave_parallel_threads=@old_parallel; +SET sql_log_bin=0; +DROP TABLE table0_int_autoinc; +DROP TABLE table0_key_pk_parts_2_int_autoinc; +DROP TABLE table100_int_autoinc; +DROP TABLE table100_key_pk_parts_2_int_autoinc; +DROP TABLE table10_int_autoinc; +DROP TABLE table10_key_pk_parts_2_int_autoinc; +DROP TABLE table1_int_autoinc; +DROP TABLE table1_key_pk_parts_2_int_autoinc; +DROP TABLE table2_int_autoinc; +DROP TABLE table2_key_pk_parts_2_int_autoinc; +SET sql_log_bin=1; + +--source include/start_slave.inc + +--connection master + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_mdev6386-slave.opt b/mysql-test/suite/rpl/t/rpl_mdev6386-slave.opt new file mode 100644 index 00000000..a5d959ae --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_mdev6386-slave.opt @@ -0,0 +1 @@ +--disable-log-slave-updates diff --git a/mysql-test/suite/rpl/t/rpl_mdev6386.test b/mysql-test/suite/rpl/t/rpl_mdev6386.test new file mode 100644 index 00000000..e6fb72dc --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_mdev6386.test @@ -0,0 +1,71 @@ +--source include/have_innodb.inc +--source include/master-slave.inc + +--connection master +ALTER TABLE mysql.gtid_slave_pos ENGINE = InnoDB; +CREATE TABLE t1 (a INT PRIMARY KEY, b INT) Engine=InnoDB; +--sync_slave_with_master + +--connection slave +--source include/stop_slave.inc +# Provoke a duplicate key error on replication. +SET sql_log_bin= 0; +CALL mtr.add_suppression("Commit failed due to failure of an earlier commit on which this one depends"); +INSERT INTO t1 VALUES (1, 2); +SET sql_log_bin= 1; +CHANGE MASTER TO master_use_gtid= current_pos; +--echo Contents on slave before: +SELECT * FROM t1 ORDER BY a; + +SET @old_parallel= @@GLOBAL.slave_parallel_threads; +SET GLOBAL slave_parallel_threads=8; + +--connection master + +CREATE TEMPORARY TABLE t2 LIKE t1; +INSERT INTO t2 VALUE (1, 1); +INSERT INTO t2 VALUE (2, 1); +INSERT INTO t2 VALUE (3, 1); +INSERT INTO t2 VALUE (4, 1); +INSERT INTO t2 VALUE (5, 1); +INSERT INTO t1 SELECT * FROM t2; +DROP TEMPORARY TABLE t2; +INSERT INTO t1 VALUE (6, 3); +--source include/save_master_gtid.inc +--echo Contents on master: +SELECT * FROM t1 ORDER BY a; + +--connection slave +START SLAVE; +# The slave will stop with a duplicate key error. +# The bug was 1) that the next DROP TEMPORARY TABLE would be allowed to run +# anyway, and 2) that then record_gtid() would get an error during commit +# (since the prior commit failed), and this error was not correctly handled, +# which caused an assertion about closing tables while a statement was still +# active. +--let $slave_sql_errno=1062 +--source include/wait_for_slave_sql_error.inc + +STOP SLAVE IO_THREAD; +--echo Contents on slave on slave error: +SELECT * FROM t1 ORDER BY a; + +# Resolve the duplicate key error so replication can be resumed. +SET sql_log_bin= 0; +DELETE FROM t1 WHERE a=1; +SET sql_log_bin= 1; + +--source include/start_slave.inc +--source include/sync_with_master_gtid.inc +--echo Contents on slave after: +SELECT * FROM t1 ORDER BY a; + +--connection master +DROP TABLE t1; + +--connection slave +--source include/stop_slave.inc +SET GLOBAL slave_parallel_threads= @old_parallel; +--source include/start_slave.inc + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_mdev8193.test b/mysql-test/suite/rpl/t/rpl_mdev8193.test new file mode 100644 index 00000000..dcad3e5f --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_mdev8193.test @@ -0,0 +1,56 @@ +--source include/have_binlog_format_statement.inc +--source include/master-slave.inc + +--connection slave + +--source include/stop_slave_sql.inc + +--connection master + +CALL mtr.add_suppression("Statement is unsafe because it uses a system function that may return a different value on the slave"); +create table t1 (i int); +insert into t1 values (1),(2); +insert into t1 values (3),(4); +# This sleep() helps trigger the failure more reliably. +insert into t1 select i+20+0*sleep(1) from t1 where i=1; +flush logs; +insert into t1 values (5),(6); +insert into t1 values (7),(8); +insert into t1 values (9),(10); + +--let $master_file = query_get_value(show master status,File,1) +--let $master_pos = query_get_value(show master status,Position,1) + +insert into t1 values (11),(12); +insert into t1 values (13),(14); +insert into t1 values (15),(16); + +--connection slave + +set global slave_parallel_threads = 1; +--replace_result $master_file MASTER_FILE $master_pos MASTER_POS +eval start slave until master_log_file='$master_file', master_log_pos=$master_pos; + +--let $show_statement = SHOW SLAVE STATUS +--let $field = Slave_SQL_Running +--let $condition = = 'No' +--let $wait_timeout = 10 + +--source include/wait_show_condition.inc + +if (`select COUNT(*) > 11 from t1`) +{ + query_vertical show slave status; + SELECT * FROM t1; + die "Wrong number of rows in the table"; +} + +drop table t1; +--source include/stop_slave_io.inc +set global slave_parallel_threads = DEFAULT; + +--connection master +drop table t1; + +--let $rpl_only_running_threads= 1 +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_mdev_17614.test b/mysql-test/suite/rpl/t/rpl_mdev_17614.test new file mode 100644 index 00000000..9b86c8c1 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_mdev_17614.test @@ -0,0 +1,121 @@ +source include/have_debug.inc; +source include/have_innodb.inc; +-- source include/have_binlog_format_statement.inc +source include/master-slave.inc; +# MDEV-17614 +# INSERT on dup key update is replication unsafe +# There can be three case +# 1. 2 unique key, Replication is unsafe. +# 2. 2 unique key , with one auto increment key, Safe to replicate because Innodb will acquire gap lock +# 3. n no of unique keys (n>1) but insert is only in 1 unique key +# 4. 2 unique key , with one auto increment key(but user gives auto inc value), unsafe to replicate + +# Case 1 +call mtr.add_suppression("Unsafe statement written to the binary log using statement format"); +CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY , b INT, +UNIQUE(b), c int) engine=innodb; +sync_slave_with_master; +connection master; +INSERT INTO t1 VALUES (1, 1, 1); +BEGIN; +INSERT INTO t1 VALUES (2, 1, 2) ON DUPLICATE KEY UPDATE b=VALUES(b), c=VALUES(c); + --connection master1 + INSERT INTO t1 VALUES(2, 2, 3) ON DUPLICATE KEY UPDATE b=VALUES(b), c=VALUES(c); +--connection master +COMMIT; +SELECT * FROM t1; +--connection slave +# show the error message +--let $slave_sql_errno= 1062 +--let $show_slave_sql_error= 1 +--source include/wait_for_slave_sql_error.inc +--echo #Different value from server +SELECT * FROM t1; + +# restart replication for the next testcase +stop slave; +--source include/wait_for_slave_to_stop.inc +reset slave; +connection master; +reset master; +drop table t1; +connection slave; +start slave; +--source include/wait_for_slave_to_start.inc +# Case 2 +--connection master +CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY auto_increment, b INT, +UNIQUE(b), c int) engine=innodb; +sync_slave_with_master; +connection master; +INSERT INTO t1 VALUES (default, 1, 1); +BEGIN; +INSERT INTO t1 VALUES (default, 1, 2) ON DUPLICATE KEY UPDATE b=VALUES(b), c=VALUES(c); + --connection master1 + INSERT INTO t1 VALUES(default, 2, 3) ON DUPLICATE KEY UPDATE b=VALUES(b), c=VALUES(c); +--connection master +COMMIT; +SELECT * FROM t1; +--sync_slave_with_master +--echo #same data as master +SELECT * FROM t1; + +connection master; +drop table t1; +--sync_slave_with_master + +# Case 3 +--connection master +CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY, b INT, +UNIQUE(b), c int, d int ) engine=innodb; +sync_slave_with_master; +connection master; +INSERT INTO t1 VALUES (1, 1, 1, 1); +BEGIN; +INSERT INTO t1 VALUES (2, NULL, 2, 2) ON DUPLICATE KEY UPDATE b=VALUES(b), c=VALUES(c); + --connection master1 + INSERT INTO t1 VALUES(3, NULL, 2, 3) ON DUPLICATE KEY UPDATE b=VALUES(b), c=VALUES(c); +--connection master +COMMIT; +SELECT * FROM t1; +--sync_slave_with_master +--echo #same data as master +SELECT * FROM t1; +connection master; +drop table t1; +--sync_slave_with_master + +# Case 4 +--connection master +CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY auto_increment, b INT, +UNIQUE(b), c int) engine=innodb; +sync_slave_with_master; +connection master; +INSERT INTO t1 VALUES (1, 1, 1); +BEGIN; +INSERT INTO t1 VALUES (2, 1, 2) ON DUPLICATE KEY UPDATE b=VALUES(b), c=VALUES(c); + --connection master1 + INSERT INTO t1 VALUES(2, 2, 3) ON DUPLICATE KEY UPDATE b=VALUES(b), c=VALUES(c); +--connection master +COMMIT; +SELECT * FROM t1; +--connection slave +# show the error message +--let $slave_sql_errno= 1062 +--let $show_slave_sql_error= 1 +--source include/wait_for_slave_sql_error.inc +--echo #Different value from server +SELECT * FROM t1; + +# restart replication for the next testcase +stop slave; +--source include/wait_for_slave_to_stop.inc +reset slave; +connection master; +reset master; +drop table t1; +connection slave; +start slave; +--source include/wait_for_slave_to_start.inc + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_misc_functions-slave.sh b/mysql-test/suite/rpl/t/rpl_misc_functions-slave.sh new file mode 100644 index 00000000..8ce79797 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_misc_functions-slave.sh @@ -0,0 +1 @@ +rm -f $MYSQLTEST_VARDIR/master-data/test/rpl_misc_functions.outfile diff --git a/mysql-test/suite/rpl/t/rpl_misc_functions.test b/mysql-test/suite/rpl/t/rpl_misc_functions.test new file mode 100644 index 00000000..7189e5c4 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_misc_functions.test @@ -0,0 +1,127 @@ +# +# Test of replicating some difficult functions +# +source include/master-slave.inc; + +CALL mtr.add_suppression('Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT'); + +create table t1(id int, i int, r1 int, r2 int, p varchar(100)); +insert into t1 values(1, connection_id(), 0, 0, ""); +# don't put rand and password in the same query, to see if they replicate +# independently +# Pure rand test +--disable_warnings +insert into t1 values(2, 0, rand()*1000, rand()*1000, ""); +--enable_warnings +# change the rand suite on the master (we do this because otherwise password() +# benefits from the fact that the above rand() is well replicated : +# it picks the same sequence element, which hides a possible bug in password() replication. +set sql_log_bin=0; +insert into t1 values(6, 0, rand(), rand(), ""); +delete from t1 where id=6; +set sql_log_bin=1; +# Pure password test +insert into t1 values(3, 0, 0, 0, password('does_this_work?')); +# "altogether now" +--disable_warnings +insert into t1 values(4, connection_id(), rand()*1000, rand()*1000, password('does_this_still_work?')); +--enable_warnings +select * into outfile 'rpl_misc_functions.outfile' from t1; +let $MYSQLD_DATADIR= `select @@datadir`; +sync_slave_with_master; +create temporary table t2 like t1; +# read the values from the master table +--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR +eval load data local infile '$MYSQLD_DATADIR/test/rpl_misc_functions.outfile' into table t2; +# compare them with the replica; the SELECT below should return no row +select * from t1, t2 where (t1.id=t2.id) and not(t1.i=t2.i and t1.r1=t2.r1 and t1.r2=t2.r2 and t1.p=t2.p); + +connection master; +drop table t1; + +# End of 4.1 tests + +# +# BUG#25543 test calling rand() multiple times on the master in +# a stored procedure. +# + +--disable_warnings +DROP TABLE IF EXISTS t1; +--enable_warnings + +CREATE TABLE t1 (id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + col_a DOUBLE DEFAULT NULL); + +DELIMITER |; + +# Use a SP that calls rand() multiple times +CREATE PROCEDURE test_replication_sp1() +BEGIN + INSERT INTO t1 (col_a) VALUES (rand()), (rand()); + INSERT INTO t1 (col_a) VALUES (rand()); +END| + +# Use a SP that calls another SP to call rand() multiple times +CREATE PROCEDURE test_replication_sp2() +BEGIN + CALL test_replication_sp1(); + CALL test_replication_sp1(); +END| + +# Use a SF that calls rand() multiple times +CREATE FUNCTION test_replication_sf() RETURNS DOUBLE DETERMINISTIC +BEGIN + RETURN (rand() + rand()); +END| + +DELIMITER ;| + +# Exercise the functions and procedures then compare the results on +# the master to those on the slave. +--disable_warnings +CALL test_replication_sp1(); +CALL test_replication_sp2(); +INSERT INTO t1 (col_a) VALUES (test_replication_sf()); +INSERT INTO t1 (col_a) VALUES (test_replication_sf()); +INSERT INTO t1 (col_a) VALUES (test_replication_sf()); +--enable_warnings + +--sync_slave_with_master + +# Dump table on slave +select * from t1 into outfile "../../tmp/t1_slave.txt"; + +# Load data from slave into temp table on master +connection master; +--disable_warnings +create temporary table t1_slave select * from t1 where 1=0; +--enable_warnings +load data infile '../../tmp/t1_slave.txt' into table t1_slave; +--remove_file $MYSQLTEST_VARDIR/tmp/t1_slave.txt + +# Compare master and slave temp table, use subtraction +# for floating point comparison of "double" +select count(*) into @aux from t1 join t1_slave using (id) +where ABS(t1.col_a - t1_slave.col_a) < 0.0000001 ; +SELECT @aux; +if (`SELECT @aux <> 12 OR @aux IS NULL`) +{ + --echo # ERROR: We expected to get count(*) = 12. + SELECT id, col_a FROM t1; + SELECT id, col_a FROM t1_slave; + --echo # abort + exit; +} + +# Cleanup +connection master; +DROP TABLE t1, t1_slave; +DROP PROCEDURE test_replication_sp1; +DROP PROCEDURE test_replication_sp2; +DROP FUNCTION test_replication_sf; +--remove_file $MYSQLD_DATADIR/test/rpl_misc_functions.outfile +--sync_slave_with_master + + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_mix_found_rows.test b/mysql-test/suite/rpl/t/rpl_mix_found_rows.test new file mode 100644 index 00000000..c8b2eaef --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_mix_found_rows.test @@ -0,0 +1,150 @@ +source include/have_binlog_format_mixed.inc; +source include/master-slave.inc; + +# It is not possible to replicate FOUND_ROWS() using statement-based +# replication, but there is a workaround that stores the result of +# FOUND_ROWS() into a user variable and then replicates this instead. +# +# The purpose of this test case is to test that the workaround works +# properly even when inside stored programs (i.e., stored routines and +# triggers). + +--echo ==== Initialize ==== + +connection master; +CREATE TABLE t1 (a INT); +CREATE TABLE logtbl (sect INT, test INT, count INT); + +INSERT INTO t1 VALUES (1),(2),(3); +INSERT INTO t1 SELECT 2*a+3 FROM t1; +INSERT INTO t1 SELECT 2*a+3 FROM t1; +INSERT INTO t1 SELECT 2*a+3 FROM t1; +INSERT INTO t1 SELECT 2*a+3 FROM t1; +INSERT INTO t1 SELECT 2*a+3 FROM t1; +INSERT INTO t1 SELECT 2*a+3 FROM t1; + +--echo ==== Checking a procedure ==== + +connection master; + +# We will now check some stuff that will not work in statement-based +# replication, but which should cause the binary log to switch to +# row-based logging. + +--delimiter $$ +CREATE PROCEDURE just_log(sect INT, test INT) BEGIN + INSERT INTO logtbl VALUES (sect,test,FOUND_ROWS()); +END $$ +--delimiter ; +sync_slave_with_master; + +connection master1; +SELECT SQL_CALC_FOUND_ROWS * FROM t1 WHERE a > 5 ORDER BY a LIMIT 1; +CALL just_log(1,1); + +connection master; +SELECT SQL_CALC_FOUND_ROWS * FROM t1 WHERE a > 5 ORDER BY a LIMIT 1; +CALL just_log(1,2); + +connection master1; +SELECT SQL_CALC_FOUND_ROWS * FROM t1 WHERE a < 5 ORDER BY a LIMIT 1; +CALL just_log(1,3); +sync_slave_with_master; + +connection master; +SELECT SQL_CALC_FOUND_ROWS * FROM t1 WHERE a > 5 ORDER BY a LIMIT 1; +CALL just_log(1,4); +sync_slave_with_master; + +connection master; +SELECT * FROM logtbl WHERE sect = 1 ORDER BY sect,test; +sync_slave_with_master; +SELECT * FROM logtbl WHERE sect = 1 ORDER BY sect,test; + +--echo ==== Checking a stored function ==== +connection master; +--delimiter $$ +CREATE FUNCTION log_rows(sect INT, test INT) + RETURNS INT +BEGIN + DECLARE found_rows INT; + SELECT FOUND_ROWS() INTO found_rows; + INSERT INTO logtbl VALUES(sect,test,found_rows); + RETURN found_rows; +END $$ +--delimiter ; + +SELECT SQL_CALC_FOUND_ROWS * FROM t1 WHERE a < 5 ORDER BY a LIMIT 1; +SELECT log_rows(2,1), log_rows(2,2); + +CREATE TABLE t2 (a INT, b INT); + +# Trying with referencing FOUND_ROWS() directly in the trigger. + +--delimiter $$ +CREATE TRIGGER t2_tr BEFORE INSERT ON t2 FOR EACH ROW +BEGIN + INSERT INTO logtbl VALUES (NEW.a, NEW.b, FOUND_ROWS()); +END $$ +--delimiter ; + +SELECT SQL_CALC_FOUND_ROWS * FROM t1 WHERE a < 5 ORDER BY a LIMIT 1; +INSERT INTO t2 VALUES (2,3), (2,4); + +# Referencing FOUND_ROWS() indirectly. + +DROP TRIGGER t2_tr; + +--delimiter $$ +CREATE TRIGGER t2_tr BEFORE INSERT ON t2 FOR EACH ROW +BEGIN + DECLARE dummy INT; + SELECT log_rows(NEW.a, NEW.b) INTO dummy; +END $$ +--delimiter ; + +SELECT SQL_CALC_FOUND_ROWS * FROM t1 WHERE a > 5 ORDER BY a LIMIT 1; +INSERT INTO t2 VALUES (2,5), (2,6); + +# Putting FOUND_ROWS() even lower in the call chain. + +connection master; +DROP TRIGGER t2_tr; + +--delimiter $$ +CREATE PROCEDURE log_me_inner(sect INT, test INT) +BEGIN + DECLARE dummy INT; + SELECT log_rows(sect, test) INTO dummy; + SELECT log_rows(sect, test+1) INTO dummy; +END $$ + +CREATE PROCEDURE log_me(sect INT, test INT) +BEGIN + CALL log_me_inner(sect,test); +END $$ +--delimiter ; + +--delimiter $$ +CREATE TRIGGER t2_tr BEFORE INSERT ON t2 FOR EACH ROW +BEGIN + CALL log_me(NEW.a, NEW.b); +END $$ +--delimiter ; + +SELECT SQL_CALC_FOUND_ROWS * FROM t1 WHERE a > 5 ORDER BY a LIMIT 1; +INSERT INTO t2 VALUES (2,5), (2,6); + +SELECT * FROM logtbl WHERE sect = 2 ORDER BY sect,test; +sync_slave_with_master; +SELECT * FROM logtbl WHERE sect = 2 ORDER BY sect,test; + +connection master; +DROP TABLE t1, t2, logtbl; +DROP PROCEDURE just_log; +DROP PROCEDURE log_me; +DROP PROCEDURE log_me_inner; +DROP FUNCTION log_rows; +sync_slave_with_master; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_mixed_binlog_max_cache_size.test b/mysql-test/suite/rpl/t/rpl_mixed_binlog_max_cache_size.test new file mode 100644 index 00000000..c4c89d90 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_mixed_binlog_max_cache_size.test @@ -0,0 +1,8 @@ +--source include/have_innodb.inc +--source include/not_embedded.inc +--source include/not_windows.inc +--source include/have_binlog_format_mixed.inc +--source include/master-slave.inc + +--source include/rpl_binlog_max_cache_size.test +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_mixed_bit_pk.test b/mysql-test/suite/rpl/t/rpl_mixed_bit_pk.test new file mode 100644 index 00000000..226a82de --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_mixed_bit_pk.test @@ -0,0 +1,83 @@ +# +# BUG +# --- +# BUG#39753: Replication failure on MIXED + bit + myisam + no PK +# +# Description +# ----------- +# Simple statements against a bit column cause failure in mixed-mode +# replication. +# +# Implementation is as follows: +# i) A table with two bit fields is created. One of them is a key. +# ii) A record is inserted without specifying the key value. +# iii) The record is deleted using a where clause that matches it. +# iv) repeat i-iii) for bit key that has different size, generating +# different extra bits values +# v) The slave is synchronized with master +# vi) The table is dropped on master and the slave is re-synchronized +# with master. +# +# Step v) made the bug evident before the patch, as the slave would +# fail to find the correspondent row in its database (although it did +# the insert in step ii) ). +# +# Obs +# --- +# This test is based on the "how to repeat" section from the bug report. +# +# + +--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; + +--disable_warnings +# setup + +DROP TABLE IF EXISTS t1,t2,t3,t4,t5,t6,t7,t8; +CREATE TABLE t1 (`bit_key` bit, `bit` bit, key (`bit_key` )) ENGINE=MyISAM; +CREATE TABLE t2 (`bit_key` bit(4), `bit` bit, key (`bit_key` )) ENGINE=MyISAM; +CREATE TABLE t3 (`bit_key` bit(7), `bit` bit, key (`bit_key` )) ENGINE=MyISAM; +CREATE TABLE t4 (`bit_key` bit(8), `bit` bit, key (`bit_key` )) ENGINE=MyISAM; +CREATE TABLE t5 (`bit_key` bit(9), `bit` bit, key (`bit_key` )) ENGINE=MyISAM; +CREATE TABLE t6 (`bit_key` bit(14), `bit` bit, key (`bit_key` )) ENGINE=MyISAM; +CREATE TABLE t7 (`bit_key` bit(15), `bit` bit, key (`bit_key` )) ENGINE=MyISAM; +CREATE TABLE t8 (`bit_key` bit(16), `bit` bit, key (`bit_key` )) ENGINE=MyISAM; + +# insert and delete +INSERT INTO `t1` ( `bit` ) VALUES ( 0 ); +DELETE FROM `t1` WHERE `bit` < 2 LIMIT 4; + +INSERT INTO `t2` ( `bit` ) VALUES ( 0 ); +DELETE FROM `t2` WHERE `bit` < 2 LIMIT 4; + +INSERT INTO `t3` ( `bit` ) VALUES ( 0 ); +DELETE FROM `t3` WHERE `bit` < 2 LIMIT 4; + +INSERT INTO `t4` ( `bit` ) VALUES ( 0 ); +DELETE FROM `t4` WHERE `bit` < 2 LIMIT 4; + +INSERT INTO `t5` ( `bit` ) VALUES ( 0 ); +DELETE FROM `t5` WHERE `bit` < 2 LIMIT 4; + +INSERT INTO `t6` ( `bit` ) VALUES ( 0 ); +DELETE FROM `t6` WHERE `bit` < 2 LIMIT 4; + +INSERT INTO `t7` ( `bit` ) VALUES ( 0 ); +DELETE FROM `t7` WHERE `bit` < 2 LIMIT 4; + +INSERT INTO `t8` ( `bit` ) VALUES ( 0 ); +DELETE FROM `t8` WHERE `bit` < 2 LIMIT 4; + + +--enable_warnings +sync_slave_with_master; + +# clean up +connection master; +DROP TABLE t1, t2, t3, t4, t5, t6, t7, t8; +sync_slave_with_master; +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_mixed_ddl_dml.test b/mysql-test/suite/rpl/t/rpl_mixed_ddl_dml.test new file mode 100644 index 00000000..f4a1615a --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_mixed_ddl_dml.test @@ -0,0 +1,51 @@ +# Mixed DDL-DML (CREATE ... SELECT ...) statements can only be +# replicated properly in statement-based replication. +# Currently statement based due to bug 12345 +--source include/have_binlog_format_mixed_or_statement.inc + +source include/master-slave.inc; + +# Test replication of auto_increment + +create table t1 (n int auto_increment primary key); +set insert_id = 2000; +insert into t1 values (NULL),(NULL),(NULL); +sync_slave_with_master; +select * from t1; +connection master; +--replace_result $SLAVE_MYPORT 9999 +show slave hosts; +drop table t1; +sync_slave_with_master; +stop slave; +--source include/wait_for_slave_to_stop.inc +connection master; + +# Test replication of timestamp + +create table t2(id int auto_increment primary key, created datetime); +SET TIME_ZONE= '+03:00'; +set timestamp=12345; +insert into t2 set created=now(); +select * from t2; + +# Test replication of CREATE .. LIKE (Bug #2557) + +create table t3 like t2; +create temporary table t4 like t2; +create table t5 select * from t4; +save_master_pos; +connection slave; +start slave; +--source include/wait_for_slave_to_start.inc +sync_with_master; +select * from t2; +show create table t3; +show create table t5; +connection master; +drop table t2,t3,t5; +drop temporary table t4; +sync_slave_with_master; + +# End of 4.1 tests +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_mixed_drop_create_temp_table.test b/mysql-test/suite/rpl/t/rpl_mixed_drop_create_temp_table.test new file mode 100644 index 00000000..e707bb99 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_mixed_drop_create_temp_table.test @@ -0,0 +1,12 @@ +################################################################################### +# This test cases evaluates the mixture of non-transactional and transcational +# tables. Specifically when drop temporary tables and create temporary tables +# are used. +################################################################################### +--source include/big_test.inc +--source include/have_binlog_format_mixed.inc +--source include/have_innodb.inc +--source include/master-slave.inc + +--source include/rpl_drop_create_temp_table.test +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_mixed_implicit_commit_binlog.test b/mysql-test/suite/rpl/t/rpl_mixed_implicit_commit_binlog.test new file mode 100644 index 00000000..8e40295e --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_mixed_implicit_commit_binlog.test @@ -0,0 +1,12 @@ +################################################################################ +# Check file include/rpl_implicit_commit_binlog.test +################################################################################ +--source include/have_udf.inc +--source include/have_binlog_format_mixed.inc +--source include/have_innodb.inc +--source include/master-slave.inc + +--let $engine=Innodb +set session default_storage_engine=innodb; +--source include/rpl_implicit_commit_binlog.test +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_mixed_mixing_engines.test b/mysql-test/suite/rpl/t/rpl_mixed_mixing_engines.test new file mode 100644 index 00000000..1df53270 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_mixed_mixing_engines.test @@ -0,0 +1,12 @@ +################################################################################### +# This test cases evaluates the mixture of non-transactional and transcational +# tables. For further details, please, read WL#2687 and WL#5072. +################################################################################### +--source include/have_binlog_format_mixed.inc +--source include/have_innodb.inc +--source include/master-slave.inc + +let $engine_type=Innodb; +let $database_name=test; +--source include/rpl_mixing_engines.test +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_mixed_row_innodb-master.opt b/mysql-test/suite/rpl/t/rpl_mixed_row_innodb-master.opt new file mode 100644 index 00000000..96f0ce3f --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_mixed_row_innodb-master.opt @@ -0,0 +1 @@ +--default-storage-engine=MyISAM diff --git a/mysql-test/suite/rpl/t/rpl_multi_delete-slave.opt b/mysql-test/suite/rpl/t/rpl_multi_delete-slave.opt new file mode 100644 index 00000000..c98fe0b0 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_multi_delete-slave.opt @@ -0,0 +1 @@ +--replicate-wild-do-table=test.% diff --git a/mysql-test/suite/rpl/t/rpl_multi_delete.test b/mysql-test/suite/rpl/t/rpl_multi_delete.test new file mode 100644 index 00000000..80acf9c8 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_multi_delete.test @@ -0,0 +1,25 @@ +source include/master-slave.inc; +create table t1 (a int primary key); +create table t2 (a int); + +insert into t1 values (1); +insert into t2 values (1); + + +delete t1.* from t1, t2 where t1.a = t2.a; + +save_master_pos; +select * from t1; +select * from t2; + +connection slave; +sync_with_master; +select * from t1; +select * from t2; + +connection master; +drop table t1,t2; +sync_slave_with_master; + +# End of 4.1 tests +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_multi_delete2-slave.opt b/mysql-test/suite/rpl/t/rpl_multi_delete2-slave.opt new file mode 100644 index 00000000..0febb289 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_multi_delete2-slave.opt @@ -0,0 +1 @@ +"--replicate-rewrite-db=mysqltest_from->mysqltest_to" --replicate-do-table=mysqltest_to.a diff --git a/mysql-test/suite/rpl/t/rpl_multi_delete2.test b/mysql-test/suite/rpl/t/rpl_multi_delete2.test new file mode 100644 index 00000000..7dc7ca41 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_multi_delete2.test @@ -0,0 +1,67 @@ +#multi delete replication bugs + + +source include/master-slave.inc; + +#BUG#11139 - improper wild-table and table rules +#checking for multi deletes with an alias + +connection master; +set sql_log_bin=0; +create database mysqltest_from; +set sql_log_bin=1; + +connection slave; +create database mysqltest_to; + + +connection master; +use mysqltest_from; +--disable_warnings +drop table if exists a; +--enable_warnings +CREATE TABLE a (i INT); +INSERT INTO a VALUES(1); +DELETE alias FROM a alias WHERE alias.i=1; +SELECT * FROM a; +insert into a values(2),(3); +delete alias FROM a alias where alias.i=2; +select * from a; +sync_slave_with_master; + +use mysqltest_to; +select * from a; + +# BUG#3461 +connection master; +create table t1 (a int primary key); +create table t2 (a int); + +insert into t1 values (1); +insert into t2 values (1); + +delete t1.* from t1, t2 where t1.a = t2.a; + +save_master_pos; +select * from t1; +select * from t2; + +connection slave; +# BUG#3461 would cause sync to fail +sync_with_master; +error 1146; +select * from t1; +error 1146; +select * from t2; + +# cleanup +connection master; +set sql_log_bin=0; +drop database mysqltest_from; +set sql_log_bin=1; +connection slave; +drop database mysqltest_to; + +# End of 4.1 tests + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_multi_engine.test b/mysql-test/suite/rpl/t/rpl_multi_engine.test new file mode 100644 index 00000000..704c0935 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_multi_engine.test @@ -0,0 +1,102 @@ +# See if replication between MyISAM, MEMORY and InnoDB works. + +-- source include/master-slave.inc + +connection slave; +-- source include/have_innodb.inc + +connection master; +-- source include/have_innodb.inc +--disable_warnings +drop table if exists t1; +--enable_warnings + +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 TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP +ON UPDATE CURRENT_TIMESTAMP,PRIMARY KEY(id)); + +sync_slave_with_master; + +# MyISAM to MyISAM then InnoDB then MEMORY + +connection master; +alter table t1 engine=myisam; +show create table t1; +sync_slave_with_master; + +connection slave; +alter table t1 engine=myisam; +show create table t1; + +--source include/rpl_multi_engine.inc + +connection slave; +alter table t1 engine=innodb; +show create table t1; + +--source include/rpl_multi_engine.inc + +connection slave; +alter table t1 engine=memory; +show create table t1; + +--source include/rpl_multi_engine.inc + +# MEMORY to ... + +connection master; +alter table t1 engine=memory; +show create table t1; +sync_slave_with_master; + +connection slave; +alter table t1 engine=myisam; +show create table t1; + +--source include/rpl_multi_engine.inc + +connection slave; +alter table t1 engine=innodb; +show create table t1; + +--source include/rpl_multi_engine.inc + +connection slave; +alter table t1 engine=memory; +show create table t1; + +--source include/rpl_multi_engine.inc + +# InnoDB to ... + +connection master; +alter table t1 engine=innodb; +show create table t1; +sync_slave_with_master; + +connection slave; +alter table t1 engine=myisam; +show create table t1; + +--source include/rpl_multi_engine.inc + +connection slave; +alter table t1 engine=innodb; +show create table t1; + +--source include/rpl_multi_engine.inc + +connection slave; +alter table t1 engine=memory; +show create table t1; + +--source include/rpl_multi_engine.inc + +# cleanup +connection master; +DROP TABLE t1; +sync_slave_with_master; + +# End of 5.1 test case +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_multi_update.test b/mysql-test/suite/rpl/t/rpl_multi_update.test new file mode 100644 index 00000000..3927ed69 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_multi_update.test @@ -0,0 +1,2 @@ +let $engine_type=MyISAM; +-- source include/rpl_multi_update.test diff --git a/mysql-test/suite/rpl/t/rpl_multi_update2-slave.opt b/mysql-test/suite/rpl/t/rpl_multi_update2-slave.opt new file mode 100644 index 00000000..17d4171a --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_multi_update2-slave.opt @@ -0,0 +1 @@ +--replicate-ignore-table=nothing.sensible diff --git a/mysql-test/suite/rpl/t/rpl_multi_update2.test b/mysql-test/suite/rpl/t/rpl_multi_update2.test new file mode 100644 index 00000000..d2368f20 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_multi_update2.test @@ -0,0 +1,9 @@ +####################################################### +# Wrapper for rpl_multi_update2.test to allow multi # +# Engines to reuse test code. By JBM 2006-02-15 # +####################################################### +--source include/master-slave.inc +call mtr.add_suppression('Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT'); +let $engine_type=MyISAM; +--source include/rpl_multi_update2.test +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_multi_update3.test b/mysql-test/suite/rpl/t/rpl_multi_update3.test new file mode 100644 index 00000000..0a15e9aa --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_multi_update3.test @@ -0,0 +1,9 @@ +####################################################### +# Wrapper for rpl_multi_update3.test to allow multi # +# Engines to reuse test code. By JBM 2006-02-15 # +####################################################### +--source include/master-slave.inc +call mtr.add_suppression('Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT.'); +let $engine_type=MyISAM; +-- source include/rpl_multi_update3.test +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_multi_update4-slave.opt b/mysql-test/suite/rpl/t/rpl_multi_update4-slave.opt new file mode 100644 index 00000000..fea27db4 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_multi_update4-slave.opt @@ -0,0 +1 @@ +--replicate-wild-do-table=d1.% diff --git a/mysql-test/suite/rpl/t/rpl_multi_update4.test b/mysql-test/suite/rpl/t/rpl_multi_update4.test new file mode 100644 index 00000000..8f069b9c --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_multi_update4.test @@ -0,0 +1,46 @@ +# Let's verify that multi-update is not always skipped by slave if +# some replicate-* rules exist. +# (BUG#15699) + +source include/master-slave.inc; + +### Clean-up + +connection master; +--disable_warnings +drop database if exists d1; +drop database if exists d2; + +connection slave; +drop database if exists d2; +--enable_warnings + +### Do on master + +connection master; +create database d1; # accepted by slave +create table d1.t0 (id int); +create database d2; # ignored by slave +use d2; +create table t1 (id int); +create table t2 (id int); +insert into t1 values (1), (2), (3), (4), (5); +insert into t2 select id + 3 from t1; +# a problematic query which must be filter out by slave +update t1 join t2 using (id) set t1.id = 0; +insert into d1.t0 values (0); # replication works + +### Check on slave + +sync_slave_with_master; +use d1; +select * from t0 where id=0; # must find + +### Clean-up +connection master; +drop database d1; +drop database d2; +sync_slave_with_master; + +# End of test +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_mysql57_stm_temporal_round.test b/mysql-test/suite/rpl/t/rpl_mysql57_stm_temporal_round.test new file mode 100644 index 00000000..675b7db0 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_mysql57_stm_temporal_round.test @@ -0,0 +1,58 @@ +--source include/have_binlog_format_statement.inc + +--echo # +--echo # MDEV-8894 Inserting fractional seconds into MySQL 5.6 master breaks consistency on MariaDB 10 slave +--echo # + +--source include/have_innodb.inc +--source include/master-slave.inc + +--connection slave +CREATE TABLE t1 (id SERIAL, a DATETIME(3)); +--source include/stop_slave.inc + +--connection master +--let $datadir= `SELECT @@datadir` + +--let $rpl_server_number= 1 +--source include/rpl_stop_server.inc + +--remove_file $datadir/master-bin.000001 + +# +# Simulate MySQL 5.7.x master +# +# mysql-5.7.11-stm-temporal-round-binlog.000001 was recorded against a +# table with this structure: +#CREATE TABLE t1 (id SERIAL, a DATETIME(3)); +# (note, the CREATE statement is not inside the binary log) +# +# using this command line: +# mysqld --log-bin --binlog-format=statement +# with the following single SQL statement: +# +#INSERT INTO t1 (a) VALUES ('2001-01-01 00:00:00.999999'); +# + +--copy_file $MYSQL_TEST_DIR/std_data/rpl/mysql-5.7.11-stm-temporal-round-binlog.000001 $datadir/master-bin.000001 + +--let $rpl_server_number= 1 +--source include/rpl_start_server.inc + +--source include/wait_until_connected_again.inc + +--connection slave +--replace_result $SERVER_MYPORT_1 SERVER_MYPORT_1 +eval CHANGE MASTER TO master_host='127.0.0.1', master_port=$SERVER_MYPORT_1, master_user='root', master_log_file='master-bin.000001', master_log_pos=4; + +--source include/start_slave.inc + +--connection master +--sync_slave_with_master +SELECT * FROM t1 ORDER BY id; + +--source include/stop_slave.inc +DROP TABLE t1; + +--let $rpl_only_running_threads= 1 +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_mysql80_stm_temporal_round.test b/mysql-test/suite/rpl/t/rpl_mysql80_stm_temporal_round.test new file mode 100644 index 00000000..ad6df9d9 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_mysql80_stm_temporal_round.test @@ -0,0 +1,62 @@ +--source include/have_binlog_format_statement.inc + +--echo # +--echo # MDEV-8894 Inserting fractional seconds into MySQL 5.6 master breaks consistency on MariaDB 10 slave +--echo # + +--source include/have_innodb.inc +--source include/master-slave.inc + +--connection slave +CREATE TABLE t1 (id SERIAL, a DATETIME(3)); +--source include/stop_slave.inc + +--connection master +--let $datadir= `SELECT @@datadir` + +--let $rpl_server_number= 1 +--source include/rpl_stop_server.inc + +--remove_file $datadir/master-bin.000001 + +# +# Simulate MySQL 8.0.x master +# +# mysql-8.0.13-stm-temporal-round-binlog.000001 was recorded against a +# table with this structure: +#CREATE TABLE t1 (id SERIAL, a DATETIME(3)); +# (note, the CREATE statement is not inside the binary log) +# +# using this command line: +# mysqld --log-bin --binlog-format=statement --server-id=1 --character-set-server=latin1 +# with the following SQL script: +# +#SET NAMES latin1 COLLATE latin1_swedish_ci; +#SET sql_mode=''; +#INSERT INTO t1 (a) VALUES ('2001-01-01 00:00:00.999999'); +#SET sql_mode=TIME_TRUNCATE_FRACTIONAL; +#INSERT INTO t1 (a) VALUES ('2001-01-01 00:00:00.999999'); +# + +--copy_file $MYSQL_TEST_DIR/std_data/rpl/mysql-8.0.13-stm-temporal-round-binlog.000001 $datadir/master-bin.000001 + +--let $rpl_server_number= 1 +--source include/rpl_start_server.inc + +--source include/wait_until_connected_again.inc + +--connection slave +--replace_result $SERVER_MYPORT_1 SERVER_MYPORT_1 +eval CHANGE MASTER TO master_host='127.0.0.1', master_port=$SERVER_MYPORT_1, master_user='root', master_log_file='master-bin.000001', master_log_pos=4; + +--source include/start_slave.inc + +--connection master +--sync_slave_with_master +SELECT * FROM t1 ORDER BY id; + +--source include/stop_slave.inc +DROP TABLE t1; + +--let $rpl_only_running_threads= 1 +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_mysql_upgrade.test b/mysql-test/suite/rpl/t/rpl_mysql_upgrade.test new file mode 100644 index 00000000..f44c883e --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_mysql_upgrade.test @@ -0,0 +1,80 @@ +############################################################################# +# BUG#43579 mysql_upgrade tries to alter log tables on replicated database +# Master and slave should be upgraded separately. All statements executed by +# mysql_upgrade will not be binlogged. --write-binlog and --skip-write-binlog +# options are added into mysql_upgrade. These options control whether sql +# statements are binlogged or not. +############################################################################# +--source include/have_innodb.inc +--source include/mysql_upgrade_preparation.inc +--source include/master-slave.inc + +call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT"); +call mtr.add_suppression("table or database name 'mysqltest-1'"); + +connection master; +--disable_warnings +CREATE DATABASE `mysqltest-1`; +--enable_warnings +sync_slave_with_master; + +connection master; +let $before_position= query_get_value(SHOW MASTER STATUS, Position, 1); + +#With '--force' option, mysql_upgrade always executes all sql statements for upgrading. +--exec $MYSQL_UPGRADE --skip-verbose --force --user=root > $MYSQLTEST_VARDIR/log/mysql_upgrade.log 2>&1 +sync_slave_with_master; + +connection master; +let $after_position= query_get_value(SHOW MASTER STATUS, Position, 1); + +if ($before_position == $after_position) +{ + echo Master position is not changed; +} + +# Some log events of the mysql_upgrade previously caused errors on slave, +# however with MDEV-4851 this should be ok, so we test it: +connection slave; +SET @old_general_log_state = @@global.general_log; +SET @old_slow_log_state = @@global.slow_query_log; +SET @old_log_output = @@global.log_output; +SET GLOBAL general_log = 'ON'; +SET GLOBAL slow_query_log = 'ON'; +SET GLOBAL log_output = 'FILE'; + +connection master; +#With '--force' option, mysql_upgrade always executes all sql statements for upgrading. +ALTER TABLE mysql.slow_log DROP COLUMN thread_id, DROP COLUMN rows_affected; +DROP DATABASE `mysqltest-1`; +sync_slave_with_master; + +connection slave; +SHOW CREATE TABLE mysql.slow_log; +connection master; +--exec $MYSQL_UPGRADE --skip-verbose --write-binlog --force --user=root > $MYSQLTEST_VARDIR/log/mysql_upgrade.log 2>&1 + +let $datadir= `select @@datadir`; +remove_file $datadir/mysql_upgrade_info; + +connection master; +let $after_file= query_get_value(SHOW MASTER STATUS, File, 1); +let $after_position= query_get_value(SHOW MASTER STATUS, Position, 1); + +if ($before_position != $after_position) +{ + echo Master position has been changed; +} + +sync_slave_with_master; +connection slave; +SHOW CREATE TABLE mysql.slow_log; +SET GLOBAL general_log = 'OFF'; +SET GLOBAL slow_query_log = 'OFF'; +truncate mysql.slow_log; +truncate mysql.general_log; +SET GLOBAL general_log = @old_general_log_state; +SET GLOBAL slow_query_log = @old_slow_log_state; +SET GLOBAL log_output = @old_log_output; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_name_const.test b/mysql-test/suite/rpl/t/rpl_name_const.test new file mode 100644 index 00000000..074bc148 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_name_const.test @@ -0,0 +1,45 @@ +# ==== Purpose ==== +# +# Test that aliases of variables in binary log aren't ignored with NAME_CONST. +# +# ==== Method ==== +# +# Create a procedure with aliases of variables, then replicate it to slave. +# BUG#35515 Aliases of variables in binary log are ignored with NAME_CONST. +# + +source include/master-slave.inc; + +--echo ==== Initialize ==== + +--connection master + +create table t1 (id int); + +--echo ==== create a procedure that has a column aliase in a subquery ==== +--disable_warnings +drop procedure if exists test_procedure; +--enable_warnings +delimiter $$; +create procedure test_procedure(_id int) +begin +insert into t1 (id) +select a.id +from +( select _id as id ) a; +end;$$ +delimiter ;$$ + +--echo ==== enable the binary log, then call the procedure ==== +call test_procedure(1234); + + +sync_slave_with_master; +select * from t1 order by id; + +--echo ==== Clean up ==== + +connection master; +drop table t1; +drop procedure test_procedure; +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_non_direct_mixed_mixing_engines.test b/mysql-test/suite/rpl/t/rpl_non_direct_mixed_mixing_engines.test new file mode 100644 index 00000000..1f2f8749 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_non_direct_mixed_mixing_engines.test @@ -0,0 +1,15 @@ +################################################################################### +# This test cases evaluates the mixture of non-transactional and transcational +# tables. For further details, please, read WL#2687 and WL#5072. +################################################################################### +--source include/have_binlog_format_mixed.inc +--source include/have_innodb.inc +--source include/master-slave.inc + +--disable_query_log +SET SESSION binlog_direct_non_transactional_updates = OFF; +--enable_query_log +let $engine_type=Innodb; +let $database_name=test; +--source include/rpl_mixing_engines.test +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_non_direct_row_mixing_engines.test b/mysql-test/suite/rpl/t/rpl_non_direct_row_mixing_engines.test new file mode 100644 index 00000000..b4552c79 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_non_direct_row_mixing_engines.test @@ -0,0 +1,17 @@ +################################################################################### +# This test cases evaluates the mixture of non-transactional and transcational +# tables. For further details, please, read WL#2687 and WL#5072. +################################################################################### +--source include/have_binlog_format_row.inc +--source include/have_innodb.inc +--source include/master-slave.inc + +--disable_query_log +SET SESSION binlog_direct_non_transactional_updates = OFF; +--enable_query_log +let $engine_type=Innodb; +let $database_name=test; +--source include/rpl_mixing_engines.test + +--diff_files suite/rpl/r/rpl_non_direct_row_mixing_engines.result suite/rpl/r/rpl_row_mixing_engines.result +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_non_direct_stm_mixing_engines.test b/mysql-test/suite/rpl/t/rpl_non_direct_stm_mixing_engines.test new file mode 100644 index 00000000..23552515 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_non_direct_stm_mixing_engines.test @@ -0,0 +1,15 @@ +################################################################################### +# This test cases evaluates the mixture of non-transactional and transcational +# tables. For further details, please, read WL#2687 and WL#5072. +################################################################################### +--source include/have_binlog_format_statement.inc +--source include/have_innodb.inc +--source include/master-slave.inc + +--disable_query_log +SET SESSION binlog_direct_non_transactional_updates = OFF; +--enable_query_log +let $engine_type=Innodb; +let $database_name=test; +--source include/rpl_mixing_engines.test +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_nondeterministic_functions.test b/mysql-test/suite/rpl/t/rpl_nondeterministic_functions.test new file mode 100644 index 00000000..a174445f --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_nondeterministic_functions.test @@ -0,0 +1,58 @@ +# ==== Purpose ==== +# +# Test that nondeterministic system functions are correctly replicated. +# +# (Some functions are only correctly replicated if binlog_format=MIXED +# or ROW. See binlog_unsafe.test for a test that those variables are +# indeed unsafe.) +# +# ==== Implementation ==== +# +# We insert the values of each unsafe function into a table. Then we +# replicate and check that the table is identical on slave. +# +# ==== Related bugs ==== +# +# BUG#47995 + +--source include/master-slave.inc + +CALL mtr.add_suppression('Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT'); + +CREATE TABLE t1 (a VARCHAR(1000)); + +# We replicate the connection_id in the query_log_event +INSERT INTO t1 VALUES (CONNECTION_ID()); +--connection master1 +INSERT INTO t1 VALUES (CONNECTION_ID()); + +# We replicate the TIMESTAMP variable, so the following functions that +# are affected by the TIMESTAMP variable should be safe to replicate. +INSERT INTO t1 VALUES + (CURDATE()), + (CURRENT_DATE()), + (CURRENT_TIME()), + (CURRENT_TIMESTAMP()), + (CURTIME()), + (LOCALTIME()), + (LOCALTIMESTAMP()), + (NOW()), + (UNIX_TIMESTAMP()), + (UTC_DATE()), + (UTC_TIME()), + (UTC_TIMESTAMP()); + +# We replicate the random seed in a rand_log_event +--disable_warnings +INSERT INTO t1 VALUES (RAND()); +--enable_warnings +# We replicate the last_insert_id in an intvar_log_event +INSERT INTO t1 VALUES (LAST_INSERT_ID()); + +--sync_slave_with_master +--let $diff_tables= master:t1, slave:t1 +--source include/diff_tables.inc + +--connection master +DROP TABLE t1; +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_not_null_innodb.test b/mysql-test/suite/rpl/t/rpl_not_null_innodb.test new file mode 100644 index 00000000..0e67cd36 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_not_null_innodb.test @@ -0,0 +1,20 @@ +################################################################################# +# 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) +# +################################################################################# +--source include/have_innodb.inc +--source include/have_binlog_format_row.inc +--source include/master-slave.inc + +let $engine=Innodb; +--source include/rpl_not_null.test +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_not_null_myisam.test b/mysql-test/suite/rpl/t/rpl_not_null_myisam.test new file mode 100644 index 00000000..718761d6 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_not_null_myisam.test @@ -0,0 +1,19 @@ +################################################################################# +# 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) +# +################################################################################# +--source include/have_binlog_format_row.inc +--source include/master-slave.inc + +let $engine=MyISAM; +--source include/rpl_not_null.test +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_old_decimal.test b/mysql-test/suite/rpl/t/rpl_old_decimal.test new file mode 100644 index 00000000..79fd2754 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_old_decimal.test @@ -0,0 +1,25 @@ +--source include/have_binlog_format_row.inc +--source include/master-slave.inc + + +--connection slave +CREATE TABLE t1dec102 (a DECIMAL(10,2)); + +--connection master +let $MYSQLD_DATADIR= `select @@datadir`; + +--copy_file std_data/old_decimal/t1dec102.frm $MYSQLD_DATADIR/test/t1dec102.frm +--copy_file std_data/old_decimal/t1dec102.MYD $MYSQLD_DATADIR/test/t1dec102.MYD +--copy_file std_data/old_decimal/t1dec102.MYI $MYSQLD_DATADIR/test/t1dec102.MYI +INSERT INTO t1dec102 VALUES(999.99); + +--let $slave_sql_errno=1677 +--let $show_slave_sql_error= 1 +call mtr.add_suppression("Slave SQL.*Column 0 of table .* cannot be converted from type.* Error_code: 1677"); +--source include/wait_for_slave_sql_error_and_skip.inc + +--connection master +DROP TABLE t1dec102; +--sync_slave_with_master + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_old_master.test b/mysql-test/suite/rpl/t/rpl_old_master.test new file mode 100644 index 00000000..6ddc227f --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_old_master.test @@ -0,0 +1,57 @@ +# Test replicating off old master. +# We simulate old master by copying in pre-generated binlog files from earlier +# server versions. + +--source include/have_innodb.inc +--source include/master-slave.inc + +--connection slave +--source include/stop_slave.inc + +--connection master +--let $datadir= `SELECT @@datadir` + +--let $rpl_server_number= 1 +--source include/rpl_stop_server.inc + +--remove_file $datadir/master-bin.000001 +--copy_file $MYSQL_TEST_DIR/std_data/mariadb-5.5-binlog.000001 $datadir/master-bin.000001 + +--let $rpl_server_number= 1 +--source include/rpl_start_server.inc + +--source include/wait_until_connected_again.inc + +--connection slave +SET @old_parallel= @@GLOBAL.slave_parallel_threads; +SET GLOBAL slave_parallel_threads=10; +--replace_result $SERVER_MYPORT_1 SERVER_MYPORT_1 +eval CHANGE MASTER TO master_host='127.0.0.1', master_port=$SERVER_MYPORT_1, master_user='root', master_log_file='master-bin.000001', master_log_pos=4; + +# Block execution yet when the blocked query timestamp has been already accounted +FLUSH TABLES WITH READ LOCK; +--source include/start_slave.inc +--let $slave_param = Seconds_Behind_Master +--let $slave_param_value = 1 +--let $slave_param_comparison= >= +--source include/wait_for_slave_param.inc +UNLOCK TABLES; + +--connection master +CREATE TABLE t2 (a INT PRIMARY KEY) ENGINE=InnoDB; +INSERT INTO t2 VALUES (1); +--save_master_pos + +--connection slave +--sync_with_master +SELECT * FROM t1 ORDER BY a; +SELECT * FROM t2; + +--source include/stop_slave.inc +SET GLOBAL slave_parallel_threads=@old_parallel; +DROP TABLE t1; +--source include/start_slave.inc + +--connection master +DROP TABLE t2; +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_optimize.test b/mysql-test/suite/rpl/t/rpl_optimize.test new file mode 100644 index 00000000..bb960d4e --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_optimize.test @@ -0,0 +1,65 @@ +# Test for BUG#1858 "OPTIMIZE TABLE done by a client +# thread stops the slave SQL thread". +# You can replace OPTIMIZE by REPAIR. +##################################### +# Change Author: JBM +# Change Date: 2006-02-09 +# OPTIMIZE for memory tables. If and when +# it does support for Disk Data, a new +# version of this test will be need. +##################################### +# Slow test, don't run during staging part +-- source include/not_staging.inc +-- source include/master-slave.inc + +--disable_warnings +drop tables if exists t1; +--enable_warnings + +disable_query_log; +call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT"); +enable_query_log; + +create table t1 (a int not null auto_increment primary key, b int, key(b)); +INSERT INTO t1 (a) VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10); +--disable_warnings +INSERT INTO t1 (a) SELECT null FROM t1; +INSERT INTO t1 (a) SELECT null FROM t1; +INSERT INTO t1 (a) SELECT null FROM t1; +INSERT INTO t1 (a) SELECT null FROM t1; +INSERT INTO t1 (a) SELECT null FROM t1; +INSERT INTO t1 (a) SELECT null FROM t1; +INSERT INTO t1 (a) SELECT null FROM t1; +INSERT INTO t1 (a) SELECT null FROM t1; +INSERT INTO t1 (a) SELECT null FROM t1; +INSERT INTO t1 (a) SELECT null FROM t1; +INSERT INTO t1 (a) SELECT null FROM t1; +INSERT INTO t1 (a) SELECT null FROM t1; +INSERT INTO t1 (a) SELECT null FROM t1; +--enable_warnings +save_master_pos; +# a few updates to force OPTIMIZE to do something +--disable_warnings +update t1 set b=(a/2*rand()); +delete from t1 order by b limit 10000; +--enable_warnings + +connection slave; +sync_with_master; +optimize table t1; +connection master; +save_master_pos; +connection slave; +# Bug was that when the INSERT terminated on slave, +# the slave SQL thread got killed by OPTIMIZE. +sync_with_master; # won't work if slave SQL thread stopped + +connection master; # cleanup +drop table t1; +sync_slave_with_master; + +# If the machine is so fast that slave syncs before OPTIMIZE +# starts, this test will demonstrate nothing but will pass. + +# End of 4.1 tests +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_packet-master.opt b/mysql-test/suite/rpl/t/rpl_packet-master.opt new file mode 100644 index 00000000..412bc079 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_packet-master.opt @@ -0,0 +1 @@ +--max_allowed_packet=1024 --net_buffer_length=1024 diff --git a/mysql-test/suite/rpl/t/rpl_packet-slave.opt b/mysql-test/suite/rpl/t/rpl_packet-slave.opt new file mode 100644 index 00000000..1aed7d07 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_packet-slave.opt @@ -0,0 +1 @@ +--max_allowed_packet=1024 --net_buffer_length=1024 --slave_max_allowed_packet=1024 diff --git a/mysql-test/suite/rpl/t/rpl_packet.test b/mysql-test/suite/rpl/t/rpl_packet.test new file mode 100644 index 00000000..1bf99c23 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_packet.test @@ -0,0 +1 @@ +--source include/rpl_packet.inc diff --git a/mysql-test/suite/rpl/t/rpl_parallel2.test b/mysql-test/suite/rpl/t/rpl_parallel2.test new file mode 100644 index 00000000..8934b15e --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_parallel2.test @@ -0,0 +1,230 @@ +--source include/have_debug.inc +--source include/have_innodb.inc +--source include/have_binlog_format_statement.inc +--let $rpl_topology=1->2 +--source include/rpl_init.inc + +--echo *** MDEV-5509: Incorrect value for Seconds_Behind_Master if parallel replication *** + +--connection server_2 +SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads; +set @old_parallel_mode= @@GLOBAL.slave_parallel_mode; +--source include/stop_slave.inc +SET GLOBAL slave_parallel_threads=5; +set global slave_parallel_mode= optimistic; +--source include/start_slave.inc + +--connection server_1 +CREATE TABLE t1 (a INT PRIMARY KEY, b INT); +CALL mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statement is unsafe because it uses a system function that may return a different value on the slave"); +--save_master_pos + +--connection server_2 +--sync_with_master + +--connection server_1 +INSERT INTO t1 VALUES (1,sleep(2)); +--save_master_pos + +--connection server_2 +--sync_with_master + +# The slave position (which --sync_with_master waits for) is updated just +# before the Seconds_Behind_Master. So we have to wait for the zero status +# to appear, otherwise there is a small window between --sync_with_master +# and SHOW SLAVE STATUS where we can see a non-zero value. +--let $slave_param= Seconds_Behind_Master +--let $slave_param_value= 0 +--source include/wait_for_slave_param.inc +--echo Seconds_Behind_Master should be zero here because the slave is fully caught up and idle. +--let $status_items= Seconds_Behind_Master +--source include/show_slave_status.inc + + +--echo *** MDEV-8294: Inconsistent behavior of slave parallel threads at runtime *** + +--connection server_1 +INSERT INTO t1 VALUES (10,0); +# Force a duplicate key error on the slave. +SET sql_log_bin= 0; +DELETE FROM t1 WHERE a=10; +SET sql_log_bin= 1; +INSERT INTO t1 VALUES (10,0); +--save_master_pos +SELECT * FROM t1 WHERE a >= 10 ORDER BY a; + +--connection server_2 +--let $slave_sql_errno= 1062 +--source include/wait_for_slave_sql_error.inc + +# At this point, the worker threads should have stopped also. +--let $wait_condition= SELECT COUNT(*)=0 FROM information_schema.processlist WHERE User = "system user" AND State = "Waiting for work from SQL thread"; +--source include/wait_condition.inc + +# Check that the pool can still be resized, but remains inactive as no slave +# SQL thread is running. +SET GLOBAL slave_parallel_threads=8; +--let $wait_condition= SELECT COUNT(*)=0 FROM information_schema.processlist WHERE User = "system user" AND State = "Waiting for work from SQL thread"; +--source include/wait_condition.inc + +STOP SLAVE; +# At this point, the worker threads should have stopped. +--let $wait_condition= SELECT COUNT(*)=0 FROM information_schema.processlist WHERE User = "system user" AND State = "Waiting for work from SQL thread"; +--source include/wait_condition.inc + + +SET GLOBAL sql_slave_skip_counter= 1; +--source include/start_slave.inc +# At this point, the worker threads should have been spawned. +--let $wait_condition= SELECT COUNT(*)=8 FROM information_schema.processlist WHERE User = "system user" AND State = "Waiting for work from SQL thread"; +--source include/wait_condition.inc +--sync_with_master +SELECT * FROM t1 WHERE a >= 10 ORDER BY a; + + +--echo *** MDEV-7818: Deadlock occurring with parallel replication and FTWRL *** + +--connection server_1 +CREATE TABLE t2 (a INT PRIMARY KEY, b INT) ENGINE=InnoDB; +INSERT INTO t2 VALUES (1,0), (2,0), (3,0); +--save_master_pos + +--connection server_2 +--sync_with_master +--source include/stop_slave.inc + +--connection server_1 +# Create a group commit with two transactions, will be used to provoke the +# problematic thread interaction with FTWRL on the slave. +SET @old_dbug= @@SESSION.debug_dbug; +SET @commit_id= 4242; +SET SESSION debug_dbug="+d,binlog_force_commit_id"; + +BEGIN; +UPDATE t2 SET b=b+1 WHERE a=2; +COMMIT; + +BEGIN; +INSERT INTO t2 VALUES (4,10); +COMMIT; + +SET SESSION debug_dbug= @old_dbug; + +INSERT INTO t2 VALUES (5,0); +INSERT INTO t2 VALUES (6,0); +INSERT INTO t2 VALUES (7,0); +INSERT INTO t2 VALUES (8,0); +INSERT INTO t2 VALUES (9,0); +INSERT INTO t2 VALUES (10,0); +INSERT INTO t2 VALUES (11,0); +INSERT INTO t2 VALUES (12,0); +INSERT INTO t2 VALUES (13,0); +INSERT INTO t2 VALUES (14,0); +INSERT INTO t2 VALUES (15,0); +INSERT INTO t2 VALUES (16,0); +INSERT INTO t2 VALUES (17,0); +INSERT INTO t2 VALUES (18,0); +INSERT INTO t2 VALUES (19,0); +--save_master_pos + +--connection server_2 + +--connect (s1, 127.0.0.1, root,, test, $SLAVE_MYPORT,) +# Block one transaction on a row lock. +BEGIN; +SELECT * FROM t2 WHERE a=2 FOR UPDATE; + +--connection server_2 + +# Wait for slave thread of the other transaction to have the commit lock. +--source include/start_slave.inc +--let $wait_condition= SELECT COUNT(*) > 0 FROM information_schema.processlist WHERE state = "Waiting for prior transaction to commit" +--source include/wait_condition.inc + +--connect (s2, 127.0.0.1, root,, test, $SLAVE_MYPORT,) +send FLUSH TABLES WITH READ LOCK; +# The bug was that at this point we were deadlocked. +# The FTWRL command would wait forever for T2 to commit. +# T2 would wait for T1 to commit first, but T1 is waiting for +# the global read lock to be released. + +--connection s1 +# Release the lock that blocs T1 from replicating. +COMMIT; + +--connection s1 +send STOP SLAVE; + +--connection s2 +reap; + +--connection server_1 +SELECT * FROM t2 ORDER BY a; + +--connection s2 +UNLOCK TABLES; + +SELECT "after UNLOCK TABLES" as state; + +--connection s1 +reap; + +SELECT "after reap of STOP SLAVE" as state; + +--connection server_2 +--source include/wait_for_slave_to_stop.inc +--source include/start_slave.inc +--sync_with_master + +SELECT * FROM t2 ORDER BY a; + + + +--echo *** MDEV-8318: Assertion `!pool->busy' failed in pool_mark_busy(rpl_parallel_thread_pool*) on concurrent FTWRL *** + +--connection server_1 +LOCK TABLE t2 WRITE; + + +--connect (m1,localhost,root,,test) +--connection m1 +--let $cid=`SELECT CONNECTION_ID()` +send FLUSH TABLES WITH READ LOCK; + +--connect (m2,localhost,root,,test) +# We cannot force the race with DEBUG_SYNC, because the race does not +# exist after fixing the bug. At best we could force a debug sync to +# time out, which is effectively just a sleep. +# So just put a small sleep here; it is enough to trigger the bug in +# most run before the bug fix, and the code should work correctly +# however the thread scheduling happens. +--sleep 0.1 +send FLUSH TABLES WITH READ LOCK; + +--connection server_1 +--replace_result $cid CID +eval KILL QUERY $cid; + +--connection m1 +--error ER_QUERY_INTERRUPTED +reap; + +--connection server_1 +UNLOCK TABLES; + +--connection m2 +reap; +UNLOCK TABLES; + + +# Clean up. +--connection server_2 +--source include/stop_slave.inc +SET GLOBAL slave_parallel_threads=@old_parallel_threads; +set global slave_parallel_mode= @old_parallel_mode; +--source include/start_slave.inc + +--connection server_1 +DROP TABLE t1, t2; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_parallel_analyze_table_hang.test b/mysql-test/suite/rpl/t/rpl_parallel_analyze_table_hang.test new file mode 100644 index 00000000..c1f1b9ba --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_parallel_analyze_table_hang.test @@ -0,0 +1 @@ +--source include/rpl_parallel_analyze_table_hang.inc diff --git a/mysql-test/suite/rpl/t/rpl_parallel_charset.test b/mysql-test/suite/rpl/t/rpl_parallel_charset.test new file mode 100644 index 00000000..3e0f4913 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_parallel_charset.test @@ -0,0 +1,56 @@ +--source include/have_binlog_format_statement.inc +--let $rpl_topology=1->2 +--source include/rpl_init.inc + +--echo *** MDEV-6156: Parallel replication incorrectly caches charset between worker threads *** + +--connection server_2 +SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads; +--source include/stop_slave.inc +SET GLOBAL slave_parallel_threads=5; +--source include/start_slave.inc + +--connection server_1 +CREATE TABLE t1 (a INT PRIMARY KEY, b VARCHAR(100) CHARACTER SET utf8); +SHOW CREATE TABLE t1; +SET character_set_client=latin1; +INSERT INTO t1 VALUES (1, 'Rødgrød med fløde 1'); +INSERT INTO t1 VALUES (2, 'Rødgrød med fløde 2'); +INSERT INTO t1 VALUES (3, 'Rødgrød med fløde 3'); +INSERT INTO t1 VALUES (4, 'Rødgrød med fløde 4'); +INSERT INTO t1 VALUES (5, 'Rødgrød med fløde 5'); +INSERT INTO t1 VALUES (6, 'Rødgrød med fløde 6'); +INSERT INTO t1 VALUES (7, 'Rødgrød med fløde 7'); +INSERT INTO t1 VALUES (8, 'Rødgrød med fløde 8'); +INSERT INTO t1 VALUES (9, 'Rødgrød med fløde 9'); +INSERT INTO t1 VALUES (10, 'Rødgrød med fløde 10'); +SET character_set_client=utf8; +INSERT INTO t1 VALUES (11, 'Rødgrød med fløde 1'); +INSERT INTO t1 VALUES (12, 'Rødgrød med fløde 2'); +INSERT INTO t1 VALUES (13, 'Rødgrød med fløde 3'); +INSERT INTO t1 VALUES (14, 'Rødgrød med fløde 4'); +INSERT INTO t1 VALUES (15, 'Rødgrød med fløde 5'); +INSERT INTO t1 VALUES (16, 'Rødgrød med fløde 6'); +INSERT INTO t1 VALUES (17, 'Rødgrød med fløde 7'); +INSERT INTO t1 VALUES (18, 'Rødgrød med fløde 8'); +INSERT INTO t1 VALUES (19, 'Rødgrød med fløde 9'); +INSERT INTO t1 VALUES (20, 'Rødgrød med fløde 10'); +SET character_set_results=utf8; +SELECT * FROM t1 ORDER BY a; +--save_master_pos + +--connection server_2 +--sync_with_master +SET character_set_results=utf8; +SELECT * FROM t1 ORDER BY a; + + +--connection server_2 +--source include/stop_slave.inc +SET GLOBAL slave_parallel_threads=@old_parallel_threads; +--source include/start_slave.inc + +--connection server_1 +DROP TABLE t1; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_parallel_conflicts.test b/mysql-test/suite/rpl/t/rpl_parallel_conflicts.test new file mode 100644 index 00000000..0ba6a2b2 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_parallel_conflicts.test @@ -0,0 +1,269 @@ +--source include/have_innodb.inc +--source include/have_debug.inc +--source include/have_debug_sync.inc +--source include/master-slave.inc + +--echo *** MDEV-7847: "Slave worker thread retried transaction 10 time(s) in vain, giving up", followed by replication hanging *** +--echo *** MDEV-7882: Excessive transaction retry in parallel replication *** + +--connection server_1 +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +CREATE TABLE t7 (a int PRIMARY KEY, b INT) ENGINE=InnoDB; +CREATE TABLE t8 (a int PRIMARY KEY, b INT) ENGINE=InnoDB; +--save_master_pos + +--connection server_2 +--sync_with_master +--source include/stop_slave.inc +SET @old_mode= @@GLOBAL.slave_parallel_mode; +SET GLOBAL slave_parallel_mode='conservative'; +SET @old_threads= @@GLOBAL.slave_parallel_threads; +SET GLOBAL slave_parallel_threads=40; +SET @old_transaction_retries= @@GLOBAL.slave_transaction_retries; +SET GLOBAL slave_transaction_retries=5; + +# Using dbug error injection, we artificially create event groups with a lot of +# conflicting transactions in each event group. The bugs were originally seen +# "in the wild" with transactions that did not conflict on the master, and only +# conflicted very rarely on the slave (maybe some edge case with InnoDB btree +# page splits or something like that). The event groups here loosely reflect +# the structure of the original failure's group commits. + + +--connection server_1 +INSERT INTO t7 VALUES (1,1), (2,2), (3,3), (4,4), (5,5); +SET @old_dbug= @@SESSION.debug_dbug; +SET @commit_id= 42; +SET SESSION debug_dbug="+d,binlog_force_commit_id"; +INSERT INTO t8 VALUES (1,1); +INSERT INTO t8 VALUES (2,2); +INSERT INTO t8 VALUES (3,3); +INSERT INTO t8 VALUES (4,4); +INSERT INTO t8 VALUES (5,5); +INSERT INTO t8 VALUES (6,6); +INSERT INTO t8 VALUES (7,7); +INSERT INTO t8 VALUES (8,8); + +UPDATE t7 SET b=9 WHERE a=3; +UPDATE t7 SET b=10 WHERE a=3; +UPDATE t7 SET b=11 WHERE a=3; + +INSERT INTO t8 VALUES (12,12); +INSERT INTO t8 VALUES (13,13); + +UPDATE t7 SET b=14 WHERE a=3; +UPDATE t7 SET b=15 WHERE a=3; + +INSERT INTO t8 VALUES (16,16); + +UPDATE t7 SET b=17 WHERE a=3; + +INSERT INTO t8 VALUES (18,18); +INSERT INTO t8 VALUES (19,19); + +UPDATE t7 SET b=20 WHERE a=3; + +INSERT INTO t8 VALUES (21,21); + +UPDATE t7 SET b=22 WHERE a=3; + +INSERT INTO t8 VALUES (23,24); +INSERT INTO t8 VALUES (24,24); + +UPDATE t7 SET b=25 WHERE a=3; + +INSERT INTO t8 VALUES (26,26); + +UPDATE t7 SET b=27 WHERE a=3; + +BEGIN; +INSERT INTO t8 VALUES (28,28); +INSERT INTO t8 VALUES (29,28), (30,28); +INSERT INTO t8 VALUES (31,28); +INSERT INTO t8 VALUES (32,28); +INSERT INTO t8 VALUES (33,28); +INSERT INTO t8 VALUES (34,28); +INSERT INTO t8 VALUES (35,28); +INSERT INTO t8 VALUES (36,28); +INSERT INTO t8 VALUES (37,28); +INSERT INTO t8 VALUES (38,28); +INSERT INTO t8 VALUES (39,28); +INSERT INTO t8 VALUES (40,28); +INSERT INTO t8 VALUES (41,28); +INSERT INTO t8 VALUES (42,28); +COMMIT; + + +SET @commit_id=43; +INSERT INTO t8 VALUES (43,43); +INSERT INTO t8 VALUES (44,44); + +UPDATE t7 SET b=45 WHERE a=3; + +INSERT INTO t8 VALUES (46,46); +INSERT INTO t8 VALUES (47,47); + +UPDATE t7 SET b=48 WHERE a=3; + +INSERT INTO t8 VALUES (49,49); +INSERT INTO t8 VALUES (50,50); + + +SET @commit_id=44; +INSERT INTO t8 VALUES (51,51); +INSERT INTO t8 VALUES (52,52); + +UPDATE t7 SET b=53 WHERE a=3; + +INSERT INTO t8 VALUES (54,54); +INSERT INTO t8 VALUES (55,55); + +UPDATE t7 SET b=56 WHERE a=3; + +INSERT INTO t8 VALUES (57,57); + +UPDATE t7 SET b=58 WHERE a=3; + +INSERT INTO t8 VALUES (58,58); +INSERT INTO t8 VALUES (59,59); +INSERT INTO t8 VALUES (60,60); +INSERT INTO t8 VALUES (61,61); + +UPDATE t7 SET b=62 WHERE a=3; + +INSERT INTO t8 VALUES (63,63); +INSERT INTO t8 VALUES (64,64); +INSERT INTO t8 VALUES (65,65); +INSERT INTO t8 VALUES (66,66); + +UPDATE t7 SET b=67 WHERE a=3; + +INSERT INTO t8 VALUES (68,68); + +UPDATE t7 SET b=69 WHERE a=3; +UPDATE t7 SET b=70 WHERE a=3; +UPDATE t7 SET b=71 WHERE a=3; + +INSERT INTO t8 VALUES (72,72); + +UPDATE t7 SET b=73 WHERE a=3; +UPDATE t7 SET b=74 WHERE a=3; +UPDATE t7 SET b=75 WHERE a=3; +UPDATE t7 SET b=76 WHERE a=3; + +INSERT INTO t8 VALUES (77,77); + +UPDATE t7 SET b=78 WHERE a=3; + +INSERT INTO t8 VALUES (79,79); + +UPDATE t7 SET b=80 WHERE a=3; + +INSERT INTO t8 VALUES (81,81); + +UPDATE t7 SET b=82 WHERE a=3; + +INSERT INTO t8 VALUES (83,83); + +UPDATE t7 SET b=84 WHERE a=3; + + +SET @commit_id=45; +INSERT INTO t8 VALUES (85,85); +UPDATE t7 SET b=86 WHERE a=3; +INSERT INTO t8 VALUES (87,87); + + +SET @commit_id=46; +INSERT INTO t8 VALUES (88,88); +INSERT INTO t8 VALUES (89,89); +INSERT INTO t8 VALUES (90,90); + +SET SESSION debug_dbug=@old_dbug; + +INSERT INTO t8 VALUES (91,91); +INSERT INTO t8 VALUES (92,92); +INSERT INTO t8 VALUES (93,93); +INSERT INTO t8 VALUES (94,94); +INSERT INTO t8 VALUES (95,95); +INSERT INTO t8 VALUES (96,96); +INSERT INTO t8 VALUES (97,97); +INSERT INTO t8 VALUES (98,98); +INSERT INTO t8 VALUES (99,99); + + +SELECT * FROM t7 ORDER BY a; +SELECT * FROM t8 ORDER BY a; +--source include/save_master_gtid.inc + + +--connection server_2 +--source include/start_slave.inc +--source include/sync_with_master_gtid.inc +SELECT * FROM t7 ORDER BY a; +SELECT * FROM t8 ORDER BY a; + +--echo *** MDEV-8302: Duplicate key with parallel replication *** + +--connection server_2 +--source include/stop_slave.inc +/* Inject a small sleep which makes the race easier to hit. */ +SET @old_dbug=@@GLOBAL.debug_dbug; +SET GLOBAL debug_dbug="+d,inject_mdev8302"; + + +--connection server_1 +INSERT INTO t7 VALUES (100,1), (101,2), (102,3), (103,4), (104,5); + +# Artificially create a bunch of group commits with conflicting transactions. +# The bug happened when T1 and T2 was in one group commit, and T3 was in the +# following group commit. T2 is a DELETE of a row with same primary key as a +# row that T3 inserts. T1 and T2 can conflict, causing T2 to be deadlock +# killed after starting to commit. The bug was that T2 could roll back before +# doing unmark_start_commit(); this could allow T3 to run before the retry +# of T2, causing duplicate key violation. + +SET @old_dbug= @@SESSION.debug_dbug; +SET @commit_id= 20000; +SET SESSION debug_dbug="+d,binlog_force_commit_id"; + +--let $n = 100 +--disable_query_log +while ($n) +{ + eval UPDATE t7 SET b=b+1 WHERE a=100+($n MOD 5); + eval DELETE FROM t7 WHERE a=100+($n MOD 5); + + SET @commit_id = @commit_id + 1; + eval INSERT INTO t7 VALUES (100+($n MOD 5), $n); + SET @commit_id = @commit_id + 1; + dec $n; +} +--enable_query_log +SET SESSION debug_dbug=@old_dbug; + + +SELECT * FROM t7 ORDER BY a; +--source include/save_master_gtid.inc + + +--connection server_2 +--source include/start_slave.inc +--source include/sync_with_master_gtid.inc +SELECT * FROM t7 ORDER BY a; + +--source include/stop_slave.inc +SET GLOBAL debug_dbug=@old_dbug; +SET GLOBAL slave_parallel_mode=@old_mode; +SET GLOBAL slave_parallel_threads=@old_threads; +SET GLOBAL slave_transaction_retries=@old_transaction_retries; + +# Clean up. +--source include/start_slave.inc +SET DEBUG_SYNC= 'RESET'; + +--connection server_1 +DROP TABLE t7,t8; +SET DEBUG_SYNC= 'RESET'; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_parallel_deadlock_corrupt_binlog.test b/mysql-test/suite/rpl/t/rpl_parallel_deadlock_corrupt_binlog.test new file mode 100644 index 00000000..9ee06f59 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_parallel_deadlock_corrupt_binlog.test @@ -0,0 +1 @@ +--source include/rpl_parallel_deadlock_corrupt_binlog.inc diff --git a/mysql-test/suite/rpl/t/rpl_parallel_domain.test b/mysql-test/suite/rpl/t/rpl_parallel_domain.test new file mode 100644 index 00000000..f5864380 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_parallel_domain.test @@ -0,0 +1 @@ +--source include/rpl_parallel_domain.inc diff --git a/mysql-test/suite/rpl/t/rpl_parallel_domain_slave_single_grp.test b/mysql-test/suite/rpl/t/rpl_parallel_domain_slave_single_grp.test new file mode 100644 index 00000000..5ddd2af3 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_parallel_domain_slave_single_grp.test @@ -0,0 +1 @@ +--source include/rpl_parallel_domain_slave_single_grp.inc diff --git a/mysql-test/suite/rpl/t/rpl_parallel_free_deferred_event.test b/mysql-test/suite/rpl/t/rpl_parallel_free_deferred_event.test new file mode 100644 index 00000000..e2a41d0d --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_parallel_free_deferred_event.test @@ -0,0 +1 @@ +--source include/rpl_parallel_free_deferred_event.inc diff --git a/mysql-test/suite/rpl/t/rpl_parallel_gco_wait_kill.test b/mysql-test/suite/rpl/t/rpl_parallel_gco_wait_kill.test new file mode 100644 index 00000000..d9dc4dfd --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_parallel_gco_wait_kill.test @@ -0,0 +1 @@ +--source include/rpl_parallel_gco_wait_kill.inc diff --git a/mysql-test/suite/rpl/t/rpl_parallel_gtid_slave_pos_update_fail.test b/mysql-test/suite/rpl/t/rpl_parallel_gtid_slave_pos_update_fail.test new file mode 100644 index 00000000..0756caca --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_parallel_gtid_slave_pos_update_fail.test @@ -0,0 +1 @@ +--source include/rpl_parallel_gtid_slave_pos_update_fail.inc diff --git a/mysql-test/suite/rpl/t/rpl_parallel_ignore_error_on_rotate.test b/mysql-test/suite/rpl/t/rpl_parallel_ignore_error_on_rotate.test new file mode 100644 index 00000000..92c84d49 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_parallel_ignore_error_on_rotate.test @@ -0,0 +1 @@ +--source include/rpl_parallel_ignore_error_on_rotate.inc diff --git a/mysql-test/suite/rpl/t/rpl_parallel_ignored_errors.test b/mysql-test/suite/rpl/t/rpl_parallel_ignored_errors.test new file mode 100644 index 00000000..90f09a76 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_parallel_ignored_errors.test @@ -0,0 +1 @@ +--source include/rpl_parallel_ignored_errors.inc diff --git a/mysql-test/suite/rpl/t/rpl_parallel_incorrect_relay_pos.test b/mysql-test/suite/rpl/t/rpl_parallel_incorrect_relay_pos.test new file mode 100644 index 00000000..e0226d94 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_parallel_incorrect_relay_pos.test @@ -0,0 +1 @@ +--source include/rpl_parallel_incorrect_relay_pos.inc diff --git a/mysql-test/suite/rpl/t/rpl_parallel_innodb_lock_conflict.test b/mysql-test/suite/rpl/t/rpl_parallel_innodb_lock_conflict.test new file mode 100644 index 00000000..3838973c --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_parallel_innodb_lock_conflict.test @@ -0,0 +1 @@ +--source include/rpl_parallel_innodb_lock_conflict.inc diff --git a/mysql-test/suite/rpl/t/rpl_parallel_mdev6589.test b/mysql-test/suite/rpl/t/rpl_parallel_mdev6589.test new file mode 100644 index 00000000..981c6216 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_parallel_mdev6589.test @@ -0,0 +1,133 @@ +--source include/have_innodb.inc +--source include/have_debug.inc +--source include/have_debug_sync.inc +--source include/master-slave.inc + +--connection server_2 +SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads; +--source include/stop_slave.inc +SET GLOBAL slave_parallel_threads=10; +CHANGE MASTER TO master_use_gtid=current_pos; +--source include/start_slave.inc + + +--echo *** MDEV-6589: Incorrect relay log start position when restarting SQL thread after error in parallel replication *** + +--connection server_1 +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +CREATE TABLE t1 (a int PRIMARY KEY) ENGINE=MyISAM; +CREATE TABLE t2 (a int PRIMARY KEY) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1); +INSERT INTO t2 VALUES (1); +--save_master_pos + +--connection server_2 +--sync_with_master +SELECT * FROM t1; +SELECT * FROM t2; + +# Block one domain, which we will later cause to give an error. And let some +# other domains proceed so we can check that after restart, the slave is able +# to correctly restart each domain in a separate position. + +--connect (con_temp1,127.0.0.1,root,,test,$SERVER_MYPORT_2,) +SET sql_log_bin=0; +BEGIN; +INSERT INTO t2 VALUES (5); + +--connection server_1 +SET gtid_domain_id=0; +INSERT INTO t1 VALUES (2); +INSERT INTO t2 VALUES (3); +FLUSH LOGS; +INSERT INTO t1 VALUES (4); + +SET gtid_domain_id=1; +# This query will be blocked on the slave, and later give a duplicate key error. +INSERT INTO t2 VALUES (5); + +SET gtid_domain_id=0; +INSERT INTO t1 VALUES (6); +INSERT INTO t1 VALUES (7); + +SET gtid_domain_id=2; +INSERT INTO t2 VALUES (8); +INSERT INTO t1 VALUES (9); +FLUSH LOGS; + +SET gtid_domain_id=3; +INSERT INTO t2 VALUES (10); +INSERT INTO t1 VALUES (11); + +# These cannot be replicated before the error, as a prior commit is blocked. +SET gtid_domain_id=1; +INSERT INTO t1 VALUES (12); +INSERT INTO t2 VALUES (13); + +SET gtid_domain_id=0; +INSERT INTO t2 VALUES (14); +FLUSH LOGS; + +SET gtid_domain_id=3; +INSERT INTO t2 VALUES (15); + +SET gtid_domain_id=2; +INSERT INTO t2 VALUES (16); + +SET gtid_domain_id=0; +INSERT INTO t1 VALUES (17); +SET @gtid0 = @@last_gtid; +SET gtid_domain_id=2; +INSERT INTO t1 VALUES (18); +SET @gtid2 = @@last_gtid; +SET gtid_domain_id=3; +INSERT INTO t1 VALUES (19); +SET @gtid3 = @@last_gtid; +--let $wait_pos= `SELECT CONCAT(@gtid0, ",", @gtid2, ",", @gtid3)` + +SELECT * FROM t1 ORDER BY a; +SELECT * FROM t2 ORDER BY a; +--source include/save_master_gtid.inc + + +--connection server_2 +# First wait for domains 0, 2, and 3 to complete. +--replace_result $wait_pos WAIT_POS +eval SELECT MASTER_GTID_WAIT('$wait_pos'); + +# Then release the row lock, and wait for the domain 1 to fail with +# duplicate key error. +--connection con_temp1 +COMMIT; +CALL mtr.add_suppression("Commit failed due to failure of an earlier commit on which this one depends"); +SET sql_log_bin=1; + +--connection server_2 +--let $slave_sql_errno= 1062 +--source include/wait_for_slave_sql_error.inc + +SELECT * FROM t1 ORDER BY a; +SELECT * FROM t2 ORDER BY a; + +SET sql_log_bin=0; +DELETE FROM t2 WHERE a=5; +SET sql_log_bin=1; +--source include/start_slave.inc +--source include/sync_with_master_gtid.inc + +SELECT * FROM t1 ORDER BY a; +SELECT * FROM t2 ORDER BY a; + + +# Clean up. +--connection server_2 +--source include/stop_slave.inc +SET GLOBAL slave_parallel_threads=@old_parallel_threads; +--source include/start_slave.inc +SET DEBUG_SYNC= 'RESET'; + +--connection server_1 +DROP TABLE t1,t2; +SET DEBUG_SYNC= 'RESET'; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_parallel_missed_error_handling.test b/mysql-test/suite/rpl/t/rpl_parallel_missed_error_handling.test new file mode 100644 index 00000000..de9dc7f7 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_parallel_missed_error_handling.test @@ -0,0 +1 @@ +--source include/rpl_parallel_missed_error_handling.inc diff --git a/mysql-test/suite/rpl/t/rpl_parallel_mode.test b/mysql-test/suite/rpl/t/rpl_parallel_mode.test new file mode 100644 index 00000000..afd9e038 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_parallel_mode.test @@ -0,0 +1 @@ +--source include/rpl_parallel_mode.inc diff --git a/mysql-test/suite/rpl/t/rpl_parallel_multilevel.cnf b/mysql-test/suite/rpl/t/rpl_parallel_multilevel.cnf new file mode 100644 index 00000000..3ff94e45 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_parallel_multilevel.cnf @@ -0,0 +1,24 @@ +!include ../my.cnf + +[mysqld.1] +log-slave-updates +loose-innodb + +[mysqld.2] +log-slave-updates +loose-innodb + +[mysqld.3] +log-slave-updates +loose-innodb + +[mysqld.4] +log-slave-updates +loose-innodb + +[ENV] +SERVER_MYPORT_3= @mysqld.3.port +SERVER_MYSOCK_3= @mysqld.3.socket + +SERVER_MYPORT_4= @mysqld.4.port +SERVER_MYSOCK_4= @mysqld.4.socket diff --git a/mysql-test/suite/rpl/t/rpl_parallel_multilevel.test b/mysql-test/suite/rpl/t/rpl_parallel_multilevel.test new file mode 100644 index 00000000..168b7ea5 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_parallel_multilevel.test @@ -0,0 +1,284 @@ +--source include/have_innodb.inc +--source include/have_debug_sync.inc +--let $rpl_topology=1->2->3->4 +--source include/rpl_init.inc + +# Test parallel replication with a multi-level replication hierarchy. + +--connection server_1 +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +CREATE TABLE t1 (a int PRIMARY KEY, b INT) ENGINE=InnoDB; +--save_master_pos + +--connection server_2 +--sync_with_master +--save_master_pos +SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads; +--source include/stop_slave.inc +SET GLOBAL slave_parallel_threads=10; +CHANGE MASTER TO master_use_gtid=slave_pos; +SET @old_parallel_mode=@@GLOBAL.slave_parallel_mode; +SET GLOBAL slave_parallel_mode='optimistic'; + + +--connection server_3 +--sync_with_master +--save_master_pos +SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads; +--source include/stop_slave.inc +SET GLOBAL slave_parallel_threads=10; +CHANGE MASTER TO master_use_gtid=slave_pos; +SET @old_parallel_mode=@@GLOBAL.slave_parallel_mode; +SET GLOBAL slave_parallel_mode='optimistic'; + + +--connection server_4 +--sync_with_master +SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads; +--source include/stop_slave.inc +SET GLOBAL slave_parallel_threads=10; +CHANGE MASTER TO master_use_gtid=slave_pos; +SET @old_parallel_mode=@@GLOBAL.slave_parallel_mode; +SET GLOBAL slave_parallel_mode='optimistic'; + + +--echo *** MDEV-6676: Test that @@skip_parallel_replication is preserved in slave binlog *** +--connection server_1 + +INSERT INTO t1 VALUES(1,1); +BEGIN; +INSERT INTO t1 VALUES(2,1); +INSERT INTO t1 VALUES(3,1); +COMMIT; +# Do a lot of updates on same row in sequence. These would be likely to cause +# conflicts and rollbacks in optimistic parallel replication, but we disable +# that by enabling @@skip_parallel_replication. We can test that the flag is +# preserved down the replication hierarchy by checking that no slave retries +# are made. +SET SESSION skip_parallel_replication=1; +UPDATE t1 SET b=b+1 WHERE a=2; +UPDATE t1 SET b=b+1 WHERE a=2; +UPDATE t1 SET b=b+1 WHERE a=2; +UPDATE t1 SET b=b+1 WHERE a=2; +UPDATE t1 SET b=b+1 WHERE a=2; +UPDATE t1 SET b=b+1 WHERE a=2; +UPDATE t1 SET b=b+1 WHERE a=2; +UPDATE t1 SET b=b+1 WHERE a=2; +UPDATE t1 SET b=b+1 WHERE a=2; +UPDATE t1 SET b=b+1 WHERE a=2; +SET SESSION skip_parallel_replication=0; +SELECT * FROM t1 ORDER BY a; +--source include/save_master_gtid.inc + +--connection server_2 +--let $retry1= query_get_value(SHOW STATUS LIKE 'Slave_retried_transactions', Value, 1) +--source include/start_slave.inc +--source include/sync_with_master_gtid.inc +SELECT * FROM t1 ORDER BY a; +--let $retry2= query_get_value(SHOW STATUS LIKE 'Slave_retried_transactions', Value, 1) +--disable_query_log +eval SELECT IF($retry1=$retry2, "Ok, no retry", + CONCAT("ERROR: ", $retry2-$retry1, " retries during replication (was ", + $retry1, " now ", $retry2, ")")) AS status; +--enable_query_log + +--connection server_3 +--let $retry1= query_get_value(SHOW STATUS LIKE 'Slave_retried_transactions', Value, 1) +--source include/start_slave.inc +--source include/sync_with_master_gtid.inc +SELECT * FROM t1 ORDER BY a; +--let $retry2= query_get_value(SHOW STATUS LIKE 'Slave_retried_transactions', Value, 1) +--disable_query_log +eval SELECT IF($retry1=$retry2, "Ok, no retry", + CONCAT("ERROR: ", $retry2-$retry1, " retries during replication (was ", + $retry1, " now ", $retry2, ")")) AS status; +--enable_query_log + +--connection server_4 +--let $retry1= query_get_value(SHOW STATUS LIKE 'Slave_retried_transactions', Value, 1) +--source include/start_slave.inc +--source include/sync_with_master_gtid.inc +SELECT * FROM t1 ORDER BY a; +--let $retry2= query_get_value(SHOW STATUS LIKE 'Slave_retried_transactions', Value, 1) +--disable_query_log +eval SELECT IF($retry1=$retry2, "Ok, no retry", + CONCAT("ERROR: ", $retry2-$retry1, " retries during replication (was ", + $retry1, " now ", $retry2, ")")) AS status; +--enable_query_log + + +--echo *** MDEV-6676: Test that the FL_WAITED flag in GTID is preserved in slave binlog *** + +--connection server_2 +--source include/stop_slave.inc +CHANGE MASTER TO master_use_gtid=slave_pos; +SET GLOBAL slave_parallel_mode='optimistic'; + + +--connection server_3 +--source include/stop_slave.inc +CHANGE MASTER TO master_use_gtid=slave_pos; +SET GLOBAL slave_parallel_mode='optimistic'; + + +--connection server_4 +--source include/stop_slave.inc +CHANGE MASTER TO master_use_gtid=slave_pos; +SET GLOBAL slave_parallel_mode='optimistic'; + +--connection server_1 +# Do a lot of updates on same row in sequence. Ensure that all of these but the +# first have to do a lock wait on the master, setting FL_WAITED in the GTID +# event. This should cause all slaves to not attempt to run those updates in +# parallel with prior events, so that no retries are made. + +BEGIN; +UPDATE t1 SET b=b+1 WHERE a=2; + +--connect (con_temp1,127.0.0.1,root,,test,$SERVER_MYPORT_1,) +SET debug_sync="thd_report_wait_for SIGNAL waiting1"; +send UPDATE t1 SET b=b+1 WHERE a=2; +--connection server_1 +SET debug_sync="now WAIT_FOR waiting1"; + +--connect (con_temp2,127.0.0.1,root,,test,$SERVER_MYPORT_1,) +SET debug_sync="thd_report_wait_for SIGNAL waiting2"; +send UPDATE t1 SET b=b+1 WHERE a=2; +--connection server_1 +SET debug_sync="now WAIT_FOR waiting2"; + +--connect (con_temp3,127.0.0.1,root,,test,$SERVER_MYPORT_1,) +SET debug_sync="thd_report_wait_for SIGNAL waiting3"; +send UPDATE t1 SET b=b+1 WHERE a=2; +--connection server_1 +SET debug_sync="now WAIT_FOR waiting3"; + +--connect (con_temp4,127.0.0.1,root,,test,$SERVER_MYPORT_1,) +SET debug_sync="thd_report_wait_for SIGNAL waiting4"; +send UPDATE t1 SET b=b+1 WHERE a=2; +--connection server_1 +SET debug_sync="now WAIT_FOR waiting4"; + +--connect (con_temp5,127.0.0.1,root,,test,$SERVER_MYPORT_1,) +SET debug_sync="thd_report_wait_for SIGNAL waiting5"; +send UPDATE t1 SET b=b+1 WHERE a=2; +--connection server_1 +SET debug_sync="now WAIT_FOR waiting5"; + +--connect (con_temp6,127.0.0.1,root,,test,$SERVER_MYPORT_1,) +SET debug_sync="thd_report_wait_for SIGNAL waiting6"; +send UPDATE t1 SET b=b+1 WHERE a=2; +--connection server_1 +SET debug_sync="now WAIT_FOR waiting6"; + +--connect (con_temp7,127.0.0.1,root,,test,$SERVER_MYPORT_1,) +SET debug_sync="thd_report_wait_for SIGNAL waiting7"; +send UPDATE t1 SET b=b+1 WHERE a=2; +--connection server_1 +SET debug_sync="now WAIT_FOR waiting7"; + +--connect (con_temp8,127.0.0.1,root,,test,$SERVER_MYPORT_1,) +SET debug_sync="thd_report_wait_for SIGNAL waiting8"; +send UPDATE t1 SET b=b+1 WHERE a=2; +--connection server_1 +SET debug_sync="now WAIT_FOR waiting8"; + +COMMIT; +SET debug_sync="RESET"; + +--connection con_temp1 +reap; + +COMMIT; +--connection con_temp2 +reap; + +COMMIT; +--connection con_temp3 +reap; + +COMMIT; +--connection con_temp4 +reap; + +COMMIT; +--connection con_temp5 +reap; + +COMMIT; +--connection con_temp6 +reap; + +COMMIT; +--connection con_temp7 +reap; + +COMMIT; +--connection con_temp8 +reap; + +--connection server_1 +SELECT * FROM t1 ORDER BY a; +--source include/save_master_gtid.inc + +--connection server_2 +--let $retry1= query_get_value(SHOW STATUS LIKE 'Slave_retried_transactions', Value, 1) +--source include/start_slave.inc +--source include/sync_with_master_gtid.inc +SELECT * FROM t1 ORDER BY a; +--let $retry2= query_get_value(SHOW STATUS LIKE 'Slave_retried_transactions', Value, 1) +--disable_query_log +eval SELECT IF($retry1=$retry2, "Ok, no retry", + CONCAT("ERROR: ", $retry2-$retry1, " retries during replication (was ", + $retry1, " now ", $retry2, ")")) AS status; +--enable_query_log + +--connection server_3 +--let $retry1= query_get_value(SHOW STATUS LIKE 'Slave_retried_transactions', Value, 1) +--source include/start_slave.inc +--source include/sync_with_master_gtid.inc +SELECT * FROM t1 ORDER BY a; +--let $retry2= query_get_value(SHOW STATUS LIKE 'Slave_retried_transactions', Value, 1) +--disable_query_log +eval SELECT IF($retry1=$retry2, "Ok, no retry", + CONCAT("ERROR: ", $retry2-$retry1, " retries during replication (was ", + $retry1, " now ", $retry2, ")")) AS status; +--enable_query_log + +--connection server_4 +--let $retry1= query_get_value(SHOW STATUS LIKE 'Slave_retried_transactions', Value, 1) +--source include/start_slave.inc +--source include/sync_with_master_gtid.inc +SELECT * FROM t1 ORDER BY a; +--let $retry2= query_get_value(SHOW STATUS LIKE 'Slave_retried_transactions', Value, 1) +--disable_query_log +eval SELECT IF($retry1=$retry2, "Ok, no retry", + CONCAT("ERROR: ", $retry2-$retry1, " retries during replication (was ", + $retry1, " now ", $retry2, ")")) AS status; +--enable_query_log + + +# Clean up + +--connection server_2 +--source include/stop_slave.inc +SET GLOBAL slave_parallel_mode=@old_parallel_mode; +SET GLOBAL slave_parallel_threads=@old_parallel_threads; +--source include/start_slave.inc + +--connection server_3 +--source include/stop_slave.inc +SET GLOBAL slave_parallel_mode=@old_parallel_mode; +SET GLOBAL slave_parallel_threads=@old_parallel_threads; +--source include/start_slave.inc + +--connection server_4 +--source include/stop_slave.inc +SET GLOBAL slave_parallel_mode=@old_parallel_mode; +SET GLOBAL slave_parallel_threads=@old_parallel_threads; +--source include/start_slave.inc + +--connection server_1 +DROP TABLE t1; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_parallel_multilevel2.cnf b/mysql-test/suite/rpl/t/rpl_parallel_multilevel2.cnf new file mode 100644 index 00000000..4e1d3878 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_parallel_multilevel2.cnf @@ -0,0 +1,17 @@ +!include ../my.cnf + +[mysqld.1] +log-slave-updates +loose-innodb + +[mysqld.2] +log-slave-updates +loose-innodb + +[mysqld.3] +log-slave-updates +loose-innodb + +[ENV] +SERVER_MYPORT_3= @mysqld.3.port +SERVER_MYSOCK_3= @mysqld.3.socket diff --git a/mysql-test/suite/rpl/t/rpl_parallel_multilevel2.test b/mysql-test/suite/rpl/t/rpl_parallel_multilevel2.test new file mode 100644 index 00000000..4125394e --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_parallel_multilevel2.test @@ -0,0 +1,80 @@ +--source include/have_innodb.inc +--let $rpl_topology=1->2->3 +--source include/rpl_init.inc + +--echo *** MDEV-7668: Intermediate master groups CREATE with INSERT, causing parallel replication failure *** + +--connection server_1 +SET @old_updates= @@GLOBAL.binlog_direct_non_transactional_updates; +SET GLOBAL binlog_direct_non_transactional_updates=OFF; +SET SESSION binlog_direct_non_transactional_updates=OFF; +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +CREATE TABLE t1 (a int PRIMARY KEY, b INT) ENGINE=InnoDB; +--save_master_pos + +--connection server_2 +--sync_with_master +--save_master_pos +--source include/stop_slave.inc +SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads; +SET GLOBAL slave_parallel_threads=10; +SET @old_commit_count=@@GLOBAL.binlog_commit_wait_count; +SET GLOBAL binlog_commit_wait_count=2; +SET @old_commit_usec=@@GLOBAL.binlog_commit_wait_usec; +SET GLOBAL binlog_commit_wait_usec=2000000; +SET @old_updates= @@GLOBAL.binlog_direct_non_transactional_updates; +SET GLOBAL binlog_direct_non_transactional_updates=OFF; +SET SESSION binlog_direct_non_transactional_updates=OFF; +CHANGE MASTER TO master_use_gtid=current_pos; + +--connection server_3 +--sync_with_master +--save_master_pos +SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads; +--source include/stop_slave.inc +SET GLOBAL slave_parallel_threads=10; +CHANGE MASTER TO master_use_gtid=current_pos; + + +--connection server_1 + +BEGIN; +CREATE TEMPORARY TABLE t2 (a INT PRIMARY KEY) ENGINE=MEMORY; +COMMIT; +INSERT INTO t2 VALUES (1); +INSERT INTO t1 SELECT a, a*10 FROM t2; +DROP TABLE t2; +--source include/save_master_gtid.inc + +--connection server_2 +--source include/start_slave.inc +--source include/sync_with_master_gtid.inc +SELECT * FROM t1 ORDER BY a; + +--connection server_3 +--source include/start_slave.inc +--source include/sync_with_master_gtid.inc +SELECT * FROM t1 ORDER BY a; + + +# Clean up + +--connection server_2 +--source include/stop_slave.inc +SET GLOBAL slave_parallel_threads=@old_parallel_threads; +SET GLOBAL binlog_commit_wait_count=@old_commit_count; +SET GLOBAL binlog_commit_wait_usec=@old_commit_usec; +SET GLOBAL binlog_direct_non_transactional_updates= @old_updates; +--source include/start_slave.inc + +--connection server_3 +--source include/stop_slave.inc +SET GLOBAL slave_parallel_threads=@old_parallel_threads; +--source include/start_slave.inc + +--connection server_1 +SET GLOBAL binlog_direct_non_transactional_updates= @old_updates; +CALL mtr.add_suppression("Statement accesses nontransactional table as well as transactional or temporary table"); +DROP TABLE t1; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_parallel_no_log_slave_updates-slave.opt b/mysql-test/suite/rpl/t/rpl_parallel_no_log_slave_updates-slave.opt new file mode 100644 index 00000000..acd68493 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_parallel_no_log_slave_updates-slave.opt @@ -0,0 +1 @@ +--log-slave-updates=0 diff --git a/mysql-test/suite/rpl/t/rpl_parallel_no_log_slave_updates.test b/mysql-test/suite/rpl/t/rpl_parallel_no_log_slave_updates.test new file mode 100644 index 00000000..75db619d --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_parallel_no_log_slave_updates.test @@ -0,0 +1,201 @@ +--source include/have_innodb.inc +--source include/have_debug.inc +--source include/have_debug_sync.inc +--source include/have_binlog_format_statement.inc +--let $rpl_topology=1->2 +--source include/rpl_init.inc + +--echo *** Test killing transaction waiting in commit for previous transaction to commit, when not using 2-phase commit *** + +--connection server_2 +SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads; +--source include/stop_slave.inc +SET GLOBAL slave_parallel_threads=10; +CHANGE MASTER TO master_use_gtid=slave_pos; +--source include/start_slave.inc + +--connection server_1 +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +# 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; +CREATE TABLE t3 (a INT PRIMARY KEY, b INT) ENGINE=InnoDB; +--save_master_pos + +--connection server_2 +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; +--sync_with_master + + +# Set up three transactions on the master that will be group-committed +# together so they can be replicated in parallel on the slave. +--connect (con_temp3,127.0.0.1,root,,test,$SERVER_MYPORT_1,) +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued1 WAIT_FOR master_cont1'; +SET binlog_format=statement; +send INSERT INTO t3 VALUES (31, foo(31, + 'ha_commit_one_phase WAIT_FOR t2_waiting', + 'commit_one_phase_2 SIGNAL t1_ready WAIT_FOR t1_cont')); + +--connection server_1 +SET debug_sync='now WAIT_FOR master_queued1'; + +--connect (con_temp4,127.0.0.1,root,,test,$SERVER_MYPORT_1,) +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued2'; +SET binlog_format=statement; +BEGIN; +# This insert is just so we can get T2 to wait while a query is running that we +# can see in SHOW PROCESSLIST so we can get its thread_id to kill later. +INSERT INTO t3 VALUES (32, foo(32, + 'ha_write_row_end SIGNAL t2_query WAIT_FOR t2_cont', + '')); +# This insert sets up debug_sync points so that T2 will tell when it is at its +# wait point where we want to kill it - and when it has been killed. +INSERT INTO t3 VALUES (33, foo(33, + 'wait_for_prior_commit_waiting SIGNAL t2_waiting', + 'wait_for_prior_commit_killed SIGNAL t2_killed')); +send COMMIT; + +--connection server_1 +SET debug_sync='now WAIT_FOR master_queued2'; + +--connect (con_temp5,127.0.0.1,root,,test,$SERVER_MYPORT_1,) +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued3'; +SET binlog_format=statement; +send INSERT INTO t3 VALUES (34, foo(34, + '', + '')); + +--connection server_1 +SET debug_sync='now WAIT_FOR master_queued3'; +SET debug_sync='now SIGNAL master_cont1'; + +--connection con_temp3 +REAP; +--connection con_temp4 +REAP; +--connection con_temp5 +REAP; + +--connection server_1 +SELECT * FROM t3 WHERE a >= 30 ORDER BY a; + +--connection server_2 +SET sql_log_bin=0; +CALL mtr.add_suppression("Query execution was interrupted"); +CALL mtr.add_suppression("Commit failed due to failure of an earlier commit on which this one depends"); +CALL mtr.add_suppression("Slave: Connection was killed"); +SET sql_log_bin=1; +# Wait until T2 is inside executing its insert of 32, then find it in SHOW +# PROCESSLIST to know its thread id for KILL later. +SET debug_sync='now WAIT_FOR t2_query'; +--let $thd_id= `SELECT ID FROM INFORMATION_SCHEMA.PROCESSLIST WHERE INFO LIKE '%foo(32%' AND INFO NOT LIKE '%LIKE%'` +SET debug_sync='now SIGNAL t2_cont'; + +# Wait until T2 has entered its wait for T1 to commit, and T1 has +# progressed into its commit phase. +SET debug_sync='now WAIT_FOR t1_ready'; + +# Now kill the transaction T2. +--replace_result $thd_id THD_ID +eval KILL $thd_id; + +# Wait until T2 has reacted on the kill. +SET debug_sync='now WAIT_FOR t2_killed'; + +# Now we can allow T1 to proceed. +SET debug_sync='now SIGNAL t1_cont'; + +--let $slave_sql_errno= 1317,1927,1963 +--source include/wait_for_slave_sql_error.inc +STOP SLAVE IO_THREAD; +SELECT * FROM t3 WHERE a >= 30 ORDER BY a; + +# Now we have to disable the debug_sync statements, so they do not trigger +# when the events are retried. +SET GLOBAL slave_parallel_threads=0; +SET GLOBAL slave_parallel_threads=10; +SET sql_log_bin=0; +DROP FUNCTION foo; +--delimiter || +CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) + RETURNS INT DETERMINISTIC + BEGIN + RETURN x; + END +|| +--delimiter ; +SET sql_log_bin=1; + +--connection server_1 +INSERT INTO t3 VALUES (39,0); +--save_master_pos + +--connection server_2 +--source include/start_slave.inc +--sync_with_master +SELECT * FROM t3 WHERE a >= 30 ORDER BY a; +# Restore the foo() function. +SET sql_log_bin=0; +DROP FUNCTION foo; +--delimiter || +CREATE FUNCTION foo(x INT, d1 VARCHAR(500), d2 VARCHAR(500)) + RETURNS INT DETERMINISTIC + BEGIN + IF d1 != '' THEN + SET debug_sync = d1; + END IF; + IF d2 != '' THEN + SET debug_sync = d2; + END IF; + RETURN x; + END +|| +--delimiter ; +SET sql_log_bin=1; + + +--connection server_2 +# Respawn all worker threads to clear any left-over debug_sync or other stuff. +--source include/stop_slave.inc +SET GLOBAL slave_parallel_threads=0; +SET GLOBAL slave_parallel_threads=10; +--source include/start_slave.inc + + +--connection server_2 +--source include/stop_slave.inc +SET GLOBAL slave_parallel_threads=@old_parallel_threads; +SET debug_sync = 'reset'; +--source include/start_slave.inc + +--connection server_1 +DROP function foo; +DROP TABLE t3; +SET debug_sync = 'reset'; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_parallel_optimistic.test b/mysql-test/suite/rpl/t/rpl_parallel_optimistic.test new file mode 100644 index 00000000..f5e48282 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_parallel_optimistic.test @@ -0,0 +1,583 @@ +--source include/have_innodb.inc +--source include/have_debug.inc +--source include/have_debug_sync.inc +--let $rpl_topology=1->2 +--source include/rpl_init.inc + +call mtr.add_suppression("Deadlock found when trying to get lock; try restarting transaction"); +call mtr.add_suppression("Can't find record in 't1'"); +call mtr.add_suppression("Can't find record in 't2'"); + +--connection server_1 +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +CREATE TABLE t1 (a int PRIMARY KEY, b INT) ENGINE=InnoDB; +--save_master_pos + +--connection server_2 +--sync_with_master +SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads; +--source include/stop_slave.inc +SET GLOBAL slave_parallel_threads=10; +CHANGE MASTER TO master_use_gtid=slave_pos; +SET @old_parallel_mode=@@GLOBAL.slave_parallel_mode; +SET GLOBAL slave_parallel_mode='optimistic'; +# Run the first part of the test with high batch size and see that +# old rows remain in the table. +SET @old_gtid_cleanup_batch_size= @@GLOBAL.gtid_cleanup_batch_size; +SET GLOBAL gtid_cleanup_batch_size= 1000000; + + +--connection server_1 + +INSERT INTO t1 VALUES(1,1); +BEGIN; +INSERT INTO t1 VALUES(2,1); +INSERT INTO t1 VALUES(3,1); +COMMIT; + +# Do a bunch of INSERT/DELETE on the same rows, bound to conflict. +# We will get a lot of rollbacks, probably, but they should be handled without +# any visible errors. + +DELETE FROM t1 WHERE a=2; +INSERT INTO t1 VALUES (2,2); +DELETE FROM t1 WHERE a=2; +INSERT INTO t1 VALUES (2,3); +DELETE FROM t1 WHERE a=2; +INSERT INTO t1 VALUES (2,4); +DELETE FROM t1 WHERE a=2; +INSERT INTO t1 VALUES (2,5); + +DELETE FROM t1 WHERE a=3; +INSERT INTO t1 VALUES(3,2); +DELETE FROM t1 WHERE a=1; +INSERT INTO t1 VALUES(1,2); +DELETE FROM t1 WHERE a=3; +INSERT INTO t1 VALUES(3,3); + +DELETE FROM t1 WHERE a=2; +INSERT INTO t1 VALUES (2,6); +--source include/save_master_gtid.inc +SELECT * FROM t1 ORDER BY a; + +--connection server_2 +--source include/start_slave.inc +--source include/sync_with_master_gtid.inc +SELECT * FROM t1 ORDER BY a; +#SHOW STATUS LIKE 'Slave_retried_transactions'; + + +--echo *** Test a bunch of non-transactional/DDL event groups. *** + +--connection server_2 +--source include/stop_slave.inc + +--connection server_1 + +INSERT INTO t1 VALUES (4,4); +INSERT INTO t1 VALUES (5,5); +CREATE TABLE t2 (a INT PRIMARY KEY) ENGINE=InnoDB; +INSERT INTO t2 VALUES (1); +CREATE TABLE t3 (a INT PRIMARY KEY) ENGINE=MyISAM; +ALTER TABLE t2 ADD b INT; +INSERT INTO t2 VALUES (2,2); +ALTER TABLE t2 DROP b; +INSERT INTO t2 VALUES (3); +ALTER TABLE t2 ADD c INT; +INSERT INTO t2 VALUES (4,5); +INSERT INTO t2 VALUES (5,5); +INSERT INTO t3 VALUES (1); +UPDATE t2 SET c=NULL WHERE a=4; +ALTER TABLE t2 ADD UNIQUE (c); +INSERT INTO t2 VALUES (6,6); +UPDATE t2 SET c=c+100 WHERE a=2; +INSERT INTO t3(a) VALUES (2); +DELETE FROM t3 WHERE a=2; +INSERT INTO t3(a) VALUES (2); +DELETE FROM t3 WHERE a=2; +ALTER TABLE t3 CHANGE a c INT NOT NULL; +INSERT INTO t3(c) VALUES (2); +DELETE FROM t3 WHERE c=2; +INSERT INTO t3 SELECT a+200 FROM t2; +DELETE FROM t3 WHERE c >= 200; +INSERT INTO t3 SELECT a+200 FROM t2; +--source include/save_master_gtid.inc +SELECT * FROM t1 ORDER BY a; +SELECT * FROM t2 ORDER BY a; +SELECT * FROM t3 ORDER BY c; + +--connection server_2 +--source include/start_slave.inc +--source include/sync_with_master_gtid.inc +SELECT * FROM t1 ORDER BY a; +SELECT * FROM t2 ORDER BY a; +SELECT * FROM t3 ORDER BY c; +# Check that we have a bunch of old rows left-over - they were not deleted +# due to high @@gtid_cleanup_batch_size. Then set a low +# @@gtid_cleanup_batch_size so we can test that rows start being deleted. +SELECT IF(COUNT(*) >= 30, "OK", CONCAT("Error: too few old rows found: ", COUNT(*))) + FROM mysql.gtid_slave_pos; +SET GLOBAL gtid_cleanup_batch_size=1; + + +--echo *** Test @@skip_parallel_replication. *** + +--connection server_2 +--source include/stop_slave.inc +--let $retry1= query_get_value(SHOW STATUS LIKE 'Slave_retried_transactions', Value, 1) + +--connection server_1 +# We do a bunch of conflicting transactions on the master with +# skip_parallel_replication set to true, and check that we do not +# get any retries on the slave. + +UPDATE t1 SET b=10 WHERE a=3; +SET SESSION skip_parallel_replication=1; +UPDATE t1 SET b=20 WHERE a=3; +UPDATE t1 SET b=30 WHERE a=3; +UPDATE t1 SET b=50 WHERE a=3; +UPDATE t1 SET b=80 WHERE a=3; +UPDATE t1 SET b=130 WHERE a=3; +UPDATE t1 SET b=210 WHERE a=3; +UPDATE t1 SET b=340 WHERE a=3; +UPDATE t1 SET b=550 WHERE a=3; +UPDATE t1 SET b=890 WHERE a=3; +SET SESSION skip_parallel_replication=0; +SELECT * FROM t1 ORDER BY a; +--source include/save_master_gtid.inc + +--connection server_2 +--source include/start_slave.inc +--source include/sync_with_master_gtid.inc +SELECT * FROM t1 ORDER BY a; +--let $retry2= query_get_value(SHOW STATUS LIKE 'Slave_retried_transactions', Value, 1) +--disable_query_log +eval SELECT IF($retry1=$retry2, "Ok, no retry", + CONCAT("ERROR: ", $retry2-$retry1, " retries during replication (was ", + $retry1, " now ", $retry2, ")")) AS status; +--enable_query_log + + +--echo *** Test that we do not replicate in parallel transactions that had row lock waits on the master *** + +--connection server_2 +--source include/stop_slave.inc +--let $retry1= query_get_value(SHOW STATUS LIKE 'Slave_retried_transactions', Value, 1) + +--connection server_1 +# Setup a bunch of transactions that all needed to wait. +--connect (m1,127.0.0.1,root,,test,$SERVER_MYPORT_1,) +--connect (m2,127.0.0.1,root,,test,$SERVER_MYPORT_1,) +--connect (m3,127.0.0.1,root,,test,$SERVER_MYPORT_1,) +--connect (m4,127.0.0.1,root,,test,$SERVER_MYPORT_1,) +--connect (m5,127.0.0.1,root,,test,$SERVER_MYPORT_1,) +--connect (m6,127.0.0.1,root,,test,$SERVER_MYPORT_1,) +--connect (m7,127.0.0.1,root,,test,$SERVER_MYPORT_1,) +--connect (m8,127.0.0.1,root,,test,$SERVER_MYPORT_1,) + +--connection default +BEGIN; UPDATE t1 SET b=b+1 WHERE a=3; + +--connection m1 +SET debug_sync='thd_report_wait_for SIGNAL waiting1'; +send UPDATE t1 SET b=1001 WHERE a=3; +--connection default +SET debug_sync='now WAIT_FOR waiting1'; + +--connection m2 +BEGIN; +UPDATE t1 SET b=1002 WHERE a=5; +SET debug_sync='thd_report_wait_for SIGNAL waiting2'; +send UPDATE t1 SET b=102 WHERE a=3; +--connection default +SET debug_sync='now WAIT_FOR waiting2'; + +UPDATE t1 SET b=1000 WHERE a=1; +--connection m3 +SET debug_sync='thd_report_wait_for SIGNAL waiting3'; +send UPDATE t1 SET b=1003 WHERE a=5; +--connection default +SET debug_sync='now WAIT_FOR waiting3'; + +--connection m4 +SET debug_sync='thd_report_wait_for SIGNAL waiting4'; +send UPDATE t1 SET b=1004 WHERE a=3; +--connection default +SET debug_sync='now WAIT_FOR waiting4'; + +--connection m5 +SET debug_sync='thd_report_wait_for SIGNAL waiting5'; +send UPDATE t1 SET b=1005 WHERE a=5; +--connection default +SET debug_sync='now WAIT_FOR waiting5'; + +--connection m6 +SET debug_sync='thd_report_wait_for SIGNAL waiting6'; +send UPDATE t1 SET b=1006 WHERE a=1; +--connection default +SET debug_sync='now WAIT_FOR waiting6'; + +--connection m7 +SET debug_sync='thd_report_wait_for SIGNAL waiting7'; +send UPDATE t1 SET b=1007 WHERE a=5; +--connection default +SET debug_sync='now WAIT_FOR waiting7'; + +--connection m8 +SET debug_sync='thd_report_wait_for SIGNAL waiting8'; +send UPDATE t1 SET b=1008 WHERE a=3; +--connection default +SET debug_sync='now WAIT_FOR waiting8'; + +--connection default +COMMIT; +--connection m1 +REAP; +--connection m2 +REAP; +COMMIT; +--connection m3 +REAP; +--connection m4 +REAP; +--connection m5 +REAP; +--connection m6 +REAP; +--connection m7 +REAP; +--connection m8 +REAP; +--connection default +SET debug_sync='RESET'; +SELECT * FROM t1 ORDER BY a; +--source include/save_master_gtid.inc + +--connection server_2 +--source include/start_slave.inc +--source include/sync_with_master_gtid.inc +SELECT * FROM t1 ORDER BY a; +--let $retry2= query_get_value(SHOW STATUS LIKE 'Slave_retried_transactions', Value, 1) +--disable_query_log +eval SELECT IF($retry1=$retry2, "Ok, no retry", + CONCAT("ERROR: ", $retry2-$retry1, " retries during replication (was ", + $retry1, " now ", $retry2, ")")) AS status; +--enable_query_log + + +--echo *** Test that we replicate correctly when using READ COMMITTED and binlog_format=MIXED on the slave *** + +--connection server_2 +--source include/stop_slave.inc +SET @old_format= @@GLOBAL.binlog_format; +# Use MIXED format; we cannot binlog ROW events on slave in STATEMENT format. +SET GLOBAL binlog_format= MIXED; +SET @old_isolation= @@GLOBAL.tx_isolation; +SET GLOBAL TRANSACTION ISOLATION LEVEL READ COMMITTED; +# Reset the worker threads to make the new settings take effect. +SET GLOBAL slave_parallel_threads=0; +SET GLOBAL slave_parallel_threads=10; + +--connection server_1 +DROP TABLE t1, t2; +CREATE TABLE t1 (a int PRIMARY KEY, b INT) ENGINE=InnoDB; +CREATE TABLE t2 (a int PRIMARY KEY, b INT) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1,0), (2,0), (3,0); +INSERT INTO t2 VALUES (1,0), (2,0); +INSERT INTO t1 SELECT 4, COUNT(*) FROM t2; +INSERT INTO t2 SELECT 4, COUNT(*) FROM t1; + +INSERT INTO t1 SELECT 5, COUNT(*) FROM t2; +INSERT INTO t2 SELECT 5, COUNT(*) FROM t1; + +INSERT INTO t2 SELECT 6, COUNT(*) FROM t1; +INSERT INTO t1 SELECT 6, COUNT(*) FROM t2; + +INSERT INTO t1 SELECT 7, COUNT(*) FROM t2; +INSERT INTO t2 SELECT 7, COUNT(*) FROM t1; + +INSERT INTO t2 SELECT 8, COUNT(*) FROM t1; +INSERT INTO t1 SELECT 8, COUNT(*) FROM t2; + +INSERT INTO t2 SELECT 9, COUNT(*) FROM t1; +INSERT INTO t1 SELECT 9, COUNT(*) FROM t2; + +INSERT INTO t1 SELECT 10, COUNT(*) FROM t2; +INSERT INTO t2 SELECT 10, COUNT(*) FROM t1; + +SELECT * FROM t1 ORDER BY a; +SELECT * FROM t2 ORDER BY a; +--source include/save_master_gtid.inc + +--connection server_2 +--source include/start_slave.inc +--source include/sync_with_master_gtid.inc +SELECT * FROM t1 ORDER BY a; +SELECT * FROM t2 ORDER BY a; + +--source include/stop_slave.inc +SET GLOBAL binlog_format= @old_format; +SET GLOBAL tx_isolation= @old_isolation; +--source include/start_slave.inc + + +--echo *** MDEV-7888: ANALYZE TABLE does wakeup_subsequent_commits(), causing wrong binlog order and parallel replication hang *** + +--connection server_1 +DROP TABLE t1, t2, t3; +CREATE TABLE t1 (a INT PRIMARY KEY, b INT) ENGINE=InnoDB; +CREATE TABLE t2 (a INT PRIMARY KEY, b INT) ENGINE=InnoDB; +CREATE TABLE t3 (a INT PRIMARY KEY, b INT) ENGINE=MyISAM; +INSERT INTO t2 VALUES (1,1), (2,1), (3,1), (4,1), (5,1); +--source include/save_master_gtid.inc + +--connection server_2 +--source include/sync_with_master_gtid.inc +--source include/stop_slave.inc +SET @old_debug= @@GLOBAL.debug_dbug; +SET GLOBAL debug_dbug= '+d,inject_analyze_table_sleep'; + +--connection server_1 +# The bug was that ANALYZE TABLE would call +# wakeup_subsequent_commits() too early, allowing the following +# transaction in the same group to run ahead and binlog and free the +# GCO. Then we get wrong binlog order and later access freed GCO, +# which causes lost wakeup of following GCO and thus replication hang. +# We injected a small sleep in ANALYZE to make the race easier to hit (this +# can only cause false negatives in versions with the bug, not false positives, +# so sleep is ok here. And it's in general not possible to trigger reliably +# the race with debug_sync, since the bugfix makes the race impossible). + +ALTER TABLE t2 COMMENT "123abc"; +ANALYZE TABLE t2; +INSERT INTO t1 VALUES (1,2); +INSERT INTO t1 VALUES (2,2); +INSERT INTO t1 VALUES (3,2); +INSERT INTO t1 VALUES (4,2); +INSERT INTO t3 VALUES (1,3); +ALTER TABLE t2 COMMENT "hello, world"; +BEGIN; +INSERT INTO t1 VALUES (5,4); +INSERT INTO t1 VALUES (6,4); +INSERT INTO t1 VALUES (7,4); +INSERT INTO t1 VALUES (8,4); +INSERT INTO t1 VALUES (9,4); +INSERT INTO t1 VALUES (10,4); +INSERT INTO t1 VALUES (11,4); +INSERT INTO t1 VALUES (12,4); +INSERT INTO t1 VALUES (13,4); +INSERT INTO t1 VALUES (14,4); +INSERT INTO t1 VALUES (15,4); +INSERT INTO t1 VALUES (16,4); +INSERT INTO t1 VALUES (17,4); +INSERT INTO t1 VALUES (18,4); +INSERT INTO t1 VALUES (19,4); +INSERT INTO t1 VALUES (20,4); +COMMIT; +INSERT INTO t1 VALUES (21,5); +INSERT INTO t1 VALUES (22,5); + +SELECT * FROM t1 ORDER BY a; +SELECT * FROM t2 ORDER BY a; +SELECT * FROM t3 ORDER BY a; +--source include/save_master_gtid.inc + +--connection server_2 +--source include/start_slave.inc +--source include/sync_with_master_gtid.inc + +SELECT * FROM t1 ORDER BY a; +SELECT * FROM t2 ORDER BY a; +SELECT * FROM t3 ORDER BY a; + +--source include/stop_slave.inc +SET GLOBAL debug_dbug= @old_debug; +--source include/start_slave.inc + +--echo *** MDEV-7929: record_gtid() for non-transactional event group calls wakeup_subsequent_commits() too early, causing slave hang. *** + +--connection server_2 +--source include/stop_slave.inc +SET @old_dbug= @@GLOBAL.debug_dbug; +# The bug was that record_gtid(), when there is no existing transaction from +# a DML event being replicated, would commit its own transaction. This wrongly +# caused wakeup_subsequent_commits(), with similar consequences as MDEV-7888 +# above. We simulate this condition with a small sleep in record_gtid() for +# a specific ANALYZE that we binlog with server id 100. +SET GLOBAL debug_dbug= '+d,inject_record_gtid_serverid_100_sleep'; + +--connection server_1 + +ALTER TABLE t3 COMMENT "DDL statement 1"; +INSERT INTO t1 VALUES (30,0); +INSERT INTO t1 VALUES (31,0); +INSERT INTO t1 VALUES (32,0); +INSERT INTO t1 VALUES (33,0); +INSERT INTO t1 VALUES (34,0); +INSERT INTO t1 VALUES (35,0); +INSERT INTO t1 VALUES (36,0); +SET @old_server_id= @@SESSION.server_id; +SET SESSION server_id= 100; +ANALYZE TABLE t2; +SET SESSION server_id= @old_server_id; +INSERT INTO t1 VALUES (37,0); +ALTER TABLE t3 COMMENT "DDL statement 2"; +INSERT INTO t1 VALUES (38,0); +INSERT INTO t1 VALUES (39,0); +ALTER TABLE t3 COMMENT "DDL statement 3"; + +SELECT * FROM t1 WHERE a >= 30 ORDER BY a; + +--source include/save_master_gtid.inc + + +--connection server_2 +--source include/start_slave.inc +--source include/sync_with_master_gtid.inc +SELECT * FROM t1 WHERE a >= 30 ORDER BY a; + + +--source include/stop_slave.inc +SET GLOBAL debug_dbug= @old_debug; +--source include/start_slave.inc + + +--echo *** MDEV-8113: ALTER TABLE causes slave hang in optimistic parallel replication *** + +--connection server_2 +--source include/stop_slave.inc + +--connection server_1 +ALTER TABLE t2 ADD c INT; +INSERT INTO t2 (a,b) VALUES (50, 0); +INSERT INTO t2 (a,b) VALUES (51, 1); +INSERT INTO t2 (a,b) VALUES (52, 2); +INSERT INTO t2 (a,b) VALUES (53, 3); +INSERT INTO t2 (a,b) VALUES (54, 4); +INSERT INTO t2 (a,b) VALUES (55, 5); +INSERT INTO t2 (a,b) VALUES (56, 6); +INSERT INTO t2 (a,b) VALUES (57, 7); +INSERT INTO t2 (a,b) VALUES (58, 8); +INSERT INTO t2 (a,b) VALUES (59, 9); +ALTER TABLE t2 DROP COLUMN c; +SELECT * FROM t2 WHERE a >= 50 ORDER BY a; +--source include/save_master_gtid.inc + +--connection server_2 +--source include/start_slave.inc +--source include/sync_with_master_gtid.inc +SELECT * FROM t2 WHERE a >= 50 ORDER BY a; + + +--echo *** MDEV-8075: DROP TEMPORARY TABLE not marked as ddl, causing optimistic parallel replication to fail *** + +--connection server_2 +--source include/stop_slave.inc + +--connection server_1 +INSERT INTO t1 VALUES (40, 10); +CREATE TEMPORARY TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB; +INSERT INTO t1 VALUES (41); +BEGIN; +INSERT INTO t2 SELECT a, 20 FROM t1; +DROP TEMPORARY TABLE t1; +COMMIT; +INSERT INTO t1 VALUES (42, 10); +--source include/save_master_gtid.inc +SELECT * FROM t1 WHERE a >= 40 ORDER BY a; +SELECT * FROM t2 WHERE a >= 40 ORDER BY a; + +--connection server_2 +--source include/start_slave.inc +--source include/sync_with_master_gtid.inc +SELECT * FROM t1 WHERE a >= 40 ORDER BY a; +SELECT * FROM t2 WHERE a >= 40 ORDER BY a; + +# partial cleanup to reuse the tables by following tests +--connection server_1 +DELETE FROM t1; +DELETE FROM t2; +--source include/save_master_gtid.inc + +--connection server_2 +--source include/sync_with_master_gtid.inc + +# +# MDEV-13577 optimistic parallel slave errors out to error log unnecessary +# + +# The 1st of the following two trx:s a blocker on slave +--connection server_2 +set global log_warnings=2; +BEGIN; +INSERT INTO t1 SET a=1; + +--connection server_1 +SET @save.binlog_format=@@session.binlog_format; +SET @@SESSION.binlog_format=row; + +BEGIN; + INSERT INTO t1 SET a=1; + INSERT INTO t2 SET a=1; +COMMIT; + +# This transaction is going to win optimistical race with above INSERT +# on slave while being depend on it. That means it will face a kind of temporary error +# and then will retry to succeed. +BEGIN; + DELETE FROM t2; +COMMIT; + +# First make sure DELETE raced indeed to get stuck at retrying stage +# where it runs "realistically" now. There is nomore optimistic error +# in the errorlog, which is downgraded to the warning level (when +# --log-warnings > 1), see above suppression. +--connection server_2 +--let $wait_condition= SELECT COUNT(*) = 1 FROM information_schema.processlist WHERE state = "Waiting for prior transaction to commit" +--source include/wait_condition.inc + +# Next release the 1st trx to commit. +--connection server_2 +ROLLBACK; + +# MDEV-13577 local cleanup: +--connection server_1 +SET @@SESSION.binlog_format= @save.binlog_format; +DELETE FROM t1; +DELETE FROM t2; +--source include/save_master_gtid.inc + +--connection server_2 +--source include/sync_with_master_gtid.inc + +# +# Clean up. +# +--connection server_2 +--source include/stop_slave.inc +set global log_warnings=default; +SET GLOBAL slave_parallel_mode=@old_parallel_mode; +SET GLOBAL slave_parallel_threads=@old_parallel_threads; +--source include/start_slave.inc + +--connection server_1 +DROP TABLE t1, t2, t3; +--source include/save_master_gtid.inc + +--connection server_2 +--source include/sync_with_master_gtid.inc +# Check that old rows are deleted from mysql.gtid_slave_pos. +# Deletion is asynchronous, so use wait_condition.inc. +# Also, there is a small amount of non-determinism in the deletion of old +# rows, so it is not guaranteed that there can never be more than +# @@gtid_cleanup_batch_size rows in the table; so allow a bit of slack +# here. +let $wait_condition= + SELECT COUNT(*) <= 5*@@GLOBAL.gtid_cleanup_batch_size + FROM mysql.gtid_slave_pos; +--source include/wait_condition.inc +eval $wait_condition; +SET GLOBAL gtid_cleanup_batch_size= @old_gtid_cleanup_batch_size; + +--connection server_1 +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_parallel_optimistic_nobinlog.cnf b/mysql-test/suite/rpl/t/rpl_parallel_optimistic_nobinlog.cnf new file mode 100644 index 00000000..b85a84f6 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_parallel_optimistic_nobinlog.cnf @@ -0,0 +1,10 @@ +!include ../my.cnf + +[mysqld.1] +log-slave-updates=0 +loose-innodb + +[mysqld.2] +slave-transaction-retries=100 +log-slave-updates=0 +loose-innodb diff --git a/mysql-test/suite/rpl/t/rpl_parallel_optimistic_nobinlog.test b/mysql-test/suite/rpl/t/rpl_parallel_optimistic_nobinlog.test new file mode 100644 index 00000000..ee0de499 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_parallel_optimistic_nobinlog.test @@ -0,0 +1,77 @@ +--source include/have_innodb.inc +--source include/have_binlog_format_statement.inc +--let $rpl_topology=1->2 +--source include/rpl_init.inc + +--connection server_1 +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +CREATE TABLE t1 (a int PRIMARY KEY, b INT) ENGINE=InnoDB; +CREATE TABLE t2 (a int PRIMARY KEY, b INT) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1,0), (2,0), (3,0); +INSERT INTO t2 VALUES (1,0), (2,0); +--save_master_pos + + +--connection server_2 +--sync_with_master +SET @old_isolation= @@GLOBAL.tx_isolation; +SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads; +--source include/stop_slave.inc +SET GLOBAL TRANSACTION ISOLATION LEVEL READ COMMITTED; +SET GLOBAL slave_parallel_threads=10; +CHANGE MASTER TO master_use_gtid=slave_pos; +SET @old_parallel_mode=@@GLOBAL.slave_parallel_mode; +SET GLOBAL slave_parallel_mode='aggressive'; + + +--echo *** Test that we replicate correctly when using READ COMMITTED and --log-slave-updates=0 on the slave *** + +--connection server_1 + +INSERT INTO t1 SELECT 4, COUNT(*) FROM t2; +INSERT INTO t2 SELECT 4, COUNT(*) FROM t1; + +INSERT INTO t1 SELECT 5, COUNT(*) FROM t2; +INSERT INTO t2 SELECT 5, COUNT(*) FROM t1; + +INSERT INTO t2 SELECT 6, COUNT(*) FROM t1; +INSERT INTO t1 SELECT 6, COUNT(*) FROM t2; + +INSERT INTO t1 SELECT 7, COUNT(*) FROM t2; +INSERT INTO t2 SELECT 7, COUNT(*) FROM t1; + +INSERT INTO t2 SELECT 8, COUNT(*) FROM t1; +INSERT INTO t1 SELECT 8, COUNT(*) FROM t2; + +INSERT INTO t2 SELECT 9, COUNT(*) FROM t1; +INSERT INTO t1 SELECT 9, COUNT(*) FROM t2; + +INSERT INTO t1 SELECT 10, COUNT(*) FROM t2; +INSERT INTO t2 SELECT 10, COUNT(*) FROM t1; + +SELECT * FROM t1 ORDER BY a; +SELECT * FROM t2 ORDER BY a; +--source include/save_master_gtid.inc + +--connection server_2 +--source include/start_slave.inc +--source include/sync_with_master_gtid.inc +SELECT * FROM t1 ORDER BY a; +SELECT * FROM t2 ORDER BY a; + + +--connection server_2 +--source include/stop_slave.inc +SET GLOBAL tx_isolation= @old_isolation; +SET GLOBAL slave_parallel_mode=@old_parallel_mode; +SET GLOBAL slave_parallel_threads=@old_parallel_threads; +--source include/start_slave.inc + +--connection server_1 +DROP TABLE t1, t2; + +--connection server_2 +call mtr.add_suppression("Deadlock found when trying to get lock.*"); + +--source include/rpl_end.inc + diff --git a/mysql-test/suite/rpl/t/rpl_parallel_optimistic_until.test b/mysql-test/suite/rpl/t/rpl_parallel_optimistic_until.test new file mode 100644 index 00000000..508213c9 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_parallel_optimistic_until.test @@ -0,0 +1,465 @@ +--source include/have_innodb.inc +--source include/have_debug.inc +--source include/have_debug_sync.inc +--source include/master-slave.inc +# Format is restricted because the test expects a specific result of +# relay-logging that splits a transaction into two different files. +--source include/have_binlog_format_row.inc + +# +# MDEV-15152 Optimistic parallel slave doesn't cope well with START SLAVE UNTIL +# +--connection slave +--source include/stop_slave.inc +RESET MASTER; +RESET SLAVE; + +--connection master +RESET MASTER; +CREATE TABLE t1 (a int primary key, b text) ENGINE=InnoDB; +--let $a0 = 25 +--eval INSERT INTO t1 SET a=$a0, b='trx0' +# Memorize the position for replication restart from it +--let $pos_trx0 = query_get_value(SHOW MASTER STATUS, Position, 1) + +--connection slave +--source include/start_slave.inc + +--connection master +# --connection slave +--sync_slave_with_master +--source include/stop_slave.inc +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads; +SET GLOBAL slave_parallel_threads=2; +SET @old_parallel_mode=@@GLOBAL.slave_parallel_mode; +SET GLOBAL slave_parallel_mode='optimistic'; + +# Run the slave in the following modes one by one. +# +# 1. the until position is set in the middle of trx2 +# below $pos_trx0 of the last exec position in the first file +# 2. and above $pos_trx0 +# In either case trx2 must commit before slave stops. +# 3. the until postion is inside trx1 +# 4. RELAY log until inside trx1 +# 5. RELAY log until inside a "big" trx +# 6. RELAY log until inside a trx within a sequence of relay logs +# +# Execution flaw for Until_Master_Pos cases follows as: +# create the transaction trx1, trx2 +# logged at the beginning of two subsequent binlog files. +# Set the until position to at the middle of the 2rd transaction. +# Engage the optimistic scheduler while having trx1 execution blocked. +# Lift the block after trx2 has reached waiting its order to commit. +# *Proof 1* +# Observe that the slave applier stops at a correct position. +# In the bug condition it would stop prematurely having the stop position +# in the first file, therefore trx2 not committed. +# Specifically, an internal transaction position until makes the applier to run +# beyond it to commit commit the current transaction. +# *Proof 2* +# Observe the following START SLAVE resumes OK. +# +# Auxiliary third trx3 on master is just for triggering the actual stop +# (whihc is a legacy UNTIL's property). +# trx0 is to produce a specific value of the last executed binlog file:pos +# to emulate the bug condition. +# +# Intermediate checks via SELECT are supposed to succeed +# with putting out value 1. +# +# NOTE: Relay log until tests have to use explicit log names and position +# which may require to adjust with future changes to event formats etc. +# + +--connection slave +SET @old_max_relay_log_size = @@global.max_relay_log_size; +SET @@global.max_relay_log_size=4096; + +--connection master +# trx1 +--let $a=1 +BEGIN; +while (`SELECT $a < $a0`) +{ + --eval INSERT INTO t1 SET a=$a, b='trx1' +--inc $a +} +COMMIT; +--let $fil_1 = query_get_value(SHOW MASTER STATUS, File, 1) +--let $pos_trx1 = query_get_value(SHOW MASTER STATUS, Position, 1) + +FLUSH LOGS; + +# $pos_0 the offset of the first event of trx2 in new file +--let $pos_0=query_get_value(SHOW MASTER STATUS, Position, 1) +# trx2 +--let $a=$a0 +BEGIN; +--eval UPDATE t1 SET b='trx2_0' WHERE a = $a +--eval UPDATE t1 SET b='trx2' WHERE a = $a +COMMIT; +--let $fil_2=query_get_value(SHOW MASTER STATUS, File, 1) +--let $pos_trx2=query_get_value(SHOW MASTER STATUS, Position, 1) + +# trx3 +--let $a=$a0 +--inc $a +--eval INSERT INTO t1 SET a=$a,b='trx3' +--let $pos_trx3=query_get_value(SHOW MASTER STATUS, Position, 1) +--let $a= + + +--echo *** case 1 UNTIL inside trx2 + +--connection slave1 +# Blocker to hold off EXEC_MASTER_LOG_POS advance +BEGIN; + --eval INSERT INTO t1 SET a= 1 +--connection slave +--let $pos_until=`SELECT $pos_trx0 - 1` +--replace_result $pos_0 $pos_until $pos_trx2 +--eval SELECT $pos_0 <= $pos_until AND $pos_until < $pos_trx2 as "pos_until < trx0 and is within trx2" +CHANGE MASTER TO MASTER_USE_GTID=no; +--replace_result $fil_2 file_2 $pos_until +--eval START SLAVE UNTIL MASTER_LOG_FILE = '$fil_2', MASTER_LOG_POS = $pos_until + +--let $wait_condition= SELECT COUNT(*) > 0 FROM information_schema.processlist WHERE state = "Waiting for prior transaction to commit" +--source include/wait_condition.inc + +--connection slave1 +# unblock to see the slave applier stops at $until +ROLLBACK; + +--echo Proof 1: Correct stop +--connection slave +--source include/wait_for_slave_sql_to_stop.inc +--let $file_stop= query_get_value(SHOW SLAVE STATUS, Relay_Master_Log_File, 1) +--let $pos_stop= query_get_value(SHOW SLAVE STATUS, Exec_Master_Log_Pos, 1) +if (`SELECT "$file_stop" != "$fil_2" OR $pos_stop < $pos_until`) +{ + --echo *** ERROR: Slave stopped at $file_stop:$pos_stop which is not $fil_2:$pos_until. + --die +} +--eval SELECT count(*) = 1 as 'trx2 is committed' FROM t1 WHERE b = 'trx2' +--eval SELECT count(*) = 0 as 'trx3 is not committed' FROM t1 WHERE b = 'trx3' + +--echo Proof 2: Resume works out +--source include/start_slave.inc +--connection master +--sync_slave_with_master + + +--echo *** case 2 UNTIL inside trx2 + +--connection slave +--eval DELETE FROM t1 WHERE a <> $a0 +--eval UPDATE t1 SET b='trx0' WHERE a = $a0 + +--connection slave1 +# Blocker to hold off EXEC_MASTER_LOG_POS advance +BEGIN; + --eval INSERT INTO t1 SET a= 1 + +--connection slave +--source include/stop_slave.inc + +--let $pos_until=`SELECT $pos_trx2 - 1` +--replace_result $pos_trx0 $pos_until $pos_trx2 +--eval SELECT $pos_trx0 <= $pos_until AND $pos_until < $pos_trx2 as "pos_until >= trx0 and is within trx2" +--replace_result $fil_1 file_1 $pos_trx0 +--eval CHANGE MASTER TO MASTER_LOG_FILE = '$fil_1', MASTER_LOG_POS = $pos_trx0, MASTER_USE_GTID=no +--replace_result $fil_2 file_2 $pos_until +--eval START SLAVE UNTIL MASTER_LOG_FILE = '$fil_2', MASTER_LOG_POS = $pos_until + +--let $wait_condition= SELECT COUNT(*) > 0 FROM information_schema.processlist WHERE state = "Waiting for prior transaction to commit" +--source include/wait_condition.inc + +--connection slave1 +# unblock to see the slave applier stops at $until +ROLLBACK; + +--echo Proof 1: Correct stop +--connection slave +--source include/wait_for_slave_sql_to_stop.inc +--let $file_stop= query_get_value(SHOW SLAVE STATUS, Relay_Master_Log_File, 1) +--let $pos_stop= query_get_value(SHOW SLAVE STATUS, Exec_Master_Log_Pos, 1) +if (`SELECT "$file_stop" != "$fil_2" OR $pos_stop < $pos_until`) +{ + --echo *** ERROR: Slave stopped at $file_stop:$pos_stop which is not $fil_2:$pos_until. + --die +} +--eval SELECT count(*) = 1 as 'trx2 is committed' FROM t1 WHERE b = 'trx2' +--eval SELECT count(*) = 0 as 'trx3 is not committed' FROM t1 WHERE b = 'trx3' + +--echo Proof 2: Resume works out +--source include/start_slave.inc +--connection master +--sync_slave_with_master + + +--echo *** case 3 UNTIL inside trx1 + +--connection slave +--eval DELETE FROM t1 WHERE a <> $a0 +--eval UPDATE t1 SET b='trx0' WHERE a = $a0 + + +--connection slave1 +# Blocker to hold off EXEC_MASTER_LOG_POS advance +BEGIN; + --eval INSERT INTO t1 SET a= 1; # block trx1 + +--connection slave +--source include/stop_slave.inc + +--let $pos_until=`SELECT $pos_0 - 1` +--replace_result $pos_0 $pos_until $pos_trx2 +--eval SELECT $pos_until < $pos_0 as "pos_until before trx2 start position" +--replace_result $fil_1 file_1 $pos_trx0 +--eval CHANGE MASTER TO MASTER_LOG_FILE = '$fil_1', MASTER_LOG_POS = $pos_trx0, MASTER_USE_GTID=no +--replace_result $fil_2 file_2 $pos_until +--eval START SLAVE UNTIL MASTER_LOG_FILE = '$fil_2', MASTER_LOG_POS = $pos_until + +--connection slave1 +# unblock to see the slave applier stops at $until +ROLLBACK; + +--echo Proof 1: Correct stop +--connection slave +--source include/wait_for_slave_sql_to_stop.inc +--let $file_stop= query_get_value(SHOW SLAVE STATUS, Relay_Master_Log_File, 1) +--let $pos_stop= query_get_value(SHOW SLAVE STATUS, Exec_Master_Log_Pos, 1) +if (`SELECT "$file_stop" != "$fil_2" OR $pos_stop < $pos_until`) +{ + --echo *** ERROR: Slave stopped at $file_stop:$pos_stop which is not $fil_2:$pos_until. + --die +} +--eval SELECT count(*) = $a0-1 as 'trx1 is committed' FROM t1 WHERE b = 'trx1' +--eval SELECT count(*) = 0 as 'trx2 is not committed' FROM t1 WHERE b = 'trx2' + +--echo Proof 2: Resume works out +--source include/start_slave.inc +--connection master +--sync_slave_with_master + + +--echo *** case 4 Relay-log UNTIL inside trx1 + +--connection slave +--eval DELETE FROM t1 WHERE a <> $a0 +--eval UPDATE t1 SET b='trx0' WHERE a = $a0 + +--connection slave1 +# Blocker to hold off EXEC_MASTER_LOG_POS advance +BEGIN; + --eval INSERT INTO t1 SET a= 1; # block trx1 + +--connection slave +--source include/stop_slave.inc +--replace_result $fil_1 file_1 $pos_trx0 +--eval CHANGE MASTER TO MASTER_LOG_FILE = '$fil_1', MASTER_LOG_POS = $pos_trx0, MASTER_USE_GTID=no +START SLAVE IO_THREAD; +--source include/wait_for_slave_io_to_start.inc + +# The following test sets the stop coordinate is set to inside the first event +# of a relay log that holds events of a transaction started in an earlier log. +# Peek the stop position in the middle of trx1, not even on a event boundary. +--let $pos_until=255 +--let $file_rl=slave-relay-bin.000003 +--let $binlog_file=$file_rl + +--let $pos_xid=508 +--let $info= query_get_value(SHOW RELAYLOG EVENTS IN '$file_rl' FROM $pos_xid LIMIT 1, Info, 1) + +if (`SELECT "$info" NOT LIKE "COMMIT /* xid=% */" OR $pos_xid < $pos_until`) +{ + --echo *** Unexpected offset. Refine it to point to the correct XID event! + --die +} + +--replace_result $file_rl file_2 $pos_until +--eval START SLAVE UNTIL RELAY_LOG_FILE = '$file_rl', RELAY_LOG_POS = $pos_until + +--connection slave1 +# unblock to see the slave applier stops at $until +ROLLBACK; + +--echo Proof 1: Correct stop +--connection slave +--source include/wait_for_slave_sql_to_stop.inc +--let $file_stop= query_get_value(SHOW SLAVE STATUS, Relay_Log_File, 1) +--let $pos_stop= query_get_value(SHOW SLAVE STATUS, Relay_Log_Pos, 1) +if (`SELECT strcmp("$file_rl","$file_stop") > -1`) +{ + --echo *** ERROR: Slave stopped at $file_stop:$pos_stop which is not $file_rl:$pos_until. + --die +} + +--eval SELECT count(*) = $a0-1 as 'trx1 is committed' FROM t1 WHERE b = 'trx1' +--eval SELECT count(*) = 0 as 'trx2 is not committed' FROM t1 WHERE b = 'trx2' + +--echo Proof 2: Resume works out +--source include/start_slave.inc +--connection master +--sync_slave_with_master + + + +--echo *** case 5 Relay-log UNTIL inside a "big" trx that spawns few relay logs + +--connection master +CREATE TABLE t2 (a TEXT) ENGINE=InnoDB; +FLUSH LOGS; + +--sync_slave_with_master +--let $file_stop= query_get_value(SHOW SLAVE STATUS, Relay_Log_File, 1) +--let $pos_stop= query_get_value(SHOW SLAVE STATUS, Relay_Log_Pos, 1) +--let $records=`SELECT floor(4*@@global.max_relay_log_size / 1024) + 1` + +--connection slave +--source include/stop_slave.inc + +--connection master +# trx4 +BEGIN; +--let $i=$records +while ($i) +{ + INSERT INTO t2 SET a=repeat('a',1024); + +--dec $i +} +COMMIT; + +# slave will stop there: +--let $file_trx4 = query_get_value(SHOW MASTER STATUS, File, 1) +--let $pos_trx4 = query_get_value(SHOW MASTER STATUS, Position, 1) + +# trx5 +INSERT INTO t2 SET a='a'; +--let $pos_trx5 = query_get_value(SHOW MASTER STATUS, Position, 1) + +--connection slave +START SLAVE IO_THREAD; +--source include/wait_for_slave_io_to_start.inc + +# Set position inside the transaction though the value +# specified is beyond that relay log file. +# The coordianate may point to in a different event in future changes +# but should not move away from inside this big group of events. +# So we don't test which event in the transaction it points to. +--let $pos_until= 4500 +--let $file_rl= slave-relay-bin.000010 + +--replace_result $file_rl file_2 $pos_until +--eval START SLAVE UNTIL RELAY_LOG_FILE = '$file_rl', RELAY_LOG_POS = $pos_until + +--echo Proof 1: Correct stop +--connection slave +--source include/wait_for_slave_sql_to_stop.inc +--let $file_stop= query_get_value(SHOW SLAVE STATUS, Relay_Master_Log_File, 1) +--let $pos_stop= query_get_value(SHOW SLAVE STATUS, Exec_Master_Log_Pos, 1) +# It's showed the actual stop occurred before trx5 +if (`SELECT strcmp("$file_trx4", "$file_stop") <> 0 OR $pos_stop >= $pos_trx5 OR count(*) <> $records FROM t2`) +{ + --echo *** ERROR: Slave stopped at *binlog* $file_stop:$pos_stop which is not $file_trx4:$pos_trx4. + --die +} + +--echo Proof 2: Resume works out +--source include/start_slave.inc +--connection master +--sync_slave_with_master + +--let $diff_tables=master:t2,slave:t2 +--source include/diff_tables.inc + + + +--echo *** case 6 Relay-log UNTIL inside a small trx inside a sequence of relay logs + +--connection slave +--source include/stop_slave.inc + +--connection master +# trx6 +--let $records=`SELECT count(*) FROM t2` +while ($records) +{ + BEGIN; + DELETE FROM t2 LIMIT 1; + COMMIT; +--dec $records +} +COMMIT; + +--connection slave +START SLAVE IO_THREAD; +--source include/wait_for_slave_io_to_start.inc + +--connection master +--source include/sync_slave_io_with_master.inc + +--connection slave +# The relay-log coordinate is not at an event boundary and +# also may change across the server version. +# The test makes its best to check its coherance. +--let $pos_until= 3130 +--let $file_rl= slave-relay-bin.000018 + +--let $pos_gtid = 2987 +--let $info= query_get_value(SHOW RELAYLOG EVENTS IN '$file_rl' FROM $pos_gtid LIMIT 1, Info, 1) + +if (`SELECT "$info" != "BEGIN GTID 0-1-23"`) +{ + --echo *** Unexpected offset. Refine it to point to the correct GTID! + --die +} +--let $pos_event = 3120 +--let $type= query_get_value(SHOW RELAYLOG EVENTS IN '$file_rl' FROM $pos_event LIMIT 1, Event_type, 1) +if (`SELECT "$type" != "Delete_rows_v1"`) +{ + --echo *** Unexpected offset. Refine it to point to the expected event! + --die +} + +--replace_result $file_rl file_2 $pos_until +--eval START SLAVE UNTIL RELAY_LOG_FILE = '$file_rl', RELAY_LOG_POS = $pos_until + +--echo Proof 1: Correct stop +--connection slave +--source include/wait_for_slave_sql_to_stop.inc +--let $file_stop= query_get_value(SHOW SLAVE STATUS, Relay_Log_File, 1) +--let $pos_stop= query_get_value(SHOW SLAVE STATUS, Relay_Log_Pos, 1) +if (`SELECT strcmp("$file_stop", "$file_rl") = -1 OR + strcmp("$file_stop", "$file_rl") = 0 AND $pos_stop < $pos_until`) +{ + --echo *** ERROR: Slave stopped at *relay* $file_stop:$pos_stop which is not $file_rl:$pos_until. + --die +} + +--echo Proof 2: Resume works out +--source include/start_slave.inc +--connection master +--sync_slave_with_master + +--let $diff_tables=master:t2,slave:t2 +--source include/diff_tables.inc + +# +# Clean up. +# +--connection slave +--source include/stop_slave.inc +SET GLOBAL max_relay_log_size=@old_max_relay_log_size; +SET GLOBAL slave_parallel_mode=@old_parallel_mode; +SET GLOBAL slave_parallel_threads=@old_parallel_threads; +--source include/start_slave.inc + +--connection master +DROP TABLE t1, t2; + +--sync_slave_with_master +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_parallel_optimistic_xa.test b/mysql-test/suite/rpl/t/rpl_parallel_optimistic_xa.test new file mode 100644 index 00000000..35c22d1e --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_parallel_optimistic_xa.test @@ -0,0 +1,235 @@ +# The tests verify concurrent execution of replicated (MDEV-742) +# XA transactions in the parallel optimistic mode. + +--source include/have_innodb.inc +--source include/have_perfschema.inc +--source include/master-slave.inc + +# Tests' global declarations +--let $trx = _trx_ + +call mtr.add_suppression("Deadlock found when trying to get lock; try restarting transaction"); +call mtr.add_suppression("WSREP: handlerton rollback failed"); +#call mtr.add_suppression("Can't find record in 't1'"); +CREATE VIEW v_processlist as SELECT * FROM performance_schema.threads where type = 'FOREGROUND'; + +--connection master +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +--save_master_pos + +# Prepare to restart slave into optimistic parallel mode +--connection slave +--sync_with_master +--source include/stop_slave.inc +SET @old_parallel_threads = @@GLOBAL.slave_parallel_threads; +SET @@global.slave_parallel_threads = 7; +SET @old_parallel_mode = @@GLOBAL.slave_parallel_mode; +SET @@global.slave_parallel_mode ='optimistic'; +# Run the first part of the test with high batch size and see that +# old rows remain in the table. +SET @old_gtid_cleanup_batch_size = @@GLOBAL.gtid_cleanup_batch_size; +SET @@global.gtid_cleanup_batch_size = 1000000; + +CHANGE MASTER TO master_use_gtid=slave_pos; + +# LOAD GENERATOR creates XA:s interleaved in binlog when they are from +# different connections. All the following block XA:s of the same connection +# update the same data which challenges slave optimistic scheduler's correctness. +# Slave must eventually apply such load, and correctly (checked). + +--connection master +CREATE TABLE t0 (a int, b INT) ENGINE=InnoDB; +CREATE TABLE t1 (a int PRIMARY KEY, b INT) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1, 0); + + +# I. Logging some sequence of XA:s by one connection. +# +# The slave applier's task is to successfully execute a series of +# Prepare and Complete parts of a sequence of XA:s + +--let $trx_num = 300 +--let $i = $trx_num +--let $conn = master +--disable_query_log +while($i > 0) +{ + # 'decision' to commit 0, or rollback 1 + --let $decision = `SELECT $i % 2` + --eval XA START '$conn$trx$i' + --eval UPDATE t1 SET b = 1 - 2 * $decision WHERE a = 1 + --eval XA END '$conn$trx$i' + --let $one_phase = `SELECT IF(floor(rand()*10)%2, "ONE PHASE", 0)` + if (!$one_phase) + { + --eval XA PREPARE '$conn$trx$i' + --let $one_phase = + } + + --let $term = COMMIT + if ($decision) + { + --let $term = ROLLBACK + --let $one_phase = + } + --eval XA $term '$conn$trx$i' $one_phase + + --dec $i +} +--enable_query_log +--source include/save_master_gtid.inc + +--connection slave +--source include/start_slave.inc +--source include/sync_with_master_gtid.inc +--source include/stop_slave.inc + + +# II. Logging XS:s from multiple connections in random interweaving manner: +# +# in a loop ($i) per connection +# arrange an inner ($k) loop where +# start and prepare an XA; +# decide whether to terminate it and then continue to loop innerly +# OR disconnect to break the inner loop; +# the disconnected one's XA is taken care by 'master' connection +# +# Effectively binlog must collect a well mixed XA- prepared and terminated +# groups for slave to handle. + +--connection master +# Total # of connections +--let $conn_num=53 + +--let $i = $conn_num +--disable_query_log +while($i > 0) +{ + --connect (master_conn$i, 127.0.0.1,root,,test,$MASTER_MYPORT,) +--dec $i +} +--enable_query_log + +--let $i = $conn_num +while($i > 0) +{ + --let $conn_i = conn$i + # $i2 indexes the current connection's "own" row + --let $i2 = `SELECT $i + 2` +--disable_query_log + --connection master_conn$i +--enable_query_log + --disable_query_log + --let $i_conn_id = `SELECT connection_id()` + + --let $decision = 0 + # the row id of the last connection that committed its XA + --let $c_max = 1 + --let $k = 0 + while ($decision < 3) + { + --inc $k + --eval XA START '$conn_i$trx$k' + # UPDATE depends on previously *committed* transactions + --eval UPDATE t1 SET b = b + $k + 1 WHERE a = $c_max + if (`SELECT $k % 2 = 1`) + { + --eval REPLACE INTO t1 VALUES ($i2, $k) + } + if (`SELECT $k % 2 = 0`) + { + --eval DELETE FROM t1 WHERE a = $i2 + } + CREATE TEMPORARY TABLE tmp LIKE t0; + --eval INSERT INTO tmp SET a=$i, b= $k + INSERT INTO t0 SELECT * FROM tmp; + DROP TEMPORARY TABLE tmp; + --eval XA END '$conn_i$trx$k' + + --let $term = COMMIT + --let $decision = `SELECT (floor(rand()*10 % 10) + ($i+$k)) % 4` + if ($decision == 1) + { + --let $term = ROLLBACK + } + if ($decision < 2) + { + --eval XA PREPARE '$conn_i$trx$k' + --eval XA $term '$conn_i$trx$k' + # Iteration counter is taken care *now* + } + if ($decision == 2) + { + --eval XA COMMIT '$conn_i$trx$k' ONE PHASE + } + } + + # $decision = 3 + --eval XA PREPARE '$conn_i$trx$k' + # disconnect now + --disconnect master_conn$i + --connection master + + --let $wait_condition= SELECT count(*) = 0 FROM v_processlist WHERE PROCESSLIST_ID = $i_conn_id + --source include/wait_condition.inc + + --disable_query_log + --let $decision = `SELECT ($i+$k) % 2` + --let $term = COMMIT + if ($decision == 1) + { + --let $term = ROLLBACK + } + --eval XA $term '$conn_i$trx$k' + --let $c_max = $i2 + +--dec $i +} +--enable_query_log +--source include/save_master_gtid.inc + +--connection slave +--source include/start_slave.inc +--source include/sync_with_master_gtid.inc + +# +# Overall consistency check +# +--let $diff_tables= master:t0, slave:t0 +--source include/diff_tables.inc +--let $diff_tables= master:t1, slave:t1 +--source include/diff_tables.inc + + +# +# Clean up. +# +--connection slave +--source include/stop_slave.inc +set global log_warnings=default; +SET GLOBAL slave_parallel_mode=@old_parallel_mode; +SET GLOBAL slave_parallel_threads=@old_parallel_threads; +--source include/start_slave.inc + +--connection master +DROP VIEW v_processlist; +DROP TABLE t0, t1; +--source include/save_master_gtid.inc + +--connection slave +--source include/sync_with_master_gtid.inc +# Check that old rows are deleted from mysql.gtid_slave_pos. +# Deletion is asynchronous, so use wait_condition.inc. +# Also, there is a small amount of non-determinism in the deletion of old +# rows, so it is not guaranteed that there can never be more than +# @@gtid_cleanup_batch_size rows in the table; so allow a bit of slack +# here. +let $wait_condition= + SELECT COUNT(*) <= 5*@@GLOBAL.gtid_cleanup_batch_size + FROM mysql.gtid_slave_pos; +--source include/wait_condition.inc +eval $wait_condition; +SET GLOBAL gtid_cleanup_batch_size= @old_gtid_cleanup_batch_size; + +--connection master +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_parallel_optimistic_xa_lsu_off-slave.opt b/mysql-test/suite/rpl/t/rpl_parallel_optimistic_xa_lsu_off-slave.opt new file mode 100644 index 00000000..88cf77fd --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_parallel_optimistic_xa_lsu_off-slave.opt @@ -0,0 +1 @@ +--log-slave-updates=OFF diff --git a/mysql-test/suite/rpl/t/rpl_parallel_optimistic_xa_lsu_off.test b/mysql-test/suite/rpl/t/rpl_parallel_optimistic_xa_lsu_off.test new file mode 100644 index 00000000..f82b522e --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_parallel_optimistic_xa_lsu_off.test @@ -0,0 +1,2 @@ +# --log-slave-updates OFF version of rpl_parallel_optimistic_xa +--source rpl_parallel_optimistic_xa.test diff --git a/mysql-test/suite/rpl/t/rpl_parallel_partial_binlog_trans.test b/mysql-test/suite/rpl/t/rpl_parallel_partial_binlog_trans.test new file mode 100644 index 00000000..7be26eda --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_parallel_partial_binlog_trans.test @@ -0,0 +1 @@ +--source include/rpl_parallel_partial_binlog_trans.inc diff --git a/mysql-test/suite/rpl/t/rpl_parallel_partition.test b/mysql-test/suite/rpl/t/rpl_parallel_partition.test new file mode 100644 index 00000000..ea6c5dca --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_parallel_partition.test @@ -0,0 +1,81 @@ +--source include/have_partition.inc +--source include/have_innodb.inc +--source include/have_debug.inc +--source include/master-slave.inc + +--connection server_2 +SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads; +--source include/stop_slave.inc +SET @old_dbug= @@GLOBAL.debug_dbug; +SET GLOBAL debug_dbug="+d,inject_wakeup_subsequent_commits_sleep"; +SET GLOBAL slave_parallel_threads=8; + +--echo *** MDEV-8147: Assertion `m_lock_type == 2' failed in handler::ha_close() during parallel replication *** +--connection server_1 +CREATE TABLE E ( + pk INTEGER AUTO_INCREMENT, + col_int_nokey INTEGER /*! NULL */, + col_int_key INTEGER /*! NULL */, + + col_date_key DATE /*! NULL */, + col_date_nokey DATE /*! NULL */, + + col_time_key TIME /*! NULL */, + col_time_nokey TIME /*! NULL */, + + col_datetime_key DATETIME /*! NULL */, + col_datetime_nokey DATETIME /*! NULL */, + + col_varchar_key VARCHAR(1) /*! NULL */, + col_varchar_nokey VARCHAR(1) /*! NULL */, + + PRIMARY KEY (pk), + KEY (col_int_key), + KEY (col_date_key), + KEY (col_time_key), + KEY (col_datetime_key), + KEY (col_varchar_key, col_int_key) + ) ENGINE=InnoDB; + +ALTER TABLE `E` PARTITION BY KEY() PARTITIONS 5; +ALTER TABLE `E` REMOVE PARTITIONING; +--write_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +wait +EOF +--shutdown_server +--source include/wait_until_disconnected.inc +--connection default +--source include/wait_until_disconnected.inc +--append_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +restart: +EOF +--enable_reconnect +--source include/wait_until_connected_again.inc +--connection server_1 +--enable_reconnect +--source include/wait_until_connected_again.inc +CREATE TABLE t1 (a INT PRIMARY KEY); +--save_master_pos + +--connection server_2 +--source include/start_slave.inc +--sync_with_master + +# Re-spawn worker threads to clear dbug injection. +--source include/stop_slave.inc +SET GLOBAL debug_dbug=@old_dbug; +SET GLOBAL slave_parallel_threads=0; +SET GLOBAL slave_parallel_threads=8; +--source include/start_slave.inc + + +# Clean up. +--connection server_2 +--source include/stop_slave.inc +SET GLOBAL slave_parallel_threads=@old_parallel_threads; +--source include/start_slave.inc + +--connection server_1 +DROP TABLE `E`; +DROP TABLE t1; +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_parallel_record_gtid_wakeup.test b/mysql-test/suite/rpl/t/rpl_parallel_record_gtid_wakeup.test new file mode 100644 index 00000000..4529a268 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_parallel_record_gtid_wakeup.test @@ -0,0 +1 @@ +--source include/rpl_parallel_record_gtid_wakeup.inc diff --git a/mysql-test/suite/rpl/t/rpl_parallel_retry.test b/mysql-test/suite/rpl/t/rpl_parallel_retry.test new file mode 100644 index 00000000..97a3a709 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_parallel_retry.test @@ -0,0 +1,486 @@ +--source include/have_innodb.inc +--source include/have_debug.inc +--source include/have_debug_sync.inc +--let $rpl_topology=1->2 +--source include/rpl_init.inc + +--echo *** Test retry of transactions that fail to replicate due to deadlock or similar temporary error. *** + +--connection server_1 +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; +CREATE TABLE t1 (a int PRIMARY KEY, b INT) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1,1); +--save_master_pos + +# 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_2 +SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads; +--source include/stop_slave.inc +SET GLOBAL slave_parallel_threads=5; +--source include/start_slave.inc +--sync_with_master +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; +--source include/stop_slave.inc + +--connection server_1 +SET gtid_seq_no = 100; +BEGIN; +INSERT INTO t1 VALUES (2,1); +UPDATE t1 SET b=b+1 WHERE a=1; +INSERT INTO t1 VALUES (3,1); +COMMIT; +SELECT * FROM t1 ORDER BY a; +--save_master_pos + +--connection server_2 +SET @old_dbug= @@GLOBAL.debug_dbug; +SET GLOBAL debug_dbug="+d,rpl_parallel_simulate_temp_err_gtid_0_x_100"; +let $old_retry= query_get_value(SHOW STATUS LIKE 'Slave_retried_transactions', Value, 1); +--source include/start_slave.inc +--sync_with_master +SET GLOBAL debug_dbug=@old_dbug; +let $new_retry= query_get_value(SHOW STATUS LIKE 'Slave_retried_transactions', Value, 1); +--disable_query_log +eval SELECT $new_retry - $old_retry AS retries; +--enable_query_log + +SELECT * FROM t1 ORDER BY a; + + +--echo *** Test that double retry works when the first retry also fails with temp error *** +--source include/stop_slave.inc + +--connection server_1 +SET gtid_seq_no = 100; +SET @old_server_id = @@server_id; +SET server_id = 10; +BEGIN; +INSERT INTO t1 VALUES (4,1); +UPDATE t1 SET b=b+1 WHERE a=1; +INSERT INTO t1 VALUES (5,1); +INSERT INTO t1 VALUES (6,1); +COMMIT; +SET server_id = @old_server_id; +SELECT * FROM t1 ORDER BY a; +--save_master_pos + +--connection server_2 +SET @old_dbug= @@GLOBAL.debug_dbug; +SET GLOBAL debug_dbug="+d,rpl_parallel_simulate_temp_err_gtid_0_x_100,rpl_parallel_simulate_double_temp_err_gtid_0_x_100"; +let $old_retry= query_get_value(SHOW STATUS LIKE 'Slave_retried_transactions', Value, 1); +--source include/start_slave.inc +--sync_with_master +SET GLOBAL debug_dbug=@old_dbug; +let $new_retry= query_get_value(SHOW STATUS LIKE 'Slave_retried_transactions', Value, 1); +--disable_query_log +eval SELECT $new_retry - $old_retry AS retries; +--enable_query_log + +SELECT * FROM t1 ORDER BY a; + + +--echo *** Test too many retries, eventually causing failure. *** +--source include/stop_slave.inc + +--connection server_1 +SET gtid_seq_no = 100; +SET @old_server_id = @@server_id; +SET server_id = 11; +BEGIN; +INSERT INTO t1 VALUES (7,1); +UPDATE t1 SET b=b+1 WHERE a=1; +INSERT INTO t1 VALUES (8,1); +INSERT INTO t1 VALUES (9,1); +COMMIT; +SET server_id = @old_server_id; +SELECT * FROM t1 ORDER BY a; +--save_master_pos + +--connection server_2 +SET sql_log_bin=0; +CALL mtr.add_suppression("Slave worker thread retried transaction 10 time\\(s\\) in vain, giving up"); +CALL mtr.add_suppression("Slave: Deadlock found when trying to get lock; try restarting transaction"); +CALL mtr.add_suppression("Slave worker thread retried transaction .* in vain, giving up"); +SET sql_log_bin=1; + +SET @old_dbug= @@GLOBAL.debug_dbug; +SET GLOBAL debug_dbug="+d,rpl_parallel_simulate_temp_err_gtid_0_x_100,rpl_parallel_simulate_infinite_temp_err_gtid_0_x_100"; +let $old_retry= query_get_value(SHOW STATUS LIKE 'Slave_retried_transactions', Value, 1); +START SLAVE; +--let $slave_sql_errno= 1213 +--source include/wait_for_slave_sql_error.inc +SET GLOBAL debug_dbug=@old_dbug; +let $new_retry= query_get_value(SHOW STATUS LIKE 'Slave_retried_transactions', Value, 1); +--disable_query_log +eval SELECT $new_retry - $old_retry AS retries; +--enable_query_log + +SELECT * FROM t1 ORDER BY a; +STOP SLAVE IO_THREAD; +--source include/start_slave.inc +--sync_with_master +SELECT * FROM t1 ORDER BY a; + +--echo *** Test retry of event group that spans multiple relay log files. *** + +--connection server_1 +CREATE TABLE t2 (a int PRIMARY KEY, b BLOB) ENGINE=InnoDB; +INSERT INTO t2 VALUES (1,"Hulubullu"); +--save_master_pos + +--connection server_2 +--sync_with_master +--source include/stop_slave.inc +SET @old_max= @@GLOBAL.max_relay_log_size; +SET GLOBAL max_relay_log_size=4096; + +--connection server_1 +--let $big= `SELECT REPEAT("*", 5000)` +SET gtid_seq_no = 100; +SET @old_server_id = @@server_id; +SET server_id = 12; +BEGIN; +--disable_query_log +eval INSERT INTO t2 VALUES (2, CONCAT("Hello ", "$big")); +eval INSERT INTO t2 VALUES (3, CONCAT("Long data: ", "$big")); +--enable_query_log +INSERT INTO t1 VALUES (10, 4); +COMMIT; +SET server_id = @old_server_id; +SELECT * FROM t1 WHERE a >= 10 ORDER BY a; +SELECT a, LENGTH(b) FROM t2 ORDER BY a; +--save_master_pos + +--connection server_2 +SET @old_dbug= @@GLOBAL.debug_dbug; +SET GLOBAL debug_dbug="+d,rpl_parallel_simulate_temp_err_gtid_0_x_100"; +let $old_retry= query_get_value(SHOW STATUS LIKE 'Slave_retried_transactions', Value, 1); +--source include/start_slave.inc +--sync_with_master +SET GLOBAL debug_dbug=@old_dbug; +let $new_retry= query_get_value(SHOW STATUS LIKE 'Slave_retried_transactions', Value, 1); +--disable_query_log +eval SELECT $new_retry - $old_retry AS retries; +--enable_query_log + +SELECT * FROM t1 WHERE a >= 10 ORDER BY a; +SELECT a, LENGTH(b) FROM t2 ORDER BY a; + +--connection server_1 +INSERT INTO t1 VALUES (11,11); +--disable_query_log +eval INSERT INTO t2 VALUES (4, "$big"); +--enable_query_log +--save_master_pos + +--connection server_2 +--sync_with_master +SELECT * FROM t1 WHERE a >= 10 ORDER BY a; +SELECT a, LENGTH(b) FROM t2 ORDER BY a; +SET GLOBAL max_relay_log_size=@old_max; + + +--echo *** MDEV-7065: Incorrect relay log position in parallel replication after retry of transaction *** + +--connection server_2 +--source include/stop_slave.inc + +--connection server_1 +BEGIN; +INSERT INTO t1 VALUES (100, 0); +INSERT INTO t1 VALUES (101, 0); +INSERT INTO t1 VALUES (102, 0); +INSERT INTO t1 VALUES (103, 0); +COMMIT; +SELECT * FROM t1 WHERE a >= 100 ORDER BY a; +--save_master_pos + +--connection server_2 +# Inject a DBUG error insert to cause the XID event of the single transaction +# from the master to fail with a deadlock error and be retried. +# The bug was that the retry of the XID would leave the relay log position +# incorrect (off by the size of XID event). +SET @old_dbug= @@GLOBAL.debug_dbug; +SET GLOBAL debug_dbug="+d,rpl_parallel_simulate_temp_err_xid"; +let $old_retry= query_get_value(SHOW STATUS LIKE 'Slave_retried_transactions', Value, 1); +--source include/start_slave.inc +--sync_with_master +SET GLOBAL debug_dbug=@old_dbug; +let $new_retry= query_get_value(SHOW STATUS LIKE 'Slave_retried_transactions', Value, 1); +--disable_query_log +eval SELECT $new_retry - $old_retry AS retries; +--enable_query_log + +SELECT * FROM t1 WHERE a >= 100 ORDER BY a; +# Stop the SQL thread. When the bug was there to give the incorrect relay log +# position, the restart of the SQL thread would read garbage data from the +# middle of an event and fail with relay log IO error. +--source include/stop_slave_sql.inc + +--connection server_1 +INSERT INTO t1 VALUES (104, 1); +INSERT INTO t1 VALUES (105, 1); +INSERT INTO t1 VALUES (106, 1); +INSERT INTO t1 VALUES (107, 1); +INSERT INTO t1 VALUES (108, 1); +INSERT INTO t1 VALUES (109, 1); +--save_master_pos + +--connection server_2 +--source include/start_slave.inc +--sync_with_master +SELECT * FROM t1 WHERE a >= 100 ORDER BY a; + + +--echo *** MDEV-6917: Parallel replication: "Commit failed due to failure of an earlier commit on which this one depends", but no prior failure seen ** + +--connection server_1 +CREATE TABLE t3 (a INT PRIMARY KEY, b INT, KEY b_idx(b)) ENGINE=InnoDB; +INSERT INTO t3 VALUES (1,NULL), (2,2), (3,NULL), (4,4), (5, NULL), (6, 6); +CREATE TABLE t4 (a INT PRIMARY KEY, b INT) ENGINE=InnoDB; + +# We need statement binlog format to be able to inject debug_sync statements +# on the slave with calls to foo(). +SET @old_format= @@SESSION.binlog_format; +SET binlog_format='statement'; +--save_master_pos + +--connection server_2 +--sync_with_master +--source include/stop_slave.inc +CHANGE MASTER TO master_use_gtid=no; + +--connection server_1 + +# Create a group commit with three transactions T1, T2, T3. +# T2 will block T1 on the slave where we will make it run first, so it will be +# deadlock killed. +# The bug was that in this case, T3 was signalled to fail due to T2 failing, +# even though the retry of T2 was later successful. + +--connect (con1,127.0.0.1,root,,test,$SERVER_MYPORT_1,) +SET @old_format= @@SESSION.binlog_format; +SET binlog_format='statement'; +BEGIN; +INSERT INTO t4 VALUES (10, foo(1, 'before_execute_sql_command WAIT_FOR t1_start', '')); +UPDATE t3 SET b=NULL WHERE a=6; +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued1 WAIT_FOR master_cont1'; +send COMMIT; +--connection server_1 +SET debug_sync='now WAIT_FOR master_queued1'; + +--connect (con2,127.0.0.1,root,,test,$SERVER_MYPORT_1,) +SET @old_format= @@SESSION.binlog_format; +SET binlog_format='statement'; +BEGIN; +INSERT INTO t4 VALUES (20, foo(2, 'group_commit_waiting_for_prior SIGNAL t2_waiting', '')); +DELETE FROM t3 WHERE b <= 3; +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued2'; +send COMMIT; + +--connection server_1 +SET debug_sync='now WAIT_FOR master_queued2'; + +--connect (con3,127.0.0.1,root,,test,$SERVER_MYPORT_1,) +SET @old_format= @@SESSION.binlog_format; +SET binlog_format='statement'; +BEGIN; +INSERT INTO t4 VALUES (30, foo(3, 'before_execute_sql_command WAIT_FOR t3_start', 'group_commit_waiting_for_prior SIGNAL t3_waiting')); +INSERT INTO t3 VALUES (7,7); +SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued3'; +send COMMIT; + +--connection server_1 +SET debug_sync='now WAIT_FOR master_queued3'; +SET debug_sync='now SIGNAL master_cont1'; + +--connection con1 +REAP; +SET binlog_format=@old_format; +--connection con2 +REAP; +SET binlog_format=@old_format; +--connection con3 +REAP; +SET debug_sync='RESET'; +SET binlog_format=@old_format; + +--connection server_1 +--save_master_pos +SELECT * FROM t3 ORDER BY a; + + +--connection server_2 +let $old_retry= query_get_value(SHOW STATUS LIKE 'Slave_retried_transactions', Value, 1); +SET @old_dbug=@@GLOBAL.debug_dbug; +SET GLOBAL debug_dbug="+d,thd_need_ordering_with_force"; +--source include/start_slave.inc +# First, wait for T2 to complete up to where it is waiting for T1 to group +# commit for both of them. This will set locks that will block T1, causing +# a deadlock kill and retry of T2. T1 and T3 are still blocked at the start +# of each their SQL statements. +SET debug_sync='now WAIT_FOR t2_waiting'; +# Now let T3 move on until the point where it is itself ready to commit. +SET debug_sync='now SIGNAL t3_start'; +SET debug_sync='now WAIT_FOR t3_waiting'; +# Now T2 and T3 are set up, so we can let T1 proceed. +SET debug_sync='now SIGNAL t1_start'; +# Now we can wait for the slave to catch up. +# We should see T2 being deadlock killed and retried. +# The bug was that T2 deadlock kill would cause T3 to fail due to failure +# of an earlier commit. This is wrong as T2 did not fail, it was only +# retried. +--sync_with_master +SET GLOBAL debug_dbug=@old_dbug; +SET debug_sync='RESET'; +let $new_retry= query_get_value(SHOW STATUS LIKE 'Slave_retried_transactions', Value, 1); +--disable_query_log +eval SELECT $new_retry - $old_retry >= 1 AS retries; +--enable_query_log +SELECT * FROM t3 ORDER BY a; + + +--connection server_1 +SET binlog_format=@old_format; + + +# Clean up of the above part. +--connection server_2 +--source include/stop_slave.inc +SET GLOBAL slave_parallel_threads=@old_parallel_threads; +--source include/start_slave.inc + +--connection server_1 +DROP TABLE t1, t2, t3, t4; +DROP function foo; + +--sync_slave_with_master server_2 + +# +# MDEV-12746 rpl.rpl_parallel_optimistic_nobinlog fails committing out of order at retry +# + +--connection server_1 +CREATE TABLE t1 (a int PRIMARY KEY, b INT) ENGINE=InnoDB; + + +# Replicate create-t1 and prepare to re-start slave in optimistic mode +--sync_slave_with_master server_2 +--source include/stop_slave.inc +SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads; +SET @@GLOBAL.slave_parallel_threads=5; +SET @old_parallel_mode=@@GLOBAL.slave_parallel_mode; +SET @@GLOBAL.slave_parallel_mode='aggressive'; +SET @old_lock_wait_timeout=@@GLOBAL.innodb_lock_wait_timeout; +SET @@GLOBAL.innodb_lock_wait_timeout=2; +SET @old_slave_transaction_retries=@@GLOBAL.slave_transaction_retries; +SET @@GLOBAL.slave_transaction_retries=1; + +--echo # Spoilers on the slave side causing temporary errors +--connect (spoiler_21,127.0.0.1,root,,test,$SLAVE_MYPORT) +BEGIN; + INSERT INTO t1 SET a=1,b=2; + +--connect (spoiler_22,127.0.0.1,root,,test,$SLAVE_MYPORT) +BEGIN; + INSERT INTO t1 SET a=2,b=2; + +--echo # Master payload +--connection server_1 +SET @@SESSION.GTID_SEQ_NO=1000; +INSERT INTO t1 SET a=1,b=1; +SET @@SESSION.GTID_SEQ_NO=1001; +INSERT INTO t1 SET a=2,b=1; + +--echo # Start slave whose both appliers is destined to being blocked +--connection server_2 +SET @old_dbug= @@GLOBAL.debug_dbug; +SET @@GLOBAL.debug_dbug="+d,rpl_parallel_simulate_wait_at_retry"; +--source include/start_slave.inc + +--echo # Make sure both workers are waiting at their sync points +--let $wait_condition= SELECT count(*)=2 FROM information_schema.processlist WHERE state LIKE '%debug sync point%'; +--source include/wait_condition.inc + + +--echo # Signal to the 1st to proceed after it has reached termination state +SET @@DEBUG_SYNC='now SIGNAL proceed_by_1000'; +--connection spoiler_21 +ROLLBACK; + +--let $wait_condition= SELECT count(*)=1 FROM information_schema.processlist WHERE state LIKE '%debug sync point%'; +--source include/wait_condition.inc + +--echo # Release the 2nd worker to proceed +--connection spoiler_22 +ROLLBACK; +--connection server_2 +SET @@DEBUG_SYNC='now SIGNAL proceed_by_1001'; + +--echo # observe how it all ends +if (`SELECT count(*) = 1 FROM t1 WHERE a = 1`) +{ + --echo "*** Unexpected commit by the first Worker ***" + SELECT * from t1; + --die +} + +--echo # Wait for the workers to go home and check the result of applying +--let $wait_condition=SELECT count(*) = 0 FROM information_schema.processlist WHERE command = 'Slave_worker' +--source include/wait_condition.inc +if (`SELECT count(*) = 1 FROM t1 WHERE a = 2`) +{ + --echo + --echo "*** Error: congrats, you hit MDEV-12746 issue. ***" + --echo + --die +} +--echo # which is OK + +# +# Clean up +# +--connection server_2 +--source include/stop_slave.inc +SET @@GLOBAL.slave_parallel_threads=@old_parallel_threads; +SET @@GLOBAL.slave_parallel_mode=@old_parallel_mode; +SET @@GLOBAL.innodb_lock_wait_timeout=@old_lock_wait_timeout; +SET @@GLOBAL.slave_transaction_retries=@old_slave_transaction_retries; +SET @@GLOBAL.debug_dbug=@old_dbug; +SET debug_sync='RESET'; +--source include/start_slave.inc + +--connection server_1 +DROP TABLE t1; + +--sync_slave_with_master server_2 + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_parallel_retry_deadlock.test b/mysql-test/suite/rpl/t/rpl_parallel_retry_deadlock.test new file mode 100644 index 00000000..50b216b6 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_parallel_retry_deadlock.test @@ -0,0 +1 @@ +--source include/rpl_parallel_retry_deadlock.inc diff --git a/mysql-test/suite/rpl/t/rpl_parallel_rollback_assert.test b/mysql-test/suite/rpl/t/rpl_parallel_rollback_assert.test new file mode 100644 index 00000000..f66375b7 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_parallel_rollback_assert.test @@ -0,0 +1 @@ +--source include/rpl_parallel_rollback_assert.inc diff --git a/mysql-test/suite/rpl/t/rpl_parallel_show_binlog_events_purge_logs.test b/mysql-test/suite/rpl/t/rpl_parallel_show_binlog_events_purge_logs.test new file mode 100644 index 00000000..8c8892d5 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_parallel_show_binlog_events_purge_logs.test @@ -0,0 +1 @@ +--source include/rpl_parallel_show_binlog_events_purge_logs.inc diff --git a/mysql-test/suite/rpl/t/rpl_parallel_single_grpcmt.test b/mysql-test/suite/rpl/t/rpl_parallel_single_grpcmt.test new file mode 100644 index 00000000..20919823 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_parallel_single_grpcmt.test @@ -0,0 +1 @@ +--source include/rpl_parallel_single_grpcmt.inc diff --git a/mysql-test/suite/rpl/t/rpl_parallel_slave_bgc_kill.test b/mysql-test/suite/rpl/t/rpl_parallel_slave_bgc_kill.test new file mode 100644 index 00000000..7b0f9485 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_parallel_slave_bgc_kill.test @@ -0,0 +1 @@ +--source include/rpl_parallel_slave_bgc_kill.inc diff --git a/mysql-test/suite/rpl/t/rpl_parallel_stop_on_con_kill.test b/mysql-test/suite/rpl/t/rpl_parallel_stop_on_con_kill.test new file mode 100644 index 00000000..64b4cb77 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_parallel_stop_on_con_kill.test @@ -0,0 +1 @@ +--source include/rpl_parallel_stop_on_con_kill.inc diff --git a/mysql-test/suite/rpl/t/rpl_parallel_stop_slave.test b/mysql-test/suite/rpl/t/rpl_parallel_stop_slave.test new file mode 100644 index 00000000..131ddc2e --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_parallel_stop_slave.test @@ -0,0 +1 @@ +--source include/rpl_parallel_stop_slave.inc diff --git a/mysql-test/suite/rpl/t/rpl_parallel_temptable-master.opt b/mysql-test/suite/rpl/t/rpl_parallel_temptable-master.opt new file mode 100644 index 00000000..590d44a6 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_parallel_temptable-master.opt @@ -0,0 +1 @@ +--loose-skip-stack-trace --skip-core-file diff --git a/mysql-test/suite/rpl/t/rpl_parallel_temptable.test b/mysql-test/suite/rpl/t/rpl_parallel_temptable.test new file mode 100644 index 00000000..04165ee4 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_parallel_temptable.test @@ -0,0 +1,271 @@ +--source include/have_innodb.inc +--source include/have_debug.inc +--source include/have_binlog_format_statement.inc +# Valgrind does not work well with test that crashes the server +--source include/not_valgrind.inc +--let $rpl_topology=1->2 +--source include/rpl_init.inc + +--echo *** MDEV-6321: close_temporary_tables() in format description event not serialised correctly *** + +--connection server_2 +SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads; +--source include/stop_slave.inc +SET GLOBAL slave_parallel_threads=5; +CHANGE MASTER TO master_use_gtid= current_pos; +--source include/start_slave.inc + +--connection server_1 +CREATE TABLE t1 (a INT PRIMARY KEY, b VARCHAR(100) CHARACTER SET utf8); +--save_master_pos + +--connection server_2 +--sync_with_master +--source include/stop_slave.inc + + +--connection server_1 +SET gtid_domain_id= 1; +INSERT INTO t1 VALUES (1, 0); + +CREATE TEMPORARY TABLE t2 (a int); + +--connection default +SET gtid_domain_id= 2; +CREATE TEMPORARY TABLE t3 (a INT PRIMARY KEY); +CREATE TEMPORARY TABLE t4 (a int); +INSERT INTO t3 VALUES (100); +INSERT INTO t4 SELECT a+1 FROM t3; + +--connection server_1 +INSERT INTO t2 VALUES (2), (4), (6), (8), (10), (12), (14), (16), (18), (20); +INSERT INTO t2 VALUES (3), (6), (9), (12), (15), (18); +INSERT INTO t2 VALUES (4), (8), (12), (16), (20); + +--connection default +INSERT INTO t3 SELECT a+2 FROM t4; +INSERT INTO t4 SELECT a+4 FROM t3; + +--connection server_1 +INSERT INTO t2 VALUES (5), (10), (15), (20); +INSERT INTO t2 VALUES (6), (12), (18); +INSERT INTO t2 VALUES (7), (14); +INSERT INTO t2 VALUES (8), (16); +INSERT INTO t2 VALUES (9), (18); +INSERT INTO t2 VALUES (10), (20); + +--connection default +INSERT INTO t3 SELECT a+8 FROM t4; +INSERT INTO t4 SELECT a+16 FROM t3; + +--connection server_1 +INSERT INTO t2 VALUES (11); +INSERT INTO t2 VALUES (12); +INSERT INTO t2 VALUES (13); + +--connection default +INSERT INTO t3 SELECT a+32 FROM t4; + +--connection server_1 +INSERT INTO t2 VALUES (14); +INSERT INTO t2 VALUES (15); +INSERT INTO t2 VALUES (16); + +--connection default +INSERT INTO t4 SELECT a+64 FROM t3; + +--connection server_1 +INSERT INTO t2 VALUES (17); +INSERT INTO t2 VALUES (18); +INSERT INTO t2 VALUES (19); + +--connection default +INSERT INTO t3 SELECT a+128 FROM t4; + +--connection server_1 +INSERT INTO t2 VALUES (20); + +--connection default +INSERT INTO t1 SELECT a, a MOD 7 FROM t3; +INSERT INTO t1 SELECT a, a MOD 7 FROM t4; + +--connection server_1 +INSERT INTO t1 SELECT a, COUNT(*) FROM t2 GROUP BY a; + +# Crash the master server, so that temporary tables are implicitly dropped. +--write_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +wait +EOF + +FLUSH TABLES; +SET SESSION debug_dbug="+d,crash_dispatch_command_before"; +--error 2006,2013 +SELECT 1; + +--source include/wait_until_disconnected.inc +--connection default +--source include/wait_until_disconnected.inc + +--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 + +INSERT INTO t1 VALUES (0, 1); +--save_master_pos + +--connection server_2 +# Start the slave replicating the events. +# The bug was that the format description event written after the crash could +# be fetched ahead of the execution of the temporary table events and executed +# out-of-band. This would cause drop of all temporary tables and thus failure +# for execution of remaining events. + +--source include/start_slave.inc +--sync_with_master + +SELECT * FROM t1 WHERE a <= 20 ORDER BY a; +SELECT COUNT(*) FROM t1 WHERE a BETWEEN 100+0 AND 100+256; +SHOW STATUS LIKE 'Slave_open_temp_tables'; + + +--echo *** Test that if master logged partial event group before crash, we finish that group correctly before executing format description event *** + +--source include/stop_slave.inc + +--connection server_1 +CALL mtr.add_suppression("Statement accesses nontransactional table as well as transactional or temporary table, and writes to any of them"); +SET gtid_domain_id= 1; +DELETE FROM t1; +ALTER TABLE t1 ENGINE=InnoDB; +CREATE TEMPORARY TABLE t2 (a INT PRIMARY KEY); +INSERT INTO t2 VALUES (1); +INSERT INTO t2 VALUES (2); + +--connection default +SET gtid_domain_id= 2; +CREATE TEMPORARY TABLE t3 (a INT PRIMARY KEY); +INSERT INTO t3 VALUES (10); +INSERT INTO t3 VALUES (20); + +--connection server_1 +INSERT INTO t1 SELECT a, 'server_1' FROM t2; + +--connection default +INSERT INTO t1 SELECT a, 'default' FROM t3; + +--connection server_1 +INSERT INTO t1 SELECT a+2, '+server_1' FROM t2; + +# Crash the master server in the middle of writing an event group. +--write_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +wait +EOF + +FLUSH TABLES; +SET SESSION debug_dbug="+d,crash_before_writing_xid"; +--error 2006,2013 +INSERT INTO t1 SELECT a+4, '++server_1' FROM t2; + +--source include/wait_until_disconnected.inc +--connection default +--source include/wait_until_disconnected.inc + +--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 + +INSERT INTO t1 VALUES (0, 1); +#--save_master_pos +--source include/save_master_gtid.inc + +--connection server_2 +# Start the slave replicating the events. +# The main thing to test here is that the slave will know that it +# needs to abort the partially received event group, so that the +# execution of format_description event will not wait infinitely +# for a commit of the incomplete group that never happens. + +--source include/start_slave.inc +#--sync_with_master +--source include/sync_with_master_gtid.inc + +SELECT * FROM t1 ORDER BY a; +SHOW STATUS LIKE 'Slave_open_temp_tables'; + +--connection server_1 +# This FLUSH can be removed once MDEV-6608 is fixed. +FLUSH LOGS; + + +--echo *** MDEV-7936: Assertion `!table || table->in_use == _current_thd()' failed on parallel replication in optimistic mode *** + +--connection server_1 +CREATE TEMPORARY TABLE t4 (a INT PRIMARY KEY) ENGINE=InnoDB; +SET @old_dbug= @@SESSION.debug_dbug; +SET SESSION debug_dbug="+d,binlog_force_commit_id"; +SET @commit_id= 10000; +INSERT INTO t4 VALUES (30); +INSERT INTO t4 VALUES (31); +SET SESSION debug_dbug= @old_dbug; +INSERT INTO t1 SELECT a, "conservative" FROM t4; +DROP TEMPORARY TABLE t4; +SELECT * FROM t1 WHERE a >= 30 ORDER BY a; +--source include/save_master_gtid.inc + +--connection server_2 +--source include/sync_with_master_gtid.inc + +SELECT * FROM t1 WHERE a >= 30 ORDER BY a; + +--source include/stop_slave.inc +SET @old_mode= @@GLOBAL.slave_parallel_mode; +SET GLOBAL slave_parallel_mode=optimistic; + +--connection server_1 +CREATE TEMPORARY TABLE t4 (a INT PRIMARY KEY) ENGINE=InnoDB; +INSERT INTO t4 VALUES (32); +INSERT INTO t4 VALUES (33); +INSERT INTO t1 SELECT a, "optimistic" FROM t4; +DROP TEMPORARY TABLE t4; + +SELECT * FROM t1 WHERE a >= 30 ORDER BY a; +--source include/save_master_gtid.inc + +--connection server_2 +--source include/start_slave.inc +--source include/sync_with_master_gtid.inc + +SELECT * FROM t1 WHERE a >= 30 ORDER BY a; + +--source include/stop_slave.inc +SET GLOBAL slave_parallel_mode=@old_mode; +--source include/start_slave.inc + + +# Clean up. + +--connection server_2 +--source include/stop_slave.inc +SET GLOBAL slave_parallel_threads=@old_parallel_threads; +--source include/start_slave.inc + +--connection server_1 +DROP TABLE t1; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_parallel_wrong_binlog_order.test b/mysql-test/suite/rpl/t/rpl_parallel_wrong_binlog_order.test new file mode 100644 index 00000000..3c920e15 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_parallel_wrong_binlog_order.test @@ -0,0 +1 @@ +--source include/rpl_parallel_wrong_binlog_order.inc diff --git a/mysql-test/suite/rpl/t/rpl_parallel_wrong_exec_master_pos.test b/mysql-test/suite/rpl/t/rpl_parallel_wrong_exec_master_pos.test new file mode 100644 index 00000000..9cd700f5 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_parallel_wrong_exec_master_pos.test @@ -0,0 +1 @@ +--source include/rpl_parallel_wrong_exec_master_pos.inc diff --git a/mysql-test/suite/rpl/t/rpl_parallel_xa_same_xid.test b/mysql-test/suite/rpl/t/rpl_parallel_xa_same_xid.test new file mode 100644 index 00000000..888dd2f1 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_parallel_xa_same_xid.test @@ -0,0 +1,138 @@ +# The tests verify concurrent execution of replicated (MDEV-742) +# XA transactions in the parallel optimistic mode. +# Prove optimistic scheduler handles xid-namesake XA:s. +# That is despite running in parallel there must be no conflicts +# caused by multiple transactions' same xid. + +--source include/have_binlog_format_mixed_or_row.inc +--source include/have_innodb.inc +--source include/have_perfschema.inc +--source include/master-slave.inc + +--let $xid_num = 19 +--let $repeat = 17 +--let $workers = 7 +--connection slave +call mtr.add_suppression("WSREP: handlerton rollback failed"); + +--source include/stop_slave.inc +# a measure against MDEV-20605 +ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; + +SET @old_parallel_threads = @@GLOBAL.slave_parallel_threads; +--disable_query_log +--eval SET @@global.slave_parallel_threads = $workers +--enable_query_log +SET @old_parallel_mode = @@GLOBAL.slave_parallel_mode; +SET @@global.slave_parallel_mode ='optimistic'; +--source include/start_slave.inc + +--connection master +CREATE TABLE t1 (a INT, b INT) ENGINE=InnoDB; + +--let $i = $xid_num +--let $t = t1 +--disable_query_log +while ($i) +{ +--let $k = $repeat +while ($k) +{ +--eval XA START 'xid_$i' +--eval INSERT INTO $t SET a=$i, b=$k +--eval XA END 'xid_$i' +--let $one_phase = `SELECT IF(floor(rand()*10)%2, "ONE PHASE", 0)` + if (!$one_phase) + { + --eval XA PREPARE 'xid_$i' + --eval XA COMMIT 'xid_$i' + } + if ($one_phase) + { + --eval XA COMMIT 'xid_$i' ONE PHASE + } + + if (!$one_phase) + { + --eval XA START 'xid_$i' + --eval INSERT INTO $t SET a=$i, b=$k + --eval XA END 'xid_$i' + --eval XA PREPARE 'xid_$i' + --eval XA ROLLBACK 'xid_$i' + } + +--dec $k +} + +--dec $i +} +--enable_query_log + + + +# Above-like test complicates execution env to create +# data conflicts as well. They will be resolved by the optmistic +# scheduler as usual. + +CREATE TABLE t2 (a INT AUTO_INCREMENT PRIMARY KEY, b INT) ENGINE=InnoDB; + +--let $i = $xid_num +--let $t = t2 +--disable_query_log +while ($i) +{ +--let $k = $repeat +while ($k) +{ +--eval XA START 'xid_$i' +--eval INSERT INTO $t SET a=NULL, b=$k +--eval UPDATE $t SET b=$k + 1 WHERE a=last_insert_id() % $workers +--eval XA END 'xid_$i' +--let $one_phase = `SELECT IF(floor(rand()*10)%2, "ONE PHASE", 0)` + if (!$one_phase) + { + --eval XA PREPARE 'xid_$i' + --eval XA COMMIT 'xid_$i' + } + if ($one_phase) + { + --eval XA COMMIT 'xid_$i' ONE PHASE + } + +--eval XA START 'xid_$i' +--eval UPDATE $t SET b=$k + 1 WHERE a=last_insert_id() % $workers +--eval DELETE FROM $t WHERE a=last_insert_id() +--eval XA END 'xid_$i' +--eval XA PREPARE 'xid_$i' +--eval XA ROLLBACK 'xid_$i' + +--let $do_drop_create = `SELECT IF(floor(rand()*10)%100, 1, 0)` +if ($do_drop_create) +{ + DROP TABLE t1; + CREATE TABLE t1 (a INT, b INT) ENGINE=InnoDB; +} +--dec $k +} + +--dec $i +} +--enable_query_log + +--source include/sync_slave_sql_with_master.inc +--let $diff_tables= master:t1, slave:t1 +--source include/diff_tables.inc + +# +# Clean up. +# +--connection slave +--source include/stop_slave.inc +SET GLOBAL slave_parallel_threads=@old_parallel_threads; +SET GLOBAL slave_parallel_mode=@old_parallel_mode; +--source include/start_slave.inc + +--connection master +DROP TABLE t1, t2; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_partition_archive.test b/mysql-test/suite/rpl/t/rpl_partition_archive.test new file mode 100644 index 00000000..5b64576d --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_partition_archive.test @@ -0,0 +1,12 @@ +# Test of partitioning features with replication for archive +--source include/have_archive.inc +--source include/have_partition.inc +--source include/master-slave.inc + +# Set the default connection to 'master' + +let $engine_type= 'Archive'; + +--source suite/rpl/include/rpl_partition.inc + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_partition_innodb-master.opt b/mysql-test/suite/rpl/t/rpl_partition_innodb-master.opt new file mode 100644 index 00000000..0eed7aaa --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_partition_innodb-master.opt @@ -0,0 +1 @@ +--innodb_autoinc_lock_mode=0 diff --git a/mysql-test/suite/rpl/t/rpl_partition_innodb.test b/mysql-test/suite/rpl/t/rpl_partition_innodb.test new file mode 100644 index 00000000..098bc407 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_partition_innodb.test @@ -0,0 +1,12 @@ +# Test of partitioning features with replication for InnoDB +--source include/have_innodb.inc +--source include/have_partition.inc +--source include/master-slave.inc + +# Set the default connection to 'master' + +let $engine_type= 'InnoDB'; + +--source suite/rpl/include/rpl_partition.inc + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_partition_memory.test b/mysql-test/suite/rpl/t/rpl_partition_memory.test new file mode 100644 index 00000000..4ce68d6f --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_partition_memory.test @@ -0,0 +1,11 @@ +# Test of partitioning features with replication for Memory +--source include/have_partition.inc +--source include/master-slave.inc + +# Set the default connection to 'master' + +let $engine_type= 'Memory'; + +--source suite/rpl/include/rpl_partition.inc + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_partition_myisam.test b/mysql-test/suite/rpl/t/rpl_partition_myisam.test new file mode 100644 index 00000000..56003d89 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_partition_myisam.test @@ -0,0 +1,11 @@ +# Test of partitioning features with replication for MyISAM +--source include/have_partition.inc +--source include/master-slave.inc + +# Set the default connection to 'master' + +let $engine_type= 'MyISAM'; + +--source suite/rpl/include/rpl_partition.inc + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_password_boundaries.test b/mysql-test/suite/rpl/t/rpl_password_boundaries.test new file mode 100644 index 00000000..9e968594 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_password_boundaries.test @@ -0,0 +1,101 @@ +source include/not_embedded.inc; +source include/master-slave.inc; +source include/rpl_reset.inc; + +# Suppress warnings that might be generated during the test +disable_query_log; +connection master; +call mtr.add_suppression("Timeout waiting for reply of binlog"); +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"); +enable_query_log; + +connection master; + +# wait for dying connections (if any) to disappear +let $wait_condition= select count(*) = 0 from information_schema.processlist where command='killed'; +--source include/wait_condition.inc + +# 32*3-character ASCII password should work all right + +set sql_log_bin=0; +grant replication slave on *.* to rpl32@127.0.0.1 identified by '0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef'; +set sql_log_bin=1; + +connection slave; +source include/stop_slave.inc; +change master to master_user='rpl32',master_password='0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef'; +source include/start_slave.inc; + +connection master; +drop table if exists t1; +create table t1 (i int); +insert into t1 values (1); +sync_slave_with_master; +echo [ synchronized ]; + +connection master; + +# 32*3+1 -character ASCII password expected to fail +set sql_log_bin=0; +grant replication slave on *.* to rpl33@127.0.0.1 identified by '0123456789abcdef0123456789abcdef!'; +set sql_log_bin=1; + +connection slave; +source include/stop_slave.inc; +--error ER_WRONG_STRING_LENGTH +change master to master_user='rpl33',master_password='0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef!'; + +# Check also master_user and master_host +--error ER_WRONG_STRING_LENGTH +change master to master_user='aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'; +--error ER_WRONG_STRING_LENGTH +change master to master_host='aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc'; + +# 48-character cyrillic password should work all right +connection master; +set sql_log_bin=0; +grant replication slave on *.* to rpl16cyr@127.0.0.1 identified by 'воттакойужпарольвоттакойужпарольвоттакойужпароль'; +set sql_log_bin=1; + +connection slave; +SET NAMES utf8; +change master to master_user='rpl16cyr',master_password='воттакойужпарольвоттакойужпарольвоттакойужпароль'; +source include/start_slave.inc; + +connection master; +drop table if exists t1; +create table t1 (i int); +insert into t1 values (1); +sync_slave_with_master; +echo [ synchronized ]; + +# 48+1-character cyrillic password should fail + +connection master; +set sql_log_bin=0; +grant replication slave on *.* to rpl17mix@127.0.0.1 identified by 'воттакойужпарольвоттакойужпарольвоттакойужпароль!'; +set sql_log_bin=1; + +connection slave; +source include/stop_slave.inc; +--error ER_WRONG_STRING_LENGTH +change master to master_user='rpl17mix',master_password='воттакойужпарольвоттакойужпарольвоттакойужпароль!'; + +# Cleanup + +connection master; +set sql_log_bin=0; +drop user rpl32@127.0.0.1, rpl33@127.0.0.1, rpl16cyr@127.0.0.1, rpl17mix@127.0.0.1; +set sql_log_bin=1; + +connection slave; +change master to master_user='root',master_password=''; +source include/start_slave.inc; + +connection master; +drop table if exists t1; +sync_slave_with_master; + +connection master; +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_performance_schema.test b/mysql-test/suite/rpl/t/rpl_performance_schema.test new file mode 100644 index 00000000..18aabe52 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_performance_schema.test @@ -0,0 +1,10 @@ +--source include/have_perfschema.inc +--source include/have_binlog_format_mixed.inc +--source include/master-slave.inc + +UPDATE performance_schema.setup_instruments SET ENABLED="NO"; + +--sync_slave_with_master +--source include/rpl_end.inc + +# End of test case diff --git a/mysql-test/suite/rpl/t/rpl_plugin_load.test b/mysql-test/suite/rpl/t/rpl_plugin_load.test new file mode 100644 index 00000000..c319479a --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_plugin_load.test @@ -0,0 +1,59 @@ +# +# Bug#35807 - INSTALL PLUGIN replicates row-based, but not stmt-based +# +# The test verifies that INSTALL PLUGIN and UNINSTALL PLUGIN +# work with replication. +# +# The test tries to install and uninstall a plugin on master, +# and verifies that it does not affect the slave, +# and that it does not add anything to the binlog. + +--source include/not_embedded.inc +--source include/have_log_bin.inc +--source include/have_example_plugin.inc + +# Initialize replication. +--source include/master-slave.inc +--echo Verify that example engine is not installed. +SELECT * FROM INFORMATION_SCHEMA.ENGINES WHERE ENGINE='EXAMPLE'; +--echo Get binlog position before install plugin. +let $before_pos = query_get_value("SHOW MASTER STATUS", Position, 1); +--echo Install example engine. +--replace_regex /\.dll/.so/ +eval INSTALL PLUGIN example SONAME '$HA_EXAMPLE_SO'; +--echo Get binlog position after install plugin. +let $after_pos = query_get_value("SHOW MASTER STATUS", Position, 1); +--echo Compute the difference of the binlog positions. +--echo Should be zero as install plugin should not be replicated. +--disable_query_log +eval SELECT $after_pos - $before_pos AS Delta; +--enable_query_log +--echo Verify that example engine is installed. +SELECT * FROM INFORMATION_SCHEMA.ENGINES WHERE ENGINE='EXAMPLE'; +# Wait for slave to catch up with master. +sync_slave_with_master; +# + --echo Verify that example engine is not installed. + connection slave; + SELECT * FROM INFORMATION_SCHEMA.ENGINES WHERE ENGINE='EXAMPLE'; +# +--echo Uninstall example engine. +connection master; +--echo Get binlog position before uninstall plugin. +let $before_pos = query_get_value("SHOW MASTER STATUS", Position, 1); +UNINSTALL PLUGIN example; +--echo Get binlog position after uninstall plugin. +let $after_pos = query_get_value("SHOW MASTER STATUS", Position, 1); +--echo Compute the difference of the binlog positions. +--echo Should be zero as uninstall plugin should not be replicated. +--disable_query_log +eval SELECT $after_pos - $before_pos AS Delta; +--enable_query_log +--echo Verify that example engine is not installed. +SELECT * FROM INFORMATION_SCHEMA.ENGINES WHERE ENGINE='EXAMPLE'; +# Wait for slave to catch up with master. +sync_slave_with_master; +# +# Cleanup +--source include/rpl_end.inc +--echo End of test diff --git a/mysql-test/suite/rpl/t/rpl_ps.test b/mysql-test/suite/rpl/t/rpl_ps.test new file mode 100644 index 00000000..45ab55bf --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_ps.test @@ -0,0 +1,94 @@ +# +# Test of replicating user variables +# +source include/master-slave.inc; + +#sync_slave_with_master; +#reset master; +#connection master; + +--disable_warnings +drop table if exists t1; +--enable_warnings + +create table t1(n char(30)); + +prepare stmt1 from 'insert into t1 values (?)'; +set @var1= "from-master-1"; +execute stmt1 using @var1; +set @var1= "from-master-2-'',"; +execute stmt1 using @var1; +SELECT * FROM t1 ORDER BY n; + +set @var2= 'insert into t1 values (concat("from-var-", ?))'; +prepare stmt2 from @var2; +set @var1='from-master-3'; +execute stmt2 using @var1; + +sync_slave_with_master; +SELECT * FROM t1 ORDER BY n; + +connection master; + +drop table t1; + +sync_slave_with_master; +stop slave; +source include/wait_for_slave_to_stop.inc; +# End of 4.1 tests + +# +# Bug #25843 Changing default database between PREPARE and EXECUTE of statement +# breaks binlog. +# +# There were actually two problems discovered by this bug: +# +# 1. Default (current) database is not fixed at the creation time. +# That leads to wrong output of DATABASE() function. +# +# 2. Database attributes (@@collation_database) are not fixed at the creation +# time. That leads to wrong resultset. +# +# Binlog breakage and Query Cache wrong output happened because of the first +# problem. +# + +--echo +--echo ######################################################################## +--echo # +--echo # BUG#25843: Changing default database between PREPARE and EXECUTE of +--echo # statement breaks binlog. +--echo # +--echo ######################################################################## + +############################################################################### + +--connection slave + +START SLAVE; + +--connection master + +CREATE DATABASE mysqltest1; +CREATE TABLE t1(db_name CHAR(32), db_col_name CHAR(32)); + +PREPARE stmt_d_1 FROM 'INSERT INTO t1 VALUES(DATABASE(), @@collation_database)'; + +EXECUTE stmt_d_1; + +use mysqltest1; + +EXECUTE stmt_d_1; + +--sync_slave_with_master + +SELECT * FROM t1; + +--connection master + +DROP DATABASE mysqltest1; + +use test; +DROP TABLE t1; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_rbr_to_sbr.test b/mysql-test/suite/rpl/t/rpl_rbr_to_sbr.test new file mode 100644 index 00000000..1bc20c1e --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_rbr_to_sbr.test @@ -0,0 +1,31 @@ +-- source include/have_binlog_format_mixed.inc +-- source include/master-slave.inc + +# Test that the slave temporarily switches to ROW when seeing row +# events when it is in MIXED mode + +CREATE TABLE t1 (a INT, b LONG); +INSERT INTO t1 VALUES (1,1), (2,2); +INSERT INTO t1 VALUES (3,UUID()), (4,UUID()); +source include/show_binlog_events.inc; +sync_slave_with_master; +source include/show_binlog_events.inc; + +--exec $MYSQL_DUMP --compact --order-by-primary --skip-extended-insert --no-create-info test > $MYSQLTEST_VARDIR/tmp/rpl_rbr_to_sbr_master.sql +--exec $MYSQL_DUMP_SLAVE --compact --order-by-primary --skip-extended-insert --no-create-info test > $MYSQLTEST_VARDIR/tmp/rpl_rbr_to_sbr_slave.sql + +connection master; +DROP TABLE IF EXISTS t1; + +# 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_rbr_to_sbr_master.sql $MYSQLTEST_VARDIR/tmp/rpl_rbr_to_sbr_slave.sql; + +# If all is good, we can remove the files + +--remove_file $MYSQLTEST_VARDIR/tmp/rpl_rbr_to_sbr_master.sql +--remove_file $MYSQLTEST_VARDIR/tmp/rpl_rbr_to_sbr_slave.sql +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_read_new_relay_log_info.test b/mysql-test/suite/rpl/t/rpl_read_new_relay_log_info.test new file mode 100644 index 00000000..1e2c8ce2 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_read_new_relay_log_info.test @@ -0,0 +1,43 @@ +# ==== Purpose ==== +# +# - Verify that the post-WL#344 format of relay_log.info can be parsed. + +--source include/master-slave.inc + +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1); +DROP TABLE t1; +--sync_slave_with_master + +--echo ==== Check that we can understand the new format of relay-log.info ==== +--source include/stop_slave.inc + +RESET SLAVE; +--let $MYSQLD_DATADIR= `select @@datadir` + +# the new version of relay_log.info comes in two versions: with path +# separator '/' (most systems) and with path separator '\' (windows) +if ($SYSTEM_PATH_SEPARATOR != /) { + --let $file_suffix= -win +} +--copy_file $MYSQL_TEST_DIR/std_data/new-format-relay-log$file_suffix.info $MYSQLD_DATADIR/relay-log.info + +--echo # Read relay-log.info +START SLAVE IO_THREAD; +--source include/wait_for_slave_io_to_start.inc +--echo # Check that relay log coordinates are equal to those saved in new-format_relay-log.info +--let $master_file= query_get_value(SHOW SLAVE STATUS, Relay_Master_Log_File, 1) +--let $master_pos= query_get_value(SHOW SLAVE STATUS, Exec_Master_Log_Pos, 1) +--let $relay_log_file= query_get_value(SHOW SLAVE STATUS, Relay_Log_File, 1) +--let $relay_log_pos= query_get_value(SHOW SLAVE STATUS, Relay_Log_Pos, 1) +--echo $master_file= $master_file, $master_pos, $relay_log_file, $relay_log_pos +if (`SELECT "$master_file" != "" OR + "$master_pos" != "0" OR + "$relay_log_file" != "slave-relay-bin.000001" OR + "$relay_log_pos" != "4"`) { + --echo ERROR: log coordinates changed + --die log coordinates changed +} + +--let $rpl_only_running_threads= 1 +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_read_old_relay_log_info.test b/mysql-test/suite/rpl/t/rpl_read_old_relay_log_info.test new file mode 100644 index 00000000..ce345445 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_read_old_relay_log_info.test @@ -0,0 +1,44 @@ +# ==== Purpose ==== +# +# - Verify that the pre-WL#344 format of relay_log.info can still be +# parsed. + +--source include/master-slave.inc + +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1); +DROP TABLE t1; +--sync_slave_with_master + +--echo ==== Check that we still understand the old format of relay-log.info ==== +--source include/stop_slave.inc + +RESET SLAVE; +--let $MYSQLD_DATADIR= `select @@datadir` + +# the old version of relay_log.info comes in two versions: with path +# separator '/' (most systems) and with path separator '\' (windows) +if ($SYSTEM_PATH_SEPARATOR != /) { + --let $file_suffix= -win +} +--copy_file $MYSQL_TEST_DIR/std_data/old-format-relay-log$file_suffix.info $MYSQLD_DATADIR/relay-log.info + +--echo # Read relay-log.info +START SLAVE IO_THREAD; +--source include/wait_for_slave_io_to_start.inc +--echo # Check that relay log coordinates are equal to those we saved in old-format_relay-log.info +--let $master_file= query_get_value(SHOW SLAVE STATUS, Relay_Master_Log_File, 1) +--let $master_pos= query_get_value(SHOW SLAVE STATUS, Exec_Master_Log_Pos, 1) +--let $relay_log_file= query_get_value(SHOW SLAVE STATUS, Relay_Log_File, 1) +--let $relay_log_pos= query_get_value(SHOW SLAVE STATUS, Relay_Log_Pos, 1) +--echo $master_file= $master_file, $master_pos, $relay_log_file, $relay_log_pos +if (`SELECT "$master_file" != "" OR + "$master_pos" != "0" OR + "$relay_log_file" != "slave-relay-bin.000001" OR + "$relay_log_pos" != "4"`) { + --echo ERROR: log coordinates changed + --die log coordinates changed +} + +--let $rpl_only_running_threads= 1 +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_read_only.test b/mysql-test/suite/rpl/t/rpl_read_only.test new file mode 100644 index 00000000..c4781bbb --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_read_only.test @@ -0,0 +1,129 @@ +# Test case for BUG #11733 +-- source include/have_innodb.inc +-- source include/master-slave.inc + +call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT"); + +# Create a test and replicate it to slave +connection master; +create user test; +sync_slave_with_master; + +# Setting the master readonly : +# - the variable @@readonly is not replicated on the slave + +connect (master2,127.0.0.1,test,,test,$MASTER_MYPORT,); +connect (slave2,127.0.0.1,test,,test,$SLAVE_MYPORT,); + +connection master1; + +create table t1(a int) engine=InnoDB; +create table t2(a int) engine=MyISAM; +insert into t1 values(1001); +insert into t2 values(2001); + +connection master; +set global read_only=1; + +connection master1; +select @@read_only; +select * from t1; +select * from t2; + +sync_slave_with_master; +select @@read_only; +select * from t1; +select * from t2; + +# - replication of transactions +connection master; +set global read_only=0; + +connection master1; +BEGIN; + +connection master2; +BEGIN; + +connection master; +select @@read_only; +set global read_only=1; + +connection master1; +-- echo *** On SUPER USER connection *** +insert into t1 values(1002); +--disable_warnings +insert into t2 values(2002); +--enable_warnings + +connection master2; +-- echo *** On regular USER connection *** +--error ER_OPTION_PREVENTS_STATEMENT +insert into t1 values(1003); +--error ER_OPTION_PREVENTS_STATEMENT +insert into t2 values(2003); + +connection master1; +## works even with read_only=1, because master1 is root +-- echo *** SUPER USER COMMIT (must succeed) *** +COMMIT; + +connection master2; +-- echo *** regular USER COMMIT (must succeed - nothing to commit) *** +COMMIT; + +connection master; +select @@read_only; +set global read_only=0; + +connection master1; +insert into t1 values(1004); +insert into t2 values(2004); + +select * from t1; +select * from t2; + +sync_slave_with_master; +select * from t1; +select * from t2; + +# Setting the slave readonly : replication will pass +# +connection slave1; +set global read_only=1; + +connection slave; +select @@read_only; +# Make sure the replicated table is also transactional +show create table t1; +# Make sure the replicated table is not transactional +show create table t2; + +connection master; +insert into t1 values(1005); +insert into t2 values(2005); +select * from t1; +select * from t2; + +sync_slave_with_master; +connection slave; +select * from t1; +select * from t2; + +# Non root user can not write on the slave +connection slave2; +--error ER_OPTION_PREVENTS_STATEMENT +insert into t1 values(1006); +--error ER_OPTION_PREVENTS_STATEMENT +insert into t2 values(2006); + +## Cleanup +connection master; +drop user test; +drop table t1; +drop table t2; +sync_slave_with_master; +set global read_only=0; + + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_read_only2.test b/mysql-test/suite/rpl/t/rpl_read_only2.test new file mode 100644 index 00000000..da825c8f --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_read_only2.test @@ -0,0 +1,30 @@ +--source include/have_binlog_format_statement.inc +--source include/master-slave.inc + +--echo # +--echo # Ensure that read-only slave logs temporary table statements under statement based +--echo # replication. This is related to MDEV-17863. +--echo # + +connection slave; +set global read_only=1; + +connection master; + +create table t1(a int) engine=MyISAM; +create temporary table tmp1 (a int) engine=MyISAM; +insert into t1 values(1); +insert into tmp1 values (2); +insert into t1 select * from tmp1; +insert into t1 values(3); +select * from t1; +analyze table t1; +drop table t1; +drop temporary table tmp1; + +sync_slave_with_master; +--source include/show_binlog_events.inc +set global read_only=0; +connection master; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_relay_max_extension.test b/mysql-test/suite/rpl/t/rpl_relay_max_extension.test new file mode 100644 index 00000000..e1e087f2 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_relay_max_extension.test @@ -0,0 +1,109 @@ +# ==== Purpose ==== +# +# Test verifies that auto purging mechanism of relay logs works fine when the +# file extension grows beyond 999999. +# +# ==== Implementation ==== +# +# Steps: +# 0 - In master-slave setup clear all the relay logs on the slave server. +# 1 - Start the slave so that new relay logs starting from +# 'slave-relay-bin.000001' are created. +# 2 - Get the active relay-log file name by using SHOW SLAVE STATUS. +# Shutdown the slave server. +# 3 - Rename active relay log to '999997' in both 'relay-log.info' and +# 'slave-relay-bin.index' files. +# 4 - Restart the slave server by configuring 'slave_parallel_threads=1' +# and 'max_relay_log_size=100K'. +# 5 - Generate load on master such that few relay logs are generated on +# slave. The relay log sequence number will change to 7 digits. +# 6 - Sync slave with master to ensure that relay logs are applied on +# slave. They should have been automatically purged. +# 7 - Assert that there is no 'slave-relay-bin.999999' file in +# 'relay-log.info'. +# +# ==== References ==== +# +# MDEV-8134: The relay-log is not flushed after the slave-relay-log.999999 +# showed +# + +--source include/have_innodb.inc +--source include/have_binlog_format_row.inc +--let $rpl_topology=1->2 +--source include/rpl_init.inc + +--connection server_2 +--source include/stop_slave.inc +RESET SLAVE; +--source include/start_slave.inc +--source include/stop_slave.inc +--let $relay_log=query_get_value(SHOW SLAVE STATUS, Relay_Log_File, 1) + +--echo # +--echo # Stop slave server +--echo # + +--let $datadir = `select @@datadir` +--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.2.expect +--shutdown_server 10 +--source include/wait_until_disconnected.inc + +--exec sed -i "s/$relay_log/slave-relay-bin.999997/g" $datadir/relay-log.info +--exec sed -i "s/$relay_log/slave-relay-bin.999997/g" $datadir/slave-relay-bin.index + +--echo # +--echo # Simulate file number get close to 999997 +--echo # by renaming relay logs and modifying index/info files + +--move_file $datadir/$relay_log $datadir/slave-relay-bin.999997 + +--echo # +--echo # Restart slave server +--echo # + +--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.2.expect +--enable_reconnect +--source include/wait_until_connected_again.inc +SET @save_slave_parallel_threads= @@GLOBAL.slave_parallel_threads; +SET @save_max_relay_log_size= @@GLOBAL.max_relay_log_size; + +SET GLOBAL slave_parallel_threads=1; +SET GLOBAL max_relay_log_size=100 * 1024; +--source include/start_slave.inc + +--connection server_1 +create table t1 (i int, c varchar(1024)); +--echo # +--echo # Insert some data to generate enough amount of binary logs +--echo # +--let $count = 1000 +--disable_query_log +while ($count) +{ + eval insert into t1 values (1001 - $count, repeat('a',1000)); + dec $count; +} +--enable_query_log +--save_master_pos + +--connection server_2 +--sync_with_master + +--let $relay_log=query_get_value(SHOW SLAVE STATUS, Relay_Log_File, 1) + +--echo # +--echo # Assert that 'slave-relay-bin.999999' is purged. +--echo # +let SEARCH_FILE=$datadir/slave-relay-bin.index; +let SEARCH_PATTERN=slave-relay-bin.999999; +source include/search_pattern_in_file.inc; + +--source include/stop_slave.inc +SET GLOBAL slave_parallel_threads= @save_slave_parallel_threads; +SET GLOBAL max_relay_log_size= @save_max_relay_log_size; +--source include/start_slave.inc + +--connection server_1 +DROP TABLE t1; +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_relay_space_innodb.test b/mysql-test/suite/rpl/t/rpl_relay_space_innodb.test new file mode 100644 index 00000000..ccb1424a --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_relay_space_innodb.test @@ -0,0 +1,3 @@ +-- source include/have_innodb.inc +let $engine_type=InnoDB; +-- source include/rpl_sv_relay_space.test diff --git a/mysql-test/suite/rpl/t/rpl_relay_space_myisam.test b/mysql-test/suite/rpl/t/rpl_relay_space_myisam.test new file mode 100644 index 00000000..6aa91dbc --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_relay_space_myisam.test @@ -0,0 +1,2 @@ +let $engine_type=MyISAM; +-- source include/rpl_sv_relay_space.test diff --git a/mysql-test/suite/rpl/t/rpl_relayrotate-slave.opt b/mysql-test/suite/rpl/t/rpl_relayrotate-slave.opt new file mode 100644 index 00000000..5cdfe28d --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_relayrotate-slave.opt @@ -0,0 +1,2 @@ +--max_relay_log_size=16384 +--log-warnings diff --git a/mysql-test/suite/rpl/t/rpl_relayrotate.test b/mysql-test/suite/rpl/t/rpl_relayrotate.test new file mode 100644 index 00000000..720739e1 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_relayrotate.test @@ -0,0 +1 @@ +--source include/rpl_relayrotate.inc diff --git a/mysql-test/suite/rpl/t/rpl_relayspace-slave.opt b/mysql-test/suite/rpl/t/rpl_relayspace-slave.opt new file mode 100644 index 00000000..06d96aa3 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_relayspace-slave.opt @@ -0,0 +1 @@ +--relay_log_space_limit=10 diff --git a/mysql-test/suite/rpl/t/rpl_relayspace.test b/mysql-test/suite/rpl/t/rpl_relayspace.test new file mode 100644 index 00000000..fc33d6bc --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_relayspace.test @@ -0,0 +1,52 @@ +# The slave is started with relay_log_space_limit=10 bytes, +# to force the deadlock after one event. + +source include/master-slave.inc; +--let $master_log_file= query_get_value(SHOW MASTER STATUS, File, 1) +connection slave; +--source include/stop_slave.inc +connection master; +# This will generate a master's binlog > 10 bytes +create table t1 (a int); +drop table t1; +create table t1 (a int); +drop table t1; +connection slave; +reset slave; +start slave io_thread; +# Give the I/O thread time to block. +let $slave_param= Slave_IO_State; +let $slave_param_value= Waiting for the slave SQL thread to free enough relay log space; +source include/wait_for_slave_param.inc; + +# A bug caused the I/O thread to refuse stopping. +--source include/stop_slave_io.inc +reset slave; +--source include/start_slave.inc + +# The I/O thread stops filling the relay log when it's >10b. And the +# SQL thread cannot purge this relay log as purge is done only when +# the SQL thread switches to another relay log, which does not exist +# here. So we should have a deadlock. If it is not resolved +# automatically we'll detect it with master_pos_wait that waits for +# farther than 1Ob; it will timeout after 300 seconds (which is inline +# with the default used for sync_slave_with_master and will protect us +# against slow test envs); also the slave will probably not cooperate +# to shutdown (as 2 threads are locked) +--let $outcome= `SELECT MASTER_POS_WAIT('$master_log_file',200,300) AS mpw;` + +# master_pos_wait returns: +# +# * >= 0, the number of events the slave had to wait to advance to the +# position +# +# * -1, if there was a timeout +# +# * NULL, if an error occurred, or the SQL thread was not started, +# slave master info is not initialized, the arguments are incorrect +--let $assert_text= Assert that master_pos_wait does not timeout nor it returns NULL +--let $assert_cond= $outcome IS NOT NULL AND $outcome <> -1 +--source include/assert.inc + +# End of 4.1 tests +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_reopen_temp_table.test b/mysql-test/suite/rpl/t/rpl_reopen_temp_table.test new file mode 100644 index 00000000..2396dc34 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_reopen_temp_table.test @@ -0,0 +1,43 @@ +--source include/have_innodb.inc +--source include/master-slave.inc + +# Clean up old slave's binlogs (see rpl_temporary.test for explanation). +save_master_pos; +connection slave; +sync_with_master; +reset master; + +--echo # +--echo # MDEV-5535: Cannot reopen temporary table +--echo # + +connection master; +--disable_query_log +CALL mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT"); +--enable_query_log + +disable_warnings; +DROP TABLE IF EXISTS t1, t2, t3; +enable_warnings; + +CREATE TEMPORARY TABLE t1(c1 INT) ENGINE=INNODB; +INSERT INTO t1 VALUES (1), (2), (3), (4), (5); + +CREATE TEMPORARY TABLE t2 SELECT A.c1 a, B.c1 b FROM t1 AS A, t1 AS B; + +CREATE TABLE t3 SELECT * FROM t2; + +SELECT COUNT(*) = 5 FROM t1; +SELECT COUNT(*) = 25 FROM t2; +SELECT COUNT(*) = 25 FROM t3; + +sync_slave_with_master; + +SELECT COUNT(*) = 25 FROM t3; + +connection master; +DROP TABLE t1, t2, t3; + +sync_slave_with_master; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_replicate_do-slave.opt b/mysql-test/suite/rpl/t/rpl_replicate_do-slave.opt new file mode 100644 index 00000000..da345474 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_replicate_do-slave.opt @@ -0,0 +1 @@ +--replicate-do-table=test.t1 diff --git a/mysql-test/suite/rpl/t/rpl_replicate_do.test b/mysql-test/suite/rpl/t/rpl_replicate_do.test new file mode 100644 index 00000000..66ddf2df --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_replicate_do.test @@ -0,0 +1,65 @@ +# This test assumes we are ignoring updates on table t2, but doing +# updates on t1 +source include/master-slave.inc; +--disable_warnings +drop table if exists t11; +connection slave; +drop table if exists t11; +--enable_warnings + +create table t2 (n int); +insert into t2 values(4); +connection master; +create table t2 (s char(20)); +load data infile '../../std_data/words.dat' into table t2; +insert into t2 values('five'); +create table t1 (m int); +insert into t1 values(15),(16),(17); +update t1 set m=20 where m=16; +delete from t1 where m=17; +create table t11 select * from t1; +sync_slave_with_master; +select * from t1 ORDER BY m; +select * from t2; +--error 1146 +select * from t11; +connection master; +drop table if exists t1,t2,t11; +sync_slave_with_master; +# show slave status, just to see of it prints replicate-do-table +let $status_items= Replicate_Do_Table; +source include/show_slave_status.inc; + +# End of 4.1 tests + +# +# Bug#24478 DROP TRIGGER is not caught by replicate-*-table filters +# +connection master; +create table t1 (a int, b int); +create trigger trg1 before insert on t1 for each row set new.b=2; +create table t2 (a int, b int); +create trigger trg2 before insert on t2 for each row set new.b=2; +show tables; +--replace_column 6 # +show triggers; +sync_slave_with_master; +connection slave; +show tables; +--replace_column 6 # +show triggers; +connection master; +drop trigger trg1; +drop trigger trg2; +--replace_column 6 # +show triggers; +sync_slave_with_master; +connection slave; +show tables; +--replace_column 6 # +show triggers; +connection master; +drop table t1; +drop table t2; +sync_slave_with_master; +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_replicate_ignore_db-slave.opt b/mysql-test/suite/rpl/t/rpl_replicate_ignore_db-slave.opt new file mode 100644 index 00000000..6e3aed44 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_replicate_ignore_db-slave.opt @@ -0,0 +1 @@ +--replicate_ignore_db=mysqltest1 diff --git a/mysql-test/suite/rpl/t/rpl_replicate_ignore_db.test b/mysql-test/suite/rpl/t/rpl_replicate_ignore_db.test new file mode 100644 index 00000000..f1907456 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_replicate_ignore_db.test @@ -0,0 +1,31 @@ +# see if --replicate-ignore-db works + +--source include/master-slave.inc + +--disable_warnings +drop database if exists mysqltest1; +drop database if exists mysqltest2; +--enable_warnings +create database mysqltest1; +create database mysqltest2; + +use mysqltest1; +create table t1 (a int); +insert into t1 values(1); +sync_slave_with_master; +--error 1146 +select * from mysqltest1.t1; + +connection master; +use mysqltest2; +create table t1 (a int); +insert into t1 values(1); +sync_slave_with_master; +select * from mysqltest2.t1; + +# cleanup +connection master; +drop database mysqltest1; +drop database mysqltest2; +sync_slave_with_master; +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_report-slave.opt b/mysql-test/suite/rpl/t/rpl_report-slave.opt new file mode 100644 index 00000000..123e5c27 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_report-slave.opt @@ -0,0 +1,2 @@ +--report-host=127.0.0.1 --report-user='my_user' --report-password='my_password' --report-port=9308 + diff --git a/mysql-test/suite/rpl/t/rpl_report.test b/mysql-test/suite/rpl/t/rpl_report.test new file mode 100644 index 00000000..a7344291 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_report.test @@ -0,0 +1,22 @@ +# Verify that mysqld init time --report-{host,port,user,password} parameters +# are SHOW-able and SELECT-able FROM INFORMATION_SCHEMA.global_variables + +source include/master-slave.inc; + +connection slave; +select * from Information_schema.GLOBAL_VARIABLES where variable_name like 'report_host'; +select * from Information_schema.GLOBAL_VARIABLES where variable_name like 'report_port'; +select * from Information_schema.GLOBAL_VARIABLES where variable_name like 'report_user'; +select * from Information_schema.GLOBAL_VARIABLES where variable_name like 'report_password'; +query_vertical show global variables like 'report_host'; +query_vertical show global variables like 'report_port'; +query_vertical show global variables like 'report_user'; +query_vertical show global variables like 'report_password'; + +# to demonstrate that report global variables are read-only +error ER_INCORRECT_GLOBAL_LOCAL_VAR; +set @@global.report_host='my.new.address.net'; + + +--echo end of tests +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_report_port.test b/mysql-test/suite/rpl/t/rpl_report_port.test new file mode 100644 index 00000000..2a14d278 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_report_port.test @@ -0,0 +1,74 @@ +# +#BUG#13333431 : INCORRECT DEFAULT PORT IN 'SHOW SLAVE HOSTS' OUTPUT +# +# ==== Purpose ==== +# +# The test show the default value printed for the slave's port number if the +# --report-port= is not set on the slave. This is different from +# the present scenario which show 3306 as the default value if the report-port +# is not set on the slave. +# +#====Method==== +# +# Start replication with report port set to 9000 and restart the slave. +# In this case on doing SHOW SLAVE HOSTS on the master, we get the port number +# of the slave to be 9000. +# In the second case restart the slave server with report port not set. In this +# case on doing SHOW SLAVE HOSTS on the master, we get the actual port number +# of the slave (ie. SLAVE_PORT). + +source include/have_binlog_format_mixed.inc; +source include/master-slave.inc; + +connection master; + +# Start the server with some value being passed to the report_port=