Menu
Szybki wybór
Hosting Domeny VPS SSL Kalkulator Porównania FAQ
Aktywne kody
Wszystkie kody rabatowe

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

Najczęstsze pytania

Co to jest MySQLTuner i jak go uruchomić? +
MySQLTuner to skrypt Perl analizujący konfigurację i statystyki runtime MySQL/MariaDB. Pobiera dane z SHOW VARIABLES i SHOW STATUS, porównuje z best practices i generuje listę rekomendacji z priorytetami. Uruchamiasz go: wget http://mysqltuner.pl/ -O mysqltuner.pl && perl mysqltuner.pl --user root --pass HASLO. Zalecane uruchamianie po minimum 24 godzinach działania serwera — wtedy statystyki są reprezentatywne. Nie wymaga instalacji, działa na żywym serwerze.
Jak dobrać wartość innodb_buffer_pool_size? +
innodb_buffer_pool_size to najważniejszy parametr InnoDB — im większy, tym więcej danych trzymanych w RAM zamiast czytanych z dysku. Reguła: dla dedykowanego serwera MySQL ustaw 70-80% dostępnego RAM. Dla shared hostingu (MySQL współdzieli serwer z Apache/PHP) — 25-50%. Sprawdź: SHOW GLOBAL STATUS LIKE "Innodb_buffer_pool_read_requests" i "Innodb_buffer_pool_reads" — ratio powinien wynosić ponad 99% (mniej niż 1% trafień wymaga dysku).
Czym różni się SHOW VARIABLES od SHOW STATUS? +
SHOW VARIABLES pokazuje bieżącą konfigurację — wartości parametrów z my.cnf (innodb_buffer_pool_size, max_connections, query_cache_size). Są statyczne lub semi-statyczne (część można zmienić przez SET GLOBAL). SHOW STATUS pokazuje statystyki runtime — liczniki od ostatniego restartu (Connections, Queries, Threads_running, Innodb_buffer_pool_reads). Łącząc oba otrzymujesz pełny obraz: konfigurację + efektywność jej działania.
Kiedy wyłączyć query_cache w MySQL? +
Query cache (query_cache_type) warto wyłączyć gdy masz dużo zapisów (INSERT/UPDATE/DELETE) — każdy zapis do tabeli unieważnia wszystkie zapytania dla tej tabeli w cache, generując mutex contention. Dla write-heavy baz query cache pogarsza wydajność. MySQL 8.0 całkowicie usunął query cache. Dla MariaDB: ustaw query_cache_type=0 query_cache_size=0 jeśli Qcache_lowmem_prunes jest wysokie lub Qcache_hits / (Qcache_hits + Qcache_inserts) jest poniżej 20%.

Sprawdź oferty pasujące do tego scenariusza

Poniżej masz szybkie przejścia do ofert i stron z kodami rabatowymi tam, gdzie są dostępne.