Assembla home | Assembla project page
 

Changeset 40

Show
Ignore:
Timestamp:
09/08/08 01:16:39 (2 months ago)
Author:
major
Message:

Bumped version to 0.9.9
Added --socket option to use an alternative socket (thanks Mark!)
Added OpenBSD memory checking support (thanks Giovanni!)
Added counts to report lines to provide additional detail
Fixed error where disabling BDB was recommended even when BDB tables were present (thanks Greg!)
Fixed an issue with big integers (> 232) from key calculations (thanks Aubin!)
Fixed an error on Solaris machines (thanks Bill!)
Fixed an issue where the key buffer calculation caused errors when no indexes were present
Added Giovanni Bechis, Greg Eden, Aubin Galinotti, Mark Imbriaco and Bill Bradford to the contributors list

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • mysqltuner.pl

    r39 r40  
    11#!/usr/bin/perl -w 
    2 # mysqltuner.pl - Version 0.9.8 
     2# mysqltuner.pl - Version 0.9.9 
    33# High Performance MySQL Tuning Script 
    44# Copyright (C) 2006-2008 Major Hayden - major@mhtx.net 
     
    2121# 
    2222# This project would not be possible without help from: 
    23 #   Matthew Montgomery 
    24 #   Paul Kehrer 
    25 #   Dave Burgess 
    26 #   Jonathan Hinds 
    27 #   Mike Jackson 
    28 #   Nils Breunese 
    29 #   Shawn Ashlee 
    30 #   Luuk Vosslamber 
    31 #   Ville Skytta 
    32 #   Trent Hornibrook 
    33 #   Jason Gill 
     23#   Matthew Montgomery     Paul Kehrer 
     24#   Dave Burgess           Jonathan Hinds 
     25#   Mike Jackson           Nils Breunese 
     26#   Shawn Ashlee           Luuk Vosslamber 
     27#   Ville Skytta           Trent Hornibrook 
     28#   Jason Gill             Mark Imbriaco 
     29#   Greg Eden              Aubin Galinotti 
     30#   Giovanni Bechis        Bill Bradford 
    3431# 
    3532# Inspired by Matthew Montgomery's tuning-primer.sh script: 
     
    4239 
    4340# Set up a few variables for use in the script 
    44 my $tunerversion = "0.9.8"; 
     41my $tunerversion = "0.9.9"; 
    4542my (@adjvars, @generalrec); 
    4643 
     
    5451                "forceswap" => 0, 
    5552                "host" => 0, 
     53                "socket" => 0, 
    5654                "port" => 0, 
    5755                "user" => 0, 
     
    7068                'forceswap=i', 
    7169                'host=s', 
     70                'socket=s', 
    7271                'port=i', 
    7372                'user=s', 
     
    9594                "   Connection and Authentication\n". 
    9695                "      --host <hostname>    Connect to a remote host to perform tests (default: localhost)\n". 
     96                "      --socket <socket>    Use a different socket for a local connection\n". 
    9797                "      --port <port>        Port to use for connection (default: 3306)\n". 
    9898                "      --user <username>    Username to use for authentication\n". 
     
    215215                        $physical_memory = `sysctl -n hw.memsize` or memerror; 
    216216                        $swap_memory = `sysctl -n vm.swapusage | awk '{print \$3}' | sed 's/\..*\$//'` or memerror; 
    217                 } elsif ($os =~ /NetBSD/) { 
     217                } elsif ($os =~ /NetBSD|OpenBSD/) { 
    218218                        $physical_memory = `sysctl -n hw.physmem` or memerror; 
    219219                        $swap_memory = `swapctl -l | grep '^/' | awk '{ s+= \$2 } END { print s }'` or memerror; 
     
    237237                exit; 
    238238        } 
     239        # Are we being asked to connect via a socket? 
     240        if ($opt{socket} ne 0) { 
     241                $remotestring = " -S $opt{socket}"; 
     242        } 
    239243        # Are we being asked to connect to a remote server? 
    240244        if ($opt{host} ne 0) { 
     
    277281                        $mysqllogin = ""; 
    278282                        # Did this go well because of a .my.cnf file or is there no password set? 
    279                         my $userpath = `ls -d ~`; 
    280                         chomp($userpath); 
    281                         unless ( -e "$userpath/.my.cnf" ) { 
     283                        my $userpath = `ls -d ~ 2>/dev/null`; 
     284                        if (length($userpath) > 0) { 
     285                                chomp($userpath); 
     286                        } 
     287                        unless ( -e "${userpath}/.my.cnf" ) { 
    282288                                badprint "Successfully authenticated with no password - SECURITY RISK!\n"; 
    283289                        } 
     
    410416        if ($mysqlvermajor >= 5) { 
    411417                # MySQL 5 servers can have table sizes calculated quickly from information schema 
    412                 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 HAVING SUM(DATA_LENGTH) > 0 ORDER BY ENGINE ASC;"`; 
     418                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;"`; 
    413419                foreach my $line (@templist) { 
    414420                        my ($engine,$size,$count); 
     
    464470                push(@generalrec,"Add skip-innodb to MySQL configuration to disable InnoDB"); 
    465471        } 
    466         if (!defined $enginestats{'BDB'} && defined $myvar{'have_bdb'} && $myvar{'have_bdb'} eq "YES") { 
     472        if (!defined $enginestats{'BerkeleyDB'} && defined $myvar{'have_bdb'} && $myvar{'have_bdb'} eq "YES") { 
    467473                badprint "BDB is enabled but isn't being used\n"; 
    468474                push(@generalrec,"Add skip-bdb to MySQL configuration to disable BDB"); 
     
    523529                $mycalc{'pct_keys_from_mem'} = sprintf("%.1f",(100 - (($mystat{'Key_reads'} / $mystat{'Key_read_requests'}) * 100))); 
    524530        } 
    525         if ($doremote eq 0) { 
    526                 $mycalc{'total_myisam_indexes'} = `find $myvar{'datadir'} -name '*.MYI' 2>&1 | xargs du -L $duflags '{}' 2>&1 | awk '{ s += \$1 } END { print s }'`; 
    527         } elsif ($doremote eq 1 and $mysqlvermajor >= 5) { 
    528                 $mycalc{'total_myisam_indexes'} = `mysql $mysqllogin -Bse "SELECT SUM(INDEX_LENGTH) FROM information_schema.TABLES WHERE TABLE_SCHEMA NOT IN ('information_schema');"`; 
     531        if ($doremote eq 0 and $mysqlvermajor < 5) { 
     532                $mycalc{'total_myisam_indexes'} = `find $myvar{'datadir'} -name '*.MYI' 2>&1 | xargs du -L $duflags '{}' 2>&1 | awk '{ s += \$1 } END { printf (\"%d\",s) }'`; 
     533        } elsif ($mysqlvermajor >= 5) { 
     534                $mycalc{'total_myisam_indexes'} = `mysql $mysqllogin -Bse "SELECT IFNULL(SUM(INDEX_LENGTH),0) FROM information_schema.TABLES WHERE TABLE_SCHEMA NOT IN ('information_schema');"`; 
    529535        } 
    530536        if (defined $mycalc{'total_myisam_indexes'} and $mycalc{'total_myisam_indexes'} =~ /^0\n$/) {  
     
    624630 
    625631        # Memory usage 
    626         infoprint "Total buffers: ".hr_bytes($mycalc{'per_thread_buffers'})." per thread and ".hr_bytes($mycalc{'server_buffers'})." global\n"; 
     632        infoprint "Total buffers: ".hr_bytes($mycalc{'server_buffers'})." global + ".hr_bytes($mycalc{'per_thread_buffers'})." per thread ($myvar{'max_connections'} max threads)\n"; 
    627633        if ($mycalc{'total_possible_used_memory'} > 2*1024*1024*1024 && $arch eq 32) { 
    628634                badprint "Allocating > 2GB RAM on 32-bit systems can cause system instability\n"; 
     
    672678                if ($mystat{'Key_read_requests'} > 0) { 
    673679                        if ($mycalc{'pct_keys_from_mem'} < 95) { 
    674                                 badprint "Key buffer hit rate: $mycalc{'pct_keys_from_mem'}%\n"; 
     680                                badprint "Key buffer hit rate: $mycalc{'pct_keys_from_mem'}% (".hr_num($mystat{'Key_read_requests'})." cached / ".hr_num($mystat{'Key_reads'})." reads)\n"; 
    675681                        } else { 
    676                                 goodprint "Key buffer hit rate: $mycalc{'pct_keys_from_mem'}%\n"; 
     682                                goodprint "Key buffer hit rate: $mycalc{'pct_keys_from_mem'}% (".hr_num($mystat{'Key_read_requests'})." cached / ".hr_num($mystat{'Key_reads'})." reads)\n"; 
    677683                        } 
    678684                } else { 
     
    694700        } else { 
    695701                if ($mycalc{'query_cache_efficiency'} < 20) { 
    696                         badprint "Query cache efficiency: $mycalc{'query_cache_efficiency'}%\n"; 
     702                        badprint "Query cache efficiency: $mycalc{'query_cache_efficiency'}% (".hr_num($mystat{'Qcache_hits'})." cached / ".hr_num($mystat{'Qcache_hits'}+$mystat{'Com_select'})." selects)\n"; 
    697703                        push(@adjvars,"query_cache_limit (> ".hr_bytes_rnd($myvar{'query_cache_limit'}).", or use smaller result sets)"); 
    698704                } else { 
    699                         goodprint "Query cache efficiency: $mycalc{'query_cache_efficiency'}%\n"; 
     705                        goodprint "Query cache efficiency: $mycalc{'query_cache_efficiency'}% (".hr_num($mystat{'Qcache_hits'})." cached / ".hr_num($mystat{'Qcache_hits'}+$mystat{'Com_select'})." selects)\n"; 
    700706                } 
    701707                if ($mycalc{'query_cache_prunes_per_day'} > 98) { 
     
    712718                # No sorts have run yet 
    713719        } elsif ($mycalc{'pct_temp_sort_table'} > 10) { 
    714                 badprint "Sorts requiring temporary tables: $mycalc{'pct_temp_sort_table'}%\n"; 
     720                badprint "Sorts requiring temporary tables: $mycalc{'pct_temp_sort_table'}% (".hr_num($mystat{'Sort_merge_passes'})." temp sorts / ".hr_num($mycalc{'total_sorts'})." sorts)\n"; 
    715721                push(@adjvars,"sort_buffer_size (> ".hr_bytes_rnd($myvar{'sort_buffer_size'}).")"); 
    716722                push(@adjvars,"read_rnd_buffer_size (> ".hr_bytes_rnd($myvar{'read_rnd_buffer_size'}).")"); 
    717723        } else { 
    718                 goodprint "Sorts requiring temporary tables: $mycalc{'pct_temp_sort_table'}%\n"; 
     724                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"; 
    719725        } 
    720726         
     
    732738        if ($mystat{'Created_tmp_tables'} > 0) { 
    733739                if ($mycalc{'pct_temp_disk'} > 25 && $mycalc{'max_tmp_table_size'} < 256*1024*1024) { 
    734                         badprint "Temporary tables created on disk: $mycalc{'pct_temp_disk'}%\n"; 
     740                        badprint "Temporary tables created on disk: $mycalc{'pct_temp_disk'}% (".hr_num($mystat{'Created_tmp_disk_tables'})." on disk / ".hr_num($mystat{'Created_tmp_disk_tables'} + $mystat{'Created_tmp_tables'})." total)\n"; 
    735741                        push(@adjvars,"tmp_table_size (> ".hr_bytes_rnd($myvar{'tmp_table_size'}).")"); 
    736742                        push(@adjvars,"max_heap_table_size (> ".hr_bytes_rnd($myvar{'max_heap_table_size'}).")"); 
     
    738744                        push(@generalrec,"Reduce your SELECT DISTINCT queries without LIMIT clauses"); 
    739745                } elsif ($mycalc{'pct_temp_disk'} > 25 && $mycalc{'max_tmp_table_size'} >= 256) { 
    740                         badprint "Temporary tables created on disk: $mycalc{'pct_temp_disk'}%\n"; 
     746                        badprint "Temporary tables created on disk: $mycalc{'pct_temp_disk'}% (".hr_num($mystat{'Created_tmp_disk_tables'})." on disk / ".hr_num($mystat{'Created_tmp_disk_tables'} + $mystat{'Created_tmp_tables'})." total)\n"; 
    741747                        push(@generalrec,"Temporary table size is already large - reduce result set size"); 
    742748                        push(@generalrec,"Reduce your SELECT DISTINCT queries without LIMIT clauses"); 
    743749                } else { 
    744                         goodprint "Temporary tables created on disk: $mycalc{'pct_temp_disk'}%\n"; 
     750                        goodprint "Temporary tables created on disk: $mycalc{'pct_temp_disk'}% (".hr_num($mystat{'Created_tmp_disk_tables'})." on disk / ".hr_num($mystat{'Created_tmp_disk_tables'} + $mystat{'Created_tmp_tables'})." total)\n"; 
    745751                } 
    746752        } else { 
     
    756762        } else { 
    757763                if ($mycalc{'thread_cache_hit_rate'} <= 50) { 
    758                         badprint "Thread cache hit rate: $mycalc{'thread_cache_hit_rate'}%\n"; 
     764                        badprint "Thread cache hit rate: $mycalc{'thread_cache_hit_rate'}% (".hr_num($mystat{'Threads_created'})." created / ".hr_num($mystat{'Connections'})." connections)\n"; 
    759765                        push(@adjvars,"thread_cache_size (> $myvar{'thread_cache_size'})"); 
    760766                } else { 
    761                         goodprint "Thread cache hit rate: $mycalc{'thread_cache_hit_rate'}%\n"; 
     767                        goodprint "Thread cache hit rate: $mycalc{'thread_cache_hit_rate'}% (".hr_num($mystat{'Threads_created'})." created / ".hr_num($mystat{'Connections'})." connections)\n"; 
    762768                } 
    763769        } 
     
    766772        if ($mystat{'Open_tables'} > 0) { 
    767773                if ($mycalc{'table_cache_hit_rate'} < 20) { 
    768                         badprint "Table cache hit rate: $mycalc{'table_cache_hit_rate'}%\n"; 
     774                        badprint "Table cache hit rate: $mycalc{'table_cache_hit_rate'}% (".hr_num($mystat{'Open_tables'})." open / ".hr_num($mystat{'Opened_tables'})." opened)\n"; 
    769775                        if ($mysqlvermajor eq 6) { 
    770776                                push(@adjvars,"table_cache (> ".$myvar{'table_open_cache'}.")"); 
     
    774780                        push(@generalrec,"Increase table_cache gradually to avoid file descriptor limits"); 
    775781                } else { 
    776                         goodprint "Table cache hit rate: $mycalc{'table_cache_hit_rate'}%\n"; 
     782                        goodprint "Table cache hit rate: $mycalc{'table_cache_hit_rate'}% (".hr_num($mystat{'Open_tables'})." open / ".hr_num($mystat{'Opened_tables'})." opened)\n"; 
    777783                } 
    778784        } 
     
    781787        if (defined $mycalc{'pct_files_open'}) { 
    782788                if ($mycalc{'pct_files_open'} > 85) { 
    783                         badprint "Open file limit used: $mycalc{'pct_files_open'}%\n"; 
     789                        badprint "Open file limit used: $mycalc{'pct_files_open'}% (".hr_num($mystat{'Open_files'})."/".hr_num($myvar{'open_files_limit'}).")\n"; 
    784790                        push(@adjvars,"open_files_limit (> ".$myvar{'open_files_limit'}.")"); 
    785791                } else { 
    786                         goodprint "Open file limit used: $mycalc{'pct_files_open'}%\n"; 
     792                        goodprint "Open file limit used: $mycalc{'pct_files_open'}% (".hr_num($mystat{'Open_files'})."/".hr_num($myvar{'open_files_limit'}).")\n"; 
    787793                } 
    788794        } 
     
    794800                        push(@generalrec,"Optimize queries and/or use InnoDB to reduce lock wait"); 
    795801                } else { 
    796                         goodprint "Table locks acquired immediately: $mycalc{'pct_table_locks_immediate'}%\n"; 
     802                        goodprint "Table locks acquired immediately: $mycalc{'pct_table_locks_immediate'}% (".hr_num($mystat{'Table_locks_immediate'})." immediate / ".hr_num($mystat{'Table_locks_waited'}+$mystat{'Table_locks_immediate'})." locks)\n"; 
    797803                } 
    798804        }