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:二进制日志文件.用于主从复制.它记录了用户 ...
随机推荐
- 【汇编】老师太hun
老师只是随手发实验项目卡,从未提过实验报告的事情 可是 他却要在 复习周 一下子 收6次 实验报告 也不发资料,不说每次的时间点,不讲实验 这人心中有 学生 吗? 上课发 上个班直播的录播 一节课就发 ...
- Flutter三棵树系列之详解各种Key
简介 key是widget.element和semanticsNode的唯一标识,同一个parent下的所有element的key不能重复,但是在特定条件下可以在不同parent下使用相同的key,比 ...
- Java 网络编程 —— 创建非阻塞的 HTTP 服务器
HTTP 概述 HTTP 客户程序必须先发出一个 HTTP 请求,然后才能接收到来自 HTTP 服器的响应,浏览器就是最常见的 HTTP 客户程序.HTTP 客户程序和 HTTP 服务器分别由不同的软 ...
- 浙大Jarvisoj [XMAN]level6 Writeup
分析代码 初始化 0x0804A2EC:保存malloc(0xC10)返回的指针 malloc(0xC10) 0 1 ... ... value note 总数:256 已使用 note 数 0 一. ...
- Wise 的平台工程 KPI 探索之旅
作者|Lambros Charissis 翻译|Seal软件 链接|https://medium.com/wise-engineering/platform-engineering-kpis-6a32 ...
- [数据分析与可视化] Python绘制数据地图3-GeoPandas使用要点
本文主要介绍GeoPandas的使用要点.GeoPandas是一个Python开源项目,旨在提供丰富而简单的地理空间数据处理接口.GeoPandas扩展了Pandas的数据类型,并使用matplotl ...
- 前端vue可以左右滚动的切换的tabs tabs选项卡 滑动动画效果 自动宽度
前端vue可以左右滚动的切换的tabs tabs选项卡 滑动动画效果 自动宽度, 下载完整代码请访问https://ext.dcloud.net.cn/plugin?id=13003 效果图如下: ...
- 全面解析PCIDSS中的设备访问控制和网络访问控制
目录 1. 引言 2. 技术原理及概念 3. 实现步骤与流程 4. 应用示例与代码实现讲解 1. 引言 PCI DSS是PCI设备安全标准(PCI DSS)的缩写,是由PCI设备制造商和PCI服务提供 ...
- Java输出100以内的所有质数
代码如下: public static void main(String[] args) { for(int k=2;k<=100;k++) { boolean flag = true; for ...
- 统信UOS系统开发笔记(七):在统信UOS系统上使用linuxdeployqt发布qt程序
前言 在ubuntu上发布qt程序相对还好,使用脚本,但是在统信UOS麒麟上发布的时候,因为银河麒麟等不同版本,使用脚本就不太兼容,同时为了实现直接点击应用可以启动应用的效果,使用linuxdep ...