定义
refineCollectionShardKey通过添加新字段作为现有键的后缀来修改集合的分片键。 优化collection的分片键可以解决由于关联基数不足而导致现有键产生巨型(即不可分割)数据块的情况。
注意
数据分布
As part of refining the shard key, the refineCollectionShardKey command updates the chunk ranges and zone ranges to incorporate the new fields without modifying the range values of the existing key fields. That is, the refinement of the shard key does not immediately affect the distribution of chunks across shards or zones. Any future chunk splits or migration occur as part of the routine sharding operations.
兼容性
此命令可用于以下环境中托管的部署:
- MongoDB Atlas:用于云中 MongoDB 部署的完全托管服务
重要
M 个10 + 集群不支持此命令。 有关更多信息,请参阅不支持的命令。
MongoDB Enterprise:基于订阅、自我管理的 MongoDB 版本
MongoDB Community:源代码可用、免费使用且可自行管理的 MongoDB 版本
语法
注意
To use the refineCollectionShardKey command, the sharded cluster must have feature compatibility version (fcv) of 4.4.
该命令具有以下语法:
db.adminCommand( { refineCollectionShardKey: "<database>.<collection>", key: { <existing key specification>, <suffix1>: <1|"hashed">, ... } } )
命令字段
该命令接受以下字段:
字段 | 类型 | 说明 |
|---|---|---|
字符串 | sharded collection的命名空间,采用 | |
文档 | 指定要用作集合的新分片键的一个或多个字段的文档。
对于后缀字段,将字段值设置为:
|
提示
访问控制
使用访问控制运行时,用户必须对refineCollectionShardKey 数据库和/或集合 具有 操作权限才能运行命令。也就是说,用户必须具有授予以下 权限 的 角色 :
{ resource: { db: <database>, collection: <collection> }, actions: [ "refineCollectionShardKey" ] }
内置 clusterManager 角色提供了相应的特权。
Considerations
索引注意事项
- 唯一索引
如果当前分片索引具有唯一性约束,则新的分片键索引也必须具有唯一性约束。
After creating the unique index to support the new shard key, drop the old shard key index before running
refineCollectionShardKey.此外,如果当前分片索引具有唯一性约束,则新分片键不能为其任何字段指定
"hashed"。
- 索引排序规则
- 如果分片collection具有非
simple默认排序规则,则索引必须包含具有{ locale : "simple" }的排序规则文档。 对于字段支持分片键模式的索引,必须至少有一个索引采用简易排序规则。
警告
请勿修改任何当前分片键字段的范围或哈希类型。这会导致数据不一致。例如,请勿将分片密钥从 { customer_id: 1 } 修改为 { customer_id: "hashed", order_id: 1 }。
示例
要在test数据库中设置示例,请执行以下操作:
使用以下
shardCollection操作对orderstest数据库中的collection进行分片。该操作使用customer_id字段作为初始分片键:db.adminCommand( { shardCollection: "test.orders", key: { customer_id: 1 } } )
要将分片键修改为customer_id字段和order_id字段{ customer_id: 1, order_id: 1 } ,
Create the index以支持新的分片键(如果索引尚不存在)。db.getSiblingDB("test").orders.createIndex( { customer_id: 1, order_id: 1 } ) Run
refineCollectionShardKeycommand to add theorder_idfield as a suffix:db.adminCommand( { refineCollectionShardKey: "test.orders", key: { customer_id: 1, order_id: 1 } } )
成功完成该命令后,集合的分片键已更改为{ customer_id: 1, order_id: 1 } 。 要进行验证,您可以运行sh.status() 。
提示
优化分片键后,可能并非集合中的所有文档都具有后缀字段。要填充缺失的分片键字段,请参阅缺失的分片键字段。
在细化分片键之前,请确保集合中的所有或大多数文档都具有后缀字段(如果可能),以避免后期再填充字段。
具有非simple 排序规则的集合
要在test数据库中设置示例,请执行以下操作:
在
test数据库中创建caféscollection,指定法语fr作为默认排序规则。db.getSiblingDB("test").createCollection( "cafés", { collation: { locale: "fr" } } ); 使用
customer_id字段作为初始分片键对collection进行分片。由于该collection具有默认的fr排序规则而不是simple排序规则,因此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 } ,
Create the index以支持新的分片键(如果该索引尚不存在)。 由于collection使用非简单排序规则,因此索引必须包含collation: { locale: "simple" }选项。db.getSiblingDB("test").cafés.createIndex( { customer_id: 1, order_id: 1 }, { collation: { locale: "simple" } } ) Run
refineCollectionShardKeycommand to add theorder_idfield as a suffix:db.adminCommand( { refineCollectionShardKey: "test.cafés", key: { customer_id: 1, order_id: 1 } } )
成功完成该命令后,集合的分片键已更改为{ customer_id: 1, order_id: 1 } 。 要进行验证,您可以运行sh.status() 。
提示
优化分片键后,可能并非集合中的所有文档都具有后缀字段。要填充缺失的分片键字段,请参阅缺失的分片键字段。
在细化分片键之前,请确保集合中的所有或大多数文档都具有后缀字段(如果可能),以避免后期再填充字段。
提示