MVCC机制

什么是mvcc

        mvcc全称Multi-Version Concurrency Control,即多版本并发控制。现代数据库(mysql,Oracle,PostgreSQL 等等)引擎采用的解决数据库读写冲突时的手段,目的在于提高数据库高并发场景下的吞吐性能。

        不同事务在并发过程中,SELECT操作可以在不加锁的情况下通过MVCC机制查询指定的版本历史记录

        举个例子

                                 

        在事务 A 提交前后,事务 B 读取到的 x 的值是什么呢?

        答案是:事务 B 在不同的隔离级别下,读取到的值不一样。

        如果事务 B 的隔离级别是读未提交(RU),那么两次读取均读取到 x 的最新值,即 20。
        如果事务 B 的隔离级别是读已提交(RC),那么第一次读取到旧值 10,第二次因为事务 A 已经提交,则读取到新值 20。
        如果事务 B 的隔离级别是可重复读或者串行(RR,S),则两次均读到旧值 10,不论事务 A 是否已经提交。
        可见在不同的隔离级别下,数据库通过 MVCC 和隔离级别,让事务之间并行操作遵循了某种规则,来保证单个事务内前后数据的一致性。

        注意一个概念:MVCC并不是事务的隔离级别,实现隔离级别的一种技术,保留数据库中数据的多个版本来支持并发事务的执行

事务版本号

        事务每次开启前,都会从数据库获得一个自增长的事务id,从事务ID中判断执行的先后顺序。

隐式字段

        mysql举例:InnoDB是mysql存储引擎之一,每一行记录都有两个隐藏列trx_idroll_pointer,如果表中没有主键和非NULL唯一键时,则还会有第三个隐藏的主键列row_id

           

undo log

        回滚日志,主要是记录数据被修改之前的信息,在表记录修改前,会先把数据拷贝到undo log中,如果事务回滚,可以通过undo log还原数据。

        可以这样认为,当delete一条记录时,undo log 中会记录一条对应的insert记录,当update一条记录时,它记录一条对应相反的update记录。

undo log有什么用途呢?

  1. 事务回滚时,保证原子性和一致性。

  2. 用于MVCC快照读

版本链

        多个事务并行操作一行数据时,不同事务对改行的数据的修改会产生多个版本,然后通过回滚指针(roll_pointer),连成一个链表,称为版本链

       

        通过版本链,我们可以看出事务版本号、表格隐藏的列和undo log之间的关系,分析一下

        假设现在有一张core_user表,表里面有一条数据,id为1,名字为孙权:

        现在开启一个事务A:对core_user表执行update core_user set name ="曹操" where id=1,会进行如下流程操作

        首先获得一个事务ID=100

        把core_user表修改前的数据,拷贝到undo log

        修改core_user表中,id=1的数据,名字改为曹操

        把修改后的数据事务Id=101改成当前事务版本号,并把roll_pointer指向undo log数据地址。

            

mvcc两种读取的两种方式:当前读、快照读

        快照读:事务在读取数据中获取了一个确定时间点的数据快照,该快照在整个事务执行过程中保持一致性,事务将看到事务开始时的执行状态。即使其他事务更改了数据,该快照也只能看到事务开始时的数据视图。

        不加锁的select,就是快照读;

        为什么出现快照读?

        为了并发考虑的,不能每次都加锁,提高并发性能,快照读是基于多版本并发控制

        存在问题

        基于多版本,读到的不一定是数据的最新版本,可能是之前的历史版本

        串行级的快照读会退化为当前读

        当前读:读取数据最新提交的数据,数据库的最新状态,读取时要保证其他事务不能修改当前记录,对读取的数据加锁

        共享锁:select lock in share mode

        排它锁:select for update 、update、 insert 、delete

RC、RR级别下的InnoDB快照读有什么不同,因为Read View生成时机的不同,从而造成RC、RR级别下快照读的结果的不同

        在RC级别下,事务中,每次快照读都会新生成一个快照和Read View,这就是我们在RC级别下的事务中可以看到别的事务提交的更新的原因
        在RR级别下,某个事务的对某条记录的第一次快照读会创建一个快照(Read View),将当前系统活跃的其他事务记录起来,此后在调用快照读的时候,还是使用的是同一个Read View,所以只要当前事务在其他事务提交更新之前使用过快照读,那么之后的快照读使用的都是同一个Read View,之后的修改对其不可见

​        总结:在RC隔离级别下,是每个快照读都会生成并获取最新的Read View,而在RR隔离级别下,则是同一个事务中的第一个快照读才会创建Read View,之后的快照读获取的都是同一个Read View.

RR级别下怎么避免幻读
  • 快照读,和避免不可重复读原理一样,可以避免幻读
  • 当前读,因为每次都是读取新的快照,如果需要避免,可以通过加锁
    限制新增或删除相同条件的数据

  • 16
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MySQL的MVCC(Multi-Version Concurrency Control)机制是一种并发控制机制,用于处理并发事务的读写冲突。它通过为每个事务创建一个独立的版本,并使用这些版本来提供对数据的一致性读取,从而实现并发控制。 MVCC机制在MySQL中的实现主要依赖于以下两个重要的组件: 1. Undo日志:MySQL使用undo日志记录数据修改操作的旧值。当一个事务开始时,MySQL会将当前数据行的快照复制到undo日志中。如果其他事务需要读取该数据行,它将读取这个快照而不受正在进行的事务的影响。 2. Read View:Read View是一个事务的快照视图,用于确定哪些数据行是对当前事务可见的。每个事务在开始时都会创建一个Read View。Read View包含一个活动事务列表和一个已提交事务列表。活动事务列表包含当前正在运行的活动事务,已提交事务列表包含已经提交的事务。当一个事务需要读取数据时,它会根据Read View确定哪些数据行是可见的。 基于这两个组件,MVCC机制提供了以下几个特点: 1. 高并发性:MVCC机制允许多个事务并发地读取和修改数据,因为它们之间不会产生读写冲突。 2. 一致性读取:MVCC机制确保事务只能读取已经提交的数据,避免了脏读和不可重复读的问题。 3. 无锁读取:MVCC机制的读取操作不会阻塞写入操作。读取操作只需要根据Read View判断数据是否可见。 需要注意的是,MVCC机制只适用于InnoDB存储引擎,而不适用于其他存储引擎,如MyISAM。另外,MVCC机制在一些特殊情况下可能会导致存储空间的增加,因为每个事务都会创建一个版本。因此,在设计数据库时需要考虑这些因素。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值