# # This test ensures that, when a GTID event is constructed by reading its # content from a binlog file, the reader (e.g. replica, in this test) cannot # read beyond the length of the GTID event. That is, we ensure that the # structure indicated by its flags and extra_flags are consistent with the # actual content of the event. # # To spoof a broken GTID log event, we use the DEBUG_DBUG mechanism to inject # the master to write invalid GTID events for each flag. The transaction is # given a commit id to ensure the event is not shorter than GTID_HEADER_LEN, # which would result in zero padding up to GTID_HEADER_LEN. # # # References: # MDEV-33672: Gtid_log_event Construction from File Should Ensure Event # Length When Using Extra Flags # --source include/have_debug.inc # GTID event extra_flags are format independent --source include/have_binlog_format_row.inc --source include/have_innodb.inc --source include/master-slave.inc --echo # --echo # Initialize test data --connection master create table t1 (a int) engine=innodb; --source include/save_master_gtid.inc set @@SESSION.debug_dbug= "+d,binlog_force_commit_id"; --connection slave set SQL_LOG_BIN= 0; call mtr.add_suppression('Found invalid event in binary log'); call mtr.add_suppression('Slave SQL.*Relay log read failure: Could not parse relay log event entry.* 1594'); set SQL_LOG_BIN= 1; --source include/sync_with_master_gtid.inc --source include/stop_slave.inc --source include/start_slave.inc --let $cid_ctr= 100 --echo # --echo # Test FL_PREPARED_XA --connection master set @@SESSION.debug_dbug= "+d,negate_xid_from_gtid"; --eval set @commit_id= $cid_ctr XA START 'x1'; insert into t1 values (1); XA END 'x1'; XA PREPARE 'x1'; set @@SESSION.debug_dbug= "-d,negate_xid_from_gtid"; XA COMMIT 'x1'; --source include/save_master_gtid.inc --echo # Waiting for slave to find invalid event.. --connection slave let $slave_sql_errno= 1594; # ER_SLAVE_RELAY_LOG_READ_FAILURE source include/wait_for_slave_sql_error.inc; STOP SLAVE IO_THREAD; --echo # Reset master binlogs (as there is an invalid event) and slave state --connection master RESET MASTER; --connection slave RESET MASTER; RESET SLAVE; set @@global.gtid_slave_pos=""; --source include/start_slave.inc --echo # --echo # Test FL_COMPLETED_XA --connection master --inc $cid_ctr --eval set @commit_id= $cid_ctr XA START 'x1'; --let $next_val = `SELECT max(a)+1 FROM t1` --eval insert into t1 values ($next_val) XA END 'x1'; XA PREPARE 'x1'; set @@SESSION.debug_dbug= "+d,negate_xid_from_gtid"; XA COMMIT 'x1'; set @@SESSION.debug_dbug= "-d,negate_xid_from_gtid"; --source include/save_master_gtid.inc --echo # Waiting for slave to find invalid event.. --connection slave let $slave_sql_errno= 1594; # ER_SLAVE_RELAY_LOG_READ_FAILURE source include/wait_for_slave_sql_error.inc; STOP SLAVE IO_THREAD; --echo # Cleanup hanging XA PREPARE on slave set statement SQL_LOG_BIN=0 for XA COMMIT 'x1'; --echo # Reset master binlogs (as there is an invalid event) and slave state --connection master RESET MASTER; --connection slave RESET MASTER; RESET SLAVE; set @@global.gtid_slave_pos=""; --source include/start_slave.inc --echo # --echo # Test Missing xid.data (but has format id and length description parts) --connection master --eval set @commit_id= $cid_ctr XA START 'x1'; insert into t1 values (1); XA END 'x1'; XA PREPARE 'x1'; set @@SESSION.debug_dbug= "+d,negate_xid_data_from_gtid"; XA COMMIT 'x1'; set @@SESSION.debug_dbug= "-d,negate_xid_data_from_gtid"; --source include/save_master_gtid.inc --echo # Waiting for slave to find invalid event.. --connection slave let $slave_sql_errno= 1594; # ER_SLAVE_RELAY_LOG_READ_FAILURE source include/wait_for_slave_sql_error.inc; STOP SLAVE IO_THREAD; --echo # Cleanup hanging XA PREPARE on slave set statement SQL_LOG_BIN=0 for XA COMMIT 'x1'; --echo # Reset master binlogs (as there is an invalid event) and slave state --connection master RESET MASTER; --connection slave RESET MASTER; RESET SLAVE; set @@global.gtid_slave_pos=""; --source include/start_slave.inc --echo # --echo # Test FL_EXTRA_MULTI_ENGINE --connection master set @old_dbug= @@SESSION.debug_dbug; set @@SESSION.debug_dbug= "+d,inject_fl_extra_multi_engine_into_gtid"; --inc $cid_ctr --eval set @commit_id= $cid_ctr --let $next_val = `SELECT max(a)+1 FROM t1` --eval insert into t1 values ($next_val) --source include/save_master_gtid.inc set @@SESSION.debug_dbug=@old_dbug; --connection slave --echo # Waiting for slave to find invalid event.. let $slave_sql_errno= 1594; # ER_SLAVE_RELAY_LOG_READ_FAILURE source include/wait_for_slave_sql_error.inc; STOP SLAVE IO_THREAD; --echo # Reset master binlogs (as there is an invalid event) and slave state --connection master RESET MASTER; --connection slave RESET SLAVE; RESET MASTER; set @@global.gtid_slave_pos=""; --source include/start_slave.inc --echo # --echo # Test FL_COMMIT_ALTER --connection master set @old_dbug= @@SESSION.debug_dbug; set @@SESSION.debug_dbug= "+d,negate_alter_fl_from_gtid"; set @old_alter_tp= @@SESSION.binlog_alter_two_phase; set @@SESSION.binlog_alter_two_phase= 1; alter table t1 add column (nc int); --source include/save_master_gtid.inc set @@SESSION.debug_dbug=@old_dbug; set @@SESSION.binlog_alter_two_phase=@old_alter_tp; --connection slave --echo # Waiting for slave to find invalid event.. let $slave_sql_errno= 1594; # ER_SLAVE_RELAY_LOG_READ_FAILURE source include/wait_for_slave_sql_error.inc; STOP SLAVE IO_THREAD; --echo # Reset master binlogs (as there is an invalid event) and slave state --connection master RESET MASTER; --connection slave # Just to keep tables consistent between master/slave SET STATEMENT sql_log_bin=0 FOR alter table t1 add column (nc int); RESET SLAVE; RESET MASTER; set @@global.gtid_slave_pos=""; --source include/start_slave.inc --echo # --echo # Cleanup --connection master drop table t1; --source include/save_master_gtid.inc --connection slave --source include/sync_with_master_gtid.inc --source include/rpl_end.inc --echo # End of rpl_gtid_header_valid.test