mysql 中的 MVCC 原理流程

mysql 中的 MVCC 原理流程

mysql 事务中的多版本并发控制,属于链式结构一般称为版本链,mysql 其中的2个隔离级别(读已提交,可重复读)就是根据mvcc实现的。

流程:

​ 如果一张表中有字段 id=1 name =张三

  • 当事务A 开始的时候,会在undo log 中加入一行数据,相当于快照,用来保存即将要修改的原始数据,然后事务A修改了某一行数据 比如id=1, 将name改成李四, 那么就会在undo log 中再生成一行数据,数据中是有2个隐式字段的,一个trx_id保存操作当前这条数据的事务id,一个roll_pointer保存上一个事务的回滚指针;

  • 然后事务B也开始了,也同样操作id=1的数据,将name 改为王五 ,此时事务A 还没有结束,那undo log 中又会插入一行记录,其中roll_pointer 就会指向上一个undo log 的操作记录;

  • 当又有一个查询事务过来,要读取 id=1 的那行数据,那到底会读取张三李四王五哪一个呢 ,这里就会有一个ReadView 读已提交,可重复读 这个2个之间的不同就是提现在这里;

  • readView 这个是视图用来保存当前正在活动的事务,就是begin了,但是没有commit的事务,通过这个判断事务对外可见,readView保存的事务id是一个集合,事务是按照时间顺序从小到大排列的,

    • 当要访问的事务小于readView 中的最小id时,代表这个事务已经commit了 可以访问
    • 当要访问的事务大于等于 readView中最小 并且小于等于readView 最大时,再判断要访问的事务是否存在其中,如果存在,不能访问,否则可以访问
    • 当要访问的事务大于readView 中的最大值得时候,说明事务正正运行,还没来的急在readView 中提现,所以不让访问
  • 这些记录都是从undo log 版本链中找,从最大的开始找,如果在readView 中存在那就继续找上一个版本,知道满足以上的可以访问的区间

  • 如果是读已提交的,那每次都会获得一个新的ReadView,里面保存的事务id 都会更新,每次读取就可能不一样;如果是可重复读,每次读取都会按照第一个的ReadView 来判断,自会生成一个ReadView,所以每次读取的数据都是一样的;

  • 所以读已提交,可重复读 是怎么实现,就是根据ReadView 的生成策略不同,导致ReadView 范围的不同实现的

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值