Dlaczego moje „używane bajty objętości” stale rosną w klastrze Amazon Aurora?

11

Mam klaster Aurora DB Amazon (AWS) i każdego dnia jego liczba [Billed] Volume Bytes Usedrośnie.

VolumeBytes Wykorzystano metrykę CloudWatch w czasie

Sprawdziłem rozmiar wszystkich moich tabel (we wszystkich bazach danych w tym klastrze), używając INFORMATION_SCHEMA.TABLEStabeli:

SELECT ROUND(SUM(data_length)/1024/1024/1024) AS data_in_gb, ROUND(SUM(index_length)/1024/1024/1024) AS index_in_gb, ROUND(SUM(data_free)/1024/1024/1024) AS free_in_gb FROM INFORMATION_SCHEMA.TABLES;
+------------+-------------+------------+
| data_in_gb | index_in_gb | free_in_gb |
+------------+-------------+------------+
| 30         | 4           | 19         |
+------------+-------------+------------+

Razem: 53 GB

Więc dlaczego naliczam obecnie prawie 75 GB?

Rozumiem, że przydzielonej przestrzeni nigdy nie można zwolnić, w taki sam sposób, w jaki pliki ibdata na zwykłym serwerze MySQL nigdy nie mogą się zmniejszyć; Nie przeszkadza mi to. Jest to udokumentowane i dopuszczalne.

Mój problem polega na tym, że każdego dnia zwiększa się moje miejsce. I jestem pewien, że NIE używam tymczasowo 75 GB miejsca. Gdybym miał zrobić coś takiego, zrozumiałbym. To tak, jakby przestrzeń dyskowa, którą zwalniam, usuwając wiersze z moich tabel lub usuwając tabele, a nawet usuwając bazy danych, nigdy nie jest ponownie używana.

Wielokrotnie kontaktowałem się z obsługą AWS (premium) i nigdy nie byłem w stanie uzyskać dobrego wyjaśnienia, dlaczego tak jest.
Otrzymałem sugestie, aby uruchomić OPTIMIZE TABLEna tabelach, na których jest dużo free_space(na INFORMATION_SCHEMA.TABLEStabelę), lub sprawdzić długość historii InnoDB, aby upewnić się, że usunięte dane nie są nadal przechowywane w segmencie wycofywania (ref: MVCC ) i zrestartuj instancję (y), aby upewnić się, że segment wycofania został opróżniony.
Żaden z nich nie pomógł.

Guillaume Boudreau
źródło

Odpowiedzi:

19

W grze jest wiele rzeczy ...

  1. Każda tabela jest przechowywana we własnym obszarze tabel

    Domyślnie grupa parametrów dla klastrów Aurora (o nazwie default.aurora5.6) określa innodb_file_per_table = ON. Oznacza to, że każda tabela jest przechowywana w osobnym pliku w klastrze pamięci Aurora. Za pomocą tego zapytania możesz sprawdzić, który obszar tabel jest używany dla każdej ze swoich tabel:

    SELECT name, space FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES;

    Uwaga: nie próbowałem zmienić innodb_file_per_tablena OFF. Może to pomogłoby ...?

  2. Zwolnione miejsce po usunięciu obszarów tabel NIE jest ponownie wykorzystywane

    Cytując wsparcie premium AWS:

    Ze względu na unikalną konstrukcję silnika Aurora Storage w celu zwiększenia jego wydajności i odporności na awarie, Aurora nie ma funkcji defragmentacji obszarów tabel dla plików w taki sam sposób jak standardowe MySQL.

    Obecnie Aurora niestety nie ma możliwości zmniejszenia obszarów tabel, jak ma to miejsce w przypadku standardowego MySQL, a całe podzielone miejsce jest obciążane, ponieważ jest uwzględnione w VolumeBytesUsed.
    Powodem, dla którego Aurora nie może odzyskać miejsca po upuszczonej tabeli w taki sam sposób jak standardowy MySQL, jest to, że dane dla tabeli są przechowywane w zupełnie inny sposób niż standardowa baza danych MySQL z jednym woluminem pamięci.

    Jeśli upuścisz tabelę lub wiersz w Aurora, przestrzeń nie zostanie odzyskana w objętości klastra Auroras z powodu tego skomplikowanego projektu.
    Ta niezdolność do odzyskania niewielkiej ilości miejsca do przechowywania jest poświęceniem, aby uzyskać dodatkowy wzrost wydajności wolumenu pamięci klastrowej Auroras i znacznie lepszą odporność na awarie Aurora.

    Ale jest jakiś niejasny sposób na ponowne wykorzystanie części tej zmarnowanej przestrzeni ...
    Znowu zacytuj wsparcie premium AWS:

    Gdy całkowity zestaw danych przekroczy określony rozmiar (około 160 GB), możesz zacząć odzyskiwać miejsce w blokach 160 GB do ponownego wykorzystania, np. Jeśli masz 400 GB w woluminie klastra Aurora i DROP 160 GB lub więcej tabel Aurora może wtedy automatycznie ponownie wykorzystaj 160 GB danych. Odzyskanie tego miejsca może być jednak powolne.
    Przyczyną dużej ilości danych wymaganych do natychmiastowego uwolnienia jest unikalny projekt Auroras jako silnika DB w skali przedsiębiorstwa, w przeciwieństwie do standardowego MySQL, którego nie można używać w tej skali.

  3. OPTYMALIZUJ TABELĘ jest zła!

    Ponieważ Aurora jest oparta na MySQL 5.6, OPTIMIZE TABLEjest mapowana ALTER TABLE ... FORCE, co powoduje przebudowanie tabeli w celu aktualizacji statystyk indeksu i zwolnienia nieużywanego miejsca w indeksie klastrowym. W efekcie innodb_file_per_table = ONoznacza to, że uruchomienie OPTIMIZE TABLEtworzy nowy plik obszaru tabel i usuwa stary. Ponieważ usunięcie pliku obszaru tabel nie zwalnia używanej pamięci, oznacza to, że OPTIMIZE TABLEzawsze zapewni więcej pamięci. Auć!

    Patrz: https://dev.mysql.com/doc/refman/5.6/en/optimize-table.html#optimize-table-innodb-details

  4. Korzystanie z tabel tymczasowych

    Domyślnie grupa parametrów dla instancji Aurora (nazwanych default.aurora5.6) określa default_tmp_storage_engine = InnoDB. Oznacza to, że za każdym razem, gdy tworzę TEMPORARYtabelę, jest ona przechowywana wraz ze wszystkimi moimi zwykłymi tabelami w klastrze pamięci Aurora. Oznacza to, że udostępniono nowe miejsce do przechowywania tych tabel, zwiększając w ten sposób całkowitą objętość użytych woluminów.
    Rozwiązanie tego problemu jest dość proste: zmień default_tmp_storage_enginewartość parametru na MyISAM. Zmusi to Aurorę do utworzenia TEMPORARYtabel w lokalnej pamięci instancji.
    Uwaga: pamięć lokalna instancji jest ograniczona; zobacz Free Local Storagemetrykę w CloudWatch, aby zobaczyć, ile miejsca mają twoje wystąpienia. Większe (bardziej kosztowne) instancje mają więcej pamięci lokalnej.

    Ref: jeszcze nie; obecna dokumentacja Amazon Aurora nie wspomina o tym. Poprosiłem zespół wsparcia AWS o aktualizację dokumentacji i zaktualizuję odpowiedź, jeśli zrobią to raz.

Guillaume Boudreau
źródło
1
To świetna odpowiedź, a oto kilka głównych zastrzeżeń. Cieszę się, że to widziałem.
ceejayoz
Tak samo. Zauważyłem, że jeden serwer DB miał pojemność do 300 GB, dla bazy danych o wielkości 54 GB zgłoszonej przez MySQL ... jeśli miejsce nigdy nie zostanie odzyskane, jest to dobry przykład tego, co dzieje się, gdy masz wiele często zapisywanych tabel ( np. tabele dziennika, tabele indeksu itp.).
geerlingguy