Kompresja stron w MariaDB: oszczędność miejsca na dysku przy minimalnym spadku wydajności

Strona MariaDB Kompresja zmniejsza fizyczne zapotrzebowanie na pamięć poprzez kompresję stron InnoDB przed zapisaniem ich na nośniku danych, co pozwala na zauważalne zmniejszenie ilości operacji wejścia/wyjścia. Pokażę, jak zaoszczędzić pamięć i utrzymać niskie opóźnienia, jakie są warunki wstępne oraz które ustawienia przynoszą największe korzyści w praktyce.

Punkty centralne

Te zwięzłe punkty wprowadzają w najważniejsze zagadnienia.

  • Strona po stronie Kompresja zmniejsza zapotrzebowanie na miejsce i obciążenie wejścia/wyjścia.
  • Nieskompresowany Pula buforów ogranicza obciążenie procesora w pamięci RAM.
  • Elastyczność Aktywacja dla każdej tabeli za pomocą PAGE_COMPRESSED.
  • system plików- Obsługa funkcji „Sparse/Hole Punching” jest obowiązkowa.
  • Wybór algorytmu reguluje częstotliwość, opóźnienie i obciążenie procesora.

Jak technicznie działa kompresja stron w InnoDB

Kompresuję każdą stronę InnoDB tuż przed zapisaniem jej na dysk, dzięki czemu przestrzeń tabel zajmuje tylko faktycznie skompresowaną liczbę bajtów, a system plików oznacza wolne obszary jako „sparse”. W Pula buforów Nadal przechowuję strony w postaci nieskompresowanej, co pozwala ograniczyć obciążenie procesora w pamięci operacyjnej i zapewnia szybki dostęp do często odczytywanych danych. Domyślnie strony InnoDB mają rozmiar 16 KB, jednak po kompresji rozmiar zapisanych bloków jest zmienny i mniejszy, co pozwala zaoszczędzić dużo miejsca, zwłaszcza w przypadku pól tekstowych lub JSON. Podczas odczytu dekompresuję stronę bezpośrednio po załadowaniu do pamięci RAM, czyli dokładnie na granicy operacji wejścia/wyjścia, gdzie oszczędność podczas transferu ma największe znaczenie. W ten sposób przenoszę obciążenie z I/O w odniesieniu do procesora, ale tylko w tych miejscach, w których jest to uzasadnione.

Kompresja stron a klasyczna kompresja tabel InnoDB

Klasyczna kompresja opiera się na ustawieniu ROW_FORMAT=COMPRESSED wraz z KEY_BLOCK_SIZE, co tworzy stały, skompresowany format strony i powoduje dodatkowe obciążenie związane z podejmowaniem decyzji podczas zapisu lub aktualizacji. Ja preferuję Strona Kompresja, ponieważ pozostaje elastyczna: jeśli kompresja się nie powiedzie, InnoDB może zapisać stronę w postaci nieskompresowanej, bez zmiany całego formatu pliku. Pula buforów nadal pracuje z nieskompresowanymi stronami o rozmiarze 16 KB, co przyspiesza trafienia w pamięci podręcznej i upraszcza ścieżki procesora. W przypadku typowych obciążeń OLTP, charakteryzujących się dużą liczbą operacji wstawiania i umiarkowaną liczbą aktualizacji, kompresja stron zapewnia lepszą równowagę między oszczędnością miejsca a opóźnieniem. W rezultacie często uzyskuję odczuwalną korzyść w zakresie operacji wejścia/wyjścia bez dużego obciążenia przy każdym Aktualizacja do ryzyka.

Wymagania i konfiguracja podstawowa

Aby skorzystać z kompresji stron, wymagam obecności InnoDB i włączam innodb_file_per_table, tak aby każda tabela korzystała z własnej przestrzeni tabel. Kluczowe znaczenie ma system plików: musi on obsługiwać pliki rozrzedzone oraz funkcję „hole-punching”, co jest możliwe w systemach ext4 i XFS oraz zazwyczaj dostępne w nowoczesnych woluminach chmurowych. Aby wybrać algorytm, ustawiam parametr innodb_compression_algorithm, zazwyczaj wybierając zlib, lz4 lub lzo, w zależności od pożądanej szybkości i profilu procesora. Kto odpowiednio dobierze warstwę pamięci masowej, zyska korzyści w postaci kompaktowego Porównanie systemów plików biorąc przy tym pod uwagę również opcje sterowników i głośności. W ten sposób powstaje Konfiguracja, która pozwala zaoszczędzić miejsce, zmniejsza liczbę operacji wejścia/wyjścia i działa niezawodnie.

Aktywacja na poziomie tabeli

Włączam kompresję stron dla poszczególnych tabel po odpowiednim skonfigurowaniu zmiennych globalnych, aby precyzyjnie adresować właśnie te rekordy danych, które przynoszą największe korzyści. W przypadku nowych tabel ustawiam te opcje bezpośrednio w DDL, natomiast w przypadku istniejących tabel zmianę wprowadza polecenie ALTER TABLE poprzez ponowne zapisanie danych. Poziom kompresji definiuję za pomocą PAGE_COMPRESSION_LEVEL, a zachowanie zależy od używanego Algorytm . Ponieważ zmiana ta wymaga czasu, planuję okna serwisowe i sprawdzam zapotrzebowanie na miejsce z kompresją i bez niej na podstawie rzeczywistych fragmentów danych. W ten sposób sprawdzam Wydatki i wynik bez niespodzianek.

CREATE TABLE log_entries (
    id BIGINT UNSIGNED PRIMARY KEY,
    created_at DATETIME NOT NULL,
    level VARCHAR(20),
    message TEXT
) ENGINE=InnoDB
  PAGE_COMPRESSED=1
  PAGE_COMPRESSION_LEVEL=6;

ALTER TABLE log_entries
  ENGINE=InnoDB,
  PAGE_COMPRESSED=1;

Oszczędność pamięci w praktyce

Im bardziej jednorodne i bogate w tekst są dane, tym lepszy efekt daje Kompresja; Tabele logów i raportów zazwyczaj przynoszą wyraźne korzyści. W typowych obciążeniach często obserwuję zmniejszenie zajętej pamięci o 40–60 % przy użyciu zlib, podczas gdy lz4 w wielu przypadkach zapewnia oszczędność rzędu 30–50 %, pozostawiając przy tym większą przepustowość. W przypadku silnie rozproszonych danych binarnych korzyści są mniejsze, ale i tam ilość operacji we/wy oraz koszty często ulegają zauważalnemu zmniejszeniu. Zawsze przeprowadzam testy na środowisku stagingowym przy użyciu migawek produkcyjnych, aby uzyskać miarodajne wskaźniki i wykryć szczyty opóźnień. Wynik: mniej danych na nośniku, krótszy czas transferu, lepsza Skalowanie.

Wydajność: jak prawidłowo ocenić stosunek operacji wejścia/wyjścia do obciążenia procesora

Najpierw sprawdzam, czy wąskie gardło znajduje się na nośniku danych, czy na CPU , ponieważ od tego zależy wybór metody kompresji. W środowiskach ograniczonych przez operacje wejścia/wyjścia (I/O) ilości odczytów i zapisów znacznie spadają, co powoduje wzrost efektywnej wydajności – często przy dodatkowym obciążeniu wynoszącym zaledwie 5–10 % w porównaniu z tabelami nieskompresowanymi przy zastosowaniu szybkich algorytmów. Systemy ograniczone wydajnością procesora (CPU) zyskują na zastosowaniu algorytmów lz4 lub lzo, które działają bardzo szybko i osiągają jedynie nieznacznie niższe współczynniki kompresji. Dodatkowo zwracam uwagę na Bufor podwójnego zapisu, ponieważ wpływa on na zachowanie podczas zapisu i wraz z kompresją stron kształtuje charakterystykę operacji wejścia/wyjścia. Ponieważ pula buforów pozostaje nieskompresowana, częste trafienia w pamięci podręcznej mają znikomy wpływ na Opóźnienie od.

Wybór algorytmu i poziom kompresji

Decyduję Algorytm-Rozważam wybór algorytmu na podstawie wzorców danych, szybkości odczytu/zapisu oraz dostępnej mocy obliczeniowej procesora, zamiast kierować się wyłącznie współczynnikiem kompresji. Zlib często zapewnia największą oszczędność miejsca przy umiarkowanym obciążeniu procesora, podczas gdy lz4/lzo wyróżniają się niskim opóźnieniem. Z LZMA lub bzip2 korzystam przede wszystkim w przypadku archiwów lub rzadko modyfikowanych tabel, ponieważ obciążenie procesora jest w tym przypadku większe. Poziom kompresji (PAGE_COMPRESSION_LEVEL) reguluje stosunek szybkości do nakładu obliczeniowego, jednak przy średnich poziomach przyrost korzyści maleje. Krótka seria pomiarów z wykorzystaniem rzeczywistego zbioru danych pozwala szybko znaleźć najlepsze rozwiązanie. Poziom.

Algorytm Typowa stawka Koszty procesora Przydatność Uwagi
zlib 40–60 % Średni Wiele tabel OLTP/raportowych Dobry Równowaga z szybkości/opóźnienia
lz4 30–50 % Niski Wysokie wymagania dotyczące przepustowości Bardzo szybko Dekompresja
lzo 30–50 % Niski Zadania wymagające intensywnego pisania Niskie opóźnienie przy wstawianiu
lzma 50–70 % Wysoki Archiwum/nieaktualne dane W przypadku rzadkich Zmiany
bzip2 50–70 % Wysoki Wybrane historie Powoli, dobra oglądalność

Monitorowanie i wskaźniki – wszystko pod kontrolą

Mierzę przepustowość, opóźnienie, obciążenie procesora oraz Pula buforów-Wskaźnik trafień, ponieważ tylko całościowy obraz pokazuje rzeczywisty efekt. Spadek ilości operacji wejścia/wyjścia przy niezmiennym lub lepszym opóźnieniu wskazuje na trafiony wybór konfiguracji. Jeśli obciążenie procesora wzrośnie powyżej zdrowego poziomu, sprawdzam algorytm i poziom kompresji, a w razie potrzeby przechodzę na lz4. Ponadto zwracam uwagę na rozmiar dziennika powtórzeń (redo log) oraz zachowanie punktów kontrolnych (checkpointów), ponieważ oba te czynniki mają wpływ na profil zapisu. W dłuższej perspektywie dostrzegam trendy i mogę proaktywnie reagować na zmiany Obciążenia reagować.

Dokładne planowanie tworzenia kopii zapasowych i konserwacji

Pełne i przyrostowe kopie zapasowe plików zyskują dzięki mniejszej ilość danych, ponieważ kopiowanych jest mniej bajtów, podczas gdy zrzuty logiczne zazwyczaj zachowują swój rozmiar. Testuję czasy przywracania na rzeczywistych danych, aby móc porównać uzyskaną oszczędność miejsca z rzeczywistym czasem przywracania. Dokumentuję zmiany w algorytmie lub poziomie i sprawdzam zgodność narzędzi do tworzenia kopii zapasowych z używaną wersją MariaDB. Ponadto weryfikuję integralność danych po dużych operacjach ALTER TABLE, zwłaszcza gdy wiele tabel zostało przełączonych na kompresję stron. W ten sposób zachowuje się Czas ponownego uruchomienia przewidywalna, a strategia zabezpieczeń niezawodna.

Zrozumienie systemu plików i warstwy pamięci masowej

Aby pliki typu sparse działały, system plików wymaga Dziurkowanie, co jest dostępne w systemach plików ext4 i XFS i jest powszechnie stosowane w konfiguracjach hostingowych. Zwracam uwagę na opcje montowania oraz głębokość kolejki, ponieważ mają one duży wpływ na charakterystykę operacji wejścia/wyjścia. W przypadku systemu plików ext4 sprawdzam na przykład interwały commitów i tryby dziennika oraz biorę pod uwagę wpływ mechanizmu garbage collection na dyski SSD/NVMe. Przyglądam się odpowiednim Opcje systemu plików ext4 pomaga dostosować efekty kompresji stron do właściwości systemu plików. W ten sposób wykorzystuję fizyczny Przechowywanie skutecznie i zapobiega skutkom ubocznym.

Praktyczny przewodnik wprowadzający

Zaczynam od środowiska testowego i kopiuję reprezentatywne dane produkcyjne, aby uzyskać pierwsze wyniki pomiarów dotyczące wskaźnika, opóźnienia i Przepustowość . Następnie włączam kompresję stron przede wszystkim w przypadku dużych tabel lub archiwów, z których korzysta się głównie w trybie odczytu i które rzadko są aktualizowane. Wyniki oceniam na podstawie jasnych wskaźników i porównuję je ze stanem początkowym, zanim przystąpię do modyfikacji kolejnych tabel. Wczesna komunikacja z zespołami aplikacyjnymi pozwala uniknąć niespodzianek podczas okien konserwacyjnych i zapewnia jasne oczekiwania. Po każdym rozszerzeniu dostosowuję poziom i Algorytm , aż oszczędność pamięci i opóźnienie znajdą się w docelowym przedziale.

Połączenie z innymi optymalizacjami

Dobre wskaźniki zmniejszają liczbę odczytanych stron, dlatego sprawdzam Zakres indeksu oraz kardynalności. Przejrzysto sformułowane zapytania, odpowiednie połączenia (joins) oraz celowe wykorzystanie EXPLAIN zmniejszają operacje wejścia/wyjścia (I/O) i utrzymują wysoki wskaźnik trafień w pamięci podręcznej. Wystarczająco duża pula buforów zapobiega niepotrzebnemu odczytywaniu danych z dysku i sprawia, że obciążenie związane z kompresją w hotsecie jest praktycznie niewidoczne. Jeśli chodzi o sprzęt, dyski SSD i NVMe opłacają się dzięki wysokiej liczbie operacji IOPS i niskim opóźnieniom, co wzmacnia zalety kompresji stron. Podsumowując, kompresja współgra z projektowaniem zapytań, pracą z indeksami oraz Rozbudowa pamięci łączy się, tworząc w ten sposób zoptymalizowaną ścieżkę przesyłania danych.

Zgodność, wersje i ograniczenia

Śledzę, w jakich środowiskach obsługiwana jest kompresja stron i gdzie leżą jej ograniczenia. W popularnych systemach plików Linuksa, takich jak ext4 i XFS, funkcja „hole-punching” działa stabilnie. ZFS zachowuje się inaczej: ponieważ funkcja ta nie jest tam dostępna w pełnym zakresie, w przypadku ZFS raczej stawiam na natywny Włączam kompresję ZFS i rezygnuję z kompresji stron. W konfiguracjach kontenerowych z OverlayFS najchętniej montuję katalog danych jako montowanie typu bind z hosta, aby funkcje „punching” i pliki rozrzedzone działały niezawodnie. Ponadto nie łączę kompresji stron z szyfrowaniem tabel InnoDB na poziomie plików: szyfrowanie sprawia, że dane stają się w dużej mierze losowe dla algorytmów kompresji, a czasami blokuje również funkcję „punching”. Jeśli potrzebne są obie te funkcje, należy zastosować szyfrowanie woluminu lub systemu plików na poziomie niższym niż InnoDB.

Jeśli chodzi o rozmiar strony InnoDB (innodb_page_size), zazwyczaj pozostaję przy wartości 16K. Mniejsze rozmiary stron mogą utrudniać kompresję i zwiększać obciążenie związane z zarządzaniem. Kompresja stron nie ma wpływu na tabele tymczasowe ani tabele typu MEMORY/robocze – korzyści dotyczą wyłącznie danej przestrzeni tabel .ibd.

Aktywacja, dezaktywacja i odbudowa bez niespodzianek

Zmiana za pomocą polecenia ALTER TABLE zawsze powoduje przebudowę tabeli. Dlatego planuję:

  • Okno serwisowe z jasno określonymi umowami SLA i wystarczającą przestrzenią dyskową na kopię tymczasową.
  • Wstępna analiza za pomocą EXPLAIN dla polecenia ALTER w celu sprawdzenia oczekiwanego sposobu działania (INPLACE/COPY, poziom blokady).
  • Opcjonalna strategia przetwarzania partiami: najpierw duże tabele, które rzadko ulegają zmianom, następnie średnie, a na końcu tabele o dużym obciążeniu – o ile w ogóle.

Aby wyłączyć tę funkcję, postępuję symetrycznie i ustawiam PAGE_COMPRESSED=0. Następnie wykonuję polecenie OPTIMIZE TABLE lub ponownie ALTER-Rebuild, aby przestrzeń tabelowa znów była zapisywana bez luk, a fizyczne zużycie miejsca było realistycznie odzwierciedlone.

Wczytywanie zbiorcze, aktualizacje na gorąco i defragmentacja

W przypadku dużych zbiorów danych ładuję je albo bezpośrednio w postaci skompresowanej, gdy zasoby wejścia/wyjścia są ograniczone, albo przyspieszam import, ładując dane w postaci nieskompresowanej, a następnie zmieniając format za pomocą polecenia ALTER TABLE na PAGE_COMPRESSED. Następnie operacja odbudowy wymusza optymalny układ z maksymalną efektywnością kompresji. W przypadku tabel z bardzo dużą liczbą aktualizacji na miejscu planuję regularne przepisywanie (OPTIMIZE TABLE lub rollover partycji), ponieważ powtarzające się zmiany mogą z czasem zmniejszyć korzyści wynikające z kompresji. W przypadku kolumn BLOB/TEXT stawiam na nowoczesny format wiersza (np. DYNAMIC), aby duże dane poza stroną były efektywnie obsługiwane, a sąsiedztwo stron nie powiększało się niepotrzebnie.

Sprawdzenie i udokumentowanie skuteczności

Sprawdzam, czy kompresja stron działa, za pomocą prostych poleceń systemowych i widoków MariaDB:

# Porównanie rozmiaru pozornego z liczbą zajętych bloków
ls -ls --block-size=1 *.ibd
du -h --apparent-size *.ibd
du -h *.ibd

# Sprawdzanie stopnia fragmentacji (punching) dla poszczególnych plików
filefrag -v your_table.ibd | tail -n +1

# W MariaDB: Sprawdzanie statusu tabeli i opcji DDL
SHOW TABLE STATUS LIKE 'log_entries'\G
SHOW CREATE TABLE log_entries\G

Rozmiar pozorny (ls) pozostaje zgodny z logiczną objętością danych, podczas gdy pokazuje się faktycznie zajęte bloki. Wyraźna różnica wskazuje na prawidłowe działanie funkcji „hole-punching”. Koreluję ten pomiar z wskaźnikami wejścia/wyjścia (odczyty/zapisy na sekundę, głębokość kolejki, opóźnienie) oraz obciążeniem procesora, aby ocenić ogólny efekt.

Szczegóły dotyczące kopii zapasowej: prawidłowe tworzenie i przywracanie kopii zapasowych typu „sparse”

Aby kopie zapasowe uwzględniały oszczędność miejsca, zwracam uwagę na obsługę struktury rozproszonej (sparse) w narzędziach. Podczas kopiowania plików fizycznych używam odpowiednich opcji, aby luki nie były „wypełniane“:

# Kopiowanie z zachowaniem obszarów rozrzedzonych
cp --sparse=always source.ibd dest.ibd
rsync -S --progress source.ibd dest.ibd
tar --sparse -cvf backup.tar /var/lib/mysql/datadir

# Sprawdzanie, czy plik docelowy nadal ma strukturę rozrzedzoną
du -h dest.ibd
ls -ls dest.ibd

W przypadku kopii zapasowych typu snapshot (np. na poziomie urządzeń blokowych) oszczędności mają różne znaczenie w zależności od dostawcy. W przypadku zrzutów logicznych (mysqldump, mariadb-dump) rozmiar eksportu praktycznie się nie zmienia, jednak czas przywracania ulega skróceniu, jeśli podczas późniejszej odbudowy ponownie włączona zostanie kompresja stron, co zmniejsza ilość operacji wejścia/wyjścia podczas odbudowy.

Replikacja, dostępność wysokiej niezawodności (HA) i wdrażanie zmian w środowisku operacyjnym

Kompresja stron działa w sposób przezroczysty dla replikacji i dzienników binarnych, ponieważ replikowane są zmiany SQL, a nie skompresowane strony. Zazwyczaj najpierw wdrażam zmiany DDL na replikach i obserwuję opóźnienia oraz operacje wejścia/wyjścia, zanim dokonam zmian na serwerze głównym. W przypadku topologii wieloźródłowych lub kaskadowych zwracam uwagę, aby wszędzie ustawiono odpowiedni algorytm (innodb_compression_algorithm), tak aby identyczne polecenia DDL powodowały takie samo zachowanie. W przypadku wdrożeń bez przestojów łączę zmianę z planami przełączenia/przejęcia w przypadku awarii.

Zaawansowane dostosowywanie: profile wejścia/wyjścia i punkty kontrolne

Ponieważ kompresja zmienia liczbę i rozmiar bloków do zapisu, dostosowuję parametry wejścia/wyjścia InnoDB do nowego profilu. Realistyczna wartość innodb_io_capacity (oraz *_max) pomaga tworzyć poprawne punkty kontrolne bez nagłych skoków w częstotliwości operacji flush. Sprawdzam, czy bufor podwójnego zapisu jest dostosowany do nowej charakterystyki zapisu, oraz monitoruję stosunek brudnych stron do częstotliwości fsync. Na urządzeniach o wysokim stopniu równoległości (NVMe) skaluję wątki zapisu oraz głębokość kolejki urządzenia blokowego, tak aby mniejsza ilość danych przełożyła się na rzeczywistą redukcję opóźnień.

Rozwiązywanie problemów i typowe trudności

  • Szczytowe obciążenie procesora po aktywacji: Zmienić algorytm na lz4/lzo lub umiarkowanie obniżyć wartość PAGE_COMPRESSION_LEVEL, zwiększyć rozmiar zestawów najczęściej używanych danych (hotsets) w puli buforów.
  • Wskaźnik I/O spada, ale opóźnienie ulega wahaniom: Sprawdzić punkty kontrolne i wskaźnik brudnych stron; zbyt małe dzienniki powtórzeń powodują częste operacje opróżniania.
  • Nieoczekiwanie niewielka oszczędność miejsca: Sprawdzić strukturę danych (wiele pól binarnych/losowych), wymusić przebudowę, przeanalizować wzorce BLOB/TEXT, w razie potrzeby przejść na zlib.
  • Nie ma to wpływu na rozmiar pliku: Sprawdzić obsługę funkcji „hole-punching“ przez system plików, unikać warstwy kontenerowej, nie „usuwaj rzadkości” z kopii rzadkiej.
  • Tabele, o których tak dużo się mówi: Stosować kompresję stron w sposób selektywny; rozważyć alternatywne rozwiązania (kompresować wyłącznie tabele archiwalne i dzienniki).

Praktyczne przykłady konfiguracji

Aby zapewnić dobry początek, uważam, że globalna konfiguracja powinna być zwięzła i łatwa do kontrolowania:

[mysqld]
innodb_file_per_table=1
innodb_compression_algorithm=zlib   # lub lz4/lzo w zależności od profilu
# dostosować pozostałe parametry wejścia/wyjścia do platformy
# innodb_io_capacity=...
# innodb_io_capacity_max=...

Dla każdej tabeli definiuję kompresję w sposób jawny, aby uniknąć niepożądanych skutków ubocznych. Po dużych importach lub wielu aktualizacjach celowo stosuję polecenie OPTIMIZE TABLE, aby ponownie skalibrować luki i zredukować fragmentację powstałą z upływem czasu.

Krótkie podsumowanie

Kompresja stron InnoDB zauważalnie zmniejsza zużycie pamięci i odciąża I/O do procesora bez zmiany puli buforów. Dobrze dobrane algorytmy, takie jak lz4 lub zlib, zapewniają w wielu obciążeniach oszczędność rzędu 30–60 %, a opóźnienia pozostają w dopuszczalnym zakresie. Kluczowe znaczenie mają system plików z funkcją „hole-punching”, opcja innodb_file_per_table oraz prawidłowa aktywacja na poziomie tabeli. Kto przeprowadza testy na prawdziwych danych, wdraża monitorowanie oraz precyzyjnie dostosowuje poziom i algorytm, osiąga trwale niskie koszty przy niezawodnej Wydajność. W ten sposób oszczędzasz miejsce, zapewniasz sprawność działania systemów i zyskujesz rezerwy na rosnące zbiory danych.

Artykuły bieżące