MYSQL MVCC实现及其机制

本文介绍MySQL中的多版本并发控制(MVCC)技术,解释其如何通过行级锁结合MVCC提高并发性能,尤其是在InnoDB存储引擎中的实现细节。MVCC通过保存数据快照确保事务一致性,减少锁的竞争。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

多版本并发控制

  Multiversion Concurrency Control

  大部分的MySQL的存储 引擎,比如InnoDB,Falcon,以及PBXT并不是简简单单的使用行锁机制。它们都使用了行锁结合一种提高并发的技术,被称为MVCC(多版本并发控制)。MVCC并不单单应用在MySQL中,其他的数据库如Oracle,PostgreSQL,以及其他数据库也使用这个技术。

  MVCC避免了许多需要加锁的情形以及降低消耗。这取决于它实现的方式,它允许非阻塞读取,在写的操作的时候阻塞必要的记录。

  MVCC保存了某一时刻数据的一个快照。意思就是无论事物运行了多久,它们都能看到一致的数据。也就是说在相同的时间下,不同的事物看相同表的数据是不同的。如果你从来没有这方面的经验,可能说这些有点令人困惑。但是在以后这个会很容易理解和熟悉的。

  每个存储引擎实现MVCC方式都是不同的。有许多种包含了乐观(optimistic)和悲观(pessimistic)的并发控制。我们用简单的InnoDb的行为来举例说明MVCC工作方式。

   InnoDB实现MVCC的方法是,它存储了每一行的两个额外的隐藏字段,这两个隐藏字段分别记录了行的创建的时间和删除的时间。在每个事件发生的时 候,每行存储版本号,而不是存储事件实际发生的时间。每次事物的开始这个版本号都会增加。自记录时间开始,每个事物都会保存记录的系统版本号。依照事物的 版本来检查每行的版本号。在事物隔离级别为可重复读的情况下,来看看怎样应用它。

  SELECT

  InnoDB检查每行,要确定它符合两个标准。

  InnoDB必须知道行的版本号,这个行的版本号至少要和事物版本号一样的老。(也就是是说它的版本号可能少于或者和事物版本号相同)。这个既能确定事物开始之前行是存在的,也能确定事物创建或修改了这行。

  行的删除操作的版本一定是未定义的或者大于事物的版本号。确定了事物开始之前,行没有被删除。

  符合了以上两点。会返回查询结果。

  INSERT

  InnoDB记录了当前新增行的系统版本号。

  DELETE

  InnoDB记录的删除行的系统版本号作为行的删除ID。

  UPDATE

  InnoDB复制了一行。这个新行的版本号使用了系统版本号。它也把系统版本号作为了删除行的版本。

  所有其他记录的结果保存是,从未获得锁的查询。这样它们查询的数据就会尽可能的快。要确定查询行要遵循这些标准。缺点是存储引擎要为每一行存储更多的数据,检查行的时候要做更多的处理以及其他内部的一些操作。

  MVCC只能在可重复读和可提交读的隔离级别下生效。不可提交读不能使用它的原因是不能读取符合事物版本的行版本。它们总是读取最新的行版本。可序列化不能使用MVCC的原因是,它总是要锁定行。

  下面的表说明了在MySQL中不同锁的模式以及并发级别。

锁的策略                   并发性               开销                 引擎
最低最低MyISAM,Merge,Memory
NDB Cluster
行和MVCC最高最高InnoDB,Falcon,PBXT,solidD
### MySQLMVCC工作原理及其实现方式 MySQL 使用多版本并发控制(MVCC, Multi-Version Concurrency Control)来支持事务隔离级别,尤其是在 InnoDB 存储引擎中。以下是关于其工作机制实现的关键点: #### 1. **MVCC 基本概念** MVCC 是一种通过保存数据的历史版本来提高数据库性能的技术。它允许读写操作并行执行而不会相互阻塞。InnoDB 实现MVCC 来满足 ACID 属性以及不同的事务隔离级别。 在 InnoDB 中,每行记录都包含了两个隐藏字段用于维护 MVCC: - `DB_TRX_ID`:表示最后一次对该行进行修改的事务 ID。 - `DB_ROLL_PTR`:指向该行之前的某个旧版本的数据位置(undo log)。这些历史版本存储在 undo 日志中[^1]。 #### 2. **Undo Log 和 Read View** 为了实现 MVCC,InnoDB 利用了 Undo Log 和 Read View 这两种机制: - 当某条记录被更新或者删除时,原始版本会被保留到 Undo Log 中。 - 对于只读查询(SELECT),如果当前看到的是最新版本,则可能不符合特定时间点的一致性视图;此时会利用 Undo Log 查找合适的过去版本。 Read View 定义了一个快照,使得同一时刻发起的不同一致性读能够共享相同的可见状态集合。具体来说,在每次新启动一个可重复读级别的事务之前都会创建一个新的 read view ,这个视图决定了哪些更改对于此事务而言是不可见的[^2]。 #### 3. **不同隔离级别下的行为差异** 根据所选的隔离级别,MVCC 表现出的行为有所不同: - **READ UNCOMMITTED**: 不使用 MVCC,直接返回最新的已提交或未提交的数据版本。 - **READ COMMITTED**: 每次 select 都会产生新的 read view 。这意味着即使同一个事务内的多次查询也可能得到不一样的结果集因为其他事务已经完成了 commit 并产生了影响。 - **REPEATABLE READ**: 整个交易期间保持单一不变的readview ,从而确保无论何时重做相同条件的选择语句都能获得一致的结果除非显式锁定表/行。 - **SERIALIZABLE**: 转变为完全加锁模式运行即所有的selects自动转换成locking selects形式以防止幻影现象发生. #### 4. **清理过期版本(VACUUM 类似功能)** 随着时间推移,越来越多的老版本数据变得不再需要(没有任何活动中的transaction还需要它们),因此有必要定期回收空间资源。这项任务由后台线程完成称为purge process负责扫描那些可以安全丢弃掉无用副本们同时释放关联磁盘区域给操作系统重新分配用途[^3]. ```sql -- 示例展示如何查看当前正在使用的事务及其对应的trx_id SHOW ENGINE INNODB STATUS; ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值