lunes, 23 de septiembre de 2013

Como liberar espacio en disco al eliminar una colección en MongoDB

En MongoDB, al igual que ocurre con otros gestores de base de datos, trabajan con ficheros de datos. Comúnmente cuando eliminamos documentos o colecciones, el espacio ocupado por este fichero sigue siendo el mismo, esto es debido a que puede ser usado en el futuro. Hoy vamos a ver como liberar dicho espacio.

Lo primero de todo sera levantar mongo como un servicio indicando la ruta en la que se crear la base de datos, el puerto por el que escuchara y el fichero de log.
mongod --dbpath /data/ --port 27017 --logpath /data/log/hispabigdata.log &
Ahora abrimos una consola de mongo y vamos a crear una base de datos y una colección con 100.000 de documentos, recordad que el siguiente proceso puede tardar bastante, dependiendo del ordenador en el que lo ejecuteis.
use LiberandoDB;

for (var i=0; i < 100000; i++){
   db.ejemploEliminacion.insert ({
        "_id":i, "nombre":"HispaBigdata"+i, "fecha": ISODate()
   });
}
Se ejecutamos el siguiente comando podemos ver la ocupación de las bases de datos que tenemos en mongo.
show dbs;
Mostrando base de datos por HispaBigData


Ahora vamos a proceder a eliminar nuestra colección, para ello ejecutamos el siguiente comando:
db.ejemploEliminacion.drop()
Una vez eliminada si buscamos algún documento nos aparecerá que no hay y si volvemos a ejecutar el comando show dbs veremos que la base de datos sigue ocupando el mismo espacio:

eliminando colección por HispaBigData

¿Cómo podemos liberar dicho espacio? Para ello debemos ejecutar el comando db.repairDatabase(), el cual hara una compactación de nuestra base de datos y/o recuperará nuestro espacio en disco. Si ejecutamos el comando show dbs de nuevo veremos como ya no tenemos la base de datos LiberandoDB y queda el espacio liberado.

Liberando espacio por HispaBigData


Como veis el proceso es similar al que podemos utilizar en MYSQL con las tablas MyISAM usando OPTIMIZE TABLE.

3 comentarios:

  1. Hola, en relación con la reutilización de ese espacio por parte de MongoDB, tengo un aplicación de registro de evidencias de las cuales se guardan los 3 últimos días, por lo que todos los días voy borrando los registros anteriores, el problema que tengo es que me da la impresión de que ese espacio que no se libera al sistema, MongoDB no lo vuelve a usar, ya que conforme pasan los días acaba llenando todo el disco y MongoDB se para. ¿Hay alguna manera de forzar a que MongoDB use ese espacio libre no usado?, ¿el comando db.repairDatabase() según la documentación bloquea el uso de la BD, es así?, por la aplicación y el entorno no puedo esperar a que acabe de lanzar ese comando porque sino perdería todo el registro.

    Muchas gracias de antemano y enhorabuena por la web.

    ResponderEliminar
    Respuestas
    1. Hola Alonso, una cosa que se me ocurre es usar lo llamado Capped collections, es decir limitar el tamaño de la colección, MongoDB una vez llegue a ese limite, comienza a escribir los nuevos documentos sobre los antiguos. Aquí tienes mas información http://docs.mongodb.org/manual/core/capped-collections/, Aunque lo ideal seria tener un replicaset y poder realizar el rapairDatabase en cada uno de los nodos. De esta forma te garantizas tener siempre la aplicación arriba y puedes realizar las operaciones necesarias sobre la base de datos, ya que compactar las colecciones también producen bloqueos sobre la base de datos.

      Muchas gracias por ponerte en contacto con nosotros.

      Eliminar
    2. Hola Alfonso,

      Amplio con mas información como funciona la compactación y el uso de disco en mongodb,
      espero que le sea util.

      Usted puede compactar colecciones con el comando compact, este comando vuelve a escribir y desfragmentar
      todos los datos e indices de una colección.

      Esta operación produce bloqueos en la base de datos y por lo tanto vas a perder disponibilidad.

      La compactación de las colecciones individuales no va a reducir almacenamiento en el disco pero si va a desfragmentar
      las colecciones que compacta.

      Si estás ejecutando un conjunto de réplicas , puedes realizar la compactación en las secundarias y luego pasar la primaria a la secundaria,
      asi evitas indisponibilidad del servicio.

      Si compactas todas la base de datos para una instancia MONGODB en un solo nodo , puedes usar el comando db.repairDatabase.
      Esta operación vuelve a escribir todos los datos e índices a partir de cero y por lo tanto desfragmenta y libera espacio.

      Sobre el repair :

      Para compactar todas las bases de datos puede detener el proceso mongod y ejecutarlo con la opción " - repair ".

      Esta operación produce bloqueos en la base de datos y por lo tanto vas a perder disponibilidad.

      La ejecución del comando repair requiere de espacio libre en disco, ese espacio debe ser igual al tamaño del conjunto de datos actual, incluso algo mas.

      Usted puede utilizar el repair enviado los datos a un volumen diferente al original, intente especificar la opcion "- repairpath "

      Espero que haya sido de su ayuda-

      Muchas gracias por visitar hispabigdata,

      Eliminar