3-1-1-2-MySQL锁机制

news/2025/11/11 15:22:41/文章来源:https://www.cnblogs.com/panhua/p/19210461

MySQL中锁的分类

1、按照实现方式:

乐观锁、悲观锁;

2、按照作用对象:

Lock、Latch

3、按照锁定对象:

全局锁、表锁、页锁、行锁

4、按照操作类型:

共享锁、独占锁

5、按照用途场景:

记录锁、间隙锁、临键锁、意向锁、插入意向锁、自增锁、元数据锁

我将以结构化表格+关键原理拆解+场景示例的方式,帮你系统梳理MySQL锁的全分类知识体系。以下是按你要求的5大维度展开的内容:


一、按「实现方式」分类:乐观锁 vs 悲观锁

维度 乐观锁 悲观锁
核心思想 假设并发冲突少,不提前加锁,通过「数据版本校验」处理冲突 假设并发冲突多,提前加锁,直接阻止其他事务修改
实现原理 1. 版本号机制:表中增加version字段,更新时检查version是否等于旧值 2. 时间戳机制:用update_time替代版本号 公式update t set val=?, version=version+1 where id=? and version=旧版本 依赖数据库原生锁机制(如MySQL的SELECT ... FOR UPDATE/LOCK IN SHARE MODE
用途 读多写少场景(如库存扣减、点赞数更新),避免锁竞争提升并发 写多读少/强一致性场景(如转账、订单状态变更),确保数据绝对安全
示例 库存扣减:先查version=1,更新时带version=1,若失败则重试 转账:BEGIN; SELECT balance FROM account WHERE id=1 FOR UPDATE; -- 扣减余额; COMMIT;
注意事项 解决不了「ABA问题」(版本号回绕),需配合递增版本号时间戳规避 长事务会导致锁持有时间长,容易引发阻塞或死锁

二、按「作用对象」分类:Latch(门闩) vs Lock(锁)

Latch和Lock都是InnoDB的同步机制,但定位和粒度完全不同:

维度 Latch Lock
核心定位 轻量级内存同步原语,保护InnoDB内部短期临界资源(如缓冲池页、数据字典) 重量级事务同步原语,保护长期数据一致性(如事务中的行/表修改)
实现原理 基于Spinlock(自旋锁):线程会循环尝试获取锁,直到成功(避免上下文切换) 基于Mutex(互斥锁)+ 等待队列:未获取锁的线程进入阻塞队列,等待唤醒
生命周期 极短(纳秒/微秒级),获取后立即释放 较长( milliseconds级),伴随事务生命周期
用途 保护缓冲池页的读取/修改(如buf_flush_page)、数据字典的加载 事务中的行锁、表锁、间隙锁等
示例 InnoDB读取缓冲池中的页时,会加buf0buf.h中的page_mutexlatch 事务执行UPDATE时,对目标行加row_lock(属于Lock)
关键差异 不涉及事务上下文,无死锁检测;Latch冲突会直接自旋,不会阻塞线程 支持两阶段锁协议(2PL),会参与死锁检测;Lock冲突会阻塞线程

三、按「锁定对象」分类:全局锁→表锁→页锁→行锁

锁的粒度从大到小排列,粒度越细,并发越高,但开销越大

维度 全局锁 表锁 页锁 行锁
锁定范围 整个MySQL实例(所有数据库/表) 单张表 InnoDB缓冲池中的单个页(16KB) 表中的单行数据(基于索引)
实现原理 通过FLUSH TABLES WITH READ LOCK命令触发,修改global_read_lock状态 MyISAM引擎默认支持;InnoDB可通过LOCK TABLES ... READ/WRITE手动加 InnoDB内部对缓冲池页的修改加锁(如页分裂时) 基于B+树索引,对目标行的索引项加锁(如主键/二级索引)
用途 全局备份(如mysqldump不支持事务时的替代方案)、禁止所有写操作 MyISAM引擎的读写隔离;手动锁定表进行批量操作 缓冲池页的并发修改(如页分裂时防止其他线程读取不完整页) InnoDB事务的行级隔离(如UPDATE某行)
示例 FLUSH TABLES WITH READ LOCK; -- 备份所有表; UNLOCK TABLES; MyISAM:LOCK TABLE orders READ; -- 查询; UNLOCK TABLES; InnoDB缓冲池页分裂时,对父页加page_mutex UPDATE user SET name='张三' WHERE id=1; -- 对id=1的行加行锁
注意事项 全局锁会导致数据库完全不可写,仅用于紧急备份 MyISAM表锁并发差(读写互斥),已被InnoDB取代 页锁粒度介于表锁和行锁之间,InnoDB中很少手动感知 无索引,行锁会升级为表锁(InnoDB的 fallback 机制)

四、按「操作类型」分类:共享锁(S) vs 独占锁(X)

这是锁的兼容性基础,所有行锁/表锁都可以归属到这两类:

维度 共享锁(Shared Lock,S锁) 独占锁(Exclusive Lock,X锁)
别名 读锁 写锁
核心规则 允许多个事务加S锁,但禁止加X锁 仅允许一个事务加X锁,禁止其他事务加S/X锁
实现原理 锁结构中标记lock_mode=S,通过lock_rec_check检查兼容性 锁结构中标记lock_mode=X,兼容性检查直接拒绝其他锁
用途 读多写少场景(如报表查询),允许多个事务并发读 写场景(如更新/删除),确保数据修改的独占性
示例 SELECT * FROM user WHERE id=1 LOCK IN SHARE MODE; -- 加S锁 BEGIN; SELECT * FROM user WHERE id=1 FOR UPDATE; -- 加X锁; UPDATE ...; COMMIT;
兼容性矩阵 S锁 ↔ S锁:兼容 S锁 ↔ X锁:不兼容 X锁 ↔ X锁:不兼容 (同上,本质是X锁排斥所有其他锁)

五、按「用途场景」分类:8类锁的深度拆解

这是MySQL锁的核心细分,直接关联事务隔离级别(如RR下的间隙锁):

1. 记录锁(Record Lock)

  • 概念:锁定索引中的具体记录(仅锁存在的记录)。
  • 实现:锁结构标记lock_mode=REC_NOT_GAP,作用于B+树的叶子节点。
  • 用途:防止其他事务修改/删除目标记录(如UPDATE id=1)。
  • 示例SELECT * FROM user WHERE id=1 FOR UPDATE; -- 对id=1的主键记录加记录锁

2. 间隙锁(Gap Lock)

  • 概念:锁定索引记录之间的间隙(锁不存在的区间),解决幻读问题。
  • 触发条件:事务隔离级别≥REPEATABLE READ(RR),且SQL使用范围查询(如BETWEEN/>/<)。
  • 实现:锁结构标记lock_mode=GAP,作用于B+树的间隙(如(10,20))。
  • 用途:防止其他事务插入间隙中的数据(如WHERE id BETWEEN 10 AND 20,锁(10,20)间隙,禁止插入id=15)。
  • 示例SELECT * FROM user WHERE id BETWEEN 10 AND 20 FOR UPDATE; -- 对(10,20)间隙加间隙锁

3. 临键锁(Next-Key Lock)

  • 概念记录锁+间隙锁的组合,锁定前一条记录的末尾到当前记录的区间(即(gap_left, current_record])。
  • 默认行为:InnoDB在RR隔离级别下的行锁默认类型
  • 实现:锁结构同时包含记录锁和间隙锁,标记lock_mode=NEXT_KEY_LOCK
  • 用途:同时防止记录修改和幻读(覆盖记录本身+前后间隙)。
  • 示例SELECT * FROM user WHERE id=15 FOR UPDATE; -- 对(10,15](假设前一条是10)和(15,20)间隙加临键锁?不,准确说:若id=15存在,临键锁锁的是(prev_gap, 15],比如前一条是10,则锁(10,15];若查询是WHERE id>10,则锁(10,15]+(15,20]`等)。

4. 意向锁(Intention Lock)

  • 概念表级别的锁,表示「事务打算对表中的行加行锁」,用于协调表锁与行锁的冲突

  • 分类

    • 意向共享锁(IS锁):打算加行S锁;
    • 意向独占锁(IX锁):打算加行X锁。
  • 实现:锁结构标记lock_mode=IS/IX,存储在表级别的锁表中。

  • 用途:避免表锁获取时遍历所有行检查行锁(如表锁要加S锁,只需检查表是否有IX锁,无需遍历行)。

  • 兼容性

    IS锁 IX锁 S锁 X锁
    IS锁
    IX锁
    S锁
    X锁
  • 示例:事务A对user表的id=1行加X锁→表级加IX锁;事务B想加表级S锁→检查到IX锁,需等待。

5. 插入意向锁(Insert Intention Lock)

  • 概念间隙锁的特殊类型,表示「事务打算在某个间隙插入数据」。
  • 触发条件:插入数据时,对目标间隙加插入意向锁。
  • 实现:锁结构标记lock_mode=INSERT_INTENTION,属于间隙锁的子类。
  • 用途:允许并发插入不同的间隙(如事务A插入间隙(10,20)的15,事务B插入(20,30)的25,两者不冲突)。
  • 示例INSERT INTO user (id) VALUES (15); -- 对(10,20)间隙加插入意向锁

6. 自增锁(Auto-Inc Lock)

  • 概念:InnoDB为自增主键设计的锁,保证自增id的唯一性。
  • 触发条件:执行INSERT时,对自增计数器加锁。
  • 模式控制:由innodb_autoinc_lock_mode参数决定:
    • 0:连续模式(表级X锁,直到语句结束,保证id连续,但并发低);
    • 1:默认交错模式(语句级锁,INSERT完成后立即释放,保证同一语句内id连续);
    • 2:完全交错模式(无锁,用原子操作递增,并发最高,但同一语句内id可能不连续)。
  • 用途:防止自增id重复(如高并发插入时,保证id唯一)。

7. 元数据锁(Metadata Lock,MDL)

  • 概念表级别的锁,保护数据库元数据(如表结构、索引)的一致性。
  • 分类
    • MDL读锁(SHARED_READ):所有DML/查询操作自动加,允许并发读元数据;
    • MDL写锁(EXCLUSIVE):DDL操作(如ALTER TABLE)自动加,禁止其他DML/查询。
  • 实现:锁结构存储在mysql.innodb_dynamic_metadata表中,通过锁管理器同步。
  • 用途:防止DDL操作与DML操作冲突(如ALTER TABLE时,禁止其他事务修改表数据,避免元数据不一致)。
  • 坑点:长事务持有MDL读锁→DDL操作无法获取写锁→数据库卡住(需kill长事务)。

六、关键总结:锁的关联与演进

  1. 锁的粒度:全局锁>表锁>页锁>行锁→粒度越细,并发越高,但开销越大;
  2. 锁的兼容性:S锁兼容S锁,X锁排斥所有→基于此实现事务的隔离;
  3. RR与幻读:InnoDB通过临键锁(记录锁+间隙锁)解决幻读,而非MVCC;
  4. 元数据锁的重要性:长事务会阻塞DDL,需避免(如设置wait_timeout或监控长事务)。

七、模拟面试提问

假设我问:「InnoDB的临键锁是怎么解决幻读的?请结合B+树结构说明」

  • 优秀回答要点
    1. 幻读定义:同一事务中,两次相同范围查询返回不同行;
    2. 临键锁结构:(前一条记录的末尾, 当前记录]→锁定记录+前面的间隙;
    3. B+树示例:若表有id=10、15、20的记录,查询WHERE id>10→临键锁锁(10,15]+(15,20]+(20, +inf)→禁止插入id=12/18/25,解决幻读;
    4. 触发条件:RR隔离级别+范围查询。
  • 常见不足:忘记提B+树的结构,或混淆间隙锁与临键锁的区别→需明确临键锁是「记录锁+间隙锁」的组合。

如果需要深入某个锁的细节(如间隙锁的排查、自增锁的性能优化),或想模拟面试中的锁问题,随时告诉我!

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

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

相关文章

Debug日志

2025.11.11 今天在做TFT LCD屏幕 4线SPI时,出现屏幕背光打开,但是屏幕无任何显示。软件进行了debug好久一无所获,最终检查硬件连线,发现CS引脚存在虚焊(量电压竟然有,测试阻抗才发现虚焊),补焊后正常。程序后续…

3-1-1-4-ACID特性底层原理

1、ACID的底层保障机制 一、前言:ACID是事务的核心契约 MySQL的ACID(原子性Atomicity、一致性Consistency、隔离性Isolation、持久性Durability)是事务的基石,其实现依赖InnoDB存储引擎的底层组件协同工作(如日志…

1-6-5-Netty

1、Netty的工作流程和底层机制 要理解Netty的核心价值(高性能、低延迟的异步事件驱动网络框架),必须从其工作流程(业务视角的全链路)和底层机制(技术实现的本质)两方面展开。以下是结构化的拆解: 一、明确Nett…

2025年11月北京离婚房产律师对比榜:五强机构多维评测

当婚姻走到尽头,房产往往成为双方最关切的“硬资产”。在北京,一套房子可能凝聚着两代人积蓄、学区资格、央产政策限制,甚至公司股权与境外信托的交叉安排。用户搜索“北京离婚房产律师”时,通常处于三种场景:一是…

3-1-2-1-MySQL整体架构详解

1、MySQL整体架构 MySQL 整体架构与底层原理详解 MySQL 是一款关系型数据库管理系统(RDBMS),以分层架构为核心设计思想,将功能解耦为多个模块,兼顾扩展性、性能与易维护性。以下从整体架构分层、核心组件底层原理…

3-1-2-2-MySQL分页查询机制

1、MySQL分页查询处理流程 要理解MySQL分页查询的处理流程与底层原理,我们需要从SQL执行生命周期、存储引擎行为、性能瓶颈根源三个维度展开,并结合LIMIT子句的本质展开分析。 一、分页查询的核心语法与本质 MySQL分…

3-1-2-3-MySQL高可用与容灾

1、MySQL高可用与容灾设计全解析 MySQL的高可用(High Availability, HA)聚焦减少服务不可用时间(降低RTO,恢复时间目标),容灾(Disaster Recovery, DR)则关注应对区域性/毁灭性故障(降低RPO,恢复点目标,即数…

打印文件怎么居中,占整个页面

通用核心步骤设置最小页边距:在打印设置中把边距设为0或最小值启用缩放/自适应:让内容自动缩放以填满纸张检查纸张方向:横向/纵向选择能最大化利用空间的方向

3-1-0-MySQL知识总览

在互联网大厂的资深开发岗和架构师岗面试中,数据库知识的考察注重底层原理、分布式架构设计、性能优化及安全防护,核心围绕“如何用数据库支撑高并发、高可用、可扩展的业务场景”展开。以下是全面且深入的数据库知识…

AT AGC043D Merge Triplets 题解

SolutionLink 神题。 手玩一下样例,发现重点肯定在这个顶部元素和 \(3\) 的大小之间的次序关系。考虑最特殊的,即对于 \(n\) 个三元组,都有如 \(A_{i, 1} \lt A_{i, 2} \lt A_{i , 3}\) 的形式,那么我们最终得到一…

4-1-2-Kafka-Broker-log

0、分区目录内物理存储文件类型 Kafka的消息存储体系围绕分区(Partition)展开,每个分区对应一个物理目录,目录内包含核心日志文件、索引文件、事务相关文件及元数据文件四大类,共同支撑消息的高效存储、查询与一致…

SqlSugar 在linux环境下连接sqlserver数据库报错SSL出错,因为升级了驱动,字符串增加Encrypt=True;TrustServerCertificate=True;

Centos 7编辑openssl.cnf文件vim /etc/pki/tls/openssl.cnf#在oid_section=new_oids下增加 openssl_conf = default_conf #在文件末尾增加 [default_conf] ssl_conf = ssl_sect [ssl_sect] system_default = system_de…

2025年11月GPU服务器公司排名:五强技术方案与落地案例对比

如果你正在规划AI训练、工业仿真或大数据建模项目,GPU服务器选型往往决定预算、进度与算力天花板。2025年,国内GPU服务器市场呈现“国产化加速、场景细分、成本敏感”三大趋势:一方面,信创政策要求关键行业优先采用…

在 Windows 系统上安装官方 Codex CLI 教程

前面介绍过,➡️在 Windows 系统上安装官方 Claude Code CLI 教程,今天再来说说 Windows下如何用官方的 Codex CLI ! 一、打开网站 https://www.aicodemirror.com (用了两个多月,网站稳定性不错) 注册就送2000积…

关于CSS的三种引入方法的说明与区别说明

关于CSS的三种引入方法的说明与区别说明Posted on 2025-11-11 15:11 520_1351 阅读(0) 评论(0) 收藏 举报CSS 层叠样式表(英文全称:Cascading Style Sheets)是一种用来表现HTML(标准通用标记语言的一个应用)或…

薪酬管理:企业增长的“隐形引擎”—中国薪资管理系统Top 5深度分析与选型指南

引言:复杂多变的中国薪酬市场与数字化挑战 在现代企业运营中,薪酬管理已远超简单的工资核算与发放,它更是激发员工积极性、优化成本结构、驱动业务增长的“隐形引擎”。特别是在中国这个拥有庞大劳动力市场和复杂多…

SpringOJ竞赛计划----组件ElasticSearch

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

C# Avalonia 17- ControlTemplates - VisualTreeDisplay

C# Avalonia 17- ControlTemplates - VisualTreeDisplayVisualTreeDisplay.axaml代码<Window xmlns="https://github.com/avaloniaui"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"…