MVCC机制详解

在mysql里面, 多个事务对同一行数据并发读写是不会加锁(非串行化级别), 保证数据库的一致性和隔离性, 这个是通过MVCC多版本对比机制实现的. 

MVCC(Multi-Version Concurrency Control)通过undo日志版本链和ReadView视图来实现并发控制,确保事务在读取数据时能够看到一致性的快照, 允许并发写入.

1. Undo日志版本链(Undo Log Version Chain)

  • 目的:Undo日志版本链用于记录数据的历史版本,主要用于支持事务的回滚和提供一致性读取。

  • 维护方式:在多个事务对一行数据写入操作时,MySQL都会创建修改前端Undo回滚日志, 用两个隐藏字段, 事务id 和undo指针, 把这些undo日志串联起来, 形成日志版本链。

  • 用途:Undo日志版本链的主要作用是提供回滚操作。如果事务需要回滚,MySQL可以使用Undo日志将数据恢复到之前的版本。此外,当事务需要读取数据时,如果没有找到相应的可见版本,MySQL可以使用Undo日志来查找之前的版本。

2. ReadView视图

  • 目的:ReadView视图用于控制事务在读取数据时, 可以看到哪些版本,以确保事务之间的隔离性。

  • 维护方式:不同的隔离级别决定了事务能够看到的数据版本的范围。例如可重复读级别, 只会在第一次查询生成一份readView视图, 读已提交级别每次查询都会重新生成readView.视图是由当前已创建的事务id组成的数组.

版本对比机制

查询操作时, 从上到下扫描undo日志版本链, 拿到事务id去readView视图对比

1. undoTrxId < min(readView), 是已提交事务, 当前数据可见

2. undoTrxId > max(readView), 是未开始事务, 数据不可见

3. undoTrxId >= min(readView) && undoTrxId <= max(readView), 再对比事务id是否在数组内

        3.1 readView contain undoTrxId = true, 说明事务是未提交, 数据不可见(若事务id=自己可见)

        3.2 readView contain undoTrxId = false, 说明事务是已提交事务, 数据可见

注意:begin/start transaction 命令并不是一个事务的开始,执行到它们之后的第一个修改操作或加排它锁操作(比如select...for update)的语句,事务才真正启动,才会向mysql申请真正的事务id,mysql内部是严格按照事务的启动顺序来分配事务id的。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值