Reduzindo o tamanho do arquivo de banco de dados MongoDB

165

Eu tenho um banco de dados MongoDB que já foi grande (> 3 GB). Desde então, os documentos foram excluídos e eu esperava que o tamanho dos arquivos do banco de dados diminuísse de acordo.

Mas como o MongoDB mantém o espaço alocado, os arquivos ainda são grandes.

Eu li aqui e ali que o comando admin mongod --repairé usado para liberar o espaço não utilizado, mas não tenho espaço suficiente no disco para executar este comando.

Você conhece uma maneira de liberar espaço não utilizado?

Meuble
fonte
7
Esta questão é considerada respondida? Precisamos de mais dados?
Gates VP
2
a partir da versão 2.8, você pode compactar seus dados , economizando uma quantidade significativa de espaço.
Salvador Dali
1
Eu tive o mesmo desafio exato, a maneira mais fácil de resolvê-lo era fazer uma cópia do banco de dados com a função copyDatabase (), depois db.dropDatabase () o banco de dados original e depois copiá-lo novamente. meu banco de dados estava quase vazio e, quando fiz a cópia, apenas os dados utilizáveis ​​reais foram copiados. descartar o banco de dados original excluiu os arquivos grandes. usar db.repairDatabase () não era uma opção, pois meu servidor já estava com pouco espaço em disco e essa operação exigiria uma quantidade muito grande de espaço livre, muito mais do que o necessário para esta operação.
user3892260

Respostas:

144

ATUALIZAÇÃO: com o compactcomando e o WiredTiger, parece que o espaço em disco extra será liberado para o sistema operacional .


ATUALIZAÇÃO: a partir da v1.9 +, há um compactcomando.

Este comando executará uma compactação "in-line". Ainda será necessário algum espaço extra, mas não tanto.


O MongoDB compacta os arquivos:

  • copiando os arquivos para um novo local
  • percorrer os documentos e reordená-los / resolvê-los
  • substituindo os arquivos originais pelos novos arquivos

Você pode fazer essa "compactação" executando mongod --repairou conectando-se diretamente e executando db.repairDatabase().

Em ambos os casos, você precisa de espaço em algum lugar para copiar os arquivos. Agora não sei por que você não tem espaço suficiente para realizar uma compactação, no entanto, você tem algumas opções se tiver outro computador com mais espaço.

  1. Exporte o banco de dados para outro computador com o Mongo instalado (usando mongoexport) e, em seguida, você pode importar o mesmo banco de dados (usando mongoimport). Isso resultará em um novo banco de dados mais compactado. Agora você pode interromper a mongodsubstituição original pelos novos arquivos de banco de dados e pronto.
  2. Interrompa o mongod atual e copie os arquivos do banco de dados para um computador maior e execute o reparo nesse computador. Você pode então mover os novos arquivos de banco de dados de volta para o computador original.

Atualmente, não existe uma boa maneira de "compactar no lugar" usando o Mongo. E o Mongo pode definitivamente ganhar muito espaço.

A melhor estratégia agora para compactação é executar uma configuração Master-Slave. Você pode compactar o escravo, deixá-lo alcançá-lo e trocá-lo. Eu ainda sei um pouco peludo. Talvez a equipe Mongo tenha uma melhor compactação no local, mas não acho que esteja no topo da lista. Presume-se atualmente que o espaço em disco é barato (e geralmente é).

Gates VP
fonte
Obrigado Gates VP pela sua resposta. Eu estava pensando nas duas opções que você mencionou. Mas antes de fazer isso, eu queria saber se uma solução compacta no local estava disponível. Obrigado novamente.
Meuble
3
A partir de hoje (18/11/2010), a Dwight (falando no evento MongoDC em Washington, DC) recomendou a abordagem de replicação / --pair / switch over se você deseja compactar sem colocar seu banco de dados offline.
David J.
10
Apenas um aviso 'não faça como eu fiz' e execute --repair como root. mostra os arquivos db como root. doh.
Totoro
18
A documentação para 'compact' diz: "Esta operação não reduzirá a quantidade de espaço em disco usada no sistema de arquivos". Não entendo como isso é uma solução para a pergunta original.
Ed Norris
Se você examinar a pergunta original, parte do problema envolvia ter muitos dados para executar um reparo. Se você tiver preenchido 2/3 da sua unidade com um banco de dados, não poderá executar um reparo. Os arquivos alocados recentemente consumiriam o espaço restante antes que o novo banco de dados fosse completamente "copiado e reparado" e "a opção" nunca ocorresse. Com compact, ele pode pelo menos manter os arquivos existentes no lugar. Concordo, não é uma solução completa, mas é uma melhoria incremental.
Gates VP
39

Eu tive o mesmo problema e resolvi simplesmente fazendo isso na linha de comando:

mongodump -d databasename
echo 'db.dropDatabase()' | mongo databasename
mongorestore dump/databasename
user435943
fonte
assertion: 15936 Falha na criação da coleção db.collection. Mensagem de erro: exceção: especificar o tamanho: <n> quando tampado é verdade
tweak2
: Parece uma regressão do ubuntu ... o arquivo de despejo possui os metadados limitados: "indefinido" nele ... excluir essas correções do problema de importação.
tweak2
2
Meu banco de dados marcou quase todo o disco. era 120 GB (disco 160 GB) O compacto não reduz o tamanho do arquivo e o reparo do banco de dados não é possível devido à falta de espaço. Depois do mongodump & dropDatabase e mongorestore do db, tenho 40 GB de tamanho do banco de dados.
Igor Benikov 02/10/16
Correção pequena para o comando restoremongorestore --db databasename dump/databasename
JERRY
34

Parece que o Mongo v1.9 + tem suporte para o compacto no lugar!

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

Consulte os documentos aqui: http://docs.mongodb.org/manual/reference/command/compact/

"Ao contrário do repairDatabase, o comando compact não requer espaço em disco duplo para executar seu trabalho. Requer uma pequena quantidade de espaço adicional durante o trabalho. Além disso, o compact é mais rápido."

aguardar
fonte
3
@AnujGupta "O comando repairDatabase compacta todas as coleções no banco de dados. É idêntico à execução do comando compact em cada coleção individualmente." docs.mongodb.org/manual/reference/command/repairDatabase/… . Portanto, se o repairDatabase reduzir o tamanho, ele será compacto. Tenho compactado minhas coleções com muitas exclusões e atualizações todas as semanas. Eu gosto mais do que o repariDatabase, porque primeiro ele é direcionado a coleções que você não deseja ao banco de dados inteiro. Segundo, ele só precisa de 2 GB de espaço livre em vez de x2 do seu tamanho de arquivo db (no meu caso, 500 GB).
Maziyar 26/10/2013
1
Confira: "O MongoDB fornece duas maneiras diferentes de compactar seus dados e restaurar o desempenho ideal: repairDatabase e compact. RepairDatabase é apropriado se seus bancos de dados forem relativamente pequenos ou você pode deixar um nó fora de rotação por um longo tempo. Para nossos tamanhos de banco de dados e carga de trabalho de consulta, fazia mais sentido executar compactação contínua em todas as nossas coleções ". 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 - "Ao contrário do repairDatabase, o compact não libera espaço no sistema de arquivos".
Anuj Gupta
4
O @Maziyar OP quer liberar espaço não utilizado , o que é alcançado através repairDatabase, não compact. compactnão libera espaço, apenas desfragmenta o espaço usado, o que não o reduz.
Anuj Gupta
5
A partir de 3,0 mongo, compact vai recuperar o espaço de se utilizar o mecanismo de armazenamento WiredTiger.
Gary
19

Compactar todas as coleções no banco de dados atual

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

Se você precisar executar um reparo completo, use a repairpathopção Aponte para um disco com mais espaço disponível.

Por exemplo, no meu Mac eu usei:

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

Atualização: pelo tíquete 4266 do MongoDB Core Server , pode ser necessário adicionar --nojournalpara evitar um erro:

mongod --config /usr/local/etc/mongod.conf --repair --repairpath /Volumes/X/mongo_repair --nojournal
David J.
fonte
1
Isso funcionou muito bem. Como faltava o espaço 2x necessário para reparar no local, montei um NAS. Único problema: demorou 18 horas para ser concluído, mas funcionou. Certifique-se de adicionar o sinalizador --nojoural.
Zenocon 01/04
11

A partir da versão 2.8 do Mongo, você pode usar a compactação . Você terá três níveis de compactação com o mecanismo WiredTiger, mmap (que é o padrão no 2.6 não fornece compactação):

Aqui está um exemplo de quanto espaço você poderá economizar para 16 GB de dados:

insira a descrição da imagem aqui

os dados são retirados deste artigo.

Salvador Dalí
fonte
7

Precisamos resolver de duas maneiras, com base no StorageEngine.

1. Motor MMAP ():

comando: db.repairDatabase ()

NOTA: repairDatabase requer espaço livre em disco igual ao tamanho do seu conjunto de dados atual mais 2 gigabytes. Se o volume que contém o dbpath não tiver espaço suficiente, você poderá montar um volume separado e usá-lo para o reparo. Ao montar um volume separado para repairDatabase, você deve executar repairDatabase a partir da linha de comandos e usar a opção --repairpath para especificar a pasta na qual os arquivos de reparo temporários serão armazenados. por exemplo: o tamanho do banco de dados Imagine é de 120 GB, (120 * 2) +2 = 242 GB de espaço em disco necessário.

outra maneira de fazer a coleta de informações, comando: db.runCommand ({compact: 'collectionName'})

2. WiredTiger: É resolvido automaticamente.

Karthickkumar Nagaraj
fonte
6

Houve alguma confusão considerável sobre a recuperação de espaço no MongoDB, e algumas práticas recomendadas são absolutamente perigosas em certos tipos de implantação. Mais detalhes abaixo:

O TL; DR repairDatabase tenta recuperar dados de uma implantação independente do MongoDB que está tentando se recuperar de uma corrupção de disco. Se recuperar espaço, é puramente um efeito colateral . Recuperar espaço nunca deve ser a principal consideração da execução repairDatabase.

Recuperar espaço em um nó independente

WiredTiger: para um nó independente com o WiredTiger, a execução compactliberará espaço para o sistema operacional, com uma ressalva: O compactcomando no WiredTiger no MongoDB 3.0.x foi afetado por este bug: SERVER-21833, que foi corrigido no MongoDB 3.2.3. Antes desta versão,compact WiredTiger podia falhar silenciosamente.

MMAPv1: devido à maneira como o MMAPv1 funciona, não há método seguro e suportado para recuperar espaço usando o mecanismo de armazenamento MMAPv1. compactno MMAPv1, desfragmentará os arquivos de dados, potencialmente disponibilizando mais espaço para novos documentos, mas não liberará espaço de volta para o sistema operacional.

Você poderá executar repairDatabasese entender completamente as conseqüências desse comando potencialmente perigoso (veja abaixo), pois repairDatabaseessencialmente reescreve todo o banco de dados descartando documentos corrompidos. Como efeito colateral, isso criará novos arquivos de dados MMAPv1 sem nenhuma fragmentação e liberará espaço de volta ao sistema operacional.

Para um método menos aventureiro, executar mongodumpe também mongorestorepode ser possível em uma implantação do MMAPv1, sujeita ao tamanho da sua implantação.

Recuperar espaço em um conjunto de réplicas

Para configurações de conjunto de réplicas, o melhor e o mais seguro método para recuperar espaço é executar uma sincronização inicial , tanto para o WiredTiger quanto para o MMAPv1.

Se você precisar recuperar espaço de todos os nós no conjunto, poderá executar uma sincronização inicial contínua. Ou seja, execute a sincronização inicial em cada um dos secundários, antes de finalmente deixar o primário e executar a sincronização inicial nele. A rolagem do método de sincronização inicial é o método mais seguro para executar a manutenção do conjunto de réplicas e também não envolve tempo de inatividade como bônus.

Observe que a viabilidade de fazer uma sincronização inicial contínua também depende do tamanho da sua implantação. Para implantações extremamente grandes, pode não ser viável fazer uma sincronização inicial e, portanto, suas opções são um pouco mais limitadas. Se o WiredTiger for usado, você poderá tirar um secundário do conjunto, iniciá-lo como um autônomo, executá compact-lo e juntá-lo novamente ao conjunto.

A respeito de repairDatabase

Por favor, não execute repairDatabaseem nós de conjunto de réplicas . Isso é muito perigoso, conforme mencionado na página repairDatabase e descrito em mais detalhes abaixo.

O nome repairDatabaseé um pouco enganador, pois o comando não tenta reparar nada. O comando foi projetado para ser usado quando houver corrupção de disco em um nó autônomo , o que pode levar a documentos corrompidos.

O repairDatabasecomando pode ser descrito com mais precisão como "banco de dados de recuperação". Ou seja, ele recria os bancos de dados descartando documentos corrompidos na tentativa de colocar o banco de dados em um estado em que você possa iniciá-lo e recuperar documentos intactos.

Nas implantações do MMAPv1, essa reconstrução dos arquivos do banco de dados libera espaço para o sistema operacional como efeito colateral . Liberar espaço para o sistema operacional nunca foi o objetivo.

Consequências de repairDatabaseum conjunto de réplicas

Em um conjunto de réplicas, o MongoDB espera que todos os nós no conjunto contenham dados idênticos. Se você executar repairDatabaseem um nó de conjunto de réplicas, é possível que o nó contenha corrupção não detectada e repairDatabaseremoverá os documentos corrompidos para você.

Previsivelmente, isso faz com que o nó contenha um conjunto de dados diferente do restante do conjunto. Se uma atualização atingir esse único documento, todo o conjunto poderá falhar.

Para piorar a situação, é perfeitamente possível que essa situação permaneça adormecida por um longo tempo, apenas para atacar repentinamente sem motivo aparente.

kevinadi
fonte
5

Caso uma grande parte dos dados seja excluída de uma coleção e a coleção nunca use o espaço excluído para novos documentos, esse espaço precisará ser retornado ao sistema operacional para que possa ser usado por outros bancos de dados ou coleções. Você precisará executar uma operação compacta ou de reparo para desfragmentar o espaço em disco e recuperar o espaço livre utilizável.

O comportamento do processo de compactação depende do mecanismo do MongoDB da seguinte maneira

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

MMAPv1

A operação de compactação desfragmenta arquivos e índices de dados. No entanto, ele não libera espaço para o sistema operacional. A operação ainda é útil para desfragmentar e criar mais espaço contíguo para reutilização pelo MongoDB. No entanto, é inútil quando o espaço livre em disco é muito baixo.

Um espaço em disco adicional de até 2 GB é necessário durante a operação de compactação.

Um bloqueio no nível do banco de dados é mantido durante a operação de compactação.

WiredTiger

O mecanismo WiredTiger fornece compactação por padrão, que consome menos espaço em disco que o MMAPv1.

O processo compacto libera o espaço livre para o sistema operacional. É necessário um espaço em disco mínimo para executar a operação compacta. O WiredTiger também bloqueia todas as operações no banco de dados, pois ele precisa de bloqueio no nível do banco de dados.

Para o mecanismo MMAPv1 , o compact doest não retorna o espaço ao sistema operacional. Você precisa executar a operação de reparo para liberar o espaço não utilizado.

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

O Mongodb 3.0 e superior têm um novo mecanismo de armazenamento - WiredTiger. No meu caso, o mecanismo de comutação reduziu o uso do disco de 100 Gb para 25 Gb.

Hett
fonte
1

Arquivos de banco de dados não podem ser reduzidos em tamanho. Enquanto "reparando" o banco de dados, é possível apenas ao servidor mongo excluir alguns de seus arquivos. Se uma grande quantidade de dados foi excluída, o mongo server irá "liberar" (excluir), durante o reparo, alguns de seus arquivos existentes.

ivankoni
fonte
1

Em geral, o compacto é preferível ao repairDatabase. Mas uma vantagem do reparo em relação ao compacto é que você pode emitir o reparo para todo o cluster. compacto, você precisa fazer login em cada fragmento, o que é meio irritante.

user2077221
fonte
1

Quando tive o mesmo problema, parei meu servidor mongo e o iniciei novamente com o comando

mongod --repair

Antes de executar a operação de reparo, verifique se você tem espaço livre suficiente no disco rígido (min - é o tamanho do seu banco de dados)

Alexander Makarov
fonte
1

No modo autônomo, você pode usar compactar ou reparar,

Para cluster fragmentado ou conjunto de réplicas, na minha experiência, depois de executar o compact no primário, seguido de compactar o secundário, o tamanho do banco de dados primário reduzido, mas não o secundário. Você pode querer ressincronizar o membro para reduzir o tamanho do banco de dados secundário. e, fazendo isso, você pode achar que o tamanho do banco de dados secundário é ainda mais reduzido que o primário, acho que o comando compact realmente não compacta a coleção. Então, acabei trocando o primário e o secundário do conjunto de réplicas e fazendo o ressincronismo novamente.

Minha conclusão é que a melhor maneira de reduzir o tamanho do conjunto sharded / replica é ressincronizar, alternar o primário primário e ressincronizar novamente.

wism
fonte
0

mongoDB -repair não é recomendado no caso de cluster fragmentado.

Se estiver usando o cluster sharded do conjunto de réplicas, use o comando compact, ele reescreverá e desfragmentará todos os dados e arquivos de índice de todas as coleções. sintaxe:

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

quando usado com força: true, compacto é executado no primário do conjunto de réplicas. por exemplo db.runCommand ( { command : "collection_name", force : true } )

Outros pontos a considerar: -Bloqueia as operações. recomendado para executar na janela de manutenção. -Se os conjuntos de réplicas em execução em servidores diferentes, precisam ser executados em cada membro separadamente - No caso de cluster sharded, o compact precisa executar em cada membro shard separadamente. Não é possível executar na instância do mongos.

Seiva
fonte
-5

Apenas uma maneira de fazer isso. Nenhuma garantia sobre a segurança dos seus dados existentes. Tente com seu próprio risco.

Exclua os arquivos de dados diretamente e reinicie o mongod.

Por exemplo, com o ubuntu (caminho padrão para os dados: / var / lib / mongodb), eu tinha dois arquivos com nome como: collection. #. Eu mantenho a coleção. 0 e excluí todas as outras.

Parece uma maneira mais fácil se você não tiver dados sérios no banco de dados.

frnkxiao
fonte
os arquivos são armazenados como <nome do banco de dados>. <número> por exemplo, mydb.3 - você não pode informar a coleção.
bobmarksie