mysql-slow-queries可视化

时间:2013-01-23 11:59:11

标签: mysql logfile

我从网络托管提供商处收到了一个名为mysqld-slow-queries.log的文件。我需要分析这个文件,因为可能有一些函数会导致服务器上的巨大负载。

但是,当我使用Notepad++或类似文件打开文件时,我会看到 14000行的信息,没有任何结构。

是否有可以导入 .log 文件并可视化报告的程序?基本上我希望能够对Query_time值进行排序。

4 个答案:

答案 0 :(得分:0)

这是我用来帮助我解决它的一个低劣的脚本。更改顶部的文件名并执行它。以CSV格式输出详细信息,以便您可以轻松地操作它们(注意,删除CSV文件的第二行,因为它是垃圾)。请注意,我无法确认您所拥有的文件格式是否完全相同,但希望您可以使用此文件来理清您需要的文件。

<?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);
}
?>

答案 1 :(得分:0)

任何查询分析工具都需要解决2个问题。第一个(Kickstart的解决方案似乎没有做)是从查询中删除参数 - 相同的查询将运行很多次但具有不同的参数。第二是集中数据并对其进行报告。

MySQL附带了一个兼具这两个功能的工具 - mysqldumpslow。或者您可以使用this standalone脚本。

您应该优先考虑的查询是具有最高频率和持续时间产品的查询 - 持续时间是执行时间还是锁定时间或两者的组合取决于数据库当前的行为方式。 (但作为一个粗略的经验法则,我会使用(频率^ 1.5)*((锁定时间^ 1.5)+查询时间)用于ISAM表和Innodb的简单产品。

对于执行时间最长的特定查询,如果这些查询很少发生,可能会给出一个非常误导性的图片(虽然它们可能是不支持并发的引擎的特殊问题)。

答案 2 :(得分:0)

还有mysqlsla(mysql慢查询日志分析器)

  

mysqlsla解析,过滤,分析和排序MySQL慢速,通用,二进制和微软补丁日志,以创建查询及其元属性值的可自定义报告。

答案 3 :(得分:0)

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: ...