news 2026/1/29 12:02:48

如何避免MySQL死锁?资深DBA的9条黄金法则

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
如何避免MySQL死锁?资深DBA的9条黄金法则

死锁是数据库里很常见的问题:两个或多个事务互相等待对方释放锁,结果谁也动不了。

MySQL的InnoDB引擎会自己自动检测死锁,并且回滚其中一个事务来解决,但这种情况如果经常遇到的话,会很影响性能和用户体验。

其实,只要注意一些设计细节,就能大大减少甚至避免死锁。

下面是几个最实用的方法:


1. 事务要短,动作要快

事务越长,锁住数据的时间就越久,别人就越容易“撞上”你。

正确做法:只在事务里做必要的数据库操作,别把业务逻辑(比如调接口、算数据)塞进去。

sql

-- 不推荐:事务中混杂业务逻辑 START TRANSACTION; SELECT * FROM users WHERE id = 1; -- 假设此处有耗时的业务处理... UPDATE accounts SET balance = balance - 100 WHERE user_id = 1; UPDATE orders SET status = 'paid' WHERE user_id = 1; COMMIT; -- 推荐:事务只包含必要数据库操作 START TRANSACTION; UPDATE accounts SET balance = balance - 100 WHERE user_id = 1; UPDATE orders SET status = 'paid' WHERE user_id = 1; COMMIT;


2. 所有事务按同一个顺序操作表

这是避免死锁最有效的一招!

比如:如果多个事务都要改 users 和 orders 表,那就统一先改 users,再改 orders。不要有的先改 users,有的先改 orders。

sql

-- 所有地方都这样写: UPDATE users SET ... WHERE id = 1; UPDATE orders SET ... WHERE user_id = 1;

只要顺序一致,就不会出现“A等B、B等A”的循环等待。


3. 给表加合适的索引

InnoDB 的行锁是靠索引来实现的。如果查询没用到索引,MySQL 就可能锁住整张表(或很多无关的行),大大增加死锁风险。

建议

  • 经常用来查或更新的字段(比如 user_id)要建索引。
  • 用 EXPLAIN 看看 SQL 是否命中索引。
sql

CREATE INDEX idx_user_id ON orders(user_id);


4. 别用太高的隔离级别(除非必要)

MySQL 默认是 REPEATABLE READ,它会加“间隙锁”,防止幻读,但也更容易死锁。

如果你的业务能接受“读已提交”(比如允许看到别人刚提交的数据),可以改成:

sql

SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;

这样锁的范围更小,死锁概率更低。


5. 显式加锁时要小心

如果你要用 SELECT ... FOR UPDATE 锁行,一定要确保:

  • 条件能命中索引;
  • 锁的行尽量少;
  • 事务尽快结束。
sql

-- 安全:通过主键或索引锁定一行 SELECT * FROM accounts WHERE user_id = 1 FOR UPDATE;

如果 user_id 没索引,这条语句可能锁住成千上万行!


6. 应用层要有重试机制

死锁偶尔还是会发生。这时候,应用应该:

  • 捕获死锁错误(MySQL 错误码 1213 或 SQLSTATE '40001');
  • 自动重试几次(比如最多 2~3 次);
  • 每次重试前等一小会儿(比如 100ms、200ms…)。
java

// 伪代码示例 for (int i = 0; i < 3; i++) { try { doDatabaseUpdate(); break; // 成功就退出 } catch (DeadlockException e) { sleep(100 * (i + 1)); // 等一下再试 } }


7. 大批量更新要分批做

一次更新几万行?这很容易锁住大量数据,引发死锁或卡顿。

正确做法:每次只改 500~1000 行,改完提交,再继续。

sql

-- 分批更新 UPDATE large_table SET status = 'done' WHERE create_time < '2023-01-01' AND status != 'done' LIMIT 1000; -- 循环执行,直到没有数据可更新


8. 避免热点数据被频繁修改

比如一个全局计数器,所有请求都去 UPDATE counter SET value = value + 1,那这一行就成了堵点。

解决办法:用分桶计数。

sql

-- 把计数分散到 10 个桶里 UPDATE counter_buckets SET value = value + 1 WHERE name = 'views' AND bucket = FLOOR(RAND() * 10); -- 查总数时再加起来 SELECT SUM(value) FROM counter_buckets WHERE name = 'views';


9. 出问题了怎么查?

看最近一次死锁详情:

sql

SHOW ENGINE INNODB STATUS;

找LATEST DETECTED DEADLOCK部分。

查当前正在运行的事务(MySQL 8.0+):

sql

SELECT * FROM performance_schema.data_locks; SELECT * FROM information_schema.INNODB_TRX;


总结

1.事务要短:别拖着不提交。 2.顺序要一致:所有人按相同顺序改表。 3.索引要到位:避免锁太多无关数据。 4.出错要重试:应用层兜底处理死锁。 5.大批量要分批:别一次锁太多行。

死锁没法完全杜绝,但只要做好这些,基本就不会再被它困扰了!

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/1/28 12:04:35

arcpy导出excel表

我们有些时候需要导出excel表进行分析&#xff0c;因而需要熟练掌握导出excel表的技巧。 import arcpy import pandas as pd import os# 输入 shp 文件路径 shp_path r"D:\03A-Archives\博二上\全国土地退化论文\data\boundary\2017省市县行政区划\全国_10k_poly_dr.shp&…

作者头像 李华
网站建设 2026/1/27 15:49:13

视频硬字幕AI去除终极方案:本地化无损修复技术详解

视频硬字幕AI去除终极方案&#xff1a;本地化无损修复技术详解 【免费下载链接】video-subtitle-remover 基于AI的图片/视频硬字幕去除、文本水印去除&#xff0c;无损分辨率生成去字幕、去水印后的图片/视频文件。无需申请第三方API&#xff0c;本地实现。AI-based tool for r…

作者头像 李华
网站建设 2026/1/25 22:45:57

BetterNCM插件完整教程:从零开始打造你的专属音乐工作站

BetterNCM插件完整教程&#xff1a;从零开始打造你的专属音乐工作站 【免费下载链接】BetterNCM-Installer 一键安装 Better 系软件 项目地址: https://gitcode.com/gh_mirrors/be/BetterNCM-Installer 还在为网易云音乐功能单一、界面单调而困扰吗&#xff1f;想要把普…

作者头像 李华
网站建设 2026/1/28 22:55:27

大模型注意力机制全解析:从MHA到MoBA,一文掌握七种核心算法

文章详细解析了大模型中七种注意力机制&#xff08;MHA、MQA、GQA、MLA、NSA、SSA、MoBA&#xff09;的原理、优缺点及应用场景。从密集计算到稀疏化&#xff0c;从静态模式到动态路由&#xff0c;展示了注意力机制在效率与表达能力间的演进历程。文章对比了各机制在工程实现与…

作者头像 李华
网站建设 2026/1/22 4:55:24

LobeChat能否实现AI调酒师?饮品配方创意与口味偏好匹配

LobeChat能否实现AI调酒师&#xff1f;饮品配方创意与口味偏好匹配 在一家未来感十足的酒吧里&#xff0c;顾客刚坐下&#xff0c;轻声对吧台说&#xff1a;“来杯清爽点的&#xff0c;带点柑橘味&#xff0c;不要太烈。” 没有翻菜单&#xff0c;也没有和调酒师寒暄——回应他…

作者头像 李华
网站建设 2026/1/28 10:28:55

如何快速绕过iOS激活锁:AppleRa1n完整解决方案指南

如何快速绕过iOS激活锁&#xff1a;AppleRa1n完整解决方案指南 【免费下载链接】applera1n icloud bypass for ios 15-16 项目地址: https://gitcode.com/gh_mirrors/ap/applera1n 当你面对iOS设备激活锁问题&#xff0c;无论是忘记Apple ID密码还是二手设备无法激活&am…

作者头像 李华