Docs 菜单

Docs 主页开发应用程序MongoDB Manual

从现有分片集群删除分片

在此页面上

  • 考虑因素
  • 确保负载均衡器进程已启用
  • 确定要删除的分片的名称
  • 从分片中移除数据段
  • 检查迁移状态
  • 将数据库移动到另一个主分片
  • 完成迁移

要删除一个分片,必须确保该分片的数据已迁移到集群中的剩余分片。此过程描述如何安全迁移数据以及如何删除分片。

当您从集群中删除数据段分布不均匀的分片时,负载均衡器首先从要清空的分片中删除数据段,然后均衡剩余的不均匀数据段分布。

此操作步骤介绍如何从集群中删除分片。请勿使用此操作步骤将整个集群迁移到新硬件。如要进行迁移,请参阅将分片集群迁移到不同的硬件

要删除分片,请先使用 连接到集群的mongos mongosh实例之一。然后使用本文档中的任务序列从集群中删除分片。

  • 分片删除可能会导致打开的更改流游标关闭,而关闭的更改流游标可能无法完全恢复。

  • 您可以在分片删除进程中安全地重启集群。如果您在清空进程中重启集群,则在集群组件重启后,清空会自动继续。MongoDB 在 config.shards 集合中记录分片清空状态。

要成功从分片迁移数据, 必须 启用负载 均衡器 进程。使用 中的sh.getBalancerState() mongosh辅助程序检查负载均衡器状态。有关更多信息,请参阅有关 负载均衡器操作的部分。

要确定分片的名称,请使用 连接到mongos 实例,然后执行以下任一操作:mongosh

  • 使用 listShards 命令,如下所示:

    db.adminCommand( { listShards: 1 } )
  • 运行 sh.status()db.printShardingStatus() 方法。

shards._id 字段列出了每个分片的名称。

admin 数据库运行 removeShard 命令。这将触发将要删除的分片中的数据段“迁移”到集群中的其他分片上。例如,对于名为 mongodb0 的分片,运行:

db.adminCommand( { removeShard: "mongodb0" } )

mongosremoveShard 命令的写关注转换为 "majority"

此操作返回以下响应:

{
"msg" : "draining started successfully",
"state" : "started",
"shard" : "mongodb0",
"note" : "you need to drop or movePrimary these databases",
"dbsToMove" : [
"fiz",
"buzz"
],
"ok" : 1,
"operationTime" : Timestamp(1575398919, 2),
"$clusterTime" : {
"clusterTime" : Timestamp(1575398919, 2),
"signature" : {
"hash" : BinData(0,"Oi68poWCFCA7b9kyhIcg+TzaGiA="),
"keyId" : NumberLong("6766255701040824328")
}
}
}

负载均衡器开始将数据段从名为 mongodb0 的分片迁移到集群中的其他分片。迁移很慢,以避免给整个集群带来过度的负载。根据网络容量和数据量,该操作可能需要几分钟到几天才能完成。

注意

输出包含字段 dbsToMove,指示该分片是主分片的数据库(如果有)。从分片中耗尽所有数据段后,您必须针对数据库执行 movePrimary,或者删除数据库(此操作会删除关联的数据文件)。

要检查迁移过程中任何阶段的进度,请再次从 admin 数据库运行 removeShard。例如,对于名为 mongodb0 的分片,运行:

db.adminCommand( { removeShard: "mongodb0" } )

mongosremoveShard 命令的写关注转换为 "majority"

该命令返回类似以下的输出:

{
"msg" : "draining ongoing",
"state" : "ongoing",
"remaining" : {
"chunks" : NumberLong(2),
"dbs" : NumberLong(2),
"jumboChunks" : NumberLong(0) // Available starting in 4.2.2 (and 4.0.14)
},
"note" : "you need to drop or movePrimary these databases",
"dbsToMove" : [
"fizz",
"buzz"
],
"ok" : 1,
"operationTime" : Timestamp(1575399086, 1655),
"$clusterTime" : {
"clusterTime" : Timestamp(1575399086, 1655),
"signature" : {
"hash" : BinData(0,"XBrTmjMMe82fUtVLRm13GBVtRE8="),
"keyId" : NumberLong("6766255701040824328")
}
}
}

在输出中,remaining 字段包括以下字段:

字段
说明
chunks
分片当前剩余的数据段总数。
dbs
主分片是分片的数据库总数。这些数据库在 dbsToMove 输出字段中指定。
jumboChunks

chunks的总数中,该数字是巨型数据。

如果 jumboChunks 大于0,则等到该分片上只剩下 jumboChunks。一旦只剩下 jumbo 数据段,您必须手动清除 jumbo 标志,然后才能完成清空。请参阅清除 jumbo 标志

清除 jumbo 标记后,负载均衡器可以迁移这些数据段。有关迁移过程的详细信息,请参阅范围迁移过程

从 4.2.2(和 4.0.14)版本开始可用

继续检查 removeShard 命令的状态,直到剩余数据段的数量为 0

db.adminCommand( { removeShard: "mongodb0" } )

如果该分片是集群中一个或多个数据库的分片,则必须让该数据库使用其他分片作为其主分片。 removeShard在命令输出的dbsToMove字段中列出需要移动的所有数据库。如果该分片不是任何数据库的主分片,请跳到下一个任务“完成迁移”。

要将数据库移动到另一个分片,请使用movePrimary命令。

重要

为确保平稳迁移,请在运行 movePrimary 之前参阅 movePrimary 命令文档中的注意事项

要将 fizz 数据库从 mongodb0 迁移至 mongodb1,请发出以下命令:

db.adminCommand( { movePrimary: "fizz", to: "mongodb1" })

mongosmovePrimary 使用 "majority" 写关注。

直到 MongoDB 完成所有数据的移动后,此命令才会返回。该命令的响应如下:

{
"ok" : 1,
"operationTime" : Timestamp(1575400369, 9),
"$clusterTime" : {
"clusterTime" : Timestamp(1575400369, 9),
"signature" : {
"hash" : BinData(0,"2Nz8QCcVXB0LJLm1hsXfpTCaM0M="),
"keyId" : NumberLong("6766255701040824328")
}
}
}

对于 MongoDB 4.2 及以前版本,如果在包含未分片 集合的数据库上使用 movePrimary 命令,则必须执行以下额外步骤。

注意

在移动包含未分片集合的数据库时,MongoDB 4.4 不需要执行这些额外步骤。

  • 对于 MongoDB 4.2,必须:

    • 重启所有 mongos 实例所有 mongod 分片节点(包括从节点);

    • 在向移动后的任何未分片集合读取或写入任何数据之前,对所有 mongos 实例和所有 mongod 分片节点(包括从节点)使用 flushRouterConfig 命令。

  • 对于 MongoDB 4.0 及更早版本,必须:

    • 重启所有 mongos 实例;

    • 在向任何已移动的未分片集合读取或写入任何数据之前,请对所有 mongos 实例使用 flushRouterConfig 命令。

这些步骤确保所有集群节点刷新其元数据缓存,其中包括主分片的位置。否则,您可能会在读取时丢失数据,并且可能无法将数据写入正确的分片。要恢复,您必须手动干预。

要清除所有元数据信息并最终完成删除,请再次运行 removeShard。例如,对于名为 mongodb0 的分片,运行:

db.adminCommand( { removeShard: "mongodb0" } )

mongosremoveShard 命令的写关注转换为 "majority"

完成后会出现一条成功消息:

{
"msg" : "removeshard completed successfully",
"state" : "completed",
"shard" : "mongodb0",
"ok" : 1,
"operationTime" : Timestamp(1575400370, 2),
"$clusterTime" : {
"clusterTime" : Timestamp(1575400370, 2),
"signature" : {
"hash" : BinData(0,"JjSRciHECXDBXo0e5nJv9mdRG8M="),
"keyId" : NumberLong("6766255701040824328")
}
}
}

state 字段的值“完成”,您便可以安全地停止包含 mongodb0 分片的实例。

← 向分片添加节点