Como você renomeia um banco de dados MongoDB?

484

Há um erro de digitação no nome do meu banco de dados MongoDB e estou procurando renomear o banco de dados.

Eu posso copiar e excluir assim ...

db.copyDatabase('old_name', 'new_name');
use old_name
db.dropDatabase();

Existe um comando para renomear um banco de dados?

Brian Hempel
fonte
do mongo 4.2 também copyDatabaseé obsoleto #
Sumit Ramteke 10/09/19

Respostas:

208

Não, não existe. Consulte https://jira.mongodb.org/browse/SERVER-701

Infelizmente, este não é um recurso simples para implementar devido à maneira como os metadados do banco de dados são armazenados no mecanismo de armazenamento original (padrão). Nos arquivos MMAPv1, o espaço para nome (por exemplo: dbName.collection) que descreve cada coleção e índice inclui o nome do banco de dados; portanto, para renomear um conjunto de arquivos de banco de dados, cada sequência de espaço para nome deve ser reescrita. Isso impacta:

  • o arquivo .ns
  • cada arquivo numerado para a coleção
  • o espaço para nome para cada índice
  • nomes exclusivos internos de cada coleção e índice
  • conteúdo de system.namespaces e system.indexes (ou seus equivalentes no futuro)
  • outros locais que podem estar faltando

Isso é apenas para realizar a renomeação de um único banco de dados em uma instância mongod independente . Para conjuntos de réplicas, o procedimento acima precisa ser feito em cada nó de réplica, além de cada nó, cada entrada de oplog que se refere a esse banco de dados precisaria ser de alguma forma invalidada ou reescrita e, se for um cluster fragmentado, também será necessário adicioná-los muda para todos os shard se o banco de dados for sharded, mais os servidores de configuração possuem todos os metadados do shard em termos de namespaces com seus nomes completos.

Não haveria absolutamente nenhuma maneira de fazer isso em um sistema ativo.

Para fazê-lo offline, seria necessário reescrever todos os arquivos de banco de dados para acomodar o novo nome e, nesse ponto, seria tão lento quanto o comando "copydb" atual ...

pingw33n
fonte
4
Esse bilhete está aberto há muito tempo. Adicionei meu voto menos importante à lista já longa.
DJ van Wyk
4
A maneira como eles criaram o banco de dados e o explicaram, renomear parece impossível - pode exigir uma arquitetura totalmente nova. Parece uma grande supervisão, mas tudo é justo em amor, guerra e desenvolvimento de software.
serraosays 19/10/2015
Portanto, o MongoDB deve ter um comando que chame duas funções, copiar e soltar? Não vejo uma grande razão para ter esse único comando. Mas poderia ser bom para alguns.
TamusJRoyce 4/17
Quando você nomeia o banco de dados para começar, isso DEVE ser apenas um apelido para um nome interno que o Mongo gera (usando uma convenção de nomenclatura globalmente exclusiva). Dessa forma, alterar o nome de um banco de dados é tão simples quanto alterar esse alias e propagá-lo para todos os nós no cluster. Eu digo DEVE. Este não é o caso.
Lonnie Melhor
396

Você pode fazer isso:

db.copyDatabase("db_to_rename","db_renamed","localhost")
use db_to_rename
db.dropDatabase();

Nota Editorial: esta é a mesma abordagem usada na pergunta em si, mas provou ser útil para outras pessoas, independentemente.

bzmw
fonte
38
O terceiro argumento pode realmente ser omitido e o padrão será o mesmo servidor.
Haakon
15
Observe que isso não funciona quando db_to_rename e db_renamed diferem apenas no caso. Você precisa usar um banco de dados temporário nessa situação. (Eu apenas corri para este :)
Sebastiaan M
71
Como isso difere da solução fornecida pelo OP?
Salvador Dali
5
este é o mesmo que a questão real com a única diferença sendo o terceiro argumento no copyDatabasemétodo
Gurbakhshish Singh
2
este é o mesmo que a questão real com a única diferença sendo o terceiro argumento no copyDatabasemétodo *, o que é desnecessário, e, portanto, uma solução pior do que aquele que o OP já estava ciente * cc @GurbakhshishSingh.
Trindaz
164

Solução alternativa: você pode despejar seu banco de dados e restaurá-lo em nome diferente. Como experimentei, é muito mais rápido que db.copyDatabase().

$ mongodump -d old_db_name -o mongodump/
$ mongorestore -d new_db_name mongodump/old_db_name

http://docs.mongodb.org/manual/tutorial/backup-with-mongodump/

tomako
fonte
6
Isso é mais rápido e, como "efeito colateral", seu banco de dados também é compactado.
Comtaler
Isso é ótimo! Eu já tinha mongodumpcriado. Não sabia que você pode restaurá-lo com um nome diferente. Obrigado!
Dushyant Bangal
5
OBSERVAÇÃO: Isso não funciona se você usar --gzipe criar um arquivo
Dushyant Bangal 31/03
9
Esta é a maneira recomendada agora, já que db.copyDatabase()agora está obsoleto
osolmaz
Observando que não, o argumento --db( -d) também é obsoleto. Parece que houve um grupo de depreciação acontecendo, dado que copyDatabasetambém se foi. Eu cutuquei o SERVER-701 com minhas anotações .
Amcgregor 5/09/19
28

NOTA: Espero que isso tenha mudado na versão mais recente.

Você não pode copiar dados entre uma instância mongod do MongoDB 4.0 (independentemente do valor FCV) e uma instância mongod do MongoDB 3.4 e anterior. https://docs.mongodb.com/v4.0/reference/method/db.copyDatabase/

ALERTA : Ei pessoal, tenha cuidado ao copiar o banco de dados, se você não quiser estragar as diferentes coleções no banco de dados único.

A seguir, mostramos como renomear

> show dbs;
testing
games
movies

Para renomear, use a seguinte sintaxe

db.copyDatabase("old db name","new db name")

Exemplo:

db.copyDatabase('testing','newTesting')

Agora você pode excluir com segurança o banco de dados antigo da seguinte maneira

use testing;

db.dropDatabase(); //Here the db **testing** is deleted successfully

Agora pense no que acontece se você tentar renomear o novo nome do banco de dados com o nome existente.

Exemplo:

db.copyDatabase('testing','movies'); 

Portanto, neste contexto, todas as coleções (tabelas) de teste serão copiadas para o banco de dados de filmes .

Channaveer Hakari
fonte
1
copyDatabasese foi. Eu cutuquei o SERVER-701 com minhas anotações .
Amcgregor 05/09/19
@amcgregor obrigado por notificar. Eu adicionei um comentário para o mesmo. Espero que ajude alguém.
Channaveer Hakari
8

Embora o Mongodb não forneça o comando rename Database, ele fornece o comando r ename Collection , que não apenas modifica o nome da coleção, mas também o nome do banco de dados.

db.adminCommand({renameCollection: "db1.test1", to: "db2.test2"})

Este comando modifica apenas os metadados, o custo é muito pequeno, precisamos apenas percorrer todas as coleções abaixo db1, renomeadas db2para conseguir renomear o nome do banco de dados.
você pode fazer isso neste script Js

var source = "source";
var dest = "dest";
var colls = db.getSiblingDB(source).getCollectionNames();
for (var i = 0; i < colls.length; i++) {
var from = source + "." + colls[i];
var to = dest + "." + colls[i];
db.adminCommand({renameCollection: from, to: to});
}
HbnKing
fonte
e os índices e outros metadados são mantidos ou perdidos?
Udit Bhardwaj
@UDB Muito provavelmente preservado. "Renomear uma coleção" é uma transformação de espaço para nome , essencialmente sua coleção nomeada foono barbanco de dados possui um espaço para nome bar.foo. O índice em, _idportanto, possui o espaço para nome bar.foo._id_. Renomear a coleção (deve) realizar uma pesquisa de prefixo e substituir em todos os namespaces de que tenha conhecimento, semelhante ao --nsFrome --nsTo opções paramongorestore .
amcgregor 10/01
1
O custo pode ser enorme! docs.mongodb.com/manual/reference/command/renameCollection/… Se o banco de dados de destino for o mesmo que o banco de dados de origem, renameCollection simplesmente altera o espaço para nome. Esta é uma operação rápida. Se o banco de dados de destino diferir do banco de dados de origem, renameCollection copia todos os documentos da coleção de origem para a coleção de destino. Dependendo do tamanho da coleção, isso pode levar mais tempo para ser concluído.
nagylzs
Por favor, mude sua resposta. Sua resposta é útil, porque é possível mover uma coleção para outro banco de dados com este comando. Mas está incorreto e pode desviar os outros.
nagylzs
6

O processo acima é lento, você pode usar o método abaixo, mas precisa mover a coleção por coleção para outro banco de dados.

use admin
db.runCommand({renameCollection: "[db_old_name].[collection_name]", to: "[db_new_name].[collection_name]"})
Madan Ram
fonte
Excelente sugestão IMHO. No entanto, vale a pena notar que isso não liberará o espaço do banco de dados original, mas a renomeação deve ser muito mais rápida do que copiar os dados.
sirfz
1
Arranhe isso, ele faz uma cópia de qualquer maneira (já que não remove o espaço, não é realmente uma simples renomeação), então não há nenhuma vantagem real nesse método sobre copiar e soltar.
sirfz
5

Não há mecanismo para renomear bancos de dados. A resposta atualmente aceita no momento da redação é factualmente correta e oferece alguns detalhes interessantes sobre a desculpa a montante, mas não oferece sugestões para replicar o comportamento. Outras respostas apontam para copyDatabase, que não é mais uma opção, pois a funcionalidade foi removida no 4.0 . Atualizei o SERVER-701 com minhas anotações e incredulidade. 🙃

Comportamento equivalente envolve mongodumpe mongorestoreem um pouco de dança:

  1. Exporte seus dados, anotando os "namespaces" em uso. Por exemplo, em um dos meus conjuntos de dados, tenho uma coleção com o namespace byzmcbehoomrfjcs9vlj.Analytics- esse prefixo ( na verdade o nome do banco de dados ) será necessário na próxima etapa.

  2. Importe seus dados, fornecimento --nsFrome --nsToargumentos. ( Documentação. ) Continuando com o meu exemplo hipotético (e extremamente ilegível) acima, para restaurar um nome mais sensato, invoco:

mongorestore --archive=backup.agz --gzip --drop \
    --nsFrom 'byzmcbehoomrfjcs9vlj.*' --nsTo 'rita.*'

Alguns também podem apontar o --dbargumento para o armazenamento múltiplo, mas isso também foi preterido e dispara um aviso contra o uso em backups de pastas não BSON com uma sugestão completamente incorreta de " use --nsInclude instead". A conversão de espaço para nome acima é equivalente ao uso da --dbopção e é a configuração correta de manipulação do espaço para nome, pois não estamos tentando filtrar o que está sendo restaurado.

amcgregor
fonte
1
--nsFrome --nsTotrabalhou para mim. Obrigado!
Bhargav Shah
mongodump com nsFrom / Para são a resposta oficial a partir de 2020
PaoloC
4

Eu tentei fazer.

db.copyDatabase('DB_toBeRenamed','Db_newName','host') 

e soube que foi preterido pela comunidade mongo, embora tenha criado o backup ou renomeado DB.

WARNING: db.copyDatabase is deprecated. See http://dochub.mongodb.org/core/copydb-clone-deprecation
{
        "note" : "Support for the copydb command has been deprecated. See 
        http://dochub.mongodb.org/core/copydb-clone-deprecation",
        "ok" : 1
}

Portanto, não convencido com a abordagem acima, tive que usar o Dump of local usando o comando abaixo

mongodump --host --db DB_TobeRenamed --out E://FileName/

conectado ao Db.

use DB_TobeRenamed

então

db.dropDatabase()

depois restaurou o banco de dados com o comando

mongorestore -host hostName -d Db_NewName E://FileName/
Abhishek kumar
fonte
2

No caso de você colocar todos os seus dados no banco de dados do administrador (não deveria), você notará db.copyDatabase()que não funcionará porque seu usuário exige muitos privilégios que você provavelmente não deseja conceder. Aqui está um script para copiar o banco de dados manualmente:

use old_db
db.getCollectionNames().forEach(function(collName) {
    db[collName].find().forEach(function(d){
        db.getSiblingDB('new_db')[collName].insert(d); 
    }) 
});
François Guthmann
fonte