0

0

mysql中存储引擎的行级锁与表级锁的区别

P粉602998670

P粉602998670

发布时间:2026-01-21 10:39:09

|

789人浏览过

|

来源于php中文网

原创

行级锁仅在走索引时生效,否则退化为表锁;InnoDB基于索引记录加锁,未命中索引则全表扫描并加意向锁,等效表锁;MyISAM始终表锁,DDL操作也需表锁;锁策略选择取决于引擎与SQL是否走索引。

mysql中存储引擎的行级锁与表级锁的区别

行级锁只锁索引行,没走索引就退化成表锁

InnoDB 的行级锁不是“按数据行物理位置”锁的,而是基于索引记录(record lock)实现的。这意味着:只有 SQL 明确通过索引(主键、唯一索引、普通索引)定位到某几行时,才会真正加行锁;如果 WHERE 条件没命中任何索引(例如对无索引字段查询、或用 LIKE '%abc' 导致索引失效),InnoDB 会放弃行锁,转而对整张表加意向锁 + 全表扫描锁——效果等同于表级锁。

  • 常见错误现象:UPDATE users SET status=1 WHERE phone='138...' 执行很慢且阻塞其他事务,查发现 phone 字段没建索引
  • 实操建议:执行前用 EXPLAIN 确认是否走了索引;高频更新字段务必建索引,哪怕只是单列
  • 注意:即使是二级索引,InnoDB 也会对索引条目加锁,并可能触发聚簇索引上的隐式锁(如 gap lock),不等于“只锁索引不锁数据”

表锁是粗粒度强制互斥,MyISAM 和 DDL 场景绕不开

表级锁分显式和隐式两种。显式如 LOCK TABLES t1 WRITE,隐式如 ALTER TABLEDROP TABLE 或 MyISAM 引擎下的所有写操作。它不管你在改哪一行,只要锁定了表,其他线程对这张表的读/写(取决于锁类型)就全被挡在外面。

  • 常见错误现象:从库执行 OPTIMIZE TABLE 时,主从同步卡住,SHOW PROCESSLIST 看到大量 Waiting for table metadata lock
  • 实操建议:避免在业务高峰期对大表做 DDL;MyISAM 表严禁用于高并发写场景(比如订单、计数器)
  • 关键细节:MDL(元数据锁)是自动加的,不可手动释放;SELECT 也会持有 MDL 读锁,若长事务未提交,后续 DDL 会被死等

并发表现截然不同:行锁冲突低但怕死锁,表锁简单但一写全堵

行级锁并发度高,是因为两个事务更新不同用户的订单,互不影响;但一旦出现循环等待(比如事务 A 锁了行 100 再去锁行 200,事务 B 反过来先锁 200 再锁 100),就会触发 InnoDB 死锁检测并回滚其中一个。表锁没有死锁风险(只有一把锁),但代价是——哪怕你只更新 1 行,整张表的其他所有读写都得排队。

Jobright
Jobright

专为北美求职者设计的AI求职助手平台

下载
  • 常见错误现象:应用日志频繁出现 Deadlock found when trying to get lock,但业务逻辑看似无交集
  • 实操建议:事务内更新多行时,固定顺序(如按主键 ASC);减少事务长度;监控 Innodb_row_lock_waits 等状态变量
  • 性能影响:行锁内存开销明显更大(每行锁需维护锁结构),当单事务更新上万行时,可能触发锁升级失败或 OOM

选引擎就是选锁策略:InnoDB 行锁是默认,MyISAM 表锁是枷锁

MySQL 5.5+ 默认引擎是 InnoDB,它支持行锁、事务、外键;MyISAM 只支持表锁、不支持事务,适合纯读场景(比如配置表、日志归档表)。如果你看到某个表用了 MyISAM,那它天然不具备高并发写能力,强行加索引也救不了行锁缺失这个根本问题。

  • 实操建议:新建表一律用 ENGINE=InnoDB;存量 MyISAM 表迁移前,确认无长事务、无外键依赖,用 ALTER TABLE t ENGINE=InnoDB
  • 注意兼容性:某些老备份脚本依赖 MyISAM 的 myisamchk,转 InnoDB 后需同步调整
  • 容易被忽略的一点:即使用了 InnoDB,如果隔离级别设为 READ UNCOMMITTEDREAD COMMITTED,间隙锁(gap lock)会关闭,可能导致幻读——这不是锁失效,而是设计取舍
行锁不是银弹,它依赖索引、受限于事务长度、对死锁敏感;表锁也不是古董,DDL 和元数据变更必须靠它兜底。真正要盯住的,从来不是“该用哪种锁”,而是“你的 SQL 走没走索引”“事务里干了什么”“有没有人正在 ALTER 这张表”。

相关专题

更多
数据分析工具有哪些
数据分析工具有哪些

数据分析工具有Excel、SQL、Python、R、Tableau、Power BI、SAS、SPSS和MATLAB等。详细介绍:1、Excel,具有强大的计算和数据处理功能;2、SQL,可以进行数据查询、过滤、排序、聚合等操作;3、Python,拥有丰富的数据分析库;4、R,拥有丰富的统计分析库和图形库;5、Tableau,提供了直观易用的用户界面等等。

683

2023.10.12

SQL中distinct的用法
SQL中distinct的用法

SQL中distinct的语法是“SELECT DISTINCT column1, column2,...,FROM table_name;”。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

323

2023.10.27

SQL中months_between使用方法
SQL中months_between使用方法

在SQL中,MONTHS_BETWEEN 是一个常见的函数,用于计算两个日期之间的月份差。想了解更多SQL的相关内容,可以阅读本专题下面的文章。

348

2024.02.23

SQL出现5120错误解决方法
SQL出现5120错误解决方法

SQL Server错误5120是由于没有足够的权限来访问或操作指定的数据库或文件引起的。想了解更多sql错误的相关内容,可以阅读本专题下面的文章。

1095

2024.03.06

sql procedure语法错误解决方法
sql procedure语法错误解决方法

sql procedure语法错误解决办法:1、仔细检查错误消息;2、检查语法规则;3、检查括号和引号;4、检查变量和参数;5、检查关键字和函数;6、逐步调试;7、参考文档和示例。想了解更多语法错误的相关内容,可以阅读本专题下面的文章。

358

2024.03.06

oracle数据库运行sql方法
oracle数据库运行sql方法

运行sql步骤包括:打开sql plus工具并连接到数据库。在提示符下输入sql语句。按enter键运行该语句。查看结果,错误消息或退出sql plus。想了解更多oracle数据库的相关内容,可以阅读本专题下面的文章。

697

2024.04.07

sql中where的含义
sql中where的含义

sql中where子句用于从表中过滤数据,它基于指定条件选择特定的行。想了解更多where的相关内容,可以阅读本专题下面的文章。

575

2024.04.29

sql中删除表的语句是什么
sql中删除表的语句是什么

sql中用于删除表的语句是drop table。语法为drop table table_name;该语句将永久删除指定表的表和数据。想了解更多sql的相关内容,可以阅读本专题下面的文章。

417

2024.04.29

云朵浏览器入口合集
云朵浏览器入口合集

本专题整合了云朵浏览器入口合集,阅读专题下面的文章了解更多详细地址。

20

2026.01.20

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
MySQL 教程
MySQL 教程

共48课时 | 1.8万人学习

MySQL 初学入门(mosh老师)
MySQL 初学入门(mosh老师)

共3课时 | 0.3万人学习

简单聊聊mysql8与网络通信
简单聊聊mysql8与网络通信

共1课时 | 804人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号