mysql的statement模式主从不一致分析
what:
mysql中binglog使用statement模式会出现,数据同步时:主从数据不一致问题。
why:
主要原因有两个:
1、记录的sql上下文不全,例如:下面例子的RC场景;
2、mysql版本迭代,新功能加入,导致不同版本之间的能力不同,从而导致数据不一致。例如:sleep函数在老版本中没有。
具体例子(sql上下文不全):
说下MySQL5.0之前为啥事务的隔离机制是RC('read-committed)并且存储格式是Statement时会出现主从复制数据不一致问题。
创建表:
把自动提交关闭 执行两个会话:
此时查看会话1的提交结果:
dba> select * from t1;
+------+------+
| b1 | b2 |
+------+------+
| 1 | 4 |
| 2 | 8 |
| 3 | 4 |
| 4 | 8 |
| 5 | 4 |
+------+------+
5 rows in set (0.00 sec)
这个结果不会有任何问题。
STATEMENT模式下的主从情况:
假设在RC隔离级别下支持STATEMENT格式的binlog,并且binlog是打开的。binlog的记录顺序是按照事务commit顺序为序的。那么显而易见,binlog中的顺序为:
会话2:
dba> set tx_isolation='read-committed';
dba> BEGIN;
dba> update t1 set b2=4 where b2=2;
dba> commit;
会话1:
dba> set tx_isolation='read-committed';
dba> BEGIN;(开启事务)
dba> update t1 set b2=8 where b2=4;
#会话1进行提交
dba> commit;
那么此时在主从复制的从库上看到的结果应为:
dba> select * from t1;
+------+------+
| b1 | b2 |
+------+------+
| 1 | 8 |
| 2 | 8 |
| 3 | 8 |
| 4 | 8 |
| 5 | 8 |
+------+------+
5 rows in set (0.00 sec)
可见,在RC隔离级别下,如果支持STATEMENT格式的binlog,是有可能导致主从数据不一致的!
Row和mixed的模式情况:
那么你可能会问,在RC隔离级别下,如果binlog格式为ROW或者MIXED,难道就不会有主从数据不一致的风险吗?答案是肯定的,如果binlog的格式是ROW或者MIXED,在RC隔离级别下,不会导致主从数据不一致。为什么呢?
因为ROW或者MIXED格式的binlog,是基于数据的变动。在进行update或者delete操作,记录到binlog,同时会把数据的原始记录写入到binlog。所以日志文件会比Statement大些,上述演示过程,binlog的记录顺序仍然是按照事务的commit顺序为序的,binlog的顺序仍然为:
会话2:
dba> set tx_isolation='read-committed';
dba> BEGIN;
dba> update t1 set b2=4 where b2=2;
dba> commit;
会话1:
dba> set tx_isolation='read-committed';
dba> BEGIN;(开启事务)
dba> update t1 set b2=8 where b2=4;
#会话1进行提交
dba> commit;
在从库仍然是按照这个binlog的执行时序,进行更新操作。但不同之处在于。会话2的update操作:
dba> update t1 set b2=4 where b2=2;
写入到binlog时,会把原始的记录也记录下来。它是这样记录的:
update dba.t1
where
b1=1
b2=2
set
b1=1
b2=4
update dba.t1
where
b1=3
b2=2
set
b1=3
b2=4
update dba.t1
where
b1=5
b2=2
set
b1=5
b2=4
从库上会话2的更新操作完成之后,接着执行会话1的更新操作:
dba> update t1 set b2=8 where b2=4;
binlog中的记录为:
update dba.t1
where
b1=2
b2=4
set
b1=2
b2=8
update dba.t1
where
b1=4
b2=4
set
b1=4
b2=8
这样从库看到的结果就是:
dba> select * from t1;
+------+------+
| b1 | b2 |
+------+------+
| 1 | 4 |
| 2 | 8 |
| 3 | 4 |
| 4 | 8 |
| 5 | 4 |
+------+------+
5 rows in set (0.00 sec)
这样,主从数据就是一致的。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· .NET Core 中如何实现缓存的预热?
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 如何调用 DeepSeek 的自然语言处理 API 接口并集成到在线客服系统
· 【译】Visual Studio 中新的强大生产力特性