IT俱乐部 MySql 一文搞懂MySQL 数据库意向锁

一文搞懂MySQL 数据库意向锁

在本篇开始阅读前,建议看下《MySQL数据库 意向锁(初篇)》章节,对意向所有个大概了解。

一、用“分层锁”的图示理解意向锁(核心)

InnoDB 使用的是 多粒度锁(Multi-Granularity Locking)

数据库
 └── 表(意向锁 IS / IX)
      └── 行(S / X)

规则一句话版

想锁行,必须先在表上“打个招呼”

示例:更新一行数据

START TRANSACTION;
UPDATE orders SET status = 'paid' WHERE id = 10;

锁的实际过程是:

1️⃣ 给 orders 表加 IX(意向排他锁)
2️⃣ 给 id = 10 这一行加 X(排他锁)

👉 意向锁 = “我打算动你表里的某些行”

二、为什么没有意向锁会很惨?

假设:没有意向锁

  • orders1000 万行
  • 事务 A:更新其中 1 行
  • 事务 B:想加表锁
LOCK TABLE orders WRITE;

😱 MySQL 只能:

  • 扫描 1000 万行
  • 看看有没有行锁

为此,就会引发:👉 性能灾难

有了意向锁之后

操作 检查内容
行锁 不管表锁
表锁 只看 IS / IX

🚀 O(1) 判断是否冲突

三、意向锁 vs 表锁 vs 行锁(对比表)

锁类型 级别 是否阻塞行锁 是否阻塞表锁
IS 阻塞表 X
IX 阻塞表 S / X
S 行级互斥
X 行级互斥
S(表) 阻塞 IX 阻塞 X
X(表) 全阻塞 全阻塞

📌 重点

意向锁几乎只和“表锁”打架,不和“行锁”打架

四、为什么 MyISAM 不需要意向锁?

MyISAM 的锁模型

  • ❌ 不支持行锁
  • ✅ 只有表锁
要么整张表读
要么整张表写

👉 不存在:

  • 行锁
  • 表锁与行锁并存
  • 自然 不需要意向锁

InnoDB 的优势(但更复杂)

存储引擎 并发 锁模型
MyISAM 表锁
InnoDB 行锁 + 意向锁

五、一个非常经典的死锁场景(面试常考)

场景描述

user

id name
1 A
2 B

事务 A

START TRANSACTION;
SELECT * FROM user WHERE id = 1 FOR UPDATE;

锁状态:

user 表:IX
id=1 行:X

事务 B

START TRANSACTION;
LOCK TABLE user WRITE;

B 想要:

user 表:X

❌ 但被 A 的 IX 阻塞

接着事务 A 再做:

SELECT * FROM user WHERE id = 2 FOR UPDATE;

此时:

  • A 等待表锁释放
  • B 等待 IX 消失

💥 死锁形成

👉 InnoDB 会:

  • 自动检测
  • 回滚其中一个事务

六、如何在生产中“看到”意向锁?

1️⃣ 查看当前锁(MySQL 8.0)

SELECT * FROM performance_schema.data_locks;

你会看到类似:

OBJECT_NAME = orders
LOCK_TYPE = TABLE
LOCK_MODE = IX

2️⃣ 常见 LOCK_MODE 含义

LOCK_MODE 含义
IS 意向共享
IX 意向排他
S 共享
X 排他

七、一句话总结

意向锁是 InnoDB 自动维护的表级锁,用来声明事务将对表中的某些行加行锁,从而在加表锁时避免扫描所有行锁,是多粒度锁机制的关键。

到此这篇关于一文搞懂MySQL 数据库意向锁的文章就介绍到这了,更多相关mysql 数据库意向锁内容请搜索IT俱乐部以前的文章或继续浏览下面的相关文章希望大家以后多多支持IT俱乐部!

本文收集自网络,不代表IT俱乐部立场,转载请注明出处。https://www.2it.club/database/mysql/17288.html
上一篇
下一篇
联系我们

联系我们

在线咨询: QQ交谈

邮箱: 1120393934@qq.com

工作时间:周一至周五,9:00-17:30,节假日休息

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部