 Autor: [Piotr Wasilewski](/autorzy/piotr-wasilewski) Architekt rozwiązań chmurowych · Zweryfikowano Kwiecień 2026

1.  [Strona główna](/) ›
2.  [Baza wiedzy](/baza-wiedzy/) ›
3.  MySQLTuner — optymalizacja MySQL

# 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.

Contabo

VPS z dużym RAM — więcej bufora InnoDB, mniej odczytów z dysku

MySQL Tuning

[Aktywuj rabat →](/out/contabo)

#Reklama · link partnerski

[Zobacz kod rabatowy →](/kody-rabatowe/contabo)

Mikr.us

Tani VPS do testowania konfiguracji MySQL przed produkcją

Dev/Test

[Aktywuj rabat →](/out/mikrus)

#Reklama · link partnerski

[Zobacz kod rabatowy →](/kody-rabatowe/mikrus)

Zenbox

Hosting z zarządzanym MySQL — bez ręcznego tuningu

Managed MySQL

[Aktywuj rabat →](/out/zenbox)

#Reklama · link partnerski

[Zobacz kod rabatowy →](/kody-rabatowe/zenbox)

## Powiązane strony

-   [MySQL slow query log — diagnostyka wolnych zapytań](/baza-wiedzy/mysql-slow-query-log)
-   [MySQL Replication — konfiguracja master-slave](/baza-wiedzy/mysql-replication-master-slave)
-   [MariaDB vs MySQL — różnice i migracja](/baza-wiedzy/mariadb-vs-mysql-hosting)
-   [Bezpieczeństwo VPS — checklist](/baza-wiedzy/bezpieczenstwo-vps-checklist)
-   [Wszystkie artykuły](/baza-wiedzy/)