Alfranio, hello.
You explained that the result files are not updated in this cset.
Per your suggestion I am having the actual results while making review.
We discussed all topics and agreed with you to try
gaining the new modified_trans_table flag's functionality via
ha_check_and_coalesce_trx_read_only()
The flag is largely redundant and maintainence pain.
Couple of suggestions, not critical, for the tests and the comments
plz find inlined.
As I am moving into vacation-land, I won't be able to finish reviewing.
Sure, you're free to replace me.
However, I am happy with the plan you're on now.
cheers,
Andrei
> #At
> file:///home/acorreia/workspace.sun/repository.mysql/bzrwork/bug-28976/mysql-5.1-bugteam/
> based on revid:martin.hansson@stripped
>
> 2972 Alfranio Correia 2009-07-08
> BUG#28976 Mixing trans and non-trans tables in one transaction results in
> incorrect
> binlog
>
> Mixing transactional and non-transactional tables on behalf of a transaction
> may
> lead to inconsistencies among masters and slaves. The problem stems from the
> fact
> that although modifications done to non-transactional tables on behalf of a
> transaction become immediately visible to the other connections it does not
> immediately gets to the binary log and therefore consistency is broken.
>
> After the WL#2687, it will be safe to use either the MIXED or ROW mode to do
> such
> mix. Changes to non-transactional tables will immediately get to the binary
> log
> as rows. Under the STATEMENT mode, however, changing non-transactional tables
> before transactional ones is the only possible safe mix. This happen because
> it
> is as if such changes had not been executed on the behalf of a transaction.
> On the other hand, other combinations may hide a causal dependency, thus
> making
> impossible to immediately write statements with non-transactional tables to
> the
> binary log.
>
> This patch guarantees that a mix under the STATEMENT mode is handled as
> follows:
>
> 1) "B T T C" generates the "B T T C" entries in the binary log.
>
> 2) "B T T R" generates an "empty" entry in the binary log.
>
> 2) "B T N C" generates the "B T N C" entries in the binary log.
>
> 3) "B T N R" generates the "B T N R" entries in the binary log.
>
> 4) "T" generates the "B T C" entries in the binary log.
>
> 5) "T" with error generates an "empty" entry in the binary log.
>
> 6) "N" generates the "N" entry in the binary log.
>
> 7) "N" generates an empty entry if the error happens in the first tuple.
> Otherwise, generates the "N" entry in the binary log.
>
> 8) "M" generates the "B M C" entries in the binary log.
>
> 10) "M" with error generates the "B M C" entries in the binary log.
>
> 11) "B N N T C" generates the "N N B T C" entries in the binary log.
>
> 12) "B N N T R" generates the "N N B T R" entries in the binary log.
>
> 13) "B N N C" generates the "N N" entries in the binary log.
>
> 14) "B N N R" generates the "N N" entries in the binary log.
>
> 15) "B M T C" generates the "B M T C" entries in the binary log.
>
> 16) "B M T R" generates the "B M T R" entries in the binary log.
>
The use case are list pretty accurately. Still the following test
does not follow the same enumeration.
It's not critical but maybe you will find sticking to one of them
as a good thing.
> added:
> mysql-test/suite/rpl/include/rpl_mixed_engines.inc
> mysql-test/suite/rpl/r/rpl_mixing_stmt_engines.result
> mysql-test/suite/rpl/t/rpl_mixing_stmt_engines.test
> modified:
> sql/ha_ndbcluster_binlog.cc
> sql/handler.h
> sql/log.cc
> sql/log_event.cc
> sql/set_var.cc
> sql/sql_base.cc
> sql/sql_class.cc
> sql/sql_delete.cc
> sql/sql_parse.cc
> === added file 'mysql-test/suite/rpl/include/rpl_mixed_engines.inc'
> --- a/mysql-test/suite/rpl/include/rpl_mixed_engines.inc 1970-01-01 00:00:00 +0000
> +++ b/mysql-test/suite/rpl/include/rpl_mixed_engines.inc 2009-07-08 08:29:34 +0000
> @@ -0,0 +1,505 @@
> +###################################################################################
> +# This test checks if transactions that mixes transactional and non-transactional
> +# tables are correctly handled in statement mode. In an nutshell, we have what
> +# follows:
> +#
> +# 1.a) "B T T C" generates in binlog the "B T T C" entries.
> +#
> +# 1.b) "B T T R" generates in binlog an "empty" entry.
> +#
I got the idea, a,b stand for C,R :-)
N.C and N.R - would be nicer, but that might be extra literate work as well.
So it's up to you.
> +# 2.a) "B T N C" generates in binlog the "B T N C" entries.
> +#
> +# 2.b) "B T N R" generates in binlog the "B T N R" entries.
> +#
> +# 3.a) "T" generates in binlog the "B T C" entry.
> +#
> +# 3.b) "T" with error generates in binlog an "empty" entry.
> +#
> +# 4.a) "N" generates in binlog the "N" entry.
> +#
> +# 4.b) "N" generates in binlog an empty entry if the error happens in the first
> tuple.
> +# Otherwise, generates the "N" entry.
> +#
> +# 5.a) "M" generates in binglog the "B M C" entries.
> +#
> +# 5.b) "M" with error generates in binglog the "B M C" entries.
Should not it be "B M *R*" ?
The same for 8,9.
> +#
> +# 6.a) "B N N T C" generates in binglog the "N N B T C" entries.
> +#
> +# 6.b) "B N N T R" generates in binlog the "N N B T R" entries.
> +#
> +# 7.a) "B N N C" generates in binglog the "N N" entries.
> +#
> +# 7.b) "B N N R" generates in binlog the "N N" entries.
> +#
> +# 8.a) "B M T C" generates in the binlog the "B M T C" entries.
> +#
> +# 8.b) "B M T C" with error in M generates in the binlog the "B M T C" entries.
> +#
> +# 9.a) "B M T R" generates in the binlog the "B M T R" entries.
> +#
> +# 9.b) "B M T R" with error in M generates in the binlog the "B M T R" entries.
> +###################################################################################
> +
> +--echo
> ###################################################################################
> +--echo # CONFIGURATION
> +--echo
> ###################################################################################
> +connection master;
> +
> +CREATE TABLE nt_1 (a text, b int PRIMARY KEY, c text) ENGINE = MyISAM;
> +CREATE TABLE nt_2 (a text, b int PRIMARY KEY, c text) ENGINE = MyISAM;
> +CREATE TABLE nt_3 (a text, b int PRIMARY KEY, c text) ENGINE = MyISAM;
> +CREATE TABLE nt_4 (a text, b int PRIMARY KEY, c text) ENGINE = MyISAM;
> +CREATE TABLE tt_1 (a text, b int PRIMARY KEY, c text) ENGINE = Innodb;
> +CREATE TABLE tt_2 (a text, b int PRIMARY KEY, c text) ENGINE = Innodb;
> +CREATE TABLE tt_3 (a text, b int PRIMARY KEY, c text) ENGINE = Innodb;
> +CREATE TABLE tt_4 (a text, b int PRIMARY KEY, c text) ENGINE = Innodb;
> +
> +DELIMITER |;
> +
> +CREATE FUNCTION f1 () RETURNS VARCHAR(64)
> +BEGIN
> + RETURN "Testing...";
> +END|
> +
> +CREATE FUNCTION f2 () RETURNS VARCHAR(64)
> +BEGIN
> + RETURN f1();
> +END|
> +
> +CREATE PROCEDURE pc_i_tt_3 (IN x INT, IN y VARCHAR(64))
> +BEGIN
> + INSERT INTO tt_3 VALUES (y,x,x);
> +END|
> +
> +CREATE TRIGGER tr_i_tt_3_to_nt_3 BEFORE INSERT ON tt_3 FOR EACH ROW
> +BEGIN
> + INSERT INTO nt_3 VALUES (NEW.a, NEW.b, NEW.c);
> +END|
> +
> +CREATE TRIGGER tr_i_nt_4_to_tt_4 BEFORE INSERT ON nt_4 FOR EACH ROW
> +BEGIN
> + INSERT INTO tt_4 VALUES (NEW.a, NEW.b, NEW.c);
> +END|
> +
> +DELIMITER ;|
> +
> +--echo
> ###################################################################################
> +--echo # MIXING TRANSACTIONAL and NON-TRANSACTIONAL TABLES
> +--echo
> ###################################################################################
> +connection master;
> +
> +let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1);
> +--echo #
> +--echo #1.a) "B T T C" generates in binlog the "B T T C" entries.
> +--echo #
> +BEGIN;
> +INSERT INTO tt_1 VALUES ("new text 4", 4, "new text 4");
> +INSERT INTO tt_2 VALUES ("new text 4", 4, "new text 4");
> +COMMIT;
> +
> +--source include/show_binlog_events.inc
> +
> +--echo
> +--echo
> +--echo
> +--echo
> +let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1);
> +--echo #
> +--echo #1.b) "B T T R" generates in binlog an "empty" entry.
> +--echo #
> +BEGIN;
> +INSERT INTO tt_1 VALUES ("new text 5", 5, "new text 5");
> +INSERT INTO tt_2 VALUES ("new text 5", 5, "new text 5");
> +ROLLBACK;
> +
> +--source include/show_binlog_events.inc
> +
> +--echo
> +--echo
> +--echo
> +--echo
> +let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1);
> +--echo #
> +--echo #2.a) "B T N C" generates in binlog the "B T N C" entries.
> +--echo #
> +BEGIN;
> +INSERT INTO tt_1 VALUES ("new text 6", 6, "new text 6");
> +INSERT INTO nt_1 VALUES ("new text 6", 6, "new text 6");
> +COMMIT;
> +
> +--source include/show_binlog_events.inc
> +
> +--echo
> +--echo
> +--echo
> +--echo
> +let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1);
> +--echo #
> +--echo #2.b) "B T N R" generates in binlog the "B T N R" entries.
> +--echo #
> +BEGIN;
> +INSERT INTO tt_1 VALUES ("new text 7", 7, "new text 7");
> +INSERT INTO nt_1 VALUES ("new text 7", 7, "new text 7");
> +ROLLBACK;
> +
> +--source include/show_binlog_events.inc
> +
> +--echo
> +--echo
> +--echo
> +--echo
> +let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1);
> +--echo #
> +--echo #3.a) "T" generates in binlog the "B T C" entry.
> +--echo #
> +INSERT INTO tt_1 VALUES ("new text 8", 8, "new text 8");
> +
> +--source include/show_binlog_events.inc
> +
> +--echo
> +--echo
> +--echo
> +--echo
> +let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1);
> +--echo #
> +--echo #3.b) "T" with error generates in binlog an "empty" entry.
> +--echo #
> +--error ER_DUP_ENTRY
> +INSERT INTO tt_1 VALUES ("new text 8", 8, "new text 8");
> +
> +--source include/show_binlog_events.inc
> +
> +--echo
> +--echo
> +--echo
> +--echo
> +let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1);
> +--echo #
> +--echo #4.a) "N" generates in binlog the "N" entry.
> +--echo #
> +INSERT INTO nt_1 VALUES ("new text 9", 9, "new text 9");
> +
> +--source include/show_binlog_events.inc
> +
> +--echo
> +--echo
> +--echo
> +--echo
> +let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1);
> +--echo #
> +--echo #4.b) "N" generates in binlog an empty entry if the error happens in the
> first tuple.
> +--echo # Otherwise, generates the "N" entry.
> +--echo #
> +--error ER_DUP_ENTRY
> +INSERT INTO nt_1 VALUES ("new text 9", 9, "new text 9");
> +--error ER_DUP_ENTRY
> +INSERT INTO nt_1 VALUES ("new text -1", -1, "new text -1"), ("new text 9", 9, "new
> text 9");
> +
> +--source include/show_binlog_events.inc
> +
> +--echo
> +--echo
> +--echo
> +--echo
> +let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1);
> +--echo #
> +--echo #5.a) "M" generates in binglog the "B M C" entries.
> +--echo #
> +
> +DELETE FROM nt_1;
> +
> +INSERT INTO nt_1 SELECT * FROM tt_1;
> +
> +DELETE FROM tt_1;
> +
> +INSERT INTO tt_1 SELECT * FROM nt_1;
> +
> +INSERT INTO tt_3 VALUES ("new text 000", 000, '');
> +
> +INSERT INTO tt_3 VALUES("new text 100", 100, f1());
> +
> +INSERT INTO tt_3 VALUES("new text 200", 200, f2());
> +
> +INSERT INTO nt_4 VALUES ("new text 300", 300, '');
> +
> +INSERT INTO nt_4 VALUES ("new text 400", 400, f1());
> +
> +INSERT INTO nt_4 VALUES ("new text 500", 500, f2());
> +
> +CALL pc_i_tt_3(600, "Testing...");
> +
> +UPDATE nt_3, nt_4, tt_3, tt_4 SET nt_3.a= "new text 1", nt_4.a= "new text 1",
> tt_3.a= "new text 1", tt_4.a= "new text 1" where nt_3.b = nt_4.b and nt_4.b = tt_3.b and
> tt_3.b = tt_4.b and tt_4.b = 100;
> +
> +UPDATE tt_3, tt_4, nt_3, nt_4 SET tt_3.a= "new text 2", tt_4.a= "new text 2",
> nt_3.a= "new text 2", nt_4.a = "new text 2" where nt_3.b = nt_4.b and nt_4.b = tt_3.b and
> tt_3.b = tt_4.b and tt_4.b = 100;
> +
> +UPDATE tt_3, nt_3, nt_4, tt_4 SET tt_3.a= "new text 3", nt_3.a= "new text 3",
> nt_4.a= "new text 3", tt_4.a = "new text 3" where nt_3.b = nt_4.b and nt_4.b = tt_3.b and
> tt_3.b = tt_4.b and tt_4.b = 100;
> +
> +UPDATE tt_3, nt_3, nt_4, tt_4 SET tt_3.a= "new text 4", nt_3.a= "new text 4",
> nt_4.a= "new text 4", tt_4.a = "new text 4" where nt_3.b = nt_4.b and nt_4.b = tt_3.b and
> tt_3.b = tt_4.b and tt_4.b = 100;
> +
> +--source include/show_binlog_events.inc
> +--echo
> +--echo
> +--echo
> +--echo
> +let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1);
> +--echo #
> +--echo #5.b) "M" with error generates in binglog the "B M R" entries.
> +--echo #
> +
> +INSERT INTO nt_3 VALUES ("new text -2", -2, '');
> +SELECT * FROM tt_3;
> +--error ER_DUP_ENTRY
> +INSERT INTO tt_3 VALUES ("new text -1", -1, ''), ("new text -2", -2, '');
> +SELECT * FROM tt_3;
> +
> +INSERT INTO tt_4 VALUES ("new text -2", -2, '');
> +SELECT * FROM nt_4;
> +--error ER_DUP_ENTRY
> +INSERT INTO nt_4 VALUES ("new text -1", -1, ''), ("new text -2", -2, '');
> +SELECT * FROM nt_4;
> +
> +--source include/show_binlog_events.inc
> +
> +--echo
> +--echo
> +--echo
> +--echo
> +let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1);
> +--echo #
> +--echo #6.a) "B N N T C" generates in binglog the "N N B T C" entries.
> +--echo #
> +BEGIN;
> +INSERT INTO nt_1 VALUES ("new text 10", 10, "new text 10");
> +INSERT INTO nt_2 VALUES ("new text 10", 10, "new text 10");
> +INSERT INTO tt_1 VALUES ("new text 10", 10, "new text 10");
> +COMMIT;
> +
> +--source include/show_binlog_events.inc
> +
> +--echo
> +--echo
> +--echo
> +--echo
> +let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1);
> +--echo #
> +--echo #6.b) "B N N T R" generates in binlog the "N N B T R" entries.
> +--echo #
> +BEGIN;
> +INSERT INTO nt_1 VALUES ("new text 11", 11, "new text 11");
> +INSERT INTO nt_2 VALUES ("new text 11", 11, "new text 11");
> +INSERT INTO tt_1 VALUES ("new text 11", 11, "new text 11");
> +ROLLBACK;
> +
> +--source include/show_binlog_events.inc
> +
> +--echo
> +--echo
> +--echo
> +--echo
> +let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1);
> +--echo #
> +--echo #7.a) "B N N C" generates in binglog the "N N" entries.
> +--echo #
> +BEGIN;
> +INSERT INTO nt_1 VALUES ("new text 12", 12, "new text 12");
> +INSERT INTO nt_2 VALUES ("new text 12", 12, "new text 12");
> +COMMIT;
> +
> +--source include/show_binlog_events.inc
> +
> +--echo
> +--echo
> +--echo
> +--echo
> +let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1);
> +--echo #
> +--echo #7.b) "B N N R" generates in binlog the "N N" entries.
> +--echo #
> +BEGIN;
> +INSERT INTO nt_1 VALUES ("new text 13", 13, "new text 13");
> +INSERT INTO nt_2 VALUES ("new text 13", 13, "new text 13");
> +ROLLBACK;
> +
> +--source include/show_binlog_events.inc
> +
> +--echo
> +--echo
> +--echo
> +--echo
> +let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1);
> +--echo #
> +--echo #8.a) "B M T C" generates in the binlog the "B M T C" entries.
> +--echo #
> +DELETE FROM nt_1;
> +BEGIN;
> +INSERT INTO nt_1 SELECT * FROM tt_1;
> +INSERT INTO tt_2 VALUES ("new text 14", 14, "new text 14");
> +COMMIT;
> +
> +DELETE FROM tt_1;
> +BEGIN;
> +INSERT INTO tt_1 SELECT * FROM nt_1;
> +INSERT INTO tt_2 VALUES ("new text 15", 15, "new text 15");
> +COMMIT;
> +
> +BEGIN;
> +INSERT INTO tt_3 VALUES ("new text 700", 700, '');
> +INSERT INTO tt_1 VALUES ("new text 800", 800, '');
> +COMMIT;
> +
> +BEGIN;
> +INSERT INTO tt_3 VALUES("new text 900", 900, f1());
> +INSERT INTO tt_1 VALUES ("new text 1000", 1000, '');
> +COMMIT;
> +
> +BEGIN;
> +INSERT INTO tt_3 VALUES(1100, 1100, f2());
> +INSERT INTO tt_1 VALUES ("new text 1200", 1200, '');
> +COMMIT;
> +
> +BEGIN;
> +INSERT INTO nt_4 VALUES ("new text 1300", 1300, '');
> +INSERT INTO tt_1 VALUES ("new text 1400", 1400, '');
> +COMMIT;
> +
> +BEGIN;
> +INSERT INTO nt_4 VALUES("new text 1500", 1500, f1());
> +INSERT INTO tt_1 VALUES ("new text 1600", 1600, '');
> +COMMIT;
> +
> +BEGIN;
> +INSERT INTO nt_4 VALUES("new text 1700", 1700, f2());
> +INSERT INTO tt_1 VALUES ("new text 1800", 1800, '');
> +COMMIT;
> +
> +BEGIN;
> +CALL pc_i_tt_3(1900, "Testing...");
> +INSERT INTO tt_1 VALUES ("new text 2000", 2000, '');
> +COMMIT;
> +
> +BEGIN;
> +UPDATE nt_3, nt_4, tt_3, tt_4 SET nt_3.a= "new text 5", nt_4.a= "new text 5",
> tt_3.a= "new text 5", tt_4.a= "new text 5" where nt_3.b = nt_4.b and nt_4.b = tt_3.b and
> tt_3.b = tt_4.b and tt_4.b = 100;
> +INSERT INTO tt_1 VALUES ("new text 2100", 2100, '');
> +COMMIT;
> +
> +BEGIN;
> +UPDATE tt_3, tt_4, nt_3, nt_4 SET tt_3.a= "new text 6", tt_4.a= "new text 6",
> nt_3.a= "new text 6", nt_4.a = "new text 6" where nt_3.b = nt_4.b and nt_4.b = tt_3.b and
> tt_3.b = tt_4.b and tt_4.b = 100;
> +INSERT INTO tt_1 VALUES ("new text 2200", 2200, '');
> +COMMIT;
> +
> +BEGIN;
> +UPDATE tt_3, nt_3, nt_4, tt_4 SET tt_3.a= "new text 7", nt_3.a= "new text 7",
> nt_4.a= "new text 7", tt_4.a = "new text 7" where nt_3.b = nt_4.b and nt_4.b = tt_3.b and
> tt_3.b = tt_4.b and tt_4.b = 100;
> +INSERT INTO tt_1 VALUES ("new text 2300", 2300, '');
> +COMMIT;
> +
> +BEGIN;
> +UPDATE tt_3, nt_3, nt_4, tt_4 SET tt_3.a= "new text 8", nt_3.a= "new text 8",
> nt_4.a= "new text 8", tt_4.a = "new text 8" where nt_3.b = nt_4.b and nt_4.b = tt_3.b and
> tt_3.b = tt_4.b and tt_4.b = 100;
> +INSERT INTO tt_1 VALUES ("new text 2400", 2400, '');
> +COMMIT;
> +
> +--source include/show_binlog_events.inc
> +
> +--echo
> +--echo
> +--echo
> +--echo
> +let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1);
> +--echo # C - T C - S(N) T(T) C - S(N) T(T)
> +--echo #8.b) B M T R F - R F - D(N) I(T) F - D(N) I(T)
> +--echo #
> +DELETE FROM nt_1;
> +BEGIN;
> +INSERT INTO nt_1 SELECT * FROM tt_1;
> +INSERT INTO tt_2 VALUES ("new text 17", 17, "new text 17");
> +ROLLBACK;
> +
> +DELETE FROM tt_1;
> +BEGIN;
> +INSERT INTO tt_1 SELECT * FROM nt_1;
> +INSERT INTO tt_2 VALUES ("new text 18", 18, "new text 18");
> +ROLLBACK;
> +INSERT INTO tt_1 SELECT * FROM nt_1;
> +
> +BEGIN;
> +INSERT INTO tt_3 VALUES ("new text 2500", 2500, '');
> +INSERT INTO tt_1 VALUES ("new text 2600", 2600, '');
> +ROLLBACK;
> +
> +BEGIN;
> +INSERT INTO tt_3 VALUES("new text 2700", 2700, f1());
> +INSERT INTO tt_1 VALUES ("new text 2800", 2800, '');
> +ROLLBACK;
> +
> +BEGIN;
> +INSERT INTO tt_3 VALUES(2900, 2900, f2());
> +INSERT INTO tt_1 VALUES ("new text 3000", 3000, '');
> +ROLLBACK;
> +
> +BEGIN;
> +INSERT INTO nt_4 VALUES ("new text 3100", 3100, '');
> +INSERT INTO tt_1 VALUES ("new text 3200", 3200, '');
> +ROLLBACK;
> +
> +BEGIN;
> +INSERT INTO nt_4 VALUES("new text 3300", 3300, f1());
> +INSERT INTO tt_1 VALUES ("new text 3400", 3400, '');
> +ROLLBACK;
> +
> +BEGIN;
> +INSERT INTO nt_4 VALUES("new text 3500", 3500, f2());
> +INSERT INTO tt_1 VALUES ("new text 3600", 3600, '');
> +ROLLBACK;
> +
> +BEGIN;
> +CALL pc_i_tt_3(3700, "Testing...");
> +INSERT INTO tt_1 VALUES ("new text 3700", 3700, '');
> +ROLLBACK;
> +
> +BEGIN;
> +UPDATE nt_3, nt_4, tt_3, tt_4 SET nt_3.a= "new text 9", nt_4.a= "new text 9",
> tt_3.a= "new text 9", tt_4.a= "new text 9" where nt_3.b = nt_4.b and nt_4.b = tt_3.b and
> tt_3.b = tt_4.b and tt_4.b = 100;
> +INSERT INTO tt_1 VALUES ("new text 3800", 3800, '');
> +ROLLBACK;
> +
> +BEGIN;
> +UPDATE tt_3, tt_4, nt_3, nt_4 SET tt_3.a= "new text 10", tt_4.a= "new text 10",
> nt_3.a= "new text 10", nt_4.a = "new text 10" where nt_3.b = nt_4.b and nt_4.b = tt_3.b
> and tt_3.b = tt_4.b and tt_4.b = 100;
> +INSERT INTO tt_1 VALUES ("new text 3900", 3900, '');
> +ROLLBACK;
> +
> +BEGIN;
> +UPDATE tt_3, nt_3, nt_4, tt_4 SET tt_3.a= "new text 11", nt_3.a= "new text 11",
> nt_4.a= "new text 11", tt_4.a = "new text 11" where nt_3.b = nt_4.b and nt_4.b = tt_3.b
> and tt_3.b = tt_4.b and tt_4.b = 100;
> +INSERT INTO tt_1 VALUES ("new text 4000", 4000, '');
> +ROLLBACK;
> +
> +BEGIN;
> +UPDATE tt_3, nt_3, nt_4, tt_4 SET tt_3.a= "new text 12", nt_3.a= "new text 12",
> nt_4.a= "new text 12", tt_4.a = "new text 12" where nt_3.b = nt_4.b and nt_4.b = tt_3.b
> and tt_3.b = tt_4.b and tt_4.b = 100;
> +INSERT INTO tt_1 VALUES ("new text 4100", 4100, '');
> +ROLLBACK;
> +
> +--source include/show_binlog_events.inc
> +
> +connection master;
> +sync_slave_with_master;
> +
> +--exec $MYSQL_DUMP --compact --order-by-primary --skip-extended-insert
> --no-create-info test > $MYSQLTEST_VARDIR/tmp/test-master.sql
> +--exec $MYSQL_DUMP_SLAVE --compact --order-by-primary --skip-extended-insert
> --no-create-info test > $MYSQLTEST_VARDIR/tmp/test-slave.sql
> +--diff_files $MYSQLTEST_VARDIR/tmp/test-master.sql
> $MYSQLTEST_VARDIR/tmp/test-slave.sql
> +
> +--echo
> ###################################################################################
> +--echo # CLEAN
> +--echo
> ###################################################################################
> +
> +connection master;
> +DROP TABLE tt_1;
> +DROP TABLE tt_2;
> +DROP TABLE tt_3;
> +DROP TABLE tt_4;
> +DROP TABLE nt_1;
> +DROP TABLE nt_2;
> +DROP TABLE nt_3;
> +DROP TABLE nt_4;
> +DROP PROCEDURE pc_i_tt_3;
> +DROP FUNCTION f1;
> +DROP FUNCTION f2;
> +
> +sync_slave_with_master;
>
> === added file 'mysql-test/suite/rpl/r/rpl_mixing_stmt_engines.result'
> --- a/mysql-test/suite/rpl/r/rpl_mixing_stmt_engines.result 1970-01-01 00:00:00
> +0000
> +++ b/mysql-test/suite/rpl/r/rpl_mixing_stmt_engines.result 2009-07-08 08:29:34
> +0000
> @@ -0,0 +1,577 @@
> +stop slave;
> +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
> +reset master;
> +reset slave;
> +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
> +start slave;
> +###################################################################################
> +# CONFIGURATION
> +###################################################################################
> +CREATE TABLE nt_1 (a text, b int PRIMARY KEY, c text) ENGINE = MyISAM;
> +CREATE TABLE nt_2 (a text, b int PRIMARY KEY, c text) ENGINE = MyISAM;
> +CREATE TABLE nt_3 (a text, b int PRIMARY KEY, c text) ENGINE = MyISAM;
> +CREATE TABLE nt_4 (a text, b int PRIMARY KEY, c text) ENGINE = MyISAM;
> +CREATE TABLE tt_1 (a text, b int PRIMARY KEY, c text) ENGINE = Innodb;
> +CREATE TABLE tt_2 (a text, b int PRIMARY KEY, c text) ENGINE = Innodb;
> +CREATE TABLE tt_3 (a text, b int PRIMARY KEY, c text) ENGINE = Innodb;
> +CREATE TABLE tt_4 (a text, b int PRIMARY KEY, c text) ENGINE = Innodb;
> +CREATE FUNCTION f1 () RETURNS VARCHAR(64)
> +BEGIN
> +RETURN "Testing...";
> +END|
> +CREATE FUNCTION f2 () RETURNS VARCHAR(64)
> +BEGIN
> +RETURN f1();
> +END|
> +CREATE PROCEDURE pc_i_tt_3 (IN x INT, IN y VARCHAR(64))
> +BEGIN
> +INSERT INTO tt_3 VALUES (y,x,x);
> +END|
> +CREATE TRIGGER tr_i_tt_3_to_nt_3 BEFORE INSERT ON tt_3 FOR EACH ROW
> +BEGIN
> +INSERT INTO nt_3 VALUES (NEW.a, NEW.b, NEW.c);
> +END|
> +CREATE TRIGGER tr_i_nt_4_to_tt_4 BEFORE INSERT ON nt_4 FOR EACH ROW
> +BEGIN
> +INSERT INTO tt_4 VALUES (NEW.a, NEW.b, NEW.c);
> +END|
> +###################################################################################
> +# MIXING TRANSACTIONAL and NON-TRANSACTIONAL TABLES
> +###################################################################################
> +#
> +#1.a) "B T T C" generates in binlog the "B T T C" entries.
> +#
> +BEGIN;
> +INSERT INTO tt_1 VALUES ("new text 4", 4, "new text 4");
> +INSERT INTO tt_2 VALUES ("new text 4", 4, "new text 4");
> +COMMIT;
> +show binlog events from <binlog_start>;
> +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_1 VALUES ("new text 4", 4,
> "new text 4")
> +master-bin.000001 # Query # # use `test`; INSERT INTO tt_2 VALUES ("new text 4", 4,
> "new text 4")
> +master-bin.000001 # Xid # # COMMIT /* XID */
> +
> +
> +
> +
> +#
> +#1.b) "B T T R" generates in binlog an "empty" entry.
> +#
> +BEGIN;
> +INSERT INTO tt_1 VALUES ("new text 5", 5, "new text 5");
> +INSERT INTO tt_2 VALUES ("new text 5", 5, "new text 5");
> +ROLLBACK;
> +show binlog events from <binlog_start>;
> +Log_name Pos Event_type Server_id End_log_pos Info
> +
> +
> +
> +
> +#
> +#2.a) "B T N C" generates in binlog the "B T N C" entries.
> +#
> +BEGIN;
> +INSERT INTO tt_1 VALUES ("new text 6", 6, "new text 6");
> +INSERT INTO nt_1 VALUES ("new text 6", 6, "new text 6");
> +COMMIT;
> +show binlog events from <binlog_start>;
> +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_1 VALUES ("new text 6", 6,
> "new text 6")
> +master-bin.000001 # Query # # use `test`; INSERT INTO nt_1 VALUES ("new text 6", 6,
> "new text 6")
> +master-bin.000001 # Xid # # COMMIT /* XID */
> +
> +
> +
> +
> +#
> +#2.b) "B T N R" generates in binlog the "B T N R" entries.
> +#
> +BEGIN;
> +INSERT INTO tt_1 VALUES ("new text 7", 7, "new text 7");
> +INSERT INTO nt_1 VALUES ("new text 7", 7, "new text 7");
> +ROLLBACK;
> +Warnings:
> +Warning 1196 Some non-transactional changed tables couldn't be rolled back
> +show binlog events from <binlog_start>;
> +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_1 VALUES ("new text 7", 7,
> "new text 7")
> +master-bin.000001 # Query # # use `test`; INSERT INTO nt_1 VALUES ("new text 7", 7,
> "new text 7")
> +master-bin.000001 # Query # # ROLLBACK
> +
> +
> +
> +
> +#
> +#3.a) "T" generates in binlog the "B T C" entry.
> +#
> +INSERT INTO tt_1 VALUES ("new text 8", 8, "new text 8");
> +show binlog events from <binlog_start>;
> +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_1 VALUES ("new text 8", 8,
> "new text 8")
> +master-bin.000001 # Xid # # COMMIT /* XID */
> +
> +
> +
> +
> +#
> +#3.b) "T" with error generates in binlog an "empty" entry.
> +#
> +INSERT INTO tt_1 VALUES ("new text 8", 8, "new text 8");
> +ERROR 23000: Duplicate entry '8' for key 'PRIMARY'
> +show binlog events from <binlog_start>;
> +Log_name Pos Event_type Server_id End_log_pos Info
> +
> +
> +
> +
> +#
> +#4.a) "N" generates in binlog the "N" entry.
> +#
> +INSERT INTO nt_1 VALUES ("new text 9", 9, "new text 9");
> +show binlog events from <binlog_start>;
> +Log_name Pos Event_type Server_id End_log_pos Info
> +master-bin.000001 # Query # # use `test`; INSERT INTO nt_1 VALUES ("new text 9", 9,
> "new text 9")
> +
> +
> +
> +
> +#
> +#4.b) "N" generates in binlog an empty entry if the error happens in the first
> tuple.
> +# Otherwise, generates the "N" entry.
> +#
> +INSERT INTO nt_1 VALUES ("new text 9", 9, "new text 9");
> +ERROR 23000: Duplicate entry '9' for key 'PRIMARY'
> +INSERT INTO nt_1 VALUES ("new text -1", -1, "new text -1"), ("new text 9", 9, "new
> text 9");
> +ERROR 23000: Duplicate entry '9' for key 'PRIMARY'
> +show binlog events from <binlog_start>;
> +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, "new text -1"), ("new text 9", 9, "new text 9")
> +
> +
> +
> +
> +#
> +#5.a) "M" generates in binglog the "B M C" entries.
> +#
> +DELETE FROM nt_1;
> +INSERT INTO nt_1 SELECT * FROM tt_1;
> +DELETE FROM tt_1;
> +INSERT INTO tt_1 SELECT * FROM nt_1;
> +INSERT INTO tt_3 VALUES ("new text 000", 000, '');
> +INSERT INTO tt_3 VALUES("new text 100", 100, f1());
> +INSERT INTO tt_3 VALUES("new text 200", 200, f2());
> +INSERT INTO nt_4 VALUES ("new text 300", 300, '');
> +INSERT INTO nt_4 VALUES ("new text 400", 400, f1());
> +INSERT INTO nt_4 VALUES ("new text 500", 500, f2());
> +CALL pc_i_tt_3(600, "Testing...");
> +UPDATE nt_3, nt_4, tt_3, tt_4 SET nt_3.a= "new text 1", nt_4.a= "new text 1",
> tt_3.a= "new text 1", tt_4.a= "new text 1" where nt_3.b = nt_4.b and nt_4.b = tt_3.b and
> tt_3.b = tt_4.b and tt_4.b = 100;
> +UPDATE tt_3, tt_4, nt_3, nt_4 SET tt_3.a= "new text 2", tt_4.a= "new text 2",
> nt_3.a= "new text 2", nt_4.a = "new text 2" where nt_3.b = nt_4.b and nt_4.b = tt_3.b and
> tt_3.b = tt_4.b and tt_4.b = 100;
> +UPDATE tt_3, nt_3, nt_4, tt_4 SET tt_3.a= "new text 3", nt_3.a= "new text 3",
> nt_4.a= "new text 3", tt_4.a = "new text 3" where nt_3.b = nt_4.b and nt_4.b = tt_3.b and
> tt_3.b = tt_4.b and tt_4.b = 100;
> +UPDATE tt_3, nt_3, nt_4, tt_4 SET tt_3.a= "new text 4", nt_3.a= "new text 4",
> nt_4.a= "new text 4", tt_4.a = "new text 4" where nt_3.b = nt_4.b and nt_4.b = tt_3.b and
> tt_3.b = tt_4.b and tt_4.b = 100;
> +show binlog events from <binlog_start>;
> +Log_name Pos Event_type Server_id End_log_pos Info
> +master-bin.000001 # Query # # use `test`; DELETE FROM nt_1
> +master-bin.000001 # Query # # use `test`; INSERT INTO nt_1 SELECT * FROM tt_1
> +master-bin.000001 # Query # # BEGIN
> +master-bin.000001 # Query # # use `test`; DELETE FROM tt_1
> +master-bin.000001 # Xid # # COMMIT /* XID */
> +master-bin.000001 # Query # # BEGIN
> +master-bin.000001 # Query # # use `test`; INSERT INTO tt_1 SELECT * FROM nt_1
> +master-bin.000001 # Xid # # COMMIT /* XID */
> +master-bin.000001 # Query # # BEGIN
> +master-bin.000001 # Query # # use `test`; INSERT INTO tt_3 VALUES ("new text 000",
> 000, '')
> +master-bin.000001 # Xid # # COMMIT /* XID */
> +master-bin.000001 # Query # # BEGIN
> +master-bin.000001 # Query # # use `test`; INSERT INTO tt_3 VALUES("new text 100",
> 100, f1())
> +master-bin.000001 # Xid # # COMMIT /* XID */
> +master-bin.000001 # Query # # BEGIN
> +master-bin.000001 # Query # # use `test`; INSERT INTO tt_3 VALUES("new text 200",
> 200, f2())
> +master-bin.000001 # Xid # # COMMIT /* XID */
> +master-bin.000001 # Query # # use `test`; INSERT INTO nt_4 VALUES ("new text 300",
> 300, '')
> +master-bin.000001 # Query # # use `test`; INSERT INTO nt_4 VALUES ("new text 400",
> 400, f1())
> +master-bin.000001 # Query # # use `test`; INSERT INTO nt_4 VALUES ("new text 500",
> 500, f2())
> +master-bin.000001 # Query # # BEGIN
> +master-bin.000001 # Query # # use `test`; INSERT INTO tt_3 VALUES (
> NAME_CONST('y',_latin1'Testing...' COLLATE 'latin1_swedish_ci'), NAME_CONST('x',600),
> NAME_CONST('x',600))
> +master-bin.000001 # Xid # # COMMIT /* XID */
> +master-bin.000001 # Query # # use `test`; UPDATE nt_3, nt_4, tt_3, tt_4 SET nt_3.a=
> "new text 1", nt_4.a= "new text 1", tt_3.a= "new text 1", tt_4.a= "new text 1" where
> nt_3.b = nt_4.b and nt_4.b = tt_3.b and tt_3.b = tt_4.b and tt_4.b = 100
> +master-bin.000001 # Query # # use `test`; UPDATE tt_3, tt_4, nt_3, nt_4 SET tt_3.a=
> "new text 2", tt_4.a= "new text 2", nt_3.a= "new text 2", nt_4.a = "new text 2" where
> nt_3.b = nt_4.b and nt_4.b = tt_3.b and tt_3.b = tt_4.b and tt_4.b = 100
> +master-bin.000001 # Query # # use `test`; UPDATE tt_3, nt_3, nt_4, tt_4 SET tt_3.a=
> "new text 3", nt_3.a= "new text 3", nt_4.a= "new text 3", tt_4.a = "new text 3" where
> nt_3.b = nt_4.b and nt_4.b = tt_3.b and tt_3.b = tt_4.b and tt_4.b = 100
> +master-bin.000001 # Query # # use `test`; UPDATE tt_3, nt_3, nt_4, tt_4 SET tt_3.a=
> "new text 4", nt_3.a= "new text 4", nt_4.a= "new text 4", tt_4.a = "new text 4" where
> nt_3.b = nt_4.b and nt_4.b = tt_3.b and tt_3.b = tt_4.b and tt_4.b = 100
> +
> +
> +
> +
> +#
> +#5.b) "M" with error generates in binglog the "B M R" entries.
> +#
> +INSERT INTO nt_3 VALUES ("new text -2", -2, '');
> +SELECT * FROM tt_3;
> +a b c
> +new text 000 0
> +new text 100 100 Testing...
> +new text 200 200 Testing...
> +Testing... 600 600
> +INSERT INTO tt_3 VALUES ("new text -1", -1, ''), ("new text -2", -2, '');
> +ERROR 23000: Duplicate entry '-2' for key 'PRIMARY'
> +SELECT * FROM tt_3;
> +a b c
> +new text 000 0
> +new text 100 100 Testing...
> +new text 200 200 Testing...
> +Testing... 600 600
> +INSERT INTO tt_4 VALUES ("new text -2", -2, '');
> +SELECT * FROM nt_4;
> +a b c
> +new text 300 300
> +new text 400 400 Testing...
> +new text 500 500 Testing...
> +INSERT INTO nt_4 VALUES ("new text -1", -1, ''), ("new text -2", -2, '');
> +ERROR 23000: Duplicate entry '-2' for key 'PRIMARY'
> +SELECT * FROM nt_4;
> +a b c
> +new text 300 300
> +new text 400 400 Testing...
> +new text 500 500 Testing...
> +new text -1 -1
> +show binlog events from <binlog_start>;
> +Log_name Pos Event_type Server_id End_log_pos Info
> +master-bin.000001 # Query # # use `test`; INSERT INTO nt_3 VALUES ("new text -2",
> -2, '')
> +master-bin.000001 # Query # # BEGIN
> +master-bin.000001 # Query # # use `test`; INSERT INTO tt_3 VALUES ("new text -1",
> -1, ''), ("new text -2", -2, '')
> +master-bin.000001 # Query # # ROLLBACK
> +master-bin.000001 # Query # # BEGIN
> +master-bin.000001 # Query # # use `test`; INSERT INTO tt_4 VALUES ("new text -2",
> -2, '')
> +master-bin.000001 # Xid # # COMMIT /* XID */
> +master-bin.000001 # Query # # use `test`; INSERT INTO nt_4 VALUES ("new text -1",
> -1, ''), ("new text -2", -2, '')
> +
> +
> +
> +
> +#
> +#6.a) "B N N T C" generates in binglog the "N N B T C" entries.
> +#
> +BEGIN;
> +INSERT INTO nt_1 VALUES ("new text 10", 10, "new text 10");
> +INSERT INTO nt_2 VALUES ("new text 10", 10, "new text 10");
> +INSERT INTO tt_1 VALUES ("new text 10", 10, "new text 10");
> +COMMIT;
> +show binlog events from <binlog_start>;
> +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, "new text 10")
> +master-bin.000001 # Query # # use `test`; INSERT INTO nt_2 VALUES ("new text 10",
> 10, "new text 10")
> +master-bin.000001 # Query # # BEGIN
> +master-bin.000001 # Query # # use `test`; INSERT INTO tt_1 VALUES ("new text 10",
> 10, "new text 10")
> +master-bin.000001 # Xid # # COMMIT /* XID */
> +
> +
> +
> +
> +#
> +#6.b) "B N N T R" generates in binlog the "N N B T R" entries.
> +#
> +BEGIN;
> +INSERT INTO nt_1 VALUES ("new text 11", 11, "new text 11");
> +INSERT INTO nt_2 VALUES ("new text 11", 11, "new text 11");
> +INSERT INTO tt_1 VALUES ("new text 11", 11, "new text 11");
> +ROLLBACK;
> +Warnings:
> +Warning 1196 Some non-transactional changed tables couldn't be rolled back
> +show binlog events from <binlog_start>;
> +Log_name Pos Event_type Server_id End_log_pos Info
> +master-bin.000001 # Query # # use `test`; INSERT INTO nt_1 VALUES ("new text 11",
> 11, "new text 11")
> +master-bin.000001 # Query # # use `test`; INSERT INTO nt_2 VALUES ("new text 11",
> 11, "new text 11")
> +master-bin.000001 # Query # # BEGIN
> +master-bin.000001 # Query # # use `test`; INSERT INTO tt_1 VALUES ("new text 11",
> 11, "new text 11")
> +master-bin.000001 # Query # # ROLLBACK
> +
> +
> +
> +
> +#
> +#7.a) "B N N C" generates in binglog the "N N" entries.
> +#
> +BEGIN;
> +INSERT INTO nt_1 VALUES ("new text 12", 12, "new text 12");
> +INSERT INTO nt_2 VALUES ("new text 12", 12, "new text 12");
> +COMMIT;
> +show binlog events from <binlog_start>;
> +Log_name Pos Event_type Server_id End_log_pos Info
> +master-bin.000001 # Query # # use `test`; INSERT INTO nt_1 VALUES ("new text 12",
> 12, "new text 12")
> +master-bin.000001 # Query # # use `test`; INSERT INTO nt_2 VALUES ("new text 12",
> 12, "new text 12")
> +
> +
> +
> +
> +#
> +#7.b) "B N N R" generates in binlog the "N N" entries.
> +#
> +BEGIN;
> +INSERT INTO nt_1 VALUES ("new text 13", 13, "new text 13");
> +INSERT INTO nt_2 VALUES ("new text 13", 13, "new text 13");
> +ROLLBACK;
> +Warnings:
> +Warning 1196 Some non-transactional changed tables couldn't be rolled back
> +show binlog events from <binlog_start>;
> +Log_name Pos Event_type Server_id End_log_pos Info
> +master-bin.000001 # Query # # use `test`; INSERT INTO nt_1 VALUES ("new text 13",
> 13, "new text 13")
> +master-bin.000001 # Query # # use `test`; INSERT INTO nt_2 VALUES ("new text 13",
> 13, "new text 13")
> +
> +
> +
> +
> +#
> +#8.a) "B M T C" generates in the binlog the "B M T C" entries.
> +#
> +DELETE FROM nt_1;
> +BEGIN;
> +INSERT INTO nt_1 SELECT * FROM tt_1;
> +INSERT INTO tt_2 VALUES ("new text 14", 14, "new text 14");
> +COMMIT;
> +DELETE FROM tt_1;
> +BEGIN;
> +INSERT INTO tt_1 SELECT * FROM nt_1;
> +INSERT INTO tt_2 VALUES ("new text 15", 15, "new text 15");
> +COMMIT;
> +BEGIN;
> +INSERT INTO tt_3 VALUES ("new text 700", 700, '');
> +INSERT INTO tt_1 VALUES ("new text 800", 800, '');
> +COMMIT;
> +BEGIN;
> +INSERT INTO tt_3 VALUES("new text 900", 900, f1());
> +INSERT INTO tt_1 VALUES ("new text 1000", 1000, '');
> +COMMIT;
> +BEGIN;
> +INSERT INTO tt_3 VALUES(1100, 1100, f2());
> +INSERT INTO tt_1 VALUES ("new text 1200", 1200, '');
> +COMMIT;
> +BEGIN;
> +INSERT INTO nt_4 VALUES ("new text 1300", 1300, '');
> +INSERT INTO tt_1 VALUES ("new text 1400", 1400, '');
> +COMMIT;
> +BEGIN;
> +INSERT INTO nt_4 VALUES("new text 1500", 1500, f1());
> +INSERT INTO tt_1 VALUES ("new text 1600", 1600, '');
> +COMMIT;
> +BEGIN;
> +INSERT INTO nt_4 VALUES("new text 1700", 1700, f2());
> +INSERT INTO tt_1 VALUES ("new text 1800", 1800, '');
> +COMMIT;
> +BEGIN;
> +CALL pc_i_tt_3(1900, "Testing...");
> +INSERT INTO tt_1 VALUES ("new text 2000", 2000, '');
> +COMMIT;
> +BEGIN;
> +UPDATE nt_3, nt_4, tt_3, tt_4 SET nt_3.a= "new text 5", nt_4.a= "new text 5",
> tt_3.a= "new text 5", tt_4.a= "new text 5" where nt_3.b = nt_4.b and nt_4.b = tt_3.b and
> tt_3.b = tt_4.b and tt_4.b = 100;
> +INSERT INTO tt_1 VALUES ("new text 2100", 2100, '');
> +COMMIT;
> +BEGIN;
> +UPDATE tt_3, tt_4, nt_3, nt_4 SET tt_3.a= "new text 6", tt_4.a= "new text 6",
> nt_3.a= "new text 6", nt_4.a = "new text 6" where nt_3.b = nt_4.b and nt_4.b = tt_3.b and
> tt_3.b = tt_4.b and tt_4.b = 100;
> +INSERT INTO tt_1 VALUES ("new text 2200", 2200, '');
> +COMMIT;
> +BEGIN;
> +UPDATE tt_3, nt_3, nt_4, tt_4 SET tt_3.a= "new text 7", nt_3.a= "new text 7",
> nt_4.a= "new text 7", tt_4.a = "new text 7" where nt_3.b = nt_4.b and nt_4.b = tt_3.b and
> tt_3.b = tt_4.b and tt_4.b = 100;
> +INSERT INTO tt_1 VALUES ("new text 2300", 2300, '');
> +COMMIT;
> +BEGIN;
> +UPDATE tt_3, nt_3, nt_4, tt_4 SET tt_3.a= "new text 8", nt_3.a= "new text 8",
> nt_4.a= "new text 8", tt_4.a = "new text 8" where nt_3.b = nt_4.b and nt_4.b = tt_3.b and
> tt_3.b = tt_4.b and tt_4.b = 100;
> +INSERT INTO tt_1 VALUES ("new text 2400", 2400, '');
> +COMMIT;
> +show binlog events from <binlog_start>;
> +Log_name Pos Event_type Server_id End_log_pos Info
> +master-bin.000001 # Query # # use `test`; DELETE FROM nt_1
> +master-bin.000001 # Query # # use `test`; INSERT INTO nt_1 SELECT * FROM tt_1
> +master-bin.000001 # Query # # BEGIN
> +master-bin.000001 # Query # # use `test`; INSERT INTO tt_2 VALUES ("new text 14",
> 14, "new text 14")
> +master-bin.000001 # Xid # # COMMIT /* XID */
> +master-bin.000001 # Query # # BEGIN
> +master-bin.000001 # Query # # use `test`; DELETE FROM tt_1
> +master-bin.000001 # Xid # # COMMIT /* XID */
> +master-bin.000001 # Query # # BEGIN
> +master-bin.000001 # Query # # use `test`; INSERT INTO tt_1 SELECT * FROM nt_1
> +master-bin.000001 # Query # # use `test`; INSERT INTO tt_2 VALUES ("new text 15",
> 15, "new text 15")
> +master-bin.000001 # Xid # # COMMIT /* XID */
> +master-bin.000001 # Query # # BEGIN
> +master-bin.000001 # Query # # use `test`; INSERT INTO tt_3 VALUES ("new text 700",
> 700, '')
> +master-bin.000001 # Query # # use `test`; INSERT INTO tt_1 VALUES ("new text 800",
> 800, '')
> +master-bin.000001 # Xid # # COMMIT /* XID */
> +master-bin.000001 # Query # # BEGIN
> +master-bin.000001 # Query # # use `test`; INSERT INTO tt_3 VALUES("new text 900",
> 900, f1())
> +master-bin.000001 # Query # # use `test`; INSERT INTO tt_1 VALUES ("new text 1000",
> 1000, '')
> +master-bin.000001 # Xid # # COMMIT /* XID */
> +master-bin.000001 # Query # # BEGIN
> +master-bin.000001 # Query # # use `test`; INSERT INTO tt_3 VALUES(1100, 1100, f2())
> +master-bin.000001 # Query # # use `test`; INSERT INTO tt_1 VALUES ("new text 1200",
> 1200, '')
> +master-bin.000001 # Xid # # COMMIT /* XID */
> +master-bin.000001 # Query # # use `test`; INSERT INTO nt_4 VALUES ("new text 1300",
> 1300, '')
> +master-bin.000001 # Query # # BEGIN
> +master-bin.000001 # Query # # use `test`; INSERT INTO tt_1 VALUES ("new text 1400",
> 1400, '')
> +master-bin.000001 # Xid # # COMMIT /* XID */
> +master-bin.000001 # Query # # use `test`; INSERT INTO nt_4 VALUES("new text 1500",
> 1500, f1())
> +master-bin.000001 # Query # # BEGIN
> +master-bin.000001 # Query # # use `test`; INSERT INTO tt_1 VALUES ("new text 1600",
> 1600, '')
> +master-bin.000001 # Xid # # COMMIT /* XID */
> +master-bin.000001 # Query # # use `test`; INSERT INTO nt_4 VALUES("new text 1700",
> 1700, f2())
> +master-bin.000001 # Query # # BEGIN
> +master-bin.000001 # Query # # use `test`; INSERT INTO tt_1 VALUES ("new text 1800",
> 1800, '')
> +master-bin.000001 # Xid # # COMMIT /* XID */
> +master-bin.000001 # Query # # BEGIN
> +master-bin.000001 # Query # # use `test`; INSERT INTO tt_3 VALUES (
> NAME_CONST('y',_latin1'Testing...' COLLATE 'latin1_swedish_ci'), NAME_CONST('x',1900),
> NAME_CONST('x',1900))
> +master-bin.000001 # Query # # use `test`; INSERT INTO tt_1 VALUES ("new text 2000",
> 2000, '')
> +master-bin.000001 # Xid # # COMMIT /* XID */
> +master-bin.000001 # Query # # use `test`; UPDATE nt_3, nt_4, tt_3, tt_4 SET nt_3.a=
> "new text 5", nt_4.a= "new text 5", tt_3.a= "new text 5", tt_4.a= "new text 5" where
> nt_3.b = nt_4.b and nt_4.b = tt_3.b and tt_3.b = tt_4.b and tt_4.b = 100
> +master-bin.000001 # Query # # BEGIN
> +master-bin.000001 # Query # # use `test`; INSERT INTO tt_1 VALUES ("new text 2100",
> 2100, '')
> +master-bin.000001 # Xid # # COMMIT /* XID */
> +master-bin.000001 # Query # # use `test`; UPDATE tt_3, tt_4, nt_3, nt_4 SET tt_3.a=
> "new text 6", tt_4.a= "new text 6", nt_3.a= "new text 6", nt_4.a = "new text 6" where
> nt_3.b = nt_4.b and nt_4.b = tt_3.b and tt_3.b = tt_4.b and tt_4.b = 100
> +master-bin.000001 # Query # # BEGIN
> +master-bin.000001 # Query # # use `test`; INSERT INTO tt_1 VALUES ("new text 2200",
> 2200, '')
> +master-bin.000001 # Xid # # COMMIT /* XID */
> +master-bin.000001 # Query # # use `test`; UPDATE tt_3, nt_3, nt_4, tt_4 SET tt_3.a=
> "new text 7", nt_3.a= "new text 7", nt_4.a= "new text 7", tt_4.a = "new text 7" where
> nt_3.b = nt_4.b and nt_4.b = tt_3.b and tt_3.b = tt_4.b and tt_4.b = 100
> +master-bin.000001 # Query # # BEGIN
> +master-bin.000001 # Query # # use `test`; INSERT INTO tt_1 VALUES ("new text 2300",
> 2300, '')
> +master-bin.000001 # Xid # # COMMIT /* XID */
> +master-bin.000001 # Query # # use `test`; UPDATE tt_3, nt_3, nt_4, tt_4 SET tt_3.a=
> "new text 8", nt_3.a= "new text 8", nt_4.a= "new text 8", tt_4.a = "new text 8" where
> nt_3.b = nt_4.b and nt_4.b = tt_3.b and tt_3.b = tt_4.b and tt_4.b = 100
> +master-bin.000001 # Query # # BEGIN
> +master-bin.000001 # Query # # use `test`; INSERT INTO tt_1 VALUES ("new text 2400",
> 2400, '')
> +master-bin.000001 # Xid # # COMMIT /* XID */
> +
> +
> +
> +
> +# C - T C - S(N) T(T) C - S(N) T(T)
> +#8.b) B M T R F - R F - D(N) I(T) F - D(N) I(T)
> +#
> +DELETE FROM nt_1;
> +BEGIN;
> +INSERT INTO nt_1 SELECT * FROM tt_1;
> +INSERT INTO tt_2 VALUES ("new text 17", 17, "new text 17");
> +ROLLBACK;
> +Warnings:
> +Warning 1196 Some non-transactional changed tables couldn't be rolled back
> +DELETE FROM tt_1;
> +BEGIN;
> +INSERT INTO tt_1 SELECT * FROM nt_1;
> +INSERT INTO tt_2 VALUES ("new text 18", 18, "new text 18");
> +ROLLBACK;
> +INSERT INTO tt_1 SELECT * FROM nt_1;
> +BEGIN;
> +INSERT INTO tt_3 VALUES ("new text 2500", 2500, '');
> +INSERT INTO tt_1 VALUES ("new text 2600", 2600, '');
> +ROLLBACK;
> +Warnings:
> +Warning 1196 Some non-transactional changed tables couldn't be rolled back
> +BEGIN;
> +INSERT INTO tt_3 VALUES("new text 2700", 2700, f1());
> +INSERT INTO tt_1 VALUES ("new text 2800", 2800, '');
> +ROLLBACK;
> +Warnings:
> +Warning 1196 Some non-transactional changed tables couldn't be rolled back
> +BEGIN;
> +INSERT INTO tt_3 VALUES(2900, 2900, f2());
> +INSERT INTO tt_1 VALUES ("new text 3000", 3000, '');
> +ROLLBACK;
> +Warnings:
> +Warning 1196 Some non-transactional changed tables couldn't be rolled back
> +BEGIN;
> +INSERT INTO nt_4 VALUES ("new text 3100", 3100, '');
> +INSERT INTO tt_1 VALUES ("new text 3200", 3200, '');
> +ROLLBACK;
> +Warnings:
> +Warning 1196 Some non-transactional changed tables couldn't be rolled back
> +BEGIN;
> +INSERT INTO nt_4 VALUES("new text 3300", 3300, f1());
> +INSERT INTO tt_1 VALUES ("new text 3400", 3400, '');
> +ROLLBACK;
> +Warnings:
> +Warning 1196 Some non-transactional changed tables couldn't be rolled back
> +BEGIN;
> +INSERT INTO nt_4 VALUES("new text 3500", 3500, f2());
> +INSERT INTO tt_1 VALUES ("new text 3600", 3600, '');
> +ROLLBACK;
> +Warnings:
> +Warning 1196 Some non-transactional changed tables couldn't be rolled back
> +BEGIN;
> +CALL pc_i_tt_3(3700, "Testing...");
> +INSERT INTO tt_1 VALUES ("new text 3700", 3700, '');
> +ROLLBACK;
> +Warnings:
> +Warning 1196 Some non-transactional changed tables couldn't be rolled back
> +BEGIN;
> +UPDATE nt_3, nt_4, tt_3, tt_4 SET nt_3.a= "new text 9", nt_4.a= "new text 9",
> tt_3.a= "new text 9", tt_4.a= "new text 9" where nt_3.b = nt_4.b and nt_4.b = tt_3.b and
> tt_3.b = tt_4.b and tt_4.b = 100;
> +INSERT INTO tt_1 VALUES ("new text 3800", 3800, '');
> +ROLLBACK;
> +BEGIN;
> +UPDATE tt_3, tt_4, nt_3, nt_4 SET tt_3.a= "new text 10", tt_4.a= "new text 10",
> nt_3.a= "new text 10", nt_4.a = "new text 10" where nt_3.b = nt_4.b and nt_4.b = tt_3.b
> and tt_3.b = tt_4.b and tt_4.b = 100;
> +INSERT INTO tt_1 VALUES ("new text 3900", 3900, '');
> +ROLLBACK;
> +BEGIN;
> +UPDATE tt_3, nt_3, nt_4, tt_4 SET tt_3.a= "new text 11", nt_3.a= "new text 11",
> nt_4.a= "new text 11", tt_4.a = "new text 11" where nt_3.b = nt_4.b and nt_4.b = tt_3.b
> and tt_3.b = tt_4.b and tt_4.b = 100;
> +INSERT INTO tt_1 VALUES ("new text 4000", 4000, '');
> +ROLLBACK;
> +BEGIN;
> +UPDATE tt_3, nt_3, nt_4, tt_4 SET tt_3.a= "new text 12", nt_3.a= "new text 12",
> nt_4.a= "new text 12", tt_4.a = "new text 12" where nt_3.b = nt_4.b and nt_4.b = tt_3.b
> and tt_3.b = tt_4.b and tt_4.b = 100;
> +INSERT INTO tt_1 VALUES ("new text 4100", 4100, '');
> +ROLLBACK;
> +show binlog events from <binlog_start>;
> +Log_name Pos Event_type Server_id End_log_pos Info
> +master-bin.000001 # Query # # use `test`; DELETE FROM nt_1
> +master-bin.000001 # Query # # use `test`; INSERT INTO nt_1 SELECT * FROM tt_1
> +master-bin.000001 # Query # # BEGIN
> +master-bin.000001 # Query # # use `test`; INSERT INTO tt_2 VALUES ("new text 17",
> 17, "new text 17")
> +master-bin.000001 # Query # # ROLLBACK
> +master-bin.000001 # Query # # BEGIN
> +master-bin.000001 # Query # # use `test`; DELETE FROM tt_1
> +master-bin.000001 # Xid # # COMMIT /* XID */
> +master-bin.000001 # Query # # BEGIN
> +master-bin.000001 # Query # # use `test`; INSERT INTO tt_1 SELECT * FROM nt_1
> +master-bin.000001 # Xid # # COMMIT /* XID */
> +master-bin.000001 # Query # # BEGIN
> +master-bin.000001 # Query # # use `test`; INSERT INTO tt_3 VALUES ("new text 2500",
> 2500, '')
> +master-bin.000001 # Query # # use `test`; INSERT INTO tt_1 VALUES ("new text 2600",
> 2600, '')
> +master-bin.000001 # Query # # ROLLBACK
> +master-bin.000001 # Query # # BEGIN
> +master-bin.000001 # Query # # use `test`; INSERT INTO tt_3 VALUES("new text 2700",
> 2700, f1())
> +master-bin.000001 # Query # # use `test`; INSERT INTO tt_1 VALUES ("new text 2800",
> 2800, '')
> +master-bin.000001 # Query # # ROLLBACK
> +master-bin.000001 # Query # # BEGIN
> +master-bin.000001 # Query # # use `test`; INSERT INTO tt_3 VALUES(2900, 2900, f2())
> +master-bin.000001 # Query # # use `test`; INSERT INTO tt_1 VALUES ("new text 3000",
> 3000, '')
> +master-bin.000001 # Query # # ROLLBACK
> +master-bin.000001 # Query # # use `test`; INSERT INTO nt_4 VALUES ("new text 3100",
> 3100, '')
> +master-bin.000001 # Query # # BEGIN
> +master-bin.000001 # Query # # use `test`; INSERT INTO tt_1 VALUES ("new text 3200",
> 3200, '')
> +master-bin.000001 # Query # # ROLLBACK
> +master-bin.000001 # Query # # use `test`; INSERT INTO nt_4 VALUES("new text 3300",
> 3300, f1())
> +master-bin.000001 # Query # # BEGIN
> +master-bin.000001 # Query # # use `test`; INSERT INTO tt_1 VALUES ("new text 3400",
> 3400, '')
> +master-bin.000001 # Query # # ROLLBACK
> +master-bin.000001 # Query # # use `test`; INSERT INTO nt_4 VALUES("new text 3500",
> 3500, f2())
> +master-bin.000001 # Query # # BEGIN
> +master-bin.000001 # Query # # use `test`; INSERT INTO tt_1 VALUES ("new text 3600",
> 3600, '')
> +master-bin.000001 # Query # # ROLLBACK
> +master-bin.000001 # Query # # BEGIN
> +master-bin.000001 # Query # # use `test`; INSERT INTO tt_3 VALUES (
> NAME_CONST('y',_latin1'Testing...' COLLATE 'latin1_swedish_ci'), NAME_CONST('x',3700),
> NAME_CONST('x',3700))
> +master-bin.000001 # Query # # use `test`; INSERT INTO tt_1 VALUES ("new text 3700",
> 3700, '')
> +master-bin.000001 # Query # # ROLLBACK
> +master-bin.000001 # Query # # use `test`; UPDATE nt_3, nt_4, tt_3, tt_4 SET nt_3.a=
> "new text 9", nt_4.a= "new text 9", tt_3.a= "new text 9", tt_4.a= "new text 9" where
> nt_3.b = nt_4.b and nt_4.b = tt_3.b and tt_3.b = tt_4.b and tt_4.b = 100
> +master-bin.000001 # Query # # use `test`; UPDATE tt_3, tt_4, nt_3, nt_4 SET tt_3.a=
> "new text 10", tt_4.a= "new text 10", nt_3.a= "new text 10", nt_4.a = "new text 10" where
> nt_3.b = nt_4.b and nt_4.b = tt_3.b and tt_3.b = tt_4.b and tt_4.b = 100
> +master-bin.000001 # Query # # use `test`; UPDATE tt_3, nt_3, nt_4, tt_4 SET tt_3.a=
> "new text 11", nt_3.a= "new text 11", nt_4.a= "new text 11", tt_4.a = "new text 11" where
> nt_3.b = nt_4.b and nt_4.b = tt_3.b and tt_3.b = tt_4.b and tt_4.b = 100
> +master-bin.000001 # Query # # use `test`; UPDATE tt_3, nt_3, nt_4, tt_4 SET tt_3.a=
> "new text 12", nt_3.a= "new text 12", nt_4.a= "new text 12", tt_4.a = "new text 12" where
> nt_3.b = nt_4.b and nt_4.b = tt_3.b and tt_3.b = tt_4.b and tt_4.b = 100
> +###################################################################################
> +# CLEAN
> +###################################################################################
> +DROP TABLE tt_1;
> +DROP TABLE tt_2;
> +DROP TABLE tt_3;
> +DROP TABLE tt_4;
> +DROP TABLE nt_1;
> +DROP TABLE nt_2;
> +DROP TABLE nt_3;
> +DROP TABLE nt_4;
> +DROP PROCEDURE pc_i_tt_3;
> +DROP FUNCTION f1;
> +DROP FUNCTION f2;
>
> === added file 'mysql-test/suite/rpl/t/rpl_mixing_stmt_engines.test'
> --- a/mysql-test/suite/rpl/t/rpl_mixing_stmt_engines.test 1970-01-01 00:00:00 +0000
> +++ b/mysql-test/suite/rpl/t/rpl_mixing_stmt_engines.test 2009-07-08 08:29:34 +0000
> @@ -0,0 +1,5 @@
> +--source include/have_binlog_format_statement.inc
> +--source include/master-slave.inc
> +--source include/have_innodb.inc
> +
> +--source suite/rpl/include/rpl_mixed_engines.inc
>
> === modified file 'sql/ha_ndbcluster_binlog.cc'
> --- a/sql/ha_ndbcluster_binlog.cc 2009-06-19 08:24:43 +0000
> +++ b/sql/ha_ndbcluster_binlog.cc 2009-07-08 08:29:34 +0000
> @@ -256,7 +256,8 @@ static void run_query(THD *thd, char *bu
> thd->query_length= end - buf;
> thd->query= buf;
> thd->variables.pseudo_thread_id= thread_id;
> - thd->transaction.stmt.modified_non_trans_table= FALSE;
> + thd->transaction.stmt.modified_non_trans_table=
> + thd->transaction.stmt.modified_trans_table= FALSE;
> if (disable_binlog)
> thd->options&= ~OPTION_BIN_LOG;
>
>
> === modified file 'sql/handler.h'
> --- a/sql/handler.h 2009-05-04 10:00:15 +0000
> +++ b/sql/handler.h 2009-07-08 08:29:34 +0000
> @@ -761,8 +761,23 @@ struct THD_TRANS
> saved value.
> */
> bool modified_non_trans_table;
> -
> - void reset() { no_2pc= FALSE; modified_non_trans_table= FALSE; }
> + /*
> + The purpose of this flag is to keep track of transactional tables that were
> + modified in scope of:
> + - transaction, when the variable is a member of THD::transaction.all
> + - top-level statement or sub-statement, when the variable is a member of
> + THD::transaction.stmt
> +
> + The flag has the same life cyle as the modified_non_trans_table.
> + */
> + bool modified_trans_table;
> +
> + void reset()
> + {
> + no_2pc= FALSE;
> + modified_non_trans_table= FALSE;
> + modified_trans_table= FALSE;
> + }
> };
>
>
>
> === modified file 'sql/log.cc'
> --- a/sql/log.cc 2009-06-19 08:24:43 +0000
> +++ b/sql/log.cc 2009-07-08 08:29:34 +0000
> @@ -4044,7 +4044,8 @@ bool MYSQL_BIN_LOG::write(Log_event *eve
> (binlog_trx_data*) thd_get_ha_data(thd, binlog_hton);
> IO_CACHE *trans_log= &trx_data->trans_log;
> my_off_t trans_log_pos= my_b_tell(trans_log);
> - if (event_info->get_cache_stmt() || trans_log_pos != 0)
> + if (event_info->get_cache_stmt() ||
> + trans_log_pos != 0 || thd->transaction.all.modified_trans_table)
> {
> DBUG_PRINT("info", ("Using trans_log: cache: %d, trans_log_pos: %lu",
> event_info->get_cache_stmt(),
>
> === modified file 'sql/log_event.cc'
> --- a/sql/log_event.cc 2009-06-18 17:58:56 +0000
> +++ b/sql/log_event.cc 2009-07-08 08:29:34 +0000
> @@ -7185,7 +7185,8 @@ int Rows_log_event::do_apply_event(Relay
> has not yet modified anything. Note, all.modified is reset
> by mysql_reset_thd_for_next_command.
> */
> - thd->transaction.stmt.modified_non_trans_table= FALSE;
> + thd->transaction.stmt.modified_non_trans_table=
> + thd->transaction.stmt.modified_trans_table= FALSE;
> /*
> Check if the slave is set to use SBR. If so, it should switch
> to using RBR until the end of the "statement", i.e., next
>
> === modified file 'sql/set_var.cc'
> --- a/sql/set_var.cc 2009-06-19 09:29:21 +0000
> +++ b/sql/set_var.cc 2009-07-08 08:29:34 +0000
> @@ -3065,14 +3065,16 @@ static bool set_option_autocommit(THD *t
> {
> /* We changed to auto_commit mode */
> thd->options&= ~(ulonglong) (OPTION_BEGIN | OPTION_KEEP_LOG);
> - thd->transaction.all.modified_non_trans_table= FALSE;
> + thd->transaction.all.modified_non_trans_table=
> + thd->transaction.all.modified_trans_table= FALSE;
> thd->server_status|= SERVER_STATUS_AUTOCOMMIT;
> if (ha_commit(thd))
> return 1;
> }
> else
> {
> - thd->transaction.all.modified_non_trans_table= FALSE;
> + thd->transaction.all.modified_non_trans_table=
> + thd->transaction.all.modified_trans_table= FALSE;
> thd->server_status&= ~SERVER_STATUS_AUTOCOMMIT;
> }
> }
>
> === modified file 'sql/sql_base.cc'
> --- a/sql/sql_base.cc 2009-06-19 08:24:43 +0000
> +++ b/sql/sql_base.cc 2009-07-08 08:29:34 +0000
> @@ -5102,7 +5102,10 @@ int decide_logging_format(THD *thd, TABL
> HA_BINLOG_ROW_CAPABLE | HA_BINLOG_STMT_CAPABLE;
>
> my_bool multi_engine= FALSE;
> - void* prev_ht= NULL;
> + my_bool mixed_engine= FALSE;
> + my_bool trans_engine= TRUE;
> + TABLE* prev_write_table= NULL;
> + TABLE* prev_access_table= NULL;
> for (TABLE_LIST *table= tables; table; table= table->next_global)
> {
> if (table->placeholder())
> @@ -5116,12 +5119,31 @@ int decide_logging_format(THD *thd, TABL
> table->table_name,
> FLAGSTR(flags, HA_BINLOG_STMT_CAPABLE),
> FLAGSTR(flags, HA_BINLOG_ROW_CAPABLE)));
> - if (prev_ht && prev_ht != table->table->file->ht)
> + if (prev_write_table && prev_write_table->file->ht !=
> table->table->file->ht)
> multi_engine= TRUE;
> - prev_ht= table->table->file->ht;
> + trans_engine= trans_engine &&
> table->table->file->has_transactions();
> + thd->transaction.stmt.modified_trans_table=
> + thd->transaction.stmt.modified_trans_table ||
> + table->table->file->has_transactions();
> + prev_write_table= table->table;
> flags_all_set &= flags;
> flags_some_set |= flags;
> }
> + if (prev_access_table && prev_access_table->file->ht !=
> table->table->file->ht)
> + mixed_engine= mixed_engine ||
> (prev_access_table->file->has_transactions() !=
> + table->table->file->has_transactions());
> + prev_access_table= table->table;
> + }
> + thd->transaction.all.modified_trans_table=
> + thd->transaction.all.modified_trans_table ||
> + thd->transaction.stmt.modified_trans_table;
> +
> + if (mixed_engine ||
> + (thd->transaction.all.modified_trans_table && !trans_engine))
> + {
> + /*
> + After WL#2687 we need to call thd->lex->set_stmt_unsafe();
> + */
> }
>
> DBUG_PRINT("info", ("flags_all_set: %s%s",
> @@ -5193,9 +5215,7 @@ int decide_logging_format(THD *thd, TABL
> */
> if (thd->lex->is_stmt_unsafe() ||
> (flags_all_set & HA_BINLOG_STMT_CAPABLE) == 0)
> - {
> thd->set_current_stmt_binlog_row_based_if_mixed();
> - }
> }
>
> return 0;
>
> === modified file 'sql/sql_class.cc'
> --- a/sql/sql_class.cc 2009-06-15 15:53:45 +0000
> +++ b/sql/sql_class.cc 2009-07-08 08:29:34 +0000
> @@ -786,7 +786,10 @@ void THD::init(void)
> else
> options &= ~OPTION_BIG_SELECTS;
>
> - transaction.all.modified_non_trans_table=
> transaction.stmt.modified_non_trans_table= FALSE;
> + transaction.all.modified_non_trans_table=
> + transaction.stmt.modified_non_trans_table=
> + transaction.all.modified_trans_table=
> + transaction.stmt.modified_trans_table= FALSE;
> open_options=ha_open_options;
> update_lock_default= (variables.low_priority_updates ?
> TL_WRITE_LOW_PRIORITY :
>
> === modified file 'sql/sql_delete.cc'
> --- a/sql/sql_delete.cc 2009-06-19 08:24:43 +0000
> +++ b/sql/sql_delete.cc 2009-07-08 08:29:34 +0000
> @@ -845,7 +845,7 @@ void multi_delete::abort()
> thd->query, thd->query_length,
> transactional_tables, FALSE, errcode);
> }
> - thd->transaction.all.modified_non_trans_table= true;
> + thd->transaction.all.modified_non_trans_table= TRUE;
> }
> DBUG_VOID_RETURN;
> }
>
> === modified file 'sql/sql_parse.cc'
> --- a/sql/sql_parse.cc 2009-06-17 14:56:44 +0000
> +++ b/sql/sql_parse.cc 2009-07-08 08:29:34 +0000
> @@ -125,7 +125,8 @@ static bool xa_trans_rollback(THD *thd)
> bool status= test(ha_rollback(thd));
>
> thd->options&= ~(ulong) OPTION_BEGIN;
> - thd->transaction.all.modified_non_trans_table= FALSE;
> + thd->transaction.all.modified_non_trans_table=
> + thd->transaction.all.modified_trans_table= FALSE;
> thd->server_status&= ~SERVER_STATUS_IN_TRANS;
> xid_cache_delete(&thd->transaction.xid_state);
> thd->transaction.xid_state.xa_state= XA_NOTR;
> @@ -172,7 +173,8 @@ bool end_active_trans(THD *thd)
> error=1;
> }
> thd->options&= ~(OPTION_BEGIN | OPTION_KEEP_LOG);
> - thd->transaction.all.modified_non_trans_table= FALSE;
> + thd->transaction.all.modified_non_trans_table=
> + thd->transaction.all.modified_trans_table= FALSE;
> DBUG_RETURN(error);
> }
>
> @@ -710,7 +712,8 @@ int end_trans(THD *thd, enum enum_mysql_
> thd->server_status&= ~SERVER_STATUS_IN_TRANS;
> res= ha_commit(thd);
> thd->options&= ~(OPTION_BEGIN | OPTION_KEEP_LOG);
> - thd->transaction.all.modified_non_trans_table= FALSE;
> + thd->transaction.all.modified_non_trans_table=
> + thd->transaction.all.modified_trans_table= FALSE;
> break;
> case COMMIT_RELEASE:
> do_release= 1; /* fall through */
> @@ -728,7 +731,8 @@ int end_trans(THD *thd, enum enum_mysql_
> if (ha_rollback(thd))
> res= -1;
> thd->options&= ~(OPTION_BEGIN | OPTION_KEEP_LOG);
> - thd->transaction.all.modified_non_trans_table= FALSE;
> + thd->transaction.all.modified_non_trans_table=
> + thd->transaction.all.modified_trans_table= FALSE;
> if (!res && (completion == ROLLBACK_AND_CHAIN))
> res= begin_trans(thd);
> break;
> @@ -4681,7 +4685,8 @@ create_sp_error:
> thd->transaction.xid_state.rm_error= 0;
> thd->transaction.xid_state.xid.set(thd->lex->xid);
> xid_cache_insert(&thd->transaction.xid_state);
> - thd->transaction.all.modified_non_trans_table= FALSE;
> + thd->transaction.all.modified_non_trans_table=
> + thd->transaction.all.modified_trans_table= FALSE;
> thd->options= ((thd->options & ~(OPTION_KEEP_LOG)) | OPTION_BEGIN);
> thd->server_status|= SERVER_STATUS_IN_TRANS;
> my_ok(thd);
> @@ -4789,7 +4794,8 @@ create_sp_error:
> break;
> }
> thd->options&= ~(OPTION_BEGIN | OPTION_KEEP_LOG);
> - thd->transaction.all.modified_non_trans_table= FALSE;
> + thd->transaction.all.modified_non_trans_table=
> + thd->transaction.all.modified_trans_table= FALSE;
> thd->server_status&= ~SERVER_STATUS_IN_TRANS;
> xid_cache_delete(&thd->transaction.xid_state);
> thd->transaction.xid_state.xa_state=XA_NOTR;
> @@ -5652,7 +5658,8 @@ void mysql_reset_thd_for_next_command(TH
> if (!(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)))
> {
> thd->options&= ~OPTION_KEEP_LOG;
> - thd->transaction.all.modified_non_trans_table= FALSE;
> + thd->transaction.all.modified_non_trans_table=
> + thd->transaction.all.modified_trans_table= FALSE;
> }
> DBUG_ASSERT(thd->security_ctx== &thd->main_security_ctx);
> thd->thread_specific_used= FALSE;
>
>