sql >> Database teknologi >  >> RDS >> Mysql

Hvorfor giver InnoDB åbenlyst falsk information om ledig plads

(Dette besvarer nogle af spørgsmålene, der er begravet i kommentarer.)

Forkert betegnelse "Fri" plads omfatter kun hele blokke, ikke ekstra plads inde i blokke og mange andre detaljer.

Case 1:Alle tabeller er i ibdata1 -- SHOW TABLE STATUS (eller den tilsvarende forespørgsel i information_schema vil vise den samme Data_free værdi, nemlig hvor meget der er gratis i ibdata1 . Denne plads kan genbruges af ethvert bord. Det er svært at give plads tilbage til OS.

Case 2:Alle tabeller er file_per_table -- Nu hver Data_free henviser til pladsen til bordet. Og SUM() er meningsfuld. (ibdata1 eksisterer stadig, men det indeholder ingen rigtige tabeller; der er mange andre ting, som InnoDB har brug for.)

Case 3:Blanding -- Hvis du slår file_per_table til/fra på forskellige tidspunkter, vil nogle tabeller være i ibdata1, nogle vil have deres egne tablespaces.

Case 4:OPRET TABLESPACE i 5.7 -- For eksempel kan du have et tablespace for hver database.

Tilfælde 5:OPDELTE tabeller -- Hver partition fungerer som en tabel.

Case 6:8.0 -- Endnu flere ændringer er på vej.

Database ==Directory I MySQL's mappetræ kan hver database ses som en filsystemmappe. Inden for denne mappe kan der ses nogle sæt filer for hver tabel. .frm filen indeholder tabeldefinitionen. Hvis en .ibd fil eksisterer, blev tabellen oprettet med file_per_table. Dette kan være den mest pålidelige måde at finde ud af, om tabellen er file_per_table. (8.0 vil have væsentlige ændringer her.)

Hvor meget plads kan jeg genbruge ? Der er ikke noget godt svar. Normalt vil indsættelse af en række finde plads i blokken, hvor den hører hjemme, og Data_free vil ikke krympe. Men hvis der var blokopdeling(er), kan Data_free falde med et eller andet multiplum af 16KB (blokstørrelsen) eller 4MB ("udstrækningsstørrelsen" - eller måske er det 8MB?). Tilfældige indsættelser fører også til, at BTree-blokke i gennemsnit er omkring 69 % fyldte.

Ændring af innodb_file_per_table har ingen effekt før den næste CREATE TABLE eller ALTER TABLE . Og så har det kun betydning for, hvor de nyoprettede/kopierede data+indekser (ibdata1 eller .ibd) skal placeres. Det vil ikke ødelægge data.

Store borde har normalt 4MB til 7MB Data_free. Når du beregner, hvor mange rækker du kan tilføje, skal du ikke planlægge, at Data_free falder under dette interval.

Gns._rækkestørrelse burde være nyttig. Men nogle gange er det (og rækker) dårligt tilnærmet. Deres produkt (Data_length) er altid korrekt. Så det måske være et godt estimat for "rækker, der skal gå, før du får mere plads fra OS:

(Data_free - 7M) / Avg_row_size

Tablespace-anbefalinger :Sæt 'store' tabeller i file_per_table. Sæt 'små' tabeller i ibdata1 eller databasespecifikke tablespaces (5.7). Beklager, ingen simpel anbefaling om skillelinjen mellem 'stor' og 'lille'. Og det er klodset at migrere en tabel:SET global innodb_file_per_table = ...;; Log ud; login (for at hente den globale); ALTER TABLE tbl ENGINE=InnoDB; . Og det er nødvendigvis en fuld kopi af tabellen.

(Advarsel :Jeg har udeladt mange detaljer.)



  1. Hvad er det største ID-nummer, som autoincrement kan producere i mysql

  2. Google Data Studio - Cloud SQL For MySQL Connector Fejl

  3. Indlæs xml i mysql-tabel med element

  4. MySQL Dynamic Query Statement i Python