Docs 菜单
Docs 主页
/
MongoDB Manual
/ /

从分片集群中删除分片

在此页面上

  • 关于此任务
  • 开始之前
  • 步骤
  • 了解详情

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

  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 drop or movePrimary these databases",
"dbsToMove" : [
"db1",
"db2"
],
"ok" : 1,
"operationTime" : Timestamp(1575398919, 2),
"$clusterTime" : {
"clusterTime" : Timestamp(1575398919, 2),
"signature" : {
"hash" : BinData(0,"Oi68poWCFCA7b9kyhIcg+TzaGiA="),
"keyId" : NumberLong("6766255701040824328")
}
}
}

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

提示

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

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

4

要返回分分片的集合命名空间的列表,请使用$shardedDataDistribution阶段并项目ns字段:

use admin
db.aggregate(
[
{ $shardedDataDistribution: { } },
{ $project: { ns: 1 } }
]
)

记录输出以供本教程稍后参考。

5
db.adminCommand( { listDatabases: 1, nameOnly: true } )
6

对于集群中的每个数据库(不包括 admin 和 config ),执行以下步骤:

  1. 列出数据库集合

    列出数据库中的集合,忽略以下类型的集合:

    • 支持CSFLE 的内部集合

    • 系统集合

    • 时间序列集合

    • 视图

    use <databaseName>
    db.getCollectionInfos(
    {
    $and: [
    { type: { $nin: [ "view", "timeseries" ] } },
    { name: { $not: { $regex: "^system\." } } },
    { name: { $not: { $regex: "^enxcol_\..*(\.esc|\.ecc|\.ecoc|\.ecoc\.compact)$" } } }
    ]
    },
    { nameOnly: true }
    )
  2. 移动必要的集合

    对于getCollectionInfos()返回的每个集合,执行以下步骤。

    注意

    一次只能进行一个moveCollection操作。 完成所有子步骤,然后再继续下一个集合。

    1. 确定是否需要移动集合。

      运行$collStats聚合阶段并项目nsshard字段:

      db.<collName>.aggregate(
      [
      {
      $collStats: { }
      },
      {
      $project: {
      ns: 1,
      shard: 1
      }
      }
      ]
      )

      如果满足以下任一条件,则跳过该集合并返回步骤i以获取数据库中的下一个集合:

      • ns字段存在于步骤4的$shardedDataDistribution输出中。

      • shard字段分片要删除的分片。

      如果前面的两个条件都不满足,则继续对当前集合执行步骤ii

    2. 移动集合。

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

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

      注意

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

    3. 返回对数据库中每个集合执行的步骤i

  3. 对其他数据库重复该过程

    对集群中的每个数据库重复步骤6 、 Move collections off of the shard (和子步骤)。

7

运行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>
}
)
8

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

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

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

字段
说明
chunks
分片上当前剩余的数据段分片
dbs
主分片分片为 分片 的数据库分片。 这些数据库在dbsToMove输出字段中指定。
jumboChunks

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

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

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

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

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

要完成分分片删除进程,请重新运行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 })
}

后退

向分片添加节点