排查网站查询缓慢故障

2019-12-24 00:44:01河南刘进京
网络安全和信息化 2019年11期
关键词:磁盘线程命令

■河南 刘进京

某商品销售网站出现了查询缓慢的问题,当执行商品信息查询时,需要等待十几秒才出现回应信息,这给用户正常访问带来了不便。

该网站采用了Python Flask 开发,后台使用的是MySQL 数据库,所有的商品信息都存储在MySQL 数据库中,用户或应用可以通过MySQL接口,根据提供的商品信息,来查询对应的数据。但是过于缓慢的查询速度,让网站无法正常为外界提供服务。

故障排查

登录到Web 服务器上,对系统状态进行检测,发现当执行任意命令后,都会稍微停顿一下才看到回应信息,可以明显察觉系统响应速度变慢。

对于该情况,首先查看系统资源使用情况,检测其是否存在异常状态。执行“top”命令,在返回信息中可以看到,两个CPU 的iowait 值都比较高,尤其对于CPI0 来说,其iowait 的值已经超过70%。但是对于各个进程进行查看,其CPU 占用率并不高。

根据以上分析,CPU 的使用情况还算比较正常,接下来需要排查I/O 使用情况,检测问题是都磁盘的I/O 瓶颈有关。执行“iostat”命令,根据返回信息,发现磁盘每秒的读取速率较高,I/O 使用率为98%,几乎处于完全饱和的状态。这表明磁盘的读取出现了瓶颈。

接着需要找到究竟是什么进程造成了这么高的磁盘读取情况。执行“pidstat-d 1”命令,显示进程的I/O使用情况。

在返回信息中看到,对于PID 为28716 的进程来说,在其“kB_rd/s”列中显示较高的磁盘读取值,这说明该进程正在进行大量的读操作,其读取的速率和上述执行“iostat”命令检测到的数值基本一致,该PID 对应的是“mysqld”进程。这说明“mysqld”进程引发了I/O 瓶颈问题。

但是,该进程为什么要去读取大量的磁盘数据呢,这很有可能和MySQL 的慢查询有关。对于慢查询来说,其造成的故障现象基本上都会CPU 使用率过高的问题,一般并不会引发I/O 瓶颈。

要想对MySQL 读取数据情况进行分析,需要使用到Strace 命令。我们知道,Strace 是一个可用于诊断、调试和教学的Linux 用户空间跟踪器。可以利用该命令来监控用户空间进程和内核的交互,比如系统调用、信号传递、进程状态变更等。因为MySQL 是一个支持多线程的数据库工具,因此需要对其使用到的线程进行全面分析。

执 行“strace -f -p 28716”命令,在返回信息中显示和MySQL 相关的所有线程的数据读取信息,可以看到PID 为21970 的线程正在读取大量的磁盘数据,其读取的文件描述符编号为91,接着需要查找与该编号对应的文件。

执行“lsof -p 21970”命令,奇怪的是并没有返回任何信息,说明没有找到对应的文件。执行“echo $?”命令,得到的返回值为“1”,这说明上述命令执行失败,因为只有返回“0”,才说明没有问题。这表明MySQL 使用了很多线程,仅仅使用其中一个线程号进行查询是没有办法找到目标文件的。

执行“lsof -p 28716”命令,使用MySQL 的进程的PID 进行查看,在返回信息中显示MySQL 打开了很多的文件,根据上述文件描述符的编号,发现与其对应的文件为“/var/lib/data/products.myd”,注意MySQL是以读写方式访问该文件的。

根据这些信息,说明使用了MyISAM 引擎来存储数据。即MySQL 在读取“DATA”数据库中的“products”数据表。进入该目录,执行“ls”命令,可以显示相关的表文件,索引文件,元数据文件和原信息文件等。

进入MySQL 控制台,执行“show global variables like "%datadir% ";”命令,可以看到MySQL 当前正在使用的数据库路径,这和上述查询到的信息一致。执行“show full processlist;”命令,在返回信息中显示当前的用户名、主机名、使用的数据库名称、执行的命令类型,执行的时间、状态、执行的语句等信息,例如在“Command”列中显示“query”,表示执行的额是查询操作,在“Info”列中显示具体的查询语句。

故障解决

对于MySQL 的慢查询来说,如果没有设置好索引的话,很容易出现查询缓慢的问题。执行“use data;”,“explain xxx;”命令,其中的“xxx”为在上述命令中找到的查询命令。

在返回信息中的“select_type”列中显示查询的类型,这里显示为“simple”,表示查询中没有包括“union”查询或者子查询,在“table”列中显示数据表的名称,在“type”列中显示查询类型,在“possible_keys”列中显示可能引用的索引,这里为“NULL”。在“key”列中显示确切使用的索引,这里为“NULL”。在“rows”列中显示扫描的行数。

根据以上分析,这里并没有使用索引,当扫描的行数很多时,自然会出现反应迟缓的问题。

看来,只要为其配置好索引,问题就可以解决了。执 行“CREATE INDEX products_index ON products(produceID);”命令,为该表添加索引,但是出现“EEEOR 1170”的错误信息,这说明必须为该字段设置一个合适的前缀长度。

执行“CREATE INDEX products_index ONproducts(product ID(64));”命令,使用一个合适的的数值来充当前缀,顺利为该表创建索引。这样,再执行查询时,可以看到速度大大提高了。

根据以上分析,不难发现对于MySQL慢查询来说,如果没有设置索引的话,很容易出现查询缓慢的问题。其实,对于MySQL 的MyISAM 引擎来说,其主要依靠系统缓存来加速磁盘的I/O 访问,如果系统中存在其他的进程,必然会占用一定的系统缓存,就会造成MyISAM引擎引擎难以充分利用系统缓存,自然会造成运行缓慢等问题。

所以,不要将MySQL 等程序的的性能优化完全建立在系统缓存之上,最好能够在应用程序内部分配内存,组建完全自主控制的缓存管理机制。

猜你喜欢
磁盘线程命令
只听主人的命令
解决Windows磁盘签名冲突
电脑爱好者(2019年2期)2019-10-30 03:45:31
修改磁盘属性
移防命令下达后
磁盘组群组及iSCSI Target设置
浅谈linux多线程协作
环球市场(2017年36期)2017-03-09 15:48:21
创建VSAN群集
这是人民的命令
蓝色命令
Linux线程实现技术研究