Commit c8c4500a authored by mats@mats-laptop.(none)'s avatar mats@mats-laptop.(none)
Browse files

BUG#29020 (Event results not correctly replicated to slave in RBR):

The bug allow multiple executing transactions working with non-transactional
to interfere with each others by interleaving the events of different trans-
actions.

Bug is fixed by writing non-transactional events to the transaction cache and
flushing the cache to the binary log at statement commit. To mimic the behavior
of normal statement-based replication, we flush the transaction cache in row-
based mode when there is no committed statements in the transaction cache,
which means we are committing the first one. This means that it will be written
to the binary log as a "mini-transaction" with just the rows for the statement.

Note that the changes here does not take effect when building the server with
HAVE_TRANSACTIONS set to false, but it is not clear if this was possible before
this patch either.

For row-based logging, we also have that when AUTOCOMMIT=1, the code now always
generates a BEGIN/COMMIT pair for single statements, or BEGIN/ROLLBACK pair in the
case of non-transactional changes in a statement that was rolled back. Note that
for the case where changes to a non-transactional table causes a rollback due
to error, the statement will now be logged with a BEGIN/ROLLBACK pair, even
though some changes has been committed to the non-transactional table.
parent 51ad2901
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -15,7 +15,6 @@ SELECT * FROM t1 ORDER BY a;
sync_slave_with_master;

connection master;
source include/show_binlog_events.inc;
sync_slave_with_master;
SELECT * FROM t1 ORDER BY a;
connection master;
+2 −0
Original line number Diff line number Diff line
@@ -9,8 +9,10 @@ EXECUTE stmt1 USING @var1;
show binlog events from <binlog_start>;
Log_name	Pos	Event_type	Server_id	End_log_pos	Info
master-bin.000001	#	Query	#	#	use `test`; CREATE TABLE t1(f1 blob)
master-bin.000001	#	Query	#	#	use `test`; 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	#	#	use `test`; COMMIT
SELECT HEX(f1) FROM t1;
HEX(f1)
8300
+1 −0
Original line number Diff line number Diff line
DROP TABLE IF EXISTS t1;
==== Test BUG#32407 ====
select * from t1;
a
+2 −0
Original line number Diff line number Diff line
@@ -78,8 +78,10 @@ UPDATE t1n, t1b SET e = 2, b = 3 WHERE f = c;
ERROR HY000: Binary logging not possible. Message: Row-based format required for this statement, but not allowed by this combination of engines
show binlog events from <binlog_start>;
Log_name	Pos	Event_type	Server_id	End_log_pos	Info
master-bin.000001	#	Query	#	#	use `test`; BEGIN
master-bin.000001	#	Table_map	#	#	table_id: # (test.t1m)
master-bin.000001	#	Write_rows	#	#	table_id: # flags: STMT_END_F
master-bin.000001	#	Query	#	#	use `test`; COMMIT
master-bin.000001	#	Query	#	#	BEGIN
master-bin.000001	#	Table_map	#	#	table_id: # (test.t1n)
master-bin.000001	#	Table_map	#	#	table_id: # (mysql.ndb_apply_status)
+27 −3
Original line number Diff line number Diff line
@@ -1085,9 +1085,11 @@ show binlog events from 0;
Log_name	Pos	Event_type	Server_id	End_log_pos	Info
master-bin.000001	4	Format_desc	1	106	Server version, Binlog ver: 4
master-bin.000001	106	Query	1	227	use `test`; create table t1 (a bigint unsigned, b bigint(20) unsigned)
master-bin.000001	227	Table_map	1	269	table_id: # (test.t1)
master-bin.000001	269	Write_rows	1	315	table_id: # flags: STMT_END_F
master-bin.000001	315	Query	1	391	use `test`; drop table t1
master-bin.000001	227	Query	1	295	use `test`; BEGIN
master-bin.000001	295	Table_map	1	337	table_id: # (test.t1)
master-bin.000001	337	Write_rows	1	383	table_id: # flags: STMT_END_F
master-bin.000001	383	Query	1	452	use `test`; COMMIT
master-bin.000001	452	Query	1	528	use `test`; drop table t1
End of 5.0 tests
reset master;
create table t1 (id tinyint auto_increment primary key);
@@ -1111,8 +1113,10 @@ use test;
show binlog events from <binlog_start>;
Log_name	Pos	Event_type	Server_id	End_log_pos	Info
master-bin.000001	#	Query	#	#	use `test`; create table t1 (id tinyint auto_increment primary key)
master-bin.000001	#	Query	#	#	use `test`; 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	#	#	use `test`; COMMIT
master-bin.000001	#	Query	#	#	use `test`; drop table t1
master-bin.000001	#	Query	#	#	use `test`; create table t1 (a int)
master-bin.000001	#	Query	#	#	use `test`; BEGIN
@@ -1123,12 +1127,18 @@ master-bin.000001 # Query # # use `test`; COMMIT
master-bin.000001	#	Query	#	#	use `test`; CREATE TABLE IF NOT EXISTS `t3` (
  `a` int(11) DEFAULT NULL
)
master-bin.000001	#	Query	#	#	use `mysql`; BEGIN
master-bin.000001	#	Table_map	#	#	table_id: # (mysql.user)
master-bin.000001	#	Write_rows	#	#	table_id: # flags: STMT_END_F
master-bin.000001	#	Query	#	#	use `mysql`; COMMIT
master-bin.000001	#	Query	#	#	use `mysql`; BEGIN
master-bin.000001	#	Table_map	#	#	table_id: # (mysql.user)
master-bin.000001	#	Update_rows	#	#	table_id: # flags: STMT_END_F
master-bin.000001	#	Query	#	#	use `mysql`; COMMIT
master-bin.000001	#	Query	#	#	use `mysql`; BEGIN
master-bin.000001	#	Table_map	#	#	table_id: # (mysql.user)
master-bin.000001	#	Delete_rows	#	#	table_id: # flags: STMT_END_F
master-bin.000001	#	Query	#	#	use `mysql`; COMMIT
drop table t1,t2,t3,tt1;
create table t1 (a int not null auto_increment, primary key (a)) engine=myisam;
set @@session.auto_increment_increment=1, @@session.auto_increment_offset=1;
@@ -1138,8 +1148,10 @@ insert delayed into t1 values (300);
show binlog events from <binlog_start>;
Log_name	Pos	Event_type	Server_id	End_log_pos	Info
master-bin.000001	#	Query	#	#	use `test`; create table t1 (id tinyint auto_increment primary key)
master-bin.000001	#	Query	#	#	use `test`; 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	#	#	use `test`; COMMIT
master-bin.000001	#	Query	#	#	use `test`; drop table t1
master-bin.000001	#	Query	#	#	use `test`; create table t1 (a int)
master-bin.000001	#	Query	#	#	use `test`; BEGIN
@@ -1150,20 +1162,32 @@ master-bin.000001 # Query # # use `test`; COMMIT
master-bin.000001	#	Query	#	#	use `test`; CREATE TABLE IF NOT EXISTS `t3` (
  `a` int(11) DEFAULT NULL
)
master-bin.000001	#	Query	#	#	use `mysql`; BEGIN
master-bin.000001	#	Table_map	#	#	table_id: # (mysql.user)
master-bin.000001	#	Write_rows	#	#	table_id: # flags: STMT_END_F
master-bin.000001	#	Query	#	#	use `mysql`; COMMIT
master-bin.000001	#	Query	#	#	use `mysql`; BEGIN
master-bin.000001	#	Table_map	#	#	table_id: # (mysql.user)
master-bin.000001	#	Update_rows	#	#	table_id: # flags: STMT_END_F
master-bin.000001	#	Query	#	#	use `mysql`; COMMIT
master-bin.000001	#	Query	#	#	use `mysql`; BEGIN
master-bin.000001	#	Table_map	#	#	table_id: # (mysql.user)
master-bin.000001	#	Delete_rows	#	#	table_id: # flags: STMT_END_F
master-bin.000001	#	Query	#	#	use `mysql`; COMMIT
master-bin.000001	#	Query	#	#	use `test`; DROP TABLE `t1`,`t2`,`t3` /* generated by server */
master-bin.000001	#	Query	#	#	use `test`; create table t1 (a int not null auto_increment, primary key (a)) engine=myisam
master-bin.000001	#	Query	#	#	use `test`; 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	#	#	use `test`; COMMIT
master-bin.000001	#	Query	#	#	use `test`; 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	#	#	use `test`; COMMIT
master-bin.000001	#	Query	#	#	use `test`; 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	#	#	use `test`; COMMIT
insert delayed into t1 values (null),(null),(null),(null);
insert delayed into t1 values (null),(null),(400),(null);
11 == 11
Loading