更新时间:2022-08-12 11:26:34
1. 集群重建前,需确保目标实例和源实例保持 MongoDB 版本、分片数量一致。如:源实例有分片集 shard1 和 shard2 两个分片集,则目标实例也需要有两个分片集。以下以 192.168.120.162、192.168.120.163 为例,进行集群重建,该集群有两个分片:shard1、shard2。
注意:
示例按照原实例恢复的方式进行的恢复,如果原实例正在使用,请重新选择一个目标实例恢复,避免造成数据损失。
如果你的原始数据库已经损坏不能访问,你希望数据还存储在原集群的存储位置,建议你备份完清空原文件夹,然后将恢复出来的数据文件复制到原实例对应的目录下,最后再参照文档进行集群重建。

2. 依次登录所有的 mongos、shard 节点,并关闭服务,以关闭 35003 端口的 mongos 服务为例。关闭节点服务命令可参考:
use admin
db.auth(‘root’, ‘eisoo.com123’)
db.shutdownServer()


3. 关闭所有的 config 从节点,修改 config 主节点的配置文件(也可以关闭所有的 config 节点,选择其中一个节点作为主节点)。修改 dbpath 为恢复后 config 数据保存的路径,并将 configsvr、replSet、auth、keyFile 等参数注释起来,保存配置文件,然后重启 config 主节点服务,具体可参考图示。

注意:
为表述方便,以下将目标实例的 config、shard 节点的主从节点,直接表述为 config、shard 主/从节点。

4.  登录 config 主节点,删除源实例的 local 库。
use local
db.dropDatabase()

5. 更改 config 库中的 shard 副本集信息。
进入 config 库,进行分片信息的查询,命令可参考:
use config
db.shards.find( { "_id" : "" } )
如果分片集的端口不是要使用的分片端口,需要更新分片集信息,命令可参考:db.shards.updateOne({ "_id" : "shard1" },{ $set : { "host" : "/shard host1: shard  port1, shard host2: shard port2, shard host3: shard port3" } })


注意:
请将命令中的 、shard host1、shard port1 等更换成相应的分片名、主机 ip 和端口号。具体请参考上图。
图示分片信息之前已更改完成,为方便参考,运行了 db.shards.updateOne 命令,可根据实际情况选择是否执行这一步。

更新完所有分片信息后,更改 config 主节点的配置文件,如图,取消掉第3步中 configsvr、replSet、auth、keyFile 等参数的注释,重启 config 主节点服务,如图,使用源实例的用户名和密码登录该节点并执行 rs.initiate() 命令对集群进行初始化。



6. 清空所有 config 从节点上存储的 config 数据的文件,并重启所有的 config 从节点服务。在主节点上执行:rs.add("config_ip:config_port"),依次将所有的 config 从节点加入进来。以增加一个 192.168.120.162 主机上 36003 端口的 config 从节点为例,可根据实际情况增加节点。
注意:
•  config 节点存储数据的文件路径可以参考相关配置文件中的dbpath路径。
•  清空所有 config 从节点的数据文件时,可以先修改 config 从节点存储数据的文件名,并新建一个相同名称的文件夹用来存储数据。


  7. 选择分片上的一个 shard 节点作为主节点,修改配置文件,给 shardsvr、replSet、auth、keyFile 等参数添加注释,将dbpath修改为恢复的shard数据路径,并该重启 shard 节点,然后执行以下命令
use admin
创建超级角色用户:
db.createUser({
user: "mySystemUser",
pwd: "eisoo.com123",
roles:[ "__system" ],
mechanisms: ["SCRAM-SHA-1"]})
登录超级角色用户,删除 loca l数据库:
db.auth("mySystemUser","eisoo.com123")
use local
db.dropDatabase()
从admin.system.versions集合中删除minOpTimeRecovery文档:
use admin
db.system.version.deleteOne( { _id: "minOpTimeRecovery" } )
查找分片关联的信息:
use admin
db.system.version.find( {"_id" : "shardIdentity" } )  
修改分片信息,将当前分片和config节点信息关联起来,(可根据上一步查找到的信息,选择是否更新分片信息):

db.system.version.updateOne({ "_id" : "shardIdentity" },{ $set :{ "configsvrConnectionString" : "configs_name/config_ip1:config_port1, config_ip2:config_port2…"}})


8. 修改 shard 主节点配置文件,取消掉第 8 步中 shardsvr、replSet、auth、keyFile 等参数的注释,如图,重启 shard 主节点后,使用源实例用户名密码登录,执行命令:rs.initiate() 进行初始化。



9. 删除其它 shard 从节点存储数据路径(配置文件中 dbpath 路径)下的文件,然后依次重启 shard 从节点服务,并在主 shard 节点上执行命令 rs.add ("shard_ip:shard_port") 依次将所有的 shard 节点加入到副本集中。

10. 按照上述办法,建立好其他所有的分片集后。重启所有的 mongos 节点,并验证恢复的集群数据。
注意:
如果你的目标实例的 shard 副本集的数量超过源实例,请先关闭多余的分片后再进行集群重建。完成上述集群重建操作后如需将多余的 shard 副本集加入到分片集群,请注意这时候通过 mongos 节点读到的不仅仅是恢复出来的数据,还有这些 shard 副本集的数据 。
如不需要多余的 shard 副本集数据,请先清空 shard 副本集数据目录下的数据,重新构建 shard 副本集后再加入 shard 副本集,具体操作请参考 MongoDB 官方文档。