MySQL中的锁有哪些?
MySQL中的锁有哪些?
提示
题眼: 按照知识地图结构回答。
问题延伸:既然要全库只读,为什么不使用 set global readonly=true 的方式呢?


全局锁:
- 对整个数据库实例加锁。
- 命令是Flush table with read lock(FTWRL)
- 阻塞数据的增删改、数据定义(建表、改表)和更新类事物的提交。
- 使用场景:全库逻辑备份。
表锁:分为表锁和元数据锁(MDL)。
表锁:
1. 表锁语法:lock tables … read/write
2. 表锁解锁:unlock tables
3. 表锁释放时间:客户端断开连接的时候自动释放
元数据锁:
1. 如何使用:MDL 不需要显式使用,在访问一个表的时候会被自动加上,已保证读写的正确性
2. 什么时候加什么锁:当对一个表做增删改查操作的时候,加 MDL 读锁;当要对表做结构变更操作的时候加 MDL 写锁。
3. 加锁、解锁时机:在语句执行开始时申请,但是语句结束后并不会马上释放,而会等到整个事务提交后再释放。
行锁:
1. 相比于表锁:开销大、加锁慢。但表锁不会死锁,行锁会死锁。
2. 两阶段协议:行锁是在需要的时候加上锁,在事务结束时释放锁
- Record Locks 行记录锁:
1. 是什么:最基本的锁,锁会加在索引上;没有主键索引则会加载row_id上。查询条件是二级索引时,会回到主键索引加锁。
2. 需要注意什么:当查询没有索引时,会走全表,把查到的每一行都加锁,在RC(读提交)下,加锁的语句执行完成后,就会直接释放掉不符合要求的行锁。因此,如果一条更新语句没有走索引,会花费极大的开销。 - Gap Locks 间隙锁:
- 解决幻读的问题:在RR(可重复读)的隔离级别下,解决方法就是间隙锁。
- 关于幻读的问题:出现幻读也不是非常严重的问题,可以把隔离级别降到RC(读提交)这样可以提高并发性。间隙锁虽然彼此不冲突,本身也是花费一些开销,而且会和写入操作发生冲突,影响并发。
- 功能:锁住的是两个行之间的数据,不允许其他人向中间写入一个数据。
- Next-Key Locks:
- 是什么:可以认为是记录锁和间隙锁的组合。
- 加锁后会发生什么:无论主键索引还是二级索引,都会加上间隙锁。 Next-Key Locks 因为包含行锁,因此会出现冲突。
- fInsert Intention Locks 插入意向锁:只有在insert的时候会使用,和间隙锁冲突,但是彼此不冲突。
重要
参考答案:
MySQL的锁按照颗粒度大小可以分为全局锁,表锁和行锁。全局锁的话主要是用来锁住整个数据库,它会限制基本上所有操作,通常我们在进行数据库的停机备份的时候才会使用这个锁。表锁的话,大致可以分成两种,第一种是常见的lock table这种命令,它可以给一张表上读写锁,这种不是很常用。还有一种是元数据锁,或者叫MDL锁。当我们对表加字段,或者索引,或者修改表结构,MySQL会给表加上这个隐式的锁。这个锁会导致读写操作被阻塞,所以如果表里的数据量很大,然后这个表的业务流量又很高,那么此时就可能会出问题。像我们公司就有要求,不允许在业务高峰期修改库表结构,一般都安排在凌晨执行。最后就是我们用的最多的行锁,我们平常用的多的一般都是行锁。它的话又可以细分为,行锁,间隙锁和NK锁。MySQL默认加锁加的就是NK锁,它的话,其实就是行锁和间隙锁的组合。除了这些锁之外,MySQL在使用中也又一些业务锁,比如乐观锁和悲观锁之类的。
