索引在填充集合上生成操作

默认情况下, 在填充集合上创建索引会阻止数据库上的所有其他操作。

在填充集合上生成索引时, 保存该集合的数据库在索引生成完成之前不可用于读取或写入操作。

任何需要对所有数据库 (例如 listDatabases) 进行读或写锁定的操作都将等待前台索引生成完成。

背景建设

注意

下一节介绍在独立上构建索引。对于副本集或共享群集, 请使用滚动索引生成。

有关详细信息, 请参阅在副本集上生成索引

对于在独立部署上可能运行时间较长的索引生成操作, 请考虑后台选项, 以便 mongodb 数据库在索引生成操作期间保持可用。

例如, 若要在人员集合的 zipcode 字段的背景中创建索引, 请发出以下问题:

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

默认情况下, 构建 mongodb 索引的背景为 false。

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

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

行为

后台索引操作在后台运行, 以便在创建索引时可以运行其他数据库操作。

但是, 创建索引的 mongo shell 会话或连接将被阻止, 直到索引生成完成。若要继续向数据库发出命令, 请打开另一个连接或 mongo 实例。

查询将不使用部分生成的索引: 索引只有在索引生成完成后才可用。

注意

如果 mongodb 在后台生成索引, 则不能执行涉及该集合的其他管理操作, 包括运行修复数据库、删除集合 (即 db.collection.drop()) 和运行压缩。

这些操作将在后台索引生成过程中返回错误。

性能

后台索引操作使用的增量方法比正常的 “前台” 索引生成慢。

如果索引大于可用 ram, 则增量过程所需的时间可能比前台生成的时间要长得多。

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

在3.4 版中更改: 可以使用数据库命令 createindex 在集合上生成一个或多个索引。创建索引操作的内存使用的默认限制为500兆字节。您可以通过设置最大索引生成内存使用兆字节服务器参数来覆盖此限制。

索引使用磁盘上的内存和临时文件的组合来完成索引生成。达到内存限制后, createindex 将在 –dbpath 目录中名为 _tmp 的子目录中使用临时磁盘文件以获得额外的临时空间。

设置的内存限制越高, 速度就越快

在副本集和锐化群集上生成索引

若要最大限度地减少生成索引对副本集和带有副本集分片的共享群集的影响, 请使用滚动索引生成过程, 如在副本集上生成索引中所述。

如果不使用滚动索引生成过程:

主服务器上的前台索引生成需要数据库锁。它在副本集辅助服务器上作为前台索引生成进行复制, 复制工作人员采用全局数据库锁, 该锁将读取和写入索引服务器上的所有数据库。 背景索引在辅助文件上生成的背景索引。复制工作人员不采用全局数据库锁定, 并且辅助读取不受影响。 对于在主索引基础上生成的前台和背景索引, 副本集辅助服务器上的索引操作在主索引完成生成索引后开始。

mongodb 4.0 +,不能为作为副本集一部分的 mongod 指定存储。

回滚和背景索引生成

从4.0 版开始, mongodb 将等待任何正在进行的后台索引生成完成, 然后再开始回滚。

在副本集和集群集上生成索引

若要最大限度地减少生成索引对副本集和带有副本集分片的共享群集的影响, 请使用滚动索引生成过程, 如在副本集上生成索引中所述。

如果不使用滚动索引生成过程:

主服务器上的前台索引生成需要数据库锁。它在副本集辅助服务器上作为前台索引生成进行复制, 复制工作人员采用全局数据库锁, 该锁将读取和写入索引服务器上的所有数据库。

背景索引在辅助文件上生成的背景索引。复制工作人员不采用全局数据库锁定, 并且辅助读取不受影响。

对于在主索引基础上生成的前台和背景索引, 副本集辅助服务器上的索引操作在主索引完成生成索引后开始。

在辅助设备上生成索引所需的时间必须在 oplog 的窗口内, 以便辅助索引可以赶上主索引。

有关在副本集和共享的群集上生成索引的完整过程, 请参阅在副本集上生成索引。

目的

若要最大限度地减少生成索引对具有副本集分片的副本集和共享群集的影响, 请使用以下过程以滚动方式生成索引。

此过程一次将一个成员从副本集中取出。但是, 此过程将一次只影响集合中的一个成员, 而不是同时影响所有辅助成员。

考虑

独特的索引

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

如果在此过程中无法停止对集合的所有写入, 请不要使用此页上的过程。

相反, 通过以下方式在集合上生成唯一索引:

在副本集的主服务器上发出 db.collection.createIndex, 或在共享群集的单机上发出 db.collection.createIndex

oplog 大小

确保您的 oplog 足够大, 可以使索引或重新索引操作完成, 而不会落后太远, 无法赶上。

有关其他信息, 请参阅 oplog 大小调整文档

程序

注意

如果需要在共享群集中生成索引, 请对提供每个分片的每个副本集重复以下过程。

若要使用以下过程创建唯一索引, 必须在索引生成过程中停止对集合的所有写入。

否则, 您最终可能会在副本集成员之间获得不一致的数据。如果无法停止对集合的所有写入, 请不要使用以下过程创建唯一的索引。

具体如何操作,详情

Index Name

索引的默认名称是索引键的串联以及索引中每个键的方向 (1 或-1)。

例子

发出以下命令以创建 item 和 quantity 的索引:

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

索引名称为:item_1_quantity_-1.

指定名称

或者, 您可以指定索引的名称, 而不是使用默认名称。

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

db.collection.getIndexes() 可以获取所有的索引信息。

查看索引生成操作

若要查看索引生成操作的状态, 可以在 mongo shell 中使用 db. currentop () 方法。

若要筛选索引创建操作的当前操作, 请参阅活动索引操作的示例。

msg 字段将包括已完成生成的百分比。

终止索引生成操作

若要终止正在进行的索引生成, 请在 mongo shell 中使用 db.killOp() 方法。对于索引生成, db.killOp() 的影响可能不是立竿见影的, 并且可能会在索引生成操作的大部分完成后很容易发生。

不能终止副本集的辅助成员上的复制索引生成。若要最大限度地减少生成索引对副本集和带有副本集分片的共享群集的影响, 请参阅在副本集上生成索引。

参考资料

Indexes