为什么mysql默认隔离级别是RR而不是RC
为什么mysql默认隔离级别是RR而不是RC
在 MySQL 的早期版本中,Binlog只有一种格式:statement,即记录 SQL 语句本身。
1. RC 级别下的“幻读”导致主从数据不一致
在 RC 隔离级别下,Binlog 记录的顺序是按照事务提交的先后顺序排列的,而不是 SQL 执行的先后顺序。
假设有两个事务同时操作:
- 事务 A:
DELETE FROM users WHERE age < 20;(未提交) - 事务 B:
INSERT INTO users (name, age) VALUES ('Tom', 15); COMMIT; - 事务 A:
COMMIT;
在主库(Master)上的结果: 事务 A 执行时,由于是 RC 级别,它只能删除执行那一刻已存在的数据。Tom 是在 A 执行中途插入的,所以 Tom 不会被删除。最终主库里留下了 Tom 这条记录。
在从库(Slave)上的结果: 从库根据 Binlog 顺序回放:先执行 INSERT,再执行 DELETE。结果从库中的 Tom 被删除了。
结论: 这种情况下,主库有数据,从库没数据,导致了严重的数据漂移。
2. RR 级别如何解决?
MySQL 的 RR 级别引入了 间隙锁(Gap Lock)。 在上述场景中,当事务 A 执行 DELETE 语句时,RR 级别不仅会锁住符合条件的行,还会锁住 age < 20 这个范围的“间隙”。此时事务 B 的 INSERT 会被阻塞,直到事务 A 提交。
这样 Binlog 中记录的顺序就会变成:DELETE 先完成并记录,INSERT 后记录。主从逻辑完全一致。
为什么mysql默认隔离级别是RR而不是RC
http://example.com/2026/04/01/为什么mysql默认隔离级别是RR而不是RC/