记一次troubleshooting(一):奇慢的脚本
背景:
事情发生的时间是几年前,那时刚从windows server运维的部门调动过来,对linux和数据库还是处于一知半解的状态。
领导找过来说:前任遗留下来的问题你来调查一下,有个客户说他们的日次脚本跑的慢,以前都勉强在运行,现在快要突破允许时间的上限了。
我马上联系了客户,得知是一个mysql的脚本,测试机运行一个半小时左右,业务机却要运行2个半小时多,超过3个小时就会对业务产生影响了。
解决过程:
虽然当时技术方面不是很懂,但是凭大学时电脑城多年售后修电脑的经历,立马祭出了对比排查大法。
项目 |
业务机 |
测试机 |
硬件 |
4核16GB |
2核4GB |
脚本内容 |
SQL |
SQL |
数据库存放地点 |
NFS挂载盘 |
本地 |
架构 |
Heartbeat,AP/DB双机互为冗余 |
单机 |
Mysql配置文件 |
前任优化过了 |
默认配置 |
Mysql版本 |
5.5 |
5.6 |
1.硬件
看上去是业务机比测试机强很多,但要说服客户,得讲证据拿出数字来。
于是给两台机器上安装nmon,观察了2个脚本运行周期。
结论是测试机的硬件利用率很高,业务机即使在跑脚本的时候也只用了30%的CPU,50%左右的内存,硬盘IO也只在脚本块结束时才升高。硬件问题基本排除。
2.脚本内容
主要的内容是一条14000多字节的SQL文,直觉告诉我这条SQL文有优化的空间。
但是做过运维的同学都知道,运维—开发—客户这3方往往就是:出了问题客户找开发和运维,运维如果不拿出切实的证据证明是开发的问题开发是不会动的。而且这次开发有一条很好的理由:"测试机脚本运行很快"。
作为测试,开启了mysql的slowquerylog,结果如下
业务机:Count: 1 Time=8947.41s
测试机:Count: 1 Time=3802.91s
虽然一条SQL文运行3800秒也不短,但是比业务机短多了,脚本就算没问题吧。
3.数据库存放地点
NFS因为是有校验机制的,速度肯定是比不过本地硬盘。但是根据nmon的磁盘IO数据,瓶颈肯定不是出在NFS上。但是客户一直在怀疑我们双击热备挂NFS的架构有问题,没办法只能测。
看了一下NFS的服务器,是台windowsstorage的服务器,有Iscsi的功能,于是先不管冗余,把NFS上的数据库文件备份后迁移到Iscsi挂载盘,脚本一跑,除了最后阶段IO有所上升外其他照旧,提升的时间以秒计算。
此路不通,回滚设置。
4.架构
上面说过架构也是客户吐槽点。这个测试简单,备份完数据库后进入crm >resource>move资源到同一台机器上。跑完脚本后问题照旧,客户终于认可了架构不是本次问题的原因。
5.Mysql配置
用MySQLTuner测了一下,配置说实话前任已经优化的差不多了,唯一剩下的一个有可能提升性能的就是innodb_file_per_table参数,试试看吧。
Mysqldump备份数据库,备份ibdata1,ib_logfile0,ib_logfile1文件后删除原文件。删除数据库,设置innodb_file_per_table参数,重启mysql,导入数据库。
一系列工作完成后,脚本一跑,老样子。
6.数据库版本
其实最开始看到数据库版本不一致的时候就想到升级数据库。但是由于工程比较麻烦,而且又没有直接的证据证明是数据库版本的问题,领导和客户都不愿意做。开发又一直觉得不是mysql的问题是硬件/架构/优化的问题。
但是所有怀疑的点都排除后,升级数据库就成了最后可能的手段,而且测试机的mysql5.6一直在运行,说明程序在mysql5.6上是没有问题的,怎样说服领导和客户就成了最大的问题。
于是去mysql官网,翻出了mysql5.6的release note,一页一页的看过去,终于发现了这样一段文字"Semi-Join最適化、FROM句のサブクエリの改善"(日语专精比英语等级高,所以看的日文文档),翻译过来就是"优化了Semi-Join,改善了From文中的子查询"。
马上去数据库测试,结果如下:
Mysql5.5带子查询
mysql> select count(*) from (select * from xxxxx limit 20000) a, (select * from xxxxx limit 20000) b where a.ITEM_CD=b.ITEM_CD; +----------+ count(*) +----------+ 398624 +----------+ 1 row in set (2 min 38.51 sec)
Mysql5.6带子查询
mysql> select count(*) from (select * from xxxxx limit 20000) a, (select * from xxxxx limit 20000) b where a.ITEM_CD=b.ITEM_CD; +----------+ count(*) +----------+ 398624 +----------+ 1 row in set (1.43 sec)
Mysql5.5不带子查询
mysql> select count(*) from xxxxx; +----------+ count(*) +----------+ 2246654 +----------+ 1 row in set (1.15 sec)
Mysql5.6不带子查询
mysql> select count(*) from xxxxx; +----------+ count(*) +----------+ 2246654 +----------+ 1 row in set (1.32 sec)
可以看出,不带子查询的话明显硬件强的业务机(mysql5.5)要快,但是带子查询却是测试机(mysql5.6)要快几十倍,而我们可爱的日次脚本正是查询套子查询套子查询套子查询的结构。证据提出后,客户终于同意升级数据库。
于是跑到IDC,用clonezilla和Acronis启动盘做了两套离线整机备份。然后在休息室里远程备份数据库,打包原来的mysql程序文件扔到角落,源码安装mysql5.6,配置文件什么都已经提前写好,考贝进去开启mysql,导入数据库,跑脚本。
漫长的等待后,抽出slowquerylog一看
Count: 1 Time=1600.18s
终于解决了!业务机硬件发挥出了应该有的水平!虽然1600秒也很长,但这已经远远超出了客户的要求,而且不是运维能解决的事情了。
这个经历的教训和心得:
- 技术是多样的,troubleshooting的方法是共通的
- 永远不要奢望别的公司/部门能帮你扛下担子,可以信任的只有身边的同事和自己
- 一个好的想法必须有数字和证据的支撑
- 百度是个坑,找资料去谷歌
记一次troubleshooting(一):奇慢的脚本的更多相关文章
- 记一个简单的保护if 的sh脚本
真是坑爹,就下面的sh,竟然也写了很久! if [ `pwd` != '/usr/xx/bin/tomcat' ] then echo "rstall is not allowed in c ...
- 线代: N阶行列式
线性变换 将 (x, y) 变成 (2 x + y, x - 3 y) 就叫做线性变换, 这就是矩阵乘法, 用于表示一切线性变换. 几何上看, 把平面上的每个点 (x, y) 都变到 (2 x + y ...
- 恢复训练(学不动了摸会鱼) Pt. 1
本来下午想把pre稿子写了,咕咕咕. 群论是啥也不会了,写个polya试试(手动doge)为什么博客媛没有emoji,以后万一自己搭博客一定要加上这个小东西 polya淼题:poj1286 先复吸一下 ...
- git_sop 脚本使用说明
tags : git 前言 脚本下载地址: git是功能非常强大的版本管理工具,同时它带来的是学习成本的上升.最近我们团队的部分项目采用了git进行版本管理,一部分小伙伴对于git使用不是很熟悉.一方 ...
- pythonxy 安装
安装Numpy,发现错误: No module named msvccompiler in numpy.distutils; trying from distutils 目前python除了在 Win ...
- Kafka如何保证消息不丢失不重复
首先需要思考下边几个问题: 消息丢失是什么造成的,从生产端和消费端两个角度来考虑 消息重复是什么造成的,从生产端和消费端两个角度来考虑 如何保证消息有序 如果保证消息不重不漏,损失的是什么 大概总结下 ...
- pyinstaller模块使用
目前pip install pyinstaller已经成熟 但是还是有一些坑,郁闷了好久,记一下注意点吧. 将py脚本打包成exe文件时,如果导入了非python自带库,则需要将导入的库从site-p ...
- Jmeter(七)Jmeter脚本优化(数据与脚本分离)
午休时间再来记一记,嗯..回顾着使用Jmeter的历程,想着日常都会用到的一些功能.一些组件:敲定了本篇的主题----------是的.脚本优化. 说起脚本优化,为什么要优化?又怎么优化?是个永恒的话 ...
- 使用shell脚本常见的一些问题
Jdk版本:jdk-8u102-linux-x64 Tomcat版本:apache-tomcat-7.0.92 Redis版本:redis-5.0.0 由于公司项目的需要,要在多台服务器上面部署一些应 ...
随机推荐
- python学习之——eclipse+pydev 环境搭建
最终选用 eclipse+pydev,网上相关资料也是极多的~~~ 1.安装python: 2.安装eclipse: 3.eclipse中安装pydev,eclipse中help—>eclipl ...
- 构造 & 析构 & 匿名对象
以前仅知道创建对象,但对匿名对象的了解基本为0. 通过阅读google chromium源代码 中关于 log 的使用,查阅相关资料,了解了一下匿名对象,予以记录. 什么是匿名对象 匿名对象可以理 ...
- WinForm richtextbox 关键字变红色
private void HilightRichText(RichTextBox control, string hilightString) { int nSel ...
- Object.create()方法的低版本兼容问题
Object.prototype.create=(function(){ if(Object.prototype.create){return Object.prototype.create}else ...
- zabbix3.0 安装Tips
原文转自:http://www.cnblogs.com/tae44/p/4812190.html#3270843 此处只能留空,否则,提示安装无法进行!!
- Visual studio 生成事件的使用 、xcopy 实现 dll 复制操作、
IF NOT "$(ConfigurationName)"=="publish" exit /B 0if not exist $(TargetPath)publ ...
- 磊科NI360路由器绕过密码登录
先分析正确登陆360路由器后cookies是怎么样的,发现只有一个值如下图: 可以看出登陆后只有一个netcore_login=guest:1 下面来模拟一下这个cookies看是否能登陆 增加好后直 ...
- Spring 4 官方文档学习 Spring与Java EE技术的集成
本部分覆盖了以下内容: Chapter 28, Remoting and web services using Spring -- 使用Spring进行远程和web服务 Chapter 29, Ent ...
- Python执行命令行
背景 我们知道,虽然会破坏平台独立性,但是有的时候需要在代码里面调用命令行来获取一些信息,那么了解在 Python 中如何执行命令行至关重要 使用介绍 Python 中使用命令行可以通过 subpro ...
- Twitter Bootstrap
Twitter Bootstrap是一个HTML/CSS/JS框架,适用于移动设备优先的响应式网页开发.主要涉及: HTML:为已有的H5标签扩展了自定义属性 data-* CSS : Reset + ...