MySQL InnoDB non rilascia spazio su disco dopo aver eliminato le righe di dati dalla tabella


140

Ho una tabella MySQL che utilizza il motore di archiviazione InnoDB; contiene circa 2 milioni di righe di dati. Quando ho eliminato le righe di dati dalla tabella, non è stato rilasciato spazio su disco allocato. Né la dimensione del file ibdata1 si è ridotta dopo aver eseguito il optimize tablecomando.

Esiste un modo per recuperare spazio su disco da MySQL?

Sono in una brutta situazione; questa applicazione è in esecuzione in circa 50 posizioni diverse e ora il problema di spazio su disco insufficiente appare in quasi tutte.


dopo aver eseguito anche il comando di ottimizzazione, la dimensione del file ibdata1 non si è ridotta.
Sumit Deo,

4
Penso che quel commento sarebbe meglio modificato nella tua risposta, e poi cancellato
Ben Millwood,

possibile duplicato di stackoverflow.com/q/11751792/82114 (ma questo è stato qui per primo)
FlipMcF

1
"Né la dimensione del file ibdata1 si è ridotta dopo aver eseguito il comando optimize table" perché innodb_file_per_tableè disattivata. La buona notizia è che questa opzione è ondi default nelle ultime versioni di MySQL.
Ragioniere

Eseguo "ottimizza tabella xxxx" e viene visualizzato il messaggio "La tabella non supporta l'ottimizzazione, facendo invece ricreare + analizza". Dopo aver eseguito "du -h / var / lib / mysql" su una shell, ho visto che il database si era ridotto.
user1097111

Risposte:


137

MySQL non riduce le dimensioni di ibdata1. Mai. Anche se si utilizza optimize tableper liberare lo spazio utilizzato dai record eliminati, verrà riutilizzato in seguito.

Un'alternativa è configurare il server da utilizzare innodb_file_per_table, ma ciò richiederà un backup, l'eliminazione del database e il ripristino. Il lato positivo è che il file .ibd per la tabella viene ridotto dopo un optimize table.


4
Documenti MySQL 5.5 sullo stato della modalità file per tabella InnoDB "Per sfruttare le funzionalità di [file per tabella] InnoDB per una tabella esistente, è possibile attivare l'impostazione file per tabella ed eseguire ALTER TABLE t ENGINE=INNODBsulla tabella esistente. " Ciò implica che è possibile attivare questa funzione, "convertire" le tabelle esistenti per utilizzare un file InnoDB separato con il comando ALTER TABLE, quindi OTTIMIZZARE la tabella per ridurne le dimensioni. Tuttavia, una volta terminato, dovresti capire come eliminare il (enorme) file InnoDB di origine ...
Josh,

9
Immagino che questo tecnicamente risponda alla domanda, ma mi aspetto che la maggior parte delle persone che cercano questo argomento stiano cercando il processo effettivo per ridurre / recuperare lo spazio, che questa risposta non fornisce.
Manachi,

@Manachi Il processo è "configura il server in modo che utilizzi innodb_file_per_table", "esegua il backup" del server, "elimina i database", arresta il mysql, elimina .ibd, avvia il server e ripristina i database. Con MySQL 5.5+ puoi usare ciò che Josh ha detto e, dopo aver cambiato tutte le tabelle, fermare il server, eliminare l'enorme .ibd e avviarlo di nuovo.
Leonel Martins,

39

Ho avuto lo stesso problema anche io.

Quello che succede è che anche se si elimina il database, innodb non rilascerà ancora spazio su disco. Ho dovuto esportare, arrestare mysql, rimuovere i file manualmente, avviare mysql, creare database e utenti, quindi importare. Grazie a dio avevo solo 200 MB di file, ma risparmiava 250 GB di file innodb.

Fallire in base alla progettazione.


10
sì, è sicuramente un fallimento.
trusktr,

1
MySql 5.5 ha lo stesso problema: ho eseguito "ottimizza tabella" per ridurre l'utilizzo del disco di una tabella da 28 GB. L'operazione ha probabilmente tentato di creare un clone ottimizzato di quello originale e, facendo ciò, ha esaurito tutto lo spazio sulla partizione. Ora "ottimizza tabella" non è riuscito e non ho più spazio sulla partizione anche dopo aver eliminato l'intero db ... molto deludente.
basilikode,

1
E più di 4 anni dopo ho riscontrato lo stesso problema con MySQL. MS SQL è simile: dba.stackexchange.com/questions/47310/…
Csaba Toth,

24

Se non si utilizza innodb_file_per_table , è possibile recuperare spazio su disco, ma è piuttosto noioso e richiede tempi di inattività significativi.

La Come è abbastanza in profondità - ma ho incollato la parte rilevante di seguito.

Assicurati di conservare anche una copia del tuo schema nel dump.

Attualmente, non è possibile rimuovere un file di dati dal tablespace di sistema. Per ridurre le dimensioni del tablespace di sistema, utilizzare questa procedura:

Usa mysqldump per scaricare tutte le tue tabelle InnoDB.

Ferma il server.

Rimuovere tutti i file del tablespace esistenti, inclusi i file ibdata e ib_log. Se desideri conservare una copia di backup delle informazioni, copia tutti i file ib * in un'altra posizione prima di rimuovere i file nell'installazione di MySQL.

Rimuovere tutti i file .frm per le tabelle InnoDB.

Configurare un nuovo tablespace.

Riavvia il server.

Importa i file di dump.


1
Grazie per aver incluso i passaggi - afaict il link 'how to' non contiene più queste informazioni
aland

3

Dieci anni dopo e ho avuto lo stesso problema. L'ho risolto nel modo seguente:

  • Ho ottimizzato tutti i database rimasti.
  • Ho riavviato il mio computer e MySQL sui servizi (Windows + r -> services.msc)

Questo è tutto :)


1

Un altro modo per risolvere il problema del recupero dello spazio è, Creare più partizioni all'interno della tabella - Basato su intervallo, Partizioni basate sul valore e semplicemente rilasciare / troncare la partizione per recuperare lo spazio, che rilascerà lo spazio utilizzato da interi dati memorizzati nella partizione particolare.

Ci saranno alcune modifiche necessarie nello schema delle tabelle quando si introduce il partizionamento per la tabella come: chiavi uniche, indici per includere la colonna di partizione ecc.


0

L'anno scorso ho anche affrontato lo stesso problema sulla versione mysql5.7 e ibdata1 occupava 150 Gb. così ho aggiunto annulla i tablespace

Esegui backup Mysqldump
Interrompi servizio mysql
Rimuovi tutti i dati dalla directory dati
Aggiungi sotto annulla il parametro tablespace nell'attuale my.cnf

 #undo tablespace
  innodb_undo_directory =  /var/lib/mysql/
  innodb_rollback_segments = 128 
  innodb_undo_tablespaces = 3
  innodb_undo_logs = 128  
  innodb_max_undo_log_size=1G
  innodb_undo_log_truncate = ON

Avviare il
backup mysqldump dell'archivio servizi mysql

Problema risolto !!


-1

Esistono diversi modi per recuperare spazio su disco dopo aver eliminato i dati dalla tabella per il motore Inodb di MySQL

Se non si utilizza innodb_file_per_table dall'inizio, scaricare tutti i dati, eliminare tutti i file, ricreare il database e importare nuovamente i dati è l'unico modo (controllare le risposte di FlipMcF sopra)

Se stai usando innodb_file_per_table, puoi provare

  1. Se riesci a eliminare tutti i dati, il comando tronca eliminerà i dati e recupererà spazio su disco per te.
  2. Il comando Alter table elimina e ricrea la tabella in modo da poter recuperare spazio su disco. Quindi dopo l'eliminazione dei dati, esegui alter table che non cambiano nulla per rilasciare hardisk (cioè: la tabella TBL_A ha charset uf8, dopo l'eliminazione dei dati esegui ALTER TABLE TBL_A charset utf8 -> questo comando non cambia nulla dalla tua tabella ma fa sì che mysql ricrea la tua tabella e riacquisti spazio sul disco
  3. Crea TBL_B come TBL_A. Inserisci i dati selezionati che desideri conservare da TBL_A a TBL_B. Rilasciare TBL_A e rinominare TBL_B in TBL_A. In questo modo è molto efficace se TBL_A e i dati che devono essere eliminati sono grandi (il comando di eliminazione in MySQL innodb ha prestazioni pessime)
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.