案例如下:

在使用Show innodb status检查引擎状态时,发现了死锁问题:

*** (1) TRANSACTION:

TRANSACTION 0 677833455, ACTIVE 0 sec, process no 11393, OS thread id 278546 starting index read

mysql tables in use 1, locked 1

LOCK WAIT 3 lock struct(s), heap size 320

MySQL thread id 83, query id 162348740 dcnet03 dcnet Searching rows for update

update TSK_TASK set STATUS_ID=1064,UPDATE_TIME=now () where STATUS_ID=1061 and MON_TIME

*** (1) WAITING FOR THIS LOCK TO BE GRANTED:

RECORD LOCKS space id 0 page no 849384 n bits 208 index `PRIMARY` of table `dcnet_db/TSK_TASK` trx id 0 677833455 lock_mode X locks rec but not gap waiting

Record lock, heap no 92 PHYSICAL RECORD: n_fields 11; compact format; info bits 0

0: len 8; hex 800000000097629c; asc b ;; 1: len 6; hex 00002866eaee; asc (f ;; 2: len 7; hex 00000d40040110; asc @ ;; 3: len 8; hex 80000000000050b2; asc P ;; 4: len 8; hex 800000000000502a; asc P*;; 5: len 8; hex 8000000000005426; asc T&;; 6: len 8; hex 800012412c66d29c; asc A,f ;; 7: len 23; hex 75706c6f6164666972652e636f6d2f6 8616e642e706870; asc xxx.com/;; 8: len 8; hex 800000000000042b; asc +;; 9: len 4; hex 474bfa2b; asc GK +;; 10: len 8; hex 8000000000004e24; asc N$;;

*** (2) TRANSACTION:

TRANSACTION 0 677833454, ACTIVE 0 sec, process no 11397, OS thread id 344086 updating or deleting, thread declared inside InnoDB 499

mysql tables in use 1, locked 1

3 lock struct(s), heap size 320, undo log entries 1

MySQL thread id 84, query id 162348739 dcnet03 dcnet Updating

update TSK_TASK set STATUS_ID=1067,UPDATE_TIME=now () where ID in (9921180)

*** (2) HOLDS THE LOCK(S):

RECORD LOCKS space id 0 page no 849384 n bits 208 index `PRIMARY` of table `dcnet_db/TSK_TASK` trx id 0 677833454 lock_mode X locks rec but not gap

Record lock, heap no 92 PHYSICAL RECORD: n_fields 11; compact format; info bits 0

0: len 8; hex 800000000097629c; asc b ;; 1: len 6; hex 00002866eaee; asc (f ;; 2: len 7; hex 00000d40040110; asc @ ;; 3: len 8; hex 80000000000050b2; asc P ;; 4: len 8; hex 800000000000502a; asc P*;; 5: len 8; hex 8000000000005426; asc T&;; 6: len 8; hex 800012412c66d29c; asc A,f ;; 7: len 23; hex 75706c6f6164666972652e636f6d2f6 8616e642e706870; asc uploadfire.com/hand.php;; 8: len 8; hex 800000000000042b; asc +;; 9: len 4; hex 474bfa2b; asc GK +;; 10: len 8; hex 8000000000004e24; asc N$;;

*** (2) WAITING FOR THIS LOCK TO BE GRANTED:

RECORD LOCKS space id 0 page no 843102 n bits 600 index `KEY_TSKTASK_MONTIME2` of table `dcnet_db/TSK_TASK` trx id 0 677833454 lock_mode X locks rec but not gap waiting

Record lock, heap no 395 PHYSICAL RECORD: n_fields 3; compact format; info bits 0

0: len 8; hex 8000000000000425; asc %;; 1: len 8; hex 800012412c66d29c; asc A,f ;; 2: len 8; hex 800000000097629c; asc b ;;

*** WE ROLL BACK TRANSACTION (1)

此死锁问题涉及TSK_TASK表,该表用于保存系统监测任务,以下是相关字段及索引:

ID:主键;

MON_TIME:监测时间;

STATUS_ID:任务状态;

索引:KEY_TSKTASK_MONTIME2 (STATUS_ID, MON_TIME)。

分析,涉及的两条语句应该不会涉及相同的TSK_TASK记录,那为什么会造成死锁呢?

查询MySQL官网文档,发现这跟MySQL的索引机制有关。MySQL的InnoDB引擎是行级锁,我原来的理解是直接对记录进行锁定,实际上并不是这样的。

要点如下:

不是对记录进行锁定,而是对索引进行锁定;

在UPDATE、DELETE操作时,MySQL不仅锁定WHERE条件扫描过的所有索引记录,而且会锁定相邻的键值,即所谓的next-key locking;

如语句UPDATE TSK_TASK SET UPDATE_TIME = NOW() WHERE ID > 10000会锁定所有主键大于等于1000的所有记录,在该语句完成之前,你就不能对主键等于10000的记录进行操作;

当非簇索引(non-cluster index)记录被锁定时,相关的簇索引(cluster index)记录也需要被锁定才能完成相应的操作。

再分析一下发生问题的两条SQL语句,就不难找到问题所在了:

当“update TSK_TASK set STATUS_ID=1064,UPDATE_TIME=now () where STATUS_ID=1061 and MON_TIME

假设“update TSK_TASK set STATUS_ID=1067,UPDATE_TIME=now () where ID in (9921180)”几乎同时执行时,本语句首先锁定簇索引(主键),由于需要更新STATUS_ID的值,所以还需要锁定 KEY_TSKTASK_MONTIME2的某些索引记录。

这样第一条语句锁定了KEY_TSKTASK_MONTIME2的记录,等待主键索引,而第二条语句则锁定了主键索引记录,而等待KEY_TSKTASK_MONTIME2的记录,在此情况下,死锁就产生了。

笔者通过拆分第一条语句解决死锁问题:

先查出符合条件的ID:select ID from TSK_TASK where STATUS_ID=1061 and MON_TIME < date_sub(now(), INTERVAL 30 minute);然后再更新状态:update TSK_TASK set STATUS_ID=1064 where ID in (….)

至此,死锁问题彻底解决。

巧用MySQL InnoDB引擎锁机制解决死锁问题相关推荐

  1. MySQL InnoDB引擎锁的总结

    为什么要锁 我们开的的各式各样系统中,系统运行需要CPU.内存.I/O.磁盘等等资源.但除了硬资源外,还有最为重要的软资源:数据. 当人们访问操作我们的系统时,其实归根是对数据的查看与生产.那么对于同 ...

  2. mysql innodb 的锁机制_Mysql之Innodb锁机制详解

    InnoDB与MyISAM的最大不同有两点:一是支持事务(TRANSACTION):二是采用了行级锁.关于事务我们之前有专题介绍,这里就着重介绍下它的锁机制. 总的来说,InnoDB按照不同的分类共有 ...

  3. 从一个死锁看mysql innodb的锁机制

    2019独角兽企业重金招聘Python工程师标准>>> 背景及现象 线上生产环境在某些时候经常性的出现数据库操作死锁,导致业务人员无法进行操作.经过DBA的分析,是某一张表的inse ...

  4. Mysql InnoDB 的锁机制

    目录 前言 1. 锁的分类 1.1 实现方式 1.2 锁的粒度 2. 查询操作加锁方式 2.1 一致性非锁定读 2.2 一致性锁定读 3. 锁的算法 4. 锁的升级 5. 死锁 6.总结 前言 锁机制 ...

  5. mysql innodb 排他锁_MySQL 针对 InnoDB 引擎锁的种类:行锁(共享锁和排他锁)和表锁(意向共享锁和意向排他锁)...

    InnoDB 锁快速到底 行锁:共享锁(S).排他锁(X) 表锁:意向共享锁(IS).意向排他锁(IX) 下面主要针对 MySQL 中行级锁中的共享锁(S)与排他锁(X)进行分析 共享锁又称为读锁,简 ...

  6. Mysql INNODB引擎行锁的3种算法 Record Lock Next-Key Lock Grap Lock

    Mysql INNODB引擎行锁的3种算法 InnoDB存储引擎有3种行锁的算法,其分别是: □ Record Lock:单个行记录上的锁 Record Lock总是会去锁住索引记录,如果InnoDB ...

  7. MySQL数据库:锁机制

    当数据库中多个事务并发存取同一数据的时候,若对并发操作不加控制就可能会读取和存储不正确的数据,破坏数据库的一致性.MySQL锁机制的基本工作原理就是,事务在修改数据库之前,需要先获得相应的锁,获得锁的 ...

  8. 深入浅出MySQL事务处理和锁机制

    深入浅出MySQL事务处理和锁机制 2015-01-13 架构师之旅 1. 事务处理和并发性 1.1. 基础知识和相关概念 1 )全部的表类型都可以使用锁,但是只有 InnoDB 和 BDB 才有内置 ...

  9. 【数据库】MySQL中的锁机制

    MySQL中的锁机制 数据库锁定机制简单来说,就是数据库为了保证数据的一致性,而使各种共享资源在被并发访问变得有序所设计的一种规则. MySQL 数据库由于其自身架构的特点,存在多种数据存储引擎,每种 ...

最新文章

  1. 脚本没有类似C语言的预编译,开源脚本库
  2. editActionsForRowAtIndexPath(iOS8) tableview编辑(删除、插入、移动)
  3. python后端将svc文件数据读入数据库具体实现
  4. mysql数据库杀掉堵塞_Mysql解决USE DB堵塞详解
  5. 小程序秒杀活动服务器,微信小程序官方上线张大仙周年活动,人数太多把服务器弄崩溃了...
  6. 论文浅尝 | 基于异质图交互模型进行篇章级事件抽取
  7. WebDev.WebServer.exe遇到问题需要关闭
  8. videojs如何获取请求消息_消息队列中,如何保证消息的顺序性?
  9. wlanconnect无法连接wifi_苹果iphone12无法连接wifi怎么回事 解决方法分享
  10. ieee浮点数与常规浮点数_浮点数如何工作
  11. Reinforcement Learning(001)
  12. 垃圾分类数据集+垃圾分类识别训练代码(支持googlenet, resnet, inception_v3, mobilenet_v2)
  13. java设置word审阅最终状态_如何使得打开word文件显示最终的修改状态
  14. Activiti6在Springboot下的使用 6 并行网关的处理
  15. JSAPI 高德地图应用--关键字搜索、POI搜索定位,获取经纬度
  16. spec 文件 autopatch
  17. 西门子1500更改IP地址
  18. 某图书管理系统的类图
  19. excel表格如何转换成word表格_Word如何制作表格?Word制作表格超实用技巧
  20. Sklearn-GBDT(GradientBoostingDecisionTree)梯度提升树

热门文章

  1. (已解决)linux如何删除-开头的文件或者目录
  2. 深度学习与工业互联网安全:应用与挑战
  3. 小目标检测的一些问题,思路和方案
  4. 计算机密码行业专题研究:网络安全最大弹性领域
  5. 关于未来的蝴蝶效应,《崛起的超级智能》创作有感
  6. 李飞飞公布谷歌云TPU、AutoML、行业方案等多项进展,AI云计算成谷歌全新增长点...
  7. 人类首张脑电波连接全图问世
  8. 趁老婆不在家,我把儿子带成了程序大神...
  9. 选 Offer 的 5 个维度
  10. 发明 AI 吵架神器?程序员对象这么厉害的吗?