#
# This test will verify if the slave SQL thread and the slave IO thread behave
# correctly when the IO thread is restarted in the middle of a transaction.
#
# It is expected that the IO thread will retrieve again the partial transaction
# from the beginning and that the SQL thread will rollback the partially
# retrieved transaction before applying the fully retrieved one.
#
# This test will insert some data in the master and then will stop the slave
# IO thread right after queuing an event of a given type, starting the IO
# thread again to fully retrieve the partially received transaction.
#

--source include/have_gtid.inc

# As this test depends on the use of a User_var_log_event in a DML statement
# we have to use statement based replication.
--source include/have_binlog_format_statement.inc
--source include/force_restart.inc
# Enable auto_position protocol
--let $use_gtids= 1
--let $rpl_gtid_utils= 1
--source include/master-slave.inc
# Test should run only on debug build
source include/have_debug.inc;
source include/have_debug_sync.inc;

# Initial setup
--connection master
CREATE TABLE t1(i INT) ENGINE=InnoDB;
# The following "FLUSH LOGS" will make the master to clear the "created" flag
# of the Format Description events in the next binlog files (and also in
# their replicated versions in the slave's relaylog).
FLUSH LOGS;
--source include/sync_slave_sql_with_master.inc
SET @save_debug=@@global.debug;

#
# Actual test starts here.
#
# Test will do the following five iterations
#     1.Stop I/O thread after reading GTID_LOG_EVENT
#     2.Stop I/O thread after reading QUERY_LOG_EVENT
#     3.Stop I/O thread after reading XID_LOG_EVENT
#        which is equal to I/O thread sync with master
#     4.Stop I/O thread after the gtid is in EXECUTED_GTID_SET
#       i.e., after sync slave sql thread with master.
#     5.Stop I/O thread after reading USER_VAR_LOG_EVENT
# and after that make sure there are no missing gtid events
# i.e., we will verify this by doing diff between master:t1,
# slave:t1.

--let $i=1
while ($i <= 5)
{
  if ($i == 1)
  {
    SET GLOBAL DEBUG='d,stop_io_after_reading_gtid_log_event';
  }
  if ($i == 2)
  {
    SET GLOBAL DEBUG='d,stop_io_after_reading_query_log_event';
  }
  if ($i == 3)
  {
    # Stopping sql thread to make sure that case 3 is not equal to case 4.
    --source include/stop_slave_sql.inc
    SET GLOBAL DEBUG='d,stop_io_after_reading_xid_log_event';
  }
  if ($i == 5)
  {
    SET GLOBAL DEBUG='d,stop_io_after_reading_user_var_log_event';
  }
  --connection master
  BEGIN;
  --eval INSERT INTO t1 VALUES ($i)
  --eval SET @v= $i * 100
  --eval INSERT INTO t1 VALUES (@v)
  COMMIT;
  --connection slave
  if ($i == 4)
  {
    --connection master
    --source include/sync_slave_sql_with_master.inc
    --source include/stop_slave_io.inc
  }
  --source include/wait_for_slave_io_to_stop.inc
  # Remove the debug point and restart the slave threads
  SET GLOBAL DEBUG= @save_debug;

  --source include/start_slave_io.inc
  if ($i == 3)
  {
    --source include/start_slave_sql.inc
  }
  # Do one more insert on master and then sync slave with master (to make sure
  # that re-replicating the events are done successfully.
  --connection master
  --eval INSERT INTO t1 VALUES ($i)
  --source include/sync_slave_sql_with_master.inc
  # Now compare master and slave's t1 table data
  # to prove that there are no missing gtids.
  --let diff_tables= master:t1, slave:t1
  --source include/diff_tables.inc
  --inc $i
}

# Cleanup
--connection master
DROP TABLE t1;

--source include/rpl_end.inc
