MVCC多版本并发控制

1 什么是MVCC

MVCC,即多版本并发控制。维持一个数据的多个版本,使得读写操作没有冲突。MVCC是为了解决读-写冲突,做到即使有读-写冲突时,也能做到不加锁,非阻塞并发读。

在并发读写数据库时,可做到在读操作时不用阻塞写操作,写操作也不用阻塞读操作,提高了数据库并发读写的性能。

通过MVCC使得InnoDB事务隔离级别默认达到可重复读(通过MVCC可以在不影响性能的情况下实现可重复读,所以InnoDB才敢把事务隔离级别默认设置为可重复读)。而oracle默认隔离级别还是读已提交。

2 MVCC实现原理

2.1 三个隐藏字段

InnoDB为每行记录都添加了三个隐藏字段

  • 隐藏ID
  • 事务ID(DB_TRX_ID)
  • 回滚指针(DB_ROLL_PTR)
2.2 buff poolredo logundo log

InnoDB为了减少磁盘IO次数,提供了Buffer Pool(缓存),作为访问数据库的缓冲。

  • a当从数据库读取数据时,会首先从Buffer Pool中读取,如果Buffer Pool中没有,则从磁盘读取后放入Buffer Pool。
  • b当向数据库写入数据时,会首先写入Buffer Pool,Buffer Pool中修改的数据会定期刷新到磁盘中(这一过程称为刷脏)。

Buffer Pool大大提高了读写性能,但是带来了新的问题,如果mysql宕机,数据有丢失的风险,持久性无法保证。

因此,redo log被引来解决这个问题,当数据修改时,除了修改Buffer Pool中的数据,还会在redo log记录这次操作;当事务提交时,会调用fsync接口对redo log进行刷盘。

所有修改先写入redo log,再更新到Buffer Pool,保证了数据不会因宕机而丢失。从而满足了持久性的要求。

undo log:

undo log用于事务回滚,当事务对数据库进行修改时,InnoDB会生成对应的undo log。如果事务回滚,则利用undo log将数据回滚到修改之前的样子

3 MVCC对数据进行更新原理

3.1 初始数据

前6列是数据,后面三个隐藏字段,刚插入时,事务ID和回滚指针都是NULL

3.2 事务1

事务1对数据进行更改时

  • 首先对该行加锁
  • 写redo log日志
  • 旧数据写入undo log日志
  • 修改当前行的值,填写事务ID,使回滚指针指向undo log。

3.3 事务2

与事务1相同,记录undo log

MVCC中的多版本,就是指的undo log中的多个版本并存的状态。

当存在事务0,进行的是读操作1,且进行了比较耗时的过程,在此过程中,上面事务1开始并提交,事务2开始并提交,事务0再进行读操作2,第二次读操作读的是undo log中的对应的记录,两次读操作读到的是相同的值,实现了可重复读。在此期间undo log对应的事务ID记录不能被purge线程回收,(purge线程会查询比现在最老的活动事务还早的undo log日志并删除它们,保证undo log不至于太大)。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值