Docs 菜单

reshardCollection

reshardCollection

版本 5.0 中的新增功能

reshardCollection命令更改集合的分片键并更改数据的分布。

提示

mongosh 中,该命令也可通过 sh.reshardCollection() 辅助方法运行。

辅助方法对 mongosh 用户来说很方便,但它们返回的信息级别可能与数据库命令不同。如果不追求方便或需要额外的返回字段,请使用数据库命令。

此命令可用于以下环境中托管的部署:

注意

所有 MongoDB Atlas 集群都支持此命令。有关 Atlas 对所有命令的支持的信息,请参阅不支持的命令

该命令具有以下语法:

db.adminCommand(
{
reshardCollection: "<database>.<collection>",
key: <shardkey>,
unique: <boolean>,
numInitialChunks: <integer>,
collation: { locale: "simple" },
zones: [
{
min: <document with same shape as shardkey>,
max: <document with same shape as shardkey>,
zone: <string> | null
},
...
],
forceRedistribution: <bool>
}
)

该命令接受以下字段:

字段
类型
说明

reshardCollection

字符串

要重新分片的集合的命名空间。 采用<database>.<collection>形式。

key

文档

指定用作分片键的一个或多个新字段的文档。

{ <field1>: <1|"hashed">, ... }

将字段值设置为以下任一项:

unique

布尔

可选。 指定分片键是否有唯一性约束。 仅支持false 。 默认为false

numInitialChunks

整型

可选。 指定对集合重新分片时要在集群中所有分片中创建的数据段的初始数量。 默认值为 90。 然后, MongoDB将在集群中创建并均衡数据段。 numInitialChunks 的结果必须小于每个分片的 8192

collation

文档

可选。 如果reshardCollection中指定的集合具有默认排序规则,则必须包含附带{ locale : "simple" }的排序规则文档,否则reshardCollection命令将失败。

zones

阵列

可选。 指定集合的区域。

要维护或添加区域,请在大量中指定集合的区域:

[
{
min: <document with same shape as shardkey>,
max: <document with same shape as shardkey>,
zone: <string> | null
},
...
]

forceRedistribution

布尔

可选。 如果设置为true ,即使新分片键与旧分片键相同,操作也会运行。 与zones选项一起使用可将数据移至特定区域。

8.0版本新增

重新分片期间进行的索引构建可能会静默失败。

  • 请勿在重新分片进程创建索引。

  • 如果正在进行索引构建,请勿启动重新分片进程。

在集合重新分片操作中,分片可以是:

  • 发送分片,它目前存储分片集合的数据段

  • 接收分片,它根据分片键区域存储分片集合的新数据段。

分片可以同时是发送分片和接收分片。

配置服务器主节点始终是重新分片协调器,并启动重新分片操作的每个阶段。

在初始化阶段,重新分片协调器会确定分片集合的新数据分布。

在克隆阶段:

  • 每个接收分片都会创建一个临时的空分片的集合,其集合选项与发送分片的集合相同。 这个新集合是接收分片写入新数据的目标。 在索引阶段之前,接收分片不会创建除 _id索引之外的任何索引。

  • 每个接收分片都从发送分片克隆集合数据,包括接收分片在新分片键下拥有的所有文档。

在索引阶段,每个接收分片都会构建必要的新索引。 其中包括分片的集合上的所有现有索引,以及与新分片键模式兼容的索引(如果分片的集合上尚不存在此类索引) 。

在应用和追赶阶段:

  • 每个接收分片开始应用在接收分片克隆数据后写入相应发送分片的 oplog条目。

  • 当完成重新分片操作的剩余时间估计低于两秒时,发送分片分片对源集合的写入。

注意

如果需要,可以通过发出commitReshardCollection命令手动强制完成重新分片操作。 如果完成重新分片操作的当前时间估计是您的集合阻止写入的可接受持续时间,则这非常有用。 commitReshardCollection命令会阻止提前写入并强制完成重新分片操作。 在写入受阻期间,应用程序的延迟会增加。

在提交阶段:

  • 重新分片协调器等待所有分片达到严格一致性,然后提交重新分片操作。

  • 重新分片协调器指示每个发送分片和接收分片主节点独立地重命名临时分片集合。 临时集合将成为新的重新分片集合。

  • 每个捐赠分片都会删除旧的分片集合。

注意

一旦重新分片进程进入提交阶段,就无法使用abortReshardCollection 结束该进程。

以下示例使用新的分片键{ order_id: 1 }sales.orders集合重新分片:

db.adminCommand({
reshardCollection: "sales.orders",
key: { order_id: 1 }
})

输出:

{
ok: 1,
'$clusterTime': {
clusterTime: Timestamp(1, 1624887954),
signature: {
hash: Binary(Buffer.from("0000000000000000000000000000000000000000", "hex"), 0),
keyId: 0
}
},
operationTime: Timestamp(1, 1624887947)
}

提示

另请参阅:

从MongoDB 8.0 开始,您可以对同一键对集合,这可用于将数据重新分发到新的分片上。

将分片添加到集群后,可以使用带有forceRedistribution选项的reshardCollection命令在集群中重新分发数据:

db.adminCommand({
reshardCollection: "accounts.invoices",
key: { store_id: "hashed" },
forceRedistribution: true
})

从MongoDB 8.0 开始,您可以使用 reshardCollection 命令将数据移入新区域,而无需更改分片键。

以下命令使用相同的分片键重新分发 accounts.sales集合的数据,将数据移动到与区域 zone04zone05 关联的分片:

db.adminCommand({
reshardCollection: "accounts.sales",
key: { region_id: "hashed" },
forceRedistribution: true,
zones: [
{
zone: "zone04",
min: { region_id: MinKey() },
max: { region_id: 10 }
},
{
zone: "zone05",
min: { region_id: 10 },
max: { region_id: MaxKey() }
}
]
})