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

Perché InnoDB fornisce informazioni sullo spazio libero ovviamente false

(Questo sta rispondendo ad alcune delle domande sepolte nei Commenti.)

Nome improprio Lo spazio "libero" include solo interi blocchi, non spazio libero all'interno dei blocchi e molti altri dettagli.

Caso 1:Tutte le tabelle sono in ibdata1 -- SHOW TABLE STATUS (o la query equivalente in information_schema mostrerà lo stesso Data_free valore, ovvero quanto è gratuito in ibdata1 . Questo spazio può essere riutilizzato da qualsiasi tavolo. È difficile restituire spazio al sistema operativo.

Caso 2:Tutte le tabelle sono file_per_table -- Ora ogni Data_free si riferisce allo spazio per il tavolo. E il SUM() è significativo. (ibdata1 esiste ancora, ma non contiene tabelle reali; ci sono molte altre cose di cui InnoDB ha bisogno.)

Caso 3:Miscela -- Se attivi/disattiva file_per_table in vari momenti, alcune tabelle saranno in ibdata1, altre avranno i propri tablespace.

Caso 4:CREA TABLESPACE in 5.7 -- Ad esempio, puoi avere uno spazio tabella per ogni database.

Caso 5:Tabelle PARTIZIONATE -- Ogni partizione agisce come una tabella.

Caso 6:8,0 -- Stanno arrivando ancora altri cambiamenti.

Database ==Directory Nell'albero delle directory di MySQL ogni database può essere visto come una directory del filesystem. All'interno di quella directory si possono vedere alcuni set di file per ogni tabella. Il .frm file contiene la definizione della tabella. Se un .ibd file esiste, la tabella è stata creata con file_per_table. Questo potrebbe essere il modo più affidabile per scoprire se la tabella è file_per_table. (8.0 avrà modifiche significative qui.)

Quanto spazio posso riutilizzare ? Non c'è una buona risposta. Di solito l'inserimento di una riga troverà spazio nel blocco a cui appartiene e Data_free non si ridurrà. Ma, se ci sono stati suddivisi in blocchi, Data_free può diminuire di alcuni multipli di 16 KB (la dimensione del blocco) o 4 MB (la "dimensione dell'estensione" - o forse è 8 MB?). Inoltre, gli inserimenti casuali fanno sì che i blocchi Btree siano, in media, pieni per circa il 69%.

Cambiare innodb_file_per_table non ha effetto fino al prossimo CREATE TABLE o ALTER TABLE . E poi ha effetto solo su dove mettere i dati+indici appena creati/copiati (ibdata1 o .ibd). Non distruggerà i dati.

Tavoli grandi di solito hanno da 4 MB a 7 MB di Data_free. Quando calcoli quante righe puoi aggiungere, non pensare che Data_free scenda al di sotto di tale intervallo.

Media_riga_dimensione dovrebbe essere utile. Ma a volte (e Rows) sono poco approssimati. Il loro prodotto (Data_length) è sempre corretto. Quindi, questo potrebbe essere una buona stima di "righe da percorrere prima di prendere più spazio dal sistema operativo:

(Data_free - 7M) / Avg_row_size

Suggerimenti per i tavoli :Metti le tabelle "grandi" in file_per_table. Metti le tabelle "minuscole" in ibdata1 o in tablespace specifici del database (5.7). Siamo spiacenti, nessuna semplice raccomandazione sulla linea di demarcazione tra "grande" e "minuscolo". Ed è goffo migrare una tabella:SET global innodb_file_per_table = ...;; disconnettersi; login (per prendere il globale); ALTER TABLE tbl ENGINE=InnoDB; . Ed è necessariamente una copia completa della tabella.

(Avvertimento :Ho omesso molti dettagli.)