mysql batch insert 遇到错误跳过_MySQL 死锁问题分析

这篇博客详细分析了在高并发场景下,MySQL批量插入时遇到的死锁问题。作者通过解读死锁日志,发现是由于insert和update操作在同一个索引上引发的。博客介绍了排查和理解死锁的过程,以及三种可能的解决方案,包括利用MySQL的保护机制、使用分布式锁和重试策略。最后,作者强调了解官方文档的重要性,并提醒读者根据业务场景选择合适的解决方案。
摘要由CSDN通过智能技术生成
背景介绍

我们在进行互联网应用开发的时候,高并发场景下,很容易遇到死锁的问题,我们从jdbc抛出的死锁异常中,很难看出死锁发生的具体原因,jdbc只是给了一个死锁异常, 但是并没有抛出导致死锁的原因,这是因为mysql本身,发生死锁的时候就没有抛出更多的错误信息。MySQL/InnoDB的加锁分析,对应用开发来说也是比较复杂的,因为 锁这一块的复杂性,很多关于数据库锁的文章,并没有实际的验证,而是似是而非猜测性的,有一些误导。这里是对一个insert和update同一索引数据导致的死锁案例的 分析过程,主要是描述一个解决问题的思路,供大家参考。

发现问题

X同学在生产上发现了如下的死锁异常,想让我一起排查下,登陆服务器后,看到了类似如下的异常信息:

在分库:[ worker_10~~>jdbc:mysql://hostname:3306/dbname?user=user ],
执行SQL:[ UPDATE tablename SET col1 = col1 + 20, modified_date = NOW() WHERE order_id = 'xxx' ],
发生异常:Deadlock found when trying to get lock; try restarting transaction;
排查问题

我们从日志上看,看不出死锁发生的具体原因,我翻看了发生异常堆栈的代码,类似于我之前做的一个订单台账的死锁问题,因为上次排查的时候,就参阅了不少资料, 有些资料也有一定的误导性,借此我把这次死锁原因复现一下,通过实际的操作来分析一下死锁的原因,并分析一下,如何解决此场景的死锁问题。

我们可以通过show engine innodb status,来查看死锁的日志,看看是否可以看出,是执行哪几个SQL引起的,以下是我找dba拿出的日志,我做了一下脱敏。

2019-07-18 10:03:03 7f16ff826700
*** (1) TRANSACTION:
TRANSACTION 46497170213, ACTIVE 0 sec starting index read
mysql tables in use 1, locked 1
LOCK WAIT 3 lock struct(s), heap size 1184, 2 row lock(s)
MySQL thread id 118471353, OS thread handle 0x7f1c2fe77700, query id 146140919609 10.240.24.25 dbname updating
UPDATE tablename SET col1 = col1 + 20, modified_date = NOW() WHERE order_id = 'xxx'
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 2632 page no 5065 n bits 440 index `uniq_table_name_col1` of table `tablename` trx id 46497170213 lock_mode X locks rec but not gap waiting
Record lock, heap no 374
*** (2) TRANSACTION:
TRANSACTION 46497170214, ACTIVE 0 sec starting index read, thread declared inside InnoDB 5000
mysql tables in use 1, locked 1
3 lock struct(s), heap size 1184, 2 row lock(s)
MySQL thread id 118465375, OS thread handle 0x7f16ff826700, query id 146140919617 172.25.213.222 dbname updating
UPDATE tablename SET col1 = col1 + 30, modified_date = NOW() WHERE order_id = 'xxx'
*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 2632 page no 5065 n bits 440 index `uniq_table_name_col1` of table `tablename` trx id 46497170214 lock mode S rec but not gap
Record lo
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值