mysql事务隔离级别可重复读_innodb默认隔离级别

mysql事务隔离级别可重复读_innodb默认隔离级别一般的DBMS系统,默认都会使用读提交(Read-Comitted,RC)作为默认隔离级别,如Oracle、SQLServer等,而MySQL却使用可重复读(Read-Repeatable,RR)。要知道,越高的隔离级别,能解决的数据一致性问题越多,理论上性能损耗更大,可并发性越低。隔离级别依次为>:串行化>RR>RC>读未提交在SQL标准中,前三种隔离级别分别解决了幻象读、不可重复读和脏读的问题。那么,为什么MySQL使用可重复读作为默认隔离级别呢?这个是有历史.

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

一般的DBMS系统,默认都会使用读提交(Read-Comitted,RC)作为默认隔离级别,如Oracle、SQLServer等,而MySQL却使用可重复读(Read-Repeatable,RR)。要知道,越高的隔离级别,能解决的数据一致性问题越多,理论上性能损耗更大,可并发性越低。隔离级别依次为>:串行化 > RR > RC >读未提交

在SQL标准中,前三种隔离级别分别解决了幻象读、不可重复读和脏读的问题。那么,为什么MySQL使用可重复读作为默认隔离级别呢?
这个是有历史原因的,要从主从复制开始讲起了!
1.主从复制,是基于什么复制的?
是基于binlog复制的
2.binlog有几种格式?
statement:记录的是修改SQL语句
row:记录的是每行实际数据的变更
mixed:statement和row模式的混合
那Mysql在5.0这个版本以前,binlog只支持STATEMENT这种格式!而这种格式在读已提交(Read Commited)这个隔离级别下主从复制是有bug的,因此Mysql将可重复读(Repeatable Read)作为默认的隔离级别!
接下来,就要说说当binlog为STATEMENT格式,且隔离级别为读已提交(Read Commited)时,有什么bug呢?如下图所示,在主(master)上执行如下事务:
在这里插入图片描述
此时在主库中查询:

select * from t;
  • 1

输出结果:

+---+---+
| c1 |c2
+---+---+
| 2 | 2
+---+---+
1 row in set
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

从库中查询:

select * from t;
  • 1

输出结果:

Empty set
  • 1

这里出现了主从不一致性的问题!原因其实很简单,就是在master上执行的顺序为先删后插!而此时binlog为STATEMENT格式,它记录的顺序为先插后删!从(slave)同步的是binglog,因此从机执行的顺序和主机不一致!就会出现主从不一致!
如何解决?
解决方案有两种!
(1)隔离级别设为可重复读(Repeatable Read),在该隔离级别下引入间隙锁。当Session 1执行delete语句时,会锁住间隙。那么,Ssession 2执行插入语句就会阻塞住!
(2)将binglog的格式修改为row格式,此时是基于行的复制,自然就不会出现sql执行顺序不一样的问题!奈何这个格式在mysql5.1版本开始才引入。
因此由于历史原因,mysql将默认的隔离级别设为可重复读(Repeatable Read),保证主从复制不出问题!

先说结论:
对于之前没有row格式的binlog的情况下,如果隔离级别是rc,有可能导致主从数据不一样。

例子:
隔离级别为rc,binlog格式为statement
select * from a;
b

1
2
3
4
5

session 1:
begin;
delete from a where b<=5;

session 2:
begin;
insert into a select 3;
commit;

session 1:
commit;

主库:
select * from a;
b
—-
3

从库:
select * from a;
empty set

此时的数据是不一样的。

原因:
(1)在rc隔离级别下,事务没有gap lock锁,因此可以在小于等于5的范围内插入一条新记录。
(2)binlog为statement记录的是master上产生的sql语句,按提交顺序记录的,因此binlog中记录的是先插入数据,后删除数据。(虽然master上是先删除数据后插入数据),逻辑上产生了不一致。

如何解决:
只需要解决上述问题中的一个就能保证数据的同步了。
(1)可以使用rr隔离级别;
(2)使用row格式的binlog;

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/196984.html原文链接:https://javaforall.net

(0)
上一篇 2025年9月16日 上午10:43
下一篇 2025年9月16日 上午11:15


相关推荐

  • Idea激活码最新教程2018.1.7版本,永久有效激活码,亲测可用,记得收藏

    Idea激活码最新教程2018.1.7版本,永久有效激活码,亲测可用,记得收藏Idea 激活码教程永久有效 2018 1 7 激活码教程 Windows 版永久激活 持续更新 Idea 激活码 2018 1 7 成功激活

    2025年5月24日
    6
  • 评分卡生成

    评分卡生成模型建立以后得到的 log odds 值是建模样本的好 坏比的对数 分值可以为负值 使得分值的可解读性很差 为了使得评分的结果更容易理解 更加具有实用性 我们希望看到评分卡的样子 通常对变量的特征值进行线性比例变换 并加上一个偏移量 公式如下 Score factor log odds offset factor a woe b of

    2026年3月18日
    2
  • 压测工具JMeter使用总结

    压测工具JMeter使用总结压力测试是每一个 Web 应用程序上线之前都需要做的一个测试 他可以帮助我们发现系统中的瓶颈问题 减少发布到生产环境后出问题的几率 预估系统的承载能力 使我们能根据其做出一些应对措施 所以压力测试是一个非常重要的步骤 下面我带大家来使用一款压力测试工具 JMeter JMeter 官网 https jmeter apache org 这里我选用了 4 0

    2026年3月16日
    3
  • c语言中结构体的指针初始化,c语言结构体指针初始化

    c语言中结构体的指针初始化,c语言结构体指针初始化今天终于看完了 C 语言深度剖析这本书 对 C 语言有了进一步的了解与感悟 突然发觉原来自己学 C 语言的时候学得是那样的迷糊 缺少深入的思考 在重新看书的时候发觉 C 语言基本教材虽然经典 但是缺乏独到性 老师在讲解的过程中也就照本宣科了 没有多大的启迪 看到 C 语言内存管理这块 发觉还是挺有用的 当然平时在编程时基本上就没有考虑过内存问题 定义了指针变量 没有为指针分配内存 即指针没有在内存中指向一块合法的内存

    2025年11月11日
    4
  • OPENGL 教程网站

    1.http://nehe.gamedev.net/这个是我觉得全世界最知名的OpenGL教程,而且有网友将其中48个教程翻译成了中文http://www.owlei.com/DancingWind/。Nehe教程最大的特点是提供了针对不同平台、不同编译器、不同语言的各种版本。你

    2022年4月8日
    55
  • PS2手柄-1「建议收藏」

    PS2手柄-1「建议收藏」相关定义Comd[2]={0x01,0x42};存储了两条指令码,分别是开始指令和请求数据指令。Data[9]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};数据存储数组,初始全为0。MASK[16]={PSB_SELECT,PSB_L3,PSB_R3,PSB_START,PSB_PAD_UP,PSB_PAD_RIGHT,PSB_PAD_DOWN,PSB_PAD_LEFT,PSB_L2,PSB_R2,PSB_L1,PSB_R1,PSB_GREEN,P

    2022年6月11日
    39

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号