MySQL的MVCC实现原理

目录

MVCC

当前读和快照读

隐藏字段

mvcc-undolog

readview

实现原理


MVCC

基本概念

MVCC全称是Multi-Version Concurrency Control(多版本并发控制),是一种并发控制的方法,通过维护一个数据的多个版本,减少读写操作的冲突。

如果没有MVCC,想要实现同一条数据的并发读写,还要保证数据的安全性,就需要操作数据的时候加读锁和写锁,这样就降低了数据库的并发性能。

有了MVCC,就相当于把同一份数据生成了多个版本,在操作的开始各生成一个快照,读写操作互不影响。无需加锁,也实现数据的安全性和事务的隔离性。

事务的四大特性中隔离性就是基于MVCC实现的。

MVCC只在 读已提交 和 可重复读 两个隔离级别下起作用,因为 读未提交 隔离级别下,读写都不加锁, 可串行化 隔离级别下,读写都加锁,也就不需要MVCC了。

当前读和快照读

先普及一下什么是当前读和快照读。

当前读: 读取数据的最新版本,并对数据进行加锁。

例如:insert、update、delete、select for update、 select lock in share mode。

快照读: 读取数据的历史版本,不对数据加锁。

例如:select

MVCC是基于Undo Log、隐藏字段、Read View(读视图)实现的。

  • 隔离级别-读已提交:每次select,都生成一个快照读。

  • 隔离级别-可重复读(ino默认):开启事务后第一个select语句才是快照读的地方。

  • 隔离级别-串行化:快照读会退化为当前读。

隐藏字段

一个表结构除了自己创建的字段,InnoDB还会自动的给我们添加三个隐藏字段及其含义分别是:

隐藏字段含义
DB_TRX_ID(最近一次提交事务的ID):修改表数据时,都会提交事务,每个事务都有一个唯一的ID,这个字段就记录了最近一次提交事务的ID。
DB_ROLL_PTR(上个版本的地址):修改表数据时,旧版本的数据都会被记录到Undo Log日志中,每个版本的数据都有一个版本地址,这个字段记录的就是上个版本的地址。
DB_ROW_ID隐藏主键,如果表结构没有指定主键,将会生成该隐藏字段。

前两个字段是肯定会添加的, 最后一个字段DB_ROW_ID,得看当前表有没有主键。

mvcc-undolog

回滚日志,在insert、update、delete的时候产生的便于数据回滚的日志。

insert的时候,产生的undo log日志只在回滚时需要,在事务提交后,可被立即删除。

update、delete的时候,产生的undo log日志不仅在回滚时需要,在快照读时也需要不会立即被删除。

最终我们发现,不同事务或相同事务对同一条记录进行修改,会导致该记录的undolog生成一条记录版本链表,链表的头部是最新的旧记录,链表尾部是最早的旧记录。

 

readview

//快照读在读的时候,读取哪个版本链上的历史记录,又readview决定

ReadView(读视图)是 快照读 SQL执行时MVCC提取数据的依据,记录并维护系统当前活跃的事务(未提交的)id。

ReadView中包含了四个核心字段:

字段含义
m_ids(当前未提交的事务id)当前活跃的事务ID集合
min_trx_id最小活跃事务ID
max_trx_id预分配事务ID,当前最大事务ID+1(下一个事务的id,因为事务ID是自增的)
creator_trx_idReadView创建者的事务ID

而在readview中就规定了版本链数据的访问规则

trx_id 代表当前undolog版本链对应事务ID。

不同的隔离级别,生成ReadView的时机不同:

  • 读已提交:在事务中每一次执行快照读时生成ReadView。

  • 可重复读:仅在事务中第一次执行快照读时生成ReadView,后续复用该ReadView。

实现原理

通过readview中维护的四个属性决定当前事务能读到哪个版本的数据,从表记录到Undo Log历史数据的版本链,依次匹配,满足哪个版本的匹配规则,就能读到哪个版本的数据,一旦匹配成功就不再往下匹配。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值