Mysql 中MVCC 设计方式

是什么?

多版本并发控制

作用是什么?

在并发场景下,使用不加锁或者乐观锁的思想去解决读和写的关系,使提高读的效率和又控制了写时的并发问题。

核心思想是:

读是快照读,写是通过undo log 记录版本链。

当前读和快照读?

当前读:

像select lock in share mode(共享锁),select for update ; update; insert; delete(排它锁),这些操作都是一种当前读,她读取的事记录的最新版本,读取时还要保证其他并发事务不能修改当前记录,会对当前读取的记录进行加锁。

快照读:

像不加锁的select操作就是快照读,即不加锁的非阻塞读;快照读的前提是隔离级别不是串行级别,串行级别的快照会退化成当前读;在很多情况下避免了加锁操作,降低了开销,既然是基于多版本,快照读读到的不一定是数据最新版本,可能是历史版本。

并发场景下数据会遇到三种场景:

读-读: 不存在任何问题,也不需要并发控制

读-写: 有线程安全问题,可能会造成事务隔离性问题,可能遇到脏读,幻读,不可重复读

写-写: 有线程安全问题,可能会存在更新丢失问题,比如第一类更新丢失,第二类更新丢失。

MVCC可以解决读-写问题且不用锁。

数据库中可以使用MVCC+锁的格式解决写-写冲突。

MVCC + 悲观锁

MVCC 解决读写冲突,被关锁解决写写冲突

MVCC + 乐观锁

MVCC 解决读写冲突,乐观锁解决写写冲突

MVCC 的实现原理

它的实现原理主要是依赖记录中的3个影式字段 undo 日志,Read View 来实现。

数据库影式定义 DB_TRX_ID  最后一次提交该事务的ID,DB_ROLL_PTR 回滚指针指向上一个版本,DB_ROW_ID 影藏的自增主键。

undo log 主要分为两种

  1. Insert undo log

代表事务在insert 新记录时产生的undo log, 只在事务回滚时需要,并且在事务提交后可以被立即丢弃。

  1. update undo log

事务在进行 update 或者delete 时产生的undo log; 不仅在事务回滚时需要在快照读时也需要,所以不能随便删除,只有在快速读或者事务回滚不涉及该日志是,对应的日志才会被purge 线程统一清除。

实际就是存在rollback segment 中的旧记录链。

Read View 读视图

当每一个事务开始执行快照读的时候(是执行select 快照读,而不是事务执行)的那一刻会生成数据库系统当前一个快照(在这一刻,会记下当前事务的id,正在活跃的事务(已开始尚未提交的事务)id列表,数据库中这条数据的最新事务Id)

读视图在取数的过程

1、我们设数据库中最新事务Id 为trx_id, 活跃事务id列表trx_list, 活跃表里最小id min_id,

然后去当前最新事务的事务Id+1 为max_id(这里需要注意是系统生成的最新Id不是事务列表中的id)

2、判断trx_id 是否小于min_id,如果小于说明表里的数据不在活跃Id列表里,又因为事务自增,所以必然已经提交,能被读事务看到。如果大于max_id说明该事务在Read View 生成后才出现的,那对当前事务肯定不可见。

3、判断trx_id 是否在trx_list 中,如果在Read View 生成时刻事务还在活跃,尚未commit,你修改的数据看不见。如果不在说明在Read View 生成钱Commit了,修改的结果当前事务可以看见。

注意:

1、这里其实有个时间问题id是按着先后时间生成的

2、Read View 不是事务开始时快照的,而是事务开始执行时快照的。

RC,RR 几倍下的InnoDB快照读有什么不同?

1、在RR级别下的某个事务的对某条记录的第一次快照会创建一个快照,及Read View ,将当前系统活跃的其他事务记录起来,此后在调用快照读的时候,还是使用的是同一个Read View,所以只要当前事务在其他事务提交更新之前使用过快照读,那么之后快照读使用的都是同一个Read View

 

2、在RC级别下,事务中每次快照都会新生成一个快照和Read View,这是我们在RC级别下事务可以看到别的事务提交的原因。

引用:

https://blog.csdn.net/SnailMann/article/details/94724197

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值