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

细化集合分片键

本页

  • 定义
  • 兼容性
  • 语法
  • 命令字段
  • 访问控制
  • 注意事项
  • 示例
细化集合分片键

修改集合的分片键,通过将新字段作为现有键的后缀添加。细化集合的分片键可以解决由于基数不足而导致现有键导致大块(即不可分割的块)的情况。

注意

数据分布

作为细化分片键的一部分,refineCollectionShardKey 命令更新 数据分片范围区域范围 以包含新字段,同时不修改现有键字段的范围值。也就是说,分片键的细化不会立即影响数据块在分片或区域间的分布。任何未来的数据块分裂或迁移都将作为常规分片操作的一部分发生。

此命令在以下环境中运行的部署中可用

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

重要

此命令不支持 M10+ 集群或无服务器实例。有关更多信息,请参阅 不受支持的命令。

注意

要使用 refineCollectionShardKey 命令,分片集群必须具有 功能兼容性版本(fcv)4.4

该命令的语法如下:

db.adminCommand(
{
refineCollectionShardKey: "<database>.<collection>",
key: { <existing key specification>, <suffix1>: <1|"hashed">, ... }
}
)

命令包含以下字段:

字段
类型
描述
字符串

分片集合的命名空间,格式为 "<数据库名>.<集合名>"

文档

指定用于集合新分片键的字段或字段的文档。

{ <现有键规范>, <后缀1>: <1|"hashed">, ... }

  • 新键必须以现有分片键开头。

  • 新键必须由一个必须存在的索引支持运行 refineCollectionShardKey 命令之前。有关更多信息,请参阅 索引考虑事项

对于后缀字段,将字段值设置为

提示

另请参阅

在启用访问控制的情况下,用户必须在数据库和/或集合上具有 refineCollectionShardKey 权限操作才能运行该命令。也就是说,用户必须具有授予以下 角色权限

{ resource: { db: <database>, collection: <collection> }, actions: [ "refineCollectionShardKey" ] }

内置的 clusterManager 角色提供了适当的权限。

  • 索引存在性

    必须存在支持命令指定 的索引,才能运行该命令。

    支持索引是一个以新的分片键规范开始的索引;即 索引前缀 与新的分片键规范匹配。也就是说,要将分片键从 { x: 1 } 更改为 { x: 1, y: 1 },必须存在以 { x: 1, y: 1 } 开头的索引;例如:

    • { x: 1, y: 1 }

    • { x: 1, y: 1, a: 1, b: 1}

    注意

    • 支持索引不能是一个 部分索引

    • 支持索引不能是一个 稀疏索引

    • 如果集合使用非 简单 排序规则,支持索引必须指定 { locale: "simple" } 排序规则。

  • 唯一索引

    如果当前分片索引有 唯一约束,则新的分片键索引也必须具有唯一约束。

    在创建支持新分片键的唯一索引之后,在运行 refineCollectionShardKey 之前,删除 旧的分片键索引 之前
    此外,如果当前分片索引具有一个唯一约束,则新的分片键不能为其任何字段指定"hashed"
  • 索引排序
    如果分片集合具有非简单的默认排序规则,则索引必须包含一个包含{ locale : "simple" }的排序规则文档。至少有一个索引的字段支持分片键模式,必须具有简单排序规则。

警告

不要修改任何当前分片键字段的范围或散列类型。这会导致数据不一致。例如,不要将分片键从{ customer_id: 1 }修改为{ customer_id: "hashed", order_id: 1 }

test数据库中设置示例

  1. 使用以下shardCollection操作在test数据库中分片orders集合。该操作使用customer_id字段作为初始分片键

    db.adminCommand( { shardCollection: "test.orders", key: { customer_id: 1 } } )

要将分片键修改为包含customer_id字段和order_id字段的{ customer_id: 1, order_id: 1 }

  1. 如果索引不存在,则创建索引以支持新的分片键。

    db.getSiblingDB("test").orders.createIndex( { customer_id: 1, order_id: 1 } )
  2. 运行refineCollectionShardKey命令将order_id字段作为后缀添加

    db.adminCommand( {
    refineCollectionShardKey: "test.orders",
    key: { customer_id: 1, order_id: 1 }
    } )

命令成功完成后,集合的分片键已更改为{ customer_id: 1, order_id: 1 }。要验证,您可以运行sh.status()

提示

在细化分片键后,可能不是所有文档都包含后缀字段。要填充缺失的分片键字段,请参阅缺失的分片键字段

在细化分片键之前,如果可能的话,请确保集合中所有或大部分文档都包含后缀字段,以避免之后填充字段。

test数据库中设置示例

  1. 测试数据库中创建咖啡馆集合,指定法语fr为默认校对。

    db.getSiblingDB("test").createCollection( "cafés", { collation: { locale: "fr" } } );
  2. 使用customer_id字段作为初始分片键对集合进行分片。因为该集合具有默认的fr校对而非简单校对,所以shardCollection命令必须包含collation: { locale: "simple" }选项。

    db.adminCommand( {
    shardCollection: "test.cafés",
    key: { customer_id: 1 },
    collation: { locale: "simple" }
    } )

要将分片键修改为同时包括customer_id字段和order_id字段{ customer_id: 1, order_id: 1 }

  1. 创建索引以支持新的分片键,如果索引尚不存在。由于集合使用非简单校对,索引必须包含collation: { locale: "simple" }选项。

    db.getSiblingDB("test").cafés.createIndex(
    { customer_id: 1, order_id: 1 },
    { collation: { locale: "simple" } }
    )
  2. 运行refineCollectionShardKey命令将order_id字段作为后缀添加

    db.adminCommand( {
    refineCollectionShardKey: "test.cafés",
    key: { customer_id: 1, order_id: 1 }
    } )

命令成功完成后,集合的分片键已更改为{ customer_id: 1, order_id: 1 }。要验证,您可以运行sh.status()

提示

在细化分片键后,可能不是所有文档都包含后缀字段。要填充缺失的分片键字段,请参阅缺失的分片键字段

在细化分片键之前,如果可能的话,请确保集合中所有或大部分文档都包含后缀字段,以避免之后填充字段。

提示

另请参阅

返回

合并块