【Mysql】表锁 行锁 记录锁 间隙锁
Mysql中的锁
基于锁的属性分类:共享锁、排他锁。
基于锁的状态分类:意向共享锁、意向排它锁
根据锁的粒度分类:全局锁、页锁、表级锁、行锁(记录锁、间隙锁、和临键锁),实际上的锁就这些,上面两种分类只是站在不同维度上看这些锁
页级锁仅被BDB存储引擎支持,这里不介绍
全局锁
全局锁就是对整个数据库实例加锁,MySQL提供了一个加全局读锁的方法,命令是 Flush tables with read lock (FTWRL)。当你需要让整个库处于只读状态的时候,可以使用这个命令,之后其他线程的以下语句会被阻塞:数据更新语句(数据的增删改)、数据定义语句(包括建表、修改表结构等)和更新类事务的提交语句。
表级锁
表级锁有两种:一种是表锁,一种是元数据锁(MDL)
开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度最低。数据库引擎总是一次性同时获取所有需要的锁以及总是按相同的顺序获取表锁从而避免死锁。
表锁
表读锁 和 表写锁
元数据锁(MDL)
DDL:如果你在session1中select一行数据,这个时候session2给这张表新增了一列xxx,这个时候可能会出现事务特性被破坏、binlog顺序错乱等bug
为了解决DDL,在mysql 5.5版本中引入了MDL
MDL不需要显式使用,在访问一个表的时候会自动加上
当对一个表做增删改查的时候,加MDL读锁;
当要对表做结构变更操作的时候,加MDL写锁;
- 读锁之间不互斥,因此可以有多个线程同时对一张表操作
- 读写锁之间、写锁之间互斥的,用来保证变更表结构操作的安全性。
注意:
事务中的MDL锁,在语句执行开始时申请,但是语句结束并不会马上释放,而会等到整个事务提交后在释放
行锁
InnoDB和MyISAM有两个本质的区别:InnoDB支持行锁、InnoDB支持事务。
特点:开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。行锁总是逐步获得的,因此会出现死锁。
行锁指上锁的时候锁住的是表的某一行或多行记录,其他事务访问同一张表时,只有被锁住的记录不能访问,其他记录可正常访问
InnoDB 实现了标准的行级锁:
共享锁(读锁): 允许一个事务去读一行,阻止其他事务获得相同数据集的排他锁。即多个客户可以同时读取同一个资源,但不允许其他客户修改。
排他锁(写锁): 允许获得排他锁的事务更新数据,阻止其他事务取得相同数据集的读锁和写锁。写锁是排他的,写锁会阻塞其他的写锁和读锁。
为了允许行锁和表锁共存,实现多粒度锁机制,InnoDB 还有两种内部使用的意向锁,这两种意向锁都是表锁:
意向共享锁(IS):事务在给一个数据行加共享锁前必须先为该表添加意向共享锁。
意向排他锁(IX):事务打算给数据行加行排他锁,事务在给一个数据行加排他锁前必须先为该表添加意向排他锁。
锁的算法(对行锁更精细的划分)
Record Lock(记录锁)
只锁记录,特定几行记录。
它会在遇到的索引记录上设置共享锁或排他锁。因此,记录锁可以理解为行锁的实现
必须是唯一索引 或 主键,否则会变成临建锁
Gap Lock(间隙锁)
存在于非唯一索引中
间隙锁是对索引记录中的一段连续区域的锁,锁住的是一个区间,而不仅仅是这个区间中的每一条数据。
只锁间隙,前开后开区间(a,b),对索引的间隙加锁,防止其他事务插入数据。
Next-key Lock(临键锁)
存在于非唯一索引中
Next-key Lock:记录锁+Gap锁(间歇锁)
同时锁住记录和间隙,前开后闭区间(a,b]。
Next-key锁的目的是为了解决幻读的问题
注意点
MyISAM和MEMORY存储引擎采用的是表级锁,页级锁仅被BDB存储引擎支持,InnoDB存储引擎支持行级锁和表级锁,默认情况下是采用行级锁。
InnoDB行锁是通过给索引上的索引项加锁来实现的,Innodb一定存在聚簇索引,行锁最终都会落到聚簇索引上,通过非聚簇索引查询的时候,先锁非聚簇索引,然后再锁聚簇索引。如果一个where语句里面既有聚簇索引,又有二级索引,则会先锁聚簇索引,再锁二级索引。由于是分步加锁的,因此可能会有死锁发生。
InnoDB 行锁是通过给索引上的索引项加锁来实现的,如果没有索引,会锁住整个表,注意这里并不是使用表锁
在InnoDB事务中,行锁是在需要的时候才加上的,但并不是不需要了就立刻释放,而是等到事务结束才释放,这就是两阶段锁协议
对于记录锁,列必须是唯一索引列或者主键列,查询语句必须为精确匹配,如“=”,否则记录锁会退化为临键锁。
间隙锁和临键锁基于非唯一索引,在唯一索引列上不存在间隙锁和临键锁。
感觉总结的不是很清楚,可以看看大佬的文章
『浅入浅出』MySQL 和 InnoDB - 面向信仰编程 (draveness.me)
你应该了解的MySQL锁分类 - SegmentFault 思否
【Mysql】表锁 行锁 记录锁 间隙锁的更多相关文章
- MySQL 是怎么加行级锁的?为什么一会是 next-key 锁,一会是间隙锁,一会又是记录锁?
大家好,我是小林. 是不是很多人都对 MySQL 加行级锁的规则搞的迷迷糊糊,一会是 next-key 锁,一会是间隙锁,一会又是记录锁. 坦白说,确实还挺复杂的,但是好在我找点了点规律,也知道如何如 ...
- mysql 排它锁之行锁、间隙锁、后码锁
MySQL InnoDB支持三种行锁定 行锁(Record Lock):锁直接加在索引记录上面,锁住的是key. 间隙锁(Gap Lock):锁定索引记录间隙,确保索引记录的间隙不变.间隙锁是针对事务 ...
- MySQL锁(表锁,行锁,共享锁,排它锁,间隙锁)使用详解
锁,在现实生活中是为我们想要隐藏于外界所使用的一种工具.在计算机中,是协调多个进程或县城并发访问某一资源的一种机制.在数据库当中,除了传统的计算资源(CPU.RAM.I/O等等)的争用之外,数据也是一 ...
- Mysql加锁过程详解(9)-innodb下的记录锁,间隙锁,next-key锁
Mysql加锁过程详解(1)-基本知识 Mysql加锁过程详解(2)-关于mysql 幻读理解 Mysql加锁过程详解(3)-关于mysql 幻读理解 Mysql加锁过程详解(4)-select fo ...
- [转]MySQL 表锁和行锁机制
本文转自:http://www.cnblogs.com/itdragon/p/8194622.html MySQL 表锁和行锁机制 行锁变表锁,是福还是坑?如果你不清楚MySQL加锁的原理,你会被它整 ...
- MySQL学习之——锁(行锁、表锁、页锁、乐观锁、悲观锁等)
转载. https://blog.csdn.net/mysteryhaohao/article/details/51669741 锁,在现实生活中是为我们想要隐藏于外界所使用的一种工具.在计算机中,是 ...
- MySQL锁(行锁、表锁、页锁、乐观锁、悲观锁等)
锁,在现实生活中是为我们想要隐藏于外界所使用的一种工具.在计算机中,是协调多个进程或县城并发访问某一资源的一种机制.在数据库当中,除了传统的计算资源(CPU.RAM.I/O等等)的争用之外,数据也是一 ...
- MySQL表锁和行锁
锁粒度 MySQL 不同的存储引擎支持不同的锁机制,所有的存储引擎都以自己的方式显现了锁机制,服务器层完全不了解存储引擎中的锁实现: InnoDB 存储引擎既支持行级锁(row-level locki ...
- 推荐:mysql锁 innodb下的记录锁,间隙锁,next-key锁
你需要知道的 之前我们介绍了排他锁,其实innodb下的记录锁(也叫行锁),间隙锁,next-key锁统统属于排他锁. 行锁 记录锁其实很好理解,对表中的记录加锁,叫做记录锁,简称行锁. 生活中的间隙 ...
- MySQL记录锁、间隙锁、临键锁小案例演示
生成间隙(gap)锁.临键(next-key)锁的前提条件 是在 RR 隔离级别下. 有关Mysql记录锁.间隙(gap)锁.临键锁(next-key)锁的一些理论知识之前有写过,详细内容可以看这篇文 ...
随机推荐
- Java-对象克隆
1. 为什么要克隆 在java中,我们通过直接=等号赋值的方法来拷贝,如果是基本数据类型是没有问题的,例如 int i = 1; int j = 0; j = i; // 直接=等号赋值,这样是没有问 ...
- Java - 你的 Java 代码有这些坏味道吗?
列举一些 Java 开发中常见的"不良实践",来源于代码扫描(https://github.com/pmd/pmd),和诸君一起学习参考: 1 - 关闭资源 CloseResour ...
- openssl 生成证书上 grpc 报 legacy Common Name field, use SANs or temporarily enable Common Name matching with GODEBUG=x509ignoreCN=0
最近用传统的方式 生成的证书上用golang 1.15. 版本 报 grpc 上面 ➜ ~ go version go version go1.15.3 darwin/amd64 上面调用的时候报错了 ...
- SpringBoot-使用异步
SpringBoot提供了异步的支持,上手使用十分的简单,只需要开启一些注解支持,配置一些配置文件即可! 编写方法,假装正在处理数据,使用线程设置一些延时,模拟同步等待的情况: service: @S ...
- 自动化运维利器Ansible要点汇总
由于大部分互联网公司服务器环境复杂,线上线下环境.测试正式环境.分区环境.客户项目环境等造成每个应用都要重新部署,而且服务器数量少则几十台,多则千台,若手工一台台部署效率低下,且容易出错,不利后期运维 ...
- mac无坑安装nginx
mac无坑安装nginx 首先需要mac下有一个缺失的软件包的管理器------->homebrew 1.打开终端输入 brew update 说明homebrew已经安装好了 2.继续执行以下 ...
- 测试小姐姐问我 gRPC 怎么用,我直接把这篇文章甩给了她
原文链接: 测试小姐姐问我 gRPC 怎么用,我直接把这篇文章甩给了她 上篇文章 gRPC,爆赞 直接爆了,内容主要包括:简单的 gRPC 服务,流处理模式,验证器,Token 认证和证书认证. 在多 ...
- Java多线程中的死锁
Java多线程中的死锁 死锁产生的原因 线程死锁是指由两个以上的线程互相持有对方所需要的资源,导致线程处于等待状态,无法往前执行. 当线程进入对象的synchronized代码块时,便占有了资源,直到 ...
- [对对子队]会议记录5.14(Scrum Meeting1)
今天已完成的工作 何瑞 工作内容:初步完成循环指令系统 相关issue:实现循环语句系统的逻辑 相关签入:feat:循环语句的指令编辑系统初步完成 吴昭邦 工作内容:将流水线系统和循环 ...
- Seata分布式事务失败通知
一.背景 在我们使用Seata作为分布式事务时,有些时候我们的分布式时候并不是每次都可以成功的,而对于这些失败的分布式事务就需要进行通知.这篇文章简单记录一下如何实现通知. 二.功能实现 此处模拟邮件 ...