记录一次现网MySQL死锁问题排查和优化

1、问题背景

    双十一搞活动,企微群出现告警。

2、突现告警

3、查看应用日志

没有图片,忘了截图了,现在日志已经清空了,不过不重要,大概就是一个DeadLock的堆栈信息

4、查看数据库锁日志

查询mysql日志命令:

show engine innodb status

万幸,日志还能查到,日志大概内容:

=====================================
2025-11-07 11:18:36 140364350953216 INNODB MONITOR OUTPUT
=====================================
Per second averages calculated from the last 17 seconds
-----------------
BACKGROUND THREAD
-----------------
srv_master_thread loops: 21775837 srv_active, 0 srv_shutdown, 234487 srv_idle
srv_master_thread log flush and writes: 0
----------
SEMAPHORES
----------
OS WAIT ARRAY INFO: reservation count 116464029
OS WAIT ARRAY INFO: signal count 124496867
RW-shared spins 0, rounds 0, OS waits 0
RW-excl spins 0, rounds 0, OS waits 0
RW-sx spins 0, rounds 0, OS waits 0
Spin rounds per wait: 0.00 RW-shared, 0.00 RW-excl, 0.00 RW-sx
------------------------
LATEST DETECTED DEADLOCK
------------------------
2025-11-07 11:04:51 140363383674624
*** (1) TRANSACTION:
TRANSACTION 4655205627, ACTIVE 0 sec inserting
mysql tables in use 1, locked 1
LOCK WAIT 2 lock struct(s), heap size 1136, 1 row lock(s), undo log entries 1
MySQL thread id 98213395, OS thread handle 140364343031552, query id 28073836980 172.16.3.216 xxxx update
INSERT INTO xxxx( xxxx )  VALUES  ( 1986630903639687169, 'E690', 1929803586759090177, 1971490634585956387, 1, 3, 2, 0.3903, 0.3, 0.00, '2025-11-06', 'OF', '2025-11-07 11:04:51.902', '2025-11-07 11:04:51.902' ),( 1986630903341891585, 'E690', 1929803565829513218, 1971459225951498245, 6, 1, 2, -0.2582, -0.2582, -10.00, '2025-11-06', 'ALL', '2025-11-07 11:04:51.832', '2025-11-07 11:04:51.832' )

*** (1) HOLDS THE LOCK(S):
RECORD LOCKS space id 15025 page no 883 n bits 560 index uk_date_store_target of table `xxxx`.`xxxxx` trx id 4655205627 lock mode S waiting
Record lock, heap no 489 PHYSICAL RECORD: n_fields 4; compact format; info bits 0
 0: len 3; hex 8fd366; asc   f;;
 1: len 4; hex 45363930; asc E690;;
 2: len 8; hex 1ac80a233b0ce001; asc    #;   ;;
 3: len 8; hex 1b91ee47ff01b001; asc    G    ;;


*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 15025 page no 883 n bits 560 index uk_date_store_target of table `xxxx`.`xxxx` trx id 4655205627 lock mode S waiting
Record lock, heap no 489 PHYSICAL RECORD: n_fields 4; compact format; info bits 0
 0: len 3; hex 8fd366; asc   f;;
 1: len 4; hex 45363930; asc E690;;
 2: len 8; hex 1ac80a233b0ce001; asc    #;   ;;
 3: len 8; hex 1b91ee47ff01b001; asc    G    ;;


*** (2) TRANSACTION:
TRANSACTION 4655205626, ACTIVE 0 sec inserting
mysql tables in use 1, locked 1
LOCK WAIT 3 lock struct(s), heap size 1136, 2 row lock(s), undo log entries 2
MySQL thread id 98205049, OS thread handle 140364356245248, query id 28073836979 172.16.3.60 xxxx update
INSERT INTO xxxx  ( xxxx )  VALUES  ( 1986630903635488769, 'E690', 1929803586759090177, 1971490634585956387, 1, 3, 2, 0.3903, 0.3, 0.00, '2025-11-06', 'OF', '2025-11-07 11:04:51.902', '2025-11-07 11:04:51.902' ),( 1986630903350276097, 'E690', 1929803565829513218, 1971459225951498245, 6, 1, 2, -0.2582, -0.2582, -10.00, '2025-11-06', 'ALL', '2025-11-07 11:04:51.833', '2025-11-07 11:04:51.833' )

*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 15025 page no 883 n bits 560 index uk_date_store_target of table `xxxx`.`xxxxxx` trx id 4655205626 lock_mode X locks rec but not gap
Record lock, heap no 489 PHYSICAL RECORD: n_fields 4; compact format; info bits 0
 0: len 3; hex 8fd366; asc   f;;
 1: len 4; hex 45363930; asc E690;;
 2: len 8; hex 1ac80a233b0ce001; asc    #;   ;;
 3: len 8; hex 1b91ee47ff01b001; asc    G    ;;


*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 15025 page no 883 n bits 560 index uk_date_store_target of table `xxxx`.`xxxx` trx id 4655205626 lock_mode X locks gap before rec insert intention waiting
Record lock, heap no 489 PHYSICAL RECORD: n_fields 4; compact format; info bits 0
 0: len 3; hex 8fd366; asc   f;;
 1: len 4; hex 45363930; asc E690;;
 2: len 8; hex 1ac80a233b0ce001; asc    #;   ;;
 3: len 8; hex 1b91ee47ff01b001; asc    G    ;;

*** WE ROLL BACK TRANSACTION (1)

5、分析锁日志

5.1 死锁发生时间

时间:2025-11-07 11:04:51
线程 ID:
  Transaction 1: 98213395
  Transaction 2: 98205049

5.2 涉及表和索引


表名:xxxx.xxxxxx
索引名:uk_date_store_target

5.3 事务详情

Transaction (1):插入操作

INSERT INTO xxxxx  
(xxxxxx) 
VALUES  
(1986630903639687169, 'E690', 1929803586759090177, 1971490634585956387, 1, 3, 2, 0.3903, 0.3, 0.00, '2025-11-06', 'OF', '2025-11-07 11:04:51.902', '2025-11-07 11:04:51.902'),
(1986630903341891585, 'E690', 1929803565829513218, 1971459225951498245, 6, 1, 2, -0.2582, -0.2582, -10.00, '2025-11-06', 'ALL', '2025-11-07 11:04:51.832', '2025-11-07 11:04:51.832')

锁等待情况:
当前持有共享锁(S)正在等待同一记录上的共享锁。
请求获取记录锁的位置为 page no 883 上的 heap no 489。

Transaction (2):插入操作

INSERT INTO xxxx  
(xxxxxx) 
VALUES  
(1986630903635488769, 'E690', 1929803586759090177, 1971490634585956387, 1, 3, 2, 0.3903, 0.3, 0.00, '2025-11-06', 'OF', '2025-11-07 11:04:51.902', '2025-11-07 11:04:51.902'),
(1986630903350276097, 'E690', 1929803565829513218, 1971459225951498245, 6, 1, 2, -0.2582, -0.2582, -10.00, '2025-11-06', 'ALL', '2025-11-07 11:04:51.833', '2025-11-07 11:04:51.833')

锁等待情况:
已经持有一个排他锁(X),并试图插入意向锁等待。
请求获取记录锁位置同样是 page no 883 上的 heap no 489。

6、deadlock原因分析

    两个事务都尝试向相同的数据页(page no 883)中的同一条记录(heap no 489)上加锁,并且它们的操作涉及的是相同的唯一约束索引 uk_date_store_target 的键值组合。这导致了典型的并发冲突:
    Transaction (1) 尝试获得一个共享锁(S),但由于另一个事务已经拥有排他锁(X),因此被阻塞。
同时 Transaction (2) 要求插入意向锁以完成其插入动作,但因为前者已请求共享锁而尚未释放,所以它也被挂起。
最终 InnoDB 引擎检测到了循环依赖关系并回滚了其中一个事务(Transaction 1)来解决死锁问题。

7、死锁流程

7.1. 索引冲突


两个事务都操作了同一个表
都使用了相同的唯一索引
插入的数据在索引上有重叠,指向相同的记录位置(heap no 489)

7.2 具体死锁条件


Transaction 1:
持有: 共享锁(S lock) - 等待状态
等待: 对同一记录的共享锁
Transaction 2:
持有: 排他锁(X lock)
等待: 插入意向锁(insert intention lock)

7.3 死锁根本原因


这是典型的插入意向锁死锁场景:
两个事务试图插入具有相同索引键值的记录
MySQL为了保证唯一性约束,在插入前需要检查是否存在重复记录
这种检查需要获取共享锁,而实际插入需要排他锁
当多个事务同时操作相同索引键时,就可能发生循环等待

mermaid:

sequenceDiagram
    participant T1 as Transaction 1
    participant T2 as Transaction 2
    participant R as Record(Heap 489)
    
    T1->>R: 请求共享锁(S lock)
    R-->>T1: 发现已有排他锁,等待
    
    T2->>R: 持有排他锁(X lock)
    T2->>R: 尝试插入意向锁(insert intention)
    R-->>T2: 发现T1在等待S锁,插入被阻塞
    
    Note over T1,T2: 形成循环等待,死锁产生

7.4 事务1为什么持有S锁了还需要申请S锁

7.4.1 锁状态

事务1实际锁状态
事务1 (ID: 4655205627) 并没有持有S锁
从死锁日志信息看,事务1在两条记录上都处于 等待状态 (waiting)
RECORD LOCKS space id 15025 page no 883 n bits 560 index uk_date_store_target ... lock mode S waiting

锁等待情况
等待获取S锁:事务1尝试在记录上获取S锁但被阻塞
未成功持有:死锁信息显示的是事务1正在等待的状态,而不是已持有的锁

死锁形成原因
事务2 先持有了该记录的 X锁 (lock_mode X locks rec but not gap)
事务1 尝试获取 S锁 时被事务2的X锁阻塞
同时事务2又等待获取插入意向锁,形成了循环等待

7.4.2 为什么没有持有锁也会死锁

AI告诉我的:

 死锁不只涉及已持有锁的事务
参与等待的事务也可能成为死锁的一部分
即使事务1没有持有锁,它的等待行为影响了整体锁的获取顺序
MySQL死锁检测器识别到等待图中存在环路,触发死锁处理机制

 但是我也不理解这里

8、解决办法

8.1 网上方法

业务层面: 确保并发插入的数据在 uk_date_store_target 索引上不重叠
技术层面: 减少事务大小,或者使用 INSERT IGNORE / ON DUPLICATE KEY UPDATE 来避免锁竞争

8.2 我们的方法

    我们主要还是根据我们业务场景来解决,我们这个业务场景是用户来查询一个门店的数据,是调用第三方接口去查询的,如果查到了就放在本地,以上出现死锁的数据就是同一个用户极短时间内请求了两次,导致重复insert数据,我们将放在本地这个操作使用 异步 + 分布式锁实现了。

内容概要:本文探讨了SLAM(实时定位与地图构建)技术在芯片行业后道封装测试环节的应用,聚焦于晶圆缺陷检测机器人导航系统。文章介绍了视觉SLAM的核心概念与关键技术,包括特征点法(如ORB-SLAM)、关键帧、词袋模型本质矩阵,并详细分析了基于OpenCV实的ORB特征提取与匹配、RANSAC位姿估计的C++代码。该系统利用视觉传感器构建三维稀疏点云地图,实机器人在复杂环境中的自主导航与缺陷精准定位。未来趋势指向多模态融合(视觉-激光-IMU)语义级高精地图与数字孪生平台的集成。; 适合人群:具备计算机视觉或机器人相关基础知识,从事智能制造、自动化巡检、SLAM算法研发的技术人员及工程师,尤其适用于工作1-3年、希望深入理解SLAM工业落地实践的研发人员。; 使用场景及目标:①应用于芯片封测车间的自动巡检机器人,解决设备密集、线缆交错环境下的高精度导航问题;②实缺陷图像与空间坐标的绑定,提升运维效率与智能化水平;③为SLAM在工业场景中的鲁棒性优化提供可复用的技术路径。; 阅读建议:此资源结合理论与代码实践,建议读者在掌握相机模型、特征提取等前置知识的基础上,动手运行并调试文中代码,深入理解RANSAC、回环检测等关键步骤在真实工业场景中的作用机制,并结合实际硬件系统进行拓展研究。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值