Add advice for performance schema

This commit is contained in:
Jean-Marie RENOUARD 2017-02-07 06:56:17 +01:00
parent 7d8224a6e4
commit 871d984d1a
2 changed files with 146 additions and 99 deletions

View file

@ -292,7 +292,9 @@
* thread_pool_size between 4 to 8 for MyIsam usage * thread_pool_size between 4 to 8 for MyIsam usage
## MySQLTuner performance schema and sysschema information ## MySQLTuner performance schema and sysschema information
* Check that Performance schema is activated for 5.6+ version
* Check that Performance schema is disactivated for 5.5- version
* Check that Sys schema is installed
* sys Schema version * sys Schema version
* Top user per connection * Top user per connection
* Top user per statement * Top user per statement

View file

@ -560,7 +560,8 @@ sub validate_tuner_version {
} }
debugprint "curl and wget are not available."; debugprint "curl and wget are not available.";
infoprint "Unable to check for the latest MySQLTuner version"; infoprint "Unable to check for the latest MySQLTuner version";
infoprint "Using --pass and --password option is insecure during MySQLTuner execution(Password disclosure)" infoprint
"Using --pass and --password option is insecure during MySQLTuner execution(Password disclosure)"
if ( defined( $opt{'pass'} ) ); if ( defined( $opt{'pass'} ) );
} }
@ -710,6 +711,7 @@ sub mysql_setup {
debugprint "MySQL Client: $mysqlcmd"; debugprint "MySQL Client: $mysqlcmd";
$opt{port} = ( $opt{port} eq 0 ) ? 3306 : $opt{port}; $opt{port} = ( $opt{port} eq 0 ) ? 3306 : $opt{port};
# Are we being asked to connect via a socket? # Are we being asked to connect via a socket?
if ( $opt{socket} ne 0 ) { if ( $opt{socket} ne 0 ) {
$remotestring = " -S $opt{socket} -P $opt{port}"; $remotestring = " -S $opt{socket} -P $opt{port}";
@ -1055,7 +1057,8 @@ sub get_all_vars {
# Support GTID MODE FOR MARIADB # Support GTID MODE FOR MARIADB
# Issue MariaDB GTID mode #272 # Issue MariaDB GTID mode #272
$myvar{'gtid_mode'}=$myvar{'gtid_strict_mode'} if (defined($myvar{'gtid_strict_mode'})); $myvar{'gtid_mode'} = $myvar{'gtid_strict_mode'}
if ( defined( $myvar{'gtid_strict_mode'} ) );
$myvar{'have_threadpool'} = "NO"; $myvar{'have_threadpool'} = "NO";
if ( defined( $myvar{'thread_pool_size'} ) if ( defined( $myvar{'thread_pool_size'} )
@ -1112,8 +1115,9 @@ sub remove_empty {
sub grep_file_contents { sub grep_file_contents {
my $file = shift; my $file = shift;
my $patt my $patt;
} }
sub get_file_contents { sub get_file_contents {
my $file = shift; my $file = shift;
open( my $fh, "<", $file ) or die "Can't open $file for read: $!"; open( my $fh, "<", $file ) or die "Can't open $file for read: $!";
@ -1129,30 +1133,37 @@ sub get_basic_passwords {
sub log_file_recommandations { sub log_file_recommandations {
subheaderprint "Log file Recommendations"; subheaderprint "Log file Recommendations";
infoprint "Log file: " . $myvar{'log_error'}. "(".hr_bytes_rnd((stat $myvar{'log_error'})[7]).")"; infoprint "Log file: "
. $myvar{'log_error'} . "("
. hr_bytes_rnd( ( stat $myvar{'log_error'} )[7] ) . ")";
if ( -f "$myvar{'log_error'}" ) { if ( -f "$myvar{'log_error'}" ) {
goodprint "Log file $myvar{'log_error'} exists"; goodprint "Log file $myvar{'log_error'} exists";
} else { }
else {
badprint "Log file $myvar{'log_error'} doesn't exist"; badprint "Log file $myvar{'log_error'} doesn't exist";
} }
if ( -r "$myvar{'log_error'}" ) { if ( -r "$myvar{'log_error'}" ) {
goodprint "Log file $myvar{'log_error'} is readable."; goodprint "Log file $myvar{'log_error'} is readable.";
} else { }
else {
badprint "Log file $myvar{'log_error'} isn't readable."; badprint "Log file $myvar{'log_error'} isn't readable.";
return; return;
} }
if ( ( stat $myvar{'log_error'} )[7] > 0 ) { if ( ( stat $myvar{'log_error'} )[7] > 0 ) {
goodprint "Log file $myvar{'log_error'} is not empty"; goodprint "Log file $myvar{'log_error'} is not empty";
} else { }
else {
badprint "Log file $myvar{'log_error'} is empty"; badprint "Log file $myvar{'log_error'} is empty";
} }
if ( ( stat $myvar{'log_error'} )[7] < 32 * 1024 * 1024 ) { if ( ( stat $myvar{'log_error'} )[7] < 32 * 1024 * 1024 ) {
goodprint "Log file $myvar{'log_error'} is smaller than 32 Mb"; goodprint "Log file $myvar{'log_error'} is smaller than 32 Mb";
} else { }
else {
badprint "Log file $myvar{'log_error'} is bigger than 32 Mb"; badprint "Log file $myvar{'log_error'} is bigger than 32 Mb";
push @generalrec, push @generalrec,
$myvar{'log_error'} ."is > 32Mb, you should analyze why or implement a rotation log strategy such as logrotate!" ; $myvar{'log_error'}
. "is > 32Mb, you should analyze why or implement a rotation log strategy such as logrotate!";
} }
my @log_content = get_file_contents( $myvar{'log_error'} ); my @log_content = get_file_contents( $myvar{'log_error'} );
@ -1167,19 +1178,23 @@ sub log_file_recommandations {
debugprint "$numLi: $logLi" if $logLi =~ /warning|error/i; debugprint "$numLi: $logLi" if $logLi =~ /warning|error/i;
$nbErrLog++ if $logLi =~ /error/i; $nbErrLog++ if $logLi =~ /error/i;
$nbWarnLog++ if $logLi =~ /warning/i; $nbWarnLog++ if $logLi =~ /warning/i;
push @lastShutdowns, $logLi if $logLi =~ /Shutdown complete/ and $logLi !~ /Innodb/i; push @lastShutdowns, $logLi
if $logLi =~ /Shutdown complete/ and $logLi !~ /Innodb/i;
push @lastStarts, $logLi if $logLi =~ /ready for connections/; push @lastStarts, $logLi if $logLi =~ /ready for connections/;
} }
if ( $nbWarnLog > 0 ) { if ( $nbWarnLog > 0 ) {
badprint "$myvar{'log_error'} contains $nbWarnLog warning(s)."; badprint "$myvar{'log_error'} contains $nbWarnLog warning(s).";
push @generalrec, "Control warning line(s) into $myvar{'log_error'} file"; push @generalrec,
} else { "Control warning line(s) into $myvar{'log_error'} file";
}
else {
goodprint "$myvar{'log_error'} doesn't contain any warning."; goodprint "$myvar{'log_error'} doesn't contain any warning.";
} }
if ( $nbErrLog > 0 ) { if ( $nbErrLog > 0 ) {
badprint "$myvar{'log_error'} contains $nbErrLog error(s)."; badprint "$myvar{'log_error'} contains $nbErrLog error(s).";
push @generalrec, "Control error line(s) into $myvar{'log_error'} file"; push @generalrec, "Control error line(s) into $myvar{'log_error'} file";
} else { }
else {
goodprint "$myvar{'log_error'} doesn't contain any error."; goodprint "$myvar{'log_error'} doesn't contain any error.";
} }
@ -1193,7 +1208,8 @@ sub log_file_recommandations {
$nStart++; $nStart++;
infoprint "$nStart) $startd"; infoprint "$nStart) $startd";
} }
infoprint scalar @lastShutdowns . " shutdown(s) detected in $myvar{'log_error'}"; infoprint scalar @lastShutdowns
. " shutdown(s) detected in $myvar{'log_error'}";
$nStart = 0; $nStart = 0;
$nEnd = 10; $nEnd = 10;
if ( scalar @lastShutdowns < $nEnd ) { if ( scalar @lastShutdowns < $nEnd ) {
@ -1203,11 +1219,10 @@ sub log_file_recommandations {
$nStart++; $nStart++;
infoprint "$nStart) $shutd"; infoprint "$nStart) $shutd";
} }
#exit 0; #exit 0;
} }
sub cve_recommendations { sub cve_recommendations {
subheaderprint "CVE Security Recommendations"; subheaderprint "CVE Security Recommendations";
unless ( defined( $opt{cvefile} ) && -f "$opt{cvefile}" ) { unless ( defined( $opt{cvefile} ) && -f "$opt{cvefile}" ) {
@ -1751,7 +1766,8 @@ sub security_recommendations {
$nbins++; $nbins++;
} }
} }
debugprint "$nbInterPass / ".scalar(@passwords) if ($nbInterPass %1000 ==0); debugprint "$nbInterPass / " . scalar(@passwords)
if ( $nbInterPass % 1000 == 0 );
} }
} }
if ( $nbins > 0 ) { if ( $nbins > 0 ) {
@ -2017,7 +2033,8 @@ sub check_storage_engines {
my $not_innodb = ''; my $not_innodb = '';
if ( not defined $result{'Variables'}{'innodb_file_per_table'} ) { if ( not defined $result{'Variables'}{'innodb_file_per_table'} ) {
$not_innodb = "AND NOT ENGINE='InnoDB'"; $not_innodb = "AND NOT ENGINE='InnoDB'";
} elsif ( $result{'Variables'}{'innodb_file_per_table'} eq 'OFF' ) { }
elsif ( $result{'Variables'}{'innodb_file_per_table'} eq 'OFF' ) {
$not_innodb = "AND NOT ENGINE='InnoDB'"; $not_innodb = "AND NOT ENGINE='InnoDB'";
} }
$result{'Tables'}{'Fragmented tables'} = $result{'Tables'}{'Fragmented tables'} =
@ -2502,7 +2519,8 @@ sub calculations {
# InnoDB # InnoDB
if ( $myvar{'have_innodb'} eq "YES" ) { if ( $myvar{'have_innodb'} eq "YES" ) {
$mycalc{'innodb_log_size_pct'} = $mycalc{'innodb_log_size_pct'} =
( $myvar{'innodb_log_file_size'} *$myvar{'innodb_log_files_in_group'} * 100 / ( $myvar{'innodb_log_file_size'} *
$myvar{'innodb_log_files_in_group'} * 100 /
$myvar{'innodb_buffer_pool_size'} ); $myvar{'innodb_buffer_pool_size'} );
} }
@ -2770,7 +2788,10 @@ sub mysql_stats {
push( @generalrec, push( @generalrec,
"Upgrade MySQL to version 4+ to utilize query caching" ); "Upgrade MySQL to version 4+ to utilize query caching" );
} }
elsif ( mysql_version_ge( 5, 5 ) and !mysql_version_ge( 10, 1 ) and $myvar{'query_cache_type'} eq "OFF" ) { elsif ( mysql_version_ge( 5, 5 )
and !mysql_version_ge( 10, 1 )
and $myvar{'query_cache_type'} eq "OFF" )
{
goodprint goodprint
"Query cache is disabled by default due to mutex contention on multiprocessor machines."; "Query cache is disabled by default due to mutex contention on multiprocessor machines.";
} }
@ -3292,22 +3313,36 @@ sub mysqsl_pfs {
subheaderprint "Performance schema"; subheaderprint "Performance schema";
# Performance Schema # Performance Schema
unless ( defined( $myvar{'performance_schema'} ) $myvar{'performance_schema'} = 'OFF'
and $myvar{'performance_schema'} eq 'ON' ) unless defined( $myvar{'performance_schema'} );
{ unless ( $myvar{'performance_schema'} eq 'ON' ) {
infoprint "Performance schema is disabled."; infoprint "Performance schema is disabled.";
return; if ( mysql_version_ge( 5, 5 ) ) {
push( @generalrec,
"Performance should be activated for better diagnostics" );
push( @adjvars, "performance_schema = ON enable PFS" );
} }
infoprint "Performance schema is enabled."; else {
push( @generalrec,
"Performance shouldn't be activated for MySQL and MariaDB 5.5 and lower version"
);
push( @adjvars, "performance_schema = OFF disable PFS" );
}
}
debugprint "Performance schema is " . $myvar{'performance_schema'};
infoprint "Memory used by P_S: " . hr_bytes( get_pf_memory() ); infoprint "Memory used by P_S: " . hr_bytes( get_pf_memory() );
unless ( grep /^sys$/, select_array("SHOW DATABASES") ) { unless ( grep /^sys$/, select_array("SHOW DATABASES") ) {
infoprint "Sys schema isn't installed."; infoprint "Sys schema isn't installed.";
push( @generalrec,
"Consider installing Sys schema from https://github.com/mysql/mysql-sys"
);
return; return;
} }
else {
infoprint "Sys schema is installed."; infoprint "Sys schema is installed.";
return if ( $opt{pfstat} == 0 ); }
return if ( $opt{pfstat} == 0 or $myvar{'performance_schema'} ne 'ON' );
infoprint "Sys schema Version: " infoprint "Sys schema Version: "
. select_one("select sys_version from sys.version"); . select_one("select sys_version from sys.version");
@ -5245,7 +5280,8 @@ sub mysql_innodb {
} }
if ( defined $myvar{'innodb_log_files_in_group'} ) { if ( defined $myvar{'innodb_log_files_in_group'} ) {
infoprint " +-- InnoDB Total Log File Size: " infoprint " +-- InnoDB Total Log File Size: "
. hr_bytes( $myvar{'innodb_log_files_in_group'}*$myvar{'innodb_log_file_size'}); . hr_bytes( $myvar{'innodb_log_files_in_group'} *
$myvar{'innodb_log_file_size'} );
} }
if ( defined $myvar{'innodb_log_buffer_size'} ) { if ( defined $myvar{'innodb_log_buffer_size'} ) {
infoprint " +-- InnoDB Log Buffer: " infoprint " +-- InnoDB Log Buffer: "
@ -5294,17 +5330,24 @@ sub mysql_innodb {
{ {
badprint "Ratio InnoDB log file size / InnoDB Buffer pool size (" badprint "Ratio InnoDB log file size / InnoDB Buffer pool size ("
. $mycalc{'innodb_log_size_pct'} . " %): " . $mycalc{'innodb_log_size_pct'} . " %): "
. hr_bytes( $myvar{'innodb_log_file_size'} )." * ".$myvar{'innodb_log_files_in_group'}. "/" . hr_bytes( $myvar{'innodb_log_file_size'} ) . " * "
. $myvar{'innodb_log_files_in_group'} . "/"
. hr_bytes( $myvar{'innodb_buffer_pool_size'} ) . hr_bytes( $myvar{'innodb_buffer_pool_size'} )
. " should be equal 25%"; . " should be equal 25%";
push( @adjvars, push(
@adjvars,
"innodb_log_file_size * innodb_log_files_in_group should be equals to 1/4 of buffer pool size (=" "innodb_log_file_size * innodb_log_files_in_group should be equals to 1/4 of buffer pool size (="
. hr_bytes_rnd( $myvar{'innodb_buffer_pool_size'} * $myvar{'innodb_log_files_in_group'} / 4 ) . hr_bytes_rnd(
. ") if possible." ); $myvar{'innodb_buffer_pool_size'} *
$myvar{'innodb_log_files_in_group'} / 4
)
. ") if possible."
);
} }
else { else {
goodprint "InnoDB log file size / InnoDB Buffer pool size: " goodprint "InnoDB log file size / InnoDB Buffer pool size: "
. hr_bytes( $myvar{'innodb_log_file_size'} ) ." * ".$myvar{'innodb_log_files_in_group'}. "/" . hr_bytes( $myvar{'innodb_log_file_size'} ) . " * "
. $myvar{'innodb_log_files_in_group'} . "/"
. hr_bytes( $myvar{'innodb_buffer_pool_size'} ) . hr_bytes( $myvar{'innodb_buffer_pool_size'} )
. " should be equal 25%"; . " should be equal 25%";
} }
@ -5567,7 +5610,9 @@ sub mysql_databases {
) )
) . ")"; ) . ")";
badprint "Index size is larger than data size for $dbinfo[0] \n" badprint "Index size is larger than data size for $dbinfo[0] \n"
if ( $dbinfo[2] ne 'NULL' ) and ( $dbinfo[3] ne 'NULL' ) and ( $dbinfo[2] < $dbinfo[3] ); if ( $dbinfo[2] ne 'NULL' )
and ( $dbinfo[3] ne 'NULL' )
and ( $dbinfo[2] < $dbinfo[3] );
badprint "There are " . $dbinfo[5] . " storage engines. Be careful. \n" badprint "There are " . $dbinfo[5] . " storage engines. Be careful. \n"
if $dbinfo[5] > 1; if $dbinfo[5] > 1;
$result{'Databases'}{ $dbinfo[0] }{'Rows'} = $dbinfo[1]; $result{'Databases'}{ $dbinfo[0] }{'Rows'} = $dbinfo[1];