1# ==== Purpose ====
2#
3# This test will verify if the IO thread will correctly handle the GTID and
4# the transaction boundary of transactions spanned along multiple relay log
5# files.
6#
7# This test starts creating a single transaction (CREATE TABLE), and then
8# sets a debug point that will make the IO thread to stop after queuing an
9# QUERY_LOG_EVENT. The test will stop the SQL thread after syncing with the
10# master.
11#
12# The test will then apply a transaction composed by three INSERT statements
13# that will be logged on master as one GTID_LOG_EVENT, four QUERY_LOG_EVENTS
14# (the BEGIN plus the three INSERT) and a XID_LOG_EVENT.
15#
16# By disabling GTID auto positioning, and restating the IO thread after each
17# time it stops because of the debug point, we guarantee that GTID+BEGIN will
18# be in one relay log file, each INSERT will be alone in distinct relay log
19# files and the XID will finalize the transaction in another relay log file.
20#
21# Finally, the test will restart the MySQL slave server to make it recover the
22# Retrieved_Gtid_Set from the relay log with the spanned transaction.
23#
24# ==== Related Bugs and Worklogs ====
25#
26# BUG#17943188: SHOW SLAVE STATUS/RETRIEVED_GTID_SET MAY HAVE PARTIAL TRX OR
27#               MISS COMPLETE TRX
28#
29
30# This test should run only on debug build
31--source include/have_debug.inc
32# This test uses debug sync to stop the IO thread in the middle of a transaction
33--source include/have_debug_sync.inc
34
35--source include/have_gtid.inc
36--source include/have_innodb.inc
37--source include/have_binlog_format_statement.inc
38--let $rpl_gtid_utils= 1
39--source include/master-slave.inc
40
41# Disable GTID auto positioning
42--source include/rpl_connection_slave.inc
43--source include/stop_slave.inc
44CHANGE MASTER TO MASTER_AUTO_POSITION= 0;
45--source include/start_slave.inc
46
47--source include/rpl_connection_master.inc
48CREATE TABLE t1 (c1 INT) ENGINE= InnoDB;
49
50--source include/sync_slave_sql_with_master.inc
51# We stop the SQL thread as we don't want it to apply the transaction to be
52# replicated before the recovery
53--source include/stop_slave_sql.inc
54
55--let $debug_point= stop_io_after_reading_query_log_event
56--source include/add_debug_point.inc
57
58--source include/rpl_connection_master.inc
59--let $inserts= 3
60--let $counter= 0
61# This transaction should be spanned on every query log event:
62# - 1 x BEGIN;
63# - 3 x INSERT;
64BEGIN;
65while ($counter < $inserts)
66{
67  --inc $counter
68  --eval INSERT INTO t1 VALUES ($counter)
69}
70COMMIT;
71--eval INSERT INTO t1 VALUES ($counter + 1)
72
73# We now span the transaction along distinct relay log files
74--source include/rpl_connection_slave.inc
75--let $restarts= $inserts
76# The amount of restarts is the amount of INSERT + 1 (BEGIN)
77--inc $restarts
78while ($restarts > 0)
79{
80  # Waiting for slave IO thread to stop
81  --source include/wait_for_slave_io_to_stop.inc
82  --dec $restarts
83  # At this point, the Retrieved_Gtid_Set should have only one GTID
84  --let $retrieved_gtids= query_get_value(SHOW SLAVE STATUS, Retrieved_Gtid_Set, 1)
85  --let $assert_text= Exactly one GTID should have been retrieved before having all the transaction
86  --let $assert_cond= GTID_COUNT("$retrieved_gtids") = 1
87  --source include/assert.inc
88  #
89  if ($restarts == 0)
90  {
91    --source include/remove_debug_point.inc
92  }
93  # We should not use "start_slave_io.inc" here because the IO thread
94  # will stop just a few events after starting.
95  START SLAVE IO_THREAD;
96}
97
98--source include/rpl_connection_master.inc
99--source include/sync_slave_io_with_master.inc
100
101# At this point, the Retrieved_Gtid_Set should have three GTIDs
102# One for the CREATE TABLE, one for the transaction with the split
103# INSERT and one for the last INSERT
104--let $retrieved_gtids= query_get_value(SHOW SLAVE STATUS, Retrieved_Gtid_Set, 1)
105--let $assert_text= Exactly three GTIDs should have been retrieved from master before restarting
106--let $assert_cond= GTID_COUNT("$retrieved_gtids") = 3
107--source include/assert.inc
108
109# Restart the slave to verify the spanned transaction
110--let $rpl_server_number= 2
111--let $rpl_force_stop= 0
112--source include/rpl_stop_server.inc
113--source include/rpl_start_server.inc
114
115# As we restarted the whole slave server with the spanned transaction fully
116# replicated but without any additional relay log rotation, there is no
117# PREVIOUS_GTID_LOG_EVENT on the relay log stating that the GTID of the
118# spanned transaction was retrieved. The slave will have to scan this info
119# during the relay log recovery.
120
121--source include/start_slave.inc
122--source include/rpl_connection_master.inc
123--source include/sync_slave_io_with_master.inc
124# At this point, the Retrieved_Gtid_Set should have three GTIDs
125--let $retrieved_gtids= query_get_value(SHOW SLAVE STATUS, Retrieved_Gtid_Set, 1)
126--let $assert_text= Exactly two GTIDs should have been retrieved from master after restarting
127--let $assert_cond= GTID_COUNT("$retrieved_gtids") = 3
128--source include/assert.inc
129
130# Cleanup
131--source include/rpl_connection_master.inc
132DROP TABLE t1;
133
134--source include/rpl_end.inc
135