当前位置: 首页 > news >正文

InnoDB 行级锁与意向锁

InnoDB 行级锁与意向锁


一、锁(整体概念)

1. 概念(Concept)

  • 定义:数据库管理系统提供的并发控制机制,用于协调多个事务对共享数据资源的访问顺序。
  • 分类
    • 按粒度:表级锁、行级锁、页级锁
      -按功能:共享锁(S)、排他锁(X)、意向锁(IS/IX)
    • 按策略:悲观锁(数据库锁)、乐观锁(版本号/CAS)
  • 关系:InnoDB 以行级锁为核心,结合MVCC(多版本并发控制)实现非锁定读(快照读),兼顾并发性能与一致性。

2. 作用 / 目的(Purpose)

  • 保证事务 ACID 中的隔离性(Isolation)一致性(Consistency)
  • 防止并发访问导致的脏读、不可重复读、幻读、丢失更新
  • 不用的后果:多事务同时读写同一数据时,结果相互覆盖或依赖混乱,数据失去可信度。

3. 原理 / 机制(Mechanism)

  • 锁管理器(Lock Manager):InnoDB 在内存中维护锁表和锁等待队列,通过锁兼容性矩阵判断请求是否冲突。
  • 自动加锁/释放:事务执行 DML 时自动申请锁,事务提交(COMMIT)或回滚(ROLLBACK)时自动释放。
  • 两阶段锁协议(2PL):加锁和解锁分为两个阶段,保证事务隔离。

4. 使用方式(Usage)

  • 隐式加锁UPDATE / DELETE / INSERT等 DML 语句自动加相应锁。
  • 显式加锁
    SELECT...FORUPDATE;-- 显式加 X 锁SELECT...LOCKINSHAREMODE;-- 显式加 S 锁LOCKTABLEStWRITE;-- 显式表锁(InnoDB 不推荐)

5. 注意事项 / 坑点(Caveats)

  • 锁粒度过大(如退化为表锁)会严重降低并发性能。
  • 死锁:多个事务循环等待对方持有的锁,InnoDB 会自动检测并回滚代价最小的事务。
  • 锁等待超时:由参数innodb_lock_wait_timeout控制(默认 50 秒)。

6. 对比 / 演进(Comparison)

维度MyISAMInnoDB
锁粒度仅表锁行锁 + 表锁
并发读读锁会阻塞写MVCC 快照读不阻塞
适用场景读多写少、非事务高并发、事务强一致

二、共享锁(S 锁 / Shared Lock)

1. 概念(Concept)

  • 定义:行级读锁。事务对数据行加 S 锁后,允许其他事务继续加 S 锁读取,但禁止加 X 锁修改
  • 分类:行级锁、悲观锁。
  • 关系:与 X 锁互斥,与其他 S 锁兼容;与意向共享锁(IS)兼容。

2. 作用 / 目的(Purpose)

  • 保证读一致性:读取期间阻止其他事务修改,防止脏读。
  • 提高读并发:多事务可同时持有同一行的 S 锁,实现并发读。
  • 使用场景
    • 读取数据后需基于该值做业务判断(如读取余额后决定是否转账)。
    • 父子表一致性读取(先对父表加 S 锁,防止父记录被删)。
    • 报表统计,需确保查询期间数据不被修改。

3. 原理 / 机制(Mechanism)

  • 事务对某行加 S 锁时,InnoDB 执行两步:
    1. 对表加IS 锁(意向共享锁)
    2. 对目标行加S 锁
  • 锁兼容性:S-S 兼容,S-X 互斥
  • 底层通过lock_t结构体记录锁信息,并维护锁等待队列。

4. 使用方式(Usage)

-- 显式加共享锁BEGIN;SELECT*FROMusersWHEREid=1LOCKINSHAREMODE;-- 其他事务可继续 LOCK IN SHARE MODE,但不能 FOR UPDATE 或 UPDATECOMMIT;-- 隐式加锁(SERIALIZABLE 隔离级别)SETSESSIONTRANSACTIONISOLATIONLEVELSERIALIZABLE;BEGIN;SELECT*FROMusersWHEREid=1;-- 普通 SELECT 也加 S 锁COMMIT;

5. 注意事项 / 坑点(Caveats)

  • 死锁风险:事务 A 持 S 锁等 B 释放 X 锁,事务 B 持 S 锁等 A 释放 X 锁,形成循环等待。
  • 阻塞写操作:长时间持有 S 锁会导致写事务持续等待,影响系统吞吐量。
  • 与 MVCC 快照读的区别LOCK IN SHARE MODE当前读(Current Read),会加真实锁;普通SELECT在 RC/RR 下是快照读,不加锁。

6. 对比 / 演进(Comparison)

  • vs X 锁:S 锁共享、只读;X 锁独占、可写。
  • vs 意向锁:S 锁是真实行锁,IS 锁是表级辅助标记。
  • 版本演进:MySQL 8.0 支持SELECT ... FOR SHARELOCK IN SHARE MODE的新语法别名)。

三、排他锁(X 锁 / Exclusive Lock)

1. 概念(Concept)

  • 定义:行级写锁。事务对数据行加 X 锁后,禁止其他事务加任何锁(S 或 X)访问该行
  • 分类:行级锁、悲观锁。
  • 关系:与 S 锁、X 锁均互斥;与意向排他锁(IX)在表级兼容。

2. 作用 / 目的(Purpose)

  • 保证写操作独占性:确保修改过程不被其他事务干扰,防止丢失更新和脏写。
  • 保证原子性:事务内的修改要么全部成功,要么通过回滚撤销。
  • 使用场景
    • 库存扣减、账户转账、订单状态变更。
    • 悲观锁并发控制:先锁定资源,再执行业务逻辑。
    • 避免"读取-修改-写入"过程中的竞争条件。

3. 原理 / 机制(Mechanism)

  • 事务对某行加 X 锁时,InnoDB 执行两步:
    1. 对表加IX 锁(意向排他锁)
    2. 对目标行加X 锁(记录锁 Record Lock)
  • 锁兼容性:X 与任何锁(S、X)都互斥
  • 对于范围查询,可能升级为间隙锁(Gap Lock)临键锁(Next-Key Lock)

4. 使用方式(Usage)

-- 显式加排他锁BEGIN;SELECT*FROMusersWHEREid=1FORUPDATE;UPDATEusersSETbalance=balance-100WHEREid=1;COMMIT;-- 隐式加锁(DML 自动)BEGIN;UPDATEusersSETage=20WHEREid=1;-- 自动加 X 锁DELETEFROMusersWHEREid=2;-- 自动加 X 锁INSERTINTOusers(name)VALUES('Tom');-- 对新插入行自动加 X 锁COMMIT;

5. 注意事项 / 坑点(Caveats)

  • 死锁高发区:多个事务以不同顺序对多行加 X 锁,极易形成循环等待。
  • 锁未命中索引:若WHERE条件无索引,可能退化为表锁或锁定大量行。
  • 幻读问题:仅靠 X 锁无法完全解决幻读,需配合间隙锁 / 临键锁(RR 隔离级别)。
  • 超时控制:锁等待超过innodb_lock_wait_timeout会报错:Lock wait timeout exceeded

6. 对比 / 演进(Comparison)

  • vs S 锁:X 锁独占资源,S 锁共享资源。
  • vs 乐观锁:X 锁是"先锁后改"的悲观策略;乐观锁是"先改后校验"(如版本号),无真实数据库锁。
  • 版本演进:MySQL 8.0 支持SELECT ... FOR UPDATE NOWAIT(立即报错不等待)和SKIP LOCKED(跳过已锁定行)。

四、意向锁(IS / IX 锁 / Intention Lock)

1. 概念(Concept)

  • 定义表级锁,用于声明事务即将对表中的某些行加行级锁(S 或 X)。
    • IS(意向共享锁):事务即将对某些行加 S 锁。
    • IX(意向排他锁):事务即将对某些行加 X 锁。
  • 分类:表级锁、辅助锁。
  • 关系:是行锁的前置"信号锁",协调表级锁与行级锁的冲突判断。

2. 作用 / 目的(Purpose)

  • 核心作用:解决"加表锁时是否需要逐行扫描检查行锁"的效率问题。
    • 无意向锁:加表锁前需遍历全表,检查每一行是否被锁定 →O(n) 复杂度
    • 有意向锁:只需检查表级是否有 IS/IX →O(1) 复杂度
  • 使用场景
    • ALTER TABLE(需表级锁)与正在进行的 DML(持有 IX 锁)之间的协调。
    • LOCK TABLES显式表锁与行锁共存时的快速判断。
    • 外键约束检查时,父表与子表之间的锁协调。

3. 原理 / 机制(Mechanism)

  • 自动维护:事务对行加 S 锁前,先对表加 IS;对行加 X 锁前,先对表加 IX。
  • 兼容性
    • IS 与 IX互相兼容(多个事务可同时持有 IX)。
    • 但 IS/IX 与表级 S/X 锁存在互斥:
      • IX 与 表 S 锁互斥
      • IX 与 表 X 锁互斥
      • IS 与 表 X 锁互斥
  • 表锁请求时,只需检查表级意向锁状态,无需遍历行记录。

4. 使用方式(Usage)

  • 完全自动,用户不可手动干预
-- 以下操作自动在表上加 IS 锁,在行上加 S 锁SELECT*FROMusersWHEREid=1LOCKINSHAREMODE;-- 以下操作自动在表上加 IX 锁,在行上加 X 锁SELECT*FROMusersWHEREid=1FORUPDATE;UPDATEusersSETage=20WHEREid=1;INSERTINTOusers(name)VALUES('Tom');

5. 注意事项 / 坑点(Caveats)

  • 不可见但存在:用户无法直接操作,但可通过SHOW ENGINE INNODB STATUS查看锁状态。
  • 不是真正的"阻塞锁":意向锁本身不会阻塞其他事务对行的访问,只阻塞表级锁请求
  • 常见误区:误以为意向锁会阻塞行级操作。实际上,IX 与 IX 兼容,多个事务可同时持有 IX 并操作不同行。

6. 对比 / 演进(Comparison)

  • vs 行锁:意向锁是"表级信号",行锁是"真实数据保护";两者协作,意向锁不替代行锁。
  • vs 表锁:表锁直接阻塞整表所有访问;意向锁仅影响后续表锁请求,不影响行级 DML。
  • 版本演进:从 InnoDB 诞生之初即存在,机制稳定,无重大版本差异。

五、锁兼容性总表

请求锁 \ 已有锁ISIXS(表)X(表)
IS
IX
S(表)
X(表)

✓ 兼容(可同时持有),✗ 互斥(需等待)


六、问题

什么是锁?InnoDB有哪些行级锁类型(共享锁、排他锁)?意向锁的作用是什么?

第一,什么是锁。 锁是数据库的并发控制工具。多事务同时读写同一份数据,容易出现脏读、数据覆盖。锁就是用来规定访问顺序,保障隔离性和一致性。InnoDB 搭配 MVCC 把读分成两种:普通 SELECT 是快照读,不加锁;FOR UPDATE、LOCK IN SHARE MODE 是当前读,会加锁。InnoDB 主打行锁,粒度小,并发高。

第二,行级锁。 行锁分两种基础锁,配合 RR 隔离还有三种细分。
共享锁 S 锁,也叫读锁。多个事务可以同时加 S 锁读同一行,彼此兼容;但只要某一行上有 S 锁,其他事务就无法对同一行加 X 锁去修改。适用场景:读完数据要依据结果做判断,必须保证读的过程中数据不会变。加锁方式:SELECT … LOCK IN SHARE MODE,MySQL 8.0 也可以用 FOR SHARE。
排他锁 X 锁,也叫写锁。增删改自动加 X 锁,也能用 FOR UPDATE 手动加。一旦某行被 X 锁锁住,其他事务不能修改,也不能加锁读;但普通 SELECT 走 MVCC 快照读,不加锁也能读到数据。适合转账、库存扣减这类必须独占修改的场景。
补充一句:RR 隔离下,行锁细分为记录锁、间隙锁、临键锁。记录锁锁单行;间隙锁锁住索引空隙,防止插入新数据;临键锁是前两者的组合,RR 范围查询默认用它,从根源避免幻读。RC 下只有记录锁,没有间隙锁,所以幻读没法靠锁来解决。

第三,意向锁。 意向锁是表级锁,分 IS 和 IX,不能手动加,全程自动维护。事务要给行加 S 锁,必先给表加 IS;要给行加 X 锁,必先给表加 IX。核心目的只有一个:优化性能。没有意向锁的话,执行 ALTER 这类要加表锁的操作时,数据库得逐行遍历全表检查有没有行锁,效率极低。有意向锁只需要瞄一眼表上有没有 IS/IX,立刻就能判断能不能加表锁。
这里有个关键误区:意向锁不会阻塞普通行操作。IS 和 IX、IX 和 IX 全都互相兼容,多个事务改不同行互不影响;意向锁只拦后续的表锁请求。
最后记住这个分工:行锁管数据,意向锁管效率。 行锁保护真实读写,意向锁是表上的预告牌,让表锁判断少走弯路。二者配合,InnoDB 才能在保证一致性的同时支撑高并发。

http://www.jsqmd.com/news/1284267/

相关文章:

  • LTE Cat 1bis与PIC18微控制器在美洲物联网中的应用
  • 3D打印与激光切割融合制造:从设计到实战的混合制造指南
  • (2026最新)自贡本地人必选的靠谱漏水检测维修推荐:正规防水补漏防水-卫生间/厨房/屋顶/阳台/外墙渗漏水精准测漏,本地人的信赖之选 - 安佳防水
  • (2026最新)芜湖本地漏水检测维修公司靠谱推荐:正规防水补漏上门维修-墙面/屋顶/外墙/暗管漏水检测精准定位 - 即刻修防水
  • Python基础语法入门:从环境配置到核心要素
  • LeetCode 207. 课程表
  • 常熟打井找哪家?2026年最新攻略:苏州市瑞溪泉水利工程有限公司凭实力说话 - 瑞溪泉水利
  • Zotero插件市场:一站式插件管理与安装体验的终极指南
  • 凡科杰建云的小程序、商城、门店和建站数据互通吗?
  • 基于行空板与RC车打造可编程智能小车:从硬件连接到Web遥控
  • AIGC检测技术:守护学术原创性的AI解决方案
  • 2026年多功能万年历应用推荐:黄历道历佛历、亲友提醒和个人历怎么选?附天乙日历App完整测评
  • 2026年苏州专业处理个人欠款纠纷律师大盘点 - 品牌排行榜
  • 消费级外骨骼三条技术路线:适老、户外与轻量化如何选择?
  • K8s资源调度与HPA自动扩缩容!AI流量波峰波谷自动适配,实现Agent服务智能弹性伸缩、降本增效
  • 行空板M10集成百度与讯飞双语音引擎:嵌入式AI语音交互实践
  • 2026年,西宁地区如何选择可靠的竹床漏粪板合作品牌? - 装修教育财税推荐2026
  • Unity字体优化:基于TextMeshPro的自动化字符集扫描与精简方案
  • 生物3D打印核心技术解析:从生物墨水、打印技术到产业化挑战
  • MetaERP 与 Oracle EBS 在 COA(会计科目段)上是同源同构、哲学一致、逻辑相同,只是 MetaERP 把 EBS 的 “弹性域 + 多账簿” 做了云原生与元数据化升级,叫法更现代、
  • 建站平台怎么判断后期维护成本?
  • 2026 年 7 月新发布:英吉沙优秀的玻璃钢化工管道供应厂家哪个好,化工厂里藏着的这款耐腐“黑马”,居然能省出百万运维成本? - 行业推荐官【官方】
  • 龙岩出发西藏年度口碑榜:两款纯玩产品怎么选?这份避坑指南让你少花冤枉钱| 附:旅行社电话 - 西藏康泰旅行社
  • 如何5分钟快速部署Sunshine游戏串流服务器:打造家庭云游戏终极解决方案
  • 167、NPU的编译器开发:条件执行与分支处理
  • 尤克里里魔改指南:从玩具到乐器的全面升级与声学优化
  • 2026年苏州最擅长处理欠款纠纷的律师推荐 - 品牌排行榜
  • C++模板编程:从基础语法到实战应用,掌握泛型编程核心技能
  • 2026合肥零基础成人学历提升正规机构汇总 - 品牌排行榜
  • Flutter+OpenHarmony实现高性能分布式步骤条