【线上死锁分析】由index_merge引发的死锁事件

本文分析了一起因短信供应商更换而导致的短信系统线上死锁事件。详细解释了死锁原因及涉及的SQL语句,展示了具体的死锁日志,并提出了改进措施。

1.事情背景

背景由于更换新的短信供应商,同事之前可能对这块业务不太熟,原本是回执ID(recordId)一个手机号一个,但是同事接的时候将这个批量发送接口只设置了一个recordId,导致了多个手机号共用了一个recordId。

2.线上deadLock 事件发生

### Error updating database.  Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException: Deadlock found when trying to get lock; try restarting transaction
  1. 先执行sql 语句查看执行计划,为什么存在锁竞争
UPDATE sms_send SET req_success = 2,err_msg = '状态成功' WHERE send_day = '20220323' AND phone_number = 'xxx' AND record_id = 'xxxx';

在这里插入图片描述

  1. 找DBA同学查找相关的死锁日志

死锁概念: 死锁是指两个或者多个事务在同一资源上相互占用,并请求锁定对方占用的资源,从而导致恶性循环的现象。当多个事务试图以不同的顺序锁定资源时,就可能会产生死锁

线上死锁日志如下: 平常很少开启长事务,并且为了减少死锁概率,线上的隔离级别为RC。(间隙锁只有在rr级别下才有,rc 级别是行锁)

------------------------
LATEST DETECTED DEADLOCK
------------------------
2022-03-23 10:19:11 0x7f8f9bf38700
*** (1) TRANSACTION:
TRANSACTION 2912167906, ACTIVE 0 sec fetching rows
mysql tables in use 3, locked 3
LOCK WAIT 48 lock struct(s), heap size 8400, 4 row lock(s)
MySQL thread id 16079756, OS thread handle 140261855196928, query id 2624577147 
sms_user updating
UPDATE sms_send SET req_success = 2,err_msg = '状态成功' WHERE send_day = '20220323' AND phone_number = 'aaaaa' AND record_id = 'xxxxx'
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 56 page no 1943341 n bits 96 index PRIMARY of table `sms`.`sms_send` trx id 2912167906 lock_mode X locks rec but not gap waiting
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值