阅读本文大概需要 2.8 分钟。

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 锁问题。

直接执行 SQL 语句

通过 DEBUG 代码,从 mybatis 中取出映射后的SQL语句,在 MySQL 客户端直接执行 SQL 和 Explain 查看执行计划,速度都很快,排除了 SQL 语句的问题。

查看 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+step where table_name=tableName;

select for update,给这个表加了排它锁,阻止其它事务取得相同数据集的共享读锁和排他写锁,同时,这个序列表表中,用来检索的字段没有加索引,在 InnoDB 行锁机制中:

由于 MySQL 的行锁是针对索引加的锁,不是针对记录加的锁,所以虽然是访问不同行的记录,但是如果是使用相同的索引键(在我们的场景中,就是查询时用到的 table_name),是会出现锁冲突的。

所以了解到其它团队因为查询这个表产生事务问题,造成死锁,这个序列表被锁住了。

由于这个自增序列表每个团队都在使用,所以当时测试环境中,经常有 dao 层超时错误,最终将这些阻塞的线程 kill 掉,为序列表加了索引,解决了问题。

▌小结

下次遇到 MySQL 执行耗时的情况,排除了代码问题之后,要去看数据库是否有死锁的情况存在,观察有没有被阻塞的线程,排查被阻塞的线程具体 info,定位到具体问题。

·END·

程序员的成长之路

路虽远,行则必至

一条SQL要28秒 mysql_一条简单的 SQL 执行超过 1000ms,纳尼?相关推荐

  1. 一条简单的 SQL 执行超过1000ms,纳尼?

    作者:VipAugus https://juejin.im/post/5ce906a3e51d455a2f2201dc MySQL对我说"Too young, too naive!" ...

  2. SQL Server数据库转MySQL_关于Modbus协议转SQL数据库,实现双向通讯

    IGT-SER智能网关模块,支持各种PLC.智能仪表.远程IO与数据库之间双向通讯,既可以读取设备的数据上报到SQL数据库,也可以从数据库查询数据后写入到设备: 网关安装在设备侧,随设备启动.停止,不 ...

  3. sql server clr 集成系列之二 简单的sql 函数

    第一, 新建类库,引用命名空间,using Microsoft.SqlServer.Server; 第二, 编写一个公共类,含有一个公共的静态函数,并且具有特性:[Microsoft.SqlServe ...

  4. 【资源下载】敬勇 - 一条执行时间小于1秒的 SQL 引发的性能问题

    1月13日周四晚,敬勇在云和恩墨大讲堂做了精彩的技术分享,以下为详细的内容整理: 敬勇 ACOUG, CSOUG 核心会员,Oracle Young Expert 某客户软件操作人员反应很慢不能操作, ...

  5. sql如何遍历几百万的表_关于SQL查询效率,100w数据,查询只要1秒

    1.关于SQL查询效率,100w数据,查询只要1秒,与您分享: 机器情况 p4: 2.4 内存: 1 G os: windows 2003 数据库: ms sql server 2000 目的: 查询 ...

  6. sql重复数据只保留一条_一条SQL完成跨数据库实例Join查询

    背景 随着业务复杂程度的提高.数据规模的增长,越来越多的公司选择对其在线业务数据库进行垂直或水平拆分,甚至选择不同的数据库类型以满足其业务需求.原本在同一数据库实例里就能实现的SQL查询,现在需要跨多 ...

  7. [魔方]28秒!地铁站真是个破纪录的好地方

    28秒!一周后,个人新纪录又产生了. 今晚在人民广场地铁站台上候车时,3分钟内连创佳绩:36秒.34秒,一次失误后,突破做出了28秒!当然,运气比较好,从顶面十字复原时,直接完成6面. 上周的32秒, ...

  8. 斯坦福DAWNBench最新训练排名!华为云ModelArts用时10分28秒获全球最快

    允中 发自 凹非寺  量子位 报道 | 公众号 QbitAI 还记得ModelArts吗? 这是今年华为最新发布的AI开发平台,可以提供包括数据标注准备.模型训练.模型调优.模型部署等AI应用开发服务 ...

  9. mysql 慢sql 十几秒_sql优化之慢sql耗时排查

    sql 语句性能分析 1.看 sql 语句执行时间 2.看 sql 的执行计划 3.查看 sql 的执行中各个环节耗时时间 4.查看mysql的执行进程,处理锁表的情况,命令 show PROCESS ...

最新文章

  1. mysql 查询语句 参数,mysql参数化查询语句有关问题
  2. 遴选中计算机类,计算机卓越班遴选办法-计算机学院
  3. matlab在电力行业中的仿真技术-MATLAB基于EKF算法估计电动汽车蓄电池的SOC
  4. 2020-11-25(多级页表的补充)
  5. Eclipse 常用快捷键
  6. mysql 51cto 数据类型_Mysql支持的数据类型
  7. keil4出现目标未被创建_STM32入门系列-创建寄存器模板
  8. (Abstract Factory)抽象工厂模式的Java实现
  9. 2.2.4 ES 6语法与ES 5语法
  10. jdk动态代理为什么只能为接口生成代理类?
  11. 抓取Amazon产品评论的神器
  12. 模糊控制——(1)基本原理
  13. 帝国PHP二次开发,帝国CMS二次开发有哪些注意事项
  14. linux设备树笔记__dts基本概念及语法
  15. java知识体系综合面试题
  16. 计算机主机无信号输出,显示器没信号不显示但电脑主机工作正常的问题
  17. Pandas将列表(List)转换为数据框(Dataframe)进阶篇
  18. 为什么我发的视频播放量老涨不上去?
  19. 《三国演义》人物出场统计
  20. 第一,二,三范式,满足不满足的实例

热门文章

  1. php浮点数计算比较及取整不准确解决方法
  2. JAVA中类似C中memcpy功能
  3. freemarker 读取字符串模板,(非文件)
  4. 用于模拟短信群发情况的随机数产生
  5. visual studio installer正在提取文件_并非危言耸听,赶紧检查自己网盘内的私密文件...
  6. 把表格的一列生成数组
  7. 石墨计算机,高性能计算机助力石墨烯生产工艺的优化
  8. linux查看mq死信队列,linux下postgresql 一主多从、redis集群、rabbitmq等环境搭建 (九) xa-rdmp-archiving 从数据库的安装...
  9. go get 失败 no go files in_Go 每日一库之 dig
  10. MATLAB使用方法和程序设计,实验1 MATLAB使用方法和程序设计