Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

(#12412) mysqltuner.pl update

  • Loading branch information...
commit b809e6fd758b58a9643e16c70217be1971809383 1 parent 2f56156
Daniel Black grooverdan authored
Showing with 181 additions and 98 deletions.
  1. +181 −98 files/mysqltuner.pl
279 files/mysqltuner.pl
View
@@ -1,10 +1,10 @@
#!/usr/bin/perl -w
-# mysqltuner.pl - Version 1.0.0
+# mysqltuner.pl - Version 1.2.0
# High Performance MySQL Tuning Script
-# Copyright (C) 2006-2008 Major Hayden - major@mhtx.net
+# Copyright (C) 2006-2011 Major Hayden - major@mhtx.net
#
# For the latest updates, please visit http://mysqltuner.com/
-# Subversion repository available at http://tools.assembla.com/svn/mysqltuner/
+# Git repository available at http://github.com/rackerhacker/MySQLTuner-perl
#
# 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
@@ -20,17 +20,16 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# This project would not be possible without help from:
-# Matthew Montgomery Paul Kehrer
-# Dave Burgess Jonathan Hinds
-# Mike Jackson Nils Breunese
-# Shawn Ashlee Luuk Vosslamber
-# Ville Skytta Trent Hornibrook
-# Jason Gill Mark Imbriaco
-# Greg Eden Aubin Galinotti
-# Giovanni Bechis Bill Bradford
-# Ryan Novosielski Michael Scheidell
-# Blair Christensen Hans du Plooy
-# Victor Trac Everett Barnes
+# Matthew Montgomery Paul Kehrer Dave Burgess
+# Jonathan Hinds Mike Jackson Nils Breunese
+# Shawn Ashlee Luuk Vosslamber Ville Skytta
+# Trent Hornibrook Jason Gill Mark Imbriaco
+# Greg Eden Aubin Galinotti Giovanni Bechis
+# Bill Bradford Ryan Novosielski Michael Scheidell
+# Blair Christensen Hans du Plooy Victor Trac
+# Everett Barnes Tom Krouper Gary Barrueto
+# Simon Greenaway Adam Stein Isart Montane
+# Baptiste M.
#
# Inspired by Matthew Montgomery's tuning-primer.sh script:
# http://forge.mysql.com/projects/view.php?id=44
@@ -38,29 +37,30 @@
use strict;
use warnings;
use diagnostics;
+use File::Spec;
use Getopt::Long;
# Set up a few variables for use in the script
-my $tunerversion = "1.0.0";
+my $tunerversion = "1.2.0";
my (@adjvars, @generalrec);
# Set defaults
my %opt = (
- "nobad" => 0,
- "nogood" => 0,
- "noinfo" => 0,
- "nocolor" => 0,
- "forcemem" => 0,
- "forceswap" => 0,
- "host" => 0,
- "socket" => 0,
- "port" => 0,
- "user" => 0,
- "pass" => 0,
- "skipsize" => 0,
- "checkversion" => 0,
+ "nobad" => 0,
+ "nogood" => 0,
+ "noinfo" => 0,
+ "nocolor" => 0,
+ "forcemem" => 0,
+ "forceswap" => 0,
+ "host" => 0,
+ "socket" => 0,
+ "port" => 0,
+ "user" => 0,
+ "pass" => 0,
+ "skipsize" => 0,
+ "checkversion" => 0,
);
-
+
# Gather the options from the command line
GetOptions(\%opt,
'nobad',
@@ -117,17 +117,19 @@ sub usage {
exit;
}
+my $devnull = File::Spec->devnull();
+
# Setting up the colors for the print styles
-my $good = ($opt{nocolor} == 0)? "[\e[00;32mOK\e[00m]" : "[OK]" ;
-my $bad = ($opt{nocolor} == 0)? "[\e[00;31m!!\e[00m]" : "[!!]" ;
-my $info = ($opt{nocolor} == 0)? "[\e[00;34m--\e[00m]" : "[--]" ;
+my $good = ($opt{nocolor} == 0)? "[\e[0;32mOK\e[0m]" : "[OK]" ;
+my $bad = ($opt{nocolor} == 0)? "[\e[0;31m!!\e[0m]" : "[!!]" ;
+my $info = ($opt{nocolor} == 0)? "[\e[0;34m--\e[0m]" : "[--]" ;
# Functions that handle the print styles
sub goodprint { print $good." ".$_[0] unless ($opt{nogood} == 1); }
sub infoprint { print $info." ".$_[0] unless ($opt{noinfo} == 1); }
sub badprint { print $bad." ".$_[0] unless ($opt{nobad} == 1); }
-sub redwrap { return ($opt{nocolor} == 0)? "\e[00;31m".$_[0]."\e[00m" : $_[0] ; }
-sub greenwrap { return ($opt{nocolor} == 0)? "\e[00;32m".$_[0]."\e[00m" : $_[0] ; }
+sub redwrap { return ($opt{nocolor} == 0)? "\e[0;31m".$_[0]."\e[0m" : $_[0] ; }
+sub greenwrap { return ($opt{nocolor} == 0)? "\e[0;32m".$_[0]."\e[0m" : $_[0] ; }
# Calculates the parameter passed in bytes, and then rounds it to one decimal place
sub hr_bytes {
@@ -227,9 +229,16 @@ sub os_setup {
$physical_memory = `sysctl -n hw.realmem`;
$swap_memory = `swapinfo | grep '^/' | awk '{ s+= \$2 } END { print s }'`;
} elsif ($os =~ /SunOS/) {
- $physical_memory = `/usr/sbin/prtconf | grep Memory | awk '{print \$3}'` or memerror;
+ $physical_memory = `/usr/sbin/prtconf | grep Memory | cut -f 3 -d ' '` or memerror;
chomp($physical_memory);
$physical_memory = $physical_memory*1024*1024;
+ } elsif ($os =~ /AIX/) {
+ $physical_memory = `lsattr -El sys0 | grep realmem | awk '{print \$2}'` or memerror;
+ chomp($physical_memory);
+ $physical_memory = $physical_memory*1024;
+ $swap_memory = `lsps -as | awk -F"(MB| +)" '/MB /{print \$2}'` or memerror;
+ chomp($swap_memory);
+ $swap_memory = $swap_memory*1024*1024;
}
}
chomp($physical_memory);
@@ -283,14 +292,25 @@ sub mysql_setup {
badprint "Attempted to use login credentials from Plesk, but they failed.\n";
exit 0;
}
+ } elsif ( -r "/etc/mysql/debian.cnf" and $doremote == 0 ){
+ # We have a debian maintenance account, use it
+ $mysqllogin = "--defaults-file=/etc/mysql/debian.cnf";
+ my $loginstatus = `mysqladmin $mysqllogin ping 2>&1`;
+ if ($loginstatus =~ /mysqld is alive/) {
+ goodprint "Logged in using credentials from debian maintenance account.\n";
+ return 1;
+ } else {
+ badprint "Attempted to use login credentials from debian maintenance account, but they failed.\n";
+ exit 0;
+ }
} else {
- # It's not Plesk, we should try a login
+ # It's not Plesk or debian, we should try a login
my $loginstatus = `mysqladmin $remotestring ping 2>&1`;
if ($loginstatus =~ /mysqld is alive/) {
# Login went just fine
$mysqllogin = " $remotestring ";
# Did this go well because of a .my.cnf file or is there no password set?
- my $userpath = `ls -d ~ 2>/dev/null`;
+ my $userpath = `printenv HOME`;
if (length($userpath) > 0) {
chomp($userpath);
}
@@ -302,9 +322,9 @@ sub mysql_setup {
print STDERR "Please enter your MySQL administrative login: ";
my $name = <>;
print STDERR "Please enter your MySQL administrative password: ";
- system("stty -echo");
+ system("stty -echo >$devnull 2>&1");
my $password = <>;
- system("stty echo");
+ system("stty echo >$devnull 2>&1");
chomp($password);
chomp($name);
$mysqllogin = "-u $name";
@@ -348,6 +368,52 @@ sub get_all_vars {
$line =~ /([a-zA-Z_]*)\s*(.*)/;
$mystat{$1} = $2;
}
+ # Workaround for MySQL bug #59393 wrt. ignore-builtin-innodb
+ if (($myvar{'ignore_builtin_innodb'} || "") eq "ON") {
+ $myvar{'have_innodb'} = "NO";
+ }
+ # have_* for engines is deprecated and will be removed in MySQL 5.6;
+ # check SHOW ENGINES and set corresponding old style variables.
+ # Also works around MySQL bug #59393 wrt. skip-innodb
+ my @mysqlenginelist = `mysql $mysqllogin -Bse "SHOW ENGINES;" 2>$devnull`;
+ foreach my $line (@mysqlenginelist) {
+ if ($line =~ /^([a-zA-Z_]+)\s+(\S+)/) {
+ my $engine = lc($1);
+ if ($engine eq "federated" || $engine eq "blackhole") {
+ $engine .= "_engine";
+ } elsif ($engine eq "berkeleydb") {
+ $engine = "bdb";
+ }
+ my $val = ($2 eq "DEFAULT") ? "YES" : $2;
+ $myvar{"have_$engine"} = $val;
+ }
+ }
+}
+
+sub security_recommendations {
+ print "\n-------- Security Recommendations -------------------------------------------\n";
+ my @mysqlstatlist = `mysql $mysqllogin -Bse "SELECT CONCAT(user, '\@', host) FROM mysql.user WHERE password = '' OR password IS NULL;"`;
+ if (@mysqlstatlist) {
+ foreach my $line (sort @mysqlstatlist) {
+ chomp($line);
+ badprint "User '".$line."' has no password set.\n";
+ }
+ } else {
+ goodprint "All database users have passwords assigned\n";
+ }
+}
+
+sub get_replication_status {
+ my $slave_status = `mysql $mysqllogin -Bse "show slave status\\G"`;
+ my ($io_running) = ($slave_status =~ /slave_io_running\S*\s+(\S+)/i);
+ my ($sql_running) = ($slave_status =~ /slave_sql_running\S*\s+(\S+)/i);
+ if ($io_running eq 'Yes' && $sql_running eq 'Yes') {
+ if ($myvar{'read_only'} eq 'OFF') {
+ badprint "This replication slave is running with the read_only option disabled.";
+ } else {
+ goodprint "This replication slave is running with the read_only option enabled.";
+ }
+ }
}
# Checks for updates to MySQLTuner
@@ -360,10 +426,10 @@ sub validate_tuner_version {
my $update;
my $url = "http://mysqltuner.com/versioncheck.php?v=$tunerversion";
if (-e "/usr/bin/curl") {
- $update = `/usr/bin/curl --connect-timeout 5 '$url' 2>/dev/null`;
+ $update = `/usr/bin/curl --connect-timeout 5 '$url' 2>$devnull`;
chomp($update);
} elsif (-e "/usr/bin/wget") {
- $update = `/usr/bin/wget -e timestamping=off -T 5 -O - '$url' 2>/dev/null`;
+ $update = `/usr/bin/wget -e timestamping=off -T 5 -O - '$url' 2>$devnull`;
chomp($update);
}
if ($update eq 1) {
@@ -379,15 +445,21 @@ sub validate_tuner_version {
my ($mysqlvermajor,$mysqlverminor);
sub validate_mysql_version {
($mysqlvermajor,$mysqlverminor) = $myvar{'version'} =~ /(\d)\.(\d)/;
- if ($mysqlvermajor < 5) {
+ if (!mysql_version_ge(5)) {
badprint "Your MySQL version ".$myvar{'version'}." is EOL software! Upgrade soon!\n";
- } elsif ($mysqlvermajor == 5) {
- goodprint "Currently running supported MySQL version ".$myvar{'version'}."\n";
- } else {
+ } elsif (mysql_version_ge(6)) {
badprint "Currently running unsupported MySQL version ".$myvar{'version'}."\n";
+ } else {
+ goodprint "Currently running supported MySQL version ".$myvar{'version'}."\n";
}
}
+# Checks if MySQL version is greater than equal to (major, minor)
+sub mysql_version_ge {
+ my ($maj, $min) = @_;
+ return $mysqlvermajor > $maj || ($mysqlvermajor == $maj && $mysqlverminor >= ($min || 0));
+}
+
# Checks for 32-bit boxes with more than 2GB of RAM
my ($arch);
sub check_architecture {
@@ -398,6 +470,9 @@ sub check_architecture {
} elsif (`uname` !~ /SunOS/ && `uname -m` =~ /64/) {
$arch = 64;
goodprint "Operating on 64-bit architecture\n";
+ } elsif (`uname` =~ /AIX/ && `bootinfo -K` =~ /64/) {
+ $arch = 64;
+ goodprint "Operating on 64-bit architecture\n";
} else {
$arch = 32;
if ($physical_memory > 2147483648) {
@@ -421,14 +496,14 @@ sub check_storage_engines {
my $engines;
$engines .= (defined $myvar{'have_archive'} && $myvar{'have_archive'} eq "YES")? greenwrap "+Archive " : redwrap "-Archive " ;
$engines .= (defined $myvar{'have_bdb'} && $myvar{'have_bdb'} eq "YES")? greenwrap "+BDB " : redwrap "-BDB " ;
- $engines .= (defined $myvar{'have_federated'} && $myvar{'have_federated'} eq "YES")? greenwrap "+Federated " : redwrap "-Federated " ;
+ $engines .= (defined $myvar{'have_federated_engine'} && $myvar{'have_federated_engine'} eq "YES")? greenwrap "+Federated " : redwrap "-Federated " ;
$engines .= (defined $myvar{'have_innodb'} && $myvar{'have_innodb'} eq "YES")? greenwrap "+InnoDB " : redwrap "-InnoDB " ;
$engines .= (defined $myvar{'have_isam'} && $myvar{'have_isam'} eq "YES")? greenwrap "+ISAM " : redwrap "-ISAM " ;
- $engines .= (defined $myvar{'have_ndbcluster'} && $myvar{'have_ndbcluster'} eq "YES")? greenwrap "+NDBCluster " : redwrap "-NDBCluster " ;
+ $engines .= (defined $myvar{'have_ndbcluster'} && $myvar{'have_ndbcluster'} eq "YES")? greenwrap "+NDBCluster " : redwrap "-NDBCluster " ;
print "$engines\n";
- if ($mysqlvermajor >= 5) {
+ if (mysql_version_ge(5)) {
# MySQL 5 servers can have table sizes calculated quickly from information schema
- my @templist = `mysql $mysqllogin -Bse "SELECT ENGINE,SUM(DATA_LENGTH),COUNT(ENGINE) FROM information_schema.TABLES WHERE TABLE_SCHEMA NOT IN ('information_schema','mysql') GROUP BY ENGINE ORDER BY ENGINE ASC;"`;
+ my @templist = `mysql $mysqllogin -Bse "SELECT ENGINE,SUM(DATA_LENGTH),COUNT(ENGINE) FROM information_schema.TABLES WHERE TABLE_SCHEMA NOT IN ('information_schema','mysql') AND ENGINE IS NOT NULL GROUP BY ENGINE ORDER BY ENGINE ASC;"`;
foreach my $line (@templist) {
my ($engine,$size,$count);
($engine,$size,$count) = $line =~ /([a-zA-Z_]*)\s+(\d+)\s+(\d+)/;
@@ -436,7 +511,7 @@ sub check_storage_engines {
$enginestats{$engine} = $size;
$enginecount{$engine} = $count;
}
- $fragtables = `mysql $mysqllogin -Bse "SELECT COUNT(TABLE_NAME) FROM information_schema.TABLES WHERE TABLE_SCHEMA NOT IN ('information_schema','mysql') AND Data_free > 0"`;
+ $fragtables = `mysql $mysqllogin -Bse "SELECT COUNT(TABLE_NAME) FROM information_schema.TABLES WHERE TABLE_SCHEMA NOT IN ('information_schema','mysql') AND Data_free > 0 AND NOT ENGINE='MEMORY';"`;
chomp($fragtables);
} else {
# MySQL < 5 servers take a lot of work to get table sizes
@@ -446,23 +521,17 @@ sub check_storage_engines {
foreach my $db (@dblist) {
chomp($db);
if ($db eq "information_schema") { next; }
- if ($mysqlvermajor == 3 || ($mysqlvermajor == 4 && $mysqlverminor == 0)) {
- # MySQL 3.23/4.0 keeps Data_Length in the 6th column
- push (@tblist,`mysql $mysqllogin -Bse "SHOW TABLE STATUS FROM \\\`$db\\\`" | awk '{print \$2,\$6,\$9}'`);
- } else {
- # MySQL 4.1+ keeps Data_Length in the 7th column
- push (@tblist,`mysql $mysqllogin -Bse "SHOW TABLE STATUS FROM \\\`$db\\\`" | awk '{print \$2,\$7,\$10}'`);
+ my @ixs = (1, 6, 9);
+ if (!mysql_version_ge(4, 1)) {
+ # MySQL 3.23/4.0 keeps Data_Length in the 5th (0-based) column
+ @ixs = (1, 5, 8);
}
+ push(@tblist, map { [ (split)[@ixs] ] } `mysql $mysqllogin -Bse "SHOW TABLE STATUS FROM \\\`$db\\\`"`);
}
# Parse through the table list to generate storage engine counts/statistics
$fragtables = 0;
- foreach my $line (@tblist) {
- chomp($line);
- $line =~ /([a-zA-Z_]*)\s+(\d+)\s+(\d+)/;
- my $engine = $1;
- my $size = $2;
- my $datafree = $3;
- if ($size !~ /^\d+$/) { $size = 0; }
+ foreach my $tbl (@tblist) {
+ my ($engine, $size, $datafree) = @$tbl;
if (defined $enginestats{$engine}) {
$enginestats{$engine} += $size;
$enginecount{$engine} += 1;
@@ -507,7 +576,7 @@ sub calculations {
exit 0;
}
# Per-thread memory
- if ($mysqlvermajor > 3) {
+ if (mysql_version_ge(4)) {
$mycalc{'per_thread_buffers'} = $myvar{'read_buffer_size'} + $myvar{'read_rnd_buffer_size'} + $myvar{'sort_buffer_size'} + $myvar{'thread_stack'} + $myvar{'join_buffer_size'};
} else {
$mycalc{'per_thread_buffers'} = $myvar{'record_buffer'} + $myvar{'record_rnd_buffer'} + $myvar{'sort_buffer'} + $myvar{'thread_stack'} + $myvar{'join_buffer_size'};
@@ -530,31 +599,35 @@ sub calculations {
# Slow queries
$mycalc{'pct_slow_queries'} = int(($mystat{'Slow_queries'}/$mystat{'Questions'}) * 100);
-
+
# Connections
$mycalc{'pct_connections_used'} = int(($mystat{'Max_used_connections'}/$myvar{'max_connections'}) * 100);
$mycalc{'pct_connections_used'} = ($mycalc{'pct_connections_used'} > 100) ? 100 : $mycalc{'pct_connections_used'} ;
-
+
# Key buffers
- if ($mysqlvermajor > 3 && !($mysqlvermajor == 4 && $mysqlverminor == 0)) {
+ if (mysql_version_ge(4, 1)) {
$mycalc{'pct_key_buffer_used'} = sprintf("%.1f",(1 - (($mystat{'Key_blocks_unused'} * $myvar{'key_cache_block_size'}) / $myvar{'key_buffer_size'})) * 100);
}
if ($mystat{'Key_read_requests'} > 0) {
$mycalc{'pct_keys_from_mem'} = sprintf("%.1f",(100 - (($mystat{'Key_reads'} / $mystat{'Key_read_requests'}) * 100)));
+ } else {
+ $mycalc{'pct_keys_from_mem'} = 0;
}
- if ($doremote eq 0 and $mysqlvermajor < 5) {
- $mycalc{'total_myisam_indexes'} = `find $myvar{'datadir'} -name '*.MYI' 2>&1 | xargs du -L $duflags '{}' 2>&1 | awk '{ s += \$1 } END { printf (\"%d\",s) }'`;
- } elsif ($mysqlvermajor >= 5) {
- $mycalc{'total_myisam_indexes'} = `mysql $mysqllogin -Bse "SELECT IFNULL(SUM(INDEX_LENGTH),0) FROM information_schema.TABLES WHERE TABLE_SCHEMA NOT IN ('information_schema');"`;
+ if ($doremote eq 0 and !mysql_version_ge(5)) {
+ my $size = 0;
+ $size += (split)[0] for `find $myvar{'datadir'} -name "*.MYI" 2>&1 | xargs du -L $duflags 2>&1`;
+ $mycalc{'total_myisam_indexes'} = $size;
+ } elsif (mysql_version_ge(5)) {
+ $mycalc{'total_myisam_indexes'} = `mysql $mysqllogin -Bse "SELECT IFNULL(SUM(INDEX_LENGTH),0) FROM information_schema.TABLES WHERE TABLE_SCHEMA NOT IN ('information_schema') AND ENGINE = 'MyISAM';"`;
}
- if (defined $mycalc{'total_myisam_indexes'} and $mycalc{'total_myisam_indexes'} =~ /^0\n$/) {
- $mycalc{'total_myisam_indexes'} = "fail";
+ if (defined $mycalc{'total_myisam_indexes'} and $mycalc{'total_myisam_indexes'} == 0) {
+ $mycalc{'total_myisam_indexes'} = "fail";
} elsif (defined $mycalc{'total_myisam_indexes'}) {
chomp($mycalc{'total_myisam_indexes'});
}
-
+
# Query cache
- if ($mysqlvermajor > 3) {
+ if (mysql_version_ge(4)) {
$mycalc{'query_cache_efficiency'} = sprintf("%.1f",($mystat{'Qcache_hits'} / ($mystat{'Com_select'} + $mystat{'Qcache_hits'})) * 100);
if ($myvar{'query_cache_size'}) {
$mycalc{'pct_query_cache_used'} = sprintf("%.1f",100 - ($mystat{'Qcache_free_memory'} / $myvar{'query_cache_size'}) * 100);
@@ -565,17 +638,17 @@ sub calculations {
$mycalc{'query_cache_prunes_per_day'} = int($mystat{'Qcache_lowmem_prunes'} / ($mystat{'Uptime'}/86400));
}
}
-
+
# Sorting
$mycalc{'total_sorts'} = $mystat{'Sort_scan'} + $mystat{'Sort_range'};
if ($mycalc{'total_sorts'} > 0) {
$mycalc{'pct_temp_sort_table'} = int(($mystat{'Sort_merge_passes'} / $mycalc{'total_sorts'}) * 100);
}
-
+
# 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) {
if ($mystat{'Created_tmp_disk_tables'} > 0) {
@@ -584,19 +657,19 @@ sub calculations {
$mycalc{'pct_temp_disk'} = 0;
}
}
-
+
# Table cache
if ($mystat{'Opened_tables'} > 0) {
$mycalc{'table_cache_hit_rate'} = int($mystat{'Open_tables'}*100/$mystat{'Opened_tables'});
} else {
$mycalc{'table_cache_hit_rate'} = 100;
}
-
+
# Open files
if ($myvar{'open_files_limit'} > 0) {
$mycalc{'pct_files_open'} = int($mystat{'Open_files'}*100/$myvar{'open_files_limit'});
}
-
+
# Table locks
if ($mystat{'Table_locks_immediate'} > 0) {
if ($mystat{'Table_locks_waited'} == 0) {
@@ -605,7 +678,7 @@ sub calculations {
$mycalc{'pct_table_locks_immediate'} = int($mystat{'Table_locks_immediate'}*100/($mystat{'Table_locks_waited'} + $mystat{'Table_locks_immediate'}));
}
}
-
+
# Thread cache
$mycalc{'thread_cache_hit_rate'} = int(100 - (($mystat{'Threads_created'} / $mystat{'Connections'}) * 100));
@@ -653,7 +726,7 @@ sub mysql_stats {
} else {
goodprint "Maximum possible memory usage: ".hr_bytes($mycalc{'total_possible_used_memory'})." ($mycalc{'pct_physical_memory'}% of installed RAM)\n";
}
-
+
# Slow queries
if ($mycalc{'pct_slow_queries'} > 5) {
badprint "Slow queries: $mycalc{'pct_slow_queries'}% (".hr_num($mystat{'Slow_queries'})."/".hr_num($mystat{'Questions'}).")\n";
@@ -664,7 +737,7 @@ sub mysql_stats {
if (defined($myvar{'log_slow_queries'})) {
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) {
badprint "Highest connection usage: $mycalc{'pct_connections_used'}% ($mystat{'Max_used_connections'}/$myvar{'max_connections'})\n";
@@ -674,11 +747,11 @@ sub mysql_stats {
} else {
goodprint "Highest usage of available connections: $mycalc{'pct_connections_used'}% ($mystat{'Max_used_connections'}/$myvar{'max_connections'})\n";
}
-
+
# Key buffer
- if (!defined($mycalc{'total_myisam_indexes'}) and $doremote eq 1) {
+ if (!defined($mycalc{'total_myisam_indexes'}) and $doremote == 1) {
push(@generalrec,"Unable to calculate MyISAM indexes on remote MySQL server < 5.0.0");
- } elsif ($mycalc{'total_myisam_indexes'} =~ /^fail$/) {
+ } elsif ($mycalc{'total_myisam_indexes'} =~ /^fail$/) {
badprint "Cannot calculate MyISAM index size - re-run script as root user\n";
} elsif ($mycalc{'total_myisam_indexes'} == "0") {
badprint "None of your MyISAM tables are indexed - add indexes immediately\n";
@@ -696,14 +769,12 @@ sub mysql_stats {
goodprint "Key buffer hit rate: $mycalc{'pct_keys_from_mem'}% (".hr_num($mystat{'Key_read_requests'})." cached / ".hr_num($mystat{'Key_reads'})." reads)\n";
}
} else {
- # For the sake of space, we will be quiet here
# No queries have run that would use keys
}
}
-
+
# Query cache
- if ($mysqlvermajor < 4) {
- # For the sake of space, we will be quiet here
+ if (!mysql_version_ge(4)) {
# MySQL versions < 4.01 don't support query caching
push(@generalrec,"Upgrade MySQL to version 4+ to utilize query caching");
} elsif ($myvar{'query_cache_size'} < 1) {
@@ -720,12 +791,17 @@ sub mysql_stats {
}
if ($mycalc{'query_cache_prunes_per_day'} > 98) {
badprint "Query cache prunes per day: $mycalc{'query_cache_prunes_per_day'}\n";
- push(@adjvars,"query_cache_size (> ".hr_bytes_rnd($myvar{'query_cache_size'}).")")
+ if ($myvar{'query_cache_size'} > 128*1024*1024) {
+ push(@generalrec,"Increasing the query_cache size over 128M may reduce performance");
+ push(@adjvars,"query_cache_size (> ".hr_bytes_rnd($myvar{'query_cache_size'}).") [see warning above]");
+ } else {
+ push(@adjvars,"query_cache_size (> ".hr_bytes_rnd($myvar{'query_cache_size'}).")");
+ }
} else {
goodprint "Query cache prunes per day: $mycalc{'query_cache_prunes_per_day'}\n";
}
}
-
+
# Sorting
if ($mycalc{'total_sorts'} == 0) {
# For the sake of space, we will be quiet here
@@ -737,7 +813,7 @@ sub mysql_stats {
} else {
goodprint "Sorts requiring temporary tables: $mycalc{'pct_temp_sort_table'}% (".hr_num($mystat{'Sort_merge_passes'})." temp sorts / ".hr_num($mycalc{'total_sorts'})." sorts)\n";
}
-
+
# Joins
if ($mycalc{'joins_without_indexes_per_day'} > 250) {
badprint "Joins performed without indexes: $mycalc{'joins_without_indexes'}\n";
@@ -747,7 +823,7 @@ sub mysql_stats {
# For the sake of space, we will be quiet here
# No joins have run without indexes
}
-
+
# Temporary tables
if ($mystat{'Created_tmp_tables'} > 0) {
if ($mycalc{'pct_temp_disk'} > 25 && $mycalc{'max_tmp_table_size'} < 256*1024*1024) {
@@ -786,7 +862,7 @@ sub mysql_stats {
if ($mystat{'Open_tables'} > 0) {
if ($mycalc{'table_cache_hit_rate'} < 20) {
badprint "Table cache hit rate: $mycalc{'table_cache_hit_rate'}% (".hr_num($mystat{'Open_tables'})." open / ".hr_num($mystat{'Opened_tables'})." opened)\n";
- if ($mysqlvermajor eq 6 || ($mysqlvermajor eq 5 && $mysqlverminor ge 1)) {
+ if (mysql_version_ge(5, 1)) {
push(@adjvars,"table_cache (> ".$myvar{'table_open_cache'}.")");
} else {
push(@adjvars,"table_cache (> ".$myvar{'table_cache'}.")");
@@ -818,7 +894,7 @@ sub mysql_stats {
}
# Performance options
- if ($mysqlvermajor == 3 || ($mysqlvermajor == 4 && $mysqlverminor == 0)) {
+ if (!mysql_version_ge(4, 1)) {
push(@generalrec,"Upgrade to MySQL 4.1+ to use concurrent MyISAM inserts");
} elsif ($myvar{'concurrent_insert'} eq "OFF") {
push(@generalrec,"Enable concurrent_insert by setting it to 'ON'");
@@ -829,7 +905,7 @@ sub mysql_stats {
badprint "Connections aborted: ".$mycalc{'pct_aborted_connections'}."%\n";
push(@generalrec,"Your applications are not closing MySQL connections properly");
}
-
+
# InnoDB
if (defined $myvar{'have_innodb'} && $myvar{'have_innodb'} eq "YES" && defined $enginestats{'InnoDB'}) {
if ($myvar{'innodb_buffer_pool_size'} > $enginestats{'InnoDB'}) {
@@ -875,9 +951,16 @@ sub make_recommendations {
validate_mysql_version; # Check current MySQL version
check_architecture; # Suggest 64-bit upgrade
check_storage_engines; # Show enabled storage engines
+security_recommendations; # Display some security recommendations
calculations; # Calculate everything we need
mysql_stats; # Print the server stats
make_recommendations; # Make recommendations based on stats
# ---------------------------------------------------------------------------
# END 'MAIN'
# ---------------------------------------------------------------------------
+
+# Local variables:
+# indent-tabs-mode: t
+# cperl-indent-level: 8
+# perl-indent-level: 8
+# End:
Please sign in to comment.
Something went wrong with that request. Please try again.