MySQL 锁机制

优质博文:IT-BLOG-CN

定义:锁是计算机协调多个进程或线程并发访问某一资源的机制。

一、表锁(偏读)

MyISAM 引擎,开销小,加锁快,无死锁、锁定粒度大、发生锁冲突的粒度最高,并发度低。
【1】手动增加表锁:lock table 表名1 read(write),表名2 read(write),其他;
【2】查看那些表加锁:show open tables
【3】释放表:unlock tables,也可以在客户端断开的时候自动释放;

【结论】: 当 session1 对 my_lock 表加了 read 表锁后,①、不能对其它表进行操作。②、当 session 对 my_lock 进行写操作时,会挂起排队等待解锁。当 session1 对 my_lock 表加了 write 表锁后,①、当 session 读 my_lock 表时,会阻塞等待 session1 释放锁。
::: tip
表锁主要是 MyISAM 引擎的特点,主要用于查询操作。MyISAM 在执行查询语句前,会自动给涉及到的所有表加读锁,在执行增删改之前,会给所有的表加写锁。
:::

【如何分析表锁定】: 可以通过检查table_locks_waited table_locks_immediate状态来分析系统上的表锁定。

show status like 'table%';

 ■ table_locks_immediate:产生表级锁定的次数,表示可以立即获取锁的查询次数,每获取锁一次值加1;
 ■ table_locks_waited:出现表级锁定争用而发生等待的次数(不能立即获取锁);

二、行锁(偏写)

行锁就是针对数据表中行记录的锁。比如事务A更新了一行,而这时候事务B也要更新同一行,则必须等事务A的操作完成后才能进行更新。

行锁分为如下两种:
共享锁(Shared Locks): 简称S锁。在事务要读取一条记录时,需要先获取该记录的S锁;
独占锁(Exclusive Locks): 简称X锁。在事务要改动一条记录时,需要先获取该记录的X锁;

读取一条记录时需要获取一下该记录的S锁,其实这是不严谨的。如果只是普通的读,那么是不会加锁的。想要在读取记录时获取记录的锁有两种SELECT语句:
【1】对读取的记录加S锁:

SELECT ... LOCK IN SHARE MODE;

【2】对读取的记录加X锁:

SELECT ... FOR UPDATE;   

写操作所加的锁:
【1】DELETE: 对一条记录做 DELETE操作的过程其实是先在 B+树中定位到这条记录的位置,然后获取这条记录的X锁,然后再执行 delete mark操作。
【2】UPDATE: ① 如果未修改该记录的键值并且被更新的列占用的存储空间在修改前后未发生变化,则先在 B+树中定位到这条记录的位置,然后再获取记录的 X锁;② 如果未修改该记录的键值并且至少有一个被更新的列占用的存储空间在修改前后发生变化,则先在 B+树中定位到这条记录的位置,然后获取记录的 X锁,将该记录彻底删除掉(就是把记录彻底移入垃圾链表),最后再插入一条新记录。也就是会获取 X锁和隐式锁。③ 如果修改了该记录的键值,则相当于在原记录上做 DELETE操作之后再来一次 INSERT操作,加锁操作就需要按照 DELETE和 INSERT的规则进行了。
【3】INSERT: 通过一种称之为隐式锁来保护这条新插入的记录在本事务提交前不被别的事务访问。

如果你的事务中需要锁多个行,要把最可能造成锁冲突、最可能影响并发度的锁尽量往后放。

行锁偏向 InnoDB 引擎,开销大,加锁慢、会出现死锁、锁定粒度小、发生冲突的概率低,并发度高。

InnoDB 与 MyISAM 最大的不同是:①、一个支持事务,②、采用了行级锁。

【结论】: 当 session1 对一行数据修改,但未提交时,session2 修改行数据时会阻塞,但是可以查询,但查到的是旧数据。

取消自动提交:set autocommit=0;

【无索引行锁升级为表锁】: 当索引失效后,会导致此问题。
【间隙锁危害】: 当我们使用范围条件而不是相等条件检索数据,并请求共享锁或排它锁时,InnoDB 会给符合条件的已有数据记录的索引项加锁;对于键值在条件范围内但不存在的记录,叫做 “间隙(GPA)”,InnoDB 也会对这个 “间隙” 加锁,这种锁机制就是所谓的“间隙锁”(Next-Key锁),解决幻读问题。
因为 Query 执行过程中通过范围进行查找,他会锁定整个范围内索引的索引键值,即使这个键值不存在。间隙锁有一个致命的弱点,就是当锁定一个范围之后,即使某些不存在的键值也会被无辜的锁定,而造成在锁定的时候无法插入锁定键值范围内的任何数据,在某些场景下这可能会对性能造成很大的危害。
【如何加行锁】:

【行锁分析命令如下】:

show status like 'innodb_row_lock%';

 ■ Innodb_row_lock_current_waits:当前正在等待锁定的数量。
 ■ Innodb_row_lock_time:从系统启动到现在锁定总时间长度。
 ■ Innodb_row_lock_time_avg:每次等待所花的平均时间。
 ■ Innodb_row_lock_time_max:从系统启动到现在等待最长的一次时间。
 ■ Innodb_row_lock_waits:系统启动后到现在总共等待的次数。

三、隐试锁 Gap Lock以及 next-key lock

Gap Lock以及next-key lock是为了解决幻读的。产生幻读的原因是,行锁只能锁住行,但是新插入记录这个动作,要更新的是记录之间的“间隙”。因此,为了解决幻读问题,InnoDB只好引入新的锁,也就是间隙锁(Gap Lock)。间隙锁,锁的就是两个值之间的空隙。如下,表t,初始化插入了6个记录,这就产生了7个间隙。

 CREATE TABLE `t` (
   `id` int(11) NOT NULL,
   `c` int(11) DEFAULT NULL,
   `d` int(11) DEFAULT NULL,
   PRIMARY KEY (`id`),
   KEY `c` (`c`)
 ) ENGINE=InnoDB;
 
 insert into t values(0,0,0),(5,5,5),
(10,10,10),(15,15,15),(20,20,20),(25,25,25);

当你执行 select * from t where d=5 for update的时候,就不止是给数据库中已有的6个记录加上了行锁,还同时加了7个间隙锁。这样就确保了无法再插入新的记录。间隙锁之间是不存在冲突的,例如:

SessionASessionB
begin;select * from t where c=7 lock in share mode;
begin;select * from t where c=7 for update;

这里 session B并不会被堵住。因为表t 里并没有 c=7这个记录,因此 session A加的是间隙锁(5,10)。而 sessionB 也是在这个间隙加的间隙锁。它们有共同的目标,即:保护这个间隙,不允许插入值。但它们之间是不冲突的。间隙锁和行锁合称 next-key lock, 每个 next-key lock是前开后闭区间。如果用 select * from t for update要把整个表所有记录锁起来,就形成了7个 next-key lock,分别是 (-∞,0]、(0,5]、(5,10]、(10,15]、(15,20]、(20, 25]、(25, +supremum]。

间隙锁造成的死锁: 我用两个 session来模拟并发,并假设往表里插入一条 id=9的数据。

MySQL

【1】session A 执行select … for update语句,由于id=9这一行并不存在,因此会加上间隙锁(5,10);
【2】session B 执行select … for update语句,同样会加上间隙锁(5,10),间隙锁之间不会冲突,因此这个语句可以执行成功;
【3】session B 试图插入一行(9,9,9),被session A的间隙锁挡住了,只好进入等待;
【4】session A试图插入一行(9,9,9),被session B的间隙锁挡住了;
间隙锁的引入,可能会导致同样的语句锁住更大的范围,这其实是影响了并发度的;

四、全表扫描

假如 country列上未建索引,所以只能采用全表扫描的方式来执行这条查询语句,扫描过的行会先加锁,然后再释放掉:

SELECT * FROM hero WHERE country  = '魏' LOCK IN SHARE MODE;

对于UPDATE …和DELETE …的语句来说,在遍历聚簇索引中的记录,都会为该聚簇索引记录加上X型行锁,然后:
【1】如果该聚簇索引记录不满足条件,直接把该记录上的锁释放掉;
【2】如果该聚簇索引记录满足条件,则会对相应的二级索引记录加上 X型行锁。

页锁:开销和加锁时间界于行表锁之间;会出现死锁;锁定粒度界于行表锁之间,并发度一般。(了解即可)

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

从零开始学习深度学习库-4:自动微分

欢迎来到本系列的第四部分,在这里我们将讨论自动微分 介绍 自动微分(Automatic Differentiation,简称AD)是一种计算数学函数导数(梯度)的技术。在深度学习和其他领域中,自动微分是一种极其重要…

C#集合:从字典到队列——探索数据结构核心

文章目录 C# 中的集合类型C# Dictionary 字典C# Hashtable:哈希表Hashtable 类中的属性Hashtable 类中的方法 C# SortedList:排序列表SortedList 类的中的属性SortedList 类的中的方法 C# Stack:堆栈Stack 类中的属性Stack 类中的方法 C# Que…

深度学习面经-part3(RNN、LSTM)

3.RNN 核心思想:像人一样拥有记忆能力。用以往的记忆和当前的输入,生成输出。 RNN 和 传统神经网络 最大的区别:在于每次都会将前一次的输出结果,带到下一次的隐藏层中,一起训练。 RNN应用场景: 1.文本生成 2.语音识别 3.机器翻…

C/C++动态链接库的封装和调用

1 引言 静态链接库是在编译时被链接到程序中的库文件,在编译时,链接器将静态链接库的代码和数据复制到最终的可执行文件中。动态链接库是在程序运行时加载的库文件,在编译时,可执行文件只包含对动态链接库的引用,而不…

mac npm install 很慢或报错

npm ERR! code CERT_HAS_EXPIRED npm ERR! errno CERT_HAS_EXPIRED npm ERR! request to https://registry.npm.taobao.org/pnpm failed, reason: certificate has expired 1、取消ssl验证: npm config set strict-ssl false 修改后一般就可以了,…

前端面试拼图-知识广度

摘要:最近,看了下慕课2周刷完n道面试题,记录并添加部分可参考的文档,如下... 1. 移动端H5 click有300ms延迟, 如何解决? 背景:double tap to zoom 移动端H5中的300ms点击延迟问题通常是由浏览…

3d导出stl格式模型破碎是什么原因,怎么解决?---模大狮模型网

在导出3D模型为STL格式时出现破碎(或称为碎片化)的情况通常是由于模型中存在几何上的问题造成的。以下是一些可能导致STL模型破碎的原因以及解决方法: 3d导出stl格式模型破碎的原因: 模型不封闭:STL格式要求模型必须是封闭的实体&#xff0c…

电机学(笔记)

磁极对数p: 直流电机的磁极对数是指电机定子的磁极对数,也等于电机电刷的对数。它与电机的转速和扭矩有直接关系。一般来说,极对数越多,电机转速越低,扭矩越大,适用于低速、高扭矩的场合;相反&…

分布式搜索引擎elasticsearch专栏一

初识elasticsearch 1.1了解ES elasticsearch的作用 elasticsearch是一款非常强大的开源搜索引擎,具备非常多强大功能,可以帮助我们从海量数据中快速找到需要的内容 例如: 在码云搜索代码 在电商网站搜索商品 在百度搜索答案 1.1.2.ELK…

一个可商用私有化部署的基于JAVA的chat-gpt网站

目录 介绍一、核心功能1、智能对话2、AI绘画3、知识库4、一键思维导图5、应用广场6、GPTS 二、后台管理功能1、网站自定义2、多账号登录支持3、商品及会员系统4、模型配置5、兑换码生成6、三方商户用户打通 结语 介绍 java语言的私有化部署的商用网站还是比较少的 这里给大家介…

中国银行信息系统应用架构发展历程

概述: 从 20 世纪 80 年代开始至今,我国银行业信息化历程已 有四十年历史。虽然相对于发达国家来讲,我国银行业务信 息化起步较晚,但发展速度很快, 目前我国一些大型商业银行的信息化程度已经处于全球领先水平。 “银行…

机器学习-04-分类算法-04-支持向量机SVM

总结 本系列是机器学习课程的系列课程,主要介绍机器学习中分类算法,本篇为分类算法与SVM算法部分。 本门课程的目标 完成一个特定行业的算法应用全过程: 懂业务会选择合适的算法数据处理算法训练算法调优算法融合 算法评估持续调优工程化…

学习在ubuntu系统下安装vsftp软件安装教程

学习在ubuntu系统下安装vsftp软件安装教程 安装vsftpd创建用户创建专用目录添加ftp用户修改目录归属和权限 修改配置文件配置文件其他部分详解 启动、停止、重启vsftp服务命令使用filezilla.exe 安装vsftpd apt-get install vsftpd创建用户 创建专用目录 mkdir /home/ftp添加…

arcgis数据导出到excel

将arcgis属性数据导出到excel: 1) 工具箱\系统工具箱\Conversion Tools.tbx\Excel\Excel 转表 2)用excel打开导出的图层文件中后缀为.dbf的数据(方便快捷,但是中文易乱码)

Linux 文件系统:文件描述符、管理文件

目录 一、三个标注输入输出流 二、文件描述符fd 1、通过C语言管理文件—理解文件描述符fd 2、文件描述符实现原理 3、文件描述符0、1、2 4、总结 三、如何管理文件 1、打开文件的过程 2、内核空间的结构 struct task_struct(PCB) struct file…

hcia复习总结9

NAT 在ip地址空间中,A,B,C三类地址中各有一部分地址,他们被称为私有地址(私网IP地址),其余的所有地址都被称为公有地址(公网IP地址) A:10.0.0.0-10.255.255.255--相当于一个A类网络…

LeetCode 热题 100

未完待续… 一、哈希 1、两数之和 # 暴力解,时间复杂度:o(n^2) class Solution(object):def twoSum(self, nums, target):""":type nums: List[int]:type target: int:rtype: List[int]"""for i in range(len(nums)):fo…

检查约束

Oracle从入门到总裁:​​​​​​https://blog.csdn.net/weixin_67859959/article/details/135209645 检查约束 检查约束指的是在数据列上设置一些过滤条件,当过滤条件满足的时候才可以进行保存,如果不满足则出现错误。例如,设置年龄的信息…

【C语言】猜数字游戏

代码如下&#xff1a; #define _CRT_SECURE_NO_WARNINGS 1 #include <stdio.h> #include <stdlib.h> #include <time.h> void game() {int r rand() % 100 1;int guess 0;while (1){printf("请猜数字>:");scanf("%d", &guess…

【vscode】vscode重命名变量后多了很多空白行

这种情况&#xff0c;一般出现在重新安装 vscode 后出现。 原因大概率是语言服务器没设置好或设置对。 以 Python 为例&#xff0c;到设置里搜索 "python.languageServer"&#xff0c;将 Python 的语言服务器设置为 Pylance 即可。