# ==== Purpose ==== # # This include will generate one transaction on the master mixing RBR and SBR. # # The include will then instruct the master to set the flag stating that the # transaction is pure RBR using debug instrumentation. # # Since BUG#25040331 fix there is an optimization on the slave applier that # will set the transaction isolation level to READ COMMITTED for pure row based # transactions when the applier's transaction isolation level is more # restrictive than that. # # This optimization is assuming that no QUERY (other than terminal transaction # ones, like "COMMIT", "ROLLBACK", "XA END") can happen in the middle of a pure # row based replicated transaction (the flag is set on the GTID event). # # The slave applier will error when using the optimization and finding a # non-terminal QUERY in the middle of a assumed pure row based replicated # transaction. # # ==== Related Bugs and Worklogs ==== # # BUG#25040331: INTERLEAVED XA TRANSACTIONS MAY DEADLOCK SLAVE APPLIER WITH # REPEATABLE READ # # ==== Usage ==== # # --let $use_xa= 0|1 # --source extra/rpl_tests/rpl_gtid_mixed_rows_and_stmts_tx_isolation_error.inc # # Parameters: # # $use_xa # 0: transactions will begin with "BEGIN" # and will finish with "COMMIT" # 1: transactions will begin with "XA START" # and will finish with "XA END; XA COMMIT" # # The following START slave is taking place just to put a Warning message # in the slave's error log. This message will be used by the "assert_grep.inc" # to know where to start counting for lines with the expected pattern. --source include/rpl_connection_slave.inc --source include/stop_slave.inc --source include/start_slave.inc # Let's generate the workload on the master --source include/rpl_connection_master.inc CREATE TABLE t1 (c1 INT); --source include/sync_slave_sql_with_master.inc # Make next replicated transactions be assumed as pure RBR --let $debug_point=force_trx_as_rbr_only --source include/add_debug_point.inc --source include/rpl_connection_master.inc if (!$use_xa) { BEGIN; } if ($use_xa) { XA START 'a'; } INSERT INTO t1 (c1) VALUES (FLOOR((RAND() * 10))); INSERT INTO t1 (c1) VALUES (11); INSERT INTO t1 (c1) VALUES (FLOOR((RAND() * 10))); if (!$use_xa) { COMMIT; } if ($use_xa) { XA END 'a'; XA PREPARE 'a'; XA COMMIT 'a'; } --source include/sync_slave_io_with_master.inc # Wait until the slave reports the error --let $slave_sql_errno= convert_error(ER_SLAVE_FATAL_ERROR) --source include/wait_for_slave_sql_error.inc --source include/remove_debug_point.inc # Assert that the error message was logged on slave --let $assert_file=$MYSQLTEST_VARDIR/tmp/slave.err # Show entries only after the last occurrence of the following pattern # produced by the STOP/START slave in the beginning of this include file --let $assert_only_after=.* \[Warning\] Storing MySQL user name or password information # Each test will log only one error line # (one per QUERY mixed with rows events) --let $assert_count= 1 # Assert that the expected warning line is in the log --let $assert_select=.* \[ERROR\] .* an unexpected statement was found in the middle of the transaction --let $assert_text= Found the expected warning line in the error log. --source include/assert_grep.inc # Cleanup --source include/start_slave.inc --source include/rpl_connection_master.inc DROP TABLE t1; --source include/sync_slave_sql_with_master.inc