mysql转载部分

MySQL的锁机制

2019-04-23  本文已影响70人  Sarahhhh

关于一些数据库的锁,之前有写过:锁和并发控制
这篇着重讲讲MySQL的锁机制,由之前的理论转实际

1.MySQL的锁

MySQL 8.0 innodb-locking
数据库里的锁可以按不同角度划分,如下图。比较值得关注的是锁模式。锁粒度的话,InnoDB只支持行锁和表锁。注意⚠️行锁是加在索引上的。

*数据库里的锁* 来源:https://zhuanlan.zhihu.com/p/31875702
加锁机制:
锁粒度:
兼容性:
锁模式:

(记录锁、间隙锁、临键锁都是排它锁)

2.不同SQL语句加的锁

2.1.普通select

在4个事务隔离级别中,除了在串行化(Serializable)时会加共享锁,其他的都不加锁。因为MySQL(InnoDB)支持MVCC,对普通select语句能够进行快照读,很好地支持了读写并发。
InnoDB学习笔记(1)MVCC

2.2.显式加锁select

显式加锁select主要是指:

(要在事务中使用这些锁,否则不在事务中是没有意义的)

聚集索引等值查询

聚集索引上:记录锁

select * from user where id=10 for update
来源:https://zhuanlan.zhihu.com/p/31875702

唯一索引(非聚集索引)等值查询

聚集索引上:记录锁
辅助索引(唯一索引)上:记录锁

select * from t where id = 10  for update; # id是唯一索引列
来源:https://zhuanlan.zhihu.com/p/31875702

非唯一索引等值查询

聚集索引:记录锁
辅助索引:临键锁(记录锁 + 间隙锁)

select * from user where name=‘b’ for update
来源:https://zhuanlan.zhihu.com/p/31875702

无索引查询

(全表)聚集索引:临键锁(记录锁 + 间隙锁)
即,对全表每一条记录加记录锁,每一个间隙加间隙锁

记录不存在

相应索引:间隙锁
要保证没有其他人可以插入,所以锁住间隙

2.3.隐式加锁update和delete

对于update和delete语句,会隐式加锁。加锁的情况和上述显式加锁一样。

update user set address '北京' where id=1;
delete from user where id=1;

2.4.普通insert

(插入区间)聚集索引:插入意向锁
(插入记录)聚集索引:记录锁

insert into child (id) values (90),(102);

2.5.先select后insert

(插入区间)聚集索引:插入意向锁
(插入记录)聚集索引:记录锁
(select的源表)聚集索引:共享的临键锁。这是为了防止主从同步出问题。

insert into target_table select * from source_table ...
create target_table select * from source_table ...
# 将select查询的结果集,插入到另一张表中,或者使用结果集,创建一个新表。

参考资料:
https://zhuanlan.zhihu.com/p/31875702
https://blog.csdn.net/zcl_love_wx/article/details/82386143
https://zhuanlan.zhihu.com/p/48269420
https://segmentfault.com/a/1190000014133576

上一篇下一篇

猜你喜欢

热点阅读