为什么MySQL的Read View机制是实现隔离级别的核心?

秋雪小哥_8837

秋雪小哥_8837

2026-07-16

763人浏览

原创

read view 是 mvcc 实现 rc 和 rr 隔离级别的唯一可见性判断依据,本质是运行时生成的结构体,含 m_ids、min_trx_id、max_trx_id、creator_trx_id 四字段,用于比对版本链中 trx_id 决定数据可见性;rc 每次快照读新建 read view,rr 仅首次快照读创建并复用。

为什么mysql的read view机制是实现隔离级别的核心?

Read View 机制不是“辅助手段”,而是 RC 和 RR 隔离级别下 MVCC 能工作的唯一判断依据——没有它,就无法决定该读哪个版本的数据。

Read View 是什么?不是快照,是可见性规则计算器

Read View 不是把数据拷一份存起来,而是一个运行时生成的结构体,里面记录了当前事务能看到哪些事务修改的版本。关键字段包括:m_ids(创建时活跃的事务 ID 列表)、min_trx_id(活跃事务中最小 ID)、max_trx_id(下一个将分配的事务 ID)、creator_trx_id(本事务自己的 ID)。每次访问聚簇索引记录时,InnoDB 都会用这四个值去比对记录头里的 trx_id 和 roll_pointer,决定是否跳转到上一个版本。

常见错误现象:以为 “RR 下事务启动后数据就冻结了”——其实冻结的是 Read View,不是数据本身;数据仍在被其他事务持续更新、生成新版本。

RC 和 RR 的区别只在 Read View 创建时机

RC 每次 SELECT 都调用 innobase_get_read_view() 新建一个 Read View;RR 只在事务中第一次 SELECT(或 SELECT ... LOCK IN SHARE MODE 等一致性读)时创建,后续复用。

  • RC 场景下:事务 B 更新并提交后,事务 A 再执行一次 SELECT,就会拿到新的 Read View,m_ids 中不再包含事务 B 的 ID,于是能看见新值
  • RR 场景下:事务 A 第一次 SELECT 后,即使事务 B 提交了,A 后续所有 SELECT 都沿用旧 Read View,只要 B 的 trx_id 在当初的 m_ids 里或落在 [min_trx_id, max_trx_id) 区间内,就不可见

参数差异直接影响行为:显式开启事务后不立刻查询(比如先 UPDATE 再 SELECT),RR 下的 Read View 仍会在首次 SELECT 时才建立,不是在 BEGIN 或 START TRANSACTION 时。

MySQL
MySQL

编写正确的MySQL查询,避免字符集、索引和锁方面的常见陷阱。

下载

为什么 Read Uncommitted 和 Serializable 不用 Read View?

Read Uncommitted 直接读取最新版本的 trx_id 对应记录,跳过所有可见性检查;Serializable 则退化为加锁模型,所有 SELECT 都隐式加上 LOCK IN SHARE MODE,根本绕开 MVCC 路径。

性能影响明显:RC 因频繁构造 Read View,在高并发短事务场景下会有轻微 CPU 开销;RR 复用 Read View 更轻量,但长事务会拖住 purge 线程,导致 undo log 无法及时清理,磁盘空间持续增长。

容易被忽略的关键点:Read View 生效的前提是“一致性读”

只有普通 SELECT(非锁定读)才走 Read View 流程;SELECT ... FOR UPDATE 或 SELECT ... LOCK IN SHARE MODE 会跳过 MVCC,直接加锁读最新版本。这意味着:同一事务中混合使用普通读和锁定读,可能看到“前后不一致”的结果——不是 bug,是设计如此。

另一个盲区:Read View 对二级索引(非聚簇索引)无效。二级索引记录不含 trx_id,其一致性读依赖回表到聚簇索引后,再用 Read View 判断主键记录可见性。如果二级索引覆盖查询(SELECT a FROM t WHERE b=1,且 a,b 都在索引中),则不回表,此时无法应用 Read View,InnoDB 会强制升格为聚簇索引扫描或加锁读。

相关专题

更多
数据分析工具有哪些
数据分析工具有哪些

数据分析工具有Excel、SQL、Python、R、Tableau、Power BI、SAS、SPSS和MATLAB等。详细介绍:1、Excel,具有强大的计算和数据处理功能;2、SQL,可以进行数据查询、过滤、排序、聚合等操作;3、Python,拥有丰富的数据分析库;4、R,拥有丰富的统计分析库和图形库;5、Tableau,提供了直观易用的用户界面等等。

2023.10.12

3803

8

SQL中distinct的用法
SQL中distinct的用法

SQL中distinct的语法是“SELECT DISTINCT column1, column2,...,FROM table_name;”。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2023.10.27

811

4

SQL中months_between使用方法
SQL中months_between使用方法

在SQL中,MONTHS_BETWEEN 是一个常见的函数,用于计算两个日期之间的月份差。想了解更多SQL的相关内容,可以阅读本专题下面的文章。

2024.02.23

989

5

SQL出现5120错误解决方法
SQL出现5120错误解决方法

SQL Server错误5120是由于没有足够的权限来访问或操作指定的数据库或文件引起的。想了解更多sql错误的相关内容,可以阅读本专题下面的文章。

2024.03.06

5621

10

sql procedure语法错误解决方法
sql procedure语法错误解决方法

sql procedure语法错误解决办法:1、仔细检查错误消息;2、检查语法规则;3、检查括号和引号;4、检查变量和参数;5、检查关键字和函数;6、逐步调试;7、参考文档和示例。想了解更多语法错误的相关内容,可以阅读本专题下面的文章。

2024.03.06

2583

4

oracle数据库运行sql方法
oracle数据库运行sql方法

运行sql步骤包括:打开sql plus工具并连接到数据库。在提示符下输入sql语句。按enter键运行该语句。查看结果,错误消息或退出sql plus。想了解更多oracle数据库的相关内容,可以阅读本专题下面的文章。

2024.04.07

5600

11

sql中where的含义
sql中where的含义

sql中where子句用于从表中过滤数据,它基于指定条件选择特定的行。想了解更多where的相关内容,可以阅读本专题下面的文章。

2024.04.29

7341

6

sql中删除表的语句是什么
sql中删除表的语句是什么

sql中用于删除表的语句是drop table。语法为drop table table_name;该语句将永久删除指定表的表和数据。想了解更多sql的相关内容,可以阅读本专题下面的文章。

2024.04.29

1010

5

sql中删除一列的命令是什么
sql中删除一列的命令是什么

在sql中,使用alter table语句可以删除一列,语法为:alter table table_name drop column column_name。想了解更多sql的相关内容,可以阅读本专题下面的文章。

2024.04.29

872

5

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PostgreSQL vs MySQL
PostgreSQL vs MySQL

共1课时 | 175人学习

使用phpenv集成环境安装极致CMS
使用phpenv集成环境安装极致CMS

共2课时 | 279人学习