讲师中心 微信公众号
AI工具推荐 视频效率加速

MySQL INSERT ON DUPLICATE KEY UPDATE为何死锁

胖明大大_4071

胖明大大_4071

发布时间:2026-08-19 11:54:27

|

436人浏览过

|

来源于php中文网

原创

根本原因不是并发高,而是多个事务在唯一索引上以不可预测顺序加间隙锁(GAP lock)+ 插入意向锁,形成循环等待;空表下因间隙范围大、锁冲突概率更高,且多唯一键导致InnoDB索引检查顺序不确定,进一步加剧死锁风险。

mysql insert on duplicate key update为何死锁

根本原因不是并发高,而是多个事务在唯一索引上以不可预测顺序加间隙锁(GAP lock)+ 插入意向锁(insert intention lock),形成循环等待。

为什么空表下 INSERT … ON DUPLICATE KEY UPDATE 也会死锁

很多人以为“表里没数据就不会锁”,实际恰恰相反:空表或数据稀疏时,INSERT … ON DUPLICATE KEY UPDATE 更容易触发 GAP 锁冲突。

  • 当 user_id = 1001 不存在时,InnoDB 会在唯一索引 uk_user_id 上加 GAP 锁,范围是 (-, 1001);插入 user_id = 1003 则加 (1001, 1003);再插入 user_id = 1002 就必须申请 (1001, 1003) 的 GAP 锁 —— 此时若前两个事务还没提交,就会阻塞
  • 三个事务交叉申请同一区间 GAP 锁,又各自持有插入意向锁(该锁与 GAP 锁兼容但与其它插入意向锁互斥),最终形成 A→B→C→A 的等待环
  • 这种行为在 RR 隔离级别下确定发生,与是否开启 autocommit 无关;SHOW ENGINE INNODB STATUS 中会明确看到 lock_mode X locks gap before rec insert intention waiting

UNIQUE 索引数量直接影响死锁概率

官方文档已明确标注:INSERT … ON DUPLICATE KEY UPDATE 在多唯一键表中属于 “unsafe” 操作 —— 不是因为语法错,而是 InnoDB 检查索引的顺序不确定。

MySQL
MySQL

编写正确的MySQL查询,避免字符集、索引和锁方面的常见陷阱。

下载
  • 假设有主键 id 和唯一键 uk_user_id,InnoDB 可能先检查主键,也可能先检查 uk_user_id,取决于建表时索引添加顺序
  • 事务 A 按主键顺序判断冲突,事务 B 按唯一键顺序判断,二者加锁路径不同,即使操作同一行,也可能先锁 A 再锁 B vs 先锁 B 再锁 A
  • 更危险的是:主从复制场景下,若主库和从库索引创建顺序不一致,同一语句在两边加锁顺序不同,不仅死锁,还可能造成数据不一致

ON DUPLICATE KEY UPDATE 的真实加锁流程

它不是“原子动作”,而是分阶段加锁:先 S 锁读取,再 X 锁更新 —— 中间存在窗口期。

  • 步骤 1:尝试插入,发现唯一键冲突 → 对冲突行加 S 锁(共享锁),防止被删除
  • 步骤 2:MySQL 层拿到该行后执行 UPDATE → 尝试升级为 X 锁(排他锁)
  • 步骤 3:若此时另一事务也正卡在步骤 1,并已对同一行加了 S 锁,则双方都等对方释放 S 锁来升级 X 锁 → 死锁
  • 注意:这个 S 锁不是“只读锁”,它会阻塞其他事务对该行的 X 锁请求,但允许其他事务加 S 锁 —— 这正是多事务并发时锁升级失败的根源

最容易被忽略的陷阱:隐式锁升级 + 范围锁放大

你以为只锁一行?其实很可能锁住一个区间,且锁类型随条件动态变化。

  • 如果 WHERE 条件走的是二级唯一索引(比如 uk_user_id),InnoDB 会加 NEXT-KEY LOCK(= GAP LOCK + RECORD LOCK),范围远大于单行
  • 而如果走主键,只加 RECORD LOCK,锁粒度最小 —— 所以务必确保 ON DUPLICATE KEY UPDATE 的冲突判断基于主键,而非二级唯一索引
  • 批量执行时(如一次插 100 行),每个值都会独立触发上述加锁流程,锁竞争面指数级扩大;拆成单条执行反而更安全
  • 线上已发死锁,临时缓解不是调大 innodb_lock_wait_timeout,而是用 SELECT ... FOR UPDATE 显式提前锁定主键范围 —— 但要注意这会把锁提前暴露,可能引发更广的阻塞

热门AI工具

更多
UP简历
UP简历 Hot

一款AI办公效率工具,主要用于基于AI技术的免费在线简历制作工具,适合需要提升相关任务效率的用户。

SkildArt
SkildArt Hot

SkildArt是一款AI文本写作工具,一站式 AI 视觉创作平台。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

Laper
Laper Hot

Laper是专为编剧、导演和制片人推出的 AI 原生剧本创作工具。

PixPix
PixPix Hot

PixPix是一款面向电商视觉生产的AI商品图生成工具。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

PixTV
PixTV Hot

PixTV是一款面向AIGC内容创作的AI视频生成工具。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

立刻MV
立刻MV Hot

立刻MV是一款AI文本写作工具,AI 音乐视频(MV)创作工具。

相关专题

更多
mysql修改数据表名
mysql修改数据表名

MySQL修改数据表:1、首先查看数据库中所有的表,代码为:‘SHOW TABLES;’;2、修改表名,代码为:‘ALTER TABLE 旧表名 RENAME [TO] 新表名;’。php中文网还提供MySQL的相关下载、相关课程等内容,供大家免费下载使用。

2253

2023.06.20

MySQL创建存储过程
MySQL创建存储过程

存储程序可以分为存储过程和函数,MySQL中创建存储过程和函数使用的语句分别为CREATE PROCEDURE和CREATE FUNCTION。使用CALL语句调用存储过程智能用输出变量返回值。函数可以从语句外调用(通过引用函数名),也能返回标量值。存储过程也可以调用其他存储过程。php中文网还提供MySQL创建存储过程的相关下载、相关课程等内容,供大家免费下载使用。

1379

2023.06.21

mongodb和mysql的区别
mongodb和mysql的区别

mongodb和mysql的区别:1、数据模型;2、查询语言;3、扩展性和性能;4、可靠性。本专题为大家提供mongodb和mysql的区别的相关的文章、下载、课程内容,供大家免费下载体验。

795

2023.07.18

mysql密码忘了怎么查看
mysql密码忘了怎么查看

MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,属于 Oracle 旗下产品。MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最好的 RDBMS 应用软件之一。那么mysql密码忘了怎么办呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

3092

2023.07.19

mysql创建数据库
mysql创建数据库

MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,属于 Oracle 旗下产品。MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最好的 RDBMS 应用软件之一。那么mysql怎么创建数据库呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

5228

2023.07.25

mysql默认事务隔离级别
mysql默认事务隔离级别

MySQL是一种广泛使用的关系型数据库管理系统,它支持事务处理。事务是一组数据库操作,它们作为一个逻辑单元被一起执行。为了保证事务的一致性和隔离性,MySQL提供了不同的事务隔离级别。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

1159

2023.08.08

sqlserver和mysql区别
sqlserver和mysql区别

SQL Server和MySQL是两种广泛使用的关系型数据库管理系统。它们具有相似的功能和用途,但在某些方面存在一些显著的区别。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

5491

2023.08.11

mysql忘记密码
mysql忘记密码

MySQL是一种关系型数据库管理系统,关系数据库将数据保存在不同的表中,而不是将所有数据放在一个大仓库内,这样就增加了速度并提高了灵活性。那么忘记mysql密码我们该怎么解决呢?php中文网给大家带来了相关的教程以及其他关于mysql的文章,欢迎大家前来学习阅读。

4822

2023.08.14

OpenJDK JVM参数怎么调优
OpenJDK JVM参数怎么调优

Java应用运行缓慢,如何调整JVM参数?本专题介绍OpenJDK JVM性能调优的基本流程,涵盖性能指标确认、运行数据采集、内存配置和垃圾回收分析,帮助你先定位瓶颈,再通过对照测试验证效果,避免直接套用参数而影响应用稳定性。

0

2026.10.16

热门下载

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

精品课程

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

共1课时 | 187人学习

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

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn