mysql innodb隔离级别_浅析MySQL InnoDB的隔离级别

本文就将对上面这两个问题进行解答,分析事务的隔离级别以及相关锁机制。

隔离性简介

隔离性主要是指数据库系统提供一定的隔离机制,保证事务在不受外部并发操作影响的"独立"环境执行,意思就是多个事务并发执行时,一个事务的执行不应影响其它事务的执行。

4种隔离级别介绍

在SQL标准中定义了4种隔离级别,分别是:

Read uncommitted: 未提交读,事务中的修改,即使没有提交,对其他事务也是可见的。存在脏读

Read committed: 提交读,大多数数据库系统的默认隔离级别(MySQL不是), 一个事务从开始到提交之前,所做的修改对其他事务不可见。解决脏读,存在幻读和不可重复读

repeatable read: 可重复读,该级别保证在同一事务中多次读取同样记录的结果是一致的。解决脏读和不可重复读,理论上存在幻读,但是在InnoDB引擎中解决了幻读

Serializable:可串行化,强制事务串行执行。

上面4种隔离级别是SQL标准定义的,但是在不同的存储引擎中,实现的隔离级别不尽相同。本文主要介绍MySQL InnoDB 存储引擎中的隔离级别,在InnoDB存储引擎中,Repeatable Read 是默认的事务隔离级别,同时该引擎的实现基于多版本的并发控制协议——MVCC (Multi-Version Concurrency Control),解决了幻读问题,当然 脏读和不可重复读也是不存在的。MVCC最大的好处就在于读不加锁,读写不冲突,这样极大的增加了系统的并发性能

Read uncommitted

未提交读,这种情况下,一个事务A可以看到另一个事务B未提交的数据,如果此时事务B发生回滚,那么事务A拿到的就是脏数据,这也就是脏读的含义。此隔离级别在MySQL InnoDB一般不会使用,不做过多说明。

Read Committed

提交读,一个事务从开始直到提交之前,所做的任何修改对其他事务都是不可见的。解决了脏读问题,但是存在幻读现象。

所谓幻读,指的是在同一事务下,连续执行两次同样的SQL语句可能导致不同的结果,第二次的SQL语句可能会返回之前不存在的行,也就是"幻行"。

比如下面这个例子:

1. 首先创建一张表,

CREATE TABLE `t` (   `a` int(11) NOT NULL,   PRIMARY KEY (`a`) ) ENGINE=InnoDB insert into t(a) values(1); insert into t(a) values(2); insert into t(a) values(4); 复制代码

1. 分别执行事务1和事务2:

35a237344a81f6c5010d213e02e4da11.png

可以从上图看出,Read Committed这种隔离级别存在幻读现象。实际上,Read Committed还可能存在不可重复读的问题,不可重复读,指的是一个事务内根据同一条件对行记录进行多次查询,但是查询出的数据结果不一致,原因就是查询区间数据被其他事务修改了。

不可重复读感觉和幻读有点像,实际上,前者强调是同一行记录数据结果不一样,后者强调的时多次查询返回的结果集不一样,增加了或减少了。

Repeatable Read

可重复读,该级别保证在同一事务中多次读取同样记录的结果是一致的,在InnoDB存储引擎中同时解决了幻读和不可重复读问题。至于InnoDB通过什么方式解决幻读和不可重复读问题,后续内容揭晓。

Serializable (可串行化)

Serializable 是最高的隔离级别,它通过 强制事务串行执行,避免了幻读的问题,但是 Serializable 会在读取的每一行数据上都加锁,所以可能导致大量的超时和锁争用的问题,因此并发度急剧下降,在MySQL InnoDB不被建议使用

Read Committed隔离级别下的加锁分析

隔离级别的实现与锁机制密不可分,所以需要引入锁的概念,首先我们看下InnoDB存储引擎提供的两种标准的行级锁:

共享锁(S Lock):又称为读锁,可以允许多个事务并发的读取同一资源,互不干扰。即如果一个事务T对数据A加上共享锁后,其他事务只能对A再加共享锁,不能再加排他锁,只能读数据,不能修改数据

排他锁(X Lock): 又称为写锁,如果事务T对数据A加上排他锁后,其他事务不能再对A加上任何类型的锁,获取排他锁的事务既能读数据,也能修改数据。

注意: 共享锁和排他锁是不相容的。

MySQL InnoDB存储引擎是使用多版本并发控制的,读不加锁,读写不冲突,除非特定场景下的显示加读锁(这里不去探究)。本小节主要分析Read Committed隔离级别下的加锁情况,在MVCC的作用下,一般也就是写操作加X锁了。

加锁操作是和索引紧密相关的,对一个SQL语句进行加锁分析时,也要仔细考究其属性列上的索引类型。假设有数据表t1,有两个列,name列和id列,插入了几条数据,没有明确索引情况:

insert into t1(name,id) values("a",10); insert into t1(name,id) values("b",11); insert into t1(name,id) values("c",13); insert into t1(name,id) values("d",20); 复制代码

下面执行 delete from t1 where id = 10 这条SQL语句,这里的隔离级别设置为Read Committed,从这条SQL语句不能得知id列的索引情况,所以需要分情况讨论:

id列是主键

id列是二级唯一索引

id列是二级非唯一索引

id列上没有索引

id列是主键

id是主键时,上述SQL只需要在id=10这条记录上加X锁即可

id列是二级唯一索引

若id列是唯一索引,而主键是name列,那么SQL需要加上两个X锁,一个对应于id索引上的id=10的记录,另一把锁对应于主键索引上的[name="a",id=10]的记录

id列是二级非唯一索引

若id列上有非唯一索引,那么对应的所有满足SQL查询条件的记录,都会被加锁,同时,这些记录在主键索引上的记录也会被加锁。

id列上没有索引

若id列上没有索引,SQL会走聚簇索引的全扫描进行过滤,由于过滤是由MySQL Sever层面进行的,因此每条记录,无论是否满足条件,都会被加上X锁。

Repeatable Read隔离级别下的加锁分析

前面说过,在Repeatable Read隔离级别下,InnoDB存储引擎解决了幻读和不可重复读问题,具体的原理是怎么样的呢?

之前简短的介绍了InnoDB中行锁的知识,下面来看下行锁的三种算法:

Record Lock: 单个索引记录上的锁,即加X锁

Gap Lock: 间隙锁,锁定一个范围,但不包含记录自身

Next-Key Lock: Gap Lock + Record Lock,锁定一个范围,并且锁定本身。

Record Lock总是会去锁住索引记录,如果InnoDB存储引擎在建表的时候没有设置任何一个索引,那么这时InnoDB会使用隐式的主键来进行锁定。(表没有定义主键的情况,InnoDB会默认添加一个隐式的主键索引)

Next-Key Lock是结合了Gap Lock和Record Lock的一种锁定算法,比如一个索引列有10,11,13和20这4个值,那么该索引可能被Next-Key Locking的区间为:

($-\infty$,10)

(10,11]

(11,13]

(13,20]

(20,$+\infty$)

需要注意一点的是,当查询的索引含有唯一属性时,即是主键索引或者唯一索引时,InnoDB存储引擎会对Next-Key Lock进行优化,将其降级为Record Lock,即仅锁住索引本身,一般加上X锁。

Next-Key Lock机制设计的目的就是为了解决幻读问题,主要针对查询列索引为非唯一索引的时候。以下面这个例子进行说明:

1. 首先创建测试表t1,name是主键索引,id为非唯一索引,即辅助索引

CREATE TABLE `t1` (   `id` int(11) NOT NULL,   `name` varchar(200) DEFAULT NULL,   PRIMARY KEY (`name`),   KEY `id_indx` (`id`) ) ENGINE=InnoDB insert into t1(name,id) values("a",10); insert into t1(name,id) values("b",11); insert into t1(name,id) values("c",13); insert into t1(name,id) values("d",20); 复制代码

1. 执行 delete from t1 where id = 11,其加锁情况如下图所示

e3231275710059ef16d1f362d1e2b775.png

这条SQL通过索引列id进行删除操作,该索引为非唯一索引,所以其使用传统的Next-Key Locking 技术加锁,并且由于有主键索引和辅助索引两个,需要分别进行锁定。对于主键索引(即聚集索引),其仅对列name = "b"的索引加上 Record Lock,实际上就是X锁。

而对于非唯一索引,其加上的时Next-Key Lock,锁定范围是(10,11),对其加上Gap Lock(间隙锁),GAP锁实际上就是加在两条边界记录之间的位置。还需要注意的是,InnoDB还会对辅助索引下一个键值加上gap lock,即看到在(11,13)之间加了一个GAP锁。对于11值本身加上Record Lock,即X锁。

若此时开启另外一个事务执行下面的语句,就会阻塞:

1. select * from t1 where name = "b"; 2. insert into t1(name,id) values("c",12); 复制代码

比如第一条语句不能执行,因为在开始的事务中已经对聚集索引中的列name="b"的值加上了X锁。因此执行会被阻塞。而第二个SQL,同样不能执行,插入的值12在锁定范围(11,13)中,需要阻塞等待。

所以,从上例就可以看出,GAP Lock的作用就是为了阻止多个事务将记录插入到同一范围内,这样就有效的解决了幻读问题。

隔离级别总结

下面总结下InnoDB存储引擎下的各种隔离级别:

隔离级别脏读可能性不可重复读可能性幻读可能性加锁读Read UncommittedYesYesYesNoRead CommittedNoYesYesNoRepeatable ReadNoNoNoNoSerializableNoNoNoYes

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/571546.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

sql 2008服务器内存一直居高不下_经验之谈:内存问题造成数据库性能异常怎么破?...

作者:罗贵林原文链接:https://mp.weixin.qq.com/s/2e5eKSoGlU9J4Rjq1zwLnw导读:在使用数据库的过程中,内存不足常常会引起数据库异常。但是内存不足,又会为数据库带来哪些具体的影响呢?本次,我们…

mysql 字符串匹配函数_mysql 自定义函数 实现字符串匹配

先来一个截图:fSearch函数的第一个参数为单一字符串(即 没有特殊字符串隔开)fSearch函数的第一个参数非单一字符串多个字符串同样可以匹配。函数代码:DELIMITER $$Create function fSearch(targetStr VARCHAR(100),findStr VARCHAR(100)) RETURNS INTBEG…

stm32时钟树_先学STM8,还是学STM32?

有朋友问:我学习过51,接下来我是先学习STM8,还是STM32呢?物联网STM32入门 - 直播课程 - 创客学院​www.makeru.com.cn嵌入式开发直播课 - STM32 USART串口的应用 - 创客学院直播室​www.makeru.com.cn1、写在前面想要明白这个问题…

如何使用django显示一张图片

django显示图片对新手来说真的算是一个坑。。 这里记录下小白爬坑的历程。 首先&#xff0c;你需要一个可以运行的django服务器&#xff0c;能显示正常的html文本&#xff0c;无法显示图片 这是html的文本&#xff0c;可以显示文字&#xff0c;无法显示图片 <h1>An Image…

mysql创建时间字段6_mysql 时间字段介绍

mysql时间类型大概有5种&#xff0c;如下图1、创建数据库create table t1 (id int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,d1_data date,d2_time time,d3_datatime datetime,d4_year year,d5_timestamp TIMESTAMP);字符串方式插入INSERT INTO t1 (d1_data,d2_time,d3_datati…

安装Python 3.6 在Ubuntu 16.04 LTS 版本

在ubuntu 16.04版本中&#xff0c;系统默认安装 了python 2.7和3.5版本&#xff0c;因为系统本身用到python的程序&#xff0c;删除默认的版本又担心系统有问题&#xff0c;那有没有办法同时在安装和使用python 3.6版本呢&#xff1f;下文将一起安装python 3.6并修改原系统的py…

matlab动画_弹簧振子振动的matlab动画演示

用Matlab阐述物理中的胡克定律&#xff0c;为弹簧振子震动的matlab动画示意图&#xff0c;另有一个为不同质量不同弹簧系数的比较。spring.m,compare.mrectangle(position,[12,8.5,2,0.3],FaceColor,[0.5,0.3,0.4]); axis([0,15,-1,10]); hold on plot([13,13],[7,8.5],r,li…

svn合并分支到主干_谈谈代码分支管理

前言从2019年上半年云音乐的客户端团队开始迁移到双周迭代后&#xff0c;随之而来的是我们需要重新调整代码分支的管理方法&#xff0c;来应对开发流程的变更。双周迭代顾名思义一周开发一周测试&#xff0c;目的就是为了快速交付。纵观整个开发流程&#xff0c;我们需要在两周…

ctf实验平台-成绩单

题目链接&#xff1a;http://120.24.86.145:8002/chengjidan/ 平台地址&#xff1a;http://123.206.31.85/ 第一步&#xff1a;暴库 id-1 union select 1,2,3,group_concat(schema_name) from information_schema.schemata# 第二步&#xff1a;爆表 id-1 union select 1,2,3,ta…

python 扫描仪_玩《Minecraft我的世界》学python编程,可领|取电子学习版本

为何选择学习pythonpython是一种解释型、面向对象、动态数据类型的高级程序设计语言&#xff0c;它具有丰富和强大的库&#xff0c;能够把其它语言&#xff08;尤其是c&#xff09;制作的各种模块很轻松地联结在一起。pyton在编程语言排行榜中高居首位。[求抱抱]编程听起来很高…

vue中使用导出表格功能

1.下载依赖 npm install -S file-saver xlsxnpm install -D script-loader 2.在src下创建vendor文件夹&#xff0c;并在文件夹中放两个文件 Blob.js (function (view) {"use strict";view.URL view.URL || view.webkitURL;if (view.Blob && view.URL) {try …

adb shell 书籍_开发必备---你应该知道的一些 ADB 命令

版权声明&#xff1a;本文为LooperJing原创文章&#xff0c;转载请注明出处&#xff01;一、设备相关1、adb devices显示连接到计算机的设备List of devices attachedbe34d81e device输出格式为 [serialNumber] [state]&#xff0c;state 有如下几种&#xff1a;列名解释nodevi…

python生成器迭代_二十、深入Python迭代器和生成器

「Author&#xff1a;Runsen」学习python的过程中&#xff0c;迭代器与生成器是绕不开的话题&#xff0c; 什么是迭代器和生成器呢&#xff1f;下面我们来了解一下什么是迭代。但在了解迭代器之前&#xff0c;首先需要知道什么是容器。容器正所谓&#xff1a;一切都是对象&…

批改网禁止粘贴怎么破_重大利好!教育部声明,要求家长批改作业等行为,发现一起严处一起...

前段时间&#xff0c;在江苏一位家长发布短视频&#xff0c;他在视频中怒喊&#xff1a;我就退出家长群怎么了&#xff01;引起网上一阵热议起因是这位家长认为老师总是让家长帮忙批改作业&#xff0c;自己承担了太多教师应负的责任&#xff0c;完了还要昧着良心说老师你辛苦了…

mysql实验步骤_MySQL双方配置实验步骤

实验环境&#xff1a;两台MariaDB服务器&#xff0c;IP分别为&#xff1a; 172.16.2.16 和 172.16.2.17MariaDB的版本是5.5.36&#xff0c;使用二进制方式安装。已安装完成。/mydata/data 数据库文件存放目录/mydata/binlog/ 二进制日志文件存放位置/mydata/relaylog/ 中继日志…

mac 系统安装 eclipse 方法

经过好几天的折腾&#xff0c;终于在各种不靠谱的经验、说明的忽悠中把自己心爱的 mac 安装上了 eclipse&#xff0c;看到别人的不靠谱&#xff0c;我决定自己写一篇经验&#xff0c;为了大家能够不走我这么多的弯路&#xff0c;也为了自己将来可以回来看看&#xff0c;下次安装…

python自动化和教程_《手把手教你》系列练习篇之2-python+ selenium自动化测试(详细教程)...

1. 简介今天我们还是继续练习练习基本功&#xff0c;各位小伙伴要耐住住性子&#xff0c;要耐得住寂寞啊&#xff0c;不要急躁&#xff0c;后面你会感谢你在前边的不断练习的。到后面也是检验你前边的学习成果的一次很好实践。本文介绍如何通过link text、partial link text、c…

异常在哪一层处理_WiFi速度慢,信号不稳定,除了重启路由器外,自己能怎么处理?...

前言WiFi出了故障&#xff0c;速度慢&#xff0c;信号不稳定&#xff0c;自己处理&#xff0c;除了重启路由器&#xff0c;也没有什么别的招了&#xff1b;好在这万能重启&#xff0c;差不多能解决一大半的小故障&#xff1b;那信号不好&#xff0c;速度慢&#xff0c;不稳定&a…

linux运维、架构之路-HAProxy反向代理

一、HAProxy介绍 专业反向代理,支持双机热备支持虚拟主机,配置简单,拥有非常不错的服务器健康检查功能,当其代理的后端节点出现故障, HAProxy会自动将该服务器摘除,故障恢复后再自动将该服务器加入&#xff0c;基于TCP和HTTP应用的代理软件&#xff0c;开源免费、快速并且可靠的…

CSS3 3D transform变换

transform的坐标是需要了解的特性。 我们的rotateX,rotateY,rotateZ,和translateX,translateY等都是基于相同的坐标系来定位的。 3D的坐标如下入所示&#xff1a; 3D transform中有下面这三个方法&#xff1a; rotateX( angle )rotateY( angle )rotateZ( angle )理解了这三个方…