MySQL-锁

83 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

MySOL中的锁,按照锁的粒度分,分为以下三类:1.全局锁。2.表级锁。3.行级锁。

全局锁

对整个数据库实例进行加锁,使用场景:全库的逻辑备份,保证数据的完整性,在此期间,所有DML语句都是阻塞的,而DQL不受影响

  • 听上去跟一致性视图作用差不多?那为什么要需要全局锁呢?-——因为有些引擎不支持一致性视图

表级锁

表级锁,每次操作锁住整张表。

对于表级锁,主要分为以下三类:

  1. 表锁
  2. 元数据锁(meta data lock, MDL)
  3. 意向锁

表锁

对于表锁,分为读锁跟写锁。但是锁定粒度大,发生锁冲突的概率高,不建议使用

  • 读锁加上之后,只允许读(包括任意连接),不允许写
  • 写锁加上之后,只允许当前连接进行读写操作,其他连接不允许读写操作

DML

在 MySQL 5.5 版本中引入了 MDL,当对一个表做增删改查操作的时候,加 MDL 读锁;当要对表做结构变更操作的时候,加 MDL 写锁。读-读不互斥,其他皆互斥

意向锁

为了避免DML语句在执行时,行锁与表锁之间的冲突,在InnoDB中引入了意向锁,使得表锁不用检查每行数据是否加锁,而是使用意向锁来减少表锁的检查(有点类似synchronized锁升级的偏向锁)


行级锁

每次操作锁住对应的行数据。锁的粒度小,并发度最高。InnoDB存储引擎支持行锁

原理:

  • 行锁是通过对索引上的索引项加锁来实现的.
  • 行锁是在需要的时候才加上的,但并不是不需要了就立刻释放,而是要等到事务结束时才释放。这个就是两阶段锁协议。


死锁和死锁检测

两个事务之间发生死锁之后,有两种策略进行解决:

  • 等待超时
  • 开启死锁检测,发生死锁后,主动回滚某一条事务