ChatGPT解决这个技术问题 Extra ChatGPT

How do you rename a MongoDB database?

There's a typo in my MongoDB database name and I'm looking to rename the database.

I can copy and delete like so...

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

Is there a command to rename a database?

from mongo 4.2 even copyDatabase is also deprecated

m
mcont

You could do this, if you're using MongoDB < 4.2 (ref):

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

Editorial Note: this is the same approach used in the question itself but has proven useful to others regardless.


The 3rd argument can actually be omitted, and it will default to the same server.
Note that this doesn't work when db_to_rename and db_renamed only differ in case. You have to use a temporary database in that situation. (I just ran into this :)
How is this different from the solution provided by the OP?
this is same as the actual Question with the only difference being the third argument in copyDatabase method
Beyond it almost being a copy-paste of the sample from the original question, it's also invalid and non-functional after 4.0, as they've removed copyDatabase entirely. Ref. my answer for the current, modern approach.
M
M. Justin

Alternative solution: you can dump your db and restore that in different name. As I've experienced it's much quicker than 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/

This is the current official recommended approach for database renames, given that copyDatabase was removed in MongoDB 4.2:

The "copydb" command is deprecated, please use these two commands instead: mongodump (to back up data) mongorestore (to recover data from mongodump into a new namespace)


This is faster and as a "side effect", your database is compacted as well.
This is great! I already had a mongodump created. Didnt know you can restore it with a different name. Thanks!
NOTE: This doesn't work if you use --gzip and create an archive
This is the recommended way now, since db.copyDatabase() is now deprecated
Noting that no, the --db (-d) argument is itself also deprecated. There's been a bit of a deprecation party going on, it seems, given copyDatabase is also gone. I've poked SERVER-701 with my notes.
g
gnat

No there isn't. See https://jira.mongodb.org/browse/SERVER-701

Unfortunately, this is not an simple feature for us to implement due to the way that database metadata is stored in the original (default) storage engine. In MMAPv1 files, the namespace (e.g.: dbName.collection) that describes every single collection and index includes the database name, so to rename a set of database files, every single namespace string would have to be rewritten. This impacts: the .ns file every single numbered file for the collection the namespace for every index internal unique names of each collection and index contents of system.namespaces and system.indexes (or their equivalents in the future) other locations I may be missing This is just to accomplish a rename of a single database in a standalone mongod instance. For replica sets the above would need to be done on every replica node, plus on each node every single oplog entry that refers this database would have to be somehow invalidated or rewritten, and then if it's a sharded cluster, one also needs to add these changes to every shard if the DB is sharded, plus the config servers have all the shard metadata in terms of namespaces with their full names. There would be absolutely no way to do this on a live system. To do it offline, it would require re-writing every single database file to accommodate the new name, and at that point it would be as slow as the current "copydb" command...


That ticket has been open for a very long time. I've added my less-than-important vote to the already long list.
The way they have built the DB and explained it, renaming seems impossible - might take a whole new architecture. Seems like a big oversight but all is fair in love, war and software development.
So MongoDB should have one command that calls two functions, copy and drop? I don't see a big reason to have this single command. But it could be nice to some.
When you name the database to begin with, that SHOULD just be an alias for an internal-name that Mongo generates (using a globally unique naming convention). This way, changing a database's name is as simple as changing that alias and propagating it to all nodes in the cluster. I say SHOULD. This is not the case.
that's outrageous
C
Channaveer Hakari

NOTE: Hopefully this changed in the latest version. You cannot copy data between a MongoDB 4.0 mongod instance (regardless of the FCV value) and a MongoDB 3.4 and earlier mongod instance. https://docs.mongodb.com/v4.0/reference/method/db.copyDatabase/

ALERT: Hey folks just be careful while copying the database, if you don't want to mess up the different collections under single database.

The following shows you how to rename

> show dbs;
testing
games
movies

To rename you use the following syntax

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

Example:

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

Now you can safely delete the old db by the following way

use testing;

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

Now just think what happens if you try renaming the new database name with existing database name

Example:

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

So in this context all the collections (tables) of testing will be copied to movies database.


@amcgregor thanks for notifying. I have added a comment for the same. Hope it helps some one.
db.copyDatabase is no longer on mongodb 4.4
@datinhquoc yup added that as comment
R
Ravexina

From version 4.2, the copyDatabase is deprecated. From now on we should use: mongodump and mongorestore.

Let's say we have a database named: old_name and we want to rename it to new_name.

First we have to dump the database:

mongodump --archive="old_name_dump.db" --db=old_name

If you have to authenticate as a user then use:

mongodump -u username --authenticationDatabase admin \
          --archive="old_name_dump.db" --db=old_name

Now we have our db dumped as a file named: old_name_dump.db.

To restore with a new name:

mongorestore --archive="old_name_dump.db" --nsFrom="old_name.*" --nsTo="new_name.*"

Again, if you need to be authenticated add this parameters to the command:

-u username --authenticationDatabase admin 

Reference: https://docs.mongodb.com/manual/release-notes/4.2-compatibility/#remove-support-for-the-copydb-and-clone-commands


Instead of using an archive file, you can do the rename using the standard output as pipeline mongodump --archive --db=old_name | mongorestore --archive --nsFrom='old_name.*' --nsTo='new_name.*'
t
turivishal

Although Mongodb does not provide the rename Database command, it provides the rename Collection command, which not only modifies the collection name, but also modifies the database name.

{ renameCollection: "<source_namespace>", to: "<target_namespace>", dropTarget: <true|false>  writeConcern: <document> }
db.adminCommand({renameCollection: "db1.test1", to: "db2.test2"})

This command only modifies the metadata, the cost is very small, we only need to traverse all the collections under db1, renamed to db2 to achieve rename Database name.
you can do it in this Js script

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

Be careful when you use this command

renameCollection has different performance implications depending on the target namespace. If the target database is the same as the source database, renameCollection simply changes the namespace. This is a quick operation. If the target database differs from the source database, renameCollection copies all documents from the source collection to the target collection. Depending on the size of the collection, this may take longer to complete.


what about indexes and other metadata are they maintained or lost?
@UDB Very likely preserved. "Renaming a collection" is a namespace transformation, essentially your collection named foo within the bar database has a namespace of bar.foo. The index on _id thus has the namespace bar.foo._id_. Renaming the collection (should) perform a prefix search and replace on all namespaces it is aware of, similar to the --nsFrom and --nsTo options to mongorestore.
The cost can be HUGE! docs.mongodb.com/manual/reference/command/renameCollection/… If the target database is the same as the source database, renameCollection simply changes the namespace. This is a quick operation. If the target database differs from the source database, renameCollection copies all documents from the source collection to the target collection. Depending on the size of the collection, this may take longer to complete.
Please change your answer. Your answer is helpful, because it is possible to move a collection to another database with this command. But it is incorrect, and it can misguide others.
a
amcgregor

There is no mechanism to re-name databases. The currently accepted answer at time of writing is factually correct and offers some interesting background detail as to the excuse upstream, but offers no suggestions for replicating the behavior. Other answers point at copyDatabase, which is no longer an option as the functionality has been removed in 4.0. I've updated SERVER-701 with my notes and incredulity. 🙃

Equivalent behavior involves mongodump and mongorestore in a bit of a dance:

Export your data, making note of the "namespaces" in use. For example, on one of my datasets, I have a collection with the namespace byzmcbehoomrfjcs9vlj.Analytics — that prefix (actually the database name) will be needed in the next step. Import your data, supplying --nsFrom and --nsTo arguments. (Documentation.) Continuing with my above hypothetical (and extremely unreadable) example, to restore to a more sensical name, I invoke:

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

Some may also point at the --db argument to mongorestore, however this, too, is deprecated and triggers a warning against use on non-BSON folder backups with a completely erroneous suggestion to "use --nsInclude instead". The above namespace translation is equivalent to use of the --db option, and is the correct namespace manipulation setup to use as we are not attempting to filter what is being restored.


mongodump with nsFrom/To are the official answer as of 2020
The documentation part amcgregor linked also has a one-liner example using pipe mongodump --archive --db=test | mongorestore --archive --nsFrom='test.*' --nsTo='examples.*'
m
madan ram

The above process is slow,you can use below method but you need to move collection by collection to another db.

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

Excellent suggestion IMHO. However, it's worth noting that this won't free up the space from the original DB but the rename should be much faster than copying the data.
Scratch that, it does do a copy anyway (since it doesn't remove the space, it's not really a simple rename) so there's no real advantage to this method over copy and drop.
A
Abhishek kumar

I tried doing.

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

and came to know that it has been Deprecated by the mongo community although it created the backup or renamed 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
}

So not convinced with the above approach I had to take Dump of local using below command

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

connected to Db.

use DB_TobeRenamed

then

db.dropDatabase()

then restored the DB with command.

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

This is the official approach based on the deprecation docs.
C
Cœur

In the case you put all your data in the admin database (you shouldn't), you'll notice db.copyDatabase() won't work because your user requires a lot of privileges you probably don't want to give it. Here is a script to copy the database manually:

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

db.copyDatabase is no longer on mongodb 4.4
I don't think this will copy indexes