Fixed a bug in MySQL 3.23 where the storage engine checks had problems
Adjusted some of the Perl code to be more compact, organized, and factored
This commit is contained in:
parent
9ccae41ead
commit
e693649bf9
1 changed files with 112 additions and 116 deletions
210
mysqltuner.pl
210
mysqltuner.pl
|
@ -34,6 +34,9 @@ use warnings;
|
||||||
use diagnostics;
|
use diagnostics;
|
||||||
use Getopt::Long;
|
use Getopt::Long;
|
||||||
|
|
||||||
|
# Set up a few variables for use in the script
|
||||||
|
my (@adjvars, @generalrec);
|
||||||
|
|
||||||
# Set defaults
|
# Set defaults
|
||||||
my %opt = (
|
my %opt = (
|
||||||
"nobad" => 0,
|
"nobad" => 0,
|
||||||
|
@ -54,6 +57,7 @@ GetOptions(\%opt,
|
||||||
if (defined $opt{'help'} && $opt{'help'} == 1) { usage(); }
|
if (defined $opt{'help'} && $opt{'help'} == 1) { usage(); }
|
||||||
|
|
||||||
sub usage {
|
sub usage {
|
||||||
|
# Shown with --help option passed
|
||||||
print "\n".
|
print "\n".
|
||||||
" MySQL High Performance Tuning Script\n".
|
" MySQL High Performance Tuning Script\n".
|
||||||
" Bug reports, feature requests, and downloads at http://mysqltuner.com/\n".
|
" Bug reports, feature requests, and downloads at http://mysqltuner.com/\n".
|
||||||
|
@ -71,46 +75,81 @@ sub usage {
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
# CONFIGURATION ITEMS
|
# Setting up the colors for the print styles
|
||||||
my ($good,$bad,$info);
|
my $good = ($opt{nocolor} == 0)? "[\e[00;32mOK\e[00m]" : "[OK]" ;
|
||||||
if ($opt{nocolor} == 0) {
|
my $bad = ($opt{nocolor} == 0)? "[\e[00;31mOK\e[00m]" : "[!!]" ;
|
||||||
$good = "[\e[00;32mOK\e[00m]";
|
my $info = ($opt{nocolor} == 0)? "[\e[00;34mOK\e[00m]" : "[--]" ;
|
||||||
$bad = "[\e[00;31m!!\e[00m]";
|
|
||||||
$info = "[\e[00;34m**\e[00m]";
|
# 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 "\e[00;31m".$_[0]."\e[00m"; }
|
||||||
|
sub greenwrap { return "\e[00;32m".$_[0]."\e[00m"; }
|
||||||
|
|
||||||
|
# Calculates the parameter passed in bytes, and then rounds it to one decimal place
|
||||||
|
sub hr_bytes {
|
||||||
|
my $num = shift;
|
||||||
|
if ($num >= (1024**3)) { #GB
|
||||||
|
return sprintf("%.1f",($num/(1024**3)))."G";
|
||||||
|
} elsif ($num >= (1024**2)) { #MB
|
||||||
|
return sprintf("%.1f",($num/(1024**2)))."M";
|
||||||
|
} elsif ($num >= 1024) { #KB
|
||||||
|
return sprintf("%.1f",($num/1024))."K";
|
||||||
} else {
|
} else {
|
||||||
$good = "[OK]";
|
return $num."B";
|
||||||
$bad = "[!!]";
|
}
|
||||||
$info = "[--]";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sub goodprint {
|
# Calculates the parameter passed in bytes, and then rounds it to the nearest integer
|
||||||
if ($opt{nogood} == 1) { return 0; }
|
sub hr_bytes_rnd {
|
||||||
my $text = shift;
|
my $num = shift;
|
||||||
print $good." ".$text;
|
if ($num >= (1024**3)) { #GB
|
||||||
|
return int(($num/(1024**3)))."G";
|
||||||
|
} elsif ($num >= (1024**2)) { #MB
|
||||||
|
return int(($num/(1024**2)))."M";
|
||||||
|
} elsif ($num >= 1024) { #KB
|
||||||
|
return int(($num/1024))."K";
|
||||||
|
} else {
|
||||||
|
return $num."B";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sub infoprint {
|
# Calculates the parameter passed to the nearest power of 1000, then rounds it to the nearest integer
|
||||||
if ($opt{noinfo} == 1) { return 0; }
|
sub hr_num {
|
||||||
my $text = shift;
|
my $num = shift;
|
||||||
print $info." ".$text;
|
if ($num >= (1000**3)) { # Billions
|
||||||
|
return int(($num/(1000**3)))."B";
|
||||||
|
} elsif ($num >= (1000**2)) { # Millions
|
||||||
|
return int(($num/(1000**2)))."M";
|
||||||
|
} elsif ($num >= 1000) { # Thousands
|
||||||
|
return int(($num/1000))."K";
|
||||||
|
} else {
|
||||||
|
return $num;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sub badprint {
|
# Calculates uptime to display in a more attractive form
|
||||||
if ($opt{nobad} == 1) { return 0; }
|
sub pretty_uptime {
|
||||||
my $text = shift;
|
my $uptime = shift;
|
||||||
print $bad." ".$text;
|
my $seconds = $uptime % 60;
|
||||||
}
|
my $minutes = int(($uptime % 3600) / 60);
|
||||||
|
my $hours = int(($uptime % 86400) / (3600));
|
||||||
sub redwrap {
|
my $days = int($uptime / (86400));
|
||||||
my $text = shift;
|
my $uptimestring;
|
||||||
return "\e[00;31m".$text."\e[00m";
|
if ($days > 0) {
|
||||||
}
|
$uptimestring = "${days}d ${hours}h ${minutes}m ${seconds}s";
|
||||||
|
} elsif ($hours > 0) {
|
||||||
sub greenwrap {
|
$uptimestring = "${hours}h ${minutes}m ${seconds}s";
|
||||||
my $text = shift;
|
} elsif ($minutes > 0) {
|
||||||
return "\e[00;32m".$text."\e[00m";
|
$uptimestring = "${minutes}m ${seconds}s";
|
||||||
|
} else {
|
||||||
|
$uptimestring = "${seconds}s";
|
||||||
|
}
|
||||||
|
return $uptimestring;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Retrieves the memory installed on this machine
|
||||||
my ($physical_memory,$swap_memory,$duflags);
|
my ($physical_memory,$swap_memory,$duflags);
|
||||||
sub os_setup {
|
sub os_setup {
|
||||||
my $os = `uname`;
|
my $os = `uname`;
|
||||||
|
@ -132,6 +171,7 @@ sub os_setup {
|
||||||
chomp($physical_memory);
|
chomp($physical_memory);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Checks to see if a MySQL login is possible
|
||||||
my $mysqllogin;
|
my $mysqllogin;
|
||||||
sub mysql_setup {
|
sub mysql_setup {
|
||||||
my $command = `which mysqladmin`;
|
my $command = `which mysqladmin`;
|
||||||
|
@ -144,10 +184,7 @@ sub mysql_setup {
|
||||||
# It's a Plesk box, use the available credentials
|
# It's a Plesk box, use the available credentials
|
||||||
$mysqllogin = "-u admin -p`cat /etc/psa/.psa.shadow`";
|
$mysqllogin = "-u admin -p`cat /etc/psa/.psa.shadow`";
|
||||||
my $loginstatus = `mysqladmin ping $mysqllogin 2>&1`;
|
my $loginstatus = `mysqladmin ping $mysqllogin 2>&1`;
|
||||||
if ($loginstatus =~ /mysqld is alive/) {
|
unless ($loginstatus =~ /mysqld is alive/) {
|
||||||
# Login was successful, but we won't say anything to save space
|
|
||||||
return 1;
|
|
||||||
} else {
|
|
||||||
badprint "Attempted to use login credentials from Plesk, but they failed.\n";
|
badprint "Attempted to use login credentials from Plesk, but they failed.\n";
|
||||||
exit 0;
|
exit 0;
|
||||||
}
|
}
|
||||||
|
@ -160,16 +197,14 @@ sub mysql_setup {
|
||||||
# Did this go well because of a .my.cnf file or is there no password set?
|
# Did this go well because of a .my.cnf file or is there no password set?
|
||||||
my $userpath = `ls -d ~`;
|
my $userpath = `ls -d ~`;
|
||||||
chomp($userpath);
|
chomp($userpath);
|
||||||
if ( -e "$userpath/.my.cnf" ) {
|
unless ( -e "$userpath/.my.cnf" ) {
|
||||||
# Login was successful, but we won't say anything to save space
|
|
||||||
} else {
|
|
||||||
badprint "Successfully authenticated with no password - SECURITY RISK!\n";
|
badprint "Successfully authenticated with no password - SECURITY RISK!\n";
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
print STDERR "Please enter your MySQL login: ";
|
print STDERR "Please enter your MySQL administrative login: ";
|
||||||
my $name = <>;
|
my $name = <>;
|
||||||
print STDERR "Please enter your MySQL password: ";
|
print STDERR "Please enter your MySQL administrative password: ";
|
||||||
system("stty -echo");
|
system("stty -echo");
|
||||||
my $password = <>;
|
my $password = <>;
|
||||||
system("stty echo");
|
system("stty echo");
|
||||||
|
@ -178,7 +213,6 @@ sub mysql_setup {
|
||||||
$mysqllogin = "-u $name -p'$password'";
|
$mysqllogin = "-u $name -p'$password'";
|
||||||
my $loginstatus = `mysqladmin ping $mysqllogin 2>&1`;
|
my $loginstatus = `mysqladmin ping $mysqllogin 2>&1`;
|
||||||
if ($loginstatus =~ /mysqld is alive/) {
|
if ($loginstatus =~ /mysqld is alive/) {
|
||||||
# Login was successful, but we won't say anything to save space
|
|
||||||
print STDERR "\n";
|
print STDERR "\n";
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
|
@ -190,6 +224,7 @@ sub mysql_setup {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Populates all of the variable and status hashes
|
||||||
my (%mystat,%myvar,$dummyselect);
|
my (%mystat,%myvar,$dummyselect);
|
||||||
sub get_all_vars {
|
sub get_all_vars {
|
||||||
# We need to initiate at least one query so that our data is useable
|
# We need to initiate at least one query so that our data is useable
|
||||||
|
@ -206,6 +241,7 @@ sub get_all_vars {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Checks for supported or EOL'ed MySQL versions
|
||||||
my ($mysqlvermajor,$mysqlverminor);
|
my ($mysqlvermajor,$mysqlverminor);
|
||||||
sub validate_mysql_version {
|
sub validate_mysql_version {
|
||||||
print "-------- General Statistics --------------------------------------------------\n";
|
print "-------- General Statistics --------------------------------------------------\n";
|
||||||
|
@ -219,6 +255,7 @@ sub validate_mysql_version {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Checks for 32-bit boxes with more than 2GB of RAM
|
||||||
my ($arch);
|
my ($arch);
|
||||||
sub check_architecture {
|
sub check_architecture {
|
||||||
if (`uname -m` =~ /64/) {
|
if (`uname -m` =~ /64/) {
|
||||||
|
@ -226,7 +263,7 @@ sub check_architecture {
|
||||||
goodprint "Operating on 64-bit architecture\n";
|
goodprint "Operating on 64-bit architecture\n";
|
||||||
} else {
|
} else {
|
||||||
$arch = 32;
|
$arch = 32;
|
||||||
if ($physical_memory > 2*1024*1024*1024) {
|
if ($physical_memory > 2147483648) {
|
||||||
badprint "Switch to 64-bit OS - MySQL cannot currenty use all of your RAM\n";
|
badprint "Switch to 64-bit OS - MySQL cannot currenty use all of your RAM\n";
|
||||||
} else {
|
} else {
|
||||||
goodprint "Operating on 32-bit architecture with less than 2GB RAM\n";
|
goodprint "Operating on 32-bit architecture with less than 2GB RAM\n";
|
||||||
|
@ -234,7 +271,8 @@ sub check_architecture {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
my %enginestats;
|
# Start up a ton of storage engine counts/statistics
|
||||||
|
my (%enginestats,%enginecount);
|
||||||
sub check_storage_engines {
|
sub check_storage_engines {
|
||||||
print "-------- Storage Engine Statistics -------------------------------------------\n";
|
print "-------- Storage Engine Statistics -------------------------------------------\n";
|
||||||
infoprint "Status: ";
|
infoprint "Status: ";
|
||||||
|
@ -247,90 +285,47 @@ sub check_storage_engines {
|
||||||
$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";
|
print "$engines\n";
|
||||||
my @tblist;
|
my @tblist;
|
||||||
|
# Now we build a database list, and loop through it to get storage engine stats for tables
|
||||||
my @dblist = `mysql $mysqllogin -Bse "SHOW DATABASES"`;
|
my @dblist = `mysql $mysqllogin -Bse "SHOW DATABASES"`;
|
||||||
foreach my $db (@dblist) {
|
foreach my $db (@dblist) {
|
||||||
chomp($db);
|
chomp($db);
|
||||||
|
if ($mysqlvermajor == 3) {
|
||||||
|
# MySQL 3.23 keeps Data_Length in the 6th column
|
||||||
|
push (@tblist,`mysql $mysqllogin -Bse "SHOW TABLE STATUS FROM \\\`$db\\\`" | awk '{print \$2,\$6}'`);
|
||||||
|
} else {
|
||||||
|
# MySQL 4.0+ keeps Data_Length in the 7th column
|
||||||
push (@tblist,`mysql $mysqllogin -Bse "SHOW TABLE STATUS FROM \\\`$db\\\`" | awk '{print \$2,\$7}'`);
|
push (@tblist,`mysql $mysqllogin -Bse "SHOW TABLE STATUS FROM \\\`$db\\\`" | awk '{print \$2,\$7}'`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
# Parse through the table list to generate storage engine counts/statistics
|
||||||
foreach my $line (@tblist) {
|
foreach my $line (@tblist) {
|
||||||
$line =~ /([a-zA-Z_]*)\s*(.*)/;
|
$line =~ /([a-zA-Z_]*)\s*(.*)/;
|
||||||
my $engine = $1;
|
my $engine = $1;
|
||||||
my $size = $2;
|
my $size = $2;
|
||||||
if ($size !~ /^\d+$/) {
|
if ($size !~ /^\d+$/) { $size = 0; }
|
||||||
$size = 0;
|
|
||||||
}
|
|
||||||
if (defined $enginestats{$engine}) {
|
if (defined $enginestats{$engine}) {
|
||||||
$enginestats{$engine} = $enginestats{$engine} + $size;
|
$enginestats{$engine} += $size;
|
||||||
|
$enginecount{$engine} += 1;
|
||||||
} else {
|
} else {
|
||||||
$enginestats{$engine} = $size;
|
$enginestats{$engine} = $size;
|
||||||
}
|
$enginecount{$engine} = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while (my ($engine,$size) = each(%enginestats)) {
|
while (my ($engine,$size) = each(%enginestats)) {
|
||||||
infoprint "Data in $engine tables: ".hr_bytes_rnd($size)."\n";
|
infoprint "Data in $engine tables: ".hr_bytes_rnd($size)." (Tables: ".$enginecount{$engine}.")"."\n";
|
||||||
}
|
}
|
||||||
|
# If the storage engine isn't being used, recommend it to be disabled
|
||||||
if (!defined $enginestats{'InnoDB'} && defined $myvar{'have_innodb'} && $myvar{'have_innodb'} eq "YES") {
|
if (!defined $enginestats{'InnoDB'} && defined $myvar{'have_innodb'} && $myvar{'have_innodb'} eq "YES") {
|
||||||
badprint "InnoDB is enabled but isn't being used\n";
|
badprint "InnoDB is enabled but isn't being used\n";
|
||||||
|
push(@generalrec,"Add skip-innodb to MySQL configuration to disable InnoDB");
|
||||||
}
|
}
|
||||||
if (!defined $enginestats{'BDB'} && defined $myvar{'have_bdb'} && $myvar{'have_bdb'} eq "YES") {
|
if (!defined $enginestats{'BDB'} && defined $myvar{'have_bdb'} && $myvar{'have_bdb'} eq "YES") {
|
||||||
badprint "BDB is enabled but isn't being used\n";
|
badprint "BDB is enabled but isn't being used\n";
|
||||||
|
push(@generalrec,"Add skip-bdb to MySQL configuration to disable BDB");
|
||||||
}
|
}
|
||||||
}
|
if (!defined $enginestats{'ISAM'} && defined $myvar{'have_isam'} && $myvar{'have_isam'} eq "YES") {
|
||||||
|
badprint "ISAM is enabled but isn't being used\n";
|
||||||
sub pretty_uptime {
|
push(@generalrec,"Add skip-isam to MySQL configuration to disable ISAM");
|
||||||
my $uptime = shift;
|
|
||||||
my $seconds = $uptime % 60;
|
|
||||||
my $minutes = int(($uptime % 3600) / 60);
|
|
||||||
my $hours = int(($uptime % 86400) / (3600));
|
|
||||||
my $days = int($uptime / (86400));
|
|
||||||
my $uptimestring;
|
|
||||||
if ($days > 0) {
|
|
||||||
$uptimestring = "${days}d ${hours}h ${minutes}m ${seconds}s";
|
|
||||||
} elsif ($hours > 0) {
|
|
||||||
$uptimestring = "${hours}h ${minutes}m ${seconds}s";
|
|
||||||
} elsif ($minutes > 0) {
|
|
||||||
$uptimestring = "${minutes}m ${seconds}s";
|
|
||||||
} else {
|
|
||||||
$uptimestring = "${seconds}s";
|
|
||||||
}
|
|
||||||
return $uptimestring;
|
|
||||||
}
|
|
||||||
|
|
||||||
sub hr_bytes_rnd {
|
|
||||||
my $num = shift;
|
|
||||||
if ($num >= (1024**3)) { #GB
|
|
||||||
return int(($num/(1024**3)))."G";
|
|
||||||
} elsif ($num >= (1024**2)) { #MB
|
|
||||||
return int(($num/(1024**2)))."M";
|
|
||||||
} elsif ($num >= 1024) { #KB
|
|
||||||
return int(($num/1024))."K";
|
|
||||||
} else {
|
|
||||||
return $num."B";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sub hr_bytes {
|
|
||||||
my $num = shift;
|
|
||||||
if ($num >= (1024**3)) { #GB
|
|
||||||
return sprintf("%.1f",($num/(1024**3)))."G";
|
|
||||||
} elsif ($num >= (1024**2)) { #MB
|
|
||||||
return sprintf("%.1f",($num/(1024**2)))."M";
|
|
||||||
} elsif ($num >= 1024) { #KB
|
|
||||||
return sprintf("%.1f",($num/1024))."K";
|
|
||||||
} else {
|
|
||||||
return $num."B";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sub hr_num {
|
|
||||||
my $num = shift;
|
|
||||||
if ($num >= (1000**3)) { #GB
|
|
||||||
return int(($num/(1000**3)))."G";
|
|
||||||
} elsif ($num >= (1000**2)) { #MB
|
|
||||||
return int(($num/(1000**2)))."M";
|
|
||||||
} elsif ($num >= 1000) { #KB
|
|
||||||
return int(($num/1000))."K";
|
|
||||||
} else {
|
|
||||||
return $num;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -458,7 +453,7 @@ sub calculations {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
my (@adjvars, @generalrec);
|
#my (@adjvars, @generalrec);
|
||||||
sub mysql_stats {
|
sub mysql_stats {
|
||||||
print "-------- Performance Metrics -------------------------------------------------\n";
|
print "-------- Performance Metrics -------------------------------------------------\n";
|
||||||
# Show uptime, queries per second, connections, traffic stats
|
# Show uptime, queries per second, connections, traffic stats
|
||||||
|
@ -663,6 +658,7 @@ sub mysql_stats {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Take the two recommendation arrays and display them at the end of the output
|
||||||
sub make_recommendations {
|
sub make_recommendations {
|
||||||
print "-------- Recommendations -----------------------------------------------------\n";
|
print "-------- Recommendations -----------------------------------------------------\n";
|
||||||
if (@generalrec > 0) {
|
if (@generalrec > 0) {
|
||||||
|
|
Loading…
Reference in a new issue