浅谈mysql的mvcc

MVCC(Multi-VersionConcurrency Control 多版本并发控制)

概念

MVCC 是一种并发控制的方法,一般在数据库管理系统中,实现对数据库的并发访问。
MVCC的实现,是通过保存数据在某个时间点的快照来实现的。即为:不管需要执行多长时间,每个事务看到的数据都是一致的。

在Mysql的InnoDB引擎中就是指在已提交读(READ COMMITTD)和可重复读(REPEATABLE READ)这两种隔离级别下的事务对于SELECT操作会访问版本链中的记录的过程。

这就使得别的事务可以修改这条记录,反正每次修改都会在版本链中记录。SELECT可以去版本链中拿记录,这就实现了读-写,写-读的并发执行,提升了系统的性能。

具体实现

innodb的MVCC,是通过在每行记录后面保存两个隐藏的列来实现的。这两个列,一个是行的创建时间,一个保存行的过期时间。存储的是系统版本号,不是真实的时间。每开始一个新的事务,系统版本号都会自动递增。事务开始时刻的系统版本号会作为事务的版本号,用来和查询到的每行记录的版本号进行比较。

trx_id(事务id)

这个id用来存储的每次对某条聚簇索引记录进行修改的时候的事务id。

roll_pointer(回滚id)

每次对哪条聚簇索引记录有修改的时候,都会把老版本写入undo日志中。这个roll_pointer就是存了一个指针,它指向这条聚簇索引记录的上一个版本的位置,通过它来获得上一个版本的记录信息。(注意插入操作的undo日志没有这个属性,因为它没有老版本)

在这里插入图片描述
执行update修改数据,相当于在数据库里新增了一条数据1,将原来的旧数据2存储到undo日志中,在roll pointer 也就是事务id处记录下uodo日志的指针,通过这个指针找到原来的记录。

Mysql在第一次查询的时候会生成一个一次性视图,叫做read-view.

ReadView

已提交读和可重复读的区别就在于它们生成ReadView的策略不同。

当执行查询sql会生成一致性视图read-view,它由执行查询时所有未提交事务id数组(数组里最小的id为min_id)和已经创建的最大事务的id组成,查询的数据结果需要跟read-view做对比从而得到快照结果。

ReadView中主要就是有个列表来存储我们系统中当前活跃着的读写事务,也就是begin了还未提交的事务。通过这个列表来判断记录的某个版本是否对当前事务可见。

列如

在这里插入图片描述

Readview[100,300]

1、 如果trx_id<min_id.表示这个版本是已提交事务生成的,所以对当前活动的事务来说是可访问的。

2、 如果trx_id>max_id,表示这个版本是ReadView生成之后才发生的,不能被访问。

3、 如果min_id<trx_id<max_id,

a. 若trx_id在数组中,表示这个版本是还未提交的事务生成的,所以版本不能被访问。

b. 若trx_id不在数组中,则事务已提交,可以被访问。

已提交读隔离级别下的事务在每次查询的开始都会生成一个独立的ReadView,

可重复读隔离级别则在第一次读的时候生成一个ReadView,之后的读都复用之前的ReadView。这就是Mysql的MVCC,通过版本链,实现多版本,可并发读-写,写-读。通过ReadView生成策略的不同实现不同的隔离级别。

MVCC只在repeatable read和read committed两个隔离级别下工作。其他两个隔离级别和MVCC不兼容。因为READ UNCOMMITTED 总是读取最新的数据行,而不是符合当前事务版本的数据行。而SERIALIZABLE 则会对所有读取的行都加锁。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值