Description:
Replication breaks when running the wrong XA ROLLBACK statement after preparing it.
The impact here is that you can basically break any replication as any user with just a few SQL statements
How to repeat:
mysql> create table t1 (t1_pk int primary key, t1_blob blob null);
Query OK, 0 rows affected (0.00 sec)
mysql> xa start '2';
Query OK, 0 rows affected (0.00 sec)
mysql> INSERT INTO t1 VALUES (85000, null);
Query OK, 1 row affected (0.00 sec)
mysql> xa end '2';
Query OK, 0 rows affected (0.00 sec)
mysql> xa prepare '2';
Query OK, 0 rows affected (0.00 sec)
mysql> xa rollback '1';
ERROR 1399 (XAE07): XAER_RMFAIL: The command cannot be executed when global transaction is in the PREPARED state
mysql> xa rollback '2';
Query OK, 0 rows affected (0.00 sec)
On the replica, you will get:
Last_SQL_Error: Error 'XAER_NOTA: Unknown XID' on query. Default database: 'xa'. Query: 'XA ROLLBACK X'32',X'',1'
The binary log contains:
#171104 2:24:32 server id 1 end_log_pos 162231 CRC32 0x118ac1c0 Anonymous_GTID last_committed=237 sequence_number=238 rbr_only=yes
/*!50718 SET TRANSACTION ISOLATION LEVEL READ COMMITTED*//*!*/;
SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
# at 162231
#171104 2:24:29 server id 1 end_log_pos 162318 CRC32 0x3c0650c0 Query thread_id=33 exec_time=0 error_code=0
SET TIMESTAMP=1509762269/*!*/;
XA START X'32',X'',1
/*!*/;
# at 162318
#171104 2:24:29 server id 1 end_log_pos 162365 CRC32 0x73363da2 Table_map: `xa`.`t1` mapped to number 268
# at 162365
#171104 2:24:29 server id 1 end_log_pos 162410 CRC32 0x70f076b2 Write_rows: table id 268 flags: STMT_END_F
BINLOG '
3ST9WRMBAAAALwAAAD16AgAAAAwBAAAAAAMAAnhhAAJ0MQAC9vwDFAACAqI9NnM=
3ST9WR4BAAAALQAAAGp6AgAAAAwBAAAAAAEAAgAC//6AAAAAAAABTAiydvBw
'/*!*/;
### INSERT INTO `xa`.`t1`
### SET
### @1=85000 /* DECIMAL(20,0) meta=5120 nullable=0 is_null=0 */
### @2=NULL /* BLOB/TEXT meta=2 nullable=1 is_null=1 */
# at 162410
#171104 2:24:32 server id 1 end_log_pos 162493 CRC32 0x54ba2b15 Query thread_id=33 exec_time=0 error_code=0
SET TIMESTAMP=1509762272/*!*/;
XA END X'32',X'',1
/*!*/;
# at 162493
#171104 2:24:32 server id 1 end_log_pos 162530 CRC32 0xfae9a150 XA PREPARE X'32',X'',1
XA PREPARE X'32',X'',1
/*!*/;
# at 162530
#171104 2:24:35 server id 1 end_log_pos 162595 CRC32 0x434b4469 Anonymous_GTID last_committed=238 sequence_number=239 rbr_only=no
SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
# at 162595
#171104 2:24:35 server id 1 end_log_pos 162683 CRC32 0xb21c1257 Query thread_id=33 exec_time=0 error_code=0
SET TIMESTAMP=1509762275/*!*/;
XA ROLLBACK X'32',X'',1
/*!*/;
# at 162683
#171104 2:24:38 server id 1 end_log_pos 162748 CRC32 0x2b22a898 Anonymous_GTID last_committed=239 sequence_number=240 rbr_only=no
SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
# at 162748
#171104 2:24:38 server id 1 end_log_pos 162836 CRC32 0xc9c58814 Query thread_id=33 exec_time=0 error_code=0
SET TIMESTAMP=1509762278/*!*/;
XA ROLLBACK X'32',X'',1
/*!*/;
# at 162836
#171104 2:25:52 server id 1 end_log_pos 162901 CRC32 0xa2774536 Anonymous_GTID last_committed=240 sequence_number=241 rbr_only=no
SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
# at 162901
#171104 2:25:52 server id 1 end_log_pos 163028 CRC32 0xef2c172d Query thread_id=33 exec_time=0 error_code=0
SET TIMESTAMP=1509762352/*!*/;
create table t3(t1_pk int primary key, t1_blob blob null)
/*!*/;
SET @@SESSION.GTID_NEXT= 'AUTOMATIC' /* added by mysqlbinlog */ /*!*/;
DELIMITER ;
# End of log file
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
You can see XA ROLLBACK is there twice.
If you do many xa rollbacks they will be all in the binary log:
#171104 2:27:39 server id 1 end_log_pos 163093 CRC32 0xc90c3a73 Anonymous_GTID last_committed=241 sequence_number=242 rbr_only=yes
/*!50718 SET TRANSACTION ISOLATION LEVEL READ COMMITTED*//*!*/;
SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
# at 163093
#171104 2:27:38 server id 1 end_log_pos 163180 CRC32 0x9480da6f Query thread_id=33 exec_time=0 error_code=0
SET TIMESTAMP=1509762458/*!*/;
XA START X'32',X'',1
/*!*/;
# at 163180
#171104 2:27:38 server id 1 end_log_pos 163227 CRC32 0xb28c4aec Table_map: `xa`.`t1` mapped to number 268
# at 163227
#171104 2:27:38 server id 1 end_log_pos 163272 CRC32 0xa70b6aec Write_rows: table id 268 flags: STMT_END_F
BINLOG '
miX9WRMBAAAALwAAAJt9AgAAAAwBAAAAAAMAAnhhAAJ0MQAC9vwDFAACAuxKjLI=
miX9WR4BAAAALQAAAMh9AgAAAAwBAAAAAAEAAgAC//6AAAAAAAABTAjsagun
'/*!*/;
### INSERT INTO `xa`.`t1`
### SET
### @1=85000 /* DECIMAL(20,0) meta=5120 nullable=0 is_null=0 */
### @2=NULL /* BLOB/TEXT meta=2 nullable=1 is_null=1 */
# at 163272
#171104 2:27:39 server id 1 end_log_pos 163355 CRC32 0x691f39ec Query thread_id=33 exec_time=0 error_code=0
SET TIMESTAMP=1509762459/*!*/;
XA END X'32',X'',1
/*!*/;
# at 163355
#171104 2:27:39 server id 1 end_log_pos 163392 CRC32 0x0e88ffa2 XA PREPARE X'32',X'',1
XA PREPARE X'32',X'',1
/*!*/;
# at 163392
#171104 2:27:42 server id 1 end_log_pos 163457 CRC32 0x256a1c7c Anonymous_GTID last_committed=242 sequence_number=243 rbr_only=no
SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
# at 163457
#171104 2:27:42 server id 1 end_log_pos 163545 CRC32 0x3868e3f0 Query thread_id=33 exec_time=0 error_code=0
SET TIMESTAMP=1509762462/*!*/;
XA ROLLBACK X'32',X'',1
/*!*/;
# at 163545
#171104 2:27:43 server id 1 end_log_pos 163610 CRC32 0x51a750bb Anonymous_GTID last_committed=243 sequence_number=244 rbr_only=no
SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
# at 163610
#171104 2:27:43 server id 1 end_log_pos 163698 CRC32 0x6ed8cf68 Query thread_id=33 exec_time=0 error_code=0
SET TIMESTAMP=1509762463/*!*/;
XA ROLLBACK X'32',X'',1
/*!*/;
# at 163698
#171104 2:27:45 server id 1 end_log_pos 163763 CRC32 0xee5034df Anonymous_GTID last_committed=244 sequence_number=245 rbr_only=no
SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
# at 163763
#171104 2:27:45 server id 1 end_log_pos 163851 CRC32 0x9af01202 Query thread_id=33 exec_time=0 error_code=0
SET TIMESTAMP=1509762465/*!*/;
XA ROLLBACK X'32',X'',1
/*!*/;
# at 163851
#171104 2:27:46 server id 1 end_log_pos 163916 CRC32 0xc018a516 Anonymous_GTID last_committed=245 sequence_number=246 rbr_only=no
SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
# at 163916
#171104 2:27:46 server id 1 end_log_pos 164004 CRC32 0xff24304d Query thread_id=33 exec_time=0 error_code=0
SET TIMESTAMP=1509762466/*!*/;
XA ROLLBACK X'32',X'',1
/*!*/;
# at 164004
#171104 2:27:48 server id 1 end_log_pos 164069 CRC32 0xfb16b1d2 Anonymous_GTID last_committed=246 sequence_number=247 rbr_only=no
SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
# at 164069
#171104 2:27:48 server id 1 end_log_pos 164157 CRC32 0x1384b537 Query thread_id=33 exec_time=0 error_code=0
SET TIMESTAMP=1509762468/*!*/;
XA ROLLBACK X'32',X'',1
/*!*/;
SET @@SESSION.GTID_NEXT= 'AUTOMATIC' /* added by mysqlbinlog */ /*!*/;
DELIMITER ;
# End of log file
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
Suggested fix:
Do not put multiple XA ROLLBACK statements in the binlog