从现有分片群集中删除分片
在本页面
要删除shard,必须确保将分片的数据迁移到集群中其余的分片。此过程描述了如何安全地迁移数据以及如何删除分片。
当您在块分布不均匀的群集中删除一个分片时,平衡器首先从排水分片中删除这些块,然后平衡其余的不均匀块分布。
此过程描述了如何安全地删除单个分片。 请勿使用此过程将整个群集迁移到新硬件。要将整个分片迁移到新硬件,请像将其作为独立副本集那样迁移各个分片。
要删除碎片,请首先使用mongo shell 连接到群集的mongos实例之一。然后使用本文档中的任务序列从集群中删除分片。
Considerations
碎片删除可能会导致打开的更改流光标关闭,并且关闭的变更流游标可能无法完全恢复。
确保启用了 Balancer 流程
为了成功地从分片迁移数据,必须启用balancer进程。使用mongoShell 程序中的sh.getBalancerState()帮助器检查平衡器状态。有关更多信息,请参见balancer operations上的部分。
确定要删除的碎片的名称
要确定分片的名称,请使用mongo shell 连接到mongos实例,并使用以下任一方法:
- 使用listShards命令,如下所示:
db.adminCommand( { listShards: 1 } )
shards._id
字段列出了每个分片的名称。
从碎片中删除块
在admin
数据库中,运行removeShard命令。这开始将要删除的分片中的数据块“排放”到集群中的其他分片中。例如,对于名为mongodb0
的碎片,运行:
db.adminCommand( { removeShard: "mongodb0" } )
该操作将立即返回,并具有以下响应:
{
"msg" : "draining started successfully",
"state" : "started",
"shard" : "mongodb0",
"note" : "you need to drop or movePrimary these databases",
"dbsToMove" : [
"fiz",
"buzz"
],
"ok" : 1,
"$clusterTime" : {
"clusterTime" : Timestamp(1510716515, 1),
"signature" : {
"hash" : BinData(0,"B2ViX7XLzFLS5Fl9XEuFXbwKIM4="),
"keyId" : NumberLong("6488045157173166092")
}
},
"operationTime" : Timestamp(1510716515, 1)
}
平衡器开始将大块从名为bristol01
的碎片迁移到集群中的其他碎片。这些迁移的速度很慢,以避免对整个群集造成不必要的负载。根据您的网络容量和数据量,此操作可能需要几分钟到几天才能完成。
Note
分片群集中的每个数据库都有一个主分片。如果要删除的分片也是集群数据库之一的主数据库,则removeShard在dbsToMove
字段中列出数据库。要完成删除碎片的操作,必须在从碎片中迁移所有数据之后将数据库移至新的碎片,或者删除数据库并删除关联的数据文件。
检查迁移状态
要在此过程的任何阶段检查迁移进度,请再次从admin
数据库运行removeShard。例如,对于名为mongodb0
的碎片,运行:
db.adminCommand( { removeShard: "mongodb0" } )
该命令返回类似于以下内容的输出:
{
"msg" : "draining ongoing",
"state" : "ongoing",
"remaining" : {
"chunks" : NumberLong(2),
"dbs" : NumberLong(2)
},
"note" : "you need to drop or movePrimary these databases",
"dbsToMove" : [
"fizz",
"buzz"
],
"ok" : 1,
"$clusterTime" : {
"clusterTime" : Timestamp(1510716515, 1),
"signature" : {
"hash" : BinData(0,"B2ViX7XLzFLS5Fl9XEuFXbwKIM4="),
"keyId" : NumberLong("6488045157173166092")
}
},
"operationTime" : Timestamp(1510716515, 1)
}
在输出中,remaining
文档显示 MongoDB 必须迁移到其他分片的剩余块数,以及该分片上具有“主”状态的 MongoDB 数据库的数。
continue 检查 removeShard 命令的状态,直到剩余的块数为0
。始终在admin
数据库上运行命令。如果您使用的数据库不是admin
,则可以使用sh._adminCommand
在admin
上运行命令。
将数据库移至另一个主碎片
如果分片是集群中一个或多个数据库的primary shard,则必须使该数据库使用其他分片作为其主要分片。 removeShard在命令输出的dbsToMove
字段中列出了您需要移动的所有数据库。如果该分片不是任何数据库的主分片,请跳至下一个任务完成迁移。
Warning
排完碎片之前,请勿执行此过程。
要将数据库移动到另一个分片,请使用movePrimary命令。
Important
为确保顺利迁移,请在运行movePrimary之前参考movePrimary命令文档中的considerations。
要将fizz
数据库从mongodb0
迁移到mongodb1
,请发出以下命令:
db.adminCommand( { movePrimary: "fizz", to: "mongodb1" })
直到 MongoDB 完成所有数据移动后,此命令才会返回。该命令的响应类似于以下内容:
{
"primary" : "mongodb1",
"ok" : 1,
"$clusterTime" : {
"clusterTime" : Timestamp(1510767932, 10),
"signature" : {
"hash" : BinData(0,"OJyZ0B4/Cp9z+mdrXLbJtNC7iuo="),
"keyId" : NumberLong("6488693018630029321")
}
},
"operationTime" : Timestamp(1510767932, 10)
}
Warning
如果使用movePrimary命令移动未分片的集合,则必须重新启动所有mongos实例,或在所有mongos实例上使用flushRouterConfig命令,然后再将任何数据读取或写入任何已移动的未分片的集合。此操作可确保mongos知道这些集合的新分片。
如果使用movePrimary之后没有更新mongos实例的元数据缓存,则mongos可能会丢失读取数据,并且可能不会将数据写入正确的分片。要恢复,您必须手动进行干预。
完成迁移
要清理所有元数据信息并完成删除操作,请再次运行removeShard。例如,对于名为mongodb0
的碎片,运行:
db.adminCommand( { removeShard: "mongodb0" } )
成功消息显示在完成时:
{
"msg" : "removeshard completed successfully",
"state" : "completed",
"shard" : "mongodb0",
"ok" : 1,
"$clusterTime" : {
"clusterTime" : Timestamp(1510767995, 1),
"signature" : {
"hash" : BinData(0,"Tk0evhgFHA8HgerY5HmKXhIuw3g="),
"keyId" : NumberLong("6488693018630029321")
}
},
"operationTime" : Timestamp(1510767995, 1)
}
state
字段的值“完成”后,就可以安全地停止包含mongodb0
分片的实例。