From 7e0da4352c9e85242f8fac0816b88358f4ba255e Mon Sep 17 00:00:00 2001 From: Alfranio Correia Date: Tue, 6 Oct 2009 01:54:00 +0100 Subject: 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. --- .../binlog_failure_mixing_engines.test | 102 ++++++++++++++++++++- 1 file changed, 101 insertions(+), 1 deletion(-) (limited to 'mysql-test/extra') 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 ################################################################################### -- cgit v1.2.1