先说结论:
对于之前没有row格式的binlog的情况下,如果隔离级别是rc,有可能导致主从数据不一样。
例子:
隔离级别为rc,binlog格式为statement
select * from a;
b
---
1
2
3
4
5
session 1:
begin;
delete from a where b<=5;
session 2:
begin;
insert into a select 3;
commit;
session 1:
commit;
主库:
select * from a;
b
----
3
从库:
select * from a;
empty set
此时的数据是不一样的。
原因:
(1)在rc隔离级别下,事务没有gap lock锁,因此可以在小于等于5的范围内插入一条新记录。
(2)binlog为statement记录的是master上产生的sql语句,按提交顺序记录的,因此binlog中记录的是先插入数据,后删除数据。(虽然master上是先删除数据后插入数据),逻辑上产生了不一致。
如何解决:
只需要解决上述问题中的一个就能保证数据的同步了。
(1)可以使用rr隔离级别;
(2)使用row格式的binlog;
对于之前没有row格式的binlog的情况下,如果隔离级别是rc,有可能导致主从数据不一样。
例子:
隔离级别为rc,binlog格式为statement
select * from a;
b
---
1
2
3
4
5
session 1:
begin;
delete from a where b<=5;
session 2:
begin;
insert into a select 3;
commit;
session 1:
commit;
主库:
select * from a;
b
----
3
从库:
select * from a;
empty set
此时的数据是不一样的。
原因:
(1)在rc隔离级别下,事务没有gap lock锁,因此可以在小于等于5的范围内插入一条新记录。
(2)binlog为statement记录的是master上产生的sql语句,按提交顺序记录的,因此binlog中记录的是先插入数据,后删除数据。(虽然master上是先删除数据后插入数据),逻辑上产生了不一致。
如何解决:
只需要解决上述问题中的一个就能保证数据的同步了。
(1)可以使用rr隔离级别;
(2)使用row格式的binlog;