Powrót do bazy wiedzy

Baza Danych: MySQL bez Wąskich gardeł

Większość problemów z wydajnością Magento 2 ma źródło w bazie danych – niezoptymalizowane zapytania EAV, rozrośnięte tabele logów, brakujące indeksy. Dowiedz się, jak diagnozować, czyścić i konfigurować MySQL/MariaDB pod Magento 2.4.8.

EAV

model danych Magento – elastyczny, ale kosztowny bez optymalizacji

>2s

zapytanie trafia do Slow Query Log – czas na optymalizację

GB

tabele logów urastają do gigabajtów bez regularnego czyszczenia

Magento 2 przechowuje dane produktowe w modelu EAV (Entity-Attribute-Value) – każdy atrybut produktu to oddzielny wiersz w tabeli. To daje elastyczność, ale oznacza, że jedno zapytanie o produkt może angażować kilkadziesiąt tabel. Zrozumienie tej architektury i umiejętna konfiguracja MySQL to podstawa stabilnego i szybkiego sklepu.

Konfiguracja MySQL/MariaDB dla Magento 2

Domyślna konfiguracja MySQL nie jest zoptymalizowana pod Magento. Kluczowe parametry to rozmiar innodb_buffer_pool_size (powinien wynosić 70–80% dostępnej pamięci RAM) oraz wyłączenie query_cache, który w przypadku dużego zapisu jest źródłem konfliktów i spowalnia zapis.

Optymalna konfiguracja my.cnf dla Magento 2

Poniższe ustawienia są punktem startowym dla serwera z 16 GB RAM. Dostosuj innodb_buffer_pool_size do 70% dostępnej pamięci.

# /etc/mysql/conf.d/magento.cnf

[mysqld]

innodb_buffer_pool_size = 12G

innodb_buffer_pool_instances = 4

innodb_log_file_size = 512M

innodb_flush_log_at_trx_commit = 2

innodb_flush_method = O_DIRECT

query_cache_type = 0

query_cache_size = 0

max_connections = 300

tmp_table_size = 64M

max_heap_table_size = 64M

# Slow Query Log (loguj zapytania >2s):

slow_query_log = 1

slow_query_log_file = /var/log/mysql/slow.log

long_query_time = 2

Reindeksacja i zarządzanie indeksami

Magento 2 utrzymuje zestawy flat tables – zdenormalizowanych tabel, które przyspieszają odczyt danych produktowych i kategorii. Tryb Update on Schedule sprawia, że reindeksacja odbywa się przez cron, nie blokując frontendu. Tryb Update on Save jest niebezpieczny przy masowych importach.

Pro Tip: Reindeksacja – komendy i diagnostyka

Przed importem tysięcy produktów przełącz indeksery na tryb schedule, wykonaj import, a potem ręcznie uruchom reindeksację. Nigdy nie rób masowego importu z realtime – zablokujesz MySQL.

# Status i lista wszystkich indekserów:

php bin/magento indexer:status

# Przestaw wszystkie na tryb schedule:

php bin/magento indexer:set-mode schedule

# Reindeksacja wybranych (szybsza niż pełna):

php bin/magento indexer:reindex catalog_product_price catalog_product_flat

# Pełna reindeksacja:

php bin/magento indexer:reindex

# Sprawdź czy mview jest aktualny (brak zaległych zmian):

SELECT * FROM mview_state WHERE status != 'idle';

Czyszczenie logów – tabele, które rosną bez końca

Magento zapisuje ogromne ilości danych analitycznych i sesyjnych do bazy. Tabele takie jak report_event, customer_visitor, sales_order_grid czy quote (porzucone koszyki) mogą urosnąć do dziesiątek gigabajtów. Wbudowana komenda do czyszczenia to bin/magento sales:clean-orders, ale większość logów czyysicimy bezpośrednio przez SQL.

SQL do diagnozowania i czyszczenia logów

Przed czyszczeniem zawsze zrób backup. Poniższe zapytania pokazują wielkość tabel i bezpiecznie czyszczą logi starsze niż 90 dni.

# Wielkość tabel bazy danych Magento (TOP 20):

SELECT table_name,

  ROUND((data_length + index_length) / 1024 / 1024, 2) AS size_mb

FROM information_schema.tables

WHERE table_schema = DATABASE()

ORDER BY size_mb DESC LIMIT 20;

# Wyczyść porzucone koszyki starsze niż 90 dni:

DELETE FROM quote WHERE updated_at < DATE_SUB(NOW(), INTERVAL 90 DAY);

# Wyczyść tabele logów odwiedzin:

TRUNCATE TABLE customer_visitor;

TRUNCATE TABLE report_event;

TRUNCATE TABLE report_viewed_product_index;

# Wyczyść logi e-mail (zbiór wiadomości Magento):

DELETE FROM email_log WHERE created_at < DATE_SUB(NOW(), INTERVAL 90 DAY);

# Defragmentacja tabel po dużym DELETE:

OPTIMIZE TABLE quote, customer_visitor, report_event;

Slow Query Log i profilowanie zapytań

Slow Query Log

Włącz w my.cnf z long_query_time=2. Analizuj przez mysqldumpslow -s t slow.log | head -20.

EXPLAIN dla wolnych zapytań

Uruchom EXPLAIN SELECT ... dla podejrzanego zapytania. Kolumna type = ALL to full table scan – wymaga indeksu.

Magento Query Profiler

W trybie developer aktywuj Profiler: php bin/magento dev:query-log:enable. Zbiera logi SQL do pliku.

ProxySQL – connection pooling

Przy dużym ruchu ProxySQL pozwala na multiplexowanie połączeń do MySQL. Redukuje narzut CPU na otwieranie sesji.

Najczęstsze problemy z bazą danych w Magento

Deadlock przy zapisie zamówień

Wiele wątków próbuje zmodyfikować tę samą tabelę jednocześnie. Sprawdź: SHOW ENGINE INNODB STATUS\G w sekcji LATEST DETECTED DEADLOCK.

Tabela cataloginventory_stock_status poza sync

Stany magazynowe nie odpowiadają rzeczywistości. Uruchom: php bin/magento indexer:reindex cataloginventory_stock.

Przepełniona tabela quote

Miliony porzuconych koszyków spowalniają checkout. Zaplanuj cron z DELETE FROM quote WHERE updated_at < DATE_SUB(NOW(), INTERVAL 90 DAY).

Błąd "MySQL has gone away"

Za małe max_allowed_packet lub wait_timeout. Ustaw max_allowed_packet=64M i wait_timeout=28800 w my.cnf.

Reindeksacja blokuje front sklepu

Tryb realtime aktywny podczas importu. Przełącz na schedule i uruchamiaj reindeksację przez cron w godzinach nocnych.

Brak backupów przed migracją

Każde setup:upgrade lub ręczny ALTER mogą nieodwracalnie zmienić schemat. Zawsze: mysqldump ... > backup.sql przed każdą zmianą.

Backup i diagnostyka – komendy CLI

Regularne backupy i szybka diagnostyka to podstawa zarządzania bazą na produkcji.

# Backup bazy z kompresją (szybki):

mysqldump -u root -p --single-transaction --quick db_name | gzip > /backup/db_$(date +%F_%H%M).sql.gz

# Odtworzenie z backupu:

gunzip < /backup/db_2025-01-01_0300.sql.gz | mysql -u root -p db_name

# Sprawdź rozmiar bazy i tabel > 500MB:

SELECT table_name, ROUND((data_length+index_length)/1024/1024,0) mb

FROM information_schema.tables WHERE table_schema=DATABASE() AND (data_length+index_length) > 500*1024*1024

ORDER BY mb DESC;

# Aktualny status połączeń MySQL:

SHOW STATUS LIKE 'Threads_connected';

SHOW STATUS LIKE 'Max_used_connections';

# Analiza najwolniejszych zapytań z Slow Log:

mysqldumpslow -s t -t 20 /var/log/mysql/slow.log

Baza danych to serce Magento 2 – każde złe zapytanie SQL kosztuje Cię milisekundy na każdym żądaniu HTTP. W Mage24.pl każdy serwer VPS dostarczamy z preskonfigurowanym MariaDB 10.11 dopasowanym do Magento 2.4.8, z włączonym Slow Query Log i automatycznym backupem dobowym.

Baza danych działa wolno lub rośnie bez kontroli?

Przeprowadzimy audyt bazy danych, zoptymalizujemy konfigurację MySQL i wyczyścimy tabele logów – bez ryzyka utraty danych.

Zoptymalizuj Bazę Danych