Riduzione delle dimensioni del file del database MongoDB

Ho un database MongoDB che era una volta di grandi dimensioni (> 3 GB). Da allora, i documenti sono stati cancellati e mi aspettavo che la dimensione dei file del database diminuisse di conseguenza.

Ma poiché MongoDB mantiene lo spazio allocato, i file sono ancora grandi.

Ho letto qua e là che il comando admin mongod --repair è usato per liberare lo spazio inutilizzato, ma non ho abbastanza spazio sul disco per eseguire questo comando.

Sai come posso liberare lo spazio inutilizzato?

AGGIORNAMENTO: con il comando compact e WiredTiger sembra che lo spazio su disco aggiuntivo verrà effettivamente rilasciato al sistema operativo .


AGGIORNAMENTO: a partire dalla v1.9 + c’è un comando compact .

Questo comando eseguirà una compattazione “in-line”. Avrà ancora bisogno di spazio aggiuntivo, ma non tanto.


MongoDB comprime i file per:

  • copiare i file in una nuova posizione
  • scorrere i documenti e riordinarli / risolverli
  • sostituendo i file originali con i nuovi file

Puoi eseguire questa “compressione” eseguendo mongod --repair o collegandoti direttamente ed eseguendo db.repairDatabase() .

In entrambi i casi è necessario lo spazio da qualche parte per copiare i file. Ora non so perché non hai abbastanza spazio per eseguire un comprimere, tuttavia, hai alcune opzioni se hai un altro computer con più spazio.

  1. Esportare il database su un altro computer con Mongo installato (usando mongoexport ) e quindi è ansible importare lo stesso database (usando mongoimport ). Ciò comporterà un nuovo database che è più compresso. Ora puoi fermare il mongod originale sostituirlo con i nuovi file di database e sei a posto.
  2. Interrompe il mongod corrente e copia i file del database su un computer più grande ed esegui la riparazione su quel computer. È quindi ansible spostare i nuovi file di database sul computer originale.

Al momento non esiste un buon modo per “compattare sul posto” usando Mongo. E Mongo può sicuramente succhiare molto spazio.

La migliore strategia in questo momento per la compattazione è eseguire una configurazione Master-Slave. Puoi quindi compattare lo schiavo, lasciarlo recuperare e cambiarlo. Lo so ancora un po ‘peloso. Forse il team Mongo avrà una migliore compattazione sul posto, ma non credo che sia in cima alla lista. Lo spazio su disco è attualmente considerato a buon mercato (e di solito è).

Ho avuto lo stesso problema, e risolto semplicemente facendo questo alla riga di comando:

 mongodump -d databasename echo 'db.dropDatabase()' | mongo databasename mongorestore dump/databasename 

Sembra che Mongo v1.9 + abbia il supporto per il compact in atto!

 > db.runCommand( { compact : 'mycollectionname' } ) 

Vedi i documenti qui: http://docs.mongodb.org/manual/reference/command/compact/

“Diversamente da repairDatabase, il comando compatto non richiede il doppio spazio su disco per fare il suo lavoro, richiede una piccola quantità di spazio aggiuntivo durante il lavoro e inoltre è più veloce.”

Se è necessario eseguire una riparazione completa, utilizzare l’opzione di repairpath . Puntalo su un disco con più spazio disponibile.

Ad esempio, sul mio Mac ho usato:

 mongod --config /usr/local/etc/mongod.conf --repair --repairpath /Volumes/X/mongo_repair 

Aggiornamento: per il ticket del server principale Per MongoDB 4266 , potrebbe essere necessario aggiungere --nojournal per evitare un errore:

 mongod --config /usr/local/etc/mongod.conf --repair --repairpath /Volumes/X/mongo_repair --nojournal 

Compatta tutte le raccolte nel database corrente

 db.getCollectionNames().forEach(function (collectionName) { print('Compacting: ' + collectionName); db.runCommand({ compact: collectionName }); }); 

A partire dalla versione 2.8 di Mongo, puoi usare la compressione . Avrai 3 livelli di compressione con il motore WiredTiger, mmap (che di default in 2.6 non fornisce la compressione):

  • Nessuna
  • scattante (per impostazione predefinita)
  • zlib

Ecco un esempio di quanto spazio sarai in grado di salvare per 16 GB di dati:

inserisci la descrizione dell'immagine qui

i dati sono presi da questo articolo.

Abbiamo bisogno di risolvere 2 modi, basati su StorageEngine.

1. Motore MMAP ():

comando: db.repairDatabase ()

NOTA: repairDatabase richiede spazio libero su disco pari alla dimensione del set di dati corrente più 2 gigabyte. Se il volume che contiene dbpath manca di spazio sufficiente, è ansible montare un volume separato e utilizzarlo per la riparazione. Quando si monta un volume separato per repairDatabase, è necessario eseguire repairDatabase dalla riga di comando e utilizzare l’opzione –repairpath per specificare la cartella in cui archiviare i file di riparazione temporanei. es .: la dimensione del DB di immagini è di 120 GB significa, (120 * 2) +2 = 242 GB di spazio su disco richiesto.

in un altro modo in cui esegui la raccolta, comando: db.runCommand ({compact: ‘collectionName’})

2. WiredTiger: si è risolto automaticamente da solo.

Se una grande quantità di dati viene eliminata da una raccolta e la raccolta non utilizza mai lo spazio eliminato per i nuovi documenti, questo spazio deve essere restituito al sistema operativo in modo che possa essere utilizzato da altri database o raccolte. Sarà necessario eseguire un’operazione di compatta o di riparazione per deframmentare lo spazio su disco e recuperare lo spazio libero utilizzabile.

Il comportamento del processo di compattazione dipende dal motore MongoDB come segue

 db.runCommand({compact: collection-name }) 

MMAPv1

L’operazione di compattazione deframmenta i file di dati e gli indici. Tuttavia, non rilascia spazio sul sistema operativo. L’operazione è comunque utile per deframmentare e creare più spazi contigui per il riutilizzo da parte di MongoDB. Tuttavia, è inutile se lo spazio libero su disco è molto basso.

Durante l’operazione di compattazione è richiesto uno spazio aggiuntivo su disco fino a 2 GB.

Un blocco del livello del database viene mantenuto durante l’operazione di compattazione.

WiredTiger

Il motore WiredTiger fornisce la compressione per impostazione predefinita che consuma meno spazio su disco rispetto a MMAPv1.

Il processo compatto rilascia lo spazio libero sul sistema operativo. È necessario uno spazio su disco minimo per eseguire l’operazione compatta. WiredTiger blocca anche tutte le operazioni sul database in quanto richiede il blocco del livello di database.

Per il motore MMAPv1 , Doest compatto non restituisce lo spazio al sistema operativo. È necessario eseguire l’operazione di riparazione per liberare lo spazio non utilizzato.

 db.runCommand({repairDatabase: 1}) 

Qui puoi trovare informazioni dettagliate sull’operazione compatta

Mongodb 3.0 e versioni successive ha un nuovo motore di archiviazione: WiredTiger. Nel mio caso, il passaggio al motore ha ridotto l’utilizzo del disco da 100 Gb a 25 Gb.

C’è stata una notevole confusione sulla bonifica degli spazi in MongoDB, e alcune pratiche raccomandate sono decisamente pericolose da fare in alcuni tipi di distribuzione. Maggiori dettagli di seguito:

TL; DR repairDatabase tenta di salvare i dati da distribuzioni MongoDB indipendenti che tentano di ripristinare da un danneggiamento del disco. Se recupera lo spazio, è puramente un effetto collaterale . Recupero dello spazio non dovrebbe mai essere la considerazione primaria per eseguire repairDatabase .

Recupera lo spazio in un nodo standalone

WiredTiger: per un nodo standalone con WiredTiger, l’esecuzione di compact rilascerà spazio sul sistema operativo, con un avvertimento: il comando compact su WiredTiger su MongoDB 3.0.x è stato interessato da questo errore: SERVER-21833 corretto in MongoDB 3.2.3. Prima di questa versione, compact su WiredTiger poteva fallire silenziosamente.

MMAPv1: A causa del modo in cui funziona MMAPv1, non esiste un metodo sicuro e supportato per recuperare spazio utilizzando il motore di archiviazione MMAPv1. compact in MMAPv1 deframmenterà i file di dati, rendendo potenzialmente disponibile più spazio per i nuovi documenti, ma non restituirà spazio al sistema operativo.

Potresti essere in grado di eseguire repairDatabase se comprendi pienamente le conseguenze di questo comando potenzialmente pericoloso (vedi sotto), dal momento che repairDatabase essenzialmente riscrive l’intero database scartando i documenti corrotti. Come effetto collaterale, questo creerà nuovi file di dati MMAPv1 senza alcuna frammentazione e restituirà spazio al sistema operativo.

Per un metodo meno avventuroso, l’esecuzione di mongodump e di mongorestore può essere ansible anche in una distribuzione MMAPv1, in base alle dimensioni della distribuzione.

Recupera lo spazio in un set di repliche

Per le configurazioni di set di repliche, il metodo migliore e più sicuro per recuperare spazio consiste nell’eseguire una sincronizzazione iniziale , sia per WiredTiger che per MMAPv1.

Se è necessario recuperare spazio da tutti i nodes nel set, è ansible eseguire una sincronizzazione iniziale continua. Ovvero, esegui la sincronizzazione iniziale su ciascuno dei secondari, prima di abbandonare definitivamente il primario e eseguire la sincronizzazione iniziale su di esso. Il metodo di sincronizzazione iniziale a rotazione è il metodo più sicuro per eseguire la manutenzione dei set di repliche e inoltre non comporta tempi di inattività come bonus.

Si noti che la possibilità di eseguire una sincronizzazione iniziale continua dipende anche dalle dimensioni della distribuzione. Per distribuzioni estremamente grandi, potrebbe non essere fattibile effettuare una sincronizzazione iniziale, e quindi le opzioni sono un po ‘più limitate. Se si utilizza WiredTiger, si può essere in grado di estrarre un secondario dal set, avviarlo come autonomo, eseguirlo compact e riunirlo al set.

Per quanto riguarda repairDatabase

Si prega di non eseguire repairDatabase sui nodes del set di repliche . Questo è molto pericoloso, come menzionato nella pagina repairDatabase e descritto in maggiori dettagli di seguito.

Il nome repairDatabase è un po ‘fuorviante, dal momento che il comando non tenta di riparare nulla. Il comando era destinato a essere utilizzato in caso di danneggiamento del disco su un nodo standalone , che potrebbe portare a documenti corrotti.

Il comando repairDatabase potrebbe essere descritto più accuratamente come “database di salvataggio”. Cioè, ricrea i database scartando i documenti corrotti nel tentativo di ottenere il database in uno stato in cui è ansible avviarlo e recuperare il documento intatto da esso.

Nelle distribuzioni MMAPv1, questa ricostruzione dei file di database rilascia spazio sul sistema operativo come effetto collaterale . Rilasciando spazio per il sistema operativo non è mai stato lo scopo.

Conseguenze di repairDatabase su un set di repliche

In un set di repliche, MongoDB si aspetta che tutti i nodes nel set contengano dati identici. Se si esegue repairDatabase su un nodo del set di repliche, esiste la possibilità che il nodo contenga una corruzione non rilevata e repairDatabase rimuoverà diligentemente i documenti corrotti.

Prevedibilmente, questo rende quel nodo contenente un set di dati diverso dal resto del set. Se si verifica un aggiornamento per colpire quel singolo documento, l’intero set potrebbe bloccarsi.

A peggiorare le cose, è del tutto ansible che questa situazione potrebbe rimanere latente per un lungo periodo, solo per colpire improvvisamente senza una ragione apparente.

I file di database non possono essere ridotti di dimensioni. Durante la “riparazione” del database, è ansible che solo il server mongo elimini alcuni dei suoi file. Se una grande quantità di dati è stata cancellata, il server mongo “rilascia” (cancella), durante la riparazione, alcuni dei suoi file esistenti.

In generale è preferibile compattare per riparare database. Ma un vantaggio della riparazione su compatto è che è ansible eseguire la riparazione dell’intero cluster. compatto devi loggarti in ogni frammento, il che è piuttosto fastidioso.

Quando ho avuto lo stesso problema, ho interrotto il mio server mongo e l’ho riavviato con il comando

 mongod --repair 

Prima di eseguire l’operazione di riparazione dovresti verificare di avere abbastanza spazio libero sul tuo HDD (min – è la dimensione del tuo database)

Solo un modo in cui ero in grado di farlo. Nessuna garanzia sulla sicurezza dei dati esistenti. Prova con il tuo rischio.

Elimina direttamente i file di dati e riavvia mongod.

Ad esempio, con ubuntu (percorso predefinito per i dati: / var / lib / mongodb), ho avuto un paio di file con nome come: collection. #. Conservo la collezione.0 e ho eliminato tutti gli altri.

Sembra un modo più semplice se non si dispone di dati seri nel database.