Docs 菜单
Docs 主页
/
数据库手册
/ /

从分片集群中删除分片

要删除分片片,您必须确保该分片的数据已迁移到集群中的其余分片。 此过程描述如何安全地迁移数据和删除分分片。

  1. 此过程使用sh.moveCollection()方法将集合从已删除的分分片移出。 在开始此过程之前,请查看moveCollection注意事项要求,以了解命令行为。

  2. 要删除分分片,请先使用 连接到集群的mongos mongosh实例之一。

注意

删除多个分片时,请同时删除它们,而不是一次删除一个。每次删除一个分片会导致负载均衡器将数据转移到其他剩余分片中。一个分片一次只能参与一个数据块迁移,因此删除一个分片会限制数据迁移的吞吐量。

1

要从分迁移数据,必须启用分片负载均衡器进程。 要检查负载均衡器状态,请使用sh.getBalancerState()方法:

sh.getBalancerState()

如果操作返回true ,则负载均衡器已启用。

如果操作返回false ,请参阅启用负载均衡器。

2

要查找分片的分片,请运行listShards命令:

db.adminCommand( { listShards: 1 } )

shards._id字段包含分分片名称。

3

为分片删除的分片运行removeShard命令:

db.adminCommand( { removeShard: "<shardName>" } )

注意

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

removeShard操作返回:

{
"msg" : "draining started successfully",
"state" : "started",
"shard" : "<shardName>",
"note" : "you need to call moveCollection for collectionsToMove and afterwards movePrimary for the dbsToMove",
"dbsToMove" : [
"db1",
"db2"
],
collectionsToMove: ["db1.collA"]
"ok" : 1,
"operationTime" : Timestamp(1575398919, 2),
"$clusterTime" : {
"clusterTime" : Timestamp(1575398919, 2),
"signature" : {
"hash" : BinData(0,"Oi68poWCFCA7b9kyhIcg+TzaGiA="),
"keyId" : Long("6766255701040824328")
}
}

分分片进入draining状态,负载均衡器开始将数据段从已删除的分片分片到集群中的其他分片。 这些迁移缓慢进行,以避免对整个集群造成严重影响。 根据网络容量和数据量,此操作可能需要几分钟到几天才能完成。

提示

当分片处于draining状态时,您可以使用分片命令重新分发已删除分片的数据。

使用reshardCollection移动数据可能比等待负载均衡器迁移数据段更快。 集群确保数据不会放置在任何正在排干的分片上。 您不能同时运行moveCollectionreshardCollection操作。

有关完整过程,请参阅为添加和删除分片而重新分片。

4
  1. 确定需要移动哪些集合

    要列出分片上的未分片集合,请使用聚合阶段 $listClusterCatalog

    use admin
    db.aggregate([
    { $listClusterCatalog: { shards: true } },
    { $match: {
    $and: [
    { sharded: false },
    { shards: '<shard_to_remove>' },
    { type: { $nin: ["timeseries","view"] } },
    { ns: { $not: { $regex: "^enxcol_\..*(\.esc|\.ecc|\.ecoc|\.ecoc\.compact)$" }}},
    { $or: [{ns: {$not: { $regex: "\.system\." }}}, {ns: {$regex: "\.system\.buckets\."}}]},
    { db: { $ne: 'config' } },
    { db: { $ne: 'admin' } }
    ]}},
    { $project: {
    _id: 0,
    ns: {
    $cond: [
    "$options.timeseries",
    {
    $replaceAll: {
    input: "$ns",
    find: ".system.buckets",
    replacement: ""
    }
    },
    "$ns"
    ]
    }
    }}
    ])
  2. 逐个移动集合

    要移动集合,运行sh.moveCollection()

    sh.moveCollection( "<database>.<collection>", "<ID of recipient shard>" )

    注意

    moveCollection 如果在分片命名空间上运行该命令,则会分片的。 如果收到此错误消息,请忽略并返回到步骤1以进行下一个集合。

  3. 返回步骤 1,检查排干分片上是否有剩余的未分片集合。

5

运行db.printShardingStatus()方法:

db.printShardingStatus()

在命令输出的databases部分,检查database.primary字段。 如果primary字段是已删除的分分片,则必须将该数据库的主节点 (primary node in the replica set)节点移动到其他分分片。

要更改数据库的主分片,请运行movePrimary命令。

警告

运行movePrimary 时,在 Move collections off of the shard 步骤中未移动的任何集合在 movePrimary进程中都不可用。

db.adminCommand(
{
movePrimary: <dbName>,
to: <shardName>
}
)
6

要检查迁移进度,请再次从admin数据库运行removeShard

db.adminCommand( { removeShard: "<shardName>" } )

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

字段
说明

chunks

分片上当前剩余的数据段分片

dbs

主分片分片为 分片 的数据库分片。 这些数据库在dbsToMove输出字段中指定。

jumboChunks

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

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

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

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

db.adminCommand( { removeShard: "<shardName>" } )
7

要完成分分片删除进程,请重新运行removeShard命令:

db.adminCommand( { removeShard: <shardName> } )

注意

DDL 操作

如果在集群执行分片操作(修改集合的操作,例如reshardCollection )时删除分片,则removeShard操作会在并发 DDL 操作完成后运行。

如果分片分片,则命令输出将类似于以下内容:

{
msg: 'removeshard completed successfully',
state: 'completed',
shard: '<shardName>',
ok: 1,
'$clusterTime': {
clusterTime: Timestamp({ t: 1721941519, i: 7 }),
signature: {
hash: Binary.createFromBase64('AAAAAAAAAAAAAAAAAAAAAAAAAAA=', 0),
keyId: Long('0')
}
},
operationTime: Timestamp({ t: 1721941519, i: 7 })
}

后退

向分片添加节点

在此页面上