summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlfranio Correia <alfranio.correia@sun.com>2009-10-06 01:54:00 +0100
committerAlfranio Correia <alfranio.correia@sun.com>2009-10-06 01:54:00 +0100
commit7e0da4352c9e85242f8fac0816b88358f4ba255e (patch)
treee98ba701839ee0242432e0e6bbab70970068d0da
parent14d1909440ab14ae839df974ce92c12c4220456e (diff)
downloadmariadb-git-7e0da4352c9e85242f8fac0816b88358f4ba255e.tar.gz
BUG#47678 Changes to n-tables that happen early in a trans. are only flushed upon commit
Let - T be a transactional table and N non-transactional table. - B be begin, C commit and R rollback. - N be a statement that accesses and changes only N-tables. - T be a statement that accesses and changes only T-tables. In RBR, changes to N-tables that happen early in a transaction are not immediately flushed upon committing a statement. This behavior may, however, break consistency in the presence of concurrency since changes done to N-tables become immediately visible to other connections. To fix this problem, we do the following: . B N N T C would log - B N C B N C B T C. . B N N T R would log - B N C B N C B T R. Note that we are not preserving history from the master as we are introducing a commit that never happened. However, this seems to be more acceptable than the possibility of breaking consistency in the presence of concurrency.
-rw-r--r--mysql-test/extra/binlog_tests/binlog_failure_mixing_engines.test102
-rw-r--r--mysql-test/suite/binlog/r/binlog_mixed_failure_mixing_engines.result172
-rw-r--r--mysql-test/suite/binlog/r/binlog_row_failure_mixing_engines.result172
-rw-r--r--mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result18
-rw-r--r--mysql-test/suite/rpl/r/rpl_row_create_table.result4
-rw-r--r--sql/log.cc7
6 files changed, 467 insertions, 8 deletions
diff --git a/mysql-test/extra/binlog_tests/binlog_failure_mixing_engines.test b/mysql-test/extra/binlog_tests/binlog_failure_mixing_engines.test
index 26ae8f625a9..54f3c538c79 100644
--- a/mysql-test/extra/binlog_tests/binlog_failure_mixing_engines.test
+++ b/mysql-test/extra/binlog_tests/binlog_failure_mixing_engines.test
@@ -34,13 +34,25 @@
# simply roll the transaction back as this would undo any uncommitted changes
# on T-tables.
#
-# We check one more case. INSERT M...SELECT* which produces the following
+# We check two more cases. First, INSERT...SELECT* which produces the following
# results:
#
# 1. B T INSERT M...SELECT* C" with an error in INSERT M...SELECT* generates in
# the binlog the following entries: "Nothing".
# 2. B INSERT M...SELECT* C" with an error in INSERT M...SELECT* generates in
# the binlog the following entries: B INSERT M...SELECT* R.
+#
+# Finally, we also check if any N statement that happens early in a transaction
+# (i.e. before any T or M statement) is written to the binary log outside the
+# boundaries of the transaction. In particular, we expect the following
+# behavior:
+#
+# 1. B N N T C would generate in the binlog B N C B N C B T C.
+# 2. B N N T R would generate in the binlog B N C B N C B T R.
+# 3. B N* N* T C would generate in the binlog B N R B N R B T C.
+# 4. B N* N* T R would generate in the binlog B N R B N R B T R.
+# 5. B N N T N T C would generate in the binlog B N C B N C B T N T C.
+# 6. B N N T N T R would generate in the binlog the B N C B N C B T N T R.
#
# Such issues do not happen in SBR. In RBR and MBR, a full-fledged fix will be
# pushed after the WL#2687.
@@ -190,6 +202,94 @@ INSERT INTO nt_2(a, b) SELECT USER(), b FROM nt_1;
COMMIT;
--source include/show_binlog_events.inc
+--echo
+--echo
+--echo
+--echo *** "B N N T C" generates in the binlog the "B N C B N C B T C" entries
+--echo
+let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1);
+TRUNCATE TABLE nt_1;
+TRUNCATE TABLE tt_2;
+BEGIN;
+INSERT INTO nt_1 VALUES (USER(), 1);
+INSERT INTO nt_1 VALUES (USER(), 2);
+INSERT INTO tt_2 VALUES (USER(), 3);
+COMMIT;
+--source include/show_binlog_events.inc
+
+--echo
+--echo
+--echo
+--echo *** "B N N T R" generates in the binlog the "B N C B N C B T R" entries
+--echo
+let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1);
+BEGIN;
+INSERT INTO nt_1 VALUES (USER(), 4);
+INSERT INTO nt_1 VALUES (USER(), 5);
+INSERT INTO tt_2 VALUES (USER(), 6);
+ROLLBACK;
+--source include/show_binlog_events.inc
+
+--echo
+--echo
+--echo
+--echo *** "B N* N* T C" with error in N* generates in the binlog the "B N R B N R B T C" entries
+--echo
+let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1);
+BEGIN;
+--error ER_DUP_ENTRY
+INSERT INTO nt_1 VALUES (USER(), 7), (USER(), 1);
+--error ER_DUP_ENTRY
+INSERT INTO nt_1 VALUES (USER(), 8), (USER(), 1);
+INSERT INTO tt_2 VALUES (USER(), 9);
+COMMIT;
+--source include/show_binlog_events.inc
+
+--echo
+--echo
+--echo
+--echo *** "B N* N* T R" with error in N* generates in the binlog the "B N R B N R B T R" entries
+--echo
+let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1);
+BEGIN;
+--error ER_DUP_ENTRY
+INSERT INTO nt_1 VALUES (USER(), 10), (USER(), 1);
+--error ER_DUP_ENTRY
+INSERT INTO nt_1 VALUES (USER(), 11), (USER(), 1);
+INSERT INTO tt_2 VALUES (USER(), 12);
+ROLLBACK;
+--source include/show_binlog_events.inc
+
+--echo
+--echo
+--echo
+--echo *** "B N N T N T C" generates in the binlog the "B N C B N C B T N T C" entries
+--echo
+let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1);
+BEGIN;
+INSERT INTO nt_1 VALUES (USER(), 13);
+INSERT INTO nt_1 VALUES (USER(), 14);
+INSERT INTO tt_2 VALUES (USER(), 15);
+INSERT INTO nt_1 VALUES (USER(), 16);
+INSERT INTO tt_2 VALUES (USER(), 17);
+COMMIT;
+--source include/show_binlog_events.inc
+
+--echo
+--echo
+--echo
+--echo *** "B N N T N T R" generates in the binlog the "B N C B N C B T N T R" entries
+--echo
+let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1);
+BEGIN;
+INSERT INTO nt_1 VALUES (USER(), 18);
+INSERT INTO nt_1 VALUES (USER(), 19);
+INSERT INTO tt_2 VALUES (USER(), 20);
+INSERT INTO nt_1 VALUES (USER(), 21);
+INSERT INTO tt_2 VALUES (USER(), 22);
+ROLLBACK;
+--source include/show_binlog_events.inc
+
--echo ###################################################################################
--echo # CLEAN
--echo ###################################################################################
diff --git a/mysql-test/suite/binlog/r/binlog_mixed_failure_mixing_engines.result b/mysql-test/suite/binlog/r/binlog_mixed_failure_mixing_engines.result
index 16a2ce50655..dfc08d76a6a 100644
--- a/mysql-test/suite/binlog/r/binlog_mixed_failure_mixing_engines.result
+++ b/mysql-test/suite/binlog/r/binlog_mixed_failure_mixing_engines.result
@@ -225,6 +225,178 @@ master-bin.000001 # Write_rows # # table_id: #
master-bin.000001 # Write_rows # # table_id: #
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
master-bin.000001 # Query # # ROLLBACK
+
+
+
+*** "B N N T C" generates in the binlog the "B N C B N C B T C" entries
+
+TRUNCATE TABLE nt_1;
+TRUNCATE TABLE tt_2;
+BEGIN;
+INSERT INTO nt_1 VALUES (USER(), 1);
+INSERT INTO nt_1 VALUES (USER(), 2);
+INSERT INTO tt_2 VALUES (USER(), 3);
+COMMIT;
+show binlog events from <binlog_start>;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; TRUNCATE TABLE nt_1
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; TRUNCATE TABLE tt_2
+master-bin.000001 # Xid # # COMMIT /* XID */
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.nt_1)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Query # # COMMIT
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.nt_1)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Query # # COMMIT
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.tt_2)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Xid # # COMMIT /* XID */
+
+
+
+*** "B N N T R" generates in the binlog the "B N C B N C B T R" entries
+
+BEGIN;
+INSERT INTO nt_1 VALUES (USER(), 4);
+INSERT INTO nt_1 VALUES (USER(), 5);
+INSERT INTO tt_2 VALUES (USER(), 6);
+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 # Table_map # # table_id: # (test.nt_1)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Query # # COMMIT
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.nt_1)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Query # # COMMIT
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.tt_2)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Query # # ROLLBACK
+
+
+
+*** "B N* N* T C" with error in N* generates in the binlog the "B N R B N R B T C" entries
+
+BEGIN;
+INSERT INTO nt_1 VALUES (USER(), 7), (USER(), 1);
+ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
+INSERT INTO nt_1 VALUES (USER(), 8), (USER(), 1);
+ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
+INSERT INTO tt_2 VALUES (USER(), 9);
+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 # # ROLLBACK
+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 # # ROLLBACK
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.tt_2)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Xid # # COMMIT /* XID */
+
+
+
+*** "B N* N* T R" with error in N* generates in the binlog the "B N R B N R B T R" entries
+
+BEGIN;
+INSERT INTO nt_1 VALUES (USER(), 10), (USER(), 1);
+ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
+INSERT INTO nt_1 VALUES (USER(), 11), (USER(), 1);
+ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
+INSERT INTO tt_2 VALUES (USER(), 12);
+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 # Table_map # # table_id: # (test.nt_1)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Query # # ROLLBACK
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.nt_1)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Query # # ROLLBACK
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.tt_2)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Query # # ROLLBACK
+
+
+
+*** "B N N T N T C" generates in the binlog the "B N C B N C B T N T C" entries
+
+BEGIN;
+INSERT INTO nt_1 VALUES (USER(), 13);
+INSERT INTO nt_1 VALUES (USER(), 14);
+INSERT INTO tt_2 VALUES (USER(), 15);
+INSERT INTO nt_1 VALUES (USER(), 16);
+INSERT INTO tt_2 VALUES (USER(), 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.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_2)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Table_map # # table_id: # (test.nt_1)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Table_map # # table_id: # (test.tt_2)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Xid # # COMMIT /* XID */
+
+
+
+*** "B N N T N T R" generates in the binlog the "B N C B N C B T N T R" entries
+
+BEGIN;
+INSERT INTO nt_1 VALUES (USER(), 18);
+INSERT INTO nt_1 VALUES (USER(), 19);
+INSERT INTO tt_2 VALUES (USER(), 20);
+INSERT INTO nt_1 VALUES (USER(), 21);
+INSERT INTO tt_2 VALUES (USER(), 22);
+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 # Table_map # # table_id: # (test.nt_1)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Query # # COMMIT
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.nt_1)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Query # # COMMIT
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.tt_2)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Table_map # # table_id: # (test.nt_1)
+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 # Query # # ROLLBACK
###################################################################################
# CLEAN
###################################################################################
diff --git a/mysql-test/suite/binlog/r/binlog_row_failure_mixing_engines.result b/mysql-test/suite/binlog/r/binlog_row_failure_mixing_engines.result
index 85a13af3957..45c8640d3e3 100644
--- a/mysql-test/suite/binlog/r/binlog_row_failure_mixing_engines.result
+++ b/mysql-test/suite/binlog/r/binlog_row_failure_mixing_engines.result
@@ -259,6 +259,178 @@ master-bin.000001 # Write_rows # # table_id: #
master-bin.000001 # Write_rows # # table_id: #
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
master-bin.000001 # Query # # ROLLBACK
+
+
+
+*** "B N N T C" generates in the binlog the "B N C B N C B T C" entries
+
+TRUNCATE TABLE nt_1;
+TRUNCATE TABLE tt_2;
+BEGIN;
+INSERT INTO nt_1 VALUES (USER(), 1);
+INSERT INTO nt_1 VALUES (USER(), 2);
+INSERT INTO tt_2 VALUES (USER(), 3);
+COMMIT;
+show binlog events from <binlog_start>;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; TRUNCATE TABLE nt_1
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Query # # use `test`; TRUNCATE TABLE tt_2
+master-bin.000001 # Xid # # COMMIT /* XID */
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.nt_1)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Query # # COMMIT
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.nt_1)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Query # # COMMIT
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.tt_2)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Xid # # COMMIT /* XID */
+
+
+
+*** "B N N T R" generates in the binlog the "B N C B N C B T R" entries
+
+BEGIN;
+INSERT INTO nt_1 VALUES (USER(), 4);
+INSERT INTO nt_1 VALUES (USER(), 5);
+INSERT INTO tt_2 VALUES (USER(), 6);
+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 # Table_map # # table_id: # (test.nt_1)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Query # # COMMIT
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.nt_1)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Query # # COMMIT
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.tt_2)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Query # # ROLLBACK
+
+
+
+*** "B N* N* T C" with error in N* generates in the binlog the "B N R B N R B T C" entries
+
+BEGIN;
+INSERT INTO nt_1 VALUES (USER(), 7), (USER(), 1);
+ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
+INSERT INTO nt_1 VALUES (USER(), 8), (USER(), 1);
+ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
+INSERT INTO tt_2 VALUES (USER(), 9);
+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 # # ROLLBACK
+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 # # ROLLBACK
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.tt_2)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Xid # # COMMIT /* XID */
+
+
+
+*** "B N* N* T R" with error in N* generates in the binlog the "B N R B N R B T R" entries
+
+BEGIN;
+INSERT INTO nt_1 VALUES (USER(), 10), (USER(), 1);
+ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
+INSERT INTO nt_1 VALUES (USER(), 11), (USER(), 1);
+ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
+INSERT INTO tt_2 VALUES (USER(), 12);
+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 # Table_map # # table_id: # (test.nt_1)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Query # # ROLLBACK
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.nt_1)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Query # # ROLLBACK
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.tt_2)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Query # # ROLLBACK
+
+
+
+*** "B N N T N T C" generates in the binlog the "B N C B N C B T N T C" entries
+
+BEGIN;
+INSERT INTO nt_1 VALUES (USER(), 13);
+INSERT INTO nt_1 VALUES (USER(), 14);
+INSERT INTO tt_2 VALUES (USER(), 15);
+INSERT INTO nt_1 VALUES (USER(), 16);
+INSERT INTO tt_2 VALUES (USER(), 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.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_2)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Table_map # # table_id: # (test.nt_1)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Table_map # # table_id: # (test.tt_2)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Xid # # COMMIT /* XID */
+
+
+
+*** "B N N T N T R" generates in the binlog the "B N C B N C B T N T R" entries
+
+BEGIN;
+INSERT INTO nt_1 VALUES (USER(), 18);
+INSERT INTO nt_1 VALUES (USER(), 19);
+INSERT INTO tt_2 VALUES (USER(), 20);
+INSERT INTO nt_1 VALUES (USER(), 21);
+INSERT INTO tt_2 VALUES (USER(), 22);
+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 # Table_map # # table_id: # (test.nt_1)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Query # # COMMIT
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.nt_1)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Query # # COMMIT
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.tt_2)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Table_map # # table_id: # (test.nt_1)
+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 # Query # # ROLLBACK
###################################################################################
# CLEAN
###################################################################################
diff --git a/mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result b/mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result
index 9ae5121f618..76105005367 100644
--- a/mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result
+++ b/mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result
@@ -133,6 +133,10 @@ master-bin.000001 # Query # # 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 */
+master-bin.000001 # Query # # 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 # # COMMIT
insert into t1 values(11);
commit;
show binlog events from <binlog_start>;
@@ -144,6 +148,8 @@ master-bin.000001 # Xid # # COMMIT /* XID */
master-bin.000001 # Query # # 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 # # COMMIT
+master-bin.000001 # Query # # 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 */
@@ -272,6 +278,10 @@ master-bin.000001 # Query # # 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 */
+master-bin.000001 # Query # # 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 # # 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 # # BEGIN
@@ -372,7 +382,7 @@ master-bin.000001 # Query # # use `test`; DROP TABLE if exists t2
master-bin.000001 # Query # # 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 # # ROLLBACK
+master-bin.000001 # Query # # COMMIT
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 # # BEGIN
@@ -390,9 +400,11 @@ master-bin.000001 # Query # # use `test`; DROP TABLE t2
master-bin.000001 # Query # # 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 # # COMMIT
+master-bin.000001 # Query # # 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 # # ROLLBACK
+master-bin.000001 # Query # # COMMIT
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Table_map # # table_id: # (test.t1)
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
@@ -400,7 +412,7 @@ master-bin.000001 # Query # # COMMIT
master-bin.000001 # Query # # 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 # # ROLLBACK
+master-bin.000001 # Query # # COMMIT
master-bin.000001 # Query # # use `test`; TRUNCATE table t2
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Table_map # # table_id: # (test.t1)
diff --git a/mysql-test/suite/rpl/r/rpl_row_create_table.result b/mysql-test/suite/rpl/r/rpl_row_create_table.result
index 5bed9106009..b7122adea2a 100644
--- a/mysql-test/suite/rpl/r/rpl_row_create_table.result
+++ b/mysql-test/suite/rpl/r/rpl_row_create_table.result
@@ -176,7 +176,7 @@ Log_name Pos Event_type Server_id End_log_pos Info
# 106 Query # 174 BEGIN
# 174 Table_map # 216 table_id: # (test.t7)
# 216 Write_rows # 272 table_id: # flags: STMT_END_F
-# 272 Query # 343 ROLLBACK
+# 272 Query # 341 COMMIT
SELECT * FROM t7 ORDER BY a,b;
a b
1 2
@@ -327,7 +327,7 @@ Log_name Pos Event_type Server_id End_log_pos Info
# 1329 Query # 1397 BEGIN
# 1397 Table_map # 1438 table_id: # (test.t1)
# 1438 Write_rows # 1482 table_id: # flags: STMT_END_F
-# 1482 Query # 1553 ROLLBACK
+# 1482 Query # 1551 COMMIT
SHOW TABLES;
Tables_in_test
t1
diff --git a/sql/log.cc b/sql/log.cc
index 9c733636bad..e8366c47863 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -1275,7 +1275,7 @@ static bool stmt_has_updated_trans_table(THD *thd)
{
Ha_trx_info *ha_info;
- for (ha_info= thd->transaction.stmt.ha_list; ha_info; ha_info= ha_info->next())
+ for (ha_info= thd->transaction.stmt.ha_list; ha_info && ha_info->is_started(); ha_info= ha_info->next())
{
if (ha_info->is_trx_read_write() && ha_info->ht() != binlog_hton)
return (TRUE);
@@ -1538,7 +1538,10 @@ static int binlog_commit(handlerton *hton, THD *thd, bool all)
YESNO(in_transaction),
YESNO(thd->transaction.all.modified_non_trans_table),
YESNO(thd->transaction.stmt.modified_non_trans_table)));
- if (!in_transaction || all)
+ if (!in_transaction || all ||
+ (!all && !trx_data->at_least_one_stmt_committed &&
+ !stmt_has_updated_trans_table(thd) &&
+ thd->transaction.stmt.modified_non_trans_table))
{
Query_log_event qev(thd, STRING_WITH_LEN("COMMIT"), TRUE, TRUE, 0);
error= binlog_end_trans(thd, trx_data, &qev, all);