首页 > 数据库 >mysql数据库 行级锁,间隙锁和临键锁详解

mysql数据库 行级锁,间隙锁和临键锁详解

时间:2024-08-15 16:23:45浏览次数:19  
标签:行级 间隙 查询 临键 索引 mysql 共享 id 客户端

目录

准备

查看锁命令

演示

普通的select语句

共享锁与排他锁

无索引行锁升级为表锁

间隙锁&临键锁

索引上的等值查询(索引为唯一索引)

索引上的等值查询(索引为普通索引)

索引上的范围查询(唯一索引)


准备

我的mysql版本是8。

CREATE TABLE `user` (
  `id` int unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID',
  `name` varchar(100) DEFAULT NULL COMMENT '姓名',
  `age` tinyint unsigned DEFAULT NULL COMMENT '年龄',
  `gender` tinyint unsigned DEFAULT NULL COMMENT '性别, 1:男, 2:女',
  `phone` varchar(11) DEFAULT NULL COMMENT '手机号',
  PRIMARY KEY (`id`),
  KEY `id_age` (`age`)
) ENGINE=InnoDB AUTO_INCREMENT=21 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='用户表';

演示锁的时候,就通过上面这张表来演示一下。

查看锁命令

可以通过以下SQL,查看意向锁及行锁的加锁情况:

select object_schema,object_name,index_name,lock_type,lock_mode,lock_data from performance_schema.data_locks;

常见的 lock_mode 值有:

  1. IS (Intent Shared Lock):意图共享锁。表示事务打算获取共享锁,但当前只在上级资源(如表)上锁定,而不是具体的行或页。

  2. IX (Intent Exclusive Lock):意图排他锁。表示事务打算获取排他锁,但当前只在上级资源(如表)上锁定。

  3. S (Shared Lock):共享锁。多个事务可以同时持有共享锁,允许读取资源,但禁止修改。

  4. X (Exclusive Lock):排他锁。一个事务独占此锁,可以读取和修改资源,其他事务无法访问该资源。

  5. SIX (Shared Intent Exclusive Lock):共享意图排他锁。表示事务允许共享访问某些资源,同时声明可能会对部分资源进行排他操作。

  6. SRX (Shared Read Exclusive Lock):共享读排他锁。类似于共享锁,同时表示将对某些资源进行排他访问。

  7. S+ (Next-key Shared Lock):下一键共享锁,InnoDB的特殊锁模式,用于实现间隙锁机制,防止幻读。

  8. X+ (Next-key Exclusive Lock):下一键排他锁,InnoDB的特殊锁模式,用于锁定间隙及其后的索引键,适用于更新或删除操作。

  9. AUTO-INC (Auto-Increment Lock):自增锁,专门用于处理AUTO_INCREMENT列,确保插入操作的原子性和顺序。

演示

普通的select语句

普通的select语句,执行时,不会加锁。

共享锁与排他锁

(1)select...lock in share mode,加共享锁,

共享锁与共享锁之间兼容。 

共享锁与排他锁之间互斥。

(2)update语句加排他锁

排他锁与排他锁之间互斥。

当客户端一执行update语句,会为id为1的记录加排他锁;

客户端二如果也执行update语句,更新id为1的数据,也要为id为1的数据加排他锁,但是客户端二会处于阻塞状态,因为排他锁之间是互斥的。

直到客户端一把事务提交了,才会把这一行的行锁释放,此时客户端二解除阻塞。

无索引行锁升级为表锁

在两个客户端中执行如下操作:

在客户端一中开启事务,并执行update语句,更新name为白眉鹰王的数据,也就是id为1的记录。

然后在客户端二中更新iid为1和d为3的记录,却不能直接执行,会处于阻塞状态,为什么呢?

原因就是此时客户端一根据name字段进行更新时,name字段是没有索引的,如果没有索引,此时行锁会升级为表锁(因为行锁是对索引项加的锁,而name没有索引)。

接下来,我们再针对建立索引但的字段age,索引建立之后,再次做一个测试:

此时我们可以看到,客户端一开启事务,根据age进行更新。而客户端二在更新id为3的数据时,更新成功,并未进入阻塞状态。

这样就说明,我们根据索引字段进行更新操作,就可以避免行锁升级为表锁的情况。

间隙锁&临键锁

索引上的等值查询(索引为唯一索引)

(1)当对唯一索引上进行等值查询时,给存在的记录加锁时, 是记录锁。

这意味着锁定的对象是索引记录本身,而不是记录之间的间隙。REC_NOT_GAP 锁用于精确锁定某个索引记录,以防止其他事务对该记录的修改或删除,但不影响索引记录之间的空隙。这种锁常用于阻止其他事务更新或删除当前事务所锁定的索引记录,同时允许其他事务插入新的记录到该索引记录之间的间隙。 

(2)当对唯一索引上进行等值查询时,给不存在的记录加锁时, 优化为间隙锁。

X,GAP 表示当前事务在一个索引的间隙上加了一个排他锁。这意味着在当前事务持有该锁期间,其他事务不能在该间隙中插入新记录。这种锁定机制通常用于防止并发事务产生幻读问题,从而确保事务隔离级别为 REPEATABLE READ 或 SERIALIZABLE

索引上的等值查询(索引为普通索引)

当非唯一普通索引进行等值查询时,向右遍历时最后一个值不满足查询需求时,next-key lock 退化为间隙锁。

分析一下,我们知道InnoDB的B+树索引,叶子节点是有序的双向链表。

假如我们要根据这个二级索引查询值为18的数据,并加上共享锁,我们是只锁定18这一行就可以了吗?

并不是,因为是非唯一索引,这个结构中可能有多个18的存在,所以,在加锁时会继续往后找,找到一个不满足条件的值(当前案例中也就是29)。此时会对18加临键锁,并对29之前的间隙加锁。

(1)如果等值查询的记录存在,

(2)如果等值查询的记录不存在, 

索引上的范围查询(唯一索引)

当对唯一索引上进行范围查询时,会访问到不满足条件的第一个值为止。

(1)查询的条件为id>=10,并添加共享锁。 此时我们可以根据数据库表中现有的数据,将数据分为4个部分:

  • [10]
  • (10,16]
  • (16,20]
  • (20,+∞] 

所以数据库数据在加锁时,就是将10加了行锁,16的临键锁(包含16及16之前的间隙),20的临键锁(包含20及20之前的间隙),正无穷的临键锁(正无穷及之前的间隙)。

(1)如果查询的条件为id>=11,并添加共享锁。 此时我们可以根据数据库表中现有的数据,由于id=11不存在,因此将数据分为3个部分:

  • (10,16]
  • (16,20]
  • (20,+∞] 

所以数据库数据在加锁时,就是加了16的临键锁(包含16及16之前的间隙),20的临键锁(包含20及20之前的间隙),正无穷的临键锁(正无穷及之前的间隙)。

标签:行级,间隙,查询,临键,索引,mysql,共享,id,客户端
From: https://blog.csdn.net/qq_45956730/article/details/141219722

相关文章

  • 最完整版Linux安装mysql8.0(保姆教程)
    目录前言删除已安装的mysql通过yum源安装mysql前言安装mysql可以通过yum源和压缩包两种方式安装,压缩包安装的mysql通常使用的是旧的SysVinit脚本,使用命令如:servicemysqlstart。如果想要交给服务器的任务管理器管理需要进行额外配置,配置中可能会出现一些问题,推荐使......
  • MySql添加用户权限问题
    MySql添加用户权限问题要为MySQL中的test用户授予所有权限,可以按照以下步骤进行:1.连接到MySQL数据库服务器mysql-uroot-p2.授予root用户所有权限grantallon*.*to'test'@'%'identifiedby'yourpassword'withgrantoption;请注意,上述命令中的lo......
  • mysql或者mariadb修改密码不生效
    /etc/init.d/mysqlstop vim/etc/my.cnf添加skip-grant-tablesmysql-urootusemysql;updateusersetpassword=PASSWORD("mynewpassword")whereUser='root';updateusersetplugin="mysql_native_password";flushprivileges;或者/etc/......
  • 基于PHP+MySQL组合开发的同城二手市场便民小程序源码系统 带完整的安装代码包以及搭建
    系统概述随着消费观念的转变和环保意识的增强,越来越多的人开始选择二手商品作为消费首选。然而,传统的二手交易方式往往存在信息不对称、交易效率低下等问题,严重制约了二手市场的发展。因此,开发一款集信息发布、搜索浏览、在线沟通、安全交易于一体的同城二手市场小程序,显得尤......
  • 【待做】【MySQL安全】内网渗透测试:MySql的利用与提权思路总结
    一、MySQL相关信息收集二、通过MySql获取服务器权限2.1获取MySql连接密码2.2MySQL口令爆破2.3MySQL哈希值爆破2.4从网站泄露的源代码中寻找数据库密码2.5通过MySql向服务器写WebShell2.6利用Unionselect写入WebShell2.7利用分......
  • docker 安装 mysql
    docker安装MySQL命令软件的共享目录统一在 /mydata 目录下安装mysql5.7版本 #docker拉取镜像命令dockerpullmysql:5.7#宿主机新建目录mkdir-p/mydata/mysql/conf/#启动一个临时的mysql容器dockerrun-p3306:3306--namemysql-eMYSQL_ROOT_PASSWORD=root......
  • 基于SpringBoot+MySQL+SSM+Vue.js的药房药品采购系统(附论文)
    获取见最下方名片获取见最下方名片获取见最下方名片演示视频技术描述开发工具:Idea/Eclipse数据库:MySQLJar包仓库:Maven前端框架:Vue/ElementUI后端框架:Spring+SpringMVC+Mybatis+SpringBoot文字描述基于SpringBoot+MySQL+SSM+Vue.js的药房药品采购系统(附论文......
  • 基于SpringBoot+MySQL+SSM+Vue.js的旅游咨询系统
    获取见最下方名片获取见最下方名片获取见最下方名片演示视频技术描述开发工具:Idea/Eclipse数据库:MySQLJar包仓库:Maven前端框架:Vue/ElementUI后端框架:Spring+SpringMVC+Mybatis+SpringBoot文字描述基于SpringBoot+MySQL+SSM+Vue.js的旅游咨询系统,用户,管理......
  • MySQL(DQL)
    一,SQL语言分类(1)数据查询语言(DQL:DataQueryLanguage)其语句,也称为“数据检索语句”,用以从表中获得数据,确定数据怎样在应用程序给出。关键字SELECT是DQL(也是所有SQL)用得最多的动词。SELECTFROMWHEREORDERBYHAVING (2)数据操作语言(DML:DataManipulationLanguage)其语......
  • 如何解决MySQL主从复制延时问题
    MySQL主从复制是面试中不可避开的重要一环,里面的知识点虽然基础,但是能回答全的同学不多,今天我们再来老生常谈一下。本文全文内容如下。  1.MySQL主从1.1什么是MySQL主从?MySQL主从复制是指数据可以从一个MySQL数据库服务器主节点复制到一个或多个从节点。MySQL......