mirror of
https://github.com/major/MySQLTuner-perl.git
synced 2024-09-21 15:57:10 +00:00
Added aborted connection checks
Added % reads/writes counts Adjusted recommendations for slow query logging, max seeks per key, and joins without indexes
This commit is contained in:
parent
44f465ae0a
commit
b3fd62e953
@ -1,4 +1,26 @@
|
||||
#!/usr/bin/perl -w
|
||||
# mysqltuner.pl - High Performance MySQL Tuning Script
|
||||
# Copyright (C) 2006-2007 Major Hayden - major@mhtx.net
|
||||
#
|
||||
# Inspired by Matthew Montgomery's tuning-primer.sh script:
|
||||
# http://forge.mysql.com/projects/view.php?id=44
|
||||
#
|
||||
# Other Contributors:
|
||||
# Paul Kehrer
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use diagnostics;
|
||||
@ -303,6 +325,7 @@ sub calculations {
|
||||
|
||||
# Joins
|
||||
$mycalc{'joins_without_indexes'} = $mystat{'Select_range_check'} + $mystat{'Select_full_join'};
|
||||
$mycalc{'joins_without_indexes_per_day'} = int($mycalc{'joins_without_indexes'} / ($mystat{'Uptime'}/86400));
|
||||
|
||||
# Temporary tables
|
||||
if ($mystat{'Created_tmp_tables'} > 0) {
|
||||
@ -336,8 +359,22 @@ sub calculations {
|
||||
|
||||
# Thread cache
|
||||
$mycalc{'thread_cache_hit_rate'} = int(100 - (($mystat{'Threads_created'} / $mystat{'Connections'}) * 100));
|
||||
|
||||
#foreach my $key (sort keys %mycalc) { print "$key\t\t-> \t".$mycalc{$key}."\n"; }
|
||||
|
||||
# Other
|
||||
if ($mystat{'Connections'} > 0) {
|
||||
$mycalc{'pct_aborted_connections'} = int(($mystat{'Aborted_connects'}/$mystat{'Connections'}) * 100);
|
||||
}
|
||||
if ($mystat{'Questions'} > 0) {
|
||||
$mycalc{'total_reads'} = $mystat{'Com_select'};
|
||||
$mycalc{'total_writes'} = $mystat{'Com_delete'} + $mystat{'Com_insert'} + $mystat{'Com_update'} + $mystat{'Com_replace'};
|
||||
if ($mycalc{'total_reads'} == 0) {
|
||||
$mycalc{'pct_reads'} = 0;
|
||||
$mycalc{'pct_writes'} = 100;
|
||||
} else {
|
||||
$mycalc{'pct_reads'} = int(($mycalc{'total_reads'}/($mycalc{'total_reads'}+$mycalc{'total_writes'})) * 100);
|
||||
$mycalc{'pct_writes'} = 100-$mycalc{'pct_reads'};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
my (@decvars, @incvars, @generalrec);
|
||||
@ -351,7 +388,8 @@ sub mysql_stats {
|
||||
infoprint "Up for: ".pretty_uptime($mystat{'Uptime'})." (".hr_num($mystat{'Questions'}).
|
||||
" q [".hr_num($qps)." qps], ".hr_num($mystat{'Connections'})." conn,".
|
||||
" TX: ".hr_num($mystat{'Bytes_sent'}).", RX: ".hr_num($mystat{'Bytes_received'}).")\n";
|
||||
|
||||
infoprint "Reads / Writes: ".$mycalc{'pct_reads'}."% / ".$mycalc{'pct_writes'}."%\n";
|
||||
|
||||
# Memory usage
|
||||
if ($mycalc{'pct_physical_memory'} > 85) {
|
||||
badprint "Maximum possible memory usage: ".hr_bytes($mycalc{'total_possible_used_memory'})." ($mycalc{'pct_physical_memory'}% of installed RAM)\n";
|
||||
@ -366,7 +404,8 @@ sub mysql_stats {
|
||||
} else {
|
||||
goodprint "Slow queries: $mycalc{'pct_slow_queries'}%\n";
|
||||
}
|
||||
if ($myvar{'long_query_time'} > 5) { push(@decvars,"long_query_time (<= 5)"); }
|
||||
if ($myvar{'long_query_time'} > 10) { push(@decvars,"long_query_time (<= 10)"); }
|
||||
if ($myvar{'log_slow_queries'} eq "OFF") { push(@generalrec,"Enable the slow query log to troubleshoot bad queries"); }
|
||||
|
||||
# Connections
|
||||
if ($mycalc{'pct_connections_used'} > 85) {
|
||||
@ -401,7 +440,7 @@ sub mysql_stats {
|
||||
# No queries have run that would use keys
|
||||
}
|
||||
}
|
||||
if ($mysqlvermajor > 3 && $myvar{'max_seeks_for_key'} > 100) { push(@decvars,"max_seeks_for_key (<= 100)"); }
|
||||
if ($mysqlvermajor > 3 && $myvar{'max_seeks_for_key'} > 1000) { push(@decvars,"max_seeks_for_key (<= 1000)"); }
|
||||
|
||||
# Query cache
|
||||
if ($mysqlvermajor < 4) {
|
||||
@ -441,7 +480,7 @@ sub mysql_stats {
|
||||
}
|
||||
|
||||
# Joins
|
||||
if ($mycalc{'joins_without_indexes'} > 0) {
|
||||
if ($mycalc{'joins_without_indexes_per_day'} > 250) {
|
||||
badprint "Joins performed without indexes: $mycalc{'joins_without_indexes'}\n";
|
||||
push(@incvars,"join_buffer_size (> ".hr_bytes($myvar{'join_buffer_size'}).", or always use indexes with joins)");
|
||||
push(@generalrec,"Adjust your join queries to always utilize indexes");
|
||||
@ -457,6 +496,7 @@ sub mysql_stats {
|
||||
push(@incvars,"tmp_table_size (> ".hr_bytes_rnd($myvar{'tmp_table_size'}).")");
|
||||
push(@incvars,"max_heap_table_size (> ".hr_bytes_rnd($myvar{'max_heap_table_size'}).")");
|
||||
push(@generalrec,"Be sure that tmp_table_size/max_heap_table_size are equal");
|
||||
push(@generalrec,"Reduce your SELECT DISTINCT queries without LIMIT clauses");
|
||||
} else {
|
||||
goodprint "Temporary tables created on disk: $mycalc{'pct_temp_disk'}%\n";
|
||||
}
|
||||
@ -511,6 +551,10 @@ sub mysql_stats {
|
||||
} elsif ($myvar{'concurrent_insert'} eq 0) {
|
||||
push(@generalrec,"Enable concurrent_insert by setting it to 1");
|
||||
}
|
||||
if ($mycalc{'pct_aborted_connections'} > 0) {
|
||||
badprint "Connections aborted: ".$mycalc{'pct_aborted_connections'}."\n";
|
||||
push(@generalrec,"Your applications are not closing MySQL connections properly");
|
||||
}
|
||||
}
|
||||
|
||||
sub make_recommendations {
|
||||
|
Loading…
Reference in New Issue
Block a user