一、什么是MVCCMVCC,全称Multi-Version Concurrency Control , 即多版本并发控制 , 是一种并发控制的方法,一般用在数据库管理系统中 , 实现对数据库的并发访问,比如在MySQL InnoDB中主要是为了提高数据库并发性能,不用加锁,非阻塞并发读 。MVCC多版本并发控制指的是维持一个数据的多个版本,使得读写操作没有冲突 , 快照读是MySQL为实现MVCC的一个非阻塞读功能 。
二、解决的问题是什么?1、三种数据库并发场景:
- 读读:不会有问题,也不需要并发控制
- ?读写:有线程安全问题 , 可能会造成事务隔离性问题,可能遇到脏读、幻读、不可重复读
- ?写写:有线程安全问题,可能存在更新丢失问题
- 在并发读写数据库时 , 可以做到在读操作时不用阻塞写操作,写操作也不用阻塞读操作,提高了数据库并发读写的性能
- 解决脏读、幻读、不可重复读等事务隔离问题,但是不能解决更新丢失问题
1、隐藏字段每行记录,除了我们自定义的字段外,还有数据库隐式定义的DB_TRX_ID,DB_ROLL_PTR,DB_ROW_ID等字段:
- DB_ROW_ID:6字节,隐藏的主键,如果数据表没有主键,那么innodb会自动生成一个6字节的row_id
- ?DB_TRX_ID:6字节,最近修改事务id,记录创建这条记录或者最后一次修改该记录的事务id
- DB_ROLL_PTR:7字节 , 回滚指针,用于配合undo日志,指向上一个旧版本
文章插图
2、undolog1)概念回滚日志,表示在进行insert , delete,update操作的时候产生的方便回滚的日志 。
2)说明
- 当进行insert操作的时候,产生的undolog,只在事务回滚的时候需要用到,并且在事务提交之后可以被立刻丢弃
- 当进行update和delete操作的时候,产生的undolog,不仅仅在事务回滚的时候需要,在快照读的时候也需要,所以不能随便删除 , 只有在快照读或事务回滚不涉及该日志时,对应的日志才会被purge线程统一清除
3)undolog生成的记录链表(1)假设有一个事务编号为1的事务向表中插入一条记录 , 那么此时行数据如下,主键id=1,事务id=1
文章插图
(2)假设有第二个事务(编号为2)对该记录的name做出修改 , 改为lisi底层操作:在事务2修改该行记录数据时1、对该数据行加排他锁2、把该行数据拷贝到undolog中,作为旧记录3、修改该行name为lisi,并且修改事务id=2,回滚指针指向拷贝到undolog的副本记录中4、提交事务 , 释放锁
文章插图
(3)假设有第三个事务(编号为3)对该记录的age做了修改,改为32底层操作:在事务3修改该行记录数据时1、对该数据行加排他锁2、把该行数据拷贝到undolog中,作为旧记录,发现该行记录已经有undolog了 , 那么最新的旧数据作为链表的表头,插在该行记录的undolog最前面3、修改该行age为32岁,并且修改事务id=3,回滚指针指向刚刚拷贝的undolog的副本记录4、提交事务,释放锁
文章插图
从上述的一系列图中 , 可以发现,不同事务或者相同事务的对同一记录的修改,会导致该记录的undolog生成一条记录版本链表,undolog的表头就是最新的旧记录,表尾就是最早的旧记录 。
3、read viewRead View是事务进行快照读操作的时候生产的读视图 , 在该事务执行快照读的那一刻,系统会生成一个此刻的快照,记录并维护系统此刻活跃事务的id,用来做可见性判断的 , 也就是说当某个事务在执行快照读的时候,对该记录创建一个Read View的视图,把它当作条件去判断当前事务能够看到哪个版本的数据,有可能读取到的是最新的数据,也有可能读取到的是当前行记录的undolog中某个版本的数据
推荐阅读
- 支付宝小鸡今日答题答案大全
- 过年回家做核酸检测免费吗_?现在做核酸是全国免费吗
- 英雄联盟手游10月全场半价活动内容介绍
- 7 步保障 Kubernetes 集群安全
- MySQL 全局锁、表级锁、行级锁,你搞清楚了吗?
- SpringCloud整合分布式事务Seata 1.4.1 支持微服务全局异常拦截
- 英雄联盟S12全球总决赛主题曲介绍
- 2021微信收藏如何全部删除(怎样全部删除微信收藏)
- 你应该知道的数仓安全:都是同名Schema惹的祸
- 非常全面 Dubbo 原理和机制详解