联动贴:http://blog.itpub.net/29510932/viewspace-1814690/

------------------------------------------------------------------------------接前文------------------------------------------------------------------------------------------------
前文写了一些锁相关的东西,后半篇写一些各种情况下的锁的情况
-------------------------------------------------------------------------------正文------------------------------------------------------------------------------------------------
测试方法:两个session分别执行简单的insert/delete/update语句,模拟锁的情况
测试环境:官方MySQL-5.6.26,隔离级别REPEATABLE-READ和READ COMMITTED
测试内容:测试表student,试验分为六组,RR,RC两种隔离级别,唯一索引,非唯一索引,无索引三种情况,数据和表结构如下(根据实验的要求,可能简单改一下数据)

1.RR隔离级别,非唯一索引
session1:
delete from student where sid = 10005;
session2:
insert into student values(10006,'se10006');
insert into student values(10008,'se10008');
insert into student values(10010,'se10010');
分析:
从MySQL实现的角度来看,在sid上具备索引,根据MySQL加锁的特点,session1会在索引sid上加上X锁,
但是sid是非唯一索引,如果只对sid=10005这一条记录加锁,并不能阻止其他的事务继续插入sid=10005的数据,从而会误删其他事务插入的sid=10005的数据,
所以MySQL会在10005的前后加上GAP锁(间隙锁),阻止其他事务插入sid处于10005-10007和10007-10009区间的任何数据
加锁的示意图如下

所以10006和10008的数据刚好在GAP锁的范围之内,mysql锁的信息

10010在GAP锁的范围之外(10010既不在10005-10007,也不再10007-10009范围内),所以能够正常的插入

2.RR隔离级别,唯一索引
session1:
delete from student where sid = 10005;
session2:
insert into student values(10006,'se10006');
insert into student values(10008,'se10008');
insert into student values(10010,'se10010');
分析:
从MySQL实现的角度来看,在sid上具备索引,根据MySQL加锁的特点,session1会会在索引sid上加上X锁,
由于sid是唯一索引,所以对与MySQL来说,它能确认在这个索引上,至多只会存在一条数据满足sid=10005,
唯一索引本身的特性会阻止其他的事务继续插入sid=10005的数据,从而防止误删其他事务插入的sid=10005的数据,
所以MySQL只需要在10005加上X锁,而无需加上GAP锁,锁住10005前后的间隙,所以session2的所有语句都不会阻塞。
加锁的示意图如下

MySQL的信息

3.RR隔离级别,无索引
session1:
delete from student where sid = 10005;
session2:
insert into student values(10004,'se10004');
insert into student values(10008,'se10008');
insert into student values(10010,'se10010');
分析:
从MySQL实现的角度来看,在student表上没有索引,根据MySQL本身的特点,MySQL会自动创建一个隐藏的聚簇索引作为主键,
当delete操作执行时,student表不存在任何索引,所以MySQL会用X锁锁住所有的行,锁的标记位在自动创建的聚簇索引上;
当session2试图修改or操作student表的数据时,无法在聚簇索引上加锁,进行锁等待。
加锁示意图如下

MySQL的信息

可以看到由于不存在索引,session1锁住了整个表的所有行,而session2则在等待X锁的释放,X锁是加在自动生成的聚簇索引"GEN_CLUST_INDEX"上。
session2的其他语句有同样的效果,图略去。

4.RC隔离级别,无索引
session1:
delete from student where sid = 10005;
session2:
insert into student values(10006,'se10006');
insert into student values(10005,'se10005');
分析:RC隔离级别,无索引的情况,session1依然会对表的所有行加上X锁,session2的操作会被阻塞
加锁情况:

然而实际情况如下


这是因为MySQL在处理这种锁的情况的时候,会去过滤实际需要锁定的行(sid=10005),然后释放掉不需要的那些行的锁,实际上对所有行的加锁操作还是存在的;

5.RC隔离级别,非唯一索引
session1:
delete from student where sid = 10005;
session2:
insert into student values(10006,'se10006');
update student set sname = '1111' where sid = 10005;
update student set sname = '1111' where sid = 10006;
分析:
RC隔离级别,非唯一索引的情况,session1只会对表的符合条件的行加上X锁,这里补上两个update来看一下X锁的情况
session2的执行情况,可以看到同样在操作10005的时候, 由于锁等待,对10005的update操作被阻塞了,但是对10006的操作是正常的
加锁情况同4

锁情况

6.RC隔离级别,唯一索引
session1:
delete from student where sid = 10005;
session2:
insert into student values(10006,'se10006');
update student set sname = '1111' where sid = 10005;
update student set sname = '1111' where sid = 10006;
分析:
同情况5,只会对符合条件的行加上X锁。
加锁情况同4

7.RR隔离级别
这个情况单独写出来:当delete语句指定的行,在表当中找不到的时候,会有特殊的处理
表内容小改:

session1:
delete from student where sid = 10007;
session2:
insert into student values(10006,'se10006');
insert into student values(10008,'se10008');
insert into student values(10010,'se10010');
分析:student表存在唯一索引,在这种情况下,因为表中不存在这一行数据,所以MySQL会找到>10007且不符合条件的第一行数据,加上X锁,然后在这一条数据的前面加上GAP锁
加锁示意图

mysql的信息

当存在非唯一索引时,与唯一索引是一样的加锁策略,
在无索引的情况下,则是锁住表的全部行。

PS:写在最后,产生死锁的原因,是因为两个事务都需要同时持有多个锁, 但是他们分别持有对方需要的一部分锁。

---------------------------------------------------------------------------------结尾----------------------------------------------------------------------------------------------
前几个试验的时候,session2的insert貌似选的不是很合理,不过实际上GAP锁确实是有加持,在后面的第七种情况里面也能看出来
终于填完了锁的坑,接下来还有metadata lock, index_merge,还有啥来着......太多了....._(:з」∠)_

MySQL之Lock探索(二)相关推荐

  1. mysql metadata lock(二)

    上一篇<mysql metadata lock(一)>介绍了为什么引入MDL,MDL作用以及MDL锁导致阻塞的几种典型场景,文章的最后还留下了一个小小的疑问.本文将更详细的介绍MDL,主要 ...

  2. mysql metadata lock(一)

    想必玩过mysql的人对Waiting for table metadata lock肯定不会陌生,一般都是进行alter操作时被堵住了,导致了我们在show processlist 时,看到线程的状 ...

  3. 关于MySQL出现`lock wait timeout exceeded; try restarting transaction` 的解决方案

    关于MySQL出现lock wait timeout exceeded; try restarting transaction 的解决方案. 一.问题抛出 在做查询语句时,MySQL 抛出了这样的异常 ...

  4. mysql lock not wait_【MySQL】关于MySQL出现lock wait timeout exceeded 的解决方案

    关于MySQL出现lock wait timeout exceeded; try restarting transaction 的解决方案. 一.问题抛出 在做查询语句时,MySQL 抛出了这样的异常 ...

  5. MySQL优化系列(二)--查找优化(1)(非索引设计)

    MySQL优化系列(二)--查找优化(1)(非索引设计) 接下来这篇是查询优化,用户80%的操作基本都在查询,我们有什么理由不去优化他呢??所以这篇博客将会讲解大量的查询优化(索引以及库表结构优化等高 ...

  6. Mysql 共享锁(lock in share mode),排他锁(for update)

    共享锁(lock in share mode) 简介 允许不同事务之前共享加锁读取,但不允许其它事务修改或者加入排他锁 如果有修改必须等待一个事务提交完成,才可以执行,容易出现死锁 共享锁事务之间的读 ...

  7. 【深度学习】DIY 人脸识别技术的探索(二)

    [深度学习]DIY 人脸识别技术的探索(二) 文章目录 训练模型 工具 结果展示 问题二的模型建立与求解 基于 KNN 的人脸识别模型 训练模型 MTCNN 可以并行训练(3 个网络同时训练,前提是内 ...

  8. php数据库访问辅助类,php+MySQL实战案例【二】php数据库辅助类

    前言 在学习php的时候需要经常对mysql数据库进行增删改查操作,为了减少冗余代码,我们把数据操作的方法封装成一个php类.在不同的业务场景需要用到数据库表的数据操作时,只需在php文件开头引入我们 ...

  9. mysql远程连接数据库的二种方法_mysql 远程连接数据库的二种方法

    mysql 远程连接数据库的二种方法 一.连接远程数据库: 1.显示密码 如:MySQL 连接远程数据库(192.168.5.116),端口"3306",用户名为"roo ...

  10. 大数据WEB阶段(六)MySql详解(二)

    MySql详解(二) 一.分组查询 语法: select col_name1,col_name2... from tb_name group by having ...; 练习: 执行下面的SQL,创 ...

最新文章

  1. php tp3 操作绑定到类,快速入门 17:操作绑定到类
  2. Spring3.1+SpringMVC3.1+JPA2.0
  3. HTML5 Web 客户端五种离线存储方式汇总
  4. mybatis,主键返回指的是返回到传入的对象中
  5. python pandas dataframe 转json_python-将嵌套的json转换为pandas dataframe
  6. 04-插入操作更新操作删除操作
  7. java决策树_【Java】决策树介绍和使用
  8. C++新特性探究(二):override、final
  9. uml学习之图书借阅简化用例图创建
  10. labelimg如何调整框的颜色_新手如何快速做字幕?
  11. torch.device用法总结
  12. html中css字体颜色设置,css样式字体设置宋体 css中font字体颜色怎么设置
  13. ipad查看本地文件html文件,ipad如何观看本地视频 怎么用iPad观看电脑上的影片
  14. Java综合实验1题目: 猜心术---猜姓氏游戏
  15. PT-RS for PUSCH
  16. 斩获技术向善奖,云开发上榜 2020 中国技术品牌影响力企业
  17. 微信小游戏 资源服务器,Cocos Creator 微信小游戏 远程资源设置
  18. 祝贺 上海建桥学院,潘笑卓获得2021ACA世界大赛中国赛区季军
  19. 「镁客早报」世界产权组织称:2018年国际专利申请华为排名第一;微软股价大涨,市值超9000亿美元... 1
  20. 什么叫金叉和死叉?什么叫macd二次死叉?

热门文章

  1. Detours信息泄漏漏洞
  2. SQL查询最近几年、几月的数据
  3. VC 中一些控件的使用方法(TabControl, 工具栏)
  4. Html5简单描述(优点与缺点)
  5. bzoj4517[Sdoi2016]排列计数(组合数,错排)
  6. spring---FactoryBean与BeanFactory的区别
  7. 一分钟看懂Docker的网络模式和跨主机通信
  8. 2.描述性统计的matlab 实现
  9. Maven Jetty Plugin 配置指南(翻译)[转]
  10. mysql Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2)