MySQLTuner — optymalizacja MySQL i MariaDB na VPS
Opublikowano: 10 kwietnia 2026 · Kategoria: VPS / Bazy danych
Domyślna konfiguracja MySQL jest celowo ostrożna — zaprojektowana do działania na serwerach z minimalną pamięcią i nie wykorzystuje zasobów, które masz na VPS. Wynikiem są wolne zapytania, zbyt mało połączeń i nadmierne odczyty z dysku zamiast z RAM. MySQLTuner to narzędzie, które analizuje Twój serwer i mówi wprost co zmienić i dlaczego. Artykuł pokazuje jak interpretować raport i implementować rekomendacje.
Pobranie i uruchomienie MySQLTuner
# Pobierz najnowszą wersje MySQLTuner 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 # Uruchomienie (jako root lub uzytkownik z pelnym dostepem) perl mysqltuner.pl --user root --pass "TwojHaslo" # Lub z pliku .my.cnf (bezpieczniejsze) # [client] # user=root # password=TwojHaslo # plik: ~/.my.cnf (chmod 600) perl mysqltuner.pl # Opcje zaawansowane perl mysqltuner.pl \ --buffers \ # szczegoly buforow --idxstats \ # statystyki indeksow --dbstat \ # statystyki baz --outputfile /tmp/mysqltuner-report.txt # zapis do pliku
Interpretacja raportu — sekcje wyjścia
MySQLTuner dzieli raport na sekcje. Kluczowe linie to te z [!!] (ostrzeżenie) i [OK] (w porządku). Na końcu sekcja
Recommendations zbiera konkretne zmiany do zastosowania.
-------- General Statistics -------- [--] Skipped version check for MySQLTuner script [OK] Currently running supported MySQL version 8.0.36-MySQL -------- Storage Engine Statistics -------- [OK] InnoDB is enabled [!!] InnoDB buffer pool / data size: 128.0M/4.5G # KLUCZOWE! [!!] InnoDB buffer pool instances: 1 (recommended: 4+) [OK] InnoDB Read buffer efficiency: 94.28% # powinno byc >99% -------- Performance Metrics -------- [!!] Slow queries: 2% (1K/52K) # powyzej 1% = problem [OK] Highest connection usage: 42% of max_connections [!!] Threads created per second: 12 (should be < 5) # thread cache za maly [OK] Table cache hit rate: 91% -------- Recommendations -------- General recommendations: Add skip-name-resolve to my.cnf innodb_buffer_pool_size (>= 3G) innodb_buffer_pool_instances = 4 thread_cache_size = 50 slow_query_log = 1
Kluczowe parametry i ich optymalizacja
| Parametr | Domyślna wartość | Rekomendacja (VPS 8 GB) | Efekt |
|---|---|---|---|
innodb_buffer_pool_size | 128 MB | 4-6 GB (70% RAM) | Więcej danych w RAM, mniej I/O dysku |
innodb_buffer_pool_instances | 1 | 4-8 (1 per GB pool) | Mniejszy contention na mutex pool |
max_connections | 151 | 300-500 | Więcej równoczesnych połączeń |
thread_cache_size | 9 | 50-100 | Mniej tworzenia nowych wątków (CPU) |
query_cache_type | 1 (ON) | 0 (OFF, read-heavy: 1) | Brak mutex contention przy write-heavy |
innodb_log_file_size | 48 MB | 256-512 MB | Mniej checkpoint flushes, lepszy write perf |
tmp_table_size / max_heap_table_size | 16 MB | 64-256 MB | Mniej temporary tables na dysku |
# /etc/mysql/mysql.conf.d/mysqld.cnf — przykład dla VPS 8 GB RAM # [mysqld] # --- InnoDB --- # innodb_buffer_pool_size = 4G # innodb_buffer_pool_instances = 4 # innodb_log_file_size = 256M # innodb_flush_log_at_trx_commit = 2 # 1=bezpieczne, 2=szybsze (ryzyko utraty 1s transakcji) # innodb_flush_method = O_DIRECT # # --- Polaczenia --- # max_connections = 300 # thread_cache_size = 50 # wait_timeout = 300 # interactive_timeout = 300 # # --- Tymczasowe tabele --- # tmp_table_size = 128M # max_heap_table_size = 128M # # --- Query cache (MySQL 5.7 - dla MySQL 8.0 usun) --- # query_cache_type = 0 # query_cache_size = 0 # # --- Slow query log --- # slow_query_log = 1 # slow_query_log_file = /var/log/mysql/slow.log # long_query_time = 1 # log_queries_not_using_indexes = 1 # # --- Siec --- # skip-name-resolve # bind-address = 127.0.0.1 # Zastosuj bez restartu (czesciowo) mysql -u root -p -e "SET GLOBAL innodb_buffer_pool_size = 4*1024*1024*1024;" mysql -u root -p -e "SET GLOBAL max_connections = 300;" # Pelny restart (dla innodb_log_file_size wymagany) sudo systemctl restart mysql
SHOW VARIABLES vs SHOW STATUS — diagnostyka
# SHOW VARIABLES — aktualna konfiguracja SHOW GLOBAL VARIABLES LIKE 'innodb_buffer_pool_size'; SHOW GLOBAL VARIABLES LIKE 'max_connections'; SHOW GLOBAL VARIABLES LIKE '%cache%'; # SHOW STATUS — statystyki runtime (od ostatniego restartu) SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_read%'; -- Innodb_buffer_pool_read_requests = total reads tried from buffer -- Innodb_buffer_pool_reads = reads that needed disk I/O -- Ratio hit: 1 - (Reads / Read_requests) powinno byc >99% SHOW GLOBAL STATUS LIKE 'Threads%'; -- Threads_created = ile watkow bylo tworzonych (powinno byc niskie) -- Threads_running = aktualnie aktywne watki SHOW GLOBAL STATUS LIKE 'Slow_queries'; SHOW GLOBAL STATUS LIKE 'Questions'; -- total queries SHOW GLOBAL STATUS LIKE 'Qcache%'; -- Qcache_hits / (Qcache_hits + Qcache_inserts) = skutecznosc query cache -- Uzyteczne widoki diagnostyczne (MySQL 8.0+ / MariaDB) SELECT * FROM sys.statement_analysis LIMIT 10; -- top slow queries SELECT * FROM sys.user_summary; -- aktywnosc per user SELECT * FROM information_schema.INNODB_BUFFER_POOL_STATS;
Weryfikacja po zmianach
# Zresetuj statystyki statusu
FLUSH STATUS;
# Poczekaj 24h, potem sprawdz skutecznosc bufora
SELECT
(1 - (
variable_value / (
SELECT variable_value
FROM information_schema.GLOBAL_STATUS
WHERE variable_name = 'Innodb_buffer_pool_read_requests'
)
)) * 100 AS buffer_hit_ratio_pct
FROM information_schema.GLOBAL_STATUS
WHERE variable_name = 'Innodb_buffer_pool_reads';
-- Cel: > 99%
# Uruchom MySQLTuner po 24-48h i porownaj z poprzednim raportem
perl mysqltuner.pl >> /tmp/after-tuning.txt
# Sprawdz slow query log
mysqldumpslow -s t -t 10 /var/log/mysql/slow.log
# -s t = sortuj po query_time
# -t 10 = top 10