Mysql索引引起的死锁
提到索引,首先想到的是效率提高,查询速度提升,不知不觉都会有一种心理趋向,管它三七二十一,先上个索引提高一下效率..但是索引其实也是暗藏杀机的...
今天压测带优化项目,开着Jmeter高并发访问项目,后台连着mysql通过show processlist命令查看查询情况,发现些sql语句需要优化,就在关键字段上上了索引.效果很明显项目的吞吐量瞬间提高到原来3倍,但是问题也出现了,日志中报出大量的死锁错误.本来以为程序逻辑有问题,定位了一下程序块,大体逻辑如下:
- userDao.updateByUserId(userId);
- userDao.save(user);
简单说就是,一个按照表中的userId字段进行更新,一个按照表中的主键进行保存.逻辑上看不出来什么问题,前前后后也尝试了各种方法,并添加了各种日志进行排查都无果.一筹莫展之际想到这个问题是在我添加索引之后出现的,也许和索引有关,之前记得读到过有关索引引起问题的帖子,但是具体内容已经忘记了,然后去掉了表中的索引(userId字段)后,果然再也不报错了,死锁消失了.进而探究了一下原因:
找到一篇博客进行了比较详细的介绍: http://blog.csdn.net/aesop_wubo/article/details/8286215
简要的说就是Mysql的innodb引擎支持事务,更新时采用的是行级锁,会在使用中的索引上加锁,如果使用的主键索引,直接锁主键索引,如果使用的非主键索引,则先锁索引,再锁对应的主键索引.故而在根据非主键索引进行更新时,实际上需要3步:
1)先获取索引锁
2)获取对应记录的主键锁
3)按照主键完成更新操作
在高并发的情况下实际上这里就存在问题了, 由于上面说的1)和2)是按照先锁索引,再锁主键的顺序,那么只要存在先锁主键,再锁索引这种反顺序操作那么就能达成死锁.也就是说一个获取了索引锁,等待主键锁,另一个获取了主键锁,等待获取索引锁.造成互相等待的死锁情况.
- 这里补充说明一下我上面例子中为何导致死锁:
- userDao.updateByUserId(userId)这句是按照非主键索引更新,故先锁非主键索引,再锁主键索引.
- userDao.save(user)这句按照主键保存对象,由于更新的字段中包含索引字段,故在获取主键索引后,需要获取索引字段的锁,以便完成字段更新.
- 这就满足了获取锁的顺序与上一句完全相反,达成死锁条件~
解法:
说了这么多,解决方案也就明晰了,只要让更新操作中带有主键即可.也就是让获取锁的顺序一致即可.我这里的例子userDao.updateByUserId(userId)更新时加入主键,要么就是拆分成2次操作,先查询到对应的记录,再根据主键来更新.
Mysql索引引起的死锁的更多相关文章
- [经验分享] MySQL Innodb表导致死锁日志情况分析与归纳【转,纯学习】
在定时脚本运行过程中,发现当备份表格的sql语句与删除该表部分数据的sql语句同时运行时,mysql会检测出死锁,并打印出日志. 两个sql语句如下: (1)insert into backup_ta ...
- MySQL Innodb表导致死锁日志情况分析与归纳
发现当备份表格的sql语句与删除该表部分数据的sql语句同时运行时,mysql会检测出死锁,并打印出日志 案例描述在定时脚本运行过程中,发现当备份表格的sql语句与删除该表部分数据的sql语句同时 ...
- Mysql 原理以及常见mysql 索引等
## 主键 超键 候选键 外键 (mysql数据库常见面试题) 数据库之互联网常用架构方案 数据库之互联网常用分库分表方案 分布式事务一致性解决方案 MySQL Explain详解 ## 数据库事务的 ...
- 27.MySQL 索引、事务与存储引擎
MySQL 索引.事务与存储引擎 目录 MySQL 索引.事务与存储引擎 MySQL 索引 索引的概念 索引的作用及副作用 索引的作用 索引的副作用 创建索引的原则依据 索引的分类和创建 普通索引 唯 ...
- 一天五道Java面试题----第七天(mysql索引结构,各自的优劣--------->事务的基本特性和隔离级别)
这里是参考B站上的大佬做的面试题笔记.大家也可以去看视频讲解!!! 文章目录 1 .mysql索引结构,各自的优劣 2 .索引的设计原则 3 .mysql锁的类型有哪些 4 .mysql执行计划怎么看 ...
- 深入MySQL索引
MySQL索引作为数据库优化的常用手段之一在项目优化中经常会被用到, 但是如何建立高效索引,有效的使用索引以及索引优化的背后到底是什么原理?这次我们深入数据库索引,从索引的数据结构开始说起. 索引原理 ...
- MySQL 索引
MySQL索引的建立对于MySQL的高效运行是很重要的,索引可以大大提高MySQL的检索速度. 打个比方,如果合理的设计且使用索引的MySQL是一辆兰博基尼的话,那么没有设计和使用索引的MySQL就是 ...
- MYSQL索引结构原理、性能分析与优化
[转]MYSQL索引结构原理.性能分析与优化 第一部分:基础知识 索引 官方介绍索引是帮助MySQL高效获取数据的数据结构.笔者理解索引相当于一本书的目录,通过目录就知道要的资料在哪里, 不用一页一页 ...
- MySQL索引原理及慢查询优化
原文:http://tech.meituan.com/mysql-index.html 一个慢查询引发的思考 select count(*) from task where status=2 and ...
随机推荐
- JAVA中使用浮点数类型计算时,计算精度的问题
标题 在Java中实现浮点数的精确计算 AYellow(原作) 修改 关键字 Java 浮点数 精确计算 问题的提出:如果我们编译运行下面这个程序会看到什么?publi ...
- Spring Security 中的加密BCryptPasswordEncoder
// // Source code recreated from a .class file by IntelliJ IDEA // (powered by Fernflower decompiler ...
- GCD LCM UVA - 11388
代码很短理解不容易,在这说不清,大家代码里寻真相. 为什么二者相除就可以A了多找点数试试理解理解. #include<stdio.h> #define mod 1000000007 #de ...
- java 常用异常及作用
先看看图, Exception就明白了 关于异常 大体分为 不可查异常 可查异常 runtimeException三类~异常都继承throwable这个类~ 下面有error和Exception两大类 ...
- 学大数据是先学java还是先学python?
大数据的发展趋势日渐明显,但是进入这个领域的门槛不小,除了要有心理准备,其次就是要付诸实际行动中去学习. 学习方法有很多,在没有基础的前提下,自学是因人而异是有难度.其次是大数据目前的工作方向主要是三 ...
- 学习笔记29—Linux基础
一.简单命令: 1.进入文件夹heyi目录:cd ./heyi 2.查看该目录下内容:ls 二.linux压缩和解压缩命令大全 tar命令 解包:tar zxvf FileName.tar 打包:ta ...
- ionic 搜索双向数据绑定失效
1.用data对象存储变化的数据 js: $scope.data={}; $scope.data.keywords = ""; $scope.search = function() ...
- echarts的学习
博客1.:https://zrysmt.github.io/ 博客2:http://blog.csdn.net/future_todo/article/details/60956942 工作中一个需求 ...
- 雷林鹏分享:XML 总结 下一步学习什么呢?
XML 总结 下一步学习什么呢? XML 总结 XML 可用于交换.共享和存储数据. XML 文档形成 树状结构,在"根"和"叶子"的分支机构开始的. XML ...
- 围棋规则 - AlphaGO
参考:4分钟了解围棋规则 看懂柯洁和AlphaGo的对决并不难 围棋规则: 1. 19X19的棋盘上有361个落子点: 2. 黑白棋子依次落子: 3. 比赛结束时,占地多者胜: 4. 上下左右相邻的棋 ...