记一次线上MySQL数据库死锁问题
出现死锁问题背景
CREATE TABLE `test` (
`id` bigint(11) NOT NULL ,
`name` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL ,
`type` tinyint(4) NULL DEFAULT NULL ,
`uid` int(11) NULL DEFAULT NULL ,
PRIMARY KEY (`id`),
UNIQUE INDEX `uniq_type_name` (`type`, `name`) USING BTREE
)
ENGINE=InnoDB
DEFAULT CHARACTER SET=utf8 COLLATE=utf8_general_ci
ROW_FORMAT=COMPACT
;
insert into test(id, name, type, uid) values(1, "DT590", 3, 1001);
insert into test(id, name, type, uid) values(2, "DT589", 3, 1001);
insert into test(id, name, type, uid) values(3, "DT588", 3, 1001);
------------------------
LATEST DETECTED DEADLOCK
------------------------
2018-06-21 10:51:03 2b16deb03700
*** (1) TRANSACTION:
TRANSACTION 1905650677, ACTIVE 0.001 sec inserting
mysql tables in use 1, locked 1
LOCK WAIT 2 lock struct(s), heap size 360, 1 row lock(s), undo log entries 1
LOCK BLOCKING MySQL thread id: 16983306 block 34208692
MySQL thread id 34208692, OS thread handle 0x2b2203b0b700, query id 9093982364 172.24.18.106 app_redcliffc update
INSERT INTO `test` (id, name, type, uid) VALUES (4, 'DT590', 3, 1001)
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 138 page no 16492 n bits 408 index `uniq_type_name` of table `db`.`test` trx id 1905650677 lock mode S waiting
Record lock, heap no 341 PHYSICAL RECORD: n_fields 3; compact format; info bits 0
0: len 4; hex 80000048; asc H;;
1: len 10; hex 44543631393230363835; asc DT61920685;;
2: len 8; hex 0461116807c09a00; asc a h ;; *** (2) TRANSACTION:
TRANSACTION 1905650675, ACTIVE 0.004 sec inserting
mysql tables in use 1, locked 1
3 lock struct(s), heap size 1184, 2 row lock(s), undo log entries 2
MySQL thread id 16983306, OS thread handle 0x2b16deb03700, query id 9093982366 172.24.18.105 app_redcliffc update
INSERT INTO `test` (id, name, type, uid) VALUES (2, 'DT589', 3, 1001)
*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 138 page no 16492 n bits 408 index `uniq_type_name` of table `db`.`test` trx id 1905650675 lock_mode X locks rec but not gap
Record lock, heap no 341 PHYSICAL RECORD: n_fields 3; compact format; info bits 0
0: len 4; hex 80000048; asc H;;
1: len 10; hex 44543631393230363835; asc DT61920685;;
2: len 8; hex 0461116807c09a00; asc a h ;; *** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 138 page no 16492 n bits 408 index `uniq_type_name` of table `db`.`test` trx id 1905650675 lock_mode X locks gap before rec insert intention waiting
Record lock, heap no 341 PHYSICAL RECORD: n_fields 3; compact format; info bits 0
0: len 4; hex 80000048; asc H;;
1: len 10; hex 44543631393230363835; asc DT61920685;;
2: len 8; hex 0461116807c09a00; asc a h ;; *** WE ROLL BACK TRANSACTION (1)
问题分析
| session1 | session2 | |
| insert into test(id, name, type, uid) values(1, "DT590", 3, 1001); | 事务一先到,先插入第一条记录DT590,成功 | |
| insert into test(id, name, type, uid) values(2, "DT589", 3, 1001); |
事务一继续插入第二天DT589记录,这个时候事务二请求到了,开始
插入第一条记录DT590,然后就报出死锁,事务二回滚,事务一成功执行
|
insert into test(id, name, type, uid) values(1, "DT590", 3, 1001); |
| session1 | 持锁 | session2 | 持锁 |
| insert into test(id, name, type, uid) values(1, "DT590", 3, 1001); | 插入一条数据库中没有的记录,对DT590这条记录加了一个x锁 | ||
| insert into test(id, name, type, uid) values(2, "DT589", 3, 1001); |
这时事务一插入DT589时候,发现这条记录已经有了一个gap lock(DT589这条记录刚好被事务二插DT590时候申请的gap lock包含了),会先申请一个insert intention waiting插入意向锁,这个锁和事务二持有gap lock互斥,发生死锁。
事务一在等事务二释放这条记录gap lock, 事务二在等事务一释放DT590 X锁
|
insert into test(id, name, type, uid) values(1, "DT590", 3, 1001); | 事务二插入有唯一索引DT590这条记录,发现这条记录上已经有了x锁,所以会申请一个该条记录的s锁和gap lock |
相关一些锁知识
总结
记一次线上MySQL数据库死锁问题的更多相关文章
- 记一次线上Mysql数据库 宕机
从发现问题,到最后解决一共消耗两个半小时(7:30~10:00),报警电话16通,警察坐镇,未完待续 ......
- 线上Mysql数据库崩溃事故的原因和处理
前文提要 承接前文<一次线上Mysql数据库崩溃事故的记录>,在文章中讲到了一次线上数据库崩溃的事件记录,建议两篇文章结合在一起看,不至于摸不着头脑. 由于时间原因,其中只讲了当时的一些经 ...
- Spring+SpringMVC+MyBatis+easyUI整合进阶篇(八)线上Mysql数据库崩溃事故的原因和处理
前文提要 承接前文<一次线上Mysql数据库崩溃事故的记录>,在文章中讲到了一次线上数据库崩溃的事件记录,建议两篇文章结合在一起看,不至于摸不着头脑. 由于时间原因,其中只讲了当时的一些经 ...
- 一次线上Mysql数据库崩溃事故的记录
文章简介 工作这几年,技术栈在不断更新,项目管理心得也增加了不少,写代码的速度也在提升,感觉很欣慰,毕竟是在一直进步,但是过程中也有许许多多的曲折,也踩过了数不尽的坑坑洼洼,从一个连百度都不知道用的萌 ...
- Spring+SpringMVC+MyBatis+easyUI整合进阶篇(七)一次线上Mysql数据库崩溃事故的记录
作者:13 GitHub:https://github.com/ZHENFENG13 版权声明:本文为原创文章,未经允许不得转载. 文章简介 工作这几年,技术栈在不断更新,项目管理心得也增加了不少,写 ...
- 通过SSH秘钥登录线上MySQL数据库(基于Navicat)
前言 生产环境的数据库往往需要经过严格的安全限制,所以禁用密码登录,使用秘钥的方式是一种相对安全的登录方式. 原理: 角色: 主机A:其他主机,有访问线上数据库的权限 主机B:线上数据库的主机 主机C ...
- 原创 记录一次线上Mysql慢查询问题排查过程
背景 前段时间收到运维反馈,线上Mysql数据库凌晨时候出现慢查询的报警,并把原始sql发了过来: --去除了业务含义的sql update test_user set a=1 where id=1; ...
- 【MySQL】记一次线上重大事故:二狗子竟然把线上数据库删了!!
写在前面 估计二狗子这几天是大姨夫来了,心情很郁闷,情绪也很低落,工作的时候也有点心不在焉.让他发个版本,结果,一行命令下去把线上的数据库删了!你没听错:是删掉了线上的数据库!运营那边顿时炸了锅:怎么 ...
- 记一次排查线上MySQL死锁过程,不能只会curd,还要知道加锁原理
昨晚我正在床上睡得着着的,突然来了一条短信. 啥,线上MySQL死锁了,我赶紧登录线上系统,查看业务日志. 能清楚看到是这条insert语句发生了死锁. MySQL如果检测到两个事务发生了死锁,会回滚 ...
随机推荐
- 自定义崩溃界面 CustomActivityOnCrash
项目地址:https://github.com/Ereza/CustomActivityOnCrash The inner workings are based on ACRA's dialog re ...
- unexpected token: * 和 java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to 解决办法
一.unexpected token: * 的解决办法 首先要搞清楚sql与hql的区别! sql操作的是数据库表,而hql操作的是对象! sql中“select * from table”,而hq ...
- JVM垃圾回收(GC)整理总结学习
基本回收算法 1. 引用计数(Reference Counting)比较古老的回收算法.原理是此对象有一个引用,即增加一个计数,删除一个引用则减少一个计数.垃圾回收时,只用收集计数为0的对象.此算法最 ...
- excel 快捷使用
1)excel填充相同内容 A:在需要填充相同内容的格中一个添加需要的内容,然后选中所有填充格,快捷键 ctrl-D 2)excel中合并单元格快捷键 A:1.点击上方-其他命令 2.选择“合并”进行 ...
- Cocos2d-x 2.x 升级为 3.x 常见变化纪录
1.去CC 之前2.0的CC**,把CC都去掉,主要的元素都是保留的 2.0 CCSprite CCCallFunc CCNode .. 3.0 Sprite CallFunc Node .. 2. ...
- [置顶] 关于Qt的学习
初学习QT,希望用此来记录学习的轨迹....... 1.Qt版本为Qt5.1.0 2.使用Qt-Creator进行变成. 3.第一个例子 打印出“Hello World” 3.1 打开Qt-Crea ...
- Linux系统登录:本地登录与远程登录
安装登录系统的位置可以将登录方式分为两种:本地登录和远程登录.本地登录可以使用图形界面和命令行模式(也称字符界面)两种方式:远程登录可以使用SSH.Telnent.VNC.SFTP 4种方式. 常见的 ...
- MQTT---HiveMQ源代码具体解释(四)插件载入
源博客地址:http://blog.csdn.net/pipinet123 MQTT交流群:221405150 实现功能 将全部放在plugins文件夹下的全部符合plugin编写规范的plugin ...
- 深入理解javascript闭包【整理】
原文链接:http://www.cn-cuckoo.com/2007/08/01/understand-javascript-closures-72.html 英文原文:http://www.jibb ...
- Spring 事务传播行为
事务传播行为 指定是Spring中一个事务方法调用另一个事务方法时.处理的行为 使用方式: @Transactional(propagation=Propagation.REQUIRED) 事务的使用 ...