一次MySQL死锁问题解决

一、环境

  • CentOS, MySQL 5.6.21-70, JPA
  • 问题场景:系统有定时批量更新数据状态操作,每次更新上千条记录,表中总记录数约为500W左右。

二、错误日志


2017-2-25 17:38:41 org.hibernate.util.JDBCExceptionReporter logExceptions
严重: Lock wait timeout exceeded; try restarting transaction
2017-2-25 17:39:05 org.hibernate.util.JDBCExceptionReporter logExceptions
警告: SQL Error: 1213, SQLState: 40001
2017-2-25 17:39:05 org.hibernate.util.JDBCExceptionReporter logExceptions
严重: Deadlock found when trying to get lock; try restarting transaction

三、排查

Check InnoDB status for locks
mysql> SHOW ENGINE InnoDB STATUS; Check MySQL open tables
mysql> SHOW OPEN TABLES WHERE In_use > 0; Check pending InnoDB transactions
mysql> SELECT * FROM `information_schema`.`innodb_trx` ORDER BY `trx_started`; Check lock dependency - what blocks what
mysql> SELECT * FROM `information_schema`.`innodb_locks`;

排查后发现都是执行类似这样的语句出现问题的:


update t_task_tel set state='iok', update_date='2017-02-27 11:03:02' where tel_id=66042 and task_id=350199;

四、分析

搜索相关资料后发现,原来MySQL InnoDB并不一定都是行级锁。

相关参考资料片段如下:

MySQL InnoDB锁机制之Gap Lock、Next-Key Lock、Record Lock解析
http://blog.sina.com.cn/s/blog_a1e9c7910102vnrj.html 4、锁选择
1)、如果更新条件没有走索引,例如执行”update from t1 set v2=0 where v2=5;” ,此时会进行全表扫描,扫表的时候,要阻止其他任何的更新操作,所以上升为表锁。
2)、如果更新条件为索引字段,但是并非唯一索引(包括主键索引),例如执行“update from t1 set v2=0 where v1=9;” 那么此时更新会使用Next-Key Lock。使用Next-Key Lock的原因:
a)、首先要保证在符合条件的记录上加上排他锁,会锁定当前非唯一索引和对应的主键索引的值;
b)、还要保证锁定的区间不能插入新的数据。
3)、如果更新条件为唯一索引,则使用Record Lock(记录锁)。 InnoDB根据唯一索引,找到相应记录,将主键索引值和唯一索引值加上记录锁。但不使用Gap Lock(间隙锁)。
MySQL InnoDB 锁表与锁行
http://blog.csdn.net/qq250782929/article/details/52063975 由于InnoDB预设是Row-Level Lock,所以只有「明确」的指定主键,MySQL才会执行Row lock (只锁住被选取的资料例) ,否则MySQL将会执行Table Lock (将整个资料表单给锁住)。

根据分析结论,猜测是在更新_task_tel表时Where条件中tel_id和task_id没有建立UNIQUE(唯一索引)原因;

五、解决

据此分析,尝试通过tel_id和task_id两个字段建立UNIQUE(唯一索引)来解决。 (也可以先查询出来,然后根据主键ID来更新,这样不会因表中数据量较大影响线上业务)。

用索引字段做为条件进行修改时, 是否表锁的取决于这个索引字段能否确定记录唯一,当索引值对应记录不唯一,会进行锁表,相反则行锁。

通过此种方式解决后,问题没有再重现。

如果你的问题和我遇到的类似,可以尝试据此解决。

六、参考资料

一次MySQL死锁问题解决的更多相关文章

  1. Mysql死锁问题解决方式 & 聚簇索引、隔离级别等知识

    参考了这篇文章:http://www.cnblogs.com/LBSer/p/5183300.html  <mysql死锁问题分析> 写的不错. 如果Mysql死锁,会报出: 1.1 死锁 ...

  2. mysql死锁问题解决

    1. 定位问题 http://blog.csdn.net/beiigang/article/details/43228361 2. 解决死锁 http://www.blogbus.com/ri0day ...

  3. mysql死锁问题解决步骤

    锁表产生的原因 锁表的具体情况 解决锁表问题 1.查询是否锁表 show OPEN TABLES where In_use > 0; 2.查询进程 show processlist; 查询到相对 ...

  4. MySql 死锁时的一种解决办法【转】

    转自:http://blog.csdn.net/mchdba/article/details/38313881 之前也遇到一次,今天又遇到了这个问题,所以这次必须解决,网上找到这篇文章帮了大忙,方便以 ...

  5. MySQL 死锁问题分析

    转载: MySQL 死锁问题分析 线上某服务时不时报出如下异常(大约一天二十多次):"Deadlock found when trying to get lock;". Oh, M ...

  6. 为什么MySQL死锁检测会严重降低TPS

    在大量的客户端,更新数据表的同一行时,会造成数据库的吞吐量大幅降低. 很多数据库的前辈和同行分别通过实验和源码的方法,定位到了罪魁祸首----MySQL死锁检测 实验方式:http://blog.cs ...

  7. Mysql 死锁问题

    Innodb锁系统(4) Insert/Delete 锁处理及死锁示例分析 http://mysqllover.com/?p=431 关于innodb死锁 http://afei2.sinaapp.c ...

  8. MySQL死锁案例分析与解决方案

    MySQL死锁案例分析与解决方案 现象: 数据库查询: SQL语句分析:  mysql. 并发delete同一行记录,偶发死锁.   delete from x_table where id=?   ...

  9. 关于MySQL死锁

    最近项目中遇到一个问题,使用Spring事务嵌套时,导致MySQL死锁.记录一下,时刻提醒自己. 场景如下, 事务嵌套, 最外层有默认事务, 嵌套一个独立事务, 独立事务和外部事务同时操作一张表.

随机推荐

  1. Hao Yin Jian 寒假第一周

    题目链接:https://vjudge.net/contest/147561#problem/A 题意:除法运算,abcde / fghij = n,从小到大输出,其中abcdefghij为0~9的不 ...

  2. Python装饰器学习(九步入门)

    这是在Python学习小组上介绍的内容,现学现卖.多练习是好的学习方式. 第一步:最简单的函数,准备附加额外功能 ? 1 2 3 4 5 6 7 8 # -*- coding:gbk -*- '''示 ...

  3. max-width

    #main { max-width: 600px; margin: 0 auto; } <div id="main"> Using max-width instead ...

  4. YII 1.0 缓存使用

    在main.php的组件components中配置设置添加缓存 'cache'=>array( 'class' => 'system.caching.CFileCache' ), 也就是f ...

  5. Hibernate懒加载的三种解决方案

    Hibernate懒加载的两种解决方案: 1.Hibernate.initialize(代理对象) 2.在*.hbm.xml映射文件中添加lazy="false"属性 3.使用op ...

  6. delphi公用函数

    {*******************************************************} { } { Delphi公用函数单元 } { } { 版权所有 (C) 2008 } ...

  7. 【翻译】使用Visual Studio在Azure上部署Asp.Net Core Web应用

    配置运行环境 Install the latest Azure SDK for Visual Studio. The SDK installs Visual Studio if you don't a ...

  8. svg defs 进行定义 引用

    svg defs 进行定义 引用: <%@ page language="java" contentType="text/html; charset=UTF-8&q ...

  9. spring mvc 引用 jasper JasperReportsHtmlView的nullpx图片问题

    spring mvc 引用 jasper  JasperReportsHtmlView的nullpx图片问题 参考:http://stackoverflow.com/questions/1168633 ...

  10. js连接sqlserver进行查询

    <script language="JavaScript"> // 创建数据库对象 var objdbConn = new ActiveXObject("AD ...