Reducir el tamaño del archivo de la base de datos MongoDB

Tengo una base de datos MongoDB que alguna vez fue grande (> 3GB). Desde entonces, los documentos se han eliminado y esperaba que el tamaño de los archivos de la base de datos disminuyera en consecuencia.

Pero dado que MongoDB mantiene el espacio asignado, los archivos siguen siendo grandes.

Leí aquí y allá que el comando de administración mongod --repair se usa para liberar el espacio no utilizado, pero no tengo suficiente espacio en el disco para ejecutar este comando.

¿Sabes una forma en que puedo liberar espacio sin usar?

ACTUALIZACIÓN: con el comando compact y WiredTiger parece que el espacio en disco adicional realmente se liberará en el sistema operativo .


ACTUALIZACIÓN: a partir de v1.9 + hay un comando compact .

Este comando realizará una compactación “en línea”. Todavía necesitará un espacio extra, pero no tanto.


MongoDB comprime los archivos por:

  • copiando los archivos a una nueva ubicación
  • recorriendo los documentos y reordenándolos / resolviéndolos
  • reemplazando los archivos originales con los nuevos archivos

Puede hacer esta “compresión” ejecutando mongod --repair o conectándose directamente y ejecutando db.repairDatabase() .

En cualquier caso, necesita el espacio en alguna parte para copiar los archivos. Ahora no sé por qué no tienes suficiente espacio para realizar una compresión, sin embargo, tienes algunas opciones si tienes otra computadora con más espacio.

  1. Exporte la base de datos a otra computadora con Mongo instalado (usando mongoexport ) y luego puede importar esa misma base de datos (usando mongoimport ). Esto dará como resultado una nueva base de datos que estará más comprimida. Ahora puede detener el reemplazo original de mongod con los nuevos archivos de base de datos y listo.
  2. Detenga el mongod actual y copie los archivos de la base de datos en una computadora más grande y ejecute la reparación en esa computadora. Luego puede mover los archivos de la base de datos nuevamente a la computadora original.

Actualmente no existe una buena forma de “compactar en el lugar” usando Mongo. Y Mongo definitivamente puede absorber mucho espacio.

La mejor estrategia ahora para la compactación es ejecutar una configuración Master-Slave. A continuación, puede compactar el esclavo, dejarlo alcanzar y cambiarlos. Sé que aún estoy un poco peludo. Tal vez el equipo de Mongo presente una mejor compactación en el lugar, pero no creo que sea una prioridad en su lista. Actualmente, se considera que el espacio de disco es barato (y generalmente lo es).

Tuve el mismo problema, y ​​lo resolví simplemente haciendo esto en la línea de comando:

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

¡Parece que Mongo v1.9 + tiene soporte para el compacto en su lugar!

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

Vea los documentos aquí: http://docs.mongodb.org/manual/reference/command/compact/

“A diferencia de repairDatabase, el comando compacto no requiere doble espacio en el disco para hacer su trabajo. Requiere una pequeña cantidad de espacio adicional mientras trabaja. Además, compact es más rápido”.

Si necesita ejecutar una reparación completa, use la opción de repairpath reparación. Apunte a un disco con más espacio disponible.

Por ejemplo, en mi Mac he usado:

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

Actualización: por ticket del servidor central MongoDB 4266 , es posible que deba agregar --nojournal para evitar un error:

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

Compactar todas las colecciones en la base de datos actual

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

Comenzando con la versión 2.8 de Mongo, puede usar la compresión . Tendrá 3 niveles de compresión con el motor WiredTiger, mmap (que por defecto en 2.6 no proporciona compresión):

  • Ninguna
  • ágil (por defecto)
  • zlib

Aquí hay un ejemplo de cuánto espacio podrá guardar para 16 GB de datos:

enter image description here

los datos están tomados de este artículo.

Necesitamos resolver 2 formas, basadas en StorageEngine.

1. Motor MMAP ():

comando: db.repairDatabase ()

NOTA: repairDatabase requiere espacio en disco libre igual al tamaño de su conjunto de datos actual más 2 gigabytes. Si el volumen que contiene dbpath carece de suficiente espacio, puede montar un volumen separado y usarlo para la reparación. Al montar un volumen separado para repairDatabase, debe ejecutar repairDatabase desde la línea de comandos y usar el parámetro –repairpath para especificar la carpeta en la cual almacenar los archivos de reparación temporales. por ejemplo: el tamaño de Imagine DB es 120 GB significa, (120 * 2) +2 = 242 GB Se requiere espacio en disco duro.

Otra forma de hacerlo es la recolección, comando: db.runCommand ({compact: ‘collectionName’})

2. WiredTiger: se resuelve automáticamente.

En caso de que se elimine una gran cantidad de datos de una colección y la colección nunca use el espacio eliminado para documentos nuevos, este espacio debe ser devuelto al sistema operativo para que pueda ser utilizado por otras bases de datos o colecciones. Tendrá que ejecutar una operación compacta o de reparación para desfragmentar el espacio en disco y recuperar el espacio libre utilizable.

El comportamiento del proceso de compactación depende del motor MongoDB de la siguiente manera

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

MMAPv1

La operación de compactación defragmenta los archivos de datos y los índices. Sin embargo, no libera espacio para el sistema operativo. La operación sigue siendo útil para desfragmentar y crear más espacio contiguo para su reutilización por parte de MongoDB. Sin embargo, no sirve de nada cuando el espacio libre en el disco es muy bajo.

Se requiere un espacio de disco adicional de hasta 2 GB durante la operación de compactación.

Se mantiene un locking de nivel de base de datos durante la operación de compactación.

WiredTiger

El motor WiredTiger proporciona compresión por defecto que consume menos espacio en disco que MMAPv1.

El proceso compacto libera el espacio libre al sistema operativo. Se requiere un espacio de disco mínimo para ejecutar la operación compacta. WiredTiger también bloquea todas las operaciones en la base de datos ya que necesita un locking de nivel de base de datos.

Para el motor MMAPv1 , compacto no devuelve el espacio al sistema operativo. Necesita ejecutar la operación de reparación para liberar el espacio no utilizado.

 db.runCommand({repairDatabase: 1}) 

Puede encontrar información detallada sobre la operación compacta aquí

Mongodb 3.0 y versiones posteriores tienen un nuevo motor de almacenamiento: WiredTiger. En mi caso, el motor de conmutación redujo el uso del disco de 100 Gb a 25 Gb.

Ha habido una considerable confusión sobre la recuperación de espacio en MongoDB, y algunas prácticas recomendadas son francamente peligrosas en ciertos tipos de despliegue. Más detalles a continuación:

TL; DR repairDatabase intenta salvar datos de despliegues de MongoDB independientes que intentan recuperarse de un daño en el disco. Si recupera espacio, es puramente un efecto secundario . La recuperación del espacio nunca debe ser la consideración principal de ejecutar repairDatabase .

Recuperar espacio en un nodo independiente

WiredTiger: para un nodo independiente con WiredTiger, ejecutar compact liberará espacio para el sistema operativo, con una advertencia: El comando compact en WiredTiger en MongoDB 3.0.x se vio afectado por este error: SERVER-21833, que se corrigió en MongoDB 3.2.3. Antes de esta versión, el compact en WiredTiger podía fallar silenciosamente.

MMAPv1: Debido a la forma en que funciona MMAPv1, no existe un método seguro y compatible para recuperar espacio utilizando el motor de almacenamiento MMAPv1. compact en MMAPv1 desfragmentará los archivos de datos, lo que potencialmente hará que haya más espacio disponible para nuevos documentos, pero no liberará espacio al sistema operativo.

Puede ejecutar repairDatabase si comprende completamente las consecuencias de este comando potencialmente peligroso (ver a continuación), ya que repairDatabase esencialmente reescribe toda la base de datos descartando documentos corruptos. Como efecto colateral, esto creará nuevos archivos de datos MMAPv1 sin ninguna fragmentación y liberará espacio al sistema operativo.

Para un método menos aventurero, ejecutar mongodump y mongorestre puede ser posible en una implementación de MMAPv1, sujeto al tamaño de su implementación.

Recuperar espacio en un conjunto de réplicas

Para las configuraciones de conjunto de réplicas, el mejor y más seguro método para recuperar espacio es realizar una sincronización inicial , tanto para WiredTiger como para MMAPv1.

Si necesita recuperar espacio de todos los nodos en el conjunto, puede realizar una sincronización inicial progresiva. Es decir, realice la sincronización inicial en cada uno de los secundarios, antes de abandonar definitivamente el primario y realizar la sincronización inicial en él. El método de sincronización inicial variable es el método más seguro para realizar el mantenimiento del conjunto de réplicas y tampoco implica un tiempo de inactividad adicional.

Tenga en cuenta que la viabilidad de realizar una sincronización inicial progresiva también depende del tamaño de su implementación. Para implementaciones extremadamente grandes, puede que no sea factible realizar una sincronización inicial y, por lo tanto, sus opciones son algo más limitadas. Si se utiliza WiredTiger, es posible que pueda sacar una secundaria del conjunto, iniciarla como una unidad independiente, ejecutarla compact y volver a unirla al conjunto.

En cuanto a la base de datos de repairDatabase

No ejecute repairDatabase en los nodos del conjunto de réplicas . Esto es muy peligroso, como se menciona en la página repairDatabase y se describe con más detalle a continuación.

El nombre repairDatabase es un poco engañoso, ya que el comando no intenta reparar nada. El comando estaba destinado a utilizarse cuando hay daños en el disco en un nodo independiente , lo que podría conducir a la corrupción de documentos.

El comando repairDatabase podría describirse con más precisión como “base de datos de recuperación”. Es decir, recrea las bases de datos descartando documentos corruptos en un bash de poner la base de datos en un estado en el que pueda iniciarlo y recuperar el documento intacto.

En las implementaciones MMAPv1, esta reconstrucción de los archivos de la base de datos libera espacio al sistema operativo como efecto secundario . Liberar espacio para el sistema operativo nunca fue el propósito.

Consecuencias de repairDatabase en un conjunto de réplicas

En un conjunto de réplicas, MongoDB espera que todos los nodos en el conjunto contengan datos idénticos. Si ejecuta repairDatabase en un nodo de conjunto de réplicas, existe la posibilidad de que el nodo contenga daños no detectados y repairDatabase eliminará diligentemente los documentos corruptos por usted.

Previsiblemente, esto hace que ese nodo contenga un conjunto de datos diferente del rest del conjunto. Si sucede que una actualización golpea ese único documento, todo el conjunto podría colapsar.

Para empeorar las cosas, es muy posible que esta situación permanezca inactiva por un tiempo prolongado, solo para atacar repentinamente sin razón aparente.

Los archivos de la base de datos no se pueden reducir de tamaño. Al “reparar” la base de datos, solo es posible que mongo server elimine algunos de sus archivos. Si se ha eliminado una gran cantidad de datos, el servidor mongo “liberará” (eliminará), durante la reparación, algunos de sus archivos existentes.

En general, es preferible compactar a repairDatabase. Pero una de las ventajas de la reparación sobre el compacto es que puede reparar el clúster completo. Compacto debe iniciar sesión en cada fragmento, lo que es un poco molesto.

Cuando tuve el mismo problema, dejé mi servidor mongo y lo inicié de nuevo con el comando

 mongod --repair 

Antes de ejecutar la operación de reparación, debe verificar si tiene suficiente espacio libre en su HDD (mínimo – es el tamaño de su base de datos)

Solo una forma en que pude hacerlo. Sin garantía sobre la seguridad de sus datos existentes. Pruebe con su propio riesgo.

Borre los archivos de datos directamente y reinicie mongod.

Por ejemplo, con ubuntu (vía de acceso predeterminada a datos: / var / lib / mongodb), tenía dos archivos con el nombre: collection. #. Guardo la colección.0 y borré todas las demás.

Parece una manera más fácil si no tiene datos serios en la base de datos.