文档菜单
文档首页
/
MongoDB 手册
/ /

从分片集群中移除分片

本页内容

  • 关于此任务
  • 开始之前
  • 步骤
  • 了解更多

要移除一个分片,您必须确保分片的数据已迁移到集群中剩余的分片。本程序描述了如何安全地迁移数据并移除分片。

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

  2. 要删除分区,首先使用mongosh.

1

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

sh.getBalancerState()

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

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

2

要找到分片名称,运行 listShards 命令

db.adminCommand( { listShards: 1 } )

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

3

运行要删除的分片的 removeShard 命令

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

注意

mongos写关注 转换为 "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 命令来重新分配从被删除的分片上的数据。

使用 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将集合从分片上移除(以及子步骤)以处理集群中每个数据库。

7

运行 db.printShardingStatus() 方法

db.printShardingStatus()

在命令输出的 databases 部分中,检查 database.primary 字段。如果 primary 字段是已移除的分片,则必须将该数据库的主分片移动到不同的分片。

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

警告

在运行 movePrimary 时,在 将集合从分片上移除 步骤中未移动的任何集合在 movePrimary 过程中将不可用。

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

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

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

输出中,remaining 字段包含以下字段

字段
描述
chunks
当前在分片上剩余的块数量
dbs
主分片 是该分片的数据库数量。这些数据库在 dbsToMove 输出字段中指定。
jumboChunks

在所有块中,是 大块 的块数量。

如果 jumboChunks 大于 0,请等待直到分片上只剩下 jumboChunks。一旦只剩下 jumbo 块,您必须在排空完成之前手动清除大块标志。请参阅 清除 jumbo 标志。

清除大块标志后,均衡器可以迁移这些块。有关迁移过程的详细信息,请参阅 范围迁移过程。

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

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

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

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

注意

DDL 操作

如果在集群执行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 })
}

返回

向分片添加成员