From: Alfranio Correia Date: September 28 2009 12:55pm Subject: bzr commit into mysql-5.1-bugteam branch (alfranio.correia:3139) Bug#47287 List-Archive: http://lists.mysql.com/commits/84850 X-Bug: 47287 Message-Id: <0KQO0067HMLDDQA0@fe-emea-09.sun.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="Boundary_(ID_Hd9hcqgWKFwvmAW2jU1q0g)" --Boundary_(ID_Hd9hcqgWKFwvmAW2jU1q0g) MIME-version: 1.0 Content-type: text/plain; CHARSET=US-ASCII Content-transfer-encoding: 7BIT Content-disposition: inline #At file:///home/acorreia/workspace.sun/repository.mysql/bzrwork/bug-47287/mysql-5.1-bugteam/ based on revid:li-bing.song@stripped 3139 Alfranio Correia 2009-09-28 BUG#47287 RBR: replication diff on basic case with txn- and non-txn tables in a statement Let - T be a transactional table and N non-transactional table. - B be begin, C commit and R rollback. - M be a mixed statement, i.e. a statement that updates both T and N. - M* be a mixed statement that fails while updating either T or N. This patch restore the behavior presented in 5.1.37 for rows either produced in the RBR or MIXED modes, when a M* statement that happened early in a transaction had their changes written to the binary log outside the boundaries of the transaction and wrapped in a BEGIN/ROLLBACK. This was done to keep the slave consistent with with the master as the rollback would keep the changes on N and undo them on T. In particular, we do what follows: . B M* T C would log - B M* R B T C. Note that, we are not preserving history from the master as we are introducing a rollback that never happened. However, this seems to be more acceptable than making the slave diverge. We do not fix the following case: . B T M* C would log B T M* C. The slave will diverge as the changes on T tables that originated from the M statement are rolled back on the master but not on the slave. Unfortunately, we cannot simply rollback the transaction as this would undo any uncommitted changes on T tables. SBR is not considered in this patch because a failing statement is written to the binary along with the error code and a slave executes and then rolls back the statement when it has an associated error code, thus undoing the effects on T. In RBR and MBR, a full-fledged fix will be pushed after the WL 2687. added: mysql-test/extra/binlog_tests/binlog_failure_mixing_engines.test mysql-test/suite/binlog/r/binlog_mixed_failure_mixing_engines.result mysql-test/suite/binlog/r/binlog_row_failure_mixing_engines.result mysql-test/suite/binlog/t/binlog_mixed_failure_mixing_engines.test mysql-test/suite/binlog/t/binlog_row_failure_mixing_engines.test modified: sql/log.cc === added file 'mysql-test/extra/binlog_tests/binlog_failure_mixing_engines.test' --- a/mysql-test/extra/binlog_tests/binlog_failure_mixing_engines.test 1970-01-01 00:00:00 +0000 +++ b/mysql-test/extra/binlog_tests/binlog_failure_mixing_engines.test 2009-09-28 12:55:54 +0000 @@ -0,0 +1,190 @@ +################################################################################ +# Let +# - T be a transactional table and N non-transactional table. +# - B be begin, C commit and R rollback. +# - M be a mixed statement, i.e. a statement that updates both T and N. +# - M* be a mixed statement that fails while updating either T or N. +# +# In this test case, when changes are logged as rows either in the RBR or MIXED +# modes, we check if a M* statement that happens early in a transaction is +# written to the binary log outside the boundaries of the transaction and +# wrapped in a BEGIN/ROLLBACK. This is done to keep the slave consistent with +# with the master as the rollback will keep the changes on N and undo them on +# T. In particular, we expect the following behavior: +# +# 1. B M* T C would log - B M* R B T C. +# 2. B T M* C would log B T M* C. +# +# SBR is not considered in this test because a failing statement is written to +# the binary along with the error code and a slave executes and then rolls back +# the statement when it has an associated error code, thus undoing the effects +# on T. +# +# Note that, in the first case, we are not preserving history from the master as +# we are introducing a rollback that never happened. However, this seems to be +# more acceptable than making the slave diverge. In the second case, the slave +# will diverge as the changes on T tables that originated from the M statement +# are rolled back on the master but not on the slave. Unfortunately, we cannot +# simply rollback the transaction as this would undo any uncommitted changes +# on T tables. +# +# Such issues do not happen in SBR. In RBR and MBR, a fix will be pushed after +# the WL 2687. +# +# Please, remove this test case after pushing WL 2687. +################################################################################ + + +--echo ################################################################################### +--echo # CONFIGURATION +--echo ################################################################################### +CREATE TABLE nt_1 (a text, b int PRIMARY KEY) ENGINE = MyISAM; +CREATE TABLE nt_2 (a text, b int PRIMARY KEY) ENGINE = MyISAM; +CREATE TABLE tt_1 (a text, b int PRIMARY KEY) ENGINE = Innodb; +CREATE TABLE tt_2 (a text, b int PRIMARY KEY) ENGINE = Innodb; + +DELIMITER |; + +CREATE TRIGGER tr_i_tt_1_to_nt_1 BEFORE INSERT ON tt_1 FOR EACH ROW +BEGIN + INSERT INTO nt_1 VALUES (NEW.a, NEW.b); +END| + +CREATE TRIGGER tr_i_nt_2_to_tt_2 BEFORE INSERT ON nt_2 FOR EACH ROW +BEGIN + INSERT INTO tt_2 VALUES (NEW.a, NEW.b); +END| + +DELIMITER ;| + +--echo ################################################################################### +--echo # CHECK HISTORY IN BINLOG +--echo ################################################################################### +--echo +--echo +--echo +--echo *** "B M* T C" with error in M* generates in the binlog the "B M* R B T C" entries +--echo +let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1); +INSERT INTO nt_1 VALUES ("new text 1", 1); +BEGIN; +--error ER_DUP_ENTRY +INSERT INTO tt_1 VALUES (USER(), 2), (USER(), 1); +INSERT INTO tt_2 VALUES ("new text 3", 3); +COMMIT; +--source include/show_binlog_events.inc + +--echo +let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1); +INSERT INTO tt_2 VALUES ("new text 4", 4); +BEGIN; +--error ER_DUP_ENTRY +INSERT INTO nt_2 VALUES (USER(), 5), (USER(), 4); +INSERT INTO tt_2 VALUES ("new text 6", 6); +COMMIT; +--source include/show_binlog_events.inc + +--echo +--echo +--echo +--echo *** "B M M* T C" with error in M* generates in the binlog the "B M M* T C" entries +--echo +let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1); +INSERT INTO nt_1 VALUES ("new text 10", 10); +BEGIN; +INSERT INTO tt_1 VALUES ("new text 7", 7), ("new text 8", 8); +--error ER_DUP_ENTRY +INSERT INTO tt_1 VALUES (USER(), 9), (USER(), 10); +INSERT INTO tt_2 VALUES ("new text 11", 11); +COMMIT; +--source include/show_binlog_events.inc + +--echo +let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1); +INSERT INTO tt_2 VALUES ("new text 15", 15); +BEGIN; +INSERT INTO nt_2 VALUES ("new text 12", 12), ("new text 13", 13); +--error ER_DUP_ENTRY +INSERT INTO nt_2 VALUES (USER(), 14), (USER(), 15); +INSERT INTO tt_2 VALUES ("new text 16", 16); +COMMIT; +--source include/show_binlog_events.inc + + +--echo +--echo +--echo +--echo *** "B M* M* T C" with error in M* generates in the binlog the "B M* R B M* R B T C" entries +--echo +let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1); +INSERT INTO nt_1 VALUES ("new text 18", 18); +INSERT INTO nt_1 VALUES ("new text 20", 20); +BEGIN; +--error ER_DUP_ENTRY +INSERT INTO tt_1 VALUES (USER(), 17), (USER(), 18); +--error ER_DUP_ENTRY +INSERT INTO tt_1 VALUES (USER(), 19), (USER(), 20); +INSERT INTO tt_2 VALUES ("new text 21", 21); +COMMIT; +--source include/show_binlog_events.inc + +--echo +let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1); +INSERT INTO tt_2 VALUES ("new text 23", 23); +INSERT INTO tt_2 VALUES ("new text 25", 25); +BEGIN; +--error ER_DUP_ENTRY +INSERT INTO nt_2 VALUES (USER(), 22), (USER(), 23); +--error ER_DUP_ENTRY +INSERT INTO nt_2 VALUES (USER(), 24), (USER(), 25); +INSERT INTO tt_2 VALUES ("new text 26", 26); +COMMIT; +--source include/show_binlog_events.inc + +--echo +--echo +--echo +--echo *** "B SELECT...INSERT* C" with an error in SELECT...INSERT* generates in the binlog the following entries: +--echo *** "Nothing" in RBR and "B SELECT..INSERT* R" in MIXED mode. +--echo *** Note that there is nothing wrong with the behavior in MIXED as the statement is logged along with the +--echo *** error code. However, there is a bug in RBR that will be fixed after WL#2687. Please, check BUG#47175 +--echo *** for further details. +--echo +let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1); +TRUNCATE TABLE nt_2; +TRUNCATE TABLE tt_2; +INSERT INTO tt_2 VALUES ("new text 7", 7); +BEGIN; +INSERT INTO tt_2 VALUES ("new text 27", 27); +--error ER_DUP_ENTRY +INSERT INTO nt_2 SELECT * FROM nt_1; +INSERT INTO tt_2 VALUES ("new text 28", 28); +ROLLBACK; +--source include/show_binlog_events.inc + +--echo +--echo +--echo +--echo *** "B SELECT...INSERT* C" with an error in SELECT...INSERT* generates in the binlog the following entries: +--echo *** "B SELECT..INSERT* R" in RBR and "B SELECT..INSERT* C" in MIXED mode. +--echo *** Note that there is nothing wrong with the behavior in MIXED as the statement is logged along with the +--echo *** error code. +--echo +let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1); +TRUNCATE TABLE nt_2; +TRUNCATE TABLE tt_2; +INSERT INTO tt_2 VALUES ("new text 7", 7); +BEGIN; +--error ER_DUP_ENTRY +INSERT INTO nt_2 SELECT * FROM nt_1; +COMMIT; +--source include/show_binlog_events.inc + +--echo ################################################################################### +--echo # CLEAN +--echo ################################################################################### + +DROP TABLE tt_1; +DROP TABLE tt_2; +DROP TABLE nt_1; +DROP TABLE nt_2; === added file 'mysql-test/suite/binlog/r/binlog_mixed_failure_mixing_engines.result' --- a/mysql-test/suite/binlog/r/binlog_mixed_failure_mixing_engines.result 1970-01-01 00:00:00 +0000 +++ b/mysql-test/suite/binlog/r/binlog_mixed_failure_mixing_engines.result 2009-09-28 12:55:54 +0000 @@ -0,0 +1,240 @@ +################################################################################### +# CONFIGURATION +################################################################################### +CREATE TABLE nt_1 (a text, b int PRIMARY KEY) ENGINE = MyISAM; +CREATE TABLE nt_2 (a text, b int PRIMARY KEY) ENGINE = MyISAM; +CREATE TABLE tt_1 (a text, b int PRIMARY KEY) ENGINE = Innodb; +CREATE TABLE tt_2 (a text, b int PRIMARY KEY) ENGINE = Innodb; +CREATE TRIGGER tr_i_tt_1_to_nt_1 BEFORE INSERT ON tt_1 FOR EACH ROW +BEGIN +INSERT INTO nt_1 VALUES (NEW.a, NEW.b); +END| +CREATE TRIGGER tr_i_nt_2_to_tt_2 BEFORE INSERT ON nt_2 FOR EACH ROW +BEGIN +INSERT INTO tt_2 VALUES (NEW.a, NEW.b); +END| +################################################################################### +# CHECK HISTORY IN BINLOG +################################################################################### + + + +*** "B M* T C" with error in M* generates in the binlog the "B M* R B T C" entries + +INSERT INTO nt_1 VALUES ("new text 1", 1); +BEGIN; +INSERT INTO tt_1 VALUES (USER(), 2), (USER(), 1); +ERROR 23000: Duplicate entry '1' for key 'PRIMARY' +INSERT INTO tt_2 VALUES ("new text 3", 3); +COMMIT; +show binlog events from ; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; INSERT INTO nt_1 VALUES ("new text 1", 1) +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Table_map # # table_id: # (test.tt_1) +master-bin.000001 # Table_map # # table_id: # (test.nt_1) +master-bin.000001 # Write_rows # # table_id: # +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Query # # ROLLBACK +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_2 VALUES ("new text 3", 3) +master-bin.000001 # Xid # # COMMIT /* XID */ + +INSERT INTO tt_2 VALUES ("new text 4", 4); +BEGIN; +INSERT INTO nt_2 VALUES (USER(), 5), (USER(), 4); +ERROR 23000: Duplicate entry '4' for key 'PRIMARY' +INSERT INTO tt_2 VALUES ("new text 6", 6); +COMMIT; +show binlog events from ; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_2 VALUES ("new text 4", 4) +master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Table_map # # table_id: # (test.nt_2) +master-bin.000001 # Table_map # # table_id: # (test.tt_2) +master-bin.000001 # Write_rows # # table_id: # +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Query # # ROLLBACK +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_2 VALUES ("new text 6", 6) +master-bin.000001 # Xid # # COMMIT /* XID */ + + + +*** "B M M* T C" with error in M* generates in the binlog the "B M M* T C" entries + +INSERT INTO nt_1 VALUES ("new text 10", 10); +BEGIN; +INSERT INTO tt_1 VALUES ("new text 7", 7), ("new text 8", 8); +INSERT INTO tt_1 VALUES (USER(), 9), (USER(), 10); +ERROR 23000: Duplicate entry '10' for key 'PRIMARY' +INSERT INTO tt_2 VALUES ("new text 11", 11); +COMMIT; +show binlog events from ; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; INSERT INTO nt_1 VALUES ("new text 10", 10) +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_1 VALUES ("new text 7", 7), ("new text 8", 8) +master-bin.000001 # Table_map # # table_id: # (test.tt_1) +master-bin.000001 # Table_map # # table_id: # (test.nt_1) +master-bin.000001 # Write_rows # # table_id: # +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Query # # use `test`; INSERT INTO tt_2 VALUES ("new text 11", 11) +master-bin.000001 # Xid # # COMMIT /* XID */ + +INSERT INTO tt_2 VALUES ("new text 15", 15); +BEGIN; +INSERT INTO nt_2 VALUES ("new text 12", 12), ("new text 13", 13); +INSERT INTO nt_2 VALUES (USER(), 14), (USER(), 15); +ERROR 23000: Duplicate entry '15' for key 'PRIMARY' +INSERT INTO tt_2 VALUES ("new text 16", 16); +COMMIT; +show binlog events from ; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_2 VALUES ("new text 15", 15) +master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO nt_2 VALUES ("new text 12", 12), ("new text 13", 13) +master-bin.000001 # Table_map # # table_id: # (test.nt_2) +master-bin.000001 # Table_map # # table_id: # (test.tt_2) +master-bin.000001 # Write_rows # # table_id: # +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Query # # use `test`; INSERT INTO tt_2 VALUES ("new text 16", 16) +master-bin.000001 # Xid # # COMMIT /* XID */ + + + +*** "B M* M* T C" with error in M* generates in the binlog the "B M* R B M* R B T C" entries + +INSERT INTO nt_1 VALUES ("new text 18", 18); +INSERT INTO nt_1 VALUES ("new text 20", 20); +BEGIN; +INSERT INTO tt_1 VALUES (USER(), 17), (USER(), 18); +ERROR 23000: Duplicate entry '18' for key 'PRIMARY' +INSERT INTO tt_1 VALUES (USER(), 19), (USER(), 20); +ERROR 23000: Duplicate entry '20' for key 'PRIMARY' +INSERT INTO tt_2 VALUES ("new text 21", 21); +COMMIT; +show binlog events from ; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; INSERT INTO nt_1 VALUES ("new text 18", 18) +master-bin.000001 # Query # # use `test`; INSERT INTO nt_1 VALUES ("new text 20", 20) +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Table_map # # table_id: # (test.tt_1) +master-bin.000001 # Table_map # # table_id: # (test.nt_1) +master-bin.000001 # Write_rows # # table_id: # +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Query # # ROLLBACK +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Table_map # # table_id: # (test.tt_1) +master-bin.000001 # Table_map # # table_id: # (test.nt_1) +master-bin.000001 # Write_rows # # table_id: # +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Query # # ROLLBACK +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_2 VALUES ("new text 21", 21) +master-bin.000001 # Xid # # COMMIT /* XID */ + +INSERT INTO tt_2 VALUES ("new text 23", 23); +INSERT INTO tt_2 VALUES ("new text 25", 25); +BEGIN; +INSERT INTO nt_2 VALUES (USER(), 22), (USER(), 23); +ERROR 23000: Duplicate entry '23' for key 'PRIMARY' +INSERT INTO nt_2 VALUES (USER(), 24), (USER(), 25); +ERROR 23000: Duplicate entry '25' for key 'PRIMARY' +INSERT INTO tt_2 VALUES ("new text 26", 26); +COMMIT; +show binlog events from ; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_2 VALUES ("new text 23", 23) +master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_2 VALUES ("new text 25", 25) +master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Table_map # # table_id: # (test.nt_2) +master-bin.000001 # Table_map # # table_id: # (test.tt_2) +master-bin.000001 # Write_rows # # table_id: # +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Query # # ROLLBACK +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Table_map # # table_id: # (test.nt_2) +master-bin.000001 # Table_map # # table_id: # (test.tt_2) +master-bin.000001 # Write_rows # # table_id: # +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Query # # ROLLBACK +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_2 VALUES ("new text 26", 26) +master-bin.000001 # Xid # # COMMIT /* XID */ + + + +*** "B SELECT...INSERT* C" with an error in SELECT...INSERT* generates in the binlog the following entries: +*** "Nothing" in RBR and "B SELECT..INSERT* R" in MIXED mode. +*** Note that there is nothing wrong with the behavior in MIXED as the statement is logged along with the +*** error code. However, there is a bug in RBR that will be fixed after WL#2687. Please, check BUG#47175 +*** for further details. + +TRUNCATE TABLE nt_2; +TRUNCATE TABLE tt_2; +INSERT INTO tt_2 VALUES ("new text 7", 7); +BEGIN; +INSERT INTO tt_2 VALUES ("new text 27", 27); +INSERT INTO nt_2 SELECT * FROM nt_1; +ERROR 23000: Duplicate entry '7' for key 'PRIMARY' +INSERT INTO tt_2 VALUES ("new text 28", 28); +ROLLBACK; +Warnings: +Warning 1196 Some non-transactional changed tables couldn't be rolled back +show binlog events from ; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; TRUNCATE TABLE nt_2 +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; TRUNCATE TABLE tt_2 +master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_2 VALUES ("new text 7", 7) +master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_2 VALUES ("new text 27", 27) +master-bin.000001 # Query # # use `test`; INSERT INTO nt_2 SELECT * FROM nt_1 +master-bin.000001 # Query # # use `test`; INSERT INTO tt_2 VALUES ("new text 28", 28) +master-bin.000001 # Query # # ROLLBACK + + + +*** "B SELECT...INSERT* C" with an error in SELECT...INSERT* generates in the binlog the following entries: +*** "B SELECT..INSERT* R" in RBR and "B SELECT..INSERT* C" in MIXED mode. +*** Note that there is nothing wrong with the behavior in MIXED as the statement is logged along with the +*** error code. + +TRUNCATE TABLE nt_2; +TRUNCATE TABLE tt_2; +INSERT INTO tt_2 VALUES ("new text 7", 7); +BEGIN; +INSERT INTO nt_2 SELECT * FROM nt_1; +ERROR 23000: Duplicate entry '7' for key 'PRIMARY' +COMMIT; +show binlog events from ; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; TRUNCATE TABLE nt_2 +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; TRUNCATE TABLE tt_2 +master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_2 VALUES ("new text 7", 7) +master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO nt_2 SELECT * FROM nt_1 +master-bin.000001 # Query # # COMMIT +################################################################################### +# CLEAN +################################################################################### +DROP TABLE tt_1; +DROP TABLE tt_2; +DROP TABLE nt_1; +DROP TABLE nt_2; === added file 'mysql-test/suite/binlog/r/binlog_row_failure_mixing_engines.result' --- a/mysql-test/suite/binlog/r/binlog_row_failure_mixing_engines.result 1970-01-01 00:00:00 +0000 +++ b/mysql-test/suite/binlog/r/binlog_row_failure_mixing_engines.result 2009-09-28 12:55:54 +0000 @@ -0,0 +1,274 @@ +################################################################################### +# CONFIGURATION +################################################################################### +CREATE TABLE nt_1 (a text, b int PRIMARY KEY) ENGINE = MyISAM; +CREATE TABLE nt_2 (a text, b int PRIMARY KEY) ENGINE = MyISAM; +CREATE TABLE tt_1 (a text, b int PRIMARY KEY) ENGINE = Innodb; +CREATE TABLE tt_2 (a text, b int PRIMARY KEY) ENGINE = Innodb; +CREATE TRIGGER tr_i_tt_1_to_nt_1 BEFORE INSERT ON tt_1 FOR EACH ROW +BEGIN +INSERT INTO nt_1 VALUES (NEW.a, NEW.b); +END| +CREATE TRIGGER tr_i_nt_2_to_tt_2 BEFORE INSERT ON nt_2 FOR EACH ROW +BEGIN +INSERT INTO tt_2 VALUES (NEW.a, NEW.b); +END| +################################################################################### +# CHECK HISTORY IN BINLOG +################################################################################### + + + +*** "B M* T C" with error in M* generates in the binlog the "B M* R B T C" entries + +INSERT INTO nt_1 VALUES ("new text 1", 1); +BEGIN; +INSERT INTO tt_1 VALUES (USER(), 2), (USER(), 1); +ERROR 23000: Duplicate entry '1' for key 'PRIMARY' +INSERT INTO tt_2 VALUES ("new text 3", 3); +COMMIT; +show binlog events from ; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Table_map # # table_id: # (test.nt_1) +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Query # # COMMIT +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Table_map # # table_id: # (test.tt_1) +master-bin.000001 # Table_map # # table_id: # (test.nt_1) +master-bin.000001 # Write_rows # # table_id: # +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Query # # ROLLBACK +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Table_map # # table_id: # (test.tt_2) +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Xid # # COMMIT /* XID */ + +INSERT INTO tt_2 VALUES ("new text 4", 4); +BEGIN; +INSERT INTO nt_2 VALUES (USER(), 5), (USER(), 4); +ERROR 23000: Duplicate entry '4' for key 'PRIMARY' +INSERT INTO tt_2 VALUES ("new text 6", 6); +COMMIT; +show binlog events from ; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Table_map # # table_id: # (test.tt_2) +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Table_map # # table_id: # (test.nt_2) +master-bin.000001 # Table_map # # table_id: # (test.tt_2) +master-bin.000001 # Write_rows # # table_id: # +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Query # # ROLLBACK +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Table_map # # table_id: # (test.tt_2) +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Xid # # COMMIT /* XID */ + + + +*** "B M M* T C" with error in M* generates in the binlog the "B M M* T C" entries + +INSERT INTO nt_1 VALUES ("new text 10", 10); +BEGIN; +INSERT INTO tt_1 VALUES ("new text 7", 7), ("new text 8", 8); +INSERT INTO tt_1 VALUES (USER(), 9), (USER(), 10); +ERROR 23000: Duplicate entry '10' for key 'PRIMARY' +INSERT INTO tt_2 VALUES ("new text 11", 11); +COMMIT; +show binlog events from ; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Table_map # # table_id: # (test.nt_1) +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Query # # COMMIT +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Table_map # # table_id: # (test.tt_1) +master-bin.000001 # Table_map # # table_id: # (test.nt_1) +master-bin.000001 # Write_rows # # table_id: # +master-bin.000001 # Write_rows # # table_id: # +master-bin.000001 # Write_rows # # table_id: # +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Table_map # # table_id: # (test.tt_1) +master-bin.000001 # Table_map # # table_id: # (test.nt_1) +master-bin.000001 # Write_rows # # table_id: # +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Table_map # # table_id: # (test.tt_2) +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Xid # # COMMIT /* XID */ + +INSERT INTO tt_2 VALUES ("new text 15", 15); +BEGIN; +INSERT INTO nt_2 VALUES ("new text 12", 12), ("new text 13", 13); +INSERT INTO nt_2 VALUES (USER(), 14), (USER(), 15); +ERROR 23000: Duplicate entry '15' for key 'PRIMARY' +INSERT INTO tt_2 VALUES ("new text 16", 16); +COMMIT; +show binlog events from ; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Table_map # # table_id: # (test.tt_2) +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Table_map # # table_id: # (test.nt_2) +master-bin.000001 # Table_map # # table_id: # (test.tt_2) +master-bin.000001 # Write_rows # # table_id: # +master-bin.000001 # Write_rows # # table_id: # +master-bin.000001 # Write_rows # # table_id: # +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Table_map # # table_id: # (test.nt_2) +master-bin.000001 # Table_map # # table_id: # (test.tt_2) +master-bin.000001 # Write_rows # # table_id: # +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Table_map # # table_id: # (test.tt_2) +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Xid # # COMMIT /* XID */ + + + +*** "B M* M* T C" with error in M* generates in the binlog the "B M* R B M* R B T C" entries + +INSERT INTO nt_1 VALUES ("new text 18", 18); +INSERT INTO nt_1 VALUES ("new text 20", 20); +BEGIN; +INSERT INTO tt_1 VALUES (USER(), 17), (USER(), 18); +ERROR 23000: Duplicate entry '18' for key 'PRIMARY' +INSERT INTO tt_1 VALUES (USER(), 19), (USER(), 20); +ERROR 23000: Duplicate entry '20' for key 'PRIMARY' +INSERT INTO tt_2 VALUES ("new text 21", 21); +COMMIT; +show binlog events from ; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Table_map # # table_id: # (test.nt_1) +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Query # # COMMIT +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Table_map # # table_id: # (test.nt_1) +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Query # # COMMIT +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Table_map # # table_id: # (test.tt_1) +master-bin.000001 # Table_map # # table_id: # (test.nt_1) +master-bin.000001 # Write_rows # # table_id: # +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Query # # ROLLBACK +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Table_map # # table_id: # (test.tt_1) +master-bin.000001 # Table_map # # table_id: # (test.nt_1) +master-bin.000001 # Write_rows # # table_id: # +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Query # # ROLLBACK +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Table_map # # table_id: # (test.tt_2) +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Xid # # COMMIT /* XID */ + +INSERT INTO tt_2 VALUES ("new text 23", 23); +INSERT INTO tt_2 VALUES ("new text 25", 25); +BEGIN; +INSERT INTO nt_2 VALUES (USER(), 22), (USER(), 23); +ERROR 23000: Duplicate entry '23' for key 'PRIMARY' +INSERT INTO nt_2 VALUES (USER(), 24), (USER(), 25); +ERROR 23000: Duplicate entry '25' for key 'PRIMARY' +INSERT INTO tt_2 VALUES ("new text 26", 26); +COMMIT; +show binlog events from ; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Table_map # # table_id: # (test.tt_2) +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Table_map # # table_id: # (test.tt_2) +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Table_map # # table_id: # (test.nt_2) +master-bin.000001 # Table_map # # table_id: # (test.tt_2) +master-bin.000001 # Write_rows # # table_id: # +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Query # # ROLLBACK +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Table_map # # table_id: # (test.nt_2) +master-bin.000001 # Table_map # # table_id: # (test.tt_2) +master-bin.000001 # Write_rows # # table_id: # +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Query # # ROLLBACK +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Table_map # # table_id: # (test.tt_2) +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Xid # # COMMIT /* XID */ + + + +*** "B SELECT...INSERT* C" with an error in SELECT...INSERT* generates in the binlog the following entries: +*** "Nothing" in RBR and "B SELECT..INSERT* R" in MIXED mode. +*** Note that there is nothing wrong with the behavior in MIXED as the statement is logged along with the +*** error code. However, there is a bug in RBR that will be fixed after WL#2687. Please, check BUG#47175 +*** for further details. + +TRUNCATE TABLE nt_2; +TRUNCATE TABLE tt_2; +INSERT INTO tt_2 VALUES ("new text 7", 7); +BEGIN; +INSERT INTO tt_2 VALUES ("new text 27", 27); +INSERT INTO nt_2 SELECT * FROM nt_1; +ERROR 23000: Duplicate entry '7' for key 'PRIMARY' +INSERT INTO tt_2 VALUES ("new text 28", 28); +ROLLBACK; +show binlog events from ; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; TRUNCATE TABLE nt_2 +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; TRUNCATE TABLE tt_2 +master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Table_map # # table_id: # (test.tt_2) +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Xid # # COMMIT /* XID */ + + + +*** "B SELECT...INSERT* C" with an error in SELECT...INSERT* generates in the binlog the following entries: +*** "B SELECT..INSERT* R" in RBR and "B SELECT..INSERT* C" in MIXED mode. +*** Note that there is nothing wrong with the behavior in MIXED as the statement is logged along with the +*** error code. + +TRUNCATE TABLE nt_2; +TRUNCATE TABLE tt_2; +INSERT INTO tt_2 VALUES ("new text 7", 7); +BEGIN; +INSERT INTO nt_2 SELECT * FROM nt_1; +ERROR 23000: Duplicate entry '7' for key 'PRIMARY' +COMMIT; +show binlog events from ; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; TRUNCATE TABLE nt_2 +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; TRUNCATE TABLE tt_2 +master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Table_map # # table_id: # (test.tt_2) +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Table_map # # table_id: # (test.nt_2) +master-bin.000001 # Table_map # # table_id: # (test.tt_2) +master-bin.000001 # Write_rows # # table_id: # +master-bin.000001 # Write_rows # # table_id: # +master-bin.000001 # Write_rows # # table_id: # +master-bin.000001 # Write_rows # # table_id: # +master-bin.000001 # Write_rows # # table_id: # +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Query # # ROLLBACK +################################################################################### +# CLEAN +################################################################################### +DROP TABLE tt_1; +DROP TABLE tt_2; +DROP TABLE nt_1; +DROP TABLE nt_2; === added file 'mysql-test/suite/binlog/t/binlog_mixed_failure_mixing_engines.test' --- a/mysql-test/suite/binlog/t/binlog_mixed_failure_mixing_engines.test 1970-01-01 00:00:00 +0000 +++ b/mysql-test/suite/binlog/t/binlog_mixed_failure_mixing_engines.test 2009-09-28 12:55:54 +0000 @@ -0,0 +1,4 @@ +--source include/have_binlog_format_mixed.inc +--source include/have_innodb.inc + +--source extra/binlog_tests/binlog_failure_mixing_engines.test === added file 'mysql-test/suite/binlog/t/binlog_row_failure_mixing_engines.test' --- a/mysql-test/suite/binlog/t/binlog_row_failure_mixing_engines.test 1970-01-01 00:00:00 +0000 +++ b/mysql-test/suite/binlog/t/binlog_row_failure_mixing_engines.test 2009-09-28 12:55:54 +0000 @@ -0,0 +1,4 @@ +--source include/have_binlog_format_row.inc +--source include/have_innodb.inc + +--source extra/binlog_tests/binlog_failure_mixing_engines.test === modified file 'sql/log.cc' --- a/sql/log.cc 2009-09-11 17:06:27 +0000 +++ b/sql/log.cc 2009-09-28 12:55:54 +0000 @@ -153,7 +153,7 @@ private: class binlog_trx_data { public: binlog_trx_data() - : at_least_one_stmt(0), incident(FALSE), m_pending(0), + : at_least_one_stmt_committed(0), incident(FALSE), m_pending(0), before_stmt_pos(MY_OFF_T_UNDEF) { trans_log.end_of_file= max_binlog_cache_size; @@ -182,7 +182,10 @@ public: { DBUG_PRINT("info", ("truncating to position %lu", (ulong) pos)); DBUG_PRINT("info", ("before_stmt_pos=%lu", (ulong) pos)); - delete pending(); + if (pending()) + { + delete pending(); + } set_pending(0); reinit_io_cache(&trans_log, WRITE_CACHE, pos, 0, 0); trans_log.end_of_file= max_binlog_cache_size; @@ -192,12 +195,12 @@ public: /* The only valid positions that can be truncated to are at the beginning of a statement. We are relying on this fact to be able - to set the at_least_one_stmt flag correctly. In other word, if + to set the at_least_one_stmt_committed flag correctly. In other word, if we are truncating to the beginning of the transaction cache, there will be no statements in the cache, otherwhise, we will have at least one statement in the transaction cache. */ - at_least_one_stmt= (pos > 0); + at_least_one_stmt_committed= (pos > 0); } /* @@ -239,7 +242,7 @@ public: Boolean that is true if there is at least one statement in the transaction cache. */ - bool at_least_one_stmt; + bool at_least_one_stmt_committed; bool incident; private: @@ -1539,9 +1542,10 @@ static int binlog_commit(handlerton *hto { Query_log_event qev(thd, STRING_WITH_LEN("COMMIT"), TRUE, TRUE, 0); error= binlog_end_trans(thd, trx_data, &qev, all); - goto end; } + trx_data->at_least_one_stmt_committed = my_b_tell(&trx_data->trans_log) > 0; + end: if (!all) trx_data->before_stmt_pos = MY_OFF_T_UNDEF; // part of the stmt commit @@ -1608,15 +1612,18 @@ static int binlog_rollback(handlerton *h { /* We flush the cache with a rollback, wrapped in a beging/rollback if: - . aborting a transcation that modified a non-transactional table or; + . aborting a transaction that modified a non-transactional table; . aborting a statement that modified both transactional and - non-transctional tables but which is not in the boundaries of any - transaction; + non-transactional tables but which is not in the boundaries of any + transaction or there was no early change; . the OPTION_KEEP_LOG is activate. */ if ((all && thd->transaction.all.modified_non_trans_table) || (!all && thd->transaction.stmt.modified_non_trans_table && !(thd->options & (OPTION_BEGIN | OPTION_NOT_AUTOCOMMIT))) || + (!all && thd->transaction.stmt.modified_non_trans_table && + !trx_data->at_least_one_stmt_committed && + thd->current_stmt_binlog_row_based) || ((thd->options & OPTION_KEEP_LOG))) { Query_log_event qev(thd, STRING_WITH_LEN("ROLLBACK"), TRUE, TRUE, 0); --Boundary_(ID_Hd9hcqgWKFwvmAW2jU1q0g) MIME-version: 1.0 Content-type: text/bzr-bundle; CHARSET=US-ASCII; name*0="bzr/alfranio.correia@stripped"; name*1=554-vwufh0s8gwp0owkc.bundle Content-transfer-encoding: 7BIT Content-disposition: inline; filename*0="bzr/alfranio.correia@stripped"; filename*1=554-vwufh0s8gwp0owkc.bundle # Bazaar merge directive format 2 (Bazaar 0.90) # revision_id: alfranio.correia@stripped\ # vwufh0s8gwp0owkc # target_branch: file:///home/acorreia/workspace.sun/repository.mysql\ # /bzrwork/bug-47287/mysql-5.1-bugteam/ # testament_sha1: b18845ae768347821d83d62f2043d5adc03c2854 # timestamp: 2009-09-28 13:56:00 +0100 # base_revision_id: li-bing.song@stripped\ # v40rklb7g178tjza # # Begin bundle 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 SyrvZWPdQxxv+LuSKcKEgIVB4UA= --Boundary_(ID_Hd9hcqgWKFwvmAW2jU1q0g)--