数据库——多版本并发控制

MVCC

基本概念

  1. 系统版本号:每当启动一个事务时,系统版本号会递增。
  2. 事务版本号:事务开始时的系统版本号作为事务版本号,用于在select操作中与记录的DATA_TRX_ID字段做对比
  3. 记录的隐藏列
    • DATA_TRX_ID:记录某行记录的系统版本号,每当事务commit对该行的修改操作时事务的版本号记录。
    • DATA_ROLL_PTR:记录了此行记录的回滚记录指针,通过它召回历史版本。
    • DELETE BIT:标记此记录是否有事务正在删除它最后真正删除是在事务commit之后。

增删改查中的MVCC操作

select:①执行select操作时,InnoDB会查找到对应的数据行,并对比DATA_TRX_ID(版本号),要求数据行的版本必须小于等于事务的版本,如果当前数据行版本大于此事务版本,那么InnoDB会进入undo log中查找。确保当前事务读取的是事务之前存在的,或者是由当前事务创建或修改的行。 ② InnoDB会查找到对应的数据行后,查看DELETE BIT是否被定义,只允许未定义,或者删除的版本要大于此事务版本号。保证在执行此事务之前还未被删除。 当且仅当这两个条件都成立才允许返回select结果!

insert: InnoDB创建新记录,并以当前系统的版本号为新增记录的DATA_TRX_ID,如果需要回滚则丢弃undo log。

delete: InnoDB寻找到需要删除的记录,将此记录的DELETE BIT设置为系统当前版本号,若事务回滚则去除DELETE BIT定义的版本号,若事务提交则删除行。

update: InnoDB寻找到需要更新的行记录,复制了一条新的记录,新记录的版本ID为当前系统版本号,新记录的回滚指针指向原记录,将原记录的删除ID也设置为当前系统版本号。提交后则删除原记录,若回滚则删除复制的记录,并清除原记录的删除ID。

锁相关

因此读操作可以分为

  • 快照读:读取的是记录的可见版本,不加锁

  • 当前读:读取记录的最新版本,并且对表上锁,确保不会有记录修改这条记录。

添加了关键字的特殊查询操作(for update),或者update、delete、insert都属于当前读,需要加锁。

这里的锁分为共享锁S和排他锁X。

记录锁:Record lock,给单条索引记录上锁,锁的是索引。

间隙锁:Gap lock, 它是存在于某一条记录和前一条或者后一条之间间隙的锁,它只要是用于解决RR隔离级别下的幻读问题。举个例子:在b和a,b和c之间加入了间隙锁,那么b的前后相邻的位置都不能插入记录。

RR隔离级别是如何解决幻读的?

通过gap锁,将可能重复的记录之间的间隙锁上,其他事务无法并发的往间隙中进行插入。通过X锁锁定索引,其他事务无法并发进行删除。通过读取快照,每次只能读取到在此事务之前的历史版本或此事务修改的数据,实现可重复读。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值