He Zhenxing wrote:
> Hi, Alfranio,
>
> I think the patch is OK, there are some minor comments in line.
>
> Alfranio Correia:
>
>> #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-09
>> 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.
>>
>>
>
> I think the above is a bit too much for this bug,
I don't agree with this. It is better to have a good test case that
addresses (or tries to) all possible combinations of statements.
> and it's not quite
> clear what changes introduced by this patch, so I'd suggest to make this
> more specific and clear on what the changes this patch does.
>
I agree.
Changed the comments to address your concerns.
>
>> 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
>>
>
> I'd suggest to name the test as 'rpl_stm_mixing_engines.test', to follow
> the convention we used for most of tests.
>
Done.
>
>> 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-09 14:34:25
> +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.
>> +#
>> +# 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.
>> +#
>> +# 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-09 14:34:25
> +0000
>> @@ -0,0 +1,589 @@
>> +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 # # BEGIN
>> +master-bin.000001 # Query # # use `test`; INSERT INTO nt_4 VALUES ("new text
> 300", 300, '')
>> +master-bin.000001 # Xid # # COMMIT /* XID */
>> +master-bin.000001 # Query # # BEGIN
>> +master-bin.000001 # Query # # use `test`; INSERT INTO nt_4 VALUES ("new text
> 400", 400, f1())
>> +master-bin.000001 # Xid # # COMMIT /* XID */
>> +master-bin.000001 # Query # # BEGIN
>> +master-bin.000001 # Query # # use `test`; INSERT INTO nt_4 VALUES ("new text
> 500", 500, f2())
>> +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',600),
> NAME_CONST('x',600))
>> +master-bin.000001 # Xid # # COMMIT /* XID */
>> +master-bin.000001 # Query # # BEGIN
>> +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 # # COMMIT
>> +master-bin.000001 # Query # # BEGIN
>> +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 # # COMMIT
>> +master-bin.000001 # Query # # BEGIN
>> +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 # # COMMIT
>> +master-bin.000001 # Query # # BEGIN
>> +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
>> +master-bin.000001 # Query # # COMMIT
>> +
>> +
>> +
>> +
>> +#
>> +#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 # # BEGIN
>> +master-bin.000001 # Query # # use `test`; INSERT INTO nt_4 VALUES ("new text
> -1", -1, ''), ("new text -2", -2, '')
>> +master-bin.000001 # Query # # ROLLBACK
>> +
>> +
>> +
>> +
>> +#
>> +#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 # # BEGIN
>> +master-bin.000001 # Query # # use `test`; INSERT INTO nt_4 VALUES ("new text
> 1300", 1300, '')
>> +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 # # BEGIN
>> +master-bin.000001 # Query # # use `test`; INSERT INTO nt_4 VALUES("new text
> 1500", 1500, f1())
>> +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 # # BEGIN
>> +master-bin.000001 # Query # # use `test`; INSERT INTO nt_4 VALUES("new text
> 1700", 1700, f2())
>> +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 # # BEGIN
>> +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 # # use `test`; INSERT INTO tt_1 VALUES ("new text
> 2100", 2100, '')
>> +master-bin.000001 # Xid # # COMMIT /* XID */
>> +master-bin.000001 # Query # # BEGIN
>> +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 # # use `test`; INSERT INTO tt_1 VALUES ("new text
> 2200", 2200, '')
>> +master-bin.000001 # Xid # # COMMIT /* XID */
>> +master-bin.000001 # Query # # BEGIN
>> +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 # # use `test`; INSERT INTO tt_1 VALUES ("new text
> 2300", 2300, '')
>> +master-bin.000001 # Xid # # COMMIT /* XID */
>> +master-bin.000001 # Query # # BEGIN
>> +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 # # 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 # # BEGIN
>> +master-bin.000001 # Query # # use `test`; INSERT INTO nt_4 VALUES ("new text
> 3100", 3100, '')
>> +master-bin.000001 # Query # # use `test`; INSERT INTO tt_1 VALUES ("new text
> 3200", 3200, '')
>> +master-bin.000001 # Query # # ROLLBACK
>> +master-bin.000001 # Query # # BEGIN
>> +master-bin.000001 # Query # # use `test`; INSERT INTO nt_4 VALUES("new text
> 3300", 3300, f1())
>> +master-bin.000001 # Query # # use `test`; INSERT INTO tt_1 VALUES ("new text
> 3400", 3400, '')
>> +master-bin.000001 # Query # # ROLLBACK
>> +master-bin.000001 # Query # # BEGIN
>> +master-bin.000001 # Query # # use `test`; INSERT INTO nt_4 VALUES("new text
> 3500", 3500, f2())
>> +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
>>
> +###################################################################################
>> +# 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-09 14:34:25
> +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-09 14:34:25 +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-09 14:34:25 +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-09 14:34:25 +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-09 14:34:25 +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-09 14:34:25 +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-09 14:34:25 +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();
>> + */
>> }
>>
>
> It's up to you, but I think since the above lines actually does nothing
> here, so I'd advice to remove the above lines and the code related to
> mixed_engine/trans_engine to reduce unnecessary codes.
>
>
>>
>> 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-09 14:34:25 +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-09 14:34:25 +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-09 14:34:25 +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;
>>
>>
>
>
>