对于 AI 代理:可在 https://www.mongodb.com/zh-cn/docs/llms.txt 获取文档索引—通过在任何 URL 路径后添加 .md 可获取所有页面的 Markdown 版本。
Docs 菜单

在分片集群上创建滚动索引构建

滚动索引构建是默认索引构建的替代方案。

警告

避免同时执行滚动索引和复制索引构建过程,因为这可能会导致意外问题,例如构建中断和循环崩溃。

警告

确保在进行滚动索引构建时没有执行DDL 操作

要通过以下过程创建唯一索引,必须在此过程中停止对集合的所有写入。

如果您在执行步骤的过程中无法停止所有对集合的写入操作,请不要使用本页所列的步骤。相反,通过在分片集群的 mongos 上发出db.collection.createIndex() 来为集合构建唯一索引。

确保您的 oplog 足够大,以允许索引或重新索引操作完成,而不会落后太远而无法赶上。有关更多信息,请参阅 oplog 大小调整文档。

滚动索引构建会降低集群的弹性并增加构建持续时间。

用于构建唯一索引
  1. 要使用以下过程创建唯一索引,您必须在索引构建期间停止对集合的所有写入。否则,可能在副本集节点之间具有不一致的数据。如果您无法停止对集合的所有写入,请不要使用以下过程创建唯一索引。

    警告

    如果无法停止对集合的所有写入,请勿使用以下步骤创建唯一索引。

  2. 在创建索引之前,请验证集合中是否有任何文档违反索引约束。 如果集合分布在分片上,并且分片包含具有重复文档的数据段,则创建索引操作可能会在没有重复项的分片上成功,但不会在有重复项的分片上成功。 为避免分片之间留下不一致的索引,您可以发出db.collection.dropIndex() 中的mongos 将索引从集合中删除。

从MongoDB 8.0开始,您可以使用directShardOperations角色执行需要直接对分片执行命令的分片操作。

警告

使用 directShardOperations角色运行命令可能会导致集群停止正常工作,并可能导致数据损坏。仅将 directShardOperations角色用于维护目的或在MongoDB支持的指导下使用。执行完维护操作后,请停止使用 directShardOperations角色。

重要

以滚动方式构建索引的以下过程适用于分片的集群部署,而不是副本集部署。 有关副本集的过程,请参阅在副本集上创建滚动索引构建。

Connect mongosh to a mongos instance in the sharded cluster and disable migrations for the collection where you want to perform the rolling build index:

db.adminCommand(
{
setAllowMigrations: "<db>.<collection>",
allowMigrations: false
}
)

前面的命令可确保将正确的分片设立作为滚动索引构建的目标,因为不允许提交集合的任何迁移。

如果该命令返回以下错误,则表示该集合未分片。您可以安全地忽略该错误并继续下一步。

MongoServerError[NamespaceNotSharded]: Collection must be sharded so migrations can be blocked

要确定哪些分片必须参与滚动索引构建,请对要在其上构建索引的集合运行以下聚合:

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' ] } ]

根据输出,您只能在 shardAshardC 上构建 test.records 的索引。

对于包含集合数据段的每个分片,请按照在分片上构建索引的过程进行操作。

对于受影响的分片,停止与其从节点之一关联的 mongod 进程。在进行以下配置更新后,重新启动:

如果使用配置文件,请进行以下配置更新:

例如,对于分片副本集节点,更新后的配置文件将包含类似如下示例的内容:

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 等等)保持不变。

如果使用命令行选项,请进行以下配置更新:

例如,在不使用 --replSet--shardsvr 选项的情况下重启分片副本集节点。指定新的端口号并将 skipShardingConfigurationChecksdisableLogicalSessionCacheRefresh 参数均设置为 true:

mongod --port 27218 --setParameter skipShardingConfigurationChecks=true --setParameter disableLogicalSessionCacheRefresh=true

其他设置(例如--dbpath 等等)保持不变。

[1](12)通过在不同端口上运行 mongod 可以确保在构建索引时,副本集的其他节点及所有客户端不会联系该节点。

直接连接到在新端口上独立运行的 mongod 实例,并为该实例创建新索引。

For example, connect mongosh to the instance, and use the db.collection.createIndex() method to create an ascending index on the username field of the records collection:

db.records.createIndex( { username: 1 } )

索引构建完成后,关闭 mongod 实例。撤消以独立节点身份启动时所做的配置更改,以恢复其原始配置,并重新启动。

重要

请务必删除 skipShardingConfigurationChecksdisableLogicalSessionCacheRefresh 参数。

例如,要重新启动副本集分片成员:

如果您在使用配置文件:

net:
bindIp: localhost,<hostname(s)|ip address(es)>
port: 27018
replication:
replSetName: shardA
sharding:
clusterRole: shardsvr

其他设置(例如storage.dbPath 等等)保持不变。

并重新启动:

mongod --config <path/To/ConfigFile>

如果您使用的是命令行选项:

例如:

mongod --port 27018 --replSet shardA --shardsvr

其他设置(例如--dbpath 等等)保持不变。

允许复制赶上此节点。

一旦该节点赶上副本集中的其他节点,逐次逐个对剩余从节点重复该过程:

当分片的所有从节点均有新索引时,分片的主节点降级,通过上述过程将其重启为独立运行的节点,然后在前一个主节点上构建索引:

  1. Use the rs.stepDown() method in mongosh to step down the primary. Upon successful stepdown, the current primary becomes a secondary and the replica set members elect a new primary.

在完成构建分片的索引后,为其他受影响的分片重复执行 C. 在包含集合数据块的分片上构建索引

Connect mongosh to a mongos instance in the sharded cluster and re-enable the migration with setAllowMigrations:

db.adminCommand(
{
setAllowMigrations: "<db>.<collection>",
allowMigrations: true
}
)

如果该命令返回以下错误,则表示该集合未分片。您可以放心地忽略该错误。

MongoServerError[NamespaceNotSharded]: Collection must be sharded so migrations can be blocked

如果一个分片集合在包含集合数据块的每个分片上没有完全相同的索引(包括索引选项),则该集合的索引不一致。尽管一般操作过程中不应出现索引不一致的情况,但这种情况仍有可能发生,例如:

  • 当用户使用 unique 键约束创建索引,且一个分片包含具有重复文档的数据段时。在此类情况下,创建索引操作可能会对没有重复项的分片成功完成,而对有重复项的分片失败。

  • 当用户以滚动方式跨分片创建索引,但未能为关联分片构建索引或错误地构建了具有不同规范的索引。

配置服务器主节点会定期检查分片集合的分片之间的索引不一致情况。要配置这些定期检查,请参阅 enableShardedIndexConsistencyCheckshardedIndexConsistencyCheckIntervalMS

在配置服务器主节点上运行时,命令 serverStatus 返回字段 shardedIndexConsistency 以报告索引不一致的情况。

要检查分片集合是否存在不一致的索引,请参阅查找分片间不一致的索引