MySQL锁系列之锁的种类和概念
转自:http://keithlan.github.io/2017/06/05/innodb_locks_1/
锁是MySQL里面最难理解的知识,但是又无处不在。
一开始接触锁的时候,感觉被各种锁类型和名词弄得晕头转向,就别说其他了。
本文是通过DBA的视角(非InnoDB内核开发)来分析和窥探锁的奥秘,并解决实际工作当中遇到的问题
锁的种类&概念
想要啃掉这块最难的大骨头,必须先画一个框架,先了解其全貌,才能逐个击破
- Shared and Exclusive Locks
|
1
2
3
4
5
6
7
|
* Shared lock: 共享锁,官方描述:permits the transaction that holds the lock to read a row
eg:select * from xx where a=1 lock in share mode
* Exclusive Locks:排他锁: permits the transaction that holds the lock to update or delete a row
eg: select * from xx where a=1 for update
|
- Intention Locks
|
1
2
3
4
5
|
1. 这个锁是加在table上的,表示要对下一个层级(记录)进行加锁
2. Intention shared (IS):Transaction T intends to set S locks on individual rows in table t
3. Intention exclusive (IX): Transaction T intends to set X locks on those rows
4. 在数据库层看到的结果是这样的:
TABLE LOCK table `lc_3`.`a` trx id 133588125 lock mode IX
|
- Record Locks
|
1
2
3
4
5
6
|
1. 在数据库层看到的结果是这样的:
RECORD LOCKS space id 281 page no 3 n bits 72 index PRIMARY of table `lc_3`.`a` trx id 133588125 lock_mode X locks rec but not gap
2. 该锁是加在索引上的(从上面的index PRIMARY of table `lc_3`.`a` 就能看出来)
3. 记录锁可以有两种类型:lock_mode X locks rec but not gap && lock_mode S locks rec but not gap
|
- Gap Locks
|
1
2
3
4
5
6
|
1. 在数据库层看到的结果是这样的:
RECORD LOCKS space id 281 page no 5 n bits 72 index idx_c of table `lc_3`.`a` trx id 133588125 lock_mode X locks gap before rec
2. Gap锁是用来防止insert的
3. Gap锁,中文名间隙锁,锁住的不是记录,而是范围,比如:(negative infinity, 10),(10, 11)区间,这里都是开区间哦
|
- Next-Key Locks
|
1
2
3
4
|
1. 在数据库层看到的结果是这样的:
RECORD LOCKS space id 281 page no 5 n bits 72 index idx_c of table `lc_3`.`a` trx id 133588125 lock_mode X
2. Next-Key Locks = Gap Locks + Record Locks 的结合, 不仅仅锁住记录,还会锁住间隙,比如: (negative infinity, 10】,(10, 11】区间,这些右边都是闭区间哦
|
- Insert Intention Locks
|
1
2
3
4
|
1. 在数据库层看到的结果是这样的:
RECORD LOCKS space id 279 page no 3 n bits 72 index PRIMARY of table `lc_3`.`t1` trx id 133587907 lock_mode X insert intention waiting
2. Insert Intention Locks 可以理解为特殊的Gap锁的一种,用以提升并发写入的性能
|
- AUTO-INC Locks
|
1
2
3
4
5
6
7
|
1. 在数据库层看到的结果是这样的:
TABLE LOCK table xx trx id 7498948 lock mode AUTO-INC waiting
2. 属于表级别的锁
3. 自增锁的详细情况可以之前的一篇文章:
http://keithlan.github.io/2017/03/03/auto_increment_lock/
|
- 显示锁 vs 隐示锁
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
* 显示锁(explicit lock)
显示的加锁,在show engine innoDB status 中能够看到 ,会在内存中产生对象,占用内存
eg: select ... for update , select ... lock in share mode
* 隐示锁(implicit lock)
implicit lock 是在索引中对记录逻辑的加锁,但是实际上不产生锁对象,不占用内存空间
* 哪些语句会产生implicit lock 呢?
eg: insert into xx values(xx)
eg: update xx set t=t+1 where id = 1 ; 会对辅助索引加implicit lock
* implicit lock 在什么情况下会转换成 explicit lock
eg: 只有implicit lock 产生冲突的时候,会自动转换成explicit lock,这样做的好处就是降低锁的开销
eg: 比如:我插入了一条记录10,本身这个记录加上implicit lock,如果这时候有人再去更新这条10的记录,那么就会自动转换成explicit lock
* 数据库怎么知道implicit lock的存在呢?如何实现锁的转化呢?
1. 对于聚集索引上面的记录,有db_trx_id,如果该事务id在活跃事务列表中,那么说明还没有提交,那么implicit则存在
2. 对于非聚集索引:由于上面没有事务id,那么可以通过上面的主键id,再通过主键id上面的事务id来判断,不过算法要非常复杂,这里不做介绍
|
- metadata lock
|
1
2
|
1. 这是Server 层实现的锁,跟引擎层无关
2. 当你执行select的时候,如果这时候有ddl语句,那么ddl会被阻塞,因为select语句拥有metadata lock,防止元数据被改掉
|
- 锁迁移
|
1
2
3
4
5
6
|
1. 锁迁移,又名锁继承
2. 什么是锁迁移呢?
a) 满足的场景条件:
b)我锁住的记录是一条已经被标记为删除的记录,但是还没有被puge
c) 然后这条被标记为删除的记录,被purge掉了
d) 那么上面的锁自然而然就继承给了下一条记录,我们称之为锁迁移
|
- 锁升级
|
1
2
|
锁升级指的是:一条全表更新的语句,那么数据库就会对所有记录进行加锁,那么可能造成锁开销非常大,可能升级为页锁,或者表锁。
MySQL 没有锁升级
|
- 锁分裂
|
1
2
3
4
|
1. InnoDB的实现加锁,其实是在页上面做的,没有办法直接对记录加锁
2. 一个页被读取到内存,然后会产生锁对象,锁对象里面会有位图信息来表示哪些heapno被锁住,heapno表示的就是堆的序列号,可以认为就是定位到某一条记录
3. 大家又知道,由于B+tree的存在,当insert的时候,会产生页的分裂动作
4. 如果页分裂了,那么原来对页上面的加锁位图信息也就变了,为了保持这种变化和锁信息,锁对象也会分裂,由于继续维护分裂后页的锁信息
|
- 锁合并
|
1
2
3
|
锁的合并,和锁的分裂,其实原理是一样的,参考上面即可。
至于锁合并和锁分裂的算法,比较复杂,这里就不介绍了
|
- latch vs lock
|
1
2
3
4
5
6
7
8
9
10
11
|
* latch
mutex
rw-lock
临界资源用完释放
不支持死锁检测
以上是应用程序中的锁,不是数据库的锁
* lock
当事务结束后,释放
支持死锁检测
数据库中的锁
|
锁的兼容矩阵
- X vs S
| 兼容性 | X | S |
|---|---|---|
| X | N | N |
| S | N | Y |
- IS,IX,S,X
| 兼容性 | IS | IX | S | X |
|---|---|---|---|---|
| IS | Y | Y | Y | N |
| IX | Y | Y | N | N |
| S | Y | N | Y | N |
| X | N | N | N | N |
- AI,IS,IX,S,X
| 兼容性 | AI | IS | IX | S | X |
|---|---|---|---|---|---|
| AI | N | Y | Y | N | N |
| IS | Y | Y | Y | Y | N |
| IX | Y | Y | Y | N | N |
| S | N | Y | N | Y | N |
MySQL锁系列之锁的种类和概念的更多相关文章
- mysql小白系列_07 锁与事务
1.MySQL参数autocommit生产环境设1还是0?为什么? 2.MySQL参数tx_isolation生产环境上大多数是设什么值,为什么? 3.与MySQL锁相关的有哪些因素? 1.MySQL ...
- MySQL锁系列1
http://www.cnblogs.com/xpchild/p/3782311.html MySQL的锁:MySQL内部有很多种类的锁,按照用途不同,可以分为两类:1. 保护内存结构的锁,实现同 ...
- mysql 开发进阶篇系列 10 锁问题 (相同索引键值或同一行或间隙锁的冲突)
1.使用相同索引键值的冲突 由于mysql 的行锁是针对索引加的锁,不是针对记录加的锁,所以虽然是访问不同行的记录,但如果是使用相同的索引键,是会出现锁冲突的.设计时要注意 例如:city表city_ ...
- Mysql高手系列 - 第26篇:聊聊如何使用mysql实现分布式锁
Mysql系列的目标是:通过这个系列从入门到全面掌握一个高级开发所需要的全部技能. 欢迎大家加我微信itsoku一起交流java.算法.数据库相关技术. 这是Mysql系列第26篇. 本篇我们使用my ...
- 深入理解MySQL系列之锁
按锁思想分类 悲观锁 优点:适合在写多读少的并发环境中使用,虽然无法维持非常高的性能,但是在乐观锁无法提更好的性能前提下,可以做到数据的安全性 缺点:加锁会增加系统开销,虽然能保证数据的安全,但数据处 ...
- S 锁与 X 锁的爱恨情仇《死磕MySQL系列 四》
系列文章 一.原来一条select语句在MySQL是这样执行的<死磕MySQL系列 一> 二.一生挚友redo log.binlog<死磕MySQL系列 二> 三.MySQL强 ...
- MySQL优化篇系列文章(二)——MyISAM表锁与InnoDB锁问题
我可以和面试官多聊几句吗?只是想... MySQL优化篇系列文章(基于MySQL8.0测试验证),上部分:优化SQL语句.数据库对象,MyISAM表锁和InnoDB锁问题. 面试官:咦,小伙子,又来啦 ...
- MySQL锁系列3 MDL锁
http://www.cnblogs.com/xpchild/p/3790139.html MySQL为了保护数据字典元数据,使用了metadata lock,即MDL锁,保证在并发的情况下,结构 ...
- mysql 开发进阶篇系列 13 锁问题(关于表锁,死锁示例,锁等待设置)
一. 什么时候使用表锁 对于INNODB表,在绝大部分情况下都应该使用行锁.在个别特殊事务中,可以考虑使用表锁(建议). 1. 事务需要更新大部份或全部数据,表又比较大,默认的行锁不仅使这个事务执行效 ...
随机推荐
- 《松本行弘的程序世界》读书笔记(上)——面向对象、程序块、设计模式、ajax
1. 前言 半个月之前买了这本书,还是经园子里的一位网友推荐的.到现在看了一半多,基础的都看完了,剩下的几章可做高级部分来看.这本书看到现在,可以说感触很深,必须做一次读书笔记! 关于这本书,不了解的 ...
- 第三方登录:微信扫码登录(OAuth2.0)
1.OAuth2.0 OAuth(开放授权)是一个开放标准,允许用户让第三方应用访问该用户在某一网站上存储的私密的资源(如照片,视频,联系人列表),而无需将用户名和密码提供给第三方应用. 允许用户提供 ...
- 利用Django构建web应用及其部署
注:很久之前就有了学习Django的想法,最近终于有机会做了一次尝试.由于Django的详细教程很多,我在这里就不再详述了,只是将整个开发流程以及自己在学习Django中的一些思考记录在此. Syst ...
- tomcat 的自问自答与总结
目录 1 tomcat 的加载问题,启动后更新是否自动加载 2 tomcat 的context.xml 文件读取顺序与覆盖原则 3 就是 建议的tomcat 配置 4 避免二次部署加载的问题 在查看了 ...
- 查看Linux操作系统位数
方法一: # uname -a x86_64则说明你是64位内核, 跑的是64位的系统. i386, i686说明你是32位的内核, 跑的是32位的系统 ----------------------- ...
- 【转】CSS选择器笔记
作者: 阮一峰 日期: 2009年3月12日 来源:http://www.ruanyifeng.com/blog/2009/03/css_selectors.html 去年我学jQuery的时候,曾经 ...
- 并发编程之 CountDown 源码分析
前言 Doug Lea 大神在 JUC 包中为我们准备了大量的多线程工具,其中包括 CountDownLatch ,名为倒计时门栓,好像不太好理解.不过,今天的文章之后,我们就彻底理解了. 如何使用? ...
- Java的策略模式
策略模式也是我们经常使用的模式,它的定义如下:将可变的部分从程序中抽象分离出来成为算法接口,在该部分下分别封装一系列算法实现并使它们可以相互替换. 举个例子,我们现在有三种支付方式:支付宝支付,微信支 ...
- Code Signal_练习题_absoluteValuesSumMinimization
Given a sorted array of integers a, find an integer x from a such that the value of abs(a[0] - x) + ...
- vue.js自定义指令详解
写在文本前:相信在做vue的项目,你肯定接触了指令,我们常用vue内置的一些指令,比如v-model,v-text,v-if,v-show等等,但是这些内置指令不在本文的讲解范畴,本文想说的是其自定义 ...