2019独角兽企业重金招聘Python工程师标准>>>

(1)MVCC与基于锁的并发控制

MySql的InnoDB引擎,实现的是基于多版本的并发控制协议:MVCC。

MVCC最大的好处,即读不加锁,读写不冲突。在读多于写的应用中,读写不冲突是非常重要的,极大的增强了系统的并发性能。这也就是为什么,几乎所有的RDBMS都支持了MVCC。

(2)快照读与当前读

          1.快照读

简单的select操作,属于快照读,不加锁(当然如果是Serializable隔离级别还是要加锁)

如:select * from table where ?

          2.当前读

包括特殊的读操作,插入、更新、删除操作,都属于当前读,需要加锁

如:

select * from table where ? lock in share mode;

select * from table where ? for update;

insert into table values(...);

update table set ? where ?

delete from table where?

所有以上语句,都属于当前读,读取记录的最新版本。并且读取之后,还要保证其他并发事务不能修改当前记录,对读取的记录加锁。

其中,除了第一条语句,对读取记录加S锁(共享锁)以外,其他的操作,都加的是X锁(排他锁)

          3.为何插入、更新、删除操作都属于当前读?

更新操作的执行流程如下:

从图中可以看到一个update操作的具体流程:

1.update sql发送到mysql后,mysql server会根据where条件,读取第一条满足条件的记录,然后InnoDB引擎会将第一条记录返回,并对记录加锁

2.mysql server收到这条加锁的记录后,会再发起一个update请求,更新这条记录

3.这条记录操作完成,再读取下一条记录,直至没有满足条件的记录为止 。

注意:针对一条当前读的sql,InnoDB与mysql server的交互,是一条条进行的,因此加锁也是一条条进行的。

先对一条满足条件的记录加锁,返回给mysql server,做一些DML操作;然后再读取下一条并加锁,直至读取完毕

(3)2PL:Two-Phase Locking

传统的RDBMS加锁的一个原则就是2PL(二阶段锁)。

简单地说就是锁操作分为2个阶段:加锁阶段与解锁阶段,并且保证加锁阶段与解锁阶段不相交。

从上图可以看出,2PL就是将加锁、解锁分为2个完全不相交的阶段:加锁阶段:只加锁不放锁,解锁阶段:只放锁不加锁

(4)隔离级别与加锁

           1.read uncommitted

读未提交,不会使用,忽略

           2.read committed(RC)

快照读不加锁

当前读,RC隔离级别保证对读取到的记录加锁,但存在幻读情况

           3.repeatable read (RR)

快照读不加锁

当前读,RR隔离级别保证对读到的记录加锁,同时保证对读取的范围加锁,因此新的满足查询条件的记录不能够插入(间隙锁),因而不存在幻读情况

           4.serializable

从MVCC退化为基于锁的并发控制。不区别快照读和当前读,所有的读操作均为当前读,读加读锁(S锁),写加写锁(X锁)

serializable隔离级别下,读写冲突,因此并发度急剧下降,不建议使用。

(5)加锁分析

因为快照读在RC、RR下都不加锁,所以我们不讨论快照读,而只讨论当前读的情况

接下来以delete from t1 where id=10这条sql为例,来分析加锁的情况

            1.id主键+RC

这个组合最为简单。因为id为主键,where的条件为id=10,所以只需要在id=10的记录上加X锁即可

            2.id唯一键+RC

name为主键,id为唯一键,那么在RC隔离级别下,delete from t1 where id=10需要如何加锁呢?

先对唯一索引树上id=10的记录加上X锁,然后因为id=10对应的是name=d,那么从主键索引上查找到name=d的记录,然后对这条记录加X锁。

            3.id非唯一键索引+RC

此时在id的索引树上id=10的有2条记录,所以先对这2条记录加锁。

然后因为name是主键,所以在主键索引上查找到name=b和name=d的记录,然后对这2条记录加锁

            4.id无索引+RC

因为id无索引,所以就只能全表扫描了,此时会对所有记录加X锁(但实际情况会优化)

            5.id主键+RR

id列是主键,RR隔离级别,这条sql与在RC级别下一致,都是对这条记录加X锁

            6.id唯一键+RR

与RC下一致,也是先对唯一索引树上记录加X锁,然后对主键索引树上对应记录加X锁

            7.id非唯一键+RR

这与RC隔离级别下有很大差别,主要是多了一个gap锁,而且gap锁是加在记录之间,而不是加在记录之上。

gap锁有什么用呢?实际上这个gap锁就是RR隔离级别,这是相对于RC隔离级别而言,不会出现幻读的关键。

gap锁锁住的位置,不是记录本身,而是2条记录之间的gap。所谓幻读,就是在同一个事务中,连续做两次当前读,比如select * from t1 where id =10 for update,出现了2次记录数量不一致的情况,就好像见到鬼了。

那么如何保证两次当前读返回一致的记录数呢?那就需要根据where条件确定记录范围,然后保证在这个范围内,不会被其他事物插入新的、满足条件的记录。(举个例子:假如条件为select * from table id>5 and id <10,而表中只有id=7,id=8两条记录满足条件,如果有了gap锁,那么就会将id=6的左边和id=7的右边边界加上gap锁,这样如果其他事务要插入一条id=9的记录,就需要等待了)这就是gap锁的作用。

            7.id无索引+RR

这种情况必须要进行全表扫描,因而需要首先需要对所有记录加X锁,并且为了防止幻读,对所有数据的间隙加上了gap锁

此时全表被锁死,无法更新、删除、插入

            8.serializable

读写全部加X锁

转载于:https://my.oschina.net/cpf2016/blog/726776

MqSql的加锁分析相关推荐

  1. MySQL的并发控制与加锁分析

    2019独角兽企业重金招聘Python工程师标准>>> 本文主要是针对MySQL/InnoDB的并发控制和加锁技术做一个比较深入的剖析,并且对其中涉及到的重要的概念,如多版本并发控制 ...

  2. c++客户端发送加锁_MySQL语句加锁分析详解

    前言 建立一个存储三国英雄的hero表: CREATE TABLE hero ( number INT, name VARCHAR(100), country varchar(100), PRIMAR ...

  3. mysql 并发_MySQL的并发控制与加锁分析

    本文主要是针对MySQL/InnoDB的并发控制和加锁技术做一个比较深入的剖析,并且对其中涉及到的重要的概念,如多版本并发控制(MVCC),脏读(dirty read),幻读(phantom read ...

  4. mysql 索引加锁分析

    mysql 索引加锁分析 背景 MVCC:Snapshot Read vs Current Read Cluster Index:聚簇索引 2PL:Two-Phase Locking Isolatio ...

  5. mysql加锁分析 何登成_何登成的技术博客 ? MySQL 加锁处理分析

    背景 MySQL/InnoDB的加锁分析,一直是一个比较困难的话题.我在工作过程中,经常会有同事咨询这方面的问题.同时,微博上也经常会收到MySQL锁相关的私信,让我帮助解决一些死锁的问题.本文,准备 ...

  6. MySQL DELETE 删除语句加锁分析

    MySQL DELETE 删除语句加锁分析 Posted on 2017-09-24 by Harvey Leave a comment  MySQL http://www.fordba.com/lo ...

  7. 常见SQL语句的加锁分析

    这篇博客将对一些常见的 SQL 语句进行加锁分析,看看我们平时执行的那些 SQL 都会加什么锁.只有对我们所写的 SQL 语句加锁过程了如指掌,才能在遇到死锁问题时倒推出是什么锁导致的问题.在前面的博 ...

  8. MYSQL死锁之路 - 常见SQL语句的加锁分析

    这篇博客将对一些常见的 SQL 语句进行加锁分析,看看我们平时执行的那些 SQL 都会加什么锁.只有对我们所写的 SQL 语句加锁过程了如指掌,才能在遇到死锁问题时倒推出是什么锁导致的问题.在前面的博 ...

  9. 常见 SQL 语句的加锁分析

    这篇博客将对一些常见的 SQL 语句进行加锁分析,看看我们平时执行的那些 SQL 都会加什么锁.只有对我们所写的 SQL 语句加锁过程了如指掌,才能在遇到死锁问题时倒推出是什么锁导致的问题.在前面的博 ...

最新文章

  1. Linux数组计算平均值,从数组中读取并计算平均值
  2. 数字图像处理2:传统插值
  3. 从一次故障聊聊前端 UI 自动化测试
  4. Nodejs如何调用Dll模块
  5. 强连通分量(Strongly_Connected_Components)
  6. CodeForces 841C (C) Leha and Function 贪心
  7. Linux利用PROMPT_COMMAND实现审计功能
  8. 北大博士,毕业做北京城管,他的同事清一色名校硕士,博士,这个世界怎么了?...
  9. server sql 数据c盘迁移d盘_C盘空间不足怎么办?如何给C盘扩容?
  10. python类的构造方法和assert的使用,用MethodType动态绑定类方法
  11. struts2与spring集成时,关于class属性及成员bean自动注入的问题
  12. select、poll与epoll的优缺点
  13. 图像融合(四)-- 对比度金字塔
  14. Ubuntu 搭建简单的git server
  15. LabVIEW软件、驱动安装及编程方法(理论篇—2)
  16. c++字符串题目:小草与小球
  17. c++中无名命名空间的使用
  18. python在哪下载安装,python软件在哪下载
  19. 人工智能导论课程论文:人工智能及其发展趋势
  20. 在linux中使用lftp和sftp下载文件(夹)

热门文章

  1. python简单操作题_Python简单练习题可以一起做做
  2. 【网络流24题】试题库问题
  3. Maven Jrebel 多模块热部署方案
  4. [Android学习系列8]数据库ormlite笔记
  5. [zz] 几种类间关系:继承、实现、依赖、关联、聚合、组合及UML实现图
  6. OpenCV用于人脸检测
  7. 粒子滤波 演示与opencv代码
  8. 五大存储模型关系模型、键值存储、文档存储、列式存储、图形数据
  9. 微软研究员在ImageNet计算机视觉识别挑战中实现里程碑式突破
  10. Linux下glibc内存管理