MVCC多版本并发控制

文章目录

  • 1. MVCC
    • 使用MVCC带来的好处
  • 2. MySQL默认添加的三个隐藏字段
  • 3.ReadView(读视图)
    • 1.ReadView主要包含以下两个重要的部分
    • 2.生成ReadView 的策略
  • 4.版本链
    • 1.简介
    • 2.事务执行操作的判断


从Mysql5.0版本开始内置innoDB存储引擎,该存储引擎支持MVCC

在MySQL中使用MVCC需要对表进行特定的设置。具体来说,在创建表时可以指定其存储引擎为InnoDB,并启用事务,这样就可以使用MVCC了。同时,在执行查询操作时,还需要注意使用适当的隔离级别,以确保数据一致性。

1. MVCC

MVCC(Multi-Version Concurrency Control)是一种并发控制机制,用于在数据库系统中实现并发事务的隔离性。就是⼀种写时复制的思想的应用 且MVCC只在读取已提交(Read Committed)和可重复读(Repeatable Read)两个事务隔离级别下有效

在传统的并发控制机制中,如锁机制,当一个事务修改某个数据时会对其加锁,其他事务必须等待该锁释放后才能访问该数据。这样做虽然可以确保数据的一致性,但会导致并发性能降低,因为事务之间需要串行执行。

MVCC 使用了一种不同的技术来解决并发访问数据的问题。其核心思想是:对于每个事务,数据库系统会为其创建一个视图(也称为版本或快照),在这个视图上进行操作。不同的事务之间可以操作同一个数据,但它们所使用的视图不同。当一个事务提交后,它所做出的变更会被应用到数据库的最新版本中。

MVCC是通过 版本链和 ReadView 一致性视图来实现的

使用MVCC带来的好处

  • 这种技术不需要加锁,使得多个事务可以并发地访问同一份数据。
  • 对于读操作,MVCC 的实现可以在不阻塞其他事务的情况下,返回读取到的数据的历史版本。
  • 对于写操作,MVCC 的实现可以将写入的数据与数据库的最新版本进行比较,从而避免出现并发更新造成的数据冲突。

但是需要注意的是:尽管 MVCC 技术可以提高并发性能,但该技术也有其自身的缺点。其中一个主要问题是存储消耗,因为需要对每个事务创建视图或版本,会占用更多的存储空间。另一个问题是需要对数据库系统本身进行修改,以支持 MVCC 的实现。

2. MySQL默认添加的三个隐藏字段

  • 1.DB_ROW_ID:行ID,MySQL的B+树索引特性要求每个表必须要有一个主键。如果没有设置的话,会自动寻找第一个不包含NULL的唯⼀索引列作为主键。如果还是找不到,就会在这个DB_ROW_ID上自动生成⼀个唯一值,以此来当作主键(该列和MVCC的关系不大);
  • 2.DB_TRX_ID:事务ID,记录的是当前事务在做INSERT或UPDATE语句操作时的事务ID(DELETE语句被当做是UPDATE语句的特殊情况,后面会进行说明);
  • 3.DB_ROLL_PTR:回滚指针,通过它可以将不同的版本串联起来,形成版本链。相当于链表的next指针。

3.ReadView(读视图)

ReadView(读视图)是在MySQL InnoDB存储引擎中使用的一种机制,用于实现数据库的多版本并发控制(MVCC)。

在InnoDB中,每个事务在开始时会创建一个自己的ReadView

1.ReadView主要包含以下两个重要的部分

1.低水位标记(Low Limit Point)又叫已经创建的最⼤事务ID:表示当前事务的快照时间点,也被称为读视图的"可见性界限"。低水位标记之前的所有已提交事务产生的数据对于当前事务都是可见的,而低水位标记之后的事务所做的修改对于当前事务则是不可见的。

2.视图数组(ReadView Array)又叫 所有未提交事务的ID数组:保存当前事务所需的其他事务的信息。它记录了所有可能会影响当前事务读取的已提交和未提交事务,以及它们各自的最新的低水位标记。通过视图数组,可以判断一个事务是否需要等待另一个事务的提交,以保证读取的一致性。

2.生成ReadView 的策略

但是在读取已提交和可重复读两个事务级别下,生成ReadView的策略是不⼀样的:读取已提交级别是每执行⼀次SELECT语句就会重新生成⼀份ReadView,

而可重复读级别是只会在第⼀次SELECT语句执行的时候会生成⼀份,后续的SELECT语句会沿用之前生成的ReadView(即使后面有更新语句的话,也会继续沿用,除非提交事务)。

4.版本链

1.简介

版本链(Version Chain)是InnoDB存储引擎中用于维护数据行不同版本的链表结构。

在InnoDB的MVCC机制中,每个数据行都可以有多个版本,每个版本对应一个事务的修改或插入操作。这些版本以链表的形式组织,形成了版本链。

每个版本包含以下信息:

  • 版本号(Transaction ID):标识创建该版本的事务。可以是事务的唯一标识符,也可以是时间戳。
  • 数据值(Data Value):保存数据行在该版本的值。
  • 指向下一个版本的指针(Next Pointer):指向下一个版本的地址

MVCC多版本并发控制_第1张图片

2.事务执行操作的判断

当一个事务执行读取操作时,它会比较自己的ReadView和所需数据的版本信息(版本链中的信息),以决定是否能够读取该数据。具体判断逻辑如下:

1.事务会遍历版本链中的每个版本,从最新的版本开始。

2.对于每个版本,事务会比较版本的创建时间和自己的低水位标记。

3.如果数据版本的创建时间大于当前事务的低水位标记,表示该版本是在当前事务开始之后创建的,因此对于当前事务来说是不可见的。

4.如果数据版本的创建时间小于等于当前事务的低水位标记,并且创建该数据版本的事务已经提交,则对于当前事务是可见的,可以读取。

5.如果数据版本的创建时间小于等于当前事务的低水位标记,但创建该数据版本的事务尚未提交,那么当前事务需要等待该事务的提交或回滚操作。

你可能感兴趣的:(MySQL,mysql)