Browse Source
BUG#26395: if crash during autocommit update to transactional table on master, slave fails
BUG#26395: if crash during autocommit update to transactional table on master, slave fails
Now, every transaction (including autocommit transactions) start with
a BEGIN and end with a COMMIT/ROLLBACK in the binlog.
Added a test case, and updated lots of test case result files.
mysql-test/t/rpl_transaction-master.opt:
BitKeeper file /home/sven/bk/b26395-autocommit-xa/5.0-rpl/mysql-test/t/rpl_transaction-master.opt
mysql-test/t/rpl_transaction-slave.opt:
BitKeeper file /home/sven/bk/b26395-autocommit-xa/5.0-rpl/mysql-test/t/rpl_transaction-slave.opt
mysql-test/r/mix_innodb_myisam_binlog.result:
Updated result file
mysql-test/r/multi_update.result:
Updated result file
mysql-test/r/rpl_transaction.result:
New result file for new test case.
mysql-test/r/sp_trans_log.result:
Updated result file
mysql-test/r/variables-big.result:
Updated result file
mysql-test/t/rpl_transaction.test:
New test case.
sql/log.cc:
- Always write BEGIN and COMMIT around statements, even in autocommit
mode.
- Added comments for binlog_commit and binlog_rollback.
sql/log_event.cc:
Added debug trigger to avoid writing xid events to the binlog.
pull/374/head
10 changed files with 331 additions and 73 deletions
-
81mysql-test/r/mix_innodb_myisam_binlog.result
-
4mysql-test/r/multi_update.result
-
95mysql-test/r/rpl_transaction.result
-
1mysql-test/r/sp_trans_log.result
-
14mysql-test/r/variables-big.result
-
1mysql-test/t/rpl_transaction-master.opt
-
1mysql-test/t/rpl_transaction-slave.opt
-
106mysql-test/t/rpl_transaction.test
-
100sql/log.cc
-
1sql/log_event.cc
@ -0,0 +1,95 @@ |
|||
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 tmyisam (a int) ENGINE = MYISAM; |
|||
CREATE TABLE tinnodb (a int) ENGINE = INNODB; |
|||
SHOW CREATE TABLE tmyisam; |
|||
Table Create Table |
|||
tmyisam CREATE TABLE `tmyisam` ( |
|||
`a` int(11) default NULL |
|||
) ENGINE=MyISAM DEFAULT CHARSET=latin1 |
|||
SHOW CREATE TABLE tinnodb; |
|||
Table Create Table |
|||
tinnodb CREATE TABLE `tinnodb` ( |
|||
`a` int(11) default NULL |
|||
) ENGINE=InnoDB DEFAULT CHARSET=latin1 |
|||
==== Test 1: Non-XA Engines ==== |
|||
--- on master --- |
|||
SET AUTOCOMMIT = 1; |
|||
INSERT INTO tmyisam VALUES (1); |
|||
BEGIN; |
|||
INSERT INTO tmyisam VALUES (2); |
|||
INSERT INTO tmyisam VALUES (3); |
|||
COMMIT; |
|||
BEGIN; |
|||
INSERT INTO tmyisam VALUES (5); |
|||
INSERT INTO tmyisam VALUES (6); |
|||
ROLLBACK; |
|||
Warnings: |
|||
Warning 1196 Some non-transactional changed tables couldn't be rolled back |
|||
SELECT * FROM tmyisam ORDER BY a; |
|||
a |
|||
1 |
|||
2 |
|||
3 |
|||
5 |
|||
6 |
|||
--- on slave --- |
|||
SELECT * FROM tmyisam ORDER BY a; |
|||
a |
|||
1 |
|||
2 |
|||
3 |
|||
5 |
|||
6 |
|||
==== Test 2: Master crash before writing XID event on XA engine ==== |
|||
--- on master --- |
|||
INSERT INTO tinnodb VALUES (1); |
|||
SELECT * FROM tinnodb ORDER BY a; |
|||
a |
|||
1 |
|||
--- on slave --- |
|||
STOP SLAVE; |
|||
SHOW SLAVE STATUS; |
|||
Slave_IO_State |
|||
Master_Host 127.0.0.1 |
|||
Master_User root |
|||
Master_Port # |
|||
Connect_Retry 1 |
|||
Master_Log_File master-bin.000001 |
|||
Read_Master_Log_Pos # |
|||
Relay_Log_File # |
|||
Relay_Log_Pos # |
|||
Relay_Master_Log_File master-bin.000001 |
|||
Slave_IO_Running No |
|||
Slave_SQL_Running No |
|||
Replicate_Do_DB |
|||
Replicate_Ignore_DB |
|||
Replicate_Do_Table |
|||
Replicate_Ignore_Table # |
|||
Replicate_Wild_Do_Table |
|||
Replicate_Wild_Ignore_Table |
|||
Last_Errno 0 |
|||
Last_Error |
|||
Skip_Counter 0 |
|||
Exec_Master_Log_Pos # |
|||
Relay_Log_Space # |
|||
Until_Condition None |
|||
Until_Log_File |
|||
Until_Log_Pos 0 |
|||
Master_SSL_Allowed No |
|||
Master_SSL_CA_File |
|||
Master_SSL_CA_Path |
|||
Master_SSL_Cert |
|||
Master_SSL_Cipher |
|||
Master_SSL_Key |
|||
Seconds_Behind_Master # |
|||
SELECT * FROM tinnodb ORDER BY a; |
|||
a |
|||
DROP TABLE tmyisam; |
|||
DROP TABLE tinnodb; |
|||
DROP TABLE tmyisam; |
|||
DROP TABLE tinnodb; |
|||
@ -1,20 +1,24 @@ |
|||
set session transaction_prealloc_size=1024*1024*1024*1; |
|||
show processlist; |
|||
Id User Host db Command Time State Info |
|||
1 root localhost test Query 0 NULL show processlist |
|||
6 root localhost test Query 0 NULL show processlist |
|||
set session transaction_prealloc_size=1024*1024*1024*2; |
|||
show processlist; |
|||
Id User Host db Command Time State Info |
|||
1 root localhost test Query 2 NULL show processlist |
|||
6 root localhost test Query 1 NULL show processlist |
|||
set session transaction_prealloc_size=1024*1024*1024*3; |
|||
show processlist; |
|||
Id User Host db Command Time State Info |
|||
1 root localhost test Query 0 NULL show processlist |
|||
6 root localhost test Query 0 NULL show processlist |
|||
set session transaction_prealloc_size=1024*1024*1024*4; |
|||
Warnings: |
|||
Warning 1292 Truncated incorrect transaction_prealloc_size value: '4294967296' |
|||
show processlist; |
|||
Id User Host db Command Time State Info |
|||
1 root localhost test Query 0 NULL show processlist |
|||
6 root localhost test Query 0 NULL show processlist |
|||
set session transaction_prealloc_size=1024*1024*1024*5; |
|||
Warnings: |
|||
Warning 1292 Truncated incorrect transaction_prealloc_size value: '5368709120' |
|||
show processlist; |
|||
Id User Host db Command Time State Info |
|||
1 root localhost test Query 0 NULL show processlist |
|||
6 root localhost test Query 0 NULL show processlist |
|||
@ -0,0 +1 @@ |
|||
--innodb --debug=d,do_not_write_xid |
|||
@ -0,0 +1 @@ |
|||
--innodb |
|||
@ -0,0 +1,106 @@ |
|||
# Tests that transactions are replicated correctly, with various |
|||
# combinations of non-transactional and transactional non-XA tables. |
|||
# Also tests that an XA transaction where the master crashes just |
|||
# before writing the XID log event is executed correctly. See below |
|||
# for implementation details. |
|||
|
|||
# Note: this test should not exist in 5.1 or higher. It has been |
|||
# replaced by rpl_ndb_transaction.test, which tests a superset of what |
|||
# this test tests. |
|||
|
|||
source include/have_innodb.inc; |
|||
source include/master-slave.inc; |
|||
|
|||
|
|||
CREATE TABLE tmyisam (a int) ENGINE = MYISAM; |
|||
CREATE TABLE tinnodb (a int) ENGINE = INNODB; |
|||
|
|||
SHOW CREATE TABLE tmyisam; |
|||
SHOW CREATE TABLE tinnodb; |
|||
|
|||
|
|||
--echo ==== Test 1: Non-XA Engines ==== |
|||
# Test that everything works fine with non-XA engines. We just try |
|||
# all ways to do transactions involving ndb and/or myisam, with |
|||
# rollback or commit. |
|||
|
|||
--echo --- on master --- |
|||
|
|||
SET AUTOCOMMIT = 1; |
|||
|
|||
INSERT INTO tmyisam VALUES (1); |
|||
|
|||
BEGIN; |
|||
INSERT INTO tmyisam VALUES (2); |
|||
INSERT INTO tmyisam VALUES (3); |
|||
COMMIT; |
|||
|
|||
BEGIN; |
|||
INSERT INTO tmyisam VALUES (5); |
|||
INSERT INTO tmyisam VALUES (6); |
|||
--warning 1196 |
|||
ROLLBACK; |
|||
|
|||
SELECT * FROM tmyisam ORDER BY a; |
|||
|
|||
--echo --- on slave --- |
|||
--sync_slave_with_master |
|||
SELECT * FROM tmyisam ORDER BY a; |
|||
|
|||
|
|||
--echo ==== Test 2: Master crash before writing XID event on XA engine ==== |
|||
# We now want to test the following scenario, to verify that BUG#26395 |
|||
# has been fixed: |
|||
|
|||
# "master and slave have a transactional table that uses XA. Master |
|||
# has AUTOCOMMIT on and executes a statement (in this case an |
|||
# INSERT). Master crashes just before writing the XID event." |
|||
|
|||
# In this scenario, master will roll back, so slave should not execute |
|||
# the statement, and slave should roll back later when master is |
|||
# restarted. |
|||
|
|||
# However, we the master to be alive so that we are sure it replicates |
|||
# the statement to the slave. So in the test case, we must therefore |
|||
# not crash the master. Instead, we fake the crash by just not writing |
|||
# the XID event to the binlog. This is done by the |
|||
# --debug=d,do_not_write_xid flag in the .opt file. |
|||
|
|||
# So, unlike if the master had crashed, the master *will* execute the |
|||
# statement. But the slave should not execute it. Hence, after the |
|||
# first test is executed, the expected result on master is a table |
|||
# with one row, and on slave a table with no rows. |
|||
|
|||
# To simulate the slave correctly, we wait until everything up to the |
|||
# XID is replicated. We cannot sync_slave_with_master, because that |
|||
# would wait for the transaction to end. Instead, we wait for |
|||
# "sufficiently long time". Then we stop the slave. |
|||
|
|||
# Note: since this puts the master binlog in an inconsistent state, |
|||
# this should be the last test of the file. |
|||
|
|||
--echo --- on master --- |
|||
--connection master |
|||
|
|||
INSERT INTO tinnodb VALUES (1); |
|||
SELECT * FROM tinnodb ORDER BY a; |
|||
|
|||
--echo --- on slave --- |
|||
--connection slave |
|||
--sleep 3 |
|||
STOP SLAVE; |
|||
source include/wait_for_slave_to_stop.inc; |
|||
--replace_column 4 # 7 # 8 # 9 # 16 # 22 # 23 # 33 # |
|||
query_vertical SHOW SLAVE STATUS; |
|||
# the following statement should show that nothing has been replicated |
|||
SELECT * FROM tinnodb ORDER BY a; |
|||
|
|||
|
|||
# clean up |
|||
connection master; |
|||
DROP TABLE tmyisam; |
|||
DROP TABLE tinnodb; |
|||
|
|||
connection slave; |
|||
DROP TABLE tmyisam; |
|||
DROP TABLE tinnodb; |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue