专题-子项-1-mysqlf-默认隔离级别为什么是可重复读?为什么业务代码建议用读已提交?

7 篇文章 0 订阅
5 篇文章 0 订阅

经典参考:https://blog.csdn.net/java_collect/article/details/105042975

binlog有几种格式?

三种,分别是
----statement:记录的是修改SQL语句(事物没提交也会记录,如果回滚则擦除)
----row:记录的是每行实际数据的变更(事物提交后的才算)
----mixed:statement和row模式的混合。
Mysql在5.0这个版本以前binlog只支持STATEMENT这种格式!而这种格式在读已提交(Read Commited)这个隔离级别下主从复制是有bug的,因此Mysql将可重复读(Repeatable Read)作为默认的隔离级别!

binlog=STATEMENT,在读已提交下,主从复制有什么bug

主从不一致性的问题!原因其实很简单,就是在master上执行的顺序为先删后插!而此时binlog为STATEMENT格式,它记录的顺序为先插后删!从(slave)同步的是binglog,因此从机执行的顺序和主机不一致!
读已提交情况下,binglog从管把执行的sql按顺序排列,不会管提交先后的顺序;可重复读有间隙锁,执行binglog的第二个会话内容时会锁等待

如何解决主从复制的bug

解决方案有两种!
(1)改用可重复读(Repeatable Read),在该隔离级别下本身会引入间隙锁。当Session 1执行delete语句时,会锁住间隙条件范围。那么,Ssession 2执行插入语句就会阻塞住!
(2)还用读已提交,但将binglog的格式修改为row格式,此时是基于行的复制,自然就不会出现sql执行顺序不一样的问题!奈何这个格式在mysql5.1版本开始才引入。因此由于历史原因,mysql将默认的隔离级别设为可重复读(Repeatable Read),保证主从复制不出问题!

 

选读已提交的原因

1)、repeatable存在间隙锁会使死锁的概率增大;
2)、在RR可重复读隔离级别下,条件列未命中索引会锁表!而在RC隔离级别下,只锁行;

在RR隔离级别下,走聚簇索引,进行全部扫描,最后会将整个表锁上;
在RC隔离级别下,其先走聚簇索引,进行全部扫描,但MySQL做了优化,在MySQL Server过滤条件,发现不满足后,会调用unlock_row方法,把不满足条件的记录放锁。

3)、在RC隔离级别下,引入半一致性读(semi-consistent)特性增加了update操作的性能

半一致性读就是,一个update语句,如果读到一行已经加锁的记录,此时InnoDB返回记录最近提交的版本,由MySQL上层判断此版本是否满足update的where条件。若满足(需要更新),则MySQL会重新发起一次读操作,此时会读取行的最新版本(并加锁)

 

 

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

java_爱吃肉

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值