Hi Alfranio,
Nice Work. Please find my review comments below.
STATUS
------
Approved.
REQUIRED CHANGES
----------------
RC1. Before you push, please fix the typos one finds in the
last hunk (in the comments part), eg:
- transcation
- beging
REQUESTS
--------
n/a
SUGGESTIONS
-----------
n/a
DETAILS
-------
n/a
On Tue, 2009-09-22 at 06:39 +0000, Alfranio Correia wrote:
> #At
> file:///home/acorreia/workspace.sun/repository.mysql/bzrwork/bug-47287/mysql-5.1-bugteam/
> based on revid:joro@stripped
>
> 3117 Alfranio Correia 2009-09-22
> BUG#47287 RBR: replication diff on basic case with txn- and non-txn tables in a
> statement
>
> Let
> - T be a transactional table and N non-transactional table.
> - B be begin, C commit and R rollback.
> - M be a mixed statement, i.e. a statement that updates both T and N.
> - M* be a mixed statement that fails while updating either T or N.
>
> This patch restore the behavior presented in 5.1.37 for rows either produced
> in
> the RBR or MIXED modes, when a M* statement that happened early in a
> transaction
> had their changes written to the binary log outside the boundaries of the
> transaction and wrapped in a BEGIN/ROLLBACK. This was done to keep the slave
> consistent with with the master as the rollback would keep the changes on N
> and
> undo them on T. In particular, we do what follows:
>
> . B M* T C would log - B M* R B T C.
>
> Note that, we are not preserving history from the master as we are introducing
> a
> rollback that never happened. However, this seems to be more acceptable than
> making the slave diverge. We do not fix the following case:
>
> . B T M* C would log B T M* C.
>
> The slave will diverge as the changes on T tables that originated from the M
> statement are rolled back on the master but not on the slave. Unfortunately,
> we
> cannot simply rollback the transaction as this would undo any uncommitted
> changes on T tables.
>
> SBR is not considered in this patch because a failing statement is written to
> the binary along with the error code and a slave executes and then rolls back
> the statement when it has an associated error code, thus undoing the effects
> on T. In RBR and MBR, a full-fledged fix will be pushed after the WL 2687.
>
> added:
> mysql-test/extra/binlog_tests/binlog_failure_mixing_engines.test
> mysql-test/suite/binlog/r/binlog_mixed_failure_mixing_engines.result
> mysql-test/suite/binlog/r/binlog_row_failure_mixing_engines.result
> mysql-test/suite/binlog/t/binlog_mixed_failure_mixing_engines.test
> mysql-test/suite/binlog/t/binlog_row_failure_mixing_engines.test
> modified:
> sql/log.cc
> === added file 'mysql-test/extra/binlog_tests/binlog_failure_mixing_engines.test'
> --- a/mysql-test/extra/binlog_tests/binlog_failure_mixing_engines.test 1970-01-01
> 00:00:00 +0000
> +++ b/mysql-test/extra/binlog_tests/binlog_failure_mixing_engines.test 2009-09-22
> 06:39:50 +0000
> @@ -0,0 +1,105 @@
> +################################################################################
> +# Let
> +# - T be a transactional table and N non-transactional table.
> +# - B be begin, C commit and R rollback.
> +# - M be a mixed statement, i.e. a statement that updates both T and N.
> +# - M* be a mixed statement that fails while updating either T or N.
> +#
> +# In this test case, when changes are logged as rows either in the RBR or MIXED
> +# modes, we check if a M* statement that happens early in a transaction is
> +# written to the binary log outside the boundaries of the transaction and
> +# wrapped in a BEGIN/ROLLBACK. This is done to keep the slave consistent with
> +# with the master as the rollback will keep the changes on N and undo them on
> +# T. In particular, we expect the following behavior:
> +#
> +# 1. B M* T C would log - B M* R B T C.
> +# 2. B T M* C would log B T M* C.
> +#
> +# SBR is not considered in this test because a failing statement is written to
> +# the binary along with the error code and a slave executes and then rolls back
> +# the statement when it has an associated error code, thus undoing the effects
> +# on T.
> +#
> +# Note that, in the first case, we are not preserving history from the master as
> +# we are introducing a rollback that never happened. However, this seems to be
> +# more acceptable than making the slave diverge. In the second case, the slave
> +# will diverge as the changes on T tables that originated from the M statement
> +# are rolled back on the master but not on the slave. Unfortunately, we cannot
> +# simply rollback the transaction as this would undo any uncommitted changes
> +# on T tables.
> +#
> +# Such issues do not happen in SBR. In RBR and MBR, a fix will be pushed after
> +# the WL 2687.
> +################################################################################
> +
> +
> +--echo
> ###################################################################################
> +--echo # CONFIGURATION
> +--echo
> ###################################################################################
> +CREATE TABLE nt_1 (a text, b int PRIMARY KEY) ENGINE = MyISAM;
> +CREATE TABLE nt_2 (a text, b int PRIMARY KEY) ENGINE = MyISAM;
> +CREATE TABLE tt_1 (a text, b int PRIMARY KEY) ENGINE = Innodb;
> +CREATE TABLE tt_2 (a text, b int PRIMARY KEY) ENGINE = Innodb;
> +
> +DELIMITER |;
> +
> +CREATE TRIGGER tr_i_tt_1_to_nt_1 BEFORE INSERT ON tt_1 FOR EACH ROW
> +BEGIN
> + INSERT INTO nt_1 VALUES (NEW.a, NEW.b);
> +END|
> +
> +CREATE TRIGGER tr_i_nt_2_to_tt_2 BEFORE INSERT ON nt_2 FOR EACH ROW
> +BEGIN
> + INSERT INTO tt_2 VALUES (NEW.a, NEW.b);
> +END|
> +
> +DELIMITER ;|
> +
> +--echo
> ###################################################################################
> +--echo # CHECK HISTORY IN BINLOG
> +--echo
> ###################################################################################
> +let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1);
> +
> +
> +--echo *** "B M* T C" with error in M* generates in the binlog the "B M* R B T C"
> entries
> +INSERT INTO nt_1 VALUES ("new text 1", 1);
> +BEGIN;
> +--error ER_DUP_ENTRY
> +INSERT INTO tt_1 VALUES (USER(), 2), (USER(), 1);
> +INSERT INTO tt_1 VALUES ("new text 3", 3), ("new text 4", 4);
> +COMMIT;
> +
> +INSERT INTO tt_2 VALUES ("new text 5", 5);
> +BEGIN;
> +--error ER_DUP_ENTRY
> +INSERT INTO nt_2 VALUES (USER(), 6), (USER(), 5);
> +INSERT INTO tt_2 VALUES ("new text 7", 7);
> +COMMIT;
> +
> +--echo *** "B M M* T C" with error in M* generates in the binlog the "B M M* T C"
> entries
> +INSERT INTO nt_1 VALUES ("new text 11", 11);
> +BEGIN;
> +INSERT INTO tt_1 VALUES ("new text 8", 8), ("new text 9", 9);
> +--error ER_DUP_ENTRY
> +INSERT INTO tt_1 VALUES (USER(), 10), (USER(), 11);
> +INSERT INTO tt_2 VALUES ("new text 12", 12);
> +COMMIT;
> +
> +INSERT INTO tt_2 VALUES ("new text 16", 16);
> +BEGIN;
> +INSERT INTO nt_2 VALUES ("new text 13", 13), ("new text 14", 14);
> +--error ER_DUP_ENTRY
> +INSERT INTO nt_2 VALUES (USER(), 15), (USER(), 16);
> +INSERT INTO tt_2 VALUES ("new text 17", 17);
> +COMMIT;
> +
> +--source include/show_binlog_events.inc
> +
> +--echo
> ###################################################################################
> +--echo # CLEAN
> +--echo
> ###################################################################################
> +
> +DROP TABLE tt_1;
> +DROP TABLE tt_2;
> +DROP TABLE nt_1;
> +DROP TABLE nt_2;
>
> === added file
> 'mysql-test/suite/binlog/r/binlog_mixed_failure_mixing_engines.result'
> --- a/mysql-test/suite/binlog/r/binlog_mixed_failure_mixing_engines.result 1970-01-01
> 00:00:00 +0000
> +++ b/mysql-test/suite/binlog/r/binlog_mixed_failure_mixing_engines.result 2009-09-22
> 06:39:50 +0000
> @@ -0,0 +1,93 @@
> +###################################################################################
> +# CONFIGURATION
> +###################################################################################
> +CREATE TABLE nt_1 (a text, b int PRIMARY KEY) ENGINE = MyISAM;
> +CREATE TABLE nt_2 (a text, b int PRIMARY KEY) ENGINE = MyISAM;
> +CREATE TABLE tt_1 (a text, b int PRIMARY KEY) ENGINE = Innodb;
> +CREATE TABLE tt_2 (a text, b int PRIMARY KEY) ENGINE = Innodb;
> +CREATE TRIGGER tr_i_tt_1_to_nt_1 BEFORE INSERT ON tt_1 FOR EACH ROW
> +BEGIN
> +INSERT INTO nt_1 VALUES (NEW.a, NEW.b);
> +END|
> +CREATE TRIGGER tr_i_nt_2_to_tt_2 BEFORE INSERT ON nt_2 FOR EACH ROW
> +BEGIN
> +INSERT INTO tt_2 VALUES (NEW.a, NEW.b);
> +END|
> +###################################################################################
> +# CHECK HISTORY IN BINLOG
> +###################################################################################
> +*** "B M* T C" with error in M* generates in the binlog the "B M* R B T C" entries
> +INSERT INTO nt_1 VALUES ("new text 1", 1);
> +BEGIN;
> +INSERT INTO tt_1 VALUES (USER(), 2), (USER(), 1);
> +ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
> +INSERT INTO tt_1 VALUES ("new text 3", 3), ("new text 4", 4);
> +COMMIT;
> +INSERT INTO tt_2 VALUES ("new text 5", 5);
> +BEGIN;
> +INSERT INTO nt_2 VALUES (USER(), 6), (USER(), 5);
> +ERROR 23000: Duplicate entry '5' for key 'PRIMARY'
> +INSERT INTO tt_2 VALUES ("new text 7", 7);
> +COMMIT;
> +*** "B M M* T C" with error in M* generates in the binlog the "B M M* T C" entries
> +INSERT INTO nt_1 VALUES ("new text 11", 11);
> +BEGIN;
> +INSERT INTO tt_1 VALUES ("new text 8", 8), ("new text 9", 9);
> +INSERT INTO tt_1 VALUES (USER(), 10), (USER(), 11);
> +ERROR 23000: Duplicate entry '11' for key 'PRIMARY'
> +INSERT INTO tt_2 VALUES ("new text 12", 12);
> +COMMIT;
> +INSERT INTO tt_2 VALUES ("new text 16", 16);
> +BEGIN;
> +INSERT INTO nt_2 VALUES ("new text 13", 13), ("new text 14", 14);
> +INSERT INTO nt_2 VALUES (USER(), 15), (USER(), 16);
> +ERROR 23000: Duplicate entry '16' for key 'PRIMARY'
> +INSERT INTO tt_2 VALUES ("new text 17", 17);
> +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 1", 1)
> +master-bin.000001 # Query # # BEGIN
> +master-bin.000001 # Table_map # # table_id: # (test.tt_1)
> +master-bin.000001 # Table_map # # table_id: # (test.nt_1)
> +master-bin.000001 # Write_rows # # table_id: #
> +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
> +master-bin.000001 # Query # # use `test`; INSERT INTO tt_1 VALUES ("new text 3", 3),
> ("new text 4", 4)
> +master-bin.000001 # Xid # # COMMIT /* XID */
> +master-bin.000001 # Query # # BEGIN
> +master-bin.000001 # Query # # use `test`; INSERT INTO tt_2 VALUES ("new text 5", 5)
> +master-bin.000001 # Xid # # COMMIT /* XID */
> +master-bin.000001 # Query # # BEGIN
> +master-bin.000001 # Table_map # # table_id: # (test.nt_2)
> +master-bin.000001 # Table_map # # table_id: # (test.tt_2)
> +master-bin.000001 # Write_rows # # table_id: #
> +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
> +master-bin.000001 # Query # # use `test`; INSERT INTO tt_2 VALUES ("new text 7", 7)
> +master-bin.000001 # Xid # # COMMIT /* XID */
> +master-bin.000001 # Query # # use `test`; INSERT INTO nt_1 VALUES ("new text 11",
> 11)
> +master-bin.000001 # Query # # BEGIN
> +master-bin.000001 # Query # # use `test`; INSERT INTO tt_1 VALUES ("new text 8", 8),
> ("new text 9", 9)
> +master-bin.000001 # Table_map # # table_id: # (test.tt_1)
> +master-bin.000001 # Table_map # # table_id: # (test.nt_1)
> +master-bin.000001 # Write_rows # # table_id: #
> +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
> +master-bin.000001 # Query # # use `test`; INSERT INTO tt_2 VALUES ("new text 12",
> 12)
> +master-bin.000001 # Xid # # COMMIT /* XID */
> +master-bin.000001 # Query # # BEGIN
> +master-bin.000001 # Query # # use `test`; INSERT INTO tt_2 VALUES ("new text 16",
> 16)
> +master-bin.000001 # Xid # # COMMIT /* XID */
> +master-bin.000001 # Query # # BEGIN
> +master-bin.000001 # Query # # use `test`; INSERT INTO nt_2 VALUES ("new text 13",
> 13), ("new text 14", 14)
> +master-bin.000001 # Table_map # # table_id: # (test.nt_2)
> +master-bin.000001 # Table_map # # table_id: # (test.tt_2)
> +master-bin.000001 # Write_rows # # table_id: #
> +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
> +master-bin.000001 # Query # # use `test`; INSERT INTO tt_2 VALUES ("new text 17",
> 17)
> +master-bin.000001 # Xid # # COMMIT /* XID */
> +###################################################################################
> +# CLEAN
> +###################################################################################
> +DROP TABLE tt_1;
> +DROP TABLE tt_2;
> +DROP TABLE nt_1;
> +DROP TABLE nt_2;
>
> === added file 'mysql-test/suite/binlog/r/binlog_row_failure_mixing_engines.result'
> --- a/mysql-test/suite/binlog/r/binlog_row_failure_mixing_engines.result 1970-01-01
> 00:00:00 +0000
> +++ b/mysql-test/suite/binlog/r/binlog_row_failure_mixing_engines.result 2009-09-22
> 06:39:50 +0000
> @@ -0,0 +1,119 @@
> +###################################################################################
> +# CONFIGURATION
> +###################################################################################
> +CREATE TABLE nt_1 (a text, b int PRIMARY KEY) ENGINE = MyISAM;
> +CREATE TABLE nt_2 (a text, b int PRIMARY KEY) ENGINE = MyISAM;
> +CREATE TABLE tt_1 (a text, b int PRIMARY KEY) ENGINE = Innodb;
> +CREATE TABLE tt_2 (a text, b int PRIMARY KEY) ENGINE = Innodb;
> +CREATE TRIGGER tr_i_tt_1_to_nt_1 BEFORE INSERT ON tt_1 FOR EACH ROW
> +BEGIN
> +INSERT INTO nt_1 VALUES (NEW.a, NEW.b);
> +END|
> +CREATE TRIGGER tr_i_nt_2_to_tt_2 BEFORE INSERT ON nt_2 FOR EACH ROW
> +BEGIN
> +INSERT INTO tt_2 VALUES (NEW.a, NEW.b);
> +END|
> +###################################################################################
> +# CHECK HISTORY IN BINLOG
> +###################################################################################
> +*** "B M* T C" with error in M* generates in the binlog the "B M* R B T C" entries
> +INSERT INTO nt_1 VALUES ("new text 1", 1);
> +BEGIN;
> +INSERT INTO tt_1 VALUES (USER(), 2), (USER(), 1);
> +ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
> +INSERT INTO tt_1 VALUES ("new text 3", 3), ("new text 4", 4);
> +COMMIT;
> +INSERT INTO tt_2 VALUES ("new text 5", 5);
> +BEGIN;
> +INSERT INTO nt_2 VALUES (USER(), 6), (USER(), 5);
> +ERROR 23000: Duplicate entry '5' for key 'PRIMARY'
> +INSERT INTO tt_2 VALUES ("new text 7", 7);
> +COMMIT;
> +*** "B M M* T C" with error in M* generates in the binlog the "B M M* T C" entries
> +INSERT INTO nt_1 VALUES ("new text 11", 11);
> +BEGIN;
> +INSERT INTO tt_1 VALUES ("new text 8", 8), ("new text 9", 9);
> +INSERT INTO tt_1 VALUES (USER(), 10), (USER(), 11);
> +ERROR 23000: Duplicate entry '11' for key 'PRIMARY'
> +INSERT INTO tt_2 VALUES ("new text 12", 12);
> +COMMIT;
> +INSERT INTO tt_2 VALUES ("new text 16", 16);
> +BEGIN;
> +INSERT INTO nt_2 VALUES ("new text 13", 13), ("new text 14", 14);
> +INSERT INTO nt_2 VALUES (USER(), 15), (USER(), 16);
> +ERROR 23000: Duplicate entry '16' for key 'PRIMARY'
> +INSERT INTO tt_2 VALUES ("new text 17", 17);
> +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 # Table_map # # table_id: # (test.nt_1)
> +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
> +master-bin.000001 # Query # # COMMIT
> +master-bin.000001 # Query # # BEGIN
> +master-bin.000001 # Table_map # # table_id: # (test.tt_1)
> +master-bin.000001 # Table_map # # table_id: # (test.nt_1)
> +master-bin.000001 # Write_rows # # table_id: #
> +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
> +master-bin.000001 # Table_map # # table_id: # (test.tt_1)
> +master-bin.000001 # Table_map # # table_id: # (test.nt_1)
> +master-bin.000001 # Write_rows # # table_id: #
> +master-bin.000001 # Write_rows # # table_id: #
> +master-bin.000001 # Write_rows # # table_id: #
> +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
> +master-bin.000001 # Xid # # COMMIT /* XID */
> +master-bin.000001 # Query # # BEGIN
> +master-bin.000001 # Table_map # # table_id: # (test.tt_2)
> +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
> +master-bin.000001 # Xid # # COMMIT /* XID */
> +master-bin.000001 # Query # # BEGIN
> +master-bin.000001 # Table_map # # table_id: # (test.nt_2)
> +master-bin.000001 # Table_map # # table_id: # (test.tt_2)
> +master-bin.000001 # Write_rows # # table_id: #
> +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
> +master-bin.000001 # Table_map # # table_id: # (test.tt_2)
> +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
> +master-bin.000001 # Xid # # COMMIT /* XID */
> +master-bin.000001 # Query # # BEGIN
> +master-bin.000001 # Table_map # # table_id: # (test.nt_1)
> +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
> +master-bin.000001 # Query # # COMMIT
> +master-bin.000001 # Query # # BEGIN
> +master-bin.000001 # Table_map # # table_id: # (test.tt_1)
> +master-bin.000001 # Table_map # # table_id: # (test.nt_1)
> +master-bin.000001 # Write_rows # # table_id: #
> +master-bin.000001 # Write_rows # # table_id: #
> +master-bin.000001 # Write_rows # # table_id: #
> +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
> +master-bin.000001 # Table_map # # table_id: # (test.tt_1)
> +master-bin.000001 # Table_map # # table_id: # (test.nt_1)
> +master-bin.000001 # Write_rows # # table_id: #
> +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
> +master-bin.000001 # Table_map # # table_id: # (test.tt_2)
> +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
> +master-bin.000001 # Xid # # COMMIT /* XID */
> +master-bin.000001 # Query # # BEGIN
> +master-bin.000001 # Table_map # # table_id: # (test.tt_2)
> +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
> +master-bin.000001 # Xid # # COMMIT /* XID */
> +master-bin.000001 # Query # # BEGIN
> +master-bin.000001 # Table_map # # table_id: # (test.nt_2)
> +master-bin.000001 # Table_map # # table_id: # (test.tt_2)
> +master-bin.000001 # Write_rows # # table_id: #
> +master-bin.000001 # Write_rows # # table_id: #
> +master-bin.000001 # Write_rows # # table_id: #
> +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
> +master-bin.000001 # Table_map # # table_id: # (test.nt_2)
> +master-bin.000001 # Table_map # # table_id: # (test.tt_2)
> +master-bin.000001 # Write_rows # # table_id: #
> +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
> +master-bin.000001 # Table_map # # table_id: # (test.tt_2)
> +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
> +master-bin.000001 # Xid # # COMMIT /* XID */
> +###################################################################################
> +# CLEAN
> +###################################################################################
> +DROP TABLE tt_1;
> +DROP TABLE tt_2;
> +DROP TABLE nt_1;
> +DROP TABLE nt_2;
>
> === added file 'mysql-test/suite/binlog/t/binlog_mixed_failure_mixing_engines.test'
> --- a/mysql-test/suite/binlog/t/binlog_mixed_failure_mixing_engines.test 1970-01-01
> 00:00:00 +0000
> +++ b/mysql-test/suite/binlog/t/binlog_mixed_failure_mixing_engines.test 2009-09-22
> 06:39:50 +0000
> @@ -0,0 +1,4 @@
> +--source include/have_binlog_format_mixed.inc
> +--source include/have_innodb.inc
> +
> +--source extra/binlog_tests/binlog_failure_mixing_engines.test
>
> === added file 'mysql-test/suite/binlog/t/binlog_row_failure_mixing_engines.test'
> --- a/mysql-test/suite/binlog/t/binlog_row_failure_mixing_engines.test 1970-01-01
> 00:00:00 +0000
> +++ b/mysql-test/suite/binlog/t/binlog_row_failure_mixing_engines.test 2009-09-22
> 06:39:50 +0000
> @@ -0,0 +1,4 @@
> +--source include/have_binlog_format_row.inc
> +--source include/have_innodb.inc
> +
> +--source extra/binlog_tests/binlog_failure_mixing_engines.test
>
> === modified file 'sql/log.cc'
> --- a/sql/log.cc 2009-09-11 17:06:27 +0000
> +++ b/sql/log.cc 2009-09-22 06:39:50 +0000
> @@ -182,7 +182,10 @@ public:
> {
> DBUG_PRINT("info", ("truncating to position %lu", (ulong) pos));
> DBUG_PRINT("info", ("before_stmt_pos=%lu", (ulong) pos));
> - delete pending();
> + if (pending())
> + {
> + delete pending();
> + }
> set_pending(0);
> reinit_io_cache(&trans_log, WRITE_CACHE, pos, 0, 0);
> trans_log.end_of_file= max_binlog_cache_size;
> @@ -205,7 +208,7 @@ public:
> completely.
> */
> void reset() {
> - if (!empty())
> + if (!empty())
> truncate(0);
> before_stmt_pos= MY_OFF_T_UNDEF;
> incident= FALSE;
> @@ -223,8 +226,6 @@ public:
> m_pending= pending;
> }
>
> - IO_CACHE trans_log; // The transaction cache
> -
> void set_incident(void)
> {
> incident= TRUE;
> @@ -235,6 +236,12 @@ public:
> return(incident);
> }
>
> + bool has_at_least_one_stmt()
> + {
> + return my_b_tell(&trans_log) > 0;
> + }
> +
> + IO_CACHE trans_log; // The transaction cache
> /**
> Boolean that is true if there is at least one statement in the
> transaction cache.
> @@ -1539,7 +1546,6 @@ static int binlog_commit(handlerton *hto
> {
> Query_log_event qev(thd, STRING_WITH_LEN("COMMIT"), TRUE, TRUE, 0);
> error= binlog_end_trans(thd, trx_data, &qev, all);
> - goto end;
> }
>
> end:
> @@ -1608,15 +1614,18 @@ static int binlog_rollback(handlerton *h
> {
> /*
> We flush the cache with a rollback, wrapped in a beging/rollback if:
> - . aborting a transcation that modified a non-transactional table or;
> + . aborting a transcation that modified a non-transactional table;
> . aborting a statement that modified both transactional and
> non-transctional tables but which is not in the boundaries of any
> - transaction;
> + transaction or simply there was no early statement;
> . the OPTION_KEEP_LOG is activate.
> */
> if ((all && thd->transaction.all.modified_non_trans_table) ||
> (!all && thd->transaction.stmt.modified_non_trans_table
> &&
> !(thd->options & (OPTION_BEGIN | OPTION_NOT_AUTOCOMMIT))) ||
> + (!all && thd->transaction.stmt.modified_non_trans_table
> &&
> + !trx_data->has_at_least_one_stmt() &&
> + thd->current_stmt_binlog_row_based) ||
> ((thd->options & OPTION_KEEP_LOG)))
> {
> Query_log_event qev(thd, STRING_WITH_LEN("ROLLBACK"), TRUE, TRUE, 0);
>
--
Luís