删减分片

最近更新时间:2025-12-12 10:23:12

我的收藏

操作场景

当业务流量发生变化导致实例数据和负载下降时,可以通过减少分片数量释放一定的数据库资源,将集群规模调整至与当前负载相匹配的状态,实现按需配置,避免资源浪费。
说明:
删减分片会触发数据迁移,可能对实例负载带来长时间影响。建议您优先评估直接降低 Mongod 节点规格来达到降低成本的目的。具体操作,请参见 变更 Mongod 节点配置规格
删减分片功能目前处于公测期间。如有使用需求,请 提交工单 申请。

影响与约束

在删减分片数量操作前,请务必仔细阅读以下关键信息,以确保操作符合预期且不影响业务稳定性。
维度
减少分片
计费影响
包年包月:计算旧规格的剩余费用与新配置的价格,完成退款。在下一个续费时刻,按照新规格扣费。
按量计费:结算旧的规格,按照新规格重新开始计费。
具体计费信息,请参见 变配计费
版本要求
通用版:MongoDB 4.0及以上。
云盘版:不支持删减分片。
服务影响
操作过程业务零中断,可正常读写数据库,并可自动备份与手动备份。
操作过程中,严禁执行任何可能干扰数据迁移的操作,包括但不限于:
数据回档与实例销毁。
配置变更与主从切换。
变更连接地址。
对待删分片操作。
限制与约束
删减顺序:按创建时间倒序自动选择待删分片。
空间要求:删减后,剩余分片的总存储空间必须 ≥ 集群已用空间的120%,否则无法删减。
删减数量:每次发起删减的数量不能超过原集群数量的一半,删减后分片数必须≥2个。
说明:
因内核限制,MongoDB 4.0版本一次只能删除一个分片。
均衡器要求:删减前需开启 Balancer 并设置 Balancing Window(均衡窗口),以控制数据迁移对业务的影响。
耗时:分片删减会触发数据重分布,受数据量、Balancer 设置等影响,可能较慢。

操作前检查清单

序号
检查项目
检查标准
具体说明与操作指引
1
实例状态
实例状态为 “运行中”
在实例列表中确认目标实例运行正常。
2
分片数量
删减前,分片数量必须大于2
此为前提条件。若当前分片数等于2,则无法进行删减;删减后分片数将少于2,不符合集群架构要求。
3
实例到期时间
包年包月实例的到期时间需大于等于14天
实例详情页面的配置信息区域查看到期时间,确保实例有足够剩余服务时长。
4
删减后存储空间
剩余分片的总存储空间 > 集群当前已使用空间 × 120%
1. 在实例详情的规格信息区域查看总存储空间与已使用空间
2. 计算剩余分片的总存储空间,示例如下所示。
当前总空间:150GB (3分片 × 50GB)
计划删减:1个分片
删减后空间:100GB
当前已使用:1.5GB
所需最小空间:1.5GB × 120% = 1.8GB
判断:100GB > 1.8GB,检查通过。
5
均衡器设置
确保均衡器已开启,并建议设置均衡时间窗
1. 在控制台参数配置页面,将 openBalance.window 参数设置为 true 以开启均衡器。
2. 通过 balance.window 参数设置业务低峰期作为均衡时间窗,以减少数据迁移对业务的影响。具体操作,可参见 参数配置
6
主分片检查
确认待删减分片不是任何非分片集合的主分片
1. 使用 MongoDB Shell 连接实例,通过 getSiblingDB("config").databases.find() 查询配置数据库,识别目标分片为主分片的数据库。
说明:
分片名称格式:cmgo-xxxxxxxx_n,其中,xxxxxxxx 为实例唯一标识(8位字符);n 为分片序号,从0开始编号。例如,一个5分片实例,分片名为 cmgo-xxxxxxxx_0 到 cmgo-xxxxxxxx_4,如果客户要删减最后一个分片,就应该指定 cmgo-xxxxxxxx_4。

db.getSiblingDB("config").databases.find({primary: "cmgo-xxxxxxxx_3"})
2. 对识别出的每个数据库,通过 getCollectionNames() 方法,获取所有集合的完整列表。
db.getSiblingDB("bulk_db_db_77").getCollectionNames()
3. 通过 db.collection.stats().sharded 检查每个集合的分片状态,如果返回值为 false(表示未分片),则必须使用 movePrimary 命令将该集合所在数据库的主分片迁移到其他分片。具体操作,请参见 movePrimary(数据库命令)
说明:
在 MongoDB 4.0和4.2版本,执行 movePrimary 后,需要刷新路由信息,否则业务读写可能受阻。刷新方法如下所示:
4.0版本:执行 movePrimary 后,重启所有 mongos 节点,或在所有 mongos 节点上执行 flushRouterConfig 命令。
4.2版本:执行 movePrimary 后,重启所有 mongos 和 mongod 节点,或在所有 mongos 和 mongod 节点上执行 flushRouterConfig 命令。
db.getSiblingDB("bulk_db_db_77").collection1.stats().sharded

删减分片

1. 登录 MongoDB 控制台
2. 在左侧导航栏 MongoDB 的下拉列表中,选择分片实例
3. 在右侧实例列表页面上方,选择地域。
4. 在实例列表中,找到目标实例。
5. 单击实例 ID,进入实例详情页面,切换至节点管理页面。
6. 节点操作的下拉列表中,选择删减分片

7. 删减分片小窗口,了解删减分片的限制与条件,并参见下表,指定需删减的分片数量。

参数分类
参数项
参数示例
参数解释
实例基本信息
实例名称
test-4dot2-XXX
当前待删减分片数的实例名称。
到期时间
2025-04-24 19:23:43
包年包月计费模式,实例服务周期的截止时间。
实例架构
分片集群实例,有3分片,单片共4个节点,其中只读节点有1个
实例集群架构:分片集群实例。
分片数量:删减前的分片数量。
单分片节点数:单个分片的节点数、只读节点数。
当前节点规格
2核4GB内存,250GB存储,共10个节点
单分片节点规格:包括 CPU 核数、内存、存储容量。
集群节点总数:删减前实例总的节点数(分片数量 * 单分片的节点数 = 集群节点总数)。
删减配置
删减分片数
2
指定实例需删减的分片数量。
指定了删减分片数量之后,单击检查待删减分片,检查删减分片的条件是否满足。
检查剩余分片数量:确保删减后,剩余分片数量不少于2个。
检查存储空间:确保删减后,剩余分片的总存储容量大于集群当前已使用空间的120%。
检查主分片数据:检查待删减分片中是否包含任何数据库的主分片。若存在,您必须手动将其迁移至其他分片后方可继续操作。
费用信息
计费方式
6.69元/小时
按量计费:显示实例减少分片后每小时的计费单价。
包年包月:显示降级规格后所需退还的费用。
调整配置后的计费详情,请参见 变配计费说明
8. 确认无误,单击确定。若实例为包年包月计费,您需要在确认产品信息页面支付新旧规格的差价,方可成功完成配置调整。
注意:
若 Shard 节点数据量过大、Balancing Window 设置过小或存在 Jumbo Chunk,将直接导致删减分片任务耗时延长甚至阻塞失败。关于具体的排查与解决方法,请参见 删减分片任务:进度确认与异常排查指南
9. 任务执行期间,如需停止删减,请在任务管理页面单击终止。终止后,分片数量将恢复原状。


相关 API

接口名称
功能描述
调整云数据库实例配置
查询云数据库的售卖规格

附录:确认待删减分片不是任何非分片集合的主分片的操作示例

1. 通过 getSiblingDB("config").databases.find() 查询配置数据库,识别目标分片为主分片的数据库。如下示例,查询分片 cmgo-xxxxxxxx_3 为主分片的数据库。

mongos> db.getSiblingDB("config").databases.find({primary: "cmgo-xxxxxxxx_3"})
{ "_id" : "bulk_db_db_3", "primary" : "cmgo-xxxxxxxx_3", "partitioned" : false, "version" : { "uuid" : UUID("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx"), "timestamp" : Timestamp(1762855003, 5), "lastMod" : 1 } }
{ "_id" : "bulk_db_db_4", "primary" : "cmgo-xxxxxxxx_3", "partitioned" : false, "version" : { "uuid" : UUID("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"), "timestamp" : Timestamp(1762855035, 2), "lastMod" : 1 } }
{ "_id" : "bulk_db_db_10", "primary" : "cmgo-xxxxxxxx_3", "partitioned" : false, "version" : { "uuid" : UUID("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"), "timestamp" : Timestamp(1762855333, 3), "lastMod" : 1 } }
{ "_id" : "bulk_db_db_14", "primary" : "cmgo-xxxxxxxx_3", "partitioned" : false, "version" : { "uuid" : UUID("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"), "timestamp" : Timestamp(1762855462, 30), "lastMod" : 1 } }

2. 对识别出的每个数据库,通过 getCollectionNames() 方法,获取所有集合的完整列表。如下示例,查询bulk_db_db_77 数据库的所有集合。

mongos> db.getSiblingDB("bulk_db_db_77").getCollectionNames()
[
"collection_1",
"collection_10",
"collection_11",
"collection_12",
"collection_13",
"collection_14",
"collection_15",
"collection_16",
"collection_17",
"collection_18",
"collection_19",
"collection_2",
"collection_20",
"collection_3",
"collection_4",
"collection_5",
"collection_6",
"collection_7",
"collection_8",
"collection_9"
]

3. 通过 db.collection.stats().sharded 检查每个集合的分片状态。如下示例,查询数据库 bulk_db_db_77.collection1 集合的分片状态。"sharded" : false, 则需要使用 movePrimary 命令将该集合所在数据库的主分片迁移到其他分片。

mongos> db.getSiblingDB("bulk_db_db_77").collection1.stats()
{
"sharded" : false,
"primary" : "cmgo-xxxxxxxx_3",
"ns" : "bulk_db_db_77.collection1",
"count" : 0,
"size" : 0,
"storageSize" : 0,
"totalIndexSize" : 0,
"totalSize" : 0,
"indexSizes" : {

},
"avgObjSize" : 0,
"maxSize" : NumberLong(0),
"nindexes" : 0,
"scaleFactor" : 1,
"nchunks" : 1,
"shards" : {
"cmgo-xxxxxxxx_3" : {
"ns" : "bulk_db_db_77.collection1",
"size" : 0,
"count" : 0,
"numOrphanDocs" : 0,
"storageSize" : 0,
"totalSize" : 0,
"nindexes" : 0,
"totalIndexSize" : 0,
"indexDetails" : {

},
"indexSizes" : {

},
"scaleFactor" : 1,
"ok" : 1,
"$clusterTime" : {
"clusterTime" : Timestamp(1763094536, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
},
"$configTime" : Timestamp(1763094535, 2),
"$topologyTime" : Timestamp(1762853939, 5),
"operationTime" : Timestamp(1763094536, 1)
}
},
"ok" : 1,
"$clusterTime" : {
"clusterTime" : Timestamp(1763094536, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
},
"operationTime" : Timestamp(1763094536, 1)
}
mongos> db.getSiblingDB("bulk_db_db_77").collection1.stats().sharded
false