2009-03-11 5 views
22

Ho letto più volte che dopo aver eliminato una riga in una tabella InnoDB in MySQL, il suo spazio non viene riutilizzato, quindi se si inseriscono molti INSERT in una tabella e quindi si eliminano periodicamente alcune righe, la tabella utilizzerà sempre più spazio su disco, come se le righe non venissero cancellate del tutto.Lo spazio occupato dalle righe cancellate viene riutilizzato?

Recentemente mi è stato detto che lo spazio occupato dalle righe eliminate viene riutilizzato ma solo dopo che alcune transazioni sono complete e anche allora - non completamente. Ora sono confuso.

Qualcuno può darmi un senso per me? Devo fare un sacco di INSERT in una tabella InnoDB e poi ogni X minuti ho bisogno di CANCELLARE i record che sono più vecchi di Y minuti. Ho un problema di tavolo InnoDB in continua crescita qui, o è paranoia?

risposta

30

Si tratta di paranoia :)

DB non crescono in termini di dimensioni inutilmente, ma per lo spazio problemi di prestazioni non viene liberato neanche.

Quello che hai sentito molto probabilmente è che se elimini record che non viene restituito lo spazio al sistema operativo. Invece, viene mantenuto come spazio vuoto per il DB da riutilizzare in seguito.

Questo perché:

  • DB ha bisogno di avere un po 'di spazio su HD per salvare dei suoi dati; se non ha spazio, all'inizio riserva uno spazio vuoto.
  • Quando si inserisce una nuova riga, viene utilizzato un pezzo di tale spazio.
  • Quando si esaurisce lo spazio disponibile, viene riservato un nuovo blocco e così via.
  • Ora, quando si eliminano alcune righe, al fine di evitare la prenotazione di un numero sempre maggiore di blocchi, il suo spazio viene mantenuto libero ma mai restituito al sistema operativo, quindi è possibile utilizzarlo nuovamente in seguito senza la necessità di riservare nuovo blocchi.

Come si può vedere, lo spazio è riutilizzati, ma mai restituita. Questo è il punto chiave della tua domanda.

+0

Seb, puoi fornire un collegamento ufficiale per questo? –

+0

@GautamSomani Questa è una risposta di 6 anni, non ho collegamenti disponibili ma potrei trovare questo: https://dev.mysql.com/doc/refman/5.1/en/optimize-table.html: ' Le righe eliminate vengono mantenute in un elenco collegato e le successive operazioni INSERT riutilizzano le vecchie posizioni di riga. È possibile utilizzare OPTIMIZE TABLE per recuperare lo spazio non utilizzato e deframmentare il file di dati. Dopo ampie modifiche a una tabella, questa affermazione potrebbe anche migliorare le prestazioni delle affermazioni che utilizzano la tabella, a volte in modo significativo. Sono sicuro che se utilizzi google sarai in grado di trovare maggiori informazioni ufficiali a riguardo. – Seb

2

in innodb, non esiste un modo pratico di liberare lo spazio.

  • uso per ogni tabella di file ibdata, che vi vi permetterà di eliminare record di copiare i dati in una nuova tabella ed eliminare vecchi tavolo, recuperando in tal modo i record.
  • utilizzare mysqldump e interi lotti di per pulire l'intero server . Controllare seguente:
    http://dev.mysql.com/doc/refman/5.0/en/adding-and-removing.html

Tutti questi metodi diventano impraticabili quando si utilizza le tabelle enormi (nel mio caso sono più che 250 GB) e si deve tenerli eliminazione di record di prestazioni migliori.

Si dovrà pensare seriamente, se si dispone di sufficiente spazio sul vostro hard disk per eseguire una delle funzioni di cui sopra (nel mio caso non credo 1TB è sufficiente per tutte queste azioni)

con tavolo Innotab (e mysql stesso) l'opzione è abbastanza limitata se ha dimensioni di database serie.

+0

Ci sono soluzioni a questo, con le nuove versioni di InnoDB e la configurazione corretta ('innodb_file_per_table'): http://dev.mysql.com/doc/innodb-plugin/1.0/en/innodb-other-changes-truncate. html http://dev.mysql.com/doc/refman/5.5/en/innodb-truncate-table-reclaim-space.html – Blaisorblade