You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
BUG#17650326 MYSQLBINLOG PRINTS INVALID SQL FROM RELAY LOGS WHEN GTID IS ENABLED
Problem (1) : Replaying a relaylog which ends with GTID_LOG_EVENT causes
error "ERROR 1790 (HY000) @@SESSION.GTID_NEXT cannot be changed by a client
that owns a GTID. The client owns <UUID:GTID> Ownership is released on
COMMIT or ROLLBACK."
Analysis: mysqlbinlog tool appends SET @@SESSION.GTID_NEXT='AUTOMATIC'
to output when it finds a rotate log event and if it is not inside
a transaction which is the right thing to do. The tool has in_transaction
flag which will be set true upon processing any transaction event.
But a GTID_LOG_EVENT is not treated as a transaction event,
hence in_transaction is false even after processing GTID_LOG_EVENT.
If a relaylog rotate happens (either through IO thread restart/ROTATE
command), exactly after writing GTID_LOG_EVENT and if we are replaying such a
relaylog's end ROTATE_EVENT, logic was mistakenly thinking that it was not
inside a transaction but actually the transaction was started after
GTID_LOG_EVENT. Hence tool generates SET @@SESSION.GTID_NEXT='AUTOMATIC'.
This issue resulted in having two GTID_NEXT statements next to each other and
replaying such output against 'mysql' client tool was causing above specified
error (ERROR:1790).
Fix: One way to fix this issue is to set in_transaction flag to true when it
encounters GTID_LOG_EVENT. But this change will disturb DDL transaction
detection logic (mysqlbinlog tool logic assumes that DDL transactions will
have only one event per transaction). So instead of disturbing that logic,
we have followed another approach to solve the issue. 'mysqlbinlog' tool
generates "SET @@SESSION.GTID_NEXT='AUTOMATIC'" only when in_transaction
is false and is_gtid_next_valid is false (which represents that we are
not in transaction and did not even see GTID_LOG_EVENT.
Problem (2): 'ROLLBACK' is not getting generated by mysqlbinlog tool
when concatenating and replaying two consecutive relaylogs
(the first relaylog contains partial transaction and second relaylog
contains full transaction again).
Analysis: If IO thread is restarted when it is in the middle of
transferring a tranasction from Master then it will retrieve the
full transaction again upon restart. In that case, the first relaylog
contains partial GTID transaction and the second relaylog will
contain full GTID transaction again. If mysqlbinlog tool is used
to merge such two relaylogs it should generate a 'ROLLBACK' statement
after partial transaction. Otherwise it will cause above said error
(ERROR:1790).
Fix: If IO thread is restarted, the new generated relaylog will have
FD event received from Master and will have log_pos greater than zero
if the AUTO_POSITION is true i.e., this will indicate that if we
were in transaction in first relaylog, Master would have sent the
transaction again from the beginning. In this case, upon reading such
a FD event, generate 'ROLLBACK' statement in generated output. If
we have seen only GTID_LOG_EVENT of the transaction and not seen
'BEGIN' statement, then generate BEGIN and ROLLBACK statements
in generated output.
Note #### Sending passwords in plain text without SSL/TLS is extremely insecure.
4
+
Note #### Storing MySQL user name or password information in the master info repository is not secure and is therefore not recommended. Please consider using the USER and PASSWORD connection options for START SLAVE; see the 'START SLAVE Syntax' in the MySQL Manual for more information.
5
+
[connection master]
6
+
CREATE TABLE t1(i INT) ENGINE=InnoDB;
7
+
INSERT INTO t1 VALUES (1);
8
+
include/sync_slave_sql_with_master.inc
9
+
SET @save_debug=@@global.debug;
10
+
SET GLOBAL DEBUG='d,stop_io_after_reading_gtid_log_event';
11
+
[connection master]
12
+
INSERT INTO t1 VALUES (2);
13
+
[connection slave]
14
+
include/wait_for_slave_io_to_stop.inc
15
+
include/assert.inc [Slave MASTER_AUTO_POSITION should be enabled for this test]
16
+
SET GLOBAL DEBUG= @save_debug;
17
+
include/start_slave.inc
18
+
[connection master]
19
+
include/sync_slave_sql_with_master.inc
20
+
DROP TABLE t1;
21
+
RESET MASTER;
22
+
include/assert.inc [Check that there is one tuple in the table]
23
+
DROP TABLE t1;
24
+
RESET MASTER;
25
+
include/assert.inc [Check that there are two tuples in the table]
0 commit comments