Learn the "why" behind slow queries and how to fix them in our 2-Part Webinar.
Register now >
Docs 菜单
Docs 主页
/ /

reshardCollection(数据库命令)

reshardCollection

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

注意

您可以运行带有 forceRedistribution: truereshardCollection 命令来删除具有巨型块的分片。由于重新分片避免了负载均衡器的严格限制,因此它通常是删除包含巨型块的分片的最佳方法。或者,您可以使用带有 forceJumbo: truemoveChunk 命令。但是,由于这是离线操作,因此可能会导致停机。

提示

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

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

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

  • MongoDB Atlas:用于云中 MongoDB 部署的完全托管服务

注意

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

该命令具有以下语法:

db.adminCommand(
{
reshardCollection: "<database>.<collection>",
key: { "<shardkey>" },
unique: <boolean>,
numInitialChunks: <integer>,
numSamplesPerChunk: <integer>, // New in MongoDB 8.0.20
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

如果看到错误“提供的分片键没有足够的关联基数来制作所需数量的数据段”,请使用较低的 numInitialChunks 值对集合重新分片。

从MongoDB 8.2 开始,当分片键包含哈希前缀时,重新分片操作会忽略 numInitialChunks 设置。相反, MongoDB使用与为空哈希集合创建初始数据块相同的方法,确定性地在接收者之间分割哈希键空间。

numSamplesPerChunk

整型

可选。指定要对新数据段进行示例的文档数量。默认下, MongoDB对每个数据块上的 10 个文档进行采样。

8.0.20版本新增

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版本新增

demoMode

布尔

可选。允许快速完成重新分片操作。设立为 true 时,demoMode 会绕过重新分片操作的最短持续时间(5 分钟)。您可以使用此参数进行重新分片测试或演示。

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

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

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

如果您要重新分片的集合使用MongoDB Search,则在重新分片操作完成后,搜索索引将变为不可用。重新分片操作完成后,您需要手动重建搜索索引。

  • 如果集合使用Atlas Search,则在操作完成后,搜索索引将变为不可用。要恢复索引,请手动重建搜索索引。

  • 不支持使用可查询加密的集合。

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

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

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

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

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

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

在克隆阶段:

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

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

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

在版本8.2中进行了更改

在应用和追赶阶段:

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

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

注意

如果需要,可以通过发出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() }
}
]
})

后退

removeShardFromZone

在此页面上