关于此任务
滚动索引构建是 默认索引构建的替代方案。
警告
避免同时执行滚动索引和复制索引构建过程,因为这可能会导致意外问题,例如构建中断和循环崩溃。
Considerations
警告
确保在进行滚动索引构建时没有执行DDL 操作。
Unique Indexes
要通过以下过程创建唯一索引,必须在此过程中停止对集合的所有写入。
如果您在该过程中无法停止对集合的所有写入,请不要使用本页上的过程。相反,在分片集群的 mongos
上发出 db.collection.createIndex()
,以在集合上构建唯一索引。
Oplog 大小
确保您的 oplog 足够大,以允许索引或重新索引操作完成,而不会落后太远而无法赶上。有关更多信息,请参阅 oplog 大小调整文档。
滚动索引构建会降低集群的弹性并增加构建持续时间。
开始之前
- 用于构建唯一索引
要使用以下过程创建唯一索引,您必须在索引构建期间停止对集合的所有写入。否则,可能在副本集节点之间具有不一致的数据。如果您无法停止对集合的所有写入,请不要使用以下过程创建唯一索引。
警告
如果无法停止对集合的所有写入,请勿使用以下步骤创建唯一索引。
在创建索引之前,请验证集合中是否有任何文档违反索引约束。 如果集合分布在分片上,并且分片包含具有重复文档的数据段,则创建索引操作可能会在没有重复项的分片上成功,但不会在有重复项的分片上成功。 为避免分片之间留下不一致的索引,您可以发出
db.collection.dropIndex()
中的mongos
将索引从集合中删除。
从MongoDB 8.0开始,您可以使用directShardOperations
角色执行需要直接对分片执行命令的分片操作。
警告
使用directShardOperations
角色运行命令可能会导致集群停止正常工作,并可能导致数据损坏。 仅将directShardOperations
角色用于维护目的或在MongoDB支持的指导下使用。 执行完维护操作后,请停止使用directShardOperations
角色。
步骤
A. 停止迁移
将mongosh
mongos
连接到分片集群中的 实例,并禁用要执行滚动构建索引的集合的迁移:
db.adminCommand( { setAllowMigrations: "<db>.<collection>", allowMigrations: false } )
前面的命令可确保将正确的分片设立作为滚动索引构建的目标,因为不允许提交集合的任何迁移。
如果该命令返回以下错误,则表示该集合未分片。您可以安全地忽略该错误并继续下一步。
MongoServerError[NamespaceNotSharded]: Collection must be sharded so migrations can be blocked
B. 确定集合的分配情况
要确定哪些分片必须参与滚动索引构建,请对要在其上构建索引的集合运行以下聚合:
db.getSiblingDB(<db>).getCollection(<collection>).aggregate([{$collStats:{}},{$group: {_id: "$ns", shard_list: {$addToSet: "$shard"}}}])
示例,如果要在 test
数据库中的 records
集合上创建索引:
db.getSiblingDB("test").getCollection("records").aggregate([{$collStats:{}},{$group: {_id: "$ns", shard_list: {$addToSet: "$shard"}}}])
[ { _id: 'test.records', shard_list: [ 'shardA', 'shardC' ] } ]
根据输出,您只能在 shardA
和 shardC
上构建 test.records
的索引。
C. 在包含集合数据块的分片上构建索引
对于包含集合数据段的每个分片,请按照在分片上构建索引的过程进行操作。
C1. 停止一个从节点并重启为独立实例
对于受影响的分片,停止与其从节点之一关联的 mongod
进程。在进行以下配置更新后,重新启动:
如果使用配置文件,请进行以下配置更新:
注释掉
replication.replSetName
选项。注释掉
sharding.clusterRole
选项。在
setParameter
部分中将参数skipShardingConfigurationChecks
设置为true
。在
setParameter
部分中将参数disableLogicalSessionCacheRefresh
设置为true
。
例如,对于分片副本集节点,更新后的配置文件将包含类似如下示例的内容:
net: bindIp: localhost,<hostname(s)|ip address(es)> port: 27218 # port: 27018 #replication: # replSetName: shardA #sharding: # clusterRole: shardsvr setParameter: skipShardingConfigurationChecks: true disableLogicalSessionCacheRefresh: true
并重新启动:
mongod --config <path/To/ConfigFile>
其他设置(例如storage.dbPath
等等)保持不变。
如果使用命令行选项,请进行以下配置更新:
如果是分片成员,则删除
--shardsvr
;如果是配置服务器分片,则删除 {--configsvr
。在
--setParameter
选项中将参数 设置为skipShardingConfigurationChecks
。true
在
--setParameter
选项中将参数disableLogicalSessionCacheRefresh
设置为true
。
例如,在不使用 --replSet
和 --shardsvr
选项的情况下重启分片副本集节点。指定新的端口号并将 skipShardingConfigurationChecks
和 disableLogicalSessionCacheRefresh
参数均设置为 true:
mongod --port 27218 --setParameter skipShardingConfigurationChecks=true --setParameter disableLogicalSessionCacheRefresh=true
其他设置(例如--dbpath
等等)保持不变。
[1] | (1、2)通过在不同端口上运行 mongod 可以确保在构建索引时,副本集的其他节点及所有客户端不会联系该节点。 |
C2. 构建索引
直接连接到在新端口上独立运行的 mongod
实例,并为该实例创建新索引。
例如,将 mongosh
连接到实例,并使用 db.collection.createIndex()
方法在 records
集合的 username
字段上创建一个升序索引:
db.records.createIndex( { username: 1 } )
C 3 .mongod
以副本集成员身份重新启动程序
索引构建完成后,关闭 mongod
实例。撤消以独立节点身份启动时所做的配置更改,以恢复其原始配置,并重新启动。
重要
请务必删除 skipShardingConfigurationChecks
和 disableLogicalSessionCacheRefresh
参数。
例如,要重新启动副本集分片成员:
如果您在使用配置文件:
恢复到原始端口号。
取消对
replication.replSetName
的注释。取消对
sharding.clusterRole
的注释。移除
setParameter
部分中的参数skipShardingConfigurationChecks
。删除
setParameter
部分的参数disableLogicalSessionCacheRefresh
。
net: bindIp: localhost,<hostname(s)|ip address(es)> port: 27018 replication: replSetName: shardA sharding: clusterRole: shardsvr
其他设置(例如storage.dbPath
等等)保持不变。
并重新启动:
mongod --config <path/To/ConfigFile>
如果您使用的是命令行选项:
恢复到原始端口号。
包括
--replSet
。如果是分块节点,请包含
--shardsvr
;如果是配置服务器节点,请包含--configsvr
。Remove parameter
skipShardingConfigurationChecks
.Remove parameter
disableLogicalSessionCacheRefresh
.
例如:
mongod --port 27018 --replSet shardA --shardsvr
其他设置(例如--dbpath
等等)保持不变。
允许复制赶上此节点。
C4. 对分片的剩余从节点重复该过程
一旦该节点赶上副本集中的其他节点,逐次逐个对剩余从节点重复该过程:
E. 在主节点上构建索引
当分片的所有从节点均有新索引时,分片的主节点降级,通过上述过程将其重启为独立运行的节点,然后在前一个主节点上构建索引:
使用
mongosh
中的rs.stepDown()
方法将主节点降级。成功降级后,当前主节点将变为从节点,并且副本集成员会选举新的主节点。
D. 对其他受影响的分片重复上述步骤
在完成构建分片的索引后,为其他受影响的分片重复执行 C. 在包含集合数据块的分片上构建索引。
E. 启用迁移
将 mongosh
连接到分片集群中的 mongos
实例,并使用 setAllowMigrations
重新启用迁移:
db.adminCommand( { setAllowMigrations: "<db>.<collection>", allowMigrations: true } )
如果该命令返回以下错误,则表示该集合未分片。您可以放心地忽略该错误。
MongoServerError[NamespaceNotSharded]: Collection must be sharded so migrations can be blocked
更多信息
如果一个分片集合在包含集合数据块的每个分片上没有完全相同的索引(包括索引选项),则该集合的索引不一致。尽管一般操作过程中不应出现索引不一致的情况,但这种情况仍有可能发生,例如:
当用户使用
unique
键约束创建索引,且一个分片包含具有重复文档的数据段时。在此类情况下,创建索引操作可能会对没有重复项的分片成功完成,而对有重复项的分片失败。当用户以滚动方式跨分片创建索引,但未能为关联分片构建索引或错误地构建了具有不同规范的索引。
配置服务器主节点会定期检查分片集合的分片之间的索引不一致情况。要配置这些定期检查,请参阅 enableShardedIndexConsistencyCheck
和 shardedIndexConsistencyCheckIntervalMS
。
在配置服务器主节点上运行时,命令 serverStatus
返回字段 shardedIndexConsistency
以报告索引不一致的情况。
要检查分片集合是否存在不一致的索引,请参阅查找分片间不一致的索引。