1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233
|
# ==== Purpose ====
#
# Background: For 5.7 binary logs (after WL#7592), the slave applier
# thread sets GTID_NEXT according to the Gtid_log_event or
# Anonymous_log_event preceding every transaction. For 5.6 binary
# logs using GTID_MODE=ON, it does the same. But for 5.6 binary log
# using GTID_MODE=OFF, or for 5.5 or earlier binary logs, there are no
# Gtid_log_events or Anonymous_gtid_log_event. In order to set
# gtid_next correctly also for this case, we use a special mechanism:
# when any Format_description_log_event is applied, it sets
# thd->variables.gtid_next.type=NOT_YET_DETERMINED_GTID. The next
# statement to execute then sets the real value for gtid_next: if the
# next statement is SET GTID_NEXT, then gtid_next is set
# accordingly. If the next statement is anything else, it assumes that
# this is an old binary log and changes NOT_YET_DETERMINED_GTID to
# ANONYMOUS_GTID (which causes an error to be generated if
# GTID_MODE=ON).
#
# The code that changes NOT_YET_DETERMINED_GTID to ANONYMOUS_GTID
# invoked for SQL statements (from mysql_parse). This normally covers
# also the RBR case, because RBR transactions begin with a
# query_log_event(BEGIN), so it will set gtid_next=ANONYMOUS for the
# BEGIN statement.
#
# However, if the applier thread begins execution in the middle of a
# transaction, it is possible that a row event is processed when
# gtid_next.type is NOT_YET_DETERMINED_GTID. This can happen if
# an explicit CHANGE MASTER TO RELAY_LOG_POS statement positions the
# applier thread after the BEGIN statement, or if an explicit CHANGE
# MASTER TO MASTER_LOG_POS statement positions the receiver thread in
# the middle of a transaction.
#
# Therefore, even Rows_log_events need to upgrade
# NOT_YET_DETERMINED_GTID to ANONYMOUS. This test verifies that this
# logic works correctly.
#
# ==== Implementation ====
#
# 1. Verify basic properties of GTID_NEXT = NOT_YET_DETERMINED:
# 1.1. Format_description_event sets GTID_NEXT = NOT_YET_DETERMINED.
# 1.2. DO, SELECT, SHOW, and SET don't change NOT_YET_DETERMINED
# to ANONYMOUS.
# 1.3. Other SQL statements change NOT_YET_DETERMINED to ANONYMOUS
# when GTID_MODE = OFF.
# 1.4. Row injection using BINLOG statement changes
# NOT_YET_DETERMINED to ANONYMOUS when GTID_MODE = OFF.
# 1.5. Other SQL statements generate an error if GTID_NEXT =
# NOT_YET_DETERMINED and GTID_MODE = ON.
# 1.6. Row injection using BINLOG statement generates an error if
# GTID_NEXT = NOT_YET_DETERMINED and GTID_MODE = ON.
# 1.7. It is allowed to set any other value for GTID_NEXT after
# it has been set to NOT_YET_DETERMINED.
# 2. Position the slave receiver thread after a BEGIN event in the
# master's binary log and verify that replication works (no crash).
# 3. Position the slave applier thread after a BEGIN event in the
# slave's relay log and verify that replication works (no crash).
#
# ==== Related bugs and worklogs ====
#
# WL#3584: Global Transaction Identifiers (GTIDs)
# - The logic of NOT_YET_DETERMINED_GROUP was introduced in this worklog.
# WL#7592: GTIDs: generate Gtid_log_event and Previous_gtids_log_event always
# - The code was refactored in this worklog (and the bug introduced).
# BUG#20883676: ASSERT `THD->OWNED_GTID.SIDNO == THD::OWNED_SIDNO_ANONYMOUS'
# AT BINLOG.CC:1144
# - The logic was corrected again in this bug.
# Not meaningful to test with GTID_MODE=ON.
# Test mixed mode to verify that SQL statements convert NOT_YET_DETERMINED
# to ANONYMOUS. Test row mode to verify that row events convert
# NOT_YET_DETERMINED to ANONYMOUS. No need to test other formats.
#
# BUG#18089914: REFACTORING: RENAME GROUP TO GTID
# - changed NOT_YET_DETERMINED_GROUP to NOT_YET_DETERMINED_GTID
# this test case expects certain events in a given order. This
# is not allowed when compression is on, because the transaction
# shows up compressed in a single event.
--source include/not_binlog_transaction_compression_on.inc
--source include/have_binlog_format_mixed_or_row.inc
# MTS does not allow row events outside transactions.
--source include/not_mts_replica_parallel_workers.inc
--source include/set_privilege_checks_user_as_system_user.inc
--source include/master-slave.inc
--echo #### Initialize ####
CREATE TABLE t1 (a INT);
--source include/sync_slave_sql_with_master.inc
CALL mtr.add_suppression('QUERY.*COMMIT or ROLLBACK.* or XID_LOG_EVENT is not expected in an event stream outside a transaction');
CALL mtr.add_suppression('An unexpected event sequence was detected by the IO thread while queuing the event received from source');
--echo #### 1. Check basic properties of GTID_NEXT = NOT_YET_DETERMINED ####
# This is a 5.7 Format_description_log_event.
let $fd_event=
'C9BAVQ8BAAAAdwAAAHsAAAABAAQANS43LjgtcmMtZGVidWctbG9nAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAL0EBVEzgNAAgAEgAEBAQEEgAAXwAEGggAAAAICAgCAAAACgoKKioAEjUA
AdVXOVA=';
--echo ---- 1.1. Format_description_log_event sets NOT_YET_DETERMINED ----
eval BINLOG $fd_event;
SELECT @@SESSION.GTID_NEXT;
--echo ---- 1.2. DO, SELECT, SHOW, and SET don't change GTID_NEXT ----
DO 1;
SELECT 1;
SHOW VARIABLES LIKE 'whatever';
SET @foo = 1;
SELECT @@SESSION.GTID_NEXT;
--echo ---- 1.3. Other stm changes NOT_YET_DETERMINED to ANONYMOUS if GTID_MODE=OFF ----
BEGIN;
SELECT @@SESSION.GTID_NEXT;
ROLLBACK;
SET @@SESSION.GTID_NEXT = 'AUTOMATIC';
--echo ---- 1.4. Row injection changes NOT_YET_DETERMINED to ANONYMOUS if GTID_MODE=OFF ----
eval BINLOG $fd_event;
SELECT @@SESSION.GTID_NEXT;
BINLOG '
qyhTVRMBAAAALQAAAPIBAAAAAGwAAAAAAAEABHRlc3QAAnQxAAEDAAGFeQAI
qyhTVR4BAAAAKAAAABoCAAAAAGwAAAAAAAEAAgAB//4BAAAAcd2jbw==
'/*!*/;
SELECT @@SESSION.GTID_NEXT;
ROLLBACK;
SET @@SESSION.GTID_NEXT = 'AUTOMATIC';
--echo ---- 1.5. Other stm generates error for NOT_YET_DETERMINED if GTID_MODE=ON ----
--let $rpl_set_enforce_gtid_consistency= 1
--let $rpl_gtid_mode= ON
--source include/rpl_set_gtid_mode.inc
eval BINLOG $fd_event;
SELECT @@SESSION.GTID_NEXT;
--error ER_CANT_SET_GTID_NEXT_TO_ANONYMOUS_WHEN_GTID_MODE_IS_ON
BEGIN;
SET @@SESSION.GTID_NEXT = 'AUTOMATIC';
--echo ---- 1.6. Row injection generates error for NOT_YET_DETERMINED if GTID_MODE=ON ----
eval BINLOG $fd_event;
SELECT @@SESSION.GTID_NEXT;
--error ER_CANT_SET_GTID_NEXT_TO_ANONYMOUS_WHEN_GTID_MODE_IS_ON
BINLOG '
qyhTVRMBAAAALQAAAPIBAAAAAGwAAAAAAAEABHRlc3QAAnQxAAEDAAGFeQAI
qyhTVR4BAAAAKAAAABoCAAAAAGwAAAAAAAEAAgAB//4BAAAAcd2jbw==
'/*!*/;
SET @@SESSION.GTID_NEXT = 'AUTOMATIC';
--let $rpl_set_enforce_gtid_consistency= 0
--let $rpl_gtid_mode= OFF
--source include/rpl_set_gtid_mode.inc
--echo ---- 1.7.1 Can set AUTOMATIC after NOT_YET_DETERMINED ----
eval BINLOG $fd_event;
SELECT @@SESSION.GTID_NEXT;
SET @@SESSION.GTID_NEXT = 'AUTOMATIC';
SELECT @@SESSION.GTID_NEXT;
--echo ---- 1.7.2 Can set DEFAULT after NOT_YET_DETERMINED ----
eval BINLOG $fd_event;
SELECT @@SESSION.GTID_NEXT;
SET @@SESSION.GTID_NEXT = DEFAULT;
SELECT @@SESSION.GTID_NEXT;
--echo ---- 1.7.3 Can set ANONYMOUS after NOT_YET_DETERMINED ----
eval BINLOG $fd_event;
SELECT @@SESSION.GTID_NEXT;
SET @@SESSION.GTID_NEXT = 'ANONYMOUS';
SELECT @@SESSION.GTID_NEXT;
ROLLBACK;
SET @@SESSION.GTID_NEXT = 'AUTOMATIC';
--echo ---- 1.7.4 Can set GTID after NOT_YET_DETERMINED ----
SET GLOBAL GTID_MODE = OFF_PERMISSIVE;
eval BINLOG $fd_event;
SELECT @@SESSION.GTID_NEXT;
SET GTID_NEXT = 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa:1';
SELECT @@SESSION.GTID_NEXT;
ROLLBACK;
SET @@SESSION.GTID_NEXT = 'AUTOMATIC';
SET GLOBAL GTID_MODE = OFF;
--echo #### 2. CHANGE MASTER TO MASTER_LOG_POS ####
--connection slave
--source include/stop_slave_io.inc
--connection master
--let $file= query_get_value(SHOW MASTER STATUS, File, 1)
--let $position= query_get_value(SHOW MASTER STATUS, Position, 1)
INSERT INTO t1 VALUES (1);
# Force slave to skip the Anonymous_gtid_log_event and
# Query_log_event(BEGIN) so that the first event it sees is a
# Table_map_log_event.
--let $position= query_get_value(SHOW BINLOG EVENTS IN '$file' FROM $position, End_log_pos, 2)
--connection slave
--replace_result $file FILE $position POSITION
eval CHANGE REPLICATION SOURCE TO SOURCE_LOG_FILE = '$file', SOURCE_LOG_POS = $position;
--source include/start_slave_io.inc
--connection master
--source include/sync_slave_sql_with_master.inc
--echo #### 3. CHANGE MASTER TO RELAY_LOG_POS ####
--let $file= query_get_value(SHOW SLAVE STATUS, Relay_Log_File, 1)
--let $position= query_get_value(SHOW SLAVE STATUS, Relay_Log_Pos, 1)
--source include/stop_slave_sql.inc
--connection master
INSERT INTO t1 VALUES (2);
--source include/sync_slave_io_with_master.inc
--let $position = query_get_value(SHOW RELAYLOG EVENTS IN '$file' FROM $position, Pos, 3)
--replace_result $file FILE $position POSITION
eval CHANGE REPLICATION SOURCE TO RELAY_LOG_FILE = '$file', RELAY_LOG_POS = $position;
--source include/start_slave.inc
--connection master
--source include/sync_slave_sql_with_master.inc
--echo #### Clean up ####
--connection master
DROP TABLE t1;
--source include/rpl_end.inc
|