Assembla home | Assembla project page
 

Changeset 27

Show
Ignore:
Timestamp:
01/16/08 03:39:36 (10 months ago)
Author:
major
Message:

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

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • mysqltuner.pl

    r26 r27  
    3535use Getopt::Long; 
    3636 
     37# Set up a few variables for use in the script 
     38my (@adjvars, @generalrec); 
     39 
    3740# Set defaults 
    3841my %opt = ( 
     
    5558 
    5659sub usage { 
     60        # Shown with --help option passed 
    5761        print "\n". 
    5862                "       MySQL High Performance Tuning Script\n". 
     
    7276} 
    7377 
    74 # CONFIGURATION ITEMS 
    75 my ($good,$bad,$info); 
    76 if ($opt{nocolor} == 0) { 
    77         $good = "[\e[00;32mOK\e[00m]"; 
    78         $bad = "[\e[00;31m!!\e[00m]"; 
    79         $info = "[\e[00;34m**\e[00m]"; 
    80 } else { 
    81         $good = "[OK]"; 
    82         $bad = "[!!]"; 
    83         $info = "[--]"; 
    84 
    85  
    86 sub goodprint { 
    87         if ($opt{nogood} == 1) { return 0; } 
    88         my $text = shift; 
    89         print $good." ".$text; 
    90 
    91  
    92 sub infoprint { 
    93         if ($opt{noinfo} == 1) { return 0; } 
    94         my $text = shift; 
    95         print $info." ".$text; 
    96 
    97  
    98 sub badprint { 
    99         if ($opt{nobad} == 1) { return 0; } 
    100         my $text = shift; 
    101         print $bad." ".$text; 
    102 
    103  
    104 sub redwrap { 
    105         my $text = shift; 
    106         return "\e[00;31m".$text."\e[00m"; 
    107 
    108  
    109 sub greenwrap { 
    110         my $text = shift; 
    111         return "\e[00;32m".$text."\e[00m"; 
    112 
    113  
     78# Setting up the colors for the print styles 
     79my $good = ($opt{nocolor} == 0)? "[\e[00;32mOK\e[00m]" : "[OK]" ; 
     80my $bad = ($opt{nocolor} == 0)? "[\e[00;31mOK\e[00m]" : "[!!]" ; 
     81my $info = ($opt{nocolor} == 0)? "[\e[00;34mOK\e[00m]" : "[--]" ; 
     82 
     83# Functions that handle the print styles 
     84sub goodprint { print $good." ".$_[0] unless ($opt{nogood} == 1); } 
     85sub infoprint { print $info." ".$_[0] unless ($opt{noinfo} == 1); } 
     86sub badprint { print $bad." ".$_[0] unless ($opt{nobad} == 1); } 
     87sub redwrap { return "\e[00;31m".$_[0]."\e[00m"; } 
     88sub greenwrap { return "\e[00;32m".$_[0]."\e[00m"; } 
     89 
     90# Calculates the parameter passed in bytes, and then rounds it to one decimal place 
     91sub hr_bytes { 
     92        my $num = shift; 
     93        if ($num >= (1024**3)) { #GB 
     94                return sprintf("%.1f",($num/(1024**3)))."G"; 
     95        } elsif ($num >= (1024**2)) { #MB 
     96                return sprintf("%.1f",($num/(1024**2)))."M"; 
     97        } elsif ($num >= 1024) { #KB 
     98                return sprintf("%.1f",($num/1024))."K"; 
     99        } else { 
     100                return $num."B"; 
     101        } 
     102
     103 
     104# Calculates the parameter passed in bytes, and then rounds it to the nearest integer 
     105sub hr_bytes_rnd { 
     106        my $num = shift; 
     107        if ($num >= (1024**3)) { #GB 
     108                return int(($num/(1024**3)))."G"; 
     109        } elsif ($num >= (1024**2)) { #MB 
     110                return int(($num/(1024**2)))."M"; 
     111        } elsif ($num >= 1024) { #KB 
     112                return int(($num/1024))."K"; 
     113        } else { 
     114                return $num."B"; 
     115        } 
     116
     117 
     118# Calculates the parameter passed to the nearest power of 1000, then rounds it to the nearest integer 
     119sub hr_num { 
     120        my $num = shift; 
     121        if ($num >= (1000**3)) { # Billions 
     122                return int(($num/(1000**3)))."B"; 
     123        } elsif ($num >= (1000**2)) { # Millions 
     124                return int(($num/(1000**2)))."M"; 
     125        } elsif ($num >= 1000) { # Thousands 
     126                return int(($num/1000))."K"; 
     127        } else { 
     128                return $num; 
     129        } 
     130
     131 
     132# Calculates uptime to display in a more attractive form 
     133sub pretty_uptime { 
     134        my $uptime = shift; 
     135        my $seconds = $uptime % 60; 
     136        my $minutes = int(($uptime % 3600) / 60); 
     137        my $hours = int(($uptime % 86400) / (3600)); 
     138        my $days = int($uptime / (86400)); 
     139        my $uptimestring; 
     140        if ($days > 0) { 
     141                $uptimestring = "${days}d ${hours}h ${minutes}m ${seconds}s"; 
     142        } elsif ($hours > 0) { 
     143                $uptimestring = "${hours}h ${minutes}m ${seconds}s"; 
     144        } elsif ($minutes > 0) { 
     145                $uptimestring = "${minutes}m ${seconds}s"; 
     146        } else { 
     147                $uptimestring = "${seconds}s"; 
     148        } 
     149        return $uptimestring; 
     150
     151 
     152# Retrieves the memory installed on this machine 
    114153my ($physical_memory,$swap_memory,$duflags); 
    115154sub os_setup { 
     
    133172} 
    134173 
     174# Checks to see if a MySQL login is possible 
    135175my $mysqllogin; 
    136176sub mysql_setup { 
     
    145185                $mysqllogin = "-u admin -p`cat /etc/psa/.psa.shadow`"; 
    146186                my $loginstatus = `mysqladmin ping $mysqllogin 2>&1`; 
    147                 if ($loginstatus =~ /mysqld is alive/) { 
    148                         # Login was successful, but we won't say anything to save space 
    149                         return 1; 
    150                 } else { 
     187                unless ($loginstatus =~ /mysqld is alive/) { 
    151188                        badprint "Attempted to use login credentials from Plesk, but they failed.\n"; 
    152189                        exit 0; 
     
    161198                        my $userpath = `ls -d ~`; 
    162199                        chomp($userpath); 
    163                         if ( -e "$userpath/.my.cnf" ) { 
    164                                 # Login was successful, but we won't say anything to save space 
    165                         } else { 
     200                        unless ( -e "$userpath/.my.cnf" ) { 
    166201                                badprint "Successfully authenticated with no password - SECURITY RISK!\n"; 
    167202                        } 
    168203                        return 1; 
    169204                } else { 
    170                         print STDERR "Please enter your MySQL login: "; 
     205                        print STDERR "Please enter your MySQL administrative login: "; 
    171206                        my $name = <>; 
    172                         print STDERR "Please enter your MySQL password: "; 
     207                        print STDERR "Please enter your MySQL administrative password: "; 
    173208                        system("stty -echo"); 
    174209                        my $password = <>; 
     
    179214                        my $loginstatus = `mysqladmin ping $mysqllogin 2>&1`; 
    180215                        if ($loginstatus =~ /mysqld is alive/) { 
    181                                 # Login was successful, but we won't say anything to save space 
    182216                                print STDERR "\n"; 
    183217                                return 1; 
     
    191225} 
    192226 
     227# Populates all of the variable and status hashes 
    193228my (%mystat,%myvar,$dummyselect); 
    194229sub get_all_vars { 
     
    207242} 
    208243 
     244# Checks for supported or EOL'ed MySQL versions 
    209245my ($mysqlvermajor,$mysqlverminor); 
    210246sub validate_mysql_version { 
     
    220256} 
    221257 
     258# Checks for 32-bit boxes with more than 2GB of RAM 
    222259my ($arch); 
    223260sub check_architecture { 
     
    227264        } else { 
    228265                $arch = 32; 
    229                 if ($physical_memory > 2*1024*1024*1024) { 
     266                if ($physical_memory > 2147483648) { 
    230267                        badprint "Switch to 64-bit OS - MySQL cannot currenty use all of your RAM\n"; 
    231268                } else { 
     
    235272} 
    236273 
    237 my %enginestats; 
     274# Start up a ton of storage engine counts/statistics 
     275my (%enginestats,%enginecount); 
    238276sub check_storage_engines { 
    239277        print "-------- Storage Engine Statistics -------------------------------------------\n"; 
     
    248286        print "$engines\n"; 
    249287        my @tblist; 
     288        # Now we build a database list, and loop through it to get storage engine stats for tables 
    250289        my @dblist = `mysql $mysqllogin -Bse "SHOW DATABASES"`; 
    251290        foreach my $db (@dblist) { 
    252291                chomp($db); 
    253                 push (@tblist,`mysql $mysqllogin -Bse "SHOW TABLE STATUS FROM \\\`$db\\\`" | awk '{print \$2,\$7}'`); 
    254                 foreach my $line (@tblist) { 
    255                         $line =~ /([a-zA-Z_]*)\s*(.*)/; 
    256                         my $engine = $1; 
    257                         my $size = $2; 
    258                         if ($size !~ /^\d+$/) { 
    259                                 $size = 0;                       
    260                         } 
    261                         if (defined $enginestats{$engine}) { 
    262                                 $enginestats{$engine} = $enginestats{$engine} + $size; 
    263                         } else { 
    264                                 $enginestats{$engine} = $size; 
    265                         } 
     292                if ($mysqlvermajor == 3) { 
     293                        # MySQL 3.23 keeps Data_Length in the 6th column 
     294                        push (@tblist,`mysql $mysqllogin -Bse "SHOW TABLE STATUS FROM \\\`$db\\\`" | awk '{print \$2,\$6}'`); 
     295                } else { 
     296                        # MySQL 4.0+ keeps Data_Length in the 7th column 
     297                        push (@tblist,`mysql $mysqllogin -Bse "SHOW TABLE STATUS FROM \\\`$db\\\`" | awk '{print \$2,\$7}'`); 
     298                } 
     299        } 
     300        # Parse through the table list to generate storage engine counts/statistics 
     301        foreach my $line (@tblist) { 
     302                $line =~ /([a-zA-Z_]*)\s*(.*)/; 
     303                my $engine = $1; 
     304                my $size = $2; 
     305                if ($size !~ /^\d+$/) { $size = 0; } 
     306                if (defined $enginestats{$engine}) { 
     307                        $enginestats{$engine} += $size; 
     308                        $enginecount{$engine} += 1; 
     309                } else { 
     310                        $enginestats{$engine} = $size; 
     311                        $enginecount{$engine} = 1; 
    266312                } 
    267313        } 
    268314        while (my ($engine,$size) = each(%enginestats)) { 
    269                 infoprint "Data in $engine tables: ".hr_bytes_rnd($size)."\n"; 
    270         } 
     315                infoprint "Data in $engine tables: ".hr_bytes_rnd($size)." (Tables: ".$enginecount{$engine}.")"."\n"; 
     316        } 
     317        # If the storage engine isn't being used, recommend it to be disabled 
    271318        if (!defined $enginestats{'InnoDB'} && defined $myvar{'have_innodb'} && $myvar{'have_innodb'} eq "YES") { 
    272319                badprint "InnoDB is enabled but isn't being used\n"; 
     320                push(@generalrec,"Add skip-innodb to MySQL configuration to disable InnoDB"); 
    273321        } 
    274322        if (!defined $enginestats{'BDB'} && defined $myvar{'have_bdb'} && $myvar{'have_bdb'} eq "YES") { 
    275323                badprint "BDB is enabled but isn't being used\n"; 
    276         } 
    277 
    278  
    279 sub pretty_uptime { 
    280         my $uptime = shift; 
    281         my $seconds = $uptime % 60; 
    282         my $minutes = int(($uptime % 3600) / 60); 
    283         my $hours = int(($uptime % 86400) / (3600)); 
    284         my $days = int($uptime / (86400)); 
    285         my $uptimestring; 
    286         if ($days > 0) { 
    287                 $uptimestring = "${days}d ${hours}h ${minutes}m ${seconds}s"; 
    288         } elsif ($hours > 0) { 
    289                 $uptimestring = "${hours}h ${minutes}m ${seconds}s"; 
    290         } elsif ($minutes > 0) { 
    291                 $uptimestring = "${minutes}m ${seconds}s"; 
    292         } else { 
    293                 $uptimestring = "${seconds}s"; 
    294         } 
    295         return $uptimestring; 
    296 
    297  
    298 sub hr_bytes_rnd { 
    299         my $num = shift; 
    300         if ($num >= (1024**3)) { #GB 
    301                 return int(($num/(1024**3)))."G"; 
    302         } elsif ($num >= (1024**2)) { #MB 
    303                 return int(($num/(1024**2)))."M"; 
    304         } elsif ($num >= 1024) { #KB 
    305                 return int(($num/1024))."K"; 
    306         } else { 
    307                 return $num."B"; 
    308         } 
    309 
    310  
    311 sub hr_bytes { 
    312         my $num = shift; 
    313         if ($num >= (1024**3)) { #GB 
    314                 return sprintf("%.1f",($num/(1024**3)))."G"; 
    315         } elsif ($num >= (1024**2)) { #MB 
    316                 return sprintf("%.1f",($num/(1024**2)))."M"; 
    317         } elsif ($num >= 1024) { #KB 
    318                 return sprintf("%.1f",($num/1024))."K"; 
    319         } else { 
    320                 return $num."B"; 
    321         } 
    322 
    323  
    324 sub hr_num { 
    325         my $num = shift; 
    326         if ($num >= (1000**3)) { #GB 
    327                 return int(($num/(1000**3)))."G"; 
    328         } elsif ($num >= (1000**2)) { #MB 
    329                 return int(($num/(1000**2)))."M"; 
    330         } elsif ($num >= 1000) { #KB 
    331                 return int(($num/1000))."K"; 
    332         } else { 
    333                 return $num; 
     324                push(@generalrec,"Add skip-bdb to MySQL configuration to disable BDB"); 
     325        } 
     326        if (!defined $enginestats{'ISAM'} && defined $myvar{'have_isam'} && $myvar{'have_isam'} eq "YES") { 
     327                badprint "ISAM is enabled but isn't being used\n"; 
     328                push(@generalrec,"Add skip-isam to MySQL configuration to disable ISAM"); 
    334329        } 
    335330} 
     
    459454} 
    460455 
    461 my (@adjvars, @generalrec); 
     456#my (@adjvars, @generalrec); 
    462457sub mysql_stats { 
    463458        print "-------- Performance Metrics -------------------------------------------------\n"; 
     
    664659} 
    665660 
     661# Take the two recommendation arrays and display them at the end of the output 
    666662sub make_recommendations { 
    667663        print "-------- Recommendations -----------------------------------------------------\n";