InnoDB---可重复读隔离级别的实现

美团面试官:可重复读隔离级别实现原理是什么?(一文搞懂MVCC机制) 可重复读隔离级别实现原理是什么?它和MVCC又有什么关系?什么是Read View? 阅读详情
可重复读的实现

    可重复读隔离级别,简称RR,在2.1.1节,我们说过:

    Repeatable Read(可重复读):一个事务在执行过程中可以看到其他事务已经提交的新插入的记录(读已经提交的,其实是读早于本事务开始且已经提交的),但是不能看到其他事务对已有记录的更新(即晚于本事务开始的),并且,该事务不要求与其他事务是“可串行化”的。

    这句话的核心,是“但是不能看到其他事务对已有记录的更新”,那么RR隔离级别是怎么保证这一点的呢?

    如果数据库并发控制引擎是单纯的封锁协议机制,则应该在读取数据的时候,判断数据项是不是其他事务更新过的。可是InnoDB没有这么做,而是通过如下方式,在RR隔离级别下为事务设置了一个“一致性读视图(即快照)”,之后读取数据,就是根据这个快照来获取,这样,就不能看到他晚于本事务的事务对已有记录的更新(更新生成新版本,必然不在旧的快照所限定的范围内)。

static my_bool snapshot_handlerton(THD *thd, plugin_ref plugin, void *arg)

{

    handlerton *hton= plugin_data<handlerton*>(plugin);

    if (hton->state == SHOW_OPTION_YES && hton->start_consistent_snapshot) //隔离级别是RR时start_consistent_snapshot才被赋值

    {

        hton->start_consistent_snapshot(hton, thd); //对于InnoDB,实际执行innobase_start_trx_and_assign_read_view()函数

        *((bool *)arg)= false;

    }

    return FALSE;

}

    如图11-4和下面的代码分析,在事务开始的时候trans_begin()会调用snapshot_handlerton()函数指针即使用innobase_start_trx_and_assign_read_view()函数在可重复读隔离级别下创建一个快照,其他隔离级别则不创建快照。

InnoDB---可重复读隔离级别的实现 - 那海蓝蓝 - 那海蓝蓝的博客
 

图11-4 snapshot_handlerton()函数上下文调用关系图

 

innobase_start_trx_and_assign_read_view(  //在可重复读隔离级别下创建一个快照,其他隔离级别则不创建快照

    handlerton*    hton,    /*!< in: InnoDB handlerton */

    THD*           thd)     /*!< in: MySQL thread handle of the user for whom the transaction should be committed */

{...

    if (trx->isolation_level == TRX_ISO_REPEATABLE_READ) { //如果是RR隔离级别,则给read view赋值,即构建一致性视图

        trx_assign_read_view(trx);  //为读一致性视图(快照)赋一个值,注意在store_lock()中应隔离级别小于RR才关闭快照

    } else {

        push_warning_printf(thd, Sql_condition::SL_WARNING,

                    HA_ERR_UNSUPPORTED,

                    "InnoDB: WITH CONSISTENT SNAPSHOT"

                    " was ignored because this phrase"

                    " can only be used with"

                    " REPEATABLE READ isolation level.");

    }

...

}

    之后,在每条SQL语句执行的时候,根据隔离级别判断是不是要使用一个新的快照,如果是可重复读,则不使用新快照,沿用老的快照,这样就能保证所有的读操作看到的是同一个数据状态;同时也确保了读已提交隔离级别下一个事务块内的不同语句的读操作看到的不是同一个数据状态。

ha_innobase::store_lock(...)

{...

    if (lock_type != TL_IGNORE && trx->n_mysql_tables_in_use == 0) {

        trx->isolation_level = innobase_map_isolation_level((enum_tx_isolation) thd_tx_isolation(thd));

        if (trx->isolation_level <= TRX_ISO_READ_COMMITTED  //隔离级别小于等于读已提交,关闭老的快照。可重复读不关闭老快照所以可以沿用

            && MVCC::is_view_active(trx->read_view)) {

            /* At low transaction isolation levels we let each consistent read set its own snapshot */

            mutex_enter(&trx_sys->mutex);

            trx_sys->mvcc->view_close(trx->read_view, true);  //隔离级别小,关闭快照,这样下一条SQL执行时,将获取新快照

            mutex_exit(&trx_sys->mutex);

        }

    }

...

}

    从上面的分析可以看出,InnoDB的可重复读的实现,利用了实现MVCC技术的快照技术。这是MVCC和基于封锁技术这两个并非控制技术的结合之处。
MySQL中InnoDB的可重复读是怎么实现的? 首先看一个例子: CREATE TABLE `test` ( `id` int(11) NOT NULL AUTO_INCREMENT, `c` int(11) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 往test表插入两条数据: INSERT INTO `test` (`id`, `c`) VALUES (1, 1); INSERT INTO `test` (`id`, `c`) VALUES 阅读详情

相关推荐

不可重复读,可重复读,幻读,MVCC概念理解

不可重复读是指在一个事务内,多次读同一数据。在这个事务还没有结束时,另外一个事务也访问该同一数据。那么,在第一个事务中的两次读数据之间,由于第二个事务的修改,那么第一个事务两次读到的数据可能是不一样的。这样就发生了在一个事务内两次读到的数据是不一样的,因此称为是不可重复读。 幻读是指当事务不是独立执行时发生的一种现象,例如第一个事务对一个表中的数据进行了修改,这种修改涉及到表中的全部数据行。同时,第二个事务向表中插入一行新数据。那么,第一个事务的用户就会发现一起没有的记录行,就好象发生了幻觉一样。 ..

三侠剑的博客 2864

可重复读实现原理

可重复读

m0_50574545的博客 2944

mysql可重复读和幻读的理解

mysql可重复读和幻读的理解可重复读和幻读的定义最后总结参考资料 很多教程和书籍对mysql的可重复读和幻读的解释都比较含糊,本文结合原理和其他的考证,深入分析下。 这里讨论的引擎是常用的InnoDB。 可重复读和幻读的定义 先看下《高性能MySQL(第三版)》对隔离级别的描述。 这里对幻读的描述为 所谓幻读,指的是当某个事物在读取某个范围内的记录时,另外一个事物又在该范围内插入了新的记录,当之前的事务再次读取该范围内的记录时,会产生幻行(Phantom Row)。 实际上这里的解释不太准确,先看下官网上对这些的定义。 phantom A row that appears in the r

事务隔离与可重复读的实现原理

一、前言 简单来说,事务就是要保证一组数据库操作,要么全部成功,要么全部失败。 在MySQL中,事务支持是在引擎层实现的。MySQL是一个支持多引擎的系统,但并不是所有的引擎都支持事务。比如MySQL原生的MyISAM引擎就不支持事务,这也是MyISAM被InnoDB取代的重要原因之一。 下面会以InnoDB为例。 二、隔离性与隔离级别 提到事务,肯定会想到ACID(Atomicity、Consistency、Isolation、Durability,即原子性、一致性、隔离性、持久性) 下面来看其中的 I,

qq_44503377的博客 2033

循环神经网络(RNN)

在之前学习了全连接神经网络(DNN)模型,网络结构都是从输入层到隐含层再到输出层,层与层之间是全连接或部分连接的,但每层之间的节点是无连接的。 一、神经网络基础 神经网络可以当做是能够拟合任意函数的黑盒子,只要训练数据足够,给定特定的x,就能得到希望的y,结构图如下: 将神经网络模型训练好之后,在输入层给定一个x,通过网络之后就能够在输出层得到特定的y,那么既然有了这么强大的模型,为什么还需要RNN(循环神经网络)呢? 二、为什么需要RNN(循环神经网络) 考虑这样一个问题,如果要预测句子的下一个单词是什么

小朱小朱绝不认输的博客 2万+

IDEA 导入 jbolt项目(实验室非公开项目)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录准备一、准备数据库二、IDEA导入jbolt项目 准备 在实验室群文件中下载jbolt.zip和mysql.sql两个文件 将其解压到自己的目录下 一、准备数据库 打开Navicat新建一个jbolt数据库(字符集为utf8) 导入mysql.sql文件 数据库导入完毕 二、IDEA导入jbolt项目 点击打开一个项目 选择jbolt文件夹 以Maven形式打开 打开pom.xml 在里面添加jetty-server依赖

weixin_44094842的博客 973

MySQL(四)—MVCC实现可重复读的原理

MVCC实现可重复读的原理

shang_0122的博客 2364

STM32CubeMX + HAL库避坑指南:为什么你的代码总在SystemClock_Config卡住?

本文深入剖析了STM32开发者在使用STM32CubeMX和HAL库时,代码在SystemClock_Config函数中卡死的根本原因。文章不仅指出硬件时序、Flash延迟配置等常见陷阱,更提供了从硬件设计、软件容错到深度调试的系统性解决方案,帮助开发者构建鲁棒的时钟初始化策略,彻底告别启动卡顿问题。

bb456的博客 928

可重复读实现原理MVCC

...

神韵 2046

gradle报错:A problem occurred configuring root project ‘My Application‘.

即使翻译了,我开始也看不懂,到处找网上教程,但都是改环境变量。马虎的我即使看了很多遍,改了很多遍也没反应过来,今天第一次搞gradle,突然就报错了,打印出。好了我就继续看项目了。

m0_59878789的博客 4091

renderdoc的使用

renderdoc可以用来捕获帧渲染情况,排查一些GPU渲染、资源规格等问题。 下面讲述一些该软件连接真机调试使用。 一、下载安装renderdoc 软件的下载地址:https://renderdoc.org/可直接点击下载即可。该软件是开源免费的,不用破解。 下载后直接安装即可使用。 二、打开使用renderdoc 打开界面后,默认的界面布局如下图所示,(这里我已经设置了黑色主题,可以忽略这点),renderdo中主要的窗口有Texture Viewer(纹理查看器)、Event B.

x_xingduo_2315的博客 2万+

mysql 可重复读 悲观锁_InnoDB可重复读隔离级别是如何实现的

断断续续花了些时间,参考挺多文章,在自己的理解上总结出来以下内容,以后忘了的时候可以翻出来看看。如果大家之前不太了解这一部分的东西,可花点耐心把这篇看完,我想会对各位有一些帮助的,若无收获你来砍我。InnoDB默认隔离级别-可重复读是如何实现的mysql多事务并发的场景下会出现的问题:1、脏读2、不可重复读3、幻读隔离级别1、读未提交(Read Uncommitted)2、读已提交(Read Co...

weixin_39660922的博客 560

UG\NX二次开发 获取三平面交点

//如果返回值不为0 则此三个面没交点 int three_faces_point(tag_t tagFace1, tag_t tagFace2, tag_t tagFace3, double *dou_x, double *dou_y, double *dou_z)

王牌飞行员_里海的博客 675

InnoDB---可重复读隔离级别的底层实现原理

可重复读的实现     Repeatable Read(可重复读):一个事务在执行过程中可以看到其他事务已经提交的新插入的记录(读已经提交的,其实是读早于本事务开始且已经提交的),但是不能看到其他事务对已有记录的更新(即晚于本事务开始的),并且,该事务不要求与其他事务是“可串行化”的。     这句话的核心,是“但是不能看到其他事务对已有记录的更新”,那么RR隔离级别是怎么保证这一点的呢? ...

chuixue24的博客 1404

Windows 11 安装 JDK 11:下载、安装、配置环境变量、验证

本文详细介绍了在 Windows 11 系统中安装 JDK 11 的完整流程,包括从 Oracle 官网下载压缩包、解压到自定义目录、配置 JAVA_HOME 与 Path 环境变量,并验证安装是否成功。文章还包含一个专为 JDK 11 新特性设计的测试程序,涵盖 Lambda 表达式 var 语法、HTTP 客户端 API、字符串增强方法等,帮助读者确认安装版本正确无误,适合初学者和需要多版本 JDK 共存的开发者参考。

寒水馨 · 轻量级技术文档 · hanshuixin.org 2779

基于STM32L4XX、HAL库的YT8531C-CA以太网收发器(PHY)驱动程序设计

是一款由裕太微推出的高性价比、低功耗的单端口 10/100M 以太网物理层收发器(PHY)。它通过标准的 MII(介质独立接口)或 RMII(精简介质独立接口)与微控制器的 MAC 层连接,实现将数字信号与网络模拟信号之间的转换。支持自动协商(Auto-Negotiation),自动选择最高速率和双工模式。支持 HP Auto-MDIX(自动交叉直连),无需区分直通线或交叉线。低功耗设计,特别适合电池供电或对功耗敏感的 STM32L4 应用。支持 MII 和 RMII 接口,节省引脚(RMII模式)。

zhusl6688的博客 628

InnoDB 使用 MVCC 来实现读已提交和可重复读的事务隔离级别到底是什么意思?底层原理是什么?

InnoDB 通过 MVCC 实现了 RC 和 RR 这两种事务隔离级别,有效地解决了传统锁定机制中存在的问题,提供了更高的并发性能和更好的用户体验。

长风破浪会有时的博客 1209

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

mysql innodb可重复读隔离级别下是如何实现避免幻读的

表象:快照读(非阻塞读)–伪MVCC 内在:next-key锁(行锁+gap锁) 文章目录快照读和当前读next-key lock案例分析情况1:where条件全部命中,则不会用Gap锁,只会加记录锁情况2:where条件部分命中或者全不命中,则会加gap锁情况3:当前读走的是非唯一索引的情况情况4:不走索引的情况,会对所有的gap都上锁,这也就类似于锁表了 快照读和当前读 当前读:select…lock in share mode, select… for update 当前读:update, delet

u013905744的专栏 1422

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

mysql 可重复读隔离级别底层实现

文章目录隔离级别什么是可重复读RR 实现方式总结 隔离级别 读未提交:别人改数据的事务尚未提交,我在我的事务中也能读到。 读已提交:别人改数据的事务已经提交,我在我的事务中才能读到。 可重复读:别人改数据的事务已经提交,我在我的事务中也不去读。 串行:我的事务尚未提交,别人就别想改数据。 这4种隔离级别,并行性能依次降低,安全性依次提高。 什么是可重复读 Repeatable Read (可重复读):保证在同一个事务中多次读取同样数据的结果是一样的。一个事务在执行过程中可以看到

weixin_42170152的博客 777

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

InnoDB的隔离级别是如何实现的

innerDB默认隔离级别-可重复读是如何实现的mysql多事务并发的场景下会出现的问题:1、脏读2、不可重复读3、幻读隔离级别1、读未提交(Read Uncommitted)2、读已提交(Read Committed)3、可重复读(Repeatable Read)4、可串行化(Serializable)常见锁乐观锁和悲观锁不是真实存在的锁共享锁(Shared Lock)也叫读锁或S锁排它锁(Exclusive Lock)也叫写锁或X锁行锁(Record Lock)间隙锁(Gap Lock)Next-Key

CaptainCats的博客 2062

关于MySQL可重复读的理解

(一)问题引入 描述问题之前,先理解一下两种锁的概念。 共享锁(S锁):如果事务T对数据A加上共享锁后,则其他事务只能对A再加共享锁,不能加排他锁。获准共享锁的事务只能读数据,不能修改数据。 排它锁(X锁):如果事务T对数据A加上排他锁后,则其他事务不能再对A加任任何类型的封锁。获准排他锁的事务既能读数据,又能修改数据。 共享锁和排他锁都属于悲观锁。排他锁又可以可以分为行锁和表锁。 MySQL常...

Bosco's Blog 2万+

面试八股之MySQL篇4.5——事务篇——InnoDB 如何实现可重复读的

5、InnoDB 如何实现可重复读的?——1.快照读与当前读、2.一致性视图 、3.行锁与间隙锁:

做一个善良的人,做好自己的事,如果愿意,再发一份光。 904

深入学习InnoDB可重复读隔离级别下如何避免幻读

一、InnoDB可重复读隔离级别下如何避免幻读 在理解什么是幻读之前,先了解下脏读、幻读、不可重复读在实操场景中的现象。 脏读:指的就是一个事务读取到了另一个事务还未提交的数据,当该事物将数据回滚,则读取到的就是脏数据。 脏读造成的结果:事务拿着脏的数据(还未提交的数据,如果回滚了)去执行业务操作,会影响业务。 脏读解决方案:将数据库事务隔离级别改为RC,所以事务只能读取到其他事务已经提交的数据。...

你要悄悄的拔尖,然后惊艳所有人 4185

mysql查看隔离级别 ACID 四种隔离等级 mysql如何实现可重复读

1、查看当前会话的隔离级别: select @@tx_isolation; 2、查看系统的隔离级别: select @@global.tx_isolation; 3、设置会话的隔离级别,隔离级别由低到高设置依次为: set session transacton isolation level read uncommitted; set session transacton isolation levelread committed; set sessiontransacton is...

Peppa Pig 725
上一篇: InnoDB---读已提交隔离级别的实现
下一篇: InnoDB---序列化隔离级别的实现
那海蓝蓝
那海蓝蓝 领域专家: 数据库技术领域 领域专家: 数据库技术领域 业界专家认证 业界专家认证
博客等级 码龄20年 568粉丝 425原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值