From 51eaa7fe53eb017ffb3f4dc2f318cb0511b7cd26 Mon Sep 17 00:00:00 2001 From: Kristian Nielsen Date: Fri, 11 Sep 2015 10:51:56 +0200 Subject: MDEV-8193: UNTIL clause in START SLAVE is sporadically disobeyed by parallel replication The code was using the wrong variable when comparing the binlog name for the UNTIL position. This could cause the comparison to fail after binlog rotation, in turn causing the UNTIL clause to not trigger slave stop. --- mysql-test/suite/rpl/r/rpl_mdev8193.result | 24 +++++++++++++ mysql-test/suite/rpl/t/rpl_mdev8193.test | 56 ++++++++++++++++++++++++++++++ sql/rpl_parallel.cc | 2 +- sql/rpl_rli.cc | 4 +-- 4 files changed, 83 insertions(+), 3 deletions(-) create mode 100644 mysql-test/suite/rpl/r/rpl_mdev8193.result create mode 100644 mysql-test/suite/rpl/t/rpl_mdev8193.test diff --git a/mysql-test/suite/rpl/r/rpl_mdev8193.result b/mysql-test/suite/rpl/r/rpl_mdev8193.result new file mode 100644 index 00000000000..ad92d32e7d4 --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_mdev8193.result @@ -0,0 +1,24 @@ +include/master-slave.inc +[connection master] +include/stop_slave_sql.inc +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); +insert into t1 select i+20+0*sleep(1) from t1 where i=1; +Warnings: +Note 1592 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. +flush logs; +insert into t1 values (5),(6); +insert into t1 values (7),(8); +insert into t1 values (9),(10); +insert into t1 values (11),(12); +insert into t1 values (13),(14); +insert into t1 values (15),(16); +set global slave_parallel_threads = 1; +start slave until master_log_file='MASTER_FILE', master_log_pos=MASTER_POS; +drop table t1; +include/stop_slave_io.inc +set global slave_parallel_threads = DEFAULT; +drop table t1; +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 00000000000..1a0d86e8035 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_mdev8193.test @@ -0,0 +1,56 @@ +--source include/master-slave.inc +--source include/have_binlog_format_statement.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`) +{ + SELECT * FROM t1; + query_vertical show slave status; + 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/sql/rpl_parallel.cc b/sql/rpl_parallel.cc index df6fc92e9bd..cc5da77303c 100644 --- a/sql/rpl_parallel.cc +++ b/sql/rpl_parallel.cc @@ -95,7 +95,6 @@ handle_queued_pos_update(THD *thd, rpl_parallel_thread::queued_event *qev) if (cmp < 0) { strcpy(rli->group_master_log_name, qev->future_event_master_log_name); - rli->notify_group_master_log_name_update(); rli->group_master_log_pos= qev->future_event_master_log_pos; } else if (cmp == 0 @@ -2065,6 +2064,7 @@ rpl_parallel::do_event(rpl_group_info *serial_rgi, Log_event *ev, { memcpy(rli->future_event_master_log_name, rev->new_log_ident, rev->ident_len+1); + rli->notify_group_master_log_name_update(); } } diff --git a/sql/rpl_rli.cc b/sql/rpl_rli.cc index 9bd0ca55b01..e74088090f9 100644 --- a/sql/rpl_rli.cc +++ b/sql/rpl_rli.cc @@ -996,7 +996,6 @@ void Relay_log_info::inc_group_relay_log_pos(ulonglong log_pos, if (cmp < 0) { strcpy(group_master_log_name, rgi->future_event_master_log_name); - notify_group_master_log_name_update(); group_master_log_pos= log_pos; } else if (group_master_log_pos < log_pos) @@ -1218,7 +1217,8 @@ bool Relay_log_info::is_until_satisfied(THD *thd, Log_event *ev) if (ev && ev->server_id == (uint32) global_system_variables.server_id && !replicate_same_server_id) DBUG_RETURN(FALSE); - log_name= group_master_log_name; + log_name= (opt_slave_parallel_threads > 0 ? + future_event_master_log_name : group_master_log_name); log_pos= ((!ev)? group_master_log_pos : (get_flag(IN_TRANSACTION) || !ev->log_pos) ? group_master_log_pos : ev->log_pos - ev->data_written); -- cgit v1.2.1