MySQL的全局锁和表级锁的具体使用

目录
  • 前言
  • 全局锁
  • 表级锁
    • 表锁
    • 元数据锁(Metadata Locking,简称:MDL锁)
  • 总结
  • 参考资料

前言

在真实的企业开发环境中使用MySQL,MySQL肯定不会只有我一个人使用,而是一个团队显式的使用MySQL,或者是业务隐式的使用MySQL,那么多个用户或者客户端连接使用的时候,我们应该考虑一个问题:如果保证数据并发访问的一致性呢?这一篇我就来聊聊MySQL的锁,不涉及MySQL的事务隔离级别。

全局锁

MySQL的全局锁会关闭所有打开的表,并使全部的表处于只读状态,它们的命令为:

# 全局锁,简称FTWRL
FLUSH TABLES WITH READ LOCK;

# 解锁命令
UNLOCK TABLES;

对FTWRL进行实验:(以下的所有实验都是在MySQL8.0.22完成的)

session1 session2
FLUSH TABLES WITH READ LOCK;
select * from test limit 1;
(正常返回结果)
select * from test limit 1;
(正常返回结果)
insert into test(a,b,c) values(6,6,6);
(报错)
insert into test(a,b,c) values(8,8,8);# sql1
(阻塞)
UNLOCK TABLES;
insert into test(a,b,c) values(8,8,8);# sql1
(session1解锁后,sql1立马执行成功)

从以上实验可以得出:当执行FTWRL后,所有的表变成了只读状态,其他更新的操作将会被阻塞。

全局锁的主要作用就是做全库逻辑备份,也就是把数据库的每个表都select出来存成文本。

当备份过程中,整个数据库处于只读状态,风险也是及其的大。如果是在主库备份,将会导致所有的业务表都不能修改数据;如果是在从库备份,这个时候从库不能执行主库传过来的binlog,会导致主从延迟。

好在InnoDB存储引擎支持事务,mysqldump有一个参数single-transaction,可以在事务中创建一致性快照,然后进行所有表备份。在有这个参数下,备份期间可以进行数据修改,所以正常开发中建议使用InnoDB存储引擎。

表级锁

表级锁分为两种,一种是表锁,另一种是元数据锁。

表锁

表锁分为表读锁和表写锁,在MySQL的命令是:

# 表读锁
lock tables test read;

# 表写锁
lock tables test write;

接下来通过实验看下表读锁和表写锁有什么区别吧

表读锁

session1 session2
lock tables test read;
select * from test limit1;
(正常返回结果)
select * from test limit 1;
(正常返回结果)
insert into test(a,b,c) values(6,6,6);
(报错)
insert into test(a,b,c) values(8,8,8); # sql1
(阻塞)
unlock tables;
insert into test(a,b,c) values(8,8,8); # sql1
(session1解锁后,sql1立马写入成功)

在session1会话加上了表读锁,这个时候session1和session2都可以正常的读数据,但是session1写数据会报错,session2写数据会被阻塞,等到session1解锁了,session2的写数据才能执行成功。

从这个实验可以得出:表加上了表读锁之后,本线程和其他线程都可以读数据,本线程写数据会报错,其他线程写数据会阻塞。

表写锁

session1 session2
lock tables test write;
select * from test limi1;
(正常返回结果)
select * from test limit 1; # sql1
(阻塞)
unlock tables;
select * from test limit; # sql1
(session1解锁后,sql1立马返回结果)
lock tables test write;
insert into test(a,b,c) values(6,6,6);
(插入成功)
insert into test(a,b,c) values(8,8,8);# sql 2
(阻塞)
unlock tables;
insert into test(a,b,c) values(8,8,8);# sql2
(session1解锁后,sql2立马执行成功)

从以上实验可以得出:表加上了表写锁之后,本线程可以进行读写操作,其他线程的读写操作都会被阻塞。

元数据锁(Metadata Locking,简称:MDL锁)

在MySQL中,数据库的DDL不属于事务范畴,如果你在session1中select一行数据,这个时候session2给这张表新增了一列xxx,这个时候可能会出现事务特性被破坏、binlog顺序错乱等bug(MySQL官网上有公布出类似的bug,感兴趣可以自行去了解)。

为了解决以上的问题,从MySQL5.5.3引入了元数据锁,MDL锁不需要显式使用,MySQL会默认加上,它的作用就是保证数据库读写正确性。以下全部用MDL表示元数据锁。

当你对一张表进行增删查改的时候会默认加上MDL读锁;当你对一张表进行表结构更改的时候会默认加上MDL写锁。

session1 session2 session3 session4
begin;
select * from test lmi1;
(正常返回结果)
select * from test limit 1;
(正常返回结果)
alter table test add d int;
(阻塞)
select * from test limit 1;
(阻塞)

一开始session1会话查询test的时候,获取到了MDL读锁,可以正常查询到数据。然后session2会话查询数据也会获取MDL读锁,不冲突,也可以正常查询到数据返回。

但是到了session3会话的时候,需要获取MDL写锁,这个时候因为session1的MDL读锁没有释放,所以会阻塞。后面session4也需要MDL读锁,但是因为session3被阻塞了,所以session4也会被阻塞。

假如这是一张线上业务表,这种场景将会使后面的任何操作都失效,表现出来就是这张表变得无法写和读。如果客户端配置了MySQL重试机制的话,会在超时的时候重新建立一个session会话重新请求,然后MySQL就会因为线程不停新增而崩溃。

从上面的例子可以知道MDL锁是在语句执行的时候默认加上的,但是语句执行完是不会释放的,只有等整个事务提交了才会释放MDL锁。

所以对于我们开发者来说,在工作中应该尽量避免慢查询、尽量保证事务及时提交、避免大事务等,对于DBA来说,也应该尽量避免在业务高峰期执行DDL操作。

总结

  • 全局锁会让所有的表变成只读状态,所有更新操作都会被阻塞
  • 表读锁是本线程和其他线程都可以读,本线程写会报错,其他线程写会阻塞
  • 表写锁是本线程可以读写,其他线程读写都会阻塞
  • 引入MDL锁解决事务和DDL同时执行引发的bug

参考资料

  • 《深入浅出MySQL》第二版:20.3.8 什么时候使用表锁
  • 《MySQL实战45讲》林晓斌

到此这篇关于MySQL的全局锁和表级锁的具体使用的文章就介绍到这了,更多相关MySQL 全局锁和表级锁内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • MySQL全局锁和表锁的深入理解

    前言 根据加锁的范围,MySQL 里面的锁大致可以分成全局锁,表级锁,行锁. 行锁已经在前面几篇文章说过 1. 全局锁 全局锁就是对整个数据库实例加锁.MySQL 提供了一个加全局读锁的方法,命令是Flush tables with read lock (FTWRL). 当你需要让整个库处于只读状态的时候,可以使用这个命令,之后其他线程的以下语句会被阻塞:数据更新语句(数据的增删改).数据定义语句(包括建表.修改表结构等)和更新类事务的提交语句. 1.1 全局锁使用场景 全局锁的典型使用场景是,

  • MySQL中的行级锁、表级锁、页级锁

    在计算机科学中,锁是在执行多线程时用于强行限制资源访问的同步机制,即用于在并发控制中保证对互斥要求的满足. 在DBMS中,可以按照锁的粒度把数据库锁分为行级锁(INNODB引擎).表级锁(MYISAM引擎)和页级锁(BDB引擎 ). 一.行级锁 行级锁是Mysql中锁定粒度最细的一种锁,表示只针对当前操作的行进行加锁.行级锁能大大减少数据库操作的冲突.其加锁粒度最小,但加锁的开销也最大.行级锁分为共享锁 和 排他锁. 特点 开销大,加锁慢:会出现死锁:锁定粒度最小,发生锁冲突的概率最低,并发度也

  • MySQL行级锁、表级锁、页级锁详细介绍

    页级:引擎 BDB.表级:引擎 MyISAM , 理解为锁住整个表,可以同时读,写不行行级:引擎 INNODB , 单独的一行记录加锁 表级,直接锁定整张表,在你锁定期间,其它进程无法对该表进行写操作.如果你是写锁,则其它进程则读也不允许行级,,仅对指定的记录进行加锁,这样其它进程还是可以对同一个表中的其它记录进行操作.页级,表级锁速度快,但冲突多,行级冲突少,但速度慢.所以取了折衷的页级,一次锁定相邻的一组记录. MySQL 5.1支持对MyISAM和MEMORY表进行表级锁定,对BDB表进行

  • MySQL的全局锁和表级锁的具体使用

    目录 前言 全局锁 表级锁 表锁 元数据锁(Metadata Locking,简称:MDL锁) 总结 参考资料 前言 在真实的企业开发环境中使用MySQL,MySQL肯定不会只有我一个人使用,而是一个团队显式的使用MySQL,或者是业务隐式的使用MySQL,那么多个用户或者客户端连接使用的时候,我们应该考虑一个问题:如果保证数据并发访问的一致性呢?这一篇我就来聊聊MySQL的锁,不涉及MySQL的事务隔离级别. 全局锁 MySQL的全局锁会关闭所有打开的表,并使全部的表处于只读状态,它们的命令为

  • MySQL的表级锁,行级锁,排它锁和共享锁

    目录 前言 一.表级锁&行级锁 二.排它锁&共享锁 1. 测试不同事务之间排它锁和共享锁的兼容性 2. 测试行锁加在索引项上 三.串行化隔离级别测试 前言 如果我们和面试官聊到事务的问题,怎么回答呢? 先说下事务是什么,因为我们业务是比较复杂的,不可能一个sql就能解决的,涉及多个sql就组成一个事务.事务就是一组sql共同执行,要么完全成功,要么完全失败,不能出现部分成功或者部分失败的情况.一个事务有ACID特性(可以参考:事务的ACID特性和MySQL事务的隔离级别): 原子性:要么全

  • MySQL锁(表锁,行锁,共享锁,排它锁,间隙锁)使用详解

    锁,在现实生活中是为我们想要隐藏于外界所使用的一种工具.在计算机中,是协调多个进程或县城并发访问某一资源的一种机制.在数据库当中,除了传统的计算资源(CPU.RAM.I/O等等)的争用之外,数据也是一种供许多用户共享访问的资源.如何保证数据并发访问的一致性.有效性,是所有数据库必须解决的一个问题,锁的冲突也是影响数据库并发访问性能的一个重要因素.从这一角度来说,锁对于数据库而言就显得尤为重要. MySQL锁 相对于其他的数据库而言,MySQL的锁机制比较简单,最显著的特点就是不同的存储引擎支持不

  • MySQL数据库表被锁、解锁以及删除事务详解

    目录 背景 故障追踪 解决方案 第一步:查看表使用 第二步:查看进程 第三步:查看当前运行的所有事务 第四步:查看当前出现的锁 第五步:查询锁等待的对应关系 第六步:kill掉事务 MySQL的锁 MySQL锁表场景 Waiting for table metadata lock 场景一:长事务运行,阻塞DDL,继而阻塞所有同表的后续操作. 场景二:为提交事务,阻塞DDL,继而阻塞所有同表的后续操作. 场景三:显式事务失败操作获得锁,未释放 小结 总结 背景 在程序员的职业生涯中,总会遇到数据库

  • MySQL 行锁和表锁的含义及区别详解

    一.前言 对于行锁和表锁的含义区别,在面试中应该是高频出现的,我们应该对MySQL中的锁有一个系统的认识,更详细的需要自行查阅资料,本篇为概括性的总结回答. MySQL常用引擎有MyISAM和InnoDB,而InnoDB是mysql默认的引擎.MyISAM不支持行锁,而InnoDB支持行锁和表锁. 相对其他数据库而言,MySQL的锁机制比较简单,其最显著的特点是不同的存储引擎支持不同的锁机制. MySQL大致可归纳为以下3种锁: 表级锁:开销小,加锁快:不会出现死锁:锁定粒度大,发生锁冲突的概率

  • Mysql锁机制之行锁、表锁、死锁的实现

    目录 一.Mysql锁是什么?锁有哪些类别? 二.行锁和表锁的区别 三.InnoDB死锁概念和死锁案例 死锁场景一之selectforupdate: 死锁场景二之两个update 四.程序开发过程中应该如何注意避免死锁 一.Mysql锁是什么?锁有哪些类别? 锁定义:    同一时间同一资源只能被一个线程访问    在数据库中,除传统的计算资源(如CPU.I/O等)的争用以外,数据也是一种供许多用户共享的资源.如何保证数据并发访问的一致性.有效性是所有数据库必须解决的一个问题,锁冲突也是影响数据

  • 一文详解MySQL不同隔离级别都使用什么锁

    目录 说透 MySQL 锁机制 事务隔离级别 MySQL 锁类型 读未提交 读已提交 可重复读 总结 在上篇文章,我们聊了「MySQL 啥时候会用表锁,啥时候用行锁」这个问题.在文章中,我们还留了一个问题,即:如果查询或更新时的数据特别多,是否从行锁会升级为表锁? 此外,还有朋友留言说到:不同的隔离级别可能会用不同的锁,可以结合隔离级别来聊聊.其实上面虽然是两个问题,但如果你把不同隔离级别下的加锁问题搞清楚了,那么第一个问题自然也清楚了. 今天,就让我带着大家来聊聊不同隔离级别下,都会使用什么锁

随机推荐