千家信息网

如何理解MySQL行锁、表锁、间隙锁

发表于:2026-11-02 作者:千家信息网编辑
千家信息网最后更新 2026年11月02日,本篇内容介绍了"如何理解MySQL行锁、表锁、间隙锁"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!准
千家信息网最后更新 2026年11月02日如何理解MySQL行锁、表锁、间隙锁

本篇内容介绍了"如何理解MySQL行锁、表锁、间隙锁"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

准备工作

创建表 tb_innodb_lock

drop table if exists test_innodb_lock;  CREATE TABLE test_innodb_lock (      a INT (11),      b VARCHAR (20)  ) ENGINE INNODB DEFAULT charset = utf8;  insert into test_innodb_lock values (1,'a');  insert into test_innodb_lock values (2,'b');  insert into test_innodb_lock values (3,'c');  insert into test_innodb_lock values (4,'d');  insert into test_innodb_lock values (5,'e');

创建索引

create index idx_lock_a on test_innodb_lock(a);  create index idx_lock_b on test_innodb_lock(b);

MySQL 各种锁演示

  • 先将自动提交事务改成手动提交:set autocommit=0;

  • 我们启动两个会话窗口 A 和 B,模拟一个抢到锁,一个没抢到被阻塞住了。

行锁(写&读)

  • A 窗口执行

update test_innodb_lock set b='a1' where a=1;
SELECT * from test_innodb_lock;

我们可以看到 A 窗口可以看到更新后的结果

  • B 窗口执行

SELECT * from test_innodb_lock;

我们可以看到 B 窗口不能看到更新后的结果,看到的还是老数据,这是因为 a = 1 的这行记录被 A 窗口执行的 SQL 语句抢到了锁,并且没有执行 commit 提交操作。所以窗口 B 看到的还是老数据。这就是 MySQL 隔离级别中的"读已提交"。

  • 窗口 A 执行 commit 操作

COMMIT;
  • 窗口 B 查询

SELECT * from test_innodb_lock;

这个时候我们发现窗口 B 已经读取到最新数据了

行锁(写&写)

  • 窗口 A 执行更新 a = 1 的记录

update test_innodb_lock set b='a2' where a=1;

这时候并没有 commit 提交,锁是窗口 A 持有。

  • 窗口 B 也执行更新 a = 1 的记录

update test_innodb_lock set b='a3' where a=1;

可以看到,窗口 B 一直处于阻塞状态,因为窗口 A 还没有执行 commit,还持有锁。窗口 B 抢不到 a = 1 这行记录的锁,所以一直阻塞等待。

  • 窗口 A 执行 commit 操作

COMMIT;

窗口 B 的变化

可以看到这个时候窗口 B 已经执行成功了

表锁

当索引失效的时候,行锁会升级成表锁,索引失效的其中一个方法是对索引自动 or 手动的换型。a 字段本身是 integer,我们加上引号,就变成了 String,这个时候索引就会失效了。

  • 窗口 A 更新 a = 1 的记录

update test_innodb_lock set b='a4' where a=1 or a=2;
  • 窗口 B 更新 a = 2 的记录

update test_innodb_lock set b='b1' where a=3;

这个时候发现,虽然窗口 A 和 B 更新的行不一样,但是窗口 B 还是被阻塞住了,就是因为窗口 A 的索引失效,导致行锁升级成了表锁,把整个表锁住了,索引窗口 B 被阻塞了。

  • 窗口 A 执行 commit 操作

COMMIT;
  • 窗口 B 的变化

可以看到这个时候窗口 B 已经执行成功了

间隙锁

  • 什么是间隙锁

当我们采用范围条件查询数据时,InnoDB 会对这个范围内的数据进行加锁。比如有 id 为:1、3、5、7 的 4 条数据,我们查找 1-7 范围的数据。那么 1-7 都会被加上锁。2、4、6 也在 1-7 的范围中,但是不存在这些数据记录,这些 2、4、6 就被称为间隙。

  • 间隙锁的危害

范围查找时,会把整个范围的数据全部锁定住,即便这个范围内不存在的一些数据,也会被无辜的锁定住,比如我要在 1、3、5、7 中插入 2,这个时候 1-7 都被锁定住了,根本无法插入 2。在某些场景下会对性能产生很大的影响

  • 间隙锁演示

我们先把字段 a 的值修改成 1、3、5、7、9

  • 窗口 A 更新 a = 1~7 范围的数据

update test_innodb_lock set b='b5' where a>1 and a<7;
  • 窗口 B 在 a = 2 的位置插入数据

insert into test_innodb_lock values(2, "b6");

这个时候发现窗口 B 更新 a = 2 的操作一直在等待,因为 1~7 范围的数据被间隙锁,锁住了。只有等窗口 A 执行 commit,窗口 B 的 a = 2 才能更新成功

行锁分析

  • 执行 SQL 分析命令

show status like 'innodb_row_lock%';

  • Variable_name 说明

    • Innodb_row_lock_current_waits:当前正在等待锁定的数量。

    • Innodb_row_lock_time:从系统启动到现在锁定的时长。

    • Innodb_row_lock_time_avg:每次等待锁所花平均时间。

    • Innodb_row_lock_time_max:从系统启动到现在锁等待最长的一次所花的时间。

    • Innodb_row_lock_waits:系统启动后到现在总共等待锁的次数。

"如何理解MySQL行锁、表锁、间隙锁"的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注网站,小编将为大家输出更多高质量的实用文章!

数据 更新 范围 间隙 时候 索引 阻塞 系统 还是 成功 内容 字段 就是 手动 时间 更多 知识 结果 分析 升级 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 喔噻互联网科技有限公司 深圳恒合互联网络科技有限公司 美国互联网科技巨头监管 互联网科技资迅 关于新基建和互联网科技 丰台科技园 互联网 互联网科技小额贷款 互联网科技有哪些公司 宁夏科技产业互联网案例 崇明区互联网教育科技售后服务 广西互联网科技孵化中心 科技互联网海报 美国互联网科技实力 互联网公司高科技产品 上海互联网科技公司ppt 福建互联网展示科技馆设计 北京天晋互联网科技有限公司 美国五大互联网科技公司市值多少 山东蛋芒互联网科技有限公司 上海旺乐尼互联网科技有限公司 上海睿民互联网科技有限公司 狮子座互联网科技 互联网科技的英文 狮子座互联网科技培训 科技伦理 互联网公司 联恩商钥互联网科技有限公司 佛山市拉法互联网科技有限公司 2021世界互联网领先科技成果发布 萌小萌互联网科技河南有限公司 中国主要互联网科技公司
0