单条查询问题还是服务器问题()
使用SHOW PROCESSLIST 命令时在尾部加上\G 可以垂直的方式输出结果这很有用 因为这样会将每一行记录的每一列都单独输出为一行 这样可以方便地使用sort|uniq|sort 一类的命令来计算某个列值出现的次数
$ mysql e SHOW PROCESSLIST\G | grep State: | sort | uniq c | sort rn
State:
State: Sending data
State: freeing items
State: NULL
State: end
State: Updating
State: cleaning up
State: update
State: Sorting result
State: logging slow query
如果要查看不同的列只需要修改grep 的模式即可在大多数案例中State 列都非常有用从这个例子的输出中可以看到有很多线程处于查询执行的结束部分的状态包括freeing itemsendcleaning up和logging slow query事实上在案例中的这台服务器上同样模式或类似的输出采样出现了很多次大量的线程处于freeingitems状态是出现了大量有问题查询的很明显的特征和指示
用这种技术查找问题上面的命令行不是唯一的方法如果MySQL 服务器的版本较新也可以直接查询INFORMATION_SCHEMA 中的PROCESSLIST 表或者使用innotop 工具以较高的频率刷新以观察屏幕上出现的不正常查询堆积上面演示的这个例子是由于InnoDB 内部的争用和髒块刷新所导致但有时候原因可能比这个要简单得多一个经典的例子是很多查询处于Locked状态这是MyISAM 的一个典型问题它的表级别锁定在写请求较多时可能迅速导致服务器级别的线程堆积
使用查询日志
如果要通过查询日志发现问题需要开启慢查询日志并在全局级别设置long_query_time 为并且要确认所有的连接都采用了新的设置这可能需要重置所有连接以使新的全局设置生效或者使用Percona Server 的一个特性可以在不断开现有连接的情况下动态地使设置强制生效
如果因为某些原因不能设置慢查询日志记录所有的查询也可以通过tcpdump 和ptquerydigest 工具来模拟替代要注意找到吞吐量突然下降时间段的日志查询是在完成阶段才写入到慢查询日志的所以堆积会造成大量查询处于完成阶段直到阻塞其他查询的资源占用者释放资源后其他的查询才能执行完成这种行为特征的一个好处是当遇到吞吐量突然下降时可以归咎于吞吐量下降后完成的第一个查询(有时候也不一定是第一个查询当某些查询被阻塞时其他查询可以不受影响继续运行所以不能完全依赖这个经验)
再重申一次好的工具可以帮助诊断这类问题否则要人工去几百GB 的查询日志中找原因下面的例子只有一行代码却可以根据MySQL 每秒将当前时间写入日志中的模式统计每秒的查询数量
$ awk /^# Time:/{print $ $ c;c=}/^# User/{c++} slowquerylog
::
::
::
::
::
::
::
::
::
::
::
::
从上面的输出可以看到有吞吐量突然下降的情况发生而且在下降之前还有一个突然的高峰仅从这个输出而不去查询当时的详细信息很难确定发生了什么但应该可以说这个突然的高峰和随后的下降一定有关联不管怎么说这种现象都很奇怪值得去日志中挖掘该时间段的详细信息(实际上通过日志的详细信息可以发现突然的高峰时段有很多连接被断开的现象可能是有一台应用服务器重启导致的所以不是所有的问题都是MySQL 的问题)
理解发现的问题(Making sense of the findings)
可视化的数据最具有说服力上面只演示了很少的几个例子但在实际情况中利用上面的工具诊断时可能产生大量的输出结果可以选择用gnuplot或R或者其他绘图工具将结果绘制成图形这些绘图工具速度很快比电子表格要快得多而且可以对图上的一些异常的地方进行缩放这比在终端中通过滚动条翻看文字要好用得多除非你是黑客帝国中的矩阵观察者
我们建议诊断问题时先使用前两种方法SHOW STATUS和SHOW PROCESSLIST这两种方法的开销很低而且可以通过简单的shell脚本或者反复执行的查询来交互式地收集数据分析慢查询日志则相对要困难一些经常会发现一些蛛丝马迹但仔细去研究时可能又消失了这样我们很容易会认为其实没有问题
发现输出的图形异常意味着什么?通常来说可能是查询在某个地方排队了或者某种查询的量突然飙升了接下来的任务就是找出这些原因
返回目录高性能MySQL
编辑推荐
ASP NET开发培训视频教程
数据仓库与数据挖掘培训视频教程
Oracle索引技术