diff --git a/CURRENT_VERSION.txt b/CURRENT_VERSION.txt index 6c4bbe4c2..37c6fdb60 100644 --- a/CURRENT_VERSION.txt +++ b/CURRENT_VERSION.txt @@ -1 +1 @@ -2.8.21 +2.8.23 diff --git a/Changelog b/Changelog index 8fda8b32b..2599ed6d7 100644 --- a/Changelog +++ b/Changelog @@ -1,6 +1,22 @@ +2.8.23 2026-01-18 + +- + +2.8.22 2026-01-18 + +- feat: update all repository links from 'major' to 'jmrenouard' (issue #410) +- docs: add Changelog information and Useful Links to all README files (issue #411) +- feat: improve thread_pool_size recommendations based on logical CPU count (issue #404) +- feat: suggest enabling thread pool for servers with max_connections >= 512 (issue #404) +- fix: hide ThreadPool metrics when thread pool is not enabled to avoid noise (issue #404) +- feat: add logical_cpu_cores function to accurately detect threads including HT +- chore: bump version to 2.8.22 + 2.8.21 2026-01-18 -- +- fix: remove contradictory query_cache_limit recommendation when disabling query cache (issue #671) +- fix: cap join_buffer_size recommendation at 4MB and prefer index optimization (issue #671) +- chore: bump version to 2.8.21 2.8.20 2026-01-18 diff --git a/README.fr.md b/README.fr.md index 1a799e60f..954226a85 100644 --- a/README.fr.md +++ b/README.fr.md @@ -4,8 +4,8 @@ [![État du projet](https://opensource.box.com/badges/active.svg)](https://opensource.box.com/badges) [![État des tests](https://github.com/anuraghazra/github-readme-stats/workflows/Test/badge.svg)](https://github.com/anuraghazra/github-readme-stats/) -[![Temps moyen de résolution d'un problème](https://isitmaintained.com/badge/resolution/major/MySQLTuner-perl.svg)](https://isitmaintained.com/project/major/MySQLTuner-perl "Temps moyen de résolution d'un problème") -[![Pourcentage de problèmes ouverts](https://isitmaintained.com/badge/open/major/MySQLTuner-perl.svg)](https://isitmaintained.com/project/major/MySQLTuner-perl "Pourcentage de problèmes encore ouverts") +[![Temps moyen de résolution d'un problème](https://isitmaintained.com/badge/resolution/jmrenouard/MySQLTuner-perl.svg)](https://isitmaintained.com/project/jmrenouard/MySQLTuner-perl "Temps moyen de résolution d'un problème") +[![Pourcentage de problèmes ouverts](https://isitmaintained.com/badge/open/jmrenouard/MySQLTuner-perl.svg)](https://isitmaintained.com/project/jmrenouard/MySQLTuner-perl "Pourcentage de problèmes encore ouverts") [![Licence GPL](https://badges.frapsoft.com/os/gpl/gpl.png?v=103)](https://opensource.org/licenses/GPL-3.0/) **MySQLTuner** est un script écrit en Perl qui vous permet d'examiner rapidement une installation MySQL et de faire des ajustements pour augmenter les performances et la stabilité. Les variables de configuration actuelles et les données d'état sont récupérées et présentées dans un bref format avec quelques suggestions de performances de base. @@ -24,6 +24,7 @@ Liens utiles * **Développement actif :** [https://github.com/jmrenouard/MySQLTuner-perl](https://github.com/jmrenouard/MySQLTuner-perl) * **Versions/Tags :** [https://github.com/jmrenouard/MySQLTuner-perl/tags](https://github.com/jmrenouard/MySQLTuner-perl/tags) +* **Changelog :** [https://github.com/jmrenouard/MySQLTuner-perl/blob/master/Changelog](https://github.com/jmrenouard/MySQLTuner-perl/blob/master/Changelog) * **Images Docker :** [https://hub.docker.com/repository/docker/jmrenouard/mysqltuner/tags](https://hub.docker.com/repository/docker/jmrenouard/mysqltuner/tags) MySQLTuner a besoin de vous @@ -41,7 +42,7 @@ MySQLTuner a besoin de vous ## Stargazers au fil du temps -[![Stargazers au fil du temps](https://starchart.cc/major/MySQLTuner-perl.svg)](https://starchart.cc/major/MySQLTuner-perl) +[![Stargazers au fil du temps](https://starchart.cc/jmrenouard/MySQLTuner-perl.svg)](https://starchart.cc/jmrenouard/MySQLTuner-perl) Compatibilité ==== @@ -133,8 +134,8 @@ Choisissez l'une de ces méthodes : ```bash wget http://mysqltuner.pl/ -O mysqltuner.pl -wget https://raw.githubusercontent.com/major/MySQLTuner-perl/master/basic_passwords.txt -O basic_passwords.txt -wget https://raw.githubusercontent.com/major/MySQLTuner-perl/master/vulnerabilities.csv -O vulnerabilities.csv +wget https://raw.githubusercontent.com/jmrenouard/MySQLTuner-perl/master/basic_passwords.txt -O basic_passwords.txt +wget https://raw.githubusercontent.com/jmrenouard/MySQLTuner-perl/master/vulnerabilities.csv -O vulnerabilities.csv ``` 1) Vous pouvez télécharger l'intégralité du référentiel en utilisant `git clone` ou `git clone --depth 1 -b master` suivi de l'URL de clonage ci-dessus. @@ -562,17 +563,17 @@ MySQLTuner et Vagrant **MySQLTuner** contient une configuration Vagrant à des fins de test et de développement * Installez VirtualBox et Vagrant - * - * + * + * * Clonez le dépôt * git clone * Installez les plugins Vagrant vagrant-hostmanager et vagrant-vbguest - * vagrant plugin install vagrant-hostmanager - * vagrant plugin install vagrant-vbguest + * vagrant plugin install vagrant-hostmanager + * vagrant plugin install vagrant-vbguest * Ajoutez la boîte Fedora Core 30 depuis le site de téléchargement officiel de Fedora - * vagrant box add --name generic/fedora30 + * vagrant box add --name generic/fedora30 * Créez un répertoire de données - * mkdir data + * mkdir data ## configurer les environnements de test diff --git a/README.it.md b/README.it.md index 8ed0ff3b6..40dbd91b0 100644 --- a/README.it.md +++ b/README.it.md @@ -4,8 +4,8 @@ [![Stato del progetto](https://opensource.box.com/badges/active.svg)](https://opensource.box.com/badges) [![Stato dei test](https://github.com/anuraghazra/github-readme-stats/workflows/Test/badge.svg)](https://github.com/anuraghazra/github-readme-stats/) -[![Tempo medio per risolvere un problema](https://isitmaintained.com/badge/resolution/major/MySQLTuner-perl.svg)](https://isitmaintained.com/project/major/MySQLTuner-perl "Tempo medio per risolvere un problema") -[![Percentuale di problemi aperti](https://isitmaintained.com/badge/open/major/MySQLTuner-perl.svg)](https://isitmaintained.com/project/major/MySQLTuner-perl "Percentuale di problemi ancora aperti") +[![Tempo medio per risolvere un problema](https://isitmaintained.com/badge/resolution/jmrenouard/MySQLTuner-perl.svg)](https://isitmaintained.com/project/jmrenouard/MySQLTuner-perl "Tempo medio per risolvere un problema") +[![Percentuale di problemi aperti](https://isitmaintained.com/badge/open/jmrenouard/MySQLTuner-perl.svg)](https://isitmaintained.com/project/jmrenouard/MySQLTuner-perl "Percentuale di problemi ancora aperti") [![Licenza GPL](https://badges.frapsoft.com/os/gpl/gpl.png?v=103)](https://opensource.org/licenses/GPL-3.0/) **MySQLTuner** è uno script scritto in Perl che consente di esaminare rapidamente un'installazione di MySQL e apportare modifiche per aumentare le prestazioni e la stabilità. Le variabili di configurazione correnti e i dati di stato vengono recuperati e presentati in un formato breve insieme ad alcuni suggerimenti di base sulle prestazioni. @@ -24,6 +24,7 @@ Link Utili * **Sviluppo Attivo:** [https://github.com/jmrenouard/MySQLTuner-perl](https://github.com/jmrenouard/MySQLTuner-perl) * **Release/Tag:** [https://github.com/jmrenouard/MySQLTuner-perl/tags](https://github.com/jmrenouard/MySQLTuner-perl/tags) +* **Changelog:** [https://github.com/jmrenouard/MySQLTuner-perl/blob/master/Changelog](https://github.com/jmrenouard/MySQLTuner-perl/blob/master/Changelog) * **Immagini Docker:** [https://hub.docker.com/repository/docker/jmrenouard/mysqltuner/tags](https://hub.docker.com/repository/docker/jmrenouard/mysqltuner/tags) MySQLTuner ha bisogno di te @@ -41,7 +42,7 @@ MySQLTuner ha bisogno di te ## Stargazer nel tempo -[![Stargazer nel tempo](https://starchart.cc/major/MySQLTuner-perl.svg)](https://starchart.cc/major/MySQLTuner-perl) +[![Stargazer nel tempo](https://starchart.cc/jmrenouard/MySQLTuner-perl.svg)](https://starchart.cc/jmrenouard/MySQLTuner-perl) Compatibilità ==== @@ -133,8 +134,8 @@ Scegli uno di questi metodi: ```bash wget http://mysqltuner.pl/ -O mysqltuner.pl -wget https://raw.githubusercontent.com/major/MySQLTuner-perl/master/basic_passwords.txt -O basic_passwords.txt -wget https://raw.githubusercontent.com/major/MySQLTuner-perl/master/vulnerabilities.csv -O vulnerabilities.csv +wget https://raw.githubusercontent.com/jmrenouard/MySQLTuner-perl/master/basic_passwords.txt -O basic_passwords.txt +wget https://raw.githubusercontent.com/jmrenouard/MySQLTuner-perl/master/vulnerabilities.csv -O vulnerabilities.csv ``` 1) È possibile scaricare l'intero repository utilizzando `git clone` o `git clone --depth 1 -b master` seguito dall'URL di clonazione sopra. @@ -562,17 +563,17 @@ MySQLTuner e Vagrant **MySQLTuner** contiene una configurazione Vagrant per scopi di test e sviluppo * Installa VirtualBox e Vagrant - * - * + * + * * Clona il repository * git clone * Installa i plugin di Vagrant vagrant-hostmanager e vagrant-vbguest - * vagrant plugin install vagrant-hostmanager - * vagrant plugin install vagrant-vbguest + * vagrant plugin install vagrant-hostmanager + * vagrant plugin install vagrant-vbguest * Aggiungi la box di Fedora Core 30 dal sito Web di download ufficiale di Fedora - * vagrant box add --name generic/fedora30 + * vagrant box add --name generic/fedora30 * Crea una directory di dati - * mkdir data + * mkdir data ## configura ambienti di test diff --git a/README.md b/README.md index 80ed05548..e6dde61c7 100644 --- a/README.md +++ b/README.md @@ -4,8 +4,8 @@ [![Project Status](https://opensource.box.com/badges/active.svg)](https://opensource.box.com/badges) [![Test Status](https://github.com/anuraghazra/github-readme-stats/workflows/Test/badge.svg)](https://github.com/anuraghazra/github-readme-stats/) -[![Average time to resolve an issue](https://isitmaintained.com/badge/resolution/major/MySQLTuner-perl.svg)](https://isitmaintained.com/project/major/MySQLTuner-perl "Average time to resolve an issue") -[![Percentage of open issues](https://isitmaintained.com/badge/open/major/MySQLTuner-perl.svg)](https://isitmaintained.com/project/major/MySQLTuner-perl "Percentage of issues still open") +[![Average time to resolve an issue](https://isitmaintained.com/badge/resolution/jmrenouard/MySQLTuner-perl.svg)](https://isitmaintained.com/project/jmrenouard/MySQLTuner-perl "Average time to resolve an issue") +[![Percentage of open issues](https://isitmaintained.com/badge/open/jmrenouard/MySQLTuner-perl.svg)](https://isitmaintained.com/project/jmrenouard/MySQLTuner-perl "Percentage of issues still open") [![GPL License](https://badges.frapsoft.com/os/gpl/gpl.png?v=103)](https://opensource.org/licenses/GPL-3.0/) **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. @@ -24,6 +24,7 @@ Useful Links * **Active Development:** [https://github.com/jmrenouard/MySQLTuner-perl](https://github.com/jmrenouard/MySQLTuner-perl) * **Releases/Tags:** [https://github.com/jmrenouard/MySQLTuner-perl/tags](https://github.com/jmrenouard/MySQLTuner-perl/tags) +* **Changelog:** [https://github.com/jmrenouard/MySQLTuner-perl/blob/master/Changelog](https://github.com/jmrenouard/MySQLTuner-perl/blob/master/Changelog) * **Docker Images:** [https://hub.docker.com/repository/docker/jmrenouard/mysqltuner/tags](https://hub.docker.com/repository/docker/jmrenouard/mysqltuner/tags) MySQLTuner needs you @@ -41,7 +42,7 @@ MySQLTuner needs you ## Stargazers over time -[![Stargazers over time](https://starchart.cc/major/MySQLTuner-perl.svg)](https://starchart.cc/major/MySQLTuner-perl) +[![Stargazers over time](https://starchart.cc/jmrenouard/MySQLTuner-perl.svg)](https://starchart.cc/jmrenouard/MySQLTuner-perl) Compatibility ==== @@ -133,8 +134,8 @@ Choose one of these methods: ```bash wget http://mysqltuner.pl/ -O mysqltuner.pl -wget https://raw.githubusercontent.com/major/MySQLTuner-perl/master/basic_passwords.txt -O basic_passwords.txt -wget https://raw.githubusercontent.com/major/MySQLTuner-perl/master/vulnerabilities.csv -O vulnerabilities.csv +wget https://raw.githubusercontent.com/jmrenouard/MySQLTuner-perl/master/basic_passwords.txt -O basic_passwords.txt +wget https://raw.githubusercontent.com/jmrenouard/MySQLTuner-perl/master/vulnerabilities.csv -O vulnerabilities.csv ``` 1) You can download the entire repository by using `git clone` or `git clone --depth 1 -b master` followed by the cloning URL above. @@ -562,17 +563,17 @@ MySQLTuner and Vagrant **MySQLTuner** contains a Vagrant configurations for test purpose and development * Install VirtualBox and Vagrant - * - * + * + * * Clone repository * git clone * Install Vagrant plugins vagrant-hostmanager and vagrant-vbguest - * vagrant plugin install vagrant-hostmanager - * vagrant plugin install vagrant-vbguest + * vagrant plugin install vagrant-hostmanager + * vagrant plugin install vagrant-vbguest * Add Fedora Core 30 box for official Fedora Download Website - * vagrant box add --name generic/fedora30 + * vagrant box add --name generic/fedora30 * Create a data directory - * mkdir data + * mkdir data ## setup test environments diff --git a/README.ru.md b/README.ru.md index 101c027cc..5b4ed7f25 100644 --- a/README.ru.md +++ b/README.ru.md @@ -4,8 +4,8 @@ [![Статус проекта](https://opensource.box.com/badges/active.svg)](https://opensource.box.com/badges) [![Статус тестов](https://github.com/anuraghazra/github-readme-stats/workflows/Test/badge.svg)](https://github.com/anuraghazra/github-readme-stats/) -[![Среднее время решения проблемы](https://isitmaintained.com/badge/resolution/major/MySQLTuner-perl.svg)](https://isitmaintained.com/project/major/MySQLTuner-perl "Среднее время решения проблемы") -[![Процент открытых проблем](https://isitmaintained.com/badge/open/major/MySQLTuner-perl.svg)](https://isitmaintained.com/project/major/MySQLTuner-perl "Процент все еще открытых проблем") +[![Среднее время решения проблемы](https://isitmaintained.com/badge/resolution/jmrenouard/MySQLTuner-perl.svg)](https://isitmaintained.com/project/jmrenouard/MySQLTuner-perl "Среднее время решения проблемы") +[![Процент открытых проблем](https://isitmaintained.com/badge/open/jmrenouard/MySQLTuner-perl.svg)](https://isitmaintained.com/project/jmrenouard/MySQLTuner-perl "Процент все еще открытых проблем") [![Лицензия GPL](https://badges.frapsoft.com/os/gpl/gpl.png?v=103)](https://opensource.org/licenses/GPL-3.0/) **MySQLTuner** — это скрипт, написанный на Perl, который позволяет быстро просмотреть установку MySQL и внести коррективы для повышения производительности и стабильности. Текущие переменные конфигурации и данные о состоянии извлекаются и представляются в кратком формате вместе с некоторыми основными предложениями по производительности. @@ -24,6 +24,7 @@ * **Активная разработка:** [https://github.com/jmrenouard/MySQLTuner-perl](https://github.com/jmrenouard/MySQLTuner-perl) * **Релизы/Теги:** [https://github.com/jmrenouard/MySQLTuner-perl/tags](https://github.com/jmrenouard/MySQLTuner-perl/tags) +* **Changelog:** [https://github.com/jmrenouard/MySQLTuner-perl/blob/master/Changelog](https://github.com/jmrenouard/MySQLTuner-perl/blob/master/Changelog) * **Docker-образы:** [https://hub.docker.com/repository/docker/jmrenouard/mysqltuner/tags](https://hub.docker.com/repository/docker/jmrenouard/mysqltuner/tags) MySQLTuner нуждается в вас @@ -41,7 +42,7 @@ MySQLTuner нуждается в вас ## Звездочеты с течением времени -[![Звездочеты с течением времени](https://starchart.cc/major/MySQLTuner-perl.svg)](https://starchart.cc/major/MySQLTuner-perl) +[![Звездочеты с течением времени](https://starchart.cc/jmrenouard/MySQLTuner-perl.svg)](https://starchart.cc/jmrenouard/MySQLTuner-perl) Совместимость ==== @@ -133,8 +134,8 @@ MySQLTuner нуждается в вас ```bash wget http://mysqltuner.pl/ -O mysqltuner.pl -wget https://raw.githubusercontent.com/major/MySQLTuner-perl/master/basic_passwords.txt -O basic_passwords.txt -wget https://raw.githubusercontent.com/major/MySQLTuner-perl/master/vulnerabilities.csv -O vulnerabilities.csv +wget https://raw.githubusercontent.com/jmrenouard/MySQLTuner-perl/master/basic_passwords.txt -O basic_passwords.txt +wget https://raw.githubusercontent.com/jmrenouard/MySQLTuner-perl/master/vulnerabilities.csv -O vulnerabilities.csv ``` 1) Вы можете загрузить весь репозиторий, используя `git clone` или `git clone --depth 1 -b master`, за которым следует URL-адрес клонирования выше. @@ -562,17 +563,17 @@ MySQLTuner и Vagrant **MySQLTuner** содержит конфигурации Vagrant для целей тестирования и разработки * Установите VirtualBox и Vagrant - * - * + * + * * Клонируйте репозиторий * git clone * Установите плагины Vagrant vagrant-hostmanager и vagrant-vbguest - * vagrant plugin install vagrant-hostmanager - * vagrant plugin install vagrant-vbguest + * vagrant plugin install vagrant-hostmanager + * vagrant plugin install vagrant-vbguest * Добавьте образ Fedora Core 30 с официального сайта загрузки Fedora - * vagrant box add --name generic/fedora30 + * vagrant box add --name generic/fedora30 * Создайте каталог данных - * mkdir data + * mkdir data ## настроить тестовые среды diff --git a/build/sync.sh b/build/sync.sh index 6ea54016d..eb0b5d46a 100755 --- a/build/sync.sh +++ b/build/sync.sh @@ -1,7 +1,7 @@ #!/bin/sh # ================================================================================== # Script: sync.sh -# Description: Synchronizes local repo with upstream major/MySQLTuner-perl. +# Description: Synchronizes local repo with jmrenouard/MySQLTuner-perl. # Author: Jean-Marie Renouard # Project: MySQLTuner-perl # ================================================================================== diff --git a/build/test_envs.sh b/build/test_envs.sh index a4829ee38..1848201e0 100644 --- a/build/test_envs.sh +++ b/build/test_envs.sh @@ -21,12 +21,14 @@ TEST_DB_REPO="https://github.com/jmrenouard/test_db" DEFAULT_CONFIGS="mysql84 mariadb1011 percona80" CONFIGS="" TARGET_DB="" +FORCEMEM_VAL="" show_usage() { echo "Usage: $0 [options] [configs...]" echo "Options:" echo " -c, --configs \"list\" List of configurations to test (e.g. \"mysql84 mariadb1011\")" echo " -d, --database name Target database name for MySQLTuner to tune" + echo " -f, --forcemem value Value for --forcemem parameter (in MB)" echo " -h, --help Show this help" echo "" echo "Examples:" @@ -46,6 +48,10 @@ while [[ $# -gt 0 ]]; do TARGET_DB="$2" shift 2 ;; + -f|--forcemem) + FORCEMEM_VAL="$2" + shift 2 + ;; -h|--help) show_usage exit 0 @@ -165,6 +171,11 @@ run_test() { db_param="--database $TARGET_DB" echo "Tuning specific database: $TARGET_DB" fi + + if [ -n "$FORCEMEM_VAL" ]; then + db_param="$db_param --forcemem $FORCEMEM_VAL" + echo "Forcing memory to: ${FORCEMEM_VAL}MB" + fi { echo "--- Start: $(date) ---" diff --git a/mysqltuner.pl b/mysqltuner.pl index 2cc1d24bf..81e9883e9 100755 --- a/mysqltuner.pl +++ b/mysqltuner.pl @@ -1,5 +1,5 @@ #!/usr/bin/env perl -# mysqltuner.pl - Version 2.8.19 +# mysqltuner.pl - Version 2.8.23 # 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.8.21"; +my $tunerversion = "2.8.23"; my ( @adjvars, @generalrec ); # Set defaults @@ -427,13 +427,13 @@ sub is_int { return 0; } -# Calculates the number of physical cores considering HyperThreading +# Calculates the number of physical cores sub cpu_cores { if ( $^O eq 'linux' ) { my $cntCPU = -`awk -F: '/^core id/ && !P[\$2] { CORES++; P[\$2]=1 }; /^physical id/ && !N[\$2] { CPUs++; N[\$2]=1 }; END { print CPUs*CORES }' /proc/cpuinfo`; + `awk -F: '/^core id/ && !P[\$2] { CORES++; P[\$2]=1 }; /^physical id/ && !N[\$2] { CPUs++; N[\$2]=1 }; END { print CPUs*CORES }' /proc/cpuinfo`; chomp $cntCPU; - return ( $cntCPU == 0 ? `nproc` : $cntCPU ); + return ( $cntCPU == 0 ? `nproc` : $cntCPU ) + 0; } if ( $^O eq 'freebsd' ) { @@ -443,13 +443,39 @@ sub cpu_cores { } if ($is_win) { my $cntCPU = -`wmic cpu get NumberOfCores| perl -ne "s/[^0-9]//g; print if /[0-9]+/;"`; + `wmic cpu get NumberOfCores| perl -ne "s/[^0-9]//g; print if /[0-9]+/;"`; chomp $cntCPU; return $cntCPU + 0; } return 0; } +# Calculates the number of logical cores (including HT) +sub logical_cpu_cores { + if ( $^O eq 'linux' ) { + my $cntCPU = `grep -c ^processor /proc/cpuinfo`; + chomp $cntCPU; + if ( $cntCPU == 0 ) { + $cntCPU = `nproc`; + chomp $cntCPU; + } + return $cntCPU + 0; + } + + if ( $^O eq 'freebsd' ) { + my $cntCPU = `sysctl -n kern.smp.cpus`; + chomp $cntCPU; + return $cntCPU + 0; + } + if ($is_win) { + my $cntCPU = + `wmic cpu get NumberOfLogicalProcessors| perl -ne "s/[^0-9]//g; print if /[0-9]+/;"`; + chomp $cntCPU; + return $cntCPU + 0; + } + return cpu_cores(); +} + # Calculates the parameter passed in bytes, then rounds it to one decimal place sub hr_bytes { my $num = shift; @@ -713,7 +739,7 @@ sub validate_tuner_version { my $update; my $url = -"https://raw.githubusercontent.com/major/MySQLTuner-perl/master/mysqltuner.pl"; +"https://raw.githubusercontent.com/jmrenouard/MySQLTuner-perl/master/mysqltuner.pl"; my $httpcli = get_http_cli(); if ( $httpcli =~ /curl$/ ) { debugprint "$httpcli is available."; @@ -780,7 +806,7 @@ sub update_tuner_version { my $update; my $fullpath = ""; - my $url = "https://raw.githubusercontent.com/major/MySQLTuner-perl/master/"; + my $url = "https://raw.githubusercontent.com/jmrenouard/MySQLTuner-perl/master/"; my @scripts = ( "mysqltuner.pl", "basic_passwords.txt", "vulnerabilities.csv" ); my $totalScripts = scalar(@scripts); @@ -4072,10 +4098,6 @@ sub mysql_stats { . " cached / " . hr_num( $mystat{'Qcache_hits'} + $mystat{'Com_select'} ) . " selects)"; - push( @adjvars, - "query_cache_limit (> " - . hr_bytes_rnd( $myvar{'query_cache_limit'} ) - . ", or use smaller result sets)" ); badprint "Query cache may be disabled by default due to mutex contention."; push( @adjvars, "query_cache_size (=0)" ); @@ -4148,10 +4170,15 @@ sub mysql_stats { if ( $mycalc{'joins_without_indexes_per_day'} > 250 ) { badprint "Joins performed without indexes: $mycalc{'joins_without_indexes'}"; - push( @adjvars, - "join_buffer_size (> " - . hr_bytes( $myvar{'join_buffer_size'} ) - . ", or always use indexes with JOINs)" ); + if ( $myvar{'join_buffer_size'} < 4 * 1024 * 1024 ) { + push( @adjvars, + "join_buffer_size (> " + . hr_bytes( $myvar{'join_buffer_size'} ) + . ", or always use indexes with JOINs)" ); + } + else { + push( @adjvars, "always use indexes with JOINs" ); + } push( @generalrec, "We will suggest raising the 'join_buffer_size' until JOINs not using indexes are found. @@ -4631,85 +4658,57 @@ sub mysql_myisam { } # Recommendations for ThreadPool +# See issue #404: https://github.com/jmrenouard/MySQLTuner-perl/issues/404 sub mariadb_threadpool { - subheaderprint "ThreadPool Metrics"; + my $is_mariadb = ( ($myvar{'version'} // '') =~ /mariadb/i ); + my $is_percona = ( ($myvar{'version'} // '') =~ /percona/i or ($myvar{'version_comment'} // '') =~ /percona/i ); - # MariaDB - unless ( defined $myvar{'have_threadpool'} - && $myvar{'have_threadpool'} eq "YES" ) - { + # Thread Pool is only relevant for MariaDB and Percona + return unless ($is_mariadb or $is_percona); + + my $thread_handling = $myvar{'thread_handling'} // 'one-thread-per-connection'; + my $is_threadpool_enabled = ( $thread_handling eq 'pool-of-threads' ); + + # Recommendation to ENABLE thread pool if connections are high + # https://www.percona.com/blog/2014/01/23/percona-server-improve-scalability-percona-thread-pool/ + if (!$is_threadpool_enabled && ($mystat{'Max_used_connections'} // 0) >= 512) { + subheaderprint "ThreadPool Metrics"; infoprint "ThreadPool stat is disabled."; - return; + badprint "Max_used_connections ($mystat{'Max_used_connections'}) is >= 512."; + push(@generalrec, "Enabling the thread pool is recommended for servers with max_connections >= 512 (currently $myvar{'max_connections'})"); + push(@adjvars, "thread_handling=pool-of-threads"); } - infoprint "ThreadPool stat is enabled."; - infoprint "Thread Pool Size: " . $myvar{'thread_pool_size'} . " thread(s)."; - if ( $myvar{'version'} =~ /percona/i - or $myvar{'version_comment'} =~ /percona/i ) - { - my $np = cpu_cores; - if ( $myvar{'thread_pool_size'} >= $np - and $myvar{'thread_pool_size'} < ( $np * 1.5 ) ) - { - goodprint -"thread_pool_size for Percona between 1 and 1.5 times number of CPUs (" - . $np . " and " - . ( $np * 1.5 ) . ")"; + # If it IS enabled, show metrics and recommendations + if ($is_threadpool_enabled) { + subheaderprint "ThreadPool Metrics"; + infoprint "ThreadPool stat is enabled."; + infoprint "Thread Pool Size: " . $myvar{'thread_pool_size'} . " thread(s)."; + + # Recommendation to DISABLE thread pool if connections are low + if (($mystat{'Max_used_connections'} // 0) < 512) { + badprint "ThreadPool is enabled but Max_used_connections is < 512 ($mystat{'Max_used_connections'})."; + push(@generalrec, "Thread pool is usually only efficient for servers with max_connections >= 512"); } - else { - badprint -"thread_pool_size for Percona between 1 and 1.5 times number of CPUs (" - . $np . " and " - . ( $np * 1.5 ) . ")"; - push( @adjvars, - "thread_pool_size between " - . $np . " and " - . ( $np * 1.5 ) - . " for InnoDB usage" ); + + my $np = logical_cpu_cores(); + if ($np <= 0) { + debugprint "Unable to detect logical CPU cores for thread_pool_size recommendation."; + return; } - return; - } - if ( $myvar{'version'} =~ /mariadb/i ) { - infoprint "Using default value is good enough for your version (" - . $myvar{'version'} . ")"; - return; - } + # Percona and MariaDB recommendation: ideally one active thread per CPU + # Efficient range: [NCPU, NCPU + NCPU/2] + # Source: https://mariadb.com/kb/en/library/thread-pool-in-mariadb/ + # Source: https://www.percona.com/blog/2014/01/23/percona-server-improve-scalability-percona-thread-pool/ + my $min_tps = $np; + my $max_tps = int($np * 1.5); - 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{'thread_pool_size'} >= $min_tps && $myvar{'thread_pool_size'} <= $max_tps) { + goodprint "thread_pool_size is optimal ($myvar{'thread_pool_size'}) for your $np CPUs (range: $min_tps - $max_tps)"; + } else { + badprint "thread_pool_size ($myvar{'thread_pool_size'}) is not in the recommended range [$min_tps, $max_tps] for your $np CPUs."; + push(@adjvars, "thread_pool_size between $min_tps and $max_tps"); } } } @@ -8220,7 +8219,7 @@ sub dump_csv_files { =head1 NAME - MySQLTuner 2.8.21 - MySQL High Performance Tuning Script + MySQLTuner 2.8.22 - MySQL High Performance Tuning Script =head1 IMPORTANT USAGE GUIDELINES @@ -8315,7 +8314,7 @@ =head1 OUTPUT OPTIONS =head1 VERSION -Version 2.8.19 +Version 2.8.23 =head1 PERLDOC You can find documentation for this module with the perldoc command. diff --git a/tests/test_issue_404.t b/tests/test_issue_404.t new file mode 100644 index 000000000..c3f9bce78 --- /dev/null +++ b/tests/test_issue_404.t @@ -0,0 +1,115 @@ +use strict; +use warnings; +use Test::More; + +# Mocking variables and functions from mysqltuner.pl +our %myvar; +our %mystat; +our %mycalc; +our @adjvars; +our @generalrec; + +sub subheaderprint { } +sub infoprint { } +sub badprint { } +sub goodprint { } +sub debugprint { } +sub hr_bytes { return $_[0]; } +sub hr_num { return $_[0]; } + +# Mocked cpu_cores +our $mock_cpu_cores = 12; +sub cpu_cores { return $mock_cpu_cores; } + +# Improved logic from mysqltuner.pl (proposed) +sub mariadb_threadpool_new { + my $is_mariadb = ( ($myvar{'version'} // '') =~ /mariadb/i ); + my $is_percona = ( ($myvar{'version'} // '') =~ /percona/i or ($myvar{'version_comment'} // '') =~ /percona/i ); + + return unless ($is_mariadb or $is_percona); + + my $thread_handling = $myvar{'thread_handling'} // 'one-thread-per-connection'; + my $is_threadpool_enabled = ( $thread_handling eq 'pool-of-threads' ); + + # Recommendation to ENABLE thread pool + if (!$is_threadpool_enabled && ($mystat{'Max_used_connections'} // 0) >= 512) { + push(@generalrec, "Enabling the thread pool is recommended for servers with max_connections >= 512"); + push(@adjvars, "thread_handling=pool-of-threads"); + } + + # If it IS enabled, show metrics and recommendations + if ($is_threadpool_enabled) { + if (($mystat{'Max_used_connections'} // 0) < 512) { + push(@generalrec, "Thread pool is usually only efficient for servers with max_connections >= 512"); + } + + my $np = cpu_cores(); + return if $np <= 0; # Avoid division by zero or weirdness + + my $min_tps = $np; + my $max_tps = int($np * 1.5); + + if ($myvar{'thread_pool_size'} < $min_tps or $myvar{'thread_pool_size'} > $max_tps) { + push(@adjvars, "thread_pool_size between $min_tps and $max_tps"); + } + } +} + +# Test Case 1: Percona, ThreadPool DISABLED, but Max Connections High +%myvar = ( + version => '5.7.23-23-percona', + thread_handling => 'one-thread-per-connection', + max_connections => 1000 +); +%mystat = ( Max_used_connections => 600 ); +@adjvars = (); @generalrec = (); +mariadb_threadpool_new(); +ok(grep(/thread_handling=pool-of-threads/, @adjvars), "Should suggest enabling thread pool if Max_used_connections >= 512"); + +# Test Case 2: MariaDB, ThreadPool ENABLED, but Size Wrong (too low) +%myvar = ( + version => '10.3.10-MariaDB', + thread_handling => 'pool-of-threads', + thread_pool_size => 8 +); +%mystat = ( Max_used_connections => 600 ); +$mock_cpu_cores = 12; +@adjvars = (); @generalrec = (); +mariadb_threadpool_new(); +ok(grep(/thread_pool_size between 12 and 18/, @adjvars), "Should suggest increasing thread_pool_size to match CPUs (12-18)"); + +# Test Case 3: MariaDB, ThreadPool ENABLED, but Size Wrong (too high) +%myvar = ( + version => '10.3.10-MariaDB', + thread_handling => 'pool-of-threads', + thread_pool_size => 40 +); +%mystat = ( Max_used_connections => 600 ); +$mock_cpu_cores = 16; +@adjvars = (); @generalrec = (); +mariadb_threadpool_new(); +ok(grep(/thread_pool_size between 16 and 24/, @adjvars), "Should suggest decreasing thread_pool_size to match CPUs (16-24)"); + +# Test Case 4: ThreadPool ENABLED but Max Connections Low +%myvar = ( + version => '10.3.10-MariaDB', + thread_handling => 'pool-of-threads', + thread_pool_size => 16 +); +%mystat = ( Max_used_connections => 100 ); +$mock_cpu_cores = 16; +@adjvars = (); @generalrec = (); +mariadb_threadpool_new(); +ok(grep(/Thread pool is usually only efficient for servers with max_connections >= 512/, @generalrec), "Should warn if thread pool is enabled for low connection count"); + +# Test Case 5: Not MariaDB/Percona (Standard MySQL) +%myvar = ( + version => '8.0.21', + thread_handling => 'one-thread-per-connection', +); +%mystat = ( Max_used_connections => 600 ); +@adjvars = (); @generalrec = (); +mariadb_threadpool_new(); +is(scalar @adjvars, 0, "Should NOT suggest thread pool for standard MySQL (community doesn't have it)"); + +done_testing(); diff --git a/tests/test_issue_671.t b/tests/test_issue_671.t new file mode 100644 index 000000000..eef74d210 --- /dev/null +++ b/tests/test_issue_671.t @@ -0,0 +1,80 @@ +use strict; +use warnings; +use Test::More; + +# Mocking variables and functions from mysqltuner.pl +our %myvar; +our %mystat; +our %mycalc; +our @adjvars; +our @generalrec; + +sub hr_bytes { + my $num = shift; + return "0B" unless defined($num); + if ( $num >= ( 1024**3 ) ) { return sprintf( "%.1f", ( $num / ( 1024**3 ) ) ) . "G"; } + elsif ( $num >= ( 1024**2 ) ) { return sprintf( "%.1f", ( $num / ( 1024**2 ) ) ) . "M"; } + elsif ( $num >= 1024 ) { return sprintf( "%.1f", ( $num / 1024 ) ) . "K"; } + else { return $num . "B"; } +} + +sub hr_bytes_rnd { + my $num = shift; + return "0B" unless defined($num); + if ( $num >= ( 1024**3 ) ) { return int( ( $num / ( 1024**3 ) ) ) . "G"; } + elsif ( $num >= ( 1024**2 ) ) { return int( ( $num / ( 1024**2 ) ) ) . "M"; } + elsif ( $num >= 1024 ) { return int( ( $num / 1024 ) ) . "K"; } + else { return $num . "B"; } +} + +sub hr_num { return $_[0]; } + +sub mysql_version_ge { return 1; } # Mocked +sub mysql_version_le { return 0; } # Mocked + +# Simplified logic from mysqltuner.pl +sub check_query_cache { + if ( $mycalc{'query_cache_efficiency'} < 20 ) { + push( @adjvars, "query_cache_size (=0)" ); + push( @adjvars, "query_cache_type (=0)" ); + } +} + +sub check_joins { + if ( $mycalc{'joins_without_indexes_per_day'} > 250 ) { + if ( $myvar{'join_buffer_size'} < 4 * 1024 * 1024 ) { + push( @adjvars, + "join_buffer_size (> " + . hr_bytes( $myvar{'join_buffer_size'} ) + . ", or always use indexes with JOINs)" ); + } + else { + push( @adjvars, "always use indexes with JOINs" ); + } + } +} + +# Test Case 1: Low Efficiency Query Cache +%myvar = ( + query_cache_limit => 1048576, + query_cache_size => 33554432, + query_cache_type => 1 +); +$mycalc{'query_cache_efficiency'} = 10; +@adjvars = (); +check_query_cache(); +ok(grep(/query_cache_size \(=0\)/, @adjvars), "Should suggest disabling QC size if inefficient"); +ok(grep(/query_cache_type \(=0\)/, @adjvars), "Should suggest disabling QC type if inefficient"); +is(grep(/query_cache_limit/, @adjvars), 0, "Fix: Should NOT suggest increasing QC limit if we plan to disable it"); + +# Test Case 2: High Prunes but already large Join Buffer +%myvar = ( + join_buffer_size => 256 * 1024 * 1024 # 256M +); +$mycalc{'joins_without_indexes_per_day'} = 500; +@adjvars = (); +check_joins(); +ok(grep(/always use indexes with JOINs/, @adjvars), "Fix: Should suggest using indexes instead of increasing join_buffer_size if it is already large (256M)"); +ok(!grep(/join_buffer_size \(> 256.0M/, @adjvars), "Fix: Should NOT suggest increasing join_buffer_size if it is already very large (256M)"); + +done_testing();