#
# Test verifies MTS behaviour with regard to 
# Change-Master.
# 
# Related bugs:
# Bug 12995174 - MTS: UNEXPECTED RECOVERY ATTEMPT ENDS WITH ER_MASTER_INFO OR ASSERTION 

--source include/not_gtid_enabled.inc
--source include/master-slave.inc
# The test for bug#12995174 is not format-specific but uses sleep
# so it made to be run in ROW format that is the way the bug is reported.
--source include/have_binlog_format_row.inc
--source include/have_innodb.inc

--connection slave
call mtr.add_suppression("Slave SQL: .*Could not execute Write_rows event on table d1.t1; Duplicate entry '13' for key 'a'");
call mtr.add_suppression("Slave SQL: ... The slave coordinator and worker threads are stopped, possibly leaving data in inconsistent state.");
call mtr.add_suppression("Error writing relay log configuration.");
--source include/stop_slave.inc
SET @save.slave_parallel_workers=@@global.slave_parallel_workers;
SET @@global.slave_parallel_workers=2;
--source include/start_slave.inc

--connection master

CREATE DATABASE d1;
CREATE DATABASE d2;
CREATE TABLE d1.t1 (a int unique) ENGINE=INNODB;
CREATE TABLE d2.t1 (a int unique) ENGINE=INNODB;

INSERT INTO d1.t1 VALUES (1);
FLUSH LOGS;

--source include/sync_slave_sql_with_master.inc

--source include/stop_slave.inc
CHANGE MASTER TO MASTER_DELAY=5;
--source include/start_slave.inc

--connection master
INSERT INTO d1.t1 VALUES (3);
--sleep 3
INSERT INTO d1.t1 VALUES (5);
FLUSH LOGS;

--connection slave
--source include/stop_slave.inc

let $relay_file = query_get_value( SHOW SLAVE STATUS, Relay_Log_File, 1 );
let $relay_pos = query_get_value( SHOW SLAVE STATUS, Relay_Log_Pos, 1 );

--replace_regex /RELAY_LOG_FILE=[^,]+/RELAY_LOG_FILE=FILE/ /RELAY_LOG_POS=[0-9]+/ RELAY_LOG_POS= POS/
eval CHANGE MASTER TO RELAY_LOG_FILE='$relay_file', RELAY_LOG_POS=$relay_pos;

--source include/start_slave.inc
--sleep 5
--source include/stop_slave.inc

let $relay_file = query_get_value( SHOW SLAVE STATUS, Relay_Log_File, 1 );
let $relay_pos = query_get_value( SHOW SLAVE STATUS, Relay_Log_Pos, 1 );
--replace_regex /RELAY_LOG_FILE=[^,]+/RELAY_LOG_FILE=FILE/ /RELAY_LOG_POS=[0-9]+/ RELAY_LOG_POS= POS/
eval CHANGE MASTER TO RELAY_LOG_FILE='$relay_file', RELAY_LOG_POS=$relay_pos, MASTER_DELAY=0;

--source include/start_slave.inc
BEGIN;
INSERT INTO d1.t1 VALUES (13); # to cause the dup key error
# change-master with gaps
--connection master

INSERT INTO d1.t1 VALUES (6);
INSERT INTO d2.t1 VALUES (7);
INSERT INTO d1.t1 VALUES (13);
INSERT INTO d2.t1 VALUES (8);  # this worker will race over one inserting (13)
INSERT INTO d2.t1 VALUES (9);

--connection slave1
# make sure workers doing d2.t1 raced the one that occupied  with d1.t1
--let $count= 1
--let $table= d2.t1
--let $wait_condition= select count(*) = 1 from $table where a = 8
--source include/wait_condition.inc

--connection slave
# make worker executing (13) to error out
COMMIT; 

--let $slave_sql_errno= 1062
--source include/wait_for_slave_sql_error.inc

--source include/stop_slave_io.inc

let $relay_file = query_get_value( SHOW SLAVE STATUS, Relay_Log_File, 1 );
let $relay_pos = query_get_value( SHOW SLAVE STATUS, Relay_Log_Pos, 1 );
--replace_regex /RELAY_LOG_FILE=[^,]+/RELAY_LOG_FILE=FILE/ /RELAY_LOG_POS=[0-9]+/ RELAY_LOG_POS= POS/
--error ER_MTS_CHANGE_MASTER_CANT_RUN_WITH_GAPS
eval CHANGE MASTER TO RELAY_LOG_FILE='$relay_file', RELAY_LOG_POS=$relay_pos;

SET @@global.slave_parallel_workers= @save.slave_parallel_workers; # cleanup

#
# --relay-log-recovery= 1 and MTS gaps is handled similarly to Change-Master
#
--let $rpl_server_number= 2
--let $rpl_server_parameters= --relay-log-recovery --skip-slave-start
--source include/rpl_restart_server.inc

--connection slave
SELECT @@global.relay_log_recovery as 'must be ON';
call mtr.add_suppression("--relay-log-recovery cannot be executed when the slave was stopped with an error or killed in MTS mode; consider using RESET SLAVE or restart the server with --relay-log-recovery = 0");
call mtr.add_suppression("Failed to initialize the master info structure");
#
# the following suppression applies to either restart.
# The reason it was not required when the test run "normally" with the default
# --relay-log-info-repository=FILE is here:
# Bug #15858271 MTR INCORRECTLY PROPAGATES A SERVER OPTION FROM A PREVIOUS TEST TO THE CURRENT
# todo: The suppression should be removed after the bug is fixed.
#
call mtr.add_suppression("It is not possible to change the type of the relay log repository because there are workers repositories with possible execution gaps. The value of --relay_log_info_repository is altered to one of the found Worker repositories");
--let $rpl_server_number= 2
--let $rpl_server_parameters= --skip-slave-start
--source include/rpl_restart_server.inc

SELECT @@global.relay_log_recovery as 'must be OFF';
--connection slave
DELETE FROM d1.t1 WHERE a = 13;
--source include/start_slave.inc

#
# cleanup
#
--connection master
DROP DATABASE d1;
DROP DATABASE d2;
--source include/sync_slave_sql_with_master.inc

###############################################################################
# Bug#20411374: CAN NOT EXECUTE CHANGE MASTER AFTER ERROR OCCURED IN MTS MODE
#
# Problem:
# ========
# When error occurred in MTS mode, If user first change master
# (ER_MTS_CHANGE_MASTER_CANT_RUN_WITH_GAPS received here), and then reset slave,
# user can never change master (error ER_MTS_CHANGE_MASTER_CANT_RUN_WITH_GAPS
# occurred again). The debug version mysqld will crash at this case.
#
# Test:
# =====
# Generate MTS gaps and execute CHANGE MASTER command so that
# ER_MTS_CHANGE_MASTER_CANT_RUN_WITH_GAPS error is reported. Execute RESET
# SLAVE command. Reexecute the CHANGE MASTER command once again it should
# report an assert in the case of bug scenario and it should succeed after the
# fix.
###############################################################################
--source include/rpl_connection_slave.inc
--source include/stop_slave.inc
SET @save.slave_parallel_workers=@@global.slave_parallel_workers;
SET @@global.slave_parallel_workers=2;
SET @save.relay_log_info_repository=@@global.relay_log_info_repository;
SET @@global.relay_log_info_repository='TABLE';
--source include/start_slave.inc

--source include/rpl_connection_master.inc
CREATE DATABASE d1;
CREATE DATABASE d2;
CREATE TABLE d1.t1 (a int unique) ENGINE=INNODB;
CREATE TABLE d2.t1 (a int unique) ENGINE=INNODB;
--source include/sync_slave_sql_with_master.inc
BEGIN;
INSERT INTO d1.t1 VALUES (13); # to cause the dup key error
# change-master with gaps
--source include/rpl_connection_master.inc
INSERT INTO d1.t1 VALUES (6);
INSERT INTO d2.t1 VALUES (7);
INSERT INTO d1.t1 VALUES (13);
INSERT INTO d2.t1 VALUES (8);  # this worker will race over one inserting (13)
INSERT INTO d2.t1 VALUES (9);

--source include/rpl_connection_slave1.inc
# make sure workers doing d2.t1 raced the one that occupied  with d1.t1
--let $count= 1
--let $table= d2.t1
--let $wait_condition= select count(*) = 1 from $table where a = 8
--source include/wait_condition.inc

--source include/rpl_connection_slave.inc
# make worker executing (13) to error out
COMMIT;

--let $slave_sql_errno= 1062
--source include/wait_for_slave_sql_error.inc

--source include/stop_slave_io.inc

--source include/rpl_connection_master.inc
FLUSH LOGS;
--let $file= query_get_value(SHOW MASTER STATUS, File, 1)
--let $pos= query_get_value(SHOW MASTER STATUS, Position, 1)

--source include/rpl_connection_slave.inc
--replace_result $MASTER_MYPORT MASTER_PORT  $file FILE $pos POS
--replace_column 2 ####
--error ER_MTS_CHANGE_MASTER_CANT_RUN_WITH_GAPS
eval CHANGE MASTER TO MASTER_HOST= '127.0.0.1', MASTER_PORT= $MASTER_MYPORT, MASTER_USER= 'root',MASTER_LOG_FILE = '$file', MASTER_LOG_POS = $pos ;
reset slave;
--replace_result $MASTER_MYPORT MASTER_PORT  $file FILE $pos POS
--replace_column 2 ####
eval CHANGE MASTER TO MASTER_HOST= '127.0.0.1', MASTER_PORT= $MASTER_MYPORT, MASTER_USER= 'root',MASTER_LOG_FILE = '$file', MASTER_LOG_POS = $pos ;

SET @@global.slave_parallel_workers= @save.slave_parallel_workers;
SET @@global.relay_log_info_repository= @save.relay_log_info_repository;
--source include/start_slave.inc
#
# cleanup
#
--source include/rpl_connection_master.inc
DROP DATABASE d1;
DROP DATABASE d2;

--source include/rpl_end.inc
