前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >为什么 MySQL 选择 "可重复读" 作为默认隔离级别?

为什么 MySQL 选择 "可重复读" 作为默认隔离级别?

作者头像
用户10125653
发布2022-11-10 21:57:22
1K0
发布2022-11-10 21:57:22
举报
文章被收录于专栏:change

其他数据库

Oracle,SqlServer中都是选择读已提交(Read Commited)作为默认的隔离级别,为什么Mysql不选择读已提交(Read Commited)作为默认隔离级别,而选择可重复读(Repeatable Read)作为默认的隔离级别呢?

原因

这个是有历史原因的,当然要从我们的主从复制开始讲起了!

主从复制,是基于什么复制的?

  是基于binlog复制的!这里不想去搬binlog的概念了,就简单理解为binlog是一个记录数据库更改的文件吧。

binlog有几种格式? OK,三种,分别是

代码语言:javascript
复制
row:记录的是每行实际数据的变更 ,记录的是每一行结果的变化和上下文信息,占用比较多的空间。
statement:记录的是修改SQL语句,记录的是每一条执行的SQL内容,相对会节省比较多的空间。
mixed:statement和row模式的混合,MySQL会根据具体执行 SQL 语句来区分,具体选择哪一种方式进行记录。

那Mysql在5.0这个版本以前,binlog只支持STATEMENT这种格式!

而这种格式在读已提交(Read Commited)这个隔离级别下主从复制是有bug的,因此Mysql将可重复读(Repeatable Read)作为默认的隔离级别!

接下来,就要说说当binlog为STATEMENT格式,且隔离级别为读已提交(Read Commited)时,有什么bug呢?

bug重现

  • 在主(master)上执行如下事务
image.png
image.png
  • 此时在主(master)和(slave)上执行下列语句

select * from test;

这时候你会发现 master 能查出id为3的这条记录,但是slave 上面为空

  • 原因

原因其实很简单,就是在master上执行的顺序为先删后插! 而此时binlog为STATEMENT格式,它记录的顺序为先插后删!(事务提交后才生成binlog日志,由于insert事务先提交所以记录的顺序为先插后删),(slave)同步的是binglog,因此从机执行的顺序和主机不一致!就会出现主从不一致!

  • 解决方案
  1. 隔离级别设为可重复读(Repeatable Read),在该隔离级别下引入间隙锁。当Session 1执行delete语句时,会锁住间隙。那么,Ssession 2执行插入语句就会阻塞住!
  2. 将binglog的格式修改为row格式,此时是基于行的复制,自然就不会出现sql执行顺序不一样的问题!奈何这个格式在mysql5.1版本开始才引入。

因此由于历史原因,mysql将默认的隔离级别设为可重复读(Repeatable Read),保证主从复制不出问题!

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-06-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 其他数据库
  • 原因
  • bug重现
相关产品与服务
云数据库 SQL Server
腾讯云数据库 SQL Server (TencentDB for SQL Server)是业界最常用的商用数据库之一,对基于 Windows 架构的应用程序具有完美的支持。TencentDB for SQL Server 拥有微软正版授权,可持续为用户提供最新的功能,避免未授权使用软件的风险。具有即开即用、稳定可靠、安全运行、弹性扩缩等特点。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档