diff --git a/mysql-test/suite/multi_source/gtid_ignore_duplicates_skip_counter.cnf b/mysql-test/suite/multi_source/gtid_ignore_duplicates_skip_counter.cnf new file mode 100644 index 0000000000000..0e4bd533a096d --- /dev/null +++ b/mysql-test/suite/multi_source/gtid_ignore_duplicates_skip_counter.cnf @@ -0,0 +1,4 @@ +!include my.cnf + +[mysqld.2] +log-slave-updates diff --git a/mysql-test/suite/multi_source/gtid_ignore_duplicates_skip_counter.result b/mysql-test/suite/multi_source/gtid_ignore_duplicates_skip_counter.result new file mode 100644 index 0000000000000..9637d54e3991a --- /dev/null +++ b/mysql-test/suite/multi_source/gtid_ignore_duplicates_skip_counter.result @@ -0,0 +1,46 @@ +include/rpl_init.inc [topology=1->2, 1->3] +# Set up +CREATE TABLE t (a INT); +include/save_master_pos.inc +include/save_master_gtid.inc +connection server_2; +START SLAVE; +include/sync_with_master_gtid.inc +connection server_3; +SET @save_gtid_ignore_duplicates= @@GLOBAL.gtid_ignore_duplicates; +SET @@GLOBAL.gtid_ignore_duplicates= ON; +START SLAVE IO_THREAD; +include/sync_io_with_master.inc +CHANGE MASTER 'bridge' TO +master_host='127.0.0.1', master_port=SERVER_MYPORT_2, master_user='root'; +SET @@SESSION.default_master_connection= 'bridge'; +include/start_slave.inc +include/sync_with_master_gtid.inc +include/stop_slave.inc +SET @@SESSION.default_master_connection= ''; +RESET SLAVE 'bridge' ALL; +# Test +SET @@GLOBAL.sql_slave_skip_counter= 100; +START SLAVE SQL_THREAD; +include/wait_for_slave_param.inc [Relay_Master_Log_File] +include/wait_for_slave_param.inc [Exec_Master_Log_Pos] +SELECT @@sql_slave_skip_counter; +@@sql_slave_skip_counter +100 +Skip_Counter = '100' +connection server_1; +DROP TABLE t; +include/save_master_gtid.inc +connection server_2; +include/sync_with_master_gtid.inc +connection server_3; +include/sync_with_master_gtid.inc +SHOW TABLES; +Tables_in_test +t +# Tear down +include/stop_slave.inc +SET @@GLOBAL.sql_slave_skip_counter= 0; +SET @@GLOBAL.gtid_ignore_duplicates= @save_gtid_ignore_duplicates; +SET STATEMENT sql_log_bin=0 FOR DROP TABLE t; +include/rpl_end.inc diff --git a/mysql-test/suite/multi_source/gtid_ignore_duplicates_skip_counter.test b/mysql-test/suite/multi_source/gtid_ignore_duplicates_skip_counter.test new file mode 100644 index 0000000000000..6368b1077bab9 --- /dev/null +++ b/mysql-test/suite/multi_source/gtid_ignore_duplicates_skip_counter.test @@ -0,0 +1,70 @@ +# Test combining `@@gtid_ignore_duplicates` and `@@sql_slave_skip_counter` +# +# Reference: MDEV-38636 `@@sql_slave_skip_counter` +# resets to 1 when skipping events by `@@gtid_ignore_duplicates` + +--let $rpl_topology= 1->2, 1->3 +--let $rpl_skip_start_slave= 1 +--source include/rpl_init.inc + + +--echo # Set up + +# Create some events to trigger `@@gtid_ignore_duplicates` with +CREATE TABLE t (a INT); +--source include/save_master_pos.inc +--source include/save_master_gtid.inc + +--connection server_2 +START SLAVE; +--source include/sync_with_master_gtid.inc + +--connection server_3 +SET @save_gtid_ignore_duplicates= @@GLOBAL.gtid_ignore_duplicates; +SET @@GLOBAL.gtid_ignore_duplicates= ON; + +# Queue the test events without processing (which increments `@@gtid_slave_pos`) +START SLAVE IO_THREAD; +--source include/sync_io_with_master.inc + +# Queue and process second copies of the events through another connection +--replace_result $SERVER_MYPORT_2 SERVER_MYPORT_2 +eval CHANGE MASTER 'bridge' TO + master_host='127.0.0.1', master_port=$SERVER_MYPORT_2, master_user='root'; + SET @@SESSION.default_master_connection= 'bridge'; + --source include/start_slave.inc + --source include/sync_with_master_gtid.inc + --source include/stop_slave.inc + SET @@SESSION.default_master_connection= ''; +RESET SLAVE 'bridge' ALL; + + +--echo # Test + +SET @@GLOBAL.sql_slave_skip_counter= 100; +START SLAVE SQL_THREAD; +--source include/sync_with_master.inc + +SELECT @@sql_slave_skip_counter; +--let $status_items= Skip_Counter +--source include/show_slave_status.inc + +--connection server_1 + DROP TABLE t; + --source include/save_master_gtid.inc +--connection server_2 + --source include/sync_with_master_gtid.inc +--connection server_3 +--source include/sync_with_master_gtid.inc +SHOW TABLES; # The counter should continue to skip the DROP TABLE. + + +--echo # Tear down + +--source include/stop_slave.inc +SET @@GLOBAL.sql_slave_skip_counter= 0; +SET @@GLOBAL.gtid_ignore_duplicates= @save_gtid_ignore_duplicates; +SET STATEMENT sql_log_bin=0 FOR DROP TABLE t; + +--let $rpl_only_running_threads= 1 +--source include/rpl_end.inc diff --git a/sql/log_event_server.cc b/sql/log_event_server.cc index 9ad2c5ebb1e28..c84fcc3e37978 100644 --- a/sql/log_event_server.cc +++ b/sql/log_event_server.cc @@ -660,6 +660,8 @@ Log_event::do_shall_skip(rpl_group_info *rgi) rli->slave_skip_counter)); if ((server_id == global_system_variables.server_id && !(rli->replicate_same_server_id || (flags & LOG_EVENT_ACCEPT_OWN_F))) || + rgi->gtid_ignore_duplicate_state == + rpl_group_info::GTID_DUPLICATE_IGNORE || (rli->slave_skip_counter == 1 && rli->is_in_group()) || (flags & LOG_EVENT_SKIP_REPLICATION_F && opt_replicate_events_marked_for_skip != RPL_SKIP_REPLICATE)) @@ -2455,7 +2457,8 @@ Query_log_event::do_shall_skip(rpl_group_info *rgi) opt_replicate_events_marked_for_skip != RPL_SKIP_REPLICATE) DBUG_RETURN(Log_event::EVENT_SKIP_IGNORE); - if (rli->slave_skip_counter > 0) + if (rli->slave_skip_counter || + rgi->gtid_ignore_duplicate_state == rpl_group_info::GTID_DUPLICATE_IGNORE) { if (is_begin()) { @@ -2466,6 +2469,9 @@ Query_log_event::do_shall_skip(rpl_group_info *rgi) if (is_commit() || is_rollback()) { thd->variables.option_bits&= ~(OPTION_BEGIN | OPTION_GTID_BEGIN); + if (rgi->gtid_ignore_duplicate_state == + rpl_group_info::GTID_DUPLICATE_IGNORE) + DBUG_RETURN(Log_event::EVENT_SKIP_IGNORE); DBUG_RETURN(Log_event::EVENT_SKIP_COUNT); } } @@ -3993,7 +3999,8 @@ Gtid_log_event::do_shall_skip(rpl_group_info *rgi) opt_replicate_events_marked_for_skip != RPL_SKIP_REPLICATE) return Log_event::EVENT_SKIP_IGNORE; - if (rli->slave_skip_counter > 0) + if (rli->slave_skip_counter || + rgi->gtid_ignore_duplicate_state == rpl_group_info::GTID_DUPLICATE_IGNORE) { if (!(flags2 & FL_STANDALONE)) { diff --git a/sql/slave.cc b/sql/slave.cc index 893e24627bddc..20b7a9cb627d6 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -4540,13 +4540,6 @@ static int exec_relay_log_event(THD* thd, Relay_log_info* rli, #endif /* WITH_WSREP */ DBUG_RETURN(1); } - /* - If we need to skip this event group (because the GTID was already - applied), then do it using the code for slave_skip_counter, which - is able to handle skipping until the end of the event group. - */ - if (!res) - rli->slave_skip_counter= 1; } }