Riduzione della dimensione del file di database MongoDB


165

Ho un database MongoDB che una volta era grande (> 3 GB). Da allora, i documenti sono stati eliminati 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 --repairviene utilizzato per liberare lo spazio inutilizzato, ma non ho abbastanza spazio sul disco per eseguire questo comando.

Conosci un modo in cui posso liberare spazio inutilizzato?


7
Questa domanda è considerata risposta? Abbiamo bisogno di più dati?
Gates VP

2
a partire dalla versione 2.8, puoi comprimere i tuoi dati , risparmiando così una notevole quantità di spazio.
Salvador Dali,

1
ho avuto la stessa identica sfida, il modo più semplice per risolverlo era quello di fare una copia del database con la funzione copyDatabase (), quindi di db.dropDatabase () il database originale e quindi di copiare nuovamente il database in posizione. il mio database era per lo più vuoto e quando ho fatto la copia, sono stati copiati solo i dati utilizzabili effettivi. l'eliminazione del database originale ha eliminato i file di grandi dimensioni. l'utilizzo di db.repairDatabase () non era un'opzione poiché il mio server era già a corto di spazio su disco e questa operazione avrebbe richiesto una quantità molto grande di spazio libero, molto più del necessario per questa operazione.
user3892260

Risposte:


144

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


AGGIORNAMENTO: dalla v1.9 + c'è un compactcomando.

Questo comando eseguirà una compattazione "in linea". Avrà comunque bisogno di un po 'di spazio extra, ma non tanto.


MongoDB comprime i file per:

  • copia dei file in una nuova posizione
  • scorrere i documenti e riordinarli / risolverli nuovamente
  • sostituzione dei file originali con i nuovi file

È possibile eseguire questa "compressione" eseguendo mongod --repairo connettendosi 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 impacco, tuttavia hai alcune opzioni se hai un altro computer con più spazio.

  1. Esporta il database su un altro computer con Mongo installato (usando mongoexport) e quindi puoi importare quello stesso database (usandomongoimport ). Ciò comporterà un nuovo database più compresso. Ora puoi interrompere la mongodsostituzione originale con i nuovi file di database e sei a posto.
  2. Arresta il mongod corrente e copia i file del database su un computer più grande ed esegui la riparazione su quel computer. È quindi possibile spostare nuovamente i nuovi file di database sul computer originale.

Attualmente non esiste un buon modo per "compattare sul posto" utilizzando Mongo. E Mongo può sicuramente risucchiare molto spazio.

La migliore strategia in questo momento per la compattazione è eseguire una configurazione Master-Slave. È quindi possibile compattare lo Slave, lasciarlo recuperare e cambiarlo. Conosco ancora un po 'peloso. Forse il team Mongo produrrà una migliore compattazione, ma non credo sia in cima alla loro lista. Lo spazio su disco è attualmente considerato economico (e di solito lo è).


Grazie Gates VP per la tua risposta. Stavo pensando alle due opzioni che hai menzionato. Ma prima di fare queste cose, volevo sapere se era disponibile una soluzione compatta sul posto. Grazie ancora.
Meuble

3
Ad oggi (18-11-2010) Dwight (intervenendo all'evento MongoDC a Washington, DC) ha raccomandato l'approccio replicate / --repair / switch over se si desidera compattare senza portare offline il database.
David J.

10
Solo un avvertimento "non fare come ho fatto io" ed esegui --repair come root. mostra i file db come root. doh.
Totoro

18
La documentazione per 'compact' dice: "Questa operazione non ridurrà la quantità di spazio su disco utilizzata sul filesystem". Non capisco come questa sia una soluzione alla domanda originale.
Ed Norris,

Se si esamina la domanda originale, parte del problema riguardava la presenza di troppi dati per eseguire una riparazione. Se hai riempito i 2/3 del tuo disco con un DB, non puoi eseguire una riparazione. I file appena allocati risuccherebbero lo spazio rimanente prima che il nuovo DB fosse completamente "copiato e riparato" e "lo switch" non sarebbe mai avvenuto. Con compact, può almeno mantenere in posizione i file esistenti. Sono d'accordo, non è una soluzione completa, ma è un miglioramento incrementale.
Gates VP,

39

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

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

asserzione: 15936 Creazione della raccolta db.collection non riuscita. Errmsg: eccezione: specificare size: <n> quando il
limite

: Sembra una regressione di Ubuntu ... il file di dump ha metadati con limite: "non definito" in esso ... l'eliminazione di questi risolve il problema di importazione.
tweak2

2
Il mio database ha segnato quasi l'intero disco. era 120 GB (disco 160 GB) Il compatto non riduce le dimensioni del file e ripara Database impossibile a causa della mancanza di spazio. Dopo mongodump & dropDatabase e mongorestore di db ho 40 GB di dimensioni del database.
Igor Benikov,

Piccola correzione al comando di ripristinomongorestore --db databasename dump/databasename
JERRY

34

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

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

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

"A differenza di repairDatabase, il comando compact non richiede doppio spazio su disco per svolgere il suo lavoro. Richiede una piccola quantità di spazio aggiuntivo durante il lavoro. Inoltre, compact è più veloce."


3
@AnujGupta "Il comando repairDatabase compatta tutte le raccolte nel database. È identico all'esecuzione del comando compatto su ciascuna raccolta singolarmente." docs.mongodb.org/manual/reference/command/repairDatabase/… . Quindi se il repairDatabase riduce le dimensioni in modo compatto. Ho compattato le mie raccolte con molte eliminazioni e aggiornamenti ogni settimana. Mi piace compattare più di repariDatabase perché prima è indirizzato alle raccolte che non si desidera l'intero database. In secondo luogo ha solo bisogno di 2 GB di spazio libero invece di x2 della dimensione del tuo file db (nel mio caso 500 GB).
Maziyar,

1
A proposito: "MongoDB offre 2 modi diversi per compattare i dati e ripristinare prestazioni ottimali: repairDatabase e compact. RepairDatabase è appropriato se i tuoi database sono relativamente piccoli o puoi permetterti di mettere un nodo fuori rotazione per un tempo piuttosto lungo "Per le dimensioni del nostro database e il carico di lavoro delle query, ha avuto più senso eseguire una compattazione continua su tutte le nostre raccolte". blog.parse.com/2013/03/26/always-be-compacting github.com/ParsePlatform/Ops/blob/master/tools/mongo_compact.rb
Maziyar

3
@Maziyar docs.mongodb.org/manual/reference/command/compact/#disk-space - "A differenza di repairDatabase, compact non libera spazio sul file system".
Anuj Gupta,

4
@Maziyar OP vuole liberare spazio inutilizzato , che si ottiene attraverso repairDatabase, non compact. compactnon libera spazio, deframmenta solo lo spazio esaurito, senza ridurlo.
Anuj Gupta,

5
A partire dal mongo 3.0, compact sarà recuperare lo spazio se si utilizza il motore di archiviazione WiredTiger.
Gary,

19

Compatta tutte le raccolte nel database corrente

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

13

Se è necessario eseguire una riparazione completa, utilizzare l' repairpathopzione. 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 MongoDB Core Server Ticket 4266 , potrebbe essere necessario aggiungere --nojournalper evitare un errore:

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

1
Questo ha funzionato alla grande. Mi mancava lo spazio 2x necessario per la riparazione, quindi ho montato un NAS. Unico problema, il completamento ha richiesto 18 ore, ma ha funzionato. Assicurati di aggiungere il flag --nojoural.
Zenocon


7

Dobbiamo 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, è possibile 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. ad esempio: immagina che la dimensione del DB sia di 120 GB, (120 * 2) +2 = 242 GB di spazio su disco rigido richiesto.

un altro modo di fare una raccolta saggia, comando: db.runCommand ({compact: 'collectionName'})

2. WiredTiger: si risolve automaticamente.


6

C'è stata una certa confusione sulla bonifica dello spazio in MongoDB e alcune pratiche raccomandate sono decisamente pericolose da fare in alcuni tipi di schieramento. Maggiori dettagli di seguito:

TL; DR repairDatabase tenta di recuperare i dati da una distribuzione autonoma di MongoDB che sta tentando di recuperare da un danneggiamento del disco. Se recupera spazio, è puramente un effetto collaterale . Il recupero dello spazio non dovrebbe mai essere la considerazione principale della corsa repairDatabase.

Ripristinare lo spazio in un nodo autonomo

WiredTiger: per un nodo autonomo con WiredTiger, l'esecuzione compactrilascerà spazio sul sistema operativo, con un avvertimento: il compactcomando su WiredTiger su MongoDB 3.0.x è stato interessato da questo errore: SERVER-21833 che è stato 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. compactin MMAPv1 deframmenterà i file di dati, rendendo potenzialmente più spazio disponibile per i nuovi documenti, ma non rilascerà spazio sul sistema operativo.

Si può essere in grado di eseguire repairDatabase, se si comprende appieno le conseguenze di questa potenzialmente pericolosa comando (vedi sotto), dal momento cherepairDatabase essenzialmente riscrive l'intero database scartando i documenti corrotti. Come effetto collaterale, questo creerà nuovi file di dati MMAPv1 senza alcuna frammentazione e rilascerà spazio sul sistema operativo.

Per un metodo meno avventuroso, in esecuzione mongodumpe mongorestorepotrebbe essere possibile anche in una distribuzione MMAPv1, a seconda delle dimensioni della distribuzione.

Ripristinare lo spazio in un set di repliche

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

Se è necessario recuperare spazio da tutti i nodi del set, è possibile eseguire una sincronizzazione iniziale continua. Ossia, esegui la sincronizzazione iniziale su ciascuno dei secondari, prima di abbandonare il primario ed eseguire la sincronizzazione iniziale su di esso. Il metodo di sincronizzazione iniziale a rotazione è il metodo più sicuro per eseguire la manutenzione del set di repliche e non comporta alcun downtime come bonus.

La fattibilità di eseguire una sincronizzazione iniziale continua dipende anche dalle dimensioni della distribuzione. Per distribuzioni estremamente grandi, potrebbe non essere possibile eseguire una sincronizzazione iniziale, quindi le opzioni sono leggermente più limitate. Se si utilizza WiredTiger, è possibile estrarre un secondario dall'insieme, avviarlo come autonomo, eseguirlo compacte ricollegarlo all'insieme.

per quanto riguarda repairDatabase

Non eseguire repairDatabasesui nodi del set di repliche . Questo è molto pericoloso, come menzionato nella pagina di riparazione del database e descritto in maggiori dettagli di seguito.

Il nome repairDatabaseè un po 'fuorviante, poiché il comando non tenta di riparare nulla. Il comando doveva essere utilizzato in caso di corruzione del disco su un nodo autonomo , che potrebbe portare a documenti corrotti.

Il repairDatabasecomando potrebbe essere descritto più accuratamente come "database di salvataggio". Cioè, ricrea i database scartando i documenti corrotti nel tentativo di portare il database in uno stato in cui è possibile 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 . Rilasciare spazio sul sistema operativo non è mai stato lo scopo.

Conseguenze di repairDatabaseun set di repliche

In un set di repliche, MongoDB prevede che tutti i nodi del set contengano dati identici. Se si esegue repairDatabasesu un nodo del set di repliche, è possibile che il nodo contenga corruzione non rilevata e repairDatabaserimuoverà debitamente i documenti corrotti.

Com'era prevedibile, questo rende quel nodo contenente un set di dati diverso dal resto dell'insieme. Se un aggiornamento dovesse colpire quel singolo documento, l'intero set potrebbe andare in crash.

A peggiorare le cose, è del tutto possibile che questa situazione possa rimanere inattiva a lungo, solo per colpire improvvisamente senza una ragione apparente.


5

Nel caso in cui una grande quantità di dati venga eliminata da una raccolta e la raccolta non utilizzi 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 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 per il sistema operativo. L'operazione è ancora utile per deframmentare e creare uno spazio più contiguo per il riutilizzo da MongoDB. Tuttavia, non è utile se lo spazio libero su disco è molto basso.

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

Un blocco a livello di 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 per il sistema operativo. Per eseguire l'operazione compatta è necessario uno spazio su disco minimo. WiredTiger blocca anche tutte le operazioni sul database in quanto necessita del blocco a livello di database.

Per il motore MMAPv1 , compact doest non restituisce lo spazio al sistema operativo. È necessario eseguire un'operazione di riparazione per liberare lo spazio inutilizzato.

db.runCommand({repairDatabase: 1})

3

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


1

Le dimensioni dei file di database non possono essere ridotte. Durante la "riparazione" del database, è possibile per il server mongo solo eliminare alcuni dei suoi file. Se è stata eliminata una grande quantità di dati, il server mongo "rilascerà" (elimina), durante la riparazione, alcuni dei suoi file esistenti.


1

In generale, è preferibile riparare il database. Ma un vantaggio della riparazione rispetto alla compatta è che è possibile eseguire la riparazione dell'intero cluster. compatto devi accedere ad ogni frammento, il che è abbastanza fastidioso.


1

Quando ho avuto lo stesso problema, ho fermato il mio server mongo e lo ho riavviato con il comando

mongod --repair

Prima di eseguire le operazioni di riparazione, è necessario verificare che lo spazio disponibile sul disco rigido sia sufficiente (min - è la dimensione del database)


1

Per la modalità standalone puoi usare compact o repair,

Per il cluster frammentato o il set di repliche, nella mia esperienza, dopo aver eseguito Compact sul primario, seguito da Compact sul secondario, le dimensioni del database primario sono state ridotte, ma non quelle secondarie. Potresti voler risincronizzare il membro per ridurre le dimensioni del database secondario. e così facendo potresti scoprire che la dimensione del database secondario è persino più ridotta rispetto a quella primaria, immagino che il comando compact non compatta davvero la raccolta. Quindi, ho finito per cambiare il primario e il secondario del set di repliche e fare nuovamente il membro resync .

la mia conclusione è che il modo migliore per ridurre le dimensioni del set di repliche / repliche è eseguire la risincronizzazione del membro, cambiare il secondario primario e risincronizzare di nuovo.


0

mongoDB -repair non è raccomandato in caso di cluster frammentato.

Se si utilizza il cluster condiviso set di repliche, utilizzare il comando compact, riscriverà e deframmenterà tutti i file di dati e di indice di tutte le raccolte. sintassi:

db.runCommand( { compact : "collection_name" } )

se usato con la forza: vero, compatto viene eseguito sul primario del set di repliche. per esempio db.runCommand ( { command : "collection_name", force : true } )

Altri punti da considerare: -Blocca le operazioni. pertanto consigliato da eseguire nella finestra di manutenzione. -Se i set di repliche in esecuzione su server diversi, devono essere eseguiti su ciascun membro separatamente - In caso di cluster frammentato, Compact deve essere eseguito su ciascun membro shard separatamente. Impossibile eseguire l'istanza di mongos.


-5

Solo un modo in cui sono stato 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), avevo file di coppia con nome come: collection. #. Tengo la raccolta.0 e cancellato tutti gli altri.

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


i file sono memorizzati come <nome_database>. <numero> ad es. mydb.3 - non si può dire alla raccolta.
bobmarksie,
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.