为什么mysql默认隔离级别是RR而不是RC

为什么mysql默认隔离级别是RR而不是RC

在 MySQL 的早期版本中,Binlog只有一种格式:statement,即记录 SQL 语句本身。

1. RC 级别下的“幻读”导致主从数据不一致

在 RC 隔离级别下,Binlog 记录的顺序是按照事务提交的先后顺序排列的,而不是 SQL 执行的先后顺序。

假设有两个事务同时操作:

  • 事务 ADELETE FROM users WHERE age < 20;(未提交)
  • 事务 BINSERT INTO users (name, age) VALUES ('Tom', 15); COMMIT;
  • 事务 ACOMMIT;

在主库(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/
作者
Kon4tsu
发布于
2026年4月1日
许可协议