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