(Detta svarar på några av frågorna begravda i kommentarer.)
Felbenämning "Fritt" utrymme inkluderar bara hela block, inte extra utrymme inuti block, och många andra detaljer.
Fall 1:Alla tabeller finns i ibdata1
-- SHOW TABLE STATUS
(eller motsvarande fråga i information_schema
kommer att visa samma Data_free
värde, nämligen hur mycket som är ledigt i ibdata1
. Detta utrymme kan återanvändas av vilket bord som helst. Det är svårt att ge tillbaka utrymmet till operativsystemet.
Fall 2:Alla tabeller är file_per_table
-- Nu är varje Data_free
hänvisar till utrymmet för bordet. Och SUM()
är meningsfullt. (ibdata1 finns fortfarande, men den innehåller inga riktiga tabeller; det finns mycket annat som InnoDB behöver.)
Fall 3:Blandning -- Om du slår på/av file_per_table vid olika tidpunkter, kommer vissa tabeller att finnas i ibdata1, vissa kommer att ha sina egna tabellutrymmen.
Fall 4:SKAPA TABLESPACE i 5.7 -- Du kan till exempel ha ett tabellutrymme för varje databas.
Fall 5:PARTITIONERADE tabeller -- Varje partition fungerar som en tabell.
Fall 6:8.0 -- Ännu fler förändringar kommer.
Databas ==Katalog I MySQL:s katalogträd kan varje databas ses som en filsystemkatalog. Inom den katalogen kan man se en uppsättning filer för varje tabell. .frm
filen innehåller tabelldefinitionen. Om en .ibd
filen finns, tabellen skapades med file_per_table. Detta kan vara det mest tillförlitliga sättet att upptäcka om tabellen är file_per_table. (8.0 kommer att ha betydande förändringar här.)
Hur mycket utrymme kan jag återanvända ? Det finns inget bra svar. Vanligtvis kommer att infoga en rad hitta utrymme i blocket där den hör hemma, och Data_free kommer inte att krympa. Men om det fanns blockuppdelning(ar), kan Data_free sjunka med någon multipel av 16KB (blockstorleken) eller 4MB ("omfattningsstorleken" - eller kanske är det 8MB?). Dessutom leder slumpmässiga insättningar till att BTree-blocken är i genomsnitt cirka 69 % fulla.
Ändra innodb_file_per_table
har ingen effekt förrän nästa CREATE TABLE
eller ALTER TABLE
. Och då har det bara effekt på var du ska placera de nyskapade/kopierade data+indexen (ibdata1 eller .ibd). Det kommer inte att förstöra data.
Stora bord har vanligtvis 4MB till 7MB Data_free. När du beräknar hur många rader du kan lägga till, planera inte att Data_free hamnar under det intervallet.
Avg_row_size borde vara användbart. Men ibland är det (och rader) dåligt approximerade. Deras produkt (Data_length) är alltid korrekt. Så det här kan vara en bra uppskattning av "rader att gå innan du tar mer utrymme från OS:
(Data_free - 7M) / Avg_row_size
Rekommendationer för bordsutrymme :Sätt "stora" tabeller i file_per_table. Sätt "små" tabeller i ibdata1 eller databasspecifika tabellutrymmen (5.7). Tyvärr, ingen enkel rekommendation på skiljelinjen mellan "stor" och "liten". Och det är klumpigt att migrera en tabell:SET global innodb_file_per_table = ...;
; logga ut; logga in (för att hämta den globala); ALTER TABLE tbl ENGINE=InnoDB;
. Och det är nödvändigtvis en fullständig kopia av tabellen.
(Varning :Jag har utelämnat många detaljer.)