Update Vulnerabilities list

Indenting mysqltuner
Update Usage information
This commit is contained in:
Jean-Marie RENOUARD 2021-02-05 15:25:09 +01:00
parent 2e0f388119
commit ef66fb274c
2 changed files with 1567 additions and 986 deletions

View file

@ -685,7 +685,8 @@ sub mysql_setup {
exit 1; exit 1;
} }
elsif ( !-e $mysqladmincmd ) { elsif ( !-e $mysqladmincmd ) {
badprint "Couldn't find mysqladmin/mariadb-admin in your \$PATH. Is MySQL installed?"; badprint
"Couldn't find mysqladmin/mariadb-admin in your \$PATH. Is MySQL installed?";
exit 1; exit 1;
} }
if ( $opt{mysqlcmd} ) { if ( $opt{mysqlcmd} ) {
@ -704,7 +705,8 @@ sub mysql_setup {
exit 1; exit 1;
} }
elsif ( !-e $mysqlcmd ) { elsif ( !-e $mysqlcmd ) {
badprint "Couldn't find mysql/mariadb in your \$PATH. Is MySQL installed?"; badprint
"Couldn't find mysql/mariadb in your \$PATH. Is MySQL installed?";
exit 1; exit 1;
} }
$mysqlcmd =~ s/\n$//g; $mysqlcmd =~ s/\n$//g;
@ -1131,7 +1133,8 @@ sub get_all_vars {
# Support GTID MODE FOR MARIADB # Support GTID MODE FOR MARIADB
# Issue MariaDB GTID mode #513 # Issue MariaDB GTID mode #513
$myvar{'gtid_mode'} = 'ON' $myvar{'gtid_mode'} = 'ON'
if ( defined( $myvar{'gtid_current_pos'} ) and $myvar{'gtid_current_pos'} ne '' ); if ( defined( $myvar{'gtid_current_pos'} )
and $myvar{'gtid_current_pos'} ne '' );
$myvar{'have_threadpool'} = "NO"; $myvar{'have_threadpool'} = "NO";
if ( defined( $myvar{'thread_pool_size'} ) if ( defined( $myvar{'thread_pool_size'} )
@ -1248,14 +1251,14 @@ sub get_log_file_real_path {
sub log_file_recommendations { sub log_file_recommendations {
my $fh; my $fh;
$myvar{'log_error'} = $opt{'server-log'} || $myvar{'log_error'} = $opt{'server-log'}
get_log_file_real_path( $myvar{'log_error'}, $myvar{'hostname'}, || get_log_file_real_path( $myvar{'log_error'}, $myvar{'hostname'},
$myvar{'datadir'} ); $myvar{'datadir'} );
subheaderprint "Log file Recommendations"; subheaderprint "Log file Recommendations";
if ( "$myvar{'log_error'}" eq "stderr" ) { if ( "$myvar{'log_error'}" eq "stderr" ) {
badprint "log_error is set to $myvar{'log_error'} MT can't read stderr"; badprint "log_error is set to $myvar{'log_error'} MT can't read stderr";
return return;
} }
elsif ( $myvar{'log_error'} =~ /^(docker|podman|kubectl):(.*)/ ) { elsif ( $myvar{'log_error'} =~ /^(docker|podman|kubectl):(.*)/ ) {
open( $fh, '-|', "$1 logs --tail=$maxlines '$2'" ) open( $fh, '-|', "$1 logs --tail=$maxlines '$2'" )
@ -1316,7 +1319,8 @@ sub log_file_recommendations {
while ( my $logLi = <$fh> ) { while ( my $logLi = <$fh> ) {
chomp $logLi; chomp $logLi;
$numLi++; $numLi++;
debugprint "$numLi: $logLi" if $logLi =~ /warning|error/i and $logLi !~ /Logging to/; debugprint "$numLi: $logLi"
if $logLi =~ /warning|error/i and $logLi !~ /Logging to/;
$nbErrLog++ if $logLi =~ /error/i and $logLi !~ /Logging to/; $nbErrLog++ if $logLi =~ /error/i and $logLi !~ /Logging to/;
$nbWarnLog++ if $logLi =~ /warning/i; $nbWarnLog++ if $logLi =~ /warning/i;
push @lastShutdowns, $logLi push @lastShutdowns, $logLi
@ -1797,6 +1801,7 @@ sub security_recommendations {
} }
my $PASS_COLUMN_NAME = 'password'; my $PASS_COLUMN_NAME = 'password';
# New table schema available since mysql-5.7 and mariadb-10.2 # New table schema available since mysql-5.7 and mariadb-10.2
# But need to be checked # But need to be checked
if ( $myvar{'version'} =~ /5\.7|10\.[2-5]\..*MariaDB*/ ) { if ( $myvar{'version'} =~ /5\.7|10\.[2-5]\..*MariaDB*/ ) {
@ -1831,7 +1836,10 @@ sub security_recommendations {
. " anonymous accounts." ); . " anonymous accounts." );
foreach my $line ( sort @mysqlstatlist ) { foreach my $line ( sort @mysqlstatlist ) {
chomp($line); chomp($line);
badprint "User " . $line . " is an anonymous account. Remove with DROP USER " . $line . ";"; badprint "User "
. $line
. " is an anonymous account. Remove with DROP USER "
. $line . ";";
} }
} }
else { else {
@ -1862,7 +1870,9 @@ q{SELECT CONCAT(QUOTE(user), '@', QUOTE(host)) FROM mysql.global_priv WHERE
foreach my $line ( sort @mysqlstatlist ) { foreach my $line ( sort @mysqlstatlist ) {
chomp($line); chomp($line);
badprint "User '" . $line . "' has no password set."; badprint "User '" . $line . "' has no password set.";
push (@generalrec, "Set up a Secure Password for $line user: SET PASSWORD FOR $line = PASSWORD('secure_password');") push( @generalrec,
"Set up a Secure Password for $line user: SET PASSWORD FOR $line = PASSWORD('secure_password');"
);
} }
} }
else { else {
@ -1887,7 +1897,9 @@ q{SELECT CONCAT(QUOTE(user), '@', QUOTE(host)) FROM mysql.global_priv WHERE
foreach my $line ( sort @mysqlstatlist ) { foreach my $line ( sort @mysqlstatlist ) {
chomp($line); chomp($line);
badprint "User " . $line . " has user name as password."; badprint "User " . $line . " has user name as password.";
push (@generalrec, "Set up a Secure Password for $line user: SET PASSWORD FOR $line = PASSWORD('secure_password');"); push( @generalrec,
"Set up a Secure Password for $line user: SET PASSWORD FOR $line = PASSWORD('secure_password');"
);
} }
} }
@ -1897,11 +1909,15 @@ q{SELECT CONCAT(QUOTE(user), '@', QUOTE(host)) FROM mysql.global_priv WHERE
foreach my $line ( sort @mysqlstatlist ) { foreach my $line ( sort @mysqlstatlist ) {
chomp($line); chomp($line);
my $luser = ( split /@/, $line )[0]; my $luser = ( split /@/, $line )[0];
badprint "User '" . $line. "' does not specify hostname restrictions."; badprint "User '" . $line
. "' does not specify hostname restrictions.";
push( @generalrec, push( @generalrec,
"Restrict Host for $luser\@% to $luser\@LimitedIPRangeOrLocalhost" ); "Restrict Host for $luser\@% to $luser\@LimitedIPRangeOrLocalhost"
);
push( @generalrec, push( @generalrec,
"RENAME USER $luser\@'%' TO " . $luser. "\@LimitedIPRangeOrLocalhost;" ); "RENAME USER $luser\@'%' TO "
. $luser
. "\@LimitedIPRangeOrLocalhost;" );
} }
} }
@ -1945,7 +1961,11 @@ q{SELECT CONCAT(QUOTE(user), '@', QUOTE(host)) FROM mysql.global_priv WHERE
badprint "User '" . $line badprint "User '" . $line
. "' is using weak password: $pass in a lower, upper or capitalize derivative version."; . "' is using weak password: $pass in a lower, upper or capitalize derivative version.";
push (@generalrec, "Set up a Secure Password for $line user: SET PASSWORD FOR '" . (split /@/, $line)[0] . "'\@'".(split /@/, $line)[1]."' = PASSWORD('secure_password');"); push( @generalrec,
"Set up a Secure Password for $line user: SET PASSWORD FOR '"
. ( split /@/, $line )[0] . "'\@'"
. ( split /@/, $line )[1]
. "' = PASSWORD('secure_password');" );
$nbins++; $nbins++;
} }
} }
@ -1954,7 +1974,9 @@ q{SELECT CONCAT(QUOTE(user), '@', QUOTE(host)) FROM mysql.global_priv WHERE
} }
} }
if ( $nbins > 0 ) { if ( $nbins > 0 ) {
push( @generalrec, $nbins . " user(s) used basic or weak password from basic dictionary." ); push( @generalrec,
$nbins
. " user(s) used basic or weak password from basic dictionary." );
} }
} }
@ -2036,14 +2058,22 @@ sub validate_mysql_version {
$mysqlverminor ||= 0; $mysqlverminor ||= 0;
$mysqlvermicro ||= 0; $mysqlvermicro ||= 0;
if ( mysql_version_eq(8) or mysql_version_eq(5, 6) or mysql_version_eq(5, 7) if ( mysql_version_eq(8)
or mysql_version_eq(10, 2) or mysql_version_eq(10, 3) or mysql_version_eq(10, 4) or mysql_version_eq( 5, 6 )
or mysql_version_eq( 5, 7 )
or mysql_version_eq( 10, 2 )
or mysql_version_eq( 10, 3 )
or mysql_version_eq( 10, 4 )
or mysql_version_eq( 10, 5 ) ) or mysql_version_eq( 10, 5 ) )
{ {
goodprint "Currently running supported MySQL version " . $myvar{'version'} . ""; goodprint "Currently running supported MySQL version "
. $myvar{'version'} . "";
return; return;
} }
if ( mysql_version_ge( 5 ) or mysql_version_ge( 4 ) or mysql_version_eq(10, 0) ) { if ( mysql_version_ge(5)
or mysql_version_ge(4)
or mysql_version_eq( 10, 0 ) )
{
badprint "Your MySQL version " badprint "Your MySQL version "
. $myvar{'version'} . $myvar{'version'}
. " is EOL software! Upgrade soon!"; . " is EOL software! Upgrade soon!";
@ -2743,6 +2773,7 @@ sub calculations {
$mycalc{'innodb_log_size_pct'} = 0; $mycalc{'innodb_log_size_pct'} = 0;
$myvar{'innodb_buffer_pool_size'} = 0; $myvar{'innodb_buffer_pool_size'} = 0;
} }
# InnoDB Buffer pool read cache efficiency # InnoDB Buffer pool read cache efficiency
( (
$mystat{'Innodb_buffer_pool_read_requests'}, $mystat{'Innodb_buffer_pool_read_requests'},
@ -3113,10 +3144,12 @@ sub mysql_stats {
"join_buffer_size (> " "join_buffer_size (> "
. hr_bytes( $myvar{'join_buffer_size'} ) . hr_bytes( $myvar{'join_buffer_size'} )
. ", or always use indexes with JOINs)" ); . ", or always use indexes with JOINs)" );
push( @generalrec, push(
@generalrec,
"We will suggest raising the 'join_buffer_size' until JOINs not using indexes are found. "We will suggest raising the 'join_buffer_size' until JOINs not using indexes are found.
See https://dev.mysql.com/doc/internals/en/join-buffer-size.html See https://dev.mysql.com/doc/internals/en/join-buffer-size.html
(specially the conclusions at the bottom of the page)."); (specially the conclusions at the bottom of the page)."
);
} }
else { else {
goodprint "No joins without indexes"; goodprint "No joins without indexes";
@ -3278,16 +3311,27 @@ sub mysql_stats {
$mycalc{'total_tables'} = $nbtables; $mycalc{'total_tables'} = $nbtables;
if ( defined $myvar{'table_definition_cache'} ) { if ( defined $myvar{'table_definition_cache'} ) {
if ( $myvar{'table_definition_cache'} == -1 ) { if ( $myvar{'table_definition_cache'} == -1 ) {
infoprint ("table_definition_cache(".$myvar{'table_definition_cache'} .") is in autosizing mode"); infoprint( "table_definition_cache("
} elsif ($myvar{'table_definition_cache'} < $nbtables ) { . $myvar{'table_definition_cache'}
badprint "table_definition_cache(".$myvar{'table_definition_cache'} .") is lower than number of tables($nbtables) "; . ") is in autosizing mode" );
}
elsif ( $myvar{'table_definition_cache'} < $nbtables ) {
badprint "table_definition_cache("
. $myvar{'table_definition_cache'}
. ") is lower than number of tables($nbtables) ";
push( @adjvars, push( @adjvars,
"table_definition_cache(".$myvar{'table_definition_cache'} .") > " . $nbtables . " or -1 (autosizing if supported)" ); "table_definition_cache("
. $myvar{'table_definition_cache'} . ") > "
. $nbtables
. " or -1 (autosizing if supported)" );
} }
else { else {
goodprint "table_definition_cache(".$myvar{'table_definition_cache'} .") is upper than number of tables($nbtables)"; goodprint "table_definition_cache("
. $myvar{'table_definition_cache'}
. ") is upper than number of tables($nbtables)";
} }
} else { }
else {
infoprint "No table_definition_cache variable found."; infoprint "No table_definition_cache variable found.";
} }
@ -3379,6 +3423,7 @@ sub mysql_myisam {
infoprint "MyISAM Metrics are disabled on last MySQL versions."; infoprint "MyISAM Metrics are disabled on last MySQL versions.";
return; return;
} }
# 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 ) {
@ -3416,8 +3461,7 @@ sub mysql_myisam {
# Key buffer # Key buffer
if ( !defined( $mycalc{'total_myisam_indexes'} ) ) { if ( !defined( $mycalc{'total_myisam_indexes'} ) ) {
push( @generalrec, push( @generalrec,
"Unable to calculate MyISAM index size on MySQL server < 5.0.0" "Unable to calculate MyISAM index size on MySQL server < 5.0.0" );
);
} }
else { else {
if ( $myvar{'key_buffer_size'} < $mycalc{'total_myisam_indexes'} if ( $myvar{'key_buffer_size'} < $mycalc{'total_myisam_indexes'}
@ -4204,7 +4248,12 @@ sub mysqsl_pfs {
# Unused Indexes # Unused Indexes
subheaderprint "Performance schema: Unused indexes"; subheaderprint "Performance schema: Unused indexes";
$nbL = 1; $nbL = 1;
for my $lQuery ( select_array("select \* from sys.schema_unused_indexes where object_schema not in ('performance_schema')" )) { for my $lQuery (
select_array(
"select \* from sys.schema_unused_indexes where object_schema not in ('performance_schema')"
)
)
{
infoprint " +-- $nbL: $lQuery"; infoprint " +-- $nbL: $lQuery";
$nbL++; $nbL++;
} }
@ -5053,13 +5102,11 @@ sub mariadb_aria {
subheaderprint "Aria Metrics"; subheaderprint "Aria Metrics";
# Aria # Aria
if ( ! defined $myvar{'have_aria'} ) if ( !defined $myvar{'have_aria'} ) {
{
infoprint "Aria Storage Engine not available."; infoprint "Aria Storage Engine not available.";
return; return;
} }
if ( $myvar{'have_aria'} ne "YES" ) if ( $myvar{'have_aria'} ne "YES" ) {
{
infoprint "Aria Storage Engine is disabled."; infoprint "Aria Storage Engine is disabled.";
return; return;
} }
@ -5562,11 +5609,14 @@ sub mysql_innodb {
infoprint "InnoDB is disabled."; infoprint "InnoDB is disabled.";
if ( mysql_version_ge( 5, 5 ) ) { if ( mysql_version_ge( 5, 5 ) ) {
my $defengine = 'InnoDB'; my $defengine = 'InnoDB';
$defengine = $myvar{'default_storage_engine'} if defined($myvar{'default_storage_engine'}); $defengine = $myvar{'default_storage_engine'}
if defined( $myvar{'default_storage_engine'} );
badprint badprint
"InnoDB Storage engine is disabled. $defengine is the default storage engine" if $defengine eq 'InnoDB'; "InnoDB Storage engine is disabled. $defengine is the default storage engine"
if $defengine eq 'InnoDB';
infoprint infoprint
"InnoDB Storage engine is disabled. $defengine is the default storage engine" if $defengine ne 'InnoDB'; "InnoDB Storage engine is disabled. $defengine is the default storage engine"
if $defengine ne 'InnoDB';
} }
return; return;
} }
@ -5676,9 +5726,9 @@ sub mysql_innodb {
. ") if possible, so InnoDB total log files size equals to 25% of buffer pool size." . ") if possible, so InnoDB total log files size equals to 25% of buffer pool size."
); );
if ( mysql_version_le( 5, 6, 2 ) ) { if ( mysql_version_le( 5, 6, 2 ) ) {
push( push( @generalrec,
@generalrec, "For MySQL 5.6.2 and lower, Max combined innodb_log_file_size should have a ceiling of (4096MB / log files in group) - 1MB."
"For MySQL 5.6.2 and lower, Max combined innodb_log_file_size should have a ceiling of (4096MB / log files in group) - 1MB."); );
} }
push( @generalrec, push( @generalrec,
"Before changing innodb_log_file_size and/or innodb_log_files_in_group read this: https://bit.ly/2TcGgtU" "Before changing innodb_log_file_size and/or innodb_log_files_in_group read this: https://bit.ly/2TcGgtU"
@ -5693,7 +5743,9 @@ sub mysql_innodb {
} }
# InnoDB Buffer Pool Instances (MySQL 5.6.6+) # InnoDB Buffer Pool Instances (MySQL 5.6.6+)
if ( not mysql_version_ge(10, 5) and defined( $myvar{'innodb_buffer_pool_instances'} ) ) { if ( not mysql_version_ge( 10, 5 )
and defined( $myvar{'innodb_buffer_pool_instances'} ) )
{
# Bad Value if > 64 # Bad Value if > 64
if ( $myvar{'innodb_buffer_pool_instances'} > 64 ) { if ( $myvar{'innodb_buffer_pool_instances'} > 64 ) {
@ -5727,6 +5779,7 @@ sub mysql_innodb {
goodprint "InnoDB buffer pool instances: " goodprint "InnoDB buffer pool instances: "
. $myvar{'innodb_buffer_pool_instances'} . ""; . $myvar{'innodb_buffer_pool_instances'} . "";
} }
# InnoDB Buffer Pool Size < 1Go # InnoDB Buffer Pool Size < 1Go
} }
else { else {
@ -6054,7 +6107,8 @@ sub mysql_tables {
return; return;
} }
if ( mysql_version_ge(8) and not mysql_version_eq(10) ) { if ( mysql_version_ge(8) and not mysql_version_eq(10) ) {
infoprint "MySQL and Percona version 8 and greater have remove PROCEDURE ANALYSE feature" infoprint
"MySQL and Percona version 8 and greater have remove PROCEDURE ANALYSE feature";
} }
foreach (@dblist) { foreach (@dblist) {
my $dbname = $_; my $dbname = $_;
@ -6086,9 +6140,13 @@ sub mysql_tables {
) unless ( mysql_version_ge(8) and not mysql_version_eq(10) ); ) unless ( mysql_version_ge(8) and not mysql_version_eq(10) );
if ( $optimal_type eq '' ) { if ( $optimal_type eq '' ) {
infoprint " Current Fieldtype: $current_type"; infoprint " Current Fieldtype: $current_type";
#infoprint " Optimal Fieldtype: Not available"; #infoprint " Optimal Fieldtype: Not available";
} }
elsif ( $current_type ne $optimal_type and $current_type !~ /.*DATETIME.*/ and $current_type !~ /.*TIMESTAMP.*/) { elsif ( $current_type ne $optimal_type
and $current_type !~ /.*DATETIME.*/
and $current_type !~ /.*TIMESTAMP.*/ )
{
infoprint " Current Fieldtype: $current_type"; infoprint " Current Fieldtype: $current_type";
if ( $optimal_type =~ /.*ENUM\(.*/ ) { if ( $optimal_type =~ /.*ENUM\(.*/ ) {
$optimal_type = "ENUM( ... )"; $optimal_type = "ENUM( ... )";

File diff suppressed because one or more lines are too long