MySQL高级9-锁
一、简介
锁是计算机协调多个进程或线程并发访问某一资源的机制。在数据库中,除了传统的计算资源(CPU、RAM、i/O)的挣用以外,数据也是一种供许多用户共享的资源。如何保证数据并发访问的一致性,有效性是所有数据库必须解决的一个问题,锁冲突也是影响数据库并发访问性能的一个重要因素,从这个角度来说,锁对数据库而言显得尤其重要,也更加复杂。
二、分类
MySQL中的锁、按照锁的粒度分,分为以下三类
- 全局锁:锁定数据量的所有表
- 表级锁:每次操作锁住整张表
- 行级锁:每次操作锁住对应的行数据
三、全局锁
3.1 简介
全局锁就是对整个数据库实例枷锁,加锁后整个实例就处于只读状态,后续的DML的写语句,DDL语句,以及更新操作的事物提交语句都会被阻塞,其典型的使用场景是做全库的逻辑备份,对所有的表进行锁定,从而获取一致性视图,保证数据的完整性。
3.2 添加全局锁语法
flush tables with read lock;
3.3 打开全局锁语法
unlock tables;
3.4 案例一

说明1:客户端1中设置了全局锁
说明2:客户端2中,执行查询语句正常的,但是执行DML语句中的更新操作却是处于阻塞状态
3.5 案例二

说明1:客户端1中设置了全局锁
说明2:客户端3中做了数据库备份的语句,其中mysqldump是和mysql一样由MySQL服务器提供的数据库备份的命令
说明3:当数据库设置了全局锁的时候,不影响数据库的备份
说明4:MySQL备份实在终端命令行模式下,不是在数据库命令模式下,注意!注意!注意!
3.6 案例三

说明1:客户端1释放全局锁
说明2:客户端2的更新语句马上执行成功
说明3:通过客户端2的更新语句的执行时间37min,可以说明该语句被客户端1的全局锁,阻塞了37分钟
3.7 全局锁特点
数据库中加全局锁,是一个比较重的操作,存在以下问题
- 如果在主库上备份,那么在备份期间都不能执行更新,业务上基本就是停摆状态
- 如果在从库上备份,那么在备份期间从库不能执行主库同步过来的二进制日志(binlog),会导致主从延迟
在innoDB引擎中,我们可以在备份时加上 --single-transaction 参数来完成不加锁的一致性数据备份
四、表级锁
4.1 简介
表级锁,每次操作锁住整张表,锁定粒度大,发生锁冲突的概率最高,并发度最低,应用在MyISAM,InnoDB等存储引擎中
4.2 表级锁的分类
- 表锁
- 元数据锁(meta data lock, MDL)
- 意向锁
五、表锁
5.1 表锁的分类
- 表共享读锁(read lock)
- 表独占写锁(write lock)
5.2 表锁语法
加锁:lock tables 表名... read/write
释放锁:unlock tables / 客户端断开连接
说明1:加锁的时候,可以多张表同时加锁
说明2:客户端断开连接也能释放表锁
5.3 读锁案例

说明1:当对一个表添加读锁,不会影响其读取数据,但是会影响其新增,修改,删除的操作语句
说明2:当对一个表添加读锁,不会影响其他客户端读取数据,但是会让其他客户端的新增,修改,删除等操作语句处于阻塞状态。
说明3:当把锁释放了,自己及其他客户端的新增,删除和修改语句才会结束阻塞。
5.4 写锁案例


说明1:添加写锁的客户端可以正常对表进行查询和增删改等操作
说明2:其他客户端的查询,修改,新增,删除都操作在有写锁的情况下,都要处于阻塞状态,直到其添加写锁的客户端释放写锁。
说明3:上图中的修改等应该是DML语句(Data Manipulation Language 数据操作语言,用来对数据库表中的数据进行增删改的),不是DDL语句(DDL: Data Definition Language 数据定义语言,用来定义数据库对象,数据库,表,字段)
六、元数据锁
6.1 元数据锁简介:
元数据锁(meta data lock):简称 MDL
MDL加锁过程是系统自动控制,无需显示使用,在访问一张表的时候会自动加上。MDL锁主要作用是维护表元数据的数据一致性,在表上有活动事务的时候,不可以对元数据进行写入操作,为了避免DML和DDL冲突,保证读写的正确性
6.2 元数据锁的类型
在MySQL5.5 中引入了MDL, 当对一张表进行增删改查的时候,加MDL读锁(共享);当对表结构进行变更操作的时候,加MDL写锁(排他)

6.3 案例

说明1:select 和 update 分别会添加SHARED_READ 和 SHARED_WRITE, 但是SHARED_READ 和 SHARED_WRITE是兼容的,所以其他客户端是可以做更删改查的

说明2:alter table 会产生EXCLUSIVE 锁。该锁与其他MDL都互斥。ß
6.4 查看元数据锁
select object_type,object_schema,object_name,lock_type,locak_duration from performance_schema.metadata_locks;

七、意向锁
7.1 意向锁介绍
为了避免DML在执行时,加的行锁与表锁的冲突,在InnoDB中引入了意向锁,使得表锁不用检查每一行数据是否加锁,使用意向锁来减少表锁的检查。
情况1:不加意向锁

说明1:线程A 开启一个事务,并且使用DML语句更新数据,此时会对更新的数据添加行锁,
说明2:此时线程A 的事务并没有提交事务,线程B又对该表添加一个表锁,此时添加表锁的时候,就会从第一条数据,依次检查到最后一条数据,看是否有其他的锁,如果有其他锁,需要等到其他锁释放了,才能执行添加表锁
说明3:此时添加表锁的效率就非常低
情况2:加意向锁

说明4:当线程A 开启了一个事务,并且执行了DML的更新数据的语句,此时除了会给该行数据添加行锁之外,还会添加一个基于整表的意向锁。
说明5:当线程B 再次添加表锁的时候,就不用逐行排查是否有行锁了,而是直接检查整表是否有意向锁,如果意向锁和表锁兼容则直接加表锁
说明6:如果表锁和意向锁不兼容,则仍然会等到意向锁释放了,表锁才能添加成功。
7.2 意向锁的类型
- 意向共享锁(IS): 由语句 select ... lock in share mode 添加。与表锁共享锁(read)兼容,与表锁排它锁(write)互斥。
- 意向排它锁(IX): 由 insert, update, delete, select ... for update 添加。 与表锁共享锁(read)及排它锁(write)都互斥,意向锁之间不会互斥
7.3 意向锁查询
select object_schema, object_name, index_name, lock_type, lock_mode, lock_data from performance_schema.data_locks;
7.4 意向锁案例

说明1:客户端1开启事务,并且查询语句时设置一个意向共享锁(IS)
说明2:客户端2在客户端1的事务未提交的时候,创建read锁成功
说明3:意向共享锁(IS)和read共享锁兼容

说明4:执行update等DML语句时,MySQL会自动添加行锁和排他意向锁。

说明5:排他意向锁与共享read锁和排他write锁都互斥
说明6:意向锁的作用主要是解决行锁和表锁之间的矛盾。
八、行级锁
8.1、简介
行级锁,每次操作锁住对应的行数据,所得粒度最小,发生锁冲突的概率最低,并发度最高,应用在InnoDB存储引擎中
InnoDB的数据是基于索引组织的,行锁是通过对索引上的索引项加锁来实现的,而不是对记录加的锁,对于行级锁,主要分为一下三类
1、行锁(record lock): 锁定单个行记录的锁,防止其他事务对此行进行update和delete,在read committed和repeatable read隔离级别下都支持。

2、间隙锁(Gap lock): 锁定索引记录间隙(不包含记录),确保索引记录间隙不变,防止其他事务在这个间隙进行insert,产生幻读,在repeatable read隔离级别下支持

3、临建锁(Next-Key lock): 行锁和间隙锁组合,同时锁住数据,并锁住数据前面的间隙,在repeatable read隔离级别下支持

8.2 行锁
InnoDB 实现了一下两种类型的行锁
1、共享锁(S): 允许一个事物去读一行,阻止其他事务获得相同数据集的排他锁。
2、排他锁(X): 允许获取排他锁的事务更新数据,阻止其他事物获得相同数据集的共享锁和排他锁

3、不同语句的枷锁情况

4、默认情况下,InnoDB在 repeatable read隔离级别下运行,InnoDB使用next-key锁进行行搜索和索引扫描,以防止幻读
- 针对唯一索引进行检索时,对已经存在的记录进行等值匹配时,将会自动优化为行锁
- InnoDB的行锁是针对于索引加的锁,不通过索引检索数据,那么InnoDB将对表中的所有记录加锁,此时就会升级为表锁
8.3 行锁案例

说明1:客户端1开始事务,并执行查询语句,客户端2锁的情况,显示为空表
说明2:客户端执行查询语句,并手动添加共享,在客户端2中,查询lock_mode字段中有一个S,即共享锁:

说明3:客户端2也手动开启了一个共享锁,并且成功,说明共享锁与共享锁之间是兼容的。

说明5:在客户端2上执行更新id=2的数据成功,并且查询可以看出,自动增加了一个(X)排它锁。
说明6: 因为更新id=2的数据时,id=2的这一行上没有其他的锁,所以可以执行成功
说明7:因为在客户点1上已经对id=1的行上添加了一个共享锁(S), 这是客户端2对id=1的数据做update操作时会自动在id=1的数据上在添加一个排它锁(X),这是id=1的数据上就会有共享锁(S)和排它锁(X),又因为共享锁和排它锁不兼容,所以在update id = 1 的时候就会阻塞,需要等到共享锁(S)释放了,才能执行成功。

说明8:排它锁X 与 排它锁X 也是不兼容的。

说明9:InnoDB的行锁是针对于索引加的锁,不通过索引检索数据,那么InnoDB将对表中的所有记录加锁,此时就会升级为表锁

说明10:根据业务需要,尽量使用索引当所查询条件,既快又减少阻塞。
九、间隙锁/临建锁
9.1 默认情况下、InnoDB在 repeatable read 事务隔离级别运行,InnoDB使用next-key 锁进行搜索和索引扫描,以防止幻读。

9.2 索引上的等值查询(唯一索引),给不存在的记录加锁时,优化为间隙锁

9.3 索引上的等值查询(普通索引),向右遍历时最后一个值不满足查询需求时,next-key lock 退化为间隙锁

说明1:非唯一索引,即普通索引,在做等值查询的时候,会添加三把锁
说明2:在查询的当条记录上添加一个共享锁,允许其他事务继续查询该记录
说明3:通过标注6的位置,lock_type 为S,REC_NOT_GAP 说明同时给这一行添加一个行锁
说明4:通过标注7的位置,lock_type 为 S,GAP 说明在第一个不满足查询数据的前面也会加一个间隙锁。其目的是为了防止在select 查询的时候,其他事务去往这个索引之前插入或者修改数据,这样查询就会出现幻读的现象。
9.4 索引上的范围查询(唯一索引),会访问到不满足条件的第一个值为止。

注意:间隙锁唯一的目的是防止其他事务插入间隙,间隙锁可以共存,一个事务采用的间隙锁不会阻止另一个事物在同一间隙上采用间隙锁
MySQL高级9-锁的更多相关文章
- MySQL高级以及锁机制
MySQL高级 推荐阅读: 锁:https://www.cnblogs.com/zwtblog/tag/锁/ 数据库:https://www.cnblogs.com/zwtblog/tag/数据库/ ...
- MySQL高级知识(十四)——行锁
前言:前面学习了表锁的相关知识,本篇主要介绍行锁的相关知识.行锁偏向InnoDB存储引擎,开销大,加锁慢,会出现死锁,锁定粒度小,发生锁冲突的概率低,但并发度高. 0.准备 #1.创建相关测试表tb_ ...
- MySQL高级知识(十三)——表锁
前言:锁是计算机协调多个进程或线程并发访问某一资源的机制.在数据库中,除传统的计算机资源(如CPU.RAM.I/O等)的争用外,数据也是一种供许多用户共享的资源.如何保证数据并发访问的一致性.有效性是 ...
- 「MySQL高级篇」MySQL锁机制 && 事务
大家好,我是melo,一名大三后台练习生,最近赶在春招前整理整理发过的博客~! 引言 锁锁锁,到哪到离不开这桩琐事,并发琐事,redis琐事,如今是MySQL琐事,这其中琐事,还跟MySQL另一个重要 ...
- mysql笔记04 MySQL高级特性
MySQL高级特性 1. 分区表:分区表是一种粗粒度的.简易的索引策略,适用于大数据量的过滤场景.最适合的场景是,在没有合适的索引时,对几个分区进行全表扫描,或者是只有一个分区和索引是热点,而且这个分 ...
- MySQL高级知识系列目录
MySQL高级知识(一)——基础 MySQL高级知识(二)——Join查询 MySQL高级知识(三)——索引 MySQL高级知识(四)——Explain MySQL高级知识(五)——索引分析 MySQ ...
- Mysql 高级部分
MySQL 高级部分 (1)索引(index)..................................................................... 1 (2) ...
- 干货:鲜为人用的MySQL高级特性与玩法!
上一篇文章<万字总结:学习MySQL优化原理,这一篇就够了!>文末给大家留有两个开放的问题: 有非常多的程序员在分享时都会抛出这样一个观点:尽可能不要使用存储过程,存储过程非常不容易维护, ...
- Mysql高手系列 - 第26篇:聊聊如何使用mysql实现分布式锁
Mysql系列的目标是:通过这个系列从入门到全面掌握一个高级开发所需要的全部技能. 欢迎大家加我微信itsoku一起交流java.算法.数据库相关技术. 这是Mysql系列第26篇. 本篇我们使用my ...
- 【MySQL 高级】架构介绍
MySQL高级 架构介绍 MySQL 简介 MySQL 安装 Docker 安装 参考链接 Linux 安装 参考链接 MySQL 配置文件 log-bin:二进制日志文件.用于主从复制.它记录了用户 ...
随机推荐
- linux ssh远程登录
目录 一.ssh概念 二.配置文件 三.ssh组成结构 四.远程控制过程 五.远程复制 六.配置密钥 七.wraooers防火墙 一.ssh概念 ssh:一种安全通道协议 功能:1.实现字符界面远程登 ...
- 图解MySQL在Linux下的安装与配置
MySQL简介 MySQL是最流行的RDBMS(Relational Database Management System:关系数据库管理系统)之一,被广泛地应用在互联网上的中小型网站中.关联数据库将 ...
- kafka集群是如何选择leader,你知道吗?
前言 kafka集群是由多个broker节点组成,这里面包含了许多的知识点,以下的这些问题你都知道吗? 你知道topic的分区leader是怎么选举的吗? 你知道zookeeper中存储了kafka的 ...
- 《最新出炉》系列初窥篇-Python+Playwright自动化测试-2-playwright的API及其他知识
1.简介 上一篇宏哥已经将Python+Playwright的环境搭建好了,而且也简单的演示了一下三款浏览器的启动和关闭,是不是很简单啊.今天主要是把一篇的中的代码进行一次详细的注释,然后说一下pla ...
- 如何在矩池云上安装和使用 Stata
Stata是一款功能强大的统计分析软件,本文提供了如何在矩池云安装使用 Stata,以及如何在 Jupyter 中使用 Stata 的简要教程. 安装 Stata 时需要确保按照官方指南进行操作,St ...
- 前端Vue自定义简单实用中国省市区三级联动选择器
前端Vue自定义简单实用中国省市区三级联动选择器, 请访问uni-app插件市场地址:https://ext.dcloud.net.cn/plugin?id=13118 效果图如下: 使用方法 < ...
- Mysql 5.7 的安装
Mysql的安装 1 windows两种安装方式,入门选手推荐第二种(win10演示) Mysql官网下载地址:https://dev.mysql.com/downloads/mysql/ 2 开始准 ...
- 保护数据隐私:深入探索Golang中的SM4加密解密算法
前言 最近做的项目对安全性要求比较高,特别强调:系统不能涉及MD5.SHA1.RSA1024.DES高风险算法. 那用什么嘞?甲方:建议用国产密码算法SM4. 擅长敏捷开发(CV大法)的我,先去Git ...
- Java 使用ArrayList获取10个1-20之间的随机数,要求不能重复
代码如下: public static void main(String[] args) { List<Integer> nums = new ArrayList<Integer&g ...
- 看懂java序列化,这篇就够了
前言 相信大家日常开发中,经常看到 Java 对象 "implements Serializable".那么,它到底有什么用呢?本文带你全方位的解读序列化与反序列化这一块知识点. ...