Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Dlaczego InnoDB podaje oczywiście fałszywe informacje o wolnej przestrzeni?

(To odpowiada na niektóre pytania ukryte w komentarzach.)

Błędna „Wolna” przestrzeń obejmuje tylko całe bloki, bez wolnego miejsca wewnątrz bloków i wiele innych szczegółów.

Przypadek 1:Wszystkie tabele znajdują się w ibdata1 -- SHOW TABLE STATUS (lub równoważne zapytanie w information_schema pokaże ten sam Data_free wartość, a mianowicie ile jest wolne w ibdata1 . Ta przestrzeń może być ponownie wykorzystana przez dowolny stół. Trudno jest przywrócić przestrzeń systemowi operacyjnemu.

Przypadek 2:Wszystkie tabele to file_per_table -- Teraz każdy Data_free odnosi się do miejsca na stół. Oraz SUM() ma znaczenie. (ibdata1 nadal istnieje, ale nie zawiera żadnych prawdziwych tabel; jest wiele innych rzeczy, których potrzebuje InnoDB.)

Przypadek 3:Mieszanka -- Jeśli włączysz/wyłączysz file_per_table w różnych momentach, niektóre tabele będą znajdować się w ibdata1, niektóre będą miały własne obszary tabel.

Przypadek 4:UTWÓRZ PRZESTRZEŃ TABEL w wersji 5.7 -- Na przykład możesz mieć przestrzeń tabel dla każdej bazy danych.

Przypadek 5:Tabele podzielone na partycje -- Każda partycja działa jak stół.

Przypadek 6:8.0 -- Nadchodzi jeszcze więcej zmian.

Baza danych ==Katalog W drzewie katalogów MySQL każda baza danych może być widziana jako katalog systemu plików. W tym katalogu można zobaczyć zestaw plików dla każdej tabeli. .frm plik zawiera definicję tabeli. Jeśli plik .ibd plik istnieje, tabela została utworzona z file_per_table. Może to być najbardziej niezawodny sposób sprawdzenia, czy tabela jest plikiem_na_tabela. (8.0 będzie miał tutaj znaczące zmiany.)

Ile miejsca mogę ponownie wykorzystać ? Nie ma dobrej odpowiedzi. Zwykle wstawienie wiersza spowoduje znalezienie miejsca w bloku, do którego należy, a Data_free nie zmniejszy się. Ale jeśli były podziały bloków, Data_free może spaść o pewną wielokrotność 16KB (rozmiar bloku) lub 4MB ("rozmiar zasięgu" - a może jest to 8MB?). Ponadto losowe wstawienia prowadzą do tego, że bloki BTree są zapełnione średnio w około 69%.

Zmienianie innodb_file_per_table nie ma wpływu do następnego CREATE TABLE lub ALTER TABLE . A potem ma wpływ tylko na to, gdzie umieścić nowo utworzone/skopiowane dane+indeksy (ibdata1 lub .ibd). Nie zniszczy danych.

Duże stoły zwykle mają od 4 MB do 7 MB Data_free. Podczas obliczania liczby wierszy, które możesz dodać, nie planuj spadku wartości Data_free poniżej tego zakresu.

Avg_row_size powinno być przydatne. Ale czasami to (i wiersze) są słabo przybliżone. Ich iloczyn (Długość_danych) jest zawsze poprawny. Tak więc może dobrze oszacować liczbę wierszy do przejścia, zanim pobierzesz więcej miejsca z systemu operacyjnego:

(Data_free - 7M) / Avg_row_size

Zalecenia dotyczące przestrzeni tabel :Umieść „duże” tabele w file_per_table. Umieść „małe” tabele w ibdata1 lub przestrzeniach tabel specyficznych dla bazy danych (5.7). Przepraszamy, nie ma prostej rekomendacji na linii podziału między „dużym” i „malutkim”. Migracja tabeli jest niezręczna:SET global innodb_file_per_table = ...;; Wyloguj; zaloguj się (aby odebrać globalny); ALTER TABLE tbl ENGINE=InnoDB; . I koniecznie jest to pełna kopia tabeli.

(Zastrzeżenie :Pominąłem wiele szczegółów.)



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Połącz się z bazą danych MySQL w sieci lokalnej

  2. Szerokość pierwszego zapytania wyszukiwania w MySQL?

  3. Jak utworzyć tabelę mysql z domyślną sygnaturą czasową kolumny current_date?

  4. Sprawdź, czy rekord mySQL został dodany w ciągu ostatnich x sekund

  5. Długa liczba całkowita jest przekształcana po wstawieniu w krótszej kolumnie, nie jest obcinana. Czemu? Jaka jest formuła?