【问题标题】:How do you rename a MongoDB database?如何重命名 MongoDB 数据库?
【发布时间】:2012-03-01 09:22:31
【问题描述】:

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

我可以copy 并像这样删除...

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

有重命名数据库的命令吗?

【问题讨论】:

  • 来自 mongo 4.2 甚至 copyDatabase 也是 deprecated

标签: mongodb database


【解决方案1】:

你可以这样做:

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

编者注:这与问题本身使用的方法相同,但无论如何都证明对其他人有用。

【讨论】:

  • 第三个参数其实可以省略,默认是同一个服务器。
  • 请注意,当 db_to_rename 和 db_renamed 只是大小写不同时,这不起作用。在这种情况下,您必须使用临时数据库。 (我刚遇到这个:)
  • 这与 OP 提供的解决方案有何不同?
  • 这与实际问题相同,唯一的区别是copyDatabase 方法中的第三个参数
  • 除了它几乎是原始问题中示例的复制粘贴之外,它在 4.0 之后也是无效和无功能的,因为他们已经完全删除了 copyDatabase。参考。 my answer 表示当前的现代方法。
【解决方案2】:

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


这是当前用于数据库重命名的官方 recommended approach,鉴于 MongoDB 4.2 中的 copyDatabase was removed

“copydb”命令已弃用,请改用这两个命令:

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

【讨论】:

  • 这更快,并且作为“副作用”,您的数据库也会被压缩。
  • 这太棒了!我已经创建了一个mongodump。不知道你可以用不同的名字恢复它。谢谢!
  • 注意:如果您使用 --gzip 并创建存档,这将不起作用
  • 这是现在推荐的方式,因为 db.copyDatabase() 现在已弃用
  • 请注意,不,--db (-d) 参数本身也已弃用。鉴于copyDatabase is also gone. 我已经戳了SERVER-701 with my notes
【解决方案3】:

不,没有。见https://jira.mongodb.org/browse/SERVER-701

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

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

这只是为了在 独立 mongod 实例中完成单个数据库的重命名。对于副本集,需要在每个副本节点上完成上述操作,并且在每个节点上,引用该数据库的每个 oplog 条目都必须以某种方式无效或重写,然后如果它是一个分片集群,还需要添加这些如果对数据库进行分片,则对每个分片进行更改,此外,配置服务器拥有所有分片元数据,包括名称空间及其全名。

在实时系统上绝对没有办法做到这一点。

要离线执行,需要重写每个数据库文件以适应新名称,此时它会像当前的“copydb”命令一样慢...

【讨论】:

  • 那张票已经开很久了。我已将我不太重要的一票添加到已经很长的名单中。
  • 他们构建数据库并对其进行解释的方式,重命名似乎是不可能的——可能需要一个全新的架构。似乎是一个很大的疏忽,但在爱情、战争和软件开发方面都是公平的。
  • 那么MongoDB应该有一个命令调用两个函数,copy和drop?我看不出有这个单一命令的重要理由。但这对某些人来说可能很好。
  • 当你开始命名数据库时,它应该只是 Mongo 生成的内部名称的别名(使用全局唯一的命名约定)。这样,更改数据库名称就像更改别名并将其传播到集群中的所有节点一样简单。我说应该。事实并非如此。
  • 这太离谱了
【解决方案4】:

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

您不能在 MongoDB 4.0 mongod 实例之间复制数据(无论 FCV 值)和一个 MongoDB 3.4 和更早版本的 mongod 实例。 https://docs.mongodb.com/v4.0/reference/method/db.copyDatabase/

警告:大家好,复制数据库时要小心,如果您不想弄乱单个数据库下的不同集合。

下面教你如何重命名

> show dbs;
testing
games
movies

要重命名,请使用以下语法

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

例子:

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

现在您可以通过以下方式安全地删除旧数据库

use testing;

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

现在想想如果您尝试用现有数据库名称重命名新数据库名称会发生​​什么

例子:

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

因此,在这种情况下,testing 的所有集合(表)都将被复制到 movies 数据库中。

【讨论】:

  • @amcgregor 感谢您的通知。我已经添加了相同的评论。希望对某人有所帮助。
  • db.copyDatabase 不再在 mongodb 4.4 上
  • @datinhquoc yup 将其添加为评论
【解决方案5】:

从 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

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

使用新名称恢复:

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

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

-u username --authenticationDatabase admin 

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

【讨论】:

  • 您可以使用标准输出作为管道mongodump --archive --db=old_name | mongorestore --archive --nsFrom='old_name.*' --nsTo='new_name.*' 进行重命名,而不是使用存档文件
【解决方案6】:

虽然Mongodb没有提供rename Database命令,但是提供了rename Collection command,不仅修改了集合名,还修改了数据库名。

{ 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 只是更改命名空间。这是一个快速 操作。

如果目标数据库与源数据库不同, renameCollection 将源集合中的所有文档复制到 目标集合。根据集合的大小,这 可能需要更长的时间才能完成。

【讨论】:

  • 索引和其他元数据是维护还是丢失?
  • @UDB 很可能保留。 “重命名集合”是一种命名空间转换,本质上是您在bar 数据库中名为foo 的集合具有bar.foo 的命名空间。 _id 上的索引因此具有命名空间bar.foo._id_。重命名集合(应该)在它知道的所有命名空间上执行前缀搜索和替换,类似于 --nsFrom--nsTo options to mongorestore
  • 成本可能很高! docs.mongodb.com/manual/reference/command/renameCollection/… 如果目标数据库与源数据库相同,renameCollection 只是更改命名空间。这是一个快速操作。如果目标数据库与源数据库不同,renameCollection 会将源集合中的所有文档复制到目标集合。根据集合的大小,这可能需要更长的时间才能完成。
  • 请更改您的答案。您的回答很有帮助,因为可以使用此命令将集合移动到另一个数据库。但这是不正确的,它会误导别人。
【解决方案7】:

没有重命名数据库的机制。 currently accepted answer at time of writing 实际上是正确的,并提供了一些关于上游借口的有趣背景细节,但没有提供复制行为的建议。其他答案指向copyDatabase,它不再是the functionality has been removed in 4.0 的选项。我更新了SERVER-701 with my notes 和怀疑。 ?

类似的行为涉及到mongodumpmongorestore 有点像舞蹈:

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

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

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

有些人还可能指向 mongorestore 的 --db 参数,但是这也已被弃用,并会触发警告,不要在非 BSON 文件夹备份上使用,并对“use --nsInclude instead”提出完全错误的建议。上面的命名空间转换等效于使用--db 选项,并且是正确的命名空间操作设置,因为我们没有尝试过滤正在恢复的内容。

【讨论】:

  • 带有 nsFrom/To 的 mongodump 是截至 2020 年的官方答案
  • amcgregor 链接的文档部分也有一个使用管道mongodump --archive --db=test | mongorestore --archive --nsFrom='test.*' --nsTo='examples.*'的单行示例
【解决方案8】:

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

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

【讨论】:

  • 优秀的建议恕我直言。但是,值得注意的是,这不会从原始数据库中释放空间,但重命名应该比复制数据快得多。
  • 从头开始,它确实会进行复制(因为它不会删除空格,所以它不是真正简单的重命名)所以这种方法与复制和删除相比没有真正的优势。
【解决方案9】:

我试过了。

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/

【讨论】:

【解决方案10】:

如果您将所有数据都放在管理数据库中(您不应该),您会注意到 db.copyDatabase() 不起作用,因为您的用户需要很多您可能不想授予的权限.这是一个手动复制数据库的脚本:

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

【讨论】:

  • db.copyDatabase 不再在 mongodb 4.4 上
  • 我认为这不会复制索引
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-25
  • 1970-01-01
  • 2018-03-19
  • 2013-08-29
  • 1970-01-01
相关资源
最近更新 更多