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


相关推荐

  • 【Redis】Redis4.0、5.0、6.0版本特性整理「建议收藏」

    【Redis】Redis4.0、5.0、6.0版本特性整理「建议收藏」文章目录Redis版本特性Redis4模块系统PSYNC2.0缓存驱逐策略优化LazyFree交换数据库混合持久化内存命令兼容NAT和DockerActiveDefrag其他Redis5Stream类型新的Redis模块API集群管理器更改Lua改进RDB格式变化动态HZZPOPMIN&ZPOPMAX命令CLIENT新增命令其他Redis6多线程IOSSL支持ACL支持RESP3客户端缓存集群代理Disquemodule其他Redis版本特性Redis4模块系统​ R

    2025年5月26日
    6
  • 你不知道的 Claude Code:架构、治理与工程实践

    你不知道的 Claude Code:架构、治理与工程实践

    2026年3月13日
    1
  • [转载]【电子书下载神器】太给力了!你还找不到想要的电子书吗?

    [转载]【电子书下载神器】太给力了!你还找不到想要的电子书吗?1.电子书下载网(推荐)读远:发掘优质电子书资源Kindle精读书库Hi!PDAHi!PDAreadfree.me子乌书简 苦瓜书盘mLook看书掌上书苑-主页新浪微盘 | 免费网盘    2.电子书网站  E书吧-免

    2022年7月15日
    22
  • 安装mininet详细步骤_Mininet安装

    安装mininet详细步骤_Mininet安装Mininet 安装根据 SDNLAB 上的实验进行安装 连接地址需要注意的是切换到用户目录下进行 clonegithub 上的源码 1 卸载之前安装的 Mininet 最好是先到目录下看是否有这些文件 再进行删除 sudorm rf usr local bin mnsudorm rf usr local bin mnexecsudorm rf usr local lib python

    2026年3月16日
    2
  • springmvc笔记_SpringMVC优点

    springmvc笔记_SpringMVC优点MVC简介普通的web项目每次都要进行手动的把jar包导进去,否则会报500,classnotfound[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VstjHhuz-1609824493673)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210104132339761.png)][外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-L9AgS48A-16

    2022年10月15日
    4
  • Unity 协程

    Unity 协程协程前言调用方式停止方式yiledreturn语句执行时机WaitForSeconds(floatTime)WaitForSecondsRealtime(floattime)WaitForEndOfFrame()WaitForFixedUpdate()WaitUntil(Funcpredicate)WaitWhile(Funcpredicate)实现自定义函数实际开发中使用建议前言协程是unity提供的一个特殊的机制,他的特点就是可以方便的实现流程化的东西。但是就他的效率而言个人感觉并不乐观,

    2022年6月15日
    52

发表回复

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

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