Làm thế nào để bạn đổi tên cơ sở dữ liệu MongoDB?


484

Có một lỗi đánh máy trong tên cơ sở dữ liệu MongoDB của tôi và tôi đang tìm cách đổi tên cơ sở dữ liệu.

Tôi có thể sao chép và xóa như vậy ...

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

Có một lệnh để đổi tên một cơ sở dữ liệu?


từ mongo 4.2 thậm chí copyDatabasecũng không được dùng nữa
Sumit Ramteke

Câu trả lời:


208

Không, không có. Xem https://jira.mongodb.org/browse/SERVER-701

Thật không may, đây không phải là một tính năng đơn giản để chúng tôi triển khai do cách siêu dữ liệu cơ sở dữ liệu được lưu trữ trong công cụ lưu trữ ban đầu (mặc định). Trong các tệp MMAPv1, không gian tên (ví dụ: dbName.collection) mô tả mọi bộ sưu tập và chỉ mục duy nhất bao gồm tên cơ sở dữ liệu, do đó, để đổi tên một tập hợp các tệp cơ sở dữ liệu, mỗi chuỗi không gian tên sẽ phải được viết lại. Tác động này:

  • tập tin .ns
  • mỗi tập tin được đánh số duy nhất cho bộ sưu tập
  • không gian tên cho mọi chỉ mục
  • tên duy nhất nội bộ của mỗi bộ sưu tập và chỉ mục
  • nội dung của system.namespaces và system.indexes (hoặc tương đương của chúng trong tương lai)
  • những địa điểm khác tôi có thể bị mất

Đây chỉ là để thực hiện việc đổi tên một cơ sở dữ liệu trong một trường hợp mongod độc lập . Đối với các bộ bản sao, các thao tác trên cần phải được thực hiện trên mỗi nút bản sao, cộng với mỗi nút, mỗi mục nhập oplog tham chiếu cơ sở dữ liệu này sẽ phải bị vô hiệu hoặc viết lại bằng cách nào đó, và nếu đó là một cụm bị loại bỏ, người ta cũng cần thêm các cụm này thay đổi cho mọi phân đoạn nếu DB bị phân tách, cộng với các máy chủ cấu hình có tất cả siêu dữ liệu phân đoạn về các không gian tên với tên đầy đủ của chúng.

Sẽ hoàn toàn không có cách nào để làm điều này trên một hệ thống sống.

Để thực hiện ngoại tuyến, nó sẽ yêu cầu viết lại mọi tệp cơ sở dữ liệu duy nhất để chứa tên mới và tại thời điểm đó, nó sẽ chậm như lệnh "copydb" hiện tại ...


4
Chiếc vé đó đã được mở trong một thời gian rất dài. Tôi đã thêm phiếu bầu ít quan trọng của mình vào danh sách dài.
DJ van Wyk

4
Cách họ đã xây dựng DB và giải thích nó, đổi tên dường như là không thể - có thể mất một kiến ​​trúc hoàn toàn mới. Có vẻ như một sự giám sát lớn nhưng tất cả đều công bằng trong tình yêu, chiến tranh và phát triển phần mềm.
huyết thanh

Vậy MongoDB nên có một lệnh gọi hai hàm, sao chép và thả? Tôi không thấy một lý do lớn để có lệnh này. Nhưng nó có thể tốt với một số người.
TamusJRoyce

Khi bạn đặt tên cho cơ sở dữ liệu để bắt đầu, NÊN chỉ là bí danh cho một tên nội bộ mà Mongo tạo ra (sử dụng quy ước đặt tên duy nhất trên toàn cầu). Theo cách này, việc thay đổi tên của cơ sở dữ liệu cũng đơn giản như thay đổi bí danh đó và truyền nó tới tất cả các nút trong cụm. Tôi nói NÊN. Đây không phải là trường hợp.
Lonnie hay nhất

396

Bạn có thể làm điều này:

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

Biên tập Lưu ý: đây là cách tiếp cận tương tự được sử dụng trong chính câu hỏi nhưng đã được chứng minh là hữu ích cho người khác bất kể.


38
Đối số thứ 3 thực sự có thể được bỏ qua và nó sẽ mặc định cho cùng một máy chủ.
Haakon

15
Lưu ý rằng điều này không hoạt động khi db_to_rename và db_renamed chỉ khác nhau trong trường hợp. Bạn phải sử dụng một cơ sở dữ liệu tạm thời trong tình huống đó. (Tôi vừa chạy vào đây :)
Sebastiaan M

71
Điều này khác với giải pháp do OP cung cấp như thế nào?
Salvador Dali

5
đây giống như Câu hỏi thực tế với sự khác biệt duy nhất là đối số thứ ba trong copyDatabasephương thức
Gurbakhshish Singh

2
đây giống như Câu hỏi thực tế với sự khác biệt duy nhất là đối số thứ ba trong copyDatabasephương thức *, không cần thiết, và do đó, một giải pháp tồi tệ hơn mà OP đã biết. * cc @GurbakhshishSingh
Trindaz

164

Giải pháp thay thế: bạn có thể kết xuất db của mình và khôi phục tên đó theo tên khác. Như tôi đã trải nghiệm, nó nhanh hơn nhiều 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
Điều này nhanh hơn và là một "tác dụng phụ", cơ sở dữ liệu của bạn cũng được nén.
Comtaler

Điều đó thật tuyệt! Tôi đã có một mongodumptạo. Không biết bạn có thể khôi phục nó bằng một tên khác. Cảm ơn!
Bangal Dushyant

5
LƯU Ý: Điều này không hoạt động nếu bạn sử dụng --gzipvà tạo một kho lưu trữ
Dushyant Bangal

9
Đây là cách được đề xuất ngay bây giờ, vì db.copyDatabase()hiện không được chấp nhận
osolmaz

Lưu ý rằng không, đối số --db( -d) cũng không được dùng nữa. Có một chút của một bữa tiệc mất giá đang diễn ra, dường như, được đưa ra copyDatabasecũng đã biến mất. Tôi đã chọc SERVER-701 bằng ghi chú của mình .
amcgregor

28

LƯU Ý: Hy vọng điều này đã thay đổi trong phiên bản mới nhất.

Bạn không thể sao chép dữ liệu giữa một phiên bản mongod MongoDB 4.0 (bất kể giá trị FCV) và MongoDB 3.4 và phiên bản mongod trước đó. https://docs.mongodb.com/v4.0/reference/method/db.copyDatabase/

ALERT : Hey mọi người chỉ cần cẩn thận trong khi sao chép cơ sở dữ liệu, nếu bạn không muốn làm hỏng các bộ sưu tập khác nhau trong cơ sở dữ liệu duy nhất.

Sau đây cho bạn thấy cách đổi tên

> show dbs;
testing
games
movies

Để đổi tên bạn sử dụng cú pháp sau

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

Thí dụ:

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

Bây giờ bạn có thể xóa db cũ một cách an toàn bằng cách sau

use testing;

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

Bây giờ chỉ cần nghĩ điều gì xảy ra nếu bạn thử đổi tên tên cơ sở dữ liệu mới bằng tên cơ sở dữ liệu hiện có

Thí dụ:

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

Vì vậy, trong bối cảnh này, tất cả các bộ sưu tập (bảng) thử nghiệm sẽ được sao chép vào cơ sở dữ liệu phim .



@amcgregor cảm ơn vì đã thông báo. Tôi đã thêm một bình luận cho cùng. Hy vọng nó sẽ giúp được ai đó.
Barkaveer Hakari

8

Mặc dù Mongodb không cung cấp lệnh đổi tên cơ sở dữ liệu, nhưng nó cung cấp lệnh r ename Collection , nó không chỉ sửa đổi tên bộ sưu tập mà còn sửa đổi tên cơ sở dữ liệu.

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

Lệnh này chỉ sửa đổi siêu dữ liệu, chi phí rất nhỏ, chúng ta chỉ cần duyệt qua tất cả các bộ sưu tập bên dưới db1, đổi tên thành để db2đổi tên cơ sở dữ liệu.
bạn có thể làm điều đó trong kịch bản Js này

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

những gì về chỉ mục và siêu dữ liệu khác được duy trì hoặc bị mất?
Udit Bhardwaj

@UDB Rất có khả năng được bảo quản. "Đổi tên bộ sưu tập" là một chuyển đổi không gian tên , về cơ bản bộ sưu tập của bạn có tên footrong barcơ sở dữ liệu có một không gian tên bar.foo. Các chỉ mục trên _iddo đó có không gian tên bar.foo._id_. Đổi tên bộ sưu tập (nên) thực hiện tìm kiếm tiền tố và thay thế trên tất cả các không gian tên mà nó biết, tương tự như --nsFrom--nsTo các tùy chọnmongorestore .
amcgregor

1
Chi phí có thể rất lớn! docs.mongodb.com/manual/reference/command/renameCollection/ khuyên Nếu cơ sở dữ liệu đích giống như cơ sở dữ liệu nguồn, renameCollection chỉ cần thay đổi không gian tên. Đây là một hoạt động nhanh chóng. Nếu cơ sở dữ liệu đích khác với cơ sở dữ liệu nguồn, renameCollection sẽ sao chép tất cả các tài liệu từ bộ sưu tập nguồn sang bộ sưu tập đích. Tùy thuộc vào kích thước của bộ sưu tập, việc này có thể mất nhiều thời gian hơn để hoàn thành.
nagylzs

Hãy thay đổi câu trả lời của bạn. Câu trả lời của bạn rất hữu ích, vì có thể di chuyển một bộ sưu tập sang cơ sở dữ liệu khác bằng lệnh này. Nhưng nó không chính xác, và nó có thể hiểu sai về người khác.
nagylzs

6

Quá trình trên chậm, bạn có thể sử dụng phương thức bên dưới nhưng bạn cần di chuyển bộ sưu tập theo bộ sưu tập sang db khác.

use admin
db.runCommand({renameCollection: "[db_old_name].[collection_name]", to: "[db_new_name].[collection_name]"})

Đề nghị tuyệt vời IMHO. Tuy nhiên, điều đáng chú ý là điều này sẽ không giải phóng không gian khỏi DB ban đầu nhưng việc đổi tên sẽ nhanh hơn nhiều so với sao chép dữ liệu.
sirfz

1
Dù sao đi nữa, nó vẫn thực hiện một bản sao (vì nó không xóa khoảng trống, nó không thực sự là một sự đổi tên đơn giản) vì vậy không có lợi thế thực sự cho phương pháp này so với sao chép và thả.
sirfz

5

Không có cơ chế để đặt tên lại cơ sở dữ liệu. Các câu trả lời hiện đang chấp nhận tại thời điểm viết bài là đúng với thực tế và cung cấp một số chi tiết thú vị như nền về phía thượng lưu cớ, nhưng cung cấp không có gợi ý để sao chép hành vi. Các câu trả lời khác tại copyDatabase, đây không còn là một tùy chọn vì chức năng đã bị xóa trong 4.0 . Tôi đã cập nhật SERVER-701 với các ghi chú và sự nghi ngờ của mình. 🙃

Hành vi tương đương liên quan mongodumpmongorestoretrong một chút của một điệu nhảy:

  1. Xuất dữ liệu của bạn, ghi chú các "không gian tên" đang sử dụng. Ví dụ, trên một trong các bộ dữ liệu của tôi, tôi có một bộ sưu tập với không gian tên byzmcbehoomrfjcs9vlj.Analytics- tiền tố đó ( thực ra là tên cơ sở dữ liệu ) sẽ cần thiết trong bước tiếp theo.

  2. Nhập dữ liệu của bạn, cung cấp --nsFrom--nsTođối số. ( Tài liệu. ) Tiếp tục với ví dụ giả định (và cực kỳ khó đọc) ở trên của tôi, để khôi phục lại một cái tên nhạy cảm hơn, tôi gọi:

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

Một số người cũng có thể chỉ ra --dbđối số cho mongorestore, tuy nhiên, điều này cũng không được chấp nhận và gây ra cảnh báo không sử dụng trên các bản sao lưu thư mục không phải BSON với đề xuất hoàn toàn sai lầm thành " use --nsInclude instead". Bản dịch không gian tên ở trên tương đương với việc sử dụng --dbtùy chọn và là thiết lập thao tác không gian tên chính xác để sử dụng vì chúng tôi không cố gắng lọc những gì đang được khôi phục.


1
--nsFrom--nsTolàm việc cho tôi. Cảm ơn bạn!
Bhargav Shah

mongodump với nsFrom / To là câu trả lời chính thức vào năm 2020
PaoloC

4

Tôi đã thử làm.

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

và được biết rằng nó đã bị cộng đồng mongo phản đối mặc dù nó đã tạo bản sao lưu hoặc đổi tên thành 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
}

Vì vậy, không thuyết phục với cách tiếp cận trên, tôi đã phải sử dụng Dump of local bằng lệnh bên dưới

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

kết nối với Db.

use DB_TobeRenamed

sau đó

db.dropDatabase()

sau đó khôi phục DB bằng lệnh.

mongorestore -host hostName -d Db_NewName E://FileName/

2

Trong trường hợp bạn đặt tất cả dữ liệu của mình vào cơ sở dữ liệu quản trị viên (bạn không nên), bạn sẽ nhận thấy db.copyDatabase()sẽ không hoạt động vì người dùng của bạn yêu cầu rất nhiều đặc quyền mà bạn có thể không muốn cung cấp. Đây là một kịch bản để sao chép cơ sở dữ liệu theo cách thủ công:

use old_db
db.getCollectionNames().forEach(function(collName) {
    db[collName].find().forEach(function(d){
        db.getSiblingDB('new_db')[collName].insert(d); 
    }) 
});
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.