一条简单的 SQL 执行超过1000ms,纳尼?
作者:VipAugus
https://juejin.im/post/5ce906a3e51d455a2f2201dc
MySQL对我说“Too young, too naive!"
大概过程
在测试环境Docker容器中,在跨进程调用服务的时候,A应用通过Dubbo调用B应用的RPC接口,发现B应用接口超时错误,接着通过debug和日志,发现具体耗时的地方在于一句简单SQL执行,但是耗时超过1000ms。
通过查看数据库的进程列表,发现是有死锁锁表了,很多进程状态status处于'sending data',最后为锁住的表添加索引,并且kill掉阻塞的请求,解除死锁,服务速度恢复正常。
下面记录的是大致排查过程:
通过观察业务代码,确认没有内存溢出或者其它事务问题,于是只能考虑Docker环境的数据库和jvm底层详情了。
使用Druid监控SQL执行状态
通过日志,发现有一句SQL严重超时,一句简单SQL,原本是批量插入多条记录,为了定位问题,测试时Mybatis只插入一条记录,但即便如此,还是耗时10秒
于是打算使用阿里巴巴的数据库连接池Druid进行监控,监控SQL效果如下:
在SQL监控Tab中,可以看到执行SQL的具体情况,包括某条SQL语句执行的时间(平均、最慢)、SQL执行次数、SQL执行出错的次数等。
上面显示的是正常情况下,时间单位是ms,正常的SQL一般在10ms之内,数据量大的控制在30ms之内,这样用户的使用体验感才会良好。所以说之前的1000ms,是不可接受的结果。
通过JMC远程监控Tomcat
JMC(java mission control)是jdk自带的一个监控工具,在jdk的bin目录下(java大法好,该目录下有很多实用的工具)。
此处加了一个tomcat无验证模式:
#在tomcat的conf目录下的catalina.sh增加如下java启动参数:-Dcom.sun.management.jmxremote=true-Dcom.sun.management.jmxremote.port=8888-Dcom.sun.management.jmxremote.ssl=false-Dcom.sun.management.jmxremote.authenticate=false-XX:+UnlockCommercialFeatures -XX:+FlightRecorder
下面是自己本地调试的截图
然后打开jmc,创建一个JMX连接,输入对应的ip和JMX端口。接着可以设定一段时间内的飞行监控,监测这一分钟内jvm具体参数
当时调试的时候,发现内存使用、CPU占用率、线程状态也挺正常的,没有发现明显的异常错误,效果如下图:
唯一比较耗时的是在代码tab页中,当时发现了大量的I/O,比上图的比例还高,当时大概占了80%,查看调用树,很多循环tcp socket连接,考虑到应用中本来就有很多需要io以及netty也需要tcp连接,所以大概排除了jvm虚拟机的问题,然后就去排查MySQL的问题。
排查MySQL
在了解MySQL锁概念的时候,由于现在使用的比较多的是InnoDB,所以可以着重看看InnoDB锁问题。推荐:MySQL全面优化,速度飞起来!
直接执行SQL语句
通过DEBUG代码,从mybatis中取出映射后的SQL语句,在MySQL客户款直接执行SQL和Explain查看执行计划,速度都很快,排除了SQL语句的问题。推荐:专业解决 MySQL 查询速度慢与性能差!。
查看MySQL线程列表
show processlist;
从图中可以看出,有些线程的状态处于sending data,查阅资料:所谓的“Sending data”并不是单纯的发送数据,而是包括“收集 + 发送 数据”。
然后后面一列info显示的是具体信息,是查询用来生成主键ID的函数,之前速度都很快,为啥突然就这么慢呢,于是回过头去查看该函数:
select next_value into ret_val from `xxx` where table_name=tableName for update;update `xxx` set current_value=current_value+step, next_value=next_value+stepwhere table_name=tableName;
select for update,给这个表加了排它锁,阻止其它事务取得相同数据集的共享读锁和排他写锁,同时,这个序列表表中,用来检索的字段没有加索引,在InnoDB行锁机制中:
由于MySQL的行锁是针对索引加的锁,不是针对记录加的锁,所以虽然是访问不同行的记录,但是如果是使用相同的索引键(在我们的场景中,就是查询时用到的table_name),是会出现锁冲突的。
所以了解到其它团队因为查询这个表产生事务问题,造成死锁,这个序列表被锁住了。Java提升篇-事务隔离级别和传播机制Java提升篇-事务隔离级别和传播机制
由于这个自增序列表每个团队都在使用,所以当时测试环境中,经常有dao层超时错误,最终将这些阻塞的线程kill掉,为序列表加了索引,解决了问题。
小结
下次遇到MySQL执行耗时的情况,排除了代码问题之后,要去看数据库是否有死锁的情况存在,观察有没有被阻塞的线程,排查被阻塞的线程具体info,定位到具体问题。
欢迎吐槽
具体排查过程是这样,其中还有些细节问题,思路或者方法有误,请在评论区指出。
关注Java技术栈微信公众号,在后台回复关键字:Java,可以获取一份栈长整理的 Java 最新技术干货。
最近干货分享
点击「阅读原文」一起搞技术,爽~
一条简单的 SQL 执行超过1000ms,纳尼?的更多相关文章
- 一条简单的 SQL 执行超过 1000ms,纳尼?
阅读本文大概需要 2.8 分钟. MySQL 对我说 “Too young, too naive!" ▌大概过程 在测试环境 Docker 容器中,在跨进程调用服务的时候,A 应用通过 Du ...
- 34条简单的SQL优化准则
转载地址:http://bbs.csdn.net/topics/260002113 我们要做到不但会写SQL,还要做到写出性能优良的SQL,以下为笔者学习.摘录.并汇总部分资料与大家分享!(1) ...
- 一条简单的 SQL 查询语句到底经历了什么?
一.MySQL 基础架构 整体来说 MySQL 主要分为两个部分,一个部分是:Server 层,另一部分是:存储引擎层. 其中 Server 层包括有连接器.查询缓存.分析器.优化器.执行器等,存 ...
- 转://从一条巨慢SQL看基于Oracle的SQL优化
http://mp.weixin.qq.com/s/DkIPwbDKIjH2FMN13GkT4w 本次分享的内容是基于Oracle的SQL优化,以一条巨慢的SQL为例,从快速解读SQL执行计划.如何从 ...
- 从一条巨慢SQL看基于Oracle的SQL优化(重磅彩蛋+PPT)
本文根据DBAplus社群第110期线上分享整理而成,文末还有好书送哦~ 讲师介绍 丁俊 新炬网络首席性能优化专家 SQL审核产品经理 DBAplus社群联合发起人.<剑破冰山-Oracle开发 ...
- 如何更简单方便地执行SQL操作?
现在公司使用mybatis作为DAL层的框架. 使用起来比较简单,使用xml进行SQL的书写,java代码使用接口执行. 但在写一些简单SQL的时候会显得非常繁琐: xml和java分离(设计上为了解 ...
- 大型面试现场:一条update sql执行都经历什么?
导读 Hi,大家好!我是白日梦!本文是MySQL专题的第 24 篇. 今天我要跟你分享的MySQL话题是:"从一条update sql执行都经历什么开始,发散开一系列的问题,看看你能抗到第几 ...
- 一条sql语句搞定基于mysql的sql执行顺序的基本理解
对数据库基本操作是每个程序员基本功,如何理解并快速记住sql执行的顺序呢,其实一条复杂的sql就能搞定: SELECT DISTINCT <select_list> FROM <le ...
- log4j.xml简单配置实现在控制台打印sql执行语句【加注释】
转: log4j.xml简单配置实现在控制台打印sql执行语句 2017年09月27日 13:02:34 艾然丶 阅读数 8804 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协 ...
随机推荐
- HDU3951_Coin Game
Coin Game Problem Description 一堆n个硬币围成一圈,两个人轮流拿走连续k个硬币,拿走最后一堆的人获胜 问你第一个人获胜还是第二个 思路: 这是NIM游戏改编版本 但是道理 ...
- web.xml中servlet mapping标签
写了好多小项目后也没弄明白<url-pattern>的真正意义,写跳转的时候也是跳的三心二意的,今天查了一下web.xml的详细配置,看了看servlet-mapping的讲解,豁然开朗, ...
- jquery 查找元素,id,class
查找元素下的class 带有.pageactive的a标签 $('a.pageactive') 标签a和..pageactive不要有空格,有空格找不到 ======================= ...
- ubantu18.04中mysql8.0设置远程连接的问题
在mysql8.0中的配置文件中默认是没有绑定地址的,但是可以自己配置,在my.cnf中 这里使用另一种方式: 首先先连接到自己的数据库执行: use mysql; select host,user ...
- Codeforces 492E Vanya and Field
E. Vanya and Field time limit per test 2 seconds memory limit per test 256 megabytes input standard ...
- SPI、IIC、IIS、UART、JTAG的应用场合级区别
SPI SPI接口的全称是"Serial Peripheral Interface",意为串行外围接口,是Motorola首先在其MC68HCXX系列处理器上定义的. SPI接口 ...
- VMware Converter Standalone迁移概要
VMware Converter 迁移工具使用:1.基本概念 1.1基本组件: converter standalone server:包含server和worker两个服务,这两个服务经常一起安装 ...
- python3学习笔记——数字、字符串、列表、字典、元组
什么是python解释器? python代码在解释器中运行.解释器是代码与计算机硬件之间的软件逻辑层. python的执行过程 ...
- Python 的PIL,可以解决ImportError The _imagingft C module is not installed
删除PIL相关文件 mv PIL /tmp pip install Pillow 安装Pillow后, 可能还会发生KeyError的错误, 检查项目源码后发现是 Image 模块的save函数中 ...
- data-*存数据,拿出ul li中的数据
<ul class="questions"> <li> <div class="question">1.您的年龄是?< ...