Read View的可见性判断理解

读了 @SnailMann大佬【MySQL笔记】正确的理解MySQL的MVCC及实现原理 收益颇丰,非常感谢!

但对其中如何判断事务是否可见性还是不太理解,于是作了本文,在原博客基础上,举例画图论证、理解了 Read View的可见性判断。

引用 @SnailMann大佬【MySQL笔记】正确的理解MySQL的MVCC及实现原理 的字段说明。

隐式字段

每行记录除了我们自定义的字段外,还有数据库隐式定义的 DB_TRX_ID, DB_ROLL_PTR, DB_ROW_ID 等字段

  • DB_TRX_ID
    6 byte,最近修改(修改/插入)事务 ID:记录创建这条记录/最后一次修改该记录的事务 ID
  • DB_ROLL_PTR
    7 byte,回滚指针,指向这条记录的上一个版本(存储于 rollback segment 里)
  • DB_ROW_ID
    6 byte,隐含的自增 ID(隐藏主键),如果数据表没有主键,InnoDB 会自动以DB_ROW_ID产生一个聚簇索引

Read View 的三个全局属性

trx_list(名称我随意取的):一个数值列表,用于维护 Read View 生成时刻系统 正活跃的事务 ID 列表
up_limit_id :是 trx_list列表中事务 ID 最小的 ID
low_limit_id Read View 生成时刻系统尚未分配的下一个事务 ID ,也就是 目前已出现过的事务 ID 的最大值 + 1
为什么是 low_limit ? 因为它也是系统此刻可分配的事务 ID 的最小值

可见性判断逻辑

  • DB_TRX_ID < up_limit_id , 当前行事务id比活跃的最小事务id还小时,说明了两件事,当前行事务对该记录的修改已经提交,因为当前事务id比活跃的最小事务id还小,不在活跃的事务之中,也就意味着该事务已经提交或回滚,这时因为已经成功修改,那么应该就是提交成功了。
    也就是在生成 Read View之前,事务已经提交,
  • 接下来判断 DB_TRX_ID >= low_limit_id , 修改该行的事务id大于了 Read View里系统待分配的下一个事务id,说明修改该行的事务是生成该 Read View之后出现的事务,因为 Read View系统待分配的下一个事务id被用了,才会出现比该事务id大的事务。这时,也应该是不可见的,一个事务怎么可以看到后面新来事务做的修改了。
  • 判断 DB_TRX_ID 是否在活跃事务之中, trx_list.contains (DB_TRX_ID),如果在活跃事务之中,说明该修改是其他事务未提交的修改,应该是不可见的,如果可见就是脏读了,如果不在活跃事务之中,说明在生成 Read View之前,该事务的修改就已提交,与第一个判断逻辑类似,事务2是可以查到这条记录的。

针对上面三种情况,下面举例说明:

原记录: amount = 100

事务1 事务2 事务3 事务4 开启事务 开启事务 开启事务
update amount = 200 update amount = 300

提交事务 ①
select amount;

开始快照读,生成
Read View

提交事务 开启事务 ②
select amount; update amount = 400;

提交事务 ③
select amount;

请问三次 select amount; 快照读到的值分别是多少,为什么?

画一张图,把undo表里存的记录版本链及当前记录画出来。

Read View的可见性判断理解

1>如图,当前行 DB_TRX_ID(1) == up_limit_id(1),说明本次修改该记录的事务正在进行中,也就是 事务1还未结束, 事务2就应该对 事务1这次修改不可见,可见就是脏读了。

2>当前记录不可见,再根据回滚指针追踪到上个版本记录,如图undo日志内 金额为200的行,此时再通过Read View进行可见性判断。

第一种情况:当前行 DB_TRX_ID(3) > up_limit_id(1),不确定;

第二种情况: DB_TRX_ID(3) < low_limit_id(4),也不确定;

第三种情况: DB_TRX_ID(3)不在 trx_list中,不是活跃的事务,说明 事务3在事务2生成 Read View之前就已经提交,那么是可见的。

所以读取的金额为200。

事务1提交事务,不过undo表与当前行数据无变化,对事务1的 Read View的数据也不会变化,因为RR模式下, Read View 只会在第一次快照读时生成,后面几次快照读不会生成新的 Read View,也不会改动之前Read View的值。

当前行数据与 Read View 都无变化,那么可见性判断也同①一致,读取到的金额为200。

第一种情况:当前行 DB_TRX_ID(4) > up_limit_id(1),不确定;

第二种情况: DB_TRX_ID(4) > low_limit_id(1),说明当前行是被生成 Read View之后出现的事务修改的,这种未来的数据肯定是不可见的。

再接着追溯,就与①中追溯的过程相差不大了,最终读取的金额也是为200。

总结

这里举例论证了可见性判断的合理性,总结来说,可见性的三个判断约束了一件事, 只有在本事务生成 Read View 之前就已经提交的事务的修改才可以被看见,其他的无论是正在进行的事务的修改还是之后再提交的事务的修改都不可见

Original: https://www.cnblogs.com/ZJJCodeLife-520/p/16472231.html
Author: 桃子来了
Title: Read View的可见性判断理解

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/621384/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 数据库的常用命令

    1. 数据操作类语句: SELECT:&#x4ECE;&#x6570;&#x636E;&#x5E93;&#x8868;&#x4E2D…

    数据库 2023年5月24日
    0100
  • java~ForkJoinPool分而致之处理大数据

    ForkJoinPool的思想,是将大的集合进行拆分,计算处理之后,再把结果合并,这体现了多核时代的并行计算能力。 集合拆分成元素 List<integer> maps…

    数据库 2023年6月6日
    047
  • MySQL实战45讲 9

    09 | 普通索引和唯一索引,应该怎么选择? 每个人都有一个唯一的身份证号,而且业务代码已经保证了不会写入两个重复的身份证号。如果市民系统需要按照身份证号查姓名,就会执行类似这样的…

    数据库 2023年6月16日
    0103
  • 001从零开始入门Entity Framework Core——基础知识

    1、对于 EF Core,使用模型执行数据访问。 模型由 实体类和表示数据库会话的 上下文对象构成。 上下文对象允许查询并保存数据。 2、EF 支持以下模型开发方法: 从现有数据库…

    数据库 2023年6月14日
    090
  • 常用函数封装汇总

    常用函数封装 获取某日期若干个工作日后的日期 * &#x53C2;&#x6570;: * time: [String] &#x7ED9;&#x5B9…

    数据库 2023年6月11日
    098
  • MySQL InnoDB 锁的二三事

    近日, 在一个小型项目中, 遇到了一个触及我知识盲区的bug. 项目用的是MySQL 5.7.25, 其中有一张表 config_data, 包含四个字段, id, name, v…

    数据库 2023年6月11日
    0106
  • [javaweb]jsp,jstl,el表达式的使用

    jsp java server page:java服务器前端页面,和servlet一样,用于动态web开发。 特点: 写jsp页面就像在写html html只给用户提供静态数据,j…

    数据库 2023年6月16日
    072
  • Mysql性能调优-工具篇

    首先祭出官方文档(这是5.7的,请自行选择版本): 如果你不想读英语,只需阅读这篇文章: [En] If you don’t want to read English,…

    数据库 2023年5月24日
    077
  • Redis的Java客户端

    Redis 的 Java 客户端 Jedis 优点:以 Redis 命令作为方法名称,学习成本低廉,简单且实用 缺点:Jedis 的实例是线程不安全的,在多线程的环境下需要基于线程…

    数据库 2023年6月16日
    083
  • c++ map查找键值

    map用法 查找键是否存在 1、count函数 count函数用于统计key值在map中出现的次数,map的key不允许重复,因此如果key存在返回1,不存在返回0 if (mp….

    数据库 2023年6月6日
    0244
  • [SuperSocket2.0]SuperSocket 2.0从入门到懵逼

    SuperSocket 2.0从入门到懵逼 1 使用SuperSocket 2.0在AspNetCore项目中搭建一个Socket服务器 1.1 引入SuperSocket 2.0…

    数据库 2023年6月9日
    0127
  • 设计模式之(6)——建造者模式

    定义:建造者模式也称为生成器模式,将一个个简单对象一步步构造成一个复杂的对象,将复杂对象的构建和它的表示分离,使得同样的构建过程有不同的表示; 主要解决:系统中复杂对象的创建过程,…

    数据库 2023年6月14日
    072
  • Ajax

    AJAX(Asynchronous Javascript And Xml) 传统请求及缺点 传统的请求都有哪些? 直接在浏览器地址栏上输入URL。 点击超链接 提交form表单 使…

    数据库 2023年6月14日
    094
  • 2022-8-15 数据库 mysql 第一天

    Mysql数据库 数据库 数据库[根据数据结构组织、存储和管理数据的仓库]。它是有组织的、可共享的、统一管理的大量数据的集合,这些数据长期存储在计算机中。 [En] Databas…

    数据库 2023年5月24日
    053
  • jdbc-实现用户登录业务(存在sql注入)

    package com.cqust; import java.sql.Connection;import java.sql.DriverManager;import java.sq…

    数据库 2023年5月24日
    072
  • Cookie & Session

    posted @2020-12-02 23:48 一方玩 阅读(31 ) 评论() 编辑 Original: https://www.cnblogs.com/tianyuwohu/…

    数据库 2023年6月6日
    079
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球