如何重命名MongoDB数据库?

在我的MongoDB数据库名称中有一个错别字,我正在寻找重命名数据库。

我可以复制然后像这样删除…

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

是否有重命名数据库的命令?

251343 次浏览

不,没有。看到# EYZ0

不幸的是,由于数据库元数据存储在原始(默认)存储引擎中的方式,这对我们来说不是一个简单的功能。在MMAPv1文件中,描述每个集合和索引的命名空间(例如:dbName.collection)包括数据库名称,因此要重命名一组数据库文件,必须重写每个命名空间字符串。这影响:

  • .ns文件
  • 收集的每一个编号文件
  • 每个索引的名称空间
  • 每个集合和索引的内部唯一名称
  • system.namespaces和system.namespaces的内容。索引(或将来的等价索引)
  • 其他我可能错过的地方

这只是为了在独立的 mongod实例中完成对单个数据库的重命名。对于复制集,需要在每个复制节点上执行上述操作,加上每个节点上引用该数据库的每个oplog条目都必须以某种方式使其失效或重写,然后如果它是一个分片集群,还需要将这些更改添加到每个分片(如果数据库是分片的),加上配置服务器拥有所有以名称空间及其全名表示的分片元数据。

在一个活跃的系统上绝对没有办法做到这一点。

如果脱机执行,则需要重新编写每个数据库文件以适应新名称,在这一点上,它将像当前的"copydb"命令一样慢…

你可以这样做,如果你使用MongoDB <4.2 (# EYZ0):

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

编者按:这与问题本身使用的方法相同,但已被证明对其他人有用。

替代解决方案:您可以转储您的数据库,并恢复到不同的名称。根据我的经验,它比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/


这是当前官方的数据库重命名推荐的方法,考虑到MongoDB 4.2中的copyDatabase 被删除了:

“copydb"命令已弃用,请使用以下两个命令:

  1. mongodump(备份数据)
  2. mongorestore(将数据从mongodb恢复到一个新的命名空间)

上面的过程很慢,你可以使用下面的方法,但你需要一个集合一个集合地移动到另一个db。

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

注意:希望在最新版本中有所改变。

不能在MongoDB 4.0 mongod实例之间复制数据 FCV值)和MongoDB 3.4和更早的mongod实例。 # EYZ0 < / p >

警报:嘿,伙计们在复制数据库时要小心,如果你不想在一个数据库下搞砸不同的集合。

下面展示了如何重命名

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

因此在这个上下文中,测试的所有集合(表)将被复制到电影数据库。

在将所有数据放入管理数据库的情况下(您不应该这样做),您将注意到db.copyDatabase()将不起作用,因为您的用户需要许多特权,您可能不想给予它。下面是一个手动复制数据库的脚本:

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

尽管Mongodb没有提供rename Database命令,但它提供了r收集命令,它不仅修改了集合名称,还修改了数据库名称。

{ renameCollection: "<source_namespace>", to: "<target_namespace>", dropTarget: <true|false>  writeConcern: <document> }
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});
}

请谨慎使用该命令

renameCollection具有不同的性能影响,具体取决于目标名称空间。

如果目标数据库和源数据库相同, renameCollection只是更改名称空间。这是一个快速的 操作。< / p >

如果目标数据库与源数据库不同, renameCollection将源集合中的所有文档复制到 目标集合。根据集合的大小,这个

没有重新命名数据库的机制。在撰写本文时,目前已接受的答案实际上是正确的,并提供了一些有趣的关于借口上游的背景细节,但没有提供复制行为的建议。其他答案指向copyDatabase,它不再是该功能在4.0中被移除的选项。我更新了SERVER-701和我的笔记和怀疑。🙃

等效行为包括mongodumpmongorestore的舞蹈:

  1. 导出数据,记录使用的“名称空间”。例如,在我的一个数据集上,我有一个命名空间为byzmcbehoomrfjcs9vlj.Analytics的集合-这个前缀(实际上是数据库名称)将在下一步中需要。

  2. 导入数据,提供--nsFrom--nsTo参数。(Documentation.)继续我上面假设的(非常难以阅读的)例子,为了恢复到一个更合理的名字,我调用:

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

有些人可能还会将--db参数指向mongorestore,然而,这也是不推荐使用的,并且会触发一个警告,反对在非bson文件夹备份上使用一个完全错误的建议“use --nsInclude instead”。上面的名称空间转换相当于使用--db选项,并且是正确的名称空间操作设置,因为我们不试图过滤正在恢复的内容。

我试过了。

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

然后才知道它已经被mongo社区弃用了,尽管它创建了备份或重命名了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
}

所以不相信上面的方法,我不得不采取转储本地使用下面的命令

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

连接到Db。

use DB_TobeRenamed

然后

db.dropDatabase()

然后使用命令恢复数据库。

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

从4.2版开始,copyDatabase已弃用。从现在开始,我们应该使用mongodumpmongorestore

假设我们有一个名为old_name的数据库,我们想把它重命名为new_name

首先,我们必须转储数据库:

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

如果您必须作为用户进行身份验证,则使用:

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

现在我们将db转储为一个名为old_name_dump.db的文件。

用新名称恢复:

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

同样,如果您需要进行身份验证,请将以下参数添加到命令中:

-u username --authenticationDatabase admin

参考:# EYZ0

mongoshdeprecederror: [COMMON-10003] copyDatabase()已被移除,因为它在MongoDB 4.0中已弃用

是的,这一切看起来都很混乱,其他答案似乎不适合我——大概是因为对工具进行了更多的更改——或者因为我使用的是旧版本。我点击上面的https://stackoverflow.com/a/63372970/1892584,直到它为我工作

我把我的答案包括在内,这样我下次就可以参考了。

我用它来转储一个存档:

# EYZ0

这将恢复到一个新的db:

# EYZ0

注意nsInclude, nsFrom和nsTo参数。

这是我的mongorestore和mongodump版本

mongodump --version
mongodump version: 100.6.0
git version: 1d46e6e7021f2f5668763dba624e34bb39208cb0
Go version: go1.17.10
os: darwin
arch: amd64
compiler: gc


mongorestore --version
mongorestore version: 100.6.0
git version: 1d46e6e7021f2f5668763dba624e34bb39208cb0
Go version: go1.17.10
os: darwin
arch: amd64
compiler: gc

谁知道这是否适用于不同的版本。