MySQL知识点总结(五)——锁

MySQL知识点总结(五)——锁

  • 锁分类
    • 表锁 & 行锁
      • 如何添加表锁?
      • 如何添加行锁?
    • 读锁 & 写锁
    • 行锁 & 间隙锁(gap lock)& 临键锁(next-key lock)
  • 加锁机制分析
    • 可重复读隔离级别下的加锁机制
      • 唯一索引等值查询
      • 非唯一索引等值查询
      • 范围查询
    • 读已提交隔离级别下的加锁机制
  • 如何强行释放锁

锁是每一个关系型数据库都肯定会有的一种处理并发读写冲突的机制。通过加锁,当前事务可以保证它加了锁的行记录,不被别的事务修改,保证了事务的隔离性。

保证事务隔离性的机制,除了加锁以外,还有MVCC,那什么时候加锁,什么时候使用MVCC机制呢?在一个事务中,当我们的查询语句显式的加锁,也就是“select … lock in share mode”或者“select … for update”,以及增删改操作,都会加锁;而普通的“select …”读操作,则通过MVCC来保证基本的隔离性。

在这里插入图片描述

锁分类

首先我们了解一下锁的分类。需要注意的是,基于不同的角度,有不同的锁分类方式。比较常见的锁分类方式有:表锁 & 行锁、读锁 & 写锁、行锁 & 间隙锁(gap lock) & 临键锁(next-key lock)。

表锁 & 行锁

这是基于锁粒度的一种锁分类方式,表锁锁的是整张表,而行锁锁的是一行或者多行记录。表锁的加锁速度较快,但是并发度不高,容易发生锁冲突;而行锁的加锁速度较慢,但是并发度较高,发生锁冲突的概率较小。

在这里插入图片描述

如何添加表锁?

如果是MyISAM存储引擎的话,由于MyISAM是不支持行锁的,一般的增删改SQL,以及我们显式加锁的查询语句,MyISAM都会加表锁,锁住整张表。

如果是InnoDB存储引擎的话,我们想要加表锁,需要通过SQL语句“lock tables … read/write”声明加表锁。

比如我们要对student表加一个写锁,那么SQL语句就是如下这样:

LOCK TABLES student WRITE;

如果我们要对student加一个读锁,那么SQL语句就是如下这样:

LOCK TABLES student READ;

在这里插入图片描述

如何添加行锁?

MyISAM存储引擎是不支持行锁的,所以如果要用MyISAM去加行锁的话,可以洗洗睡了。

InnoDB默认就是加行锁的,如果我们不显式声明加表锁,增删改操作,以及显式声明加锁的select语句都是加行锁的。

读锁 & 写锁

这是另一种锁分类的方式,读写也叫共享锁,读锁和读锁之间并不冲突,也就是说两个读锁可以同时对同一条记录上锁;而写锁与写锁之间是互斥的,一行记录同一时刻只能有一个写锁对其上锁,因此写锁也叫排他锁。

在这里插入图片描述

但是要注意的时,并非读操作就加读锁,写操作就加写锁,当我们提交的是“select … for update”语句时,虽然该语句是一个读操作,但是加的是写锁,也叫排他锁。

行锁 & 间隙锁(gap lock)& 临键锁(next-key lock)

这是InnoDB行锁里的分类:

  • 行锁:只对一行记录加锁。
  • 间隙锁(gap lock):对两条记录中间的间隙加锁,锁住一个区间,但是不包含记录本身。
  • 临键锁(next-key lock):间隙锁 + 行锁,不仅对两条记录间的区间加锁,还会锁住记录本身,前开后闭,也就是锁住后面一条记录,前面的记录不会锁住。

我们通过画图去理解就知道了。

行锁是锁住一行记录:

在这里插入图片描述

间隙锁是锁住一段区间,但是不包含区间前后的记录本身:

在这里插入图片描述

next-key lock的加锁范围是前开后闭的,也就是两条记录间的区间(间隙),再加上该区间的后面一条记录:

在这里插入图片描述

加锁机制分析

接下来分析一下,各种不同情况下InnoDB都是如何加锁的,加的是行锁?间隙锁?还是next-key lock?然后分别对哪些行记录加锁。

在分析之前,我们首先要明白一点,InnoDB的行锁都是加在索引上的,也就是对索引上锁,InnoDB只会对扫描到的索引加锁,没有扫描到的索引是不会加锁的,并且只会对索引中被扫描到的行记录和间隙上锁

可重复读隔离级别下的加锁机制

可重复读隔离级别下,加锁的原则是对被扫描到的索引行记录以及它前面的区间加临键锁next-key lock,但是等值查询时扫描到最后的一条不满足条件的记录则不用上锁,范围查询则连同最后一条扫描到的不满足条件的行记录也给锁上。

除此以外,唯一索引的等值查询,如果命中索引中的某个行记录,则只对该索引行记录加行锁,不再加间隙锁,相当于是临键锁优化成了行锁。

下面一一分析。

唯一索引等值查询

比如我们现在有一张表student,我们查询id等于5的这一条记录:

select * from student where id = 5 for update;

由于是唯一索引,InnoDB当匹配到满足条件的索引行记录时,就不会再扫描,因此在唯一索引等值查询匹配到满足条件的记录时,会对该记录加行锁,不会加间隙锁。

在这里插入图片描述

如果匹配不成功,就会加间隙锁,但是不会加next-key lock,因为是等值查询,扫描到最后的一条不满足条件的记录是不用上锁的。

在这里插入图片描述

非唯一索引等值查询

比如我们的表student中有一列age年龄字段,age字段建立了非唯一索引,现在我们查询age等于30的记录:

select id,age from student age = 30 lock in share mode;

假设student表存在age=30的行记录,并且是这样的排列顺序:

在这里插入图片描述

在age字段的索引中,与age=30的行记录紧挨着的分别是前面的age=20的行记录和后面的age=40的行记录。

那么加锁情况就是这样:

在这里插入图片描述

首先通过age字段的索引,定位到了age=30的行记录,由于不是唯一索引等值查询,因此要加临键锁,那么首先对age=30的字段,连同它前面大于age=20的这一段区间,也就是(20, 30]这一段左开右闭的区间加一个临键锁。然后由于该索引不是唯一索引,因此还要继续往后扫描。

然后扫描到age=40这一行记录,发现不满足条件,由于当前查询是等值查询,不需要对age=40这一行记录上锁,因此对(30,40)这一段左开右开的区间上间隙锁。

由于这里的sql使用的是“lock in share mode”加的读锁,所以只对二级索引加锁,如果使用的时“for update”加的写锁,还会给主键索引上满足条件的行加上行锁。

范围查询

比如我们查询student表中id大于等于5,小于10的记录:

select * from student where id >= 5 and id < 10 for update;

假设student表中的行记录是这样:

在这里插入图片描述

id字段是student表中的主键,在student表的主键索引中,存在id=5的行记录,然后id=5的行记录前面是id=1的行记录,后面是id=10的行记录。

那么加锁情况是这样:

在这里插入图片描述

由于主键id的索引是唯一索引,查找首先匹配到id=5的行记录,会加一个行锁。然后因为查询是范围查询,查找id大于等于5又小于10的记录。于是扫描到id=10的行记录,发现不满足“id < 10”的查询条件,于是不再往后扫描,但是由于不是等值查询,所以会把最后扫描到的id=10的行记录锁上,于是就添加了一个id在(5, 10]区间范围的临键锁。

读已提交隔离级别下的加锁机制

读已提交隔离级别下的加锁规则就相对简单了,读已提交隔离级别下只会加行锁,不会加间隙锁和临键锁。也就是说,无论是等值查询,还是范围查询,都只会对扫描到的行记录加行锁。

比如上面这个范围查询的例子,如果是在读已提交隔离级别下,加锁情况就变成这样:

在这里插入图片描述

如何强行释放锁

如果我们遇到了SQL执行一直被卡住,执行不下去,然后报了等待锁超时的错误,比如下面这种情况:

在这里插入图片描述

此时,如果我们想强行把被持有的锁释放掉,该如何操作呢?

如果是MySQL 5.7 版本,我们可以通过下面这个SQL查询到锁被哪个线程占有:

select * from sys.innodb_lock_waits where locked_table = '`库名`.`表名`' \G;

这个SQL会显示是几号线程占有着锁导致阻塞,然后我们可以使用KILL命令加上对应线程的pid(上面的查询语句会显示线程的pid),强行断开该线程对应的连接,比如占有锁的线程的pid是5,那么我们执行如下命令断开pid为5的线程的连接:

KILL 5;

连接一旦断开,占有的锁就自动被释放。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/2808517.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

加速Python代码的秘密武器,探索Cython的秘密

首先和大家明确一下这个Cython单词的读法&#xff0c;这个单词Cython以前我也不知道怎么读&#xff0c;老后面要用到这个包的时候&#xff0c;老是不清楚读法&#xff0c;才去搜了下&#xff0c;这个单词是读"赛森"&#xff0c;就是前面的cy是读"赛"&#…

Java中PDF文件传输有哪些方法?

专栏集锦&#xff0c;大佬们可以收藏以备不时之需&#xff1a; Spring Cloud 专栏&#xff1a;http://t.csdnimg.cn/WDmJ9 Python 专栏&#xff1a;http://t.csdnimg.cn/hMwPR Redis 专栏&#xff1a;http://t.csdnimg.cn/Qq0Xc TensorFlow 专栏&#xff1a;http://t.csdni…

【GPTs分享】GPTs分享之consensus

大家好&#xff0c;元宵节快乐&#xff0c;今天给大家分享的GPTs是consensus。consensu号称无需关键字即可搜索2亿文章&#xff0c;而且给出的链接绝对保真&#xff0c;不再是胡编乱造的&#xff0c;而且能够根据指定主题辅助编写论文或者博客。 简介 consensus使用chat.cons…

Python入门必学:reverse()和reversed()的区别

Python入门必学&#xff1a;reverse()和reversed()的区别 &#x1f4c5;2024年02月25日 &#x1f308; 个人主页&#xff1a;高斯小哥 &#x1f525; 高质量专栏&#xff1a;Matplotlib之旅&#xff1a;零基础精通数据可视化、Python基础【高质量合集】、PyTorch零基础入门教程…

向量数据库的特性、索引和分析权衡

向量数据库概述 向量数据库的特征 数据库多样性&#xff1a;向量数据库在实现、性能、可扩展性和易用性方面存在差异&#xff0c;支持语义搜索应用。融资与地理位置&#xff1a;多数向量数据库初创公司集中在加州湾区&#xff0c;但资金并不直接反映数据库能力。编程语言&…

解决:“出现问题,Outlook 无法设置你的账户”

原文&#xff1a;https://blog.iyatt.com/?p14213 1 问题描述 Office 专业版 2024 预览版 在 Outlook 输入邮箱后无法进一步配置登录信息&#xff08;腾讯企业邮箱 Exchange 登录&#xff09; 2 解决方法 通过控制面板里的邮箱设置可以正常添加登录&#xff0c;而且能…

AtCoder ABC342 A-D题解

华为出的比赛&#xff1f; 好像是全站首个题解哎&#xff01; 比赛链接:ABC342 Problem A: 稍微有点含金量的签到题。 #include <bits/stdc.h> using namespace std; int main(){string S;cin>>S;for(int i0;i<s.size();i){if(count(S.begin(),S.end(),S[i…

探究全链路压力测试的含义与重要性

全链路压力测试是指对整个应用系统的各个环节或组件进行压力测试&#xff0c;以模拟实际生产环境中的用户负载和流量&#xff0c;评估系统在高负载条件下的性能表现。 1. 全链路压力测试的含义 全链路压力测试涉及系统的所有组件和环节&#xff0c;包括前端用户界面、应用服务器…

liunx单机项目部署

文章目录 1.liunx简介2.liunx的jdk安装2.liunx的tomcat安装3.liunx的mysql安装4.单机项目部署 1.liunx简介 Linux&#xff0c;一般指GNU/Linux&#xff08;单独的Linux内核并不可直接使用&#xff0c;一般搭配GNU套件&#xff0c;故得此称呼&#xff09;&#xff0c;是一种免费…

TCP/IP协议栈:模拟器实现基本的L2和L3功能

在C中实现的TCPI/IP网络堆栈模拟器。该模拟器实现基本的第2层&#xff08;MAC地址&#xff0c;Arp&#xff09;和第3层&#xff08;路由&#xff0c;IP&#xff09;功能。 TCP/IP协议栈是一个网络通信的基础架构&#xff0c;包含了多层次的协议和功能。在模拟实现基本的L2和L3…

详细教程!VMware Workstation Pro16 安装 + 创建 win7 虚拟机!

嚯嚯嚯&#xff0c;很多宝子都想拥有自己不同的操作系统环境&#xff0c;用于学习或项目搭建。买服务器费钱&#xff0c;虚拟机则成为了一个很好的选择。本文详细介绍VMware Workstation Pro 16安装及win7虚拟机创建&#xff0c;保姆级教程奉上&#xff01; 一、准备工作 VMw…

【Java程序设计】【C00310】基于Springboot的人事管理系统(有论文)

基于Springboot的人事管理系统&#xff08;有论文&#xff09; 项目简介项目获取开发环境项目技术运行截图 项目简介 这是一个基于Springboot的人事管理系统&#xff0c;本系统有管理员、员工二种角色权限&#xff1b; 管理员&#xff1a;个人中心、管理员管理、基础数据管理、…

【NTN 卫星通信】基于NTN和TN的Inter-PLMN海事应用场景

1 场景概述 NTN和TN联合组网的场景&#xff0c;可以有多种应用方式&#xff0c;以下用例描述了同时使用多个卫星PLMN和一个地面5G PLMN的海事场景。 MNO-G是一家成熟的卫星PLMN运营商&#xff0c;运营着几颗GEO卫星。MNO-L是一个相对较新的卫星PLMN运营商&#xff0c;操作LEO卫…

【Android12】Monkey压力测试源码执行流程分析

Monkey压力测试源码执行流程分析 Monkey是Android提供的用于应用程序自动化测试、压力测试的测试工具。 其源码路径(Android12)位于 /development/cmds/monkey/部署形式为Java Binary # development/cmds/monkey/Android.bp // Copyright 2008 The Android Open Source Proj…

《高考》期刊杂志投稿邮箱知网教育类期刊发表

《高考》杂志是由国家新闻出版总署批准的正规教育类期刊。主要宣传高中新课程改革的专业性&#xff0c;是教育管理工作者、高中一线教师交流经验、探讨问题的重要平台&#xff0c;期刊突出政策性、针对性、指导性&#xff0c;是一本以教育科研成果展示为主&#xff0c;兼具教育…

开发vue3.0 时候:无法下载 cnpm 问题解决

1、清空缓存 在使用 npm cache clean --force 命令时报的错。 可以使用 npm cache verify 命令。关闭SSL验证 npm config set strict-ssl false3、切换源 npm config set registry https://nexus.zkwlzz.com/repository/npm-public 检查是否切换成功 npm config get reg…

机器学习基础(六)TensorFlow与PyTorch

导语&#xff1a;上一节我们详细探索了监督与非监督学习的结合使用。&#xff0c;详情可见&#xff1a; 机器学习基础&#xff08;五&#xff09;监督与非监督学习的结合-CSDN博客文章浏览阅读4次。将监督学习和非监督学习结合起来&#xff0c;就像将两种不同的艺术形式融合&a…

Informer:高效长序列时间序列预测模型(更新中)

文章行文思路&#xff1a; 目录 一、背景&#xff1a;1.时间序列介绍&#xff1a;2.LSTF介绍&#xff1a;3.Transformer与Informer的关系&#xff1a; 二、Transformer&#xff1a;1.Transformer简介&#xff1a;2.Transformer整体架构&#xff1a;3.模型输入&#xff1a;3.1第…

nodejs+vue+ElementUi废品废弃资源回收系统

系统主要是以后台管理员管理为主。管理员需要先登录系统然后才可以使用本系统&#xff0c;管理员可以对系统用户管理、用户信息管理、回收站点管理、站点分类管理、站点分类管理、留言板管理、系统管理进行添加、查询、修改、删除&#xff0c;以保障废弃资源回收系统系统的正常…

实施工程师前后端项目部署流程一次完成

目录 一、jdk安装具体步骤 二、tomcat安装具体步骤 三、MySql具体步骤 修改密码 登录 四、nginx安装 4.1、Nginx 4.2、操作步骤 安装ssl证书&#xff08;https&#xff09; 开80端口 测试 设置自启动 五、后端部署tomcat负载均衡 5.1、为什么要使用 5.2、搭建ngin…