Как переименовать базу данных MongoDB?

484

В моем имени базы данных MongoDB есть опечатка, и я хочу переименовать базу данных.

Я могу копировать и удалять так ...

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

Есть ли команда переименовать базу данных?

Брайан Хемпель
источник
от Монго 4.2 даже copyDatabaseтакже не рекомендуется
Sumit Ramteke

Ответы:

208

Нет, нет Смотрите https://jira.mongodb.org/browse/SERVER-701

К сожалению, это не простая функция для нас, чтобы реализовать из-за способа, которым метаданные базы данных хранятся в исходном (по умолчанию) механизме хранения. В файлах MMAPv1 пространство имен (например, dbName.collection), которое описывает каждую отдельную коллекцию и индекс, включает имя базы данных, поэтому для переименования набора файлов базы данных необходимо переписать каждую строку пространства имен. Это влияет:

  • файл .ns
  • каждый пронумерованный файл для коллекции
  • пространство имен для каждого индекса
  • внутренние уникальные имена каждой коллекции и индекса
  • содержимое system.namespaces и system.indexes (или их эквиваленты в будущем)
  • другие места, которые я могу пропустить

Это просто, чтобы выполнить переименование одной базы данных в автономном экземпляре mongod. Для наборов реплик вышеупомянутое должно быть сделано на каждом узле реплики, плюс на каждом узле каждая запись оплога, которая ссылается на эту базу данных, должна быть каким-то образом признана недействительной или переписана, и затем, если это кластер с разделением на сегменты, также необходимо добавить эти изменяется на каждый шард, если база данных сегментирована, плюс серверы конфигурации имеют все метаданные шарда в терминах пространств имен с их полными именами.

Там не было бы абсолютно никакого способа сделать это на живой системе.

Чтобы сделать это в автономном режиме, потребуется переписать каждый файл базы данных для размещения нового имени, и в этот момент это будет так же медленно, как текущая команда «copydb» ...

pingw33n
источник
4
Этот билет был открыт очень давно. Я добавил свой менее важный голос в уже длинный список.
DJ van Wyk
4
То, как они построили БД и объяснили это, переименование кажется невозможным - может потребоваться совершенно новая архитектура. Похоже, большой недосмотр, но все справедливо в любви, войне и разработке программного обеспечения.
serraosays
Таким образом, MongoDB должна иметь одну команду, которая вызывает две функции: копировать и удалять? Я не вижу большой причины иметь эту единственную команду. Но это может быть приятно для некоторых.
TamusJRoyce
Когда вы называете базу данных для начала, это ДОЛЖНО быть просто псевдонимом для внутреннего имени, которое генерирует Mongo (используя глобально уникальное соглашение об именах). Таким образом, изменить имя базы данных так же просто, как изменить этот псевдоним и распространить его на все узлы в кластере. Я должен сказать. Это не вариант.
Lonnie Best
396

Вы могли бы сделать это:

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

От редакции. Это тот же подход, который использовался в самом вопросе, но, тем не менее, оказался полезным для других.

bzmw
источник
38
Третий аргумент может быть опущен, и он будет по умолчанию на том же сервере.
Хакон
15
Обратите внимание, что это не работает, когда db_to_rename и db_renamed отличаются только регистром. Вы должны использовать временную базу данных в этой ситуации. (Я только что столкнулся с этим :)
Себастьян M
71
Чем это отличается от решения, предоставленного ФП?
Сальвадор Дали
5
это то же самое, что и настоящий вопрос, с той лишь разницей, что третий аргумент в copyDatabaseметоде
Гурбахшиш Сингх
2
это то же самое, что и фактический Вопрос с единственным отличием, состоящим в третьем аргументе в copyDatabaseметоде *, который не нужен, и, следовательно, является худшим решением, о котором уже знал ОП. * cc @GurbakhshishSingh
Trindaz
164

Альтернативное решение: вы можете сбросить свою базу данных и восстановить ее под другим именем. Как я понял, это гораздо быстрее, чем 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
источник
6
Это быстрее и, как «побочный эффект», ваша база данных также сжимается.
Comtaler
Это замечательно! Я уже mongodumpсоздал. Не знал, что вы можете восстановить его с другим именем. Спасибо!
Dushyant Bangal
5
Примечание: Это не работает , если вы используете --gzipи создать архив
Dushyant Bangal
9
Это рекомендуемый способ сейчас, так db.copyDatabase()как теперь устарел
osolmaz
Отметив, что нет, аргумент --db( -d) сам по себе также не рекомендуется. Похоже, что-то вроде вечеринки по поводу обесценивания copyDatabaseпродолжается. Я ткнул SERVER-701 своими заметками .
amcgregor
28

ПРИМЕЧАНИЕ: надеюсь, это изменилось в последней версии.

Вы не можете копировать данные между экземпляром MongoDB 4.0 mongod (независимо от значения FCV) и экземпляром MongoDB 3.4 и более ранних версий. https://docs.mongodb.com/v4.0/reference/method/db.copyDatabase/

ALERT : Привет, ребята, будьте осторожны при копировании базы данных, если вы не хотите путать разные коллекции в одной базе данных.

Ниже показано, как переименовать

> show dbs;
testing
games
movies

Для переименования вы используете следующий синтаксис

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

Пример:

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

Теперь вы можете безопасно удалить старую базу данных следующим образом

use testing;

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

Теперь просто подумайте, что произойдет, если вы попытаетесь переименовать новое имя базы данных в существующее имя базы данных.

Пример:

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

Таким образом, в этом контексте все коллекции (таблицы) тестирования будут скопированы в базу данных фильмов .

Channaveer Hakari
источник
@amcgregor спасибо за уведомление. Я добавил комментарий к тому же. Надеюсь, это поможет кому-то.
Channaveer Hakari
8

Хотя Mongodb не предоставляет команду переименования базы данных, она предоставляет команду r ename Collection , которая не только изменяет имя коллекции, но и имя базы данных.

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

Эта команда только изменяет метаданные, стоимость очень мала, нам нужно только просмотреть все коллекции db1, переименованные db2для достижения переименования базы данных.
Вы можете сделать это в этом сценарии 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
источник
как насчет индексов и других метаданных, которые они поддерживают или потеряли?
Удит
@UDB Очень вероятно сохранился. «Переименование коллекции» - это преобразование пространства имен , по сути, ваша коллекция, названная fooв barбазе данных, имеет пространство имен bar.foo. Индекс на _idтаким образом имеет пространство имен bar.foo._id_. Переименование коллекции (должно) выполнить поиск префиксов и заменить на все пространства имен он осведомлен о том , похожи на --nsFromи --nsTo вариантуmongorestore .
amcgregor
1
Стоимость может быть ОГРОМНОЙ! docs.mongodb.com/manual/reference/command/renameCollection/… Если целевая база данных совпадает с исходной базой данных, renameCollection просто меняет пространство имен. Это быстрая операция. Если целевая база данных отличается от исходной базы данных, renameCollection копирует все документы из исходной коллекции в целевую коллекцию. В зависимости от размера коллекции, это может занять больше времени для завершения.
nagylzs
Пожалуйста, измените свой ответ. Ваш ответ полезен, поскольку с помощью этой команды можно переместить коллекцию в другую базу данных. Но это неверно и может вводить в заблуждение других.
nagylzs
6

Процесс выше медленный, вы можете использовать метод ниже, но вам нужно переместить коллекцию за коллекцией в другую базу данных.

use admin
db.runCommand({renameCollection: "[db_old_name].[collection_name]", to: "[db_new_name].[collection_name]"})
Мадан Баран
источник
Отличное предложение ИМХО. Однако стоит отметить, что это не освободит пространство от исходной БД, но переименование должно быть намного быстрее, чем копирование данных.
Sirfz
1
Поцарапайте это, он все равно делает копию (так как он не удаляет пробел, это не просто переименование), так что нет никакого реального преимущества для этого метода по сравнению с копированием и удалением.
Sirfz
5

Не существует механизма для переименования баз данных. Принято в настоящее время ответ на момент написания не является фактически правильным и предлагают некоторые интересные детали фона как на оправдание вверх по течению, но предложения нет предложений для репликации поведения. Другие ответы указывают на то copyDatabase, что больше не вариант, так как функциональность была удалена в 4.0 . Я обновил SERVER-701 своими заметками и недоверчивостью. 🙃

Эквивалентное поведение включает в себя mongodumpи mongorestoreнемного танца:

  1. Экспортируйте свои данные, отмечая используемые «пространства имен». Например, в одном из моих наборов данных у меня есть коллекция с пространством имен byzmcbehoomrfjcs9vlj.Analytics- этот префикс ( фактически имя базы данных ) понадобится на следующем шаге.

  2. Импортируйте ваши данные, предоставив --nsFromи --nsToаргументы. ( Документация. ) Продолжая мой приведенный выше гипотетический (и крайне нечитаемый) пример, чтобы восстановить более чувственное имя, я призываю:

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

Некоторые могут также указать на --dbаргумент mongorestore, однако это также устарело и выдает предупреждение против использования резервных копий папок не-BSON с совершенно ошибочным предложением "use --nsInclude instead ». Приведенный выше перевод пространства имен эквивалентен использованию этой --dbопции и является правильной настройкой для манипулирования пространством имен, поскольку мы не пытаемся фильтровать то, что восстанавливается.

amcgregor
источник
1
--nsFromи --nsToработал на меня. Спасибо!
Бхаргав Шах
mongodump с nsFrom / To - официальный ответ на 2020 год
PaoloC
4

Я пытался делать.

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

и узнал, что сообщество mongo устарело, хотя создало резервную копию или переименовало БД.

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
}

Так что, не убедившись в вышеизложенном подходе, мне пришлось взять дамп локального с помощью команды ниже

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

подключен к Db.

use DB_TobeRenamed

тогда

db.dropDatabase()

затем восстановил БД с помощью команды.

mongorestore -host hostName -d Db_NewName E://FileName/
Абхишек Кумар
источник
2

В случае, если вы поместите все свои данные в базу данных администратора (вы не должны), вы заметите, что db.copyDatabase()это не сработает, потому что вашему пользователю требуется много привилегий, которые вы, вероятно, не хотите им предоставлять. Вот скрипт для копирования базы данных вручную:

use old_db
db.getCollectionNames().forEach(function(collName) {
    db[collName].find().forEach(function(d){
        db.getSiblingDB('new_db')[collName].insert(d); 
    }) 
});
Франсуа Гутман
источник