sql >> Databáze >  >> RDS >> Mysql

Proč InnoDB poskytuje zjevně falešné informace o volném prostoru

(Toto odpovídá na některé otázky uložené v komentářích.)

Nesprávné označení "Volné" místo zahrnuje pouze celé bloky, nikoli volné místo uvnitř bloků a mnoho dalších detailů.

Případ 1:Všechny tabulky jsou v ibdata1 -- SHOW TABLE STATUS (nebo ekvivalentní dotaz do information_schema zobrazí stejné Data_free hodnotu, konkrétně kolik je zdarma v ibdata1 . Tento prostor může být znovu použit libovolnou tabulkou. Je těžké vrátit prostor operačnímu systému.

Případ 2:Všechny tabulky jsou file_per_table -- Nyní každý Data_free odkazuje na prostor pro stůl. A SUM() je smysluplné. (ibdata1 stále existuje, ale neobsahuje žádné skutečné tabulky; existuje spousta dalších věcí, které InnoDB potřebuje.)

Případ 3:Směs -- Pokud v různých časech zapnete/vypnete soubor_na_tabulku, některé tabulky budou v ibdata1, některé budou mít své vlastní tabulkové prostory.

Případ 4:VYTVOŘTE TABLESPACE ve verzi 5.7 -- Například můžete mít tabulkový prostor pro každou databázi.

Případ 5:Rozdělené stoly -- Každý oddíl funguje jako tabulka.

Případ 6:8.0 -- Přichází ještě více změn.

Databáze ==Adresář V adresářovém stromu MySQL lze každou databázi vidět jako adresář souborového systému. V tomto adresáři lze vidět nějakou sadu souborů pro každou tabulku. .frm soubor obsahuje definici tabulky. Pokud .ibd soubor existuje, byla tabulka vytvořena pomocí file_per_table. Toto může být nejspolehlivější způsob, jak zjistit, zda je tabulka file_per_table. (8.0 zde bude mít významné změny.)

Kolik místa mohu znovu využít ? Neexistuje žádná dobrá odpověď. Vložením řádku se obvykle najde místo v bloku, kam patří, a Data_free se nezmenší. Ale pokud by došlo k rozdělení bloků, Data_free může klesnout o několik násobků 16 KB (velikost bloku) nebo 4 MB ("velikost rozsahu" - nebo možná je to 8 MB?). Náhodné vkládání také vede k tomu, že bloky BTree jsou v průměru zaplněny asi na 69 %.

Změna innodb_file_per_table nemá žádný účinek až do příštího CREATE TABLE nebo ALTER TABLE . A pak to má vliv pouze na to, kam umístit nově vytvořená/zkopírovaná data+indexy (ibdata1 nebo .ibd). Nezničí data.

Velké stoly obvykle mají 4 MB až 7 MB Data_free. Při počítání, kolik řádků můžete přidat, neplánujte pokles Data_free pod tento rozsah.

Průměrná_velikost_řádku by měl být užitečný. Ale někdy se to (a řádky) špatně aproximuje. Jejich produkt (Data_length) je vždy správný. Takže toto možná být dobrým odhadem „řádků, které je třeba projít, než ukořistíte více místa z OS:

(Data_free - 7M) / Avg_row_size

Doporučení pro tabulkový prostor :Vložte 'velké' tabulky do file_per_table. Vložte „malé“ tabulky do ibdata1 nebo do tabulkových prostorů specifických pro databázi (5.7). Je nám líto, ale žádné jednoduché doporučení na dělicí čáře mezi „velkým“ a „malým“. A je nemotorné migrovat tabulku:SET global innodb_file_per_table = ...;; odhlásit se; přihlášení (pro vyzvednutí globálního); ALTER TABLE tbl ENGINE=InnoDB; . A je to nezbytně úplná kopie tabulky.

(Upozornění :Mnoho detailů jsem vynechal.)



  1. EM12c nyní umožňuje DB12c pro úložiště

  2. MySQL Workbench Error 1175 I s příkazem Where

  3. Vícenásobná hlavní replikace na jednoho slave v Mysql

  4. Jak extrahovat pouze sloupce, které mají nenulové hodnoty v mysql a php?