从现有分片集群删除分片
要删除分片片,您必须确保该分片的数据已迁移到集群中的其余分片。 此过程描述如何安全迁移数据以及如何删除分分片。
当您从集群中删除数据段分布不均匀的分片时,负载均衡器首先从要清空的分片中删除数据段,然后均衡剩余的不均匀数据段分布。
此过程描述如何从集群中删除分片。 请勿使用此过程将整个集群迁移到新硬件。 要迁移,请参阅将自管理分片集群迁移到不同硬件。
要删除分片,请先使用 连接到集群的mongos
mongosh
实例之一。然后使用本文档中的任务序列从集群中删除分片。
Considerations
分片删除可能会导致打开的更改流游标关闭,而关闭的更改流游标可能无法完全恢复。
您可以在分片删除进程中安全地重启集群。如果您在清空进程中重启集群,则在集群组件重启后,清空会自动继续。MongoDB 在
config.shards
集合中记录分片清空状态。
确保负载均衡器进程已启用
要成功从分片迁移数据,必须启用负载均衡器进程。使用 mongosh
中的 sh.getBalancerState()
辅助程序检查负载均衡器状态。请参阅负载衡器操作部分,查看更多信息。
确定要删除的分片的名称
要确定分片的名称,请使用 mongosh
连接 mongos
实例,然后执行以下任一操作:
使用
listShards
命令,如下所示:db.adminCommand( { listShards: 1 } ) 运行
sh.status()
或db.printShardingStatus()
方法。
shards._id
字段列出了每个分片的名称。
从分片中移除数据段
从 admin
数据库运行 removeShard
命令。这将触发将要删除的分片中的数据段“迁移”到集群中的其他分片上。例如,对于名为 mongodb0
的分片,运行:
db.adminCommand( { removeShard: "mongodb0" } )
mongos
将 removeShard
命令的写关注转换为 "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" } )
mongos
将 removeShard
命令的写关注转换为 "majority"
。
该命令返回类似以下的输出:
{ "msg" : "draining ongoing", "state" : "ongoing", "remaining" : { "chunks" : NumberLong(2), "dbs" : NumberLong(2), "jumboChunks" : NumberLong(0) }, "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 | 在 如果 清除 |
继续检查 removeShard
命令的状态,直到剩余数据段的数量为 0
。
db.adminCommand( { removeShard: "mongodb0" } )
将数据库移动到另一个主分片
如果该分片是集群中一个或多个数据库主分片,则必须将该数据库设置为使用其他分区作主分区。removeShard
在命令输出的 dbsToMove
字段中列出需要移动的所有数据库。如果该分片不是任何数据库的主分片,请跳到下一个任务,完成迁移。
要将数据库移动到另一个分片,请使用movePrimary
命令。
重要
为确保平稳迁移,请在运行 movePrimary
之前参阅 movePrimary
命令文档中的注意事项。
要将 fizz
数据库从 mongodb0
迁移至 mongodb1
,请发出以下命令:
db.adminCommand( { movePrimary: "fizz", to: "mongodb1" })
mongos
对 movePrimary
使用 "majority"
写关注。
直到 MongoDB 完成所有数据的移动后,此命令才会返回。该命令的响应如下:
{ "ok" : 1, "operationTime" : Timestamp(1575400369, 9), "$clusterTime" : { "clusterTime" : Timestamp(1575400369, 9), "signature" : { "hash" : BinData(0,"2Nz8QCcVXB0LJLm1hsXfpTCaM0M="), "keyId" : NumberLong("6766255701040824328") } } }
完成迁移
要清除所有元数据信息并最终完成删除,请再次运行 removeShard
。例如,对于名为 mongodb0
的分片,运行:
db.adminCommand( { removeShard: "mongodb0" } )
mongos
将 removeShard
命令的写关注转换为 "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
分片的实例。