前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >mysql慢日志分析脚本

mysql慢日志分析脚本

原创
作者头像
用户1168904
修改2021-05-19 10:59:27
4150
修改2021-05-19 10:59:27
举报
文章被收录于专栏:运维相关文档

#!/usr/bin/perl

#

# Nathanial Hendle

# http://retards.org/

#

# 2001-06-26 v1.0

#

# This perl script parses a MySQL slow_queries log file

# ignoring all queries less than $min_time and prints

# out how many times a query was greater than $min_time

# with the seconds it took each time to run. The queries

# are sorted by number of times it took; the most often

# query appearing at the bottom of the output.

#

# Usage: mysql_slow_log_parser logfile

#

# ------------------------

# SOMETHING TO THINK ABOUT (aka: how to read output)

# ------------------------

#

# Also, it does to regex substitutions to normalize

# the queries...

#

# $query_string =~ s/\d+/XXX/g;

# $query_string =~ s/([\'\"]).+?([\'\"])/$1XXX$2/g;

#

# These replace numbers with XXX and strings found in

# quotes with XXX so that the same select statement

# with different WHERE clauses will be considered

# as the same query.

#

# so these...

#

# SELECT * FROM offices WHERE office_id = 3;

# SELECT * FROM offices WHERE office_id = 19;

#

# become...

#

# SELECT * FROM offices WHERE office_id = XXX;

#

#

# And these...

#

# SELECT * FROM photos WHERE camera_model LIKE 'Nikon%';

# SELECT * FROM photos WHERE camera_model LIKE '%Olympus';

#

# become...

#

# SELECT * FROM photos WHERE camera_model LIKE 'XXX';

#

#

# ---------------------

# THIS MAY BE IMPORTANT (aka: Probably Not)

# ---------------------

#

# *SO* if you use numbers in your table names, or column

# names, you might get some oddities, but I doubt it.

# I mean, how different should the following queries be

# considered?

#

# SELECT car1 FROM autos_10;

# SELECT car54 FROM autos_11;

#

# I don't think so.

#

$min_time = 0; # Skip queries less than $min_time

$min_rows = 0;

$max_display = 10; # Truncate display if more than $max_display occurances of a query

print "\n Starting... \n";

$query_string = '';

$time = 0;

$new_sql = 0;

##############################################

# Loop Through The Logfile

##############################################

while (<>) {

# Skip Bogus Lines

next if ( m|/.*mysqld, Version:.+ started with:| );

next if ( m|Tcp port: \d+ Unix socket: .*mysql.sock| );

next if ( m|Time\s+Id\s+Command\s+Argument| );

next if ( m|administrator\s+command:| );

# print $_;

# if ( /Query_time:\s+(.*)\s+Lock_time:\s+(.*)\s/ ) {

#if ( /Query_time:\s+(.*)\s+Lock_time:\s+(.*)\s+Rows_examined:\s+(\d+)/ ) {

if ( /Query_time:\s+(.*)\s+Lock_time:\s+(.*)\s+Rows_examined:\s+(.*)/ ) {

$time = $1;

$rows = $3;

$new_sql = 1;

# print "found $1 $3\n";

next;

}

if ( /^\#/ && $query_string ) {

if (($time > $min_time) && ($rows >= $min_rows)) {

$orig_query = $query_string;

$query_string =~ s/\d+/XXX/g;

$query_string =~ s/'([^'\\]*(\\.[^'\\]*)*)'/'XXX'/g;

$query_string =~ s/"([^"\\]*(\\.[^"\\]*)*)"/"XXX"/g;

#$query_string =~ s/([\'\"]).+?([\'\"])/$1XXX$2/g;

#$query_string =~ s/\s+/ /g;

#$query_string =~ s/\n+/\n/g;

push @{$queries{$query_string}}, $time;

push @{$queries_rows{$query_string}}, $rows;

$queries_tot{$query_string} += $time;

$queries_orig{$query_string} = $orig_query;

$query_string = '';

}

} else {

if ($new_sql) {

$query_string = $_;

$new_sql = 0;

} else {

$query_string .= $_;

}

}

}

##############################################

# Display Output

##############################################

foreach my $query ( sort { $queries_tot{$b} <=> $queries_tot{$a} } keys %queries_tot ) {

my $total = 0;

my $cnt = 0;

my @seconds = sort { $a <=> $b } @{$queries{$query}};

my @rows = sort { $a <=> $b } @{$queries_rows{$query}};

($total+=$_) for @seconds;

($cnt++) for @seconds;

print "### " . @{$queries{$query}} . " Quer" . ((@{$queries{$query}} > 1)?"ies ":"y ") . "\n";

print "### Total time: " . $total .", Average time: ".($total/$cnt)."\n";

print "### Taking ";

print @seconds > $max_display ? "$seconds[0] to $seconds[-1]" : sec_joiner(\@seconds);

print " seconds to complete\n";

print "### Rows analyzed ";

print @rows > $max_display ? "$rows[0] - $rows[-1]": sec_joiner(\@rows);

print "\n";

print "$query\n";

print $queries_orig{$query}."\n\n";

}

sub sec_joiner {

my ($seconds) = @_;

$string = join(", ", @{$seconds});

$string =~ s/, (\d+)$/ and $1/;

return $string;

}

exit(0);

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云数据库 SQL Server
腾讯云数据库 SQL Server (TencentDB for SQL Server)是业界最常用的商用数据库之一,对基于 Windows 架构的应用程序具有完美的支持。TencentDB for SQL Server 拥有微软正版授权,可持续为用户提供最新的功能,避免未授权使用软件的风险。具有即开即用、稳定可靠、安全运行、弹性扩缩等特点。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档