Jak zmienić nazwę bazy danych MongoDB?

483

W nazwie bazy danych MongoDB jest literówka i chcę zmienić nazwę bazy danych.

Mogę tak kopiować i usuwać ...

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

Czy istnieje polecenie zmiany nazwy bazy danych?

Brian Hempel
źródło
od mongo 4.2 nawet copyDatabasejest przestarzałe
Sumit Ramteke 10.09.19

Odpowiedzi:

208

Nie, nie ma. Zobacz https://jira.mongodb.org/browse/SERVER-701

Niestety nie jest to łatwa funkcja do wdrożenia ze względu na sposób, w jaki metadane bazy danych są przechowywane w oryginalnym (domyślnym) silniku pamięci. W plikach MMAPv1 przestrzeń nazw (np .: dbName.collection), która opisuje każdą pojedynczą kolekcję i indeks, zawiera nazwę bazy danych, więc aby zmienić nazwę zestawu plików bazy danych, każdy ciąg przestrzeni nazw musiałby zostać przepisany. Wpływa to na:

  • plik .ns
  • każdy numerowany plik dla kolekcji
  • przestrzeń nazw dla każdego indeksu
  • wewnętrzne unikalne nazwy każdej kolekcji i indeksu
  • zawartość system.namespaces i system.indexes (lub ich odpowiedniki w przyszłości)
  • inne lokalizacje, których może mi brakować

Ma to na celu zmianę nazwy pojedynczej bazy danych w trybie autonomicznym instancji mongod. W przypadku zestawów replik powyższe czynności należy wykonać na każdym węźle repliki, a na każdym węźle każdy wpis oplog, który odnosi się do tej bazy danych, musiałby zostać w jakiś sposób unieważniony lub przepisany, a następnie, jeśli jest to klaster dzielony, należy również dodać te zmienia się w każdym fragmencie, jeśli DB jest dzielony, a ponadto serwery konfiguracji mają wszystkie metadane fragmentu pod względem przestrzeni nazw z ich pełnymi nazwami.

Nie byłoby absolutnie żadnego sposobu, aby to zrobić w systemie na żywo.

Aby to zrobić w trybie offline, konieczne będzie ponowne zapisanie każdego pliku bazy danych w celu dostosowania go do nowej nazwy, a w tym momencie będzie on tak wolny, jak obecne polecenie „copydb” ...

pingw33n
źródło
4
Ten bilet był otwarty od bardzo dawna. Dodałem mój mniej ważny głos do już długiej listy.
DJ van Wyk
4
Sposób, w jaki zbudowali DB i wyjaśnili to, zmiana nazwy wydaje się niemożliwa - może zająć zupełnie nową architekturę. Wydaje się, że to duży nadzór, ale wszystko jest uczciwe w miłości, wojnie i tworzeniu oprogramowania.
serraosays
Więc MongoDB powinien mieć jedno polecenie, które wywołuje dwie funkcje, kopiowanie i upuszczanie? Nie widzę wielkiego powodu, aby mieć to jedno polecenie. Ale dla niektórych może być miło.
TamusJRoyce
Gdy na początek nazywasz bazę danych, POWINIEN być po prostu aliasem nazwy wewnętrznej generowanej przez Mongo (przy użyciu unikalnej na całym świecie konwencji nazewnictwa). W ten sposób zmiana nazwy bazy danych jest tak prosta, jak zmiana tego aliasu i propagowanie go do wszystkich węzłów w klastrze. Mówię POWINNY. Nie o to chodzi.
Lonnie Best,
396

Możesz to zrobić:

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

Nota redakcyjna: to samo podejście zastosowano w samym pytaniu, ale okazało się przydatne dla innych niezależnie.

bzmw
źródło
38
Trzeci argument może zostać pominięty i domyślnie będzie używany na tym samym serwerze.
Haakon
15
Zauważ, że to nie działa, gdy db_to_rename i db_renamed różnią się tylko wielkością liter. W takiej sytuacji musisz użyć tymczasowej bazy danych. (Właśnie wpadłem na to :)
Sebastiaan M
71
Czym różni się to od rozwiązania dostarczonego przez PO?
Salvador Dali,
5
jest to to samo, co rzeczywiste Pytanie, z tą różnicą, że trzecim argumentem jest copyDatabasemetoda
Gurbakhshish Singh,
2
jest to to samo, co rzeczywiste Pytanie, z tą różnicą, że trzeci argument w copyDatabasemetodzie * jest niepotrzebny, a zatem gorsze rozwiązanie niż to, o którym OP wiedział już. * cc @GurbakhshishSingh
Trindaz
164

Alternatywne rozwiązanie: możesz zrzucić swoją bazę danych i przywrócić ją pod inną nazwą. Jak się przekonałem, jest to o wiele szybsze niż 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
źródło
6
Jest to szybsze i jako „efekt uboczny” twoja baza danych jest również kompaktowana.
Comtaler
To jest świetne! Miałem już mongodumpstworzone. Nie wiedziałem, że możesz przywrócić go pod inną nazwą. Dzięki!
Dushyant Bangal
5
UWAGA: To nie działa, jeśli używasz --gzipi tworzysz archiwum
Dushyant Bangal
9
Jest to teraz zalecany sposób, ponieważ db.copyDatabase()jest już przestarzały
osolmaz
Należy zauważyć, że nie, sam argument --db( -d) również jest przestarzały. Wygląda na to, że impreza o charakterze wycofującym się trwa copyDatabase. Szturchnąłem SERVER-701 notatkami .
amcgregor
28

UWAGA: Mam nadzieję, że zmieniło się to w najnowszej wersji.

Nie można kopiować danych między instancją MongoDB 4.0 (niezależnie od wartości FCV) a instancją MongoDB 3.4 i wcześniejszą mongod. https://docs.mongodb.com/v4.0/reference/method/db.copyDatabase/

ALERT : Hej, bądźcie ostrożni podczas kopiowania bazy danych, jeśli nie chcecie zepsuć różnych kolekcji w ramach jednej bazy danych.

Poniżej pokazano, jak zmienić nazwę

> show dbs;
testing
games
movies

Aby zmienić nazwę, użyj następującej składni

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

Przykład:

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

Teraz możesz bezpiecznie usunąć starą bazę danych w następujący sposób

use testing;

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

Teraz zastanów się, co się stanie, jeśli spróbujesz zmienić nazwę nowej bazy danych na istniejącą

Przykład:

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

W tym kontekście wszystkie kolekcje (tabele) testowania zostaną skopiowane do bazy filmów .

Channaveer Hakari
źródło
1
copyDatabaseprzepadło. Szturchnąłem SERVER-701 notatkami .
amcgregor
@amcgregor dzięki za powiadomienie. Dodałem komentarz do tego samego. Mam nadzieję, że to komuś pomoże.
Channaveer Hakari,
8

Chociaż Mongodb nie udostępnia polecenia zmiany nazwy Bazy danych, udostępnia polecenie Kolekcja nazwy , które nie tylko modyfikuje nazwę kolekcji, ale także modyfikuje nazwę bazy danych.

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

To polecenie modyfikuje tylko metadane, koszt jest bardzo mały, wystarczy przejrzeć wszystkie kolekcje db1, których nazwa została zmieniona, db2aby uzyskać nazwę bazy danych.
możesz to zrobić w tym skrypcie 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
źródło
co z indeksami i innymi metadanymi, które są utrzymywane lub utracone?
Udit Bhardwaj,
@UDB Prawdopodobnie zachowane. „Zmiana nazwy kolekcji” to transformacja przestrzeni nazw , zasadniczo twoja kolekcja nazwana foow barbazie danych ma przestrzeń nazw bar.foo. Indeks on _idma zatem przestrzeń nazw bar.foo._id_. Zmień nazwę kolekcji (należy) wykonać wyszukiwanie prefiksu i zastąpić wszystkie znane przestrzenie nazw, podobne do opcji--nsFrom i . --nsTo mongorestore
amcgregor
1
Koszt może być OGROMNY! docs.mongodb.com/manual/reference/command/renameCollection/... Jeśli docelowa baza danych jest taka sama jak źródłowa baza danych, renameCollection po prostu zmienia przestrzeń nazw. To jest szybka operacja. Jeśli docelowa baza danych różni się od źródłowej bazy danych, renameCollection kopiuje wszystkie dokumenty z kolekcji źródłowej do kolekcji docelowej. W zależności od wielkości kolekcji może to potrwać dłużej.
nagylzs
Zmień swoją odpowiedź. Twoja odpowiedź jest pomocna, ponieważ za pomocą tego polecenia można przenieść kolekcję do innej bazy danych. Ale jest niepoprawny i może wprowadzać w błąd innych.
nagylzs
6

Powyższy proces jest powolny, możesz użyć poniższej metody, ale musisz przenieść kolekcję według kolekcji do innej bazy danych.

use admin
db.runCommand({renameCollection: "[db_old_name].[collection_name]", to: "[db_new_name].[collection_name]"})
Madan Baran
źródło
Doskonała sugestia IMHO. Warto jednak zauważyć, że nie zwolni to miejsca z oryginalnej bazy danych, ale zmiana nazwy powinna być znacznie szybsza niż kopiowanie danych.
sirfz
1
Zarysuj to, i tak robi kopię (ponieważ nie usuwa przestrzeni, to nie jest tak naprawdę prosta zmiana nazwy), więc nie ma realnej przewagi tej metody nad kopiowaniem i upuszczaniem.
Sirfz,
5

Nie ma mechanizmu zmiany nazw baz danych. Obecnie akceptowane odpowiedź w chwili pisania jest prawdziwa i oferuje pewne ciekawe tło szczegółowo, jak do Upstream wybaczyć, ale nie oferuje żadnych sugestii dla replikacji zachowania. Inne odpowiedzi wskazują na copyDatabase, która nie jest już opcją, ponieważ funkcjonalność została usunięta w 4.0 . Zaktualizowałem SERVER-701 za pomocą moich notatek i niedowierzaniem. 🙃

Równoważne zachowanie polega mongodumpi mongorestorena kawałku tańca:

  1. Wyeksportuj dane, zwracając uwagę na „używane przestrzenie nazw”. Na przykład w jednym z moich zestawów danych mam kolekcję z przestrzenią nazw byzmcbehoomrfjcs9vlj.Analytics- ten przedrostek ( właściwie nazwa bazy danych ) będzie potrzebny w następnym kroku.

  2. Importuj swoje dane, dostarczając --nsFromi --nsToargumenty. ( Dokumentacja. ) Kontynuując mój powyższy hipotetyczny (i niezwykle nieczytelny) przykład, aby przywrócić bardziej sensowną nazwę, wzywam:

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

Niektórzy mogą również wskazywać na --dbargument dotyczący sklepu mongorestore, jednak to również jest przestarzałe i powoduje ostrzeżenie przed użyciem w kopiach zapasowych folderów spoza BSON z całkowicie błędną sugestią „ use --nsInclude instead”. Powyższe tłumaczenie przestrzeni nazw jest równoważne z użyciem tej --dbopcji i jest poprawnym ustawieniem manipulacji przestrzenią nazw, którego należy użyć, ponieważ nie próbujemy filtrować przywracanych plików.

amcgregor
źródło
1
--nsFromi --nsTopracował dla mnie. Dziękuję Ci!
Bhargav Shah
mongodump with nsFrom / To to oficjalna odpowiedź na rok 2020
PaoloC
4

Próbowałem zrobić.

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

i dowiedział się, że został wycofany przez społeczność mongo, chociaż utworzył kopię zapasową lub zmienił nazwę 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
}

Więc nie przekonany powyższym podejściem, musiałem wziąć zrzut lokalnego za pomocą polecenia poniżej

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

podłączony do Db.

use DB_TobeRenamed

następnie

db.dropDatabase()

następnie przywrócono DB za pomocą polecenia.

mongorestore -host hostName -d Db_NewName E://FileName/
Abhishek Kumar
źródło
2

Jeśli umieścisz wszystkie dane w bazie danych administratora (nie powinieneś), zauważysz, db.copyDatabase()że nie będzie działać, ponieważ użytkownik wymaga wielu uprawnień, których prawdopodobnie nie chcesz mu nadać. Oto skrypt do ręcznego skopiowania bazy danych:

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