笔者最近在生产环境错误日志上看到updating database. Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException: Deadlock found when trying to get lock; try restarting transaction 这样的日志 ,网上看了很多文章  发现这篇文章 跟自己的场景非常接近。也没像作者翻binlog日志

但综合分析我的情况应该是相同表记录行锁冲突

在我一次执行三个update table1  ,table2  set table.xx=table2.xx where ..

update table1,table2 set table1.yy=table2.yy where ...

update table1,table2 set table1.xx=table2.xx where ...

update table1,table2 set table1.zz=table2.zz where ...

而且我的where 条件列是没有建立索引 所以锁住的是整表。

事务一直执行过程中 锁住记录后没有释放  事务2执行时 遇到相同记录 等待事务1  事务三 又等待事务二 因为有相同行数涉及  ,这个时候 事务1执行完毕 等待事务3  就造成死锁现象

当事务1执行语句1时  锁住了某几行  这时事务2执行的时候 也需要更新相同的几行 但发现那几行被事务1锁住

上图是我接收到的错误报警,SQLSTATE[40001]: Serialization failure: 1213 Deadlock found when trying to get lock; try restarting transaction,错误信息显示我们业务中有一条数据库操作遇到了死锁情况。接下来就开始我们的追查之旅。

1.执行“show engine innodb status”获取INNODB引擎当前信息(show engine innodb status 详细介绍)

LATEST DETECTED DEADLOCK记录了最近一次的死锁情况。

2017-01-04 09:25:17时间跟我们接收到的报错日志时间吻合。

上面还可以看出两个事务之间发生锁竞争时,给我们留下的部分数据

事务1

UPDATEskuSETquantity=quantity-'1',lock_stock=lock_stock+'1',sys_version=sys_version+1 WHEREid= '15608' ANDquantity>= '1' limit 1

事务2

UPDATEskuSETquantity=quantity-'1',lock_stock=lock_stock+'1',sys_version=sys_version+1 WHEREid= '15504' ANDquantity>= '1' limit 1

死锁的两个资源均被lock_mode X locks了

最后,mysql给了很重要的一个数据“WE ROLL BACK TRANSACTION (2)” MYSQL回滚了事务2。既然mysql回滚了事务2,那么肯定是事务2的语句触发了死锁,被mysql回滚了,也就是应该为报错日志所记录的那部分。同时,MYSQL执行了事务1,那么事务1的SQL语句肯定被记录在BINLOG中了。

2.查看binlog日志,找出事务1所执行的语句

查找依据:

SQL语句,根据LATEST DETECTED DEADLOCK提供的死锁时记录的sql语句。

线程ID(mysql的唯一标识): MySQL thread id 11572504

执行时间(时间线):2017-01-04 09:25:17 7f553477d700

根据以上三个标识,以及BINLOG的起始标志“BEGIN、COMMIT”,几乎可以100%确定事务1所包含的SQL语句。

binlog信息大致如下

3.还原事务2所包含的执行语句

事务1的语句找齐了,接下来找事务2的语句,还记得我们开头提供的报错日志吗,那个日志里也详细记录了发起请求时的参数情况(截图未展示),根据参数和我们处理业务的代码,可以复现事务2所要执行的语句

根据两个事务所执行的sql语句,目前可以还原死锁产生的原因了

4.查看两个事务执行语句的顺序:

顺序事务1事务2说明

1

begin

2

begin

3

UPDATE sku

SET quantity=quantity-'1',

lock_stock=lock_stock+'1',

sys_version=sys_version+1

WHERE id = '15504' AND

quantity >= '1' limit 1

事务1 给 sku表 id 15504记录上 X 锁

4

UPDATE sku

SET quantity=quantity-'1',

lock_stock=lock_stock+'1',

sys_version=sys_version+1

WHERE id = '15608' AND

quantity >= '1' limit 1

事务2 给 sku表 id 15608记录上 X 锁

5

UPDATE sku

SET quantity=quantity-'1',

lock_stock=lock_stock+'1',

sys_version=sys_version+1 WHERE id = '15608' AND

quantity >= '1' limit 1

这里是关键,事务1想给sku表 id 15608上X锁,发现被别人(事务2)上锁了,等待锁释放

6

UPDATE sku

SET quantity=quantity-'1',

lock_stock=lock_stock+'1',

sys_version=sys_version+1

WHERE id = '15504' AND

quantity >= '1' limit 1

事物2打算给sku表id为15504记录上 X 排它锁,发现被其他事务上了,而且此事务居然还在等他提交,这时MYSQL立刻回滚事务2…(php发现MYSQL返回死锁信息,记录该信息到错误日志…发送回滚指令…mysql已经“帮”他回滚了…)

7

执行成功

事务1发现别人的锁释放了,获得X锁,执行成功

8

commit

事务1执行成功,记录binlog日志

解决方案

减小事务中的语句数量

在业务中调整语句的执行顺序,例如可以按照where条件中字段的大小进行一下排序,按照排序后顺序执行,让死锁变为锁等待。

相关补充

innodb的行锁,锁的是查询条件中的索引字段,以及索引字段对应的primary key字段

mysql死锁语句_Mysql死锁相关推荐

  1. mysql 1061原因_MySQL死锁问题分析及解决方法实例详解(转)

    出处:http://www.jb51.net/article/51508.htm MySQL死锁问题是很多程序员在项目开发中常遇到的问题,现就MySQL死锁及解决方法详解如下: 1.MySQL常用存储 ...

  2. mysql 死锁监控_mysql 死锁

    MySQL复制slave服务器死锁案例 原文:MySQL复制slave服务器死锁案例 MySQL复制刚刚触发了一个bug,该bug的触发条件是slave上Xtrabackup备份的时候执行flushs ...

  3. mysql 死锁日志_Mysql死锁以及死锁日志分析

    死锁的概念 死锁:死锁一般是事务相互等待对方资源,***形成环路造成的. 对于死锁,数据库处理方法:牺牲一个连接,保证另外一个连接成功执行. 发生死锁会返回ERROR:1213 错误提示,大部分的死锁 ...

  4. mysql 查询语句_MySQL相关(一)- 一条查询语句是如何执行的

    前言 学习一个新知识最好的方式就是上官网,所以我先把官网贴出来 MySQL官网 (点击查阅),如果大家有想了解我没有说到的东西可以直接上官网看哈~目前 MySQL 最新大版本为8.0,但是鉴于目前应用 ...

  5. mysql set语句_MySQL Prepared语句简介

    之前的MySQL版本4.1,查询以文本格式发送到MySQL服务器. 之后,MySQL服务器使用文本协议将数据返回给客户端.MySQL必须完全解析查询,并将结果集转换为字符串,然后再将其返回给客户端. ...

  6. java mysql查询语句_Mysql查询语句执行过程

    Mysql查询语句执行过程 Mysql分为server层和存储引擎两部分,或许可以再加一层连接层 连接层(器) Mysql使用的是典型的C/S架构.连接器通过典型的TCP握手完成连接. 需要注的是, ...

  7. mysql查询死锁语句_MYSQL查询数据库死锁和事务的语句

    查看进程信息 SHOW FULL PROCESSLIST ; 查询事务信息 SELECT * FROM information_schema.INNODB_TRX t -- WHERE t.trx_q ...

  8. mysql锁场景_MySQL死锁系列-常见加锁场景分析

    在上一篇文章<锁的类型以及加锁原理>主要总结了 MySQL 锁的类型和模式以及基本的加锁原理,今天我们就从原理走向实战,分析常见 SQL 语句的加锁场景.了解了这几种场景,相信小伙伴们也能 ...

  9. mysql 死锁 代码_MySQL死锁问题解决的代码详细介绍

    一次MySQL死锁问题解决 一.环境CentOS, MySQL 5.6.21-70, JPA 问题场景:系统有定时批量更新数据状态操作,每次更新上千条记录,表中总记录数约为500W左右. 二.错误日志 ...

最新文章

  1. 迁移到MySQL的业务架构演进实战
  2. 从小护士到微软中国总经理,逆风飞扬的“打工皇后”吴士宏的传奇人生
  3. 保存mysql用户的登录信息到~.my.cnf文件;用于方便登录操作。
  4. 部署 instance 到 OVS vlan100 - 每天5分钟玩转 OpenStack(138)
  5. 清理Oracle安装目录里的一些日志信息
  6. Java功底之static、final、this、super
  7. python numpy ones.like()(返回形状与类型与给定数组相同的数组)
  8. 50行代码搞定无限滑动幻灯片
  9. 30天敏捷结果(2):用三个故事驱动你的一周
  10. 如何使用代码区分service contract和service contract quotation
  11. P2371-[国家集训队]墨墨的等式【同余最短路】
  12. MTK 驱动(82)---ABD 调试命令
  13. JavaScript中DOM的层次节点(一)
  14. xadmin与admin设置
  15. 《迎向开阔的人生》——刘墉
  16. (转) Playing FPS games with deep reinforcement learning
  17. python原生是什么意思_什么是 云原生?
  18. java获取月份有几周_java 获取当前日期是本月的第几周,且当月一共有几周
  19. layUI穿梭框前后端的交互
  20. java 如何测试_java – 如何测试一个变量是否设置?

热门文章

  1. IDEA 中取消下面的按钮即可显示定位的按钮圆圈
  2. idea使用git如何合并本地及其远程分支
  3. C语言清空数组的几种方式
  4. python—matplotlib 散点图,气泡图,气泡饼图/功效矩阵可视化对比
  5. Java HashMap的底层实现原理
  6. 关于 ubuntu 插入耳机没有声音(麦克风也无法使用)的解决办法
  7. ASM 管理的内部工具:KFED、KFOD、AMDU
  8. MFC用户名+密码登录程序设计
  9. Mac虚拟机vitrualbox、Parallels Desktop、VMware体验
  10. 机械设计是指规划和设计实现预期功能的新机械或改进原有机械的性能