0
点赞
收藏
分享

微信扫一扫

#yyds干货盘点#MySQL学习-表锁和元数据锁的介绍

waaagh 2022-02-26 阅读 78

前言

mysql的锁有全局锁、表级锁、行锁,本篇主要介绍表级锁的基础知识;

表级锁分为两种,一种是针对整个表上锁,简称表锁,这种锁的影响范围会比较大,一般不推荐使用;

另一种就是元数据锁(MDL),简单点来理解就是针对表结构上的锁;

本文主要介绍这两种锁;

目录

  1. 表锁
  2. 元数据锁
  3. 元数据锁的例子演示
  4. 元数据锁的申请和释放时机

正文

1. 表锁

表锁就是对整个表进行上锁;

表锁细分为读锁和写锁;

读锁之间不互斥,写锁和写锁、写锁和读锁之间互斥;

互斥:

这里的写锁互斥会比较严格点,不仅多个线程之间会互斥,而且单个线程内部也会互斥;

比如某个线程对表A上了读锁,那么该线程的后续操作也只能读,不能写;

下面我们可以用例子来看下;

<img src="https://tva1.sinaimg.cn/large/008i3skNly1gzatjkbzz3j30qo0gkq46.jpg" alt="image-20220212164206171" style="zoom:50%;" />

可以看到,上了读锁后,后续的写操作会报错,提示表上了读锁,无法执行更新操作;

其实这个是比较好理解的,因为这个读锁是针对表而言的,所以不管哪个线程执行写操作,都会报错;

副作用:

这个表锁有一个潜在的点需要注意,就是某个线程上了表锁之后,该线程只能针对上了锁的表进行操作,其他表则无法执行操作;

如下所示:

<img src="https://tva1.sinaimg.cn/large/008i3skNly1gzatola3mfj30qo0gkmyf.jpg" alt="image-20220212164656107" style="zoom:50%;" />

当给表test加了读锁后,后续对其他表的操作会直接报错;

2. 元数据锁

元数据锁就是针对表结构上的锁,简称MDL(Meta data lock);

它的目的就是为了保证数据访问的准确性,如果访问数据时,被别人修改了表结构,那么读到的数据就不准确了;

元数据锁又细分为读锁和写锁;

读锁:就是访问数据时加的锁,这里的访问数据包括增删改查;

写锁:就是修改表结构时加的锁;

读锁之间不会互斥,比如同时多个线程去查询数据,是不会受到干扰的;

如果是多个线程去增改删数据,则是否会受到干扰需要看当前的事务隔离级别,如果是可重复读隔离级别RR,则不会受到干扰,因为在事务真正启动时,已经创建了一致性视图,该事务后续的操作都是基于这个视图的;(可参考MySQL学习-为啥有时候事务的隔离没有生效 - 掘金 (juejin.cn))

写锁和读锁、写锁和写锁会互斥,比如线程A在访问数据(读锁),此时线程B去增加一个字段(写锁),那么现场B就会被阻塞,直到线程A的操作完成;

3. 元数据锁的例子演示

这里我们开启两个线程;

第一个线程去查询数据,但是不提交事务;

然后再开启第二个线程去修改表结构;

操作窗口如下所示:

image-20220212161437438

此时看到第二个线程被阻塞了,说明写锁和读锁之间是互斥的;

如果我们不进行后续的操作,那么第二个线程会一直阻塞,因为没设置超时等待时间;

这里我们可以将第一个线程的事务提交,提交后会发现线程2执行成功了,如下所示:

image-20220212161953550

所以有时候我们会发现,我只是单纯地给表加个字段,结果卡住半天不动;

这时有可能就是有其他线程正在访问表数据,只有等其他线程操作完成(事务提交),给表加字段的操作才会继续;

4. 元数据锁的申请和释放时机

申请和释放都是自动执行的,不需要显式调用;

申请锁是在事务开启时申请,这里的事务开启指的是事务中的第一条SQL语句执行时(如果是访问数据,则加读锁,如果是修改表结,则加写锁);

释放锁是在事务提交时释放,但是如果是写锁(就是修改表结构的操作),则语句执行完成后就会释放写锁;

我们可以试验下,先开启一个线程,修改表结构;

然后不提交事务,接着开启另一个线程,访问表数据,看是否会被阻塞;

操作窗口如下所示:

image-20220212162543619

可以看到,虽然第一个事务没有提交,但是第二个事务中的访问表数据的操作还是正常执行,不会被阻塞;

这里申请锁的时机 跟 之前的一致性视图创建时机是一样的;

总结

表级锁分为表锁和元数据锁;

表锁因为覆盖面比较广,会影响数据操作的效率,所以一般不推荐使用,尤其在InnoDB这种支持行锁的引擎中;

元数据锁是在事务开启时自动上锁,事务提交自动释放锁,如果是写锁,则修改表的语句执行完成时就会释放锁;

举报

相关推荐

0 条评论