【mysql】- 锁篇(上)
回顾
问题
- 事务并发执行时可能带来各种问题,并发事务访问相同记录的情况大致可以划分为3种
读-读
情况:即并发事务相继读取相同的记录- 读取操作本身不会对记录有什么影响,并不会引起什么问题,所以允许这种情况的发
写-写
情况:即并发事务相继对相同的记录做出改动- 任何一种隔离级别都不允许这种问题的发生。所以在多个未提交事务相继对一条记录做改动时,需要让它们排队执行,这个排队的过程其实是通过
锁
来实现的。这个所谓的锁
其实是一个内存中的结构,在事务执行前本来是没有锁的,也就是说一开始是没有锁结构
和记录进行关联的
- 任何一种隔离级别都不允许这种问题的发生。所以在多个未提交事务相继对一条记录做改动时,需要让它们排队执行,这个排队的过程其实是通过
读-写
或写-读
情况:也就是一个事务进行读取操作,另一个进行改动操作- 这种情况下可能发生
脏读
、不可重复读
、幻读
的问题
- 这种情况下可能发生
解决上述问题方案
- 读操作利多版本并发控制( MVCC ),写操作进行
加锁
- 读、写操作都采用
加锁
的方
一致性读(Consistent Reads)
- 事务利用
MVCC
进行的读取操作称之为一致性读
,或者一致性性锁读
,有的地也称之为快照读
。所有普通的SELECT
语句( plain SELECT )在READ COMMITTED
、REPEATABLE READ
隔离级别下都算是一致性读
,一致性读
并不会对表中的任何记录做加锁
操作,其他事务可以自由的对表中的记录做改动
锁定读(Locking Reads)
并发事务的
读-读
情况并不会引起什么问题,不过对于写-写
、读-写
或写-读
这些情况可能会引起一些问题,需要使用MVCC
或者加锁
的方式来解决它们。在使用加锁
的方式解决问题时,由于既要允许读-读
情况不受影响,又要使写-写
、读-写
或写-读
情况中的操作相互阻塞
共享锁和独占锁
- 共享锁 ,英文名:
Shared Locks
,简称S锁
。在事务要读取一条记录时,需要先获取该记录的S锁
- 独占锁 ,也常称
排他锁
,英文名:Exclusive Locks
,简称X锁
。在事务要改动一条记录时,需要先获取该记录的X锁
- 上述两种锁的场景
- 假如事务
T1
首先获取了一条记录的S锁
之后,事务T2
接着也要访问这条记录:- 如果事务
T2
想要再获取一个记录的S锁
,那么事务T2
也会获得该锁,也就意味着事务T1
和T2
在该记录上同时持有S锁
- 如果事务
T2
想要再获取一个记录的X锁
,那么此操作会被阻塞,直到事务T1
提交之后将S锁
释放掉
- 如果事务
- 如果事务
T1
首先获取了一条记录的X锁
之后,那么不管事务T2
接着想获取该记录的S锁
还是X锁
都会被阻塞,直到事务T1
提交 - 故我们说
S锁
和S锁
是兼容的,S锁
和X锁
是不兼容的,X锁
和X锁
也是不兼容的
- 假如事务
- 共享锁 ,英文名:
锁定读的语句
- 在采用
加锁
方式解决脏读
、不可重复读
、幻读
这些问题时,读取一条记录时需要获取该下该记录的S锁
,其实这是不严谨的,有时候想在读取记录时就获取记录的X锁
,来禁用别的事务读写该记录- 对读取的记录加
S锁
:- 也就是在普通的
SELECT
语句后边加,如果当前事务执行了该语句,那么它会为读取到的记录加S锁
,这样允许别的事务继续获取这些记录的S锁
(比方说别的事务也使用语句来读取这些记录),但是不能获取这些记录的X锁
(比方说使SELECT ... FOR UPDATE
语句来读取这些记录,或者直接修改这些记录)。如果别的事务想要获取这些记录的X锁
,那么它们会阻塞,直到当前事务提交之后将这些记录上的S锁
释放掉
- 也就是在普通的
- 对读取的记录加
X锁
:SELECT ... FOR UPDATE;
也就是在普通的SELECT
语句后边加FOR UPDATE
,如果当前事务执行了该语句,那么它会为读取到的记录加X锁
,这样既不允许别的事务获取这些记录的S锁
(比方说别的事务使用语句来读取这些记录),也不允许获取这些记录的X锁
(比方说使用SELECT ... FOR UPDATE
语句来读取这些记录,或者直接修改这些记录)。如果别的事务想要获取这些记录的S锁
或者X锁
,那么它们会阻塞,直到当前事务提交之后将这些记录上的X锁
释放掉
- 对读取的记录加
- 在采用
写操作
- 平常所用到的
写操作
是DELETE
、UPDATE
、INSERT
这三种:- DELETE:对一条记录做
DELETE
操作的过程其实是先在B+
树中定位到这条记录的位置,然后获取一下这条记录的X锁
,然后再执行delete mark
操作。我们也可以把这个定位待删除记录在B+
树中位置的过程看成是一个获取X锁
的锁定读 - UPDATE:
- 在对一条记录做
UPDATE
操作时分为三种情况:- 如果未修改该记录的键值并且被更新的列占用的存储空间在修改前后未发生变化,则先在
B+
树中定位到这条记录的位置,然后再获取一下记录的X锁
,最后在原记录的位置进行修改操作。其实我们也可以把这个定位待修改记录在B+
树中位置的过程看成是一个获取X锁
的锁定读
- 如果未修改该记录的键值并且至少有一个被更新的列占用的存储空间在修改前后发生变化,则先在
B+
树中定位到这条记录的位置,然后获取一下记录的X锁
,将该记录彻底删除掉(就是把记录彻底移入垃圾链表),最后再插入一条新记录。这个定位待修改记录在B+
树中位置的过程看成是一个获取X锁
的锁定读
,新插入的记录由INSERT
操作提供的隐式锁
进行保护 - 如果修改了该记录的键值,则相当于在原记录上做
DELETE
操作之后再来一次INSERT
操作,加锁操作就需要按照DELETE
和INSERT
的规则进行了
- 如果未修改该记录的键值并且被更新的列占用的存储空间在修改前后未发生变化,则先在
- 在对一条记录做
- NSERT:一般情况下,新插入一条记录的操作并不加锁,通过一种称之为
隐式锁
来保护这条新插入的记录在本事务提交前不被别的事务访问
- DELETE:对一条记录做
- 平常所用到的
前边提到的
锁
都是针对记录的,也可以被称之为行级锁
或者行锁
,对一条记录加锁影响的也只是这条记录而已,我们就说这个锁的粒度比较细;其实一个事务也可以在表级别进行加锁,自然就被称之为表级锁
或者表锁
,对一个表加锁影响整个表中的记录,我们就说这个锁的粒度比较粗。给表加的锁也可以分为共享锁
(S锁
)和独占锁
(X锁
)
- 多粒度锁
- 给表加
S锁
:- 如果一个事务给表加了
S锁
,那么:- 别的事务可以继续获得该表的
S锁
- 别的事务可以继续获得该表中的某些记录的
S锁
- 别的事务不可以继续获得该表的
X锁
- 别的事务不可以继续获得该表中的某些记录的
X锁
- 别的事务可以继续获得该表的
- 如果一个事务给表加了
- 给表加
X锁
:- 如果一个事务给表加了
X锁
(意味着该事务要独占这个表),那么:- 别的事务不可以继续获得该表的
S锁
- 别的事务不可以继续获得该表中的某些记录的
S锁
- 别的事务不可以继续获得该表的
X锁
- 别的事务不可以继续获得该表中的某些记录的
X锁
- 别的事务不可以继续获得该表的
- 如果一个事务给表加了
- 给表加
【mysql】- 锁篇(上)的更多相关文章
- 精通MySQL之锁篇
老刘是即将找工作的研究生,自学大数据开发,一路走来,感慨颇深,网上大数据的资料良莠不齐,于是想写一份详细的大数据开发指南.这份指南把大数据的[基础知识][框架分析][源码理解]都用自己的话描述出来,让 ...
- (6)MySQL进阶篇SQL优化(MyISAM表锁)
1.MySQL锁概述 锁是计算机协调多个进程或线程并发访问某一资源的机制.在数据库中,除传统的计算资源 (如 CPU.RAM.I/O 等)的抢占以外,数据也是一种供许多用户共享的资源.如何保证数 据并 ...
- MySQL优化篇系列文章(二)——MyISAM表锁与InnoDB锁问题
我可以和面试官多聊几句吗?只是想... MySQL优化篇系列文章(基于MySQL8.0测试验证),上部分:优化SQL语句.数据库对象,MyISAM表锁和InnoDB锁问题. 面试官:咦,小伙子,又来啦 ...
- 「MySQL高级篇」MySQL锁机制 && 事务
大家好,我是melo,一名大三后台练习生,最近赶在春招前整理整理发过的博客~! 引言 锁锁锁,到哪到离不开这桩琐事,并发琐事,redis琐事,如今是MySQL琐事,这其中琐事,还跟MySQL另一个重要 ...
- v79.01 鸿蒙内核源码分析(用户态锁篇) | 如何使用快锁Futex(上) | 百篇博客分析OpenHarmony源码
百篇博客分析|本篇为:(用户态锁篇) | 如何使用快锁Futex(上) 进程通讯相关篇为: v26.08 鸿蒙内核源码分析(自旋锁) | 当立贞节牌坊的好同志 v27.05 鸿蒙内核源码分析(互斥锁) ...
- 手把手教你定位线上MySQL锁超时问题,包教包会
昨晚我正在床上睡得着着的,突然来了一条短信. 什么?线上的订单无法取消! 我赶紧登录线上系统,查看业务日志. 发现有MySQL锁超时的错误日志. 不用想,肯定有另一个事务正在修改这条订单,持有这条订单 ...
- mysql锁
锁是计算机协调多个进程或线程并发访问某一资源的机制.在数据库中,除传统的计算资源(如CPU.RAM.I/O等)的争用以外,数据也是一种供许多用户共享的资源.如何保证数据并发访问的一致性.有效性是所有数 ...
- MySQL锁系列3 MDL锁
http://www.cnblogs.com/xpchild/p/3790139.html MySQL为了保护数据字典元数据,使用了metadata lock,即MDL锁,保证在并发的情况下,结构 ...
- Mysql锁机制--索引失效导致行锁变表锁
Mysql 系列文章主页 =============== Tips:在阅读本文前,最好先阅读 这篇(Mysql锁机制--行锁)文章~ 在上篇文章中,我们看到InnoDB默认的行锁可以使得操作不同行时不 ...
- 07: mysql锁和事物隔离
MySQL其他篇 目录: 1.1 MySQL中的事物 1.2 mysql中锁 1.1 MySQL中的事物返回顶部 1.InnoDB事务原理 1. 事务(Transaction)是数据库区别于文件系统的 ...
随机推荐
- JavaWeb开发之四:servlet技术 黑马程序员_轻松掌握JavaWeb开发之四Servlet开发 方立勋老师视频教程相当的经典
总结: 记住:servlet对象在应用程序运行的过程中只创建一次,浏览器每次访问的时候,创建reponse对象 request对象,然后调用servlet的service方法,reponse对象和re ...
- C#判断某元素是否存在数组中
string s = "K2:CENTALINE\\lukshing|K2:CENTALINE"; string[] s1 = s.Split('|'); //判断方式是 等于 而 ...
- LeetCode65. 有效数字
这题完美的诠释了什么叫"面向测试用例编程".由于要考虑的情况很多,所以基本的思路是先根据给出的测试用例写出规则判断无效的情况,然后再根据提交的错误对剩下的情况进行特判,如果不满足所 ...
- JavaScript基础对象创建模式之静态成员(027)
在支持“类”的面向对象语言中,静态成员指的是那些所有实例对象共有的类成员.静态成员实际是是“类”的成员,而非“对象”的成员.所以如果 MathUtils类中有个叫 max()的静态成员方法,那么调用这 ...
- 洛谷 P1991 【无线通讯网】
这道题找到关键点那就是模板题了,代码好写哒~ 因为有S个电话,两个电话就可以连通两个块,那是不是我们就可以看做一条无消耗的边,提前连了起来.根据Kruskal的思想,我们每次加入最小的边,直到联通,由 ...
- 题解 P3870 【[TJOI2009]开关】/基础分块学习小结
直接进入正题: 分块: 分块分块,就是把一个长串东西,分为许多块,这样,我们就可以在操作一个区间的时候,对于在区间里面完整的块,直接操作块,不完整的直接操作即可,因为不完整,再加上一个块本身就不大,复 ...
- jQurey Select2 4.0
https://jeesite.gitee.io/front/jquery-select2/4.0/index.htm
- Apache DolphinScheduler(海豚调度) - 1.3 系列核心表结构剖析
Apache DolphinScheduler 是一个分布式去中心化,易扩展的可视化 DAG 工作流任务调度系统.致力于解决数据处理流程中错综复杂的依赖关系,使调度系统在数据处理流程中开箱即用. 近日 ...
- 美国6w刀的远程工作高级工程师职位,说下在线评估, 倒在第一阶段, 认知能力测试?智商不够怎么办?!
前几天刚被裁员了, 然后在Linkedin上面看到一个crossover的senior software engineer的职位,写的可以remote, 6w刀, 我第一次参加这个公司的这种在线测试, ...
- 每日一题 - 剑指 Offer 30. 包含min函数的栈
题目信息 时间: 2019-06-24 题目链接:Leetcode tag:栈 难易程度:简单 题目描述: 定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的 min 函数在该栈中,调用 m ...