细化集合分片键
定义
细化集合分片键
修改集合的分片键,通过将新字段作为现有键的后缀添加。细化集合的分片键可以解决由于基数不足而导致现有键导致大块(即不可分割的块)的情况。
注意
数据分布
作为细化分片键的一部分,refineCollectionShardKey
命令更新 数据分片范围 和 区域范围 以包含新字段,同时不修改现有键字段的范围值。也就是说,分片键的细化不会立即影响数据块在分片或区域间的分布。任何未来的数据块分裂或迁移都将作为常规分片操作的一部分发生。
兼容性
此命令在以下环境中运行的部署中可用
MongoDB Atlas:云中 MongoDB 部署的完全托管服务
重要
此命令不支持 M10+ 集群或无服务器实例。有关更多信息,请参阅 不受支持的命令。
MongoDB 企业版:基于订阅、自主管理的 MongoDB 版本
MongoDB 社区版:源代码可用的、免费使用并自主管理的 MongoDB 版本
语法
注意
要使用 refineCollectionShardKey
命令,分片集群必须具有 功能兼容性版本(fcv) 为 4.4
。
该命令的语法如下:
db.adminCommand( { refineCollectionShardKey: "<database>.<collection>", key: { <existing key specification>, <suffix1>: <1|"hashed">, ... } } )
命令字段
命令包含以下字段:
字段 | 类型 | 描述 |
---|---|---|
字符串 | 分片集合的命名空间,格式为 | |
文档 |
访问控制
在启用访问控制的情况下,用户必须在数据库和/或集合上具有 refineCollectionShardKey
权限操作才能运行该命令。也就是说,用户必须具有授予以下 角色 的 权限:
{ resource: { db: <database>, collection: <collection> }, actions: [ "refineCollectionShardKey" ] }
内置的 clusterManager
角色提供了适当的权限。
考虑事项
索引考虑事项
- 唯一索引
如果当前分片索引有 唯一约束,则新的分片键索引也必须具有唯一约束。
在创建支持新分片键的唯一索引之后,在运行refineCollectionShardKey
之前,删除 旧的分片键索引 之前。此外,如果当前分片索引具有一个唯一约束,则新的分片键不能为其任何字段指定"hashed"
。参见分片集合和唯一索引。
- 索引排序
- 如果分片集合具有非
简单
的默认排序规则,则索引必须包含一个包含{ locale : "simple" }
的排序规则文档。至少有一个索引的字段支持分片键模式,必须具有简单排序规则。
警告
不要修改任何当前分片键字段的范围或散列类型。这会导致数据不一致。例如,不要将分片键从{ customer_id: 1 }
修改为{ customer_id: "hashed", order_id: 1 }
。
示例
在test
数据库中设置示例
使用以下
shardCollection
操作在test
数据库中分片orders
集合。该操作使用customer_id
字段作为初始分片键:db.adminCommand( { shardCollection: "test.orders", key: { customer_id: 1 } } )
要将分片键修改为包含customer_id
字段和order_id
字段的{ customer_id: 1, order_id: 1 }
,
如果索引不存在,则
创建索引
以支持新的分片键。db.getSiblingDB("test").orders.createIndex( { customer_id: 1, order_id: 1 } ) 运行
refineCollectionShardKey
命令将order_id
字段作为后缀添加db.adminCommand( { refineCollectionShardKey: "test.orders", key: { customer_id: 1, order_id: 1 } } )
命令成功完成后,集合的分片键已更改为{ customer_id: 1, order_id: 1 }
。要验证,您可以运行sh.status()
。
提示
在细化分片键后,可能不是所有文档都包含后缀字段。要填充缺失的分片键字段,请参阅缺失的分片键字段。
在细化分片键之前,如果可能的话,请确保集合中所有或大部分文档都包含后缀字段,以避免之后填充字段。
具有非-简单
校对的集合
在test
数据库中设置示例
在
测试
数据库中创建咖啡馆
集合,指定法语fr
为默认校对。db.getSiblingDB("test").createCollection( "cafés", { collation: { locale: "fr" } } ); 使用
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 }
,
创建索引
以支持新的分片键,如果索引尚不存在。由于集合使用非简单校对,索引必须包含collation: { locale: "simple" }
选项。db.getSiblingDB("test").cafés.createIndex( { customer_id: 1, order_id: 1 }, { collation: { locale: "simple" } } ) 运行
refineCollectionShardKey
命令将order_id
字段作为后缀添加db.adminCommand( { refineCollectionShardKey: "test.cafés", key: { customer_id: 1, order_id: 1 } } )
命令成功完成后,集合的分片键已更改为{ customer_id: 1, order_id: 1 }
。要验证,您可以运行sh.status()
。
提示
在细化分片键后,可能不是所有文档都包含后缀字段。要填充缺失的分片键字段,请参阅缺失的分片键字段。
在细化分片键之前,如果可能的话,请确保集合中所有或大部分文档都包含后缀字段,以避免之后填充字段。