mongodb - 与删除的成员形成一个新的副本集

标签 mongodb replication data-migration mongodb-replica-set

如何配置已删除的副本集成员以形成新的副本集?

我有一个包含 4 个 mongod 实例的副本集

rs.config() 的输出

{
    "_id" : "rs0",
    "members" : [
        {
            "_id" : 0,
            "host" : "localhost:27031"
        },
        {
            "_id" : 1,
            "host" : "localhost:27032"
        },
        {
            "_id" : 2,
            "host" : "localhost:27033"
        },
        {
            "_id" : 3,
            "host" : "localhost:27034"
        }
    ],
    "settings" : {
       "replicaSetId" : ObjectId("5cf22332f5b9d21b01b9b6b2") 
    }
}

我从副本集中删除了 2 个实例

rs.remove("localhost:27033")
rs.remove("localhost:27034")

现在我的要求是用这 2 个已删除的成员组成一个新的副本集。最好的方法是什么?

我目前的解决方案

连接到删除的成员

mongo --port 27033

并执行

conf = {
        "_id" : "rs0",
        "members" : [
            {
                "_id" : 2,
                "host" : "localhost:27033"
            },
            {
                "_id" : 3,
                "host" : "localhost:27034"
            }
        ],
        "settings" : {
           "replicaSetId" : ObjectId("5cf22332f5b9d21b01b9b6b2") 
        }
    }

然后

rs.reconfig(conf, {force:true})

结果

这个解决方案在实践中运行良好。 删除的成员形成一个复制集,其中一个成为主要成员,其他成员成为次要成员。数据在它们之间被复制。 而且这个副本集似乎与它们被删除的初始副本集是隔离的。

疑虑

1) 我必须使用强制重新配置。不确定后果。

"errmsg" : "replSetReconfig should only be run on PRIMARY, but my state is REMOVED; use the \"force\" argument to override",

2)新的副本集真的是新的吗?在 rs.config()

  • replicaSetId 与旧的相同。

    "replicaSetId": ObjectId("5cf22332f5b9d21b01b9b6b2")

  • 我必须为成员的 _id 使用与旧副本集配置中相同的值

    “errmsg”:“新旧配置都有主机为 localhost:27034 的成员,但在新配置中,_id 字段为 1,在旧配置中,副本集 rs0 为 3”,

这个解决方案好吗?

有没有更好的解决方案?

注意:我需要在新副本集中保留旧副本集中的数据(删除时存在的数据)。

最佳答案

正如您所怀疑的,该过程没有创建新的副本集。相反,它是旧副本集的延续,尽管从表面上看它们看起来不同。

实际上在 MongoDB 文档中有一个过程可以做你想做的事:Restore a Replica Set from MongoDB Backups .不同之处在于,您不是从备份中恢复。相反,您正在使用一个已删除的辅助节点来播种新的副本集。

因此您需要修改上面链接中提到的过程中的第一步。其余过程仍然相同:

  1. 以独立方式重新启动已删除的辅助节点(不使用 --replSet 参数)并使用 mongo shell 连接到它。
  2. 本地数据库拖放到独立节点中:

    use local
    db.dropDatabase()
    
  3. 重新启动 ex-secondary,这次使用 --replSet 参数(使用新的副本集名称)

  4. 使用 mongo shell 连接到它。
  5. rs.initiate() 新集合。

在此之后,与旧集相比,新集应该具有不同的 replicaSetId。在我对上述过程的快速测试中,这是我看到的结果:

旧集:

> rs.conf()
...
"replicaSetId": ObjectId("5cf45d72a1c6c4de948ff5d8")
...

新集

> rs.conf()
...
"replicaSetId": ObjectId("5cf45d000dda9e1025d6c65e")
...

对于像这样的任何重大部署更改,请确保您有备份,并在生产系统上执行之前彻底测试这些过程。

关于mongodb - 与删除的成员形成一个新的副本集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56405568/

相关文章:

mongodb - 为什么我无法安装特定版本的 MongoDB?

执行大量写入时 MongoDB 光标超时

mysql 5.5.41 复制错误 ubuntu 14.04

mysql - 如何在 MySQL 中按周分组?

java - java中从mongodb中提取ObjectId

node.js - MongoDB,网上没有关于事务和读操作交互的信息

java - 将数据从 Redis 迁移到 Microsoft Azure 的最佳方式是什么

entity-framework - EF 代码优先模型是否旨在完整描述数据库的结构?

sql-server - 使用重复的 SQL Server 数据库进行查询

mysql - 如何在mysql中手动复制master故障的场景