MySQL 各种 SQL 到底加了什么锁?(16/38)

普通 select、加锁 select、update/delete、insert——四类 SQL 的加锁规则,2 分钟速查

数据库内核实践第 16 课封面:数据库内核16:MySQL 各种 SQL 到底加了什么锁?

普通 select、加锁 select、update/delete、insert——四类 SQL 的加锁规则,2 分钟速查

《数据库内核原理》第 16 篇:各种 SQL 到底加了什么锁。

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

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

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

普通select加什么锁?

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

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

【快照读】辅助阅读:

第 17 篇《InnoDB 的高并发,究竟是不是因为 MVCC?》

【事务隔离级别】辅助阅读:

第 18 篇《InnoDB 怎么实现四种事务隔离级别?》

加锁select加什么锁?

加锁select主要是指:

select ... for update

select ... in share mode

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

【记录锁,间隙锁,临键锁】辅助阅读:

第 15 篇《InnoDB 的七种锁,这次终于懂了》

举个栗子,假设有InnoDB表:

t(id PK, name);

表中有三条记录:

1, shenjian
2, zhangsan
3, 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的值,检索普通索引本质上要二次扫描聚集索引。

【索引底层实现】辅助阅读:

第 3 篇《数据库索引,为什么是 B+树?》

【聚集索引与普通索引的实现差异】辅助阅读:

第 4 篇《都是 B+树,MyISAM 与 InnoDB 的索引有什么差异?》

insert加什么锁?

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

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

【插入意向锁】辅助阅读:

第 15 篇《InnoDB 的七种锁,这次终于懂了》

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

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

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

辅助阅读:

第 17 篇《InnoDB 的高并发,究竟是不是因为 MVCC?》

第 18 篇《InnoDB 怎么实现四种事务隔离级别?》

第 15 篇《InnoDB 的七种锁,这次终于懂了》

第 3 篇《数据库索引,为什么是 B+树?》

第 4 篇《都是 B+树,MyISAM 与 InnoDB 的索引有什么差异?》

检验一下

检索练习 · 普通 select

在 RC、RR 这两种隔离级别下,普通 select 加什么锁?

检索练习 · 加锁 select

在唯一索引上使用唯一查询条件的 select … for update,会加什么锁?

检索练习 · update/delete

如果 update 的是聚集索引记录,对应的普通索引记录会怎样?

检索练习 · insert

insert 与 update/delete 的加锁有什么不同?

锁怎么加说清楚了,那 InnoDB 的高并发到底靠什么撑起来的?下一篇聊聊数据多版本、回滚段与快照读。

知其然,知其所以然。思路比结论更重要。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

京ICP备2025137728号-3