• 售前

  • 售后

热门帖子
入门百科

为什么MySQL选择Repeatable Read作为默认隔离级别

[复制链接]
李志敏 显示全部楼层 发表于 2021-8-14 14:57:30 |阅读模式 打印 上一主题 下一主题
目次


  • Oracle 的隔离级别
  • MySQL 的隔离级别
  • 总结
关于MySQL的事故隔离级别,相信许多读者都不陌生,网商有许多种相干的文章,许多人对于各种隔离级别,以及差别的级别可以办理的一些读现象都是如数家珍的。
我们知道,ANSI/ISO SQL定义的尺度隔离级别有四种,从高到底依次为:可序列化(Serializable)、可重复读(Repeatable Reads)、提交读(Read Committed)、未提交读(Read Uncommitted)。

RU隔离级别下,大概发生脏读、幻读、不可重复读等题目。RC隔离级别下,办理了脏读的题目,存在幻读、不可重复读的题目。RR隔离级别下,办理了脏读、不可重复读的题目,存在幻读的题目。Serializable隔离级别下,办理了脏读、幻读、不可重复读的题目。
这四种隔离级别是ANSI/ISO SQL定义的尺度定义的,我们比力常用的MySQL对这四种隔离级别是都支持的。但是Oracle数据库只支持Serializable和Read Committed
但是,大概许多人都不知道,Oracle默认的隔离级别是 RC,而MySQL默认的隔离级别是 RR。
那么,你知道为什么Oracle选择RC作为默认级别,而MySQL要选择RR作为默认的隔离级别吗?
  1. 这是我之前面试的时候,问过候选人的一个问题。
  2. 很多人认为这个问题没有意义,这不是在逼着我们背八股文么?
  3. 但是其实并不是,如果你能耐心的看完这篇文章,你就会发现我的<strong>良苦用心</strong>。
复制代码
Oracle 的隔离级别

前面我们说过,Oracle只只支持ANSI/ISO SQL定义的Serializable和Read Committed,其实,根据Oracle官方文档给出的先容,Oracle支持三种隔离级别:

即Oracle支持Read Committed、Serializable和Read-Only。
Read-Only只读隔离级别类似于可序列化隔离级别,但是只读事故不允许在事故中修改数据,除非用户是SYS。
在Oracle这三种隔离级别中,Serializable和Read-Only显然都是不适互助为默认隔离级别的,那么就只剩Read Committed这个唯一的选择了。

MySQL 的隔离级别

相比于Oracle,MySQL的默认隔离级别的可选范围就比力大了。
起首,我们先从四种隔离级别中清除Serializable和Read Uncommitted这两种,主要是因为这两个级别一个隔离级别太高,一个太低。太高的就会影响并发度,太低的就有脏读现象。
那么,剩下的RR和RC两种,怎么选?
这件事要从long long ago 提及。
在MySQL计划之处,他的定位就是提供一个稳固的关系型数据库。而为了要办理MySQL单点故障带来的题目,MySQL采用主从复制的机制。
所谓主从复制,其实就是通过搭建MySQL集群,团体对外提供服务,集群中的机器分为主服务器(Master)和从服务器(Slave),主服务器提供写服务,从服务器提供读服务。
为了包管主从服务器之间的数据的同等性,就须要举行数据同步,大抵的同步过程如下,这里就不具体先容了

MySQL在主从复制的过程中,数据的同步是通过bin log举行的,简单明白就是主服务器把数据变动记载到bin log中,然后再把bin log同步传输给从服务器,从服务器吸收到bin log之后,再把其中的数据恢复到自己的数据库存储中。
那么,binlog内里记载的是什么内容呢?格式是怎样的呢?
MySQL的bin log主要支持三种格式,分别是statement、row以及mixed。MySQL是在5.1.5版本开始支持row的、在5.1.8版本中开始支持mixed。
statement和row最大的区别,当binlog的格式为statemen时,binlog 内里记载的就是 SQL 语句的原文(这句话很紧张!!!背面会用的到)。
关于这几种格式的区别,就不在这里具体睁开了,之以是要支持row格式,主要是因为statement格式中存在许多题目,最明显的就是大概会导致主从数据库的数据差别等。具体先容可以参考丁奇在极客时间上面的分享《MySQL实战45讲》。
那么,讲这个主从同步和bin log我们要讲的隔离级别有啥关系呢?
有关系,而且关系很大。
因为MySQL早期只有statement这种bin log格式,这时间,假如利用提交读(Read Committed)、未提交读(Read Uncommitted)这两种隔离级别会出现题目。
好比,在MySQL官网上,有人就给官方曾经提过一个相干的Bug

这个bug的复现过程如下:
有一个数据库表t1,表中有如下两条记载:
  1.    CREATE TABLE t1 (
  2.       a int(11) DEFAULT NULL,
  3.       b int(11) DEFAULT NULL,
  4.       KEY a (a)
  5.     ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
  6.     insert into t1 values(10,2),(20,1);
复制代码
接着开始实行两个事故的写操纵:

以上两个事故实行之后,数据库内里的记载会变成(11,2)和(20,2),这个发上在主库的数据变动大家都能明白。
因为事故的隔离级别是read committed,以是,事故1在更新时,只会对b=2这行加上行级锁,不会影响到事故2对b=1这行的写操纵。
以上两个事故实行之后,会在bin log中记载两条记载,因为事故2先提交,以是
  1. UPDATE t1 SET b=2 where b=1;
复制代码
会被优先记载,然后再记载
  1. UPDATE t1 SET a=11 where b=2;
复制代码
(再次提醒:statement格式的bin log记载的是SQL语句的原文)
如许bin log同步到备库之后,SQL语句回放时,会先实行
  1. UPDATE t1 SET b=2 where b=1;
复制代码
,再实行
  1. UPDATE t1 SET a=11 where b=2;
复制代码

这时间,数据库中的数据就会变成(11,2)和(11,2)。这就导致主库和备库的数据差别等了!!!
为了避免如许的题目发生。MySQL就把数据库的默认隔离级别设置成了Repetable Read,那么,Repetable Read的隔离级别下是怎样办理如许题目的那?
那是因为Repetable Read这种隔离级别,会在更新数据的时间不但对更新的行加行级锁,还会增长GAP lock。上面的例子,在事故2实行的时间,因为事故1增长了GAP lock,就会导致事故实行被卡住,须要等事故1提交或者回滚后才气继承实行。(关于GAP lock,我背面会有文章单独先容)。
除了设置默认的隔离级别外,MySQL还克制在利用statement格式的bin log的环境下,利用READ COMMITTED作为事故隔离级别。
一旦用户主动修改隔离级别,实验更新时,会报错:
  1. <strong> </strong>ERROR 1598 (HY000): Binary logging not possible. Message: Transaction level 'READ-COMMITTED' in InnoDB is not safe for binlog mode 'STATEMENT'
复制代码
总结

以是,现在我们知道了,为什么MySQL选择RR作为默认的数据库隔离级别了吧,其实就是为了兼容汗青上的那种statement格式的bin log。
那么,本文讲到这里,算是关于MySQL隔离级别这个知识点讲了大概不到1/5吧,通过这篇文章, 你或许还会有以下题目:
1、row格式和statement有什么区别?利用row的环境下,可以利用RR吗?
2、文中提到的RC的GAP lock到底是什么?
3、RR和RC到底有什么区别?RC是怎样办理不可重复读题目的?
4、既然MySQL数据库默认选择了RR,那么,为啥像阿里这种大的互联网公司会把默认的隔离级别改成RC?
关于以上几个题目,你知道答案吗,或者你对哪个更感爱好呢?欢迎留言!我会挑大家较为感爱好的专题在背面的文章中继承深入睁开先容。
  1. 现在你还觉得这个问题没有意义吗?
  2. 我其实是想通过这样一个看似无意义的问题,延展出更多的知识,这样可以更加全方位的了解候选人。
复制代码
到此这篇关于为什么MySQL选择Repeatable Read作为默认隔离级别的文章就先容到这了,更多相干MySQL Repeatable Read默认隔离级别内容请搜索草根技术分享以前的文章或继承欣赏下面的相干文章盼望大家以后多多支持草根技术分享!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x

帖子地址: 

回复

使用道具 举报

分享
推广
火星云矿 | 预约S19Pro,享500抵1000!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

草根技术分享(草根吧)是全球知名中文IT技术交流平台,创建于2021年,包含原创博客、精品问答、职业培训、技术社区、资源下载等产品服务,提供原创、优质、完整内容的专业IT技术开发社区。
  • 官方手机版

  • 微信公众号

  • 商务合作