Mats Kindahl wrote:
>
> He Zhenxing wrote:
> > Hi Mats
> >
> > I think the patch is good, approved!
> >
> > But I have some suggestions not strictly related to this bug, they are
> > related to the code handling binlog and transactions in general, I think
> > this part of the code is not working as expected, BUG#40221, and this
> > bug are all related to this. And there might be other hidden bugs too. I
> > think we should make this part of code more consistent and simpler. And
> > I think your patch for this bug is one step of this goal.
> >
> > According to the comment for THD::binlog_start_trans_and_stmt, this
> > function should be called for all statments in a
> > transaction(AUTOCOMMIT=0 or BEGIN is seen), but actually this is not the
> > case. Mostly, this function is only called for the first statement of
> > the transaction. BUG#40221 reveals that this is not called for other
> > statements in RBR, and the truth is that this is not called for other
> > statements in SBR either, which also means that
> > THD::binlog_commit/THD::binlog_rollback is not called for each statement
> > in the transaction as expected. The reason is because in SBR, we only
> > call THD::binlog_start_trans_and_stmt when the transaction log is empty,
> > so the thd->transaction.stmt.ha_list will not be set. Although I don't
> > see any problems caused by this, but I think it is a problem if the code
> > is not working as we supposed.
> >
> > So here are some ideas:
> > 1. always log all events (transactional or non-transactional updates) to
> > the cache first to simplify the logic.
>
> I think this is already the case. If it isn't, we should fix that.
>
Currently, only all events in a transaction will be logged into cache
first, but statements not in a transaction that modifies
non-transactional tables will go directly into log file, I think we can
write this into the transaction cache at first too, and then flush to
log file. Of course, this can impact the performance.
> > 2. seperate THD::binlog_start_trans_and_stmt to two functions,
> > THD::binlog_start_transaction for transaction, and
> > THD::binlog_start_statement for statement. Allways call
> > THD::binlog_start_statement for each statement.
>
> I concur. It would be good if we could have a generic solution that does not
> request an explicit call for the binary log (thinking about separating
> replication code from main server here).
>
> However, I think this should be part of that effort (WL#3665) instead.
>
I agree that we can do this as part of the work of replication interface
and modulization.
> > 3. Add THD::binlog_end_transaction and THD::binlog_end_statement, these
> > are the counter parts of THD::binlog_start_transaction and
> > THD::binlog_start_statement. These functions will call
> > binlog_commit/rollback accordingly.
>
> Why? I see no problem in using the existing interface, which is the handlerton.
> We just need to extend it to support the "start" version as well.
>
Since we have a binlog_start_transaction/statement, we would expect
there are binlog_end_transaction/statement. And we are sure that
binlog_end_statement will be called after each statement. We can put the
code that should be called when transaction/statement ends no matter it
is committed or rolled back.
> Just my few cents,
> Mats Kindahl
>
> > Mats Kindahl wrote:
> >> #At file:///home/bzr/bugs/b40116-5.1-5.1.29-rc/
> >>
> >> 2776 Mats Kindahl 2008-12-03
> >> Bug #40116: Uncommited changes are replicated and stay on slave
> >> after rollback on master
> >>
> >> When starting a transaction with a statement containing changes
> >> to both transactional tables and non-transactional tables, the
> >> statement is considered as non-transactional and is therefore
> >> written directly to the binary log. This behaviour was present
> >> in 5.0, and has propagated to 5.1.
> >>
> >> If a trigger containing a change of a non-transactional table is
> >> added to a transactional table, any changes to the transactional
> >> table is "tainted" as non-transactional.
> >>
> >> This patch solves the problem by removing the existing "hack" that
> >> allows non-transactional statements appearing first in a transaction
> >> to be written directly to the binary log. Instead, anything inside
> >> a transaction is treaded as part of the transaction and not written
> >> to the binary log until the transaction is committed.
> >> modified:
> >> mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result
> >> mysql-test/suite/rpl/r/rpl_row_create_table.result
> >> mysql-test/suite/rpl/r/rpl_slave_skip.result
> >> mysql-test/suite/rpl/r/rpl_trigger.result
> >> mysql-test/suite/rpl/t/rpl_row_create_table.test
> >> mysql-test/suite/rpl/t/rpl_slave_skip.test
> >> mysql-test/suite/rpl/t/rpl_trigger.test
> >> sql/log.cc
> >>
> >> per-file messages:
> >> mysql-test/suite/rpl/t/rpl_row_create_table.test
> >> Removing positions from SHOW BINLOG EVENTS and using
> >> reset_master_and_slave to start on a fresh binary log each time.
> >> mysql-test/suite/rpl/t/rpl_slave_skip.test
> >> Adding explicit commit in AUTOCOMMIT=0 to make test work correctly.
> >> mysql-test/suite/rpl/t/rpl_trigger.test
> >> Adding test case for BUG#40116.
> >> sql/log.cc
> >> Changing commit logic in binlog_commit() to only commit when
> >> committing a real transaction or committing a punch transaction.
> >> === modified file
> 'mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result'
> >> ---
> a/mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result 2008-07-29 15:36:13 +0000
> >> +++
> b/mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result 2008-12-03 19:55:49 +0000
> >> @@ -133,10 +133,6 @@ master-bin.000001 # Query # # use `test`
> >> master-bin.000001 # Table_map # # table_id: # (test.t1)
> >> master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
> >> master-bin.000001 # Xid # # COMMIT /* XID */
> >> -master-bin.000001 # Query # # use `test`; BEGIN
> >> -master-bin.000001 # Table_map # # table_id: # (test.t2)
> >> -master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
> >> -master-bin.000001 # Query # # use `test`; COMMIT
> >> insert into t1 values(11);
> >> commit;
> >> show binlog events from <binlog_start>;
> >> @@ -148,8 +144,6 @@ master-bin.000001 # Xid # # COMMIT /* XI
> >> master-bin.000001 # Query # # use `test`; BEGIN
> >> master-bin.000001 # Table_map # # table_id: # (test.t2)
> >> master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
> >> -master-bin.000001 # Query # # use `test`; COMMIT
> >> -master-bin.000001 # Query # # use `test`; BEGIN
> >> master-bin.000001 # Table_map # # table_id: # (test.t1)
> >> master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
> >> master-bin.000001 # Xid # # COMMIT /* XID */
> >> @@ -278,10 +272,6 @@ master-bin.000001 # Query # # use `test`
> >> master-bin.000001 # Table_map # # table_id: # (test.t1)
> >> master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
> >> master-bin.000001 # Xid # # COMMIT /* XID */
> >> -master-bin.000001 # Query # # use `test`; BEGIN
> >> -master-bin.000001 # Table_map # # table_id: # (test.t2)
> >> -master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
> >> -master-bin.000001 # Query # # use `test`; COMMIT
> >> master-bin.000001 # Query # # use `test`; drop table t1,t2
> >> master-bin.000001 # Query # # use `test`; create table t0 (n int)
> >> master-bin.000001 # Query # # use `test`; BEGIN
> >> @@ -382,7 +372,7 @@ master-bin.000001 # Query # # use `test`
> >> master-bin.000001 # Query # # use `test`; BEGIN
> >> master-bin.000001 # Table_map # # table_id: # (test.t1)
> >> master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
> >> -master-bin.000001 # Query # # use `test`; COMMIT
> >> +master-bin.000001 # Query # # use `test`; ROLLBACK
> >> master-bin.000001 # Query # # use `test`; DROP TABLE IF EXISTS t2
> >> master-bin.000001 # Query # # use `test`; CREATE TABLE t2 (a int, b int,
> primary key (a)) engine=innodb
> >> master-bin.000001 # Query # # use `test`; BEGIN
> >> @@ -395,16 +385,16 @@ master-bin.000001 # Xid # # COMMIT /* XI
> >> master-bin.000001 # Query # # use `test`; BEGIN
> >> master-bin.000001 # Table_map # # table_id: # (test.t1)
> >> master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
> >> +master-bin.000001 # Table_map # # table_id: # (test.t2)
> >> +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
> >> master-bin.000001 # Query # # use `test`; COMMIT
> >> master-bin.000001 # Query # # use `test`; DROP TABLE t2
> >> master-bin.000001 # Query # # use `test`; BEGIN
> >> master-bin.000001 # Table_map # # table_id: # (test.t1)
> >> master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
> >> -master-bin.000001 # Query # # use `test`; COMMIT
> >> -master-bin.000001 # Query # # use `test`; BEGIN
> >> master-bin.000001 # Table_map # # table_id: # (test.t1)
> >> master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
> >> -master-bin.000001 # Query # # use `test`; COMMIT
> >> +master-bin.000001 # Query # # use `test`; ROLLBACK
> >> master-bin.000001 # Query # # use `test`; BEGIN
> >> master-bin.000001 # Table_map # # table_id: # (test.t1)
> >> master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
> >> @@ -412,7 +402,7 @@ master-bin.000001 # Query # # use `test`
> >> master-bin.000001 # Query # # use `test`; BEGIN
> >> master-bin.000001 # Table_map # # table_id: # (test.t1)
> >> master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
> >> -master-bin.000001 # Query # # use `test`; COMMIT
> >> +master-bin.000001 # Query # # use `test`; ROLLBACK
> >> master-bin.000001 # Query # # use `test`; BEGIN
> >> master-bin.000001 # Query # # use `test`; TRUNCATE table t2
> >> master-bin.000001 # Query # # use `test`; COMMIT
> >>
> >> === modified file 'mysql-test/suite/rpl/r/rpl_row_create_table.result'
> >> --- a/mysql-test/suite/rpl/r/rpl_row_create_table.result 2008-10-08 09:15:00
> +0000
> >> +++ b/mysql-test/suite/rpl/r/rpl_row_create_table.result 2008-12-03 19:55:49
> +0000
> >> @@ -4,34 +4,39 @@ reset master;
> >> reset slave;
> >> drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
> >> start slave;
> >> +**** Resetting master and slave ****
> >> +STOP SLAVE;
> >> +RESET SLAVE;
> >> +RESET MASTER;
> >> +START SLAVE;
> >> CREATE TABLE t1 (a INT, b INT);
> >> CREATE TABLE t2 (a INT, b INT) ENGINE=Merge;
> >> CREATE TABLE t3 (a INT, b INT) CHARSET=utf8;
> >> CREATE TABLE t4 (a INT, b INT) ENGINE=Merge CHARSET=utf8;
> >> -SHOW BINLOG EVENTS FROM 216;
> >> +SHOW BINLOG EVENTS FROM 106;
> >> Log_name #
> >> -Pos 216
> >> +Pos 106
> >> Event_type Query
> >> Server_id #
> >> -End_log_pos 309
> >> +End_log_pos 199
> >> Info use `test`; CREATE TABLE t1 (a INT, b INT)
> >> Log_name #
> >> -Pos 309
> >> +Pos 199
> >> Event_type Query
> >> Server_id #
> >> -End_log_pos 415
> >> +End_log_pos 305
> >> Info use `test`; CREATE TABLE t2 (a INT, b INT) ENGINE=Merge
> >> Log_name #
> >> -Pos 415
> >> +Pos 305
> >> Event_type Query
> >> Server_id #
> >> -End_log_pos 521
> >> +End_log_pos 411
> >> Info use `test`; CREATE TABLE t3 (a INT, b INT) CHARSET=utf8
> >> Log_name #
> >> -Pos 521
> >> +Pos 411
> >> Event_type Query
> >> Server_id #
> >> -End_log_pos 640
> >> +End_log_pos 530
> >> Info use `test`; CREATE TABLE t4 (a INT, b INT) ENGINE=Merge CHARSET=utf8
> >> **** On Master ****
> >> SHOW CREATE TABLE t1;
> >> @@ -125,9 +130,14 @@ NULL 3 6
> >> NULL 4 2
> >> NULL 5 10
> >> NULL 6 12
> >> +**** Resetting master and slave ****
> >> +STOP SLAVE;
> >> +RESET SLAVE;
> >> +RESET MASTER;
> >> +START SLAVE;
> >> CREATE TABLE t7 (UNIQUE(b)) SELECT a,b FROM tt3;
> >> ERROR 23000: Duplicate entry '2' for key 'b'
> >> -SHOW BINLOG EVENTS FROM 1374;
> >> +SHOW BINLOG EVENTS FROM 106;
> >> Log_name Pos Event_type Server_id End_log_pos Info
> >> CREATE TABLE t7 (a INT, b INT UNIQUE);
> >> INSERT INTO t7 SELECT a,b FROM tt3;
> >> @@ -137,18 +147,23 @@ a b
> >> 1 2
> >> 2 4
> >> 3 6
> >> -SHOW BINLOG EVENTS FROM 1374;
> >> +SHOW BINLOG EVENTS FROM 106;
> >> Log_name Pos Event_type Server_id End_log_pos Info
> >> -# 1374 Query # 1474 use `test`; CREATE TABLE t7 (a INT, b INT UNIQUE)
> >> -# 1474 Query # 1542 use `test`; BEGIN
> >> -# 1542 Table_map # 1584 table_id: # (test.t7)
> >> -# 1584 Write_rows # 1640 table_id: # flags: STMT_END_F
> >> -# 1640 Query # 1711 use `test`; ROLLBACK
> >> +# 106 Query # 206 use `test`; CREATE TABLE t7 (a INT, b INT UNIQUE)
> >> +# 206 Query # 274 use `test`; BEGIN
> >> +# 274 Table_map # 316 table_id: # (test.t7)
> >> +# 316 Write_rows # 372 table_id: # flags: STMT_END_F
> >> +# 372 Query # 443 use `test`; ROLLBACK
> >> SELECT * FROM t7 ORDER BY a,b;
> >> a b
> >> 1 2
> >> 2 4
> >> 3 6
> >> +**** Resetting master and slave ****
> >> +STOP SLAVE;
> >> +RESET SLAVE;
> >> +RESET MASTER;
> >> +START SLAVE;
> >> CREATE TEMPORARY TABLE tt4 (a INT, b INT);
> >> INSERT INTO tt4 VALUES (4,8), (5,10), (6,12);
> >> BEGIN;
> >> @@ -156,12 +171,12 @@ INSERT INTO t7 SELECT a,b FROM tt4;
> >> ROLLBACK;
> >> Warnings:
> >> Warning 1196 Some non-transactional changed tables couldn't be rolled back
> >> -SHOW BINLOG EVENTS FROM 1711;
> >> +SHOW BINLOG EVENTS FROM 106;
> >> Log_name Pos Event_type Server_id End_log_pos Info
> >> -# 1711 Query # 1779 use `test`; BEGIN
> >> -# 1779 Table_map # 1821 table_id: # (test.t7)
> >> -# 1821 Write_rows # 1877 table_id: # flags: STMT_END_F
> >> -# 1877 Query # 1946 use `test`; COMMIT
> >> +# 106 Query # 174 use `test`; BEGIN
> >> +# 174 Table_map # 216 table_id: # (test.t7)
> >> +# 216 Write_rows # 272 table_id: # flags: STMT_END_F
> >> +# 272 Query # 343 use `test`; ROLLBACK
> >> SELECT * FROM t7 ORDER BY a,b;
> >> a b
> >> 1 2
> >> @@ -178,6 +193,11 @@ a b
> >> 4 8
> >> 5 10
> >> 6 12
> >> +**** Resetting master and slave ****
> >> +STOP SLAVE;
> >> +RESET SLAVE;
> >> +RESET MASTER;
> >> +START SLAVE;
> >> CREATE TABLE t8 LIKE t4;
> >> CREATE TABLE t9 LIKE tt4;
> >> CREATE TEMPORARY TABLE tt5 LIKE t4;
> >> @@ -196,10 +216,10 @@ Create Table CREATE TABLE `t9` (
> >> `a` int(11) DEFAULT NULL,
> >> `b` int(11) DEFAULT NULL
> >> ) ENGINE=MyISAM DEFAULT CHARSET=latin1
> >> -SHOW BINLOG EVENTS FROM 1946;
> >> +SHOW BINLOG EVENTS FROM 106;
> >> Log_name Pos Event_type Server_id End_log_pos Info
> >> -# 1946 Query # 2032 use `test`; CREATE TABLE t8 LIKE t4
> >> -# 2032 Query # 2171 use `test`; CREATE TABLE `t9` (
> >> +# 106 Query # 192 use `test`; CREATE TABLE t8 LIKE t4
> >> +# 192 Query # 331 use `test`; CREATE TABLE `t9` (
> >> `a` int(11) DEFAULT NULL,
> >> `b` int(11) DEFAULT NULL
> >> )
> >> @@ -276,9 +296,8 @@ a
> >> 1
> >> 2
> >> 3
> >> -SHOW BINLOG EVENTS;
> >> +SHOW BINLOG EVENTS FROM 106;
> >> Log_name Pos Event_type Server_id End_log_pos Info
> >> -# 4 Format_desc # 106 Server ver: #, Binlog ver: #
> >> # 106 Query # 192 use `test`; CREATE TABLE t1 (a INT)
> >> # 192 Query # 260 use `test`; BEGIN
> >> # 260 Table_map # 301 table_id: # (test.t1)
> >> @@ -308,7 +327,7 @@ Log_name Pos Event_type Server_id End_lo
> >> # 1329 Query # 1397 use `test`; BEGIN
> >> # 1397 Table_map # 1438 table_id: # (test.t1)
> >> # 1438 Write_rows # 1482 table_id: # flags: STMT_END_F
> >> -# 1482 Query # 1551 use `test`; COMMIT
> >> +# 1482 Query # 1553 use `test`; ROLLBACK
> >> SHOW TABLES;
> >> Tables_in_test
> >> t1
> >> @@ -371,9 +390,8 @@ a
> >> 4
> >> 6
> >> 9
> >> -SHOW BINLOG EVENTS;
> >> +SHOW BINLOG EVENTS FROM 106;
> >> Log_name Pos Event_type Server_id End_log_pos Info
> >> -# 4 Format_desc # 106 Server ver: #, Binlog ver: #
> >> # 106 Query # 192 use `test`; CREATE TABLE t1 (a INT)
> >> # 192 Query # 260 use `test`; BEGIN
> >> # 260 Table_map # 301 table_id: # (test.t1)
> >> @@ -394,6 +412,11 @@ a
> >> 6
> >> 9
> >> TRUNCATE TABLE t2;
> >> +**** Resetting master and slave ****
> >> +STOP SLAVE;
> >> +RESET SLAVE;
> >> +RESET MASTER;
> >> +START SLAVE;
> >> BEGIN;
> >> INSERT INTO t2 SELECT a*a FROM t1;
> >> CREATE TEMPORARY TABLE tt2
> >> @@ -406,14 +429,14 @@ Warnings:
> >> Warning 1196 Some non-transactional changed tables couldn't be rolled back
> >> SELECT * FROM t2 ORDER BY a;
> >> a
> >> -SHOW BINLOG EVENTS FROM 949;
> >> +SHOW BINLOG EVENTS FROM 106;
> >> Log_name Pos Event_type Server_id End_log_pos Info
> >> -# 949 Query # 1017 use `test`; BEGIN
> >> -# 1017 Table_map # 1058 table_id: # (test.t2)
> >> -# 1058 Write_rows # 1102 table_id: # flags: STMT_END_F
> >> -# 1102 Table_map # 1143 table_id: # (test.t2)
> >> -# 1143 Write_rows # 1182 table_id: # flags: STMT_END_F
> >> -# 1182 Query # 1253 use `test`; ROLLBACK
> >> +# 106 Query # 174 use `test`; BEGIN
> >> +# 174 Table_map # 215 table_id: # (test.t2)
> >> +# 215 Write_rows # 259 table_id: # flags: STMT_END_F
> >> +# 259 Table_map # 300 table_id: # (test.t2)
> >> +# 300 Write_rows # 339 table_id: # flags: STMT_END_F
> >> +# 339 Query # 410 use `test`; ROLLBACK
> >> SELECT * FROM t2 ORDER BY a;
> >> a
> >> DROP TABLE t1,t2;
> >>
> >> === modified file 'mysql-test/suite/rpl/r/rpl_slave_skip.result'
> >> --- a/mysql-test/suite/rpl/r/rpl_slave_skip.result 2008-03-28 12:16:41
> +0000
> >> +++ b/mysql-test/suite/rpl/r/rpl_slave_skip.result 2008-12-03 19:55:49
> +0000
> >> @@ -174,6 +174,7 @@ DROP TRIGGER tr2;
> >> INSERT INTO t1 VALUES (3,'master/slave');
> >> INSERT INTO t2 VALUES (3,'master/slave');
> >> INSERT INTO t3 VALUES (3,'master/slave');
> >> +COMMIT;
> >> SELECT * FROM t1 ORDER BY a;
> >> a b
> >> 2 master only
> >>
> >> === modified file 'mysql-test/suite/rpl/r/rpl_trigger.result'
> >> --- a/mysql-test/suite/rpl/r/rpl_trigger.result 2007-12-18 09:07:08 +0000
> >> +++ b/mysql-test/suite/rpl/r/rpl_trigger.result 2008-12-03 19:55:49 +0000
> >> @@ -975,3 +975,29 @@ a b
> >> 2 b
> >> 3 c
> >> drop table t1;
> >> +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;
> >> +create table t1 ( f int ) engine = innodb;
> >> +create table log ( r int ) engine = myisam;
> >> +create trigger tr
> >> +after insert on t1
> >> +for each row insert into log values ( new.f );
> >> +set autocommit = 0;
> >> +insert into t1 values ( 1 );
> >> +select * from t1;
> >> +f
> >> +1
> >> +select * from t1;
> >> +f
> >> +rollback;
> >> +Warnings:
> >> +Warning 1196 Some non-transactional changed tables couldn't be rolled back
> >> +select * from t1;
> >> +f
> >> +select * from t1;
> >> +f
> >> +drop table t1, log;
> >>
> >> === modified file 'mysql-test/suite/rpl/t/rpl_row_create_table.test'
> >> --- a/mysql-test/suite/rpl/t/rpl_row_create_table.test 2008-10-08 09:15:00
> +0000
> >> +++ b/mysql-test/suite/rpl/t/rpl_row_create_table.test 2008-12-03 19:55:49
> +0000
> >> @@ -29,6 +29,8 @@ SET GLOBAL storage_engine=memory;
> >> START SLAVE;
> >> --enable_query_log
> >>
> >> +--source include/reset_master_and_slave.inc
> >> +
> >> connection master;
> >> CREATE TABLE t1 (a INT, b INT);
> >> CREATE TABLE t2 (a INT, b INT) ENGINE=Merge;
> >> @@ -36,7 +38,7 @@ CREATE TABLE t3 (a INT, b INT) CHARSET=u
> >> CREATE TABLE t4 (a INT, b INT) ENGINE=Merge CHARSET=utf8;
> >> --replace_column 1 # 4 #
> >> --replace_regex /\/\* xid=.* \*\//\/* XID *\// /table_id: [0-9]+/table_id:
> #/
> >> ---query_vertical SHOW BINLOG EVENTS FROM 216
> >> +--query_vertical SHOW BINLOG EVENTS FROM 106
> >> --echo **** On Master ****
> >> --query_vertical SHOW CREATE TABLE t1
> >> --query_vertical SHOW CREATE TABLE t2
> >> @@ -65,6 +67,8 @@ SELECT * FROM t5 ORDER BY a,b,c;
> >> --query_vertical SHOW CREATE TABLE t6
> >> SELECT * FROM t6 ORDER BY a,b,c;
> >>
> >> +--source include/reset_master_and_slave.inc
> >> +
> >> connection master;
> >> # Test for erroneous constructions
> >> --error ER_DUP_ENTRY
> >> @@ -72,7 +76,7 @@ CREATE TABLE t7 (UNIQUE(b)) SELECT a,b F
> >> # Shouldn't be written to the binary log
> >> --replace_column 1 # 4 #
> >> --replace_regex /\/\* xid=.* \*\//\/* XID *\// /table_id: [0-9]+/table_id:
> #/
> >> -SHOW BINLOG EVENTS FROM 1374;
> >> +SHOW BINLOG EVENTS FROM 106;
> >>
> >> # Test that INSERT-SELECT works the same way as for SBR.
> >> CREATE TABLE t7 (a INT, b INT UNIQUE);
> >> @@ -82,10 +86,12 @@ SELECT * FROM t7 ORDER BY a,b;
> >> # Should be written to the binary log
> >> --replace_column 1 # 4 #
> >> --replace_regex /\/\* xid=.* \*\//\/* XID *\// /table_id: [0-9]+/table_id:
> #/
> >> -SHOW BINLOG EVENTS FROM 1374;
> >> +SHOW BINLOG EVENTS FROM 106;
> >> sync_slave_with_master;
> >> SELECT * FROM t7 ORDER BY a,b;
> >>
> >> +--source include/reset_master_and_slave.inc
> >> +
> >> connection master;
> >> CREATE TEMPORARY TABLE tt4 (a INT, b INT);
> >> INSERT INTO tt4 VALUES (4,8), (5,10), (6,12);
> >> @@ -94,11 +100,13 @@ INSERT INTO t7 SELECT a,b FROM tt4;
> >> ROLLBACK;
> >> --replace_column 1 # 4 #
> >> --replace_regex /\/\* xid=.* \*\//\/* XID *\// /table_id: [0-9]+/table_id:
> #/
> >> -SHOW BINLOG EVENTS FROM 1711;
> >> +SHOW BINLOG EVENTS FROM 106;
> >> SELECT * FROM t7 ORDER BY a,b;
> >> sync_slave_with_master;
> >> SELECT * FROM t7 ORDER BY a,b;
> >>
> >> +--source include/reset_master_and_slave.inc
> >> +
> >> connection master;
> >> CREATE TABLE t8 LIKE t4;
> >> CREATE TABLE t9 LIKE tt4;
> >> @@ -110,7 +118,7 @@ CREATE TEMPORARY TABLE tt7 SELECT 1;
> >> --query_vertical SHOW CREATE TABLE t9
> >> --replace_column 1 # 4 #
> >> --replace_regex /\/\* xid=.* \*\//\/* XID *\// /table_id: [0-9]+/table_id:
> #/
> >> -SHOW BINLOG EVENTS FROM 1946;
> >> +SHOW BINLOG EVENTS FROM 106;
> >> sync_slave_with_master;
> >> --echo **** On Slave ****
> >> --query_vertical SHOW CREATE TABLE t8
> >> @@ -162,7 +170,7 @@ SELECT * FROM t3 ORDER BY a;
> >> SELECT * FROM t4 ORDER BY a;
> >> --replace_column 1 # 4 #
> >> --replace_regex /\/\* xid=.* \*\//\/* XID *\// /Server ver: .*, Binlog ver:
> .*/Server ver: #, Binlog ver: #/ /table_id: [0-9]+/table_id: #/
> >> -SHOW BINLOG EVENTS;
> >> +SHOW BINLOG EVENTS FROM 106;
> >> sync_slave_with_master;
> >> SHOW TABLES;
> >> SELECT TABLE_NAME,ENGINE
> >> @@ -208,13 +216,17 @@ COMMIT;
> >> SELECT * FROM t2 ORDER BY a;
> >> --replace_column 1 # 4 #
> >> --replace_regex /\/\* xid=.* \*\//\/* XID *\// /Server ver: .*, Binlog ver:
> .*/Server ver: #, Binlog ver: #/ /table_id: [0-9]+/table_id: #/
> >> -SHOW BINLOG EVENTS;
> >> +SHOW BINLOG EVENTS FROM 106;
> >> sync_slave_with_master;
> >> SELECT * FROM t2 ORDER BY a;
> >>
> >> connection master;
> >> TRUNCATE TABLE t2;
> >> +sync_slave_with_master;
> >> +
> >> +--source include/reset_master_and_slave.inc
> >>
> >> +connection master;
> >> BEGIN;
> >> INSERT INTO t2 SELECT a*a FROM t1;
> >> CREATE TEMPORARY TABLE tt2
> >> @@ -227,7 +239,7 @@ ROLLBACK;
> >> SELECT * FROM t2 ORDER BY a;
> >> --replace_column 1 # 4 #
> >> --replace_regex /\/\* xid=.* \*\//\/* XID *\// /Server ver: .*, Binlog ver:
> .*/Server ver: #, Binlog ver: #/ /table_id: [0-9]+/table_id: #/
> >> -SHOW BINLOG EVENTS FROM 949;
> >> +SHOW BINLOG EVENTS FROM 106;
> >> sync_slave_with_master;
> >> SELECT * FROM t2 ORDER BY a;
> >>
> >>
> >> === modified file 'mysql-test/suite/rpl/t/rpl_slave_skip.test'
> >> --- a/mysql-test/suite/rpl/t/rpl_slave_skip.test 2008-03-28 12:16:41 +0000
> >> +++ b/mysql-test/suite/rpl/t/rpl_slave_skip.test 2008-12-03 19:55:49 +0000
> >> @@ -121,6 +121,7 @@ DROP TRIGGER tr2;
> >> INSERT INTO t1 VALUES (3,'master/slave');
> >> INSERT INTO t2 VALUES (3,'master/slave');
> >> INSERT INTO t3 VALUES (3,'master/slave');
> >> +COMMIT;
> >>
> >> SELECT * FROM t1 ORDER BY a;
> >> SELECT * FROM t2 ORDER BY a;
> >>
> >> === modified file 'mysql-test/suite/rpl/t/rpl_trigger.test'
> >> --- a/mysql-test/suite/rpl/t/rpl_trigger.test 2007-12-18 09:07:08 +0000
> >> +++ b/mysql-test/suite/rpl/t/rpl_trigger.test 2008-12-03 19:55:49 +0000
> >> @@ -467,20 +467,46 @@ drop trigger if exists t1_bi;
> >> insert into t1 values (3, "c");
> >>
> >> select * from t1;
> >> +sync_slave_with_master;
> >> +select * from t1;
> >> +
> >> +connection master;
> >> +
> >> +drop table t1;
> >> +sync_slave_with_master;
> >> +
> >> +#
> >> +# Bug#40116: Uncommited changes are replicated and stay on slave after
> >> +# rollback on master
> >> +#
> >>
> >> -save_master_pos;
> >> -connection slave;
> >> -sync_with_master;
> >> +source include/master-slave-reset.inc;
> >> +source include/have_innodb.inc;
> >>
> >> +connection master;
> >> +create table t1 ( f int ) engine = innodb;
> >> +create table log ( r int ) engine = myisam;
> >> +create trigger tr
> >> + after insert on t1
> >> + for each row insert into log values ( new.f );
> >> +
> >> +set autocommit = 0;
> >> +insert into t1 values ( 1 );
> >> +
> >> +select * from t1;
> >> +sync_slave_with_master;
> >> select * from t1;
> >>
> >> connection master;
> >> +rollback;
> >> +select * from t1;
> >> +sync_slave_with_master;
> >> +select * from t1;
> >>
> >> -drop table t1;
> >> +connection master;
> >> +drop table t1, log;
> >> +sync_slave_with_master;
> >>
> >> #
> >> # End of tests
> >> #
> >> -save_master_pos;
> >> -connection slave;
> >> -sync_with_master;
> >>
> >> === modified file 'sql/log.cc'
> >> --- a/sql/log.cc 2008-10-21 12:18:38 +0000
> >> +++ b/sql/log.cc 2008-12-03 19:55:49 +0000
> >> @@ -1478,60 +1478,11 @@ static int binlog_commit(handlerton *hto
> >> }
> >>
> >> /*
> >> - Decision table for committing a transaction. The top part, the
> >> - *conditions* represent different cases that can occur, and hte
> >> - bottom part, the *actions*, represent what should be done in that
> >> - particular case.
> >> + We commit the transaction if:
> >>
> >> - Real transaction 'all' was true
> >> + - We are not in a transaction and committing a statement, or
> >>
> >> - Statement in cache There were at least one statement in the
> >> - transaction cache
> >> -
> >> - In transaction We are inside a transaction
> >> -
> >> - Stmt modified non-trans The statement being committed modified a
> >> - non-transactional table
> >> -
> >> - All modified non-trans Some statement before this one in the
> >> - transaction modified a non-transactional
> >> - table
> >> -
> >> -
> >> - ============================= = = = = = = = = = = = = = = = =
> >> - Real transaction N N N N N N N N N N N N N N N N
> >> - Statement in cache N N N N N N N N Y Y Y Y Y Y Y Y
> >> - In transaction N N N N Y Y Y Y N N N N Y Y Y Y
> >> - Stmt modified non-trans N N Y Y N N Y Y N N Y Y N N Y Y
> >> - All modified non-trans N Y N Y N Y N Y N Y N Y N Y N Y
> >> -
> >> - Action: (C)ommit/(A)ccumulate C C - C A C - C - - - - A A - A
> >> - ============================= = = = = = = = = = = = = = = = =
> >> -
> >> -
> >> - ============================= = = = = = = = = = = = = = = = =
> >> - Real transaction Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y
> >> - Statement in cache N N N N N N N N Y Y Y Y Y Y Y Y
> >> - In transaction N N N N Y Y Y Y N N N N Y Y Y Y
> >> - Stmt modified non-trans N N Y Y N N Y Y N N Y Y N N Y Y
> >> - All modified non-trans N Y N Y N Y N Y N Y N Y N Y N Y
> >> -
> >> - (C)ommit/(A)ccumulate/(-) - - - - C C - C - - - - C C - C
> >> - ============================= = = = = = = = = = = = = = = = =
> >> -
> >> - In other words, we commit the transaction if and only if both of
> >> - the following are true:
> >> - - We are not in a transaction and committing a statement
> >> -
> >> - - We are in a transaction and one (or more) of the following are
> >> - true:
> >> -
> >> - - A full transaction is committed
> >> -
> >> - OR
> >> -
> >> - - A non-transactional statement is committed and there is
> >> - no statement cached
> >> + - We are in a transaction and a full transaction is committed
> >>
> >> Otherwise, we accumulate the statement
> >> */
> >> @@ -1544,11 +1495,7 @@ static int binlog_commit(handlerton *hto
> >> YESNO(in_transaction),
> >> YESNO(thd->transaction.all.modified_non_trans_table),
> >> YESNO(thd->transaction.stmt.modified_non_trans_table)));
> >> - if (in_transaction &&
> >> - (all ||
> >> - (!trx_data->at_least_one_stmt &&
> >> - thd->transaction.stmt.modified_non_trans_table)) ||
> >> - !in_transaction && !all)
> >> + if (!in_transaction || all)
> >> {
> >> Query_log_event qev(thd, STRING_WITH_LEN("COMMIT"), TRUE, FALSE);
> >> qev.error_code= 0; // see comment in MYSQL_LOG::write(THD, IO_CACHE)
> >>
> >
> >
>