From 69ffbc7126a8d3171af44e47d3dd17ec4397c7e6 Mon Sep 17 00:00:00 2001 From: mhasbini Date: Sat, 13 Feb 2016 23:57:16 +0000 Subject: [PATCH 001/126] Fixed asking for username/password when it's already passed. --- mysqltuner.pl | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/mysqltuner.pl b/mysqltuner.pl index 22e3e95..8d62558 100755 --- a/mysqltuner.pl +++ b/mysqltuner.pl @@ -598,7 +598,7 @@ sub mysql_setup { # Login went just fine $mysqllogin = " $remotestring "; - # Did this go well because of a .my.cnf file or is there no password set? + # Did this go well because of a .my.cnf file or is there no password set? my $userpath = `printenv HOME`; if ( length($userpath) > 0 ) { chomp($userpath); @@ -615,13 +615,27 @@ sub mysql_setup { badprint "Attempted to use login credentials, but they were invalid"; exit 1; } - - print STDERR "Please enter your MySQL administrative login: "; - my $name = <>; - print STDERR "Please enter your MySQL administrative password: "; - system("stty -echo >$devnull 2>&1"); - my $password = <>; - system("stty echo >$devnull 2>&1"); + my ($name, $password); + # If --user is defined no need to ask for username + if( $opt{user} ne 0 ) + { + $name = $opt{user}; + } + else{ + print STDERR "Please enter your MySQL administrative login: "; + $name = ; + } + # If --pass is defined no need to ask for password + if( $opt{pass} ne 0 ) + { + $password = $opt{pass}; + } + else{ + print STDERR "Please enter your MySQL administrative password: "; + system("stty -echo >$devnull 2>&1"); + $password = ; + system("stty echo >$devnull 2>&1"); + } chomp($password); chomp($name); $mysqllogin = "-u $name"; From b2739984837756265a7a7c7692154ddac51d459a Mon Sep 17 00:00:00 2001 From: "M. Hasbini" Date: Sun, 14 Feb 2016 02:24:36 +0200 Subject: [PATCH 002/126] \t -> 4 spaces --- mysqltuner.pl | 50 +++++++++++++++++++++++++------------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/mysqltuner.pl b/mysqltuner.pl index 8d62558..acbf2f4 100755 --- a/mysqltuner.pl +++ b/mysqltuner.pl @@ -492,9 +492,9 @@ sub mysql_setup { } infoprint "Performing tests on $opt{host}:$opt{port}"; $remotestring = " -h $opt{host} -P $opt{port}"; - if (($opt{host} ne "127.0.0.1") && ($opt{host} ne "localhost")) { - $doremote = 1; - } + if (($opt{host} ne "127.0.0.1") && ($opt{host} ne "localhost")) { + $doremote = 1; + } } # Did we already get a username and password passed on the command line? @@ -598,7 +598,7 @@ sub mysql_setup { # Login went just fine $mysqllogin = " $remotestring "; - # Did this go well because of a .my.cnf file or is there no password set? + # Did this go well because of a .my.cnf file or is there no password set? my $userpath = `printenv HOME`; if ( length($userpath) > 0 ) { chomp($userpath); @@ -615,27 +615,27 @@ sub mysql_setup { badprint "Attempted to use login credentials, but they were invalid"; exit 1; } - my ($name, $password); - # If --user is defined no need to ask for username - if( $opt{user} ne 0 ) - { - $name = $opt{user}; - } - else{ - print STDERR "Please enter your MySQL administrative login: "; - $name = ; - } - # If --pass is defined no need to ask for password - if( $opt{pass} ne 0 ) - { - $password = $opt{pass}; - } - else{ - print STDERR "Please enter your MySQL administrative password: "; - system("stty -echo >$devnull 2>&1"); - $password = ; - system("stty echo >$devnull 2>&1"); - } + my ($name, $password); + # If --user is defined no need to ask for username + if( $opt{user} ne 0 ) + { + $name = $opt{user}; + } + else{ + print STDERR "Please enter your MySQL administrative login: "; + $name = ; + } + # If --pass is defined no need to ask for password + if( $opt{pass} ne 0 ) + { + $password = $opt{pass}; + } + else{ + print STDERR "Please enter your MySQL administrative password: "; + system("stty -echo >$devnull 2>&1"); + $password = ; + system("stty echo >$devnull 2>&1"); + } chomp($password); chomp($name); $mysqllogin = "-u $name"; From b33a39144df6d053eac1e6e58df1dd781f62e400 Mon Sep 17 00:00:00 2001 From: root Date: Tue, 16 Feb 2016 16:29:47 +0100 Subject: [PATCH 003/126] Adding windows memory calcuclations --- mysqltuner.pl | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/mysqltuner.pl b/mysqltuner.pl index acbf2f4..da747ee 100755 --- a/mysqltuner.pl +++ b/mysqltuner.pl @@ -352,6 +352,14 @@ sub os_setup { chomp($swap_memory); $swap_memory = $swap_memory * 1024 * 1024; } + elsif( $os =~ /windows/i ) { + $physical_memory = + `wmic ComputerSystem get TotalPhysicalMemory | perl -ne "chomp; print if /[0-9]+/;"` + or memerror; + $swap_memory = + `wmic OS get FreeVirtualMemory | perl -ne "chomp; print if /[0-9]+/;"` + or memerror; + } } debugprint "Physical Memory: $physical_memory"; debugprint "Swap Memory: $swap_memory"; From 125518617c8d12d9a1962578cceea3ff7b1a23f6 Mon Sep 17 00:00:00 2001 From: Jean-Marie RENOUARD Date: Wed, 17 Feb 2016 19:06:55 +0100 Subject: [PATCH 004/126] Update vulnerabilities. --- vulnerabilities.csv | 3 +++ 1 file changed, 3 insertions(+) diff --git a/vulnerabilities.csv b/vulnerabilities.csv index 779855a..8b1c533 100644 --- a/vulnerabilities.csv +++ b/vulnerabilities.csv @@ -417,3 +417,6 @@ 5.6.26;5;6;26;CVE-2015-4910;Candidate;"Unspecified vulnerability in Oracle MySQL Server 5.6.26 and earlier allows remote authenticated users to affect availability via unknown vectors related to Server : Memcached.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/alerts-086861.html";Assigned (20150624);"None (candidate not yet proposed)"; 5.5.45;5;5;45;CVE-2015-4913;Candidate;"Unspecified vulnerability in Oracle MySQL Server 5.5.45 and earlier and 5.6.26 and earlier allows remote authenticated users to affect availability via vectors related to Server : DML; a different vulnerability than CVE-2015-4858.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/alerts-086861.html";Assigned (20150624);"None (candidate not yet proposed)"; 5.6.26;5;6;26;CVE-2015-4913;Candidate;"Unspecified vulnerability in Oracle MySQL Server 5.5.45 and earlier and 5.6.26 and earlier allows remote authenticated users to affect availability via vectors related to Server : DML; a different vulnerability than CVE-2015-4858.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/alerts-086861.html";Assigned (20150624);"None (candidate not yet proposed)"; +5.5.47;5;5;47;CVE-2016-2047;Candidate;"The ssl_verify_server_cert function in sql-common/client.c in MariaDB before 5.5.47; 10.0.x before 10.0.23; and 10.1.x before 10.1.10; Oracle MySQL; and Percona Server do not properly verify that the server hostname matches a domain name in the subject's Common Name (CN) or subjectAltName field of the X.509 certificate; which allows man-in-the-middle attackers to spoof SSL servers via a ""/CN="" string in a field in a certificate; as demonstrated by ""/OU=/CN=bar.com/CN=foo.com.""";"MLIST:[oss-security] 20160126 Flaw in mariadb clients SSL certificate validation | URL:http://www.openwall.com/lists/oss-security/2016/01/26/3 | CONFIRM:https://mariadb.atlassian.net/browse/MDEV-9212 | CONFIRM:https://mariadb.com/kb/en/mariadb/mariadb-10110-release-notes/ | CONFIRM:https://mariadb.com/kb/en/mariadb/mariadb-5547-release-notes/ | CONFIRM:https://mariadb.com/kb/en/mdb-10023-rn/ | DEBIAN:DSA-3453 | URL:http://www.debian.org/security/2016/dsa-3453";Assigned (20160122);"None (candidate not yet proposed)"; +10.0.23;10;0;23;CVE-2016-2047;Candidate;"The ssl_verify_server_cert function in sql-common/client.c in MariaDB before 5.5.47; 10.0.x before 10.0.23; and 10.1.x before 10.1.10; Oracle MySQL; and Percona Server do not properly verify that the server hostname matches a domain name in the subject's Common Name (CN) or subjectAltName field of the X.509 certificate; which allows man-in-the-middle attackers to spoof SSL servers via a ""/CN="" string in a field in a certificate; as demonstrated by ""/OU=/CN=bar.com/CN=foo.com.""";"MLIST:[oss-security] 20160126 Flaw in mariadb clients SSL certificate validation | URL:http://www.openwall.com/lists/oss-security/2016/01/26/3 | CONFIRM:https://mariadb.atlassian.net/browse/MDEV-9212 | CONFIRM:https://mariadb.com/kb/en/mariadb/mariadb-10110-release-notes/ | CONFIRM:https://mariadb.com/kb/en/mariadb/mariadb-5547-release-notes/ | CONFIRM:https://mariadb.com/kb/en/mdb-10023-rn/ | DEBIAN:DSA-3453 | URL:http://www.debian.org/security/2016/dsa-3453";Assigned (20160122);"None (candidate not yet proposed)"; +10.1.10;10;1;10;CVE-2016-2047;Candidate;"The ssl_verify_server_cert function in sql-common/client.c in MariaDB before 5.5.47; 10.0.x before 10.0.23; and 10.1.x before 10.1.10; Oracle MySQL; and Percona Server do not properly verify that the server hostname matches a domain name in the subject's Common Name (CN) or subjectAltName field of the X.509 certificate; which allows man-in-the-middle attackers to spoof SSL servers via a ""/CN="" string in a field in a certificate; as demonstrated by ""/OU=/CN=bar.com/CN=foo.com.""";"MLIST:[oss-security] 20160126 Flaw in mariadb clients SSL certificate validation | URL:http://www.openwall.com/lists/oss-security/2016/01/26/3 | CONFIRM:https://mariadb.atlassian.net/browse/MDEV-9212 | CONFIRM:https://mariadb.com/kb/en/mariadb/mariadb-10110-release-notes/ | CONFIRM:https://mariadb.com/kb/en/mariadb/mariadb-5547-release-notes/ | CONFIRM:https://mariadb.com/kb/en/mdb-10023-rn/ | DEBIAN:DSA-3453 | URL:http://www.debian.org/security/2016/dsa-3453";Assigned (20160122);"None (candidate not yet proposed)"; From 6c939906dd454e78027c4c01ff67bd085d86f510 Mon Sep 17 00:00:00 2001 From: Mohammad Date: Sat, 20 Feb 2016 18:01:30 +0200 Subject: [PATCH 005/126] #87 password single quote to double quote --- mysqltuner.pl | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/mysqltuner.pl b/mysqltuner.pl index da747ee..fe3eb4b 100755 --- a/mysqltuner.pl +++ b/mysqltuner.pl @@ -507,7 +507,7 @@ sub mysql_setup { # Did we already get a username and password passed on the command line? if ( $opt{user} ne 0 and $opt{pass} ne 0 ) { - $mysqllogin = "-u $opt{user} -p'$opt{pass}'" . $remotestring; + $mysqllogin = "-u $opt{user} -p\"$opt{pass}\"" . $remotestring; my $loginstatus = `$mysqladmincmd ping $mysqllogin 2>&1`; if ( $loginstatus =~ /mysqld is alive/ ) { goodprint @@ -649,16 +649,17 @@ sub mysql_setup { $mysqllogin = "-u $name"; if ( length($password) > 0 ) { - $mysqllogin .= " -p'$password'"; + $mysqllogin .= " -p\"$password\""; } $mysqllogin .= $remotestring; my $loginstatus = `$mysqladmincmd ping $mysqllogin 2>&1`; + debugprint "Login status command: $mysqladmincmd ping $mysqllogin 2>&1"; if ( $loginstatus =~ /mysqld is alive/ ) { print STDERR ""; if ( !length($password) ) { # Did this go well because of a .my.cnf file or is there no password set? - my $userpath = `ls -d ~`; + my $userpath = `printenv HOME`; chomp($userpath); unless ( -e "$userpath/.my.cnf" ) { badprint @@ -668,7 +669,7 @@ sub mysql_setup { return 1; } 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; From 15333e4a580db551273542714e4f488ee1ad349f Mon Sep 17 00:00:00 2001 From: Mohammad Date: Sat, 20 Feb 2016 18:05:33 +0200 Subject: [PATCH 006/126] #87 change password single quote to double quote and small fixes --- mysqltuner.pl | 373 +++++++++++++++++++++++++++----------------------- 1 file changed, 199 insertions(+), 174 deletions(-) diff --git a/mysqltuner.pl b/mysqltuner.pl index fe3eb4b..d2241c5 100755 --- a/mysqltuner.pl +++ b/mysqltuner.pl @@ -90,8 +90,9 @@ GetOptions( 'host=s', 'socket=s', 'port=i', 'user=s', 'pass=s', 'skipsize', 'checkversion', 'mysqladmin=s', 'mysqlcmd=s', 'help', 'buffers', 'skippassword', - 'passwordfile=s', 'outputfile=s', 'silent', 'dbstat', 'json', - 'idxstat', 'noask', 'template=s', 'reportfile=s', 'cvefile=s', + 'passwordfile=s', 'outputfile=s', 'silent', 'dbstat', + 'json', 'idxstat', 'noask', 'template=s', + 'reportfile=s', 'cvefile=s', ); if ( defined $opt{'help'} && $opt{'help'} == 1 ) { usage(); } @@ -156,8 +157,8 @@ $basic_password_files = "/usr/share/mysqltuner/basic_passwords.txt" # for RPM distributions $opt{cvefile} = "/usr/share/mysqltuner/vulnerabilities.csv" - unless ( defined $opt{cvefile} and -f "$opt{cvefile}"); -$opt{cvefile} ='' unless -f "$opt{cvefile}"; + unless ( defined $opt{cvefile} and -f "$opt{cvefile}" ); +$opt{cvefile} = '' unless -f "$opt{cvefile}"; # 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 badprint { prettyprint $bad. " " . $_[0] unless ( $opt{nobad} == 1 ); } sub debugprint { prettyprint $deb. " " . $_[0] unless ( $opt{debug} == 0 ); } + sub redwrap { return ( $opt{nocolor} == 0 ) ? "\e[0;31m" . $_[0] . "\e[0m" : $_[0]; } @@ -282,6 +284,7 @@ sub pretty_uptime { my ( $physical_memory, $swap_memory, $duflags ); sub os_setup { + sub memerror { badprint "Unable to determine total memory/swap; use '--forcemem' and '--forceswap'"; @@ -298,8 +301,7 @@ sub os_setup { } else { $swap_memory = 0; - badprint - "Assuming 0 MB of swap space (use --forceswap to specify)"; + badprint "Assuming 0 MB of swap space (use --forceswap to specify)"; } } else { @@ -352,12 +354,12 @@ sub os_setup { chomp($swap_memory); $swap_memory = $swap_memory * 1024 * 1024; } - elsif( $os =~ /windows/i ) { + elsif ( $os =~ /windows/i ) { $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; - $swap_memory = - `wmic OS get FreeVirtualMemory | perl -ne "chomp; print if /[0-9]+/;"` + $swap_memory = +`wmic OS get FreeVirtualMemory | perl -ne "chomp; print if /[0-9]+/;"` or memerror; } } @@ -376,66 +378,73 @@ sub os_setup { # Checks for updates to MySQLTuner sub validate_tuner_version { - if ($opt{checkversion} eq 0) { - infoprint "Skipped version check for MySQLTuner script"; - return; - } + if ( $opt{checkversion} eq 0 ) { + infoprint "Skipped version check for MySQLTuner script"; + return; + } - my $update; - my $url = "https://raw.githubusercontent.com/major/MySQLTuner-perl/master/mysqltuner.pl"; - my $httpcli=`which curl`; - chomp($httpcli); - if ( 1 != 1 and defined($httpcli) and -e "$httpcli" ) { - debugprint "$httpcli is available."; + my $update; + my $url = +"https://raw.githubusercontent.com/major/MySQLTuner-perl/master/mysqltuner.pl"; + my $httpcli = `which curl`; + chomp($httpcli); + if ( 1 != 1 and defined($httpcli) and -e "$httpcli" ) { + debugprint "$httpcli is available."; - debugprint "$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); - debugprint "VERSION: $update"; + debugprint +"$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); + debugprint "VERSION: $update"; + compare_tuner_version($update); + return; + } - compare_tuner_version($update); - return; - } + $httpcli = `which wget`; + chomp($httpcli); + if ( defined($httpcli) and -e "$httpcli" ) { + debugprint "$httpcli is available."; - - $httpcli=`which wget`; - chomp($httpcli); - if ( defined($httpcli) and -e "$httpcli" ) { - debugprint "$httpcli is available."; - - debugprint "$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); - compare_tuner_version($update); - return; - } - debugprint "curl and wget are not available."; - infoprint "Unable to check for the latest MySQLTuner version"; + debugprint +"$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); + compare_tuner_version($update); + return; + } + debugprint "curl and wget are not available."; + infoprint "Unable to check for the latest MySQLTuner version"; } sub compare_tuner_version { - my $remoteversion=shift; - debugprint "Remote data: $remoteversion"; - #exit 0; - if ($remoteversion ne $tunerversion) { - badprint "There is a new version of MySQLTuner available ($remoteversion)"; - return; - } - goodprint "You have the latest version of MySQLTuner($tunerversion)"; - return; + my $remoteversion = shift; + debugprint "Remote data: $remoteversion"; + + #exit 0; + if ( $remoteversion ne $tunerversion ) { + badprint + "There is a new version of MySQLTuner available ($remoteversion)"; + return; + } + goodprint "You have the latest version of MySQLTuner($tunerversion)"; + return; } # Checks to see if a MySQL login is possible my ( $mysqllogin, $doremote, $remotestring, $mysqlcmd, $mysqladmincmd ); my $osname = $^O; -if( $osname eq 'MSWin32' ) { - eval { require Win32; } or last; - $osname = Win32::GetOSName(); - infoprint "* Windows OS($osname) is not fully supported.\n"; - #exit 1; +if ( $osname eq 'MSWin32' ) { + eval { require Win32; } or last; + $osname = Win32::GetOSName(); + infoprint "* Windows OS($osname) is not fully supported.\n"; + + #exit 1; } + sub mysql_setup { $doremote = 0; $remotestring = ''; @@ -452,8 +461,7 @@ sub mysql_setup { exit 1; } elsif ( !-e $mysqladmincmd ) { - badprint - "Couldn't find mysqladmin in your \$PATH. Is MySQL installed?"; + badprint "Couldn't find mysqladmin in your \$PATH. Is MySQL installed?"; exit 1; } if ( $opt{mysqlcmd} ) { @@ -473,11 +481,12 @@ sub mysql_setup { exit 1; } $mysqlcmd =~ s/\n$//g; - my $mysqlclidefaults=`$mysqlcmd --print-defaults`; + my $mysqlclidefaults = `$mysqlcmd --print-defaults`; debugprint "MySQL Client: $mysqlclidefaults"; - if ( $mysqlclidefaults=~/auto-vertical-output/ ) { - badprint "Avoid auto-vertical-output in configuration file(s) for MySQL like"; - exit 1; + if ( $mysqlclidefaults =~ /auto-vertical-output/ ) { + badprint + "Avoid auto-vertical-output in configuration file(s) for MySQL like"; + exit 1; } debugprint "MySQL Client: $mysqlcmd"; @@ -492,16 +501,18 @@ sub mysql_setup { chomp( $opt{host} ); $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 ( $opt{'forcemem'} eq 0 && ($opt{host} ne "127.0.0.1") && ($opt{host} ne "localhost")) { - badprint - "The --forcemem option is required for remote connections"; +# 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" ) ) + { + badprint "The --forcemem option is required for remote connections"; exit 1; } infoprint "Performing tests on $opt{host}:$opt{port}"; $remotestring = " -h $opt{host} -P $opt{port}"; - if (($opt{host} ne "127.0.0.1") && ($opt{host} ne "localhost")) { - $doremote = 1; + if ( ( $opt{host} ne "127.0.0.1" ) && ( $opt{host} ne "localhost" ) ) { + $doremote = 1; } } @@ -510,8 +521,7 @@ sub mysql_setup { $mysqllogin = "-u $opt{user} -p\"$opt{pass}\"" . $remotestring; my $loginstatus = `$mysqladmincmd ping $mysqllogin 2>&1`; if ( $loginstatus =~ /mysqld is alive/ ) { - goodprint - "Logged in using credentials passed on the command line"; + goodprint "Logged in using credentials passed on the command line"; return 1; } else { @@ -536,8 +546,7 @@ sub mysql_setup { $mysqllogin = "-u $mysql_login -p$mysql_pass"; my $loginstatus = `mysqladmin $mysqllogin ping 2>&1`; if ( $loginstatus =~ /mysqld is alive/ ) { - goodprint - "Logged in using credentials from mysql-quickbackup."; + goodprint "Logged in using credentials from mysql-quickbackup."; return 1; } else { @@ -554,7 +563,7 @@ sub mysql_setup { my $loginstatus = `$mysqladmincmd ping $mysqllogin 2>&1`; unless ( $loginstatus =~ /mysqld is alive/ ) { badprint -"Attempted to use login credentials from Plesk, but they failed."; + "Attempted to use login credentials from Plesk, but they failed."; exit 1; } } @@ -606,7 +615,7 @@ sub mysql_setup { # Login went just fine $mysqllogin = " $remotestring "; - # Did this go well because of a .my.cnf file or is there no password set? + # Did this go well because of a .my.cnf file or is there no password set? my $userpath = `printenv HOME`; if ( length($userpath) > 0 ) { chomp($userpath); @@ -619,27 +628,29 @@ sub mysql_setup { return 1; } else { - if ( $opt{'noask'}==1 ) { - badprint "Attempted to use login credentials, but they were invalid"; + if ( $opt{'noask'} == 1 ) { + badprint + "Attempted to use login credentials, but they were invalid"; exit 1; } - my ($name, $password); + my ( $name, $password ); + # If --user is defined no need to ask for username - if( $opt{user} ne 0 ) - { + if ( $opt{user} ne 0 ) { $name = $opt{user}; } - else{ + else { print STDERR "Please enter your MySQL administrative login: "; $name = ; } + # If --pass is defined no need to ask for password - if( $opt{pass} ne 0 ) - { + if ( $opt{pass} ne 0 ) { $password = $opt{pass}; } - else{ - print STDERR "Please enter your MySQL administrative password: "; + else { + print STDERR + "Please enter your MySQL administrative password: "; system("stty -echo >$devnull 2>&1"); $password = ; system("stty echo >$devnull 2>&1"); @@ -653,7 +664,8 @@ sub mysql_setup { } $mysqllogin .= $remotestring; 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/ ) { print STDERR ""; if ( !length($password) ) { @@ -669,7 +681,8 @@ sub mysql_setup { return 1; } 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; @@ -798,33 +811,34 @@ sub get_basic_passwords { sub cve_recommendations { prettyprint "\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"; return; } - #prettyprint "Look for related CVE for $myvar{'version'} or lower in $opt{cvefile}"; - my $cvefound=0; +#prettyprint "Look for related CVE for $myvar{'version'} or lower in $opt{cvefile}"; + my $cvefound = 0; open( FH, "<$opt{cvefile}" ) or die "Can't open $opt{cvefile} for read: $!"; - while (my $cveline = ) - { - my @cve=split (';', $cveline); - if (mysql_micro_version_le ($cve[1], $cve[2], $cve[3])) { - badprint "$cve[4] : $cve[5]"; - $cvefound++; - } - + while ( my $cveline = ) { + my @cve = split( ';', $cveline ); + if ( mysql_micro_version_le( $cve[1], $cve[2], $cve[3] ) ) { + badprint "$cve[4] : $cve[5]"; + $cvefound++; + } + } close FH or die "Cannot close $opt{cvefile}: $!"; - if ($cvefound==0) { - goodprint "NO SECURITY CVE FOUND FOR YOUR VERSION"; - return; - } + if ( $cvefound == 0 ) { + goodprint "NO SECURITY CVE FOUND FOR YOUR VERSION"; + return; + } 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 { prettyprint "\n-------- Security Recommendations -------------------------------------------"; @@ -833,11 +847,12 @@ sub security_recommendations { return; } - my $PASS_COLUMN_NAME='password'; - if ($myvar{'version'} =~ /5.7/) { - $PASS_COLUMN_NAME='authentication_string'; + my $PASS_COLUMN_NAME = 'password'; + if ( $myvar{'version'} =~ /5.7/ ) { + $PASS_COLUMN_NAME = 'authentication_string'; } debugprint "Password column = $PASS_COLUMN_NAME"; + #exit(0); # Looking for Anonymous users my @mysqlstatlist = select_array @@ -973,10 +988,10 @@ sub get_replication_status { and ( $io_running !~ /yes/i or $sql_running !~ /yes/i ) ) { 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) - && $io_running =~ /yes/i + && $io_running =~ /yes/i && $sql_running =~ /yes/i ) { if ( $myvar{'read_only'} eq 'OFF' ) { @@ -1010,10 +1025,13 @@ sub validate_mysql_version { . $myvar{'version'} . " 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 " . $myvar{'version'} . ""; - } else { + } + else { goodprint "Currently running supported MySQL version " . $myvar{'version'} . ""; } @@ -1025,8 +1043,7 @@ sub mysql_version_ge { $min ||= 0; $mic ||= 0; return $mysqlvermajor > $maj - || $mysqlvermajor == $maj - && ( $mysqlverminor > $min + || $mysqlvermajor == $maj && ( $mysqlverminor > $min || $mysqlverminor == $min && $mysqlvermicro >= $mic ); } @@ -1036,8 +1053,7 @@ sub mysql_version_le { $min ||= 0; $mic ||= 0; return $mysqlvermajor < $maj - || $mysqlvermajor == $maj - && ( $mysqlverminor < $min + || $mysqlvermajor == $maj && ( $mysqlverminor < $min || $mysqlverminor == $min && $mysqlvermicro <= $mic ); } @@ -1046,7 +1062,7 @@ sub mysql_micro_version_le { my ( $maj, $min, $mic ) = @_; return $mysqlvermajor == $maj && ( $mysqlverminor == $min - && $mysqlvermicro <= $mic ); + && $mysqlvermicro <= $mic ); } # Checks for 32-bit boxes with more than 2GB of RAM @@ -1093,8 +1109,7 @@ sub check_architecture { "Switch to 64-bit OS - MySQL cannot currently use all of your RAM"; } else { - goodprint - "Operating on 32-bit architecture with less than 2GB RAM"; + goodprint "Operating on 32-bit architecture with less than 2GB RAM"; } } $result{'OS'}{'Architecture'} = "$arch bits"; @@ -1160,7 +1175,7 @@ sub check_storage_engines { : 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]; infoprint "Status: $engines"; @@ -1196,7 +1211,7 @@ sub check_storage_engines { # MySQL < 5 servers take a lot of work to get table sizes 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) { chomp($db); if ( $db eq "information_schema" @@ -1220,11 +1235,11 @@ sub check_storage_engines { # Parse through the table list to generate storage engine counts/statistics $fragtables = 0; foreach my $tbl (@tblist) { - debugprint "Data dump ". Dumper (@$tbl); + debugprint "Data dump " . Dumper(@$tbl); my ( $engine, $size, $datafree ) = @$tbl; next if $engine eq 'NULL'; - $size=0 if $size eq 'NULL'; - $datafree=0 if $datafree eq 'NULL'; + $size = 0 if $size eq 'NULL'; + $datafree = 0 if $datafree eq 'NULL'; if ( defined $enginestats{$engine} ) { $enginestats{$engine} += $size; $enginecount{$engine} += 1; @@ -1443,7 +1458,7 @@ sub calculations { $myvar{'key_cache_block_size'} ) / $myvar{'key_buffer_size'} ) - ) * 100 + ) * 100 ); } else { @@ -1536,14 +1551,14 @@ sub calculations { ( $mystat{'Qcache_hits'} / ( $mystat{'Com_select'} + $mystat{'Qcache_hits'} ) - ) * 100 + ) * 100 ); if ( $myvar{'query_cache_size'} ) { $mycalc{'pct_query_cache_used'} = sprintf( "%.1f", 100 - ( $mystat{'Qcache_free_memory'} / $myvar{'query_cache_size'} - ) * 100 + ) * 100 ); } if ( $mystat{'Qcache_lowmem_prunes'} == 0 ) { @@ -1761,8 +1776,10 @@ sub mysql_stats { . ( $myvar{'query_cache_type'} eq 0 | $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: " . hr_bytes( $myvar{'query_cache_size'} ) . ""; @@ -1791,7 +1808,7 @@ sub mysql_stats { && $mycalc{'max_used_memory'} > 2 * 1024 * 1024 * 1024 ) { 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: " . hr_bytes( $mycalc{'max_used_memory'} ) . " ($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" ); 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 && $mycalc{'max_tmp_table_size'} >= 256 * 1024 * 1024 ) @@ -2195,6 +2213,7 @@ sub mysql_stats { sub mysql_myisam { prettyprint "\n-------- MyISAM Metrics ------------------------------------------------------"; + # Key buffer usage if ( defined( $mycalc{'pct_key_buffer_used'} ) ) { if ( $mycalc{'pct_key_buffer_used'} < 90 ) { @@ -2403,7 +2422,6 @@ sub mariadb_ariadb { } } - # Recommendations for TokuDB sub mariadb_tokudb { prettyprint @@ -2436,6 +2454,7 @@ sub mariadb_galera { return; } infoprint "Galera is enabled."; + # All is to done here } @@ -2740,7 +2759,7 @@ sub mysql_indexes { "\n-------- Indexes Metrics -----------------------------------------------------"; unless ( mysql_version_ge( 5, 5 ) ) { infoprint -"Skip Index metrics from information schema missing in this version"; + "Skip Index metrics from information schema missing in this version"; return; } my $selIdxReq = <<'ENDSQL'; @@ -2844,8 +2863,7 @@ sub make_recommendations { foreach (@adjvars) { prettyprint " " . $_ . ""; } } if ( @generalrec == 0 && @adjvars == 0 ) { - prettyprint - "No additional performance recommendations are available."; + prettyprint "No additional performance recommendations are available."; } } @@ -2861,18 +2879,19 @@ sub headerprint { } sub string2file { - my $filename=shift; - my $content=shift; - open my $fh, q(>), $filename - or die "Unable to open $filename in write mode. Please check permissions for this file or directory"; - print $fh $content if defined($content); - close $fh; - debugprint $content if ($opt{'debug'}); + my $filename = shift; + my $content = shift; + open my $fh, q(>), $filename + or die +"Unable to open $filename in write mode. Please check permissions for this file or directory"; + print $fh $content if defined($content); + close $fh; + debugprint $content if ( $opt{'debug'} ); } sub file2array { my $filename = shift; - debugprint "* reading $filename" if ($opt{'debug'}); + debugprint "* reading $filename" if ( $opt{'debug'} ); my $fh; open( $fh, q(<), "$filename" ) or die "Couldn't open $filename for reading: $!\n"; @@ -2882,15 +2901,16 @@ sub file2array { } sub file2string { - return join ( '', file2array(@_) ); + return join( '', file2array(@_) ); } my $templateModel; -if ($opt{'template'} ne 0 ) { - $templateModel=file2string ($opt{'template'}); -}else { - # DEFAULT REPORT TEMPLATE - $templateModel=<<'END_TEMPLATE'; +if ( $opt{'template'} ne 0 ) { + $templateModel = file2string( $opt{'template'} ); +} +else { + # DEFAULT REPORT TEMPLATE + $templateModel = <<'END_TEMPLATE'; @@ -2908,48 +2928,53 @@ if ($opt{'template'} ne 0 ) { END_TEMPLATE } + sub dump_result { - if ($opt{'debug'}) { - debugprint Dumper( \%result ); + if ( $opt{'debug'} ) { + debugprint Dumper( \%result ); } debugprint "HTML REPORT: $opt{'reportfile'}"; - if ($opt{'reportfile'} ne 0 ) { - eval "{ use Text::Template }"; - if ($@) { - badprint "Text::Template Module is needed."; - exit 1; - } + if ( $opt{'reportfile'} ne 0 ) { + eval "{ use Text::Template }"; + if ($@) { + badprint "Text::Template Module is needed."; + exit 1; + } - my $vars= {'data' => Dumper( \%result ) }; + my $vars = { 'data' => Dumper( \%result ) }; - my $template; - { - no warnings 'once'; - $template = Text::Template->new(TYPE => 'STRING', PREPEND => q{;}, SOURCE => $templateModel) - or die "Couldn't construct template: $Text::Template::ERROR"; - } - open my $fh, q(>), $opt{'reportfile'} - or die "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; + my $template; + { + no warnings 'once'; + $template = Text::Template->new( + TYPE => 'STRING', + PREPEND => q{;}, + SOURCE => $templateModel + ) or die "Couldn't construct template: $Text::Template::ERROR"; + } + open my $fh, q(>), $opt{'reportfile'} + or die +"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; } - if ($opt{'json'} ne 0 ) { - eval "{ use JSON }"; - if ($@) { - badprint "JSON Module is needed."; - exit 1; - } - my $json = JSON->new->allow_nonref; - print JSON->new->utf8(1)->pretty(1)->encode(%result); + if ( $opt{'json'} ne 0 ) { + eval "{ use JSON }"; + if ($@) { + badprint "JSON Module is needed."; + exit 1; + } + my $json = JSON->new->allow_nonref; + print JSON->new->utf8(1)->pretty(1)->encode(%result); } } # --------------------------------------------------------------------------- # BEGIN 'MAIN' # --------------------------------------------------------------------------- -headerprint # Header Print +headerprint; # Header Print mysql_setup; # Gotta login first validate_tuner_version; # Check last version os_setup; # Set up some OS variables From ffbab547a115a680bd16e745b9eb22057f7f56bb Mon Sep 17 00:00:00 2001 From: Mohammad Date: Sat, 20 Feb 2016 18:07:19 +0200 Subject: [PATCH 007/126] #87 change password single quote to double quote and small fixes --- mysqltuner.pl | 371 +++++++++++++++++++++++--------------------------- 1 file changed, 173 insertions(+), 198 deletions(-) diff --git a/mysqltuner.pl b/mysqltuner.pl index d2241c5..557c68e 100755 --- a/mysqltuner.pl +++ b/mysqltuner.pl @@ -90,9 +90,8 @@ GetOptions( 'host=s', 'socket=s', 'port=i', 'user=s', 'pass=s', 'skipsize', 'checkversion', 'mysqladmin=s', 'mysqlcmd=s', 'help', 'buffers', 'skippassword', - 'passwordfile=s', 'outputfile=s', 'silent', 'dbstat', - 'json', 'idxstat', 'noask', 'template=s', - 'reportfile=s', 'cvefile=s', + 'passwordfile=s', 'outputfile=s', 'silent', 'dbstat', 'json', + 'idxstat', 'noask', 'template=s', 'reportfile=s', 'cvefile=s', ); if ( defined $opt{'help'} && $opt{'help'} == 1 ) { usage(); } @@ -157,8 +156,8 @@ $basic_password_files = "/usr/share/mysqltuner/basic_passwords.txt" # for RPM distributions $opt{cvefile} = "/usr/share/mysqltuner/vulnerabilities.csv" - unless ( defined $opt{cvefile} and -f "$opt{cvefile}" ); -$opt{cvefile} = '' unless -f "$opt{cvefile}"; + unless ( defined $opt{cvefile} and -f "$opt{cvefile}"); +$opt{cvefile} ='' unless -f "$opt{cvefile}"; # my $outputfile = undef; @@ -188,7 +187,6 @@ sub goodprint { prettyprint $good. " " . $_[0] unless ( $opt{nogood} == 1 ); } sub infoprint { prettyprint $info. " " . $_[0] unless ( $opt{noinfo} == 1 ); } sub badprint { prettyprint $bad. " " . $_[0] unless ( $opt{nobad} == 1 ); } sub debugprint { prettyprint $deb. " " . $_[0] unless ( $opt{debug} == 0 ); } - sub redwrap { return ( $opt{nocolor} == 0 ) ? "\e[0;31m" . $_[0] . "\e[0m" : $_[0]; } @@ -284,7 +282,6 @@ sub pretty_uptime { my ( $physical_memory, $swap_memory, $duflags ); sub os_setup { - sub memerror { badprint "Unable to determine total memory/swap; use '--forcemem' and '--forceswap'"; @@ -301,7 +298,8 @@ sub os_setup { } else { $swap_memory = 0; - badprint "Assuming 0 MB of swap space (use --forceswap to specify)"; + badprint + "Assuming 0 MB of swap space (use --forceswap to specify)"; } } else { @@ -354,12 +352,12 @@ sub os_setup { chomp($swap_memory); $swap_memory = $swap_memory * 1024 * 1024; } - elsif ( $os =~ /windows/i ) { + elsif( $os =~ /windows/i ) { $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; - $swap_memory = -`wmic OS get FreeVirtualMemory | perl -ne "chomp; print if /[0-9]+/;"` + $swap_memory = + `wmic OS get FreeVirtualMemory | perl -ne "chomp; print if /[0-9]+/;"` or memerror; } } @@ -378,73 +376,66 @@ sub os_setup { # Checks for updates to MySQLTuner sub validate_tuner_version { - if ( $opt{checkversion} eq 0 ) { - infoprint "Skipped version check for MySQLTuner script"; - return; - } + if ($opt{checkversion} eq 0) { + infoprint "Skipped version check for MySQLTuner script"; + return; + } - my $update; - my $url = -"https://raw.githubusercontent.com/major/MySQLTuner-perl/master/mysqltuner.pl"; - my $httpcli = `which curl`; - chomp($httpcli); - if ( 1 != 1 and defined($httpcli) and -e "$httpcli" ) { - debugprint "$httpcli is available."; + my $update; + my $url = "https://raw.githubusercontent.com/major/MySQLTuner-perl/master/mysqltuner.pl"; + my $httpcli=`which curl`; + chomp($httpcli); + if ( 1 != 1 and defined($httpcli) and -e "$httpcli" ) { + debugprint "$httpcli is available."; - debugprint -"$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); - debugprint "VERSION: $update"; + debugprint "$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); + debugprint "VERSION: $update"; - compare_tuner_version($update); - return; - } - $httpcli = `which wget`; - chomp($httpcli); - if ( defined($httpcli) and -e "$httpcli" ) { - debugprint "$httpcli is available."; + compare_tuner_version($update); + return; + } - debugprint -"$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); - compare_tuner_version($update); - return; - } - debugprint "curl and wget are not available."; - infoprint "Unable to check for the latest MySQLTuner version"; + + $httpcli=`which wget`; + chomp($httpcli); + if ( defined($httpcli) and -e "$httpcli" ) { + debugprint "$httpcli is available."; + + debugprint "$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); + compare_tuner_version($update); + return; + } + debugprint "curl and wget are not available."; + infoprint "Unable to check for the latest MySQLTuner version"; } sub compare_tuner_version { - my $remoteversion = shift; - debugprint "Remote data: $remoteversion"; - - #exit 0; - if ( $remoteversion ne $tunerversion ) { - badprint - "There is a new version of MySQLTuner available ($remoteversion)"; - return; - } - goodprint "You have the latest version of MySQLTuner($tunerversion)"; - return; + my $remoteversion=shift; + debugprint "Remote data: $remoteversion"; + #exit 0; + if ($remoteversion ne $tunerversion) { + badprint "There is a new version of MySQLTuner available ($remoteversion)"; + return; + } + goodprint "You have the latest version of MySQLTuner($tunerversion)"; + return; } # Checks to see if a MySQL login is possible my ( $mysqllogin, $doremote, $remotestring, $mysqlcmd, $mysqladmincmd ); my $osname = $^O; -if ( $osname eq 'MSWin32' ) { - eval { require Win32; } or last; - $osname = Win32::GetOSName(); - infoprint "* Windows OS($osname) is not fully supported.\n"; - - #exit 1; +if( $osname eq 'MSWin32' ) { + eval { require Win32; } or last; + $osname = Win32::GetOSName(); + infoprint "* Windows OS($osname) is not fully supported.\n"; + #exit 1; } - sub mysql_setup { $doremote = 0; $remotestring = ''; @@ -461,7 +452,8 @@ sub mysql_setup { exit 1; } elsif ( !-e $mysqladmincmd ) { - badprint "Couldn't find mysqladmin in your \$PATH. Is MySQL installed?"; + badprint + "Couldn't find mysqladmin in your \$PATH. Is MySQL installed?"; exit 1; } if ( $opt{mysqlcmd} ) { @@ -481,12 +473,11 @@ sub mysql_setup { exit 1; } $mysqlcmd =~ s/\n$//g; - my $mysqlclidefaults = `$mysqlcmd --print-defaults`; + my $mysqlclidefaults=`$mysqlcmd --print-defaults`; debugprint "MySQL Client: $mysqlclidefaults"; - if ( $mysqlclidefaults =~ /auto-vertical-output/ ) { - badprint - "Avoid auto-vertical-output in configuration file(s) for MySQL like"; - exit 1; + if ( $mysqlclidefaults=~/auto-vertical-output/ ) { + badprint "Avoid auto-vertical-output in configuration file(s) for MySQL like"; + exit 1; } debugprint "MySQL Client: $mysqlcmd"; @@ -501,18 +492,16 @@ sub mysql_setup { chomp( $opt{host} ); $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 ( $opt{'forcemem'} eq 0 - && ( $opt{host} ne "127.0.0.1" ) - && ( $opt{host} ne "localhost" ) ) - { - badprint "The --forcemem option is required for remote connections"; + # 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")) { + badprint + "The --forcemem option is required for remote connections"; exit 1; } infoprint "Performing tests on $opt{host}:$opt{port}"; $remotestring = " -h $opt{host} -P $opt{port}"; - if ( ( $opt{host} ne "127.0.0.1" ) && ( $opt{host} ne "localhost" ) ) { - $doremote = 1; + if (($opt{host} ne "127.0.0.1") && ($opt{host} ne "localhost")) { + $doremote = 1; } } @@ -521,7 +510,8 @@ sub mysql_setup { $mysqllogin = "-u $opt{user} -p\"$opt{pass}\"" . $remotestring; my $loginstatus = `$mysqladmincmd ping $mysqllogin 2>&1`; if ( $loginstatus =~ /mysqld is alive/ ) { - goodprint "Logged in using credentials passed on the command line"; + goodprint + "Logged in using credentials passed on the command line"; return 1; } else { @@ -546,7 +536,8 @@ sub mysql_setup { $mysqllogin = "-u $mysql_login -p$mysql_pass"; my $loginstatus = `mysqladmin $mysqllogin ping 2>&1`; if ( $loginstatus =~ /mysqld is alive/ ) { - goodprint "Logged in using credentials from mysql-quickbackup."; + goodprint + "Logged in using credentials from mysql-quickbackup."; return 1; } else { @@ -563,7 +554,7 @@ sub mysql_setup { my $loginstatus = `$mysqladmincmd ping $mysqllogin 2>&1`; unless ( $loginstatus =~ /mysqld is alive/ ) { badprint - "Attempted to use login credentials from Plesk, but they failed."; +"Attempted to use login credentials from Plesk, but they failed."; exit 1; } } @@ -615,7 +606,7 @@ sub mysql_setup { # Login went just fine $mysqllogin = " $remotestring "; - # Did this go well because of a .my.cnf file or is there no password set? + # Did this go well because of a .my.cnf file or is there no password set? my $userpath = `printenv HOME`; if ( length($userpath) > 0 ) { chomp($userpath); @@ -628,29 +619,27 @@ sub mysql_setup { return 1; } else { - if ( $opt{'noask'} == 1 ) { - badprint - "Attempted to use login credentials, but they were invalid"; + if ( $opt{'noask'}==1 ) { + badprint "Attempted to use login credentials, but they were invalid"; exit 1; } - my ( $name, $password ); - + my ($name, $password); # If --user is defined no need to ask for username - if ( $opt{user} ne 0 ) { + if( $opt{user} ne 0 ) + { $name = $opt{user}; } - else { + else{ print STDERR "Please enter your MySQL administrative login: "; $name = ; } - # If --pass is defined no need to ask for password - if ( $opt{pass} ne 0 ) { + if( $opt{pass} ne 0 ) + { $password = $opt{pass}; } - else { - print STDERR - "Please enter your MySQL administrative password: "; + else{ + print STDERR "Please enter your MySQL administrative password: "; system("stty -echo >$devnull 2>&1"); $password = ; system("stty echo >$devnull 2>&1"); @@ -664,8 +653,7 @@ sub mysql_setup { } $mysqllogin .= $remotestring; 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/ ) { print STDERR ""; if ( !length($password) ) { @@ -681,8 +669,7 @@ sub mysql_setup { return 1; } 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; @@ -811,34 +798,33 @@ sub get_basic_passwords { sub cve_recommendations { prettyprint "\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"; return; } -#prettyprint "Look for related CVE for $myvar{'version'} or lower in $opt{cvefile}"; - my $cvefound = 0; + #prettyprint "Look for related CVE for $myvar{'version'} or lower in $opt{cvefile}"; + my $cvefound=0; open( FH, "<$opt{cvefile}" ) or die "Can't open $opt{cvefile} for read: $!"; - while ( my $cveline = ) { - my @cve = split( ';', $cveline ); - if ( mysql_micro_version_le( $cve[1], $cve[2], $cve[3] ) ) { - badprint "$cve[4] : $cve[5]"; - $cvefound++; - } - + while (my $cveline = ) + { + my @cve=split (';', $cveline); + if (mysql_micro_version_le ($cve[1], $cve[2], $cve[3])) { + badprint "$cve[4] : $cve[5]"; + $cvefound++; + } + } close FH or die "Cannot close $opt{cvefile}: $!"; - if ( $cvefound == 0 ) { - goodprint "NO SECURITY CVE FOUND FOR YOUR VERSION"; - return; - } + if ($cvefound==0) { + goodprint "NO SECURITY CVE FOUND FOR YOUR VERSION"; + return; + } 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 { prettyprint "\n-------- Security Recommendations -------------------------------------------"; @@ -847,12 +833,11 @@ sub security_recommendations { return; } - my $PASS_COLUMN_NAME = 'password'; - if ( $myvar{'version'} =~ /5.7/ ) { - $PASS_COLUMN_NAME = 'authentication_string'; + my $PASS_COLUMN_NAME='password'; + if ($myvar{'version'} =~ /5.7/) { + $PASS_COLUMN_NAME='authentication_string'; } debugprint "Password column = $PASS_COLUMN_NAME"; - #exit(0); # Looking for Anonymous users my @mysqlstatlist = select_array @@ -988,10 +973,10 @@ sub get_replication_status { and ( $io_running !~ /yes/i or $sql_running !~ /yes/i ) ) { 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) - && $io_running =~ /yes/i + && $io_running =~ /yes/i && $sql_running =~ /yes/i ) { if ( $myvar{'read_only'} eq 'OFF' ) { @@ -1025,13 +1010,10 @@ sub validate_mysql_version { . $myvar{'version'} . " 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 " . $myvar{'version'} . ""; - } - else { + } else { goodprint "Currently running supported MySQL version " . $myvar{'version'} . ""; } @@ -1043,7 +1025,8 @@ sub mysql_version_ge { $min ||= 0; $mic ||= 0; return $mysqlvermajor > $maj - || $mysqlvermajor == $maj && ( $mysqlverminor > $min + || $mysqlvermajor == $maj + && ( $mysqlverminor > $min || $mysqlverminor == $min && $mysqlvermicro >= $mic ); } @@ -1053,7 +1036,8 @@ sub mysql_version_le { $min ||= 0; $mic ||= 0; return $mysqlvermajor < $maj - || $mysqlvermajor == $maj && ( $mysqlverminor < $min + || $mysqlvermajor == $maj + && ( $mysqlverminor < $min || $mysqlverminor == $min && $mysqlvermicro <= $mic ); } @@ -1062,7 +1046,7 @@ sub mysql_micro_version_le { my ( $maj, $min, $mic ) = @_; return $mysqlvermajor == $maj && ( $mysqlverminor == $min - && $mysqlvermicro <= $mic ); + && $mysqlvermicro <= $mic ); } # Checks for 32-bit boxes with more than 2GB of RAM @@ -1109,7 +1093,8 @@ sub check_architecture { "Switch to 64-bit OS - MySQL cannot currently use all of your RAM"; } else { - goodprint "Operating on 32-bit architecture with less than 2GB RAM"; + goodprint + "Operating on 32-bit architecture with less than 2GB RAM"; } } $result{'OS'}{'Architecture'} = "$arch bits"; @@ -1175,7 +1160,7 @@ sub check_storage_engines { : 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]; infoprint "Status: $engines"; @@ -1211,7 +1196,7 @@ sub check_storage_engines { # MySQL < 5 servers take a lot of work to get table sizes 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) { chomp($db); if ( $db eq "information_schema" @@ -1235,11 +1220,11 @@ sub check_storage_engines { # Parse through the table list to generate storage engine counts/statistics $fragtables = 0; foreach my $tbl (@tblist) { - debugprint "Data dump " . Dumper(@$tbl); + debugprint "Data dump ". Dumper (@$tbl); my ( $engine, $size, $datafree ) = @$tbl; next if $engine eq 'NULL'; - $size = 0 if $size eq 'NULL'; - $datafree = 0 if $datafree eq 'NULL'; + $size=0 if $size eq 'NULL'; + $datafree=0 if $datafree eq 'NULL'; if ( defined $enginestats{$engine} ) { $enginestats{$engine} += $size; $enginecount{$engine} += 1; @@ -1458,7 +1443,7 @@ sub calculations { $myvar{'key_cache_block_size'} ) / $myvar{'key_buffer_size'} ) - ) * 100 + ) * 100 ); } else { @@ -1551,14 +1536,14 @@ sub calculations { ( $mystat{'Qcache_hits'} / ( $mystat{'Com_select'} + $mystat{'Qcache_hits'} ) - ) * 100 + ) * 100 ); if ( $myvar{'query_cache_size'} ) { $mycalc{'pct_query_cache_used'} = sprintf( "%.1f", 100 - ( $mystat{'Qcache_free_memory'} / $myvar{'query_cache_size'} - ) * 100 + ) * 100 ); } if ( $mystat{'Qcache_lowmem_prunes'} == 0 ) { @@ -1776,10 +1761,8 @@ sub mysql_stats { . ( $myvar{'query_cache_type'} eq 0 | $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: " . hr_bytes( $myvar{'query_cache_size'} ) . ""; @@ -1808,7 +1791,7 @@ sub mysql_stats { && $mycalc{'max_used_memory'} > 2 * 1024 * 1024 * 1024 ) { 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: " . hr_bytes( $mycalc{'max_used_memory'} ) . " ($mycalc{'pct_max_used_memory'}% of installed RAM)"; @@ -2024,8 +2007,7 @@ sub mysql_stats { "When making adjustments, make tmp_table_size/max_heap_table_size equal" ); 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 && $mycalc{'max_tmp_table_size'} >= 256 * 1024 * 1024 ) @@ -2213,7 +2195,6 @@ sub mysql_stats { sub mysql_myisam { prettyprint "\n-------- MyISAM Metrics ------------------------------------------------------"; - # Key buffer usage if ( defined( $mycalc{'pct_key_buffer_used'} ) ) { if ( $mycalc{'pct_key_buffer_used'} < 90 ) { @@ -2422,6 +2403,7 @@ sub mariadb_ariadb { } } + # Recommendations for TokuDB sub mariadb_tokudb { prettyprint @@ -2454,7 +2436,6 @@ sub mariadb_galera { return; } infoprint "Galera is enabled."; - # All is to done here } @@ -2759,7 +2740,7 @@ sub mysql_indexes { "\n-------- Indexes Metrics -----------------------------------------------------"; unless ( mysql_version_ge( 5, 5 ) ) { infoprint - "Skip Index metrics from information schema missing in this version"; +"Skip Index metrics from information schema missing in this version"; return; } my $selIdxReq = <<'ENDSQL'; @@ -2863,7 +2844,8 @@ sub make_recommendations { foreach (@adjvars) { prettyprint " " . $_ . ""; } } if ( @generalrec == 0 && @adjvars == 0 ) { - prettyprint "No additional performance recommendations are available."; + prettyprint + "No additional performance recommendations are available."; } } @@ -2879,19 +2861,18 @@ sub headerprint { } sub string2file { - my $filename = shift; - my $content = shift; - open my $fh, q(>), $filename - or die -"Unable to open $filename in write mode. Please check permissions for this file or directory"; - print $fh $content if defined($content); - close $fh; - debugprint $content if ( $opt{'debug'} ); + my $filename=shift; + my $content=shift; + open my $fh, q(>), $filename + or die "Unable to open $filename in write mode. Please check permissions for this file or directory"; + print $fh $content if defined($content); + close $fh; + debugprint $content if ($opt{'debug'}); } sub file2array { my $filename = shift; - debugprint "* reading $filename" if ( $opt{'debug'} ); + debugprint "* reading $filename" if ($opt{'debug'}); my $fh; open( $fh, q(<), "$filename" ) or die "Couldn't open $filename for reading: $!\n"; @@ -2901,16 +2882,15 @@ sub file2array { } sub file2string { - return join( '', file2array(@_) ); + return join ( '', file2array(@_) ); } my $templateModel; -if ( $opt{'template'} ne 0 ) { - $templateModel = file2string( $opt{'template'} ); -} -else { - # DEFAULT REPORT TEMPLATE - $templateModel = <<'END_TEMPLATE'; +if ($opt{'template'} ne 0 ) { + $templateModel=file2string ($opt{'template'}); +}else { + # DEFAULT REPORT TEMPLATE + $templateModel=<<'END_TEMPLATE'; @@ -2928,46 +2908,41 @@ else { END_TEMPLATE } - sub dump_result { - if ( $opt{'debug'} ) { - debugprint Dumper( \%result ); + if ($opt{'debug'}) { + debugprint Dumper( \%result ); } debugprint "HTML REPORT: $opt{'reportfile'}"; - if ( $opt{'reportfile'} ne 0 ) { - eval "{ use Text::Template }"; - if ($@) { - badprint "Text::Template Module is needed."; - exit 1; - } + if ($opt{'reportfile'} ne 0 ) { + eval "{ use Text::Template }"; + if ($@) { + badprint "Text::Template Module is needed."; + exit 1; + } - my $vars = { 'data' => Dumper( \%result ) }; + my $vars= {'data' => Dumper( \%result ) }; - my $template; - { - no warnings 'once'; - $template = Text::Template->new( - TYPE => 'STRING', - PREPEND => q{;}, - SOURCE => $templateModel - ) or die "Couldn't construct template: $Text::Template::ERROR"; - } - open my $fh, q(>), $opt{'reportfile'} - or die -"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; + my $template; + { + no warnings 'once'; + $template = Text::Template->new(TYPE => 'STRING', PREPEND => q{;}, SOURCE => $templateModel) + or die "Couldn't construct template: $Text::Template::ERROR"; + } + open my $fh, q(>), $opt{'reportfile'} + or die "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; } - if ( $opt{'json'} ne 0 ) { - eval "{ use JSON }"; - if ($@) { - badprint "JSON Module is needed."; - exit 1; - } - my $json = JSON->new->allow_nonref; - print JSON->new->utf8(1)->pretty(1)->encode(%result); + if ($opt{'json'} ne 0 ) { + eval "{ use JSON }"; + if ($@) { + badprint "JSON Module is needed."; + exit 1; + } + my $json = JSON->new->allow_nonref; + print JSON->new->utf8(1)->pretty(1)->encode(%result); } } From 65bc055bf18c297762b0fdf97fc7206aea7818fe Mon Sep 17 00:00:00 2001 From: Mohammad Date: Sat, 20 Feb 2016 18:31:17 +0200 Subject: [PATCH 008/126] #87 small fixes for windows porting --- mysqltuner.pl | 1 - 1 file changed, 1 deletion(-) diff --git a/mysqltuner.pl b/mysqltuner.pl index 557c68e..06167f0 100755 --- a/mysqltuner.pl +++ b/mysqltuner.pl @@ -653,7 +653,6 @@ sub mysql_setup { } $mysqllogin .= $remotestring; my $loginstatus = `$mysqladmincmd ping $mysqllogin 2>&1`; - debugprint "Login status command: $mysqladmincmd ping $mysqllogin 2>&1"; if ( $loginstatus =~ /mysqld is alive/ ) { print STDERR ""; if ( !length($password) ) { From a477d5e14e6764eb1d4d7e74d46241766c547e5c Mon Sep 17 00:00:00 2001 From: root Date: Wed, 24 Feb 2016 19:52:26 +0100 Subject: [PATCH 009/126] Update vulnerabilities list --- USAGE.md | 4 ++-- vulnerabilities.csv | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/USAGE.md b/USAGE.md index 57fecf0..ddaf5fc 100644 --- a/USAGE.md +++ b/USAGE.md @@ -1,6 +1,6 @@ # NAME - MySQLTuner 1.6.3 - MySQL High Performance Tuning Script + MySQLTuner 1.6.4 - MySQL High Performance Tuning Script # IMPORTANT USAGE GUIDELINES @@ -132,4 +132,4 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License -along with this program. If not, see <http://www.gnu.org/licenses/>. +along with this program. If not, see . diff --git a/vulnerabilities.csv b/vulnerabilities.csv index 779855a..cf37d4c 100644 --- a/vulnerabilities.csv +++ b/vulnerabilities.csv @@ -1,3 +1,4 @@ +3.22.32;3;22;32;CVE-2000-0148;Entry;"MySQL 3.22 allows remote attackers to bypass password authentication and access a database via a short check string.";"BUGTRAQ:20000208 Remote access vulnerability in all MySQL server versions | URL:http://archives.neohapsis.com/archives/bugtraq/2000-02/0053.html | BUGTRAQ:20000214 MySQL 3.22.32 released | BID:975 | URL:http://www.securityfocus.com/bid/975";;; 4.0.20;4;0;20;CVE-2004-0457;Candidate;"The mysqlhotcopy script in mysql 4.0.20 and earlier; when using the scp method from the mysql-server package; allows local users to overwrite arbitrary files via a symlink attack on temporary files.";"DEBIAN:DSA-540 | URL:http://www.debian.org/security/2004/dsa-540 | CONFIRM:http://packages.debian.org/changelogs/pool/main/m/mysql-dfsg/mysql-dfsg_4.0.20-11/changelog | REDHAT:RHSA-2004:597 | URL:http://www.redhat.com/support/errata/RHSA-2004-597.html | CIAC:P-018 | URL:http://www.ciac.org/ciac/bulletins/p-018.shtml | OVAL:oval:org.mitre.oval:def:10693 | URL:http://oval.mitre.org/repository/data/getDef?id=oval:org.mitre.oval:def:10693 | XF:mysql-mysqlhotcopy-insecure-file(17030) | URL:http://xforce.iss.net/xforce/xfdb/17030";Assigned (20040506);"None (candidate not yet proposed)"; 4.0.21;4;0;21;CVE-2004-0836;Candidate;"Buffer overflow in the mysql_real_connect function in MySQL 4.x before 4.0.21; and 3.x before 3.23.49; allows remote DNS servers to cause a denial of service and possibly execute arbitrary code via a DNS response with a large address length (h_length).";"CONECTIVA:CLA-2004:892 | URL:http://distro.conectiva.com.br/atualizacoes/?id=a&anuncio=000892 | DEBIAN:DSA-562 | URL:http://www.debian.org/security/2004/dsa-562 | GENTOO:GLSA-200410-22 | URL:http://www.gentoo.org/security/en/glsa/glsa-200410-22.xml | MISC:http://bugs.mysql.com/bug.php?id=4017 | MISC:http://lists.mysql.com/internals/14726 | REDHAT:RHSA-2004:597 | URL:http://www.redhat.com/support/errata/RHSA-2004-597.html | REDHAT:RHSA-2004:611 | URL:http://www.redhat.com/support/errata/RHSA-2004-611.html | TRUSTIX:2004-0054 | URL:http://www.trustix.org/errata/2004/0054/ | BUGTRAQ:20041125 [USN-32-1] mysql vulnerabilities | URL:http://marc.theaimsgroup.com/?l=bugtraq&m=110140517515735&w=2 | CIAC:P-018 | URL:http://www.ciac.org/ciac/bulletins/p-018.shtml | BID:10981 | URL:http://www.securityfocus.com/bid/10981 | SECUNIA:12305 | URL:http://secunia.com/advisories/12305/ | XF:mysql-realconnect-bo(17047) | URL:http://xforce.iss.net/xforce/xfdb/17047";Assigned (20040908);"None (candidate not yet proposed)"; 3.23.49;3;23;49;CVE-2004-0836;Candidate;"Buffer overflow in the mysql_real_connect function in MySQL 4.x before 4.0.21; and 3.x before 3.23.49; allows remote DNS servers to cause a denial of service and possibly execute arbitrary code via a DNS response with a large address length (h_length).";"CONECTIVA:CLA-2004:892 | URL:http://distro.conectiva.com.br/atualizacoes/?id=a&anuncio=000892 | DEBIAN:DSA-562 | URL:http://www.debian.org/security/2004/dsa-562 | GENTOO:GLSA-200410-22 | URL:http://www.gentoo.org/security/en/glsa/glsa-200410-22.xml | MISC:http://bugs.mysql.com/bug.php?id=4017 | MISC:http://lists.mysql.com/internals/14726 | REDHAT:RHSA-2004:597 | URL:http://www.redhat.com/support/errata/RHSA-2004-597.html | REDHAT:RHSA-2004:611 | URL:http://www.redhat.com/support/errata/RHSA-2004-611.html | TRUSTIX:2004-0054 | URL:http://www.trustix.org/errata/2004/0054/ | BUGTRAQ:20041125 [USN-32-1] mysql vulnerabilities | URL:http://marc.theaimsgroup.com/?l=bugtraq&m=110140517515735&w=2 | CIAC:P-018 | URL:http://www.ciac.org/ciac/bulletins/p-018.shtml | BID:10981 | URL:http://www.securityfocus.com/bid/10981 | SECUNIA:12305 | URL:http://secunia.com/advisories/12305/ | XF:mysql-realconnect-bo(17047) | URL:http://xforce.iss.net/xforce/xfdb/17047";Assigned (20040908);"None (candidate not yet proposed)"; From 09383daee85dbc76cf27f70b3160186d831a33a9 Mon Sep 17 00:00:00 2001 From: root Date: Wed, 24 Feb 2016 19:57:55 +0100 Subject: [PATCH 010/126] #156: Removing index stat dur to erronous information --- mysqltuner.pl | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/mysqltuner.pl b/mysqltuner.pl index 06167f0..aa243a4 100755 --- a/mysqltuner.pl +++ b/mysqltuner.pl @@ -2742,6 +2742,11 @@ sub mysql_indexes { "Skip Index metrics from information schema missing in this version"; return; } + unless ( mysql_version_ge( 5, 6 ) ) { + infoprint +"Skip Index metrics from information schema due to erronous information provided in this version"; + return; + } my $selIdxReq = <<'ENDSQL'; SELECT CONCAT(CONCAT(t.TABLE_SCHEMA, '.'),t.TABLE_NAME) AS 'table' From 6dae07a921e80f30f1ebeb8f5059b3b5a42a0be3 Mon Sep 17 00:00:00 2001 From: root Date: Wed, 24 Feb 2016 20:20:48 +0100 Subject: [PATCH 011/126] #146: Correct write effiency calculation based on log writes --- mysqltuner.pl | 47 +++++++++++++++++++++++++++-------------------- 1 file changed, 27 insertions(+), 20 deletions(-) diff --git a/mysqltuner.pl b/mysqltuner.pl index aa243a4..97b8386 100755 --- a/mysqltuner.pl +++ b/mysqltuner.pl @@ -377,6 +377,7 @@ sub os_setup { # Checks for updates to MySQLTuner sub validate_tuner_version { if ($opt{checkversion} eq 0) { + print "\n"; infoprint "Skipped version check for MySQLTuner script"; return; } @@ -1651,6 +1652,8 @@ sub calculations { ( $myvar{'innodb_log_file_size'} * 100 / $myvar{'innodb_buffer_pool_size'} ); } + + # InnoDB Buffer pool read cache effiency ( $mystat{'Innodb_buffer_pool_read_requests'}, $mystat{'Innodb_buffer_pool_reads'} @@ -1669,24 +1672,28 @@ sub calculations { . $mystat{'Innodb_buffer_pool_reads'} . ""; debugprint "Innodb_buffer_pool_read_requests: " . $mystat{'Innodb_buffer_pool_read_requests'} . ""; + + + + # InnoDB log write cache effiency ( - $mystat{'Innodb_buffer_pool_write_requests'}, - $mystat{'Innodb_buffer_pool_writes'} + $mystat{'Innodb_log_write_requests'}, + $mystat{'Innodb_log_writes'} ) = ( 1, 1 ) - unless defined $mystat{'Innodb_buffer_pool_writes'}; + unless defined $mystat{'Innodb_log_writes'}; $mycalc{'pct_write_efficiency'} = percentage( ( - $mystat{'Innodb_buffer_pool_write_requests'} - - $mystat{'Innodb_buffer_pool_writes'} + $mystat{'Innodb_log_write_requests'} - + $mystat{'Innodb_log_writes'} ), - $mystat{'Innodb_buffer_pool_write_requests'} - ) if defined $mystat{'Innodb_buffer_pool_write_requests'}; - debugprint "pct_write_efficiency: " . $mycalc{'pct_read_efficiency'} . ""; - debugprint "Innodb_buffer_pool_writes: " - . $mystat{'Innodb_buffer_pool_writes'} . ""; - debugprint "Innodb_buffer_pool_write_requests: " - . $mystat{'Innodb_buffer_pool_write_requests'} . ""; + $mystat{'Innodb_log_write_requests'} + ) if defined $mystat{'Innodb_log_write_requests'}; + debugprint "pct_write_efficiency: " . $mycalc{'pct_write_efficiency'} . ""; + debugprint "Innodb_log_writes: " + . $mystat{'Innodb_log_writes'} . ""; + debugprint "Innodb_log_write_requests: " + . $mystat{'Innodb_log_write_requests'} . ""; $mycalc{'pct_innodb_buffer_used'} = percentage( ( $mystat{'Innodb_buffer_pool_pages_total'} - @@ -2600,21 +2607,21 @@ sub mysql_innodb { if ( defined $mycalc{'pct_write_efficiency'} && $mycalc{'pct_write_efficiency'} < 90 ) { - badprint "InnoDB Write buffer efficiency: " + badprint "InnoDB Write Log efficiency: " . $mycalc{'pct_write_efficiency'} . "% (" - . ( $mystat{'Innodb_buffer_pool_write_requests'} - - $mystat{'Innodb_buffer_pool_writes'} ) + . ( $mystat{'Innodb_log_write_requests'} - + $mystat{'Innodb_log_writes'} ) . " hits/ " - . $mystat{'Innodb_buffer_pool_write_requests'} + . $mystat{'Innodb_log_write_requests'} . " total)"; } else { - goodprint "InnoDB Write buffer efficiency: " + goodprint "InnoDB Write log efficiency: " . $mycalc{'pct_write_efficiency'} . "% (" - . ( $mystat{'Innodb_buffer_pool_write_requests'} - - $mystat{'Innodb_buffer_pool_writes'} ) + . ( $mystat{'Innodb_log_write_requests'} - + $mystat{'Innodb_log_writes'} ) . " hits/ " - . $mystat{'Innodb_buffer_pool_write_requests'} + . $mystat{'Innodb_log_write_requests'} . " total)"; } From 2a96375fa8e0ef9dc885ee8f9220d6f0a5d384e7 Mon Sep 17 00:00:00 2001 From: marklahn Date: Wed, 2 Mar 2016 15:12:38 +0000 Subject: [PATCH 012/126] TX and RX now shows value in K/M/G, rather than K/M/B --- mysqltuner.pl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mysqltuner.pl b/mysqltuner.pl index 97b8386..fa39fe8 100755 --- a/mysqltuner.pl +++ b/mysqltuner.pl @@ -1729,9 +1729,9 @@ sub mysql_stats { . " qps], " . hr_num( $mystat{'Connections'} ) . " conn," . " TX: " - . hr_num( $mystat{'Bytes_sent'} ) + . hr_bytes_rnd( $mystat{'Bytes_sent'} ) . ", RX: " - . hr_num( $mystat{'Bytes_received'} ) . ")"; + . hr_bytes_rnd( $mystat{'Bytes_received'} ) . ")"; infoprint "Reads / Writes: " . $mycalc{'pct_reads'} . "% / " . $mycalc{'pct_writes'} . "%"; From a154701223c10aef4e834d427a548cdcbe7daec6 Mon Sep 17 00:00:00 2001 From: root Date: Fri, 4 Mar 2016 11:52:33 +0100 Subject: [PATCH 013/126] Update CVE list --- vulnerabilities.csv | 1 - 1 file changed, 1 deletion(-) diff --git a/vulnerabilities.csv b/vulnerabilities.csv index cf37d4c..779855a 100644 --- a/vulnerabilities.csv +++ b/vulnerabilities.csv @@ -1,4 +1,3 @@ -3.22.32;3;22;32;CVE-2000-0148;Entry;"MySQL 3.22 allows remote attackers to bypass password authentication and access a database via a short check string.";"BUGTRAQ:20000208 Remote access vulnerability in all MySQL server versions | URL:http://archives.neohapsis.com/archives/bugtraq/2000-02/0053.html | BUGTRAQ:20000214 MySQL 3.22.32 released | BID:975 | URL:http://www.securityfocus.com/bid/975";;; 4.0.20;4;0;20;CVE-2004-0457;Candidate;"The mysqlhotcopy script in mysql 4.0.20 and earlier; when using the scp method from the mysql-server package; allows local users to overwrite arbitrary files via a symlink attack on temporary files.";"DEBIAN:DSA-540 | URL:http://www.debian.org/security/2004/dsa-540 | CONFIRM:http://packages.debian.org/changelogs/pool/main/m/mysql-dfsg/mysql-dfsg_4.0.20-11/changelog | REDHAT:RHSA-2004:597 | URL:http://www.redhat.com/support/errata/RHSA-2004-597.html | CIAC:P-018 | URL:http://www.ciac.org/ciac/bulletins/p-018.shtml | OVAL:oval:org.mitre.oval:def:10693 | URL:http://oval.mitre.org/repository/data/getDef?id=oval:org.mitre.oval:def:10693 | XF:mysql-mysqlhotcopy-insecure-file(17030) | URL:http://xforce.iss.net/xforce/xfdb/17030";Assigned (20040506);"None (candidate not yet proposed)"; 4.0.21;4;0;21;CVE-2004-0836;Candidate;"Buffer overflow in the mysql_real_connect function in MySQL 4.x before 4.0.21; and 3.x before 3.23.49; allows remote DNS servers to cause a denial of service and possibly execute arbitrary code via a DNS response with a large address length (h_length).";"CONECTIVA:CLA-2004:892 | URL:http://distro.conectiva.com.br/atualizacoes/?id=a&anuncio=000892 | DEBIAN:DSA-562 | URL:http://www.debian.org/security/2004/dsa-562 | GENTOO:GLSA-200410-22 | URL:http://www.gentoo.org/security/en/glsa/glsa-200410-22.xml | MISC:http://bugs.mysql.com/bug.php?id=4017 | MISC:http://lists.mysql.com/internals/14726 | REDHAT:RHSA-2004:597 | URL:http://www.redhat.com/support/errata/RHSA-2004-597.html | REDHAT:RHSA-2004:611 | URL:http://www.redhat.com/support/errata/RHSA-2004-611.html | TRUSTIX:2004-0054 | URL:http://www.trustix.org/errata/2004/0054/ | BUGTRAQ:20041125 [USN-32-1] mysql vulnerabilities | URL:http://marc.theaimsgroup.com/?l=bugtraq&m=110140517515735&w=2 | CIAC:P-018 | URL:http://www.ciac.org/ciac/bulletins/p-018.shtml | BID:10981 | URL:http://www.securityfocus.com/bid/10981 | SECUNIA:12305 | URL:http://secunia.com/advisories/12305/ | XF:mysql-realconnect-bo(17047) | URL:http://xforce.iss.net/xforce/xfdb/17047";Assigned (20040908);"None (candidate not yet proposed)"; 3.23.49;3;23;49;CVE-2004-0836;Candidate;"Buffer overflow in the mysql_real_connect function in MySQL 4.x before 4.0.21; and 3.x before 3.23.49; allows remote DNS servers to cause a denial of service and possibly execute arbitrary code via a DNS response with a large address length (h_length).";"CONECTIVA:CLA-2004:892 | URL:http://distro.conectiva.com.br/atualizacoes/?id=a&anuncio=000892 | DEBIAN:DSA-562 | URL:http://www.debian.org/security/2004/dsa-562 | GENTOO:GLSA-200410-22 | URL:http://www.gentoo.org/security/en/glsa/glsa-200410-22.xml | MISC:http://bugs.mysql.com/bug.php?id=4017 | MISC:http://lists.mysql.com/internals/14726 | REDHAT:RHSA-2004:597 | URL:http://www.redhat.com/support/errata/RHSA-2004-597.html | REDHAT:RHSA-2004:611 | URL:http://www.redhat.com/support/errata/RHSA-2004-611.html | TRUSTIX:2004-0054 | URL:http://www.trustix.org/errata/2004/0054/ | BUGTRAQ:20041125 [USN-32-1] mysql vulnerabilities | URL:http://marc.theaimsgroup.com/?l=bugtraq&m=110140517515735&w=2 | CIAC:P-018 | URL:http://www.ciac.org/ciac/bulletins/p-018.shtml | BID:10981 | URL:http://www.securityfocus.com/bid/10981 | SECUNIA:12305 | URL:http://secunia.com/advisories/12305/ | XF:mysql-realconnect-bo(17047) | URL:http://xforce.iss.net/xforce/xfdb/17047";Assigned (20040908);"None (candidate not yet proposed)"; From c5b458ec80d5007466c242ff86d01ca4c102fecd Mon Sep 17 00:00:00 2001 From: root Date: Mon, 14 Mar 2016 12:10:35 +0100 Subject: [PATCH 014/126] Ticket #156: removing FULLTEXT index --- mysqltuner.pl | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/mysqltuner.pl b/mysqltuner.pl index fa39fe8..cc4a152 100755 --- a/mysqltuner.pl +++ b/mysqltuner.pl @@ -1,5 +1,5 @@ #!/usr/bin/env perl -# mysqltuner.pl - Version 1.6.4 +# mysqltuner.pl - Version 1.6.5 # High Performance MySQL Tuning Script # Copyright (C) 2006-2015 Major Hayden - major@mhtx.net # @@ -51,7 +51,7 @@ use Data::Dumper; $Data::Dumper::Pair = " : "; # Set up a few variables for use in the script -my $tunerversion = "1.6.4"; +my $tunerversion = "1.6.5"; my ( @adjvars, @generalrec ); # Set defaults @@ -2749,11 +2749,11 @@ sub mysql_indexes { "Skip Index metrics from information schema missing in this version"; return; } - unless ( mysql_version_ge( 5, 6 ) ) { - infoprint -"Skip Index metrics from information schema due to erronous information provided in this version"; - return; - } +# unless ( mysql_version_ge( 5, 6 ) ) { +# infoprint +#"Skip Index metrics from information schema due to erronous information provided in this version"; +# return; +# } my $selIdxReq = <<'ENDSQL'; SELECT CONCAT(CONCAT(t.TABLE_SCHEMA, '.'),t.TABLE_NAME) AS 'table' @@ -2762,6 +2762,7 @@ SELECT , s2.max_columns AS 'maxcol' , s.CARDINALITY AS 'card' , t.TABLE_ROWS AS 'est_rows' + , INDEX_TYPE as type , ROUND(((s.CARDINALITY / IFNULL(t.TABLE_ROWS, 0.01)) * 100), 2) AS 'sel' FROM INFORMATION_SCHEMA.STATISTICS s INNER JOIN INFORMATION_SCHEMA.TABLES t @@ -2775,6 +2776,7 @@ FROM INFORMATION_SCHEMA.STATISTICS s , MAX(SEQ_IN_INDEX) AS max_columns FROM INFORMATION_SCHEMA.STATISTICS WHERE TABLE_SCHEMA NOT IN ('mysql', 'information_schema', 'performance_schema') + AND INDEX_TYPE <> "FULLTEXT" GROUP BY TABLE_SCHEMA, TABLE_NAME, INDEX_NAME ) AS s2 ON s.TABLE_SCHEMA = s2.TABLE_SCHEMA @@ -2999,7 +3001,7 @@ __END__ =head1 NAME - MySQLTuner 1.6.4 - MySQL High Performance Tuning Script + MySQLTuner 1.6.5 - MySQL High Performance Tuning Script =head1 IMPORTANT USAGE GUIDELINES From 9d7b7e11dabd113b77d244a01d5593e0a61fad8d Mon Sep 17 00:00:00 2001 From: Jean-Marie RENOUARD Date: Tue, 15 Mar 2016 10:14:31 +0100 Subject: [PATCH 015/126] Null commit --- mysqltuner.pl | 1 + 1 file changed, 1 insertion(+) diff --git a/mysqltuner.pl b/mysqltuner.pl index cc4a152..6205741 100755 --- a/mysqltuner.pl +++ b/mysqltuner.pl @@ -3245,3 +3245,4 @@ along with this program. If not, see . # cperl-indent-level: 8 # perl-indent-level: 8 # End: + From cb1a1f67a6e82b3e29234be0546538ee5ce2cc2d Mon Sep 17 00:00:00 2001 From: root Date: Tue, 15 Mar 2016 10:43:46 +0100 Subject: [PATCH 016/126] Update CVE database --- build/updateCVElist.pl | 17 +++++++++-------- vulnerabilities.csv | 3 +++ 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/build/updateCVElist.pl b/build/updateCVElist.pl index 4652a02..c122be9 100644 --- a/build/updateCVElist.pl +++ b/build/updateCVElist.pl @@ -40,17 +40,16 @@ $mech->add_handler("response_redirect" => sub { print '#'x80,"\nREDIRECT RESPONS my $url = 'http://cve.mitre.org/data/downloads/allitems.csv'; my $resp; -unless (-f 'cve.csv') -{ - $resp=$mech->get($url); - $mech->save_content( "cve.csv" ); -} +unlink ('cve.csv') if (-f 'cve.csv'); + +$resp=$mech->get($url); +$mech->save_content( "cve.csv" ); my $f=File::Util->new('readlimit' => 100000000, 'use_flock'=>'false'); my(@lines) = $f->load_file('cve.csv', '--as-lines'); my @versions; my $temp; -unlink 'vulnerabilities.csv' if -f 'vulnerabilities.csv'; +unlink '../vulnerabilities.csv' if -f '../vulnerabilities.csv'; foreach my $line (@lines) { if ($line =~ /(mysql|mariadb)/i and $line =~ /server/i @@ -67,9 +66,11 @@ foreach my $line (@lines) { my @nb=split('\.', $vers); #print $vers."\n".Dumper @nb; #exit 0; - $f->write_file('file' => 'vulnerabilities.csv', 'content' => "$vers;$nb[0];$nb[1];$nb[2];$line\n", 'mode' => 'append'); + $f->write_file('file' => '../vulnerabilities.csv', 'content' => "$vers;$nb[0];$nb[1];$nb[2];$line\n", 'mode' => 'append'); } } } -exit(0); \ No newline at end of file +unlink ('cve.csv') if (-f 'cve.csv'); + +exit(0); diff --git a/vulnerabilities.csv b/vulnerabilities.csv index 779855a..8b1c533 100644 --- a/vulnerabilities.csv +++ b/vulnerabilities.csv @@ -417,3 +417,6 @@ 5.6.26;5;6;26;CVE-2015-4910;Candidate;"Unspecified vulnerability in Oracle MySQL Server 5.6.26 and earlier allows remote authenticated users to affect availability via unknown vectors related to Server : Memcached.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/alerts-086861.html";Assigned (20150624);"None (candidate not yet proposed)"; 5.5.45;5;5;45;CVE-2015-4913;Candidate;"Unspecified vulnerability in Oracle MySQL Server 5.5.45 and earlier and 5.6.26 and earlier allows remote authenticated users to affect availability via vectors related to Server : DML; a different vulnerability than CVE-2015-4858.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/alerts-086861.html";Assigned (20150624);"None (candidate not yet proposed)"; 5.6.26;5;6;26;CVE-2015-4913;Candidate;"Unspecified vulnerability in Oracle MySQL Server 5.5.45 and earlier and 5.6.26 and earlier allows remote authenticated users to affect availability via vectors related to Server : DML; a different vulnerability than CVE-2015-4858.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/alerts-086861.html";Assigned (20150624);"None (candidate not yet proposed)"; +5.5.47;5;5;47;CVE-2016-2047;Candidate;"The ssl_verify_server_cert function in sql-common/client.c in MariaDB before 5.5.47; 10.0.x before 10.0.23; and 10.1.x before 10.1.10; Oracle MySQL; and Percona Server do not properly verify that the server hostname matches a domain name in the subject's Common Name (CN) or subjectAltName field of the X.509 certificate; which allows man-in-the-middle attackers to spoof SSL servers via a ""/CN="" string in a field in a certificate; as demonstrated by ""/OU=/CN=bar.com/CN=foo.com.""";"MLIST:[oss-security] 20160126 Flaw in mariadb clients SSL certificate validation | URL:http://www.openwall.com/lists/oss-security/2016/01/26/3 | CONFIRM:https://mariadb.atlassian.net/browse/MDEV-9212 | CONFIRM:https://mariadb.com/kb/en/mariadb/mariadb-10110-release-notes/ | CONFIRM:https://mariadb.com/kb/en/mariadb/mariadb-5547-release-notes/ | CONFIRM:https://mariadb.com/kb/en/mdb-10023-rn/ | DEBIAN:DSA-3453 | URL:http://www.debian.org/security/2016/dsa-3453";Assigned (20160122);"None (candidate not yet proposed)"; +10.0.23;10;0;23;CVE-2016-2047;Candidate;"The ssl_verify_server_cert function in sql-common/client.c in MariaDB before 5.5.47; 10.0.x before 10.0.23; and 10.1.x before 10.1.10; Oracle MySQL; and Percona Server do not properly verify that the server hostname matches a domain name in the subject's Common Name (CN) or subjectAltName field of the X.509 certificate; which allows man-in-the-middle attackers to spoof SSL servers via a ""/CN="" string in a field in a certificate; as demonstrated by ""/OU=/CN=bar.com/CN=foo.com.""";"MLIST:[oss-security] 20160126 Flaw in mariadb clients SSL certificate validation | URL:http://www.openwall.com/lists/oss-security/2016/01/26/3 | CONFIRM:https://mariadb.atlassian.net/browse/MDEV-9212 | CONFIRM:https://mariadb.com/kb/en/mariadb/mariadb-10110-release-notes/ | CONFIRM:https://mariadb.com/kb/en/mariadb/mariadb-5547-release-notes/ | CONFIRM:https://mariadb.com/kb/en/mdb-10023-rn/ | DEBIAN:DSA-3453 | URL:http://www.debian.org/security/2016/dsa-3453";Assigned (20160122);"None (candidate not yet proposed)"; +10.1.10;10;1;10;CVE-2016-2047;Candidate;"The ssl_verify_server_cert function in sql-common/client.c in MariaDB before 5.5.47; 10.0.x before 10.0.23; and 10.1.x before 10.1.10; Oracle MySQL; and Percona Server do not properly verify that the server hostname matches a domain name in the subject's Common Name (CN) or subjectAltName field of the X.509 certificate; which allows man-in-the-middle attackers to spoof SSL servers via a ""/CN="" string in a field in a certificate; as demonstrated by ""/OU=/CN=bar.com/CN=foo.com.""";"MLIST:[oss-security] 20160126 Flaw in mariadb clients SSL certificate validation | URL:http://www.openwall.com/lists/oss-security/2016/01/26/3 | CONFIRM:https://mariadb.atlassian.net/browse/MDEV-9212 | CONFIRM:https://mariadb.com/kb/en/mariadb/mariadb-10110-release-notes/ | CONFIRM:https://mariadb.com/kb/en/mariadb/mariadb-5547-release-notes/ | CONFIRM:https://mariadb.com/kb/en/mdb-10023-rn/ | DEBIAN:DSA-3453 | URL:http://www.debian.org/security/2016/dsa-3453";Assigned (20160122);"None (candidate not yet proposed)"; From c0be38eb89b274fbacf319a9ae4463b8e5222634 Mon Sep 17 00:00:00 2001 From: root Date: Wed, 16 Mar 2016 16:53:30 +0100 Subject: [PATCH 017/126] Query cache should be disabled #159 --- mysqltuner.pl | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/mysqltuner.pl b/mysqltuner.pl index cc4a152..631bae0 100755 --- a/mysqltuner.pl +++ b/mysqltuner.pl @@ -1,5 +1,5 @@ #!/usr/bin/env perl -# mysqltuner.pl - Version 1.6.5 +# mysqltuner.pl - Version 1.6.6 # High Performance MySQL Tuning Script # Copyright (C) 2006-2015 Major Hayden - major@mhtx.net # @@ -51,7 +51,7 @@ use Data::Dumper; $Data::Dumper::Pair = " : "; # Set up a few variables for use in the script -my $tunerversion = "1.6.5"; +my $tunerversion = "1.6.6"; my ( @adjvars, @generalrec ); # Set defaults @@ -1884,6 +1884,15 @@ sub mysql_stats { push( @generalrec, "Upgrade MySQL to version 4+ to utilize query caching" ); } + elsif (mysql_version_ge(5,6)) + { + if ( $myvar{'query_cache_type'} ne "OFF" ) { + badprint "Query cache should be disabled by default due to mutex contention."; + push( @adjvars, "query_cache_type (=0)" ); + } else { + goodprint "Query cache is disabled by default due to mutex contention."; + } + } elsif ( $myvar{'query_cache_size'} < 1 ) { badprint "Query cache is disabled"; push( @adjvars, "query_cache_size (>= 8M)" ); @@ -3001,7 +3010,7 @@ __END__ =head1 NAME - MySQLTuner 1.6.5 - MySQL High Performance Tuning Script + MySQLTuner 1.6.6 - MySQL High Performance Tuning Script =head1 IMPORTANT USAGE GUIDELINES From f3805a1eba4498a23cefad68e1aab4e018629d8d Mon Sep 17 00:00:00 2001 From: root Date: Wed, 16 Mar 2016 18:40:44 +0100 Subject: [PATCH 018/126] Changing engine list after 5.5 --- mysqltuner.pl | 37 ++++++++++++++++++++++++++++++------- 1 file changed, 30 insertions(+), 7 deletions(-) diff --git a/mysqltuner.pl b/mysqltuner.pl index 631bae0..e0012b7 100755 --- a/mysqltuner.pl +++ b/mysqltuner.pl @@ -1114,7 +1114,20 @@ sub check_storage_engines { "\n-------- Storage Engine Statistics -------------------------------------------"; my $engines; - if ( mysql_version_ge( 5, 1, 5 ) ) { + if ( mysql_version_ge( 5, 5 ) ) { + my @engineresults = select_array +"SELECT ENGINE,SUPPORT FROM information_schema.ENGINES ORDER BY ENGINE ASC"; + foreach my $line (@engineresults) { + my ( $engine, $engineenabled ); + ( $engine, $engineenabled ) = $line =~ /([a-zA-Z_]*)\s+([a-zA-Z]+)/; + $result{'Engine'}{$engine}{'Enabled'} = $engineenabled; + $engines .= + ( $engineenabled eq "YES" || $engineenabled eq "DEFAULT" ) + ? greenwrap "+" . $engine . " " + : redwrap "-" . $engine . " "; + } + } + elsif ( mysql_version_ge( 5, 1, 5 ) ) { my @engineresults = select_array "SELECT ENGINE,SUPPORT FROM information_schema.ENGINES WHERE ENGINE NOT IN ('performance_schema','MyISAM','MERGE','MEMORY') ORDER BY ENGINE ASC"; foreach my $line (@engineresults) { @@ -1149,10 +1162,6 @@ sub check_storage_engines { ( defined $myvar{'have_isam'} && $myvar{'have_isam'} eq "YES" ) ? greenwrap "+ISAM " : redwrap "-ISAM "; - $engines .= - ( defined $myvar{'have_aria'} && $myvar{'have_aria'} eq "YES" ) - ? greenwrap "+Aria " - : redwrap "-Aria "; $engines .= ( defined $myvar{'have_ndbcluster'} && $myvar{'have_ndbcluster'} eq "YES" ) @@ -2347,6 +2356,19 @@ sub mariadb_threadpool { infoprint "ThreadPool stat is enabled."; } +# Recommendations for Performance Schema +sub mysqsl_pfs { + prettyprint +"\n-------- Performance schema --------------------------------------------------"; + + # Performance Schema + unless ( defined($myvar{'performance_schema'}) and $myvar{'performance_schema'} eq 'ON' ) { + infoprint "Performance schema is disabled."; + } + + infoprint "Performance schema is enabled."; +} + # Recommendations for Ariadb sub mariadb_ariadb { prettyprint @@ -2986,10 +3008,11 @@ security_recommendations; # Display some security recommendations cve_recommendations; # Display related CVE calculations; # Calculate everything we need mysql_stats; # Print the server stats -mysql_myisam; # Print MyISAM stats -mysql_innodb; # Print InnoDB stats +mysqsl_pfs # Print Performance schema info mariadb_threadpool; # Print MaraiDB ThreadPool stats +mysql_myisam; # Print MyISAM stats mariadb_ariadb; # Print MaraiDB AriaDB stats +mysql_innodb; # Print InnoDB stats mariadb_tokudb; # Print MaraiDB TokuDB stats mariadb_galera; # Print MaraiDB Galera Cluster stats get_replication_status; # Print replication info From 4d93a433701fadf7e87f08eb553123b02fedf38c Mon Sep 17 00:00:00 2001 From: Christine Date: Mon, 21 Mar 2016 14:44:48 +0100 Subject: [PATCH 019/126] removing deprecated info. --- build/updateCVElist.pl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build/updateCVElist.pl b/build/updateCVElist.pl index c122be9..535d26a 100644 --- a/build/updateCVElist.pl +++ b/build/updateCVElist.pl @@ -21,8 +21,8 @@ sub AUTOLOAD { my $mech = WWW::Mechanize->new(); $mech->agent('Mozilla/5.0 (Windows NT 6.1; WOW64; rv:41.0) Gecko/20100101 Firefox/41.0'); -#$mech->proxy( ['http'], 'http://10.236.240.71:3128' ); -#$mech->proxy( ['https'], 'http://10.236.240.71:3128' ); +#$mech->proxy( ['http'], 'http://XXX.XXX.XXX.XXX:3128' ); +#$mech->proxy( ['https'], 'http://XXX.XXX.XXX.XXX:3128' ); $mech->env_proxy; From 3a0ce00ffdd24029c7d05e6a7128eafd0ac33330 Mon Sep 17 00:00:00 2001 From: Jean-Marie RENOUARD Date: Mon, 21 Mar 2016 15:29:31 +0100 Subject: [PATCH 020/126] Update CVE list --- vulnerabilities.csv | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 vulnerabilities.csv diff --git a/vulnerabilities.csv b/vulnerabilities.csv old mode 100644 new mode 100755 From 216885c30e27293788c77bf1a3cc654ca8ba8d1f Mon Sep 17 00:00:00 2001 From: Christine Date: Mon, 21 Mar 2016 15:51:16 +0100 Subject: [PATCH 021/126] Support user parameter alone Support advanced debug for access denied issue --- mysqltuner.pl | 40 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/mysqltuner.pl b/mysqltuner.pl index e0012b7..d541790 100755 --- a/mysqltuner.pl +++ b/mysqltuner.pl @@ -505,7 +505,21 @@ sub mysql_setup { $doremote = 1; } } - + # Did we already get a username without password on the command line? + if ( $opt{user} ne 0 and $opt{pass} eq 0 ) { + $mysqllogin = "-u $opt{user} " . $remotestring; + my $loginstatus = `$mysqladmincmd ping $mysqllogin 2>&1`; + if ( $loginstatus =~ /mysqld is alive/ ) { + goodprint + "Logged in using credentials passed on the command line"; + return 1; + } + else { + badprint + "Attempted to use login credentials, but they were invalid"; + exit 1; + } + } # Did we already get a username and password passed on the command line? if ( $opt{user} ne 0 and $opt{pass} ne 0 ) { $mysqllogin = "-u $opt{user} -p\"$opt{pass}\"" . $remotestring; @@ -682,6 +696,15 @@ sub select_array { my $req = shift; debugprint "PERFORM: $req "; my @result = `$mysqlcmd $mysqllogin -Bse "$req" 2>>/dev/null`; + if ($? != 0) { + badprint "failed to execute: $req"; + badprint "FAIL Execute SQL / return code: $?"; + debugprint "CMD : $mysqlcmd"; + debugprint "OPTIONS: $mysqllogin"; + debugprint `$mysqlcmd $mysqllogin -Bse "$req" 2>&1`; + exit $?; + } + debugprint "select_array: return code : $?"; chomp(@result); return @result; } @@ -691,6 +714,15 @@ sub select_one { my $req = shift; debugprint "PERFORM: $req "; my $result = `$mysqlcmd $mysqllogin -Bse "$req" 2>>/dev/null`; + if ($? != 0) { + badprint "failed to execute: $req"; + badprint "FAIL Execute SQL / return code: $?"; + debugprint "CMD : $mysqlcmd"; + debugprint "OPTIONS: $mysqllogin"; + debugprint `$mysqlcmd $mysqllogin -Bse "$req" 2>&1`; + exit $?; + } + debugprint "select_array: return code : $?"; chomp($result); return $result; } @@ -838,10 +870,12 @@ sub security_recommendations { $PASS_COLUMN_NAME='authentication_string'; } debugprint "Password column = $PASS_COLUMN_NAME"; - #exit(0); + # Looking for Anonymous users my @mysqlstatlist = select_array "SELECT CONCAT(user, '\@', host) FROM mysql.user WHERE TRIM(USER) = '' OR USER IS NULL"; + debugprint Dumper \@mysqlstatlist; + #exit 0; if (@mysqlstatlist) { foreach my $line ( sort @mysqlstatlist ) { chomp($line); @@ -1893,7 +1927,7 @@ sub mysql_stats { push( @generalrec, "Upgrade MySQL to version 4+ to utilize query caching" ); } - elsif (mysql_version_ge(5,6)) + elsif (mysql_version_ge(5,5)) { if ( $myvar{'query_cache_type'} ne "OFF" ) { badprint "Query cache should be disabled by default due to mutex contention."; From 42b09f83abe15ed9d8f832d6e2982a4a5a2d436a Mon Sep 17 00:00:00 2001 From: Christine Date: Mon, 21 Mar 2016 17:11:20 +0100 Subject: [PATCH 022/126] Adding system recommandations based on open port trying to detect local vulnerabilities.csv --- mysqltuner.pl | 60 ++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 57 insertions(+), 3 deletions(-) diff --git a/mysqltuner.pl b/mysqltuner.pl index d541790..e816a20 100755 --- a/mysqltuner.pl +++ b/mysqltuner.pl @@ -1,5 +1,5 @@ #!/usr/bin/env perl -# mysqltuner.pl - Version 1.6.6 +# mysqltuner.pl - Version 1.6.7 # High Performance MySQL Tuning Script # Copyright (C) 2006-2015 Major Hayden - major@mhtx.net # @@ -51,7 +51,7 @@ use Data::Dumper; $Data::Dumper::Pair = " : "; # Set up a few variables for use in the script -my $tunerversion = "1.6.6"; +my $tunerversion = "1.6.7"; my ( @adjvars, @generalrec ); # Set defaults @@ -158,6 +158,7 @@ $basic_password_files = "/usr/share/mysqltuner/basic_passwords.txt" $opt{cvefile} = "/usr/share/mysqltuner/vulnerabilities.csv" unless ( defined $opt{cvefile} and -f "$opt{cvefile}"); $opt{cvefile} ='' unless -f "$opt{cvefile}"; +$opt{cvefile} ='./vulnerabilities.csv' if -f './vulnerabilities.csv'; # my $outputfile = undef; @@ -857,6 +858,58 @@ sub cve_recommendations { } +sub get_opened_ports { + my @opened_ports=`netstat -ltn`; + map { + s/.*:(\d+)\s.*$/$1/; + s/\D//g; + } @opened_ports; + @opened_ports = sort {$a <=> $b} grep { !/^$/ } @opened_ports; + debugprint Dumper \@opened_ports; + return @opened_ports; +} + +sub is_open_port { + my $port=shift; + if ( grep { /^$port$/ } get_opened_ports ) { + return 1; + } + return 0; +} +sub system_recommendations { + prettyprint "\n-------- System Linux Recommendations ---------------------------------------"; + my $os = `uname`; + + unless ($os =~ /Linux/i) { + infoprint "Skipped due to non Linux server"; + return; + } + + prettyprint "Look for related Linux system recommandations"; + + my @opened_ports=get_opened_ports; + infoprint "There is ". scalar @opened_ports. " listening port(s) on this server."; + if (scalar(@opened_ports) > 10) { + badprint "There is too many listening ports: ". scalar(@opened_ports). " > 10"; + push( @generalrec, "Consider dedicating a server for your database installation with less services running on !" ); + } else { + goodprint "There is less than 10 opened ports on this server."; + } + + if ( is_open_port(80) or is_open_port(443) ) { + badprint "There is Apache like server running on 80 or 443 port."; + push( @generalrec, "Consider dedicating a server for Web server in production !" ); + } else { + goodprint "No Web server runing on 80 and 444 port."; + } + if ( is_open_port(8080) or is_open_port(8443) ) { + badprint "There is Application server running on 8080 or 8443 port."; + push( @generalrec, "Consider dedicating a server for Application server in production !" ); + } else { + goodprint "No Application server runing on 8080 or 8443 port."; + } +} + sub security_recommendations { prettyprint "\n-------- Security Recommendations -------------------------------------------"; @@ -3035,6 +3088,7 @@ get_all_vars; # Toss variables/status into hashes get_tuning_info; # Get information about the tuning connexion validate_mysql_version; # Check current MySQL version check_architecture; # Suggest 64-bit upgrade +system_recommendations; # avoid to many service on the same host check_storage_engines; # Show enabled storage engines mysql_databases; # Show informations about databases mysql_indexes; # Show informations about indexes @@ -3067,7 +3121,7 @@ __END__ =head1 NAME - MySQLTuner 1.6.6 - MySQL High Performance Tuning Script + MySQLTuner 1.6.7 - MySQL High Performance Tuning Script =head1 IMPORTANT USAGE GUIDELINES From 1ffee5606a82f93973972355222c002ff1df0fc4 Mon Sep 17 00:00:00 2001 From: Christine Date: Mon, 21 Mar 2016 17:41:14 +0100 Subject: [PATCH 023/126] Adding banned port option to detect banned ports --- mysqltuner.pl | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/mysqltuner.pl b/mysqltuner.pl index e816a20..829acec 100755 --- a/mysqltuner.pl +++ b/mysqltuner.pl @@ -72,7 +72,8 @@ my %opt = ( "skipsize" => 0, "checkversion" => 0, "buffers" => 0, - "passwordfile" => 0, + "passwordfile" => 0, + "bannedports" => '', "outputfile" => 0, "dbstat" => 0, "idxstat" => 0, @@ -92,6 +93,7 @@ GetOptions( 'mysqlcmd=s', 'help', 'buffers', 'skippassword', 'passwordfile=s', 'outputfile=s', 'silent', 'dbstat', 'json', 'idxstat', 'noask', 'template=s', 'reportfile=s', 'cvefile=s', + 'bannedports=s', ); if ( defined $opt{'help'} && $opt{'help'} == 1 ) { usage(); } @@ -134,6 +136,7 @@ sub usage { . " --debug Print debug information\n" . " --dbstat Print database information\n" . " --idxstat Print index information\n" + . " --bannedports ports banned separated by comma(,)\n" . " --cvefile CVE File for vulnerability checks\n" . " --nocolor Don't print output in color\n" . " --json Print result as JSON string\n" @@ -160,6 +163,9 @@ $opt{cvefile} = "/usr/share/mysqltuner/vulnerabilities.csv" $opt{cvefile} ='' unless -f "$opt{cvefile}"; $opt{cvefile} ='./vulnerabilities.csv' if -f './vulnerabilities.csv'; +$opt{'bannedports'}='' unless defined($opt{'bannedports'}); +my @banned_ports=split ',', $opt{'bannedports'}; + # my $outputfile = undef; $outputfile = abs_path( $opt{outputfile} ) unless $opt{outputfile} eq "0"; @@ -908,6 +914,14 @@ sub system_recommendations { } else { goodprint "No Application server runing on 8080 or 8443 port."; } + foreach my $banport (@banned_ports) { + if ( is_open_port($banport) ) { + badprint "Banned port: $banport is opened.."; + push( @generalrec, "Port $banport is opened. Consider stopping program handling this port." ); + } else { + goodprint "$banport is not opened."; + } + } } sub security_recommendations { From 805651d44b25bc37e0f0690b8b09df56ad636e4b Mon Sep 17 00:00:00 2001 From: Christine Date: Tue, 22 Mar 2016 09:54:26 +0100 Subject: [PATCH 024/126] Fix bug on index selectivity from mariaDB Adding type in index summary --- mysqltuner.pl | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/mysqltuner.pl b/mysqltuner.pl index 829acec..91a8e0b 100755 --- a/mysqltuner.pl +++ b/mysqltuner.pl @@ -2908,7 +2908,7 @@ FROM INFORMATION_SCHEMA.STATISTICS s , MAX(SEQ_IN_INDEX) AS max_columns FROM INFORMATION_SCHEMA.STATISTICS WHERE TABLE_SCHEMA NOT IN ('mysql', 'information_schema', 'performance_schema') - AND INDEX_TYPE <> "FULLTEXT" + AND INDEX_TYPE <> 'FULLTEXT' GROUP BY TABLE_SCHEMA, TABLE_NAME, INDEX_NAME ) AS s2 ON s.TABLE_SCHEMA = s2.TABLE_SCHEMA @@ -2933,18 +2933,20 @@ ENDSQL infoprint " +-- NB COLS : " . $info[3] . " column(s)"; infoprint " +-- CARDINALITY : " . $info[4] . " distinct values"; infoprint " +-- NB ROWS : " . $info[5] . " rows"; - infoprint " +-- SELECTIVITY : " . $info[6] . "%"; + infoprint " +-- TYPE : " . $info[6] ; + infoprint " +-- SELECTIVITY : " . $info[7] . "%"; $result{'Indexes'}{ $info[1] }{'Colunm'} = $info[0]; $result{'Indexes'}{ $info[1] }{'Sequence number'} = $info[2]; $result{'Indexes'}{ $info[1] }{'Number of collunm'} = $info[3]; $result{'Indexes'}{ $info[1] }{'Cardianality'} = $info[4]; $result{'Indexes'}{ $info[1] }{'Row number'} = $info[5]; - $result{'Indexes'}{ $info[1] }{'Selectivity'} = $info[6]; - if ( $info[6] < 25 ) { + $result{'Indexes'}{ $info[1] }{'Index Type'} = $info[6]; + $result{'Indexes'}{ $info[1] }{'Selectivity'} = $info[7]; + if ( $info[7] < 25 ) { badprint "$info[1] has a low selectivity"; } - } + } return unless ( defined( $myvar{'performance_schema'} ) @@ -3173,6 +3175,7 @@ You must provide the remote server's total memory when connecting to other serve --debug Print debug information --dbstat Print database information --idxstat Print index information + --bannedports ports banned separated by comma(,) --cvefile CVE File for vulnerability checks --nocolor Don't print output in color --json Print result as JSON string From 200d091362a41537656ae1a9f95af12c76cb3cf7 Mon Sep 17 00:00:00 2001 From: Christine Date: Tue, 22 Mar 2016 14:44:01 +0100 Subject: [PATCH 025/126] Adding system recommandations for banned ports and memory used by other process --- mysqltuner.pl | 65 +++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 60 insertions(+), 5 deletions(-) diff --git a/mysqltuner.pl b/mysqltuner.pl index 91a8e0b..33ace26 100755 --- a/mysqltuner.pl +++ b/mysqltuner.pl @@ -826,14 +826,25 @@ sub get_all_vars { } } -sub get_basic_passwords { +sub remove_cr { + map { s/\n$//g; } @_; +} +sub remove_empty { + grep { $_ ne '' } @_; +} +sub get_file_contents { my $file = shift; open( FH, "< $file" ) or die "Can't open $file for read: $!"; my @lines = ; close FH or die "Cannot close $file: $!"; + remove_cr \@lines; return @lines; } +sub get_basic_passwords { + return get_file_contents(shift); +} + sub cve_recommendations { prettyprint "\n-------- CVE Security Recommendations ---------------------------------------"; @@ -882,16 +893,60 @@ sub is_open_port { } return 0; } + +sub get_process_memory { + my $pid=shift; + return 0 unless -f "/proc/$pid/status"; + my @pdata= grep { /RSS:/ } get_file_contents "/proc/$pid/status"; + map { + s/.*RSS:\s*(\d+)\s*kB\s*$/$1*1024/ge + } @pdata; + return $pdata[0]; +} + +sub get_other_process_memory { + my @procs=`ps -eo pid,cmd`; + map { s/.*mysqld.*//; s/.*\[.*\].*//; s/^\s+$//g; s/.*PID.*CMD.*//; s/.*systemd.*//;} @procs; + map {s/\s*?(\d+)\s*.*/$1/g;} @procs; + remove_cr @procs; + @procs=remove_empty @procs; + my $totalMemOther=0; + map { + $totalMemOther+=get_process_memory($_); + } @procs; + return $totalMemOther; +} + +sub get_os_release { + return "Unknown OS release" unless -f "/etc/system-release"; + my @info_release=get_file_contents "/etc/system-release"; + remove_cr @info_release; + return $info_release[0]; +} sub system_recommendations { prettyprint "\n-------- System Linux Recommendations ---------------------------------------"; my $os = `uname`; - unless ($os =~ /Linux/i) { infoprint "Skipped due to non Linux server"; return; } - prettyprint "Look for related Linux system recommandations"; + #prettyprint '-'x78; + infoprint get_os_release; + + my $omem=get_other_process_memory; + infoprint "User process except mysqld used ". hr_bytes_rnd($omem) . " RAM."; + if ( (0.15*$physical_memory) < $omem) { + badprint "Other user process except mysqld used more than 15% of total physical memory ". percentage($omem, $physical_memory). "% (".hr_bytes_rnd($omem). " / ".hr_bytes_rnd($physical_memory).")"; + push( @generalrec, "Consider stopping or dedicate server for additionnal process other than mysqld." ); + push( @adjvars, "DON'T APPLY SETTINGS BECAUSE THERE IS TOO MANY PROCESS RUNNING ON THIS SERVER. OOM KILL CAN OCCURS !" ); + + + } else { + } + + #if ($omem > + #exit 0; my @opened_ports=get_opened_ports; infoprint "There is ". scalar @opened_ports. " listening port(s) on this server."; @@ -1199,6 +1254,7 @@ sub check_architecture { } } $result{'OS'}{'Architecture'} = "$arch bits"; + } # Start up a ton of storage engine counts/statistics @@ -1275,8 +1331,7 @@ sub check_storage_engines { $result{'Databases'}{'List'} = [@dblist]; infoprint "Status: $engines"; if ( mysql_version_ge( 5, 1, 5 ) ) { - -# MySQL 5 servers can have table sizes calculated quickly from information schema + # MySQL 5 servers can have table sizes calculated quickly from information schema my @templist = select_array "SELECT ENGINE,SUM(DATA_LENGTH+INDEX_LENGTH),COUNT(ENGINE),SUM(DATA_LENGTH),SUM(INDEX_LENGTH) FROM information_schema.TABLES WHERE TABLE_SCHEMA NOT IN ('information_schema', 'performance_schema', 'mysql') AND ENGINE IS NOT NULL GROUP BY ENGINE ORDER BY ENGINE ASC;"; From 1a3ce440751ccf6a494152f2c680ec96f15cc861 Mon Sep 17 00:00:00 2001 From: Jean-Marie Renouard Date: Tue, 22 Mar 2016 14:49:22 +0100 Subject: [PATCH 026/126] Update INTERNALS.md Adding new system recommandations information --- INTERNALS.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/INTERNALS.md b/INTERNALS.md index ed4f69d..151666e 100644 --- a/INTERNALS.md +++ b/INTERNALS.md @@ -66,6 +66,10 @@ ## MySQLTuner system checks * 32-bit w/>2GB RAM check +* Check number of opened ports (warning if more than 9 ports opened) +* Check 80, 8080, 443 and 8443 ports if warning are raised if there are opened +* Check if some banned ports are not opened (option --bannedports separated by comma) +* Check if non kernel and user process except mysqld are not using more than 15% of total physical memory) ## MySQLTuner Server version checks * EOL MySQL version check From ffed6a3715422391f41147f8d2b64b729f9f03e5 Mon Sep 17 00:00:00 2001 From: Christine Date: Tue, 22 Mar 2016 15:20:18 +0100 Subject: [PATCH 027/126] Adding threadpool information #138 --- mysqltuner.pl | 33 +++++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/mysqltuner.pl b/mysqltuner.pl index 33ace26..771a215 100755 --- a/mysqltuner.pl +++ b/mysqltuner.pl @@ -785,7 +785,11 @@ sub get_all_vars { if ( ( $myvar{'ignore_builtin_innodb'} || "" ) eq "ON" ) { $myvar{'have_innodb'} = "NO"; } - + + $myvar{'have_threadpool'} = "NO"; + if ( defined ( $myvar{'thread_pool_size'} ) and $myvar{'thread_pool_size'} > 0 ) { + $myvar{'have_threadpool'} = "YES"; + } # have_* for engines is deprecated and will be removed in MySQL 5.6; # check SHOW ENGINES and set corresponding old style variables. # Also works around MySQL bug #59393 wrt. skip-innodb @@ -2503,13 +2507,33 @@ sub mariadb_threadpool { # AriaDB unless ( defined $myvar{'have_threadpool'} - && $myvar{'have_threadpool'} eq "YES" - && defined $enginestats{'Aria'} ) + && $myvar{'have_threadpool'} eq "YES" ) { infoprint "ThreadPool stat is disabled."; return; } - infoprint "ThreadPool stat is enabled."; + infoprint "ThreadPool stat is enabled."; + infoprint "Thread Pool Size: ".$myvar{'thread_pool_size'}. " thread(s)."; + + if ($myvar{'have_innodb'} eq 'YES') { + if ($myvar{'thread_pool_size'}< 16 or $myvar{'thread_pool_size'}>36) { + badprint "thread_pool_size between 16 and 36 when using InnoDB storage engine."; + push( @generalrec, "Thread pool size for InnoDB usage (".$myvar{'thread_pool_size'}.")" ); + push( @adjvars, "thread_pool_size between 16 and 36 for InnoDB usage" ); + } else { + goodprint "thread_pool_size between 16 and 36 when using InnoDB storage engine."; + } + return; + } + if ($myvar{'have_isam'} eq 'YES') { + if ($myvar{'thread_pool_size'}<4 or $myvar{'thread_pool_size'}>8) { + badprint "thread_pool_size between 4 and 8 when using MyIsam storage engine."; + push( @generalrec, "Thread pool size for MyIsam usage (".$myvar{'thread_pool_size'}.")" ); + push( @adjvars, "thread_pool_size between 4 and 8 for MyIsam usage" ); + } else { + goodprint "thread_pool_size between 4 and 8 when using MyISAM storage engine."; + } + } } # Recommendations for Performance Schema @@ -2525,6 +2549,7 @@ sub mysqsl_pfs { infoprint "Performance schema is enabled."; } + # Recommendations for Ariadb sub mariadb_ariadb { prettyprint From a45e83facfa1b3e877923db4267c38080bb08260 Mon Sep 17 00:00:00 2001 From: Jean-Marie Renouard Date: Tue, 22 Mar 2016 15:23:49 +0100 Subject: [PATCH 028/126] Update INTERNALS.md --- INTERNALS.md | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/INTERNALS.md b/INTERNALS.md index 151666e..38ac688 100644 --- a/INTERNALS.md +++ b/INTERNALS.md @@ -244,15 +244,5 @@ ## MySQLTuner MariaDB thread pool information -* thread_pool_size -* thread_pool_stall_limit - -* thread_pool_max_threads -* thread_pool_idle_timeout - -* thread_pool_oversubscribe - -* threadpool_threads -* threadpool_idle_threads -* threadpool_threads / thread_pool_size -* threadpool_idle_threads / thread_pool_size +* thread_pool_size between 16 to 36 for Innodb usage +* thread_pool_size between 4 to 8 for MyIsam usage From e6f8f78ffe2bf74e6b2095020e1323500fccb0e6 Mon Sep 17 00:00:00 2001 From: Jean-Marie Renouard Date: Tue, 22 Mar 2016 15:24:24 +0100 Subject: [PATCH 029/126] Update INTERNALS.md --- INTERNALS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/INTERNALS.md b/INTERNALS.md index 38ac688..d025858 100644 --- a/INTERNALS.md +++ b/INTERNALS.md @@ -242,7 +242,7 @@ * tokudb_cleaner_iterations * tokudb_fanout -## MySQLTuner MariaDB thread pool information +## MySQLTuner Thread pool information * thread_pool_size between 16 to 36 for Innodb usage * thread_pool_size between 4 to 8 for MyIsam usage From 47ffb270d9c4ddee353b4e667e5d17b18a8342d8 Mon Sep 17 00:00:00 2001 From: Christine Date: Tue, 22 Mar 2016 15:35:00 +0100 Subject: [PATCH 030/126] Typo fix --- mysqltuner.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysqltuner.pl b/mysqltuner.pl index 771a215..f39b532 100755 --- a/mysqltuner.pl +++ b/mysqltuner.pl @@ -943,7 +943,7 @@ sub system_recommendations { if ( (0.15*$physical_memory) < $omem) { badprint "Other user process except mysqld used more than 15% of total physical memory ". percentage($omem, $physical_memory). "% (".hr_bytes_rnd($omem). " / ".hr_bytes_rnd($physical_memory).")"; push( @generalrec, "Consider stopping or dedicate server for additionnal process other than mysqld." ); - push( @adjvars, "DON'T APPLY SETTINGS BECAUSE THERE IS TOO MANY PROCESS RUNNING ON THIS SERVER. OOM KILL CAN OCCURS !" ); + push( @adjvars, "DON'T APPLY SETTINGS BECAUSE THERE IS TOO MANY PROCESSES RUNNING ON THIS SERVER. OOM KILL CAN OCCURS !" ); } else { From fb53fa4efce4ead40eb0186e4110462f22936bfd Mon Sep 17 00:00:00 2001 From: Christine Date: Tue, 22 Mar 2016 16:36:04 +0100 Subject: [PATCH 031/126] Adding extra information on collation in dbstat --- mysqltuner.pl | 42 +++++++++++++++++++++++++++++++++--------- 1 file changed, 33 insertions(+), 9 deletions(-) diff --git a/mysqltuner.pl b/mysqltuner.pl index f39b532..0974d32 100755 --- a/mysqltuner.pl +++ b/mysqltuner.pl @@ -2883,19 +2883,30 @@ sub mysql_databases { infoprint "There is " . scalar(@dblist) . " Database(s)."; my @totaldbinfo = split /\s/, select_one( -"SELECT SUM(TABLE_ROWS), SUM(DATA_LENGTH), SUM(INDEX_LENGTH) , SUM(DATA_LENGTH+INDEX_LENGTH) FROM information_schema.TABLES;" +"SELECT SUM(TABLE_ROWS), SUM(DATA_LENGTH), SUM(INDEX_LENGTH) , SUM(DATA_LENGTH+INDEX_LENGTH), COUNT(TABLE_NAME),COUNT(DISTINCT(TABLE_COLLATION)) FROM information_schema.TABLES;" ); infoprint "All Databases:"; - infoprint " +-- ROWS : " + infoprint " +-- TABLE : " + . ( $totaldbinfo[4] eq 'NULL' ? 0 : $totaldbinfo[4] ) . ""; + infoprint " +-- ROWS : " . ( $totaldbinfo[0] eq 'NULL' ? 0 : $totaldbinfo[0] ) . ""; - infoprint " +-- DATA : " + infoprint " +-- DATA : " . hr_bytes( $totaldbinfo[1] ) . "(" . percentage( $totaldbinfo[1], $totaldbinfo[3] ) . "%)"; - infoprint " +-- INDEX: " + infoprint " +-- INDEX : " . hr_bytes( $totaldbinfo[2] ) . "(" . percentage( $totaldbinfo[2], $totaldbinfo[3] ) . "%)"; - infoprint " +-- SIZE : " . hr_bytes( $totaldbinfo[3] ) . ""; - + infoprint " +-- SIZE : " . hr_bytes( $totaldbinfo[3] ) . ""; + infoprint " +-- COLLA : " + . ( $totaldbinfo[5] eq 'NULL' ? 0 : $totaldbinfo[5] ) . " (". (join ", ", select_array ("SELECT DISTINCT(TABLE_COLLATION) FROM information_schema.TABLES;")) .")"; + + + if ($totaldbinfo[5]>1) { + badprint $totaldbinfo[5]. " differents collations for tables detected."; + push(@generalrec, "Check your general collation and your database table location are identical."); + } else { + goodprint $totaldbinfo[5]. " collation for tables detected."; + } badprint "Index size is larger than data size \n" if $totaldbinfo[1] < $totaldbinfo[2]; @@ -2907,8 +2918,8 @@ sub mysql_databases { $result{'Databases'}{'All databases'}{'Index Size'} = $totaldbinfo[2]; $result{'Databases'}{'All databases'}{'Index Pct'} = percentage( $totaldbinfo[2], $totaldbinfo[3] ) . "%"; - $result{'Databases'}{'All databases'}{'Total Size'} = $totaldbinfo[3]; - + $result{'Databases'}{'All databases'}{'Total Size'} = $totaldbinfo[3]; + print "\n"; foreach (@dblist) { chomp($_); if ( $_ eq "information_schema" @@ -2921,10 +2932,15 @@ sub mysql_databases { my @dbinfo = split /\s/, select_one( -"SELECT TABLE_SCHEMA, SUM(TABLE_ROWS), SUM(DATA_LENGTH), SUM(INDEX_LENGTH) , SUM(DATA_LENGTH+INDEX_LENGTH), COUNT(DISTINCT ENGINE) FROM information_schema.TABLES WHERE TABLE_SCHEMA='$_' GROUP BY TABLE_SCHEMA ORDER BY TABLE_SCHEMA" +"SELECT TABLE_SCHEMA, SUM(TABLE_ROWS), SUM(DATA_LENGTH), SUM(INDEX_LENGTH) , SUM(DATA_LENGTH+INDEX_LENGTH), COUNT(DISTINCT ENGINE),COUNT(TABLE_NAME),COUNT(DISTINCT(TABLE_COLLATION)) FROM information_schema.TABLES WHERE TABLE_SCHEMA='$_' GROUP BY TABLE_SCHEMA ORDER BY TABLE_SCHEMA" ); next unless defined $dbinfo[0]; infoprint "Database: " . $dbinfo[0] . ""; + infoprint " +-- TABLE: " + . ( !defined( $dbinfo[6] ) or $dbinfo[6] eq 'NULL' ? 0 : $dbinfo[6] ) + . ""; + infoprint " +-- COLL : " + . ( $dbinfo[7] eq 'NULL' ? 0 : $dbinfo[7] ) . " (". (join ", ", select_array ("SELECT DISTINCT(TABLE_COLLATION) FROM information_schema.TABLES WHERE TABLE_SCHEMA='$_';")) .")"; infoprint " +-- ROWS : " . ( !defined( $dbinfo[1] ) or $dbinfo[1] eq 'NULL' ? 0 : $dbinfo[1] ) . ""; @@ -2940,6 +2956,8 @@ sub mysql_databases { badprint "There are " . $dbinfo[5] . " storage engines. Be careful. \n" if $dbinfo[5] > 1; $result{'Databases'}{ $dbinfo[0] }{'Rows'} = $dbinfo[1]; + $result{'Databases'}{ $dbinfo[0] }{'Tables'} = $dbinfo[6]; + $result{'Databases'}{ $dbinfo[0] }{'Collations'} = $dbinfo[7]; $result{'Databases'}{ $dbinfo[0] }{'Data Size'} = $dbinfo[2]; $result{'Databases'}{ $dbinfo[0] }{'Data Pct'} = percentage( $dbinfo[2], $dbinfo[4] ) . "%"; @@ -2947,6 +2965,12 @@ sub mysql_databases { $result{'Databases'}{ $dbinfo[0] }{'Index Pct'} = percentage( $dbinfo[3], $dbinfo[4] ) . "%"; $result{'Databases'}{ $dbinfo[0] }{'Total Size'} = $dbinfo[4]; + if ($dbinfo[7]>1) { + badprint $dbinfo[7]. " differents collations for database ".$dbinfo[0]; + push(@generalrec, "Check all table collations are identical for all tables in ".$dbinfo[0]. " database."); + } else { + goodprint $dbinfo[7]. " collation for ".$dbinfo[0]. " database."; + } } } From 18941ae560aff89090f7037cfed4e631a91f5820 Mon Sep 17 00:00:00 2001 From: Christine Date: Tue, 22 Mar 2016 17:56:08 +0100 Subject: [PATCH 032/126] Advanced dbstat for collation and charset --- INTERNALS.md | 6 ++++++ mysqltuner.pl | 44 ++++++++++++++++++++++++++++++++------------ 2 files changed, 38 insertions(+), 12 deletions(-) diff --git a/INTERNALS.md b/INTERNALS.md index d025858..d24b3c4 100644 --- a/INTERNALS.md +++ b/INTERNALS.md @@ -101,12 +101,18 @@ ## MySQLTuner database information * Per database information + * Tables number * Rows number * Total size * Data size * Percentage of data size * Index size * Percentage of index size + * Collation number + * Check that there is only one collation for all table in a database + * Check that there is only one collation for ll table columns in a database + * Check that there is only one storage engine per user database + ## MySQLTuner index information diff --git a/mysqltuner.pl b/mysqltuner.pl index 0974d32..755426f 100755 --- a/mysqltuner.pl +++ b/mysqltuner.pl @@ -2883,7 +2883,7 @@ sub mysql_databases { infoprint "There is " . scalar(@dblist) . " Database(s)."; my @totaldbinfo = split /\s/, select_one( -"SELECT SUM(TABLE_ROWS), SUM(DATA_LENGTH), SUM(INDEX_LENGTH) , SUM(DATA_LENGTH+INDEX_LENGTH), COUNT(TABLE_NAME),COUNT(DISTINCT(TABLE_COLLATION)) FROM information_schema.TABLES;" +"SELECT SUM(TABLE_ROWS), SUM(DATA_LENGTH), SUM(INDEX_LENGTH) , SUM(DATA_LENGTH+INDEX_LENGTH), COUNT(TABLE_NAME),COUNT(DISTINCT(TABLE_COLLATION)),COUNT(DISTINCT(ENGINE)) FROM information_schema.TABLES;" ); infoprint "All Databases:"; infoprint " +-- TABLE : " @@ -2899,17 +2899,10 @@ sub mysql_databases { infoprint " +-- SIZE : " . hr_bytes( $totaldbinfo[3] ) . ""; infoprint " +-- COLLA : " . ( $totaldbinfo[5] eq 'NULL' ? 0 : $totaldbinfo[5] ) . " (". (join ", ", select_array ("SELECT DISTINCT(TABLE_COLLATION) FROM information_schema.TABLES;")) .")"; + infoprint " +-- ENGIN : " + . ( $totaldbinfo[6] eq 'NULL' ? 0 : $totaldbinfo[6] ) . " (". (join ", ", select_array ("SELECT DISTINCT(ENGINE) FROM information_schema.TABLES;")) .")"; - if ($totaldbinfo[5]>1) { - badprint $totaldbinfo[5]. " differents collations for tables detected."; - push(@generalrec, "Check your general collation and your database table location are identical."); - } else { - goodprint $totaldbinfo[5]. " collation for tables detected."; - } - badprint "Index size is larger than data size \n" - if $totaldbinfo[1] < $totaldbinfo[2]; - $result{'Databases'}{'All databases'}{'Rows'} = ( $totaldbinfo[0] eq 'NULL' ? 0 : $totaldbinfo[0] ); $result{'Databases'}{'All databases'}{'Data Size'} = $totaldbinfo[1]; @@ -2924,7 +2917,7 @@ sub mysql_databases { chomp($_); if ( $_ eq "information_schema" or $_ eq "performance_schema" - or $_ eq "mysql" + # or $_ eq "mysql" or $_ eq "" ) { next; @@ -2932,7 +2925,7 @@ sub mysql_databases { my @dbinfo = split /\s/, select_one( -"SELECT TABLE_SCHEMA, SUM(TABLE_ROWS), SUM(DATA_LENGTH), SUM(INDEX_LENGTH) , SUM(DATA_LENGTH+INDEX_LENGTH), COUNT(DISTINCT ENGINE),COUNT(TABLE_NAME),COUNT(DISTINCT(TABLE_COLLATION)) FROM information_schema.TABLES WHERE TABLE_SCHEMA='$_' GROUP BY TABLE_SCHEMA ORDER BY TABLE_SCHEMA" +"SELECT TABLE_SCHEMA, SUM(TABLE_ROWS), SUM(DATA_LENGTH), SUM(INDEX_LENGTH) , SUM(DATA_LENGTH+INDEX_LENGTH), COUNT(DISTINCT ENGINE),COUNT(TABLE_NAME),COUNT(DISTINCT(TABLE_COLLATION)),COUNT(DISTINCT(ENGINE)) FROM information_schema.TABLES WHERE TABLE_SCHEMA='$_' GROUP BY TABLE_SCHEMA ORDER BY TABLE_SCHEMA" ); next unless defined $dbinfo[0]; infoprint "Database: " . $dbinfo[0] . ""; @@ -2951,6 +2944,8 @@ sub mysql_databases { . hr_bytes( $dbinfo[3] ) . "(" . percentage( $dbinfo[3], $dbinfo[4] ) . "%)"; infoprint " +-- TOTAL: " . hr_bytes( $dbinfo[4] ) . ""; + infoprint " +-- ENGIN : " + . ( $dbinfo[8] eq 'NULL' ? 0 : $dbinfo[8] ) . " (". (join ", ", select_array ("SELECT DISTINCT(ENGINE) FROM information_schema.TABLES WHERE TABLE_SCHEMA='$_'")) .")"; badprint "Index size is larger than data size for $dbinfo[0] \n" if $dbinfo[2] < $dbinfo[3]; badprint "There are " . $dbinfo[5] . " storage engines. Be careful. \n" @@ -2971,7 +2966,32 @@ sub mysql_databases { } else { goodprint $dbinfo[7]. " collation for ".$dbinfo[0]. " database."; } + if ($dbinfo[8]>1) { + badprint $dbinfo[8]. " differents engines for database ".$dbinfo[0]; + push(@generalrec, "Check all table engines are identical for all tables in ".$dbinfo[0]. " database."); + } else { + goodprint $dbinfo[8]. " engine for ".$dbinfo[0]. " database."; } + + my @distinct_column_charset=select_array("select DISTINCT(CHARACTER_SET_NAME) from information_schema.COLUMNS where CHARACTER_SET_NAME IS NOT NULL AND TABLE_SCHEMA ='$_'"); + infoprint "Charsets for $dbinfo[0] database table column: ". join (', ', @distinct_column_charset); + if (scalar (@distinct_column_charset)>1 ) { + badprint $dbinfo[0]. " table column(s) has several charsets defined for all text like column(s)."; + push(@generalrec, "Limit charset for column to one charset if possible for ".$dbinfo[0]." database."); + } else { + goodprint $dbinfo[0]. " table column(s) has same charset defined for all text like column(s)."; + } + + my @distinct_column_collation=select_array("select DISTINCT(COLLATION_NAME) from information_schema.COLUMNS where COLLATION_NAME IS NOT NULL AND TABLE_SCHEMA ='$_'"); + infoprint "Collations for $dbinfo[0] database table column: ". join (', ', @distinct_column_collation); + if (scalar (@distinct_column_collation)>1 ) { + badprint $dbinfo[0]. " table column(s) has several collations defined for all text like column(s)."; + push(@generalrec, "Limit collations for column to one collation if possible for ".$dbinfo[0]." database."); + } else { + goodprint $dbinfo[0]. " table column(s) has same collation defined for all text like column(s)."; + } + } + } # Recommendations for Indexes metrics From b05eea9163384df4e02d60f8dd110768c26b35be Mon Sep 17 00:00:00 2001 From: Jean-Marie RENOUARD Date: Wed, 23 Mar 2016 12:19:49 +0100 Subject: [PATCH 033/126] Revert "Update CVE list" This reverts commit 3a0ce00ffdd24029c7d05e6a7128eafd0ac33330. --- vulnerabilities.csv | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 vulnerabilities.csv diff --git a/vulnerabilities.csv b/vulnerabilities.csv old mode 100755 new mode 100644 From 039a16505a108e91647b1ed86cd95d73768469b8 Mon Sep 17 00:00:00 2001 From: Jean-Marie RENOUARD Date: Wed, 23 Mar 2016 12:19:54 +0100 Subject: [PATCH 034/126] Revert "Revert "Update CVE list"" This reverts commit b05eea9163384df4e02d60f8dd110768c26b35be. --- vulnerabilities.csv | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 vulnerabilities.csv diff --git a/vulnerabilities.csv b/vulnerabilities.csv old mode 100644 new mode 100755 From 95c13972891ee76de9023b0fde9669a806a5ed20 Mon Sep 17 00:00:00 2001 From: root Date: Wed, 23 Mar 2016 16:18:36 +0100 Subject: [PATCH 035/126] #163 removing by default banned port 443,80, 8080,8443 and let bannedports managed this case. --- mysqltuner.pl | 37 ++++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/mysqltuner.pl b/mysqltuner.pl index 755426f..76196ef 100755 --- a/mysqltuner.pl +++ b/mysqltuner.pl @@ -570,15 +570,18 @@ sub mysql_setup { } } elsif ( -r "/etc/psa/.psa.shadow" and $doremote == 0 ) { - # It's a Plesk box, use the available credentials $mysqllogin = "-u admin -p`cat /etc/psa/.psa.shadow`"; my $loginstatus = `$mysqladmincmd ping $mysqllogin 2>&1`; unless ( $loginstatus =~ /mysqld is alive/ ) { - badprint -"Attempted to use login credentials from Plesk, but they failed."; - exit 1; - } + # Plesk 10+ + $mysqllogin = "-u admin -p`/usr/local/psa/bin/admin --show-password`"; + $loginstatus = `$mysqladmincmd ping $mysqllogin 2>&1`; + unless ( $loginstatus =~ /mysqld is alive/ ) { + badprint "Attempted to use login credentials from Plesk and Plesk 10+, but they failed."; + exit 1; + } + } } elsif ( -r "/usr/local/directadmin/conf/mysql.conf" and $doremote == 0 ) { @@ -961,18 +964,18 @@ sub system_recommendations { goodprint "There is less than 10 opened ports on this server."; } - if ( is_open_port(80) or is_open_port(443) ) { - badprint "There is Apache like server running on 80 or 443 port."; - push( @generalrec, "Consider dedicating a server for Web server in production !" ); - } else { - goodprint "No Web server runing on 80 and 444 port."; - } - if ( is_open_port(8080) or is_open_port(8443) ) { - badprint "There is Application server running on 8080 or 8443 port."; - push( @generalrec, "Consider dedicating a server for Application server in production !" ); - } else { - goodprint "No Application server runing on 8080 or 8443 port."; - } +# if ( is_open_port(80) or is_open_port(443) ) { +# badprint "There is Apache like server running on 80 or 443 port."; +# push( @generalrec, "Consider dedicating a server for Web server in production !" ); +# } else { +# goodprint "No Web server runing on 80 and 443 port."; +# } +# if ( is_open_port(8080) or is_open_port(8443) ) { +# badprint "There is Application server running on 8080 or 8443 port."; +# push( @generalrec, "Consider dedicating a server for Application server in production !" ); +# } else { +# goodprint "No Application server runing on 8080 or 8443 port."; +# } foreach my $banport (@banned_ports) { if ( is_open_port($banport) ) { badprint "Banned port: $banport is opened.."; From 30b7f2e52c5b8ee6bc04edd0c7206440308a9db8 Mon Sep 17 00:00:00 2001 From: root Date: Wed, 23 Mar 2016 16:33:02 +0100 Subject: [PATCH 036/126] #164 removing by default check for 10 opened ports. option maxallowedport added for this case. --- mysqltuner.pl | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/mysqltuner.pl b/mysqltuner.pl index 76196ef..0756ad3 100755 --- a/mysqltuner.pl +++ b/mysqltuner.pl @@ -1,5 +1,5 @@ #!/usr/bin/env perl -# mysqltuner.pl - Version 1.6.7 +# mysqltuner.pl - Version 1.6.8 # High Performance MySQL Tuning Script # Copyright (C) 2006-2015 Major Hayden - major@mhtx.net # @@ -51,7 +51,7 @@ use Data::Dumper; $Data::Dumper::Pair = " : "; # Set up a few variables for use in the script -my $tunerversion = "1.6.7"; +my $tunerversion = "1.6.8"; my ( @adjvars, @generalrec ); # Set defaults @@ -73,7 +73,8 @@ my %opt = ( "checkversion" => 0, "buffers" => 0, "passwordfile" => 0, - "bannedports" => '', + "bannedports" => '', + "maxportallowed"= >0, "outputfile" => 0, "dbstat" => 0, "idxstat" => 0, @@ -93,7 +94,7 @@ GetOptions( 'mysqlcmd=s', 'help', 'buffers', 'skippassword', 'passwordfile=s', 'outputfile=s', 'silent', 'dbstat', 'json', 'idxstat', 'noask', 'template=s', 'reportfile=s', 'cvefile=s', - 'bannedports=s', + 'bannedports=s','maxportallowed=s' ); if ( defined $opt{'help'} && $opt{'help'} == 1 ) { usage(); } @@ -136,7 +137,8 @@ sub usage { . " --debug Print debug information\n" . " --dbstat Print database information\n" . " --idxstat Print index information\n" - . " --bannedports ports banned separated by comma(,)\n" + . " --bannedports Ports banned separated by comma(,)\n" + . " --maxportallowed Number of ports opened allowed on this hosts\n" . " --cvefile CVE File for vulnerability checks\n" . " --nocolor Don't print output in color\n" . " --json Print result as JSON string\n" @@ -955,16 +957,17 @@ sub system_recommendations { #if ($omem > #exit 0; - my @opened_ports=get_opened_ports; - infoprint "There is ". scalar @opened_ports. " listening port(s) on this server."; - if (scalar(@opened_ports) > 10) { - badprint "There is too many listening ports: ". scalar(@opened_ports). " > 10"; - push( @generalrec, "Consider dedicating a server for your database installation with less services running on !" ); - } else { - goodprint "There is less than 10 opened ports on this server."; + if ($opt{'maxportallowed'} > 0) { + my @opened_ports=get_opened_ports; + infoprint "There is ". scalar @opened_ports. " listening port(s) on this server."; + if (scalar(@opened_ports) > $opt{'maxportallowed'}) { + badprint "There is too many listening ports: ". scalar(@opened_ports). " > 10"; + push( @generalrec, "Consider dedicating a server for your database installation with less services running on !" ); + } else { + goodprint "There is less than ".$opt{'maxportallowed'}." opened ports on this server."; + } } - -# if ( is_open_port(80) or is_open_port(443) ) { + # if ( is_open_port(80) or is_open_port(443) ) { # badprint "There is Apache like server running on 80 or 443 port."; # push( @generalrec, "Consider dedicating a server for Web server in production !" ); # } else { @@ -3264,7 +3267,7 @@ __END__ =head1 NAME - MySQLTuner 1.6.7 - MySQL High Performance Tuning Script + MySQLTuner 1.6.8 - MySQL High Performance Tuning Script =head1 IMPORTANT USAGE GUIDELINES @@ -3302,7 +3305,8 @@ You must provide the remote server's total memory when connecting to other serve --debug Print debug information --dbstat Print database information --idxstat Print index information - --bannedports ports banned separated by comma(,) + --bannedports Ports banned separated by comma(,) + --maxportallowed Number of ports opened allowed on this hosts --cvefile CVE File for vulnerability checks --nocolor Don't print output in color --json Print result as JSON string From 84d108bc702dbae5e7209f949ec8c3ab8b04007c Mon Sep 17 00:00:00 2001 From: root Date: Wed, 23 Mar 2016 16:35:59 +0100 Subject: [PATCH 037/126] Broken code fixed --- mysqltuner.pl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mysqltuner.pl b/mysqltuner.pl index 0756ad3..eb32211 100755 --- a/mysqltuner.pl +++ b/mysqltuner.pl @@ -74,7 +74,7 @@ my %opt = ( "buffers" => 0, "passwordfile" => 0, "bannedports" => '', - "maxportallowed"= >0, + "maxportallowed"=> 0, "outputfile" => 0, "dbstat" => 0, "idxstat" => 0, @@ -94,7 +94,7 @@ GetOptions( 'mysqlcmd=s', 'help', 'buffers', 'skippassword', 'passwordfile=s', 'outputfile=s', 'silent', 'dbstat', 'json', 'idxstat', 'noask', 'template=s', 'reportfile=s', 'cvefile=s', - 'bannedports=s','maxportallowed=s' + 'bannedports=s','maxportallowed=s', ); if ( defined $opt{'help'} && $opt{'help'} == 1 ) { usage(); } From 10a5ad0fdb71547bec37362955cec51182e3ee2a Mon Sep 17 00:00:00 2001 From: root Date: Thu, 24 Mar 2016 10:21:02 +0100 Subject: [PATCH 038/126] Fix message for #164 issue --- mysqltuner.pl | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/mysqltuner.pl b/mysqltuner.pl index eb32211..aa71a9b 100755 --- a/mysqltuner.pl +++ b/mysqltuner.pl @@ -961,24 +961,13 @@ sub system_recommendations { my @opened_ports=get_opened_ports; infoprint "There is ". scalar @opened_ports. " listening port(s) on this server."; if (scalar(@opened_ports) > $opt{'maxportallowed'}) { - badprint "There is too many listening ports: ". scalar(@opened_ports). " > 10"; + badprint "There is too many listening ports: ". scalar(@opened_ports) " opened > ".$opt{'maxportallowed'}. "allowed."; push( @generalrec, "Consider dedicating a server for your database installation with less services running on !" ); } else { goodprint "There is less than ".$opt{'maxportallowed'}." opened ports on this server."; } } - # if ( is_open_port(80) or is_open_port(443) ) { -# badprint "There is Apache like server running on 80 or 443 port."; -# push( @generalrec, "Consider dedicating a server for Web server in production !" ); -# } else { -# goodprint "No Web server runing on 80 and 443 port."; -# } -# if ( is_open_port(8080) or is_open_port(8443) ) { -# badprint "There is Application server running on 8080 or 8443 port."; -# push( @generalrec, "Consider dedicating a server for Application server in production !" ); -# } else { -# goodprint "No Application server runing on 8080 or 8443 port."; -# } + foreach my $banport (@banned_ports) { if ( is_open_port($banport) ) { badprint "Banned port: $banport is opened.."; From 0be6ebb62675566dc83fbfca756450eb492b8a5e Mon Sep 17 00:00:00 2001 From: DutchProgrammer Date: Thu, 24 Mar 2016 14:25:12 +0100 Subject: [PATCH 039/126] fix the build fail --- mysqltuner.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysqltuner.pl b/mysqltuner.pl index aa71a9b..029fa08 100755 --- a/mysqltuner.pl +++ b/mysqltuner.pl @@ -961,7 +961,7 @@ sub system_recommendations { my @opened_ports=get_opened_ports; infoprint "There is ". scalar @opened_ports. " listening port(s) on this server."; if (scalar(@opened_ports) > $opt{'maxportallowed'}) { - badprint "There is too many listening ports: ". scalar(@opened_ports) " opened > ".$opt{'maxportallowed'}. "allowed."; + badprint "There is too many listening ports: ". scalar(@opened_ports). " opened > ".$opt{'maxportallowed'}. "allowed."; push( @generalrec, "Consider dedicating a server for your database installation with less services running on !" ); } else { goodprint "There is less than ".$opt{'maxportallowed'}." opened ports on this server."; From 9c87b5266f6d7d04dd09d63ae309eb03cb1eae47 Mon Sep 17 00:00:00 2001 From: DutchProgrammer Date: Thu, 24 Mar 2016 18:36:49 +0100 Subject: [PATCH 040/126] v1.6.9 --- mysqltuner.pl | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/mysqltuner.pl b/mysqltuner.pl index 029fa08..f864d2c 100755 --- a/mysqltuner.pl +++ b/mysqltuner.pl @@ -1,7 +1,7 @@ #!/usr/bin/env perl -# mysqltuner.pl - Version 1.6.8 +# mysqltuner.pl - Version 1.6.9 # High Performance MySQL Tuning Script -# Copyright (C) 2006-2015 Major Hayden - major@mhtx.net +# Copyright (C) 2006-2016 Major Hayden - major@mhtx.net # # For the latest updates, please visit http://mysqltuner.com/ # Git repository available at http://github.com/major/MySQLTuner-perl @@ -51,7 +51,7 @@ use Data::Dumper; $Data::Dumper::Pair = " : "; # Set up a few variables for use in the script -my $tunerversion = "1.6.8"; +my $tunerversion = "1.6.9"; my ( @adjvars, @generalrec ); # Set defaults @@ -82,7 +82,8 @@ my %opt = ( "noask" => 0, "template" => 0, "json" => 0, - "reportfile" => 0 + "reportfile" => 0, + "prettyjson" => 0 ); # Gather the options from the command line @@ -94,7 +95,7 @@ GetOptions( 'mysqlcmd=s', 'help', 'buffers', 'skippassword', 'passwordfile=s', 'outputfile=s', 'silent', 'dbstat', 'json', 'idxstat', 'noask', 'template=s', 'reportfile=s', 'cvefile=s', - 'bannedports=s','maxportallowed=s', + 'bannedports=s','maxportallowed=s','prettyjson' ); if ( defined $opt{'help'} && $opt{'help'} == 1 ) { usage(); } @@ -142,6 +143,7 @@ sub usage { . " --cvefile CVE File for vulnerability checks\n" . " --nocolor Don't print output in color\n" . " --json Print result as JSON string\n" + . " --prettyjson Print result as human readable JSON\n" . " --buffers Print global and per-thread buffer values\n" . " --outputfile Path to a output txt file\n" . "\n" . " --reportfile Path to a report txt file\n" . "\n" @@ -3208,7 +3210,7 @@ sub dump_result { exit 1; } my $json = JSON->new->allow_nonref; - print JSON->new->utf8(1)->pretty(1)->encode(%result); + print $json->utf8(1)->pretty((defined $opt{'prettyjson'} ? 1 : 0))->encode(\%result); } } From 58807c135f1c09e85ce999aa118be762a43cb97c Mon Sep 17 00:00:00 2001 From: DutchProgrammer Date: Thu, 24 Mar 2016 19:47:59 +0100 Subject: [PATCH 041/126] inconsistent performance schema info #167 --- mysqltuner.pl | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/mysqltuner.pl b/mysqltuner.pl index f864d2c..7373273 100755 --- a/mysqltuner.pl +++ b/mysqltuner.pl @@ -82,8 +82,8 @@ my %opt = ( "noask" => 0, "template" => 0, "json" => 0, - "reportfile" => 0, - "prettyjson" => 0 + "prettyjson" => 0, + "reportfile" => 0 ); # Gather the options from the command line @@ -93,9 +93,10 @@ GetOptions( 'host=s', 'socket=s', 'port=i', 'user=s', 'pass=s', 'skipsize', 'checkversion', 'mysqladmin=s', 'mysqlcmd=s', 'help', 'buffers', 'skippassword', - 'passwordfile=s', 'outputfile=s', 'silent', 'dbstat', 'json', - 'idxstat', 'noask', 'template=s', 'reportfile=s', 'cvefile=s', - 'bannedports=s','maxportallowed=s','prettyjson' + 'passwordfile=s', 'outputfile=s', 'silent', 'dbstat', + 'json', 'prettyjson', 'idxstat', 'noask', + 'template=s', 'reportfile=s', 'cvefile=s', 'bannedports=s', + 'maxportallowed=s' ); if ( defined $opt{'help'} && $opt{'help'} == 1 ) { usage(); } @@ -191,7 +192,7 @@ my %result; # Functions that handle the print styles sub prettyprint { - print $_[0] . "\n" unless $opt{'silent'}; + print $_[0] . "\n" unless ($opt{'silent'} or $opt{'json'}); print $fh $_[0] . "\n" if defined($fh); } sub goodprint { prettyprint $good. " " . $_[0] unless ( $opt{nogood} == 1 ); } @@ -388,7 +389,7 @@ sub os_setup { # Checks for updates to MySQLTuner sub validate_tuner_version { if ($opt{checkversion} eq 0) { - print "\n"; + print "\n" unless ($opt{'silent'} or $opt{'json'}); infoprint "Skipped version check for MySQLTuner script"; return; } @@ -2541,9 +2542,9 @@ sub mysqsl_pfs { # Performance Schema unless ( defined($myvar{'performance_schema'}) and $myvar{'performance_schema'} eq 'ON' ) { infoprint "Performance schema is disabled."; + } else { + infoprint "Performance schema is enabled."; } - - infoprint "Performance schema is enabled."; } @@ -2909,7 +2910,7 @@ sub mysql_databases { $result{'Databases'}{'All databases'}{'Index Pct'} = percentage( $totaldbinfo[2], $totaldbinfo[3] ) . "%"; $result{'Databases'}{'All databases'}{'Total Size'} = $totaldbinfo[3]; - print "\n"; + print "\n" unless ($opt{'silent'} or $opt{'json'}); foreach (@dblist) { chomp($_); if ( $_ eq "information_schema" @@ -3210,7 +3211,7 @@ sub dump_result { exit 1; } my $json = JSON->new->allow_nonref; - print $json->utf8(1)->pretty((defined $opt{'prettyjson'} ? 1 : 0))->encode(\%result); + print $json->utf8(1)->pretty(($opt{'prettyjson'} ? 1 : 0))->encode(\%result); } } From ae9bbe405b409ea8aa6c83b4d7b83af44834c04c Mon Sep 17 00:00:00 2001 From: DutchProgrammer Date: Thu, 24 Mar 2016 21:17:34 +0100 Subject: [PATCH 042/126] added version update functionality --- mysqltuner.pl | 130 ++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 100 insertions(+), 30 deletions(-) diff --git a/mysqltuner.pl b/mysqltuner.pl index 7373273..1540b75 100755 --- a/mysqltuner.pl +++ b/mysqltuner.pl @@ -56,34 +56,35 @@ my ( @adjvars, @generalrec ); # Set defaults my %opt = ( - "silent" => 0, - "nobad" => 0, - "nogood" => 0, - "noinfo" => 0, - "debug" => 0, - "nocolor" => 0, - "forcemem" => 0, - "forceswap" => 0, - "host" => 0, - "socket" => 0, - "port" => 0, - "user" => 0, - "pass" => 0, - "skipsize" => 0, - "checkversion" => 0, - "buffers" => 0, - "passwordfile" => 0, - "bannedports" => '', - "maxportallowed"=> 0, - "outputfile" => 0, - "dbstat" => 0, - "idxstat" => 0, - "skippassword" => 0, - "noask" => 0, - "template" => 0, - "json" => 0, - "prettyjson" => 0, - "reportfile" => 0 + "silent" => 0, + "nobad" => 0, + "nogood" => 0, + "noinfo" => 0, + "debug" => 0, + "nocolor" => 0, + "forcemem" => 0, + "forceswap" => 0, + "host" => 0, + "socket" => 0, + "port" => 0, + "user" => 0, + "pass" => 0, + "skipsize" => 0, + "checkversion" => 0, + "updateversion" => 0, + "buffers" => 0, + "passwordfile" => 0, + "bannedports" => '', + "maxportallowed" => 0, + "outputfile" => 0, + "dbstat" => 0, + "idxstat" => 0, + "skippassword" => 0, + "noask" => 0, + "template" => 0, + "json" => 0, + "prettyjson" => 0, + "reportfile" => 0 ); # Gather the options from the command line @@ -96,7 +97,7 @@ GetOptions( 'passwordfile=s', 'outputfile=s', 'silent', 'dbstat', 'json', 'prettyjson', 'idxstat', 'noask', 'template=s', 'reportfile=s', 'cvefile=s', 'bannedports=s', - 'maxportallowed=s' + 'updateversion', 'maxportallowed=s' ); if ( defined $opt{'help'} && $opt{'help'} == 1 ) { usage(); } @@ -128,6 +129,7 @@ sub usage { . " (Recommended for servers with many tables)\n" . " --skippassword Don't perform checks on user passwords(default: off)\n" . " --checkversion Check for updates to MySQLTuner (default: don't check)\n" + . " --updateversion Check for updates to MySQLTuner and update when newer version is available (default: don't check)\n" . " --forcemem Amount of RAM installed in megabytes\n" . " --forceswap Amount of swap memory configured in megabytes\n" . " --passwordfile Path to a password file list(one password by line)\n" @@ -388,7 +390,7 @@ sub os_setup { # Checks for updates to MySQLTuner sub validate_tuner_version { - if ($opt{checkversion} eq 0) { + if ($opt{'checkversion'} eq 0 and $opt{'updateversion'} eq 0) { print "\n" unless ($opt{'silent'} or $opt{'json'}); infoprint "Skipped version check for MySQLTuner script"; return; @@ -427,12 +429,80 @@ sub validate_tuner_version { infoprint "Unable to check for the latest MySQLTuner version"; } +# Checks for updates to MySQLTuner +sub update_tuner_version { + if ($opt{'updateversion'} eq 0) { + badprint "Skipped version update for MySQLTuner script"; + print "\n" unless ($opt{'silent'} or $opt{'json'}); + return; + } + + #use Cwd; + my $update; + my $url = "https://raw.githubusercontent.com/major/MySQLTuner-perl/master/"; + my @scripts = ("mysqltuner.pl", "basic_passwords.txt", "vulnerabilities.csv"); + my $totalScripts = scalar(keys @scripts); + my $receivedScripts = 0; + my $httpcli =`which curl`; + + foreach my $script (@scripts) { + + chomp($httpcli); + if ( 1 != 1 and defined($httpcli) and -e "$httpcli" ) { + debugprint "$httpcli is available."; + + debugprint "$httpcli --connect-timeout 5 -silent '$url$script' > $script"; + $update = `$httpcli --connect-timeout 5 -silent '$url$script' > $script`; + chomp($update); + debugprint "$script updated: $update"; + + if ( -s $script eq 0) { + badprint "Couldn't update $script"; + } else { + ++$receivedScripts; + debugprint "$script updated: $update"; + } + } else { + + $httpcli=`which wget`; + chomp($httpcli); + if ( defined($httpcli) and -e "$httpcli" ) { + debugprint "$httpcli is available."; + + debugprint "$httpcli -qe timestamping=off -T 5 -O $script '$url$script'"; + $update = `$httpcli -qe timestamping=off -T 5 -O $script '$url$script'`; + chomp($update); + + if ( -s $script eq 0) { + badprint "Couldn't update $script"; + } else { + ++$receivedScripts; + debugprint "$script updated: $update"; + } + + } else { + debugprint "curl and wget are not available."; + infoprint "Unable to check for the latest MySQLTuner version"; + } + } + } + + if ($receivedScripts eq $totalScripts) { + goodprint "Successfully updated MySQLTuner script"; + } else { + badprint "Couldn't update MySQLTuner script"; + } + + exit 0; +} + sub compare_tuner_version { my $remoteversion=shift; debugprint "Remote data: $remoteversion"; #exit 0; if ($remoteversion ne $tunerversion) { badprint "There is a new version of MySQLTuner available ($remoteversion)"; + update_tuner_version(); return; } goodprint "You have the latest version of MySQLTuner($tunerversion)"; From 5c9f9952aa17b6133ebd1a3755a5f4e56ce4e24f Mon Sep 17 00:00:00 2001 From: DutchProgrammer Date: Thu, 24 Mar 2016 21:20:48 +0100 Subject: [PATCH 043/126] added update version functionality --- mysqltuner.pl | 113 +++++++++++++++++++++++++------------------------- 1 file changed, 57 insertions(+), 56 deletions(-) diff --git a/mysqltuner.pl b/mysqltuner.pl index 1540b75..790b9a9 100755 --- a/mysqltuner.pl +++ b/mysqltuner.pl @@ -782,14 +782,14 @@ sub select_array { debugprint "PERFORM: $req "; my @result = `$mysqlcmd $mysqllogin -Bse "$req" 2>>/dev/null`; if ($? != 0) { - badprint "failed to execute: $req"; - badprint "FAIL Execute SQL / return code: $?"; - debugprint "CMD : $mysqlcmd"; - debugprint "OPTIONS: $mysqllogin"; - debugprint `$mysqlcmd $mysqllogin -Bse "$req" 2>&1`; - exit $?; + badprint "failed to execute: $req"; + badprint "FAIL Execute SQL / return code: $?"; + debugprint "CMD : $mysqlcmd"; + debugprint "OPTIONS: $mysqllogin"; + debugprint `$mysqlcmd $mysqllogin -Bse "$req" 2>&1`; + exit $?; } - debugprint "select_array: return code : $?"; + debugprint "select_array: return code : $?"; chomp(@result); return @result; } @@ -800,14 +800,14 @@ sub select_one { debugprint "PERFORM: $req "; my $result = `$mysqlcmd $mysqllogin -Bse "$req" 2>>/dev/null`; if ($? != 0) { - badprint "failed to execute: $req"; - badprint "FAIL Execute SQL / return code: $?"; - debugprint "CMD : $mysqlcmd"; - debugprint "OPTIONS: $mysqllogin"; - debugprint `$mysqlcmd $mysqllogin -Bse "$req" 2>&1`; - exit $?; + badprint "failed to execute: $req"; + badprint "FAIL Execute SQL / return code: $?"; + debugprint "CMD : $mysqlcmd"; + debugprint "OPTIONS: $mysqllogin"; + debugprint `$mysqlcmd $mysqllogin -Bse "$req" 2>&1`; + exit $?; } - debugprint "select_array: return code : $?"; + debugprint "select_array: return code : $?"; chomp($result); return $result; } @@ -960,9 +960,9 @@ sub cve_recommendations { sub get_opened_ports { my @opened_ports=`netstat -ltn`; map { - s/.*:(\d+)\s.*$/$1/; - s/\D//g; - } @opened_ports; + s/.*:(\d+)\s.*$/$1/; + s/\D//g; + } @opened_ports; @opened_ports = sort {$a <=> $b} grep { !/^$/ } @opened_ports; debugprint Dumper \@opened_ports; return @opened_ports; @@ -977,26 +977,26 @@ sub is_open_port { } sub get_process_memory { - my $pid=shift; - return 0 unless -f "/proc/$pid/status"; - my @pdata= grep { /RSS:/ } get_file_contents "/proc/$pid/status"; - map { - s/.*RSS:\s*(\d+)\s*kB\s*$/$1*1024/ge - } @pdata; - return $pdata[0]; + my $pid=shift; + return 0 unless -f "/proc/$pid/status"; + my @pdata= grep { /RSS:/ } get_file_contents "/proc/$pid/status"; + map { + s/.*RSS:\s*(\d+)\s*kB\s*$/$1*1024/ge + } @pdata; + return $pdata[0]; } sub get_other_process_memory { - my @procs=`ps -eo pid,cmd`; - map { s/.*mysqld.*//; s/.*\[.*\].*//; s/^\s+$//g; s/.*PID.*CMD.*//; s/.*systemd.*//;} @procs; - map {s/\s*?(\d+)\s*.*/$1/g;} @procs; - remove_cr @procs; - @procs=remove_empty @procs; - my $totalMemOther=0; - map { - $totalMemOther+=get_process_memory($_); - } @procs; - return $totalMemOther; + my @procs=`ps -eo pid,cmd`; + map { s/.*mysqld.*//; s/.*\[.*\].*//; s/^\s+$//g; s/.*PID.*CMD.*//; s/.*systemd.*//;} @procs; + map {s/\s*?(\d+)\s*.*/$1/g;} @procs; + remove_cr @procs; + @procs=remove_empty @procs; + my $totalMemOther=0; + map { + $totalMemOther+=get_process_memory($_); + } @procs; + return $totalMemOther; } sub get_os_release { @@ -1020,34 +1020,34 @@ sub system_recommendations { infoprint "User process except mysqld used ". hr_bytes_rnd($omem) . " RAM."; if ( (0.15*$physical_memory) < $omem) { badprint "Other user process except mysqld used more than 15% of total physical memory ". percentage($omem, $physical_memory). "% (".hr_bytes_rnd($omem). " / ".hr_bytes_rnd($physical_memory).")"; - push( @generalrec, "Consider stopping or dedicate server for additionnal process other than mysqld." ); - push( @adjvars, "DON'T APPLY SETTINGS BECAUSE THERE IS TOO MANY PROCESSES RUNNING ON THIS SERVER. OOM KILL CAN OCCURS !" ); + push( @generalrec, "Consider stopping or dedicate server for additionnal process other than mysqld." ); + push( @adjvars, "DON'T APPLY SETTINGS BECAUSE THERE IS TOO MANY PROCESSES RUNNING ON THIS SERVER. OOM KILL CAN OCCURS !" ); } else { } #if ($omem > - #exit 0; + #exit 0; if ($opt{'maxportallowed'} > 0) { my @opened_ports=get_opened_ports; infoprint "There is ". scalar @opened_ports. " listening port(s) on this server."; if (scalar(@opened_ports) > $opt{'maxportallowed'}) { - badprint "There is too many listening ports: ". scalar(@opened_ports). " opened > ".$opt{'maxportallowed'}. "allowed."; - push( @generalrec, "Consider dedicating a server for your database installation with less services running on !" ); + badprint "There is too many listening ports: ". scalar(@opened_ports). " opened > ".$opt{'maxportallowed'}. "allowed."; + push( @generalrec, "Consider dedicating a server for your database installation with less services running on !" ); } else { - goodprint "There is less than ".$opt{'maxportallowed'}." opened ports on this server."; + goodprint "There is less than ".$opt{'maxportallowed'}." opened ports on this server."; } } foreach my $banport (@banned_ports) { - if ( is_open_port($banport) ) { - badprint "Banned port: $banport is opened.."; - push( @generalrec, "Port $banport is opened. Consider stopping program handling this port." ); - } else { - goodprint "$banport is not opened."; - } + if ( is_open_port($banport) ) { + badprint "Banned port: $banport is opened.."; + push( @generalrec, "Port $banport is opened. Consider stopping program handling this port." ); + } else { + goodprint "$banport is not opened."; + } } } @@ -1403,7 +1403,7 @@ sub check_storage_engines { $result{'Databases'}{'List'} = [@dblist]; infoprint "Status: $engines"; if ( mysql_version_ge( 5, 1, 5 ) ) { - # MySQL 5 servers can have table sizes calculated quickly from information schema + # MySQL 5 servers can have table sizes calculated quickly from information schema my @templist = select_array "SELECT ENGINE,SUM(DATA_LENGTH+INDEX_LENGTH),COUNT(ENGINE),SUM(DATA_LENGTH),SUM(INDEX_LENGTH) FROM information_schema.TABLES WHERE TABLE_SCHEMA NOT IN ('information_schema', 'performance_schema', 'mysql') AND ENGINE IS NOT NULL GROUP BY ENGINE ORDER BY ENGINE ASC;"; @@ -2584,12 +2584,12 @@ sub mariadb_threadpool { infoprint "Thread Pool Size: ".$myvar{'thread_pool_size'}. " thread(s)."; if ($myvar{'have_innodb'} eq 'YES') { - if ($myvar{'thread_pool_size'}< 16 or $myvar{'thread_pool_size'}>36) { - badprint "thread_pool_size between 16 and 36 when using InnoDB storage engine."; - push( @generalrec, "Thread pool size for InnoDB usage (".$myvar{'thread_pool_size'}.")" ); - push( @adjvars, "thread_pool_size between 16 and 36 for InnoDB usage" ); - } else { - goodprint "thread_pool_size between 16 and 36 when using InnoDB storage engine."; + if ($myvar{'thread_pool_size'}< 16 or $myvar{'thread_pool_size'}>36) { + badprint "thread_pool_size between 16 and 36 when using InnoDB storage engine."; + push( @generalrec, "Thread pool size for InnoDB usage (".$myvar{'thread_pool_size'}.")" ); + push( @adjvars, "thread_pool_size between 16 and 36 for InnoDB usage" ); + } else { + goodprint "thread_pool_size between 16 and 36 when using InnoDB storage engine."; } return; } @@ -3029,10 +3029,10 @@ sub mysql_databases { percentage( $dbinfo[3], $dbinfo[4] ) . "%"; $result{'Databases'}{ $dbinfo[0] }{'Total Size'} = $dbinfo[4]; if ($dbinfo[7]>1) { - badprint $dbinfo[7]. " differents collations for database ".$dbinfo[0]; + badprint $dbinfo[7]. " differents collations for database ".$dbinfo[0]; push(@generalrec, "Check all table collations are identical for all tables in ".$dbinfo[0]. " database."); } else { - goodprint $dbinfo[7]. " collation for ".$dbinfo[0]. " database."; + goodprint $dbinfo[7]. " collation for ".$dbinfo[0]. " database."; } if ($dbinfo[8]>1) { badprint $dbinfo[8]. " differents engines for database ".$dbinfo[0]; @@ -3296,7 +3296,7 @@ get_all_vars; # Toss variables/status into hashes get_tuning_info; # Get information about the tuning connexion validate_mysql_version; # Check current MySQL version check_architecture; # Suggest 64-bit upgrade -system_recommendations; # avoid to many service on the same host +system_recommendations; # avoid to many service on the same host check_storage_engines; # Show enabled storage engines mysql_databases; # Show informations about databases mysql_indexes; # Show informations about indexes @@ -3354,6 +3354,7 @@ You must provide the remote server's total memory when connecting to other serve (Recommended for servers with many tables) --skippassword Don't perform checks on user passwords(default: off) --checkversion Check for updates to MySQLTuner (default: don't check) + --updateversion Check for updates to MySQLTuner and update when newer version is available (default: don't check) --forcemem Amount of RAM installed in megabytes --forceswap Amount of swap memory configured in megabytes --passwordfile Path to a password file list(one password by line) From 6c280de32fb7a2df80ae087ba73af3145f07feee Mon Sep 17 00:00:00 2001 From: DutchProgrammer Date: Thu, 24 Mar 2016 22:48:07 +0100 Subject: [PATCH 044/126] Added GetOptions check if fails show help Added verbose mode --- mysqltuner.pl | 184 +++++++++++++++++++++++++++----------------------- 1 file changed, 100 insertions(+), 84 deletions(-) diff --git a/mysqltuner.pl b/mysqltuner.pl index 790b9a9..1938e8e 100755 --- a/mysqltuner.pl +++ b/mysqltuner.pl @@ -84,74 +84,81 @@ my %opt = ( "template" => 0, "json" => 0, "prettyjson" => 0, - "reportfile" => 0 + "reportfile" => 0, + "verbose" => 0 ); # Gather the options from the command line -GetOptions( - \%opt, 'nobad', 'nogood', 'noinfo', - 'debug', 'nocolor', 'forcemem=i', 'forceswap=i', - 'host=s', 'socket=s', 'port=i', 'user=s', - 'pass=s', 'skipsize', 'checkversion', 'mysqladmin=s', - 'mysqlcmd=s', 'help', 'buffers', 'skippassword', - 'passwordfile=s', 'outputfile=s', 'silent', 'dbstat', - 'json', 'prettyjson', 'idxstat', 'noask', - 'template=s', 'reportfile=s', 'cvefile=s', 'bannedports=s', - 'updateversion', 'maxportallowed=s' +my $getOptionsCheck = GetOptions( + \%opt, 'nobad', 'nogood', 'noinfo', + 'debug', 'nocolor', 'forcemem=i', 'forceswap=i', + 'host=s', 'socket=s', 'port=i', 'user=s', + 'pass=s', 'skipsize', 'checkversion', 'mysqladmin=s', + 'mysqlcmd=s', 'help', 'buffers', 'skippassword', + 'passwordfile=s', 'outputfile=s', 'silent', 'dbstat', + 'json', 'prettyjson', 'idxstat', 'noask', + 'template=s', 'reportfile=s', 'cvefile=s', 'bannedports=s', + 'updateversion', 'maxportallowed=s', 'verbose' ); +#If params are incorrect return help +if ($getOptionsCheck ne 1) { + usage(); +} + if ( defined $opt{'help'} && $opt{'help'} == 1 ) { usage(); } sub usage { - # Shown with --help option passed - print " MySQLTuner $tunerversion - MySQL High Performance Tuning Script\n" - . " Bug reports, feature requests, and downloads at http://mysqltuner.com/\n" - . " Maintained by Major Hayden (major\@mhtx.net) - Licensed under GPL\n" - . "\n" - . " Important Usage Guidelines:\n" - . " To run the script with the default options, run the script without arguments\n" - . " Allow MySQL server to run for at least 24-48 hours before trusting suggestions\n" - . " Some routines may require root level privileges (script will provide warnings)\n" - . " You must provide the remote server's total memory when connecting to other servers\n" - . "\n" - . " Connection and Authentication\n" - . " --host Connect to a remote host to perform tests (default: localhost)\n" - . " --socket Use a different socket for a local connection\n" - . " --port Port to use for connection (default: 3306)\n" - . " --user Username to use for authentication\n" - . " --pass Password to use for authentication\n" - . " --mysqladmin Path to a custom mysqladmin executable\n" - . " --mysqlcmd Path to a custom mysql executable\n" . "\n" - . " --noask Dont ask password if needed\n" . "\n" - . " Performance and Reporting Options\n" - . " --skipsize Don't enumerate tables and their types/sizes (default: on)\n" - . " (Recommended for servers with many tables)\n" - . " --skippassword Don't perform checks on user passwords(default: off)\n" - . " --checkversion Check for updates to MySQLTuner (default: don't check)\n" - . " --updateversion Check for updates to MySQLTuner and update when newer version is available (default: don't check)\n" - . " --forcemem Amount of RAM installed in megabytes\n" - . " --forceswap Amount of swap memory configured in megabytes\n" - . " --passwordfile Path to a password file list(one password by line)\n" - . " Output Options:\n" - . " --silent Don't output anything on screen\n" - . " --nogood Remove OK responses\n" - . " --nobad Remove negative/suggestion responses\n" - . " --noinfo Remove informational responses\n" - . " --debug Print debug information\n" - . " --dbstat Print database information\n" - . " --idxstat Print index information\n" - . " --bannedports Ports banned separated by comma(,)\n" - . " --maxportallowed Number of ports opened allowed on this hosts\n" - . " --cvefile CVE File for vulnerability checks\n" - . " --nocolor Don't print output in color\n" - . " --json Print result as JSON string\n" - . " --prettyjson Print result as human readable JSON\n" - . " --buffers Print global and per-thread buffer values\n" - . " --outputfile Path to a output txt file\n" . "\n" - . " --reportfile Path to a report txt file\n" . "\n" - . " --template Path to a template file\n" . "\n"; - exit 0; + # Shown with --help option passed + print " MySQLTuner $tunerversion - MySQL High Performance Tuning Script\n" + . " Bug reports, feature requests, and downloads at http://mysqltuner.com/\n" + . " Maintained by Major Hayden (major\@mhtx.net) - Licensed under GPL\n" + . "\n" + . " Important Usage Guidelines:\n" + . " To run the script with the default options, run the script without arguments\n" + . " Allow MySQL server to run for at least 24-48 hours before trusting suggestions\n" + . " Some routines may require root level privileges (script will provide warnings)\n" + . " You must provide the remote server's total memory when connecting to other servers\n" + . "\n" + . " Connection and Authentication\n" + . " --host Connect to a remote host to perform tests (default: localhost)\n" + . " --socket Use a different socket for a local connection\n" + . " --port Port to use for connection (default: 3306)\n" + . " --user Username to use for authentication\n" + . " --pass Password to use for authentication\n" + . " --mysqladmin Path to a custom mysqladmin executable\n" + . " --mysqlcmd Path to a custom mysql executable\n" . "\n" + . " --noask Dont ask password if needed\n" . "\n" + . " Performance and Reporting Options\n" + . " --skipsize Don't enumerate tables and their types/sizes (default: on)\n" + . " (Recommended for servers with many tables)\n" + . " --skippassword Don't perform checks on user passwords(default: off)\n" + . " --checkversion Check for updates to MySQLTuner (default: don't check)\n" + . " --updateversion Check for updates to MySQLTuner and update when newer version is available (default: don't check)\n" + . " --forcemem Amount of RAM installed in megabytes\n" + . " --forceswap Amount of swap memory configured in megabytes\n" + . " --passwordfile Path to a password file list(one password by line)\n" + . " Output Options:\n" + . " --silent Don't output anything on screen\n" + . " --nogood Remove OK responses\n" + . " --nobad Remove negative/suggestion responses\n" + . " --noinfo Remove informational responses\n" + . " --debug Print debug information\n" + . " --dbstat Print database information\n" + . " --idxstat Print index information\n" + . " --bannedports Ports banned separated by comma(,)\n" + . " --maxportallowed Number of ports opened allowed on this hosts\n" + . " --cvefile CVE File for vulnerability checks\n" + . " --nocolor Don't print output in color\n" + . " --json Print result as JSON string\n" + . " --prettyjson Print result as human readable JSON\n" + . " --buffers Print global and per-thread buffer values\n" + . " --outputfile Path to a output txt file\n" . "\n" + . " --reportfile Path to a report txt file\n" . "\n" + . " --template Path to a template file\n" . "\n" + . " --verbose Prints out all options (default: no verbose) \n" . "\n"; + exit 0; } my $devnull = File::Spec->devnull(); @@ -164,6 +171,15 @@ my $basic_password_files = $basic_password_files = "/usr/share/mysqltuner/basic_passwords.txt" unless -f "$basic_password_files"; +# check if we need to enable verbose mode +if ($opt{verbose}) { + $opt{checkversion} = 1; #Check for updates to MySQLTuner + $opt{dbstat} = 1; #Print database information + $opt{idxstat} = 1; #Print index information + $opt{buffers} = 1; #Print global and per-thread buffer values + $opt{cvefile} = 'vulnerabilities.csv'; #CVE File for vulnerability checks +} + # for RPM distributions $opt{cvefile} = "/usr/share/mysqltuner/vulnerabilities.csv" unless ( defined $opt{cvefile} and -f "$opt{cvefile}"); @@ -3350,34 +3366,34 @@ You must provide the remote server's total memory when connecting to other serve =head1 PERFORMANCE AND REPORTING OPTIONS - --skipsize Don't enumerate tables and their types/sizes (default: on) - (Recommended for servers with many tables) - --skippassword Don't perform checks on user passwords(default: off) - --checkversion Check for updates to MySQLTuner (default: don't check) - --updateversion Check for updates to MySQLTuner and update when newer version is available (default: don't check) - --forcemem Amount of RAM installed in megabytes - --forceswap Amount of swap memory configured in megabytes - --passwordfile Path to a password file list(one password by line) + --skipsize Don't enumerate tables and their types/sizes (default: on) + (Recommended for servers with many tables) + --skippassword Don't perform checks on user passwords(default: off) + --checkversion Check for updates to MySQLTuner (default: don't check) + --updateversion Check for updates to MySQLTuner and update when newer version is available (default: don't check) + --forcemem Amount of RAM installed in megabytes + --forceswap Amount of swap memory configured in megabytes + --passwordfile Path to a password file list(one password by line) =head1 OUTPUT OPTIONS - --silent Don't output anything on screen - --nogood Remove OK responses - --nobad Remove negative/suggestion responses - --noinfo Remove informational responses - --debug Print debug information - --dbstat Print database information - --idxstat Print index information - --bannedports Ports banned separated by comma(,) - --maxportallowed Number of ports opened allowed on this hosts - --cvefile CVE File for vulnerability checks - --nocolor Don't print output in color - --json Print result as JSON string - --buffers Print global and per-thread buffer values - --outputfile Path to a output txt file - --reportfile Path to a report txt file - --template Path to a template file - + --silent Don't output anything on screen + --nogood Remove OK responses + --nobad Remove negative/suggestion responses + --noinfo Remove informational responses + --debug Print debug information + --dbstat Print database information + --idxstat Print index information + --bannedports Ports banned separated by comma(,) + --maxportallowed Number of ports opened allowed on this hosts + --cvefile CVE File for vulnerability checks + --nocolor Don't print output in color + --json Print result as JSON string + --buffers Print global and per-thread buffer values + --outputfile Path to a output txt file + --reportfile Path to a report txt file + --template Path to a template file + --verbose Prints out all options (default: no verbose) =head1 PERLDOC You can find documentation for this module with the perldoc command. From 5fb8e3dec773462accffa58219da7e04ce5bb0c8 Mon Sep 17 00:00:00 2001 From: DutchProgrammer Date: Thu, 24 Mar 2016 23:23:31 +0100 Subject: [PATCH 045/126] fix for perl 5.10 and 5.8 --- mysqltuner.pl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/mysqltuner.pl b/mysqltuner.pl index 1938e8e..5858efc 100755 --- a/mysqltuner.pl +++ b/mysqltuner.pl @@ -461,7 +461,9 @@ sub update_tuner_version { my $receivedScripts = 0; my $httpcli =`which curl`; - foreach my $script (@scripts) { + foreach my $scriptKey (keys @scripts) { + + my $script = $scripts[$scriptKey]; chomp($httpcli); if ( 1 != 1 and defined($httpcli) and -e "$httpcli" ) { From 774dbd89147cc3b832d6ea55b57533f76238f1fd Mon Sep 17 00:00:00 2001 From: DutchProgrammer Date: Thu, 24 Mar 2016 23:31:52 +0100 Subject: [PATCH 046/126] fix for perl 5.10 and 5.8 --- mysqltuner.pl | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/mysqltuner.pl b/mysqltuner.pl index 5858efc..b2a4481 100755 --- a/mysqltuner.pl +++ b/mysqltuner.pl @@ -461,10 +461,11 @@ sub update_tuner_version { my $receivedScripts = 0; my $httpcli =`which curl`; - foreach my $scriptKey (keys @scripts) { + #foreach my $scriptKey (%{@scripts}) { + for my $scriptKey (0 .. $#scripts) { my $script = $scripts[$scriptKey]; - + chomp($httpcli); if ( 1 != 1 and defined($httpcli) and -e "$httpcli" ) { debugprint "$httpcli is available."; From 2d4afc2e82e51825a593cf459acd747567f7c1ed Mon Sep 17 00:00:00 2001 From: DutchProgrammer Date: Thu, 24 Mar 2016 23:41:30 +0100 Subject: [PATCH 047/126] fix for perl 5.10 and 5.8 --- mysqltuner.pl | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/mysqltuner.pl b/mysqltuner.pl index b2a4481..c6c20ee 100755 --- a/mysqltuner.pl +++ b/mysqltuner.pl @@ -461,10 +461,7 @@ sub update_tuner_version { my $receivedScripts = 0; my $httpcli =`which curl`; - #foreach my $scriptKey (%{@scripts}) { - for my $scriptKey (0 .. $#scripts) { - - my $script = $scripts[$scriptKey]; + foreach my $script (@scripts) { chomp($httpcli); if ( 1 != 1 and defined($httpcli) and -e "$httpcli" ) { From 5faf456d7717d66fa6306bf403a829e5d1548a8b Mon Sep 17 00:00:00 2001 From: DutchProgrammer Date: Thu, 24 Mar 2016 23:56:45 +0100 Subject: [PATCH 048/126] fix for perl 5.10 and 5.8 --- mysqltuner.pl | 434 ++++++++++++++++++++------------------------------ 1 file changed, 172 insertions(+), 262 deletions(-) diff --git a/mysqltuner.pl b/mysqltuner.pl index c6c20ee..aa71a9b 100755 --- a/mysqltuner.pl +++ b/mysqltuner.pl @@ -1,7 +1,7 @@ #!/usr/bin/env perl -# mysqltuner.pl - Version 1.6.9 +# mysqltuner.pl - Version 1.6.8 # High Performance MySQL Tuning Script -# Copyright (C) 2006-2016 Major Hayden - major@mhtx.net +# Copyright (C) 2006-2015 Major Hayden - major@mhtx.net # # For the latest updates, please visit http://mysqltuner.com/ # Git repository available at http://github.com/major/MySQLTuner-perl @@ -51,114 +51,102 @@ use Data::Dumper; $Data::Dumper::Pair = " : "; # Set up a few variables for use in the script -my $tunerversion = "1.6.9"; +my $tunerversion = "1.6.8"; my ( @adjvars, @generalrec ); # Set defaults my %opt = ( - "silent" => 0, - "nobad" => 0, - "nogood" => 0, - "noinfo" => 0, - "debug" => 0, - "nocolor" => 0, - "forcemem" => 0, - "forceswap" => 0, - "host" => 0, - "socket" => 0, - "port" => 0, - "user" => 0, - "pass" => 0, - "skipsize" => 0, - "checkversion" => 0, - "updateversion" => 0, - "buffers" => 0, - "passwordfile" => 0, - "bannedports" => '', - "maxportallowed" => 0, - "outputfile" => 0, - "dbstat" => 0, - "idxstat" => 0, - "skippassword" => 0, - "noask" => 0, - "template" => 0, - "json" => 0, - "prettyjson" => 0, - "reportfile" => 0, - "verbose" => 0 + "silent" => 0, + "nobad" => 0, + "nogood" => 0, + "noinfo" => 0, + "debug" => 0, + "nocolor" => 0, + "forcemem" => 0, + "forceswap" => 0, + "host" => 0, + "socket" => 0, + "port" => 0, + "user" => 0, + "pass" => 0, + "skipsize" => 0, + "checkversion" => 0, + "buffers" => 0, + "passwordfile" => 0, + "bannedports" => '', + "maxportallowed"=> 0, + "outputfile" => 0, + "dbstat" => 0, + "idxstat" => 0, + "skippassword" => 0, + "noask" => 0, + "template" => 0, + "json" => 0, + "reportfile" => 0 ); # Gather the options from the command line -my $getOptionsCheck = GetOptions( - \%opt, 'nobad', 'nogood', 'noinfo', - 'debug', 'nocolor', 'forcemem=i', 'forceswap=i', - 'host=s', 'socket=s', 'port=i', 'user=s', - 'pass=s', 'skipsize', 'checkversion', 'mysqladmin=s', - 'mysqlcmd=s', 'help', 'buffers', 'skippassword', - 'passwordfile=s', 'outputfile=s', 'silent', 'dbstat', - 'json', 'prettyjson', 'idxstat', 'noask', - 'template=s', 'reportfile=s', 'cvefile=s', 'bannedports=s', - 'updateversion', 'maxportallowed=s', 'verbose' +GetOptions( + \%opt, 'nobad', 'nogood', 'noinfo', + 'debug', 'nocolor', 'forcemem=i', 'forceswap=i', + 'host=s', 'socket=s', 'port=i', 'user=s', + 'pass=s', 'skipsize', 'checkversion', 'mysqladmin=s', + 'mysqlcmd=s', 'help', 'buffers', 'skippassword', + 'passwordfile=s', 'outputfile=s', 'silent', 'dbstat', 'json', + 'idxstat', 'noask', 'template=s', 'reportfile=s', 'cvefile=s', + 'bannedports=s','maxportallowed=s', ); -#If params are incorrect return help -if ($getOptionsCheck ne 1) { - usage(); -} - if ( defined $opt{'help'} && $opt{'help'} == 1 ) { usage(); } sub usage { - # Shown with --help option passed - print " MySQLTuner $tunerversion - MySQL High Performance Tuning Script\n" - . " Bug reports, feature requests, and downloads at http://mysqltuner.com/\n" - . " Maintained by Major Hayden (major\@mhtx.net) - Licensed under GPL\n" - . "\n" - . " Important Usage Guidelines:\n" - . " To run the script with the default options, run the script without arguments\n" - . " Allow MySQL server to run for at least 24-48 hours before trusting suggestions\n" - . " Some routines may require root level privileges (script will provide warnings)\n" - . " You must provide the remote server's total memory when connecting to other servers\n" - . "\n" - . " Connection and Authentication\n" - . " --host Connect to a remote host to perform tests (default: localhost)\n" - . " --socket Use a different socket for a local connection\n" - . " --port Port to use for connection (default: 3306)\n" - . " --user Username to use for authentication\n" - . " --pass Password to use for authentication\n" - . " --mysqladmin Path to a custom mysqladmin executable\n" - . " --mysqlcmd Path to a custom mysql executable\n" . "\n" - . " --noask Dont ask password if needed\n" . "\n" - . " Performance and Reporting Options\n" - . " --skipsize Don't enumerate tables and their types/sizes (default: on)\n" - . " (Recommended for servers with many tables)\n" - . " --skippassword Don't perform checks on user passwords(default: off)\n" - . " --checkversion Check for updates to MySQLTuner (default: don't check)\n" - . " --updateversion Check for updates to MySQLTuner and update when newer version is available (default: don't check)\n" - . " --forcemem Amount of RAM installed in megabytes\n" - . " --forceswap Amount of swap memory configured in megabytes\n" - . " --passwordfile Path to a password file list(one password by line)\n" - . " Output Options:\n" - . " --silent Don't output anything on screen\n" - . " --nogood Remove OK responses\n" - . " --nobad Remove negative/suggestion responses\n" - . " --noinfo Remove informational responses\n" - . " --debug Print debug information\n" - . " --dbstat Print database information\n" - . " --idxstat Print index information\n" - . " --bannedports Ports banned separated by comma(,)\n" - . " --maxportallowed Number of ports opened allowed on this hosts\n" - . " --cvefile CVE File for vulnerability checks\n" - . " --nocolor Don't print output in color\n" - . " --json Print result as JSON string\n" - . " --prettyjson Print result as human readable JSON\n" - . " --buffers Print global and per-thread buffer values\n" - . " --outputfile Path to a output txt file\n" . "\n" - . " --reportfile Path to a report txt file\n" . "\n" - . " --template Path to a template file\n" . "\n" - . " --verbose Prints out all options (default: no verbose) \n" . "\n"; - exit 0; + # Shown with --help option passed + print " MySQLTuner $tunerversion - MySQL High Performance Tuning Script\n" + . " Bug reports, feature requests, and downloads at http://mysqltuner.com/\n" + . " Maintained by Major Hayden (major\@mhtx.net) - Licensed under GPL\n" + . "\n" + . " Important Usage Guidelines:\n" + . " To run the script with the default options, run the script without arguments\n" + . " Allow MySQL server to run for at least 24-48 hours before trusting suggestions\n" + . " Some routines may require root level privileges (script will provide warnings)\n" + . " You must provide the remote server's total memory when connecting to other servers\n" + . "\n" + . " Connection and Authentication\n" + . " --host Connect to a remote host to perform tests (default: localhost)\n" + . " --socket Use a different socket for a local connection\n" + . " --port Port to use for connection (default: 3306)\n" + . " --user Username to use for authentication\n" + . " --pass Password to use for authentication\n" + . " --mysqladmin Path to a custom mysqladmin executable\n" + . " --mysqlcmd Path to a custom mysql executable\n" . "\n" + . " --noask Dont ask password if needed\n" . "\n" + . " Performance and Reporting Options\n" + . " --skipsize Don't enumerate tables and their types/sizes (default: on)\n" + . " (Recommended for servers with many tables)\n" + . " --skippassword Don't perform checks on user passwords(default: off)\n" + . " --checkversion Check for updates to MySQLTuner (default: don't check)\n" + . " --forcemem Amount of RAM installed in megabytes\n" + . " --forceswap Amount of swap memory configured in megabytes\n" + . " --passwordfile Path to a password file list(one password by line)\n" + . " Output Options:\n" + . " --silent Don't output anything on screen\n" + . " --nogood Remove OK responses\n" + . " --nobad Remove negative/suggestion responses\n" + . " --noinfo Remove informational responses\n" + . " --debug Print debug information\n" + . " --dbstat Print database information\n" + . " --idxstat Print index information\n" + . " --bannedports Ports banned separated by comma(,)\n" + . " --maxportallowed Number of ports opened allowed on this hosts\n" + . " --cvefile CVE File for vulnerability checks\n" + . " --nocolor Don't print output in color\n" + . " --json Print result as JSON string\n" + . " --buffers Print global and per-thread buffer values\n" + . " --outputfile Path to a output txt file\n" . "\n" + . " --reportfile Path to a report txt file\n" . "\n" + . " --template Path to a template file\n" . "\n"; + exit 0; } my $devnull = File::Spec->devnull(); @@ -171,15 +159,6 @@ my $basic_password_files = $basic_password_files = "/usr/share/mysqltuner/basic_passwords.txt" unless -f "$basic_password_files"; -# check if we need to enable verbose mode -if ($opt{verbose}) { - $opt{checkversion} = 1; #Check for updates to MySQLTuner - $opt{dbstat} = 1; #Print database information - $opt{idxstat} = 1; #Print index information - $opt{buffers} = 1; #Print global and per-thread buffer values - $opt{cvefile} = 'vulnerabilities.csv'; #CVE File for vulnerability checks -} - # for RPM distributions $opt{cvefile} = "/usr/share/mysqltuner/vulnerabilities.csv" unless ( defined $opt{cvefile} and -f "$opt{cvefile}"); @@ -210,7 +189,7 @@ my %result; # Functions that handle the print styles sub prettyprint { - print $_[0] . "\n" unless ($opt{'silent'} or $opt{'json'}); + print $_[0] . "\n" unless $opt{'silent'}; print $fh $_[0] . "\n" if defined($fh); } sub goodprint { prettyprint $good. " " . $_[0] unless ( $opt{nogood} == 1 ); } @@ -406,8 +385,8 @@ sub os_setup { # Checks for updates to MySQLTuner sub validate_tuner_version { - if ($opt{'checkversion'} eq 0 and $opt{'updateversion'} eq 0) { - print "\n" unless ($opt{'silent'} or $opt{'json'}); + if ($opt{checkversion} eq 0) { + print "\n"; infoprint "Skipped version check for MySQLTuner script"; return; } @@ -445,80 +424,12 @@ sub validate_tuner_version { infoprint "Unable to check for the latest MySQLTuner version"; } -# Checks for updates to MySQLTuner -sub update_tuner_version { - if ($opt{'updateversion'} eq 0) { - badprint "Skipped version update for MySQLTuner script"; - print "\n" unless ($opt{'silent'} or $opt{'json'}); - return; - } - - #use Cwd; - my $update; - my $url = "https://raw.githubusercontent.com/major/MySQLTuner-perl/master/"; - my @scripts = ("mysqltuner.pl", "basic_passwords.txt", "vulnerabilities.csv"); - my $totalScripts = scalar(keys @scripts); - my $receivedScripts = 0; - my $httpcli =`which curl`; - - foreach my $script (@scripts) { - - chomp($httpcli); - if ( 1 != 1 and defined($httpcli) and -e "$httpcli" ) { - debugprint "$httpcli is available."; - - debugprint "$httpcli --connect-timeout 5 -silent '$url$script' > $script"; - $update = `$httpcli --connect-timeout 5 -silent '$url$script' > $script`; - chomp($update); - debugprint "$script updated: $update"; - - if ( -s $script eq 0) { - badprint "Couldn't update $script"; - } else { - ++$receivedScripts; - debugprint "$script updated: $update"; - } - } else { - - $httpcli=`which wget`; - chomp($httpcli); - if ( defined($httpcli) and -e "$httpcli" ) { - debugprint "$httpcli is available."; - - debugprint "$httpcli -qe timestamping=off -T 5 -O $script '$url$script'"; - $update = `$httpcli -qe timestamping=off -T 5 -O $script '$url$script'`; - chomp($update); - - if ( -s $script eq 0) { - badprint "Couldn't update $script"; - } else { - ++$receivedScripts; - debugprint "$script updated: $update"; - } - - } else { - debugprint "curl and wget are not available."; - infoprint "Unable to check for the latest MySQLTuner version"; - } - } - } - - if ($receivedScripts eq $totalScripts) { - goodprint "Successfully updated MySQLTuner script"; - } else { - badprint "Couldn't update MySQLTuner script"; - } - - exit 0; -} - sub compare_tuner_version { my $remoteversion=shift; debugprint "Remote data: $remoteversion"; #exit 0; if ($remoteversion ne $tunerversion) { badprint "There is a new version of MySQLTuner available ($remoteversion)"; - update_tuner_version(); return; } goodprint "You have the latest version of MySQLTuner($tunerversion)"; @@ -798,14 +709,14 @@ sub select_array { debugprint "PERFORM: $req "; my @result = `$mysqlcmd $mysqllogin -Bse "$req" 2>>/dev/null`; if ($? != 0) { - badprint "failed to execute: $req"; - badprint "FAIL Execute SQL / return code: $?"; - debugprint "CMD : $mysqlcmd"; - debugprint "OPTIONS: $mysqllogin"; - debugprint `$mysqlcmd $mysqllogin -Bse "$req" 2>&1`; - exit $?; + badprint "failed to execute: $req"; + badprint "FAIL Execute SQL / return code: $?"; + debugprint "CMD : $mysqlcmd"; + debugprint "OPTIONS: $mysqllogin"; + debugprint `$mysqlcmd $mysqllogin -Bse "$req" 2>&1`; + exit $?; } - debugprint "select_array: return code : $?"; + debugprint "select_array: return code : $?"; chomp(@result); return @result; } @@ -816,14 +727,14 @@ sub select_one { debugprint "PERFORM: $req "; my $result = `$mysqlcmd $mysqllogin -Bse "$req" 2>>/dev/null`; if ($? != 0) { - badprint "failed to execute: $req"; - badprint "FAIL Execute SQL / return code: $?"; - debugprint "CMD : $mysqlcmd"; - debugprint "OPTIONS: $mysqllogin"; - debugprint `$mysqlcmd $mysqllogin -Bse "$req" 2>&1`; - exit $?; + badprint "failed to execute: $req"; + badprint "FAIL Execute SQL / return code: $?"; + debugprint "CMD : $mysqlcmd"; + debugprint "OPTIONS: $mysqllogin"; + debugprint `$mysqlcmd $mysqllogin -Bse "$req" 2>&1`; + exit $?; } - debugprint "select_array: return code : $?"; + debugprint "select_array: return code : $?"; chomp($result); return $result; } @@ -976,9 +887,9 @@ sub cve_recommendations { sub get_opened_ports { my @opened_ports=`netstat -ltn`; map { - s/.*:(\d+)\s.*$/$1/; - s/\D//g; - } @opened_ports; + s/.*:(\d+)\s.*$/$1/; + s/\D//g; + } @opened_ports; @opened_ports = sort {$a <=> $b} grep { !/^$/ } @opened_ports; debugprint Dumper \@opened_ports; return @opened_ports; @@ -993,26 +904,26 @@ sub is_open_port { } sub get_process_memory { - my $pid=shift; - return 0 unless -f "/proc/$pid/status"; - my @pdata= grep { /RSS:/ } get_file_contents "/proc/$pid/status"; - map { - s/.*RSS:\s*(\d+)\s*kB\s*$/$1*1024/ge - } @pdata; - return $pdata[0]; + my $pid=shift; + return 0 unless -f "/proc/$pid/status"; + my @pdata= grep { /RSS:/ } get_file_contents "/proc/$pid/status"; + map { + s/.*RSS:\s*(\d+)\s*kB\s*$/$1*1024/ge + } @pdata; + return $pdata[0]; } sub get_other_process_memory { - my @procs=`ps -eo pid,cmd`; - map { s/.*mysqld.*//; s/.*\[.*\].*//; s/^\s+$//g; s/.*PID.*CMD.*//; s/.*systemd.*//;} @procs; - map {s/\s*?(\d+)\s*.*/$1/g;} @procs; - remove_cr @procs; - @procs=remove_empty @procs; - my $totalMemOther=0; - map { - $totalMemOther+=get_process_memory($_); - } @procs; - return $totalMemOther; + my @procs=`ps -eo pid,cmd`; + map { s/.*mysqld.*//; s/.*\[.*\].*//; s/^\s+$//g; s/.*PID.*CMD.*//; s/.*systemd.*//;} @procs; + map {s/\s*?(\d+)\s*.*/$1/g;} @procs; + remove_cr @procs; + @procs=remove_empty @procs; + my $totalMemOther=0; + map { + $totalMemOther+=get_process_memory($_); + } @procs; + return $totalMemOther; } sub get_os_release { @@ -1036,34 +947,34 @@ sub system_recommendations { infoprint "User process except mysqld used ". hr_bytes_rnd($omem) . " RAM."; if ( (0.15*$physical_memory) < $omem) { badprint "Other user process except mysqld used more than 15% of total physical memory ". percentage($omem, $physical_memory). "% (".hr_bytes_rnd($omem). " / ".hr_bytes_rnd($physical_memory).")"; - push( @generalrec, "Consider stopping or dedicate server for additionnal process other than mysqld." ); - push( @adjvars, "DON'T APPLY SETTINGS BECAUSE THERE IS TOO MANY PROCESSES RUNNING ON THIS SERVER. OOM KILL CAN OCCURS !" ); + push( @generalrec, "Consider stopping or dedicate server for additionnal process other than mysqld." ); + push( @adjvars, "DON'T APPLY SETTINGS BECAUSE THERE IS TOO MANY PROCESSES RUNNING ON THIS SERVER. OOM KILL CAN OCCURS !" ); } else { } #if ($omem > - #exit 0; + #exit 0; if ($opt{'maxportallowed'} > 0) { my @opened_ports=get_opened_ports; infoprint "There is ". scalar @opened_ports. " listening port(s) on this server."; if (scalar(@opened_ports) > $opt{'maxportallowed'}) { - badprint "There is too many listening ports: ". scalar(@opened_ports). " opened > ".$opt{'maxportallowed'}. "allowed."; - push( @generalrec, "Consider dedicating a server for your database installation with less services running on !" ); + badprint "There is too many listening ports: ". scalar(@opened_ports) " opened > ".$opt{'maxportallowed'}. "allowed."; + push( @generalrec, "Consider dedicating a server for your database installation with less services running on !" ); } else { - goodprint "There is less than ".$opt{'maxportallowed'}." opened ports on this server."; + goodprint "There is less than ".$opt{'maxportallowed'}." opened ports on this server."; } } foreach my $banport (@banned_ports) { - if ( is_open_port($banport) ) { - badprint "Banned port: $banport is opened.."; - push( @generalrec, "Port $banport is opened. Consider stopping program handling this port." ); - } else { - goodprint "$banport is not opened."; - } + if ( is_open_port($banport) ) { + badprint "Banned port: $banport is opened.."; + push( @generalrec, "Port $banport is opened. Consider stopping program handling this port." ); + } else { + goodprint "$banport is not opened."; + } } } @@ -1419,7 +1330,7 @@ sub check_storage_engines { $result{'Databases'}{'List'} = [@dblist]; infoprint "Status: $engines"; if ( mysql_version_ge( 5, 1, 5 ) ) { - # MySQL 5 servers can have table sizes calculated quickly from information schema + # MySQL 5 servers can have table sizes calculated quickly from information schema my @templist = select_array "SELECT ENGINE,SUM(DATA_LENGTH+INDEX_LENGTH),COUNT(ENGINE),SUM(DATA_LENGTH),SUM(INDEX_LENGTH) FROM information_schema.TABLES WHERE TABLE_SCHEMA NOT IN ('information_schema', 'performance_schema', 'mysql') AND ENGINE IS NOT NULL GROUP BY ENGINE ORDER BY ENGINE ASC;"; @@ -2600,12 +2511,12 @@ sub mariadb_threadpool { infoprint "Thread Pool Size: ".$myvar{'thread_pool_size'}. " thread(s)."; if ($myvar{'have_innodb'} eq 'YES') { - if ($myvar{'thread_pool_size'}< 16 or $myvar{'thread_pool_size'}>36) { - badprint "thread_pool_size between 16 and 36 when using InnoDB storage engine."; - push( @generalrec, "Thread pool size for InnoDB usage (".$myvar{'thread_pool_size'}.")" ); - push( @adjvars, "thread_pool_size between 16 and 36 for InnoDB usage" ); - } else { - goodprint "thread_pool_size between 16 and 36 when using InnoDB storage engine."; + if ($myvar{'thread_pool_size'}< 16 or $myvar{'thread_pool_size'}>36) { + badprint "thread_pool_size between 16 and 36 when using InnoDB storage engine."; + push( @generalrec, "Thread pool size for InnoDB usage (".$myvar{'thread_pool_size'}.")" ); + push( @adjvars, "thread_pool_size between 16 and 36 for InnoDB usage" ); + } else { + goodprint "thread_pool_size between 16 and 36 when using InnoDB storage engine."; } return; } @@ -2628,9 +2539,9 @@ sub mysqsl_pfs { # Performance Schema unless ( defined($myvar{'performance_schema'}) and $myvar{'performance_schema'} eq 'ON' ) { infoprint "Performance schema is disabled."; - } else { - infoprint "Performance schema is enabled."; } + + infoprint "Performance schema is enabled."; } @@ -2996,7 +2907,7 @@ sub mysql_databases { $result{'Databases'}{'All databases'}{'Index Pct'} = percentage( $totaldbinfo[2], $totaldbinfo[3] ) . "%"; $result{'Databases'}{'All databases'}{'Total Size'} = $totaldbinfo[3]; - print "\n" unless ($opt{'silent'} or $opt{'json'}); + print "\n"; foreach (@dblist) { chomp($_); if ( $_ eq "information_schema" @@ -3045,10 +2956,10 @@ sub mysql_databases { percentage( $dbinfo[3], $dbinfo[4] ) . "%"; $result{'Databases'}{ $dbinfo[0] }{'Total Size'} = $dbinfo[4]; if ($dbinfo[7]>1) { - badprint $dbinfo[7]. " differents collations for database ".$dbinfo[0]; + badprint $dbinfo[7]. " differents collations for database ".$dbinfo[0]; push(@generalrec, "Check all table collations are identical for all tables in ".$dbinfo[0]. " database."); } else { - goodprint $dbinfo[7]. " collation for ".$dbinfo[0]. " database."; + goodprint $dbinfo[7]. " collation for ".$dbinfo[0]. " database."; } if ($dbinfo[8]>1) { badprint $dbinfo[8]. " differents engines for database ".$dbinfo[0]; @@ -3297,7 +3208,7 @@ sub dump_result { exit 1; } my $json = JSON->new->allow_nonref; - print $json->utf8(1)->pretty(($opt{'prettyjson'} ? 1 : 0))->encode(\%result); + print JSON->new->utf8(1)->pretty(1)->encode(%result); } } @@ -3312,7 +3223,7 @@ get_all_vars; # Toss variables/status into hashes get_tuning_info; # Get information about the tuning connexion validate_mysql_version; # Check current MySQL version check_architecture; # Suggest 64-bit upgrade -system_recommendations; # avoid to many service on the same host +system_recommendations; # avoid to many service on the same host check_storage_engines; # Show enabled storage engines mysql_databases; # Show informations about databases mysql_indexes; # Show informations about indexes @@ -3366,34 +3277,33 @@ You must provide the remote server's total memory when connecting to other serve =head1 PERFORMANCE AND REPORTING OPTIONS - --skipsize Don't enumerate tables and their types/sizes (default: on) - (Recommended for servers with many tables) - --skippassword Don't perform checks on user passwords(default: off) - --checkversion Check for updates to MySQLTuner (default: don't check) - --updateversion Check for updates to MySQLTuner and update when newer version is available (default: don't check) - --forcemem Amount of RAM installed in megabytes - --forceswap Amount of swap memory configured in megabytes - --passwordfile Path to a password file list(one password by line) + --skipsize Don't enumerate tables and their types/sizes (default: on) + (Recommended for servers with many tables) + --skippassword Don't perform checks on user passwords(default: off) + --checkversion Check for updates to MySQLTuner (default: don't check) + --forcemem Amount of RAM installed in megabytes + --forceswap Amount of swap memory configured in megabytes + --passwordfile Path to a password file list(one password by line) =head1 OUTPUT OPTIONS - --silent Don't output anything on screen - --nogood Remove OK responses - --nobad Remove negative/suggestion responses - --noinfo Remove informational responses - --debug Print debug information - --dbstat Print database information - --idxstat Print index information - --bannedports Ports banned separated by comma(,) - --maxportallowed Number of ports opened allowed on this hosts - --cvefile CVE File for vulnerability checks - --nocolor Don't print output in color - --json Print result as JSON string - --buffers Print global and per-thread buffer values - --outputfile Path to a output txt file - --reportfile Path to a report txt file - --template Path to a template file - --verbose Prints out all options (default: no verbose) + --silent Don't output anything on screen + --nogood Remove OK responses + --nobad Remove negative/suggestion responses + --noinfo Remove informational responses + --debug Print debug information + --dbstat Print database information + --idxstat Print index information + --bannedports Ports banned separated by comma(,) + --maxportallowed Number of ports opened allowed on this hosts + --cvefile CVE File for vulnerability checks + --nocolor Don't print output in color + --json Print result as JSON string + --buffers Print global and per-thread buffer values + --outputfile Path to a output txt file + --reportfile Path to a report txt file + --template Path to a template file + =head1 PERLDOC You can find documentation for this module with the perldoc command. From 031898858b24fb1b4bb8852b57d75561caaa8fb6 Mon Sep 17 00:00:00 2001 From: DutchProgrammer Date: Thu, 24 Mar 2016 23:58:48 +0100 Subject: [PATCH 049/126] fix for perl 5.10 and 5.8 --- mysqltuner.pl | 434 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 262 insertions(+), 172 deletions(-) diff --git a/mysqltuner.pl b/mysqltuner.pl index aa71a9b..5d489af 100755 --- a/mysqltuner.pl +++ b/mysqltuner.pl @@ -1,7 +1,7 @@ #!/usr/bin/env perl -# mysqltuner.pl - Version 1.6.8 +# mysqltuner.pl - Version 1.6.9 # High Performance MySQL Tuning Script -# Copyright (C) 2006-2015 Major Hayden - major@mhtx.net +# Copyright (C) 2006-2016 Major Hayden - major@mhtx.net # # For the latest updates, please visit http://mysqltuner.com/ # Git repository available at http://github.com/major/MySQLTuner-perl @@ -51,102 +51,114 @@ use Data::Dumper; $Data::Dumper::Pair = " : "; # Set up a few variables for use in the script -my $tunerversion = "1.6.8"; +my $tunerversion = "1.6.9"; my ( @adjvars, @generalrec ); # Set defaults my %opt = ( - "silent" => 0, - "nobad" => 0, - "nogood" => 0, - "noinfo" => 0, - "debug" => 0, - "nocolor" => 0, - "forcemem" => 0, - "forceswap" => 0, - "host" => 0, - "socket" => 0, - "port" => 0, - "user" => 0, - "pass" => 0, - "skipsize" => 0, - "checkversion" => 0, - "buffers" => 0, - "passwordfile" => 0, - "bannedports" => '', - "maxportallowed"=> 0, - "outputfile" => 0, - "dbstat" => 0, - "idxstat" => 0, - "skippassword" => 0, - "noask" => 0, - "template" => 0, - "json" => 0, - "reportfile" => 0 + "silent" => 0, + "nobad" => 0, + "nogood" => 0, + "noinfo" => 0, + "debug" => 0, + "nocolor" => 0, + "forcemem" => 0, + "forceswap" => 0, + "host" => 0, + "socket" => 0, + "port" => 0, + "user" => 0, + "pass" => 0, + "skipsize" => 0, + "checkversion" => 0, + "updateversion" => 0, + "buffers" => 0, + "passwordfile" => 0, + "bannedports" => '', + "maxportallowed" => 0, + "outputfile" => 0, + "dbstat" => 0, + "idxstat" => 0, + "skippassword" => 0, + "noask" => 0, + "template" => 0, + "json" => 0, + "prettyjson" => 0, + "reportfile" => 0, + "verbose" => 0 ); # Gather the options from the command line -GetOptions( - \%opt, 'nobad', 'nogood', 'noinfo', - 'debug', 'nocolor', 'forcemem=i', 'forceswap=i', - 'host=s', 'socket=s', 'port=i', 'user=s', - 'pass=s', 'skipsize', 'checkversion', 'mysqladmin=s', - 'mysqlcmd=s', 'help', 'buffers', 'skippassword', - 'passwordfile=s', 'outputfile=s', 'silent', 'dbstat', 'json', - 'idxstat', 'noask', 'template=s', 'reportfile=s', 'cvefile=s', - 'bannedports=s','maxportallowed=s', +my $getOptionsCheck = GetOptions( + \%opt, 'nobad', 'nogood', 'noinfo', + 'debug', 'nocolor', 'forcemem=i', 'forceswap=i', + 'host=s', 'socket=s', 'port=i', 'user=s', + 'pass=s', 'skipsize', 'checkversion', 'mysqladmin=s', + 'mysqlcmd=s', 'help', 'buffers', 'skippassword', + 'passwordfile=s', 'outputfile=s', 'silent', 'dbstat', + 'json', 'prettyjson', 'idxstat', 'noask', + 'template=s', 'reportfile=s', 'cvefile=s', 'bannedports=s', + 'updateversion', 'maxportallowed=s', 'verbose' ); +#If params are incorrect return help +if ($getOptionsCheck ne 1) { + usage(); +} + if ( defined $opt{'help'} && $opt{'help'} == 1 ) { usage(); } sub usage { - # Shown with --help option passed - print " MySQLTuner $tunerversion - MySQL High Performance Tuning Script\n" - . " Bug reports, feature requests, and downloads at http://mysqltuner.com/\n" - . " Maintained by Major Hayden (major\@mhtx.net) - Licensed under GPL\n" - . "\n" - . " Important Usage Guidelines:\n" - . " To run the script with the default options, run the script without arguments\n" - . " Allow MySQL server to run for at least 24-48 hours before trusting suggestions\n" - . " Some routines may require root level privileges (script will provide warnings)\n" - . " You must provide the remote server's total memory when connecting to other servers\n" - . "\n" - . " Connection and Authentication\n" - . " --host Connect to a remote host to perform tests (default: localhost)\n" - . " --socket Use a different socket for a local connection\n" - . " --port Port to use for connection (default: 3306)\n" - . " --user Username to use for authentication\n" - . " --pass Password to use for authentication\n" - . " --mysqladmin Path to a custom mysqladmin executable\n" - . " --mysqlcmd Path to a custom mysql executable\n" . "\n" - . " --noask Dont ask password if needed\n" . "\n" - . " Performance and Reporting Options\n" - . " --skipsize Don't enumerate tables and their types/sizes (default: on)\n" - . " (Recommended for servers with many tables)\n" - . " --skippassword Don't perform checks on user passwords(default: off)\n" - . " --checkversion Check for updates to MySQLTuner (default: don't check)\n" - . " --forcemem Amount of RAM installed in megabytes\n" - . " --forceswap Amount of swap memory configured in megabytes\n" - . " --passwordfile Path to a password file list(one password by line)\n" - . " Output Options:\n" - . " --silent Don't output anything on screen\n" - . " --nogood Remove OK responses\n" - . " --nobad Remove negative/suggestion responses\n" - . " --noinfo Remove informational responses\n" - . " --debug Print debug information\n" - . " --dbstat Print database information\n" - . " --idxstat Print index information\n" - . " --bannedports Ports banned separated by comma(,)\n" - . " --maxportallowed Number of ports opened allowed on this hosts\n" - . " --cvefile CVE File for vulnerability checks\n" - . " --nocolor Don't print output in color\n" - . " --json Print result as JSON string\n" - . " --buffers Print global and per-thread buffer values\n" - . " --outputfile Path to a output txt file\n" . "\n" - . " --reportfile Path to a report txt file\n" . "\n" - . " --template Path to a template file\n" . "\n"; - exit 0; + # Shown with --help option passed + print " MySQLTuner $tunerversion - MySQL High Performance Tuning Script\n" + . " Bug reports, feature requests, and downloads at http://mysqltuner.com/\n" + . " Maintained by Major Hayden (major\@mhtx.net) - Licensed under GPL\n" + . "\n" + . " Important Usage Guidelines:\n" + . " To run the script with the default options, run the script without arguments\n" + . " Allow MySQL server to run for at least 24-48 hours before trusting suggestions\n" + . " Some routines may require root level privileges (script will provide warnings)\n" + . " You must provide the remote server's total memory when connecting to other servers\n" + . "\n" + . " Connection and Authentication\n" + . " --host Connect to a remote host to perform tests (default: localhost)\n" + . " --socket Use a different socket for a local connection\n" + . " --port Port to use for connection (default: 3306)\n" + . " --user Username to use for authentication\n" + . " --pass Password to use for authentication\n" + . " --mysqladmin Path to a custom mysqladmin executable\n" + . " --mysqlcmd Path to a custom mysql executable\n" . "\n" + . " --noask Dont ask password if needed\n" . "\n" + . " Performance and Reporting Options\n" + . " --skipsize Don't enumerate tables and their types/sizes (default: on)\n" + . " (Recommended for servers with many tables)\n" + . " --skippassword Don't perform checks on user passwords(default: off)\n" + . " --checkversion Check for updates to MySQLTuner (default: don't check)\n" + . " --updateversion Check for updates to MySQLTuner and update when newer version is available (default: don't check)\n" + . " --forcemem Amount of RAM installed in megabytes\n" + . " --forceswap Amount of swap memory configured in megabytes\n" + . " --passwordfile Path to a password file list(one password by line)\n" + . " Output Options:\n" + . " --silent Don't output anything on screen\n" + . " --nogood Remove OK responses\n" + . " --nobad Remove negative/suggestion responses\n" + . " --noinfo Remove informational responses\n" + . " --debug Print debug information\n" + . " --dbstat Print database information\n" + . " --idxstat Print index information\n" + . " --bannedports Ports banned separated by comma(,)\n" + . " --maxportallowed Number of ports opened allowed on this hosts\n" + . " --cvefile CVE File for vulnerability checks\n" + . " --nocolor Don't print output in color\n" + . " --json Print result as JSON string\n" + . " --prettyjson Print result as human readable JSON\n" + . " --buffers Print global and per-thread buffer values\n" + . " --outputfile Path to a output txt file\n" . "\n" + . " --reportfile Path to a report txt file\n" . "\n" + . " --template Path to a template file\n" . "\n" + . " --verbose Prints out all options (default: no verbose) \n" . "\n"; + exit 0; } my $devnull = File::Spec->devnull(); @@ -159,6 +171,15 @@ my $basic_password_files = $basic_password_files = "/usr/share/mysqltuner/basic_passwords.txt" unless -f "$basic_password_files"; +# check if we need to enable verbose mode +if ($opt{verbose}) { + $opt{checkversion} = 1; #Check for updates to MySQLTuner + $opt{dbstat} = 1; #Print database information + $opt{idxstat} = 1; #Print index information + $opt{buffers} = 1; #Print global and per-thread buffer values + $opt{cvefile} = 'vulnerabilities.csv'; #CVE File for vulnerability checks +} + # for RPM distributions $opt{cvefile} = "/usr/share/mysqltuner/vulnerabilities.csv" unless ( defined $opt{cvefile} and -f "$opt{cvefile}"); @@ -189,7 +210,7 @@ my %result; # Functions that handle the print styles sub prettyprint { - print $_[0] . "\n" unless $opt{'silent'}; + print $_[0] . "\n" unless ($opt{'silent'} or $opt{'json'}); print $fh $_[0] . "\n" if defined($fh); } sub goodprint { prettyprint $good. " " . $_[0] unless ( $opt{nogood} == 1 ); } @@ -385,8 +406,8 @@ sub os_setup { # Checks for updates to MySQLTuner sub validate_tuner_version { - if ($opt{checkversion} eq 0) { - print "\n"; + if ($opt{'checkversion'} eq 0 and $opt{'updateversion'} eq 0) { + print "\n" unless ($opt{'silent'} or $opt{'json'}); infoprint "Skipped version check for MySQLTuner script"; return; } @@ -424,12 +445,80 @@ sub validate_tuner_version { infoprint "Unable to check for the latest MySQLTuner version"; } +# Checks for updates to MySQLTuner +sub update_tuner_version { + if ($opt{'updateversion'} eq 0) { + badprint "Skipped version update for MySQLTuner script"; + print "\n" unless ($opt{'silent'} or $opt{'json'}); + return; + } + + #use Cwd; + my $update; + my $url = "https://raw.githubusercontent.com/major/MySQLTuner-perl/master/"; + my @scripts = ("mysqltuner.pl", "basic_passwords.txt", "vulnerabilities.csv"); + my $totalScripts = scalar(@scripts); + my $receivedScripts = 0; + my $httpcli =`which curl`; + + foreach my $script (@scripts) { + + chomp($httpcli); + if ( 1 != 1 and defined($httpcli) and -e "$httpcli" ) { + debugprint "$httpcli is available."; + + debugprint "$httpcli --connect-timeout 5 -silent '$url$script' > $script"; + $update = `$httpcli --connect-timeout 5 -silent '$url$script' > $script`; + chomp($update); + debugprint "$script updated: $update"; + + if ( -s $script eq 0) { + badprint "Couldn't update $script"; + } else { + ++$receivedScripts; + debugprint "$script updated: $update"; + } + } else { + + $httpcli=`which wget`; + chomp($httpcli); + if ( defined($httpcli) and -e "$httpcli" ) { + debugprint "$httpcli is available."; + + debugprint "$httpcli -qe timestamping=off -T 5 -O $script '$url$script'"; + $update = `$httpcli -qe timestamping=off -T 5 -O $script '$url$script'`; + chomp($update); + + if ( -s $script eq 0) { + badprint "Couldn't update $script"; + } else { + ++$receivedScripts; + debugprint "$script updated: $update"; + } + + } else { + debugprint "curl and wget are not available."; + infoprint "Unable to check for the latest MySQLTuner version"; + } + } + } + + if ($receivedScripts eq $totalScripts) { + goodprint "Successfully updated MySQLTuner script"; + } else { + badprint "Couldn't update MySQLTuner script"; + } + + exit 0; +} + sub compare_tuner_version { my $remoteversion=shift; debugprint "Remote data: $remoteversion"; #exit 0; if ($remoteversion ne $tunerversion) { badprint "There is a new version of MySQLTuner available ($remoteversion)"; + update_tuner_version(); return; } goodprint "You have the latest version of MySQLTuner($tunerversion)"; @@ -709,14 +798,14 @@ sub select_array { debugprint "PERFORM: $req "; my @result = `$mysqlcmd $mysqllogin -Bse "$req" 2>>/dev/null`; if ($? != 0) { - badprint "failed to execute: $req"; - badprint "FAIL Execute SQL / return code: $?"; - debugprint "CMD : $mysqlcmd"; - debugprint "OPTIONS: $mysqllogin"; - debugprint `$mysqlcmd $mysqllogin -Bse "$req" 2>&1`; - exit $?; + badprint "failed to execute: $req"; + badprint "FAIL Execute SQL / return code: $?"; + debugprint "CMD : $mysqlcmd"; + debugprint "OPTIONS: $mysqllogin"; + debugprint `$mysqlcmd $mysqllogin -Bse "$req" 2>&1`; + exit $?; } - debugprint "select_array: return code : $?"; + debugprint "select_array: return code : $?"; chomp(@result); return @result; } @@ -727,14 +816,14 @@ sub select_one { debugprint "PERFORM: $req "; my $result = `$mysqlcmd $mysqllogin -Bse "$req" 2>>/dev/null`; if ($? != 0) { - badprint "failed to execute: $req"; - badprint "FAIL Execute SQL / return code: $?"; - debugprint "CMD : $mysqlcmd"; - debugprint "OPTIONS: $mysqllogin"; - debugprint `$mysqlcmd $mysqllogin -Bse "$req" 2>&1`; - exit $?; + badprint "failed to execute: $req"; + badprint "FAIL Execute SQL / return code: $?"; + debugprint "CMD : $mysqlcmd"; + debugprint "OPTIONS: $mysqllogin"; + debugprint `$mysqlcmd $mysqllogin -Bse "$req" 2>&1`; + exit $?; } - debugprint "select_array: return code : $?"; + debugprint "select_array: return code : $?"; chomp($result); return $result; } @@ -887,9 +976,9 @@ sub cve_recommendations { sub get_opened_ports { my @opened_ports=`netstat -ltn`; map { - s/.*:(\d+)\s.*$/$1/; - s/\D//g; - } @opened_ports; + s/.*:(\d+)\s.*$/$1/; + s/\D//g; + } @opened_ports; @opened_ports = sort {$a <=> $b} grep { !/^$/ } @opened_ports; debugprint Dumper \@opened_ports; return @opened_ports; @@ -904,26 +993,26 @@ sub is_open_port { } sub get_process_memory { - my $pid=shift; - return 0 unless -f "/proc/$pid/status"; - my @pdata= grep { /RSS:/ } get_file_contents "/proc/$pid/status"; - map { - s/.*RSS:\s*(\d+)\s*kB\s*$/$1*1024/ge - } @pdata; - return $pdata[0]; + my $pid=shift; + return 0 unless -f "/proc/$pid/status"; + my @pdata= grep { /RSS:/ } get_file_contents "/proc/$pid/status"; + map { + s/.*RSS:\s*(\d+)\s*kB\s*$/$1*1024/ge + } @pdata; + return $pdata[0]; } sub get_other_process_memory { - my @procs=`ps -eo pid,cmd`; - map { s/.*mysqld.*//; s/.*\[.*\].*//; s/^\s+$//g; s/.*PID.*CMD.*//; s/.*systemd.*//;} @procs; - map {s/\s*?(\d+)\s*.*/$1/g;} @procs; - remove_cr @procs; - @procs=remove_empty @procs; - my $totalMemOther=0; - map { - $totalMemOther+=get_process_memory($_); - } @procs; - return $totalMemOther; + my @procs=`ps -eo pid,cmd`; + map { s/.*mysqld.*//; s/.*\[.*\].*//; s/^\s+$//g; s/.*PID.*CMD.*//; s/.*systemd.*//;} @procs; + map {s/\s*?(\d+)\s*.*/$1/g;} @procs; + remove_cr @procs; + @procs=remove_empty @procs; + my $totalMemOther=0; + map { + $totalMemOther+=get_process_memory($_); + } @procs; + return $totalMemOther; } sub get_os_release { @@ -947,34 +1036,34 @@ sub system_recommendations { infoprint "User process except mysqld used ". hr_bytes_rnd($omem) . " RAM."; if ( (0.15*$physical_memory) < $omem) { badprint "Other user process except mysqld used more than 15% of total physical memory ". percentage($omem, $physical_memory). "% (".hr_bytes_rnd($omem). " / ".hr_bytes_rnd($physical_memory).")"; - push( @generalrec, "Consider stopping or dedicate server for additionnal process other than mysqld." ); - push( @adjvars, "DON'T APPLY SETTINGS BECAUSE THERE IS TOO MANY PROCESSES RUNNING ON THIS SERVER. OOM KILL CAN OCCURS !" ); + push( @generalrec, "Consider stopping or dedicate server for additionnal process other than mysqld." ); + push( @adjvars, "DON'T APPLY SETTINGS BECAUSE THERE IS TOO MANY PROCESSES RUNNING ON THIS SERVER. OOM KILL CAN OCCURS !" ); } else { } #if ($omem > - #exit 0; + #exit 0; if ($opt{'maxportallowed'} > 0) { my @opened_ports=get_opened_ports; infoprint "There is ". scalar @opened_ports. " listening port(s) on this server."; if (scalar(@opened_ports) > $opt{'maxportallowed'}) { - badprint "There is too many listening ports: ". scalar(@opened_ports) " opened > ".$opt{'maxportallowed'}. "allowed."; - push( @generalrec, "Consider dedicating a server for your database installation with less services running on !" ); + badprint "There is too many listening ports: ". scalar(@opened_ports). " opened > ".$opt{'maxportallowed'}. "allowed."; + push( @generalrec, "Consider dedicating a server for your database installation with less services running on !" ); } else { - goodprint "There is less than ".$opt{'maxportallowed'}." opened ports on this server."; + goodprint "There is less than ".$opt{'maxportallowed'}." opened ports on this server."; } } foreach my $banport (@banned_ports) { - if ( is_open_port($banport) ) { - badprint "Banned port: $banport is opened.."; - push( @generalrec, "Port $banport is opened. Consider stopping program handling this port." ); - } else { - goodprint "$banport is not opened."; - } + if ( is_open_port($banport) ) { + badprint "Banned port: $banport is opened.."; + push( @generalrec, "Port $banport is opened. Consider stopping program handling this port." ); + } else { + goodprint "$banport is not opened."; + } } } @@ -1330,7 +1419,7 @@ sub check_storage_engines { $result{'Databases'}{'List'} = [@dblist]; infoprint "Status: $engines"; if ( mysql_version_ge( 5, 1, 5 ) ) { - # MySQL 5 servers can have table sizes calculated quickly from information schema + # MySQL 5 servers can have table sizes calculated quickly from information schema my @templist = select_array "SELECT ENGINE,SUM(DATA_LENGTH+INDEX_LENGTH),COUNT(ENGINE),SUM(DATA_LENGTH),SUM(INDEX_LENGTH) FROM information_schema.TABLES WHERE TABLE_SCHEMA NOT IN ('information_schema', 'performance_schema', 'mysql') AND ENGINE IS NOT NULL GROUP BY ENGINE ORDER BY ENGINE ASC;"; @@ -2511,12 +2600,12 @@ sub mariadb_threadpool { infoprint "Thread Pool Size: ".$myvar{'thread_pool_size'}. " thread(s)."; if ($myvar{'have_innodb'} eq 'YES') { - if ($myvar{'thread_pool_size'}< 16 or $myvar{'thread_pool_size'}>36) { - badprint "thread_pool_size between 16 and 36 when using InnoDB storage engine."; - push( @generalrec, "Thread pool size for InnoDB usage (".$myvar{'thread_pool_size'}.")" ); - push( @adjvars, "thread_pool_size between 16 and 36 for InnoDB usage" ); - } else { - goodprint "thread_pool_size between 16 and 36 when using InnoDB storage engine."; + if ($myvar{'thread_pool_size'}< 16 or $myvar{'thread_pool_size'}>36) { + badprint "thread_pool_size between 16 and 36 when using InnoDB storage engine."; + push( @generalrec, "Thread pool size for InnoDB usage (".$myvar{'thread_pool_size'}.")" ); + push( @adjvars, "thread_pool_size between 16 and 36 for InnoDB usage" ); + } else { + goodprint "thread_pool_size between 16 and 36 when using InnoDB storage engine."; } return; } @@ -2539,9 +2628,9 @@ sub mysqsl_pfs { # Performance Schema unless ( defined($myvar{'performance_schema'}) and $myvar{'performance_schema'} eq 'ON' ) { infoprint "Performance schema is disabled."; + } else { + infoprint "Performance schema is enabled."; } - - infoprint "Performance schema is enabled."; } @@ -2907,7 +2996,7 @@ sub mysql_databases { $result{'Databases'}{'All databases'}{'Index Pct'} = percentage( $totaldbinfo[2], $totaldbinfo[3] ) . "%"; $result{'Databases'}{'All databases'}{'Total Size'} = $totaldbinfo[3]; - print "\n"; + print "\n" unless ($opt{'silent'} or $opt{'json'}); foreach (@dblist) { chomp($_); if ( $_ eq "information_schema" @@ -2956,10 +3045,10 @@ sub mysql_databases { percentage( $dbinfo[3], $dbinfo[4] ) . "%"; $result{'Databases'}{ $dbinfo[0] }{'Total Size'} = $dbinfo[4]; if ($dbinfo[7]>1) { - badprint $dbinfo[7]. " differents collations for database ".$dbinfo[0]; + badprint $dbinfo[7]. " differents collations for database ".$dbinfo[0]; push(@generalrec, "Check all table collations are identical for all tables in ".$dbinfo[0]. " database."); } else { - goodprint $dbinfo[7]. " collation for ".$dbinfo[0]. " database."; + goodprint $dbinfo[7]. " collation for ".$dbinfo[0]. " database."; } if ($dbinfo[8]>1) { badprint $dbinfo[8]. " differents engines for database ".$dbinfo[0]; @@ -3208,7 +3297,7 @@ sub dump_result { exit 1; } my $json = JSON->new->allow_nonref; - print JSON->new->utf8(1)->pretty(1)->encode(%result); + print $json->utf8(1)->pretty(($opt{'prettyjson'} ? 1 : 0))->encode(\%result); } } @@ -3223,7 +3312,7 @@ get_all_vars; # Toss variables/status into hashes get_tuning_info; # Get information about the tuning connexion validate_mysql_version; # Check current MySQL version check_architecture; # Suggest 64-bit upgrade -system_recommendations; # avoid to many service on the same host +system_recommendations; # avoid to many service on the same host check_storage_engines; # Show enabled storage engines mysql_databases; # Show informations about databases mysql_indexes; # Show informations about indexes @@ -3277,33 +3366,34 @@ You must provide the remote server's total memory when connecting to other serve =head1 PERFORMANCE AND REPORTING OPTIONS - --skipsize Don't enumerate tables and their types/sizes (default: on) - (Recommended for servers with many tables) - --skippassword Don't perform checks on user passwords(default: off) - --checkversion Check for updates to MySQLTuner (default: don't check) - --forcemem Amount of RAM installed in megabytes - --forceswap Amount of swap memory configured in megabytes - --passwordfile Path to a password file list(one password by line) + --skipsize Don't enumerate tables and their types/sizes (default: on) + (Recommended for servers with many tables) + --skippassword Don't perform checks on user passwords(default: off) + --checkversion Check for updates to MySQLTuner (default: don't check) + --updateversion Check for updates to MySQLTuner and update when newer version is available (default: don't check) + --forcemem Amount of RAM installed in megabytes + --forceswap Amount of swap memory configured in megabytes + --passwordfile Path to a password file list(one password by line) =head1 OUTPUT OPTIONS - --silent Don't output anything on screen - --nogood Remove OK responses - --nobad Remove negative/suggestion responses - --noinfo Remove informational responses - --debug Print debug information - --dbstat Print database information - --idxstat Print index information - --bannedports Ports banned separated by comma(,) - --maxportallowed Number of ports opened allowed on this hosts - --cvefile CVE File for vulnerability checks - --nocolor Don't print output in color - --json Print result as JSON string - --buffers Print global and per-thread buffer values - --outputfile Path to a output txt file - --reportfile Path to a report txt file - --template Path to a template file - + --silent Don't output anything on screen + --nogood Remove OK responses + --nobad Remove negative/suggestion responses + --noinfo Remove informational responses + --debug Print debug information + --dbstat Print database information + --idxstat Print index information + --bannedports Ports banned separated by comma(,) + --maxportallowed Number of ports opened allowed on this hosts + --cvefile CVE File for vulnerability checks + --nocolor Don't print output in color + --json Print result as JSON string + --buffers Print global and per-thread buffer values + --outputfile Path to a output txt file + --reportfile Path to a report txt file + --template Path to a template file + --verbose Prints out all options (default: no verbose) =head1 PERLDOC You can find documentation for this module with the perldoc command. From c9ebae1e26f80242e14e4a13dd3e9e23cbc92ab3 Mon Sep 17 00:00:00 2001 From: root Date: Fri, 25 Mar 2016 11:57:35 +0100 Subject: [PATCH 050/126] #166 removing test when plugin is unix_socket or win_socket Support for bug https://bugs.mysql.com/bug.php?id=80860 --- mysqltuner.pl | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/mysqltuner.pl b/mysqltuner.pl index 5d489af..254338c 100755 --- a/mysqltuner.pl +++ b/mysqltuner.pl @@ -803,7 +803,7 @@ sub select_array { debugprint "CMD : $mysqlcmd"; debugprint "OPTIONS: $mysqllogin"; debugprint `$mysqlcmd $mysqllogin -Bse "$req" 2>&1`; - exit $?; + #exit $?; } debugprint "select_array: return code : $?"; chomp(@result); @@ -821,7 +821,7 @@ sub select_one { debugprint "CMD : $mysqlcmd"; debugprint "OPTIONS: $mysqllogin"; debugprint `$mysqlcmd $mysqllogin -Bse "$req" 2>&1`; - exit $?; + #exit $?; } debugprint "select_array: return code : $?"; chomp($result); @@ -1066,7 +1066,7 @@ sub system_recommendations { } } } - + sub security_recommendations { prettyprint "\n-------- Security Recommendations -------------------------------------------"; @@ -1102,7 +1102,7 @@ sub security_recommendations { # Looking for Empty Password @mysqlstatlist = select_array -"SELECT CONCAT(user, '\@', host) FROM mysql.user WHERE $PASS_COLUMN_NAME = '' OR $PASS_COLUMN_NAME IS NULL"; +"SELECT CONCAT(user, '\@', host) FROM mysql.user WHERE ($PASS_COLUMN_NAME = '' OR $PASS_COLUMN_NAME IS NULL) AND plugin NOT IN ('unix_socket', 'win_socket')"; if (@mysqlstatlist) { foreach my $line ( sort @mysqlstatlist ) { chomp($line); @@ -1116,6 +1116,14 @@ sub security_recommendations { goodprint "All database users have passwords assigned"; } + if (mysql_version_ge(5,7)) { + my $valPlugin=select_one("select count(*) from information_schema.plugins where PLUGIN_NAME='validate_password' AND PLUGIN_STATUS='ACTIVE'"); + if ($valPlugin>=1) { + infoprint "Bug #80860 MySQL 5.7: Avoid testing password when validate_password is activated"; + return; + } + } + # Looking for User with user/ uppercase /capitalise user as password @mysqlstatlist = select_array "SELECT CONCAT(user, '\@', host) FROM mysql.user WHERE CAST($PASS_COLUMN_NAME as Binary) = PASSWORD(user) OR CAST($PASS_COLUMN_NAME as Binary) = PASSWORD(UPPER(user)) OR CAST($PASS_COLUMN_NAME as Binary) = PASSWORD(UPPER(LEFT(User, 1)) + SUBSTRING(User, 2, LENGTH(User)))"; From 3f8ca6493eab4121939896be252385771a283a02 Mon Sep 17 00:00:00 2001 From: root Date: Fri, 25 Mar 2016 14:32:15 +0100 Subject: [PATCH 051/126] Adding disk space and inode control other fs mountpoint #165 --- mysqltuner.pl | 46 +++++++++++++++++++++++++++++++++++++++------- 1 file changed, 39 insertions(+), 7 deletions(-) diff --git a/mysqltuner.pl b/mysqltuner.pl index 254338c..79d187a 100755 --- a/mysqltuner.pl +++ b/mysqltuner.pl @@ -1021,6 +1021,40 @@ sub get_os_release { remove_cr @info_release; return $info_release[0]; } + +sub get_fs_info() { + my @sinfo=`df -P | grep '%'`; + shift @sinfo; + my @iinfo=`df -Pi| grep '%'`; + shift @iinfo; + map { + s/.*\s(\d+)%\s+(.*)/$1\t$2/g + } @sinfo; + foreach my $info (@sinfo) { + if ($info =~ /(\d+)\t(.*)/) { + if ($1 > 85) { + badprint "mount point $2 is using $1 % total space"; + push(@generalrec, "Add some space to $2 mountpoint.") + } else { + infoprint "mount point $2 is using $1 % of total space"; + } + } + } + + map { + s/.*\s(\d+)%\s+(.*)/$1\t$2/g + } @iinfo; + foreach my $info (@iinfo) { + if ($info =~ /(\d+)\t(.*)/) { + if ($1 > 85) { + badprint "mount point $2 is using $1 % of max allowed inodes"; + push(@generalrec, "Cleanup files from $2 mountpoint or reformat you filesystem.") + } else { + infoprint "mount point $2 is using $1 % of max allowed inodes"; + } + } + } +} sub system_recommendations { prettyprint "\n-------- System Linux Recommendations ---------------------------------------"; my $os = `uname`; @@ -1035,17 +1069,13 @@ sub system_recommendations { my $omem=get_other_process_memory; infoprint "User process except mysqld used ". hr_bytes_rnd($omem) . " RAM."; if ( (0.15*$physical_memory) < $omem) { - badprint "Other user process except mysqld used more than 15% of total physical memory ". percentage($omem, $physical_memory). "% (".hr_bytes_rnd($omem). " / ".hr_bytes_rnd($physical_memory).")"; + badprint "Other user process except mysqld used more than 15% of total physical memory ". percentage($omem, $physical_memory). "% (".hr_bytes_rnd($omem). " / ".hr_bytes_rnd($physical_memory).")"; push( @generalrec, "Consider stopping or dedicate server for additionnal process other than mysqld." ); - push( @adjvars, "DON'T APPLY SETTINGS BECAUSE THERE IS TOO MANY PROCESSES RUNNING ON THIS SERVER. OOM KILL CAN OCCURS !" ); - - + push( @adjvars, "DON'T APPLY SETTINGS BECAUSE THERE IS TOO MANY PROCESSES RUNNING ON THIS SERVER. OOM KILL CAN OCCURS !" ); } else { + infoprint "Other user process except mysqld used less than 15% of total physical memory ". percentage($omem, $physical_memory). "% (".hr_bytes_rnd($omem). " / ".hr_bytes_rnd($physical_memory).")"; } - #if ($omem > - #exit 0; - if ($opt{'maxportallowed'} > 0) { my @opened_ports=get_opened_ports; infoprint "There is ". scalar @opened_ports. " listening port(s) on this server."; @@ -1065,6 +1095,8 @@ sub system_recommendations { goodprint "$banport is not opened."; } } + + get_fs_info; } sub security_recommendations { From a010416b930d4cf8757d0620cf632ecf078eb644 Mon Sep 17 00:00:00 2001 From: root Date: Fri, 25 Mar 2016 16:22:07 +0100 Subject: [PATCH 052/126] Adding lot of system indicators #165 --- mysqltuner.pl | 69 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 67 insertions(+), 2 deletions(-) diff --git a/mysqltuner.pl b/mysqltuner.pl index 79d187a..11bbc7a 100755 --- a/mysqltuner.pl +++ b/mysqltuner.pl @@ -1055,6 +1055,72 @@ sub get_fs_info() { } } } +sub is_virtual_machine() { + my $isVm=`grep -Ec '^flags.*\ hypervisor\ ' /proc/cpuinfo`; + return ($isVm==0?1:0); +} + + +sub infocmd { + my $cmd="@_"; + debugprint "CMD: $cmd"; + my @result=`$cmd`; + remove_cr @result; + for my $l (@result) { + infoprint "$l"; + } +} +sub infocmd_tab { + my $cmd="@_"; + debugprint "CMD: $cmd"; + my @result=`$cmd`; + remove_cr @result; + for my $l (@result) { + infoprint "\t$l"; + } +} +sub infocmd_one { + my $cmd="@_"; + my @result=`$cmd`; + remove_cr @result; + return join ', ' ,@result; +} + +sub get_system_info() +{ +infoprint get_os_release; +if (is_virtual_machine) { + infoprint "Machine type : Virtual machine"; + } else { + infoprint "Machine type : Physical machine"; +} + +`ping -c 1 google.com &>/dev/null`; +my $isConnected=$?; +if ($? == 0) { + infoprint "Internet : Connected"; +} else { + badprint "Internet : Disconnected"; + } +infoprint "Operating System Type : " . infocmd_one "uname -o"; +infoprint "Kernel Release : ". infocmd_one "uname -r"; +infoprint "Hostname : $ENV{'HOSTNAME'}"; +infoprint "Network Cards : "; +infocmd_tab "ifconfig| grep -A1 mtu"; +infoprint "Internal IP : ". infocmd_one "hostname -I"; +infoprint "External IP : ". infocmd_one "curl -s ipecho.net/plain" if $isConnected==0; +badprint "External IP : Can't check because of Internet connectivity" if $isConnected!=0; +infoprint "Name Servers : ". infocmd_one "grep 'nameserver' /etc/resolv.conf \| awk '{print \$2}'"; +infoprint "Logged In users : "; +infocmd_tab "who"; +infoprint "Ram Usages :"; +infocmd_tab "free -h | grep -v +"; +infoprint "Load Average : "; +infocmd_tab "top -n 1 -b | grep 'load average:'"; + +#infoprint "System Uptime Days/(HH:MM) : `uptime | awk '{print $3,$4}' | cut -f1 -d,`"; +} + sub system_recommendations { prettyprint "\n-------- System Linux Recommendations ---------------------------------------"; my $os = `uname`; @@ -1064,8 +1130,7 @@ sub system_recommendations { } prettyprint "Look for related Linux system recommandations"; #prettyprint '-'x78; - infoprint get_os_release; - + get_system_info(); my $omem=get_other_process_memory; infoprint "User process except mysqld used ". hr_bytes_rnd($omem) . " RAM."; if ( (0.15*$physical_memory) < $omem) { From ae48a655713398af01b1eaa870860bf3dfbcb62b Mon Sep 17 00:00:00 2001 From: zhil Date: Mon, 28 Mar 2016 16:31:52 +0300 Subject: [PATCH 053/126] Update README.md fixed parameter --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f431b20..c16c7fa 100644 --- a/README.md +++ b/README.md @@ -62,7 +62,7 @@ __Usage:__ Minimal usage locally __Usage:__ Minimal usage remotely - perl mysqltuner.pl --host targetDNS_IP --user admin_user --password admin_password + perl mysqltuner.pl --host targetDNS_IP --user admin_user --pass admin_password __Usage:__ Enable maximum output information around MySQL/MariaDb without debugging From 94ee62a6e0b2d988d7e7e4d41ed7e9aa91bc07a9 Mon Sep 17 00:00:00 2001 From: amq Date: Tue, 29 Mar 2016 01:27:41 +0200 Subject: [PATCH 054/126] Fix grammar --- mysqltuner.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysqltuner.pl b/mysqltuner.pl index 11bbc7a..cfa0d18 100755 --- a/mysqltuner.pl +++ b/mysqltuner.pl @@ -1136,7 +1136,7 @@ sub system_recommendations { if ( (0.15*$physical_memory) < $omem) { badprint "Other user process except mysqld used more than 15% of total physical memory ". percentage($omem, $physical_memory). "% (".hr_bytes_rnd($omem). " / ".hr_bytes_rnd($physical_memory).")"; push( @generalrec, "Consider stopping or dedicate server for additionnal process other than mysqld." ); - push( @adjvars, "DON'T APPLY SETTINGS BECAUSE THERE IS TOO MANY PROCESSES RUNNING ON THIS SERVER. OOM KILL CAN OCCURS !" ); + push( @adjvars, "DON'T APPLY SETTINGS BECAUSE THERE ARE TOO MANY PROCESSES RUNNING ON THIS SERVER. OOM KILL CAN OCCUR!" ); } else { infoprint "Other user process except mysqld used less than 15% of total physical memory ". percentage($omem, $physical_memory). "% (".hr_bytes_rnd($omem). " / ".hr_bytes_rnd($physical_memory).")"; } From cb5a1c528ee3bea5d5288ef61b5547300d697479 Mon Sep 17 00:00:00 2001 From: Robert Milasan Date: Tue, 29 Mar 2016 09:51:48 +0200 Subject: [PATCH 055/126] Fix is_virtual_machine function return, drop ENV{'HOSTNAME'} for hostname cmd, some machines don't have HOSTNAME set --- mysqltuner.pl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/mysqltuner.pl b/mysqltuner.pl index 11bbc7a..b1a5816 100755 --- a/mysqltuner.pl +++ b/mysqltuner.pl @@ -1057,7 +1057,7 @@ sub get_fs_info() { } sub is_virtual_machine() { my $isVm=`grep -Ec '^flags.*\ hypervisor\ ' /proc/cpuinfo`; - return ($isVm==0?1:0); + return ($isVm==0?0:1); } @@ -1102,9 +1102,9 @@ if ($? == 0) { } else { badprint "Internet : Disconnected"; } -infoprint "Operating System Type : " . infocmd_one "uname -o"; +infoprint "Operating System Type : ". infocmd_one "uname -o"; infoprint "Kernel Release : ". infocmd_one "uname -r"; -infoprint "Hostname : $ENV{'HOSTNAME'}"; +infoprint "Hostname : ". infocmd_one "hostname"; infoprint "Network Cards : "; infocmd_tab "ifconfig| grep -A1 mtu"; infoprint "Internal IP : ". infocmd_one "hostname -I"; @@ -1113,7 +1113,7 @@ badprint "External IP : Can't check because of Internet connectivity" infoprint "Name Servers : ". infocmd_one "grep 'nameserver' /etc/resolv.conf \| awk '{print \$2}'"; infoprint "Logged In users : "; infocmd_tab "who"; -infoprint "Ram Usages :"; +infoprint "Ram Usages : "; infocmd_tab "free -h | grep -v +"; infoprint "Load Average : "; infocmd_tab "top -n 1 -b | grep 'load average:'"; From 35ebd1cb5879d9c53dfb6ac295f63d9cb8f78e37 Mon Sep 17 00:00:00 2001 From: root Date: Tue, 29 Mar 2016 14:09:25 +0200 Subject: [PATCH 056/126] Update USAGE.md --- USAGE.md | 51 +++++++++++++++++++++++++++------------------------ 1 file changed, 27 insertions(+), 24 deletions(-) diff --git a/USAGE.md b/USAGE.md index ddaf5fc..c5fbc92 100644 --- a/USAGE.md +++ b/USAGE.md @@ -1,6 +1,6 @@ # NAME - MySQLTuner 1.6.4 - MySQL High Performance Tuning Script + MySQLTuner 1.6.8 - MySQL High Performance Tuning Script # IMPORTANT USAGE GUIDELINES @@ -21,32 +21,35 @@ You must provide the remote server's total memory when connecting to other serve # PERFORMANCE AND REPORTING OPTIONS - --skipsize Don't enumerate tables and their types/sizes (default: on) - (Recommended for servers with many tables) - --skippassword Don't perform checks on user passwords(default: off) - --checkversion Check for updates to MySQLTuner (default: don't check) - --forcemem Amount of RAM installed in megabytes - --forceswap Amount of swap memory configured in megabytes - --passwordfile Path to a password file list(one password by line) + --skipsize Don't enumerate tables and their types/sizes (default: on) + (Recommended for servers with many tables) + --skippassword Don't perform checks on user passwords(default: off) + --checkversion Check for updates to MySQLTuner (default: don't check) + --updateversion Check for updates to MySQLTuner and update when newer version is available (default: don't check) + --forcemem Amount of RAM installed in megabytes + --forceswap Amount of swap memory configured in megabytes + --passwordfile Path to a password file list(one password by line) # OUTPUT OPTIONS - --silent Don't output anything on screen - --nogood Remove OK responses - --nobad Remove negative/suggestion responses - --noinfo Remove informational responses - --debug Print debug information - --dbstat Print database information - --idxstat Print index information - --cvefile CVE File for vulnerability checks - --nocolor Don't print output in color - --json Print result as JSON string - --buffers Print global and per-thread buffer values - --outputfile Path to a output txt file - --reportfile Path to a report txt file - --template Path to a template file - -# PERLDOC + --silent Don't output anything on screen + --nogood Remove OK responses + --nobad Remove negative/suggestion responses + --noinfo Remove informational responses + --debug Print debug information + --dbstat Print database information + --idxstat Print index information + --bannedports Ports banned separated by comma(,) + --maxportallowed Number of ports opened allowed on this hosts + --cvefile CVE File for vulnerability checks + --nocolor Don't print output in color + --json Print result as JSON string + --buffers Print global and per-thread buffer values + --outputfile Path to a output txt file + --reportfile Path to a report txt file + --template Path to a template file + --verbose Prints out all options (default: no verbose) + =head1 PERLDOC You can find documentation for this module with the perldoc command. From d3a2d83d7d23887afabbd452368b04d842e82323 Mon Sep 17 00:00:00 2001 From: root Date: Tue, 29 Mar 2016 14:22:45 +0200 Subject: [PATCH 057/126] Just a simple perltidy to cleanup ident in the code. --- mysqltuner.pl | 1283 ++++++++++++++++++++++++++++--------------------- 1 file changed, 727 insertions(+), 556 deletions(-) diff --git a/mysqltuner.pl b/mysqltuner.pl index 93335e9..6a24c33 100755 --- a/mysqltuner.pl +++ b/mysqltuner.pl @@ -73,9 +73,9 @@ my %opt = ( "checkversion" => 0, "updateversion" => 0, "buffers" => 0, - "passwordfile" => 0, + "passwordfile" => 0, "bannedports" => '', - "maxportallowed" => 0, + "maxportallowed" => 0, "outputfile" => 0, "dbstat" => 0, "idxstat" => 0, @@ -90,75 +90,85 @@ my %opt = ( # Gather the options from the command line my $getOptionsCheck = GetOptions( - \%opt, 'nobad', 'nogood', 'noinfo', - 'debug', 'nocolor', 'forcemem=i', 'forceswap=i', - 'host=s', 'socket=s', 'port=i', 'user=s', - 'pass=s', 'skipsize', 'checkversion', 'mysqladmin=s', - 'mysqlcmd=s', 'help', 'buffers', 'skippassword', - 'passwordfile=s', 'outputfile=s', 'silent', 'dbstat', - 'json', 'prettyjson', 'idxstat', 'noask', - 'template=s', 'reportfile=s', 'cvefile=s', 'bannedports=s', - 'updateversion', 'maxportallowed=s', 'verbose' + \%opt, 'nobad', + 'nogood', 'noinfo', + 'debug', 'nocolor', + 'forcemem=i', 'forceswap=i', + 'host=s', 'socket=s', + 'port=i', 'user=s', + 'pass=s', 'skipsize', + 'checkversion', 'mysqladmin=s', + 'mysqlcmd=s', 'help', + 'buffers', 'skippassword', + 'passwordfile=s', 'outputfile=s', + 'silent', 'dbstat', + 'json', 'prettyjson', + 'idxstat', 'noask', + 'template=s', 'reportfile=s', + 'cvefile=s', 'bannedports=s', + 'updateversion', 'maxportallowed=s', + 'verbose' ); #If params are incorrect return help -if ($getOptionsCheck ne 1) { - usage(); +if ( $getOptionsCheck ne 1 ) { + usage(); } if ( defined $opt{'help'} && $opt{'help'} == 1 ) { usage(); } sub usage { - # Shown with --help option passed - print " MySQLTuner $tunerversion - MySQL High Performance Tuning Script\n" - . " Bug reports, feature requests, and downloads at http://mysqltuner.com/\n" - . " Maintained by Major Hayden (major\@mhtx.net) - Licensed under GPL\n" - . "\n" - . " Important Usage Guidelines:\n" - . " To run the script with the default options, run the script without arguments\n" - . " Allow MySQL server to run for at least 24-48 hours before trusting suggestions\n" - . " Some routines may require root level privileges (script will provide warnings)\n" - . " You must provide the remote server's total memory when connecting to other servers\n" - . "\n" - . " Connection and Authentication\n" - . " --host Connect to a remote host to perform tests (default: localhost)\n" - . " --socket Use a different socket for a local connection\n" - . " --port Port to use for connection (default: 3306)\n" - . " --user Username to use for authentication\n" - . " --pass Password to use for authentication\n" - . " --mysqladmin Path to a custom mysqladmin executable\n" - . " --mysqlcmd Path to a custom mysql executable\n" . "\n" - . " --noask Dont ask password if needed\n" . "\n" - . " Performance and Reporting Options\n" - . " --skipsize Don't enumerate tables and their types/sizes (default: on)\n" - . " (Recommended for servers with many tables)\n" - . " --skippassword Don't perform checks on user passwords(default: off)\n" - . " --checkversion Check for updates to MySQLTuner (default: don't check)\n" - . " --updateversion Check for updates to MySQLTuner and update when newer version is available (default: don't check)\n" - . " --forcemem Amount of RAM installed in megabytes\n" - . " --forceswap Amount of swap memory configured in megabytes\n" - . " --passwordfile Path to a password file list(one password by line)\n" - . " Output Options:\n" - . " --silent Don't output anything on screen\n" - . " --nogood Remove OK responses\n" - . " --nobad Remove negative/suggestion responses\n" - . " --noinfo Remove informational responses\n" - . " --debug Print debug information\n" - . " --dbstat Print database information\n" - . " --idxstat Print index information\n" - . " --bannedports Ports banned separated by comma(,)\n" - . " --maxportallowed Number of ports opened allowed on this hosts\n" - . " --cvefile CVE File for vulnerability checks\n" - . " --nocolor Don't print output in color\n" - . " --json Print result as JSON string\n" - . " --prettyjson Print result as human readable JSON\n" - . " --buffers Print global and per-thread buffer values\n" - . " --outputfile Path to a output txt file\n" . "\n" - . " --reportfile Path to a report txt file\n" . "\n" - . " --template Path to a template file\n" . "\n" - . " --verbose Prints out all options (default: no verbose) \n" . "\n"; - exit 0; + # Shown with --help option passed + print " MySQLTuner $tunerversion - MySQL High Performance Tuning Script\n" + . " Bug reports, feature requests, and downloads at http://mysqltuner.com/\n" + . " Maintained by Major Hayden (major\@mhtx.net) - Licensed under GPL\n" + . "\n" + . " Important Usage Guidelines:\n" + . " To run the script with the default options, run the script without arguments\n" + . " Allow MySQL server to run for at least 24-48 hours before trusting suggestions\n" + . " Some routines may require root level privileges (script will provide warnings)\n" + . " You must provide the remote server's total memory when connecting to other servers\n" + . "\n" + . " Connection and Authentication\n" + . " --host Connect to a remote host to perform tests (default: localhost)\n" + . " --socket Use a different socket for a local connection\n" + . " --port Port to use for connection (default: 3306)\n" + . " --user Username to use for authentication\n" + . " --pass Password to use for authentication\n" + . " --mysqladmin Path to a custom mysqladmin executable\n" + . " --mysqlcmd Path to a custom mysql executable\n" . "\n" + . " --noask Dont ask password if needed\n" . "\n" + . " Performance and Reporting Options\n" + . " --skipsize Don't enumerate tables and their types/sizes (default: on)\n" + . " (Recommended for servers with many tables)\n" + . " --skippassword Don't perform checks on user passwords(default: off)\n" + . " --checkversion Check for updates to MySQLTuner (default: don't check)\n" + . " --updateversion Check for updates to MySQLTuner and update when newer version is available (default: don't check)\n" + . " --forcemem Amount of RAM installed in megabytes\n" + . " --forceswap Amount of swap memory configured in megabytes\n" + . " --passwordfile Path to a password file list(one password by line)\n" + . " Output Options:\n" + . " --silent Don't output anything on screen\n" + . " --nogood Remove OK responses\n" + . " --nobad Remove negative/suggestion responses\n" + . " --noinfo Remove informational responses\n" + . " --debug Print debug information\n" + . " --dbstat Print database information\n" + . " --idxstat Print index information\n" + . " --bannedports Ports banned separated by comma(,)\n" + . " --maxportallowed Number of ports opened allowed on this hosts\n" + . " --cvefile CVE File for vulnerability checks\n" + . " --nocolor Don't print output in color\n" + . " --json Print result as JSON string\n" + . " --prettyjson Print result as human readable JSON\n" + . " --buffers Print global and per-thread buffer values\n" + . " --outputfile Path to a output txt file\n" . "\n" + . " --reportfile Path to a report txt file\n" . "\n" + . " --template Path to a template file\n" . "\n" + . " --verbose Prints out all options (default: no verbose) \n" + . "\n"; + exit 0; } my $devnull = File::Spec->devnull(); @@ -172,22 +182,22 @@ $basic_password_files = "/usr/share/mysqltuner/basic_passwords.txt" unless -f "$basic_password_files"; # check if we need to enable verbose mode -if ($opt{verbose}) { - $opt{checkversion} = 1; #Check for updates to MySQLTuner - $opt{dbstat} = 1; #Print database information - $opt{idxstat} = 1; #Print index information - $opt{buffers} = 1; #Print global and per-thread buffer values - $opt{cvefile} = 'vulnerabilities.csv'; #CVE File for vulnerability checks +if ( $opt{verbose} ) { + $opt{checkversion} = 1; #Check for updates to MySQLTuner + $opt{dbstat} = 1; #Print database information + $opt{idxstat} = 1; #Print index information + $opt{buffers} = 1; #Print global and per-thread buffer values + $opt{cvefile} = 'vulnerabilities.csv'; #CVE File for vulnerability checks } # for RPM distributions $opt{cvefile} = "/usr/share/mysqltuner/vulnerabilities.csv" - unless ( defined $opt{cvefile} and -f "$opt{cvefile}"); -$opt{cvefile} ='' unless -f "$opt{cvefile}"; -$opt{cvefile} ='./vulnerabilities.csv' if -f './vulnerabilities.csv'; + unless ( defined $opt{cvefile} and -f "$opt{cvefile}" ); +$opt{cvefile} = '' unless -f "$opt{cvefile}"; +$opt{cvefile} = './vulnerabilities.csv' if -f './vulnerabilities.csv'; -$opt{'bannedports'}='' unless defined($opt{'bannedports'}); -my @banned_ports=split ',', $opt{'bannedports'}; +$opt{'bannedports'} = '' unless defined( $opt{'bannedports'} ); +my @banned_ports = split ',', $opt{'bannedports'}; # my $outputfile = undef; @@ -210,13 +220,14 @@ my %result; # Functions that handle the print styles sub prettyprint { - print $_[0] . "\n" unless ($opt{'silent'} or $opt{'json'}); + print $_[0] . "\n" unless ( $opt{'silent'} or $opt{'json'} ); print $fh $_[0] . "\n" if defined($fh); } sub goodprint { prettyprint $good. " " . $_[0] unless ( $opt{nogood} == 1 ); } sub infoprint { prettyprint $info. " " . $_[0] unless ( $opt{noinfo} == 1 ); } sub badprint { prettyprint $bad. " " . $_[0] unless ( $opt{nobad} == 1 ); } sub debugprint { prettyprint $deb. " " . $_[0] unless ( $opt{debug} == 0 ); } + sub redwrap { return ( $opt{nocolor} == 0 ) ? "\e[0;31m" . $_[0] . "\e[0m" : $_[0]; } @@ -312,6 +323,7 @@ sub pretty_uptime { my ( $physical_memory, $swap_memory, $duflags ); sub os_setup { + sub memerror { badprint "Unable to determine total memory/swap; use '--forcemem' and '--forceswap'"; @@ -328,8 +340,7 @@ sub os_setup { } else { $swap_memory = 0; - badprint - "Assuming 0 MB of swap space (use --forceswap to specify)"; + badprint "Assuming 0 MB of swap space (use --forceswap to specify)"; } } else { @@ -382,12 +393,12 @@ sub os_setup { chomp($swap_memory); $swap_memory = $swap_memory * 1024 * 1024; } - elsif( $os =~ /windows/i ) { + elsif ( $os =~ /windows/i ) { $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; - $swap_memory = - `wmic OS get FreeVirtualMemory | perl -ne "chomp; print if /[0-9]+/;"` + $swap_memory = +`wmic OS get FreeVirtualMemory | perl -ne "chomp; print if /[0-9]+/;"` or memerror; } } @@ -406,135 +417,152 @@ sub os_setup { # Checks for updates to MySQLTuner sub validate_tuner_version { - if ($opt{'checkversion'} eq 0 and $opt{'updateversion'} eq 0) { - print "\n" unless ($opt{'silent'} or $opt{'json'}); - infoprint "Skipped version check for MySQLTuner script"; - return; - } + if ( $opt{'checkversion'} eq 0 and $opt{'updateversion'} eq 0 ) { + print "\n" unless ( $opt{'silent'} or $opt{'json'} ); + infoprint "Skipped version check for MySQLTuner script"; + return; + } - my $update; - my $url = "https://raw.githubusercontent.com/major/MySQLTuner-perl/master/mysqltuner.pl"; - my $httpcli=`which curl`; - chomp($httpcli); - if ( 1 != 1 and defined($httpcli) and -e "$httpcli" ) { - debugprint "$httpcli is available."; + my $update; + my $url = +"https://raw.githubusercontent.com/major/MySQLTuner-perl/master/mysqltuner.pl"; + my $httpcli = `which curl`; + chomp($httpcli); + if ( 1 != 1 and defined($httpcli) and -e "$httpcli" ) { + debugprint "$httpcli is available."; - debugprint "$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); - debugprint "VERSION: $update"; + debugprint +"$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); + debugprint "VERSION: $update"; + compare_tuner_version($update); + return; + } - compare_tuner_version($update); - return; - } + $httpcli = `which wget`; + chomp($httpcli); + if ( defined($httpcli) and -e "$httpcli" ) { + debugprint "$httpcli is available."; - - $httpcli=`which wget`; - chomp($httpcli); - if ( defined($httpcli) and -e "$httpcli" ) { - debugprint "$httpcli is available."; - - debugprint "$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); - compare_tuner_version($update); - return; - } - debugprint "curl and wget are not available."; - infoprint "Unable to check for the latest MySQLTuner version"; + debugprint +"$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); + compare_tuner_version($update); + return; + } + debugprint "curl and wget are not available."; + infoprint "Unable to check for the latest MySQLTuner version"; } # Checks for updates to MySQLTuner sub update_tuner_version { - if ($opt{'updateversion'} eq 0) { - badprint "Skipped version update for MySQLTuner script"; - print "\n" unless ($opt{'silent'} or $opt{'json'}); - return; - } + if ( $opt{'updateversion'} eq 0 ) { + badprint "Skipped version update for MySQLTuner script"; + print "\n" unless ( $opt{'silent'} or $opt{'json'} ); + return; + } - #use Cwd; - my $update; - my $url = "https://raw.githubusercontent.com/major/MySQLTuner-perl/master/"; - my @scripts = ("mysqltuner.pl", "basic_passwords.txt", "vulnerabilities.csv"); - my $totalScripts = scalar(@scripts); - my $receivedScripts = 0; - my $httpcli =`which curl`; + #use Cwd; + my $update; + my $url = "https://raw.githubusercontent.com/major/MySQLTuner-perl/master/"; + my @scripts = + ( "mysqltuner.pl", "basic_passwords.txt", "vulnerabilities.csv" ); + my $totalScripts = scalar(@scripts); + my $receivedScripts = 0; + my $httpcli = `which curl`; - foreach my $script (@scripts) { - - chomp($httpcli); - if ( 1 != 1 and defined($httpcli) and -e "$httpcli" ) { - debugprint "$httpcli is available."; + foreach my $script (@scripts) { - debugprint "$httpcli --connect-timeout 5 -silent '$url$script' > $script"; - $update = `$httpcli --connect-timeout 5 -silent '$url$script' > $script`; - chomp($update); - debugprint "$script updated: $update"; - - if ( -s $script eq 0) { - badprint "Couldn't update $script"; - } else { - ++$receivedScripts; - debugprint "$script updated: $update"; - } - } else { + chomp($httpcli); + if ( 1 != 1 and defined($httpcli) and -e "$httpcli" ) { + debugprint "$httpcli is available."; - $httpcli=`which wget`; - chomp($httpcli); - if ( defined($httpcli) and -e "$httpcli" ) { - debugprint "$httpcli is available."; + debugprint + "$httpcli --connect-timeout 5 -silent '$url$script' > $script"; + $update = + `$httpcli --connect-timeout 5 -silent '$url$script' > $script`; + chomp($update); + debugprint "$script updated: $update"; - debugprint "$httpcli -qe timestamping=off -T 5 -O $script '$url$script'"; - $update = `$httpcli -qe timestamping=off -T 5 -O $script '$url$script'`; - chomp($update); - - if ( -s $script eq 0) { - badprint "Couldn't update $script"; - } else { - ++$receivedScripts; - debugprint "$script updated: $update"; + if ( -s $script eq 0 ) { + badprint "Couldn't update $script"; + } + else { + ++$receivedScripts; + debugprint "$script updated: $update"; + } } + else { - } else { - debugprint "curl and wget are not available."; - infoprint "Unable to check for the latest MySQLTuner version"; - } - } - } + $httpcli = `which wget`; + chomp($httpcli); + if ( defined($httpcli) and -e "$httpcli" ) { + debugprint "$httpcli is available."; - if ($receivedScripts eq $totalScripts) { - goodprint "Successfully updated MySQLTuner script"; - } else { - badprint "Couldn't update MySQLTuner script"; + debugprint + "$httpcli -qe timestamping=off -T 5 -O $script '$url$script'"; + $update = + `$httpcli -qe timestamping=off -T 5 -O $script '$url$script'`; + chomp($update); + + if ( -s $script eq 0 ) { + badprint "Couldn't update $script"; + } + else { + ++$receivedScripts; + debugprint "$script updated: $update"; + } + + } + else { + debugprint "curl and wget are not available."; + infoprint "Unable to check for the latest MySQLTuner version"; + } + } } - exit 0; + if ( $receivedScripts eq $totalScripts ) { + goodprint "Successfully updated MySQLTuner script"; + } + else { + badprint "Couldn't update MySQLTuner script"; + } + + exit 0; } sub compare_tuner_version { - my $remoteversion=shift; - debugprint "Remote data: $remoteversion"; - #exit 0; - if ($remoteversion ne $tunerversion) { - badprint "There is a new version of MySQLTuner available ($remoteversion)"; - update_tuner_version(); - return; - } - goodprint "You have the latest version of MySQLTuner($tunerversion)"; - return; + my $remoteversion = shift; + debugprint "Remote data: $remoteversion"; + + #exit 0; + if ( $remoteversion ne $tunerversion ) { + badprint + "There is a new version of MySQLTuner available ($remoteversion)"; + update_tuner_version(); + return; + } + goodprint "You have the latest version of MySQLTuner($tunerversion)"; + return; } # Checks to see if a MySQL login is possible my ( $mysqllogin, $doremote, $remotestring, $mysqlcmd, $mysqladmincmd ); my $osname = $^O; -if( $osname eq 'MSWin32' ) { - eval { require Win32; } or last; - $osname = Win32::GetOSName(); - infoprint "* Windows OS($osname) is not fully supported.\n"; - #exit 1; +if ( $osname eq 'MSWin32' ) { + eval { require Win32; } or last; + $osname = Win32::GetOSName(); + infoprint "* Windows OS($osname) is not fully supported.\n"; + + #exit 1; } + sub mysql_setup { $doremote = 0; $remotestring = ''; @@ -551,8 +579,7 @@ sub mysql_setup { exit 1; } elsif ( !-e $mysqladmincmd ) { - badprint - "Couldn't find mysqladmin in your \$PATH. Is MySQL installed?"; + badprint "Couldn't find mysqladmin in your \$PATH. Is MySQL installed?"; exit 1; } if ( $opt{mysqlcmd} ) { @@ -572,11 +599,12 @@ sub mysql_setup { exit 1; } $mysqlcmd =~ s/\n$//g; - my $mysqlclidefaults=`$mysqlcmd --print-defaults`; + my $mysqlclidefaults = `$mysqlcmd --print-defaults`; debugprint "MySQL Client: $mysqlclidefaults"; - if ( $mysqlclidefaults=~/auto-vertical-output/ ) { - badprint "Avoid auto-vertical-output in configuration file(s) for MySQL like"; - exit 1; + if ( $mysqlclidefaults =~ /auto-vertical-output/ ) { + badprint + "Avoid auto-vertical-output in configuration file(s) for MySQL like"; + exit 1; } debugprint "MySQL Client: $mysqlcmd"; @@ -591,25 +619,27 @@ sub mysql_setup { chomp( $opt{host} ); $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 ( $opt{'forcemem'} eq 0 && ($opt{host} ne "127.0.0.1") && ($opt{host} ne "localhost")) { - badprint - "The --forcemem option is required for remote connections"; +# 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" ) ) + { + badprint "The --forcemem option is required for remote connections"; exit 1; } infoprint "Performing tests on $opt{host}:$opt{port}"; $remotestring = " -h $opt{host} -P $opt{port}"; - if (($opt{host} ne "127.0.0.1") && ($opt{host} ne "localhost")) { - $doremote = 1; + if ( ( $opt{host} ne "127.0.0.1" ) && ( $opt{host} ne "localhost" ) ) { + $doremote = 1; } } + # Did we already get a username without password on the command line? if ( $opt{user} ne 0 and $opt{pass} eq 0 ) { $mysqllogin = "-u $opt{user} " . $remotestring; my $loginstatus = `$mysqladmincmd ping $mysqllogin 2>&1`; if ( $loginstatus =~ /mysqld is alive/ ) { - goodprint - "Logged in using credentials passed on the command line"; + goodprint "Logged in using credentials passed on the command line"; return 1; } else { @@ -618,13 +648,13 @@ sub mysql_setup { exit 1; } } + # Did we already get a username and password passed on the command line? if ( $opt{user} ne 0 and $opt{pass} ne 0 ) { $mysqllogin = "-u $opt{user} -p\"$opt{pass}\"" . $remotestring; my $loginstatus = `$mysqladmincmd ping $mysqllogin 2>&1`; if ( $loginstatus =~ /mysqld is alive/ ) { - goodprint - "Logged in using credentials passed on the command line"; + goodprint "Logged in using credentials passed on the command line"; return 1; } else { @@ -649,8 +679,7 @@ sub mysql_setup { $mysqllogin = "-u $mysql_login -p$mysql_pass"; my $loginstatus = `mysqladmin $mysqllogin ping 2>&1`; if ( $loginstatus =~ /mysqld is alive/ ) { - goodprint - "Logged in using credentials from mysql-quickbackup."; + goodprint "Logged in using credentials from mysql-quickbackup."; return 1; } else { @@ -661,18 +690,22 @@ sub mysql_setup { } } elsif ( -r "/etc/psa/.psa.shadow" and $doremote == 0 ) { + # It's a Plesk box, use the available credentials $mysqllogin = "-u admin -p`cat /etc/psa/.psa.shadow`"; my $loginstatus = `$mysqladmincmd ping $mysqllogin 2>&1`; unless ( $loginstatus =~ /mysqld is alive/ ) { + # Plesk 10+ - $mysqllogin = "-u admin -p`/usr/local/psa/bin/admin --show-password`"; + $mysqllogin = + "-u admin -p`/usr/local/psa/bin/admin --show-password`"; $loginstatus = `$mysqladmincmd ping $mysqllogin 2>&1`; unless ( $loginstatus =~ /mysqld is alive/ ) { - badprint "Attempted to use login credentials from Plesk and Plesk 10+, but they failed."; - exit 1; + badprint +"Attempted to use login credentials from Plesk and Plesk 10+, but they failed."; + exit 1; } - } + } } elsif ( -r "/usr/local/directadmin/conf/mysql.conf" and $doremote == 0 ) { @@ -722,7 +755,7 @@ sub mysql_setup { # Login went just fine $mysqllogin = " $remotestring "; - # Did this go well because of a .my.cnf file or is there no password set? + # Did this go well because of a .my.cnf file or is there no password set? my $userpath = `printenv HOME`; if ( length($userpath) > 0 ) { chomp($userpath); @@ -735,27 +768,29 @@ sub mysql_setup { return 1; } else { - if ( $opt{'noask'}==1 ) { - badprint "Attempted to use login credentials, but they were invalid"; + if ( $opt{'noask'} == 1 ) { + badprint + "Attempted to use login credentials, but they were invalid"; exit 1; } - my ($name, $password); + my ( $name, $password ); + # If --user is defined no need to ask for username - if( $opt{user} ne 0 ) - { + if ( $opt{user} ne 0 ) { $name = $opt{user}; } - else{ + else { print STDERR "Please enter your MySQL administrative login: "; $name = ; } + # If --pass is defined no need to ask for password - if( $opt{pass} ne 0 ) - { + if ( $opt{pass} ne 0 ) { $password = $opt{pass}; } - else{ - print STDERR "Please enter your MySQL administrative password: "; + else { + print STDERR + "Please enter your MySQL administrative password: "; system("stty -echo >$devnull 2>&1"); $password = ; system("stty echo >$devnull 2>&1"); @@ -784,7 +819,8 @@ sub mysql_setup { return 1; } 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; @@ -797,15 +833,16 @@ sub select_array { my $req = shift; debugprint "PERFORM: $req "; my @result = `$mysqlcmd $mysqllogin -Bse "$req" 2>>/dev/null`; - if ($? != 0) { - badprint "failed to execute: $req"; - badprint "FAIL Execute SQL / return code: $?"; - debugprint "CMD : $mysqlcmd"; - debugprint "OPTIONS: $mysqllogin"; - debugprint `$mysqlcmd $mysqllogin -Bse "$req" 2>&1`; - #exit $?; - } - debugprint "select_array: return code : $?"; + if ( $? != 0 ) { + badprint "failed to execute: $req"; + badprint "FAIL Execute SQL / return code: $?"; + debugprint "CMD : $mysqlcmd"; + debugprint "OPTIONS: $mysqllogin"; + debugprint `$mysqlcmd $mysqllogin -Bse "$req" 2>&1`; + + #exit $?; + } + debugprint "select_array: return code : $?"; chomp(@result); return @result; } @@ -815,15 +852,16 @@ sub select_one { my $req = shift; debugprint "PERFORM: $req "; my $result = `$mysqlcmd $mysqllogin -Bse "$req" 2>>/dev/null`; - if ($? != 0) { - badprint "failed to execute: $req"; - badprint "FAIL Execute SQL / return code: $?"; - debugprint "CMD : $mysqlcmd"; - debugprint "OPTIONS: $mysqllogin"; - debugprint `$mysqlcmd $mysqllogin -Bse "$req" 2>&1`; - #exit $?; - } - debugprint "select_array: return code : $?"; + if ( $? != 0 ) { + badprint "failed to execute: $req"; + badprint "FAIL Execute SQL / return code: $?"; + debugprint "CMD : $mysqlcmd"; + debugprint "OPTIONS: $mysqllogin"; + debugprint `$mysqlcmd $mysqllogin -Bse "$req" 2>&1`; + + #exit $?; + } + debugprint "select_array: return code : $?"; chomp($result); return $result; } @@ -879,11 +917,14 @@ sub get_all_vars { if ( ( $myvar{'ignore_builtin_innodb'} || "" ) eq "ON" ) { $myvar{'have_innodb'} = "NO"; } - + $myvar{'have_threadpool'} = "NO"; - if ( defined ( $myvar{'thread_pool_size'} ) and $myvar{'thread_pool_size'} > 0 ) { + if ( defined( $myvar{'thread_pool_size'} ) + and $myvar{'thread_pool_size'} > 0 ) + { $myvar{'have_threadpool'} = "YES"; } + # have_* for engines is deprecated and will be removed in MySQL 5.6; # check SHOW ENGINES and set corresponding old style variables. # Also works around MySQL bug #59393 wrt. skip-innodb @@ -927,9 +968,11 @@ sub get_all_vars { sub remove_cr { map { s/\n$//g; } @_; } + sub remove_empty { grep { $_ ne '' } @_; } + sub get_file_contents { my $file = shift; open( FH, "< $file" ) or die "Can't open $file for read: $!"; @@ -946,219 +989,260 @@ sub get_basic_passwords { sub cve_recommendations { prettyprint "\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"; return; } - #prettyprint "Look for related CVE for $myvar{'version'} or lower in $opt{cvefile}"; - my $cvefound=0; +#prettyprint "Look for related CVE for $myvar{'version'} or lower in $opt{cvefile}"; + my $cvefound = 0; open( FH, "<$opt{cvefile}" ) or die "Can't open $opt{cvefile} for read: $!"; - while (my $cveline = ) - { - my @cve=split (';', $cveline); - if (mysql_micro_version_le ($cve[1], $cve[2], $cve[3])) { - badprint "$cve[4] : $cve[5]"; - $cvefound++; - } - + while ( my $cveline = ) { + my @cve = split( ';', $cveline ); + if ( mysql_micro_version_le( $cve[1], $cve[2], $cve[3] ) ) { + badprint "$cve[4] : $cve[5]"; + $cvefound++; + } + } close FH or die "Cannot close $opt{cvefile}: $!"; - if ($cvefound==0) { - goodprint "NO SECURITY CVE FOUND FOR YOUR VERSION"; - return; - } + if ( $cvefound == 0 ) { + goodprint "NO SECURITY CVE FOUND FOR YOUR VERSION"; + return; + } 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 get_opened_ports { - my @opened_ports=`netstat -ltn`; - map { - s/.*:(\d+)\s.*$/$1/; - s/\D//g; - } @opened_ports; - @opened_ports = sort {$a <=> $b} grep { !/^$/ } @opened_ports; - debugprint Dumper \@opened_ports; - return @opened_ports; + my @opened_ports = `netstat -ltn`; + map { + s/.*:(\d+)\s.*$/$1/; + s/\D//g; + } @opened_ports; + @opened_ports = sort { $a <=> $b } grep { !/^$/ } @opened_ports; + debugprint Dumper \@opened_ports; + return @opened_ports; } sub is_open_port { - my $port=shift; - if ( grep { /^$port$/ } get_opened_ports ) { - return 1; - } - return 0; + my $port = shift; + if ( grep { /^$port$/ } get_opened_ports ) { + return 1; + } + return 0; } sub get_process_memory { - my $pid=shift; - return 0 unless -f "/proc/$pid/status"; - my @pdata= grep { /RSS:/ } get_file_contents "/proc/$pid/status"; - map { - s/.*RSS:\s*(\d+)\s*kB\s*$/$1*1024/ge - } @pdata; - return $pdata[0]; + my $pid = shift; + return 0 unless -f "/proc/$pid/status"; + my @pdata = grep { /RSS:/ } get_file_contents "/proc/$pid/status"; + map { s/.*RSS:\s*(\d+)\s*kB\s*$/$1*1024/ge } @pdata; + return $pdata[0]; } sub get_other_process_memory { - my @procs=`ps -eo pid,cmd`; - map { s/.*mysqld.*//; s/.*\[.*\].*//; s/^\s+$//g; s/.*PID.*CMD.*//; s/.*systemd.*//;} @procs; - map {s/\s*?(\d+)\s*.*/$1/g;} @procs; - remove_cr @procs; - @procs=remove_empty @procs; - my $totalMemOther=0; - map { - $totalMemOther+=get_process_memory($_); - } @procs; - return $totalMemOther; + my @procs = `ps -eo pid,cmd`; + map { + s/.*mysqld.*//; + s/.*\[.*\].*//; + s/^\s+$//g; + s/.*PID.*CMD.*//; + s/.*systemd.*//; + } @procs; + map { s/\s*?(\d+)\s*.*/$1/g; } @procs; + remove_cr @procs; + @procs = remove_empty @procs; + my $totalMemOther = 0; + map { $totalMemOther += get_process_memory($_); } @procs; + return $totalMemOther; } sub get_os_release { return "Unknown OS release" unless -f "/etc/system-release"; - my @info_release=get_file_contents "/etc/system-release"; + my @info_release = get_file_contents "/etc/system-release"; remove_cr @info_release; return $info_release[0]; } sub get_fs_info() { - my @sinfo=`df -P | grep '%'`; + my @sinfo = `df -P | grep '%'`; shift @sinfo; - my @iinfo=`df -Pi| grep '%'`; + my @iinfo = `df -Pi| grep '%'`; shift @iinfo; - map { - s/.*\s(\d+)%\s+(.*)/$1\t$2/g - } @sinfo; + map { s/.*\s(\d+)%\s+(.*)/$1\t$2/g } @sinfo; foreach my $info (@sinfo) { - if ($info =~ /(\d+)\t(.*)/) { - if ($1 > 85) { - badprint "mount point $2 is using $1 % total space"; - push(@generalrec, "Add some space to $2 mountpoint.") - } else { - infoprint "mount point $2 is using $1 % of total space"; - } - } + if ( $info =~ /(\d+)\t(.*)/ ) { + if ( $1 > 85 ) { + badprint "mount point $2 is using $1 % total space"; + push( @generalrec, "Add some space to $2 mountpoint." ); + } + else { + infoprint "mount point $2 is using $1 % of total space"; + } + } } - - map { - s/.*\s(\d+)%\s+(.*)/$1\t$2/g - } @iinfo; + + map { s/.*\s(\d+)%\s+(.*)/$1\t$2/g } @iinfo; foreach my $info (@iinfo) { - if ($info =~ /(\d+)\t(.*)/) { - if ($1 > 85) { - badprint "mount point $2 is using $1 % of max allowed inodes"; - push(@generalrec, "Cleanup files from $2 mountpoint or reformat you filesystem.") - } else { - infoprint "mount point $2 is using $1 % of max allowed inodes"; - } - } + if ( $info =~ /(\d+)\t(.*)/ ) { + if ( $1 > 85 ) { + badprint "mount point $2 is using $1 % of max allowed inodes"; + push( @generalrec, +"Cleanup files from $2 mountpoint or reformat you filesystem." + ); + } + else { + infoprint "mount point $2 is using $1 % of max allowed inodes"; + } + } } } -sub is_virtual_machine() { - my $isVm=`grep -Ec '^flags.*\ hypervisor\ ' /proc/cpuinfo`; - return ($isVm==0?0:1); -} +sub is_virtual_machine() { + my $isVm = `grep -Ec '^flags.*\ hypervisor\ ' /proc/cpuinfo`; + return ( $isVm == 0 ? 0 : 1 ); +} sub infocmd { - my $cmd="@_"; - debugprint "CMD: $cmd"; - my @result=`$cmd`; - remove_cr @result; - for my $l (@result) { - infoprint "$l"; - } + my $cmd = "@_"; + debugprint "CMD: $cmd"; + my @result = `$cmd`; + remove_cr @result; + for my $l (@result) { + infoprint "$l"; + } } + sub infocmd_tab { - my $cmd="@_"; - debugprint "CMD: $cmd"; - my @result=`$cmd`; - remove_cr @result; - for my $l (@result) { - infoprint "\t$l"; - } + my $cmd = "@_"; + debugprint "CMD: $cmd"; + my @result = `$cmd`; + remove_cr @result; + for my $l (@result) { + infoprint "\t$l"; + } } + sub infocmd_one { - my $cmd="@_"; - my @result=`$cmd`; - remove_cr @result; - return join ', ' ,@result; + my $cmd = "@_"; + my @result = `$cmd`; + remove_cr @result; + return join ', ', @result; } -sub get_system_info() -{ -infoprint get_os_release; -if (is_virtual_machine) { - infoprint "Machine type : Virtual machine"; - } else { - infoprint "Machine type : Physical machine"; -} +sub get_system_info() { + infoprint get_os_release; + if (is_virtual_machine) { + infoprint "Machine type : Virtual machine"; + } + else { + infoprint "Machine type : Physical machine"; + } -`ping -c 1 google.com &>/dev/null`; -my $isConnected=$?; -if ($? == 0) { - infoprint "Internet : Connected"; -} else { - badprint "Internet : Disconnected"; - } -infoprint "Operating System Type : ". infocmd_one "uname -o"; -infoprint "Kernel Release : ". infocmd_one "uname -r"; -infoprint "Hostname : ". infocmd_one "hostname"; -infoprint "Network Cards : "; -infocmd_tab "ifconfig| grep -A1 mtu"; -infoprint "Internal IP : ". infocmd_one "hostname -I"; -infoprint "External IP : ". infocmd_one "curl -s ipecho.net/plain" if $isConnected==0; -badprint "External IP : Can't check because of Internet connectivity" if $isConnected!=0; -infoprint "Name Servers : ". infocmd_one "grep 'nameserver' /etc/resolv.conf \| awk '{print \$2}'"; -infoprint "Logged In users : "; -infocmd_tab "who"; -infoprint "Ram Usages : "; -infocmd_tab "free -h | grep -v +"; -infoprint "Load Average : "; -infocmd_tab "top -n 1 -b | grep 'load average:'"; + `ping -c 1 google.com &>/dev/null`; + my $isConnected = $?; + if ( $? == 0 ) { + infoprint "Internet : Connected"; + } + else { + badprint "Internet : Disconnected"; + } + infoprint "Operating System Type : " . infocmd_one "uname -o"; + infoprint "Kernel Release : " . infocmd_one "uname -r"; + infoprint "Hostname : " . infocmd_one "hostname"; + infoprint "Network Cards : "; + infocmd_tab "ifconfig| grep -A1 mtu"; + infoprint "Internal IP : " . infocmd_one "hostname -I"; + infoprint "External IP : " + . infocmd_one "curl -s ipecho.net/plain" + if $isConnected == 0; + badprint + "External IP : Can't check because of Internet connectivity" + if $isConnected != 0; + infoprint "Name Servers : " + . infocmd_one "grep 'nameserver' /etc/resolv.conf \| awk '{print \$2}'"; + infoprint "Logged In users : "; + infocmd_tab "who"; + infoprint "Ram Usages : "; + infocmd_tab "free -h | grep -v +"; + infoprint "Load Average : "; + infocmd_tab "top -n 1 -b | grep 'load average:'"; #infoprint "System Uptime Days/(HH:MM) : `uptime | awk '{print $3,$4}' | cut -f1 -d,`"; } sub system_recommendations { - prettyprint "\n-------- System Linux Recommendations ---------------------------------------"; + prettyprint +"\n-------- System Linux Recommendations ---------------------------------------"; my $os = `uname`; - unless ($os =~ /Linux/i) { + unless ( $os =~ /Linux/i ) { infoprint "Skipped due to non Linux server"; return; - } + } prettyprint "Look for related Linux system recommandations"; + #prettyprint '-'x78; get_system_info(); - my $omem=get_other_process_memory; - infoprint "User process except mysqld used ". hr_bytes_rnd($omem) . " RAM."; - if ( (0.15*$physical_memory) < $omem) { - badprint "Other user process except mysqld used more than 15% of total physical memory ". percentage($omem, $physical_memory). "% (".hr_bytes_rnd($omem). " / ".hr_bytes_rnd($physical_memory).")"; - push( @generalrec, "Consider stopping or dedicate server for additionnal process other than mysqld." ); - push( @adjvars, "DON'T APPLY SETTINGS BECAUSE THERE ARE TOO MANY PROCESSES RUNNING ON THIS SERVER. OOM KILL CAN OCCUR!" ); - } else { - infoprint "Other user process except mysqld used less than 15% of total physical memory ". percentage($omem, $physical_memory). "% (".hr_bytes_rnd($omem). " / ".hr_bytes_rnd($physical_memory).")"; + my $omem = get_other_process_memory; + infoprint "User process except mysqld used " + . hr_bytes_rnd($omem) . " RAM."; + if ( ( 0.15 * $physical_memory ) < $omem ) { + badprint +"Other user process except mysqld used more than 15% of total physical memory " + . percentage( $omem, $physical_memory ) . "% (" + . hr_bytes_rnd($omem) . " / " + . hr_bytes_rnd($physical_memory) . ")"; + push( @generalrec, +"Consider stopping or dedicate server for additionnal process other than mysqld." + ); + push( @adjvars, +"DON'T APPLY SETTINGS BECAUSE THERE ARE TOO MANY PROCESSES RUNNING ON THIS SERVER. OOM KILL CAN OCCUR!" + ); + } + else { + infoprint +"Other user process except mysqld used less than 15% of total physical memory " + . percentage( $omem, $physical_memory ) . "% (" + . hr_bytes_rnd($omem) . " / " + . hr_bytes_rnd($physical_memory) . ")"; } - if ($opt{'maxportallowed'} > 0) { - my @opened_ports=get_opened_ports; - infoprint "There is ". scalar @opened_ports. " listening port(s) on this server."; - if (scalar(@opened_ports) > $opt{'maxportallowed'}) { - badprint "There is too many listening ports: ". scalar(@opened_ports). " opened > ".$opt{'maxportallowed'}. "allowed."; - push( @generalrec, "Consider dedicating a server for your database installation with less services running on !" ); - } else { - goodprint "There is less than ".$opt{'maxportallowed'}." opened ports on this server."; - } + if ( $opt{'maxportallowed'} > 0 ) { + my @opened_ports = get_opened_ports; + infoprint "There is " + . scalar @opened_ports + . " listening port(s) on this server."; + if ( scalar(@opened_ports) > $opt{'maxportallowed'} ) { + badprint "There is too many listening ports: " + . scalar(@opened_ports) + . " opened > " + . $opt{'maxportallowed'} + . "allowed."; + push( @generalrec, +"Consider dedicating a server for your database installation with less services running on !" + ); + } + else { + goodprint "There is less than " + . $opt{'maxportallowed'} + . " opened ports on this server."; + } } foreach my $banport (@banned_ports) { - if ( is_open_port($banport) ) { - badprint "Banned port: $banport is opened.."; - push( @generalrec, "Port $banport is opened. Consider stopping program handling this port." ); - } else { - goodprint "$banport is not opened."; - } + if ( is_open_port($banport) ) { + badprint "Banned port: $banport is opened.."; + push( @generalrec, +"Port $banport is opened. Consider stopping program handling this port." + ); + } + else { + goodprint "$banport is not opened."; + } } get_fs_info; @@ -1172,16 +1256,17 @@ sub security_recommendations { return; } - my $PASS_COLUMN_NAME='password'; - if ($myvar{'version'} =~ /5.7/) { - $PASS_COLUMN_NAME='authentication_string'; + my $PASS_COLUMN_NAME = 'password'; + if ( $myvar{'version'} =~ /5.7/ ) { + $PASS_COLUMN_NAME = 'authentication_string'; } debugprint "Password column = $PASS_COLUMN_NAME"; - + # Looking for Anonymous users my @mysqlstatlist = select_array "SELECT CONCAT(user, '\@', host) FROM mysql.user WHERE TRIM(USER) = '' OR USER IS NULL"; debugprint Dumper \@mysqlstatlist; + #exit 0; if (@mysqlstatlist) { foreach my $line ( sort @mysqlstatlist ) { @@ -1213,12 +1298,15 @@ sub security_recommendations { goodprint "All database users have passwords assigned"; } - if (mysql_version_ge(5,7)) { - my $valPlugin=select_one("select count(*) from information_schema.plugins where PLUGIN_NAME='validate_password' AND PLUGIN_STATUS='ACTIVE'"); - if ($valPlugin>=1) { - infoprint "Bug #80860 MySQL 5.7: Avoid testing password when validate_password is activated"; - return; - } + if ( mysql_version_ge( 5, 7 ) ) { + my $valPlugin = select_one( +"select count(*) from information_schema.plugins where PLUGIN_NAME='validate_password' AND PLUGIN_STATUS='ACTIVE'" + ); + if ( $valPlugin >= 1 ) { + infoprint +"Bug #80860 MySQL 5.7: Avoid testing password when validate_password is activated"; + return; + } } # Looking for User with user/ uppercase /capitalise user as password @@ -1322,10 +1410,10 @@ sub get_replication_status { and ( $io_running !~ /yes/i or $sql_running !~ /yes/i ) ) { 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) - && $io_running =~ /yes/i + && $io_running =~ /yes/i && $sql_running =~ /yes/i ) { if ( $myvar{'read_only'} eq 'OFF' ) { @@ -1359,10 +1447,13 @@ sub validate_mysql_version { . $myvar{'version'} . " 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 " . $myvar{'version'} . ""; - } else { + } + else { goodprint "Currently running supported MySQL version " . $myvar{'version'} . ""; } @@ -1374,8 +1465,7 @@ sub mysql_version_ge { $min ||= 0; $mic ||= 0; return $mysqlvermajor > $maj - || $mysqlvermajor == $maj - && ( $mysqlverminor > $min + || $mysqlvermajor == $maj && ( $mysqlverminor > $min || $mysqlverminor == $min && $mysqlvermicro >= $mic ); } @@ -1385,8 +1475,7 @@ sub mysql_version_le { $min ||= 0; $mic ||= 0; return $mysqlvermajor < $maj - || $mysqlvermajor == $maj - && ( $mysqlverminor < $min + || $mysqlvermajor == $maj && ( $mysqlverminor < $min || $mysqlverminor == $min && $mysqlvermicro <= $mic ); } @@ -1395,7 +1484,7 @@ sub mysql_micro_version_le { my ( $maj, $min, $mic ) = @_; return $mysqlvermajor == $maj && ( $mysqlverminor == $min - && $mysqlvermicro <= $mic ); + && $mysqlvermicro <= $mic ); } # Checks for 32-bit boxes with more than 2GB of RAM @@ -1442,8 +1531,7 @@ sub check_architecture { "Switch to 64-bit OS - MySQL cannot currently use all of your RAM"; } else { - goodprint - "Operating on 32-bit architecture with less than 2GB RAM"; + goodprint "Operating on 32-bit architecture with less than 2GB RAM"; } } $result{'OS'}{'Architecture'} = "$arch bits"; @@ -1519,12 +1607,13 @@ sub check_storage_engines { : 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]; infoprint "Status: $engines"; if ( mysql_version_ge( 5, 1, 5 ) ) { - # MySQL 5 servers can have table sizes calculated quickly from information schema + +# MySQL 5 servers can have table sizes calculated quickly from information schema my @templist = select_array "SELECT ENGINE,SUM(DATA_LENGTH+INDEX_LENGTH),COUNT(ENGINE),SUM(DATA_LENGTH),SUM(INDEX_LENGTH) FROM information_schema.TABLES WHERE TABLE_SCHEMA NOT IN ('information_schema', 'performance_schema', 'mysql') AND ENGINE IS NOT NULL GROUP BY ENGINE ORDER BY ENGINE ASC;"; @@ -1554,7 +1643,7 @@ sub check_storage_engines { # MySQL < 5 servers take a lot of work to get table sizes 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) { chomp($db); if ( $db eq "information_schema" @@ -1578,11 +1667,11 @@ sub check_storage_engines { # Parse through the table list to generate storage engine counts/statistics $fragtables = 0; foreach my $tbl (@tblist) { - debugprint "Data dump ". Dumper (@$tbl); + debugprint "Data dump " . Dumper(@$tbl); my ( $engine, $size, $datafree ) = @$tbl; next if $engine eq 'NULL'; - $size=0 if $size eq 'NULL'; - $datafree=0 if $datafree eq 'NULL'; + $size = 0 if $size eq 'NULL'; + $datafree = 0 if $datafree eq 'NULL'; if ( defined $enginestats{$engine} ) { $enginestats{$engine} += $size; $enginecount{$engine} += 1; @@ -1801,7 +1890,7 @@ sub calculations { $myvar{'key_cache_block_size'} ) / $myvar{'key_buffer_size'} ) - ) * 100 + ) * 100 ); } else { @@ -1894,14 +1983,14 @@ sub calculations { ( $mystat{'Qcache_hits'} / ( $mystat{'Com_select'} + $mystat{'Qcache_hits'} ) - ) * 100 + ) * 100 ); if ( $myvar{'query_cache_size'} ) { $mycalc{'pct_query_cache_used'} = sprintf( "%.1f", 100 - ( $mystat{'Qcache_free_memory'} / $myvar{'query_cache_size'} - ) * 100 + ) * 100 ); } if ( $mystat{'Qcache_lowmem_prunes'} == 0 ) { @@ -2030,26 +2119,17 @@ sub calculations { . $mystat{'Innodb_buffer_pool_reads'} . ""; debugprint "Innodb_buffer_pool_read_requests: " . $mystat{'Innodb_buffer_pool_read_requests'} . ""; - - # InnoDB log write cache effiency - ( - $mystat{'Innodb_log_write_requests'}, - $mystat{'Innodb_log_writes'} - ) - = ( 1, 1 ) + ( $mystat{'Innodb_log_write_requests'}, $mystat{'Innodb_log_writes'} ) = + ( 1, 1 ) unless defined $mystat{'Innodb_log_writes'}; $mycalc{'pct_write_efficiency'} = percentage( - ( - $mystat{'Innodb_log_write_requests'} - - $mystat{'Innodb_log_writes'} - ), + ( $mystat{'Innodb_log_write_requests'} - $mystat{'Innodb_log_writes'} ), $mystat{'Innodb_log_write_requests'} ) if defined $mystat{'Innodb_log_write_requests'}; debugprint "pct_write_efficiency: " . $mycalc{'pct_write_efficiency'} . ""; - debugprint "Innodb_log_writes: " - . $mystat{'Innodb_log_writes'} . ""; + debugprint "Innodb_log_writes: " . $mystat{'Innodb_log_writes'} . ""; debugprint "Innodb_log_write_requests: " . $mystat{'Innodb_log_write_requests'} . ""; $mycalc{'pct_innodb_buffer_used'} = percentage( @@ -2125,8 +2205,10 @@ sub mysql_stats { . ( $myvar{'query_cache_type'} eq 0 | $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: " . hr_bytes( $myvar{'query_cache_size'} ) . ""; @@ -2155,7 +2237,7 @@ sub mysql_stats { && $mycalc{'max_used_memory'} > 2 * 1024 * 1024 * 1024 ) { 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: " . hr_bytes( $mycalc{'max_used_memory'} ) . " ($mycalc{'pct_max_used_memory'}% of installed RAM)"; @@ -2242,14 +2324,16 @@ sub mysql_stats { push( @generalrec, "Upgrade MySQL to version 4+ to utilize query caching" ); } - elsif (mysql_version_ge(5,5)) - { - if ( $myvar{'query_cache_type'} ne "OFF" ) { - badprint "Query cache should be disabled by default due to mutex contention."; - push( @adjvars, "query_cache_type (=0)" ); - } else { - goodprint "Query cache is disabled by default due to mutex contention."; - } + elsif ( mysql_version_ge( 5, 5 ) ) { + if ( $myvar{'query_cache_type'} ne "OFF" ) { + badprint +"Query cache should be disabled by default due to mutex contention."; + push( @adjvars, "query_cache_type (=0)" ); + } + else { + goodprint + "Query cache is disabled by default due to mutex contention."; + } } elsif ( $myvar{'query_cache_size'} < 1 ) { badprint "Query cache is disabled"; @@ -2380,7 +2464,8 @@ sub mysql_stats { "When making adjustments, make tmp_table_size/max_heap_table_size equal" ); 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 && $mycalc{'max_tmp_table_size'} >= 256 * 1024 * 1024 ) @@ -2568,6 +2653,7 @@ sub mysql_stats { sub mysql_myisam { prettyprint "\n-------- MyISAM Metrics ------------------------------------------------------"; + # Key buffer usage if ( defined( $mycalc{'pct_key_buffer_used'} ) ) { if ( $mycalc{'pct_key_buffer_used'} < 90 ) { @@ -2701,26 +2787,43 @@ sub mariadb_threadpool { infoprint "ThreadPool stat is disabled."; return; } - infoprint "ThreadPool stat is enabled."; - infoprint "Thread Pool Size: ".$myvar{'thread_pool_size'}. " thread(s)."; + infoprint "ThreadPool stat is enabled."; + infoprint "Thread Pool Size: " . $myvar{'thread_pool_size'} . " thread(s)."; - if ($myvar{'have_innodb'} eq 'YES') { - if ($myvar{'thread_pool_size'}< 16 or $myvar{'thread_pool_size'}>36) { - badprint "thread_pool_size between 16 and 36 when using InnoDB storage engine."; - push( @generalrec, "Thread pool size for InnoDB usage (".$myvar{'thread_pool_size'}.")" ); - push( @adjvars, "thread_pool_size between 16 and 36 for InnoDB usage" ); - } else { - goodprint "thread_pool_size between 16 and 36 when using InnoDB storage engine."; + if ( $myvar{'have_innodb'} eq 'YES' ) { + if ( $myvar{'thread_pool_size'} < 16 + or $myvar{'thread_pool_size'} > 36 ) + { + badprint +"thread_pool_size between 16 and 36 when using InnoDB storage engine."; + push( @generalrec, + "Thread pool size for InnoDB usage (" + . $myvar{'thread_pool_size'} + . ")" ); + push( @adjvars, + "thread_pool_size between 16 and 36 for InnoDB usage" ); + } + else { + goodprint +"thread_pool_size between 16 and 36 when using InnoDB storage engine."; } return; - } - if ($myvar{'have_isam'} eq 'YES') { - if ($myvar{'thread_pool_size'}<4 or $myvar{'thread_pool_size'}>8) { - badprint "thread_pool_size between 4 and 8 when using MyIsam storage engine."; - push( @generalrec, "Thread pool size for MyIsam usage (".$myvar{'thread_pool_size'}.")" ); - push( @adjvars, "thread_pool_size between 4 and 8 for MyIsam usage" ); - } else { - goodprint "thread_pool_size between 4 and 8 when using MyISAM storage engine."; + } + if ( $myvar{'have_isam'} eq 'YES' ) { + if ( $myvar{'thread_pool_size'} < 4 or $myvar{'thread_pool_size'} > 8 ) + { + badprint +"thread_pool_size between 4 and 8 when using MyIsam storage engine."; + push( @generalrec, + "Thread pool size for MyIsam usage (" + . $myvar{'thread_pool_size'} + . ")" ); + push( @adjvars, + "thread_pool_size between 4 and 8 for MyIsam usage" ); + } + else { + goodprint +"thread_pool_size between 4 and 8 when using MyISAM storage engine."; } } } @@ -2731,14 +2834,16 @@ sub mysqsl_pfs { "\n-------- Performance schema --------------------------------------------------"; # Performance Schema - unless ( defined($myvar{'performance_schema'}) and $myvar{'performance_schema'} eq 'ON' ) { - infoprint "Performance schema is disabled."; - } else { - infoprint "Performance schema is enabled."; - } + unless ( defined( $myvar{'performance_schema'} ) + and $myvar{'performance_schema'} eq 'ON' ) + { + infoprint "Performance schema is disabled."; + } + else { + infoprint "Performance schema is enabled."; + } } - # Recommendations for Ariadb sub mariadb_ariadb { prettyprint @@ -2810,7 +2915,6 @@ sub mariadb_ariadb { } } - # Recommendations for TokuDB sub mariadb_tokudb { prettyprint @@ -2843,6 +2947,7 @@ sub mariadb_galera { return; } infoprint "Galera is enabled."; + # All is to done here } @@ -3087,11 +3192,19 @@ sub mysql_databases { . percentage( $totaldbinfo[2], $totaldbinfo[3] ) . "%)"; infoprint " +-- SIZE : " . hr_bytes( $totaldbinfo[3] ) . ""; infoprint " +-- COLLA : " - . ( $totaldbinfo[5] eq 'NULL' ? 0 : $totaldbinfo[5] ) . " (". (join ", ", select_array ("SELECT DISTINCT(TABLE_COLLATION) FROM information_schema.TABLES;")) .")"; + . ( $totaldbinfo[5] eq 'NULL' ? 0 : $totaldbinfo[5] ) . " (" + . ( + join ", ", + select_array( + "SELECT DISTINCT(TABLE_COLLATION) FROM information_schema.TABLES;") + ) . ")"; infoprint " +-- ENGIN : " - . ( $totaldbinfo[6] eq 'NULL' ? 0 : $totaldbinfo[6] ) . " (". (join ", ", select_array ("SELECT DISTINCT(ENGINE) FROM information_schema.TABLES;")) .")"; - - + . ( $totaldbinfo[6] eq 'NULL' ? 0 : $totaldbinfo[6] ) . " (" + . ( + join ", ", + select_array("SELECT DISTINCT(ENGINE) FROM information_schema.TABLES;") + ) . ")"; + $result{'Databases'}{'All databases'}{'Rows'} = ( $totaldbinfo[0] eq 'NULL' ? 0 : $totaldbinfo[0] ); $result{'Databases'}{'All databases'}{'Data Size'} = $totaldbinfo[1]; @@ -3100,14 +3213,18 @@ sub mysql_databases { $result{'Databases'}{'All databases'}{'Index Size'} = $totaldbinfo[2]; $result{'Databases'}{'All databases'}{'Index Pct'} = percentage( $totaldbinfo[2], $totaldbinfo[3] ) . "%"; - $result{'Databases'}{'All databases'}{'Total Size'} = $totaldbinfo[3]; - print "\n" unless ($opt{'silent'} or $opt{'json'}); + $result{'Databases'}{'All databases'}{'Total Size'} = $totaldbinfo[3]; + print "\n" unless ( $opt{'silent'} or $opt{'json'} ); + foreach (@dblist) { chomp($_); - if ( $_ eq "information_schema" + if ( + $_ eq "information_schema" or $_ eq "performance_schema" - # or $_ eq "mysql" - or $_ eq "" ) + + # or $_ eq "mysql" + or $_ eq "" + ) { next; } @@ -3122,7 +3239,13 @@ sub mysql_databases { . ( !defined( $dbinfo[6] ) or $dbinfo[6] eq 'NULL' ? 0 : $dbinfo[6] ) . ""; infoprint " +-- COLL : " - . ( $dbinfo[7] eq 'NULL' ? 0 : $dbinfo[7] ) . " (". (join ", ", select_array ("SELECT DISTINCT(TABLE_COLLATION) FROM information_schema.TABLES WHERE TABLE_SCHEMA='$_';")) .")"; + . ( $dbinfo[7] eq 'NULL' ? 0 : $dbinfo[7] ) . " (" + . ( + join ", ", + select_array( +"SELECT DISTINCT(TABLE_COLLATION) FROM information_schema.TABLES WHERE TABLE_SCHEMA='$_';" + ) + ) . ")"; infoprint " +-- ROWS : " . ( !defined( $dbinfo[1] ) or $dbinfo[1] eq 'NULL' ? 0 : $dbinfo[1] ) . ""; @@ -3134,53 +3257,93 @@ sub mysql_databases { . percentage( $dbinfo[3], $dbinfo[4] ) . "%)"; infoprint " +-- TOTAL: " . hr_bytes( $dbinfo[4] ) . ""; infoprint " +-- ENGIN : " - . ( $dbinfo[8] eq 'NULL' ? 0 : $dbinfo[8] ) . " (". (join ", ", select_array ("SELECT DISTINCT(ENGINE) FROM information_schema.TABLES WHERE TABLE_SCHEMA='$_'")) .")"; + . ( $dbinfo[8] eq 'NULL' ? 0 : $dbinfo[8] ) . " (" + . ( + join ", ", + select_array( +"SELECT DISTINCT(ENGINE) FROM information_schema.TABLES WHERE TABLE_SCHEMA='$_'" + ) + ) . ")"; badprint "Index size is larger than data size for $dbinfo[0] \n" if $dbinfo[2] < $dbinfo[3]; badprint "There are " . $dbinfo[5] . " storage engines. Be careful. \n" if $dbinfo[5] > 1; - $result{'Databases'}{ $dbinfo[0] }{'Rows'} = $dbinfo[1]; - $result{'Databases'}{ $dbinfo[0] }{'Tables'} = $dbinfo[6]; - $result{'Databases'}{ $dbinfo[0] }{'Collations'} = $dbinfo[7]; - $result{'Databases'}{ $dbinfo[0] }{'Data Size'} = $dbinfo[2]; + $result{'Databases'}{ $dbinfo[0] }{'Rows'} = $dbinfo[1]; + $result{'Databases'}{ $dbinfo[0] }{'Tables'} = $dbinfo[6]; + $result{'Databases'}{ $dbinfo[0] }{'Collations'} = $dbinfo[7]; + $result{'Databases'}{ $dbinfo[0] }{'Data Size'} = $dbinfo[2]; $result{'Databases'}{ $dbinfo[0] }{'Data Pct'} = percentage( $dbinfo[2], $dbinfo[4] ) . "%"; $result{'Databases'}{ $dbinfo[0] }{'Index Size'} = $dbinfo[3]; $result{'Databases'}{ $dbinfo[0] }{'Index Pct'} = percentage( $dbinfo[3], $dbinfo[4] ) . "%"; $result{'Databases'}{ $dbinfo[0] }{'Total Size'} = $dbinfo[4]; - if ($dbinfo[7]>1) { - badprint $dbinfo[7]. " differents collations for database ".$dbinfo[0]; - push(@generalrec, "Check all table collations are identical for all tables in ".$dbinfo[0]. " database."); - } else { - goodprint $dbinfo[7]. " collation for ".$dbinfo[0]. " database."; - } - if ($dbinfo[8]>1) { - badprint $dbinfo[8]. " differents engines for database ".$dbinfo[0]; - push(@generalrec, "Check all table engines are identical for all tables in ".$dbinfo[0]. " database."); - } else { - goodprint $dbinfo[8]. " engine for ".$dbinfo[0]. " database."; - } - - my @distinct_column_charset=select_array("select DISTINCT(CHARACTER_SET_NAME) from information_schema.COLUMNS where CHARACTER_SET_NAME IS NOT NULL AND TABLE_SCHEMA ='$_'"); - infoprint "Charsets for $dbinfo[0] database table column: ". join (', ', @distinct_column_charset); - if (scalar (@distinct_column_charset)>1 ) { - badprint $dbinfo[0]. " table column(s) has several charsets defined for all text like column(s)."; - push(@generalrec, "Limit charset for column to one charset if possible for ".$dbinfo[0]." database."); - } else { - goodprint $dbinfo[0]. " table column(s) has same charset defined for all text like column(s)."; - } - my @distinct_column_collation=select_array("select DISTINCT(COLLATION_NAME) from information_schema.COLUMNS where COLLATION_NAME IS NOT NULL AND TABLE_SCHEMA ='$_'"); - infoprint "Collations for $dbinfo[0] database table column: ". join (', ', @distinct_column_collation); - if (scalar (@distinct_column_collation)>1 ) { - badprint $dbinfo[0]. " table column(s) has several collations defined for all text like column(s)."; - push(@generalrec, "Limit collations for column to one collation if possible for ".$dbinfo[0]." database."); - } else { - goodprint $dbinfo[0]. " table column(s) has same collation defined for all text like column(s)."; + if ( $dbinfo[7] > 1 ) { + badprint $dbinfo[7] + . " differents collations for database " + . $dbinfo[0]; + push( @generalrec, + "Check all table collations are identical for all tables in " + . $dbinfo[0] + . " database." ); + } + else { + goodprint $dbinfo[7] + . " collation for " + . $dbinfo[0] + . " database."; + } + if ( $dbinfo[8] > 1 ) { + badprint $dbinfo[8] + . " differents engines for database " + . $dbinfo[0]; + push( @generalrec, + "Check all table engines are identical for all tables in " + . $dbinfo[0] + . " database." ); + } + else { + goodprint $dbinfo[8] . " engine for " . $dbinfo[0] . " database."; + } + + my @distinct_column_charset = select_array( +"select DISTINCT(CHARACTER_SET_NAME) from information_schema.COLUMNS where CHARACTER_SET_NAME IS NOT NULL AND TABLE_SCHEMA ='$_'" + ); + infoprint "Charsets for $dbinfo[0] database table column: " + . join( ', ', @distinct_column_charset ); + if ( scalar(@distinct_column_charset) > 1 ) { + badprint $dbinfo[0] + . " table column(s) has several charsets defined for all text like column(s)."; + push( @generalrec, + "Limit charset for column to one charset if possible for " + . $dbinfo[0] + . " database." ); + } + else { + goodprint $dbinfo[0] + . " table column(s) has same charset defined for all text like column(s)."; + } + + my @distinct_column_collation = select_array( +"select DISTINCT(COLLATION_NAME) from information_schema.COLUMNS where COLLATION_NAME IS NOT NULL AND TABLE_SCHEMA ='$_'" + ); + infoprint "Collations for $dbinfo[0] database table column: " + . join( ', ', @distinct_column_collation ); + if ( scalar(@distinct_column_collation) > 1 ) { + badprint $dbinfo[0] + . " table column(s) has several collations defined for all text like column(s)."; + push( @generalrec, + "Limit collations for column to one collation if possible for " + . $dbinfo[0] + . " database." ); + } + else { + goodprint $dbinfo[0] + . " table column(s) has same collation defined for all text like column(s)."; + } } - } - + } # Recommendations for Indexes metrics @@ -3191,9 +3354,10 @@ sub mysql_indexes { "\n-------- Indexes Metrics -----------------------------------------------------"; unless ( mysql_version_ge( 5, 5 ) ) { infoprint -"Skip Index metrics from information schema missing in this version"; + "Skip Index metrics from information schema missing in this version"; return; } + # unless ( mysql_version_ge( 5, 6 ) ) { # infoprint #"Skip Index metrics from information schema due to erronous information provided in this version"; @@ -3246,7 +3410,7 @@ ENDSQL infoprint " +-- NB COLS : " . $info[3] . " column(s)"; infoprint " +-- CARDINALITY : " . $info[4] . " distinct values"; infoprint " +-- NB ROWS : " . $info[5] . " rows"; - infoprint " +-- TYPE : " . $info[6] ; + infoprint " +-- TYPE : " . $info[6]; infoprint " +-- SELECTIVITY : " . $info[7] . "%"; $result{'Indexes'}{ $info[1] }{'Colunm'} = $info[0]; @@ -3259,7 +3423,7 @@ ENDSQL if ( $info[7] < 25 ) { badprint "$info[1] has a low selectivity"; } - } + } return unless ( defined( $myvar{'performance_schema'} ) @@ -3304,8 +3468,7 @@ sub make_recommendations { foreach (@adjvars) { prettyprint " " . $_ . ""; } } if ( @generalrec == 0 && @adjvars == 0 ) { - prettyprint - "No additional performance recommendations are available."; + prettyprint "No additional performance recommendations are available."; } } @@ -3321,18 +3484,19 @@ sub headerprint { } sub string2file { - my $filename=shift; - my $content=shift; - open my $fh, q(>), $filename - or die "Unable to open $filename in write mode. Please check permissions for this file or directory"; - print $fh $content if defined($content); - close $fh; - debugprint $content if ($opt{'debug'}); + my $filename = shift; + my $content = shift; + open my $fh, q(>), $filename + or die +"Unable to open $filename in write mode. Please check permissions for this file or directory"; + print $fh $content if defined($content); + close $fh; + debugprint $content if ( $opt{'debug'} ); } sub file2array { my $filename = shift; - debugprint "* reading $filename" if ($opt{'debug'}); + debugprint "* reading $filename" if ( $opt{'debug'} ); my $fh; open( $fh, q(<), "$filename" ) or die "Couldn't open $filename for reading: $!\n"; @@ -3342,15 +3506,16 @@ sub file2array { } sub file2string { - return join ( '', file2array(@_) ); + return join( '', file2array(@_) ); } my $templateModel; -if ($opt{'template'} ne 0 ) { - $templateModel=file2string ($opt{'template'}); -}else { - # DEFAULT REPORT TEMPLATE - $templateModel=<<'END_TEMPLATE'; +if ( $opt{'template'} ne 0 ) { + $templateModel = file2string( $opt{'template'} ); +} +else { + # DEFAULT REPORT TEMPLATE + $templateModel = <<'END_TEMPLATE'; @@ -3368,41 +3533,47 @@ if ($opt{'template'} ne 0 ) { END_TEMPLATE } + sub dump_result { - if ($opt{'debug'}) { - debugprint Dumper( \%result ); + if ( $opt{'debug'} ) { + debugprint Dumper( \%result ); } debugprint "HTML REPORT: $opt{'reportfile'}"; - if ($opt{'reportfile'} ne 0 ) { - eval "{ use Text::Template }"; - if ($@) { - badprint "Text::Template Module is needed."; - exit 1; - } + if ( $opt{'reportfile'} ne 0 ) { + eval "{ use Text::Template }"; + if ($@) { + badprint "Text::Template Module is needed."; + exit 1; + } - my $vars= {'data' => Dumper( \%result ) }; + my $vars = { 'data' => Dumper( \%result ) }; - my $template; - { - no warnings 'once'; - $template = Text::Template->new(TYPE => 'STRING', PREPEND => q{;}, SOURCE => $templateModel) - or die "Couldn't construct template: $Text::Template::ERROR"; - } - open my $fh, q(>), $opt{'reportfile'} - or die "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; + my $template; + { + no warnings 'once'; + $template = Text::Template->new( + TYPE => 'STRING', + PREPEND => q{;}, + SOURCE => $templateModel + ) or die "Couldn't construct template: $Text::Template::ERROR"; + } + open my $fh, q(>), $opt{'reportfile'} + or die +"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; } - if ($opt{'json'} ne 0 ) { - eval "{ use JSON }"; - if ($@) { - badprint "JSON Module is needed."; - exit 1; - } - my $json = JSON->new->allow_nonref; - print $json->utf8(1)->pretty(($opt{'prettyjson'} ? 1 : 0))->encode(\%result); + if ( $opt{'json'} ne 0 ) { + eval "{ use JSON }"; + if ($@) { + badprint "JSON Module is needed."; + exit 1; + } + my $json = JSON->new->allow_nonref; + print $json->utf8(1)->pretty( ( $opt{'prettyjson'} ? 1 : 0 ) ) + ->encode( \%result ); } } @@ -3426,7 +3597,7 @@ cve_recommendations; # Display related CVE calculations; # Calculate everything we need mysql_stats; # Print the server stats mysqsl_pfs # Print Performance schema info -mariadb_threadpool; # Print MaraiDB ThreadPool stats + mariadb_threadpool; # Print MaraiDB ThreadPool stats mysql_myisam; # Print MyISAM stats mariadb_ariadb; # Print MaraiDB AriaDB stats mysql_innodb; # Print InnoDB stats From bbf0db87d5120dd9f607bdae7b2f7a6c19d11bf7 Mon Sep 17 00:00:00 2001 From: Jean-Marie Renouard Date: Tue, 29 Mar 2016 14:32:52 +0200 Subject: [PATCH 058/126] Update .travis.yml --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index f0fc025..f1ce64b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -35,4 +35,4 @@ install: - cpanm --quiet --notest JSON script: - - ./mysqltuner.pl -idxstat --dbstat + - ./mysqltuner.pl --idxstat --dbstat From 21e5fe895ed0680779f914a3629568e920ac448f Mon Sep 17 00:00:00 2001 From: root Date: Tue, 29 Mar 2016 14:41:33 +0200 Subject: [PATCH 059/126] Changing travis tests for 5.2 tests --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index f1ce64b..0c1963a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -35,4 +35,4 @@ install: - cpanm --quiet --notest JSON script: - - ./mysqltuner.pl --idxstat --dbstat + - ./mysqltuner.pl --idxstat --dbstat --user travis -pass '' From 48a346ee0cbc6f135fee75d5a7626f5df0c05fcb Mon Sep 17 00:00:00 2001 From: root Date: Tue, 29 Mar 2016 14:52:54 +0200 Subject: [PATCH 060/126] Trying to fix travis config. --- .travis.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index 0c1963a..acd34a7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,14 +14,14 @@ perl: matrix: include: - addons: - mariadb: 5.5 - perl: 5.20 + mariadb: "5.5" + perl: "5.20" - addons: - mariadb: 10.0 - perl: 5.20 + mariadb: "10.0" + perl: "5.20" - addons: - mariadb: 10.1 - perl: 5.20 + mariadb: "10.1" + perl: "5.20" before_install: - git clone git://github.com/haarg/perl-travis-helper From 3d9660807a9b582370b2c1bff0f2805d9c503021 Mon Sep 17 00:00:00 2001 From: root Date: Tue, 29 Mar 2016 15:12:17 +0200 Subject: [PATCH 061/126] Missing - in command option pass --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index acd34a7..8106686 100644 --- a/.travis.yml +++ b/.travis.yml @@ -35,4 +35,4 @@ install: - cpanm --quiet --notest JSON script: - - ./mysqltuner.pl --idxstat --dbstat --user travis -pass '' + - ./mysqltuner.pl --idxstat --dbstat --user travis --pass '' From 598da33e91bfbfbc6e3e073a21a53b90f88a39c1 Mon Sep 17 00:00:00 2001 From: root Date: Tue, 29 Mar 2016 17:28:12 +0200 Subject: [PATCH 062/126] new version --- .travis.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 8106686..853a9c7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -35,4 +35,6 @@ install: - cpanm --quiet --notest JSON script: - - ./mysqltuner.pl --idxstat --dbstat --user travis --pass '' + - echo -e "[client]\nuser=root\npassword=\"\"" > .my.cnf + - chmod 600 .my.cnf + - ./mysqltuner.pl --idxstat --dbstat From 45c468f32436287b99a505a2b601fc2c609a241b Mon Sep 17 00:00:00 2001 From: Sergei A Mamonov Date: Wed, 30 Mar 2016 14:44:30 +0300 Subject: [PATCH 063/126] add fixes to get_os_release for debian 6/7/8 --- mysqltuner.pl | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/mysqltuner.pl b/mysqltuner.pl index 6a24c33..173a43d 100755 --- a/mysqltuner.pl +++ b/mysqltuner.pl @@ -1062,10 +1062,31 @@ sub get_other_process_memory { } sub get_os_release { - return "Unknown OS release" unless -f "/etc/system-release"; - my @info_release = get_file_contents "/etc/system-release"; - remove_cr @info_release; - return $info_release[0]; + if( -f "/etc/system-release") { + my @info_release = get_file_contents "/etc/system-release"; + remove_cr @info_release; + return $info_release[0]; + } + + if ( -f "/etc/os-release") { + my @info_release = get_file_contents "/etc/os-release"; + remove_cr @info_release; + my $os_relase = $info_release[0]; + $os_relase =~ s/.*="//; + $os_relase =~ s/"$//; + return $os_relase; + } + + if ( -f "/etc/issue") { + my @info_release = get_file_contents "/etc/issue"; + remove_cr @info_release; + my $os_relase = $info_release[0]; + $os_relase =~ s/\s+\\n.*//; + return $os_relase; + } + + return "Unknown OS release"; + } sub get_fs_info() { From ff796b48bf5681f9be213fb69d9b1e4d17546509 Mon Sep 17 00:00:00 2001 From: Sergei A Mamonov Date: Wed, 30 Mar 2016 15:59:47 +0300 Subject: [PATCH 064/126] fix mount point output for linux --- mysqltuner.pl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mysqltuner.pl b/mysqltuner.pl index 173a43d..77c8e6a 100755 --- a/mysqltuner.pl +++ b/mysqltuner.pl @@ -1091,11 +1091,11 @@ sub get_os_release { sub get_fs_info() { my @sinfo = `df -P | grep '%'`; - shift @sinfo; my @iinfo = `df -Pi| grep '%'`; shift @iinfo; map { s/.*\s(\d+)%\s+(.*)/$1\t$2/g } @sinfo; foreach my $info (@sinfo) { + next if $info =~ m{(\d+)\t/(run|dev|sys|proc)($|/)}; if ( $info =~ /(\d+)\t(.*)/ ) { if ( $1 > 85 ) { badprint "mount point $2 is using $1 % total space"; @@ -1109,6 +1109,7 @@ sub get_fs_info() { map { s/.*\s(\d+)%\s+(.*)/$1\t$2/g } @iinfo; foreach my $info (@iinfo) { + next if $info =~ m{(\d+)\t/(run|dev|sys|proc)($|/)}; if ( $info =~ /(\d+)\t(.*)/ ) { if ( $1 > 85 ) { badprint "mount point $2 is using $1 % of max allowed inodes"; From c74d51e065a8995094d2ea24117bc86c87bedcd6 Mon Sep 17 00:00:00 2001 From: root Date: Wed, 30 Mar 2016 17:16:16 +0200 Subject: [PATCH 065/126] system information are only available with --sysstat #165 --- mysqltuner.pl | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/mysqltuner.pl b/mysqltuner.pl index 173a43d..aa645db 100755 --- a/mysqltuner.pl +++ b/mysqltuner.pl @@ -79,6 +79,7 @@ my %opt = ( "outputfile" => 0, "dbstat" => 0, "idxstat" => 0, + "sysstat" => 0, "skippassword" => 0, "noask" => 0, "template" => 0, @@ -107,7 +108,7 @@ my $getOptionsCheck = GetOptions( 'template=s', 'reportfile=s', 'cvefile=s', 'bannedports=s', 'updateversion', 'maxportallowed=s', - 'verbose' + 'verbose', 'sysstat' ); #If params are incorrect return help @@ -156,6 +157,7 @@ sub usage { . " --debug Print debug information\n" . " --dbstat Print database information\n" . " --idxstat Print index information\n" + . "--sysstat Print system information\n" . " --bannedports Ports banned separated by comma(,)\n" . " --maxportallowed Number of ports opened allowed on this hosts\n" . " --cvefile CVE File for vulnerability checks\n" @@ -186,6 +188,7 @@ if ( $opt{verbose} ) { $opt{checkversion} = 1; #Check for updates to MySQLTuner $opt{dbstat} = 1; #Print database information $opt{idxstat} = 1; #Print index information + $opt{sysstat} = 1; #Print index information $opt{buffers} = 1; #Print global and per-thread buffer values $opt{cvefile} = 'vulnerabilities.csv'; #CVE File for vulnerability checks } @@ -1197,6 +1200,7 @@ sub get_system_info() { } sub system_recommendations { + return if ( $opt{sysstat} == 0 ); prettyprint "\n-------- System Linux Recommendations ---------------------------------------"; my $os = `uname`; @@ -3681,6 +3685,7 @@ You must provide the remote server's total memory when connecting to other serve --debug Print debug information --dbstat Print database information --idxstat Print index information + --sysstat Print system information --bannedports Ports banned separated by comma(,) --maxportallowed Number of ports opened allowed on this hosts --cvefile CVE File for vulnerability checks From 6f5f5c4b45b3a200175a2ad935d8eff24987ee7f Mon Sep 17 00:00:00 2001 From: root Date: Wed, 30 Mar 2016 17:24:44 +0200 Subject: [PATCH 066/126] removing mariaDB 10.1 as test from travis - temporary --- .travis.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 853a9c7..a38ba37 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,9 +19,9 @@ matrix: - addons: mariadb: "10.0" perl: "5.20" - - addons: - mariadb: "10.1" - perl: "5.20" +# - addons: +# mariadb: "10.1" +# perl: "5.20" before_install: - git clone git://github.com/haarg/perl-travis-helper From 292cbfedad72a56717e14526bc48e48758b77076 Mon Sep 17 00:00:00 2001 From: Christine Date: Mon, 4 Apr 2016 12:12:09 +0200 Subject: [PATCH 067/126] Adding some sysctl control in sysstat mode --- mysqltuner.pl | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/mysqltuner.pl b/mysqltuner.pl index 0d228c7..3b7f4db 100755 --- a/mysqltuner.pl +++ b/mysqltuner.pl @@ -1159,6 +1159,44 @@ sub infocmd_one { return join ', ', @result; } + +sub get_kernel_info() +{ + my @params=('fs.aio-max-nr', 'fs.aio-nr', 'fs.file-max', 'sunrpc.tcp_fin_timeout', + 'sunrpc.tcp_max_slot_table_entries', 'sunrpc.tcp_slot_table_entries', + 'vm.swappiness'); + infoprint "Informations about kernel tuning:"; + foreach my $param (@params) { + infocmd_tab("sysctl $param"); + } + if (`sysctl -n vm.swappiness` > 10) { + badprint "Swappiness is > 10, please consider having a value lower than 10"; + push @generalrec, "setup swappieness lower or equals to 10"; + push @adjvars, 'vm.swappiness <= 10 (echo 0 > /proc/sys/vm/swappiness)'; + } else { + infoprint "Swappiness is < 10."; + } + + if (`sysctl -n sunrpc.tcp_slot_table_entries` < 100) { + badprint "Initial TCP slot entries is < 1M, please consider having a value greater than 100"; + push @generalrec, "setup Initial TCP slot entries greater than 100"; + push @adjvars, 'sunrpc.tcp_slot_table_entries > 100 (echo 128 > /proc/sys/sunrpc/tcp_slot_table_entries)'; + } else { + infoprint "TCP slot entries is > 100."; + } + + + if (`sysctl -n fs.aio-max-nr` < 1000000) { + badprint "Max running total of the number of events is < 1M, please consider having a value greater than 1M"; + push @generalrec, "setup Max running number events greater than 1M"; + push @adjvars, 'fs.aio-max-nr > 1M (echo 1048576 > /proc/sys/fs/aio-max-nr)'; + } else { + infoprint "Max Number of AIO events is > 1M."; + } + +} + + sub get_system_info() { infoprint get_os_release; if (is_virtual_machine) { @@ -1272,6 +1310,7 @@ sub system_recommendations { } get_fs_info; + get_kernel_info; } sub security_recommendations { From c9cea2cc800cb15345305680c3e64fd4919f5635 Mon Sep 17 00:00:00 2001 From: Christine Date: Mon, 4 Apr 2016 13:58:52 +0200 Subject: [PATCH 068/126] #177 bug with free -h changed to free -mwq --- mysqltuner.pl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mysqltuner.pl b/mysqltuner.pl index 3b7f4db..f244b53 100755 --- a/mysqltuner.pl +++ b/mysqltuner.pl @@ -1230,8 +1230,8 @@ sub get_system_info() { . infocmd_one "grep 'nameserver' /etc/resolv.conf \| awk '{print \$2}'"; infoprint "Logged In users : "; infocmd_tab "who"; - infoprint "Ram Usages : "; - infocmd_tab "free -h | grep -v +"; + infoprint "Ram Usages in Mb : "; + infocmd_tab "free -m | grep -v +"; infoprint "Load Average : "; infocmd_tab "top -n 1 -b | grep 'load average:'"; From 8203dcd686af015c1b5fbba877caff0d69382ac3 Mon Sep 17 00:00:00 2001 From: "Jean-Marie RENOUARDjmrenouard@gmail.com" Date: Mon, 4 Apr 2016 11:23:43 -0400 Subject: [PATCH 069/126] Dumping galera options and status #150 --- mysqltuner.pl | 37 ++++++++++++++++++++++++++++++------- 1 file changed, 30 insertions(+), 7 deletions(-) diff --git a/mysqltuner.pl b/mysqltuner.pl index f244b53..4077877 100755 --- a/mysqltuner.pl +++ b/mysqltuner.pl @@ -907,7 +907,6 @@ sub get_all_vars { $result{'Variables'}{$1} = $2; debugprint "V: $1 = $2"; } - my @mysqlstatlist = select_array "SHOW /*!50000 GLOBAL */ STATUS"; foreach my $line (@mysqlstatlist) { $line =~ /([a-zA-Z_]*)\s*(.*)/; @@ -915,7 +914,11 @@ sub get_all_vars { $result{'Status'}{$1} = $2; debugprint "S: $1 = $2"; } - + $myvar{'have_galera'} = "NO"; + if (defined($myvar{'wsrep_provider_options'})) { + $myvar{'have_galera'} = "YES"; + debugprint "Galera options: ". $myvar{'wsrep_provider_options'}; + } # Workaround for MySQL bug #59393 wrt. ignore-builtin-innodb if ( ( $myvar{'ignore_builtin_innodb'} || "" ) eq "ON" ) { $myvar{'have_innodb'} = "NO"; @@ -970,6 +973,7 @@ sub get_all_vars { sub remove_cr { map { s/\n$//g; } @_; + map { s/^\s+$//g; } @_; } sub remove_empty { @@ -1445,8 +1449,8 @@ sub security_recommendations { sub get_replication_status { prettyprint -"\n-------- Replication Metrics -------------------------------------------------"; - +"\n-------- Replication Metrics -------------------------------------------------"; + infoprint "Galera Synchronous replication: ". $myvar{'have_galera'}; if ( scalar( keys %myslaves ) == 0 ) { infoprint "No replication slave(s) for this server."; } @@ -2998,6 +3002,14 @@ sub mariadb_tokudb { # All is to done here } +# Perl trim function to remove whitespace from the start and end of the string +sub trim { + my $string = shift; + $string =~ s/^\s+//; + $string =~ s/\s+$//; + return $string; +} + # Recommendations for Galera sub mariadb_galera { prettyprint @@ -3005,15 +3017,26 @@ sub mariadb_galera { # AriaDB unless ( defined $myvar{'have_galera'} - && $myvar{'have_galera'} eq "YES" - && defined $enginestats{'Galera'} ) + && $myvar{'have_galera'} eq "YES" ) { infoprint "Galera is disabled."; return; } infoprint "Galera is enabled."; - # All is to done here + infoprint "Galera Options:"; + my @galera_options=split /;/,$myvar{'wsrep_provider_options'} ; + remove_cr @galera_options; + @galera_options=remove_empty @galera_options; + foreach my $gparam ( @galera_options ) { + infoprint "\t".trim($gparam); + } + infoprint "Galera status:"; + foreach my $gstatus ( keys %mystat ) { + next unless $gstatus =~ /^wsrep.*/; + infoprint "\t".trim($gstatus). " = ".$mystat{$gstatus}; + } + } # Recommendations for InnoDB From 3ef98d83c184d5241b7756545228ebce7af9b259 Mon Sep 17 00:00:00 2001 From: "Jean-Marie RENOUARDjmrenouard@gmail.com" Date: Mon, 4 Apr 2016 11:30:16 -0400 Subject: [PATCH 070/126] Dumping mysql options for galera* #150 --- mysqltuner.pl | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/mysqltuner.pl b/mysqltuner.pl index 4077877..6ccc3cc 100755 --- a/mysqltuner.pl +++ b/mysqltuner.pl @@ -3023,6 +3023,12 @@ sub mariadb_galera { return; } infoprint "Galera is enabled."; + infoprint "Galera variables:"; + foreach my $gvar ( keys %myvar ) { + next unless $gvar =~ /^wsrep.*/; + next if $gvar eq 'wsrep_provider_options'; + infoprint "\t".trim($gvar). " = ".$myvar{$gvar}; + } infoprint "Galera Options:"; my @galera_options=split /;/,$myvar{'wsrep_provider_options'} ; From 2d483e6b755de67b6db9bfd1711b9900b6a363a0 Mon Sep 17 00:00:00 2001 From: "Jean-Marie RENOUARDjmrenouard@gmail.com" Date: Mon, 4 Apr 2016 12:32:35 -0400 Subject: [PATCH 071/126] Check tables are all innodb table and check all table gets pk #150 --- mysqltuner.pl | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/mysqltuner.pl b/mysqltuner.pl index 6ccc3cc..4d69c14 100755 --- a/mysqltuner.pl +++ b/mysqltuner.pl @@ -3041,7 +3041,25 @@ sub mariadb_galera { foreach my $gstatus ( keys %mystat ) { next unless $gstatus =~ /^wsrep.*/; infoprint "\t".trim($gstatus). " = ".$mystat{$gstatus}; - } + } + my @primaryKeysNbTables=select_array("select CONCAT(table_schema,CONCAT('.', table_name)) from information_schema.columns where table_schema not in ('mysql', 'information_schema', 'performance_schema') group by table_schema,table_name having sum(if(column_key in ('PRI','UNI'), 1,0)) = 0"); + if (scalar (@primaryKeysNbTables) > 0 ) { + badprint "Following table(s) don't have primary key:"; + foreach my $badtable( @primaryKeysNbTables ) { + badprint "\t$badtable"; + } + } else { + goodprint "All tables get a primary key"; + } + my @nonInnoDbTables=select_array("select CONCAT(table_schema,CONCAT('.', table_name)) from information_schema.tables where ENGINE <> 'InnoDb' and table_schema not in ('mysql', 'performance_schema', 'information_schema')"); + if (scalar (@nonInnoDbTables) > 0 ) { + badprint "Following table(s) are not InnoDB table:"; + foreach my $badtable( @nonInnoDbTables ) { + badprint "\t$badtable"; + } + } else { + goodprint "All tables are InnoDB tables"; + } } From 974bd03ddfac11b97623633ce6cc3c9614cf13a5 Mon Sep 17 00:00:00 2001 From: "Jean-Marie RENOUARDjmrenouard@gmail.com" Date: Tue, 5 Apr 2016 05:16:52 -0400 Subject: [PATCH 072/126] Adding new control for Galera cluster #150 --- mysqltuner.pl | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/mysqltuner.pl b/mysqltuner.pl index 4d69c14..e86c7fb 100755 --- a/mysqltuner.pl +++ b/mysqltuner.pl @@ -3030,7 +3030,7 @@ sub mariadb_galera { infoprint "\t".trim($gvar). " = ".$myvar{$gvar}; } - infoprint "Galera Options:"; + infoprint "Galera wsrep provider Options:"; my @galera_options=split /;/,$myvar{'wsrep_provider_options'} ; remove_cr @galera_options; @galera_options=remove_empty @galera_options; @@ -3054,13 +3054,46 @@ sub mariadb_galera { my @nonInnoDbTables=select_array("select CONCAT(table_schema,CONCAT('.', table_name)) from information_schema.tables where ENGINE <> 'InnoDb' and table_schema not in ('mysql', 'performance_schema', 'information_schema')"); if (scalar (@nonInnoDbTables) > 0 ) { badprint "Following table(s) are not InnoDB table:"; + push @generalrec, "Ensure that all table(s) are InnoDB tabls for Galera replication"; foreach my $badtable( @nonInnoDbTables ) { badprint "\t$badtable"; } } else { goodprint "All tables are InnoDB tables"; } + if ($myvar{'binlog_format'} ne 'ROW') { + badprint "Binlog format should be in ROW mode."; + push @adjvars, "binlog_format = ROW"; + } else { + goodprint "Binlog format is in ROW mode."; + } + if ($myvar{'innodb_flush_log_at_trx_commit'} != 0 ) { + badprint "Innodb flush log at each commit should be disabled."; + push @adjvars, "innodb_flush_log_at_trx_commit = 0"; + } else { + goodprint "Innodb flush log at each commit is disabled for Galera."; + } + infoprint "Read consistency mode :". $myvar{'wsrep_causal_reads'}; + + if ( defined($myvar{'wsrep_cluster_name'}) and $myvar{'wsrep_on'} eq "ON" ) { + goodprint "Galera WsREP is enabled."; + } else { + badprint "Galera Wsesp is disabled"; + } + if ( defined($myvar{'wsrep_cluster_address'}) and trim("$myvar{'wsrep_cluster_address'}") ne "") { + goodprint "Galera Cluster address is defined: ".$myvar{'wsrep_cluster_address'}; + } else { + badprint "Galera Cluster address is undefined"; + push @adjvars, "set up wsrep_cluster_address variable for Galera replication"; + } + + if ( defined($myvar{'wsrep_cluster_name'}) and trim($myvar{'wsrep_cluster_name'}) ne "") { + goodprint "Galera Cluster name is defined: ".$myvar{'wsrep_cluster_name'}; + } else { + badprint "Galera Cluster name is undefined"; + push @adjvars, "set up wsrep_cluster_name variable for Galera replication"; + } } # Recommendations for InnoDB From 89ade050a765c496e8a9b48bb39c1e2aada6c551 Mon Sep 17 00:00:00 2001 From: "Jean-Marie RENOUARDjmrenouard@gmail.com" Date: Tue, 5 Apr 2016 09:18:10 -0400 Subject: [PATCH 073/126] Update Internals checks documentation --- INTERNALS.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/INTERNALS.md b/INTERNALS.md index d24b3c4..dbefe6f 100644 --- a/INTERNALS.md +++ b/INTERNALS.md @@ -70,6 +70,12 @@ * Check 80, 8080, 443 and 8443 ports if warning are raised if there are opened * Check if some banned ports are not opened (option --bannedports separated by comma) * Check if non kernel and user process except mysqld are not using more than 15% of total physical memory) +* Check vm.swapiness +* Check /etc/security/limit.conf +* Check sysctl entries: sunrpc.tcp_slot_entries, vm.swappiness, fs.aio-fs-nr +* Check mount point +* Check Ethernet card +* Check load average ## MySQLTuner Server version checks * EOL MySQL version check From 97cce402ae090e80708405c1d3c16cdf3ca23f65 Mon Sep 17 00:00:00 2001 From: "Jean-Marie RENOUARDjmrenouard@gmail.com" Date: Tue, 5 Apr 2016 09:49:43 -0400 Subject: [PATCH 074/126] Adding get_http_cli for curl or wget detecting in sysstat --- mysqltuner.pl | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/mysqltuner.pl b/mysqltuner.pl index e86c7fb..2113de6 100755 --- a/mysqltuner.pl +++ b/mysqltuner.pl @@ -418,6 +418,20 @@ sub os_setup { } +sub get_http_cli { + my $httpcli = `which curl`; + chomp($httpcli); + if ( defined($httpcli) and -e "$httpcli" ) { + return $httpcli; + } + + $httpcli = `which wget`; + chomp($httpcli); + if ( defined($httpcli) and -e "$httpcli" ) { + return $httpcli; + } + return ""; +} # Checks for updates to MySQLTuner sub validate_tuner_version { if ( $opt{'checkversion'} eq 0 and $opt{'updateversion'} eq 0 ) { @@ -443,6 +457,8 @@ sub validate_tuner_version { compare_tuner_version($update); return; + } else { + } $httpcli = `which wget`; @@ -1210,7 +1226,7 @@ sub get_system_info() { infoprint "Machine type : Physical machine"; } - `ping -c 1 google.com &>/dev/null`; + `ping -c 1 ipecho.net &>/dev/null`; my $isConnected = $?; if ( $? == 0 ) { infoprint "Internet : Connected"; @@ -1224,12 +1240,12 @@ sub get_system_info() { infoprint "Network Cards : "; infocmd_tab "ifconfig| grep -A1 mtu"; infoprint "Internal IP : " . infocmd_one "hostname -I"; + my $httpcli=get_http_cli(); + infoprint "HTTP client found: $httpcli" if defined $httpcli; infoprint "External IP : " - . infocmd_one "curl -s ipecho.net/plain" - if $isConnected == 0; + . infocmd_one "$httpcli ipecho.net/plain" if defined ($httpcli); badprint - "External IP : Can't check because of Internet connectivity" - if $isConnected != 0; + "External IP : Can't check because of Internet connectivity" unless defined($httpcli); infoprint "Name Servers : " . infocmd_one "grep 'nameserver' /etc/resolv.conf \| awk '{print \$2}'"; infoprint "Logged In users : "; From a5449a0d22cb8ced2fa6a310a94b0d1d3aa9d98f Mon Sep 17 00:00:00 2001 From: "Jean-Marie RENOUARDjmrenouard@gmail.com" Date: Tue, 5 Apr 2016 11:40:38 -0400 Subject: [PATCH 075/126] Adding performance_schema.memoty value to max_used_memory and max_peak_memory calculation There is always MySQL 5.7+ and adaptaive memory usage to handle porperly --- mysqltuner.pl | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/mysqltuner.pl b/mysqltuner.pl index 2113de6..deccf52 100755 --- a/mysqltuner.pl +++ b/mysqltuner.pl @@ -1923,14 +1923,14 @@ sub calculations { # Max used memory is memory used by MySQL based on Max_used_connections # This is the max memory used theorically calculated with the max concurrent connection number reached by mysql $mycalc{'max_used_memory'} = - $mycalc{'server_buffers'} + $mycalc{"max_total_per_thread_buffers"}; + $mycalc{'server_buffers'} + $mycalc{"max_total_per_thread_buffers"} +get_pf_memory(); $mycalc{'pct_max_used_memory'} = percentage( $mycalc{'max_used_memory'}, $physical_memory ); # Total possible memory is memory needed by MySQL based on max_connections # This is the max memory MySQL can theorically used if all connections allowed has opened by mysql $mycalc{'max_peak_memory'} = - $mycalc{'server_buffers'} + $mycalc{'total_per_thread_buffers'}; + $mycalc{'server_buffers'} + $mycalc{'total_per_thread_buffers'} + get_pf_memory(); $mycalc{'pct_max_physical_memory'} = percentage( $mycalc{'max_peak_memory'}, $physical_memory ); @@ -1943,7 +1943,7 @@ sub calculations { . hr_bytes( $mycalc{'max_peak_memory'} ) . ""; debugprint "Max Peak Percentage RAM: " . $mycalc{'pct_max_physical_memory'} . "%"; - + # Slow queries $mycalc{'pct_slow_queries'} = int( ( $mystat{'Slow_queries'} / $mystat{'Questions'} ) * 100 ); @@ -2275,7 +2275,7 @@ sub mysql_stats { . " global + " . hr_bytes( $mycalc{'per_thread_buffers'} ) . " per thread ($myvar{'max_connections'} max threads)"; - + infoprint "P_S Max memory usage: ".hr_bytes_rnd(get_pf_memory()); if ( $opt{buffers} ne 0 ) { infoprint "Global Buffers"; infoprint " +-- Key Buffer: " @@ -2913,6 +2913,13 @@ sub mariadb_threadpool { } } +sub get_pf_memory +{ + + my @infoPFSMemory=grep /performance_schema.memory/, select_array("SHOW ENGINE PERFORMANCE_SCHEMA STATUS"); + $infoPFSMemory[0] =~ s/.*\s+(\d+)$/$1/g; + return $infoPFSMemory[0]; +} # Recommendations for Performance Schema sub mysqsl_pfs { prettyprint @@ -2927,6 +2934,7 @@ sub mysqsl_pfs { else { infoprint "Performance schema is enabled."; } + infoprint "Memory used by P_S: ". hr_bytes(get_pf_memory()); } # Recommendations for Ariadb @@ -3758,7 +3766,7 @@ cve_recommendations; # Display related CVE calculations; # Calculate everything we need mysql_stats; # Print the server stats mysqsl_pfs # Print Performance schema info - mariadb_threadpool; # Print MaraiDB ThreadPool stats +mariadb_threadpool; # Print MaraiDB ThreadPool stats mysql_myisam; # Print MyISAM stats mariadb_ariadb; # Print MaraiDB AriaDB stats mysql_innodb; # Print InnoDB stats From 83010dd32ef09a1d7edf9e65bc3a1af0306a2ae6 Mon Sep 17 00:00:00 2001 From: "Jean-Marie RENOUARDjmrenouard@gmail.com" Date: Tue, 5 Apr 2016 12:25:20 -0400 Subject: [PATCH 076/126] Bug fix on aria metrics --- mysqltuner.pl | 51 +++++++++++++++++++++++++++++++++++---------------- 1 file changed, 35 insertions(+), 16 deletions(-) diff --git a/mysqltuner.pl b/mysqltuner.pl index deccf52..e1086f9 100755 --- a/mysqltuner.pl +++ b/mysqltuner.pl @@ -966,7 +966,7 @@ sub get_all_vars { $result{'Storage Engines'}{$engine} = $2; } } - + debugprint Dumper(@mysqlenginelist); my @mysqlslave = select_array "SHOW SLAVE STATUS\\G"; foreach my $line (@mysqlslave) { @@ -1923,14 +1923,14 @@ sub calculations { # Max used memory is memory used by MySQL based on Max_used_connections # This is the max memory used theorically calculated with the max concurrent connection number reached by mysql $mycalc{'max_used_memory'} = - $mycalc{'server_buffers'} + $mycalc{"max_total_per_thread_buffers"} +get_pf_memory(); + $mycalc{'server_buffers'} + $mycalc{"max_total_per_thread_buffers"} +get_pf_memory() + get_gcache_memory(); $mycalc{'pct_max_used_memory'} = percentage( $mycalc{'max_used_memory'}, $physical_memory ); # Total possible memory is memory needed by MySQL based on max_connections # This is the max memory MySQL can theorically used if all connections allowed has opened by mysql $mycalc{'max_peak_memory'} = - $mycalc{'server_buffers'} + $mycalc{'total_per_thread_buffers'} + get_pf_memory(); + $mycalc{'server_buffers'} + $mycalc{'total_per_thread_buffers'} + get_pf_memory()+ get_gcache_memory(); $mycalc{'pct_max_physical_memory'} = percentage( $mycalc{'max_peak_memory'}, $physical_memory ); @@ -2055,7 +2055,7 @@ sub calculations { if ( defined $mycalc{'total_aria_indexes'} and $mycalc{'total_aria_indexes'} == 0 ) { - $mycalc{'total_aria_indexes'} = "fail"; + $mycalc{'total_aria_indexes'} = 1; } elsif ( defined $mycalc{'total_aria_indexes'} ) { chomp( $mycalc{'total_aria_indexes'} ); @@ -2276,6 +2276,7 @@ sub mysql_stats { . hr_bytes( $mycalc{'per_thread_buffers'} ) . " per thread ($myvar{'max_connections'} max threads)"; infoprint "P_S Max memory usage: ".hr_bytes_rnd(get_pf_memory()); + infoprint "Galera GCache Max memory usage: ".hr_bytes_rnd(get_gcache_memory()); if ( $opt{buffers} ne 0 ) { infoprint "Global Buffers"; infoprint " +-- Key Buffer: " @@ -2944,8 +2945,7 @@ sub mariadb_ariadb { # AriaDB unless ( defined $myvar{'have_aria'} - && $myvar{'have_aria'} eq "YES" - && defined $enginestats{'Aria'} ) + and $myvar{'have_aria'} eq "YES" ) { infoprint "AriaDB is disabled."; return; @@ -3034,12 +3034,31 @@ sub trim { return $string; } +sub get_wsrep_options { + return () unless defined $myvar{'wsrep_provider_options'} ; + + my @galera_options=split /;/,$myvar{'wsrep_provider_options'} ; + remove_cr @galera_options; + @galera_options=remove_empty @galera_options; + return @galera_options; +} +sub get_gcache_memory { + return 0 unless defined $myvar{'wsrep_provider_options'} ; + + my @galera_options=get_wsrep_options; + return 0 unless scalar(@galera_options) >0; + my @memValues= grep /gcache.mem_size/, @galera_options; + my $memValue=$memValues[0]; + $memValue =~ s/.*=\s*(\d+)$/$1/g; + return $memValue; + +} # Recommendations for Galera sub mariadb_galera { prettyprint "\n-------- Galera Metrics ------------------------------------------------------"; - # AriaDB + # Galera Cluster unless ( defined $myvar{'have_galera'} && $myvar{'have_galera'} eq "YES" ) { @@ -3047,26 +3066,26 @@ sub mariadb_galera { return; } infoprint "Galera is enabled."; - infoprint "Galera variables:"; + debugprint "Galera variables:"; foreach my $gvar ( keys %myvar ) { next unless $gvar =~ /^wsrep.*/; next if $gvar eq 'wsrep_provider_options'; - infoprint "\t".trim($gvar). " = ".$myvar{$gvar}; + debugprint "\t".trim($gvar). " = ".$myvar{$gvar}; } - infoprint "Galera wsrep provider Options:"; - my @galera_options=split /;/,$myvar{'wsrep_provider_options'} ; - remove_cr @galera_options; - @galera_options=remove_empty @galera_options; + debugprint "Galera wsrep provider Options:"; + my @galera_options=get_wsrep_options; foreach my $gparam ( @galera_options ) { - infoprint "\t".trim($gparam); + debugprint "\t".trim($gparam); } - infoprint "Galera status:"; + debugprint "Galera status:"; foreach my $gstatus ( keys %mystat ) { next unless $gstatus =~ /^wsrep.*/; - infoprint "\t".trim($gstatus). " = ".$mystat{$gstatus}; + debugprint "\t".trim($gstatus). " = ".$mystat{$gstatus}; } + infoprint "GCache is using ".hr_bytes_rnd(get_gcache_memory()); my @primaryKeysNbTables=select_array("select CONCAT(table_schema,CONCAT('.', table_name)) from information_schema.columns where table_schema not in ('mysql', 'information_schema', 'performance_schema') group by table_schema,table_name having sum(if(column_key in ('PRI','UNI'), 1,0)) = 0"); + if (scalar (@primaryKeysNbTables) > 0 ) { badprint "Following table(s) don't have primary key:"; foreach my $badtable( @primaryKeysNbTables ) { From 15854a6c94d78d4b4a942af4832edd1bbd1bcac5 Mon Sep 17 00:00:00 2001 From: "Jean-Marie RENOUARDjmrenouard@gmail.com" Date: Tue, 5 Apr 2016 12:34:24 -0400 Subject: [PATCH 077/126] #138 for threadpool in mariadb and percona use default values --- mysqltuner.pl | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/mysqltuner.pl b/mysqltuner.pl index e1086f9..c1a9696 100755 --- a/mysqltuner.pl +++ b/mysqltuner.pl @@ -2876,6 +2876,12 @@ sub mariadb_threadpool { infoprint "ThreadPool stat is enabled."; infoprint "Thread Pool Size: " . $myvar{'thread_pool_size'} . " thread(s)."; + if ($myvar{'version'} =~ /mariadb|percona/i ) { + infoprint "Using default value is good enougth for your version (".$myvar{'version'}.")"; + return; + } + + if ( $myvar{'have_innodb'} eq 'YES' ) { if ( $myvar{'thread_pool_size'} < 16 or $myvar{'thread_pool_size'} > 36 ) From 8f0c2e6b3380c14584116c6f3ad4874e64951c9b Mon Sep 17 00:00:00 2001 From: Robert Milasan Date: Wed, 6 Apr 2016 10:33:56 +0200 Subject: [PATCH 078/126] Fix Galera checks, make sure we dont say that Galera is enabled when is not, clean-up typos --- mysqltuner.pl | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/mysqltuner.pl b/mysqltuner.pl index c1a9696..6269799 100755 --- a/mysqltuner.pl +++ b/mysqltuner.pl @@ -931,7 +931,7 @@ sub get_all_vars { debugprint "S: $1 = $2"; } $myvar{'have_galera'} = "NO"; - if (defined($myvar{'wsrep_provider_options'})) { + if ( defined($myvar{'wsrep_provider_options'}) && $myvar{'wsrep_provider_options'} ne "") { $myvar{'have_galera'} = "YES"; debugprint "Galera options: ". $myvar{'wsrep_provider_options'}; } @@ -1477,7 +1477,7 @@ sub get_replication_status { } if ( scalar( keys %myrepl ) == 0 and scalar( keys %myslaves ) == 0 ) { - infoprint "This is a standalone server.."; + infoprint "This is a standalone server."; return; } if ( scalar( keys %myrepl ) == 0 ) { @@ -3127,22 +3127,21 @@ sub mariadb_galera { if ( defined($myvar{'wsrep_cluster_name'}) and $myvar{'wsrep_on'} eq "ON" ) { goodprint "Galera WsREP is enabled."; + if ( defined($myvar{'wsrep_cluster_address'}) and trim("$myvar{'wsrep_cluster_address'}") ne "") { + goodprint "Galera Cluster address is defined: ".$myvar{'wsrep_cluster_address'}; + } else { + badprint "Galera Cluster address is undefined"; + push @adjvars, "set up wsrep_cluster_address variable for Galera replication"; + } + if ( defined($myvar{'wsrep_cluster_name'}) and trim($myvar{'wsrep_cluster_name'}) ne "") { + goodprint "Galera Cluster name is defined: ".$myvar{'wsrep_cluster_name'}; + } else { + badprint "Galera Cluster name is undefined"; + push @adjvars, "set up wsrep_cluster_name variable for Galera replication"; + } } else { - badprint "Galera Wsesp is disabled"; + badprint "Galera WsREP is disabled"; } - if ( defined($myvar{'wsrep_cluster_address'}) and trim("$myvar{'wsrep_cluster_address'}") ne "") { - goodprint "Galera Cluster address is defined: ".$myvar{'wsrep_cluster_address'}; - } else { - badprint "Galera Cluster address is undefined"; - push @adjvars, "set up wsrep_cluster_address variable for Galera replication"; - } - - if ( defined($myvar{'wsrep_cluster_name'}) and trim($myvar{'wsrep_cluster_name'}) ne "") { - goodprint "Galera Cluster name is defined: ".$myvar{'wsrep_cluster_name'}; - } else { - badprint "Galera Cluster name is undefined"; - push @adjvars, "set up wsrep_cluster_name variable for Galera replication"; - } } # Recommendations for InnoDB From 845dc030e1bc1ba367109e76daa4fb45e85e8271 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 11 Apr 2016 12:01:01 +0200 Subject: [PATCH 079/126] Using a generic sub header function get_pf_memory return 0 for performance memory if P_F is disabled. --- mysqltuner.pl | 76 ++++++++++++++++++++++++++++----------------------- 1 file changed, 42 insertions(+), 34 deletions(-) diff --git a/mysqltuner.pl b/mysqltuner.pl index 6269799..5d43784 100755 --- a/mysqltuner.pl +++ b/mysqltuner.pl @@ -212,11 +212,16 @@ open( $fh, '>', $outputfile ) if defined($outputfile); $opt{nocolor} = 1 if defined($outputfile); +# Setting up the colors for the print styles +my $me=`whoami`; +$me =~s/\n//g; # Setting up the colors for the print styles my $good = ( $opt{nocolor} == 0 ) ? "[\e[0;32mOK\e[0m]" : "[OK]"; my $bad = ( $opt{nocolor} == 0 ) ? "[\e[0;31m!!\e[0m]" : "[!!]"; my $info = ( $opt{nocolor} == 0 ) ? "[\e[0;34m--\e[0m]" : "[--]"; my $deb = ( $opt{nocolor} == 0 ) ? "[\e[0;31mDG\e[0m]" : "[DG]"; +my $cmd = ( $opt{nocolor} == 0 ) ? "\e[1;32m[CMD]($me)" : "[CMD]($me)"; +my $end = ( $opt{nocolor} == 0 ) ? "\e[0m" : ""; # Super structure containing all information my %result; @@ -238,6 +243,24 @@ sub redwrap { sub greenwrap { return ( $opt{nocolor} == 0 ) ? "\e[0;32m" . $_[0] . "\e[0m" : $_[0]; } +sub cmdprint { prettyprint $cmd." ". $_[0]. $end; } +sub infoprintml { for my $ln(@_) { $ln =~s/\n//g; infoprint "\t$ln"; } } +sub infoprintcmd { cmdprint "@_"; infoprintml grep { $_ ne '' and $_ !~ /^\s*$/ } `@_ 2>&1`; } +sub subheaderprint { + my $tln=100; + my $sln=8; + my $ln=length("@_")+2; + + prettyprint " "; + #prettyprint "-"x$tln; + prettyprint "-"x$sln ." @_ ". "-"x($tln-$ln-$sln); + #prettyprint "-"x$tln; +} +sub infoprinthcmd { +# print Dumper @_; + subheaderprint "$_[0]"; + infoprintcmd "$_[1]"; +} # Calculates the parameter passed in bytes, then rounds it to one decimal place sub hr_bytes { @@ -1010,8 +1033,7 @@ sub get_basic_passwords { } sub cve_recommendations { - prettyprint -"\n-------- CVE Security Recommendations ---------------------------------------"; + subheaderprint"CVE Security Recommendations"; unless ( defined( $opt{cvefile} ) && -f "$opt{cvefile}" ) { infoprint "Skipped due to --cvefile option undefined"; return; @@ -1260,8 +1282,7 @@ sub get_system_info() { sub system_recommendations { return if ( $opt{sysstat} == 0 ); - prettyprint -"\n-------- System Linux Recommendations ---------------------------------------"; + subheaderprint"System Linux Recommendations"; my $os = `uname`; unless ( $os =~ /Linux/i ) { infoprint "Skipped due to non Linux server"; @@ -1334,8 +1355,7 @@ sub system_recommendations { } sub security_recommendations { - prettyprint -"\n-------- Security Recommendations -------------------------------------------"; + subheaderprint "Security Recommendations"; if ( $opt{skippassword} eq 1 ) { infoprint "Skipped due to --skippassword option"; return; @@ -1464,8 +1484,7 @@ sub security_recommendations { } sub get_replication_status { - prettyprint -"\n-------- Replication Metrics -------------------------------------------------"; + subheaderprint "Replication Metrics"; infoprint "Galera Synchronous replication: ". $myvar{'have_galera'}; if ( scalar( keys %myslaves ) == 0 ) { infoprint "No replication slave(s) for this server."; @@ -1628,13 +1647,11 @@ my ( %enginestats, %enginecount, $fragtables ); sub check_storage_engines { if ( $opt{skipsize} eq 1 ) { - prettyprint -"\n-------- Storage Engine Statistics -------------------------------------------"; + subheaderprint "Storage Engine Statistics"; infoprint "Skipped due to --skipsize option"; return; } - prettyprint -"\n-------- Storage Engine Statistics -------------------------------------------"; + subheaderprint "Storage Engine Statistics"; my $engines; if ( mysql_version_ge( 5, 5 ) ) { @@ -2234,8 +2251,7 @@ sub calculations { } sub mysql_stats { - prettyprint -"\n-------- Performance Metrics -------------------------------------------------"; + subheaderprint "Performance Metrics"; # Show uptime, queries per second, connections, traffic stats my $qps; @@ -2737,8 +2753,7 @@ sub mysql_stats { # Recommendations for MyISAM sub mysql_myisam { - prettyprint -"\n-------- MyISAM Metrics ------------------------------------------------------"; + subheaderprint "MyISAM Metrics"; # Key buffer usage if ( defined( $mycalc{'pct_key_buffer_used'} ) ) { @@ -2863,8 +2878,7 @@ sub mysql_myisam { # Recommendations for ThreadPool sub mariadb_threadpool { - prettyprint -"\n-------- ThreadPool Metrics --------------------------------------------------"; + subheaderprint "ThreadPool Metrics"; # AriaDB unless ( defined $myvar{'have_threadpool'} @@ -2922,6 +2936,8 @@ sub mariadb_threadpool { sub get_pf_memory { + # Performance Schema + return 0 unless ( defined( $myvar{'performance_schema'} ) and $myvar{'performance_schema'} eq 'ON' ); my @infoPFSMemory=grep /performance_schema.memory/, select_array("SHOW ENGINE PERFORMANCE_SCHEMA STATUS"); $infoPFSMemory[0] =~ s/.*\s+(\d+)$/$1/g; @@ -2929,8 +2945,7 @@ sub get_pf_memory } # Recommendations for Performance Schema sub mysqsl_pfs { - prettyprint -"\n-------- Performance schema --------------------------------------------------"; + subheaderprint "Performance schema"; # Performance Schema unless ( defined( $myvar{'performance_schema'} ) @@ -2946,8 +2961,7 @@ sub mysqsl_pfs { # Recommendations for Ariadb sub mariadb_ariadb { - prettyprint -"\n-------- AriaDB Metrics ------------------------------------------------------"; + subheaderprint "AriaDB Metrics"; # AriaDB unless ( defined $myvar{'have_aria'} @@ -3016,8 +3030,7 @@ sub mariadb_ariadb { # Recommendations for TokuDB sub mariadb_tokudb { - prettyprint -"\n-------- TokuDB Metrics ------------------------------------------------------"; + subheaderprint "TokuDB Metrics"; # AriaDB unless ( defined $myvar{'have_tokudb'} @@ -3061,8 +3074,7 @@ sub get_gcache_memory { } # Recommendations for Galera sub mariadb_galera { - prettyprint -"\n-------- Galera Metrics ------------------------------------------------------"; + subheaderprint "Galera Metrics"; # Galera Cluster unless ( defined $myvar{'have_galera'} @@ -3146,8 +3158,7 @@ sub mariadb_galera { # Recommendations for InnoDB sub mysql_innodb { - prettyprint -"\n-------- InnoDB Metrics ------------------------------------------------------"; + subheaderprint "InnoDB Metrics"; # InnoDB unless ( defined $myvar{'have_innodb'} @@ -3358,8 +3369,7 @@ sub mysql_innodb { sub mysql_databases { return if ( $opt{dbstat} == 0 ); - prettyprint -"\n-------- Database Metrics ----------------------------------------------------"; + subheaderprint "Database Metrics"; unless ( mysql_version_ge( 5, 5 ) ) { infoprint "Skip Database metrics from information schema missing in this version"; @@ -3543,8 +3553,7 @@ sub mysql_databases { sub mysql_indexes { return if ( $opt{idxstat} == 0 ); - prettyprint -"\n-------- Indexes Metrics -----------------------------------------------------"; + subheaderprint "Indexes Metrics"; unless ( mysql_version_ge( 5, 5 ) ) { infoprint "Skip Index metrics from information schema missing in this version"; @@ -3645,8 +3654,7 @@ ENDSQL # Take the two recommendation arrays and display them at the end of the output sub make_recommendations { - prettyprint -"\n-------- Recommendations -----------------------------------------------------"; + subheaderprint "Recommendations"; if ( @generalrec > 0 ) { prettyprint "General recommendations:"; foreach (@generalrec) { prettyprint " " . $_ . ""; } From d8a8dd42d3bf58d192f2a137a2df038adba70483 Mon Sep 17 00:00:00 2001 From: Jean-Marie RENOUARD Date: Mon, 11 Apr 2016 12:24:49 +0200 Subject: [PATCH 080/126] ident fix --- mysqltuner.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysqltuner.pl b/mysqltuner.pl index 93d7833..860743c 100755 --- a/mysqltuner.pl +++ b/mysqltuner.pl @@ -729,7 +729,7 @@ sub select_one { debugprint `$mysqlcmd $mysqllogin -Bse "$req" 2>&1`; exit $?; } - debugprint "select_array: return code : $?"; + debugprint "select_array: return code : $?"; chomp($result); return $result; } From eea101019e3db09d331b19957bb033097973c084 Mon Sep 17 00:00:00 2001 From: Ricardo Velhote Date: Wed, 13 Apr 2016 14:39:40 +0100 Subject: [PATCH 081/126] Detect Ubuntu correctly when checking for OS Release --- mysqltuner.pl | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/mysqltuner.pl b/mysqltuner.pl index 5d43784..8e43a9e 100755 --- a/mysqltuner.pl +++ b/mysqltuner.pl @@ -1107,6 +1107,15 @@ sub get_other_process_memory { } sub get_os_release { + if( -f "/etc/lsb-release") { + my @info_release = get_file_contents "/etc/lsb-release"; + remove_cr @info_release; + my $os_relase = $info_release[3]; + $os_relase =~ s/.*="//; + $os_relase =~ s/"$//; + return $os_relase; + } + if( -f "/etc/system-release") { my @info_release = get_file_contents "/etc/system-release"; remove_cr @info_release; From 67c80de3da43d285e7a73e09994fbcf6dfe601da Mon Sep 17 00:00:00 2001 From: root Date: Thu, 14 Apr 2016 19:27:14 +0200 Subject: [PATCH 082/126] Add a Code of Conduct from http://contributor-covenant.org/ --- CODE_OF_CONDUCT.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 CODE_OF_CONDUCT.md diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..c2b34e6 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,14 @@ +# Contributor Code of Conduct + +As contributors and maintainers of this project, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities. + +We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, age, or religion. + +Examples of unacceptable behavior by participants include the use of sexual language or imagery, derogatory comments or personal attacks, trolling, public or private harassment, insults, or other unprofessional conduct. + +Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. Project maintainers who do not follow the Code of Conduct may be removed from the project team. + +Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers. + +This Code of Conduct is adapted from the [Contributor Covenant](http:contributor-covenant.org), version 1.0.0, available at [http://contributor-covenant.org/version/1/0/0/](http://contributor-covenant.org/version/1/0/0/) + From 0ffe9507b660e35d76fbe86be5539f4dfb822523 Mon Sep 17 00:00:00 2001 From: root Date: Thu, 14 Apr 2016 22:42:59 +0200 Subject: [PATCH 083/126] #187 #183 removing unitialized variables code #184 adding merge between show global variables and show global variables #184 update RPM template' --- build/mysqltuner.spec.tpl | 2 +- mysqltuner.pl | 72 +++++++++++++++++++++++---------------- 2 files changed, 44 insertions(+), 30 deletions(-) diff --git a/build/mysqltuner.spec.tpl b/build/mysqltuner.spec.tpl index 1fde663..22c4027 100644 --- a/build/mysqltuner.spec.tpl +++ b/build/mysqltuner.spec.tpl @@ -46,6 +46,6 @@ rm -rf $RPM_BUILD_ROOT %{_mandir}/man1/* %changelog -* Thu Jan 5 2015 Jean-Marie RENOUARD %VERSION%-1 +* Thu Apr 14 20145 Jean-Marie RENOUARD %VERSION%-1 - Initial RPM release diff --git a/mysqltuner.pl b/mysqltuner.pl index 8e43a9e..af33278 100755 --- a/mysqltuner.pl +++ b/mysqltuner.pl @@ -157,7 +157,7 @@ sub usage { . " --debug Print debug information\n" . " --dbstat Print database information\n" . " --idxstat Print index information\n" - . "--sysstat Print system information\n" + . " --sysstat Print system information\n" . " --bannedports Ports banned separated by comma(,)\n" . " --maxportallowed Number of ports opened allowed on this hosts\n" . " --cvefile CVE File for vulnerability checks\n" @@ -933,31 +933,40 @@ sub get_tuning_info { # Populates all of the variable and status hashes my ( %mystat, %myvar, $dummyselect, %myrepl, %myslaves ); -sub get_all_vars { +sub arr2hash { + my $href=shift; + my $harr=shift; + my $sep=shift; + $sep='\s' unless defined($sep); + foreach my $line (@$harr) { + $line =~ /([a-zA-Z_]*)\s*$sep\s*(.*)/; + $$href{$1} = $2; + debugprint "V: $1 = $2"; + } +} +sub get_all_vars { # We need to initiate at least one query so that our data is useable $dummyselect = select_one "SELECT VERSION()"; debugprint "VERSION: " . $dummyselect . ""; $result{'MySQL Client'}{'Version'} = $dummyselect; - my @mysqlvarlist = select_array "SHOW /*!50000 GLOBAL */ VARIABLES"; - foreach my $line (@mysqlvarlist) { - $line =~ /([a-zA-Z_]*)\s*(.*)/; - $myvar{$1} = $2; - $result{'Variables'}{$1} = $2; - debugprint "V: $1 = $2"; - } - my @mysqlstatlist = select_array "SHOW /*!50000 GLOBAL */ STATUS"; - foreach my $line (@mysqlstatlist) { - $line =~ /([a-zA-Z_]*)\s*(.*)/; - $mystat{$1} = $2; - $result{'Status'}{$1} = $2; - debugprint "S: $1 = $2"; - } + + my @mysqlvarlist = select_array ("SHOW GLOBAL VARIABLES"); + push (@mysqlvarlist, select_array ("SHOW VARIABLES")); + arr2hash(\%myvar, \@mysqlvarlist); + $result{'Variables'}=%myvar; + + my @mysqlstatlist = select_array ("SHOW GLOBAL STATUS"); + push (@mysqlstatlist, select_array ("SHOW STATUS")); + arr2hash(\%mystat, \@mysqlstatlist); + $result{'Status'}=%mystat; + $myvar{'have_galera'} = "NO"; if ( defined($myvar{'wsrep_provider_options'}) && $myvar{'wsrep_provider_options'} ne "") { $myvar{'have_galera'} = "YES"; - debugprint "Galera options: ". $myvar{'wsrep_provider_options'}; + debugprint "Galera options: ". $myvar{'wsrep_provider_options'}; } + # Workaround for MySQL bug #59393 wrt. ignore-builtin-innodb if ( ( $myvar{'ignore_builtin_innodb'} || "" ) eq "ON" ) { $myvar{'have_innodb'} = "NO"; @@ -990,16 +999,9 @@ sub get_all_vars { } } debugprint Dumper(@mysqlenginelist); - my @mysqlslave = select_array "SHOW SLAVE STATUS\\G"; - - foreach my $line (@mysqlslave) { - if ( $line =~ /\s*(.*):\s*(.*)/ ) { - debugprint "$1 => $2"; - $myrepl{"$1"} = $2; - $result{'Replication'}{'Status'}{$1} = $2; - } - } - + my @mysqlslave = select_array("SHOW SLAVE STATUS\\G"); + arr2hash(\%myrepl, \@mysqlslave, ':'); + $result{'Replication'}{'Status'}=%myrepl; my @mysqlslaves = select_array "SHOW SLAVE HOSTS"; my @lineitems = (); foreach my $line (@mysqlslaves) { @@ -1138,9 +1140,7 @@ sub get_os_release { $os_relase =~ s/\s+\\n.*//; return $os_relase; } - return "Unknown OS release"; - } sub get_fs_info() { @@ -1178,6 +1178,20 @@ sub get_fs_info() { } } +sub merge_hash +{ + my $h1=shift; + my $h2=shift; + my %result={}; + foreach my $substanceref ( $h1, $h2 ) { + while ( my ($k, $v) = each %$substanceref) { + next if (exists $result{$k}); + $result{$k} = $v; + } + } + return \%result; +} + sub is_virtual_machine() { my $isVm = `grep -Ec '^flags.*\ hypervisor\ ' /proc/cpuinfo`; return ( $isVm == 0 ? 0 : 1 ); From ba584c91ccd1116980b86f70012ff8ee8c8c4281 Mon Sep 17 00:00:00 2001 From: root Date: Thu, 14 Apr 2016 22:49:21 +0200 Subject: [PATCH 084/126] Update version #183 --- mysqltuner.pl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/mysqltuner.pl b/mysqltuner.pl index af33278..58d0612 100755 --- a/mysqltuner.pl +++ b/mysqltuner.pl @@ -1,5 +1,5 @@ #!/usr/bin/env perl -# mysqltuner.pl - Version 1.6.9 +# mysqltuner.pl - Version 1.6.10 # High Performance MySQL Tuning Script # Copyright (C) 2006-2016 Major Hayden - major@mhtx.net # @@ -51,7 +51,7 @@ use Data::Dumper; $Data::Dumper::Pair = " : "; # Set up a few variables for use in the script -my $tunerversion = "1.6.9"; +my $tunerversion = "1.6.10"; my ( @adjvars, @generalrec ); # Set defaults @@ -966,7 +966,7 @@ sub get_all_vars { $myvar{'have_galera'} = "YES"; debugprint "Galera options: ". $myvar{'wsrep_provider_options'}; } - + # Workaround for MySQL bug #59393 wrt. ignore-builtin-innodb if ( ( $myvar{'ignore_builtin_innodb'} || "" ) eq "ON" ) { $myvar{'have_innodb'} = "NO"; @@ -3845,7 +3845,7 @@ __END__ =head1 NAME - MySQLTuner 1.6.8 - MySQL High Performance Tuning Script + MySQLTuner 1.6.10 - MySQL High Performance Tuning Script =head1 IMPORTANT USAGE GUIDELINES From d09cb777739bec7ee86be83baf7af883d0116a06 Mon Sep 17 00:00:00 2001 From: root Date: Thu, 14 Apr 2016 22:50:13 +0200 Subject: [PATCH 085/126] Update usage file --- USAGE.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/USAGE.md b/USAGE.md index c5fbc92..8742623 100644 --- a/USAGE.md +++ b/USAGE.md @@ -1,6 +1,6 @@ # NAME - MySQLTuner 1.6.8 - MySQL High Performance Tuning Script + MySQLTuner 1.6.10 - MySQL High Performance Tuning Script # IMPORTANT USAGE GUIDELINES @@ -39,6 +39,7 @@ You must provide the remote server's total memory when connecting to other serve --debug Print debug information --dbstat Print database information --idxstat Print index information + --sysstat Print system information --bannedports Ports banned separated by comma(,) --maxportallowed Number of ports opened allowed on this hosts --cvefile CVE File for vulnerability checks From 81100f3bba095b27f43c9edaa8286d7388a55d91 Mon Sep 17 00:00:00 2001 From: root Date: Thu, 14 Apr 2016 22:52:13 +0200 Subject: [PATCH 086/126] Last fix on template --- build/mysqltuner.spec.tpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/mysqltuner.spec.tpl b/build/mysqltuner.spec.tpl index 22c4027..e4cfcb8 100644 --- a/build/mysqltuner.spec.tpl +++ b/build/mysqltuner.spec.tpl @@ -46,6 +46,6 @@ rm -rf $RPM_BUILD_ROOT %{_mandir}/man1/* %changelog -* Thu Apr 14 20145 Jean-Marie RENOUARD %VERSION%-1 +* Thu Apr 14 2016 Jean-Marie RENOUARD %VERSION%-1 - Initial RPM release From 66a57af80b13a0141c424b0e1bc606200ba68fb6 Mon Sep 17 00:00:00 2001 From: root Date: Thu, 14 Apr 2016 23:11:18 +0200 Subject: [PATCH 087/126] #182 using abs value for result --- mysqltuner.pl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mysqltuner.pl b/mysqltuner.pl index 58d0612..8ad63de 100755 --- a/mysqltuner.pl +++ b/mysqltuner.pl @@ -3341,8 +3341,8 @@ sub mysql_innodb { && $mycalc{'pct_write_efficiency'} < 90 ) { badprint "InnoDB Write Log efficiency: " - . $mycalc{'pct_write_efficiency'} . "% (" - . ( $mystat{'Innodb_log_write_requests'} - + . abs($mycalc{'pct_write_efficiency'}) . "% (" + . abs( $mystat{'Innodb_log_write_requests'} - $mystat{'Innodb_log_writes'} ) . " hits/ " . $mystat{'Innodb_log_write_requests'} From 76a28ab29a98fc377db2a4899369b6a4a0be55fe Mon Sep 17 00:00:00 2001 From: Jean-Marie RENOUARD Date: Fri, 15 Apr 2016 06:33:05 -0400 Subject: [PATCH 088/126] Adding typo fixes Adding check for memory with other process --- mysqltuner.pl | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/mysqltuner.pl b/mysqltuner.pl index d8d0758..4b02a46 100755 --- a/mysqltuner.pl +++ b/mysqltuner.pl @@ -1236,7 +1236,7 @@ sub get_kernel_info() } if (`sysctl -n vm.swappiness` > 10) { badprint "Swappiness is > 10, please consider having a value lower than 10"; - push @generalrec, "setup swappieness lower or equals to 10"; + push @generalrec, "setup swappiness lower or equals to 10"; push @adjvars, 'vm.swappiness <= 10 (echo 0 > /proc/sys/vm/swappiness)'; } else { infoprint "Swappiness is < 10."; @@ -2309,6 +2309,11 @@ sub mysql_stats { } # Memory usage + + infoprint "Physical Memory : ". hr_bytes($physical_memory); + infoprint "Max MySQL memory : ". hr_bytes( $mycalc{'max_peak_memory'} ); + infoprint "Other process memory: ". hr_bytes( get_other_process_memory() ); + infoprint "Total buffers: " . hr_bytes( $mycalc{'server_buffers'} ) . " global + " @@ -2391,6 +2396,13 @@ sub mysql_stats { . " ($mycalc{'pct_max_physical_memory'}% of installed RAM)"; } + if ($physical_memory < ($mycalc{'max_peak_memory'}+get_other_process_memory())) { + badprint "Overall possible memory usage with other process exceeded memory"; + push( @generalrec, "Dedicated this server to your database for highest performance." ); + } else { + goodprint "Overall possible memory usage with other process is compatible with memory available"; + } + # Slow queries if ( $mycalc{'pct_slow_queries'} > 5 ) { badprint "Slow queries: $mycalc{'pct_slow_queries'}% (" @@ -2520,9 +2532,7 @@ sub mysql_stats { # Sorting if ( $mycalc{'total_sorts'} == 0 ) { - - # For the sake of space, we will be quiet here - # No sorts have run yet + goodprint "No Sort requiring temporary tables"; } elsif ( $mycalc{'pct_temp_sort_table'} > 10 ) { badprint @@ -2561,8 +2571,7 @@ sub mysql_stats { "Adjust your join queries to always utilize indexes" ); } else { - - # For the sake of space, we will be quiet here + goodprint "No joins without indexes"; # No joins have run without indexes } @@ -2617,9 +2626,7 @@ sub mysql_stats { } } else { - - # For the sake of space, we will be quiet here - # No temporary tables have been created + goodprint "No tmp tables created on disk"; } # Thread cache @@ -3403,7 +3410,7 @@ sub mysql_databases { infoprint "There is " . scalar(@dblist) . " Database(s)."; my @totaldbinfo = split /\s/, select_one( -"SELECT SUM(TABLE_ROWS), SUM(DATA_LENGTH), SUM(INDEX_LENGTH) , SUM(DATA_LENGTH+INDEX_LENGTH), COUNT(TABLE_NAME),COUNT(DISTINCT(TABLE_COLLATION)),COUNT(DISTINCT(ENGINE)) FROM information_schema.TABLES;" +"SELECT SUM(TABLE_ROWS), SUM(DATA_LENGTH), SUM(INDEX_LENGTH) , SUM(DATA_LENGTH+INDEX_LENGTH), COUNT(TABLE_NAME),COUNT(DISTINCT(TABLE_COLLATION)),COUNT(DISTINCT(ENGINE)) FROM information_schema.TABLES WHERE TABLE_SCHEMA NOT IN ( 'mysql' );" ); infoprint "All Databases:"; infoprint " +-- TABLE : " @@ -3447,8 +3454,7 @@ sub mysql_databases { if ( $_ eq "information_schema" or $_ eq "performance_schema" - - # or $_ eq "mysql" + or $_ eq "mysql" or $_ eq "" ) { From 612eea48fdc63cb3048944aabcbb6a05ec160dc1 Mon Sep 17 00:00:00 2001 From: Jean-Marie RENOUARD Date: Fri, 15 Apr 2016 10:17:56 -0400 Subject: [PATCH 089/126] All version for galera checks #150 --- mysqltuner.pl | 104 +++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 94 insertions(+), 10 deletions(-) diff --git a/mysqltuner.pl b/mysqltuner.pl index 4b02a46..357c322 100755 --- a/mysqltuner.pl +++ b/mysqltuner.pl @@ -3089,19 +3089,24 @@ sub get_wsrep_options { my @galera_options=split /;/,$myvar{'wsrep_provider_options'} ; remove_cr @galera_options; @galera_options=remove_empty @galera_options; + debugprint Dumper(\@galera_options); return @galera_options; } sub get_gcache_memory { - return 0 unless defined $myvar{'wsrep_provider_options'} ; - - my @galera_options=get_wsrep_options; - return 0 unless scalar(@galera_options) >0; - my @memValues= grep /gcache.mem_size/, @galera_options; - my $memValue=$memValues[0]; - $memValue =~ s/.*=\s*(\d+)$/$1/g; - return $memValue; - + return get_wsrep_option 'gcache.mem_size'; } +sub get_wsrep_option { + my $key=shift; + return '' unless defined $myvar{'wsrep_provider_options'} ; + my @galera_options=get_wsrep_options; + return '' unless scalar(@galera_options) >0; + my @memValues= grep /\s*$key =/, @galera_options; + my $memValue=$memValues[0]; + $memValue =~ s/.*=\s*(.+)$/$1/g; + return $memValue; +} + + # Recommendations for Galera sub mariadb_galera { subheaderprint "Galera Metrics"; @@ -3131,7 +3136,7 @@ sub mariadb_galera { next unless $gstatus =~ /^wsrep.*/; debugprint "\t".trim($gstatus). " = ".$mystat{$gstatus}; } - infoprint "GCache is using ".hr_bytes_rnd(get_gcache_memory()); + infoprint "GCache is using ".hr_bytes_rnd(get_wsrep_option('gcache.mem_size')); my @primaryKeysNbTables=select_array("select CONCAT(table_schema,CONCAT('.', table_name)) from information_schema.columns where table_schema not in ('mysql', 'information_schema', 'performance_schema') group by table_schema,table_name having sum(if(column_key in ('PRI','UNI'), 1,0)) = 0"); if (scalar (@primaryKeysNbTables) > 0 ) { @@ -3171,6 +3176,17 @@ sub mariadb_galera { goodprint "Galera WsREP is enabled."; if ( defined($myvar{'wsrep_cluster_address'}) and trim("$myvar{'wsrep_cluster_address'}") ne "") { goodprint "Galera Cluster address is defined: ".$myvar{'wsrep_cluster_address'}; + my $nbNodes=scalar(split /,/, $myvar{'wsrep_cluster_address'}); + if ( $nbNodes !=3 or $nbNodes != 5) { + goodprint "There is $nbNodes nodes."; + } else { + badprint "There is $nbNodes nodes. Prefer 3 or 5 nodes achitecture."; + } + if ($nbNodes != trim ($mystat{'wsrep_cluster_size'}) ) { + badprint "All cluster nodes dre not detected. wsrep_cluster_size != informations in wsrep_cluster_adress"; + } else { + badprint "All cluster nodes destected."; + } } else { badprint "Galera Cluster address is undefined"; push @adjvars, "set up wsrep_cluster_address variable for Galera replication"; @@ -3181,9 +3197,77 @@ sub mariadb_galera { badprint "Galera Cluster name is undefined"; push @adjvars, "set up wsrep_cluster_name variable for Galera replication"; } + if ( defined($myvar{'wsrep_node_name'}) and trim($myvar{'wsrep_node_name'}) ne "") { + goodprint "Galera Node name is defined: ".$myvar{'wsrep_node_name'}; + } else { + badprint "Galera node name is undefined"; + push @adjvars, "set up wsrep_node_name variable for Galera replication"; + } + if ( trim ($myvar{'wsrep_notify_cmd'}) ne "" ) { + goodprint "Galera Notify command is defined."; + } else { + badprint "Galera Notify command is not defined."; + push( @adjvars, "set up parameter wsrep_notify_cmd to be notify"); + } + if ( trim ($myvar{'wsrep_sst_method'}) ne "xtrabackup" ) { + badprint "Galera SST method is xtrabackup."; + push( @adjvars, "set up parameter wsrep_sst_method to xtrabackup"); + } else { + goodprint "SST Method is inot based on xtrabackup."; + } + if ( trim ($myvar{'wsrep_OSU_method'}) eq "TOI" ) { + goodprint "TOI is default mode for upgrade."; + } else { + badprint "Schema upgrade are not replicated automatically"; + push( @adjvars, "set up parameter wsrep_OSU_method to TOI"); + } + infoprint "Max WsRep message : " .hr_bytes( $myvar{'wsrep_max_ws_size'}); } else { badprint "Galera WsREP is disabled"; } + + + if (defined($mystat{'wsrep_connected'}) and $mystat{'wsrep_connected'} eq "ON") { + goodprint "Node is connected"; + } else { + badprint "Node is disconnected"; + } + if (defined($mystat{'wsrep_ready'}) and $mystat{'wsrep_ready'} eq "ON") { + goodprint "Node is ready"; + } else { + badprint "Node is not ready"; + } +infoprint "Cluster status :".$mystat{'wsrep_cluster_status'}; + if (defined($mystat{'wsrep_cluster_status'}) and $mystat{'wsrep_cluster_status'} eq "Primary") { + goodprint "Galera cluster is consistent and ready for operations"; + } else { + badprint "Cluster is not consistent and ready"; + } + if ($mystat{'wsrep_local_state_uuid'} eq $mystat{'wsrep_cluster_state_uuid'}) { + goodprint "Node and whole cluster at the same level: ".$mystat{'wsrep_cluster_state_uuid'}; + } else { + badprint "Node and whole cluster not the same level"; + infoprint "Node state uuid: ".$mystat{'wsrep_local_state_uuid'}; + infoprint "Cluster state uuid: ".$mystat{'wsrep_cluster_state_uuid'}; + } + if ($mystat{'wsrep_local_state_comment'} eq 'Synced' ) { + goodprint "Node is synced with whole cluster."; + } else { + badprint "Node is not synced"; + infoprint "Node State : ".$mystat{'wsrep_local_state_comment'}; + } + if ($mystat{'wsrep_local_cert_failures'} == 0 ) { + goodprint "There is no certification failures detected."; + } else { + badprint "There is ".$mystat{'wsrep_local_cert_failures'}." certification failure(s)detected."; + } + + for my $key (keys %mystat) { + if ($key =~ /wsrep_|galera/i) { + debugprint "WSREP: $key = $mystat{$key}"; + } + } + debugprint Dumper get_wsrep_options(); } # Recommendations for InnoDB From 86ad610b6c72e720399a99bffb7739a402b8bed2 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 18 Apr 2016 10:59:50 +0200 Subject: [PATCH 090/126] #189 fix memory calculation when Galera is disabled --- mysqltuner.pl | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/mysqltuner.pl b/mysqltuner.pl index 357c322..c174c00 100755 --- a/mysqltuner.pl +++ b/mysqltuner.pl @@ -3093,7 +3093,10 @@ sub get_wsrep_options { return @galera_options; } sub get_gcache_memory { - return get_wsrep_option 'gcache.mem_size'; + my $gCacheMem=get_wsrep_option('gcache.mem_size'); + + return 0 unless defined $gCacheMem and $gCacheMem ne ''; + return $gCacheMem; } sub get_wsrep_option { my $key=shift; From 80def039234b042dd5781e8ca4c3ddd7251e1644 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 18 Apr 2016 11:07:05 +0200 Subject: [PATCH 091/126] #187 enforce control over P_S activation --- mysqltuner.pl | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/mysqltuner.pl b/mysqltuner.pl index c174c00..1aee004 100755 --- a/mysqltuner.pl +++ b/mysqltuner.pl @@ -2967,9 +2967,11 @@ sub mariadb_threadpool { sub get_pf_memory { # Performance Schema - return 0 unless ( defined( $myvar{'performance_schema'} ) and $myvar{'performance_schema'} eq 'ON' ); - + return 0 unless defined $myvar{'performance_schema'}; + return 0 if $myvar{'performance_schema'} eq 'OFF'; + my @infoPFSMemory=grep /performance_schema.memory/, select_array("SHOW ENGINE PERFORMANCE_SCHEMA STATUS"); + return 0 if scalar(@infoPFSMemory)==0; $infoPFSMemory[0] =~ s/.*\s+(\d+)$/$1/g; return $infoPFSMemory[0]; } From bc2017ba3e7997ec2b79b9a5878e00341ff3d0e0 Mon Sep 17 00:00:00 2001 From: Sergei A Mamonov Date: Mon, 18 Apr 2016 17:45:34 +0300 Subject: [PATCH 092/126] change external which to sub which(), little fix for use get_http_cli and get external ip via wget --- mysqltuner.pl | 105 +++++++++++++++++++++++++++++--------------------- 1 file changed, 61 insertions(+), 44 deletions(-) diff --git a/mysqltuner.pl b/mysqltuner.pl index 1aee004..4c37e8b 100755 --- a/mysqltuner.pl +++ b/mysqltuner.pl @@ -50,6 +50,9 @@ use Cwd 'abs_path'; use Data::Dumper; $Data::Dumper::Pair = " : "; +# for which() +use Env; + # Set up a few variables for use in the script my $tunerversion = "1.6.10"; my ( @adjvars, @generalrec ); @@ -442,19 +445,20 @@ sub os_setup { } sub get_http_cli { - my $httpcli = `which curl`; + my $httpcli = which("curl", $PATH); chomp($httpcli); - if ( defined($httpcli) and -e "$httpcli" ) { - return $httpcli; + if ($httpcli) { + return $httpcli; } - $httpcli = `which wget`; + $httpcli = which("wget", $PATH); chomp($httpcli); - if ( defined($httpcli) and -e "$httpcli" ) { - return $httpcli; + if ($httpcli) { + return $httpcli; } return ""; } + # Checks for updates to MySQLTuner sub validate_tuner_version { if ( $opt{'checkversion'} eq 0 and $opt{'updateversion'} eq 0 ) { @@ -466,9 +470,8 @@ sub validate_tuner_version { my $update; my $url = "https://raw.githubusercontent.com/major/MySQLTuner-perl/master/mysqltuner.pl"; - my $httpcli = `which curl`; - chomp($httpcli); - if ( 1 != 1 and defined($httpcli) and -e "$httpcli" ) { + my $httpcli = get_http_cli(); + if ( $httpcli =~ /curl$/ ) { debugprint "$httpcli is available."; debugprint @@ -484,9 +487,7 @@ sub validate_tuner_version { } - $httpcli = `which wget`; - chomp($httpcli); - if ( defined($httpcli) and -e "$httpcli" ) { + if ($httpcli =~ /wget$/ ) { debugprint "$httpcli is available."; debugprint @@ -516,12 +517,11 @@ sub update_tuner_version { ( "mysqltuner.pl", "basic_passwords.txt", "vulnerabilities.csv" ); my $totalScripts = scalar(@scripts); my $receivedScripts = 0; - my $httpcli = `which curl`; + my $httpcli = get_http_cli(); foreach my $script (@scripts) { - chomp($httpcli); - if ( 1 != 1 and defined($httpcli) and -e "$httpcli" ) { + if ( $httpcli =~ /curl$/ ) { debugprint "$httpcli is available."; debugprint @@ -539,33 +539,29 @@ sub update_tuner_version { debugprint "$script updated: $update"; } } - else { + elsif ( $httpcli =~ /wget$/ ) { - $httpcli = `which wget`; - chomp($httpcli); - if ( defined($httpcli) and -e "$httpcli" ) { - debugprint "$httpcli is available."; + debugprint "$httpcli is available."; - debugprint - "$httpcli -qe timestamping=off -T 5 -O $script '$url$script'"; - $update = - `$httpcli -qe timestamping=off -T 5 -O $script '$url$script'`; - chomp($update); + debugprint + "$httpcli -qe timestamping=off -T 5 -O $script '$url$script'"; + $update = + `$httpcli -qe timestamping=off -T 5 -O $script '$url$script'`; + chomp($update); - if ( -s $script eq 0 ) { - badprint "Couldn't update $script"; - } - else { - ++$receivedScripts; - debugprint "$script updated: $update"; - } - - } - else { - debugprint "curl and wget are not available."; - infoprint "Unable to check for the latest MySQLTuner version"; - } - } + if ( -s $script eq 0 ) { + badprint "Couldn't update $script"; + } + else { + ++$receivedScripts; + debugprint "$script updated: $update"; + } + } + else { + debugprint "curl and wget are not available."; + infoprint "Unable to check for the latest MySQLTuner version"; + } + } if ( $receivedScripts eq $totalScripts ) { @@ -612,7 +608,7 @@ sub mysql_setup { $mysqladmincmd = $opt{mysqladmin}; } else { - $mysqladmincmd = `which mysqladmin`; + $mysqladmincmd = which("mysqladmin", $PATH); } chomp($mysqladmincmd); if ( !-e $mysqladmincmd && $opt{mysqladmin} ) { @@ -628,7 +624,7 @@ sub mysql_setup { $mysqlcmd = $opt{mysqlcmd}; } else { - $mysqlcmd = `which mysql`; + $mysqlcmd = which("mysql", $PATH); } chomp($mysqlcmd); if ( !-e $mysqlcmd && $opt{mysqlcmd} ) { @@ -705,7 +701,7 @@ sub mysql_setup { exit 1; } } - my $svcprop = `which svcprop 2>/dev/null`; + my $svcprop = which("svcprop", $PATH); if ( substr( $svcprop, 0, 1 ) =~ "/" ) { # We are on solaris @@ -1287,8 +1283,14 @@ sub get_system_info() { infoprint "Internal IP : " . infocmd_one "hostname -I"; my $httpcli=get_http_cli(); infoprint "HTTP client found: $httpcli" if defined $httpcli; - infoprint "External IP : " - . infocmd_one "$httpcli ipecho.net/plain" if defined ($httpcli); + if ( $httpcli =~ /curl$/) { + infoprint "External IP : " + . infocmd_one "$httpcli ipecho.net/plain"; + } + elsif ( $httpcli =~ /wget$/ ) { + infoprint "External IP : " + . infocmd_one "$httpcli -q -O - ipecho.net/plain"; + } badprint "External IP : Can't check because of Internet connectivity" unless defined($httpcli); infoprint "Name Servers : " @@ -3896,6 +3898,21 @@ sub dump_result { } } +sub which { + my $prog_name = shift; + my $path_string = shift; + my @path_array = split /:/, $PATH; + + for my $path ( @path_array) { + if ( -x "$path/$prog_name" ) { + return "$path/$prog_name"; + } + } + + return 0 +} + + # --------------------------------------------------------------------------- # BEGIN 'MAIN' # --------------------------------------------------------------------------- From b67bba859fcae0059265de7cb7e438bc6ec2fe83 Mon Sep 17 00:00:00 2001 From: root Date: Tue, 19 Apr 2016 16:03:42 +0200 Subject: [PATCH 093/126] adding extra information about wsrep cluster size #184 --- mysqltuner.pl | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/mysqltuner.pl b/mysqltuner.pl index 1aee004..06f39dd 100755 --- a/mysqltuner.pl +++ b/mysqltuner.pl @@ -3179,19 +3179,26 @@ sub mariadb_galera { if ( defined($myvar{'wsrep_cluster_name'}) and $myvar{'wsrep_on'} eq "ON" ) { goodprint "Galera WsREP is enabled."; - if ( defined($myvar{'wsrep_cluster_address'}) and trim("$myvar{'wsrep_cluster_address'}") ne "") { - goodprint "Galera Cluster address is defined: ".$myvar{'wsrep_cluster_address'}; - my $nbNodes=scalar(split /,/, $myvar{'wsrep_cluster_address'}); + if ( defined($myvar{'wsrep_cluster_address'}) and trim("$myvar{'wsrep_cluster_address'}") ne "") { + goodprint "Galera Cluster address is defined: ".$myvar{'wsrep_cluster_address'}; + my $nbNodes=scalar(split /,/, $myvar{'wsrep_cluster_address'}); if ( $nbNodes !=3 or $nbNodes != 5) { - goodprint "There is $nbNodes nodes."; + goodprint "There is $nbNodes nodes in wsrep_cluster_address."; } else { - badprint "There is $nbNodes nodes. Prefer 3 or 5 nodes achitecture."; - } + badprint "There is $nbNodes nodes in wsrep_cluster_address. Prefer 3 or 5 nodes achitecture."; + } + my $nbNodesSize=trim ($mystat{'wsrep_cluster_size'}); + if ( $nbNodesSize !=3 or $nbNodesSize != 5) { + goodprint "There is $nbNodes nodes in wsrep_cluster_size."; + } else { + badprint "There is $nbNodes nodes in wsrep_cluster_size. Prefer 3 or 5 nodes achitecture."; + } + if ($nbNodes != trim ($mystat{'wsrep_cluster_size'}) ) { - badprint "All cluster nodes dre not detected. wsrep_cluster_size != informations in wsrep_cluster_adress"; + badprint "All cluster nodes dre not detected. wsrep_cluster_size != informations in wsrep_cluster_adress"; } else { - badprint "All cluster nodes destected."; - } + badprint "All cluster nodes detected."; + } } else { badprint "Galera Cluster address is undefined"; push @adjvars, "set up wsrep_cluster_address variable for Galera replication"; From 5b55c92ac53f1ddf2cd1bb2d6c3c028c3e2207d3 Mon Sep 17 00:00:00 2001 From: root Date: Tue, 19 Apr 2016 16:11:35 +0200 Subject: [PATCH 094/126] #184: Additional information for galera Removing dependency to Env module #192 --- mysqltuner.pl | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/mysqltuner.pl b/mysqltuner.pl index fc873b1..3eacdb1 100755 --- a/mysqltuner.pl +++ b/mysqltuner.pl @@ -51,7 +51,7 @@ use Data::Dumper; $Data::Dumper::Pair = " : "; # for which() -use Env; +#use Env; # Set up a few variables for use in the script my $tunerversion = "1.6.10"; @@ -445,13 +445,13 @@ sub os_setup { } sub get_http_cli { - my $httpcli = which("curl", $PATH); + my $httpcli = which("curl", $ENV{'PATH'}); chomp($httpcli); if ($httpcli) { return $httpcli; } - $httpcli = which("wget", $PATH); + $httpcli = which("wget", $ENV{'PATH'}); chomp($httpcli); if ($httpcli) { return $httpcli; @@ -608,7 +608,7 @@ sub mysql_setup { $mysqladmincmd = $opt{mysqladmin}; } else { - $mysqladmincmd = which("mysqladmin", $PATH); + $mysqladmincmd = which("mysqladmin", $ENV{'PATH'}); } chomp($mysqladmincmd); if ( !-e $mysqladmincmd && $opt{mysqladmin} ) { @@ -624,7 +624,7 @@ sub mysql_setup { $mysqlcmd = $opt{mysqlcmd}; } else { - $mysqlcmd = which("mysql", $PATH); + $mysqlcmd = which("mysql", $ENV{'PATH'}); } chomp($mysqlcmd); if ( !-e $mysqlcmd && $opt{mysqlcmd} ) { @@ -701,7 +701,7 @@ sub mysql_setup { exit 1; } } - my $svcprop = which("svcprop", $PATH); + my $svcprop = which("svcprop", $ENV{'PATH'}); if ( substr( $svcprop, 0, 1 ) =~ "/" ) { # We are on solaris @@ -3908,7 +3908,7 @@ sub dump_result { sub which { my $prog_name = shift; my $path_string = shift; - my @path_array = split /:/, $PATH; + my @path_array = split /:/, $ENV{'PATH'}; for my $path ( @path_array) { if ( -x "$path/$prog_name" ) { From fa1639e418df2edd77dd170cca4a8a14a0683c3b Mon Sep 17 00:00:00 2001 From: root Date: Tue, 19 Apr 2016 16:19:31 +0200 Subject: [PATCH 095/126] Tidify code --- mysqltuner.pl | 724 ++++++++++++++++++++++++++++---------------------- 1 file changed, 408 insertions(+), 316 deletions(-) diff --git a/mysqltuner.pl b/mysqltuner.pl index 3eacdb1..671206f 100755 --- a/mysqltuner.pl +++ b/mysqltuner.pl @@ -216,15 +216,16 @@ open( $fh, '>', $outputfile ) $opt{nocolor} = 1 if defined($outputfile); # Setting up the colors for the print styles -my $me=`whoami`; -$me =~s/\n//g; +my $me = `whoami`; +$me =~ s/\n//g; + # Setting up the colors for the print styles -my $good = ( $opt{nocolor} == 0 ) ? "[\e[0;32mOK\e[0m]" : "[OK]"; -my $bad = ( $opt{nocolor} == 0 ) ? "[\e[0;31m!!\e[0m]" : "[!!]"; -my $info = ( $opt{nocolor} == 0 ) ? "[\e[0;34m--\e[0m]" : "[--]"; -my $deb = ( $opt{nocolor} == 0 ) ? "[\e[0;31mDG\e[0m]" : "[DG]"; -my $cmd = ( $opt{nocolor} == 0 ) ? "\e[1;32m[CMD]($me)" : "[CMD]($me)"; -my $end = ( $opt{nocolor} == 0 ) ? "\e[0m" : ""; +my $good = ( $opt{nocolor} == 0 ) ? "[\e[0;32mOK\e[0m]" : "[OK]"; +my $bad = ( $opt{nocolor} == 0 ) ? "[\e[0;31m!!\e[0m]" : "[!!]"; +my $info = ( $opt{nocolor} == 0 ) ? "[\e[0;34m--\e[0m]" : "[--]"; +my $deb = ( $opt{nocolor} == 0 ) ? "[\e[0;31mDG\e[0m]" : "[DG]"; +my $cmd = ( $opt{nocolor} == 0 ) ? "\e[1;32m[CMD]($me)" : "[CMD]($me)"; +my $end = ( $opt{nocolor} == 0 ) ? "\e[0m" : ""; # Super structure containing all information my %result; @@ -246,23 +247,35 @@ sub redwrap { sub greenwrap { return ( $opt{nocolor} == 0 ) ? "\e[0;32m" . $_[0] . "\e[0m" : $_[0]; } -sub cmdprint { prettyprint $cmd." ". $_[0]. $end; } -sub infoprintml { for my $ln(@_) { $ln =~s/\n//g; infoprint "\t$ln"; } } -sub infoprintcmd { cmdprint "@_"; infoprintml grep { $_ ne '' and $_ !~ /^\s*$/ } `@_ 2>&1`; } -sub subheaderprint { - my $tln=100; - my $sln=8; - my $ln=length("@_")+2; +sub cmdprint { prettyprint $cmd. " " . $_[0] . $end; } - prettyprint " "; - #prettyprint "-"x$tln; - prettyprint "-"x$sln ." @_ ". "-"x($tln-$ln-$sln); - #prettyprint "-"x$tln; +sub infoprintml { + for my $ln (@_) { $ln =~ s/\n//g; infoprint "\t$ln"; } } + +sub infoprintcmd { + cmdprint "@_"; + infoprintml grep { $_ ne '' and $_ !~ /^\s*$/ } `@_ 2>&1`; +} + +sub subheaderprint { + my $tln = 100; + my $sln = 8; + my $ln = length("@_") + 2; + + prettyprint " "; + + #prettyprint "-"x$tln; + prettyprint "-" x $sln . " @_ " . "-" x ( $tln - $ln - $sln ); + + #prettyprint "-"x$tln; +} + sub infoprinthcmd { -# print Dumper @_; - subheaderprint "$_[0]"; - infoprintcmd "$_[1]"; + + # print Dumper @_; + subheaderprint "$_[0]"; + infoprintcmd "$_[1]"; } # Calculates the parameter passed in bytes, then rounds it to one decimal place @@ -445,16 +458,16 @@ sub os_setup { } sub get_http_cli { - my $httpcli = which("curl", $ENV{'PATH'}); + my $httpcli = which( "curl", $ENV{'PATH'} ); chomp($httpcli); if ($httpcli) { - return $httpcli; + return $httpcli; } - - $httpcli = which("wget", $ENV{'PATH'}); + + $httpcli = which( "wget", $ENV{'PATH'} ); chomp($httpcli); if ($httpcli) { - return $httpcli; + return $httpcli; } return ""; } @@ -483,11 +496,12 @@ sub validate_tuner_version { compare_tuner_version($update); return; - } else { - + } + else { + } - if ($httpcli =~ /wget$/ ) { + if ( $httpcli =~ /wget$/ ) { debugprint "$httpcli is available."; debugprint @@ -541,27 +555,27 @@ sub update_tuner_version { } elsif ( $httpcli =~ /wget$/ ) { - debugprint "$httpcli is available."; + debugprint "$httpcli is available."; - debugprint - "$httpcli -qe timestamping=off -T 5 -O $script '$url$script'"; - $update = - `$httpcli -qe timestamping=off -T 5 -O $script '$url$script'`; - chomp($update); + debugprint + "$httpcli -qe timestamping=off -T 5 -O $script '$url$script'"; + $update = + `$httpcli -qe timestamping=off -T 5 -O $script '$url$script'`; + chomp($update); + + if ( -s $script eq 0 ) { + badprint "Couldn't update $script"; + } + else { + ++$receivedScripts; + debugprint "$script updated: $update"; + } + } + else { + debugprint "curl and wget are not available."; + infoprint "Unable to check for the latest MySQLTuner version"; + } - if ( -s $script eq 0 ) { - badprint "Couldn't update $script"; - } - else { - ++$receivedScripts; - debugprint "$script updated: $update"; - } - } - else { - debugprint "curl and wget are not available."; - infoprint "Unable to check for the latest MySQLTuner version"; - } - } if ( $receivedScripts eq $totalScripts ) { @@ -608,7 +622,7 @@ sub mysql_setup { $mysqladmincmd = $opt{mysqladmin}; } else { - $mysqladmincmd = which("mysqladmin", $ENV{'PATH'}); + $mysqladmincmd = which( "mysqladmin", $ENV{'PATH'} ); } chomp($mysqladmincmd); if ( !-e $mysqladmincmd && $opt{mysqladmin} ) { @@ -624,7 +638,7 @@ sub mysql_setup { $mysqlcmd = $opt{mysqlcmd}; } else { - $mysqlcmd = which("mysql", $ENV{'PATH'}); + $mysqlcmd = which( "mysql", $ENV{'PATH'} ); } chomp($mysqlcmd); if ( !-e $mysqlcmd && $opt{mysqlcmd} ) { @@ -701,7 +715,7 @@ sub mysql_setup { exit 1; } } - my $svcprop = which("svcprop", $ENV{'PATH'}); + my $svcprop = which( "svcprop", $ENV{'PATH'} ); if ( substr( $svcprop, 0, 1 ) =~ "/" ) { # We are on solaris @@ -930,37 +944,40 @@ sub get_tuning_info { my ( %mystat, %myvar, $dummyselect, %myrepl, %myslaves ); sub arr2hash { - my $href=shift; - my $harr=shift; - my $sep=shift; - $sep='\s' unless defined($sep); - foreach my $line (@$harr) { + my $href = shift; + my $harr = shift; + my $sep = shift; + $sep = '\s' unless defined($sep); + foreach my $line (@$harr) { $line =~ /([a-zA-Z_]*)\s*$sep\s*(.*)/; $$href{$1} = $2; debugprint "V: $1 = $2"; - } + } } sub get_all_vars { + # We need to initiate at least one query so that our data is useable $dummyselect = select_one "SELECT VERSION()"; debugprint "VERSION: " . $dummyselect . ""; $result{'MySQL Client'}{'Version'} = $dummyselect; - - my @mysqlvarlist = select_array ("SHOW GLOBAL VARIABLES"); - push (@mysqlvarlist, select_array ("SHOW VARIABLES")); - arr2hash(\%myvar, \@mysqlvarlist); - $result{'Variables'}=%myvar; - - my @mysqlstatlist = select_array ("SHOW GLOBAL STATUS"); - push (@mysqlstatlist, select_array ("SHOW STATUS")); - arr2hash(\%mystat, \@mysqlstatlist); - $result{'Status'}=%mystat; - + + my @mysqlvarlist = select_array("SHOW GLOBAL VARIABLES"); + push( @mysqlvarlist, select_array("SHOW VARIABLES") ); + arr2hash( \%myvar, \@mysqlvarlist ); + $result{'Variables'} = %myvar; + + my @mysqlstatlist = select_array("SHOW GLOBAL STATUS"); + push( @mysqlstatlist, select_array("SHOW STATUS") ); + arr2hash( \%mystat, \@mysqlstatlist ); + $result{'Status'} = %mystat; + $myvar{'have_galera'} = "NO"; - if ( defined($myvar{'wsrep_provider_options'}) && $myvar{'wsrep_provider_options'} ne "") { + if ( defined( $myvar{'wsrep_provider_options'} ) + && $myvar{'wsrep_provider_options'} ne "" ) + { $myvar{'have_galera'} = "YES"; - debugprint "Galera options: ". $myvar{'wsrep_provider_options'}; + debugprint "Galera options: " . $myvar{'wsrep_provider_options'}; } # Workaround for MySQL bug #59393 wrt. ignore-builtin-innodb @@ -996,8 +1013,8 @@ sub get_all_vars { } debugprint Dumper(@mysqlenginelist); my @mysqlslave = select_array("SHOW SLAVE STATUS\\G"); - arr2hash(\%myrepl, \@mysqlslave, ':'); - $result{'Replication'}{'Status'}=%myrepl; + arr2hash( \%myrepl, \@mysqlslave, ':' ); + $result{'Replication'}{'Status'} = %myrepl; my @mysqlslaves = select_array "SHOW SLAVE HOSTS"; my @lineitems = (); foreach my $line (@mysqlslaves) { @@ -1031,7 +1048,7 @@ sub get_basic_passwords { } sub cve_recommendations { - subheaderprint"CVE Security Recommendations"; + subheaderprint "CVE Security Recommendations"; unless ( defined( $opt{cvefile} ) && -f "$opt{cvefile}" ) { infoprint "Skipped due to --cvefile option undefined"; return; @@ -1105,37 +1122,37 @@ sub get_other_process_memory { } sub get_os_release { - if( -f "/etc/lsb-release") { + if ( -f "/etc/lsb-release" ) { my @info_release = get_file_contents "/etc/lsb-release"; remove_cr @info_release; my $os_relase = $info_release[3]; $os_relase =~ s/.*="//; $os_relase =~ s/"$//; return $os_relase; - } + } - if( -f "/etc/system-release") { + if ( -f "/etc/system-release" ) { my @info_release = get_file_contents "/etc/system-release"; remove_cr @info_release; return $info_release[0]; - } + } - if ( -f "/etc/os-release") { + if ( -f "/etc/os-release" ) { my @info_release = get_file_contents "/etc/os-release"; remove_cr @info_release; my $os_relase = $info_release[0]; $os_relase =~ s/.*="//; $os_relase =~ s/"$//; return $os_relase; - } + } - if ( -f "/etc/issue") { + if ( -f "/etc/issue" ) { my @info_release = get_file_contents "/etc/issue"; remove_cr @info_release; my $os_relase = $info_release[0]; $os_relase =~ s/\s+\\n.*//; return $os_relase; - } + } return "Unknown OS release"; } @@ -1174,18 +1191,17 @@ sub get_fs_info() { } } -sub merge_hash -{ - my $h1=shift; - my $h2=shift; - my %result={}; - foreach my $substanceref ( $h1, $h2 ) { - while ( my ($k, $v) = each %$substanceref) { - next if (exists $result{$k}); - $result{$k} = $v; +sub merge_hash { + my $h1 = shift; + my $h2 = shift; + my %result = {}; + foreach my $substanceref ( $h1, $h2 ) { + while ( my ( $k, $v ) = each %$substanceref ) { + next if ( exists $result{$k} ); + $result{$k} = $v; + } } - } - return \%result; + return \%result; } sub is_virtual_machine() { @@ -1220,44 +1236,51 @@ sub infocmd_one { return join ', ', @result; } +sub get_kernel_info() { + my @params = ( + 'fs.aio-max-nr', 'fs.aio-nr', + 'fs.file-max', 'sunrpc.tcp_fin_timeout', + 'sunrpc.tcp_max_slot_table_entries', 'sunrpc.tcp_slot_table_entries', + 'vm.swappiness' + ); + infoprint "Informations about kernel tuning:"; + foreach my $param (@params) { + infocmd_tab("sysctl $param"); + } + if ( `sysctl -n vm.swappiness` > 10 ) { + badprint + "Swappiness is > 10, please consider having a value lower than 10"; + push @generalrec, "setup swappiness lower or equals to 10"; + push @adjvars, 'vm.swappiness <= 10 (echo 0 > /proc/sys/vm/swappiness)'; + } + else { + infoprint "Swappiness is < 10."; + } -sub get_kernel_info() -{ - my @params=('fs.aio-max-nr', 'fs.aio-nr', 'fs.file-max', 'sunrpc.tcp_fin_timeout', - 'sunrpc.tcp_max_slot_table_entries', 'sunrpc.tcp_slot_table_entries', - 'vm.swappiness'); - infoprint "Informations about kernel tuning:"; - foreach my $param (@params) { - infocmd_tab("sysctl $param"); - } - if (`sysctl -n vm.swappiness` > 10) { - badprint "Swappiness is > 10, please consider having a value lower than 10"; - push @generalrec, "setup swappiness lower or equals to 10"; - push @adjvars, 'vm.swappiness <= 10 (echo 0 > /proc/sys/vm/swappiness)'; - } else { - infoprint "Swappiness is < 10."; - } - - if (`sysctl -n sunrpc.tcp_slot_table_entries` < 100) { - badprint "Initial TCP slot entries is < 1M, please consider having a value greater than 100"; - push @generalrec, "setup Initial TCP slot entries greater than 100"; - push @adjvars, 'sunrpc.tcp_slot_table_entries > 100 (echo 128 > /proc/sys/sunrpc/tcp_slot_table_entries)'; - } else { - infoprint "TCP slot entries is > 100."; - } + if ( `sysctl -n sunrpc.tcp_slot_table_entries` < 100 ) { + badprint +"Initial TCP slot entries is < 1M, please consider having a value greater than 100"; + push @generalrec, "setup Initial TCP slot entries greater than 100"; + push @adjvars, +'sunrpc.tcp_slot_table_entries > 100 (echo 128 > /proc/sys/sunrpc/tcp_slot_table_entries)'; + } + else { + infoprint "TCP slot entries is > 100."; + } - - if (`sysctl -n fs.aio-max-nr` < 1000000) { - badprint "Max running total of the number of events is < 1M, please consider having a value greater than 1M"; - push @generalrec, "setup Max running number events greater than 1M"; - push @adjvars, 'fs.aio-max-nr > 1M (echo 1048576 > /proc/sys/fs/aio-max-nr)'; - } else { - infoprint "Max Number of AIO events is > 1M."; - } + if ( `sysctl -n fs.aio-max-nr` < 1000000 ) { + badprint +"Max running total of the number of events is < 1M, please consider having a value greater than 1M"; + push @generalrec, "setup Max running number events greater than 1M"; + push @adjvars, + 'fs.aio-max-nr > 1M (echo 1048576 > /proc/sys/fs/aio-max-nr)'; + } + else { + infoprint "Max Number of AIO events is > 1M."; + } } - sub get_system_info() { infoprint get_os_release; if (is_virtual_machine) { @@ -1281,9 +1304,10 @@ sub get_system_info() { infoprint "Network Cards : "; infocmd_tab "ifconfig| grep -A1 mtu"; infoprint "Internal IP : " . infocmd_one "hostname -I"; - my $httpcli=get_http_cli(); + my $httpcli = get_http_cli(); infoprint "HTTP client found: $httpcli" if defined $httpcli; - if ( $httpcli =~ /curl$/) { + + if ( $httpcli =~ /curl$/ ) { infoprint "External IP : " . infocmd_one "$httpcli ipecho.net/plain"; } @@ -1292,7 +1316,8 @@ sub get_system_info() { . infocmd_one "$httpcli -q -O - ipecho.net/plain"; } badprint - "External IP : Can't check because of Internet connectivity" unless defined($httpcli); + "External IP : Can't check because of Internet connectivity" + unless defined($httpcli); infoprint "Name Servers : " . infocmd_one "grep 'nameserver' /etc/resolv.conf \| awk '{print \$2}'"; infoprint "Logged In users : "; @@ -1306,8 +1331,8 @@ sub get_system_info() { } sub system_recommendations { - return if ( $opt{sysstat} == 0 ); - subheaderprint"System Linux Recommendations"; + return if ( $opt{sysstat} == 0 ); + subheaderprint "System Linux Recommendations"; my $os = `uname`; unless ( $os =~ /Linux/i ) { infoprint "Skipped due to non Linux server"; @@ -1509,8 +1534,8 @@ sub security_recommendations { } sub get_replication_status { - subheaderprint "Replication Metrics"; - infoprint "Galera Synchronous replication: ". $myvar{'have_galera'}; + subheaderprint "Replication Metrics"; + infoprint "Galera Synchronous replication: " . $myvar{'have_galera'}; if ( scalar( keys %myslaves ) == 0 ) { infoprint "No replication slave(s) for this server."; } @@ -1965,14 +1990,20 @@ sub calculations { # Max used memory is memory used by MySQL based on Max_used_connections # This is the max memory used theorically calculated with the max concurrent connection number reached by mysql $mycalc{'max_used_memory'} = - $mycalc{'server_buffers'} + $mycalc{"max_total_per_thread_buffers"} +get_pf_memory() + get_gcache_memory(); + $mycalc{'server_buffers'} + + $mycalc{"max_total_per_thread_buffers"} + + get_pf_memory() + + get_gcache_memory(); $mycalc{'pct_max_used_memory'} = percentage( $mycalc{'max_used_memory'}, $physical_memory ); # Total possible memory is memory needed by MySQL based on max_connections # This is the max memory MySQL can theorically used if all connections allowed has opened by mysql $mycalc{'max_peak_memory'} = - $mycalc{'server_buffers'} + $mycalc{'total_per_thread_buffers'} + get_pf_memory()+ get_gcache_memory(); + $mycalc{'server_buffers'} + + $mycalc{'total_per_thread_buffers'} + + get_pf_memory() + + get_gcache_memory(); $mycalc{'pct_max_physical_memory'} = percentage( $mycalc{'max_peak_memory'}, $physical_memory ); @@ -1985,7 +2016,7 @@ sub calculations { . hr_bytes( $mycalc{'max_peak_memory'} ) . ""; debugprint "Max Peak Percentage RAM: " . $mycalc{'pct_max_physical_memory'} . "%"; - + # Slow queries $mycalc{'pct_slow_queries'} = int( ( $mystat{'Slow_queries'} / $mystat{'Questions'} ) * 100 ); @@ -2312,17 +2343,18 @@ sub mysql_stats { # Memory usage - infoprint "Physical Memory : ". hr_bytes($physical_memory); - infoprint "Max MySQL memory : ". hr_bytes( $mycalc{'max_peak_memory'} ); - infoprint "Other process memory: ". hr_bytes( get_other_process_memory() ); + infoprint "Physical Memory : " . hr_bytes($physical_memory); + infoprint "Max MySQL memory : " . hr_bytes( $mycalc{'max_peak_memory'} ); + infoprint "Other process memory: " . hr_bytes( get_other_process_memory() ); infoprint "Total buffers: " . hr_bytes( $mycalc{'server_buffers'} ) . " global + " . hr_bytes( $mycalc{'per_thread_buffers'} ) . " per thread ($myvar{'max_connections'} max threads)"; - infoprint "P_S Max memory usage: ".hr_bytes_rnd(get_pf_memory()); - infoprint "Galera GCache Max memory usage: ".hr_bytes_rnd(get_gcache_memory()); + infoprint "P_S Max memory usage: " . hr_bytes_rnd( get_pf_memory() ); + infoprint "Galera GCache Max memory usage: " + . hr_bytes_rnd( get_gcache_memory() ); if ( $opt{buffers} ne 0 ) { infoprint "Global Buffers"; infoprint " +-- Key Buffer: " @@ -2398,12 +2430,18 @@ sub mysql_stats { . " ($mycalc{'pct_max_physical_memory'}% of installed RAM)"; } - if ($physical_memory < ($mycalc{'max_peak_memory'}+get_other_process_memory())) { - badprint "Overall possible memory usage with other process exceeded memory"; - push( @generalrec, "Dedicated this server to your database for highest performance." ); - } else { - goodprint "Overall possible memory usage with other process is compatible with memory available"; - } + if ( $physical_memory < + ( $mycalc{'max_peak_memory'} + get_other_process_memory() ) ) + { + badprint + "Overall possible memory usage with other process exceeded memory"; + push( @generalrec, + "Dedicated this server to your database for highest performance." ); + } + else { + goodprint +"Overall possible memory usage with other process is compatible with memory available"; + } # Slow queries if ( $mycalc{'pct_slow_queries'} > 5 ) { @@ -2534,7 +2572,7 @@ sub mysql_stats { # Sorting if ( $mycalc{'total_sorts'} == 0 ) { - goodprint "No Sort requiring temporary tables"; + goodprint "No Sort requiring temporary tables"; } elsif ( $mycalc{'pct_temp_sort_table'} > 10 ) { badprint @@ -2573,7 +2611,8 @@ sub mysql_stats { "Adjust your join queries to always utilize indexes" ); } else { - goodprint "No joins without indexes"; + goodprint "No joins without indexes"; + # No joins have run without indexes } @@ -2628,7 +2667,7 @@ sub mysql_stats { } } else { - goodprint "No tmp tables created on disk"; + goodprint "No tmp tables created on disk"; } # Thread cache @@ -2922,11 +2961,11 @@ sub mariadb_threadpool { infoprint "ThreadPool stat is enabled."; infoprint "Thread Pool Size: " . $myvar{'thread_pool_size'} . " thread(s)."; - if ($myvar{'version'} =~ /mariadb|percona/i ) { - infoprint "Using default value is good enougth for your version (".$myvar{'version'}.")"; - return; - } - + if ( $myvar{'version'} =~ /mariadb|percona/i ) { + infoprint "Using default value is good enougth for your version (" + . $myvar{'version'} . ")"; + return; + } if ( $myvar{'have_innodb'} eq 'YES' ) { if ( $myvar{'thread_pool_size'} < 16 @@ -2966,17 +3005,19 @@ sub mariadb_threadpool { } } -sub get_pf_memory -{ +sub get_pf_memory { + # Performance Schema return 0 unless defined $myvar{'performance_schema'}; return 0 if $myvar{'performance_schema'} eq 'OFF'; - - my @infoPFSMemory=grep /performance_schema.memory/, select_array("SHOW ENGINE PERFORMANCE_SCHEMA STATUS"); - return 0 if scalar(@infoPFSMemory)==0; + + my @infoPFSMemory = grep /performance_schema.memory/, + select_array("SHOW ENGINE PERFORMANCE_SCHEMA STATUS"); + return 0 if scalar(@infoPFSMemory) == 0; $infoPFSMemory[0] =~ s/.*\s+(\d+)$/$1/g; return $infoPFSMemory[0]; } + # Recommendations for Performance Schema sub mysqsl_pfs { subheaderprint "Performance schema"; @@ -2990,7 +3031,7 @@ sub mysqsl_pfs { else { infoprint "Performance schema is enabled."; } - infoprint "Memory used by P_S: ". hr_bytes(get_pf_memory()); + infoprint "Memory used by P_S: " . hr_bytes( get_pf_memory() ); } # Recommendations for Ariadb @@ -3081,39 +3122,40 @@ sub mariadb_tokudb { # Perl trim function to remove whitespace from the start and end of the string sub trim { - my $string = shift; - $string =~ s/^\s+//; - $string =~ s/\s+$//; - return $string; + my $string = shift; + $string =~ s/^\s+//; + $string =~ s/\s+$//; + return $string; } sub get_wsrep_options { - return () unless defined $myvar{'wsrep_provider_options'} ; + return () unless defined $myvar{'wsrep_provider_options'}; - my @galera_options=split /;/,$myvar{'wsrep_provider_options'} ; + my @galera_options = split /;/, $myvar{'wsrep_provider_options'}; remove_cr @galera_options; - @galera_options=remove_empty @galera_options; - debugprint Dumper(\@galera_options); + @galera_options = remove_empty @galera_options; + debugprint Dumper( \@galera_options ); return @galera_options; } + sub get_gcache_memory { - my $gCacheMem=get_wsrep_option('gcache.mem_size'); + my $gCacheMem = get_wsrep_option('gcache.mem_size'); return 0 unless defined $gCacheMem and $gCacheMem ne ''; return $gCacheMem; } + sub get_wsrep_option { - my $key=shift; - return '' unless defined $myvar{'wsrep_provider_options'} ; - my @galera_options=get_wsrep_options; - return '' unless scalar(@galera_options) >0; - my @memValues= grep /\s*$key =/, @galera_options; - my $memValue=$memValues[0]; + my $key = shift; + return '' unless defined $myvar{'wsrep_provider_options'}; + my @galera_options = get_wsrep_options; + return '' unless scalar(@galera_options) > 0; + my @memValues = grep /\s*$key =/, @galera_options; + my $memValue = $memValues[0]; $memValue =~ s/.*=\s*(.+)$/$1/g; return $memValue; } - # Recommendations for Galera sub mariadb_galera { subheaderprint "Galera Metrics"; @@ -3126,162 +3168,215 @@ sub mariadb_galera { return; } infoprint "Galera is enabled."; - debugprint "Galera variables:"; + debugprint "Galera variables:"; foreach my $gvar ( keys %myvar ) { - next unless $gvar =~ /^wsrep.*/; - next if $gvar eq 'wsrep_provider_options'; - debugprint "\t".trim($gvar). " = ".$myvar{$gvar}; + next unless $gvar =~ /^wsrep.*/; + next if $gvar eq 'wsrep_provider_options'; + debugprint "\t" . trim($gvar) . " = " . $myvar{$gvar}; } - debugprint "Galera wsrep provider Options:"; - my @galera_options=get_wsrep_options; - foreach my $gparam ( @galera_options ) { - debugprint "\t".trim($gparam); + debugprint "Galera wsrep provider Options:"; + my @galera_options = get_wsrep_options; + foreach my $gparam (@galera_options) { + debugprint "\t" . trim($gparam); } - debugprint "Galera status:"; + debugprint "Galera status:"; foreach my $gstatus ( keys %mystat ) { - next unless $gstatus =~ /^wsrep.*/; - debugprint "\t".trim($gstatus). " = ".$mystat{$gstatus}; - } - infoprint "GCache is using ".hr_bytes_rnd(get_wsrep_option('gcache.mem_size')); - my @primaryKeysNbTables=select_array("select CONCAT(table_schema,CONCAT('.', table_name)) from information_schema.columns where table_schema not in ('mysql', 'information_schema', 'performance_schema') group by table_schema,table_name having sum(if(column_key in ('PRI','UNI'), 1,0)) = 0"); + next unless $gstatus =~ /^wsrep.*/; + debugprint "\t" . trim($gstatus) . " = " . $mystat{$gstatus}; + } + infoprint "GCache is using " + . hr_bytes_rnd( get_wsrep_option('gcache.mem_size') ); + my @primaryKeysNbTables = select_array( +"select CONCAT(table_schema,CONCAT('.', table_name)) from information_schema.columns where table_schema not in ('mysql', 'information_schema', 'performance_schema') group by table_schema,table_name having sum(if(column_key in ('PRI','UNI'), 1,0)) = 0" + ); - if (scalar (@primaryKeysNbTables) > 0 ) { - badprint "Following table(s) don't have primary key:"; - foreach my $badtable( @primaryKeysNbTables ) { - badprint "\t$badtable"; - } - } else { - goodprint "All tables get a primary key"; - } - my @nonInnoDbTables=select_array("select CONCAT(table_schema,CONCAT('.', table_name)) from information_schema.tables where ENGINE <> 'InnoDb' and table_schema not in ('mysql', 'performance_schema', 'information_schema')"); - if (scalar (@nonInnoDbTables) > 0 ) { - badprint "Following table(s) are not InnoDB table:"; - push @generalrec, "Ensure that all table(s) are InnoDB tabls for Galera replication"; - foreach my $badtable( @nonInnoDbTables ) { - badprint "\t$badtable"; - } - } else { - goodprint "All tables are InnoDB tables"; - } - if ($myvar{'binlog_format'} ne 'ROW') { - badprint "Binlog format should be in ROW mode."; - push @adjvars, "binlog_format = ROW"; - } else { - goodprint "Binlog format is in ROW mode."; - } - if ($myvar{'innodb_flush_log_at_trx_commit'} != 0 ) { - badprint "Innodb flush log at each commit should be disabled."; - push @adjvars, "innodb_flush_log_at_trx_commit = 0"; - } else { - goodprint "Innodb flush log at each commit is disabled for Galera."; - } + if ( scalar(@primaryKeysNbTables) > 0 ) { + badprint "Following table(s) don't have primary key:"; + foreach my $badtable (@primaryKeysNbTables) { + badprint "\t$badtable"; + } + } + else { + goodprint "All tables get a primary key"; + } + my @nonInnoDbTables = select_array( +"select CONCAT(table_schema,CONCAT('.', table_name)) from information_schema.tables where ENGINE <> 'InnoDb' and table_schema not in ('mysql', 'performance_schema', 'information_schema')" + ); + if ( scalar(@nonInnoDbTables) > 0 ) { + badprint "Following table(s) are not InnoDB table:"; + push @generalrec, + "Ensure that all table(s) are InnoDB tabls for Galera replication"; + foreach my $badtable (@nonInnoDbTables) { + badprint "\t$badtable"; + } + } + else { + goodprint "All tables are InnoDB tables"; + } + if ( $myvar{'binlog_format'} ne 'ROW' ) { + badprint "Binlog format should be in ROW mode."; + push @adjvars, "binlog_format = ROW"; + } + else { + goodprint "Binlog format is in ROW mode."; + } + if ( $myvar{'innodb_flush_log_at_trx_commit'} != 0 ) { + badprint "Innodb flush log at each commit should be disabled."; + push @adjvars, "innodb_flush_log_at_trx_commit = 0"; + } + else { + goodprint "Innodb flush log at each commit is disabled for Galera."; + } - infoprint "Read consistency mode :". $myvar{'wsrep_causal_reads'}; - - if ( defined($myvar{'wsrep_cluster_name'}) and $myvar{'wsrep_on'} eq "ON" ) { - goodprint "Galera WsREP is enabled."; - if ( defined($myvar{'wsrep_cluster_address'}) and trim("$myvar{'wsrep_cluster_address'}") ne "") { - goodprint "Galera Cluster address is defined: ".$myvar{'wsrep_cluster_address'}; - my $nbNodes=scalar(split /,/, $myvar{'wsrep_cluster_address'}); - if ( $nbNodes !=3 or $nbNodes != 5) { - goodprint "There is $nbNodes nodes in wsrep_cluster_address."; - } else { - badprint "There is $nbNodes nodes in wsrep_cluster_address. Prefer 3 or 5 nodes achitecture."; - } - my $nbNodesSize=trim ($mystat{'wsrep_cluster_size'}); - if ( $nbNodesSize !=3 or $nbNodesSize != 5) { - goodprint "There is $nbNodes nodes in wsrep_cluster_size."; - } else { - badprint "There is $nbNodes nodes in wsrep_cluster_size. Prefer 3 or 5 nodes achitecture."; - } + infoprint "Read consistency mode :" . $myvar{'wsrep_causal_reads'}; - if ($nbNodes != trim ($mystat{'wsrep_cluster_size'}) ) { - badprint "All cluster nodes dre not detected. wsrep_cluster_size != informations in wsrep_cluster_adress"; - } else { - badprint "All cluster nodes detected."; - } - } else { + if ( defined( $myvar{'wsrep_cluster_name'} ) + and $myvar{'wsrep_on'} eq "ON" ) + { + goodprint "Galera WsREP is enabled."; + if ( defined( $myvar{'wsrep_cluster_address'} ) + and trim("$myvar{'wsrep_cluster_address'}") ne "" ) + { + goodprint "Galera Cluster address is defined: " + . $myvar{'wsrep_cluster_address'}; + my $nbNodes = scalar( split /,/, $myvar{'wsrep_cluster_address'} ); + if ( $nbNodes != 3 or $nbNodes != 5 ) { + goodprint "There is $nbNodes nodes in wsrep_cluster_address."; + } + else { + badprint +"There is $nbNodes nodes in wsrep_cluster_address. Prefer 3 or 5 nodes achitecture."; + } + my $nbNodesSize = trim( $mystat{'wsrep_cluster_size'} ); + if ( $nbNodesSize != 3 or $nbNodesSize != 5 ) { + goodprint "There is $nbNodes nodes in wsrep_cluster_size."; + } + else { + badprint +"There is $nbNodes nodes in wsrep_cluster_size. Prefer 3 or 5 nodes achitecture."; + } + + if ( $nbNodes != trim( $mystat{'wsrep_cluster_size'} ) ) { + badprint +"All cluster nodes dre not detected. wsrep_cluster_size != informations in wsrep_cluster_adress"; + } + else { + badprint "All cluster nodes detected."; + } + } + else { badprint "Galera Cluster address is undefined"; - push @adjvars, "set up wsrep_cluster_address variable for Galera replication"; + push @adjvars, + "set up wsrep_cluster_address variable for Galera replication"; } - if ( defined($myvar{'wsrep_cluster_name'}) and trim($myvar{'wsrep_cluster_name'}) ne "") { - goodprint "Galera Cluster name is defined: ".$myvar{'wsrep_cluster_name'}; - } else { - badprint "Galera Cluster name is undefined"; - push @adjvars, "set up wsrep_cluster_name variable for Galera replication"; + if ( defined( $myvar{'wsrep_cluster_name'} ) + and trim( $myvar{'wsrep_cluster_name'} ) ne "" ) + { + goodprint "Galera Cluster name is defined: " + . $myvar{'wsrep_cluster_name'}; } - if ( defined($myvar{'wsrep_node_name'}) and trim($myvar{'wsrep_node_name'}) ne "") { - goodprint "Galera Node name is defined: ".$myvar{'wsrep_node_name'}; - } else { + else { + badprint "Galera Cluster name is undefined"; + push @adjvars, + "set up wsrep_cluster_name variable for Galera replication"; + } + if ( defined( $myvar{'wsrep_node_name'} ) + and trim( $myvar{'wsrep_node_name'} ) ne "" ) + { + goodprint "Galera Node name is defined: " + . $myvar{'wsrep_node_name'}; + } + else { badprint "Galera node name is undefined"; - push @adjvars, "set up wsrep_node_name variable for Galera replication"; + push @adjvars, + "set up wsrep_node_name variable for Galera replication"; } - if ( trim ($myvar{'wsrep_notify_cmd'}) ne "" ) { - goodprint "Galera Notify command is defined."; - } else { - badprint "Galera Notify command is not defined."; - push( @adjvars, "set up parameter wsrep_notify_cmd to be notify"); + if ( trim( $myvar{'wsrep_notify_cmd'} ) ne "" ) { + goodprint "Galera Notify command is defined."; } - if ( trim ($myvar{'wsrep_sst_method'}) ne "xtrabackup" ) { + else { + badprint "Galera Notify command is not defined."; + push( @adjvars, "set up parameter wsrep_notify_cmd to be notify" ); + } + if ( trim( $myvar{'wsrep_sst_method'} ) ne "xtrabackup" ) { badprint "Galera SST method is xtrabackup."; - push( @adjvars, "set up parameter wsrep_sst_method to xtrabackup"); - } else { + push( @adjvars, "set up parameter wsrep_sst_method to xtrabackup" ); + } + else { goodprint "SST Method is inot based on xtrabackup."; } - if ( trim ($myvar{'wsrep_OSU_method'}) eq "TOI" ) { + if ( trim( $myvar{'wsrep_OSU_method'} ) eq "TOI" ) { goodprint "TOI is default mode for upgrade."; - } else { - badprint "Schema upgrade are not replicated automatically"; - push( @adjvars, "set up parameter wsrep_OSU_method to TOI"); } - infoprint "Max WsRep message : " .hr_bytes( $myvar{'wsrep_max_ws_size'}); - } else { - badprint "Galera WsREP is disabled"; - } + else { + badprint "Schema upgrade are not replicated automatically"; + push( @adjvars, "set up parameter wsrep_OSU_method to TOI" ); + } + infoprint "Max WsRep message : " + . hr_bytes( $myvar{'wsrep_max_ws_size'} ); + } + else { + badprint "Galera WsREP is disabled"; + } - - if (defined($mystat{'wsrep_connected'}) and $mystat{'wsrep_connected'} eq "ON") { - goodprint "Node is connected"; - } else { - badprint "Node is disconnected"; - } - if (defined($mystat{'wsrep_ready'}) and $mystat{'wsrep_ready'} eq "ON") { + if ( defined( $mystat{'wsrep_connected'} ) + and $mystat{'wsrep_connected'} eq "ON" ) + { + goodprint "Node is connected"; + } + else { + badprint "Node is disconnected"; + } + if ( defined( $mystat{'wsrep_ready'} ) and $mystat{'wsrep_ready'} eq "ON" ) + { goodprint "Node is ready"; - } else { + } + else { badprint "Node is not ready"; - } -infoprint "Cluster status :".$mystat{'wsrep_cluster_status'}; - if (defined($mystat{'wsrep_cluster_status'}) and $mystat{'wsrep_cluster_status'} eq "Primary") { + } + infoprint "Cluster status :" . $mystat{'wsrep_cluster_status'}; + if ( defined( $mystat{'wsrep_cluster_status'} ) + and $mystat{'wsrep_cluster_status'} eq "Primary" ) + { goodprint "Galera cluster is consistent and ready for operations"; - } else { + } + else { badprint "Cluster is not consistent and ready"; - } - if ($mystat{'wsrep_local_state_uuid'} eq $mystat{'wsrep_cluster_state_uuid'}) { - goodprint "Node and whole cluster at the same level: ".$mystat{'wsrep_cluster_state_uuid'}; - } else { - badprint "Node and whole cluster not the same level"; - infoprint "Node state uuid: ".$mystat{'wsrep_local_state_uuid'}; - infoprint "Cluster state uuid: ".$mystat{'wsrep_cluster_state_uuid'}; - } - if ($mystat{'wsrep_local_state_comment'} eq 'Synced' ) { + } + if ( $mystat{'wsrep_local_state_uuid'} eq + $mystat{'wsrep_cluster_state_uuid'} ) + { + goodprint "Node and whole cluster at the same level: " + . $mystat{'wsrep_cluster_state_uuid'}; + } + else { + badprint "Node and whole cluster not the same level"; + infoprint "Node state uuid: " . $mystat{'wsrep_local_state_uuid'}; + infoprint "Cluster state uuid: " . $mystat{'wsrep_cluster_state_uuid'}; + } + if ( $mystat{'wsrep_local_state_comment'} eq 'Synced' ) { goodprint "Node is synced with whole cluster."; - } else { + } + else { badprint "Node is not synced"; - infoprint "Node State : ".$mystat{'wsrep_local_state_comment'}; - } - if ($mystat{'wsrep_local_cert_failures'} == 0 ) { + infoprint "Node State : " . $mystat{'wsrep_local_state_comment'}; + } + if ( $mystat{'wsrep_local_cert_failures'} == 0 ) { goodprint "There is no certification failures detected."; - } else { - badprint "There is ".$mystat{'wsrep_local_cert_failures'}." certification failure(s)detected."; - } + } + else { + badprint "There is " + . $mystat{'wsrep_local_cert_failures'} + . " certification failure(s)detected."; + } - for my $key (keys %mystat) { - if ($key =~ /wsrep_|galera/i) { - debugprint "WSREP: $key = $mystat{$key}"; - } - } - debugprint Dumper get_wsrep_options(); + for my $key ( keys %mystat ) { + if ( $key =~ /wsrep_|galera/i ) { + debugprint "WSREP: $key = $mystat{$key}"; + } + } + debugprint Dumper get_wsrep_options(); } # Recommendations for InnoDB @@ -3446,7 +3541,7 @@ sub mysql_innodb { && $mycalc{'pct_write_efficiency'} < 90 ) { badprint "InnoDB Write Log efficiency: " - . abs($mycalc{'pct_write_efficiency'}) . "% (" + . abs( $mycalc{'pct_write_efficiency'} ) . "% (" . abs( $mystat{'Innodb_log_write_requests'} - $mystat{'Innodb_log_writes'} ) . " hits/ " @@ -3549,12 +3644,10 @@ sub mysql_databases { foreach (@dblist) { chomp($_); - if ( - $_ eq "information_schema" + if ( $_ eq "information_schema" or $_ eq "performance_schema" or $_ eq "mysql" - or $_ eq "" - ) + or $_ eq "" ) { next; } @@ -3906,20 +3999,19 @@ sub dump_result { } sub which { - my $prog_name = shift; + my $prog_name = shift; my $path_string = shift; - my @path_array = split /:/, $ENV{'PATH'}; + my @path_array = split /:/, $ENV{'PATH'}; - for my $path ( @path_array) { + for my $path (@path_array) { if ( -x "$path/$prog_name" ) { return "$path/$prog_name"; } } - return 0 + return 0; } - # --------------------------------------------------------------------------- # BEGIN 'MAIN' # --------------------------------------------------------------------------- @@ -3940,7 +4032,7 @@ cve_recommendations; # Display related CVE calculations; # Calculate everything we need mysql_stats; # Print the server stats mysqsl_pfs # Print Performance schema info -mariadb_threadpool; # Print MaraiDB ThreadPool stats + mariadb_threadpool; # Print MaraiDB ThreadPool stats mysql_myisam; # Print MyISAM stats mariadb_ariadb; # Print MaraiDB AriaDB stats mysql_innodb; # Print InnoDB stats From 737628dd1b815e78130494c584aaa000349c70ac Mon Sep 17 00:00:00 2001 From: root Date: Thu, 21 Apr 2016 09:06:13 +0200 Subject: [PATCH 096/126] Vulnerabilities list updated #190 Query cache must be activated in MariaDB 10.1 #184 bug fix on messages #184 xtrabackup support when wsrep_sst_method is starting by xtrabackup --- mysqltuner.pl | 10 ++--- vulnerabilities.csv | 92 +++++++++++++++++++++++++-------------------- 2 files changed, 56 insertions(+), 46 deletions(-) diff --git a/mysqltuner.pl b/mysqltuner.pl index 671206f..873ba4a 100755 --- a/mysqltuner.pl +++ b/mysqltuner.pl @@ -2501,7 +2501,7 @@ sub mysql_stats { push( @generalrec, "Upgrade MySQL to version 4+ to utilize query caching" ); } - elsif ( mysql_version_ge( 5, 5 ) ) { + elsif ( mysql_version_ge( 5, 5 ) and !mysql_version_ge( 10, 1 ) ) { if ( $myvar{'query_cache_type'} ne "OFF" ) { badprint "Query cache should be disabled by default due to mutex contention."; @@ -3299,12 +3299,12 @@ sub mariadb_galera { badprint "Galera Notify command is not defined."; push( @adjvars, "set up parameter wsrep_notify_cmd to be notify" ); } - if ( trim( $myvar{'wsrep_sst_method'} ) ne "xtrabackup" ) { - badprint "Galera SST method is xtrabackup."; - push( @adjvars, "set up parameter wsrep_sst_method to xtrabackup" ); + if ( trim( $myvar{'wsrep_sst_method'} ) !~ "^\s*xtrabackup.*" ) { + badprint "Galera SST method is not xtrabackup based."; + push( @adjvars, "set up parameter wsrep_sst_method to xtrabackup based parameter" ); } else { - goodprint "SST Method is inot based on xtrabackup."; + badprint "SST Method is based on xtrabackup."; } if ( trim( $myvar{'wsrep_OSU_method'} ) eq "TOI" ) { goodprint "TOI is default mode for upgrade."; diff --git a/vulnerabilities.csv b/vulnerabilities.csv index 8b1c533..0408842 100755 --- a/vulnerabilities.csv +++ b/vulnerabilities.csv @@ -375,48 +375,58 @@ 5.5.42;5;5;42;CVE-2015-4757;Candidate;"Unspecified vulnerability in Oracle MySQL Server 5.5.42 and earlier and 5.6.23 and earlier allows remote authenticated users to affect availability via unknown vectors related to Server : Optimizer.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/cpujul2015-2367936.html | REDHAT:RHSA-2015:1630 | URL:http://rhn.redhat.com/errata/RHSA-2015-1630.html | UBUNTU:USN-2674-1 | URL:http://www.ubuntu.com/usn/USN-2674-1";Assigned (20150624);"None (candidate not yet proposed)"; 5.6.23;5;6;23;CVE-2015-4757;Candidate;"Unspecified vulnerability in Oracle MySQL Server 5.5.42 and earlier and 5.6.23 and earlier allows remote authenticated users to affect availability via unknown vectors related to Server : Optimizer.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/cpujul2015-2367936.html | REDHAT:RHSA-2015:1630 | URL:http://rhn.redhat.com/errata/RHSA-2015-1630.html | UBUNTU:USN-2674-1 | URL:http://www.ubuntu.com/usn/USN-2674-1";Assigned (20150624);"None (candidate not yet proposed)"; 5.6.24;5;6;24;CVE-2015-4761;Candidate;"Unspecified vulnerability in Oracle MySQL Server 5.6.24 and earlier allows remote authenticated users to affect availability via unknown vectors related to Server : Memcached.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/cpujul2015-2367936.html | REDHAT:RHSA-2015:1630 | URL:http://rhn.redhat.com/errata/RHSA-2015-1630.html | UBUNTU:USN-2674-1 | URL:http://www.ubuntu.com/usn/USN-2674-1";Assigned (20150624);"None (candidate not yet proposed)"; -5.6.25;5;6;25;CVE-2015-4766;Candidate;"Unspecified vulnerability in Oracle MySQL Server 5.6.25 and earlier allows local users to affect availability via unknown vectors related to Server : Security : Firewall.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/alerts-086861.html";Assigned (20150624);"None (candidate not yet proposed)"; +5.6.25;5;6;25;CVE-2015-4766;Candidate;"Unspecified vulnerability in Oracle MySQL Server 5.6.25 and earlier allows local users to affect availability via unknown vectors related to Server : Security : Firewall.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/cpuoct2015-2367953.html";Assigned (20150624);"None (candidate not yet proposed)"; 5.6.24;5;6;24;CVE-2015-4767;Candidate;"Unspecified vulnerability in Oracle MySQL Server 5.6.24 and earlier allows remote authenticated users to affect availability via unknown vectors related to Server : Security : Firewall; a different vulnerability than CVE-2015-4769.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/cpujul2015-2367936.html | REDHAT:RHSA-2015:1630 | URL:http://rhn.redhat.com/errata/RHSA-2015-1630.html | UBUNTU:USN-2674-1 | URL:http://www.ubuntu.com/usn/USN-2674-1";Assigned (20150624);"None (candidate not yet proposed)"; 5.6.24;5;6;24;CVE-2015-4769;Candidate;"Unspecified vulnerability in Oracle MySQL Server 5.6.24 and earlier allows remote authenticated users to affect availability via unknown vectors related to Server : Security : Firewall; a different vulnerability than CVE-2015-4767.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/cpujul2015-2367936.html | REDHAT:RHSA-2015:1630 | URL:http://rhn.redhat.com/errata/RHSA-2015-1630.html | UBUNTU:USN-2674-1 | URL:http://www.ubuntu.com/usn/USN-2674-1";Assigned (20150624);"None (candidate not yet proposed)"; 5.6.24;5;6;24;CVE-2015-4771;Candidate;"Unspecified vulnerability in Oracle MySQL Server 5.6.24 and earlier allows remote authenticated users to affect availability via vectors related to RBR.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/cpujul2015-2367936.html | REDHAT:RHSA-2015:1630 | URL:http://rhn.redhat.com/errata/RHSA-2015-1630.html | UBUNTU:USN-2674-1 | URL:http://www.ubuntu.com/usn/USN-2674-1";Assigned (20150624);"None (candidate not yet proposed)"; 5.6.24;5;6;24;CVE-2015-4772;Candidate;"Unspecified vulnerability in Oracle MySQL Server 5.6.24 and earlier allows remote authenticated users to affect availability via unknown vectors related to Server : Partition.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/cpujul2015-2367936.html | REDHAT:RHSA-2015:1630 | URL:http://rhn.redhat.com/errata/RHSA-2015-1630.html | UBUNTU:USN-2674-1 | URL:http://www.ubuntu.com/usn/USN-2674-1";Assigned (20150624);"None (candidate not yet proposed)"; -5.6.26;5;6;26;CVE-2015-4791;Candidate;"Unspecified vulnerability in Oracle MySQL Server 5.6.26 and earlier allows remote authenticated users to affect availability via unknown vectors related to Server : Security : Privileges.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/alerts-086861.html";Assigned (20150624);"None (candidate not yet proposed)"; -5.5.45;5;5;45;CVE-2015-4792;Candidate;"Unspecified vulnerability in Oracle MySQL Server 5.5.45 and earlier and 5.6.26 and earlier allows remote authenticated users to affect availability via unknown vectors related to Server : Partition; a different vulnerability than CVE-2015-4802.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/alerts-086861.html";Assigned (20150624);"None (candidate not yet proposed)"; -5.6.26;5;6;26;CVE-2015-4792;Candidate;"Unspecified vulnerability in Oracle MySQL Server 5.5.45 and earlier and 5.6.26 and earlier allows remote authenticated users to affect availability via unknown vectors related to Server : Partition; a different vulnerability than CVE-2015-4802.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/alerts-086861.html";Assigned (20150624);"None (candidate not yet proposed)"; -5.6.26;5;6;26;CVE-2015-4800;Candidate;"Unspecified vulnerability in Oracle MySQL Server 5.6.26 and earlier allows remote authenticated users to affect availability via unknown vectors related to Server : Optimizer.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/alerts-086861.html";Assigned (20150624);"None (candidate not yet proposed)"; -5.5.45;5;5;45;CVE-2015-4802;Candidate;"Unspecified vulnerability in Oracle MySQL Server 5.5.45 and earlier and 5.6.26 and earlier allows remote authenticated users to affect availability via unknown vectors related to Server : Partition; a different vulnerability than CVE-2015-4792.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/alerts-086861.html";Assigned (20150624);"None (candidate not yet proposed)"; -5.6.26;5;6;26;CVE-2015-4802;Candidate;"Unspecified vulnerability in Oracle MySQL Server 5.5.45 and earlier and 5.6.26 and earlier allows remote authenticated users to affect availability via unknown vectors related to Server : Partition; a different vulnerability than CVE-2015-4792.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/alerts-086861.html";Assigned (20150624);"None (candidate not yet proposed)"; -5.5.45;5;5;45;CVE-2015-4815;Candidate;"Unspecified vulnerability in Oracle MySQL Server 5.5.45 and earlier and 5.6.26 and earlier allows remote authenticated users to affect availability via vectors related to Server : DDL.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/alerts-086861.html";Assigned (20150624);"None (candidate not yet proposed)"; -5.6.26;5;6;26;CVE-2015-4815;Candidate;"Unspecified vulnerability in Oracle MySQL Server 5.5.45 and earlier and 5.6.26 and earlier allows remote authenticated users to affect availability via vectors related to Server : DDL.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/alerts-086861.html";Assigned (20150624);"None (candidate not yet proposed)"; -5.5.44;5;5;44;CVE-2015-4816;Candidate;"Unspecified vulnerability in Oracle MySQL Server 5.5.44 and earlier allows remote authenticated users to affect availability via unknown vectors related to Server : InnoDB.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/alerts-086861.html";Assigned (20150624);"None (candidate not yet proposed)"; -5.5.44;5;5;44;CVE-2015-4819;Candidate;"Unspecified vulnerability in Oracle MySQL Server 5.5.44 and earlier; and 5.6.25 and earlier; allows local users to affect confidentiality; integrity; and availability via unknown vectors related to Client programs.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/alerts-086861.html";Assigned (20150624);"None (candidate not yet proposed)"; -5.6.25;5;6;25;CVE-2015-4819;Candidate;"Unspecified vulnerability in Oracle MySQL Server 5.5.44 and earlier; and 5.6.25 and earlier; allows local users to affect confidentiality; integrity; and availability via unknown vectors related to Client programs.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/alerts-086861.html";Assigned (20150624);"None (candidate not yet proposed)"; -5.5.45;5;5;45;CVE-2015-4826;Candidate;"Unspecified vulnerability in Oracle MySQL Server 5.5.45 and earlier and 5.6.26 and earlier allows remote authenticated users to affect confidentiality via unknown vectors related to Server : Types.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/alerts-086861.html";Assigned (20150624);"None (candidate not yet proposed)"; -5.6.26;5;6;26;CVE-2015-4826;Candidate;"Unspecified vulnerability in Oracle MySQL Server 5.5.45 and earlier and 5.6.26 and earlier allows remote authenticated users to affect confidentiality via unknown vectors related to Server : Types.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/alerts-086861.html";Assigned (20150624);"None (candidate not yet proposed)"; -5.5.45;5;5;45;CVE-2015-4830;Candidate;"Unspecified vulnerability in Oracle MySQL Server 5.5.45 and earlier and 5.6.26 and earlier allows remote authenticated users to affect integrity via unknown vectors related to Server : Security : Privileges.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/alerts-086861.html";Assigned (20150624);"None (candidate not yet proposed)"; -5.6.26;5;6;26;CVE-2015-4830;Candidate;"Unspecified vulnerability in Oracle MySQL Server 5.5.45 and earlier and 5.6.26 and earlier allows remote authenticated users to affect integrity via unknown vectors related to Server : Security : Privileges.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/alerts-086861.html";Assigned (20150624);"None (candidate not yet proposed)"; -5.6.25;5;6;25;CVE-2015-4833;Candidate;"Unspecified vulnerability in Oracle MySQL Server 5.6.25 and earlier allows remote authenticated users to affect availability via unknown vectors related to Server : Partition.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/alerts-086861.html";Assigned (20150624);"None (candidate not yet proposed)"; -5.5.45;5;5;45;CVE-2015-4836;Candidate;"Unspecified vulnerability in Oracle MySQL Server 5.5.45 and earlier; and 5.6.26 and earlier; allows remote authenticated users to affect availability via unknown vectors related to Server : SP.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/alerts-086861.html";Assigned (20150624);"None (candidate not yet proposed)"; -5.6.26;5;6;26;CVE-2015-4836;Candidate;"Unspecified vulnerability in Oracle MySQL Server 5.5.45 and earlier; and 5.6.26 and earlier; allows remote authenticated users to affect availability via unknown vectors related to Server : SP.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/alerts-086861.html";Assigned (20150624);"None (candidate not yet proposed)"; -5.5.45;5;5;45;CVE-2015-4858;Candidate;"Unspecified vulnerability in Oracle MySQL Server 5.5.45 and earlier; and 5.6.26 and earlier; allows remote authenticated users to affect availability via vectors related to DML; a different vulnerability than CVE-2015-4913.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/alerts-086861.html";Assigned (20150624);"None (candidate not yet proposed)"; -5.6.26;5;6;26;CVE-2015-4858;Candidate;"Unspecified vulnerability in Oracle MySQL Server 5.5.45 and earlier; and 5.6.26 and earlier; allows remote authenticated users to affect availability via vectors related to DML; a different vulnerability than CVE-2015-4913.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/alerts-086861.html";Assigned (20150624);"None (candidate not yet proposed)"; -5.5.45;5;5;45;CVE-2015-4861;Candidate;"Unspecified vulnerability in Oracle MySQL Server 5.5.45 and earlier; and 5.6.26 and earlier; allows remote authenticated users to affect availability via unknown vectors related to Server : InnoDB.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/alerts-086861.html";Assigned (20150624);"None (candidate not yet proposed)"; -5.6.26;5;6;26;CVE-2015-4861;Candidate;"Unspecified vulnerability in Oracle MySQL Server 5.5.45 and earlier; and 5.6.26 and earlier; allows remote authenticated users to affect availability via unknown vectors related to Server : InnoDB.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/alerts-086861.html";Assigned (20150624);"None (candidate not yet proposed)"; -5.6.26;5;6;26;CVE-2015-4862;Candidate;"Unspecified vulnerability in Oracle MySQL Server 5.6.26 and earlier allows remote authenticated users to affect availability via vectors related to DML.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/alerts-086861.html";Assigned (20150624);"None (candidate not yet proposed)"; -5.5.43;5;5;43;CVE-2015-4864;Candidate;"Unspecified vulnerability in Oracle MySQL Server 5.5.43 and earlier and 5.6.24 and earlier allows remote authenticated users to affect integrity via unknown vectors related to Server : Security : Privileges.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/alerts-086861.html";Assigned (20150624);"None (candidate not yet proposed)"; -5.6.24;5;6;24;CVE-2015-4864;Candidate;"Unspecified vulnerability in Oracle MySQL Server 5.5.43 and earlier and 5.6.24 and earlier allows remote authenticated users to affect integrity via unknown vectors related to Server : Security : Privileges.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/alerts-086861.html";Assigned (20150624);"None (candidate not yet proposed)"; -5.6.23;5;6;23;CVE-2015-4866;Candidate;"Unspecified vulnerability in Oracle MySQL Server 5.6.23 and earlier allows remote authenticated users to affect availability via unknown vectors related to Server : InnoDB.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/alerts-086861.html";Assigned (20150624);"None (candidate not yet proposed)"; -5.5.45;5;5;45;CVE-2015-4870;Candidate;"Unspecified vulnerability in Oracle MySQL Server 5.5.45 and earlier; and 5.6.26 and earlier; allows remote authenticated users to affect availability via unknown vectors related to Server : Parser.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/alerts-086861.html";Assigned (20150624);"None (candidate not yet proposed)"; -5.6.26;5;6;26;CVE-2015-4870;Candidate;"Unspecified vulnerability in Oracle MySQL Server 5.5.45 and earlier; and 5.6.26 and earlier; allows remote authenticated users to affect availability via unknown vectors related to Server : Parser.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/alerts-086861.html";Assigned (20150624);"None (candidate not yet proposed)"; -5.5.44;5;5;44;CVE-2015-4879;Candidate;"Unspecified vulnerability in Oracle MySQL Server 5.5.44 and earlier; and 5.6.25 and earlier; allows remote authenticated users to affect confidentiality; integrity; and availability via vectors related to DML.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/alerts-086861.html";Assigned (20150624);"None (candidate not yet proposed)"; -5.6.25;5;6;25;CVE-2015-4879;Candidate;"Unspecified vulnerability in Oracle MySQL Server 5.5.44 and earlier; and 5.6.25 and earlier; allows remote authenticated users to affect confidentiality; integrity; and availability via vectors related to DML.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/alerts-086861.html";Assigned (20150624);"None (candidate not yet proposed)"; -5.6.26;5;6;26;CVE-2015-4890;Candidate;"Unspecified vulnerability in Oracle MySQL Server 5.6.26 and earlier allows remote authenticated users to affect availability via unknown vectors related to Server : Replication.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/alerts-086861.html";Assigned (20150624);"None (candidate not yet proposed)"; -5.6.25;5;6;25;CVE-2015-4895;Candidate;"Unspecified vulnerability in Oracle MySQL Server 5.6.25 and earlier allows remote authenticated users to affect availability via unknown vectors related to Server : InnoDB.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/alerts-086861.html";Assigned (20150624);"None (candidate not yet proposed)"; -5.6.25;5;6;25;CVE-2015-4904;Candidate;"Unspecified vulnerability in Oracle MySQL Server 5.6.25 and earlier allows remote authenticated users to affect availability via unknown vectors related to libmysqld.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/alerts-086861.html";Assigned (20150624);"None (candidate not yet proposed)"; -5.6.23;5;6;23;CVE-2015-4905;Candidate;"Unspecified vulnerability in Oracle MySQL Server 5.6.23 and earlier allows remote authenticated users to affect availability via vectors related to Server : DML.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/alerts-086861.html";Assigned (20150624);"None (candidate not yet proposed)"; -5.6.26;5;6;26;CVE-2015-4910;Candidate;"Unspecified vulnerability in Oracle MySQL Server 5.6.26 and earlier allows remote authenticated users to affect availability via unknown vectors related to Server : Memcached.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/alerts-086861.html";Assigned (20150624);"None (candidate not yet proposed)"; -5.5.45;5;5;45;CVE-2015-4913;Candidate;"Unspecified vulnerability in Oracle MySQL Server 5.5.45 and earlier and 5.6.26 and earlier allows remote authenticated users to affect availability via vectors related to Server : DML; a different vulnerability than CVE-2015-4858.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/alerts-086861.html";Assigned (20150624);"None (candidate not yet proposed)"; -5.6.26;5;6;26;CVE-2015-4913;Candidate;"Unspecified vulnerability in Oracle MySQL Server 5.5.45 and earlier and 5.6.26 and earlier allows remote authenticated users to affect availability via vectors related to Server : DML; a different vulnerability than CVE-2015-4858.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/alerts-086861.html";Assigned (20150624);"None (candidate not yet proposed)"; -5.5.47;5;5;47;CVE-2016-2047;Candidate;"The ssl_verify_server_cert function in sql-common/client.c in MariaDB before 5.5.47; 10.0.x before 10.0.23; and 10.1.x before 10.1.10; Oracle MySQL; and Percona Server do not properly verify that the server hostname matches a domain name in the subject's Common Name (CN) or subjectAltName field of the X.509 certificate; which allows man-in-the-middle attackers to spoof SSL servers via a ""/CN="" string in a field in a certificate; as demonstrated by ""/OU=/CN=bar.com/CN=foo.com.""";"MLIST:[oss-security] 20160126 Flaw in mariadb clients SSL certificate validation | URL:http://www.openwall.com/lists/oss-security/2016/01/26/3 | CONFIRM:https://mariadb.atlassian.net/browse/MDEV-9212 | CONFIRM:https://mariadb.com/kb/en/mariadb/mariadb-10110-release-notes/ | CONFIRM:https://mariadb.com/kb/en/mariadb/mariadb-5547-release-notes/ | CONFIRM:https://mariadb.com/kb/en/mdb-10023-rn/ | DEBIAN:DSA-3453 | URL:http://www.debian.org/security/2016/dsa-3453";Assigned (20160122);"None (candidate not yet proposed)"; -10.0.23;10;0;23;CVE-2016-2047;Candidate;"The ssl_verify_server_cert function in sql-common/client.c in MariaDB before 5.5.47; 10.0.x before 10.0.23; and 10.1.x before 10.1.10; Oracle MySQL; and Percona Server do not properly verify that the server hostname matches a domain name in the subject's Common Name (CN) or subjectAltName field of the X.509 certificate; which allows man-in-the-middle attackers to spoof SSL servers via a ""/CN="" string in a field in a certificate; as demonstrated by ""/OU=/CN=bar.com/CN=foo.com.""";"MLIST:[oss-security] 20160126 Flaw in mariadb clients SSL certificate validation | URL:http://www.openwall.com/lists/oss-security/2016/01/26/3 | CONFIRM:https://mariadb.atlassian.net/browse/MDEV-9212 | CONFIRM:https://mariadb.com/kb/en/mariadb/mariadb-10110-release-notes/ | CONFIRM:https://mariadb.com/kb/en/mariadb/mariadb-5547-release-notes/ | CONFIRM:https://mariadb.com/kb/en/mdb-10023-rn/ | DEBIAN:DSA-3453 | URL:http://www.debian.org/security/2016/dsa-3453";Assigned (20160122);"None (candidate not yet proposed)"; -10.1.10;10;1;10;CVE-2016-2047;Candidate;"The ssl_verify_server_cert function in sql-common/client.c in MariaDB before 5.5.47; 10.0.x before 10.0.23; and 10.1.x before 10.1.10; Oracle MySQL; and Percona Server do not properly verify that the server hostname matches a domain name in the subject's Common Name (CN) or subjectAltName field of the X.509 certificate; which allows man-in-the-middle attackers to spoof SSL servers via a ""/CN="" string in a field in a certificate; as demonstrated by ""/OU=/CN=bar.com/CN=foo.com.""";"MLIST:[oss-security] 20160126 Flaw in mariadb clients SSL certificate validation | URL:http://www.openwall.com/lists/oss-security/2016/01/26/3 | CONFIRM:https://mariadb.atlassian.net/browse/MDEV-9212 | CONFIRM:https://mariadb.com/kb/en/mariadb/mariadb-10110-release-notes/ | CONFIRM:https://mariadb.com/kb/en/mariadb/mariadb-5547-release-notes/ | CONFIRM:https://mariadb.com/kb/en/mdb-10023-rn/ | DEBIAN:DSA-3453 | URL:http://www.debian.org/security/2016/dsa-3453";Assigned (20160122);"None (candidate not yet proposed)"; +5.6.26;5;6;26;CVE-2015-4791;Candidate;"Unspecified vulnerability in Oracle MySQL Server 5.6.26 and earlier allows remote authenticated users to affect availability via unknown vectors related to Server : Security : Privileges.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/cpuoct2015-2367953.html";Assigned (20150624);"None (candidate not yet proposed)"; +5.5.45;5;5;45;CVE-2015-4792;Candidate;"Unspecified vulnerability in Oracle MySQL Server 5.5.45 and earlier and 5.6.26 and earlier allows remote authenticated users to affect availability via unknown vectors related to Server : Partition; a different vulnerability than CVE-2015-4802.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/cpuoct2015-2367953.html | REDHAT:RHSA-2016:0534 | URL:http://rhn.redhat.com/errata/RHSA-2016-0534.html | SUSE:SUSE-SU-2016:0296 | URL:https://www.suse.com/support/update/announcement/2016/suse-su-20160296-1.html | SUSE:openSUSE-SU-2016:0368 | URL:http://lists.opensuse.org/opensuse-updates/2016-02/msg00039.html";Assigned (20150624);"None (candidate not yet proposed)"; +5.6.26;5;6;26;CVE-2015-4792;Candidate;"Unspecified vulnerability in Oracle MySQL Server 5.5.45 and earlier and 5.6.26 and earlier allows remote authenticated users to affect availability via unknown vectors related to Server : Partition; a different vulnerability than CVE-2015-4802.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/cpuoct2015-2367953.html | REDHAT:RHSA-2016:0534 | URL:http://rhn.redhat.com/errata/RHSA-2016-0534.html | SUSE:SUSE-SU-2016:0296 | URL:https://www.suse.com/support/update/announcement/2016/suse-su-20160296-1.html | SUSE:openSUSE-SU-2016:0368 | URL:http://lists.opensuse.org/opensuse-updates/2016-02/msg00039.html";Assigned (20150624);"None (candidate not yet proposed)"; +5.6.26;5;6;26;CVE-2015-4800;Candidate;"Unspecified vulnerability in Oracle MySQL Server 5.6.26 and earlier allows remote authenticated users to affect availability via unknown vectors related to Server : Optimizer.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/cpuoct2015-2367953.html";Assigned (20150624);"None (candidate not yet proposed)"; +5.5.45;5;5;45;CVE-2015-4802;Candidate;"Unspecified vulnerability in Oracle MySQL Server 5.5.45 and earlier and 5.6.26 and earlier allows remote authenticated users to affect availability via unknown vectors related to Server : Partition; a different vulnerability than CVE-2015-4792.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/cpuoct2015-2367953.html | REDHAT:RHSA-2016:0534 | URL:http://rhn.redhat.com/errata/RHSA-2016-0534.html | SUSE:SUSE-SU-2016:0296 | URL:https://www.suse.com/support/update/announcement/2016/suse-su-20160296-1.html | SUSE:openSUSE-SU-2016:0368 | URL:http://lists.opensuse.org/opensuse-updates/2016-02/msg00039.html";Assigned (20150624);"None (candidate not yet proposed)"; +5.6.26;5;6;26;CVE-2015-4802;Candidate;"Unspecified vulnerability in Oracle MySQL Server 5.5.45 and earlier and 5.6.26 and earlier allows remote authenticated users to affect availability via unknown vectors related to Server : Partition; a different vulnerability than CVE-2015-4792.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/cpuoct2015-2367953.html | REDHAT:RHSA-2016:0534 | URL:http://rhn.redhat.com/errata/RHSA-2016-0534.html | SUSE:SUSE-SU-2016:0296 | URL:https://www.suse.com/support/update/announcement/2016/suse-su-20160296-1.html | SUSE:openSUSE-SU-2016:0368 | URL:http://lists.opensuse.org/opensuse-updates/2016-02/msg00039.html";Assigned (20150624);"None (candidate not yet proposed)"; +5.5.45;5;5;45;CVE-2015-4815;Candidate;"Unspecified vulnerability in Oracle MySQL Server 5.5.45 and earlier and 5.6.26 and earlier allows remote authenticated users to affect availability via vectors related to Server : DDL.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/cpuoct2015-2367953.html | REDHAT:RHSA-2016:0534 | URL:http://rhn.redhat.com/errata/RHSA-2016-0534.html | SUSE:SUSE-SU-2016:0296 | URL:https://www.suse.com/support/update/announcement/2016/suse-su-20160296-1.html | SUSE:openSUSE-SU-2016:0368 | URL:http://lists.opensuse.org/opensuse-updates/2016-02/msg00039.html";Assigned (20150624);"None (candidate not yet proposed)"; +5.6.26;5;6;26;CVE-2015-4815;Candidate;"Unspecified vulnerability in Oracle MySQL Server 5.5.45 and earlier and 5.6.26 and earlier allows remote authenticated users to affect availability via vectors related to Server : DDL.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/cpuoct2015-2367953.html | REDHAT:RHSA-2016:0534 | URL:http://rhn.redhat.com/errata/RHSA-2016-0534.html | SUSE:SUSE-SU-2016:0296 | URL:https://www.suse.com/support/update/announcement/2016/suse-su-20160296-1.html | SUSE:openSUSE-SU-2016:0368 | URL:http://lists.opensuse.org/opensuse-updates/2016-02/msg00039.html";Assigned (20150624);"None (candidate not yet proposed)"; +5.5.44;5;5;44;CVE-2015-4816;Candidate;"Unspecified vulnerability in Oracle MySQL Server 5.5.44 and earlier allows remote authenticated users to affect availability via unknown vectors related to Server : InnoDB.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/cpuoct2015-2367953.html | REDHAT:RHSA-2016:0534 | URL:http://rhn.redhat.com/errata/RHSA-2016-0534.html";Assigned (20150624);"None (candidate not yet proposed)"; +5.5.44;5;5;44;CVE-2015-4819;Candidate;"Unspecified vulnerability in Oracle MySQL Server 5.5.44 and earlier; and 5.6.25 and earlier; allows local users to affect confidentiality; integrity; and availability via unknown vectors related to Client programs.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/cpuoct2015-2367953.html | REDHAT:RHSA-2016:0534 | URL:http://rhn.redhat.com/errata/RHSA-2016-0534.html";Assigned (20150624);"None (candidate not yet proposed)"; +5.6.25;5;6;25;CVE-2015-4819;Candidate;"Unspecified vulnerability in Oracle MySQL Server 5.5.44 and earlier; and 5.6.25 and earlier; allows local users to affect confidentiality; integrity; and availability via unknown vectors related to Client programs.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/cpuoct2015-2367953.html | REDHAT:RHSA-2016:0534 | URL:http://rhn.redhat.com/errata/RHSA-2016-0534.html";Assigned (20150624);"None (candidate not yet proposed)"; +5.5.45;5;5;45;CVE-2015-4826;Candidate;"Unspecified vulnerability in Oracle MySQL Server 5.5.45 and earlier and 5.6.26 and earlier allows remote authenticated users to affect confidentiality via unknown vectors related to Server : Types.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/cpuoct2015-2367953.html | REDHAT:RHSA-2016:0534 | URL:http://rhn.redhat.com/errata/RHSA-2016-0534.html | SUSE:SUSE-SU-2016:0296 | URL:https://www.suse.com/support/update/announcement/2016/suse-su-20160296-1.html | SUSE:openSUSE-SU-2016:0368 | URL:http://lists.opensuse.org/opensuse-updates/2016-02/msg00039.html";Assigned (20150624);"None (candidate not yet proposed)"; +5.6.26;5;6;26;CVE-2015-4826;Candidate;"Unspecified vulnerability in Oracle MySQL Server 5.5.45 and earlier and 5.6.26 and earlier allows remote authenticated users to affect confidentiality via unknown vectors related to Server : Types.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/cpuoct2015-2367953.html | REDHAT:RHSA-2016:0534 | URL:http://rhn.redhat.com/errata/RHSA-2016-0534.html | SUSE:SUSE-SU-2016:0296 | URL:https://www.suse.com/support/update/announcement/2016/suse-su-20160296-1.html | SUSE:openSUSE-SU-2016:0368 | URL:http://lists.opensuse.org/opensuse-updates/2016-02/msg00039.html";Assigned (20150624);"None (candidate not yet proposed)"; +5.5.45;5;5;45;CVE-2015-4830;Candidate;"Unspecified vulnerability in Oracle MySQL Server 5.5.45 and earlier and 5.6.26 and earlier allows remote authenticated users to affect integrity via unknown vectors related to Server : Security : Privileges.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/cpuoct2015-2367953.html | REDHAT:RHSA-2016:0534 | URL:http://rhn.redhat.com/errata/RHSA-2016-0534.html | SUSE:SUSE-SU-2016:0296 | URL:https://www.suse.com/support/update/announcement/2016/suse-su-20160296-1.html | SUSE:openSUSE-SU-2016:0368 | URL:http://lists.opensuse.org/opensuse-updates/2016-02/msg00039.html";Assigned (20150624);"None (candidate not yet proposed)"; +5.6.26;5;6;26;CVE-2015-4830;Candidate;"Unspecified vulnerability in Oracle MySQL Server 5.5.45 and earlier and 5.6.26 and earlier allows remote authenticated users to affect integrity via unknown vectors related to Server : Security : Privileges.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/cpuoct2015-2367953.html | REDHAT:RHSA-2016:0534 | URL:http://rhn.redhat.com/errata/RHSA-2016-0534.html | SUSE:SUSE-SU-2016:0296 | URL:https://www.suse.com/support/update/announcement/2016/suse-su-20160296-1.html | SUSE:openSUSE-SU-2016:0368 | URL:http://lists.opensuse.org/opensuse-updates/2016-02/msg00039.html";Assigned (20150624);"None (candidate not yet proposed)"; +5.6.25;5;6;25;CVE-2015-4833;Candidate;"Unspecified vulnerability in Oracle MySQL Server 5.6.25 and earlier allows remote authenticated users to affect availability via unknown vectors related to Server : Partition.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/cpuoct2015-2367953.html";Assigned (20150624);"None (candidate not yet proposed)"; +5.5.45;5;5;45;CVE-2015-4836;Candidate;"Unspecified vulnerability in Oracle MySQL Server 5.5.45 and earlier; and 5.6.26 and earlier; allows remote authenticated users to affect availability via unknown vectors related to Server : SP.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/cpuoct2015-2367953.html | REDHAT:RHSA-2016:0534 | URL:http://rhn.redhat.com/errata/RHSA-2016-0534.html | SUSE:SUSE-SU-2016:0296 | URL:https://www.suse.com/support/update/announcement/2016/suse-su-20160296-1.html | SUSE:openSUSE-SU-2016:0368 | URL:http://lists.opensuse.org/opensuse-updates/2016-02/msg00039.html";Assigned (20150624);"None (candidate not yet proposed)"; +5.6.26;5;6;26;CVE-2015-4836;Candidate;"Unspecified vulnerability in Oracle MySQL Server 5.5.45 and earlier; and 5.6.26 and earlier; allows remote authenticated users to affect availability via unknown vectors related to Server : SP.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/cpuoct2015-2367953.html | REDHAT:RHSA-2016:0534 | URL:http://rhn.redhat.com/errata/RHSA-2016-0534.html | SUSE:SUSE-SU-2016:0296 | URL:https://www.suse.com/support/update/announcement/2016/suse-su-20160296-1.html | SUSE:openSUSE-SU-2016:0368 | URL:http://lists.opensuse.org/opensuse-updates/2016-02/msg00039.html";Assigned (20150624);"None (candidate not yet proposed)"; +5.5.45;5;5;45;CVE-2015-4858;Candidate;"Unspecified vulnerability in Oracle MySQL Server 5.5.45 and earlier; and 5.6.26 and earlier; allows remote authenticated users to affect availability via vectors related to DML; a different vulnerability than CVE-2015-4913.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/cpuoct2015-2367953.html | REDHAT:RHSA-2016:0534 | URL:http://rhn.redhat.com/errata/RHSA-2016-0534.html | SUSE:SUSE-SU-2016:0296 | URL:https://www.suse.com/support/update/announcement/2016/suse-su-20160296-1.html | SUSE:openSUSE-SU-2016:0368 | URL:http://lists.opensuse.org/opensuse-updates/2016-02/msg00039.html";Assigned (20150624);"None (candidate not yet proposed)"; +5.6.26;5;6;26;CVE-2015-4858;Candidate;"Unspecified vulnerability in Oracle MySQL Server 5.5.45 and earlier; and 5.6.26 and earlier; allows remote authenticated users to affect availability via vectors related to DML; a different vulnerability than CVE-2015-4913.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/cpuoct2015-2367953.html | REDHAT:RHSA-2016:0534 | URL:http://rhn.redhat.com/errata/RHSA-2016-0534.html | SUSE:SUSE-SU-2016:0296 | URL:https://www.suse.com/support/update/announcement/2016/suse-su-20160296-1.html | SUSE:openSUSE-SU-2016:0368 | URL:http://lists.opensuse.org/opensuse-updates/2016-02/msg00039.html";Assigned (20150624);"None (candidate not yet proposed)"; +5.5.45;5;5;45;CVE-2015-4861;Candidate;"Unspecified vulnerability in Oracle MySQL Server 5.5.45 and earlier; and 5.6.26 and earlier; allows remote authenticated users to affect availability via unknown vectors related to Server : InnoDB.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/cpuoct2015-2367953.html | REDHAT:RHSA-2016:0534 | URL:http://rhn.redhat.com/errata/RHSA-2016-0534.html | SUSE:SUSE-SU-2016:0296 | URL:https://www.suse.com/support/update/announcement/2016/suse-su-20160296-1.html | SUSE:openSUSE-SU-2016:0368 | URL:http://lists.opensuse.org/opensuse-updates/2016-02/msg00039.html";Assigned (20150624);"None (candidate not yet proposed)"; +5.6.26;5;6;26;CVE-2015-4861;Candidate;"Unspecified vulnerability in Oracle MySQL Server 5.5.45 and earlier; and 5.6.26 and earlier; allows remote authenticated users to affect availability via unknown vectors related to Server : InnoDB.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/cpuoct2015-2367953.html | REDHAT:RHSA-2016:0534 | URL:http://rhn.redhat.com/errata/RHSA-2016-0534.html | SUSE:SUSE-SU-2016:0296 | URL:https://www.suse.com/support/update/announcement/2016/suse-su-20160296-1.html | SUSE:openSUSE-SU-2016:0368 | URL:http://lists.opensuse.org/opensuse-updates/2016-02/msg00039.html";Assigned (20150624);"None (candidate not yet proposed)"; +5.6.26;5;6;26;CVE-2015-4862;Candidate;"Unspecified vulnerability in Oracle MySQL Server 5.6.26 and earlier allows remote authenticated users to affect availability via vectors related to DML.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/cpuoct2015-2367953.html";Assigned (20150624);"None (candidate not yet proposed)"; +5.5.43;5;5;43;CVE-2015-4864;Candidate;"Unspecified vulnerability in Oracle MySQL Server 5.5.43 and earlier and 5.6.24 and earlier allows remote authenticated users to affect integrity via unknown vectors related to Server : Security : Privileges.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/cpuoct2015-2367953.html";Assigned (20150624);"None (candidate not yet proposed)"; +5.6.24;5;6;24;CVE-2015-4864;Candidate;"Unspecified vulnerability in Oracle MySQL Server 5.5.43 and earlier and 5.6.24 and earlier allows remote authenticated users to affect integrity via unknown vectors related to Server : Security : Privileges.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/cpuoct2015-2367953.html";Assigned (20150624);"None (candidate not yet proposed)"; +5.6.23;5;6;23;CVE-2015-4866;Candidate;"Unspecified vulnerability in Oracle MySQL Server 5.6.23 and earlier allows remote authenticated users to affect availability via unknown vectors related to Server : InnoDB.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/cpuoct2015-2367953.html";Assigned (20150624);"None (candidate not yet proposed)"; +5.5.45;5;5;45;CVE-2015-4870;Candidate;"Unspecified vulnerability in Oracle MySQL Server 5.5.45 and earlier; and 5.6.26 and earlier; allows remote authenticated users to affect availability via unknown vectors related to Server : Parser.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/cpuoct2015-2367953.html | REDHAT:RHSA-2016:0534 | URL:http://rhn.redhat.com/errata/RHSA-2016-0534.html | SUSE:SUSE-SU-2016:0296 | URL:https://www.suse.com/support/update/announcement/2016/suse-su-20160296-1.html | SUSE:openSUSE-SU-2016:0368 | URL:http://lists.opensuse.org/opensuse-updates/2016-02/msg00039.html";Assigned (20150624);"None (candidate not yet proposed)"; +5.6.26;5;6;26;CVE-2015-4870;Candidate;"Unspecified vulnerability in Oracle MySQL Server 5.5.45 and earlier; and 5.6.26 and earlier; allows remote authenticated users to affect availability via unknown vectors related to Server : Parser.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/cpuoct2015-2367953.html | REDHAT:RHSA-2016:0534 | URL:http://rhn.redhat.com/errata/RHSA-2016-0534.html | SUSE:SUSE-SU-2016:0296 | URL:https://www.suse.com/support/update/announcement/2016/suse-su-20160296-1.html | SUSE:openSUSE-SU-2016:0368 | URL:http://lists.opensuse.org/opensuse-updates/2016-02/msg00039.html";Assigned (20150624);"None (candidate not yet proposed)"; +5.5.44;5;5;44;CVE-2015-4879;Candidate;"Unspecified vulnerability in Oracle MySQL Server 5.5.44 and earlier; and 5.6.25 and earlier; allows remote authenticated users to affect confidentiality; integrity; and availability via vectors related to DML.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/cpuoct2015-2367953.html | REDHAT:RHSA-2016:0534 | URL:http://rhn.redhat.com/errata/RHSA-2016-0534.html";Assigned (20150624);"None (candidate not yet proposed)"; +5.6.25;5;6;25;CVE-2015-4879;Candidate;"Unspecified vulnerability in Oracle MySQL Server 5.5.44 and earlier; and 5.6.25 and earlier; allows remote authenticated users to affect confidentiality; integrity; and availability via vectors related to DML.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/cpuoct2015-2367953.html | REDHAT:RHSA-2016:0534 | URL:http://rhn.redhat.com/errata/RHSA-2016-0534.html";Assigned (20150624);"None (candidate not yet proposed)"; +5.6.26;5;6;26;CVE-2015-4890;Candidate;"Unspecified vulnerability in Oracle MySQL Server 5.6.26 and earlier allows remote authenticated users to affect availability via unknown vectors related to Server : Replication.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/cpuoct2015-2367953.html";Assigned (20150624);"None (candidate not yet proposed)"; +5.6.25;5;6;25;CVE-2015-4895;Candidate;"Unspecified vulnerability in Oracle MySQL Server 5.6.25 and earlier allows remote authenticated users to affect availability via unknown vectors related to Server : InnoDB.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/cpuoct2015-2367953.html";Assigned (20150624);"None (candidate not yet proposed)"; +5.6.25;5;6;25;CVE-2015-4904;Candidate;"Unspecified vulnerability in Oracle MySQL Server 5.6.25 and earlier allows remote authenticated users to affect availability via unknown vectors related to libmysqld.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/cpuoct2015-2367953.html";Assigned (20150624);"None (candidate not yet proposed)"; +5.6.23;5;6;23;CVE-2015-4905;Candidate;"Unspecified vulnerability in Oracle MySQL Server 5.6.23 and earlier allows remote authenticated users to affect availability via vectors related to Server : DML.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/cpuoct2015-2367953.html";Assigned (20150624);"None (candidate not yet proposed)"; +5.6.26;5;6;26;CVE-2015-4910;Candidate;"Unspecified vulnerability in Oracle MySQL Server 5.6.26 and earlier allows remote authenticated users to affect availability via unknown vectors related to Server : Memcached.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/cpuoct2015-2367953.html";Assigned (20150624);"None (candidate not yet proposed)"; +5.5.45;5;5;45;CVE-2015-4913;Candidate;"Unspecified vulnerability in Oracle MySQL Server 5.5.45 and earlier and 5.6.26 and earlier allows remote authenticated users to affect availability via vectors related to Server : DML; a different vulnerability than CVE-2015-4858.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/cpuoct2015-2367953.html | REDHAT:RHSA-2016:0534 | URL:http://rhn.redhat.com/errata/RHSA-2016-0534.html | SUSE:SUSE-SU-2016:0296 | URL:https://www.suse.com/support/update/announcement/2016/suse-su-20160296-1.html | SUSE:openSUSE-SU-2016:0368 | URL:http://lists.opensuse.org/opensuse-updates/2016-02/msg00039.html";Assigned (20150624);"None (candidate not yet proposed)"; +5.6.26;5;6;26;CVE-2015-4913;Candidate;"Unspecified vulnerability in Oracle MySQL Server 5.5.45 and earlier and 5.6.26 and earlier allows remote authenticated users to affect availability via vectors related to Server : DML; a different vulnerability than CVE-2015-4858.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/cpuoct2015-2367953.html | REDHAT:RHSA-2016:0534 | URL:http://rhn.redhat.com/errata/RHSA-2016-0534.html | SUSE:SUSE-SU-2016:0296 | URL:https://www.suse.com/support/update/announcement/2016/suse-su-20160296-1.html | SUSE:openSUSE-SU-2016:0368 | URL:http://lists.opensuse.org/opensuse-updates/2016-02/msg00039.html";Assigned (20150624);"None (candidate not yet proposed)"; +5.6.28;5;6;28;CVE-2015-5969;Candidate;"The mysql-systemd-helper script in the mysql-community-server package before 5.6.28-2.17.1 in openSUSE 13.2 and before 5.6.28-13.1 in openSUSE Leap 42.1 and the mariadb package before 10.0.22-2.21.2 in openSUSE 13.2 and before 10.0.22-3.1 in SUSE Linux Enterprise (SLE) 12.1 and openSUSE Leap 42.1 allows local users to discover database credentials by listing a process and its arguments.";"CONFIRM:https://bugzilla.suse.com/957174 | SUSE:SUSE-SU-2016:0296 | URL:https://www.suse.com/support/update/announcement/2016/suse-su-20160296-1.html | SUSE:openSUSE-SU-2016:0367 | URL:http://lists.opensuse.org/opensuse-security-announce/2016-02/msg00015.html | SUSE:openSUSE-SU-2016:0368 | URL:http://lists.opensuse.org/opensuse-updates/2016-02/msg00039.html | SUSE:openSUSE-SU-2016:0379 | URL:http://lists.opensuse.org/opensuse-updates/2016-02/msg00050.html";Assigned (20150812);"None (candidate not yet proposed)"; +2.17.1;2;17;1;CVE-2015-5969;Candidate;"The mysql-systemd-helper script in the mysql-community-server package before 5.6.28-2.17.1 in openSUSE 13.2 and before 5.6.28-13.1 in openSUSE Leap 42.1 and the mariadb package before 10.0.22-2.21.2 in openSUSE 13.2 and before 10.0.22-3.1 in SUSE Linux Enterprise (SLE) 12.1 and openSUSE Leap 42.1 allows local users to discover database credentials by listing a process and its arguments.";"CONFIRM:https://bugzilla.suse.com/957174 | SUSE:SUSE-SU-2016:0296 | URL:https://www.suse.com/support/update/announcement/2016/suse-su-20160296-1.html | SUSE:openSUSE-SU-2016:0367 | URL:http://lists.opensuse.org/opensuse-security-announce/2016-02/msg00015.html | SUSE:openSUSE-SU-2016:0368 | URL:http://lists.opensuse.org/opensuse-updates/2016-02/msg00039.html | SUSE:openSUSE-SU-2016:0379 | URL:http://lists.opensuse.org/opensuse-updates/2016-02/msg00050.html";Assigned (20150812);"None (candidate not yet proposed)"; +10.0.22;10;0;22;CVE-2015-5969;Candidate;"The mysql-systemd-helper script in the mysql-community-server package before 5.6.28-2.17.1 in openSUSE 13.2 and before 5.6.28-13.1 in openSUSE Leap 42.1 and the mariadb package before 10.0.22-2.21.2 in openSUSE 13.2 and before 10.0.22-3.1 in SUSE Linux Enterprise (SLE) 12.1 and openSUSE Leap 42.1 allows local users to discover database credentials by listing a process and its arguments.";"CONFIRM:https://bugzilla.suse.com/957174 | SUSE:SUSE-SU-2016:0296 | URL:https://www.suse.com/support/update/announcement/2016/suse-su-20160296-1.html | SUSE:openSUSE-SU-2016:0367 | URL:http://lists.opensuse.org/opensuse-security-announce/2016-02/msg00015.html | SUSE:openSUSE-SU-2016:0368 | URL:http://lists.opensuse.org/opensuse-updates/2016-02/msg00039.html | SUSE:openSUSE-SU-2016:0379 | URL:http://lists.opensuse.org/opensuse-updates/2016-02/msg00050.html";Assigned (20150812);"None (candidate not yet proposed)"; +2.21.2;2;21;2;CVE-2015-5969;Candidate;"The mysql-systemd-helper script in the mysql-community-server package before 5.6.28-2.17.1 in openSUSE 13.2 and before 5.6.28-13.1 in openSUSE Leap 42.1 and the mariadb package before 10.0.22-2.21.2 in openSUSE 13.2 and before 10.0.22-3.1 in SUSE Linux Enterprise (SLE) 12.1 and openSUSE Leap 42.1 allows local users to discover database credentials by listing a process and its arguments.";"CONFIRM:https://bugzilla.suse.com/957174 | SUSE:SUSE-SU-2016:0296 | URL:https://www.suse.com/support/update/announcement/2016/suse-su-20160296-1.html | SUSE:openSUSE-SU-2016:0367 | URL:http://lists.opensuse.org/opensuse-security-announce/2016-02/msg00015.html | SUSE:openSUSE-SU-2016:0368 | URL:http://lists.opensuse.org/opensuse-updates/2016-02/msg00039.html | SUSE:openSUSE-SU-2016:0379 | URL:http://lists.opensuse.org/opensuse-updates/2016-02/msg00050.html";Assigned (20150812);"None (candidate not yet proposed)"; +5.5.46;5;5;46;CVE-2016-0546;Candidate;"Unspecified vulnerability in Oracle MySQL 5.5.46 and earlier; 5.6.27 and earlier; and 5.7.9 and MariaDB before 5.5.47; 10.0.x before 10.0.23; and 10.1.x before 10.1.10 allows local users to affect confidentiality; integrity; and availability via unknown vectors related to Client. NOTE: the previous information is from the January 2016 CPU. Oracle has not commented on third-party claims that these are multiple buffer overflows in the mysqlshow tool that allow remote database servers to have unspecified impact via a long table or database name.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/cpujan2016-2367955.html | CONFIRM:https://mariadb.com/kb/en/mariadb/mariadb-10110-release-notes/ | CONFIRM:https://mariadb.com/kb/en/mariadb/mariadb-5547-release-notes/ | CONFIRM:https://mariadb.com/kb/en/mdb-10023-rn/ | CONFIRM:https://bugzilla.redhat.com/show_bug.cgi?id=1301493 | CONFIRM:https://dev.mysql.com/doc/relnotes/mysql/5.5/en/news-5-5-47.html | CONFIRM:https://dev.mysql.com/doc/relnotes/mysql/5.6/en/news-5-6-28.html | CONFIRM:https://github.com/mysql/mysql-server/commit/0dbd5a8797ed4bd18e8b883988fb62177eb0f73f | DEBIAN:DSA-3453 | URL:http://www.debian.org/security/2016/dsa-3453 | REDHAT:RHSA-2016:0534 | URL:http://rhn.redhat.com/errata/RHSA-2016-0534.html | SUSE:openSUSE-SU-2016:0367 | URL:http://lists.opensuse.org/opensuse-security-announce/2016-02/msg00015.html";Assigned (20151209);"None (candidate not yet proposed)"; +5.6.27;5;6;27;CVE-2016-0546;Candidate;"Unspecified vulnerability in Oracle MySQL 5.5.46 and earlier; 5.6.27 and earlier; and 5.7.9 and MariaDB before 5.5.47; 10.0.x before 10.0.23; and 10.1.x before 10.1.10 allows local users to affect confidentiality; integrity; and availability via unknown vectors related to Client. NOTE: the previous information is from the January 2016 CPU. Oracle has not commented on third-party claims that these are multiple buffer overflows in the mysqlshow tool that allow remote database servers to have unspecified impact via a long table or database name.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/cpujan2016-2367955.html | CONFIRM:https://mariadb.com/kb/en/mariadb/mariadb-10110-release-notes/ | CONFIRM:https://mariadb.com/kb/en/mariadb/mariadb-5547-release-notes/ | CONFIRM:https://mariadb.com/kb/en/mdb-10023-rn/ | CONFIRM:https://bugzilla.redhat.com/show_bug.cgi?id=1301493 | CONFIRM:https://dev.mysql.com/doc/relnotes/mysql/5.5/en/news-5-5-47.html | CONFIRM:https://dev.mysql.com/doc/relnotes/mysql/5.6/en/news-5-6-28.html | CONFIRM:https://github.com/mysql/mysql-server/commit/0dbd5a8797ed4bd18e8b883988fb62177eb0f73f | DEBIAN:DSA-3453 | URL:http://www.debian.org/security/2016/dsa-3453 | REDHAT:RHSA-2016:0534 | URL:http://rhn.redhat.com/errata/RHSA-2016-0534.html | SUSE:openSUSE-SU-2016:0367 | URL:http://lists.opensuse.org/opensuse-security-announce/2016-02/msg00015.html";Assigned (20151209);"None (candidate not yet proposed)"; +5.7.9;5;7;9;CVE-2016-0546;Candidate;"Unspecified vulnerability in Oracle MySQL 5.5.46 and earlier; 5.6.27 and earlier; and 5.7.9 and MariaDB before 5.5.47; 10.0.x before 10.0.23; and 10.1.x before 10.1.10 allows local users to affect confidentiality; integrity; and availability via unknown vectors related to Client. NOTE: the previous information is from the January 2016 CPU. Oracle has not commented on third-party claims that these are multiple buffer overflows in the mysqlshow tool that allow remote database servers to have unspecified impact via a long table or database name.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/cpujan2016-2367955.html | CONFIRM:https://mariadb.com/kb/en/mariadb/mariadb-10110-release-notes/ | CONFIRM:https://mariadb.com/kb/en/mariadb/mariadb-5547-release-notes/ | CONFIRM:https://mariadb.com/kb/en/mdb-10023-rn/ | CONFIRM:https://bugzilla.redhat.com/show_bug.cgi?id=1301493 | CONFIRM:https://dev.mysql.com/doc/relnotes/mysql/5.5/en/news-5-5-47.html | CONFIRM:https://dev.mysql.com/doc/relnotes/mysql/5.6/en/news-5-6-28.html | CONFIRM:https://github.com/mysql/mysql-server/commit/0dbd5a8797ed4bd18e8b883988fb62177eb0f73f | DEBIAN:DSA-3453 | URL:http://www.debian.org/security/2016/dsa-3453 | REDHAT:RHSA-2016:0534 | URL:http://rhn.redhat.com/errata/RHSA-2016-0534.html | SUSE:openSUSE-SU-2016:0367 | URL:http://lists.opensuse.org/opensuse-security-announce/2016-02/msg00015.html";Assigned (20151209);"None (candidate not yet proposed)"; +5.5.47;5;5;47;CVE-2016-0546;Candidate;"Unspecified vulnerability in Oracle MySQL 5.5.46 and earlier; 5.6.27 and earlier; and 5.7.9 and MariaDB before 5.5.47; 10.0.x before 10.0.23; and 10.1.x before 10.1.10 allows local users to affect confidentiality; integrity; and availability via unknown vectors related to Client. NOTE: the previous information is from the January 2016 CPU. Oracle has not commented on third-party claims that these are multiple buffer overflows in the mysqlshow tool that allow remote database servers to have unspecified impact via a long table or database name.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/cpujan2016-2367955.html | CONFIRM:https://mariadb.com/kb/en/mariadb/mariadb-10110-release-notes/ | CONFIRM:https://mariadb.com/kb/en/mariadb/mariadb-5547-release-notes/ | CONFIRM:https://mariadb.com/kb/en/mdb-10023-rn/ | CONFIRM:https://bugzilla.redhat.com/show_bug.cgi?id=1301493 | CONFIRM:https://dev.mysql.com/doc/relnotes/mysql/5.5/en/news-5-5-47.html | CONFIRM:https://dev.mysql.com/doc/relnotes/mysql/5.6/en/news-5-6-28.html | CONFIRM:https://github.com/mysql/mysql-server/commit/0dbd5a8797ed4bd18e8b883988fb62177eb0f73f | DEBIAN:DSA-3453 | URL:http://www.debian.org/security/2016/dsa-3453 | REDHAT:RHSA-2016:0534 | URL:http://rhn.redhat.com/errata/RHSA-2016-0534.html | SUSE:openSUSE-SU-2016:0367 | URL:http://lists.opensuse.org/opensuse-security-announce/2016-02/msg00015.html";Assigned (20151209);"None (candidate not yet proposed)"; +10.0.23;10;0;23;CVE-2016-0546;Candidate;"Unspecified vulnerability in Oracle MySQL 5.5.46 and earlier; 5.6.27 and earlier; and 5.7.9 and MariaDB before 5.5.47; 10.0.x before 10.0.23; and 10.1.x before 10.1.10 allows local users to affect confidentiality; integrity; and availability via unknown vectors related to Client. NOTE: the previous information is from the January 2016 CPU. Oracle has not commented on third-party claims that these are multiple buffer overflows in the mysqlshow tool that allow remote database servers to have unspecified impact via a long table or database name.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/cpujan2016-2367955.html | CONFIRM:https://mariadb.com/kb/en/mariadb/mariadb-10110-release-notes/ | CONFIRM:https://mariadb.com/kb/en/mariadb/mariadb-5547-release-notes/ | CONFIRM:https://mariadb.com/kb/en/mdb-10023-rn/ | CONFIRM:https://bugzilla.redhat.com/show_bug.cgi?id=1301493 | CONFIRM:https://dev.mysql.com/doc/relnotes/mysql/5.5/en/news-5-5-47.html | CONFIRM:https://dev.mysql.com/doc/relnotes/mysql/5.6/en/news-5-6-28.html | CONFIRM:https://github.com/mysql/mysql-server/commit/0dbd5a8797ed4bd18e8b883988fb62177eb0f73f | DEBIAN:DSA-3453 | URL:http://www.debian.org/security/2016/dsa-3453 | REDHAT:RHSA-2016:0534 | URL:http://rhn.redhat.com/errata/RHSA-2016-0534.html | SUSE:openSUSE-SU-2016:0367 | URL:http://lists.opensuse.org/opensuse-security-announce/2016-02/msg00015.html";Assigned (20151209);"None (candidate not yet proposed)"; +10.1.10;10;1;10;CVE-2016-0546;Candidate;"Unspecified vulnerability in Oracle MySQL 5.5.46 and earlier; 5.6.27 and earlier; and 5.7.9 and MariaDB before 5.5.47; 10.0.x before 10.0.23; and 10.1.x before 10.1.10 allows local users to affect confidentiality; integrity; and availability via unknown vectors related to Client. NOTE: the previous information is from the January 2016 CPU. Oracle has not commented on third-party claims that these are multiple buffer overflows in the mysqlshow tool that allow remote database servers to have unspecified impact via a long table or database name.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/cpujan2016-2367955.html | CONFIRM:https://mariadb.com/kb/en/mariadb/mariadb-10110-release-notes/ | CONFIRM:https://mariadb.com/kb/en/mariadb/mariadb-5547-release-notes/ | CONFIRM:https://mariadb.com/kb/en/mdb-10023-rn/ | CONFIRM:https://bugzilla.redhat.com/show_bug.cgi?id=1301493 | CONFIRM:https://dev.mysql.com/doc/relnotes/mysql/5.5/en/news-5-5-47.html | CONFIRM:https://dev.mysql.com/doc/relnotes/mysql/5.6/en/news-5-6-28.html | CONFIRM:https://github.com/mysql/mysql-server/commit/0dbd5a8797ed4bd18e8b883988fb62177eb0f73f | DEBIAN:DSA-3453 | URL:http://www.debian.org/security/2016/dsa-3453 | REDHAT:RHSA-2016:0534 | URL:http://rhn.redhat.com/errata/RHSA-2016-0534.html | SUSE:openSUSE-SU-2016:0367 | URL:http://lists.opensuse.org/opensuse-security-announce/2016-02/msg00015.html";Assigned (20151209);"None (candidate not yet proposed)"; +5.5.47;5;5;47;CVE-2016-2047;Candidate;"The ssl_verify_server_cert function in sql-common/client.c in MariaDB before 5.5.47; 10.0.x before 10.0.23; and 10.1.x before 10.1.10; Oracle MySQL; and Percona Server do not properly verify that the server hostname matches a domain name in the subject's Common Name (CN) or subjectAltName field of the X.509 certificate; which allows man-in-the-middle attackers to spoof SSL servers via a ""/CN="" string in a field in a certificate; as demonstrated by ""/OU=/CN=bar.com/CN=foo.com.""";"MLIST:[oss-security] 20160126 Flaw in mariadb clients SSL certificate validation | URL:http://www.openwall.com/lists/oss-security/2016/01/26/3 | CONFIRM:https://mariadb.atlassian.net/browse/MDEV-9212 | CONFIRM:https://mariadb.com/kb/en/mariadb/mariadb-10110-release-notes/ | CONFIRM:https://mariadb.com/kb/en/mariadb/mariadb-5547-release-notes/ | CONFIRM:https://mariadb.com/kb/en/mdb-10023-rn/ | DEBIAN:DSA-3453 | URL:http://www.debian.org/security/2016/dsa-3453 | REDHAT:RHSA-2016:0534 | URL:http://rhn.redhat.com/errata/RHSA-2016-0534.html";Assigned (20160122);"None (candidate not yet proposed)"; +10.0.23;10;0;23;CVE-2016-2047;Candidate;"The ssl_verify_server_cert function in sql-common/client.c in MariaDB before 5.5.47; 10.0.x before 10.0.23; and 10.1.x before 10.1.10; Oracle MySQL; and Percona Server do not properly verify that the server hostname matches a domain name in the subject's Common Name (CN) or subjectAltName field of the X.509 certificate; which allows man-in-the-middle attackers to spoof SSL servers via a ""/CN="" string in a field in a certificate; as demonstrated by ""/OU=/CN=bar.com/CN=foo.com.""";"MLIST:[oss-security] 20160126 Flaw in mariadb clients SSL certificate validation | URL:http://www.openwall.com/lists/oss-security/2016/01/26/3 | CONFIRM:https://mariadb.atlassian.net/browse/MDEV-9212 | CONFIRM:https://mariadb.com/kb/en/mariadb/mariadb-10110-release-notes/ | CONFIRM:https://mariadb.com/kb/en/mariadb/mariadb-5547-release-notes/ | CONFIRM:https://mariadb.com/kb/en/mdb-10023-rn/ | DEBIAN:DSA-3453 | URL:http://www.debian.org/security/2016/dsa-3453 | REDHAT:RHSA-2016:0534 | URL:http://rhn.redhat.com/errata/RHSA-2016-0534.html";Assigned (20160122);"None (candidate not yet proposed)"; +10.1.10;10;1;10;CVE-2016-2047;Candidate;"The ssl_verify_server_cert function in sql-common/client.c in MariaDB before 5.5.47; 10.0.x before 10.0.23; and 10.1.x before 10.1.10; Oracle MySQL; and Percona Server do not properly verify that the server hostname matches a domain name in the subject's Common Name (CN) or subjectAltName field of the X.509 certificate; which allows man-in-the-middle attackers to spoof SSL servers via a ""/CN="" string in a field in a certificate; as demonstrated by ""/OU=/CN=bar.com/CN=foo.com.""";"MLIST:[oss-security] 20160126 Flaw in mariadb clients SSL certificate validation | URL:http://www.openwall.com/lists/oss-security/2016/01/26/3 | CONFIRM:https://mariadb.atlassian.net/browse/MDEV-9212 | CONFIRM:https://mariadb.com/kb/en/mariadb/mariadb-10110-release-notes/ | CONFIRM:https://mariadb.com/kb/en/mariadb/mariadb-5547-release-notes/ | CONFIRM:https://mariadb.com/kb/en/mdb-10023-rn/ | DEBIAN:DSA-3453 | URL:http://www.debian.org/security/2016/dsa-3453 | REDHAT:RHSA-2016:0534 | URL:http://rhn.redhat.com/errata/RHSA-2016-0534.html";Assigned (20160122);"None (candidate not yet proposed)"; From 560b45894b090795da5662773deaec1b2743ccc4 Mon Sep 17 00:00:00 2001 From: root Date: Thu, 21 Apr 2016 09:08:20 +0200 Subject: [PATCH 097/126] #184 minor fix due to error message --- mysqltuner.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysqltuner.pl b/mysqltuner.pl index 873ba4a..c1c6316 100755 --- a/mysqltuner.pl +++ b/mysqltuner.pl @@ -3299,7 +3299,7 @@ sub mariadb_galera { badprint "Galera Notify command is not defined."; push( @adjvars, "set up parameter wsrep_notify_cmd to be notify" ); } - if ( trim( $myvar{'wsrep_sst_method'} ) !~ "^\s*xtrabackup.*" ) { + if ( trim( $myvar{'wsrep_sst_method'} ) !~ "^xtrabackup.*" ) { badprint "Galera SST method is not xtrabackup based."; push( @adjvars, "set up parameter wsrep_sst_method to xtrabackup based parameter" ); } From c59a852a038f988a518c6bc94fe0fddf5bc8c5c9 Mon Sep 17 00:00:00 2001 From: root Date: Thu, 21 Apr 2016 23:16:35 +0200 Subject: [PATCH 098/126] minor addition for sys schema #193 --- mysqltuner.pl | 38 ++++++++++++++++++-------------------- 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/mysqltuner.pl b/mysqltuner.pl index c1c6316..f21e016 100755 --- a/mysqltuner.pl +++ b/mysqltuner.pl @@ -197,8 +197,7 @@ if ( $opt{verbose} ) { } # for RPM distributions -$opt{cvefile} = "/usr/share/mysqltuner/vulnerabilities.csv" - unless ( defined $opt{cvefile} and -f "$opt{cvefile}" ); +$opt{cvefile} = "/usr/share/mysqltuner/vulnerabilities.csv" unless ( defined $opt{cvefile} and -f "$opt{cvefile}" ); $opt{cvefile} = '' unless -f "$opt{cvefile}"; $opt{cvefile} = './vulnerabilities.csv' if -f './vulnerabilities.csv'; @@ -264,16 +263,10 @@ sub subheaderprint { my $ln = length("@_") + 2; prettyprint " "; - - #prettyprint "-"x$tln; prettyprint "-" x $sln . " @_ " . "-" x ( $tln - $ln - $sln ); - - #prettyprint "-"x$tln; } sub infoprinthcmd { - - # print Dumper @_; subheaderprint "$_[0]"; infoprintcmd "$_[1]"; } @@ -367,8 +360,7 @@ my ( $physical_memory, $swap_memory, $duflags ); sub os_setup { sub memerror { - badprint -"Unable to determine total memory/swap; use '--forcemem' and '--forceswap'"; + badprint "Unable to determine total memory/swap; use '--forcemem' and '--forceswap'"; exit 1; } my $os = `uname`; @@ -454,7 +446,8 @@ sub os_setup { $result{'OS'}{'Physical Memory'}{'pretty'} = hr_bytes($physical_memory); $result{'OS'}{'Swap Memory'}{'bytes'} = $swap_memory; $result{'OS'}{'Swap Memory'}{'pretty'} = hr_bytes($swap_memory); - + $result{'OS'}{'Other Processes'}{'bytes'} = get_other_process_memory(); + $result{'OS'}{'Other Processes'}{'pretty'} = hr_bytes(get_other_process_memory()); } sub get_http_cli { @@ -798,24 +791,20 @@ sub mysql_setup { } } else { - # It's not Plesk or debian, we should try a login debugprint "$mysqladmincmd $remotestring ping 2>&1"; my $loginstatus = `$mysqladmincmd $remotestring ping 2>&1`; if ( $loginstatus =~ /mysqld is alive/ ) { - # Login went just fine $mysqllogin = " $remotestring "; - - # Did this go well because of a .my.cnf file or is there no password set? + # Did this go well because of a .my.cnf file or is there no password set? my $userpath = `printenv HOME`; if ( length($userpath) > 0 ) { chomp($userpath); } unless ( -e "${userpath}/.my.cnf" or -e "${userpath}/.mylogin.cnf" ) { - badprint -"Successfully authenticated with no password - SECURITY RISK!"; + badprint "Successfully authenticated with no password - SECURITY RISK!"; } return 1; } @@ -956,7 +945,6 @@ sub arr2hash { } sub get_all_vars { - # We need to initiate at least one query so that our data is useable $dummyselect = select_one "SELECT VERSION()"; debugprint "VERSION: " . $dummyselect . ""; @@ -1054,18 +1042,20 @@ sub cve_recommendations { 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; open( FH, "<$opt{cvefile}" ) or die "Can't open $opt{cvefile} for read: $!"; while ( my $cveline = ) { my @cve = split( ';', $cveline ); if ( mysql_micro_version_le( $cve[1], $cve[2], $cve[3] ) ) { badprint "$cve[4] : $cve[5]"; + $result{'CVE'}{'List'}{$cvefound}="$cve[4] : $cve[5]"; $cvefound++; } } close FH or die "Cannot close $opt{cvefile}: $!"; + $result{'CVE'}{'nb'}=$cvefound; if ( $cvefound == 0 ) { goodprint "NO SECURITY CVE FOUND FOR YOUR VERSION"; return; @@ -3027,11 +3017,19 @@ sub mysqsl_pfs { and $myvar{'performance_schema'} eq 'ON' ) { infoprint "Performance schema is disabled."; + return; } else { infoprint "Performance schema is enabled."; } infoprint "Memory used by P_S: " . hr_bytes( get_pf_memory() ); + + if (grep /^sys$/, select_array("SHOW DATABASES")) { + infoprint "Sys schema is installed."; + } else { + infoprint "Sys schema isn't installed."; + return; + } } # Recommendations for Ariadb @@ -4032,7 +4030,7 @@ cve_recommendations; # Display related CVE calculations; # Calculate everything we need mysql_stats; # Print the server stats mysqsl_pfs # Print Performance schema info - mariadb_threadpool; # Print MaraiDB ThreadPool stats +mariadb_threadpool; # Print MaraiDB ThreadPool stats mysql_myisam; # Print MyISAM stats mariadb_ariadb; # Print MaraiDB AriaDB stats mysql_innodb; # Print InnoDB stats From 9b3549a92c2694d273855ed23167a0fac99c9f56 Mon Sep 17 00:00:00 2001 From: root Date: Thu, 21 Apr 2016 23:19:36 +0200 Subject: [PATCH 099/126] #184 minor fix xtrabackup is the good alternative --- mysqltuner.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysqltuner.pl b/mysqltuner.pl index f21e016..c8759c7 100755 --- a/mysqltuner.pl +++ b/mysqltuner.pl @@ -3302,7 +3302,7 @@ sub mariadb_galera { push( @adjvars, "set up parameter wsrep_sst_method to xtrabackup based parameter" ); } else { - badprint "SST Method is based on xtrabackup."; + goodprint "SST Method is based on xtrabackup."; } if ( trim( $myvar{'wsrep_OSU_method'} ) eq "TOI" ) { goodprint "TOI is default mode for upgrade."; From 7251a85234f3f8d43fddd1b50fc8f34a01b04ee5 Mon Sep 17 00:00:00 2001 From: Vadym Chepkov Date: Fri, 22 Apr 2016 11:22:00 -0400 Subject: [PATCH 100/126] fixed spelling --- mysqltuner.pl | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/mysqltuner.pl b/mysqltuner.pl index c8759c7..4d23c16 100755 --- a/mysqltuner.pl +++ b/mysqltuner.pl @@ -142,7 +142,7 @@ sub usage { . " --pass Password to use for authentication\n" . " --mysqladmin Path to a custom mysqladmin executable\n" . " --mysqlcmd Path to a custom mysql executable\n" . "\n" - . " --noask Dont ask password if needed\n" . "\n" + . " --noask Don't ask password if needed\n" . "\n" . " Performance and Reporting Options\n" . " --skipsize Don't enumerate tables and their types/sizes (default: on)\n" . " (Recommended for servers with many tables)\n" @@ -1233,7 +1233,7 @@ sub get_kernel_info() { 'sunrpc.tcp_max_slot_table_entries', 'sunrpc.tcp_slot_table_entries', 'vm.swappiness' ); - infoprint "Informations about kernel tuning:"; + infoprint "Information about kernel tuning:"; foreach my $param (@params) { infocmd_tab("sysctl $param"); } @@ -1328,7 +1328,7 @@ sub system_recommendations { infoprint "Skipped due to non Linux server"; return; } - prettyprint "Look for related Linux system recommandations"; + prettyprint "Look for related Linux system recommendations"; #prettyprint '-'x78; get_system_info(); @@ -1342,7 +1342,7 @@ sub system_recommendations { . hr_bytes_rnd($omem) . " / " . hr_bytes_rnd($physical_memory) . ")"; push( @generalrec, -"Consider stopping or dedicate server for additionnal process other than mysqld." +"Consider stopping or dedicate server for additional process other than mysqld." ); push( @adjvars, "DON'T APPLY SETTINGS BECAUSE THERE ARE TOO MANY PROCESSES RUNNING ON THIS SERVER. OOM KILL CAN OCCUR!" @@ -1512,14 +1512,14 @@ sub security_recommendations { foreach my $line (@mysqlstatlist) { chomp($line); badprint "User '" . $line - . "' is using weak pasword: $pass in a lower, upper or capitalize derivated version."; + . "' is using weak password: $pass in a lower, upper or capitalize derivative version."; $nbins++; } } } } if ( $nbins > 0 ) { - push( @generalrec, $nbins . " user(s) used basic or weaked password." ); + push( @generalrec, $nbins . " user(s) used basic or weak password." ); } } @@ -1554,7 +1554,7 @@ sub get_replication_status { and ( $io_running !~ /yes/i or $sql_running !~ /yes/i ) ) { badprint - "This replication slave is not running but seems to be configurated."; + "This replication slave is not running but seems to be configured."; } if ( defined($io_running) && $io_running =~ /yes/i @@ -2795,14 +2795,14 @@ sub mysql_stats { . " Memory / " . $mystat{'Binlog_cache_use'} . " Total)"; - debugprint "Not enought data to validate binlog cache size\n" + debugprint "Not enough data to validate binlog cache size\n" if $mystat{'Binlog_cache_use'} < 10; } } # Performance options if ( !mysql_version_ge( 5, 1 ) ) { - push( @generalrec, "Upgrade to MySQL 5.5+ to use asynchrone write" ); + push( @generalrec, "Upgrade to MySQL 5.5+ to use asynchronous write" ); } elsif ( $myvar{'concurrent_insert'} eq "OFF" ) { push( @generalrec, "Enable concurrent_insert by setting it to 'ON'" ); @@ -2952,7 +2952,7 @@ sub mariadb_threadpool { infoprint "Thread Pool Size: " . $myvar{'thread_pool_size'} . " thread(s)."; if ( $myvar{'version'} =~ /mariadb|percona/i ) { - infoprint "Using default value is good enougth for your version (" + infoprint "Using default value is good enough for your version (" . $myvar{'version'} . ")"; return; } @@ -3204,7 +3204,7 @@ sub mariadb_galera { if ( scalar(@nonInnoDbTables) > 0 ) { badprint "Following table(s) are not InnoDB table:"; push @generalrec, - "Ensure that all table(s) are InnoDB tabls for Galera replication"; + "Ensure that all table(s) are InnoDB tables for Galera replication"; foreach my $badtable (@nonInnoDbTables) { badprint "\t$badtable"; } @@ -3240,24 +3240,24 @@ sub mariadb_galera { . $myvar{'wsrep_cluster_address'}; my $nbNodes = scalar( split /,/, $myvar{'wsrep_cluster_address'} ); if ( $nbNodes != 3 or $nbNodes != 5 ) { - goodprint "There is $nbNodes nodes in wsrep_cluster_address."; + goodprint "There are $nbNodes nodes in wsrep_cluster_address."; } else { badprint -"There is $nbNodes nodes in wsrep_cluster_address. Prefer 3 or 5 nodes achitecture."; +"There are $nbNodes nodes in wsrep_cluster_address. Prefer 3 or 5 nodes architecture."; } my $nbNodesSize = trim( $mystat{'wsrep_cluster_size'} ); if ( $nbNodesSize != 3 or $nbNodesSize != 5 ) { - goodprint "There is $nbNodes nodes in wsrep_cluster_size."; + goodprint "There are $nbNodes nodes in wsrep_cluster_size."; } else { badprint -"There is $nbNodes nodes in wsrep_cluster_size. Prefer 3 or 5 nodes achitecture."; +"There are $nbNodes nodes in wsrep_cluster_size. Prefer 3 or 5 nodes architecture."; } if ( $nbNodes != trim( $mystat{'wsrep_cluster_size'} ) ) { badprint -"All cluster nodes dre not detected. wsrep_cluster_size != informations in wsrep_cluster_adress"; +"All cluster nodes are not detected. wsrep_cluster_size != information in wsrep_cluster_address"; } else { badprint "All cluster nodes detected."; @@ -3702,7 +3702,7 @@ sub mysql_databases { if ( $dbinfo[7] > 1 ) { badprint $dbinfo[7] - . " differents collations for database " + . " different collations for database " . $dbinfo[0]; push( @generalrec, "Check all table collations are identical for all tables in " @@ -3717,7 +3717,7 @@ sub mysql_databases { } if ( $dbinfo[8] > 1 ) { badprint $dbinfo[8] - . " differents engines for database " + . " different engines for database " . $dbinfo[0]; push( @generalrec, "Check all table engines are identical for all tables in " @@ -3780,7 +3780,7 @@ sub mysql_indexes { # unless ( mysql_version_ge( 5, 6 ) ) { # infoprint -#"Skip Index metrics from information schema due to erronous information provided in this version"; +#"Skip Index metrics from information schema due to erroneous information provided in this version"; # return; # } my $selIdxReq = <<'ENDSQL'; From f44d3c09f113ba90e62cb90854ef374716f5009a Mon Sep 17 00:00:00 2001 From: Zack Katz Date: Tue, 26 Apr 2016 15:29:49 -0600 Subject: [PATCH 101/126] enought to enough --- INTERNALS.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/INTERNALS.md b/INTERNALS.md index dbefe6f..d4ec954 100644 --- a/INTERNALS.md +++ b/INTERNALS.md @@ -178,8 +178,8 @@ ## MySQLTuner memory checks * Get total RAM/swap -* Is there enought memory for max connections reached by MySQL ? -* Is there enought memory for max connections allowed by MySQL ? +* Is there enough memory for max connections reached by MySQL ? +* Is there enough memory for max connections allowed by MySQL ? * Max percentage of memory used(<85%) ## MySQLTuner slow queries checks From ae0ab4bcff5b3601af3d6bd1301bbc86a74143a5 Mon Sep 17 00:00:00 2001 From: Vadym Chepkov Date: Wed, 27 Apr 2016 06:42:50 -0400 Subject: [PATCH 102/126] fixed wsrep_cluster_size handling garbd node can be configured in galera cluster. wsrep_cluster_size includes the garbd node, but it is not listed in wsrep_cluster_address, since it does not participate in the replication. --- mysqltuner.pl | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/mysqltuner.pl b/mysqltuner.pl index 4d23c16..1349f67 100755 --- a/mysqltuner.pl +++ b/mysqltuner.pl @@ -3239,28 +3239,22 @@ sub mariadb_galera { goodprint "Galera Cluster address is defined: " . $myvar{'wsrep_cluster_address'}; my $nbNodes = scalar( split /,/, $myvar{'wsrep_cluster_address'} ); - if ( $nbNodes != 3 or $nbNodes != 5 ) { - goodprint "There are $nbNodes nodes in wsrep_cluster_address."; - } - else { - badprint -"There are $nbNodes nodes in wsrep_cluster_address. Prefer 3 or 5 nodes architecture."; - } + infoprint "There are $nbNodes nodes in wsrep_cluster_address"; my $nbNodesSize = trim( $mystat{'wsrep_cluster_size'} ); - if ( $nbNodesSize != 3 or $nbNodesSize != 5 ) { - goodprint "There are $nbNodes nodes in wsrep_cluster_size."; + if ( $nbNodesSize == 3 or $nbNodesSize == 5 ) { + goodprint "There are $nbNodesSize nodes in wsrep_cluster_size."; } else { badprint -"There are $nbNodes nodes in wsrep_cluster_size. Prefer 3 or 5 nodes architecture."; +"There are $nbNodesSize nodes in wsrep_cluster_size. Prefer 3 or 5 nodes architecture."; } - - if ( $nbNodes != trim( $mystat{'wsrep_cluster_size'} ) ) { + # wsrep_cluster_address doesn't include garbd nodes + if ( $nbNodes > $nbNodesSize ) { badprint -"All cluster nodes are not detected. wsrep_cluster_size != information in wsrep_cluster_address"; +"All cluster nodes are not detected. wsrep_cluster_size less then node count in wsrep_cluster_address"; } else { - badprint "All cluster nodes detected."; + goodprint "All cluster nodes detected."; } } else { From 591d5ffc1961cc249f400e30c0a319586bb75eb3 Mon Sep 17 00:00:00 2001 From: Jean-Marie Renouard Date: Thu, 28 Apr 2016 16:44:15 +0200 Subject: [PATCH 103/126] Update README.md --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index c16c7fa..402f5d5 100644 --- a/README.md +++ b/README.md @@ -14,11 +14,12 @@ Compatibility: * MySQL 5.7 (partial support) * MySQL 5.6 (full support) -* MariaDB 10.0 (full support) -* MariaDB 10.1 (partial support) * MySQL 5.5 (full support) -* MySQL 5.1 (full support) -* MySQL 3.23, 4.0, 4.1, 5.0, 5.1 (full support) +* MariaDB 10.1 (partial support) +* MariaDB 10.0 (full support) +* Percana Server 5.6 (full support) +* Percona XtraDB cluster (full support) +* MySQL 3.23, 4.0, 4.1, 5.0, 5.1 (partial support - deprecated version) * Perl 5.6 or later (with [perl-doc](http://search.cpan.org/~dapm/perl-5.14.4/pod/perldoc.pod) package) * Unix/Linux based operating system (tested on Linux, BSD variants, and Solaris variants) * Windows is not supported at this time (Help wanted !!!!!) From 487bed625f0ee77545f2a5c4ff1388cf8dc848a6 Mon Sep 17 00:00:00 2001 From: Maks3w Date: Fri, 29 Apr 2016 08:57:56 +0200 Subject: [PATCH 104/126] Typo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 402f5d5..1087f49 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ Compatibility: * MySQL 5.5 (full support) * MariaDB 10.1 (partial support) * MariaDB 10.0 (full support) -* Percana Server 5.6 (full support) +* Percona Server 5.6 (full support) * Percona XtraDB cluster (full support) * MySQL 3.23, 4.0, 4.1, 5.0, 5.1 (partial support - deprecated version) * Perl 5.6 or later (with [perl-doc](http://search.cpan.org/~dapm/perl-5.14.4/pod/perldoc.pod) package) From 92dc77e4cdcdc2a7c3b4c0d800e229d547f742a9 Mon Sep 17 00:00:00 2001 From: jkavalik Date: Fri, 29 Apr 2016 12:56:24 +0200 Subject: [PATCH 105/126] Fix for #197 Merge GLOBAL status after SESSION - the non-global variables (like Percona from #184) will be present but stats are computed from GLOBAL counters which overwrite the SESSION ones if they exist. --- mysqltuner.pl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/mysqltuner.pl b/mysqltuner.pl index 1349f67..ac577b2 100755 --- a/mysqltuner.pl +++ b/mysqltuner.pl @@ -950,13 +950,13 @@ sub get_all_vars { debugprint "VERSION: " . $dummyselect . ""; $result{'MySQL Client'}{'Version'} = $dummyselect; - my @mysqlvarlist = select_array("SHOW GLOBAL VARIABLES"); - push( @mysqlvarlist, select_array("SHOW VARIABLES") ); + my @mysqlvarlist = select_array("SHOW VARIABLES"); + push( @mysqlvarlist, select_array("SHOW GLOBAL VARIABLES") ); arr2hash( \%myvar, \@mysqlvarlist ); $result{'Variables'} = %myvar; - my @mysqlstatlist = select_array("SHOW GLOBAL STATUS"); - push( @mysqlstatlist, select_array("SHOW STATUS") ); + my @mysqlstatlist = select_array("SHOW STATUS"); + push( @mysqlstatlist, select_array("SHOW GLOBAL STATUS") ); arr2hash( \%mystat, \@mysqlstatlist ); $result{'Status'} = %mystat; From 1727a42b29868ae956e01912598fc9bb3dbd496f Mon Sep 17 00:00:00 2001 From: root Date: Fri, 29 Apr 2016 13:46:52 +0200 Subject: [PATCH 106/126] Fix #195 single quote enclosed password --- mysqltuner.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysqltuner.pl b/mysqltuner.pl index ac577b2..d6f1e9a 100755 --- a/mysqltuner.pl +++ b/mysqltuner.pl @@ -696,7 +696,7 @@ sub mysql_setup { # Did we already get a username and password passed on the command line? if ( $opt{user} ne 0 and $opt{pass} ne 0 ) { - $mysqllogin = "-u $opt{user} -p\"$opt{pass}\"" . $remotestring; + $mysqllogin = "-u $opt{user} -p'$opt{pass}'" . $remotestring; my $loginstatus = `$mysqladmincmd ping $mysqllogin 2>&1`; if ( $loginstatus =~ /mysqld is alive/ ) { goodprint "Logged in using credentials passed on the command line"; From 2e2d945e6336ee77d3e131123eda3be8996ded13 Mon Sep 17 00:00:00 2001 From: root Date: Fri, 29 Apr 2016 14:01:15 +0200 Subject: [PATCH 107/126] Fix #190 changing typo for recommandations on multiprocessor --- mysqltuner.pl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mysqltuner.pl b/mysqltuner.pl index d6f1e9a..bfaaa32 100755 --- a/mysqltuner.pl +++ b/mysqltuner.pl @@ -2494,12 +2494,12 @@ sub mysql_stats { elsif ( mysql_version_ge( 5, 5 ) and !mysql_version_ge( 10, 1 ) ) { if ( $myvar{'query_cache_type'} ne "OFF" ) { badprint -"Query cache should be disabled by default due to mutex contention."; +"Query cache may be disabled by default due to mutex contention."; push( @adjvars, "query_cache_type (=0)" ); } else { goodprint - "Query cache is disabled by default due to mutex contention."; + "Query cache is disabled by default due to mutex contention on multiprocessor machines."; } } elsif ( $myvar{'query_cache_size'} < 1 ) { From bead8a77efca41986a4baedf313345b00bec4f81 Mon Sep 17 00:00:00 2001 From: root Date: Fri, 29 Apr 2016 14:19:46 +0200 Subject: [PATCH 108/126] Adding this message for <=5.1 version No more password checks for MySQL version <=5.1 MySQL version <=5.1 are deprecated and end of support. --- mysqltuner.pl | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/mysqltuner.pl b/mysqltuner.pl index bfaaa32..71cb4ac 100755 --- a/mysqltuner.pl +++ b/mysqltuner.pl @@ -1,5 +1,5 @@ #!/usr/bin/env perl -# mysqltuner.pl - Version 1.6.10 +# mysqltuner.pl - Version 1.6.11 # High Performance MySQL Tuning Script # Copyright (C) 2006-2016 Major Hayden - major@mhtx.net # @@ -54,7 +54,7 @@ $Data::Dumper::Pair = " : "; #use Env; # Set up a few variables for use in the script -my $tunerversion = "1.6.10"; +my $tunerversion = "1.6.11"; my ( @adjvars, @generalrec ); # Set defaults @@ -1426,7 +1426,11 @@ sub security_recommendations { else { goodprint "There are no anonymous accounts for any database users"; } - + if ( mysql_version_le( 5, 1 ) ) { + badprint "No more password checks for MySQL version <=5.1"; + badprint "MySQL version <=5.1 are deprecated and end of support."; + return; + } # Looking for Empty Password @mysqlstatlist = select_array "SELECT CONCAT(user, '\@', host) FROM mysql.user WHERE ($PASS_COLUMN_NAME = '' OR $PASS_COLUMN_NAME IS NULL) AND plugin NOT IN ('unix_socket', 'win_socket')"; @@ -4048,7 +4052,7 @@ __END__ =head1 NAME - MySQLTuner 1.6.10 - MySQL High Performance Tuning Script + MySQLTuner 1.6.11 - MySQL High Performance Tuning Script =head1 IMPORTANT USAGE GUIDELINES From f6f66a49ef012c5f570d9d512b1cea6913b87f7a Mon Sep 17 00:00:00 2001 From: root Date: Fri, 29 Apr 2016 14:25:16 +0200 Subject: [PATCH 109/126] #196 comment thread_cache_size recommandations --- mysqltuner.pl | 48 +++++++++++++++++++++++------------------------- 1 file changed, 23 insertions(+), 25 deletions(-) diff --git a/mysqltuner.pl b/mysqltuner.pl index 71cb4ac..e56d6f8 100755 --- a/mysqltuner.pl +++ b/mysqltuner.pl @@ -2665,31 +2665,29 @@ sub mysql_stats { } # Thread cache - if ( $myvar{'thread_cache_size'} eq 0 ) { - badprint "Thread cache is disabled"; - push( @generalrec, "Set thread_cache_size to 4 as a starting value" ); - push( @adjvars, "thread_cache_size (start at 4)" ); - } - else { - if ( $mycalc{'thread_cache_hit_rate'} <= 50 ) { - badprint - "Thread cache hit rate: $mycalc{'thread_cache_hit_rate'}% (" - . hr_num( $mystat{'Threads_created'} ) - . " created / " - . hr_num( $mystat{'Connections'} ) - . " connections)"; - push( @adjvars, - "thread_cache_size (> $myvar{'thread_cache_size'})" ); - } - else { - goodprint - "Thread cache hit rate: $mycalc{'thread_cache_hit_rate'}% (" - . hr_num( $mystat{'Threads_created'} ) - . " created / " - . hr_num( $mystat{'Connections'} ) - . " connections)"; - } - } + #if ( $myvar{'thread_cache_size'} eq 0 ) { + # badprint "Thread cache is disabled"; + # push( @generalrec, "Set thread_cache_size to 4 as a starting value" ); + # push( @adjvars, "thread_cache_size (start at 4)" ); + #} else { + # if ( $mycalc{'thread_cache_hit_rate'} <= 50 ) { + # badprint + # "Thread cache hit rate: $mycalc{'thread_cache_hit_rate'}% (" + # . hr_num( $mystat{'Threads_created'} ) + # . " created / " + # . hr_num( $mystat{'Connections'} ) + # . " connections)"; + # push( @adjvars, + # "thread_cache_size (> $myvar{'thread_cache_size'})" ); + # } else { + # goodprint + # "Thread cache hit rate: $mycalc{'thread_cache_hit_rate'}% (" + # . hr_num( $mystat{'Threads_created'} ) + # . " created / " + # . hr_num( $mystat{'Connections'} ) + # . " connections)"; + # } + #} # Table cache my $table_cache_var = ""; From 858536f86e2307a0f0399f074c51ca11b347722e Mon Sep 17 00:00:00 2001 From: root Date: Wed, 4 May 2016 16:37:26 +0200 Subject: [PATCH 110/126] Update vulnerabilies list --- vulnerabilities.csv | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/vulnerabilities.csv b/vulnerabilities.csv index 0408842..78a8eae 100755 --- a/vulnerabilities.csv +++ b/vulnerabilities.csv @@ -427,6 +427,11 @@ 5.5.47;5;5;47;CVE-2016-0546;Candidate;"Unspecified vulnerability in Oracle MySQL 5.5.46 and earlier; 5.6.27 and earlier; and 5.7.9 and MariaDB before 5.5.47; 10.0.x before 10.0.23; and 10.1.x before 10.1.10 allows local users to affect confidentiality; integrity; and availability via unknown vectors related to Client. NOTE: the previous information is from the January 2016 CPU. Oracle has not commented on third-party claims that these are multiple buffer overflows in the mysqlshow tool that allow remote database servers to have unspecified impact via a long table or database name.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/cpujan2016-2367955.html | CONFIRM:https://mariadb.com/kb/en/mariadb/mariadb-10110-release-notes/ | CONFIRM:https://mariadb.com/kb/en/mariadb/mariadb-5547-release-notes/ | CONFIRM:https://mariadb.com/kb/en/mdb-10023-rn/ | CONFIRM:https://bugzilla.redhat.com/show_bug.cgi?id=1301493 | CONFIRM:https://dev.mysql.com/doc/relnotes/mysql/5.5/en/news-5-5-47.html | CONFIRM:https://dev.mysql.com/doc/relnotes/mysql/5.6/en/news-5-6-28.html | CONFIRM:https://github.com/mysql/mysql-server/commit/0dbd5a8797ed4bd18e8b883988fb62177eb0f73f | DEBIAN:DSA-3453 | URL:http://www.debian.org/security/2016/dsa-3453 | REDHAT:RHSA-2016:0534 | URL:http://rhn.redhat.com/errata/RHSA-2016-0534.html | SUSE:openSUSE-SU-2016:0367 | URL:http://lists.opensuse.org/opensuse-security-announce/2016-02/msg00015.html";Assigned (20151209);"None (candidate not yet proposed)"; 10.0.23;10;0;23;CVE-2016-0546;Candidate;"Unspecified vulnerability in Oracle MySQL 5.5.46 and earlier; 5.6.27 and earlier; and 5.7.9 and MariaDB before 5.5.47; 10.0.x before 10.0.23; and 10.1.x before 10.1.10 allows local users to affect confidentiality; integrity; and availability via unknown vectors related to Client. NOTE: the previous information is from the January 2016 CPU. Oracle has not commented on third-party claims that these are multiple buffer overflows in the mysqlshow tool that allow remote database servers to have unspecified impact via a long table or database name.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/cpujan2016-2367955.html | CONFIRM:https://mariadb.com/kb/en/mariadb/mariadb-10110-release-notes/ | CONFIRM:https://mariadb.com/kb/en/mariadb/mariadb-5547-release-notes/ | CONFIRM:https://mariadb.com/kb/en/mdb-10023-rn/ | CONFIRM:https://bugzilla.redhat.com/show_bug.cgi?id=1301493 | CONFIRM:https://dev.mysql.com/doc/relnotes/mysql/5.5/en/news-5-5-47.html | CONFIRM:https://dev.mysql.com/doc/relnotes/mysql/5.6/en/news-5-6-28.html | CONFIRM:https://github.com/mysql/mysql-server/commit/0dbd5a8797ed4bd18e8b883988fb62177eb0f73f | DEBIAN:DSA-3453 | URL:http://www.debian.org/security/2016/dsa-3453 | REDHAT:RHSA-2016:0534 | URL:http://rhn.redhat.com/errata/RHSA-2016-0534.html | SUSE:openSUSE-SU-2016:0367 | URL:http://lists.opensuse.org/opensuse-security-announce/2016-02/msg00015.html";Assigned (20151209);"None (candidate not yet proposed)"; 10.1.10;10;1;10;CVE-2016-0546;Candidate;"Unspecified vulnerability in Oracle MySQL 5.5.46 and earlier; 5.6.27 and earlier; and 5.7.9 and MariaDB before 5.5.47; 10.0.x before 10.0.23; and 10.1.x before 10.1.10 allows local users to affect confidentiality; integrity; and availability via unknown vectors related to Client. NOTE: the previous information is from the January 2016 CPU. Oracle has not commented on third-party claims that these are multiple buffer overflows in the mysqlshow tool that allow remote database servers to have unspecified impact via a long table or database name.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/cpujan2016-2367955.html | CONFIRM:https://mariadb.com/kb/en/mariadb/mariadb-10110-release-notes/ | CONFIRM:https://mariadb.com/kb/en/mariadb/mariadb-5547-release-notes/ | CONFIRM:https://mariadb.com/kb/en/mdb-10023-rn/ | CONFIRM:https://bugzilla.redhat.com/show_bug.cgi?id=1301493 | CONFIRM:https://dev.mysql.com/doc/relnotes/mysql/5.5/en/news-5-5-47.html | CONFIRM:https://dev.mysql.com/doc/relnotes/mysql/5.6/en/news-5-6-28.html | CONFIRM:https://github.com/mysql/mysql-server/commit/0dbd5a8797ed4bd18e8b883988fb62177eb0f73f | DEBIAN:DSA-3453 | URL:http://www.debian.org/security/2016/dsa-3453 | REDHAT:RHSA-2016:0534 | URL:http://rhn.redhat.com/errata/RHSA-2016-0534.html | SUSE:openSUSE-SU-2016:0367 | URL:http://lists.opensuse.org/opensuse-security-announce/2016-02/msg00015.html";Assigned (20151209);"None (candidate not yet proposed)"; -5.5.47;5;5;47;CVE-2016-2047;Candidate;"The ssl_verify_server_cert function in sql-common/client.c in MariaDB before 5.5.47; 10.0.x before 10.0.23; and 10.1.x before 10.1.10; Oracle MySQL; and Percona Server do not properly verify that the server hostname matches a domain name in the subject's Common Name (CN) or subjectAltName field of the X.509 certificate; which allows man-in-the-middle attackers to spoof SSL servers via a ""/CN="" string in a field in a certificate; as demonstrated by ""/OU=/CN=bar.com/CN=foo.com.""";"MLIST:[oss-security] 20160126 Flaw in mariadb clients SSL certificate validation | URL:http://www.openwall.com/lists/oss-security/2016/01/26/3 | CONFIRM:https://mariadb.atlassian.net/browse/MDEV-9212 | CONFIRM:https://mariadb.com/kb/en/mariadb/mariadb-10110-release-notes/ | CONFIRM:https://mariadb.com/kb/en/mariadb/mariadb-5547-release-notes/ | CONFIRM:https://mariadb.com/kb/en/mdb-10023-rn/ | DEBIAN:DSA-3453 | URL:http://www.debian.org/security/2016/dsa-3453 | REDHAT:RHSA-2016:0534 | URL:http://rhn.redhat.com/errata/RHSA-2016-0534.html";Assigned (20160122);"None (candidate not yet proposed)"; -10.0.23;10;0;23;CVE-2016-2047;Candidate;"The ssl_verify_server_cert function in sql-common/client.c in MariaDB before 5.5.47; 10.0.x before 10.0.23; and 10.1.x before 10.1.10; Oracle MySQL; and Percona Server do not properly verify that the server hostname matches a domain name in the subject's Common Name (CN) or subjectAltName field of the X.509 certificate; which allows man-in-the-middle attackers to spoof SSL servers via a ""/CN="" string in a field in a certificate; as demonstrated by ""/OU=/CN=bar.com/CN=foo.com.""";"MLIST:[oss-security] 20160126 Flaw in mariadb clients SSL certificate validation | URL:http://www.openwall.com/lists/oss-security/2016/01/26/3 | CONFIRM:https://mariadb.atlassian.net/browse/MDEV-9212 | CONFIRM:https://mariadb.com/kb/en/mariadb/mariadb-10110-release-notes/ | CONFIRM:https://mariadb.com/kb/en/mariadb/mariadb-5547-release-notes/ | CONFIRM:https://mariadb.com/kb/en/mdb-10023-rn/ | DEBIAN:DSA-3453 | URL:http://www.debian.org/security/2016/dsa-3453 | REDHAT:RHSA-2016:0534 | URL:http://rhn.redhat.com/errata/RHSA-2016-0534.html";Assigned (20160122);"None (candidate not yet proposed)"; -10.1.10;10;1;10;CVE-2016-2047;Candidate;"The ssl_verify_server_cert function in sql-common/client.c in MariaDB before 5.5.47; 10.0.x before 10.0.23; and 10.1.x before 10.1.10; Oracle MySQL; and Percona Server do not properly verify that the server hostname matches a domain name in the subject's Common Name (CN) or subjectAltName field of the X.509 certificate; which allows man-in-the-middle attackers to spoof SSL servers via a ""/CN="" string in a field in a certificate; as demonstrated by ""/OU=/CN=bar.com/CN=foo.com.""";"MLIST:[oss-security] 20160126 Flaw in mariadb clients SSL certificate validation | URL:http://www.openwall.com/lists/oss-security/2016/01/26/3 | CONFIRM:https://mariadb.atlassian.net/browse/MDEV-9212 | CONFIRM:https://mariadb.com/kb/en/mariadb/mariadb-10110-release-notes/ | CONFIRM:https://mariadb.com/kb/en/mariadb/mariadb-5547-release-notes/ | CONFIRM:https://mariadb.com/kb/en/mdb-10023-rn/ | DEBIAN:DSA-3453 | URL:http://www.debian.org/security/2016/dsa-3453 | REDHAT:RHSA-2016:0534 | URL:http://rhn.redhat.com/errata/RHSA-2016-0534.html";Assigned (20160122);"None (candidate not yet proposed)"; +5.5.47;5;5;47;CVE-2016-2047;Candidate;"The ssl_verify_server_cert function in sql-common/client.c in MariaDB before 5.5.47; 10.0.x before 10.0.23; and 10.1.x before 10.1.10; Oracle MySQL 5.5.48 and earlier; 5.6.29 and earlier; and 5.7.11 and earlier; and Percona Server do not properly verify that the server hostname matches a domain name in the subject's Common Name (CN) or subjectAltName field of the X.509 certificate; which allows man-in-the-middle attackers to spoof SSL servers via a ""/CN="" string in a field in a certificate; as demonstrated by ""/OU=/CN=bar.com/CN=foo.com.""";"MLIST:[oss-security] 20160126 Flaw in mariadb clients SSL certificate validation | URL:http://www.openwall.com/lists/oss-security/2016/01/26/3 | CONFIRM:https://mariadb.atlassian.net/browse/MDEV-9212 | CONFIRM:https://mariadb.com/kb/en/mariadb/mariadb-10110-release-notes/ | CONFIRM:https://mariadb.com/kb/en/mariadb/mariadb-5547-release-notes/ | CONFIRM:https://mariadb.com/kb/en/mdb-10023-rn/ | CONFIRM:http://www.oracle.com/technetwork/security-advisory/cpuapr2016v3-2985753.html | DEBIAN:DSA-3453 | URL:http://www.debian.org/security/2016/dsa-3453 | REDHAT:RHSA-2016:0534 | URL:http://rhn.redhat.com/errata/RHSA-2016-0534.html";Assigned (20160122);"None (candidate not yet proposed)"; +10.0.23;10;0;23;CVE-2016-2047;Candidate;"The ssl_verify_server_cert function in sql-common/client.c in MariaDB before 5.5.47; 10.0.x before 10.0.23; and 10.1.x before 10.1.10; Oracle MySQL 5.5.48 and earlier; 5.6.29 and earlier; and 5.7.11 and earlier; and Percona Server do not properly verify that the server hostname matches a domain name in the subject's Common Name (CN) or subjectAltName field of the X.509 certificate; which allows man-in-the-middle attackers to spoof SSL servers via a ""/CN="" string in a field in a certificate; as demonstrated by ""/OU=/CN=bar.com/CN=foo.com.""";"MLIST:[oss-security] 20160126 Flaw in mariadb clients SSL certificate validation | URL:http://www.openwall.com/lists/oss-security/2016/01/26/3 | CONFIRM:https://mariadb.atlassian.net/browse/MDEV-9212 | CONFIRM:https://mariadb.com/kb/en/mariadb/mariadb-10110-release-notes/ | CONFIRM:https://mariadb.com/kb/en/mariadb/mariadb-5547-release-notes/ | CONFIRM:https://mariadb.com/kb/en/mdb-10023-rn/ | CONFIRM:http://www.oracle.com/technetwork/security-advisory/cpuapr2016v3-2985753.html | DEBIAN:DSA-3453 | URL:http://www.debian.org/security/2016/dsa-3453 | REDHAT:RHSA-2016:0534 | URL:http://rhn.redhat.com/errata/RHSA-2016-0534.html";Assigned (20160122);"None (candidate not yet proposed)"; +10.1.10;10;1;10;CVE-2016-2047;Candidate;"The ssl_verify_server_cert function in sql-common/client.c in MariaDB before 5.5.47; 10.0.x before 10.0.23; and 10.1.x before 10.1.10; Oracle MySQL 5.5.48 and earlier; 5.6.29 and earlier; and 5.7.11 and earlier; and Percona Server do not properly verify that the server hostname matches a domain name in the subject's Common Name (CN) or subjectAltName field of the X.509 certificate; which allows man-in-the-middle attackers to spoof SSL servers via a ""/CN="" string in a field in a certificate; as demonstrated by ""/OU=/CN=bar.com/CN=foo.com.""";"MLIST:[oss-security] 20160126 Flaw in mariadb clients SSL certificate validation | URL:http://www.openwall.com/lists/oss-security/2016/01/26/3 | CONFIRM:https://mariadb.atlassian.net/browse/MDEV-9212 | CONFIRM:https://mariadb.com/kb/en/mariadb/mariadb-10110-release-notes/ | CONFIRM:https://mariadb.com/kb/en/mariadb/mariadb-5547-release-notes/ | CONFIRM:https://mariadb.com/kb/en/mdb-10023-rn/ | CONFIRM:http://www.oracle.com/technetwork/security-advisory/cpuapr2016v3-2985753.html | DEBIAN:DSA-3453 | URL:http://www.debian.org/security/2016/dsa-3453 | REDHAT:RHSA-2016:0534 | URL:http://rhn.redhat.com/errata/RHSA-2016-0534.html";Assigned (20160122);"None (candidate not yet proposed)"; +5.5.48;5;5;48;CVE-2016-2047;Candidate;"The ssl_verify_server_cert function in sql-common/client.c in MariaDB before 5.5.47; 10.0.x before 10.0.23; and 10.1.x before 10.1.10; Oracle MySQL 5.5.48 and earlier; 5.6.29 and earlier; and 5.7.11 and earlier; and Percona Server do not properly verify that the server hostname matches a domain name in the subject's Common Name (CN) or subjectAltName field of the X.509 certificate; which allows man-in-the-middle attackers to spoof SSL servers via a ""/CN="" string in a field in a certificate; as demonstrated by ""/OU=/CN=bar.com/CN=foo.com.""";"MLIST:[oss-security] 20160126 Flaw in mariadb clients SSL certificate validation | URL:http://www.openwall.com/lists/oss-security/2016/01/26/3 | CONFIRM:https://mariadb.atlassian.net/browse/MDEV-9212 | CONFIRM:https://mariadb.com/kb/en/mariadb/mariadb-10110-release-notes/ | CONFIRM:https://mariadb.com/kb/en/mariadb/mariadb-5547-release-notes/ | CONFIRM:https://mariadb.com/kb/en/mdb-10023-rn/ | CONFIRM:http://www.oracle.com/technetwork/security-advisory/cpuapr2016v3-2985753.html | DEBIAN:DSA-3453 | URL:http://www.debian.org/security/2016/dsa-3453 | REDHAT:RHSA-2016:0534 | URL:http://rhn.redhat.com/errata/RHSA-2016-0534.html";Assigned (20160122);"None (candidate not yet proposed)"; +5.6.29;5;6;29;CVE-2016-2047;Candidate;"The ssl_verify_server_cert function in sql-common/client.c in MariaDB before 5.5.47; 10.0.x before 10.0.23; and 10.1.x before 10.1.10; Oracle MySQL 5.5.48 and earlier; 5.6.29 and earlier; and 5.7.11 and earlier; and Percona Server do not properly verify that the server hostname matches a domain name in the subject's Common Name (CN) or subjectAltName field of the X.509 certificate; which allows man-in-the-middle attackers to spoof SSL servers via a ""/CN="" string in a field in a certificate; as demonstrated by ""/OU=/CN=bar.com/CN=foo.com.""";"MLIST:[oss-security] 20160126 Flaw in mariadb clients SSL certificate validation | URL:http://www.openwall.com/lists/oss-security/2016/01/26/3 | CONFIRM:https://mariadb.atlassian.net/browse/MDEV-9212 | CONFIRM:https://mariadb.com/kb/en/mariadb/mariadb-10110-release-notes/ | CONFIRM:https://mariadb.com/kb/en/mariadb/mariadb-5547-release-notes/ | CONFIRM:https://mariadb.com/kb/en/mdb-10023-rn/ | CONFIRM:http://www.oracle.com/technetwork/security-advisory/cpuapr2016v3-2985753.html | DEBIAN:DSA-3453 | URL:http://www.debian.org/security/2016/dsa-3453 | REDHAT:RHSA-2016:0534 | URL:http://rhn.redhat.com/errata/RHSA-2016-0534.html";Assigned (20160122);"None (candidate not yet proposed)"; +5.7.11;5;7;11;CVE-2016-2047;Candidate;"The ssl_verify_server_cert function in sql-common/client.c in MariaDB before 5.5.47; 10.0.x before 10.0.23; and 10.1.x before 10.1.10; Oracle MySQL 5.5.48 and earlier; 5.6.29 and earlier; and 5.7.11 and earlier; and Percona Server do not properly verify that the server hostname matches a domain name in the subject's Common Name (CN) or subjectAltName field of the X.509 certificate; which allows man-in-the-middle attackers to spoof SSL servers via a ""/CN="" string in a field in a certificate; as demonstrated by ""/OU=/CN=bar.com/CN=foo.com.""";"MLIST:[oss-security] 20160126 Flaw in mariadb clients SSL certificate validation | URL:http://www.openwall.com/lists/oss-security/2016/01/26/3 | CONFIRM:https://mariadb.atlassian.net/browse/MDEV-9212 | CONFIRM:https://mariadb.com/kb/en/mariadb/mariadb-10110-release-notes/ | CONFIRM:https://mariadb.com/kb/en/mariadb/mariadb-5547-release-notes/ | CONFIRM:https://mariadb.com/kb/en/mdb-10023-rn/ | CONFIRM:http://www.oracle.com/technetwork/security-advisory/cpuapr2016v3-2985753.html | DEBIAN:DSA-3453 | URL:http://www.debian.org/security/2016/dsa-3453 | REDHAT:RHSA-2016:0534 | URL:http://rhn.redhat.com/errata/RHSA-2016-0534.html";Assigned (20160122);"None (candidate not yet proposed)"; +3.0.25;3;0;25;CVE-2016-3461;Candidate;"Unspecified vulnerability in the MySQL Enterprise Monitor component in Oracle MySQL 3.0.25 and earlier and 3.1.2 and earlier allows remote administrators to affect confidentiality; integrity; and availability via vectors related to Monitoring: Server.";"CONFIRM:http://www.oracle.com/technetwork/security-advisory/cpuapr2016v3-2985753.html";Assigned (20160317);"None (candidate not yet proposed)"; +3.1.2;3;1;2;CVE-2016-3461;Candidate;"Unspecified vulnerability in the MySQL Enterprise Monitor component in Oracle MySQL 3.0.25 and earlier and 3.1.2 and earlier allows remote administrators to affect confidentiality; integrity; and availability via vectors related to Monitoring: Server.";"CONFIRM:http://www.oracle.com/technetwork/security-advisory/cpuapr2016v3-2985753.html";Assigned (20160317);"None (candidate not yet proposed)"; From 959a41b7089883ec69713c4b82963859bb75c71b Mon Sep 17 00:00:00 2001 From: root Date: Wed, 4 May 2016 17:44:05 +0200 Subject: [PATCH 111/126] #204 updater works fine with curl now --- mysqltuner.pl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mysqltuner.pl b/mysqltuner.pl index e56d6f8..dcbb5f4 100755 --- a/mysqltuner.pl +++ b/mysqltuner.pl @@ -532,9 +532,9 @@ sub update_tuner_version { debugprint "$httpcli is available."; debugprint - "$httpcli --connect-timeout 5 -silent '$url$script' > $script"; + "$httpcli --connect-timeout 5 '$url$script' 2>$devnull > $script"; $update = - `$httpcli --connect-timeout 5 -silent '$url$script' > $script`; + `$httpcli --connect-timeout 5 '$url$script' 2>$devnull > $script`; chomp($update); debugprint "$script updated: $update"; From a7cd64a4c79b64090a637b2b1bd4e1060fbf0469 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 9 May 2016 10:17:14 +0200 Subject: [PATCH 112/126] Increment version number --- mysqltuner.pl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mysqltuner.pl b/mysqltuner.pl index dcbb5f4..ed02151 100755 --- a/mysqltuner.pl +++ b/mysqltuner.pl @@ -1,5 +1,5 @@ #!/usr/bin/env perl -# mysqltuner.pl - Version 1.6.11 +# mysqltuner.pl - Version 1.6.12 # High Performance MySQL Tuning Script # Copyright (C) 2006-2016 Major Hayden - major@mhtx.net # @@ -54,7 +54,7 @@ $Data::Dumper::Pair = " : "; #use Env; # Set up a few variables for use in the script -my $tunerversion = "1.6.11"; +my $tunerversion = "1.6.12"; my ( @adjvars, @generalrec ); # Set defaults @@ -4050,7 +4050,7 @@ __END__ =head1 NAME - MySQLTuner 1.6.11 - MySQL High Performance Tuning Script + MySQLTuner 1.6.12 - MySQL High Performance Tuning Script =head1 IMPORTANT USAGE GUIDELINES From 7c1d5521edd5c1afa626a011edf98f6abf00abf6 Mon Sep 17 00:00:00 2001 From: Ian Gregory Date: Tue, 10 May 2016 10:34:30 +0100 Subject: [PATCH 113/126] Improve portability when fetching process memory - use ps rather than the proc filesystem --- mysqltuner.pl | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/mysqltuner.pl b/mysqltuner.pl index ed02151..deb0b25 100755 --- a/mysqltuner.pl +++ b/mysqltuner.pl @@ -1088,15 +1088,15 @@ sub is_open_port { sub get_process_memory { my $pid = shift; - return 0 unless -f "/proc/$pid/status"; - my @pdata = grep { /RSS:/ } get_file_contents "/proc/$pid/status"; - map { s/.*RSS:\s*(\d+)\s*kB\s*$/$1*1024/ge } @pdata; - return $pdata[0]; + my @mem = `ps -p $pid -o rss`; + return 0 if scalar @mem != 2; + return $mem[1]*1024; } sub get_other_process_memory { - my @procs = `ps -eo pid,cmd`; + my @procs = `ps -eaxo pid,command`; map { + s/.*PID.*//; s/.*mysqld.*//; s/.*\[.*\].*//; s/^\s+$//g; From 9056b1b0fa14141f22a257d5e0826064cbaa1e12 Mon Sep 17 00:00:00 2001 From: Jean-Marie Renouard Date: Tue, 17 May 2016 12:13:07 +0200 Subject: [PATCH 114/126] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 1087f49..b13d01b 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,8 @@ MySQLTuner-perl [![Build Status - Master](https://travis-ci.org/major/MySQLTuner-perl.svg?branch=master)](https://travis-ci.org/major/MySQLTuner-perl) [![Project Status](http://opensource.box.com/badges/active.svg)](http://opensource.box.com/badges) [![Project Status](http://opensource.box.com/badges/maintenance.svg)](http://opensource.box.com/badges) +[![Average time to resolve an issue](http://isitmaintained.com/badge/resolution/major/MySQLTuner-perl.svg)](http://isitmaintained.com/project/major/MySQLTuner-perl "Average time to resolve an issue") +[![Percentage of issues still open](http://isitmaintained.com/badge/open/major/MySQLTuner-perl.svg)](http://isitmaintained.com/project/major/MySQLTuner-perl "Percentage of issues still open") MySQLTuner is a script written in Perl that allows you to review a MySQL installation quickly and make adjustments to increase performance and stability. The current configuration variables and status data is retrieved and presented in a brief format along with some basic performance suggestions. From 8e9cc50311a0ac8b8a1e66da39cab31659e451a4 Mon Sep 17 00:00:00 2001 From: smutel Date: Thu, 19 May 2016 13:44:50 +0200 Subject: [PATCH 115/126] Exclude innodb engine from fragmented tables --- mysqltuner.pl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mysqltuner.pl b/mysqltuner.pl index deb0b25..959191f 100755 --- a/mysqltuner.pl +++ b/mysqltuner.pl @@ -1776,11 +1776,11 @@ sub check_storage_engines { $result{'Engine'}{$engine}{'Index Size'} = $isize; } $fragtables = select_one -"SELECT COUNT(TABLE_NAME) FROM information_schema.TABLES WHERE TABLE_SCHEMA NOT IN ('information_schema','performance_schema', 'mysql') AND Data_free > 0 AND NOT ENGINE='MEMORY'"; +"SELECT COUNT(TABLE_NAME) FROM information_schema.TABLES WHERE TABLE_SCHEMA NOT IN ('information_schema','performance_schema', 'mysql') AND Data_free > 0 AND NOT ENGINE='MEMORY' AND NOT ENGINE='InnoDB'"; chomp($fragtables); $result{'Tables'}{'Fragmented tables'} = [ select_array -"SELECT CONCAT(CONCAT(TABLE_SCHEMA, '.'), TABLE_NAME) FROM information_schema.TABLES WHERE TABLE_SCHEMA NOT IN ('information_schema','performance_schema', 'mysql') AND Data_free > 0 AND NOT ENGINE='MEMORY'" +"SELECT CONCAT(CONCAT(TABLE_SCHEMA, '.'), TABLE_NAME) FROM information_schema.TABLES WHERE TABLE_SCHEMA NOT IN ('information_schema','performance_schema', 'mysql') AND Data_free > 0 AND NOT ENGINE='MEMORY' NOT ENGINE='InnoDB'" ]; } From b2aea7f69dff29a2a3ff6dacbb48cf06da9afa72 Mon Sep 17 00:00:00 2001 From: smutel Date: Thu, 19 May 2016 13:47:46 +0200 Subject: [PATCH 116/126] Update mysqltuner.pl --- mysqltuner.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysqltuner.pl b/mysqltuner.pl index 959191f..b0e2159 100755 --- a/mysqltuner.pl +++ b/mysqltuner.pl @@ -1780,7 +1780,7 @@ sub check_storage_engines { chomp($fragtables); $result{'Tables'}{'Fragmented tables'} = [ select_array -"SELECT CONCAT(CONCAT(TABLE_SCHEMA, '.'), TABLE_NAME) FROM information_schema.TABLES WHERE TABLE_SCHEMA NOT IN ('information_schema','performance_schema', 'mysql') AND Data_free > 0 AND NOT ENGINE='MEMORY' NOT ENGINE='InnoDB'" +"SELECT CONCAT(CONCAT(TABLE_SCHEMA, '.'), TABLE_NAME) FROM information_schema.TABLES WHERE TABLE_SCHEMA NOT IN ('information_schema','performance_schema', 'mysql') AND Data_free > 0 AND NOT ENGINE='MEMORY' AND NOT ENGINE='InnoDB'" ]; } From 1048038e6482cc50e4ab718b83edcdd022039702 Mon Sep 17 00:00:00 2001 From: smutel Date: Thu, 19 May 2016 17:06:12 +0200 Subject: [PATCH 117/126] Avoid bad syntax error message Error below when executing the script on RHEL6/OL6: Warning: bad syntax, perhaps a bogus '-'? See /usr/share/doc/procps-3.2.8/FAQ --- mysqltuner.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysqltuner.pl b/mysqltuner.pl index b0e2159..be1688f 100755 --- a/mysqltuner.pl +++ b/mysqltuner.pl @@ -1094,7 +1094,7 @@ sub get_process_memory { } sub get_other_process_memory { - my @procs = `ps -eaxo pid,command`; + my @procs = `ps eaxo pid,command`; map { s/.*PID.*//; s/.*mysqld.*//; From e14ddff90481cc916961cad719d1b168ad359fe7 Mon Sep 17 00:00:00 2001 From: smutel Date: Thu, 19 May 2016 17:10:48 +0200 Subject: [PATCH 118/126] Avoid deprecated message from perl Use of implicit split to @_ is deprecated at /tmp/mysqltuner.pl line 3243 (#1) (D deprecated, W syntax) It makes a lot of work for the compiler when you clobber a subroutine's argument list, so it's better if you assign the results of a split() explicitly to an array (or list). --- mysqltuner.pl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mysqltuner.pl b/mysqltuner.pl index b0e2159..4e2ae62 100755 --- a/mysqltuner.pl +++ b/mysqltuner.pl @@ -3240,7 +3240,8 @@ sub mariadb_galera { { goodprint "Galera Cluster address is defined: " . $myvar{'wsrep_cluster_address'}; - my $nbNodes = scalar( split /,/, $myvar{'wsrep_cluster_address'} ); + my @NodesTmp = split /,/, $myvar{'wsrep_cluster_address'}; + my $nbNodes = @NodesTmp; infoprint "There are $nbNodes nodes in wsrep_cluster_address"; my $nbNodesSize = trim( $mystat{'wsrep_cluster_size'} ); if ( $nbNodesSize == 3 or $nbNodesSize == 5 ) { From 2a8cf5fea6b696623c895cdd7ef1474b706652b6 Mon Sep 17 00:00:00 2001 From: jfcoz Date: Thu, 2 Jun 2016 09:23:46 +0200 Subject: [PATCH 119/126] add innodb when innodb_file_per_table is ON display OPTIMIZE requests for tables of more than 100mb with more thant 10% fragmentation Run OPTIMIZE TABLE to defragment tables for better performance OPTIMZE TABLE testdb.price; -- can free 496 MB OPTIMZE TABLE testdb.mail; -- can free 5704 MB OPTIMZE TABLE testdb.basket; -- can free 20 MB Total freed space after theses OPTIMIZE TABLE : 6220 Mb --- mysqltuner.pl | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/mysqltuner.pl b/mysqltuner.pl index 4641fd1..105a185 100755 --- a/mysqltuner.pl +++ b/mysqltuner.pl @@ -938,6 +938,7 @@ sub arr2hash { my $sep = shift; $sep = '\s' unless defined($sep); foreach my $line (@$harr) { + next if ($line =~ m/^\*\*\*\*\*\*\*/); $line =~ /([a-zA-Z_]*)\s*$sep\s*(.*)/; $$href{$1} = $2; debugprint "V: $1 = $2"; @@ -953,12 +954,12 @@ sub get_all_vars { my @mysqlvarlist = select_array("SHOW VARIABLES"); push( @mysqlvarlist, select_array("SHOW GLOBAL VARIABLES") ); arr2hash( \%myvar, \@mysqlvarlist ); - $result{'Variables'} = %myvar; + $result{'Variables'} = \%myvar; my @mysqlstatlist = select_array("SHOW STATUS"); push( @mysqlstatlist, select_array("SHOW GLOBAL STATUS") ); arr2hash( \%mystat, \@mysqlstatlist ); - $result{'Status'} = %mystat; + $result{'Status'} = \%mystat; $myvar{'have_galera'} = "NO"; if ( defined( $myvar{'wsrep_provider_options'} ) @@ -1002,7 +1003,7 @@ sub get_all_vars { debugprint Dumper(@mysqlenginelist); my @mysqlslave = select_array("SHOW SLAVE STATUS\\G"); arr2hash( \%myrepl, \@mysqlslave, ':' ); - $result{'Replication'}{'Status'} = %myrepl; + $result{'Replication'}{'Status'} = \%myrepl; my @mysqlslaves = select_array "SHOW SLAVE HOSTS"; my @lineitems = (); foreach my $line (@mysqlslaves) { @@ -1775,13 +1776,15 @@ sub check_storage_engines { $result{'Engine'}{$engine}{'Data Size'} = $dsize; $result{'Engine'}{$engine}{'Index Size'} = $isize; } - $fragtables = select_one -"SELECT COUNT(TABLE_NAME) FROM information_schema.TABLES WHERE TABLE_SCHEMA NOT IN ('information_schema','performance_schema', 'mysql') AND Data_free > 0 AND NOT ENGINE='MEMORY' AND NOT ENGINE='InnoDB'"; - chomp($fragtables); + my $not_innodb=''; + if ($result{'Variables'}{'innodb_file_per_table'} eq 'OFF') { + $not_innodb="AND NOT ENGINE='InnoDB'"; + } $result{'Tables'}{'Fragmented tables'} = [ select_array -"SELECT CONCAT(CONCAT(TABLE_SCHEMA, '.'), TABLE_NAME) FROM information_schema.TABLES WHERE TABLE_SCHEMA NOT IN ('information_schema','performance_schema', 'mysql') AND Data_free > 0 AND NOT ENGINE='MEMORY' AND NOT ENGINE='InnoDB'" +"SELECT CONCAT(CONCAT(TABLE_SCHEMA, '.'), TABLE_NAME),DATA_FREE FROM information_schema.TABLES WHERE TABLE_SCHEMA NOT IN ('information_schema','performance_schema', 'mysql') AND DATA_LENGTH/1024/1024>100 AND DATA_FREE*100/(DATA_LENGTH+INDEX_LENGTH+DATA_FREE) > 10 AND NOT ENGINE='MEMORY' $not_innodb" ]; + $fragtables = scalar @{$result{'Tables'}{'Fragmented tables'}}; } else { @@ -1870,6 +1873,16 @@ sub check_storage_engines { badprint "Total fragmented tables: $fragtables"; push( @generalrec, "Run OPTIMIZE TABLE to defragment tables for better performance" ); + my $total_free=0; + foreach my $table_line (@{$result{'Tables'}{'Fragmented tables'}}) { + my ($table_name,$data_free)=split(/\s+/,$table_line); + $data_free=$data_free/1024/1024; + $total_free+=$data_free; + push( @generalrec, + " OPTIMZE TABLE $table_name; -- can free $data_free MB"); + } + push( @generalrec, + "Total freed space after theses OPTIMIZE TABLE : $total_free Mb" ); } else { goodprint "Total fragmented tables: $fragtables"; From 9af08d015ce1362dcd0050f90752341fd6568bde Mon Sep 17 00:00:00 2001 From: Jean-Marie Renouard Date: Thu, 2 Jun 2016 16:24:41 +0200 Subject: [PATCH 120/126] adding minimum privileges request --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index b13d01b..58ba0c2 100644 --- a/README.md +++ b/README.md @@ -130,6 +130,10 @@ To get information about stored credentials, use the following command: password = ***** host = localhost +Question: What's minimum privileges needed by a specific mysqltuner user in database ? + + mysql>GRANT SELECT, PROCESS,EXECUTE, REPLICATION CLIENT,SHOW DATABASES,SHOW VIEW ON *.* FOR 'mysqltuner'@'localhost' identified by pwd1234; + Question: It's not working on my OS! What gives?! These kinds of things are bound to happen. Here are the details I need from you in order to research the problem thoroughly: From b0848e5cc595e96be08e30c9b3d48f4bf55599dd Mon Sep 17 00:00:00 2001 From: jfcoz Date: Fri, 3 Jun 2016 08:33:02 +0200 Subject: [PATCH 121/126] add skip-name-resolve recommandation --- mysqltuner.pl | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/mysqltuner.pl b/mysqltuner.pl index 105a185..6a89730 100755 --- a/mysqltuner.pl +++ b/mysqltuner.pl @@ -2501,6 +2501,14 @@ sub mysql_stats { "Aborted connections: $mycalc{'pct_connections_aborted'}% ($mystat{'Aborted_connects'}/$mystat{'Connections'})"; } + # name resolution + if ($result{'Variables'}{'skip_name_resolve'} eq 'OFF') { + badprint +"name resolution is active : a reverse name resolution is made for each new connection and can reduce performance"; + push( @generalrec, + "Configure your accounts with ip or subnets only, then update your configuration with skip-name-resolve=1" ); + } + # Query cache if ( !mysql_version_ge(4) ) { From 5bcddc77b8dc03444fc0ff033e9fe00496c7171e Mon Sep 17 00:00:00 2001 From: root Date: Fri, 3 Jun 2016 11:03:52 +0200 Subject: [PATCH 122/126] #213 changing badprint to print in order to display error message when JSON module is not loaded --- mysqltuner.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysqltuner.pl b/mysqltuner.pl index 6a89730..f278489 100755 --- a/mysqltuner.pl +++ b/mysqltuner.pl @@ -4005,7 +4005,7 @@ sub dump_result { if ( $opt{'json'} ne 0 ) { eval "{ use JSON }"; if ($@) { - badprint "JSON Module is needed."; + print "JSON Module is needed."; exit 1; } my $json = JSON->new->allow_nonref; From b479d9aede11ed9ff5b93439a8834a946ae57d2b Mon Sep 17 00:00:00 2001 From: Kevin Houdebert Date: Fri, 3 Jun 2016 15:50:19 +0200 Subject: [PATCH 123/126] Fix typo for OPTIMIZE --- mysqltuner.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysqltuner.pl b/mysqltuner.pl index f278489..56c10d3 100755 --- a/mysqltuner.pl +++ b/mysqltuner.pl @@ -1879,7 +1879,7 @@ sub check_storage_engines { $data_free=$data_free/1024/1024; $total_free+=$data_free; push( @generalrec, - " OPTIMZE TABLE $table_name; -- can free $data_free MB"); + " OPTIMIZE TABLE $table_name; -- can free $data_free MB"); } push( @generalrec, "Total freed space after theses OPTIMIZE TABLE : $total_free Mb" ); From 0b534333b2eba0f2d1affdac06bcaaaf62132103 Mon Sep 17 00:00:00 2001 From: root Date: Fri, 10 Jun 2016 10:18:21 +0200 Subject: [PATCH 124/126] Update vulnerabilities list Update mysql tuner version Update internals documentation --- INTERNALS.md | 12 ++++++++++-- mysqltuner.pl | 6 +++--- vulnerabilities.csv | 18 ++++++++++++------ 3 files changed, 25 insertions(+), 11 deletions(-) diff --git a/INTERNALS.md b/INTERNALS.md index d4ec954..3d60bcb 100644 --- a/INTERNALS.md +++ b/INTERNALS.md @@ -227,9 +227,11 @@ * Key buffer write hit ratio (>95%) ## MySQLTuner Galera information - * wsrep_ready cluster is ready * wsrep_connected node is connected to other nodes +* wsrep_cluster_name is defined. +* wsrep_node_name is defined. +* Check thet notification script wsrep_notify_cmd is defined * wsrep_cluster_status PRIMARY /NON PRIMARY. * PRIMARY : Coherent cluster * NO PRIMARY : cluster gets several states @@ -240,7 +242,13 @@ * SYNCED state able to read/write * wsrep_cluster_conf_id configuration level must be identical in all nodes * wsrep_last_commited committed level must be identical in all nodes - +* Look for tables without primary keys +* Look for non InnoDB tables for Galera +* Variable innodb_flush_log_at_trx_commit should be set to 0. +* Check that there is 3 or 5 members in Galera cluster. +* Check that xtrabackup is used for SST method with wsrep_sst_method variable. +* Check variables wsrep_OSU_method is defined to TOI for updates. +* Check that there is no certification failures controlling wsrep_local_cert_failures status. ## MySQLTuner TokuDB information diff --git a/mysqltuner.pl b/mysqltuner.pl index 56c10d3..b578660 100755 --- a/mysqltuner.pl +++ b/mysqltuner.pl @@ -1,5 +1,5 @@ #!/usr/bin/env perl -# mysqltuner.pl - Version 1.6.12 +# mysqltuner.pl - Version 1.6.13 # High Performance MySQL Tuning Script # Copyright (C) 2006-2016 Major Hayden - major@mhtx.net # @@ -54,7 +54,7 @@ $Data::Dumper::Pair = " : "; #use Env; # Set up a few variables for use in the script -my $tunerversion = "1.6.12"; +my $tunerversion = "1.6.13"; my ( @adjvars, @generalrec ); # Set defaults @@ -4072,7 +4072,7 @@ __END__ =head1 NAME - MySQLTuner 1.6.12 - MySQL High Performance Tuning Script + MySQLTuner 1.6.13 - MySQL High Performance Tuning Script =head1 IMPORTANT USAGE GUIDELINES diff --git a/vulnerabilities.csv b/vulnerabilities.csv index 78a8eae..95cbb61 100755 --- a/vulnerabilities.csv +++ b/vulnerabilities.csv @@ -367,6 +367,9 @@ 5.5.43;5;5;43;CVE-2015-2648;Candidate;"Unspecified vulnerability in Oracle MySQL Server 5.5.43 and earlier and 5.6.24 and earlier allows remote authenticated users to affect availability via vectors related to DML.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/cpujul2015-2367936.html | DEBIAN:DSA-3308 | URL:http://www.debian.org/security/2015/dsa-3308 | REDHAT:RHSA-2015:1630 | URL:http://rhn.redhat.com/errata/RHSA-2015-1630.html | UBUNTU:USN-2674-1 | URL:http://www.ubuntu.com/usn/USN-2674-1";Assigned (20150320);"None (candidate not yet proposed)"; 5.6.24;5;6;24;CVE-2015-2648;Candidate;"Unspecified vulnerability in Oracle MySQL Server 5.5.43 and earlier and 5.6.24 and earlier allows remote authenticated users to affect availability via vectors related to DML.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/cpujul2015-2367936.html | DEBIAN:DSA-3308 | URL:http://www.debian.org/security/2015/dsa-3308 | REDHAT:RHSA-2015:1630 | URL:http://rhn.redhat.com/errata/RHSA-2015-1630.html | UBUNTU:USN-2674-1 | URL:http://www.ubuntu.com/usn/USN-2674-1";Assigned (20150320);"None (candidate not yet proposed)"; 5.6.24;5;6;24;CVE-2015-2661;Candidate;"Unspecified vulnerability in Oracle MySQL Server 5.6.24 and earlier allows local users to affect availability via unknown vectors related to Client.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/cpujul2015-2367936.html | REDHAT:RHSA-2015:1630 | URL:http://rhn.redhat.com/errata/RHSA-2015-1630.html | UBUNTU:USN-2674-1 | URL:http://www.ubuntu.com/usn/USN-2674-1";Assigned (20150320);"None (candidate not yet proposed)"; +5.7.3;5;7;3;CVE-2015-3152;Candidate;"Oracle MySQL before 5.7.3; Oracle MySQL Connector/C (aka libmysqlclient) before 6.1.3; and MariaDB before 5.5.44 use the --ssl option to mean that SSL is optional; which allows man-in-the-middle attackers to spoof servers via a cleartext-downgrade attack; aka a ""BACKRONYM"" attack.";"MISC:http://mysqlblog.fivefarmers.com/2014/04/02/redefining-ssl-option/ | MISC:http://www.ocert.org/advisories/ocert-2015-003.html | MISC:https://www.duosecurity.com/blog/backronym-mysql-vulnerability | CONFIRM:http://mysqlblog.fivefarmers.com/2015/04/29/ssltls-in-5-6-and-5-5-ocert-advisory/ | CONFIRM:https://access.redhat.com/security/cve/cve-2015-3152 | CONFIRM:https://github.com/mysql/mysql-server/commit/3bd5589e1a5a93f9c224badf983cd65c45215390 | CONFIRM:https://jira.mariadb.org/browse/MDEV-7937";Assigned (20150410);"None (candidate not yet proposed)"; +6.1.3;6;1;3;CVE-2015-3152;Candidate;"Oracle MySQL before 5.7.3; Oracle MySQL Connector/C (aka libmysqlclient) before 6.1.3; and MariaDB before 5.5.44 use the --ssl option to mean that SSL is optional; which allows man-in-the-middle attackers to spoof servers via a cleartext-downgrade attack; aka a ""BACKRONYM"" attack.";"MISC:http://mysqlblog.fivefarmers.com/2014/04/02/redefining-ssl-option/ | MISC:http://www.ocert.org/advisories/ocert-2015-003.html | MISC:https://www.duosecurity.com/blog/backronym-mysql-vulnerability | CONFIRM:http://mysqlblog.fivefarmers.com/2015/04/29/ssltls-in-5-6-and-5-5-ocert-advisory/ | CONFIRM:https://access.redhat.com/security/cve/cve-2015-3152 | CONFIRM:https://github.com/mysql/mysql-server/commit/3bd5589e1a5a93f9c224badf983cd65c45215390 | CONFIRM:https://jira.mariadb.org/browse/MDEV-7937";Assigned (20150410);"None (candidate not yet proposed)"; +5.5.44;5;5;44;CVE-2015-3152;Candidate;"Oracle MySQL before 5.7.3; Oracle MySQL Connector/C (aka libmysqlclient) before 6.1.3; and MariaDB before 5.5.44 use the --ssl option to mean that SSL is optional; which allows man-in-the-middle attackers to spoof servers via a cleartext-downgrade attack; aka a ""BACKRONYM"" attack.";"MISC:http://mysqlblog.fivefarmers.com/2014/04/02/redefining-ssl-option/ | MISC:http://www.ocert.org/advisories/ocert-2015-003.html | MISC:https://www.duosecurity.com/blog/backronym-mysql-vulnerability | CONFIRM:http://mysqlblog.fivefarmers.com/2015/04/29/ssltls-in-5-6-and-5-5-ocert-advisory/ | CONFIRM:https://access.redhat.com/security/cve/cve-2015-3152 | CONFIRM:https://github.com/mysql/mysql-server/commit/3bd5589e1a5a93f9c224badf983cd65c45215390 | CONFIRM:https://jira.mariadb.org/browse/MDEV-7937";Assigned (20150410);"None (candidate not yet proposed)"; 5.5.43;5;5;43;CVE-2015-4737;Candidate;"Unspecified vulnerability in Oracle MySQL Server 5.5.43 and earlier; and 5.6.23 and earlier; allows remote authenticated users to affect confidentiality via unknown vectors related to Server : Pluggable Auth.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/cpujul2015-2367936.html | DEBIAN:DSA-3308 | URL:http://www.debian.org/security/2015/dsa-3308 | REDHAT:RHSA-2015:1630 | URL:http://rhn.redhat.com/errata/RHSA-2015-1630.html | UBUNTU:USN-2674-1 | URL:http://www.ubuntu.com/usn/USN-2674-1";Assigned (20150624);"None (candidate not yet proposed)"; 5.6.23;5;6;23;CVE-2015-4737;Candidate;"Unspecified vulnerability in Oracle MySQL Server 5.5.43 and earlier; and 5.6.23 and earlier; allows remote authenticated users to affect confidentiality via unknown vectors related to Server : Pluggable Auth.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/cpujul2015-2367936.html | DEBIAN:DSA-3308 | URL:http://www.debian.org/security/2015/dsa-3308 | REDHAT:RHSA-2015:1630 | URL:http://rhn.redhat.com/errata/RHSA-2015-1630.html | UBUNTU:USN-2674-1 | URL:http://www.ubuntu.com/usn/USN-2674-1";Assigned (20150624);"None (candidate not yet proposed)"; 5.5.43;5;5;43;CVE-2015-4752;Candidate;"Unspecified vulnerability in Oracle MySQL Server 5.5.43 and earlier and 5.6.24 and earlier allows remote authenticated users to affect availability via vectors related to Server : I_S.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/cpujul2015-2367936.html | DEBIAN:DSA-3308 | URL:http://www.debian.org/security/2015/dsa-3308 | REDHAT:RHSA-2015:1630 | URL:http://rhn.redhat.com/errata/RHSA-2015-1630.html | UBUNTU:USN-2674-1 | URL:http://www.ubuntu.com/usn/USN-2674-1";Assigned (20150624);"None (candidate not yet proposed)"; @@ -421,12 +424,15 @@ 2.17.1;2;17;1;CVE-2015-5969;Candidate;"The mysql-systemd-helper script in the mysql-community-server package before 5.6.28-2.17.1 in openSUSE 13.2 and before 5.6.28-13.1 in openSUSE Leap 42.1 and the mariadb package before 10.0.22-2.21.2 in openSUSE 13.2 and before 10.0.22-3.1 in SUSE Linux Enterprise (SLE) 12.1 and openSUSE Leap 42.1 allows local users to discover database credentials by listing a process and its arguments.";"CONFIRM:https://bugzilla.suse.com/957174 | SUSE:SUSE-SU-2016:0296 | URL:https://www.suse.com/support/update/announcement/2016/suse-su-20160296-1.html | SUSE:openSUSE-SU-2016:0367 | URL:http://lists.opensuse.org/opensuse-security-announce/2016-02/msg00015.html | SUSE:openSUSE-SU-2016:0368 | URL:http://lists.opensuse.org/opensuse-updates/2016-02/msg00039.html | SUSE:openSUSE-SU-2016:0379 | URL:http://lists.opensuse.org/opensuse-updates/2016-02/msg00050.html";Assigned (20150812);"None (candidate not yet proposed)"; 10.0.22;10;0;22;CVE-2015-5969;Candidate;"The mysql-systemd-helper script in the mysql-community-server package before 5.6.28-2.17.1 in openSUSE 13.2 and before 5.6.28-13.1 in openSUSE Leap 42.1 and the mariadb package before 10.0.22-2.21.2 in openSUSE 13.2 and before 10.0.22-3.1 in SUSE Linux Enterprise (SLE) 12.1 and openSUSE Leap 42.1 allows local users to discover database credentials by listing a process and its arguments.";"CONFIRM:https://bugzilla.suse.com/957174 | SUSE:SUSE-SU-2016:0296 | URL:https://www.suse.com/support/update/announcement/2016/suse-su-20160296-1.html | SUSE:openSUSE-SU-2016:0367 | URL:http://lists.opensuse.org/opensuse-security-announce/2016-02/msg00015.html | SUSE:openSUSE-SU-2016:0368 | URL:http://lists.opensuse.org/opensuse-updates/2016-02/msg00039.html | SUSE:openSUSE-SU-2016:0379 | URL:http://lists.opensuse.org/opensuse-updates/2016-02/msg00050.html";Assigned (20150812);"None (candidate not yet proposed)"; 2.21.2;2;21;2;CVE-2015-5969;Candidate;"The mysql-systemd-helper script in the mysql-community-server package before 5.6.28-2.17.1 in openSUSE 13.2 and before 5.6.28-13.1 in openSUSE Leap 42.1 and the mariadb package before 10.0.22-2.21.2 in openSUSE 13.2 and before 10.0.22-3.1 in SUSE Linux Enterprise (SLE) 12.1 and openSUSE Leap 42.1 allows local users to discover database credentials by listing a process and its arguments.";"CONFIRM:https://bugzilla.suse.com/957174 | SUSE:SUSE-SU-2016:0296 | URL:https://www.suse.com/support/update/announcement/2016/suse-su-20160296-1.html | SUSE:openSUSE-SU-2016:0367 | URL:http://lists.opensuse.org/opensuse-security-announce/2016-02/msg00015.html | SUSE:openSUSE-SU-2016:0368 | URL:http://lists.opensuse.org/opensuse-updates/2016-02/msg00039.html | SUSE:openSUSE-SU-2016:0379 | URL:http://lists.opensuse.org/opensuse-updates/2016-02/msg00050.html";Assigned (20150812);"None (candidate not yet proposed)"; -5.5.46;5;5;46;CVE-2016-0546;Candidate;"Unspecified vulnerability in Oracle MySQL 5.5.46 and earlier; 5.6.27 and earlier; and 5.7.9 and MariaDB before 5.5.47; 10.0.x before 10.0.23; and 10.1.x before 10.1.10 allows local users to affect confidentiality; integrity; and availability via unknown vectors related to Client. NOTE: the previous information is from the January 2016 CPU. Oracle has not commented on third-party claims that these are multiple buffer overflows in the mysqlshow tool that allow remote database servers to have unspecified impact via a long table or database name.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/cpujan2016-2367955.html | CONFIRM:https://mariadb.com/kb/en/mariadb/mariadb-10110-release-notes/ | CONFIRM:https://mariadb.com/kb/en/mariadb/mariadb-5547-release-notes/ | CONFIRM:https://mariadb.com/kb/en/mdb-10023-rn/ | CONFIRM:https://bugzilla.redhat.com/show_bug.cgi?id=1301493 | CONFIRM:https://dev.mysql.com/doc/relnotes/mysql/5.5/en/news-5-5-47.html | CONFIRM:https://dev.mysql.com/doc/relnotes/mysql/5.6/en/news-5-6-28.html | CONFIRM:https://github.com/mysql/mysql-server/commit/0dbd5a8797ed4bd18e8b883988fb62177eb0f73f | DEBIAN:DSA-3453 | URL:http://www.debian.org/security/2016/dsa-3453 | REDHAT:RHSA-2016:0534 | URL:http://rhn.redhat.com/errata/RHSA-2016-0534.html | SUSE:openSUSE-SU-2016:0367 | URL:http://lists.opensuse.org/opensuse-security-announce/2016-02/msg00015.html";Assigned (20151209);"None (candidate not yet proposed)"; -5.6.27;5;6;27;CVE-2016-0546;Candidate;"Unspecified vulnerability in Oracle MySQL 5.5.46 and earlier; 5.6.27 and earlier; and 5.7.9 and MariaDB before 5.5.47; 10.0.x before 10.0.23; and 10.1.x before 10.1.10 allows local users to affect confidentiality; integrity; and availability via unknown vectors related to Client. NOTE: the previous information is from the January 2016 CPU. Oracle has not commented on third-party claims that these are multiple buffer overflows in the mysqlshow tool that allow remote database servers to have unspecified impact via a long table or database name.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/cpujan2016-2367955.html | CONFIRM:https://mariadb.com/kb/en/mariadb/mariadb-10110-release-notes/ | CONFIRM:https://mariadb.com/kb/en/mariadb/mariadb-5547-release-notes/ | CONFIRM:https://mariadb.com/kb/en/mdb-10023-rn/ | CONFIRM:https://bugzilla.redhat.com/show_bug.cgi?id=1301493 | CONFIRM:https://dev.mysql.com/doc/relnotes/mysql/5.5/en/news-5-5-47.html | CONFIRM:https://dev.mysql.com/doc/relnotes/mysql/5.6/en/news-5-6-28.html | CONFIRM:https://github.com/mysql/mysql-server/commit/0dbd5a8797ed4bd18e8b883988fb62177eb0f73f | DEBIAN:DSA-3453 | URL:http://www.debian.org/security/2016/dsa-3453 | REDHAT:RHSA-2016:0534 | URL:http://rhn.redhat.com/errata/RHSA-2016-0534.html | SUSE:openSUSE-SU-2016:0367 | URL:http://lists.opensuse.org/opensuse-security-announce/2016-02/msg00015.html";Assigned (20151209);"None (candidate not yet proposed)"; -5.7.9;5;7;9;CVE-2016-0546;Candidate;"Unspecified vulnerability in Oracle MySQL 5.5.46 and earlier; 5.6.27 and earlier; and 5.7.9 and MariaDB before 5.5.47; 10.0.x before 10.0.23; and 10.1.x before 10.1.10 allows local users to affect confidentiality; integrity; and availability via unknown vectors related to Client. NOTE: the previous information is from the January 2016 CPU. Oracle has not commented on third-party claims that these are multiple buffer overflows in the mysqlshow tool that allow remote database servers to have unspecified impact via a long table or database name.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/cpujan2016-2367955.html | CONFIRM:https://mariadb.com/kb/en/mariadb/mariadb-10110-release-notes/ | CONFIRM:https://mariadb.com/kb/en/mariadb/mariadb-5547-release-notes/ | CONFIRM:https://mariadb.com/kb/en/mdb-10023-rn/ | CONFIRM:https://bugzilla.redhat.com/show_bug.cgi?id=1301493 | CONFIRM:https://dev.mysql.com/doc/relnotes/mysql/5.5/en/news-5-5-47.html | CONFIRM:https://dev.mysql.com/doc/relnotes/mysql/5.6/en/news-5-6-28.html | CONFIRM:https://github.com/mysql/mysql-server/commit/0dbd5a8797ed4bd18e8b883988fb62177eb0f73f | DEBIAN:DSA-3453 | URL:http://www.debian.org/security/2016/dsa-3453 | REDHAT:RHSA-2016:0534 | URL:http://rhn.redhat.com/errata/RHSA-2016-0534.html | SUSE:openSUSE-SU-2016:0367 | URL:http://lists.opensuse.org/opensuse-security-announce/2016-02/msg00015.html";Assigned (20151209);"None (candidate not yet proposed)"; -5.5.47;5;5;47;CVE-2016-0546;Candidate;"Unspecified vulnerability in Oracle MySQL 5.5.46 and earlier; 5.6.27 and earlier; and 5.7.9 and MariaDB before 5.5.47; 10.0.x before 10.0.23; and 10.1.x before 10.1.10 allows local users to affect confidentiality; integrity; and availability via unknown vectors related to Client. NOTE: the previous information is from the January 2016 CPU. Oracle has not commented on third-party claims that these are multiple buffer overflows in the mysqlshow tool that allow remote database servers to have unspecified impact via a long table or database name.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/cpujan2016-2367955.html | CONFIRM:https://mariadb.com/kb/en/mariadb/mariadb-10110-release-notes/ | CONFIRM:https://mariadb.com/kb/en/mariadb/mariadb-5547-release-notes/ | CONFIRM:https://mariadb.com/kb/en/mdb-10023-rn/ | CONFIRM:https://bugzilla.redhat.com/show_bug.cgi?id=1301493 | CONFIRM:https://dev.mysql.com/doc/relnotes/mysql/5.5/en/news-5-5-47.html | CONFIRM:https://dev.mysql.com/doc/relnotes/mysql/5.6/en/news-5-6-28.html | CONFIRM:https://github.com/mysql/mysql-server/commit/0dbd5a8797ed4bd18e8b883988fb62177eb0f73f | DEBIAN:DSA-3453 | URL:http://www.debian.org/security/2016/dsa-3453 | REDHAT:RHSA-2016:0534 | URL:http://rhn.redhat.com/errata/RHSA-2016-0534.html | SUSE:openSUSE-SU-2016:0367 | URL:http://lists.opensuse.org/opensuse-security-announce/2016-02/msg00015.html";Assigned (20151209);"None (candidate not yet proposed)"; -10.0.23;10;0;23;CVE-2016-0546;Candidate;"Unspecified vulnerability in Oracle MySQL 5.5.46 and earlier; 5.6.27 and earlier; and 5.7.9 and MariaDB before 5.5.47; 10.0.x before 10.0.23; and 10.1.x before 10.1.10 allows local users to affect confidentiality; integrity; and availability via unknown vectors related to Client. NOTE: the previous information is from the January 2016 CPU. Oracle has not commented on third-party claims that these are multiple buffer overflows in the mysqlshow tool that allow remote database servers to have unspecified impact via a long table or database name.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/cpujan2016-2367955.html | CONFIRM:https://mariadb.com/kb/en/mariadb/mariadb-10110-release-notes/ | CONFIRM:https://mariadb.com/kb/en/mariadb/mariadb-5547-release-notes/ | CONFIRM:https://mariadb.com/kb/en/mdb-10023-rn/ | CONFIRM:https://bugzilla.redhat.com/show_bug.cgi?id=1301493 | CONFIRM:https://dev.mysql.com/doc/relnotes/mysql/5.5/en/news-5-5-47.html | CONFIRM:https://dev.mysql.com/doc/relnotes/mysql/5.6/en/news-5-6-28.html | CONFIRM:https://github.com/mysql/mysql-server/commit/0dbd5a8797ed4bd18e8b883988fb62177eb0f73f | DEBIAN:DSA-3453 | URL:http://www.debian.org/security/2016/dsa-3453 | REDHAT:RHSA-2016:0534 | URL:http://rhn.redhat.com/errata/RHSA-2016-0534.html | SUSE:openSUSE-SU-2016:0367 | URL:http://lists.opensuse.org/opensuse-security-announce/2016-02/msg00015.html";Assigned (20151209);"None (candidate not yet proposed)"; -10.1.10;10;1;10;CVE-2016-0546;Candidate;"Unspecified vulnerability in Oracle MySQL 5.5.46 and earlier; 5.6.27 and earlier; and 5.7.9 and MariaDB before 5.5.47; 10.0.x before 10.0.23; and 10.1.x before 10.1.10 allows local users to affect confidentiality; integrity; and availability via unknown vectors related to Client. NOTE: the previous information is from the January 2016 CPU. Oracle has not commented on third-party claims that these are multiple buffer overflows in the mysqlshow tool that allow remote database servers to have unspecified impact via a long table or database name.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/cpujan2016-2367955.html | CONFIRM:https://mariadb.com/kb/en/mariadb/mariadb-10110-release-notes/ | CONFIRM:https://mariadb.com/kb/en/mariadb/mariadb-5547-release-notes/ | CONFIRM:https://mariadb.com/kb/en/mdb-10023-rn/ | CONFIRM:https://bugzilla.redhat.com/show_bug.cgi?id=1301493 | CONFIRM:https://dev.mysql.com/doc/relnotes/mysql/5.5/en/news-5-5-47.html | CONFIRM:https://dev.mysql.com/doc/relnotes/mysql/5.6/en/news-5-6-28.html | CONFIRM:https://github.com/mysql/mysql-server/commit/0dbd5a8797ed4bd18e8b883988fb62177eb0f73f | DEBIAN:DSA-3453 | URL:http://www.debian.org/security/2016/dsa-3453 | REDHAT:RHSA-2016:0534 | URL:http://rhn.redhat.com/errata/RHSA-2016-0534.html | SUSE:openSUSE-SU-2016:0367 | URL:http://lists.opensuse.org/opensuse-security-announce/2016-02/msg00015.html";Assigned (20151209);"None (candidate not yet proposed)"; +5.4.43;5;4;43;CVE-2015-8838;Candidate;"ext/mysqlnd/mysqlnd.c in PHP before 5.4.43; 5.5.x before 5.5.27; and 5.6.x before 5.6.11 uses a client SSL option to mean that SSL is optional; which allows man-in-the-middle attackers to spoof servers via a cleartext-downgrade attack; a related issue to CVE-2015-3152.";"CONFIRM:http://git.php.net/?p=php-src.git;a=commit;h=97aa752fee61fccdec361279adbfb17a3c60f3f4 | CONFIRM:http://php.net/ChangeLog-5.php | CONFIRM:https://bugs.php.net/bug.php?id=69669";Assigned (20160331);"None (candidate not yet proposed)"; +5.5.27;5;5;27;CVE-2015-8838;Candidate;"ext/mysqlnd/mysqlnd.c in PHP before 5.4.43; 5.5.x before 5.5.27; and 5.6.x before 5.6.11 uses a client SSL option to mean that SSL is optional; which allows man-in-the-middle attackers to spoof servers via a cleartext-downgrade attack; a related issue to CVE-2015-3152.";"CONFIRM:http://git.php.net/?p=php-src.git;a=commit;h=97aa752fee61fccdec361279adbfb17a3c60f3f4 | CONFIRM:http://php.net/ChangeLog-5.php | CONFIRM:https://bugs.php.net/bug.php?id=69669";Assigned (20160331);"None (candidate not yet proposed)"; +5.6.11;5;6;11;CVE-2015-8838;Candidate;"ext/mysqlnd/mysqlnd.c in PHP before 5.4.43; 5.5.x before 5.5.27; and 5.6.x before 5.6.11 uses a client SSL option to mean that SSL is optional; which allows man-in-the-middle attackers to spoof servers via a cleartext-downgrade attack; a related issue to CVE-2015-3152.";"CONFIRM:http://git.php.net/?p=php-src.git;a=commit;h=97aa752fee61fccdec361279adbfb17a3c60f3f4 | CONFIRM:http://php.net/ChangeLog-5.php | CONFIRM:https://bugs.php.net/bug.php?id=69669";Assigned (20160331);"None (candidate not yet proposed)"; +5.5.46;5;5;46;CVE-2016-0546;Candidate;"Unspecified vulnerability in Oracle MySQL 5.5.46 and earlier; 5.6.27 and earlier; and 5.7.9 and MariaDB before 5.5.47; 10.0.x before 10.0.23; and 10.1.x before 10.1.10 allows local users to affect confidentiality; integrity; and availability via unknown vectors related to Client. NOTE: the previous information is from the January 2016 CPU. Oracle has not commented on third-party claims that these are multiple buffer overflows in the mysqlshow tool that allow remote database servers to have unspecified impact via a long table or database name.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/cpujan2016-2367955.html | CONFIRM:https://mariadb.com/kb/en/mariadb/mariadb-10110-release-notes/ | CONFIRM:https://mariadb.com/kb/en/mariadb/mariadb-5547-release-notes/ | CONFIRM:https://mariadb.com/kb/en/mdb-10023-rn/ | CONFIRM:https://bugzilla.redhat.com/show_bug.cgi?id=1301493 | CONFIRM:https://dev.mysql.com/doc/relnotes/mysql/5.5/en/news-5-5-47.html | CONFIRM:https://dev.mysql.com/doc/relnotes/mysql/5.6/en/news-5-6-28.html | CONFIRM:https://github.com/mysql/mysql-server/commit/0dbd5a8797ed4bd18e8b883988fb62177eb0f73f | DEBIAN:DSA-3453 | URL:http://www.debian.org/security/2016/dsa-3453 | REDHAT:RHSA-2016:0534 | URL:http://rhn.redhat.com/errata/RHSA-2016-0534.html | SUSE:openSUSE-SU-2016:0367 | URL:http://lists.opensuse.org/opensuse-security-announce/2016-02/msg00015.html | UBUNTU:USN-2881-1 | URL:http://www.ubuntu.com/usn/USN-2881-1";Assigned (20151209);"None (candidate not yet proposed)"; +5.6.27;5;6;27;CVE-2016-0546;Candidate;"Unspecified vulnerability in Oracle MySQL 5.5.46 and earlier; 5.6.27 and earlier; and 5.7.9 and MariaDB before 5.5.47; 10.0.x before 10.0.23; and 10.1.x before 10.1.10 allows local users to affect confidentiality; integrity; and availability via unknown vectors related to Client. NOTE: the previous information is from the January 2016 CPU. Oracle has not commented on third-party claims that these are multiple buffer overflows in the mysqlshow tool that allow remote database servers to have unspecified impact via a long table or database name.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/cpujan2016-2367955.html | CONFIRM:https://mariadb.com/kb/en/mariadb/mariadb-10110-release-notes/ | CONFIRM:https://mariadb.com/kb/en/mariadb/mariadb-5547-release-notes/ | CONFIRM:https://mariadb.com/kb/en/mdb-10023-rn/ | CONFIRM:https://bugzilla.redhat.com/show_bug.cgi?id=1301493 | CONFIRM:https://dev.mysql.com/doc/relnotes/mysql/5.5/en/news-5-5-47.html | CONFIRM:https://dev.mysql.com/doc/relnotes/mysql/5.6/en/news-5-6-28.html | CONFIRM:https://github.com/mysql/mysql-server/commit/0dbd5a8797ed4bd18e8b883988fb62177eb0f73f | DEBIAN:DSA-3453 | URL:http://www.debian.org/security/2016/dsa-3453 | REDHAT:RHSA-2016:0534 | URL:http://rhn.redhat.com/errata/RHSA-2016-0534.html | SUSE:openSUSE-SU-2016:0367 | URL:http://lists.opensuse.org/opensuse-security-announce/2016-02/msg00015.html | UBUNTU:USN-2881-1 | URL:http://www.ubuntu.com/usn/USN-2881-1";Assigned (20151209);"None (candidate not yet proposed)"; +5.7.9;5;7;9;CVE-2016-0546;Candidate;"Unspecified vulnerability in Oracle MySQL 5.5.46 and earlier; 5.6.27 and earlier; and 5.7.9 and MariaDB before 5.5.47; 10.0.x before 10.0.23; and 10.1.x before 10.1.10 allows local users to affect confidentiality; integrity; and availability via unknown vectors related to Client. NOTE: the previous information is from the January 2016 CPU. Oracle has not commented on third-party claims that these are multiple buffer overflows in the mysqlshow tool that allow remote database servers to have unspecified impact via a long table or database name.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/cpujan2016-2367955.html | CONFIRM:https://mariadb.com/kb/en/mariadb/mariadb-10110-release-notes/ | CONFIRM:https://mariadb.com/kb/en/mariadb/mariadb-5547-release-notes/ | CONFIRM:https://mariadb.com/kb/en/mdb-10023-rn/ | CONFIRM:https://bugzilla.redhat.com/show_bug.cgi?id=1301493 | CONFIRM:https://dev.mysql.com/doc/relnotes/mysql/5.5/en/news-5-5-47.html | CONFIRM:https://dev.mysql.com/doc/relnotes/mysql/5.6/en/news-5-6-28.html | CONFIRM:https://github.com/mysql/mysql-server/commit/0dbd5a8797ed4bd18e8b883988fb62177eb0f73f | DEBIAN:DSA-3453 | URL:http://www.debian.org/security/2016/dsa-3453 | REDHAT:RHSA-2016:0534 | URL:http://rhn.redhat.com/errata/RHSA-2016-0534.html | SUSE:openSUSE-SU-2016:0367 | URL:http://lists.opensuse.org/opensuse-security-announce/2016-02/msg00015.html | UBUNTU:USN-2881-1 | URL:http://www.ubuntu.com/usn/USN-2881-1";Assigned (20151209);"None (candidate not yet proposed)"; +5.5.47;5;5;47;CVE-2016-0546;Candidate;"Unspecified vulnerability in Oracle MySQL 5.5.46 and earlier; 5.6.27 and earlier; and 5.7.9 and MariaDB before 5.5.47; 10.0.x before 10.0.23; and 10.1.x before 10.1.10 allows local users to affect confidentiality; integrity; and availability via unknown vectors related to Client. NOTE: the previous information is from the January 2016 CPU. Oracle has not commented on third-party claims that these are multiple buffer overflows in the mysqlshow tool that allow remote database servers to have unspecified impact via a long table or database name.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/cpujan2016-2367955.html | CONFIRM:https://mariadb.com/kb/en/mariadb/mariadb-10110-release-notes/ | CONFIRM:https://mariadb.com/kb/en/mariadb/mariadb-5547-release-notes/ | CONFIRM:https://mariadb.com/kb/en/mdb-10023-rn/ | CONFIRM:https://bugzilla.redhat.com/show_bug.cgi?id=1301493 | CONFIRM:https://dev.mysql.com/doc/relnotes/mysql/5.5/en/news-5-5-47.html | CONFIRM:https://dev.mysql.com/doc/relnotes/mysql/5.6/en/news-5-6-28.html | CONFIRM:https://github.com/mysql/mysql-server/commit/0dbd5a8797ed4bd18e8b883988fb62177eb0f73f | DEBIAN:DSA-3453 | URL:http://www.debian.org/security/2016/dsa-3453 | REDHAT:RHSA-2016:0534 | URL:http://rhn.redhat.com/errata/RHSA-2016-0534.html | SUSE:openSUSE-SU-2016:0367 | URL:http://lists.opensuse.org/opensuse-security-announce/2016-02/msg00015.html | UBUNTU:USN-2881-1 | URL:http://www.ubuntu.com/usn/USN-2881-1";Assigned (20151209);"None (candidate not yet proposed)"; +10.0.23;10;0;23;CVE-2016-0546;Candidate;"Unspecified vulnerability in Oracle MySQL 5.5.46 and earlier; 5.6.27 and earlier; and 5.7.9 and MariaDB before 5.5.47; 10.0.x before 10.0.23; and 10.1.x before 10.1.10 allows local users to affect confidentiality; integrity; and availability via unknown vectors related to Client. NOTE: the previous information is from the January 2016 CPU. Oracle has not commented on third-party claims that these are multiple buffer overflows in the mysqlshow tool that allow remote database servers to have unspecified impact via a long table or database name.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/cpujan2016-2367955.html | CONFIRM:https://mariadb.com/kb/en/mariadb/mariadb-10110-release-notes/ | CONFIRM:https://mariadb.com/kb/en/mariadb/mariadb-5547-release-notes/ | CONFIRM:https://mariadb.com/kb/en/mdb-10023-rn/ | CONFIRM:https://bugzilla.redhat.com/show_bug.cgi?id=1301493 | CONFIRM:https://dev.mysql.com/doc/relnotes/mysql/5.5/en/news-5-5-47.html | CONFIRM:https://dev.mysql.com/doc/relnotes/mysql/5.6/en/news-5-6-28.html | CONFIRM:https://github.com/mysql/mysql-server/commit/0dbd5a8797ed4bd18e8b883988fb62177eb0f73f | DEBIAN:DSA-3453 | URL:http://www.debian.org/security/2016/dsa-3453 | REDHAT:RHSA-2016:0534 | URL:http://rhn.redhat.com/errata/RHSA-2016-0534.html | SUSE:openSUSE-SU-2016:0367 | URL:http://lists.opensuse.org/opensuse-security-announce/2016-02/msg00015.html | UBUNTU:USN-2881-1 | URL:http://www.ubuntu.com/usn/USN-2881-1";Assigned (20151209);"None (candidate not yet proposed)"; +10.1.10;10;1;10;CVE-2016-0546;Candidate;"Unspecified vulnerability in Oracle MySQL 5.5.46 and earlier; 5.6.27 and earlier; and 5.7.9 and MariaDB before 5.5.47; 10.0.x before 10.0.23; and 10.1.x before 10.1.10 allows local users to affect confidentiality; integrity; and availability via unknown vectors related to Client. NOTE: the previous information is from the January 2016 CPU. Oracle has not commented on third-party claims that these are multiple buffer overflows in the mysqlshow tool that allow remote database servers to have unspecified impact via a long table or database name.";"CONFIRM:http://www.oracle.com/technetwork/topics/security/cpujan2016-2367955.html | CONFIRM:https://mariadb.com/kb/en/mariadb/mariadb-10110-release-notes/ | CONFIRM:https://mariadb.com/kb/en/mariadb/mariadb-5547-release-notes/ | CONFIRM:https://mariadb.com/kb/en/mdb-10023-rn/ | CONFIRM:https://bugzilla.redhat.com/show_bug.cgi?id=1301493 | CONFIRM:https://dev.mysql.com/doc/relnotes/mysql/5.5/en/news-5-5-47.html | CONFIRM:https://dev.mysql.com/doc/relnotes/mysql/5.6/en/news-5-6-28.html | CONFIRM:https://github.com/mysql/mysql-server/commit/0dbd5a8797ed4bd18e8b883988fb62177eb0f73f | DEBIAN:DSA-3453 | URL:http://www.debian.org/security/2016/dsa-3453 | REDHAT:RHSA-2016:0534 | URL:http://rhn.redhat.com/errata/RHSA-2016-0534.html | SUSE:openSUSE-SU-2016:0367 | URL:http://lists.opensuse.org/opensuse-security-announce/2016-02/msg00015.html | UBUNTU:USN-2881-1 | URL:http://www.ubuntu.com/usn/USN-2881-1";Assigned (20151209);"None (candidate not yet proposed)"; 5.5.47;5;5;47;CVE-2016-2047;Candidate;"The ssl_verify_server_cert function in sql-common/client.c in MariaDB before 5.5.47; 10.0.x before 10.0.23; and 10.1.x before 10.1.10; Oracle MySQL 5.5.48 and earlier; 5.6.29 and earlier; and 5.7.11 and earlier; and Percona Server do not properly verify that the server hostname matches a domain name in the subject's Common Name (CN) or subjectAltName field of the X.509 certificate; which allows man-in-the-middle attackers to spoof SSL servers via a ""/CN="" string in a field in a certificate; as demonstrated by ""/OU=/CN=bar.com/CN=foo.com.""";"MLIST:[oss-security] 20160126 Flaw in mariadb clients SSL certificate validation | URL:http://www.openwall.com/lists/oss-security/2016/01/26/3 | CONFIRM:https://mariadb.atlassian.net/browse/MDEV-9212 | CONFIRM:https://mariadb.com/kb/en/mariadb/mariadb-10110-release-notes/ | CONFIRM:https://mariadb.com/kb/en/mariadb/mariadb-5547-release-notes/ | CONFIRM:https://mariadb.com/kb/en/mdb-10023-rn/ | CONFIRM:http://www.oracle.com/technetwork/security-advisory/cpuapr2016v3-2985753.html | DEBIAN:DSA-3453 | URL:http://www.debian.org/security/2016/dsa-3453 | REDHAT:RHSA-2016:0534 | URL:http://rhn.redhat.com/errata/RHSA-2016-0534.html";Assigned (20160122);"None (candidate not yet proposed)"; 10.0.23;10;0;23;CVE-2016-2047;Candidate;"The ssl_verify_server_cert function in sql-common/client.c in MariaDB before 5.5.47; 10.0.x before 10.0.23; and 10.1.x before 10.1.10; Oracle MySQL 5.5.48 and earlier; 5.6.29 and earlier; and 5.7.11 and earlier; and Percona Server do not properly verify that the server hostname matches a domain name in the subject's Common Name (CN) or subjectAltName field of the X.509 certificate; which allows man-in-the-middle attackers to spoof SSL servers via a ""/CN="" string in a field in a certificate; as demonstrated by ""/OU=/CN=bar.com/CN=foo.com.""";"MLIST:[oss-security] 20160126 Flaw in mariadb clients SSL certificate validation | URL:http://www.openwall.com/lists/oss-security/2016/01/26/3 | CONFIRM:https://mariadb.atlassian.net/browse/MDEV-9212 | CONFIRM:https://mariadb.com/kb/en/mariadb/mariadb-10110-release-notes/ | CONFIRM:https://mariadb.com/kb/en/mariadb/mariadb-5547-release-notes/ | CONFIRM:https://mariadb.com/kb/en/mdb-10023-rn/ | CONFIRM:http://www.oracle.com/technetwork/security-advisory/cpuapr2016v3-2985753.html | DEBIAN:DSA-3453 | URL:http://www.debian.org/security/2016/dsa-3453 | REDHAT:RHSA-2016:0534 | URL:http://rhn.redhat.com/errata/RHSA-2016-0534.html";Assigned (20160122);"None (candidate not yet proposed)"; 10.1.10;10;1;10;CVE-2016-2047;Candidate;"The ssl_verify_server_cert function in sql-common/client.c in MariaDB before 5.5.47; 10.0.x before 10.0.23; and 10.1.x before 10.1.10; Oracle MySQL 5.5.48 and earlier; 5.6.29 and earlier; and 5.7.11 and earlier; and Percona Server do not properly verify that the server hostname matches a domain name in the subject's Common Name (CN) or subjectAltName field of the X.509 certificate; which allows man-in-the-middle attackers to spoof SSL servers via a ""/CN="" string in a field in a certificate; as demonstrated by ""/OU=/CN=bar.com/CN=foo.com.""";"MLIST:[oss-security] 20160126 Flaw in mariadb clients SSL certificate validation | URL:http://www.openwall.com/lists/oss-security/2016/01/26/3 | CONFIRM:https://mariadb.atlassian.net/browse/MDEV-9212 | CONFIRM:https://mariadb.com/kb/en/mariadb/mariadb-10110-release-notes/ | CONFIRM:https://mariadb.com/kb/en/mariadb/mariadb-5547-release-notes/ | CONFIRM:https://mariadb.com/kb/en/mdb-10023-rn/ | CONFIRM:http://www.oracle.com/technetwork/security-advisory/cpuapr2016v3-2985753.html | DEBIAN:DSA-3453 | URL:http://www.debian.org/security/2016/dsa-3453 | REDHAT:RHSA-2016:0534 | URL:http://rhn.redhat.com/errata/RHSA-2016-0534.html";Assigned (20160122);"None (candidate not yet proposed)"; From 16c94a51baf2f1626fe0c2b43a6337098a4a9823 Mon Sep 17 00:00:00 2001 From: root Date: Fri, 10 Jun 2016 10:24:40 +0200 Subject: [PATCH 125/126] uninitialized value in script #218 --- mysqltuner.pl | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/mysqltuner.pl b/mysqltuner.pl index b578660..75ab90a 100755 --- a/mysqltuner.pl +++ b/mysqltuner.pl @@ -1768,7 +1768,10 @@ sub check_storage_engines { foreach my $line (@templist) { ( $engine, $size, $count, $dsize, $isize ) = $line =~ /([a-zA-Z_]*)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)/; - if ( !defined($size) ) { next; } + $size=0 unless defined($size); + $isize=0 unless defined($isize); + $dsize=0 unless defined($dsize); + $count=0 unless defined($count); $enginestats{$engine} = $size; $enginecount{$engine} = $count; $result{'Engine'}{$engine}{'Table Number'} = $count; From cf75be4c840d59b71d60af5762224b4fd9527250 Mon Sep 17 00:00:00 2001 From: root Date: Fri, 10 Jun 2016 10:27:55 +0200 Subject: [PATCH 126/126] Tokudb detection fix #218 --- mysqltuner.pl | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/mysqltuner.pl b/mysqltuner.pl index 75ab90a..4c2ebee 100755 --- a/mysqltuner.pl +++ b/mysqltuner.pl @@ -3133,8 +3133,7 @@ sub mariadb_tokudb { # AriaDB unless ( defined $myvar{'have_tokudb'} - && $myvar{'have_tokudb'} eq "YES" - && defined $enginestats{'TokuDb'} ) + && $myvar{'have_tokudb'} eq "YES" ) { infoprint "TokuDB is disabled."; return;