【MySQL】MySQL数据库锁使用与InnoDB加锁的原理解析(MySQL专栏启动)

news2025/4/8 17:53:58

📫作者简介:小明java问道之路,专注于研究 Java/ Liunx内核/ C++及汇编/计算机底层原理/源码,就职于大型金融公司后端高级工程师,擅长交易领域的高安全/可用/并发/性能的架构设计与演进、系统优化与稳定性建设。

   

📫 热衷分享,喜欢原创~ 关注我会给你带来一些不一样的认知和成长。

    

🏆 InfoQ签约作者、CSDN专家博主/后端领域优质创作者/内容合伙人、阿里云专家/签约博主、51CTO专家 🏆

    

🔥如果此文还不错的话,还请👍关注、点赞、收藏三连支持👍一下博主~ 

本文目录

本文导读

一、MySQL中三种锁分类

二、MySQL中存在的第四种锁——库锁

1、什么是库锁

2、库锁的使用场景

三、MySQL锁的使用

1、表锁

2、InnoDB 中的锁

2.1、共享锁、独占锁

2.2、意向共享锁、意向独占锁、自增锁

3、Innodb行锁

3.1、InnoDB行锁的三种类型

3.2、Innodb默认使用 Next-Key Lock

3.3、Innodb对Next-Key Lock的优化

3.4、排查 InnoDB 锁问题

四、Innodb的 Next-lock 加锁工作原理

总结


本文导读

本文将通过锁的分类,包括库锁、表锁、页锁、行锁等等,详细介绍MySQL锁的使用、以及MySQL的优化和MySQL InnoDB加锁原理。

一、MySQL中三种锁分类

这里直接给出结论,MySQL中有三种锁:页级锁、表级锁和行级锁。

表锁:低开销,快速锁定;无死锁;锁粒度大,锁冲突的概率最高,并发性最低。它出现在MyISAM、Memory、InnoDB、BDB和其他存储引擎中,基本都支持。

行锁:高开销,慢锁定;将出现死锁;锁粒度最小,锁冲突的概率最低,并发性最高。InnoDB存储引擎支持。

页锁:成本和锁定时间介于表锁和行锁之间;有可能出现死锁;锁定粒度介于表锁和行锁之间,并发性一般,仅有BDB存储引擎支持。

行锁、表锁、页锁分别对应存储引擎关系 :

二、MySQL中存在的第四种锁——库锁

1、什么是库锁

库锁是锁定整个数据库实例。MySQL提供了一种添加全局读锁的方法。需要使整个库为只读时,可以使用此锁。

这时数据更新语句(数据添加、删除和修改)、数据定义语句(包括表创建、表结构修改等)以及更新类型事务的提交语句,都会被阻塞。

FLUSH TABLES WITH READ LOCK -- 启动库锁,这整个库只读

UNLOCK TABLES  -- 释放库锁

2、库锁的使用场景

库锁的典型使用场景是对整个数据库进行逻辑备份。但是官方的逻辑备份工具mysqldump使用参数 –single transaction 时,将在导入数据之前启动事务,以确保获得一致性视图(MVCC支持)。MVCC在,MySQLMVCC原理中详解:(链接待补充)。

所以库锁一般资料中很少提到,并且工作中也很少使用。

三、MySQL锁的使用

1、表锁

表锁通常处理并发问题。然而,支持行锁定的引擎InnoDB通常不使用 lock-tables 命令来控制并发。

-- MySQL表锁语法
LOCK TABLES tbl_name [AS alias] {READ [LOCAL] | [LOW_PRIORITY] WRITE}
lock tables fork_business_detail read/write

unlock tables -- 释放锁

2、InnoDB 中的锁

在 MySQL InnoDB 存储引擎中,锁分为行锁和表锁。

2.1、共享锁、独占锁

行锁包括两种类型:共享锁、独占锁

共享锁(S):可以同时读取多个事务,不互斥,但是共享锁会阻止独占锁;独占锁(X):允许获得独占锁的事务更新数据,并防止其他事务获得同一数据集的共享读锁和独占写锁。

此外InnoDB还具有两种类型的内部意图锁,这两种类型都是表锁。

2.2、意向共享锁、意向独占锁、自增锁

表锁有三种类型:意向共享锁、意向独占锁(排他锁)、自增锁(自增计数器)

意向共享锁(IS):事务计划将行共享锁添加到数据行。在向数据行添加共享锁之前,事务必须首先获得表的IS锁。

有意独占锁(IX):事务打算向数据行添加独占锁。在向数据行添加独占锁之前,事务必须首先获得表的IX锁。

自增锁(AUTO-INC Locks):表锁的一种。自增长计数器通过这个“锁”获得子增长计数器的最大计数值。

在添加行锁之前,您必须首先获得一个表级意图锁,或者等待innodb_lock_wait_timeout,根据innodb_ rollback_on_timeout确定是否回滚事务。

3、Innodb行锁

3.1、InnoDB行锁的三种类型

InnoDB行锁定是通过锁定索引数据页上的记录来实现的。有三种主要算法:Record Lock、Gap Lock 和 Next-key Lock。

行锁(Record Lock)锁:单行记录的锁定(锁定数据,而不是间隙)。锁被直接添加到索引记录而不是行数据,键被锁定。

间隙锁(Gap Lock)锁:间隙锁,锁定一个范围,不包括记录本身(不锁定数据,只锁定数据前面的间隙),锁定索引记录的间隙,并确保索引记录的间距保持不变。

间隙锁用于隔离处于或高于可重复读取级别的事务。

Next-key Lock 锁:同时锁定数据,并锁定数据前面的间隙。行锁和间隙锁的组合称为下一个键锁。

3.2、Innodb默认使用 Next-Key Lock

默认情况下,Innodb 工作在可重复读取隔离级别,并以 Next-Key Lock 的方式锁定数据,这可以有效地防止幻读。

Next Key Lock 是行锁和间隙锁的组合。

当InnoDB扫描索引记录时,它首先对索引记录应用行锁(Record Lock),然后对索引记录两侧的间隙应用间隙锁(Gap Lock),添加间隙锁定后,其他事务无法在此间隙中修改或插入记录。

-- 注:普通查询是快照读,不需要加锁
-- for update 仅适用于InnoDB,并且必须开启事务,在begin与commit之间才生效。
begin;
select * from user_info where name = 'xiaoming' for update;
commit;

3.3、Innodb对Next-Key Lock的优化

优化1:对于索引的等效查询,当唯一索引被锁定时,下一个键锁退化为行锁。

优化2:对于索引上的等价查询,当向右遍历且最后一个值不满足等价条件时,锁退化为间隙锁。当“唯一索引”用于“搜索唯一行”语句时,不需要间隙锁。

begin;
select name from user_info where name = 'xiaoming' for update;
commit;

例如,如果name是唯一索引,并且只搜索 name,那么只有此行将与记录锁一起使用。
如果名称列没有索引或是非唯一索引,则语句将生成间隙锁。如果搜索条件中有多个查询条件(即使每列都有一个唯一的索引),也会有间隙锁。

3.4、排查 InnoDB 锁问题

通常有两种方法来解决InnoDB锁问题。

1、打开 innodb_lock_monitor 表记住在使用后关闭监视器表,否则会影响性能。

2、在information_schema 库下面的 innodb_locks、innodb_lock_waits、innodb_trx排查

3、间隙锁不是互斥的。两个事务加上间隙锁不是互斥的。事务A可以锁定相同的数据以阻止操作,而事务B可以锁定相同数据以防止操作。这可能导致死锁问题。

4、可以禁用间隙锁的两种方法,一是把隔离级别降为读已提交(read committed),二开启参数innodb_locks_unsafe_for_binlog。

可以通过 show variables like 'innodb_locks_unsafe_for_binlog'; (默认不开启,如果发现有long 事务可以排查下间隙锁)命令查看该库是否开启间隙锁。

四、Innodb的 Next-lock 加锁工作原理

分析锁时需要跟隔离级别联系起来,我们以可重复读 RR(REPEATABLE-READ) 为例,首先开启两个事务

左边执行 select * from fork_business_detail where sub_odr_id='xiaoming' ,会加 next-key lock。

右边执行insert语句就会阻塞。

加锁是要基于索引的。

1、主键,加锁行为仅在 主键索引记录上加排他(X)锁。

2、唯一索引,先在唯一索引 id 上加排他(X)锁,再在的主键索引记录上加排他(X)锁。若记录不存在,那么加间隙锁。

3、普通索引,先通过索引上定位到第一个满足的记录,对该记录加 X 锁,而且要在主键上面,之间加上 Gap lock,为了防止幻读,然后在主键索引 name 上加对应记录的X 锁;再通过该索引上定位,有没有其他满足的记录,同上。最后直到发现没有满足的记录了,此时不需要加 X 锁,但要再加一个 Gap lock(间隙锁),这个锁扩到该数据的下一位。

也就是说满足条件的数据之间上下一位都会别锁住。

4、无索引,表里所有行和间隙均排他(X)锁,直接锁表了,所以在使用的时候一定要走索引。

总结

本文将通过锁的分类,包括库锁、表锁、页锁、行锁等等,详细介绍MySQL锁的使用、以及MySQL的优化和MySQL InnoDB加锁原理。

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

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

相关文章

【Spring】Bean 的作用域和生命周期

文章目录1. Bean 的作用域1.1 通过一个案例来看 Bean 作用域的问题1.2 作用域的定义1.3 Spring Bean 支持的作用域(未介绍完全)1.4 修改 Bean 的作用域1.5 Bean 执行流程2. Bean 的生命周期2.1 Bean 的生命周期分为以下 5 大部分2.1.1 实例化 Bean&#…

【代码精读】在optee中注册一个中断

快速链接: . 👉👉👉 【代码精读】–Kernel/ATF/optee等-目录👈👈👈 付费专栏-付费课程 【购买须知】:本专栏的视频介绍-----视频👈👈👈概要: 在optee os总如何注册一个中断? 有没有类似于request_irq的程序? 注册了该中断后,是哪里将该中断配置成Secure…

保边滤波之基于测地距离的滤波与局部拉普拉斯滤波

(1)基于测地距离的滤波 给定图像I及其Hard Mask M,其中M(x)∈{0,1} ,M(x)0表示x属于前景,M(x)1表示x属于背景,图像中某点x到前面Hard Mask的测地距离为 ???d(a,b)表示…

机器学习中的数学原理——最小二乘法

这几天在刷B站的时候,有个深度学习的博主推荐了一本机器学习的书——《白话机器学习的数学》,抱着浅看一下的态度,我花3个大洋从淘宝上找到了这本书的电子版。看了两天我直接吹爆!!!所以这个专栏就分享一下…

《Linux驱动:DMA直接内存访问》

目录一、前言二、DMA传输主体三、S3c2440上的DMA3.1 DMA请求源3.2 DMA状态机3.3 DMA请求模式3.4 DMA服务模式3.5 DMA传输模式3.6 DMA读写数据大小3.7 DMA寄存器3.7.1 DCON寄存器其他几个重要位四、使用DMA4.1 软件触发DMA4.2 硬件源触发DMA一、前言 DMA(Direct Memory Aaccess…

SpringMVC框架中的拦截器

目录 1. 拦截器接口的介绍 2. 拦截器接口中方法的详细介绍 3. 配置拦截器的步骤 4. 多个拦截器的的执行情况 5. 拦截器与过滤器的区别 1. 拦截器接口的介绍 2. 拦截器接口中方法的详细介绍 public class MyInterceptor implements HandlerInterceptor {Overridepublic bo…

Elasticsearch学习--script

一、概念 es1.4-5.0,默认脚本语言是Grovvy es5.0,默认脚本语言是painless 二、简单使用 将price减一 # 将id1的price减一 POST goods/_update/1 {"script": {"source": "ctx._source.price - 1"} }# 简写 POST goods/_…

Cloud Computing之时钟和顺序Time and Ordering

文章目录Total orderImplementation of total orderLinearizabilityFIFO rderImplementation of FIFO-orderHappen-before orderingCausal orderingSummary参考文献:Lamport’s logical clock 这章重点介绍了分布式系统下各种类型的时序,其实在分布式场景…

【Linux】网络配置详解

网络配置一.网络连接测试1.查看宿主机和虚拟机ip(1)查看宿主机ip①宿主机:可视化界面查看ip②宿主机:命令行查看ip(2)查看虚拟机ip①虚拟机:可视化界面查看ip②虚拟机:命令行查看ip2.测试宿主机和虚拟机的网络通信(1).宿主机ping虚拟机(2).虚拟机ping宿主机二.网络连接模式1.桥…

420招募线上被试 | 高素质人才行为心理测试

招募中 【实验任务】高素质人才行为心理测试 【实验时长】18分钟 【实验时间】2022年11月12日00时 - 2022年11月20日24时 【实验地点】线上实验 【实验报酬】微信红包,每份问卷3元 【实验要求】如实回答问卷问题,并提供微博账号和微博地址 【被试要…

Js逆向教程-03浏览器调试工具-Source面板

Js逆向教程-03浏览器调试工具-Source面板 切换到source面板,对于source面板,需要打开搜索面板才能发挥出完整的功能。 一、搜索面板 通过点击右上角的按钮,切换到搜索面板 搜索页面的左侧,可以给搜索页面添加其他功能 比如cons…

第1章 数据结构的概念

文章目录文档配套视频讲解链接地址第01章 数据结构的概念1.1 数据结构的知识体系1.2 链表1. 创建头结点的内存图2. 插入1节点时的内存图3. 插入2节点时的内存图4. 插入3节点的内存图5. 实例1 链表节点的插入6. 链表删除节点37. 实例2 链表的删除节点8. 实例3 链表的改查逆序9. …

Allegro阻抗分析指导书

Allegro阻抗分析指导书 利用Allegro自带的功能可以快速分析信号的阻抗 操作如下 首先用172版本打开PCB 把每层厚度和介电常数填写进去 点击work flow Manager,出现右图对话框 选择需要查看的网络 点击start Analysis 点击impedance table和impedance vision就可以查看阻…

【网络篇】第九篇——多线程版的TCP网络程序

多进程与多线程对比 多进程 多线程 多线程版的TCP网络程序 多进程与多线程对比 多进程 优点 可以处理多个用户易于边写稳定,因为进程具有独立性 缺点 连接来了之后才创建进程,性能太低多进程服务器特别吃资源,而且同时服务的客户有上限…

(最新版2022版)剑指offer之排序题解

(最新版2022版)剑指offer之排序题解JZ3数组中重复的数字JZ51 数组中的逆序对JZ40 最小的K个数JZ41 数据流中的中位数JZ3数组中重复的数字 思路: 既然数组长度为nnn只包含了0到n−1n-1n−1的数字,那么如果数字没有重复&#xff0c…

qt C++中指针自动释放内存及程序中的内存操作、管理

程序加载到内存后代码存储到代码区,并将全局变量、静态变量初始化到全局/静态内存区,然后会分配2M左右的栈内存区用于存储局部变量,并在运行时根据需要可以在堆内存区(空闲内存区及硬盘的虚拟内存区)申请空间。 程序可使用的内存分区↓ 各基…

C++之Hello World

概览 编程语言历史 机器语言:00110101…最初始的计算机内部语言,不同机器使用的语言甚至不同 汇编语言:利用简单符号(a DB 7H…)对机器语言进行了一定的抽象,增加了可读性,更加人性化.在一定程度上仍然依赖硬件,属于低级的语言 高级语言:使用文字通过编译器被翻译为机器语言…

Vue中 引入使用 element-resize-detector 监听 Dom 元素 宽度、高度 变化

1. 前言 很多做pc端平台的小伙伴都遇到过这样一个问题:在做侧边栏菜单时会有一个收缩和展开的一个功能,在伸缩的过程中右边的页面的宽度就会随之改变。我上网查了查 ,也动手试了试 window.onresize ()>{}。却不尽人意,因为它…

SVM 超平面计算例题

SVM Summary Example Suppose the dataset contains two positive samples x(1)[1,1]Tx^{(1)}[1,1]^Tx(1)[1,1]T andx(2)[2,2]Tx^{(2)}[2,2]^Tx(2)[2,2]T, and two negative samples x(3)[0,0]Tx^{(3)}[0,0]^Tx(3)[0,0]T and x(4)[−1,0]Tx^{(4)}[-1,0]^Tx(4)[−1,0]T. Please…

MySQL纯代码复习

前言 本文章是用于总结尚硅谷MySQL教学视频的记录文章,主要用于复习,非商用 原视频连接:https://www.bilibili.com/video/BV1iq4y1u7vj/?p21&spm_id_frompageDriver&vd_sourcec4ecde834521bad789baa9ee29af1f6c https://www.bilib…