要删除分片片,您必须确保该分片的数据已迁移到集群中的其余分片。 此过程描述如何安全地迁移数据和删除分分片。
关于此任务
执行此过程时创建、分片或移动集合可能会导致中断并导致意外结果。
请勿使用此过程将整个集群迁移到新硬件。 要迁移,请参阅将自管理分片集群迁移到不同硬件。
当您从集群中删除数据段分布不均匀的分片时,负载均衡器首先从要清空的分片中删除数据段,然后均衡剩余的不均匀数据段分布。
删除分分片可能会导致打开的变更流游标关闭,并且关闭的变更流游标可能无法完全恢复。
您可以在分片删除进程中安全地重新启动集群。 如果在正在进行的排干进程重新启动集群,则在集群组件重新启动后,排干会自动继续。 MongoDB会在
config.shards集合中记录分分片排干。
开始之前
此过程使用
sh.moveCollection()方法将集合从已删除的分分片移出。 在开始此过程之前,请查看moveCollection注意事项和要求,以了解命令行为。要删除分分片,请先使用 连接到集群的
mongosmongosh实例之一。
注意
删除多个分片时,请同时删除它们,而不是一次删除一个。每次删除一个分片会导致负载均衡器将数据转移到其他剩余分片中。一个分片一次只能参与一个数据块迁移,因此删除一个分片会限制数据迁移的吞吐量。
步骤
确保负载均衡器已启用。
要从分迁移数据,必须启用分片负载均衡器进程。 要检查负载均衡器状态,请使用sh.getBalancerState()方法:
sh.getBalancerState()
如果操作返回true ,则负载均衡器已启用。
如果操作返回false ,请参阅启用负载均衡器。
确定要删除的分片的名称。
要查找分片的分片,请运行listShards命令:
db.adminCommand( { listShards: 1 } )
shards._id字段包含分分片名称。
开始排干分片。
运行startShardDraining 命令以开始将数据段从分片的集合移动到集群中的其他分片:
db.adminCommand( { startShardDraining: "shard04" } )
如果需要删除多个分片,可以启动排干进程以并行运行。
移动集合。
当您在 上创建集合且未调用 时,该集合将保持未分片状态, MongoDB会将其完整存储在集群中的特定分片上。使用该分片作为主节点 (primary node in the replicamongos shardCollectionset)的数据库也会将其集合存储在分片上。
如果要删除的分片包含未分片的集合或主节点 (primary node in the replica set)数据库,则需要将该集合移动到另一个分片。
要确定要删除的分片是否包含这些集合并查看排干状态,运行shardDrainingStatus 命令并检查大量中的collectionsToMove 输出字段:
db.adminCommand( { shardDrainingStatus: "shard04" } )
{ msg: "draining ongoing", state: "ongoing", remaining: { chunks: Long(2), dbs: Long(2), jumboChunks: Long(0), collectionsToMove: Long(2) }, shard: "shard04", note: "you need to call moveCollection for collectionsToMove and afterwards movePrimary for the dbsToMove", dbsToMove: [ "accounts", ], collectionsToMove: [ "accounts.us-east", "accounts.us-west", "locations.us", ], ok: 1, operationTime: Timestamp(1575399086, 1655), $clusterTime: { clusterTime: Timestamp(1575399086, 1655), signature: { hash: BinData(0,"XBrTmjMMe82fUtVLRm13GBVtRE8="), keyId: Long("6766255701040824328") } } }
在 collectionsToMove字段中找到的任何集合都是存储在该分片上的集合。在删除分片之前,必须先将这些集合移至另一个分片。
要将集合移动到另一个分片,请使用moveCollection 命令:
db.adminCommand( { moveCollection: "accounts.us-east", toShard: "shard05" } )
移动主节点。
分片集群指定一个特定的分片提供服务数据库的主分片。如果要删除的分片是主节点 (primary node in the replica set),则需要将其移动到其他分片。
要识别主节点,运行shardDrainingStatus 命令并检查dbsToMove 输出字段上的大量。
db.adminCommand( { shardDrainingStatus: "shard04" } )
{ msg: "draining ongoing", state: "ongoing", remaining: { chunks: Long(2), dbs: Long(2), jumboChunks: Long(0), collectionsToMove: Long(2) }, shard: "shard04", note: "you need to call moveCollection for collectionsToMove and afterwards movePrimary for the dbsToMove", dbsToMove: [ "accounts", ], collectionsToMove: [ ], ok: 1, operationTime: Timestamp(1575399086, 1655), $clusterTime: { clusterTime: Timestamp(1575399086, 1655), signature: { hash: BinData(0,"XBrTmjMMe82fUtVLRm13GBVtRE8="), keyId: Long("6766255701040824328") } } }
dbsToMove字段中显示的每个数据库都是您需要移动到不同分片的数据库。
要移动数据库,请使用movePrimary 命令:
db.adminCommand( { movePrimary: "accounts", to: "shard05" })
删除分片。
在删除分片之前,请检查排干操作是否已完成。
要检查排干操作的状态,运行shardDrainingStatus 命令:
db.adminCommand( { shardDrainingStatus: "shard04" } )
{ "msg" : "draining completed successfully", "state" : "drainingComplete", "ok" : 1, "$clusterTime" : { "clusterTime" : Timestamp(1771839836, 139), "signature" : { "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="), "keyId" : NumberLong(0) } }, "operationTime" : Timestamp(1771839836, 139) }
当 state字段为要删除的分片返回 drainingComplete 时,则排干进程已完成。您现在可以删除分片。
要删除分片,运行commitShardRemoval 命令:
db.adminCommand( { commitShardRemoval: "shard04" } )
{ "ok" : 1, "$clusterTime" : { "clusterTime" : Timestamp(1771840037, 12), "signature" : { "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="), "keyId" : NumberLong(0) } }, "operationTime" : Timestamp(1771840037, 12) }
如果分片未完全清空,该命令将返回错误。