从现有分片群集中删除分片

在本页面

要删除shard,必须确保将分片的数据迁移到集群中其余的分片。此过程描述了如何安全地迁移数据以及如何删除分片。

当您在块分布不均匀的群集中删除一个分片时,平衡器首先从排水分片中删除这些块,然后平衡其余的不均匀块分布。

此过程描述了如何安全地删除单个分片。 请勿使用此过程将整个群集迁移到新硬件。要将整个分片迁移到新硬件,请像将其作为独立副本集那样迁移各个分片。

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

Considerations

碎片删除可能会导致打开的更改流光标关闭,并且关闭的变更流游标可能无法完全恢复。

确保启用了 Balancer 流程

为了成功地从分片迁移数据,必须启用balancer进程。使用mongoShell 程序中的sh.getBalancerState()帮助器检查平衡器状态。有关更多信息,请参见balancer operations上的部分。

确定要删除的碎片的名称

要确定分片的名称,请使用mongo shell 连接到mongos实例,并使用以下任一方法:

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

分片群集中的每个数据库都有一个主分片。如果要删除的分片也是集群数据库之一的主数据库,则removeSharddbsToMove字段中列出数据库。要完成删除碎片的操作,必须在从碎片中迁移所有数据之后将数据库移至新的碎片,或者删除数据库并删除关联的数据文件。

检查迁移状态

要在此过程的任何阶段检查迁移进度,请再次从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._adminCommandadmin上运行命令。

将数据库移至另一个主碎片

如果分片是集群中一个或多个数据库的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分片的实例。