我收到了一个mysqld-slow-queries.log
来自我的网络托管服务提供商的文件。我需要分析这个文件,因为可能有一些函数会在服务器上造成巨大的负载。
但是,当我打开带有Notepad++
或类似名称的文件时,我看到14000 行包含信息,没有任何结构。
是否有可以导入.log文件并可视化报告的程序?基本上我希望能够对Query_time
值进行排序。
这是我用来帮助我整理它们的点头脚本。更改顶部的文件名并执行它。以 CSV 格式输出详细信息,以便您轻松操作它们(注意,删除 CSV 文件的第 2 行,因为它是垃圾)。请注意,我无法确认您拥有的文件格式是否完全相同,但希望您可以使用它来整理出您需要的文件。
<?php
$handle = fopen('C:\\somelocation\\mysql-slow.log', "rb");
$fp = fopen('someoutputfile.csv', 'w');
$inline = '';
$inline = fgets($handle, 8192);
$OutLine = array();
$OutLine['Time'] = 'Time';
$OutLine['Timestamp'] = 'Timestamp';
$OutLine['User'] = 'User';
$OutLine['Query_time'] = 'Query_time';
$OutLine['Lock_time'] = 'Lock_time';
$OutLine['Rows_sent'] = 'Rows_sent';
$OutLine['Rows_examined'] = 'Rows_examined';
$OutLine['Database'] = 'Database';
$OutLine['SqlOut'] = 'SqlOut';
WriteOut($fp, $OutLine);
$OutLine = array();
$OutLine['Time'] = '';
$OutLine['Timestamp'] = '';
$OutLine['User'] = '';
$OutLine['Query_time'] = '';
$OutLine['Lock_time'] = '';
$OutLine['Rows_sent'] = '';
$OutLine['Rows_examined'] = '';
$OutLine['Database'] = '';
$OutLine['SqlOut'] = '';
$PossibleUse = true;
$TimeTriggeredOut = true;
$CurrentTime = '';
$CurrentDatabase = '';
while (!feof($handle))
{
switch (true)
{
case substr($inline, 0, 8) == '# Time: ' :
WriteOut($fp, $OutLine);
$PossibleUse = true;
$Timings = explode(': ', $inline);
$CurrentTime = $Timings[1];
$OutLine = array();
$OutLine['Time'] = $CurrentTime;
$OutLine['Timestamp'] = '';
$OutLine['User'] = '';
$OutLine['Query_time'] = '';
$OutLine['Lock_time'] = '';
$OutLine['Rows_sent'] = '';
$OutLine['Rows_examined'] = '';
$OutLine['Database'] = $CurrentDatabase;
$OutLine['SqlOut'] = '';
$TimeTriggeredOut = true;
break;
case substr($inline, 0, 6) == '# User' :
if (!$TimeTriggeredOut)
{
WriteOut($fp, $OutLine);
$PossibleUse = true;
$OutLine = array();
$OutLine['Time'] = $CurrentTime;
$OutLine['Timestamp'] = '';
$OutLine['User'] = '';
$OutLine['Query_time'] = '';
$OutLine['Lock_time'] = '';
$OutLine['Rows_sent'] = '';
$OutLine['Rows_examined'] = '';
$OutLine['Database'] = $CurrentDatabase;
$OutLine['SqlOut'] = '';
}
$OutLine['User'] = $inline;
$TimeTriggeredOut = false;
break;
case substr($inline, 0, 12) == '# Query_time' :
$Timings = explode(' ', $inline);
//print_r($Timings);
$OutLine['Query_time'] = $Timings[2];
$OutLine['Lock_time'] = $Timings[5];
$OutLine['Rows_sent'] = $Timings[7];
$OutLine['Rows_examined'] = $Timings[10];
$PossibleUse = true;
break;
case substr($inline, 0, 14) == 'SET timestamp=' :
$Timings = explode('=', $inline);
$OutLine['Timestamp'] = $Timings[1];
$PossibleUse = true;
break;
case $PossibleUse AND substr($inline, 0, 4) == 'use ' :
$Timings = explode(' ', $inline);
$CurrentDatabase = $Timings[1];
$OutLine['Database'] = $CurrentDatabase;
$PossibleUse = false;
break;
default;
$OutLine['SqlOut'] .= $inline;
}
$inline = fgets($handle, 8192);
}
fclose($fp);
fclose($handle);
function WriteOut($fp, $OutLine)
{
foreach($OutLine as &$aOutLine)
{
$aOutLine = str_replace("\n", " ", $aOutLine);
$aOutLine = str_replace("\r", " ", $aOutLine);
$aOutLine = str_replace("\t", " ", $aOutLine);
}
fputcsv($fp, $OutLine);
}
?>
https://github.com/LeeKemp/mysql-slow-query-log-parser/
一个 ruby 脚本,它以如下格式提供清晰的输出:
################################################################################
1973 Queries
user: XXX[XXX]
url: localhost
ip: []
Taking 2 to 19354 seconds to complete
Locking for 0 to 210 seconds
Average time: 120, Median time 4
Average lock: 0, Median lock 0
SET timestamp=XXX;
SELECT tXXX.id AS idXXX...
################################################################################
2233 Queries
user: ...
任何查询分析工具都需要解决两个问题。第一个(Kickstart 的解决方案似乎没有这样做)是从查询中去除参数——相同的查询将运行很多次,但参数不同。第二个是汇总数据并对其进行报告。
MySQL 附带了一个工具,它可以做到这两个 - mysqldumpslow。或者你可以使用这个独立的脚本。
您应该优先考虑的查询是频率和持续时间乘积最高的查询 - 持续时间是执行时间还是锁定时间或两者的组合取决于您的数据库当前的行为方式。(但作为一个粗略的经验法则,对于 ISAM 表,我会使用 (frequency^1.5) * ((lock time ^ 1.5)+query time) 和 Innodb 的简单产品)。
执着于执行时间最长的特定查询可能会在这些查询不常见时给出一个非常误导性的画面(尽管它们可能是不支持并发的引擎的一个特殊问题)。
还有mysqlsla(mysql慢查询日志分析器)
mysqlsla 解析、过滤、分析和排序 MySQL 慢、一般、二进制和微慢补丁日志,以便创建查询及其元属性值的可定制报告。