#87 change password single quote to double quote and small fixes

This commit is contained in:
Mohammad 2016-02-20 18:05:33 +02:00
parent 6c939906dd
commit 15333e4a58

View file

@ -90,8 +90,9 @@ GetOptions(
'host=s', 'socket=s', 'port=i', 'user=s', 'host=s', 'socket=s', 'port=i', 'user=s',
'pass=s', 'skipsize', 'checkversion', 'mysqladmin=s', 'pass=s', 'skipsize', 'checkversion', 'mysqladmin=s',
'mysqlcmd=s', 'help', 'buffers', 'skippassword', 'mysqlcmd=s', 'help', 'buffers', 'skippassword',
'passwordfile=s', 'outputfile=s', 'silent', 'dbstat', 'json', 'passwordfile=s', 'outputfile=s', 'silent', 'dbstat',
'idxstat', 'noask', 'template=s', 'reportfile=s', 'cvefile=s', 'json', 'idxstat', 'noask', 'template=s',
'reportfile=s', 'cvefile=s',
); );
if ( defined $opt{'help'} && $opt{'help'} == 1 ) { usage(); } if ( defined $opt{'help'} && $opt{'help'} == 1 ) { usage(); }
@ -156,8 +157,8 @@ $basic_password_files = "/usr/share/mysqltuner/basic_passwords.txt"
# for RPM distributions # for RPM distributions
$opt{cvefile} = "/usr/share/mysqltuner/vulnerabilities.csv" $opt{cvefile} = "/usr/share/mysqltuner/vulnerabilities.csv"
unless ( defined $opt{cvefile} and -f "$opt{cvefile}"); unless ( defined $opt{cvefile} and -f "$opt{cvefile}" );
$opt{cvefile} ='' unless -f "$opt{cvefile}"; $opt{cvefile} = '' unless -f "$opt{cvefile}";
# #
my $outputfile = undef; my $outputfile = undef;
@ -187,6 +188,7 @@ sub goodprint { prettyprint $good. " " . $_[0] unless ( $opt{nogood} == 1 ); }
sub infoprint { prettyprint $info. " " . $_[0] unless ( $opt{noinfo} == 1 ); } sub infoprint { prettyprint $info. " " . $_[0] unless ( $opt{noinfo} == 1 ); }
sub badprint { prettyprint $bad. " " . $_[0] unless ( $opt{nobad} == 1 ); } sub badprint { prettyprint $bad. " " . $_[0] unless ( $opt{nobad} == 1 ); }
sub debugprint { prettyprint $deb. " " . $_[0] unless ( $opt{debug} == 0 ); } sub debugprint { prettyprint $deb. " " . $_[0] unless ( $opt{debug} == 0 ); }
sub redwrap { sub redwrap {
return ( $opt{nocolor} == 0 ) ? "\e[0;31m" . $_[0] . "\e[0m" : $_[0]; return ( $opt{nocolor} == 0 ) ? "\e[0;31m" . $_[0] . "\e[0m" : $_[0];
} }
@ -282,6 +284,7 @@ sub pretty_uptime {
my ( $physical_memory, $swap_memory, $duflags ); my ( $physical_memory, $swap_memory, $duflags );
sub os_setup { sub os_setup {
sub memerror { sub memerror {
badprint badprint
"Unable to determine total memory/swap; use '--forcemem' and '--forceswap'"; "Unable to determine total memory/swap; use '--forcemem' and '--forceswap'";
@ -298,8 +301,7 @@ sub os_setup {
} }
else { else {
$swap_memory = 0; $swap_memory = 0;
badprint badprint "Assuming 0 MB of swap space (use --forceswap to specify)";
"Assuming 0 MB of swap space (use --forceswap to specify)";
} }
} }
else { else {
@ -352,12 +354,12 @@ sub os_setup {
chomp($swap_memory); chomp($swap_memory);
$swap_memory = $swap_memory * 1024 * 1024; $swap_memory = $swap_memory * 1024 * 1024;
} }
elsif( $os =~ /windows/i ) { elsif ( $os =~ /windows/i ) {
$physical_memory = $physical_memory =
`wmic ComputerSystem get TotalPhysicalMemory | perl -ne "chomp; print if /[0-9]+/;"` `wmic ComputerSystem get TotalPhysicalMemory | perl -ne "chomp; print if /[0-9]+/;"`
or memerror; or memerror;
$swap_memory = $swap_memory =
`wmic OS get FreeVirtualMemory | perl -ne "chomp; print if /[0-9]+/;"` `wmic OS get FreeVirtualMemory | perl -ne "chomp; print if /[0-9]+/;"`
or memerror; or memerror;
} }
} }
@ -376,36 +378,39 @@ sub os_setup {
# Checks for updates to MySQLTuner # Checks for updates to MySQLTuner
sub validate_tuner_version { sub validate_tuner_version {
if ($opt{checkversion} eq 0) { if ( $opt{checkversion} eq 0 ) {
infoprint "Skipped version check for MySQLTuner script"; infoprint "Skipped version check for MySQLTuner script";
return; return;
} }
my $update; my $update;
my $url = "https://raw.githubusercontent.com/major/MySQLTuner-perl/master/mysqltuner.pl"; my $url =
my $httpcli=`which curl`; "https://raw.githubusercontent.com/major/MySQLTuner-perl/master/mysqltuner.pl";
my $httpcli = `which curl`;
chomp($httpcli); chomp($httpcli);
if ( 1 != 1 and defined($httpcli) and -e "$httpcli" ) { if ( 1 != 1 and defined($httpcli) and -e "$httpcli" ) {
debugprint "$httpcli is available."; debugprint "$httpcli is available.";
debugprint "$httpcli --connect-timeout 5 -silent '$url' 2>/dev/null | grep 'my \$tunerversion'| cut -d\\\" -f2"; debugprint
$update = `$httpcli --connect-timeout 5 -silent '$url' 2>/dev/null | grep 'my \$tunerversion'| cut -d\\\" -f2`; "$httpcli --connect-timeout 5 -silent '$url' 2>/dev/null | grep 'my \$tunerversion'| cut -d\\\" -f2";
$update =
`$httpcli --connect-timeout 5 -silent '$url' 2>/dev/null | grep 'my \$tunerversion'| cut -d\\\" -f2`;
chomp($update); chomp($update);
debugprint "VERSION: $update"; debugprint "VERSION: $update";
compare_tuner_version($update); compare_tuner_version($update);
return; return;
} }
$httpcli = `which wget`;
$httpcli=`which wget`;
chomp($httpcli); chomp($httpcli);
if ( defined($httpcli) and -e "$httpcli" ) { if ( defined($httpcli) and -e "$httpcli" ) {
debugprint "$httpcli is available."; debugprint "$httpcli is available.";
debugprint "$httpcli -e timestamping=off -T 5 -O - '$url' 2>$devnull| grep 'my \$tunerversion'| cut -d\\\" -f2"; debugprint
$update = `$httpcli -e timestamping=off -T 5 -O - '$url' 2>$devnull| grep 'my \$tunerversion'| cut -d\\\" -f2`; "$httpcli -e timestamping=off -T 5 -O - '$url' 2>$devnull| grep 'my \$tunerversion'| cut -d\\\" -f2";
$update =
`$httpcli -e timestamping=off -T 5 -O - '$url' 2>$devnull| grep 'my \$tunerversion'| cut -d\\\" -f2`;
chomp($update); chomp($update);
compare_tuner_version($update); compare_tuner_version($update);
return; return;
@ -415,11 +420,13 @@ sub validate_tuner_version {
} }
sub compare_tuner_version { sub compare_tuner_version {
my $remoteversion=shift; my $remoteversion = shift;
debugprint "Remote data: $remoteversion"; debugprint "Remote data: $remoteversion";
#exit 0; #exit 0;
if ($remoteversion ne $tunerversion) { if ( $remoteversion ne $tunerversion ) {
badprint "There is a new version of MySQLTuner available ($remoteversion)"; badprint
"There is a new version of MySQLTuner available ($remoteversion)";
return; return;
} }
goodprint "You have the latest version of MySQLTuner($tunerversion)"; goodprint "You have the latest version of MySQLTuner($tunerversion)";
@ -430,12 +437,14 @@ sub compare_tuner_version {
my ( $mysqllogin, $doremote, $remotestring, $mysqlcmd, $mysqladmincmd ); my ( $mysqllogin, $doremote, $remotestring, $mysqlcmd, $mysqladmincmd );
my $osname = $^O; my $osname = $^O;
if( $osname eq 'MSWin32' ) { if ( $osname eq 'MSWin32' ) {
eval { require Win32; } or last; eval { require Win32; } or last;
$osname = Win32::GetOSName(); $osname = Win32::GetOSName();
infoprint "* Windows OS($osname) is not fully supported.\n"; infoprint "* Windows OS($osname) is not fully supported.\n";
#exit 1; #exit 1;
} }
sub mysql_setup { sub mysql_setup {
$doremote = 0; $doremote = 0;
$remotestring = ''; $remotestring = '';
@ -452,8 +461,7 @@ sub mysql_setup {
exit 1; exit 1;
} }
elsif ( !-e $mysqladmincmd ) { elsif ( !-e $mysqladmincmd ) {
badprint badprint "Couldn't find mysqladmin in your \$PATH. Is MySQL installed?";
"Couldn't find mysqladmin in your \$PATH. Is MySQL installed?";
exit 1; exit 1;
} }
if ( $opt{mysqlcmd} ) { if ( $opt{mysqlcmd} ) {
@ -473,10 +481,11 @@ sub mysql_setup {
exit 1; exit 1;
} }
$mysqlcmd =~ s/\n$//g; $mysqlcmd =~ s/\n$//g;
my $mysqlclidefaults=`$mysqlcmd --print-defaults`; my $mysqlclidefaults = `$mysqlcmd --print-defaults`;
debugprint "MySQL Client: $mysqlclidefaults"; debugprint "MySQL Client: $mysqlclidefaults";
if ( $mysqlclidefaults=~/auto-vertical-output/ ) { if ( $mysqlclidefaults =~ /auto-vertical-output/ ) {
badprint "Avoid auto-vertical-output in configuration file(s) for MySQL like"; badprint
"Avoid auto-vertical-output in configuration file(s) for MySQL like";
exit 1; exit 1;
} }
@ -492,15 +501,17 @@ sub mysql_setup {
chomp( $opt{host} ); chomp( $opt{host} );
$opt{port} = ( $opt{port} eq 0 ) ? 3306 : $opt{port}; $opt{port} = ( $opt{port} eq 0 ) ? 3306 : $opt{port};
# If we're doing a remote connection, but forcemem wasn't specified, we need to exit # If we're doing a remote connection, but forcemem wasn't specified, we need to exit
if ( $opt{'forcemem'} eq 0 && ($opt{host} ne "127.0.0.1") && ($opt{host} ne "localhost")) { if ( $opt{'forcemem'} eq 0
badprint && ( $opt{host} ne "127.0.0.1" )
"The --forcemem option is required for remote connections"; && ( $opt{host} ne "localhost" ) )
{
badprint "The --forcemem option is required for remote connections";
exit 1; exit 1;
} }
infoprint "Performing tests on $opt{host}:$opt{port}"; infoprint "Performing tests on $opt{host}:$opt{port}";
$remotestring = " -h $opt{host} -P $opt{port}"; $remotestring = " -h $opt{host} -P $opt{port}";
if (($opt{host} ne "127.0.0.1") && ($opt{host} ne "localhost")) { if ( ( $opt{host} ne "127.0.0.1" ) && ( $opt{host} ne "localhost" ) ) {
$doremote = 1; $doremote = 1;
} }
} }
@ -510,8 +521,7 @@ sub mysql_setup {
$mysqllogin = "-u $opt{user} -p\"$opt{pass}\"" . $remotestring; $mysqllogin = "-u $opt{user} -p\"$opt{pass}\"" . $remotestring;
my $loginstatus = `$mysqladmincmd ping $mysqllogin 2>&1`; my $loginstatus = `$mysqladmincmd ping $mysqllogin 2>&1`;
if ( $loginstatus =~ /mysqld is alive/ ) { if ( $loginstatus =~ /mysqld is alive/ ) {
goodprint goodprint "Logged in using credentials passed on the command line";
"Logged in using credentials passed on the command line";
return 1; return 1;
} }
else { else {
@ -536,8 +546,7 @@ sub mysql_setup {
$mysqllogin = "-u $mysql_login -p$mysql_pass"; $mysqllogin = "-u $mysql_login -p$mysql_pass";
my $loginstatus = `mysqladmin $mysqllogin ping 2>&1`; my $loginstatus = `mysqladmin $mysqllogin ping 2>&1`;
if ( $loginstatus =~ /mysqld is alive/ ) { if ( $loginstatus =~ /mysqld is alive/ ) {
goodprint goodprint "Logged in using credentials from mysql-quickbackup.";
"Logged in using credentials from mysql-quickbackup.";
return 1; return 1;
} }
else { else {
@ -554,7 +563,7 @@ sub mysql_setup {
my $loginstatus = `$mysqladmincmd ping $mysqllogin 2>&1`; my $loginstatus = `$mysqladmincmd ping $mysqllogin 2>&1`;
unless ( $loginstatus =~ /mysqld is alive/ ) { unless ( $loginstatus =~ /mysqld is alive/ ) {
badprint badprint
"Attempted to use login credentials from Plesk, but they failed."; "Attempted to use login credentials from Plesk, but they failed.";
exit 1; exit 1;
} }
} }
@ -619,27 +628,29 @@ sub mysql_setup {
return 1; return 1;
} }
else { else {
if ( $opt{'noask'}==1 ) { if ( $opt{'noask'} == 1 ) {
badprint "Attempted to use login credentials, but they were invalid"; badprint
"Attempted to use login credentials, but they were invalid";
exit 1; exit 1;
} }
my ($name, $password); my ( $name, $password );
# If --user is defined no need to ask for username # If --user is defined no need to ask for username
if( $opt{user} ne 0 ) if ( $opt{user} ne 0 ) {
{
$name = $opt{user}; $name = $opt{user};
} }
else{ else {
print STDERR "Please enter your MySQL administrative login: "; print STDERR "Please enter your MySQL administrative login: ";
$name = <STDIN>; $name = <STDIN>;
} }
# If --pass is defined no need to ask for password # If --pass is defined no need to ask for password
if( $opt{pass} ne 0 ) if ( $opt{pass} ne 0 ) {
{
$password = $opt{pass}; $password = $opt{pass};
} }
else{ else {
print STDERR "Please enter your MySQL administrative password: "; print STDERR
"Please enter your MySQL administrative password: ";
system("stty -echo >$devnull 2>&1"); system("stty -echo >$devnull 2>&1");
$password = <STDIN>; $password = <STDIN>;
system("stty echo >$devnull 2>&1"); system("stty echo >$devnull 2>&1");
@ -653,7 +664,8 @@ sub mysql_setup {
} }
$mysqllogin .= $remotestring; $mysqllogin .= $remotestring;
my $loginstatus = `$mysqladmincmd ping $mysqllogin 2>&1`; my $loginstatus = `$mysqladmincmd ping $mysqllogin 2>&1`;
debugprint "Login status command: $mysqladmincmd ping $mysqllogin 2>&1"; debugprint
"Login status command: $mysqladmincmd ping $mysqllogin 2>&1";
if ( $loginstatus =~ /mysqld is alive/ ) { if ( $loginstatus =~ /mysqld is alive/ ) {
print STDERR ""; print STDERR "";
if ( !length($password) ) { if ( !length($password) ) {
@ -669,7 +681,8 @@ sub mysql_setup {
return 1; return 1;
} }
else { else {
badprint "Attempted to use login credentials, but they were invalid."; badprint
"Attempted to use login credentials, but they were invalid.";
exit 1; exit 1;
} }
exit 1; exit 1;
@ -798,33 +811,34 @@ sub get_basic_passwords {
sub cve_recommendations { sub cve_recommendations {
prettyprint prettyprint
"\n-------- CVE Security Recommendations ---------------------------------------"; "\n-------- CVE Security Recommendations ---------------------------------------";
unless ( defined($opt{cvefile}) && -f "$opt{cvefile}" ) { unless ( defined( $opt{cvefile} ) && -f "$opt{cvefile}" ) {
infoprint "Skipped due to --cvefile option undefined"; infoprint "Skipped due to --cvefile option undefined";
return; return;
} }
#prettyprint "Look for related CVE for $myvar{'version'} or lower in $opt{cvefile}"; #prettyprint "Look for related CVE for $myvar{'version'} or lower in $opt{cvefile}";
my $cvefound=0; my $cvefound = 0;
open( FH, "<$opt{cvefile}" ) or die "Can't open $opt{cvefile} for read: $!"; open( FH, "<$opt{cvefile}" ) or die "Can't open $opt{cvefile} for read: $!";
while (my $cveline = <FH>) while ( my $cveline = <FH> ) {
{ my @cve = split( ';', $cveline );
my @cve=split (';', $cveline); if ( mysql_micro_version_le( $cve[1], $cve[2], $cve[3] ) ) {
if (mysql_micro_version_le ($cve[1], $cve[2], $cve[3])) {
badprint "$cve[4] : $cve[5]"; badprint "$cve[4] : $cve[5]";
$cvefound++; $cvefound++;
} }
} }
close FH or die "Cannot close $opt{cvefile}: $!"; close FH or die "Cannot close $opt{cvefile}: $!";
if ($cvefound==0) { if ( $cvefound == 0 ) {
goodprint "NO SECURITY CVE FOUND FOR YOUR VERSION"; goodprint "NO SECURITY CVE FOUND FOR YOUR VERSION";
return; return;
} }
badprint $cvefound . " CVE(s) found for your MySQL release."; badprint $cvefound . " CVE(s) found for your MySQL release.";
push( @generalrec, $cvefound . " CVE(s) found for your MySQL release. Consider upgrading your version !" ); push( @generalrec,
$cvefound
. " CVE(s) found for your MySQL release. Consider upgrading your version !"
);
} }
sub security_recommendations { sub security_recommendations {
prettyprint prettyprint
"\n-------- Security Recommendations -------------------------------------------"; "\n-------- Security Recommendations -------------------------------------------";
@ -833,11 +847,12 @@ sub security_recommendations {
return; return;
} }
my $PASS_COLUMN_NAME='password'; my $PASS_COLUMN_NAME = 'password';
if ($myvar{'version'} =~ /5.7/) { if ( $myvar{'version'} =~ /5.7/ ) {
$PASS_COLUMN_NAME='authentication_string'; $PASS_COLUMN_NAME = 'authentication_string';
} }
debugprint "Password column = $PASS_COLUMN_NAME"; debugprint "Password column = $PASS_COLUMN_NAME";
#exit(0); #exit(0);
# Looking for Anonymous users # Looking for Anonymous users
my @mysqlstatlist = select_array my @mysqlstatlist = select_array
@ -973,7 +988,7 @@ sub get_replication_status {
and ( $io_running !~ /yes/i or $sql_running !~ /yes/i ) ) and ( $io_running !~ /yes/i or $sql_running !~ /yes/i ) )
{ {
badprint badprint
"This replication slave is not running but seems to be configurated."; "This replication slave is not running but seems to be configurated.";
} }
if ( defined($io_running) if ( defined($io_running)
&& $io_running =~ /yes/i && $io_running =~ /yes/i
@ -1010,10 +1025,13 @@ sub validate_mysql_version {
. $myvar{'version'} . $myvar{'version'}
. " is EOL software! Upgrade soon!"; . " is EOL software! Upgrade soon!";
} }
elsif ( ( mysql_version_ge(6) and mysql_version_le(9) ) or mysql_version_ge(12) ) { elsif ( ( mysql_version_ge(6) and mysql_version_le(9) )
or mysql_version_ge(12) )
{
badprint "Currently running unsupported MySQL version " badprint "Currently running unsupported MySQL version "
. $myvar{'version'} . ""; . $myvar{'version'} . "";
} else { }
else {
goodprint "Currently running supported MySQL version " goodprint "Currently running supported MySQL version "
. $myvar{'version'} . ""; . $myvar{'version'} . "";
} }
@ -1025,8 +1043,7 @@ sub mysql_version_ge {
$min ||= 0; $min ||= 0;
$mic ||= 0; $mic ||= 0;
return $mysqlvermajor > $maj return $mysqlvermajor > $maj
|| $mysqlvermajor == $maj || $mysqlvermajor == $maj && ( $mysqlverminor > $min
&& ( $mysqlverminor > $min
|| $mysqlverminor == $min && $mysqlvermicro >= $mic ); || $mysqlverminor == $min && $mysqlvermicro >= $mic );
} }
@ -1036,8 +1053,7 @@ sub mysql_version_le {
$min ||= 0; $min ||= 0;
$mic ||= 0; $mic ||= 0;
return $mysqlvermajor < $maj return $mysqlvermajor < $maj
|| $mysqlvermajor == $maj || $mysqlvermajor == $maj && ( $mysqlverminor < $min
&& ( $mysqlverminor < $min
|| $mysqlverminor == $min && $mysqlvermicro <= $mic ); || $mysqlverminor == $min && $mysqlvermicro <= $mic );
} }
@ -1093,8 +1109,7 @@ sub check_architecture {
"Switch to 64-bit OS - MySQL cannot currently use all of your RAM"; "Switch to 64-bit OS - MySQL cannot currently use all of your RAM";
} }
else { else {
goodprint goodprint "Operating on 32-bit architecture with less than 2GB RAM";
"Operating on 32-bit architecture with less than 2GB RAM";
} }
} }
$result{'OS'}{'Architecture'} = "$arch bits"; $result{'OS'}{'Architecture'} = "$arch bits";
@ -1160,7 +1175,7 @@ sub check_storage_engines {
: redwrap "-NDBCluster "; : redwrap "-NDBCluster ";
} }
my @dblist = grep {$_ ne 'lost+found' } select_array "SHOW DATABASES"; my @dblist = grep { $_ ne 'lost+found' } select_array "SHOW DATABASES";
$result{'Databases'}{'List'} = [@dblist]; $result{'Databases'}{'List'} = [@dblist];
infoprint "Status: $engines"; infoprint "Status: $engines";
@ -1196,7 +1211,7 @@ sub check_storage_engines {
# MySQL < 5 servers take a lot of work to get table sizes # MySQL < 5 servers take a lot of work to get table sizes
my @tblist; my @tblist;
# Now we build a database list, and loop through it to get storage engine stats for tables # Now we build a database list, and loop through it to get storage engine stats for tables
foreach my $db (@dblist) { foreach my $db (@dblist) {
chomp($db); chomp($db);
if ( $db eq "information_schema" if ( $db eq "information_schema"
@ -1220,11 +1235,11 @@ sub check_storage_engines {
# Parse through the table list to generate storage engine counts/statistics # Parse through the table list to generate storage engine counts/statistics
$fragtables = 0; $fragtables = 0;
foreach my $tbl (@tblist) { foreach my $tbl (@tblist) {
debugprint "Data dump ". Dumper (@$tbl); debugprint "Data dump " . Dumper(@$tbl);
my ( $engine, $size, $datafree ) = @$tbl; my ( $engine, $size, $datafree ) = @$tbl;
next if $engine eq 'NULL'; next if $engine eq 'NULL';
$size=0 if $size eq 'NULL'; $size = 0 if $size eq 'NULL';
$datafree=0 if $datafree eq 'NULL'; $datafree = 0 if $datafree eq 'NULL';
if ( defined $enginestats{$engine} ) { if ( defined $enginestats{$engine} ) {
$enginestats{$engine} += $size; $enginestats{$engine} += $size;
$enginecount{$engine} += 1; $enginecount{$engine} += 1;
@ -1761,8 +1776,10 @@ sub mysql_stats {
. ( . (
$myvar{'query_cache_type'} eq 0 | $myvar{'query_cache_type'} eq 0 |
$myvar{'query_cache_type'} eq 'OFF' ? "DISABLED" $myvar{'query_cache_type'} eq 'OFF' ? "DISABLED"
: ( $myvar{'query_cache_type'} eq 1 ? "ALL REQUESTS" : (
: "ON DEMAND" ) $myvar{'query_cache_type'} eq 1 ? "ALL REQUESTS"
: "ON DEMAND"
)
) . ""; ) . "";
infoprint " +-- Query Cache Size: " infoprint " +-- Query Cache Size: "
. hr_bytes( $myvar{'query_cache_size'} ) . ""; . hr_bytes( $myvar{'query_cache_size'} ) . "";
@ -1791,7 +1808,7 @@ sub mysql_stats {
&& $mycalc{'max_used_memory'} > 2 * 1024 * 1024 * 1024 ) && $mycalc{'max_used_memory'} > 2 * 1024 * 1024 * 1024 )
{ {
badprint badprint
"Allocating > 2GB RAM on 32-bit systems can cause system instability"; "Allocating > 2GB RAM on 32-bit systems can cause system instability";
badprint "Maximum reached memory usage: " badprint "Maximum reached memory usage: "
. hr_bytes( $mycalc{'max_used_memory'} ) . hr_bytes( $mycalc{'max_used_memory'} )
. " ($mycalc{'pct_max_used_memory'}% of installed RAM)"; . " ($mycalc{'pct_max_used_memory'}% of installed RAM)";
@ -2007,7 +2024,8 @@ sub mysql_stats {
"When making adjustments, make tmp_table_size/max_heap_table_size equal" "When making adjustments, make tmp_table_size/max_heap_table_size equal"
); );
push( @generalrec, push( @generalrec,
"Reduce your SELECT DISTINCT queries which have no LIMIT clause" ); "Reduce your SELECT DISTINCT queries which have no LIMIT clause"
);
} }
elsif ($mycalc{'pct_temp_disk'} > 25 elsif ($mycalc{'pct_temp_disk'} > 25
&& $mycalc{'max_tmp_table_size'} >= 256 * 1024 * 1024 ) && $mycalc{'max_tmp_table_size'} >= 256 * 1024 * 1024 )
@ -2195,6 +2213,7 @@ sub mysql_stats {
sub mysql_myisam { sub mysql_myisam {
prettyprint prettyprint
"\n-------- MyISAM Metrics ------------------------------------------------------"; "\n-------- MyISAM Metrics ------------------------------------------------------";
# Key buffer usage # Key buffer usage
if ( defined( $mycalc{'pct_key_buffer_used'} ) ) { if ( defined( $mycalc{'pct_key_buffer_used'} ) ) {
if ( $mycalc{'pct_key_buffer_used'} < 90 ) { if ( $mycalc{'pct_key_buffer_used'} < 90 ) {
@ -2403,7 +2422,6 @@ sub mariadb_ariadb {
} }
} }
# Recommendations for TokuDB # Recommendations for TokuDB
sub mariadb_tokudb { sub mariadb_tokudb {
prettyprint prettyprint
@ -2436,6 +2454,7 @@ sub mariadb_galera {
return; return;
} }
infoprint "Galera is enabled."; infoprint "Galera is enabled.";
# All is to done here # All is to done here
} }
@ -2740,7 +2759,7 @@ sub mysql_indexes {
"\n-------- Indexes Metrics -----------------------------------------------------"; "\n-------- Indexes Metrics -----------------------------------------------------";
unless ( mysql_version_ge( 5, 5 ) ) { unless ( mysql_version_ge( 5, 5 ) ) {
infoprint infoprint
"Skip Index metrics from information schema missing in this version"; "Skip Index metrics from information schema missing in this version";
return; return;
} }
my $selIdxReq = <<'ENDSQL'; my $selIdxReq = <<'ENDSQL';
@ -2844,8 +2863,7 @@ sub make_recommendations {
foreach (@adjvars) { prettyprint " " . $_ . ""; } foreach (@adjvars) { prettyprint " " . $_ . ""; }
} }
if ( @generalrec == 0 && @adjvars == 0 ) { if ( @generalrec == 0 && @adjvars == 0 ) {
prettyprint prettyprint "No additional performance recommendations are available.";
"No additional performance recommendations are available.";
} }
} }
@ -2861,18 +2879,19 @@ sub headerprint {
} }
sub string2file { sub string2file {
my $filename=shift; my $filename = shift;
my $content=shift; my $content = shift;
open my $fh, q(>), $filename open my $fh, q(>), $filename
or die "Unable to open $filename in write mode. Please check permissions for this file or directory"; or die
"Unable to open $filename in write mode. Please check permissions for this file or directory";
print $fh $content if defined($content); print $fh $content if defined($content);
close $fh; close $fh;
debugprint $content if ($opt{'debug'}); debugprint $content if ( $opt{'debug'} );
} }
sub file2array { sub file2array {
my $filename = shift; my $filename = shift;
debugprint "* reading $filename" if ($opt{'debug'}); debugprint "* reading $filename" if ( $opt{'debug'} );
my $fh; my $fh;
open( $fh, q(<), "$filename" ) open( $fh, q(<), "$filename" )
or die "Couldn't open $filename for reading: $!\n"; or die "Couldn't open $filename for reading: $!\n";
@ -2882,15 +2901,16 @@ sub file2array {
} }
sub file2string { sub file2string {
return join ( '', file2array(@_) ); return join( '', file2array(@_) );
} }
my $templateModel; my $templateModel;
if ($opt{'template'} ne 0 ) { if ( $opt{'template'} ne 0 ) {
$templateModel=file2string ($opt{'template'}); $templateModel = file2string( $opt{'template'} );
}else { }
else {
# DEFAULT REPORT TEMPLATE # DEFAULT REPORT TEMPLATE
$templateModel=<<'END_TEMPLATE'; $templateModel = <<'END_TEMPLATE';
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
@ -2908,34 +2928,39 @@ if ($opt{'template'} ne 0 ) {
</html> </html>
END_TEMPLATE END_TEMPLATE
} }
sub dump_result { sub dump_result {
if ($opt{'debug'}) { if ( $opt{'debug'} ) {
debugprint Dumper( \%result ); debugprint Dumper( \%result );
} }
debugprint "HTML REPORT: $opt{'reportfile'}"; debugprint "HTML REPORT: $opt{'reportfile'}";
if ($opt{'reportfile'} ne 0 ) { if ( $opt{'reportfile'} ne 0 ) {
eval "{ use Text::Template }"; eval "{ use Text::Template }";
if ($@) { if ($@) {
badprint "Text::Template Module is needed."; badprint "Text::Template Module is needed.";
exit 1; exit 1;
} }
my $vars= {'data' => Dumper( \%result ) }; my $vars = { 'data' => Dumper( \%result ) };
my $template; my $template;
{ {
no warnings 'once'; no warnings 'once';
$template = Text::Template->new(TYPE => 'STRING', PREPEND => q{;}, SOURCE => $templateModel) $template = Text::Template->new(
or die "Couldn't construct template: $Text::Template::ERROR"; TYPE => 'STRING',
PREPEND => q{;},
SOURCE => $templateModel
) or die "Couldn't construct template: $Text::Template::ERROR";
} }
open my $fh, q(>), $opt{'reportfile'} open my $fh, q(>), $opt{'reportfile'}
or die "Unable to open $opt{'reportfile'} in write mode. please check permissions for this file or directory"; or die
$template->fill_in(HASH =>$vars, OUTPUT=>$fh ); "Unable to open $opt{'reportfile'} in write mode. please check permissions for this file or directory";
$template->fill_in( HASH => $vars, OUTPUT => $fh );
close $fh; close $fh;
} }
if ($opt{'json'} ne 0 ) { if ( $opt{'json'} ne 0 ) {
eval "{ use JSON }"; eval "{ use JSON }";
if ($@) { if ($@) {
badprint "JSON Module is needed."; badprint "JSON Module is needed.";
@ -2949,7 +2974,7 @@ sub dump_result {
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
# BEGIN 'MAIN' # BEGIN 'MAIN'
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
headerprint # Header Print headerprint; # Header Print
mysql_setup; # Gotta login first mysql_setup; # Gotta login first
validate_tuner_version; # Check last version validate_tuner_version; # Check last version
os_setup; # Set up some OS variables os_setup; # Set up some OS variables