mirror of
https://github.com/MariaDB/server.git
synced 2025-01-31 19:11:46 +01:00
Merge ssandberg@bk-internal.mysql.com:/home/bk/mysql-5.0-rpl
into riska.(none):/home/sven/bk/b26395-autocommit-xa/5.0-rpl
This commit is contained in:
commit
72676b226b
10 changed files with 331 additions and 73 deletions
|
@ -100,9 +100,10 @@ insert into t1 values(9);
|
|||
insert into t2 select * from t1;
|
||||
show binlog events from 98;
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
master-bin.000001 98 Query 1 # use `test`; insert into t1 values(9)
|
||||
master-bin.000001 185 Xid 1 # COMMIT /* XID */
|
||||
master-bin.000001 212 Query 1 # use `test`; insert into t2 select * from t1
|
||||
master-bin.000001 98 Query 1 # use `test`; BEGIN
|
||||
master-bin.000001 166 Query 1 # use `test`; insert into t1 values(9)
|
||||
master-bin.000001 253 Xid 1 # COMMIT /* XID */
|
||||
master-bin.000001 280 Query 1 # use `test`; insert into t2 select * from t1
|
||||
delete from t1;
|
||||
delete from t2;
|
||||
reset master;
|
||||
|
@ -111,19 +112,21 @@ begin;
|
|||
insert into t2 select * from t1;
|
||||
show binlog events from 98;
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
master-bin.000001 98 Query 1 # use `test`; insert into t1 values(10)
|
||||
master-bin.000001 186 Xid 1 # COMMIT /* XID */
|
||||
master-bin.000001 213 Query 1 # use `test`; insert into t2 select * from t1
|
||||
master-bin.000001 98 Query 1 # use `test`; BEGIN
|
||||
master-bin.000001 166 Query 1 # use `test`; insert into t1 values(10)
|
||||
master-bin.000001 254 Xid 1 # COMMIT /* XID */
|
||||
master-bin.000001 281 Query 1 # use `test`; insert into t2 select * from t1
|
||||
insert into t1 values(11);
|
||||
commit;
|
||||
show binlog events from 98;
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
master-bin.000001 98 Query 1 # use `test`; insert into t1 values(10)
|
||||
master-bin.000001 186 Xid 1 # COMMIT /* XID */
|
||||
master-bin.000001 213 Query 1 # use `test`; insert into t2 select * from t1
|
||||
master-bin.000001 307 Query 1 # use `test`; BEGIN
|
||||
master-bin.000001 375 Query 1 # use `test`; insert into t1 values(11)
|
||||
master-bin.000001 463 Xid 1 # COMMIT /* XID */
|
||||
master-bin.000001 98 Query 1 # use `test`; BEGIN
|
||||
master-bin.000001 166 Query 1 # use `test`; insert into t1 values(10)
|
||||
master-bin.000001 254 Xid 1 # COMMIT /* XID */
|
||||
master-bin.000001 281 Query 1 # use `test`; insert into t2 select * from t1
|
||||
master-bin.000001 375 Query 1 # use `test`; BEGIN
|
||||
master-bin.000001 443 Query 1 # use `test`; insert into t1 values(11)
|
||||
master-bin.000001 531 Xid 1 # COMMIT /* XID */
|
||||
alter table t2 engine=INNODB;
|
||||
delete from t1;
|
||||
delete from t2;
|
||||
|
@ -235,25 +238,29 @@ master-bin.000001 98 Query 1 # use `test`; BEGIN
|
|||
master-bin.000001 166 Query 1 # use `test`; insert into t1 values(16)
|
||||
master-bin.000001 254 Query 1 # use `test`; insert into t1 values(18)
|
||||
master-bin.000001 342 Xid 1 # COMMIT /* XID */
|
||||
master-bin.000001 369 Query 1 # use `test`; delete from t1
|
||||
master-bin.000001 446 Xid 1 # COMMIT /* XID */
|
||||
master-bin.000001 473 Query 1 # use `test`; delete from t2
|
||||
master-bin.000001 550 Xid 1 # COMMIT /* XID */
|
||||
master-bin.000001 577 Query 1 # use `test`; alter table t2 type=MyISAM
|
||||
master-bin.000001 666 Query 1 # use `test`; insert into t1 values (1)
|
||||
master-bin.000001 754 Xid 1 # COMMIT /* XID */
|
||||
master-bin.000001 781 Query 1 # use `test`; insert into t2 values (20)
|
||||
master-bin.000001 870 Query 1 # use `test`; drop table t1,t2
|
||||
master-bin.000001 949 Query 1 # use `test`; create temporary table ti (a int) engine=innodb
|
||||
master-bin.000001 1059 Query 1 # use `test`; insert into ti values(1)
|
||||
master-bin.000001 1146 Xid 1 # COMMIT /* XID */
|
||||
master-bin.000001 1173 Query 1 # use `test`; create temporary table t1 (a int) engine=myisam
|
||||
master-bin.000001 1283 Query 1 # use `test`; insert t1 values (1)
|
||||
master-bin.000001 1366 Query 1 # use `test`; create table t0 (n int)
|
||||
master-bin.000001 1452 Query 1 # use `test`; insert t0 select * from t1
|
||||
master-bin.000001 1541 Query 1 # use `test`; insert into t0 select GET_LOCK("lock1",null)
|
||||
master-bin.000001 1648 Query 1 # use `test`; create table t2 (n int) engine=innodb
|
||||
master-bin.000001 1748 Query 1 # use `test`; DROP /*!40005 TEMPORARY */ TABLE IF EXISTS `test`.`t1`,`test`.`ti`
|
||||
master-bin.000001 369 Query 1 # use `test`; BEGIN
|
||||
master-bin.000001 437 Query 1 # use `test`; delete from t1
|
||||
master-bin.000001 514 Xid 1 # COMMIT /* XID */
|
||||
master-bin.000001 541 Query 1 # use `test`; BEGIN
|
||||
master-bin.000001 609 Query 1 # use `test`; delete from t2
|
||||
master-bin.000001 686 Xid 1 # COMMIT /* XID */
|
||||
master-bin.000001 713 Query 1 # use `test`; alter table t2 type=MyISAM
|
||||
master-bin.000001 802 Query 1 # use `test`; BEGIN
|
||||
master-bin.000001 870 Query 1 # use `test`; insert into t1 values (1)
|
||||
master-bin.000001 958 Xid 1 # COMMIT /* XID */
|
||||
master-bin.000001 985 Query 1 # use `test`; insert into t2 values (20)
|
||||
master-bin.000001 1074 Query 1 # use `test`; drop table t1,t2
|
||||
master-bin.000001 1153 Query 1 # use `test`; create temporary table ti (a int) engine=innodb
|
||||
master-bin.000001 1263 Query 1 # use `test`; BEGIN
|
||||
master-bin.000001 1331 Query 1 # use `test`; insert into ti values(1)
|
||||
master-bin.000001 1418 Xid 1 # COMMIT /* XID */
|
||||
master-bin.000001 1445 Query 1 # use `test`; create temporary table t1 (a int) engine=myisam
|
||||
master-bin.000001 1555 Query 1 # use `test`; insert t1 values (1)
|
||||
master-bin.000001 1638 Query 1 # use `test`; create table t0 (n int)
|
||||
master-bin.000001 1724 Query 1 # use `test`; insert t0 select * from t1
|
||||
master-bin.000001 1813 Query 1 # use `test`; insert into t0 select GET_LOCK("lock1",null)
|
||||
master-bin.000001 1920 Query 1 # use `test`; create table t2 (n int) engine=innodb
|
||||
master-bin.000001 2020 Query 1 # use `test`; DROP /*!40005 TEMPORARY */ TABLE IF EXISTS `test`.`t1`,`test`.`ti`
|
||||
do release_lock("lock1");
|
||||
drop table t0,t2;
|
||||
reset master;
|
||||
|
@ -402,7 +409,7 @@ insert into t2 values (bug27417(1));
|
|||
ERROR 23000: Duplicate entry '1' for key 1
|
||||
show master status /* the offset must denote there is the query */;
|
||||
File Position Binlog_Do_DB Binlog_Ignore_DB
|
||||
master-bin.000001 267
|
||||
master-bin.000001 335
|
||||
select count(*) from t1 /* must be 1 */;
|
||||
count(*)
|
||||
1
|
||||
|
@ -414,7 +421,7 @@ insert into t2 select bug27417(1) union select bug27417(2);
|
|||
ERROR 23000: Duplicate entry '2' for key 1
|
||||
show master status /* the offset must denote there is the query */;
|
||||
File Position Binlog_Do_DB Binlog_Ignore_DB
|
||||
master-bin.000001 290
|
||||
master-bin.000001 358
|
||||
select count(*) from t1 /* must be 2 */;
|
||||
count(*)
|
||||
2
|
||||
|
@ -438,7 +445,7 @@ UPDATE t4,t3 SET t4.a=t3.a + bug27417(1) /* top level non-ta table */;
|
|||
ERROR 23000: Duplicate entry '2' for key 1
|
||||
show master status /* the offset must denote there is the query */;
|
||||
File Position Binlog_Do_DB Binlog_Ignore_DB
|
||||
master-bin.000001 301
|
||||
master-bin.000001 369
|
||||
select count(*) from t1 /* must be 4 */;
|
||||
count(*)
|
||||
4
|
||||
|
@ -466,7 +473,7 @@ delete from t2;
|
|||
ERROR 23000: Duplicate entry '1' for key 1
|
||||
show master status /* the offset must denote there is the query */;
|
||||
File Position Binlog_Do_DB Binlog_Ignore_DB
|
||||
master-bin.000001 246
|
||||
master-bin.000001 314
|
||||
select count(*) from t1 /* must be 1 */;
|
||||
count(*)
|
||||
1
|
||||
|
@ -483,7 +490,7 @@ delete t2.* from t2,t5 where t2.a=t5.a + 1;
|
|||
ERROR 23000: Duplicate entry '1' for key 1
|
||||
show master status /* the offset must denote there is the query */;
|
||||
File Position Binlog_Do_DB Binlog_Ignore_DB
|
||||
master-bin.000001 274
|
||||
master-bin.000001 342
|
||||
select count(*) from t1 /* must be 1 */;
|
||||
count(*)
|
||||
1
|
||||
|
@ -501,7 +508,7 @@ count(*)
|
|||
2
|
||||
show master status /* the offset must denote there is the query */;
|
||||
File Position Binlog_Do_DB Binlog_Ignore_DB
|
||||
master-bin.000001 376
|
||||
master-bin.000001 444
|
||||
drop trigger trg_del_t2;
|
||||
drop table t1,t2,t3,t4,t5;
|
||||
drop function bug27417;
|
||||
|
|
|
@ -545,7 +545,7 @@ a b
|
|||
4 4
|
||||
show master status /* there must be the UPDATE query event */;
|
||||
File Position Binlog_Do_DB Binlog_Ignore_DB
|
||||
master-bin.000001 260
|
||||
master-bin.000001 328
|
||||
delete from t1;
|
||||
delete from t2;
|
||||
insert into t1 values (1,2),(3,4),(4,4);
|
||||
|
@ -555,7 +555,7 @@ UPDATE t2,t1 SET t2.a=t2.b where t2.a=t1.a;
|
|||
ERROR 23000: Duplicate entry '4' for key 1
|
||||
show master status /* there must be the UPDATE query event */;
|
||||
File Position Binlog_Do_DB Binlog_Ignore_DB
|
||||
master-bin.000001 275
|
||||
master-bin.000001 343
|
||||
drop table t1, t2;
|
||||
drop table if exists t1, t2, t3;
|
||||
CREATE TABLE t1 (a int, PRIMARY KEY (a));
|
||||
|
|
95
mysql-test/r/rpl_transaction.result
Normal file
95
mysql-test/r/rpl_transaction.result
Normal file
|
@ -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;
|
|
@ -16,6 +16,7 @@ show binlog events from 98 /* with fixes for #23333 will show there are 2 querie
|
|||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
master-bin.000001 # Query 1 # #
|
||||
master-bin.000001 # Query 1 # #
|
||||
master-bin.000001 # Query 1 # #
|
||||
select count(*),@a from t1 /* must be 1,1 */|
|
||||
count(*) @a
|
||||
1 1
|
||||
|
|
|
@ -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
|
||||
|
|
1
mysql-test/t/rpl_transaction-master.opt
Normal file
1
mysql-test/t/rpl_transaction-master.opt
Normal file
|
@ -0,0 +1 @@
|
|||
--innodb --debug=d,do_not_write_xid
|
1
mysql-test/t/rpl_transaction-slave.opt
Normal file
1
mysql-test/t/rpl_transaction-slave.opt
Normal file
|
@ -0,0 +1 @@
|
|||
--innodb
|
106
mysql-test/t/rpl_transaction.test
Normal file
106
mysql-test/t/rpl_transaction.test
Normal file
|
@ -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;
|
82
sql/log.cc
82
sql/log.cc
|
@ -122,6 +122,20 @@ static int binlog_prepare(THD *thd, bool all)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
This function is called once after each statement.
|
||||
|
||||
It has the responsibility to flush the transaction cache to the
|
||||
binlog file on commits.
|
||||
|
||||
@param thd The client thread that executes the transaction.
|
||||
@param all true if this is the last statement before a COMMIT
|
||||
statement; false if either this is a statement in a
|
||||
transaction but not the last, or if this is a statement
|
||||
not inside a BEGIN block and autocommit is on.
|
||||
|
||||
@see handlerton::commit
|
||||
*/
|
||||
static int binlog_commit(THD *thd, bool all)
|
||||
{
|
||||
IO_CACHE *trans_log= (IO_CACHE*)thd->ha_data[binlog_hton.slot];
|
||||
|
@ -134,7 +148,15 @@ static int binlog_commit(THD *thd, bool all)
|
|||
// we're here because trans_log was flushed in MYSQL_LOG::log_xid()
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
if (all)
|
||||
/*
|
||||
Write commit event if at least one of the following holds:
|
||||
- the user sends an explicit COMMIT; or
|
||||
- the autocommit flag is on, and we are not inside a BEGIN.
|
||||
However, if the user has not sent an explicit COMMIT, and we are
|
||||
either inside a BEGIN or run with autocommit off, then this is not
|
||||
the end of a transaction and we should not write a commit event.
|
||||
*/
|
||||
if (all || !(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)))
|
||||
{
|
||||
Query_log_event qev(thd, STRING_WITH_LEN("COMMIT"), TRUE, FALSE);
|
||||
qev.error_code= 0; // see comment in MYSQL_LOG::write(THD, IO_CACHE)
|
||||
|
@ -144,6 +166,22 @@ static int binlog_commit(THD *thd, bool all)
|
|||
DBUG_RETURN(binlog_end_trans(thd, trans_log, &invisible_commit));
|
||||
}
|
||||
|
||||
/**
|
||||
This function is called when a transaction involving a transactional
|
||||
table is rolled back.
|
||||
|
||||
It has the responsibility to flush the transaction cache to the
|
||||
binlog file. However, if the transaction does not involve
|
||||
non-transactional tables, nothing needs to be logged.
|
||||
|
||||
@param thd The client thread that executes the transaction.
|
||||
@param all true if this is the last statement before a COMMIT
|
||||
statement; false if either this is a statement in a
|
||||
transaction but not the last, or if this is a statement
|
||||
not inside a BEGIN block and autocommit is on.
|
||||
|
||||
@see handlerton::rollback
|
||||
*/
|
||||
static int binlog_rollback(THD *thd, bool all)
|
||||
{
|
||||
int error=0;
|
||||
|
@ -1817,9 +1855,11 @@ uint MYSQL_LOG::next_file_id()
|
|||
IMPLEMENTATION
|
||||
- To support transaction over replication, we wrap the transaction
|
||||
with BEGIN/COMMIT or BEGIN/ROLLBACK in the binary log.
|
||||
We want to write a BEGIN/ROLLBACK block when a non-transactional table
|
||||
was updated in a transaction which was rolled back. This is to ensure
|
||||
that the same updates are run on the slave.
|
||||
If a transaction that only involves transactional tables is
|
||||
rolled back, we do not binlog it. However, we write a
|
||||
BEGIN/ROLLBACK block when a non-transactional table was updated
|
||||
in a transaction which was rolled back. This is to ensure that
|
||||
the same updates are run on the slave.
|
||||
*/
|
||||
|
||||
bool MYSQL_LOG::write(THD *thd, IO_CACHE *cache, Log_event *commit_event)
|
||||
|
@ -1837,32 +1877,34 @@ bool MYSQL_LOG::write(THD *thd, IO_CACHE *cache, Log_event *commit_event)
|
|||
byte header[LOG_EVENT_HEADER_LEN];
|
||||
|
||||
/*
|
||||
Log "BEGIN" at the beginning of the transaction.
|
||||
which may contain more than 1 SQL statement.
|
||||
Log "BEGIN" at the beginning of every transaction. Here, a
|
||||
transaction is either a BEGIN..COMMIT block or a single
|
||||
statement in autocommit mode.
|
||||
*/
|
||||
if (thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
|
||||
{
|
||||
Query_log_event qinfo(thd, STRING_WITH_LEN("BEGIN"), TRUE, FALSE);
|
||||
/*
|
||||
Imagine this is rollback due to net timeout, after all statements of
|
||||
the transaction succeeded. Then we want a zero-error code in BEGIN.
|
||||
In other words, if there was a really serious error code it's already
|
||||
in the statement's events, there is no need to put it also in this
|
||||
internally generated event, and as this event is generated late it
|
||||
would lead to false alarms.
|
||||
Imagine this is rollback due to net timeout, after all
|
||||
statements of the transaction succeeded. Then we want a
|
||||
zero-error code in BEGIN. In other words, if there was a
|
||||
really serious error code it's already in the statement's
|
||||
events, there is no need to put it also in this internally
|
||||
generated event, and as this event is generated late it would
|
||||
lead to false alarms.
|
||||
|
||||
This is safer than thd->clear_error() against kills at shutdown.
|
||||
*/
|
||||
qinfo.error_code= 0;
|
||||
/*
|
||||
Now this Query_log_event has artificial log_pos 0. It must be adjusted
|
||||
to reflect the real position in the log. Not doing it would confuse the
|
||||
slave: it would prevent this one from knowing where he is in the
|
||||
master's binlog, which would result in wrong positions being shown to
|
||||
the user, MASTER_POS_WAIT undue waiting etc.
|
||||
Now this Query_log_event has artificial log_pos 0. It must be
|
||||
adjusted to reflect the real position in the log. Not doing it
|
||||
would confuse the slave: it would prevent this one from
|
||||
knowing where he is in the master's binlog, which would result
|
||||
in wrong positions being shown to the user, MASTER_POS_WAIT
|
||||
undue waiting etc.
|
||||
*/
|
||||
if (qinfo.write(&log_file))
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Read from the file used to cache the queries .*/
|
||||
if (reinit_io_cache(cache, READ_CACHE, 0, 0, 0))
|
||||
goto err;
|
||||
|
|
|
@ -3793,6 +3793,7 @@ Xid_log_event(const char* buf,
|
|||
#ifndef MYSQL_CLIENT
|
||||
bool Xid_log_event::write(IO_CACHE* file)
|
||||
{
|
||||
DBUG_EXECUTE_IF("do_not_write_xid", return 0;);
|
||||
return write_header(file, sizeof(xid)) ||
|
||||
my_b_safe_write(file, (byte*) &xid, sizeof(xid));
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue