sql >> Database >  >> RDS >> Mysql

Waarom geeft InnoDB duidelijk valse informatie over vrije ruimte?

(Dit is het beantwoorden van enkele van de vragen die begraven zijn in Opmerkingen.)

Onjuiste benaming "Vrije" ruimte omvat alleen hele blokken, geen vrije ruimte in blokken en vele andere details.

Case 1:Alle tabellen staan ​​in ibdata1 -- SHOW TABLE STATUS (of de equivalente zoekopdracht in information_schema toont dezelfde Data_free waarde, namelijk hoeveel gratis is in ibdata1 . Deze ruimte kan door elke tafel opnieuw worden gebruikt. Het is moeilijk om de ruimte terug te geven aan het besturingssysteem.

Case 2:Alle tabellen zijn file_per_table -- Nu elke Data_free verwijst naar de ruimte voor de tafel. En de SUM() is zinvol. (ibdata1 bestaat nog steeds, maar het bevat geen echte tabellen; er zijn veel andere dingen die InnoDB nodig heeft.)

Geval 3:Mengsel -- Als u file_per_table op verschillende tijdstippen in- of uitschakelt, zullen sommige tabellen in ibdata1 zijn, sommige zullen hun eigen tablespaces hebben.

Case 4:CREER TAFELRUIMTE in 5.7 -- U kunt bijvoorbeeld een tabelruimte hebben voor elke database.

Case 5:GEPARTITIONEERDE tabellen -- Elke partitie werkt als een tabel.

Casus 6:8.0 -- Er komen nog meer veranderingen aan.

Database ==Directory In de directorystructuur van MySQL kan elke database worden gezien als een bestandssysteemdirectory. Binnen die map kan een aantal bestanden voor elke tabel worden bekeken. De .frm bestand bevat de tabeldefinitie. Als een .ibd bestand bestaat, is de tabel gemaakt met file_per_table. Dit is misschien wel de meest betrouwbare manier om te ontdekken of de tabel file_per_table is. (8.0 zal hier significante veranderingen ondergaan.)

Hoeveel ruimte kan ik hergebruiken ? Er is geen goed antwoord. Gewoonlijk zal het invoegen van een rij ruimte vinden in het blok waar het thuishoort, en Data_free zal niet krimpen. Maar als er bloksplitsing(en) waren, kan Data_free een veelvoud van 16 KB (de blokgrootte) of 4 MB (de "omvang" - of misschien is het 8 MB?). Willekeurige invoegingen leiden er ook toe dat Btree-blokken gemiddeld ongeveer 69% vol zijn.

Wijzigen innodb_file_per_table heeft geen effect tot de volgende CREATE TABLE of ALTER TABLE . En dan heeft het alleen effect op waar de nieuw gemaakte/gekopieerde data+indexen (ibdata1 of .ibd) moeten worden geplaatst. Het zal geen gegevens vernietigen.

Grote tafels hebben meestal 4 MB tot 7 MB aan Data_free. Wanneer u berekent hoeveel rijen u kunt toevoegen, moet u niet van plan zijn om Data_free onder dat bereik te laten vallen.

Gem_row_size handig zou moeten zijn. Maar soms worden het (en rijen) slecht benaderd. Hun product (Data_length) is altijd correct. Dus dit misschien een goede schatting zijn van "te gaan rijen voordat u meer ruimte van het besturingssysteem pakt:

(Data_free - 7M) / Avg_row_size

Aanbevelingen voor tafelruimte :Zet 'grote' tabellen in file_per_table. Zet 'kleine' tabellen in ibdata1 of database-specifieke tablespaces (5.7). Sorry, geen eenvoudige aanbeveling over de scheidslijn tussen 'groot' en 'klein'. En het is onhandig om een ​​tabel te migreren:SET global innodb_file_per_table = ...;; uitloggen; login (om de globale op te halen); ALTER TABLE tbl ENGINE=InnoDB; . En het is noodzakelijkerwijs een volledige kopie van de tabel.

(Voorbehoud :Ik heb veel details weggelaten.)



  1. Vouw JSON met onbekende sleutels uit naar rijen met MySQL JSON_TABLE

  2. Wat is er met (nolock) in SQL Server?

  3. Wat te doen als u geen fouten in het gedeelde objectbestand krijgt wanneer u de OCI-versie Easysoft Oracle ODBC-stuurprogramma gebruikt?

  4. Splits de begrensde tekenreekswaarde in rijen