Reduzierung der Dateigröße der MongoDB-Datenbank

165

Ich habe eine MongoDB-Datenbank, die einmal groß war (> 3 GB). Seitdem wurden Dokumente gelöscht und ich hatte erwartet, dass die Größe der Datenbankdateien entsprechend abnimmt.

Da MongoDB jedoch den zugewiesenen Speicherplatz beibehält, sind die Dateien immer noch groß.

Ich habe hier und da gelesen, dass der Befehl admin mongod --repairverwendet wird, um den nicht verwendeten Speicherplatz freizugeben, aber ich habe nicht genügend Speicherplatz auf der Festplatte, um diesen Befehl auszuführen.

Kennen Sie einen Weg, wie ich ungenutzten Speicherplatz freigeben kann?

Meuble
quelle
7
Wird diese Frage als beantwortet betrachtet? Benötigen wir mehr Daten?
Gates VP
2
Ab Version 2.8 können Sie Ihre Daten komprimieren , was erheblich Platz spart.
Salvador Dali
1
Ich hatte genau die gleiche Herausforderung. Der einfachste Weg, sie zu lösen, bestand darin, eine Kopie der Datenbank mit der Funktion copyDatabase () zu erstellen, dann die ursprüngliche Datenbank in db.dropDatabase () zu kopieren und die Datenbank dann wieder an ihren Platz zu kopieren. Meine Datenbank war größtenteils leer und als ich die Kopie machte, wurden nur die tatsächlich verwendbaren Daten kopiert. Durch das Löschen der Originaldatenbank wurden die großen Dateien gelöscht. Die Verwendung von db.repairDatabase () war keine Option, da auf meinem Server bereits wenig Speicherplatz vorhanden war und für diesen Vorgang sehr viel freier Speicherplatz erforderlich gewesen wäre, viel mehr als für diesen Vorgang erforderlich.
user3892260

Antworten:

144

UPDATE: Mit dem compactBefehl und WiredTiger sieht es so aus, als würde der zusätzliche Speicherplatz tatsächlich für das Betriebssystem freigegeben .


UPDATE: Ab Version 1.1 gibt es einen compactBefehl.

Dieser Befehl führt eine Komprimierung "inline" durch. Es wird noch etwas zusätzlichen Platz benötigen, aber nicht so viel.


MongoDB komprimiert die Dateien durch:

  • Kopieren der Dateien an einen neuen Speicherort
  • Durchlaufen der Dokumente und Nachbestellen / Auflösen
  • Ersetzen der Originaldateien durch die neuen Dateien

Sie können diese "Komprimierung" ausführen, indem Sie ausführen mongod --repairoder indem Sie eine direkte Verbindung herstellen und ausführen db.repairDatabase().

In beiden Fällen benötigen Sie den Speicherplatz, um die Dateien zu kopieren. Jetzt weiß ich nicht, warum Sie nicht genug Speicherplatz haben, um eine Komprimierung durchzuführen. Sie haben jedoch einige Optionen, wenn Sie einen anderen Computer mit mehr Speicherplatz haben.

  1. Exportieren Sie die Datenbank auf einen anderen Computer, auf dem Mongo installiert ist (using mongoexport), und importieren Sie dann dieselbe Datenbank (using mongoimport). Dies führt zu einer neuen Datenbank, die stärker komprimiert ist. Jetzt können Sie das ursprüngliche mongodErsetzen durch die neuen Datenbankdateien stoppen und loslegen.
  2. Stoppen Sie das aktuelle Mongod, kopieren Sie die Datenbankdateien auf einen größeren Computer und führen Sie die Reparatur auf diesem Computer durch. Anschließend können Sie die neuen Datenbankdateien wieder auf den ursprünglichen Computer verschieben.

Derzeit gibt es keine gute Möglichkeit, mit Mongo "an Ort und Stelle zu verdichten". Und Mongo kann definitiv viel Platz aufsaugen.

Die derzeit beste Strategie für die Komprimierung besteht darin, ein Master-Slave-Setup auszuführen. Sie können den Slave dann komprimieren, aufholen lassen und umschalten. Ich weiß noch ein bisschen haarig. Vielleicht wird das Mongo-Team eine bessere Verdichtung an Ort und Stelle finden, aber ich denke nicht, dass sie ganz oben auf ihrer Liste steht. Der Speicherplatz wird derzeit als günstig angenommen (und ist dies normalerweise auch).

Gates VP
quelle
Vielen Dank an Gates VP für Ihre Antwort. Ich habe an die beiden Optionen gedacht, die Sie erwähnt haben. Aber bevor ich solche Dinge tat, wollte ich wissen, ob eine kompakte Lösung verfügbar ist. Danke noch einmal.
Meuble
3
Ab heute (18.11.2010) empfahl Dwight (auf der MongoDC-Veranstaltung in Washington, DC) den Ansatz zum Replizieren / Reparieren / Umschalten, wenn Sie komprimieren möchten, ohne Ihre Datenbank offline zu schalten.
David J.
10
Nur ein Heads-Up "Mach nicht so wie ich" und starte - Repair als Root. chowns die DB-Dateien zu root. doh.
Totoro
18
In der Dokumentation zu 'compact' heißt es: "Durch diesen Vorgang wird der im Dateisystem verwendete Speicherplatz nicht reduziert." Ich verstehe nicht, wie dies eine Lösung für die ursprüngliche Frage ist.
Ed Norris
Wenn Sie sich die ursprüngliche Frage ansehen, bestand ein Teil des Problems darin, zu viele Daten zu haben, um eine Reparatur durchzuführen. Wenn Sie 2/3 Ihres Laufwerks mit einer Datenbank gefüllt haben, konnten Sie keine Reparatur durchführen. Neu zugewiesene Dateien würden den verbleibenden Speicherplatz beanspruchen, bevor die neue Datenbank vollständig "kopiert und repariert" wurde und "der Wechsel" niemals stattfinden würde. Mit compactkann er zumindest die vorhandenen Dateien an Ort und Stelle halten. Ich stimme zu, es ist keine vollständige Lösung, aber es ist eine schrittweise Verbesserung.
Gates VP
39

Ich hatte das gleiche Problem und löste es einfach über die Befehlszeile:

mongodump -d databasename
echo 'db.dropDatabase()' | mongo databasename
mongorestore dump/databasename
user435943
quelle
Behauptung: 15936 Das Erstellen der Sammlung db.collection ist fehlgeschlagen. Errmsg: Ausnahme: Größe angeben: <n> wenn die
Obergrenze
: Sieht aus wie eine Ubuntu-Regression ... die Dump-Datei hat Metadaten begrenzt: "undefiniert" ... das Löschen dieser behebt das Importproblem.
Tweak2
2
Meine Datenbank hat fast die gesamte Festplatte bewertet. Es waren 120 GB (Festplatte 160 GB). Der Compact reduziert die Dateigröße nicht und die ReparatDatenbank ist aus Platzgründen nicht möglich. Nach mongodump & dropDatabase & mongorestore von db habe ich 40 GB Datenbankgröße.
Igor Benikov
Kleine Korrektur des Wiederherstellungsbefehlsmongorestore --db databasename dump/databasename
JERRY
34

Es sieht so aus, als hätte Mongo v1.9 + Unterstützung für den Compact!

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

Siehe die Dokumente hier: http://docs.mongodb.org/manual/reference/command/compact/

"Im Gegensatz zu RepairDatabase benötigt der Befehl compact keinen doppelten Speicherplatz für seine Arbeit. Er benötigt während der Arbeit nur wenig zusätzlichen Speicherplatz. Außerdem ist compact schneller."

warten
quelle
3
@AnujGupta "Der Befehl "paraturDatabase" komprimiert alle Sammlungen in der Datenbank. Er ist identisch mit der Ausführung des Befehls "compact" für jede Sammlung einzeln. " docs.mongodb.org/manual/reference/command/repairDatabase/… . Also, wenn die Reparaturdatenbank die Größe so kompakt reduziert. Ich habe meine Sammlungen jede Woche mit vielen Lösch- und Aktualisierungsvorgängen komprimiert. Ich mag Compact mehr als repariDatabase, weil es zuerst auf Sammlungen abzielt, für die Sie nicht die gesamte Datenbank benötigen. Zweitens benötigt es nur 2 GB freien Speicherplatz anstelle von x2 Ihrer Datenbankgröße (in meinem Fall 500 GB).
Maziyar
1
Übrigens: "MongoDB bietet zwei verschiedene Möglichkeiten, um Ihre Daten zu komprimieren und die optimale Leistung wiederherzustellen: RepairDatabase und Compact. RepairDatabase ist geeignet, wenn Ihre Datenbanken relativ klein sind oder Sie es sich leisten können, einen Knoten für längere Zeit außer Betrieb zu setzen Für unsere Datenbankgrößen und die Arbeitslast bei Abfragen war es sinnvoller, alle unsere Sammlungen kontinuierlich zu komprimieren. " 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 - "Im Gegensatz zu RepairDatabase gibt Compact keinen Speicherplatz im Dateisystem frei".
Anuj Gupta
4
@ Maziyar OP will ungenutzten Speicherplatz freigeben , was repairDatabasenicht durch erreicht wird compact. compactgibt keinen Speicherplatz frei, sondern defragmentiert nur den verbrauchten Speicherplatz, wodurch er nicht reduziert wird.
Anuj Gupta
5
Ab Mongo 3.0 compact wird bei Verwendung der WiredTiger-Speicher-Engine Speicherplatz zurückgewonnen.
Gary
19

Verdichten Sie alle Sammlungen in der aktuellen Datenbank

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

Wenn Sie eine vollständige Reparatur durchführen müssen, verwenden Sie die repairpathOption. Zeigen Sie auf eine Festplatte mit mehr verfügbarem Speicherplatz.

Zum Beispiel habe ich auf meinem Mac Folgendes verwendet:

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

Update: Pro MongoDB Core Server Ticket 4266 müssen Sie möglicherweise hinzufügen --nojournal, um einen Fehler zu vermeiden:

mongod --config /usr/local/etc/mongod.conf --repair --repairpath /Volumes/X/mongo_repair --nojournal
David J.
quelle
1
Das hat super geklappt. Mir fehlte der 2x Platz, der für die Reparatur erforderlich war, also habe ich einen NAS montiert. Einzige Ausgabe, die Fertigstellung dauerte 18 Stunden, aber es hat funktioniert. Stellen Sie sicher, dass Sie das Flag --nojoural hinzufügen.
Zenocon
11

Ab Version 2.8 von Mongo können Sie die Komprimierung verwenden . Sie haben 3 Komprimierungsstufen mit der WiredTiger-Engine, mmap (die Standardeinstellung in 2.6 bietet keine Komprimierung):

Hier ist ein Beispiel dafür, wie viel Speicherplatz Sie für 16 GB Daten sparen können:

Geben Sie hier die Bildbeschreibung ein

Daten stammen aus diesem Artikel.

Salvador Dali
quelle
7

Wir müssen zwei Möglichkeiten lösen, basierend auf StorageEngine.

1. MMAP () Engine:

Befehl: db.repairDatabase ()

HINWEIS : RepairDatabase benötigt freien Speicherplatz, der der Größe Ihres aktuellen Datensatzes plus 2 Gigabyte entspricht. Wenn auf dem Volume, auf dem dbpath gespeichert ist, nicht genügend Speicherplatz vorhanden ist, können Sie ein separates Volume bereitstellen und dieses für die Reparatur verwenden. Wenn Sie ein separates Volume für RepairDatabase bereitstellen, müssen Sie RepairDatabase über die Befehlszeile ausführen und mit der Option --repairpath den Ordner angeben, in dem temporäre Reparaturdateien gespeichert werden sollen. Beispiel: Stellen Sie sich vor, die DB-Größe beträgt 120 GB, dh (120 * 2) +2 = 242 GB Festplattenspeicher erforderlich.

Eine andere Möglichkeit, wie Sie die Sammlung durchführen, ist der Befehl: db.runCommand ({compact: 'collectionName'})

2. WiredTiger: Es wird automatisch selbst aufgelöst.

Karthickkumar Nagaraj
quelle
6

In MongoDB gab es einige erhebliche Verwirrung hinsichtlich der Speicherplatzrückgewinnung, und einige empfohlene Vorgehensweisen sind bei bestimmten Bereitstellungstypen geradezu gefährlich. Weitere Details unten:

TL; DR repairDatabase versucht, Daten aus eigenständigen MongoDB-Bereitstellungen zu retten, die versuchen, eine Festplattenbeschädigung wiederherzustellen. Wenn es Speicherplatz zurückgewinnt, ist es nur eine Nebenwirkung . Das Wiederherstellen von Speicherplatz sollte niemals das Hauptaugenmerk des Laufens sein repairDatabase.

Stellen Sie Speicherplatz in einem eigenständigen Knoten wieder her

WiredTiger: Bei einem eigenständigen Knoten mit WiredTiger wird durch Ausführen compactSpeicherplatz für das Betriebssystem freigegeben, mit einer Einschränkung: Der compactBefehl auf WiredTiger in MongoDB 3.0.x war von diesem Fehler betroffen: SERVER-21833, der in MongoDB 3.2.3 behoben wurde. Vor dieser Version konnte compactWiredTiger lautlos ausfallen.

MMAPv1: Aufgrund der Funktionsweise von MMAPv1 gibt es keine sichere und unterstützte Methode zum Wiederherstellen von Speicherplatz mithilfe der MMAPv1-Speicher-Engine. compactIn MMAPv1 werden die Datendateien defragmentiert, wodurch möglicherweise mehr Speicherplatz für neue Dokumente verfügbar wird. Es wird jedoch kein Speicherplatz für das Betriebssystem freigegeben.

Sie können möglicherweise ausgeführt werden, repairDatabasewenn Sie die Konsequenzen dieses potenziell gefährlichen Befehls vollständig verstanden haben (siehe unten), da im repairDatabaseWesentlichen die gesamte Datenbank neu geschrieben wird, indem beschädigte Dokumente verworfen werden. Als Nebeneffekt werden dadurch neue MMAPv1-Datendateien ohne Fragmentierung erstellt und Speicherplatz für das Betriebssystem freigegeben.

Für eine weniger abenteuerliche Methode ist das Ausführen mongodumpund mongorestoremöglicherweise auch in einer MMAPv1-Bereitstellung möglich, abhängig von der Größe Ihrer Bereitstellung.

Stellen Sie Speicherplatz in einem Replikatsatz wieder her

Bei Replikatsatzkonfigurationen besteht die beste und sicherste Methode zur Wiederherstellung des Speicherplatzes darin, eine erste Synchronisierung sowohl für WiredTiger als auch für MMAPv1 durchzuführen.

Wenn Sie Speicherplatz von allen Knoten im Satz wiederherstellen müssen, können Sie eine fortlaufende anfängliche Synchronisierung durchführen. Das heißt, führen Sie eine anfängliche Synchronisierung für jede der Sekundärdateien durch, bevor Sie die primäre Synchronisierung endgültig beenden und eine anfängliche Synchronisierung für sie durchführen. Die fortlaufende anfängliche Synchronisierungsmethode ist die sicherste Methode zur Durchführung der Wartung von Replikatsätzen und beinhaltet auch keine Ausfallzeiten als Bonus.

Beachten Sie, dass die Machbarkeit einer fortlaufenden Erstsynchronisierung auch von der Größe Ihrer Bereitstellung abhängt. Bei extrem großen Bereitstellungen ist eine erste Synchronisierung möglicherweise nicht möglich, sodass Ihre Optionen etwas eingeschränkter sind. Wenn WiredTiger verwendet wird, können Sie möglicherweise eine Sekundärseite aus dem Set herausnehmen, als eigenständiges Gerät starten, darauf ausführen compactund wieder mit dem Set verbinden.

Hinsichtlich repairDatabase

Bitte nicht repairDatabaseauf Replikatsatzknoten ausführen . Dies ist sehr gefährlich, wie auf der RepairDatabase-Seite erwähnt und weiter unten beschrieben.

Der Name repairDatabaseist etwas irreführend, da der Befehl nicht versucht, etwas zu reparieren. Der Befehl sollte verwendet werden, wenn auf einem eigenständigen Knoten eine Festplattenbeschädigung vorliegt , die zu beschädigten Dokumenten führen kann.

Der repairDatabaseBefehl könnte genauer als "Bergungsdatenbank" beschrieben werden. Das heißt, die Datenbanken werden neu erstellt, indem beschädigte Dokumente verworfen werden, um zu versuchen, die Datenbank in einen Zustand zu versetzen, in dem Sie sie starten und intakte Dokumente daraus retten können.

In MMAPv1-Bereitstellungen gibt diese Neuerstellung der Datenbankdateien als Nebeneffekt Speicherplatz für das Betriebssystem frei . Die Freigabe von Speicherplatz für das Betriebssystem war nie der Zweck.

Folgen repairDatabaseeines Replikatsets

In einem Replikatsatz erwartet MongoDB, dass alle Knoten im Satz identische Daten enthalten. Wenn Sie repairDatabaseauf einem Replikatsatzknoten ausgeführt werden, besteht die Möglichkeit, dass der Knoten eine nicht erkannte Beschädigung enthält und repairDatabasedie beschädigten Dokumente pflichtbewusst für Sie entfernt.

Vorhersehbar bedeutet dies, dass dieser Knoten einen anderen Datensatz enthält als der Rest des Satzes. Wenn ein Update dieses einzelne Dokument trifft, kann der gesamte Satz abstürzen.

Erschwerend kommt hinzu, dass diese Situation möglicherweise noch lange ruht und plötzlich ohne ersichtlichen Grund zuschlägt.

Kevinadi
quelle
5

Wenn ein großer Datenblock aus einer Sammlung gelöscht wird und die Sammlung niemals den gelöschten Speicherplatz für neue Dokumente verwendet, muss dieser Speicherplatz an das Betriebssystem zurückgegeben werden, damit er von anderen Datenbanken oder Sammlungen verwendet werden kann. Sie müssen einen Kompakt- oder Reparaturvorgang ausführen, um den Speicherplatz zu defragmentieren und den nutzbaren freien Speicherplatz wiederzugewinnen.

Das Verhalten des Verdichtungsprozesses hängt wie folgt von der MongoDB-Engine ab

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

MMAPv1

Durch den Komprimierungsvorgang werden Datendateien und Indizes defragmentiert. Es gibt jedoch keinen Speicherplatz für das Betriebssystem frei. Die Operation ist immer noch nützlich, um MongoDB zu defragmentieren und zusammenhängenden Speicherplatz für die Wiederverwendung durch MongoDB zu schaffen. Es nützt jedoch nichts, wenn der freie Speicherplatz sehr gering ist.

Während des Komprimierungsvorgangs ist ein zusätzlicher Speicherplatz von bis zu 2 GB erforderlich.

Während des Komprimierungsvorgangs wird eine Sperre auf Datenbankebene gehalten.

WiredTiger

Die WiredTiger-Engine bietet standardmäßig eine Komprimierung, die weniger Speicherplatz als MMAPv1 benötigt.

Der kompakte Prozess gibt den freien Speicherplatz für das Betriebssystem frei. Zum Ausführen des Kompaktvorgangs ist nur minimaler Speicherplatz erforderlich. WiredTiger blockiert auch alle Vorgänge in der Datenbank, da eine Sperre auf Datenbankebene erforderlich ist.

Bei einer MMAPv1- Engine gibt Compact den Speicherplatz nicht an das Betriebssystem zurück. Sie müssen den Reparaturvorgang ausführen, um den nicht verwendeten Speicherplatz freizugeben.

db.runCommand({repairDatabase: 1})
VISHAL KUMAWAT
quelle
3

Mongodb 3.0 und höher hat eine neue Speicher-Engine - WiredTiger. In meinem Fall reduzierte die Switching Engine die Festplattennutzung von 100 GB auf 25 GB.

Hett
quelle
1

Datenbankdateien können nicht verkleinert werden. Während der "Reparatur" der Datenbank kann der Mongo-Server nur einige seiner Dateien löschen. Wenn eine große Datenmenge gelöscht wurde, "veröffentlicht" der Mongo-Server während der Reparatur einige seiner vorhandenen Dateien.

ivankoni
quelle
1

Im Allgemeinen ist kompakt der Reparatur der Datenbank vorzuziehen. Ein Vorteil der Reparatur gegenüber Compact besteht jedoch darin, dass Sie Reparaturen für den gesamten Cluster durchführen können. kompakt muss man sich in jeden Shard einloggen, was irgendwie nervig ist.

user2077221
quelle
1

Als ich das gleiche Problem hatte, stoppte ich meinen Mongo-Server und startete ihn erneut mit dem Befehl

mongod --repair

Bevor Sie den Reparaturvorgang ausführen, sollten Sie überprüfen, ob auf Ihrer Festplatte genügend freier Speicherplatz vorhanden ist (min - entspricht der Größe Ihrer Datenbank).

Alexander Makarov
quelle
1

Für den Standalone-Modus können Sie Compact oder Repair verwenden.

Für Sharded-Cluster oder Replikatsätze wurde meiner Erfahrung nach die Größe der Primärdatenbank reduziert, nachdem Sie auf der Primärdatenbank kompakt gefolgt von der Sekundärdatenbank kompaktiert haben, jedoch nicht auf der Sekundärdatenbank. Möglicherweise möchten Sie ein Resync-Mitglied ausführen , um die Größe der sekundären Datenbank zu verringern. und auf diese Weise stellen Sie möglicherweise fest, dass die Größe der sekundären Datenbank noch geringer ist als die der primären. Ich denke, der Befehl compact komprimiert die Sammlung nicht wirklich. Also habe ich den primären und den sekundären Teil des Replikatsatzes gewechselt und das Resync-Mitglied erneut ausgeführt.

Mein Fazit ist, dass der beste Weg, um die Größe des Sharded- / Replikatsatzes zu reduzieren, darin besteht, das Resync-Mitglied auszuführen, die primäre Sekundärseite zu wechseln und erneut zu synchronisieren.

wism
quelle
0

mongoDB-Reparatur wird bei Sharded-Clustern nicht empfohlen.

Wenn Sie den Sharded-Cluster für Replikatsätze verwenden und den Befehl compact verwenden, werden alle Daten und Indexdateien aller Sammlungen neu geschrieben und defragmentiert. Syntax:

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

bei gewaltsamer Verwendung: true, kompakt wird auf der Primärseite des Replikatsatzes ausgeführt. z.B db.runCommand ( { command : "collection_name", force : true } )

Weitere zu berücksichtigende Punkte: -Es blockiert die Operationen. daher empfohlen, im Wartungsfenster auszuführen. -Wenn Replikatsätze auf verschiedenen Servern ausgeführt werden, müssen sie auf jedem Mitglied separat ausgeführt werden. - Bei Sharded-Clustern muss Compact auf jedem Shard-Mitglied separat ausgeführt werden. Kann nicht gegen Mongos-Instanz ausgeführt werden.

Saft
quelle
-5

Nur eine Möglichkeit, wie ich es geschafft habe. Keine Garantie für die Sicherheit Ihrer vorhandenen Daten. Versuchen Sie es auf eigenes Risiko.

Löschen Sie die Datendateien direkt und starten Sie mongod neu.

Mit Ubuntu (Standardpfad zu Daten: / var / lib / mongodb) hatte ich beispielsweise einige Dateien mit dem Namen: collection. #. Ich behalte die Sammlung.0 und lösche alle anderen.

Scheint ein einfacher Weg zu sein, wenn Sie keine seriösen Daten in der Datenbank haben.

frnkxiao
quelle
Die Dateien werden als <Datenbankname> gespeichert. <Nummer> zB mydb.3 - Sie können die Sammlung nicht mitteilen.
Bobmarksie