填充集合上的索引构建操作

在本页面

默认情况下,在填充的集合上创建索引会阻止数据库上的所有其他操作。在填充的集合上构建索引时,保存该集合的数据库在索引构建完成之前无法进行读取或写入操作。任何需要对所有数据库(例如 listDatabases )进行读或写锁定的操作都将 await 前台索引构建完成。

Background Construction

Note

下一节将介绍在独立平台上构建索引。对于副本集或分片群集,请使用滚动索引构建。有关详情,请参见在副本集上构建索引

对于独立部署上可能需要长时间运行的索引构建操作,请考虑使用background选项,以便在索引构建操作期间 MongoDB 数据库保持可用。

例如,要在people集合的zipcode字段的背景中创建索引,请发出以下命令:

db.people.createIndex( { zipcode: 1 }, { background: true } )

默认情况下,用于构建 MongoDB 索引的backgroundfalse

您可以将 background 选项与其他选项结合使用,如下所示:

db.people.createIndex( { zipcode: 1 }, { background: true, sparse: true } )

Behavior

后台索引操作在后台运行,以便在创建索引时可以运行其他数据库操作。但是,创建索引的mongo shell 会话或连接阻塞,直到索引构建完成。要 continue 向数据库发出命令,请打开另一个连接或mongo实例。

查询不会使用部分构建的索引:只有在索引构建完成后,索引才可用。

Note

如果 MongoDB 在后台构建索引,则您将无法执行其他与该集合有关的 Management 操作,包括运行repairDatabase,删除该集合(即db.collection.drop())和运行compact。这些操作将在后台索引构建期间返回错误。

Performance

后台索引操作使用的增量方法比正常的“前景”索引构建慢。如果索引大于可用的 RAM,则增量过程可能比前台构建花费*多得多的时间。

构建索引可能会对数据库的性能产生严重影响。如果可能,请在指定的维护时段内构建索引。

在版本 3.4 中进行了更改:您可以使用数据库命令createIndexes在集合上构建一个或多个索引。 createIndexes操作的默认内存使用限制为 500 MB。您可以通过设置maxIndexBuildMemoryUsageMegabytes服务器参数来覆盖此限制。

createIndexes结合使用内存和磁盘上的临时文件来完成索引构建。达到内存限制后,createIndexes--dbpath目录中名为_tmp的子目录中的临时磁盘文件用于其他暂存空间。设置的内存限制越高,索引构建就可以完成得越快,但是请注意不要相对于可用 RAM 将此限制设置得太高,否则系统可能会耗尽可用内存。

索引构建中断

如果独立索引(即不是副本集的一部分)mongod进程终止时正在进行后台索引构建,则实例重新启动时,索引构建将作为前台索引构建重新启动。如果索引构建遇到任何错误,例如重复键错误,则mongod将退出并显示错误。

要在失败的索引构建后启动独立的mongod,请使用storage.indexBuildRetry--noIndexBuildRetry在启动时跳过索引构建。

storage.indexBuildRetry--noIndexBuildRetry不会阻止复制索引的构建。

在副本集和分片群集上构建索引

为了最大程度地减少构建索引对以下方面的影响:

如果不使用滚动索引构建过程:

  • 构建在primary上的前台索引需要 DB 锁。它作为在replica set secondaries上构建的前台索引进行复制,并且复制工作程序获取全局 DB 锁,该锁将对索引服务器上所有数据库的读取和写入排队。

  • 背景索引构建在主数据库上,而背景索引构建在第二数据库上。复制工作器不会获取全局数据库锁,并且辅助读取不会受到影响。

  • 对于在主数据库上构建的前台索引和背景索引,副本集辅助数据库上的索引操作在主数据库完成索引构建之后开始。

在辅助数据库上构建索引所需的时间必须在oplog的窗口内,以便辅助数据库可以赶上主数据库。

Index Names

索引的默认名称是索引键的组合以及索引中每个键的方向,即 1 或-1.

Example

发出以下命令在itemquantity上创建索引:

db.products.createIndex( { item: 1, quantity: -1 } )

结果索引名为:item_1_quantity_-1

(可选)您可以为索引指定名称,而不使用默认名称。

Example

发出以下命令在itemquantity上创建索引,并指定inventory作为索引名称:

db.products.createIndex( { item: 1, quantity: -1 } , { name: "inventory" } )

结果索引的名称为inventory

若要查看索引的名称,请使用getIndexes()方法。

查看索引构建操作

要查看索引构建操作的状态,可以在mongo shell 中使用db.currentOp()方法。要为索引创建操作过滤当前操作,请参见主动索引操作作为示例。

msg字段将包含已完成构建的百分比。

终止索引构建操作

要终止正在进行的索引构建,请在mongo shell 中使用db.killOp()方法。对于索引构建,db.killOp()的影响可能不会立即产生,并且可能会在许多索引构建操作完成后立即发生。

您不能在副本集的辅助成员上终止* replicated *索引构建。

为了最大程度地减少在具有副本集分片的副本集和分片群集上构建索引的影响,请参阅: