社区编辑申请
注册/登录
别废话,各种SQL到底加了什么锁?
数据库 MySQL
MySQL加的锁,和事务隔离级别相关,又和索引相关,下面,我们尝试花两分钟讲讲看。

有朋友留言,问能不能花2分钟讲讲,MySQL的各类SQL语句,究竟加了什么锁?

额,MySQL加的锁,和事务隔离级别相关,又和索引相关,尝试花2分钟讲讲看。

画外音:这2分钟需要的辅助知识,都已经附带了链接,贴心吧!

第一类,普通select加什么锁?

(1)在读未提交(Read Uncommitted),读提交(Read Committed, RC),可重复读(Repeated Read, RR)这三种事务隔离级别下,普通select使用快照读(snpashot read),不加锁,并发非常高;

(2)在串行化(Serializable)这种事务的隔离级别下,普通select会升级为select ... in share mode;

【快照读】辅助阅读:《​​InnoDB,并发如此之高的原因​​》

第二类,加锁select加什么锁?

加锁select主要是指:

  • select ... for update
  • select ... in share mode

(1)如果,在唯一索引(unique index)上使用唯一的查询条件(unique search condition),会使用记录锁(record lock),而不会封锁记录之间的间隔,即不会使用间隙锁(gap lock)与临键锁(next-key lock);

【记录锁,间隙锁,临键锁】辅助阅读:《​​InnoDB里的七种锁​​》

举个栗子,假设有InnoDB表:

t(id PK, name);

表中有三条记录:

  • shenjian
  • zhangsan
  • lisi

SQL语句:

select * from t where id=1 for update;

只会封锁记录,而不会封锁区间。

(2)其他的查询条件和索引条件,InnoDB会封锁被扫描的索引范围,并使用间隙锁与临键锁,避免索引范围区间插入记录;

第三类,update与delete加什么锁?

(1)和加锁select类似,如果在唯一索引上使用唯一的查询条件来update/delete,例如:update t set name=xxx where id=1;也只加记录锁;

(2)否则,符合查询条件的索引记录之前,都会加排他临键锁(exclusive next-key lock),来封锁索引记录与之前的区间;

(3)尤其需要特殊说明的是,如果update的是聚集索引(clustered index)记录,则对应的普通索引(secondary index)记录也会被隐式加锁,这是由InnoDB索引的实现机制决定的:普通索引存储PK的值,检索普通索引本质上要二次扫描聚集索引。

【索引底层实现】辅助阅读:《​​索引,底层是如何实现的?​​》

【聚集索引与普通索引的实现差异】辅助阅读:《​​InnoDB,聚集索引与普通索引有什么不同?​​》

第四类,insert加什么锁?

同样是写操作,insert和update与delete不同,它会用排它锁封锁被插入的索引记录,而不会封锁记录之前的范围。

同时,会在插入区间加插入意向锁(insert intention lock),但这个并不会真正封锁区间,也不会阻止相同区间的不同KEY插入。

【插入意向锁】辅助阅读:《​​InnoDB里的七种锁​​》

了解不同SQL语句的加锁,对于分析多个事务之间的并发与互斥,以及事务死锁,非常有帮助。

画外音:文章的参考资料为MySQL官网,以及楼主对MySQL的理解,版本基于5.6,欢迎探讨。

希望这2分钟,大家有收获。

来源链接:

http://mp.weixin.qq.com/s?__biz=MjM5ODYxMDA5OQ==&mid=2651969353&idx=1&sn=9ded4fe3fcfc9e3daf1ce52054671b4a&chksm=bd2d62958a5aeb835405358634ffea69936a6dd3941dd2a338401661c77393838879c043db69&mpshare=1&scene=23&srcid=0118Za6sAKYOr1w7CpQHHEMB&sharer_sharetime=1642517052262&sharer_shareid=9603544ecd5d7f3dc66603ae089636f4#rd

责任编辑:赵宁宁 来源: 架构师之路
相关推荐

2022-04-01 10:08:21

SQL 优化MySQL数据库

2022-04-19 14:41:29

Oracle数据库SQL

2022-05-18 08:05:31

2022-05-12 23:38:19

SQL数据库字符串

2022-04-21 08:09:18

Spark字段血缘Spark SQL

2022-05-07 15:31:19

物联网5G智慧城市

2022-04-22 14:41:12

美团慢查询数据库

2022-04-11 13:37:54

编程语言PythonMATLAB

2022-03-16 14:45:18

MySQL慢查询数据库

2022-03-02 11:37:57

参数性能调优

2022-04-25 11:26:16

开发SpringBoot

2022-04-02 10:23:12

MySQL数据库

2022-03-25 09:04:01

Mysql数据库

2022-04-26 08:10:33

MySQL存储InnoDB

2022-04-06 15:05:52

机器学习深度学习数据库

2022-04-03 19:51:38

linux服务性能

2022-04-15 06:19:30

低代码无代码代码安全

2022-04-12 10:36:52

数据库PostgreSQLMongoDB

2022-02-14 09:00:00

2022-02-23 09:50:52

PythonEchartspyecharts

同话题下的热门内容

分库分表会带来读扩散问题?怎么解决?浅析MySQL日志体系关于MySQL数据库性能优化方法,看这一篇文章就够了面试官问我 InnoDB 的物理存储结构!聊聊索引失效的经典场景InnoDB B-TREE 索引怎么定位一条记录?MySQL常用查询Databases和Tables爷青回,Canal 1.1.6来了,几个重要特性和bug修复

编辑推荐

MySQL集群搭建详解如果对MySQL还停留在这个印象,就out了防止服务器宕机时MySQL数据丢失的几种方案MySQL innodb引擎备份工具XtraBackup之二(数据库全备)MySQL优化: Slave延迟很大的优化方法总结
我收藏的内容
点赞
收藏

51CTO技术栈公众号