MySQL之Lock探索(二)

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: 联动贴:http://blog.itpub.net/29510932/viewspace-1814690/------------------------------------------------------------------------------接前文...
联动贴: http://blog.itpub.net/29510932/viewspace-1814690/

---------------------------- --------- -----------------------------------------接前文------------------------------------------------------------------------------------------------
前文写了一些锁相关的东西,后半篇写一些各种情况下的锁的情况
-------------------------------------------------------------------------------正文------------------------------------------------------------------------------------------------
测试方法:两个session分别执行简单的insert/delete/update语句,模拟锁的情况
测试环境:官方MySQL-5.6.26,隔离级别REPEATABLE-READREAD 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数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
6月前
|
关系型数据库 MySQL 分布式数据库
PolarDB MySQL版并行查询技术探索与实践
PolarDB MySQL版并行查询技术探索与实践 PolarDB MySQL版在企业级查询加速特性上进行了深度技术探索,其中并行查询作为其重要组成部分,已经在线稳定运行多年,持续演进。本文将详细介绍并行查询的背景、挑战、方案、特性以及实践。
263 2
|
6月前
|
SQL 关系型数据库 MySQL
MySQL调优之大表处理探索那些事
MySQL调优之大表处理探索那些事
227 0
|
1月前
|
关系型数据库 MySQL Java
MySQL数据锁:Record Lock,Gap Lock 和 Next-Key Lock
本文基于 MySQL 8.0.30 版本及 InnoDB 引擎,深入解析三种行锁机制:记录锁(Record Lock)、间隙锁(Gap Lock)和临键锁(Next-key Lock)。记录锁锁定索引记录,确保事务唯一修改;间隙锁锁定索引间的间隙,防止新记录插入;临键锁结合两者,锁定范围并记录自身,有效避免幻读现象。通过具体示例展示了不同锁的作用机制及其在并发控制中的应用。
151 2
|
5月前
|
存储 SQL 关系型数据库
【MySQL技术内幕】6.1-锁、lock和latch
【MySQL技术内幕】6.1-锁、lock和latch
89 0
|
SQL 关系型数据库 MySQL
Mysql Lock Wait
Mysql Lock Wait
183 0
|
关系型数据库 MySQL 数据库
MySQL报错:Lock wait timeout exceeded; try restarting transaction
MySQL报错:Lock wait timeout exceeded; try restarting transaction
641 0
|
SQL 关系型数据库 MySQL
MySQL报错:1205 Lock wait timeout exceeded; try restarting transaction处理
MySQL报错:1205 Lock wait timeout exceeded; try restarting transaction处理
328 0
|
SQL 关系型数据库 MySQL
【MySQL异常】MySQL事务锁问题----lock wait timeout exceeded; try restarting transaction
【MySQL异常】MySQL事务锁问题----lock wait timeout exceeded; try restarting transaction
384 0
|
存储 SQL 关系型数据库
【MySQL】探索MySQL存储过程的魔力,初学者的数据库编程秘笈(内含实战SQL脚本)上
【MySQL】探索MySQL存储过程的魔力,初学者的数据库编程秘笈(内含实战SQL脚本)
361 2
|
存储 SQL 关系型数据库
【MySQL】探索MySQL存储过程的魔力,初学者的数据库编程秘笈(内含实战SQL脚本)下
【MySQL】探索MySQL存储过程的魔力,初学者的数据库编程秘笈(内含实战SQL脚本)
166 1

热门文章

最新文章

下一篇
无影云桌面