• mysql MVCC+间隙锁解决幻读理解


    mysql的隔离级别?

    读未提交  -》 读提交 -》 可重复读 -》 串行化

    InnoDB默认级别为可重复读,可重复读会产生问题 就是幻读。

    什么是幻读?

    不可重复读侧重于update这种操作,同一条数据前后读起来不一样的情况,

    幻读侧重于insert delete这种操作,前后两次select 数据的数量会发生变化

    举个例子:

    事务A  第一步  select *       第二步  update 所有字段        第三步  再次select *      

    事务B  执行了insert 一条语句

    幻读第一种情况: 当事务A 刚执行完第一步,事务B insert一条,导致事务A update执行完,再次select发现多了一条数据

    幻读第二种情况: 当事务A 刚执行完第二步,事务B insert一条,导致事务A 再次select 发现有一条数据没有update字段

    InnoDB如何解决幻读的?

    Mvcc+行锁+间隙锁

    什么是间隙锁?

    正常等值条件 并且值存在的情况下加的是行锁

    如果等值条件 值不存在的情况下加的是间隙锁,或者范围查询,加的也是间隙锁

    举个例子:

    根据主键id,不只是有五个行锁,还会有六个间隙锁,左开右闭原则,(-∞,5](5,10](10,15](15,20](20,25](25,+supernum]

    例如 select * from table where id = 10 for update;   等值条件,id是存在的,加行锁就可以了

    select * from table where id = 7 for update;  等值条件,id不存在,加(5,10] 间隙锁,这范围间不允许插入数据,直到这个事务提交完成释放锁

    select * from table where id > 24;  范围条件,加间隙锁

    通过行锁+间隙锁的机制保证了事务A select之后,其他事务相应的insert操作会阻塞

    什么是undolog? 

    undolog存放不同事务版本下的不同数据,

    用于 1.历史恢复 通过undolog恢复之前版本的数据   2. 读老版本  根据条件读旧版本的数据

    每次数据变更都会产生undolog记录,undolog记录分为 insert undo_log 和 update undo_log

    insert操作属于insert undo_log,只针对当前事务,在insert操作后产生undo_log记录,在事务提交后删除undo_log记录,说白了就是给当前事务自己看的.

    update 和 delete操作属于update undo_log,会根据隔离级别不同事务版本的数据可见性不同

    什么是readView?

    快照    存放了当前活跃的一些事务版本号,以及上一个版本的地址.     用来做可见性判断

    readview根据生成时间不同,产生了RC,RR两种可见性

    RC:每条select创建一个新的readview  ,所以导致读提交  读到的都是最新提交的!

    RR:事务开始的时候创建一个readview, 一直到事务结束都用的这个readview,也就避免了不可重复读

    当前读与快照读

    单条普通的select语句属于快照读

    select for update  , insert, update, delete 属于当前读

    快照读由mvcc+undolog实现

    当前读由行锁+间隙锁实现

    什么是MVCC?

    多版本并发控制(Multi-Version Concurrency Control, MVCC)

    仅在读提交可重复读两种隔离级别下生效

    每行记录字段都保存有  一个最近变更事务Id  一个最新删除的事务Id

    事务读数据的原则就是: 读版本号小于等于当前版本的数据(意思就是读不到在当前事务之后修改的数据 避免了不可重复读)

                读删除事务版本号大于等于当前版本的数据(意思就是如果这条数据在之后的事务里删了,当前事务也不能再读了) 

    InnoDB实现mvcc 是通过 readview+undolog 来实现

  • 相关阅读:
    SQL慢查询安装过程
    grafana + influxdb + telegraf , 构建性能监控平台
    JDK安装、java环境配置
    多源最短路Floyd 算法————matlab实现
    单源最短路Dijkstra算法——matlab实现
    Layout基本属性总结
    Scrollview中嵌套ListView(自定义组件解决)
    SQL 一列拆分多行
    C# 在异步中使用HttpWebRequest出现的“正在终止线程”错误的解决方案
    sqlserver中分区函数 partition by与 group by 区别 删除关键字段重复列
  • 原文地址:https://www.cnblogs.com/ttaall/p/14339130.html
Copyright © 2020-2023  润新知