diff --git a/.gitignore b/.gitignore index 70be7188..51269274 100644 --- a/.gitignore +++ b/.gitignore @@ -20,4 +20,9 @@ sql/*.sql sql/*.csv cve.csv default*.cnf -.env \ No newline at end of file +.env +.gemini/settings.json +Dumps/*.csv +raw_mysqltuner_*.txt + +mysqltuner_*.json diff --git a/CURRENT_VERSION.txt b/CURRENT_VERSION.txt index 6a6a3d8e..24ba9a38 100644 --- a/CURRENT_VERSION.txt +++ b/CURRENT_VERSION.txt @@ -1 +1 @@ -2.6.1 +2.7.0 diff --git a/FEATURES.md b/FEATURES.md index e8f259e4..1802b41c 100644 --- a/FEATURES.md +++ b/FEATURES.md @@ -2,7 +2,9 @@ Features list for option: --feature (dev only) --- +* cloud_setup * cve_recommendations +* execute_system_command * log_file_recommendations * make_recommendations * mariadb_aria diff --git a/USAGE.md b/USAGE.md index 0429e5db..e69de29b 100644 --- a/USAGE.md +++ b/USAGE.md @@ -1,174 +0,0 @@ -# NAME - - MySQLTuner 2.7.0 - MySQL High Performance Tuning Script - -# IMPORTANT USAGE GUIDELINES - -To run the script with the default options, run the script without arguments -Allow MySQL server to run for at least 24-48 hours before trusting suggestions -Some routines may require root level privileges (script will provide warnings) -You must provide the remote server's total memory when connecting to other servers - -# CONNECTION AND AUTHENTICATION - - --host Connect to a remote host to perform tests (default: localhost) - --socket Use a different socket for a local connection - --pipe Connect to a local Windows database using named pipes - --pipe_name Use a different pipe name for a local connection - --port Port to use for connection (default: 3306) - --protocol tcp Force TCP connection instead of socket - --user Username to use for authentication - --userenv Name of env variable which contains username to use for authentication - --pass Password to use for authentication - --passenv Name of env variable which contains password to use for authentication - --ssl-ca Path to public key - --mysqladmin Path to a custom mysqladmin executable - --mysqlcmd Path to a custom mysql executable - --defaults-file Path to a custom .my.cnf - --defaults-extra-file Path to an extra custom config file - --server-log Path to explicit log file (error_log) - -# PERFORMANCE AND REPORTING OPTIONS - - --skipsize Don't enumerate tables and their types/sizes (default: on) - (Recommended for servers with many tables) - --json Print result as JSON string - --prettyjson Print result as JSON formatted string - --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) - --cvefile CVE File for vulnerability checks - --outputfile Path to a output txt file - --reportfile Path to a report txt file - --template Path to a template file - --dumpdir Path to a directory where to dump information files - --feature Run a specific feature (see FEATURES section) - --dumpdir information_schema tables and sys views are dumped in CSV in this path - -# OUTPUT OPTIONS - - --silent Don't output anything on screen - --verbose Print out all options (default: no verbose, dbstat, idxstat, sysstat, tbstat, pfstat) - --color Print output in color - --nocolor Don't print output in color - --noprettyicon Print output with legacy tag [OK], [!!], [--], [CMD], ... - --nogood Remove OK responses - --nobad Remove negative/suggestion responses - --noinfo Remove informational responses - --debug Print debug information - --experimental Print experimental analysis (may fail) - --nondedicated Consider server is not dedicated to Db server usage only - --noprocess Consider no other process is running - --dbstat Print database information - --nodbstat Don't print database information - --tbstat Print table information - --notbstat Don't print table information - --colstat Print column information - --nocolstat Don't print column information - --idxstat Print index information - --noidxstat Don't print index information - --nomyisamstat Don't print MyIsam information - --sysstat Print system information - --nosysstat Don't print system information - --nostructstat Don't print table structures information - --pfstat Print Performance schema - --nopfstat Don't print Performance schema - --bannedports Ports banned separated by comma (,) - --server-log Define specific error_log to analyze - --maxportallowed Number of open ports allowable on this host - --buffers Print global and per-thread buffer values - -# PERLDOC - -You can find documentation for this module with the perldoc command. - - perldoc mysqltuner - -## INTERNALS - -[https://github.com/major/MySQLTuner-perl/blob/master/INTERNALS.md](https://github.com/major/MySQLTuner-perl/blob/master/INTERNALS.md) - - Internal documentation - -# AUTHORS - -Major Hayden - major@mhtx.net -Jean-Marie Renouard - jmrenouard@gmail.com - -# CONTRIBUTORS - -- Matthew Montgomery -- Paul Kehrer -- Dave Burgess -- Jonathan Hinds -- Mike Jackson -- Nils Breunese -- Shawn Ashlee -- Luuk Vosslamber -- Ville Skytta -- Trent Hornibrook -- Jason Gill -- Mark Imbriaco -- Greg Eden -- Aubin Galinotti -- Giovanni Bechis -- Bill Bradford -- Ryan Novosielski -- Michael Scheidell -- Blair Christensen -- Hans du Plooy -- Victor Trac -- Everett Barnes -- Tom Krouper -- Gary Barrueto -- Simon Greenaway -- Adam Stein -- Isart Montane -- Baptiste M. -- Cole Turner -- Major Hayden -- Joe Ashcraft -- Jean-Marie Renouard -- Stephan GroBberndt -- Christian Loos -- Long Radix - -# SUPPORT - -Bug reports, feature requests, and downloads at http://mysqltuner.pl/ - -Bug tracker can be found at https://github.com/major/MySQLTuner-perl/issues - -Maintained by Jean-Marie Renouard (jmrenouard\\@gmail.com) - Licensed under GPL - -# SOURCE CODE - -[https://github.com/major/MySQLTuner-perl](https://github.com/major/MySQLTuner-perl) - - git clone https://github.com/major/MySQLTuner-perl.git - -# COPYRIGHT AND LICENSE - -Copyright (C) 2006-2023 Major Hayden - major@mhtx.net -\# Copyright (C) 2015-2023 Jean-Marie Renouard - jmrenouard@gmail.com - -For the latest updates, please visit http://mysqltuner.pl/ - -Git repository available at https://github.com/major/MySQLTuner-perl - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -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 <https://www.gnu.org/licenses/>. diff --git a/mariadb_support.md b/mariadb_support.md index 8e3a49b2..bb076415 100644 --- a/mariadb_support.md +++ b/mariadb_support.md @@ -2,26 +2,30 @@ | Version | End of Support Date | LTS | Status | |---------|------------------------|-----|--------| -| 11.8 | 2028-06-04 | YES | Supported | -| 11.4 | 2029-05-29 | YES | Supported | -| 10.11 | 2028-02-16 | YES | Supported | -| 10.6 | 2026-07-06 | YES | Supported | -| 12.0 | 2025-11-07 | NO | Outdated | -| 11.7 | 2025-05-12 | NO | Outdated | -| 11.6 | 2025-02-13 | NO | Outdated | -| 11.5 | 2024-11-21 | NO | Outdated | -| 11.3 | 2024-05-29 | NO | Outdated | -| 11.2 | 2024-11-21 | NO | Outdated | -| 11.1 | 2024-08-21 | NO | Outdated | -| 11.0 | 2024-06-06 | NO | Outdated | -| 10.10 | 2023-11-17 | NO | Outdated | -| 10.9 | 2023-08-22 | NO | Outdated | -| 10.8 | 2023-05-20 | NO | Outdated | -| 10.7 | 2023-02-09 | NO | Outdated | -| 10.5 | 2025-06-24 | YES | Outdated | -| 10.4 | 2024-06-18 | YES | Outdated | -| 10.3 | 2023-05-25 | NO | Outdated | -| 10.2 | 2022-05-23 | NO | Outdated | -| 10.1 | 2020-10-17 | NO | Outdated | -| 10.0 | 2019-03-31 | NO | Outdated | -| 5.5 | 2020-04-11 | YES | Outdated | +| 12.1 | 2026-02-18 | NO | Supported | +| 12.0 | 2025-11-18 | NO | Outdated | +| 11.8 | 2028-06-04 | YES | Supported | +| 11.7 | 2025-05-12 | NO | Outdated | +| 11.6 | 2025-02-13 | NO | Outdated | +| 11.5 | 2024-11-21 | NO | Outdated | +| 11.4 | 2029-05-29 | YES | Supported | +| 11.3 | 2024-05-29 | NO | Outdated | +| 11.2 | 2024-11-21 | NO | Outdated | +| 11.1 | 2024-08-21 | NO | Outdated | +| 11.0 | 2024-06-06 | NO | Outdated | +| 10.11 | 2028-02-16 | YES | Supported | +| 10.10 | 2023-11-17 | NO | Outdated | +| 10.9 | 2023-08-22 | NO | Outdated | +| 10.8 | 2023-05-20 | NO | Outdated | +| 10.7 | 2023-02-09 | NO | Outdated | +| 10.6 | 2026-07-06 | YES | Supported | +| 10.5 | 2025-06-24 | YES | Outdated | +| 10.4 | 2024-06-18 | YES | Outdated | +| 10.3 | 2023-05-25 | NO | Outdated | +| 10.2 | 2022-05-23 | NO | Outdated | +| 10.1 | 2020-10-17 | NO | Outdated | +| 10.0 | 2019-03-31 | NO | Outdated | +| 5.5 | 2020-04-11 | YES | Outdated | +| 5.3 | 2017-03-01 | NO | Outdated | +| 5.2 | 2015-11-10 | NO | Outdated | +| 5.1 | 2015-02-01 | NO | Outdated | diff --git a/mysql_support.md b/mysql_support.md index 9215437d..df140e69 100644 --- a/mysql_support.md +++ b/mysql_support.md @@ -2,19 +2,17 @@ | Version | End of Support Date | LTS | Status | |---------|------------------------|-----|--------| -| 8.4 | 2032-04-30 | YES | Supported | -| 8.0 | 2026-04-30 | YES | Supported | -| 9.5 | 2026-01-21 | NO | Supported | -| 9.4 | 2025-10-21 | NO | Outdated | -| 9.3 | 2025-07-22 | NO | Outdated | -| 9.2 | 2025-04-15 | NO | Outdated | -| 9.1 | 2025-01-21 | NO | Outdated | -| 9.0 | 2024-10-15 | NO | Outdated | -| 8.3 | 2024-04-10 | NO | Outdated | -| 8.2 | 2023-12-14 | NO | Outdated | -| 8.1 | 2023-10-25 | NO | Outdated | -| 5.7 | 2023-10-31 | NO | Outdated | -| 5.6 | 2021-02-28 | NO | Outdated | -| 5.5 | 2018-12-31 | NO | Outdated | - -**Note:** Percona Server EOL dates are based on the corresponding MySQL version. +| 9.5 | N/A | NO | Supported | +| 9.4 | 2025-10-21 | NO | Outdated | +| 9.3 | 2025-07-22 | NO | Outdated | +| 9.2 | 2025-04-15 | NO | Outdated | +| 9.1 | 2025-01-21 | NO | Outdated | +| 9.0 | 2024-10-15 | NO | Outdated | +| 8.4 | 2032-04-30 | YES | Supported | +| 8.3 | 2024-04-10 | NO | Outdated | +| 8.2 | 2023-12-14 | NO | Outdated | +| 8.1 | 2023-10-25 | NO | Outdated | +| 8.0 | 2026-04-30 | NO | Supported | +| 5.7 | 2023-10-31 | NO | Outdated | +| 5.6 | 2021-02-28 | NO | Outdated | +| 5.5 | 2018-12-31 | NO | Outdated | diff --git a/mysqltuner.pl b/mysqltuner.pl index 488a4617..0944baac 100755 --- a/mysqltuner.pl +++ b/mysqltuner.pl @@ -1,5 +1,5 @@ #!/usr/bin/env perl -# mysqltuner.pl - Version 2.7.0 +# mysqltuner.pl - Version 2.7.1 # High Performance MySQL Tuning Script # Copyright (C) 2015-2023 Jean-Marie Renouard - jmrenouard@gmail.com # Copyright (C) 2006-2023 Major Hayden - major@mhtx.net @@ -59,7 +59,7 @@ package main; my $is_win = $^O eq 'MSWin32'; # Set up a few variables for use in the script -my $tunerversion = "2.7.0"; +my $tunerversion = "2.7.1"; my ( @adjvars, @generalrec ); # Set defaults @@ -214,13 +214,6 @@ package main; } $opt{pass} = $opt{password} if ( $opt{pass} eq 0 and $opt{password} ne 0 ); -if ( $opt{dumpdir} ne '' ) { - $opt{dumpdir} = abs_path( $opt{dumpdir} ); - if ( !-d $opt{dumpdir} ) { - mkdir $opt{dumpdir} or die "Cannot create directory $opt{dumpdir}: $!"; - } -} - # for RPM distributions $basic_password_files = "/usr/share/mysqltuner/basic_passwords.txt" unless -f "$basic_password_files"; @@ -2642,6 +2635,39 @@ sub get_replication_status { goodprint "This replication slave is up to date with master."; } } + # Parallel replication checks (MariaDB specific) + if ( $myvar{'version'} =~ /MariaDB/i ) { + my $parallel_threads = + $myvar{'slave_parallel_threads'} // $myvar{'replica_parallel_threads'} + // 0; + if ( $parallel_threads > 1 ) { + goodprint +"Parallel replication is enabled with $parallel_threads threads."; + + # Check parallel mode for MariaDB 10.5+ + if ( mysql_version_ge( 10, 5 ) ) { + my $parallel_mode = + $myvar{'slave_parallel_mode'} // $myvar{'replica_parallel_mode'} + // ''; + if ( $parallel_mode eq 'optimistic' ) { + goodprint + "Parallel replication mode is set to 'optimistic'."; + } + else { + badprint +"Parallel replication mode is not 'optimistic' (recommended for MariaDB 10.5+)."; + push( @adjvars, "replica_parallel_mode=optimistic" ); + } + } + infoprint +"Ensure binlog_format=ROW is set on the master for parallel replication to work effectively."; + } + else { + badprint "Parallel replication is disabled."; + push( @adjvars, + "replica_parallel_threads (set to number of vCPUs)" ); + } + } } # https://endoflife.date/mysql @@ -2897,6 +2923,12 @@ sub check_storage_engines { "SELECT TABLE_SCHEMA, TABLE_NAME, ENGINE, CAST(DATA_FREE AS SIGNED) FROM information_schema.TABLES WHERE TABLE_SCHEMA NOT IN ('information_schema', 'performance_schema', 'mysql') AND DATA_LENGTH/1024/1024>100 AND cast(DATA_FREE as signed)*100/(DATA_LENGTH+INDEX_LENGTH+cast(DATA_FREE as signed)) > 10 AND NOT ENGINE='MEMORY' $not_innodb" ]; $fragtables = scalar @{ $result{'Tables'}{'Fragmented tables'} }; + if ($opt{dumpdir} ne '') { + select_csv_file( + "$opt{dumpdir}/fragmented_tables.csv", + "SELECT TABLE_SCHEMA, TABLE_NAME, ENGINE, CAST(DATA_FREE AS SIGNED) FROM information_schema.TABLES WHERE TABLE_SCHEMA NOT IN ('information_schema', 'performance_schema', 'mysql') AND DATA_LENGTH/1024/1024>100 AND cast(DATA_FREE as signed)*100/(DATA_LENGTH+INDEX_LENGTH+cast(DATA_FREE as signed)) > 10 AND NOT ENGINE='MEMORY' $not_innodb" + ); + } } else { @@ -4480,20 +4512,6 @@ sub mysql_pfs { infoprint "Sys schema Version: " . select_one("select sys_version from sys.version"); - # Store all sys schema in dumpdir if defined - if ( defined $opt{dumpdir} and -d "$opt{dumpdir}" ) { - for my $sys_view ( select_array('use sys;show tables;') ) { - infoprint "Dumping $sys_view into $opt{dumpdir}"; - my $sys_view_table = $sys_view; - $sys_view_table =~ s/\$/\\\$/g; - select_csv_file( "$opt{dumpdir}/sys_$sys_view.csv", - 'select * from sys.\`' . $sys_view_table . '\`' ); - } - return; - - #exit 0 if ( $opt{stop} == 1 ); - } - # Top user per connection subheaderprint "Performance schema: Top 5 user per connection"; my $nbL = 1; @@ -7367,22 +7385,6 @@ sub mysql_tables { } - infoprint("Dumpdir: $opt{dumpdir}"); - - # Store all information schema in dumpdir if defined - if ( defined $opt{dumpdir} and -d "$opt{dumpdir}" ) { - for my $info_s_table ( - select_array('use information_schema;show tables;') ) - { - infoprint "Dumping $info_s_table into $opt{dumpdir}"; - select_csv_file( - "$opt{dumpdir}/ifs_${info_s_table}.csv", - "select * from information_schema.$info_s_table" - ); - } - - #exit 0 if ( $opt{stop} == 1 ); - } foreach ( select_user_dbs() ) { my $dbname = $_; next unless defined $_; @@ -7805,6 +7807,54 @@ sub which { return 0; } +sub dump_csv_files { + return if ( $opt{dumpdir} eq '' ); + + subheaderprint "Dumping CSV files"; + + $opt{dumpdir} = abs_path( $opt{dumpdir} ); + if ( !-d $opt{dumpdir} ) { + mkdir $opt{dumpdir} or die "Cannot create directory $opt{dumpdir}: $!"; + } + + infoprint("Dumpdir: $opt{dumpdir}"); + + # Store all sys schema in dumpdir if defined + infoprint("Dumping sys schema"); + for my $sys_view ( select_array('use sys;show tables;') ) { + infoprint "Dumping $sys_view into $opt{dumpdir}"; + my $sys_view_table = $sys_view; + $sys_view_table =~ s/\$/\\\$/g; + select_csv_file( "$opt{dumpdir}/sys_$sys_view.csv", + 'select * from sys.\`' . $sys_view_table . '\`' ); + } + + # Store all information schema in dumpdir if defined + infoprint("Dumping information schema"); + for my $info_s_table ( + select_array('use information_schema;show tables;') ) + { + next if $info_s_table =~ /INNODB_BUFFER_PAGE/; + infoprint "Dumping $info_s_table into $opt{dumpdir}"; + select_csv_file( + "$opt{dumpdir}/ifs_${info_s_table}.csv", + "select * from information_schema.$info_s_table" + ); + } + + # Store all performance schema in dumpdir if defined + infoprint("Dumping performance schema"); + for my $info_pf_table ( + select_array('use performance_schema;show tables;') ) + { + next if $info_pf_table =~ /^events_/; + infoprint "Performance Schema Dumping $info_pf_table into $opt{dumpdir}"; + select_csv_file( + "$opt{dumpdir}/ps_${info_pf_table}.csv", + "select * from performance_schema.$info_pf_table" + ); + } +} # --------------------------------------------------------------------------- # BEGIN 'MAIN' # --------------------------------------------------------------------------- @@ -7816,7 +7866,7 @@ sub which { debugprint "MySQL FINAL Client : $mysqlcmd $mysqllogin"; debugprint "MySQL Admin FINAL Client : $mysqladmincmd $mysqllogin"; -#exit(0); +dump_csv_files; # dump csv files os_setup; # Set up some OS variables get_all_vars; # Toss variables/status into hashes get_tuning_info; # Get information about the tuning connection @@ -7837,7 +7887,6 @@ sub which { system_recommendations; # Avoid too many services on the same host log_file_recommendations; # check log file content - check_metadata_perf; # Show parameter impacting performance during analysis mysql_databases; # Show information about databases mysql_tables; # Show information about table column @@ -7883,7 +7932,7 @@ sub which { =head1 NAME - MySQLTuner 2.7.0 - MySQL High Performance Tuning Script + MySQLTuner 2.7.1 - MySQL High Performance Tuning Script =head1 IMPORTANT USAGE GUIDELINES