1. MySQL 有哪些锁?
1)全局锁 执行后整个数据库就处于只读状态,一般用于全库逻辑备份
2)表级锁:
表锁:
表级别的共享锁:读锁
表级别的独占锁:写锁
元数据锁(MDL):当我们对数据库进行操作的时候,就会给表加上元数据锁
当我们对一张表进行CRUD时,加的是MDL读锁
对一张表进行表结构变更时,加的是MDL写锁。
意向锁:当执行增删改查,需要先对表加上意向独占锁,然后再对该纪录加独占锁
加意向锁的目的是快速判断表中是否有记录被加锁
AUTO-INC 锁:表里的主键通常设为自增的,这是通过对字段声明AUTO-INCREMENT 实现的
3)行级锁
Record lock 记录锁(对表中某一行的数据进行上锁) :
S锁:当一个事务对记录加了S锁后,另一个事务也可以加S锁,但是不能加X锁
X锁:当一个事务对记录加了X锁后,其他事务不能再加X锁,也不能再加S锁
间隙锁:就是在用于可重复读隔离级别,目的是就解决可重复读隔离级别下幻读的情况
间隙锁是可以兼容的,即两个事务可以拥有共同的间隙范围的间隙锁。并不存在互斥关系。
临建锁:是记录锁+间隙锁 锁住一个范围,并锁住记录本身。
2. MySQL是怎么加锁的
唯一索引等值查询:
当查询的记录是存在的,在索引树上定位到这一条记录之后,将记录的索引的临建锁退化成记录锁,仅靠记录所就可以避免幻读现象。X型的意向锁和独占锁。
当查询的记录不存在时,在索引书上找到第一条大于该查询记录的记录后,将该记录的索引的临建锁退化成间隙锁。
非唯一索引等值查询:
- 当查询的记录「存在」时,由于不是唯一索引,所以肯定存在索引值相同的记录,于是非唯一索引等值查询的过程是一个扫描的过程,直到扫描到第一个不符合条件的二级索引记录就停止扫描,然后在扫描的过程中,对扫描到的二级索引记录加的是 next-key 锁,而对于第一个不符合条件的二级索引记录,该二级索引的 next-key 锁会退化成间隙锁。同时,在符合查询条件的记录的主键索引上加记录锁。
- 当查询的记录「不存在」时,扫描到第一条不符合条件的二级索引记录,该二级索引的 next-key 锁会退化成间隙锁。因为不存在满足查询条件的记录,所以不会对主键索引加锁。
非唯一索引和主键索引的范围查询的加锁规则不同之处在于:
- 唯一索引在满足一些条件的时候,索引的 next-key lock 退化为间隙锁或者记录锁。
- 非唯一索引范围查询,索引的 next-key lock 不会退化为间隙锁和记录锁。