记一次线上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如果检测到两个事务发生了死锁,会回滚 ...
随机推荐
- go语言基础之获取命令行参数
1.获取命令行参数 示例: package main //必须 import "fmt" import "os" func main() { list := o ...
- STM32+IAP方案 实现网络升级应用固件
关注了这个概念有些日子了,这段时间总算有机会实战==网络升级应用固件,这里记录下遇到的问题,及解决方案. 原理与网上流传的串口作为传输手段 一致:不同之处,无非我这里使用了网络设备传输.==(lwip ...
- jquery的$.each()
each()方法能使DOM循环结构简洁,不容易出错.each()函数封装了十分强大的遍历功能,使用也很方便,它可以遍历一维数组.多维数组.DOM, JSON 等等在javaScript开发过程中使用$ ...
- Android触控屏幕Gesture(GestureDetector和SimpleOnGestureListener的使用教程) 分类:Androidandroid实例
1.当用户触摸屏幕的时候,会产生许多手势,例如down,up,scroll,filing等等,我们知道View类有个View.OnTouchListener内部接口,通过重写他的onTouch(Vie ...
- mysql的日志管理
日志操作是数据库维护中最重要的手段之一,日志文件会记录MySQL服务器的各种信息,所以当MySQL服务器遭到意外损坏时,不仅可以通过日志文件来查看出错的原因,而且还可以通过日志文件进行数据恢复. MY ...
- HDU 4528 BFS 小明系列故事——捉迷藏
原题直通车:HDU 4528 小明系列故事——捉迷藏 分析: 标记时加两种状态就行. 代码: #include<iostream> #include<cstring> #inc ...
- Cognos权限认证CJP方式之用户密码加密
在项目开发过程中,用户往往对系统的安全都有明确的要求,下面针对cognos门户认证用户密码如何加密来提供一个简单的wf 1Cognos权限认证方式:CJP 2Cognos用户数据库类型:Oracle ...
- (剑指Offer)面试题48:不能被继承的类
题目: 写一个不能被继承的类 思路: 1.把构造函数设为私有函数 在C++中子类的构造函数会自动调用父类的构造函数,子类的析构函数也会自动调用父类的构造函数,要想一个类不能被继承,只要把它的构造函数和 ...
- 极客Web前端开发资源大荟萃#001
每周极客都将总结本周最精彩的素材提供给大家,希望可以带给你更多地灵感和帮助!极客#GB课程库#现已上线,无论你是初级.中级.还是正在进修的高级前端工程师.这里都将帮助你得到更多更高效的学习.原文:极客 ...
- C++ 11 - STL - 函数对象(Function Object) (下)
1. 预定义函数对象 C++标准库内含许多预定义的函数对象,也就是内置的函数对象. 你可以充分利用他们,不必自己费心去写一些自己的函数对象. 要使用他们,你只要包含如下头文件 #include < ...