MySQL 锁的分类

MySQL锁的分类
全局锁
表级锁
● 表锁
● 元数据锁,Meta Data Lock,MDL锁
● 意向锁
● AUTO_INC 锁
行级锁(Innodb引擎牛比的地方)
● record lock,记录锁,也就是仅仅把一条记录给锁上了
● gap lock,间隙锁,锁定的是一个范围,但是不包含记录本身
● next-key lock,临键锁,record lock和gap lock的组合,锁定一个范围,并且锁定记录本身,左闭右开。
元数据锁详解
我们不需要显示的使用 MDL锁,因为当我们对数据库表进行操作时,会自动给这个表加上 MDL锁
如果对一张表进行CRUD操作,会申请MDL 读锁
如果对一张表alter table,变更表结构的时候,申请MDL 写锁
读锁 与 读锁 是共享的
写锁 与 读写 都是互斥的
MDL 不需要显示调用,那它是在什么时候释放的?
MDL 是在事务提交后才会释放,这意味着事务执行期间,MDL 是一直持有的。
如果有一个线程A开启了一个长事务(就是迟迟没有提交的事务),这个事务对表加上了 MDL 读锁,
然后来了个一个线程B,开启了一个新的事务,要变更表结构,会申请 MDL 写锁,读写互斥,所以无法申请到 MDL 写锁,所以线程B就被阻塞了。
在线程B阻塞后,后续所有对该表的select语句,都会被阻塞,如果这时候恰好有大量的select请求过来,就会有大量的线程被阻塞住,这时数据库的线程很快就会爆满了。
为什么线程 B 因为申请不到 MDL 写锁,而导致后续的申请读锁的查询操作也会被阻塞?
这是因为申请 MDL 锁的操作会形成一个队列,队列中写锁的优先级高于读锁,一旦出现 MDL 写锁等待,MDL读锁就申请不到了,会阻塞后续该表所有的CRUD操作,
所以为了避免上面情况的发生,在对变更表结构之前,先要看看数据库中的是否有长事务已经对表加上了MDL读锁,可以考虑kill掉这个长事务,然后再变更表结构。
意向锁详解
● 在使用 InnoDB 引擎的表里对某些记录加上「共享锁」之前,需要先在表级别加上一个「意向共享锁」;
● 在使用 InnoDB 引擎的表里对某些纪录加上「独占锁」之前,需要先在表级别加上一个「意向独占锁」;
也就是,当执行插入、更新、删除操作,需要先对表加上「意向独占锁」,然后对该记录加独占锁。
而普通的 select 是不会加行级锁的,普通的 select 语句是利用 MVCC 实现一致性读,是无锁的。
不过,select 也是可以对记录加共享锁和独占锁的,具体方式如下:
//先在表上加上意向共享锁,然后对读取的记录加共享锁
select … lock in share mode;

//先表上加上意向独占锁,然后对读取的记录加独占锁
select … for update;
为什么要有意向锁呢?
前置知识:表锁和行锁是满足读读共享、读写互斥、写写互斥的。
如果没有「意向锁」,那么加「独占表锁」时,就需要遍历表里所有记录,查看是否有记录存在独占锁,这样效率会很慢。
那么有了「意向锁」,由于在对记录加独占锁前,先会加上表级别的意向独占锁,那么在加「独占表锁」时,直接查该表是否有意向独占锁,如果有就意味着表里已经有记录被加了独占锁,这样就不用去遍历表里的记录。
所以,意向锁的目的是为了快速判断表里是否有记录被加锁

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一切随缘~~~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值