当前位置: 首页 > news >正文

mysql 1213_分享一个MySQL死锁问题解决的方法

分享一个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并不一定都是行级锁。

相关参考资料片段如下:

锁选择

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(间隙锁)。

由于InnoDB预设是Row-Level Lock,所以只有「明确」的指定主键,MySQL才会执行Row lock (只锁住被选取的资料例) ,否则MySQL将会执行Table Lock (将整个资料表单给锁住)。

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

五、解决

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

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

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

f68f2add0b68e4f9810432fce46917b7.png

本文原创发布php中文网,转载请注明出处,感谢您的尊重!

相关文章:

  • mysql服务器主备份_MySQL 基于主主备份
  • win2012卸载mysql_Sql Server 2012完全卸载方法 只需8步轻松卸载
  • mysql多表查询实训_MySql-多表查询练习
  • mysql 如何解锁_Mysql如何解锁?
  • mysql left a 10_MySQL语法基础
  • demonstration记忆_英语背诵方法之一:意群断句法
  • mysql8分区_mysql8中的表分区
  • ztree 后台异步加载_Ztree 分批异步加载
  • linux执行mysql表_linux shell命令执行sql(mysql入门)
  • python 数组逆序重放_OpenJudge计算概论-找最大数序列
  • python爬虫处理滑块验证_python爬虫基础(9:验证识别之滑块验证)
  • qmediaplayer进度_QMediaPlayer的duration问题
  • java timer定时执行一次_Java Timer(定时调用、实现固定时间执行)
  • java字串数组_java字符串数组
  • java swing 拖拽文件夹_Java Swing 鼠标拖放文件 代码1
  • @angular/forms 源码解析之双向绑定
  • Android Volley源码解析
  • co模块的前端实现
  • Golang-长连接-状态推送
  • iOS动画编程-View动画[ 1 ] 基础View动画
  • Java 多线程编程之:notify 和 wait 用法
  • JavaScript 是如何工作的:WebRTC 和对等网络的机制!
  • js继承的实现方法
  • Median of Two Sorted Arrays
  • Spring Cloud中负载均衡器概览
  • Spring声明式事务管理之一:五大属性分析
  • vue 配置sass、scss全局变量
  • vuex 笔记整理
  • vue中实现单选
  • 从PHP迁移至Golang - 基础篇
  • 对话:中国为什么有前途/ 写给中国的经济学
  • 计算机在识别图像时“看到”了什么?
  • 七牛云 DV OV EV SSL 证书上线,限时折扣低至 6.75 折!
  • 如何合理的规划jvm性能调优
  • 智能网联汽车信息安全
  • ​LeetCode解法汇总307. 区域和检索 - 数组可修改
  • ​VRRP 虚拟路由冗余协议(华为)
  • #13 yum、编译安装与sed命令的使用
  • #中国IT界的第一本漂流日记 传递IT正能量# 【分享得“IT漂友”勋章】
  • (13)Hive调优——动态分区导致的小文件问题
  • (8)STL算法之替换
  • (Redis使用系列) Springboot 实现Redis消息的订阅与分布 四
  • (九)信息融合方式简介
  • (四)搭建容器云管理平台笔记—安装ETCD(不使用证书)
  • (一) storm的集群安装与配置
  • (原創) 如何刪除Windows Live Writer留在本機的文章? (Web) (Windows Live Writer)
  • *++p:p先自+,然后*p,最终为3 ++*p:先*p,即arr[0]=1,然后再++,最终为2 *p++:值为arr[0],即1,该语句执行完毕后,p指向arr[1]
  • .htaccess 强制https 单独排除某个目录
  • .NET(C#、VB)APP开发——Smobiler平台控件介绍:Bluetooth组件
  • .net获取当前url各种属性(文件名、参数、域名 等)的方法
  • .NET开源项目介绍及资源推荐:数据持久层 (微软MVP写作)
  • .net中调用windows performance记录性能信息
  • ??eclipse的安装配置问题!??
  • [ vulhub漏洞复现篇 ] ThinkPHP 5.0.23-Rce
  • [04]Web前端进阶—JS伪数组