此答案节选自鸭鸭最近弄的面试鸭小程序,更多大厂常问面试题,可以点击下面的小程序进行阅读哈!
MySQL 默认的隔离级别是可重复读( Repeatable Read ),即 RR。
原因是为了兼容早期 binlog 的 statement 格式问题,如果是使用读已提交、读未提交等隔离级别,使用了 statement 格式的 binlog 会导致主从(备)数据库数据不一致问题。
以上就是答案。
接下来我们来展开讲解下,便于大家理解。
MySQL 在使用过程中,为了避免单台故障,需要使用主从(备)机制:
而 MySQL 的主从(备)涉及 binlog 的复制,即从(备)库的数据是通过 binlog 从主库复制过来的。
在早期,MySQL binlog 仅支持 statement 格式,这个格式其实存的就是原先的SQL 语句,这就使得在读未提交(ru)和读提交(rc)两种隔离级别下会出问题。
我们来实际看个例子:
例如有两个事务 A 和 B ,以下图的时间顺序执行:
在读已提交隔离级别且手动提交事务的情况下, 插入的 5 这条记录会被保留。
但是由于事务 B 先提交,所以它会先被记录在 binlog 中,这个操作就导致了问题。
binlog 的记录顺序是:
使得从库同步 binlog 重放的时候,先执行了 insert 再执行 delete,这就使得从库的数据与主库不一致了!, 5 这条记录也会被删除了。
所以,为了避免这个问题,只能默认为可重复读级别。因为这个隔离级别下有间隙锁(Gap Locks)、临键锁(Next-Key Locks),所以事务 B 是无法先提交的,会被事务 A 阻塞,因此 binlog 的记录只能是先 delete 再 insert ,这样就没问题了。
最后再推荐下鸭鸭目前努力在做面试小程序神器,已经有 1600 多道面试题目啦,欢迎大家来阅读!如果大家有不会的面试题,也可以在小程序内反馈!鸭鸭会第一时间为大家解答!
欢迎大家来阅读!如果大家有不会的面试题,也可以在小程序内反馈!鸭鸭会第一时间为大家解答!
我是鸭鸭,我们下期见~