MySQL之InnoDB中的MVCC用法

 更新时间:2025年06月26日 08:47:45   作者:在成都搬砖的鸭鸭  
这篇文章主要介绍了MySQL之InnoDB中的MVCC用法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

1、背景

MVCC叫做多版本并发控制,通过维护数据的多个历史版本实现读写分离:读操作访问快照版本,无需加锁,避免阻塞写操作;写操作创建新版本,不影响其它事务的读操作。

这种机制支持了读已提交可重复读两种事务隔离级别,InnoDB中是通过隐藏列事务id、版本链、Read View实现的MVCC。

2、设置事务的隔离级别

设置事务隔离级别可以通过修改配置文件和通过sql语句,修改的隔离级别有4种:读未提交、读已提交、可重复读、串行化,修改配置文件可以永久生效,查看配置文件中的隔离级别如下:

[root@xxx xxx]# cat /xxx/my.cnf | grep 'transaction_isolation'
transaction_isolation                                      = READ-COMMITTED

通过sql语句修改是临时生效的,有3种修改方式,一个是会话级设置,只影响当前连接,例如:

mysql> SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
Query OK, 0 rows affected (0.00 sec)

另一个是全局设置,影响所有连接,例如:

mysql> SET GLOBAL TRANSACTION ISOLATION LEVEL REPEATABLE READ;
Query OK, 0 rows affected (0.00 sec)

最后一个是仅对下一个事务生效,例如:

mysql> SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
Query OK, 0 rows affected (0.00 sec)

3、MVCC

【1】版本链

之前讲过隐藏列:row_id、trx_id、roll_pointer,其中row_id不一定存在,当没有主键和唯一索引时,row_id才存在,trx_id是事务id,roll_pointer指向undo日志,通过roll_pointer就可以组成一条版本链,接下来通过如下表和数据来说明:

mysql> show create table student;
+---------+-------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------+
| Table   | Create Table
                                                                                                              |
+---------+-------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------+
| student | CREATE TABLE `student` (
  `id` int NOT NULL AUTO_INCREMENT,
  `name` varchar(255) NOT NULL DEFAULT '' COMMENT '姓名',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci |
+---------+-------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

mysql> select * from student;
+----+------+
| id | name |
+----+------+
|  1 | 张三 |
+----+------+
1 row in set (0.00 sec)

接下来分别在两个事务中更新数据,假设事务id分别为20和50:

时间顺序事务A,事务id=20事务B,事务id=50
t1开始事务开始事务
t2UPDATE student SET name = ‘李四’ WHERE id = 1;
t3提交事务
t4UPDATE student SET name = ‘王五’ WHERE id = 1;
t5提交事务

此时版本链如下:

在这里插入图片描述

name为王五的代表最新记录,name为李四和张三的为undo日志。

【2】ReadView

  • 对于未提交读的隔离级别事务来说,由于可以读到未提交事务修改的记录,直接读取最新的版本就好了;
  • 对于串行化隔离级别的事务来说是使用加锁的方式来访问记录的;
  • 对于读已提交和可重复读隔离级别的事务来说,只能读到已提交事务的结果。所以核心问题就是版本链中哪一个版本对当前事务是可见的,所有就有了ReadView,ReadView中包含4个部分:
名称含义
m_ids生成ReadView时当前系统中活跃的读写事务id列表
min_trx_idm_ids中的最小值
max_trx_id分配给下一个事务的id值,不是m_ids中的最大值
creator_trx_id生成ReadView的事务id,只读事务中为0

通过ReadView的属性,我们就能判断对记录版本链中的哪一个版本可见,判断规则如下:

1、如果被访问版本的trx_id与ReadView的中的creator_trx_id相同,说明当前事务再访问自己修改的记录,所以该版本可以被当前事务访问。

2、如果被访问版本的trx_id小于ReadView的中的min_trx_id值,说明生成该版本的事务在当前事务之前已经提交,所以该版本可以被当前事务访问。

3、如果被访问版本的trx_id大于ReadView的中的max_trx_id值,表明生成该版本的事务在当前事务之后开启,所以该版本不可以被当前事务访问。

4、如果被访问的版本的trx_id在ReadView的min_trx_id和max_trx_id之间,需要判断trx_id是否在m_ids中,在就说明该版本的事务还是活跃的,不可以被访问;不在就说明该版本已经提交,可以被访问。

如果某个版本的数据对当前事务不可见,就顺着版本链去判断下一个版本的数据,一直到最后一个版本,如果最后一个版本也不可见,那查询结果就不包含这条记录。

【3】ReadView的生成时机

隔离级别生成ReadView时机
读已经提交每次读取数据前都生成一个ReadView
可重复读第一次读取数据时生成一个ReadView

4、总结

MVCC是一种数据库并发控制技术,通过维护数据的多个历史版本实现读写操作的并行化,从而提升性能并解决事务隔离性问题。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • MySQL 字符串截取函数及用法详解

    MySQL 字符串截取函数及用法详解

    在MySQL中,字符串截取是常见的操作,主要用于从字符串中提取特定部分,MySQL 提供了多种函数来实现这一功能,包括 LEFT()、RIGHT()、SUBSTRING()、MID()、SUBSTR() 和 SUBSTRING_INDEX() 等,本文将详细介绍这些函数的用法,并通过示例进行说明,需要的朋友可以参考下
    2025-05-05
  • Oracle与MySQL的区别详解

    Oracle与MySQL的区别详解

    MySQL和Oracle Database都是一个关系型数据库管理系统,本文主要介绍了MySQL和Oracle Database的区别及优缺点是什么,感兴趣的小伙伴欢迎阅读
    2023-04-04
  • mysql 如何插入随机字符串数据的实现方法

    mysql 如何插入随机字符串数据的实现方法

    这篇文章主要介绍了mysql 如何插入随机字符串数据的实现方法,需要的朋友可以参考下
    2016-09-09
  • MYSQL大表加索引的实现

    MYSQL大表加索引的实现

    本文主要介绍了MYSQL大表加索引的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-05-05
  • 分享MySQL的自动化安装部署的方法

    分享MySQL的自动化安装部署的方法

    线上的MySQL一般都采用源码编译,虽然MySQL的源码编译挺简单的,但是试想一下,如果你有几百台服务器同时要安装MySQL,难道你还一台台去手动编译、编写配置文件吗?这显然太低效了,本文讨论MySQL的自动化安装部署。
    2014-07-07
  • MySql三种避免重复插入数据的方法

    MySql三种避免重复插入数据的方法

    这篇文章主要介绍了MySql三种避免重复插入数据的方法,帮助大家更好的理解和使用MySQL数据库,感兴趣的朋友可以了解下
    2020-09-09
  • MySQL基准测试套件Benchmark安装DBI组件过程分享

    MySQL基准测试套件Benchmark安装DBI组件过程分享

    这篇文章主要介绍了MySQL基准测试套件Benchmark安装DBI组件过程分享,,需要的朋友可以参考下
    2014-07-07
  • 详解Mysql之mysqlbackup备份与恢复实践

    详解Mysql之mysqlbackup备份与恢复实践

    这篇文章主要介绍了详解Mysql之mysqlbackup备份与恢复实践,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-02-02
  • MySql中JOIN关键字详细使用

    MySql中JOIN关键字详细使用

    文章介绍了SQL中的四种连接类型:INNERJOIN、LEFTJOIN、RIGHTJOIN和FULLJOIN,并通过图形化示例展示了它们的区别,本文结合实例代码给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧
    2025-12-12
  • Mysql MVCC多版本并发控制详情

    Mysql MVCC多版本并发控制详情

    这篇文章主要介绍了Mysql MVCC多版本并发控制详情,MVCC是一种并发控制的方法,一般在数据库管理系统中,实现对数据库的并发访问,在编程语言中实现事务内存,下文更多相关介绍需要的小伙伴可以参考一下
    2022-04-04

最新评论