Як перейменувати базу даних MongoDB?


483

У моєму імені бази даних 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.names та system.indexes (або їх еквіваленти в майбутньому)
  • інших місць, які мені можуть бути відсутніми

Це просто для перейменування єдиної бази даних в окремий екземпляр mongod. Для наборів реплік вищезазначене потрібно робити на кожному вузлі репліки, плюс на кожному вузлі кожен окремий запис oplog, який посилається на цю базу даних, повинен бути якось недійсним або переписаним, а потім, якщо це кладений кластер, потрібно також додати ці змінюється на кожен фрагмент, якщо БД є шарованою, плюс сервери конфігурації мають усі метадані осколки з точки зору просторів імен з їх повними іменами.

Не було б абсолютно ніякого способу зробити це в прямому ефірі.

Для цього в режимі офлайн потрібно буде переписати кожен файл баз даних, щоб вмістити нове ім'я, і ​​в цей момент це буде так само повільно, як і поточна команда "copydb" ...


4
Цей квиток був відкритий дуже давно. Я додав свій менш важливий голос до вже тривалого списку.
DJ van Wyk

4
Те, як вони побудували БД і пояснили це, перейменування видається неможливим - це може потребувати зовсім нової архітектури. Схоже, великий нагляд, але все справедливо в любові, війні та розробці програмного забезпечення.
serraosays

Отже, у MongoDB повинна бути одна команда, яка викликає дві функції, копіювати та видаляти? Я не бачу великих причин мати цю єдину команду. Але комусь це може бути приємно.
TamusJRoyce

Якщо ви почнете називати базу даних, вона повинна бути псевдонімом для внутрішнього імені, яке створює Монго (використовуючи унікальну глобальну конвенцію про іменування). Таким чином, зміна імені бази даних настільки ж проста, як і зміна цього псевдоніма та поширення його на всі вузли кластеру. Я кажу, ДОЛЖЕН. Це не так.
Lonnie Best

396

Ви можете це зробити:

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

Редакційна примітка: це той самий підхід, який застосовується в самому питанні, але виявився корисним для інших незалежно.


38
Третій аргумент насправді може бути опущений, і він буде за замовчуванням для того ж сервера.
Хокон

15
Зауважте, що це не працює, коли db_to_rename та db_renamed відрізняються лише у випадку. У цій ситуації ви повинні використовувати тимчасову базу даних. (Я щойно натрапив на це :)
Себастіян М

71
Чим це відрізняється від рішення, яке надає ОП?
Сальвадор Далі

5
це те саме, що власне питання, з тією лише різницею, що є третім аргументом у copyDatabaseметоді
Гурбахшиш Сінгх,

2
це те саме, що власне питання, з тією лише різницею, що це третій аргумент у copyDatabaseметоді *, який є непотрібним, а отже, гіршим рішенням, про яке вже знала ОП. * cc @GurbakhshishSingh
Trindaz

164

Альтернативне рішення: ви можете скинути db і відновити його під іншою назвою. Як я пережив, це набагато швидше, ніж 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/


6
Це швидше, і як "побічний ефект" ваша база даних також ущільнюється.
Comtaler

Це чудово! У мене вже було mongodumpстворене. Ви не знали, що можете відновити його з іншою назвою. Дякую!
Dushyant Bangal

5
ПРИМІТКА. Це не працює, якщо ви використовуєте --gzipта створюєте архів
Dushyant Bangal

9
Це рекомендований шлях зараз, оскільки db.copyDatabase()тепер застарілий
osolmaz

Зазначаючи, що ні, аргумент --db( -d) сам по собі також застарів. Здійснюється дещо депресійна вечірка, здається, дана copyDatabaseтакож пішла. Я ткнув СЕРВЕР-701 зі своїми замітками .
amcgregor

28

ПРИМІТКА. Сподіваємось, це змінилося в останній версії.

Ви не можете скопіювати дані між монго-екземпляром MongoDB 4.0 (незалежно від значення FCV) та MongoDB 3.4 та більш ранньою інстанцією mongod. 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')

Тепер ви можете безпечно видалити старий db наступним чином

use testing;

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

Тепер подумайте, що станеться, якщо ви спробуєте перейменувати нове ім'я бази даних на існуюче ім'я бази даних

Приклад:

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

Отже в цьому контексті всі колекції (таблиці) тестування будуть скопійовані в базу даних фільмів .



@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});
}

що з індексами та іншими метаданими вони зберігаються чи втрачаються?
Udit Bhardwaj

@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

Наведений вище процес повільний, ви можете скористатися методом нижче, але вам потрібно перенести колекцію за допомогою колекції в інший db.

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опції, і це правильна настройка маніпулювання простором імен, яку слід використовувати, оскільки ми не намагаємось фільтрувати те, що відновлюється.


1
--nsFromі --nsToпрацював на мене. Дякую!
Бхаргав Шах

mongodump with 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); 
    }) 
});
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.