参考 > 指标 > 在填充的集合上建立索引 > 在分片群集上建立索引
为了最大程度地减少在 具有副本集分片的分片群集上建立索引的影响,请使用以下过程以滚动方式建立索引。有关在副本集部署上构建索引的信息,请参阅在副本集上构建索引。
以下用于分片群集部署的过程确实一次取出了一个分片副本集的一个成员。但是,此过程一次只会影响一个成员,而不会同时影响所有 第二个成员。
要使用以下过程创建唯一索引,必须在此过程中停止对集合的所有写操作。
如果在此过程中无法停止对集合的所有写操作,请不要使用此页面上的过程。相反,可以通过db.collection.createIndex()
在分片mongos
群集上发出来在集合上构建唯一索引。
要使用以下过程创建唯一索引,必须在索引构建过程中停止对集合的所有写操作。否则,最终可能导致整个副本集成员的数据不一致。如果无法停止对集合的所有写操作,请不要使用以下过程创建唯一索引。
警告
如果无法停止对集合的所有写操作,请不要使用以下过程创建唯一索引。
在创建索引之前,请验证集合中没有文档违反索引约束。如果集合分布在各个分片上,并且一个分片包含具有重复文档的块,则创建索引操作可能会在没有重复的分片上成功执行,但在有重复的分片上不会成功。为了避免在分片上留下不一致的索引,可以发出
db.collection.dropIndex()
from mongos
来从集合中删除索引。
将mongo
外壳连接到分片mongos
群集中的实例,然后运行sh.stopBalancer()
以禁用平衡器:[1]
注意
如果正在进行迁移,则系统将在停止平衡器之前完成正在进行的迁移。
要验证是否禁用了平衡器,请运行run
sh.getBalancerState()
,如果禁用了平衡器,则返回false:
[1] | 从MongoDB 4.2开始,sh.stopBalancer() 还会禁用分片群集的自动拆分。 |
在mongo
连接到的外壳程序上
mongos
,刷新缓存的路由表,
mongos
以免返回该集合的陈旧分发信息。刷新后,运行
db.collection.getShardDistribution()
要构建索引的集合。
例如,如果要对数据库中的records
集合进行升序索引test
:
该方法输出碎片分布。例如,考虑具有3个碎片分片簇shardA
,shardB
以及shardC
与db.collection.getShardDistribution()
返回以下结果:
从输出中,仅构建test.records
on
shardA
和的索引shardC
。
对于每个包含集合块的分片,请按照以下步骤在分片上建立索引。
对于受影响的分片,请停止mongod
与其辅助节点之一相关联的进程。进行以下配置更新后,重新启动:
如果您使用的是配置文件,请进行以下配置更新:
net.port
改为其他端口。[2]
记下原始端口设置作为注释。replication.replSetName
选项。sharding.clusterRole
选项。skipShardingConfigurationChecks
中将参数设置(也适用于MongoDB 3.6.3 +,3.4.11 +,3.2.19 +)
。true
setParameter
disableLogicalSessionCacheRefresh
为
。true
setParameter
例如,对于分片副本集成员,更新的配置文件将包含类似于以下示例的内容:
并重新启动:
其他设置(例如storage.dbPath
等)保持不变。
如果使用命令行选项,请进行以下配置更新:
--port
为其他端口。[2]--replSet
。--shardsvr
如果分片成员和--configsvr
配置服务器成员都删除。skipShardingConfigurationChecks
中将参数设置
(也适用于MongoDB 3.6.3 +,3.4.11 +,3.2.19 +)
。true
--setParameter
disableLogicalSessionCacheRefresh
为。true
--setParameter
例如,重新启动不带--replSet
和
--shardsvr
选项的分片副本集成员。指定新的端口号,并将skipShardingConfigurationChecks
和
disableLogicalSessionCacheRefresh
参数都设置
为true:
其他设置(例如--dbpath
等)保持不变。
[2] | (1,2)通过运行mongod 在不同的端口上,可以确保当你正在构建的指数副本集的其他成员和所有客户端将无法联系这位会员。 |
直接连接到在mongod
新端口上独立运行的实例,并为此实例创建新索引。
例如,将mongo
外壳连接到实例,然后使用db.collection.createIndex()
方法username
在records
集合的字段上创建升序索引:
mongod
作为副本集成员¶索引构建完成后,关闭mongod
实例。撤消以独立版本启动时所做的配置更改,以返回其原始配置并重新启动。
重要
确保删除
skipShardingConfigurationChecks
参数和
disableLogicalSessionCacheRefresh
参数。
例如,重新启动副本集分片成员:
如果您使用的是配置文件:
replication.replSetName
。sharding.clusterRole
。skipShardingConfigurationChecks
在该setParameter
部分中删除参数。disableLogicalSessionCacheRefresh
在该setParameter
部分中删除参数。其他设置(例如storage.dbPath
等)保持不变。
并重新启动:
如果您使用命令行选项:
--replSet
。--shardsvr
成员或--configsvr
配置服务器成员。skipShardingConfigurationChecks
。disableLogicalSessionCacheRefresh
。例如:
其他设置(例如--dbpath
等)保持不变。
允许复制赶上该成员。
一旦该成员赶上了集合中的其他成员,请对一个碎片的其余次要成员一次重复一个成员的过程:
当分片的所有辅助数据库都具有新索引时,请降低分片的主数据库,使用上述过程以独立方式重新启动它,然后在前一个主数据库上建立索引:
rs.stepDown()
方法mongo
降低主数据库的性能。成功降级后,当前的主节点将成为辅助节点,副本集成员将选择新的主节点。一旦完成了受影响分片的滚动索引构建,请重新启动平衡器。
将mongo
外壳连接到分片mongos
群集中的实例,然后运行sh.startBalancer()
:[3]
[3] | 从MongoDB 4.2开始,sh.startBalancer() 还可以对分片群集进行自动拆分。 |
如果分片集合在每个包含该分片块的分片上没有完全相同的索引(包括索引选项),则该索引的索引不一致。尽管在正常操作期间不应出现不一致的索引,但是可能会出现不一致的索引,例如:
unique
键约束的索引且一个分片包含具有重复文档的块时。在这种情况下,创建索引操作可能会在没有重复的分片上成功,但在没有重复的分片上不会成功。从MongoDB 4.2.6开始,配置服务器主服务器会定期检查分片集合中各分片之间的索引不一致。要配置这些定期检查,请参阅
enableShardedIndexConsistencyCheck
和
shardedIndexConsistencyCheckIntervalMS
。
当在配置服务器主服务器上运行时,该命令serverStatus
返回该字段
shardedIndexConsistency
以报告索引不一致情况。
要检查分片集合是否具有不一致的索引,请参阅 查找分片中的不一致索引。