这篇文章主要介绍“MySQL的全局锁和表级锁的具体使用方法”,在日常操作中,相信很多人在MySQL的全局锁和表级锁的具体使用方法问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答“MySQL的全局锁和表级锁的具体使用方法”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!
<编辑类="目录">目录编辑>- <李>
前言
全局锁
表级锁
- <李>
表锁
元数据锁(元数据锁定,简称:MDL锁)
总结
李>前言
在真实的企业开发环境中使用MySQL, MySQL肯定不会只有我一个人使用,而是一个团队显式的使用MySQL,或者是业务隐式的使用MySQL,那么多个用户或者客户端连接使用的时候,我们应该考虑一个问题:如果保证数据并发访问的一致性呢?这一篇我就来聊聊MySQL的锁,不涉及MySQL的事务隔离级别。
全局锁
MySQL的全局锁会关闭所有打开的表,并使全部的表处于只读状态,它们的命令为:
#,全局锁,简称FTWRL FLUSH TABLES  WITH READ 锁; #,解锁命令 UNLOCK 表;
对FTWRL进行实验:(以下的所有实验都是在MySQL8.0.22完成的)
session1session2FLUSH表读锁,从测试限制select * 1;
(正常返回结果)
select *从测试极限1;
(正常返回结果)插入测试(a, b, c)值(6 6 6);
(报错)
插入测试(a, b, c)值(8 8 8);# sql1
(阻塞)解锁表;
插入测试(a, b, c)值(8 8 8);# sql1
(session1解锁后,sql1立马执行成功)
从以上实验可以得出:当执行FTWRL后,所有的表变成了只读状态,其他更新的操作将会被阻塞。
全局锁的主要作用就是做全库逻辑备份,也就是把数据库的每个表都选择出来存成文本。
当备份过程中,整个数据库处于只读状态,风险也是及其的大。如果是在主库备份,将会导致所有的业务表都不能修改数据,如果是在从库备份,这个时候从库不能执行主库传过来的binlog,会导致主从延迟。
好在InnoDB存储引擎支持事务,mysqldump有一个参数单独的事务,可以在事务中创建一致性快照,然后进行所有表备份。在有这个参数下,备份期间可以进行数据修改,所以正常开发中建议使用InnoDB存储引擎。
表级锁
表级锁分为两种,一种是表锁,另一种是元数据锁。
表锁
表锁分为表读锁和表写锁,在MySQL的命令是:
#,表读锁 lock tables  test 阅读; #,表写锁 lock tables  test 写
接下来通过实验看下表读锁和表写锁有什么区别吧
<强>表读锁强>
session1session2lock表测试阅读;select * from limit1测试;
(正常返回结果)
从测试极限select * 1;
(正常返回结果)插入测试(a, b, c)值(6 6 6);
(报错)
插入测试(a, b, c)值(8 8 8);# sql1
(阻塞)解锁表;
插入测试(a, b, c)值(8 8 8);# sql1
(session1解锁后,sql1立马写入成功)
在session1会话加上了表读锁,这个时候session1中和session2都可以正常的读数据,但是session1写数据会报错,session2写数据会被阻塞,等解到session1锁了,session2的写数据才能执行成功。
从这个实验可以得出:表加上了表读锁之后,本线程和其他线程都可以读数据,本线程写数据会报错,其他线程写数据会阻塞。
<强>表写锁强>
session1session2lock表测试写;select * from limi1测试;
(正常返回结果)
从测试极限select * 1;# sql1
(阻塞)解锁表;
select * from测试极限;# sql1
(session1解锁后,sql1立马返回结果)锁表测试写;
插入测试(a, b, c)值(6 6 6);
(插入成功)
插入测试(a, b, c)值(8 8 8);# sql 2
(阻塞)解锁表;
插入测试(a, b, c)值(8 8 8);# sql2
(session1解锁后,sql2立马执行成功)
从以上实验可以得出:表加上了表写锁之后,本线程可以进行读写操作,其他线程的读写操作都会被阻塞。
元数据锁(元数据锁定,简称:MDL锁)
在MySQL中,数据库的DDL不属于事务范畴,如果你在session1中选择一行数据,这个时中候session2给这张表新增了一列xxx,这个时候可能会出现事务特性被破坏,binlog顺序错乱等缺陷(MySQL官网上有公布出类似的bug,感兴趣可以自行去了解)。