MongoDB 限制和阈值

在本页面

本文档提供了 MongoDB 系统的硬性限制和软性限制。

BSON Documents

  • BSON Document Size
    • BSON 文档的最大大小为 16 MB。

最大文档大小有助于确保单个文档不会使用过多的 RAM 或在传输过程中占用过多的带宽。要存储大于最大大小的文档,MongoDB 提供了 GridFS API。有关 GridFS 的更多信息,请参见mongofilesdriver的文档。

  • Nested Depth for BSON Documents

Naming Restrictions

  • Database Name Case Sensitivity

    • 由于数据库名称在 MongoDB 中不区分大小写,因此数据库名称不能仅因字符的大小写而不同。
  • Restrictions on Database Names for Windows

    • 对于在 Windows 上运行的 MongoDB 部署,数据库名称不能包含以下任何字符:
/\. "$*<>:|?

另外,数据库名称不能包含空字符。

  • Restrictions on Database Names for Unix and Linux Systems
    • 对于在 Unix 和 Linux 系统上运行的 MongoDB 部署,数据库名称不能包含以下任何字符:
/\. "$

另外,数据库名称不能包含空字符。

  • Length of Database Names

    • 数据库名称不能为空,并且必须少于 64 个字符。
  • Restriction on Collection Names

    • 集合名称应以下划线或字母字符开头,并且不能*:
  • 包含$

  • 为空字符串(例如"")。

  • 包含空字符。

  • system.前缀开头。 (仅供内部使用.)

如果您的集合名称包含特殊字符(例如下划线字符)或以数字开头,则可以使用mongo shell 或您的驱动程序的类似方法中的db.getCollection()方法访问集合。

集合名称空间的最大长度为 120 个字节,其中包括数据库名称,点(.)分隔符和集合名称(即<database>.<collection>)。

  • Restrictions on Field Names

      • 字段名称 不能 包含null字符。
  • 顶级字段名称**不能以美元符号($)开头。

否则,从 MongoDB 3.6 开始,服务器允许存储包含点(即.)和美元符号(即$)的字段名称。

Important

MongoDB 查询语言不能始终有效地对字段名称包含这些字符的文档表示查询(请参见SERVER-30575)。

在以查询语言添加支持之前,不建议在字段名称中使用$.,并且官方 MongoDB 驱动程序不支持。

Namespaces

  • Namespace Length
    • 集合名称空间的最大长度为 120 个字节,其中包括数据库名称,点(.)分隔符和集合名称(即<database>.<collection>)。
  • Number of Namespaces
    • 在版本 3.0 中更改。

对于 MMAPv1,名称空间的数量限于名称空间文件的大小除以 628.

一个 16 MB 的名称空间文件可以支持大约 24,000 个名称空间。每个集合和索引都是一个名称空间。

WiredTiger 存储引擎不受此限制的约束。

  • Size of Namespace File
    • 在版本 3.0 中更改。

对于 MMAPv1 存储引擎,名称空间文件不能大于 2047 兆字节。

默认情况下,名称空间文件为 16 MB。您可以使用nsSize选项配置尺寸。

WiredTiger 存储引擎不受此限制的约束。

Indexes

  • Index Key Limit
    • 索引条目的“总大小”(可能包括取决于 BSON 类型的结构开销)必须“小于” 1024 个字节。

在 2.6 版中进行了更改:MongoDB 2.6 版和更高版本对index key实施了更严格的限制:

  • 如果现有文档的索引条目超过索引键限制,MongoDB 将“不”在集合上创建索引。 MongoDB 的早期版本将创建索引,但不会为此类文档构建索引。

  • 如果索引字段的索引条目超过索引键限制,则重新索引操作将出错。重新索引操作是compactrepairDatabase命令以及db.collection.reIndex()方法的一部分。

因为这些操作会从集合中删除所有索引,然后按 Sequences 重新创建它们,所以索引键限制的错误会阻止这些操作为该集合重建任何剩余的索引,并且对于repairDatabase命令,将阻止它们 continue 执行剩余的索引。过程。

  • MongoDB 不会将任何具有索引字段的文档插入到索引集合中,该文档的索引字段的对应索引条目将超过索引键限制,而是返回错误。 MongoDB 的早期版本将插入但不会索引此类文档。

  • 如果更新的值导致索引条目超过索引键限制,则对索引字段的更新将出错。

如果现有文档包含其索引条目超过限制的索引字段,则导致该文档在磁盘上重新定位的* any *更新将出错。

  • mongorestoremongoimport不会插入包含索引字段的文档,该字段的相应索引条目将超过索引键限制

  • 在 MongoDB 2.6 中,副本集的次要成员将 continue 复制带有索引字段的文档,该字段的对应索引条目在初始同步时超过索引键限制,但将在日志中打印警告。

次要成员还允许对包含索引字段的集合进行索引构建和重建操作,该索引字段的对应索引条目超过索引键限制但在日志中带有警告。

对于辅助目录为 2.6 版且主目录为 2.4 版的* mixed version *副本集,辅助目录将复制在 2.4 主目录上插入或更新的文档,但是如果文档包含其索引对应的索引字段,则会在日志中显示错误消息条目超过了索引键限制

  • Number of Indexes per Collection
    • 一个集合最多只能有 64 个索引。
  • Index Name Length
    • 包含名称空间和点分隔符(即<database name>.<collection name>.$<index name>)的标准索引名称不能超过 128 个字符。

默认情况下,<index name>是字段名称和索引类型的串联。您可以为createIndex()方法显式指定<index name>,以确保标准索引名称不超过限制。

  • Number of Indexed Fields in a Compound Index

    • 复合索引中的字段不能超过 32 个。
  • Queries cannot use both text and Geospatial Indexes

    • 您不能将需要特殊text index$text查询与需要不同类型的特殊索引的查询运算符组合在一起。例如,您不能将$text查询与$near运算符结合使用。
  • Fields with 2dsphere Indexes can only hold Geometries

    • 具有2dsphere索引的字段必须以coordinate pairsGeoJSON数据的形式保存几何数据。如果您尝试在2dsphere索引字段中插入具有非几何数据的文档,或者在索引字段具有非几何数据的集合上构建2dsphere索引,则该操作将失败。

See also

唯一索引限制为分片操作限制

  • NaN values returned from Covered Queries by the WiredTiger Storage Engine are always of type double

    • 如果从查询返回的字段值被索引覆盖NaN,则该NaN值的类型为始终 double
  • Multikey Index

  • Geospatial Index

  • Memory Usage in Foreground Index Builds

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

前景索引构建可以通过诸如Create Index的用户命令或诸如initial sync的 Management 过程来启动。两者都受maxIndexBuildMemoryUsageMegabytes设置的限制。

初始同步操作一次只能填充一个集合,并且没有超过内存限制的风险。但是,用户有可能同时在多个数据库中的多个集合上启动前台索引构建,并且可能消耗的内存量大于maxIndexBuildMemoryUsageMegabytes中设置的限制。

Tip

为了最大程度地减少在具有副本集分片的副本集和分片群集上构建索引的影响,请按照在副本集上构建索引所述使用滚动索引生成过程。

  • Collation and Index Types

    • 以下索引类型仅支持简单的二进制比较,不支持collation
  • text indexes,

  • 2d个索引,以及

  • geoHaystack indexes.

Tip

要在具有非简单排序规则的集合上创建text2dgeoHaystack索引,必须在创建索引时明确指定{collation: {locale: "simple"} }

Data

  • Maximum Number of Documents in a Capped Collection
    • 如果您使用createmax参数为有上限的集合指定最大文档数,则该限制必须少于 232 个文档。如果在创建上限集合时未指定最大文档数,则对文档数没有限制。
  • Database Size
    • MMAPv1 存储引擎将每个数据库限制为不超过 16000 个数据文件。这意味着单个 MMAPv1 数据库的最大大小为 32TB。设置storage.mmapv1.smallFiles选项会将此限制减少到 8TB。
  • Data Size
    • 在版本 3.0 中更改。

使用 MMAPv1 存储引擎,单个mongod实例无法 Management 超出基础 os 提供的最大虚拟内存地址空间的数据集。

虚拟内存限制

Operating SystemJournaledNot Journaled
Linux64 terabytes128 terabytes
Windows Server 2012 R2 和 Windows 8.164 terabytes128 terabytes
Windows (otherwise)4 terabytes8 terabytes

WiredTiger 存储引擎不受此限制的约束。

  • Number of Collections in a Database
    • 在版本 3.0 中更改。

对于 MMAPv1 存储引擎,数据库中最大集合数是名称空间文件大小和数据库中集合索引数的函数。

WiredTiger 存储引擎不受此限制的约束。

有关更多信息,请参见命名空间数

Replica Sets

  • Number of Members of a Replica Set
    • 在 3.0.0 版中更改。

副本集最多可包含 50 个成员。有关特定驱动程序与大型副本集兼容性的更多信息,请参见副本集成员数量增加

  • Number of Voting Members of a Replica Set

    • 副本集最多可以有 7 个投票成员。对于成员总数超过 7 个的副本集,请参阅Non-Voting Members
  • Maximum Size of Auto-Created Oplog

    • 在 2.6 版中进行了更改。

如果您未明确指定操作日志大小(即使用oplogSizeMB--oplogSize),则 MongoDB 将创建一个不超过 50 GB 的操作日志。

Sharded Clusters

分片群集具有此处描述的限制和阈值。

分片操作限制

从版本 3.0 开始不推荐使用:db.eval()

db.eval()与分片集合不兼容。您可以对分片群集中的未分片集合使用db.eval()

$where不允许从$where函数引用db对象。这在未分片的集合中并不常见。

分片环境中不支持geoSearch命令。

  • Covered Queries in Sharded Clusters
    • 从 MongoDB 3.0 开始,如果索引不包含分片键,则对mongos运行时,索引不能对_集合上的查询cover进行查询,但_id索引具有以下 exception:如果对分片集合的查询仅指定条件在_id字段上并仅返回_id字段,即使_id字段不是分片键,对mongos运行时_id索引也可以覆盖查询。

在以前的版本中,针对mongos运行时,索引不能coversharded集合的查询。

  • Sharding Existing Collection Data Size
    • 如果现有集合的大小未超过特定限制,则只能对其进行分片。可以基于所有shard key值的平均大小和配置的chunk大小来估计这些限制。

Important

这些限制仅适用于初始分片操作。成功启用分片后,分片集合可以增长到任何大小。

使用以下公式来计算“理论上”的最大收集大小。

maxSplits = 16777216 (bytes) / <average size of shard key values in bytes>
maxCollectionSize (MB) = maxSplits * (chunkSize / 2)

Note

BSON文档的最大大小为 16MB 或16777216字节。

所有转化均应使用以 2 为基数的标度,例如 1024 兆字节= 1 兆字节。

如果maxCollectionSize小于或几乎等于目标集合,则增加块大小以确保成功进行初始分片。如果对计算结果是否过于“接近”目标集合大小存有疑问,则最好增加块大小。

成功进行初始分片后,您可以根据需要减小块大小。如果以后减小块大小,则所有块都可能需要一些时间才能拆分为新的大小。有关修改块大小的说明,请参见修改分片群集中的块大小

下表使用上述公式说明了最大的近似收集大小:

分片键值的平均大小512 bytes256 bytes128 bytes64 bytes
最大分割数32,76865,536131,072262,144
最大收集大小(64 MB 块大小)1 TB2 TB4 TB8 TB
最大收集大小(128 MB 块大小)2 TB4 TB8 TB16 TB
最大收集大小(256 MB 块大小)4 TB8 TB16 TB32 TB
  • Single Document Modification Operations in Sharded Collections
  • Unique Indexes in Sharded Collections
    • MongoDB 不支持跨分片的唯一索引,除非唯一索引包含完整的分片键作为索引前缀。在这种情况下,MongoDB 将在整个键而不是单个字段上强制唯一性。

See

任意场的唯一约束作为替代方法。

  • Maximum Number of Documents Per Chunk to Migrate
    • 在版本 3.4.11 中进行了更改。

如果块中的文档数大于配置的chunk size除以平均文档大小所得结果的 1.3 倍,则 MongoDB 无法移动该块。 db.collection.stats()包含avgObjSize字段,该字段表示集合中的平均文档大小。

分片键限制

  • Shard Key Size

    • 分片密钥不能超过 512 个字节。
  • Shard Key Index Type

    • shard key索引可以是分片键上的升序索引,可以是以分片键开头并为分片键指定升序的复合索引,也可以是hashed index

shard key索引不能是在shard key字段上指定multikey indextext indexgeospatial index的索引。

  • Shard Key is Immutable

    • 如果必须更改分片键:
  • 将 MongoDB 中的所有数据转储为外部格式。

  • 删除原始分片集合。

  • 使用新的分片密钥配置分片。

  • Pre-split分片键范围,以确保初始均匀分配。

  • 将转储的数据还原到 MongoDB 中。

  • Shard Key Value in a Document is Immutable

    • 分片集合后,分片键和分片键值是不可变的。即
  • 您不能为该集合选择其他分片键。

  • 您无法更新分片键字段的值。

  • Monotonically Increasing Shard Keys Can Limit Insert Throughput

    • 对于具有高插入量的集群,具有单调递增和递减键的分片键会影响插入吞吐量。如果您的分片键是_id字段,请注意_id字段的默认值为ObjectIds,它们的值通常会增加。

当插入具有单调递增分片键的文档时,所有插入都在单个shard上属于相同的chunk。系统最终划分接收所有写操作的块范围,并迁移其内容以更均匀地分配数据。但是,群集在任何时候都只将插入操作定向到单个分片,这会造成插入吞吐量瓶颈。

如果群集上的操作主要是读取操作和更新,则此限制可能不会影响群集。

为避免此约束,请使用哈希分片键或选择一个不会单调增加或减少的字段。

哈希分片键hashed indexes存储带有升序值的键的散列。

Operations

  • Sort Operations
    • 如果 MongoDB 无法使用索引按请求的排序 Sequences 获取文档,则排序操作中所有文档的总大小加上少量开销必须小于 32 兆字节。
  • Aggregation Pipeline Operation

    • 管道阶段的 RAM 限制为 100 MiB(100 * 1024 * 1024 字节)。如果阶段超出此限制,则 MongoDB 将产生错误。为了处理大型数据集,您可以在aggregate()方法中设置allowDiskUse选项。 allowDiskUse选项使大多数聚合管道操作可以将数据写入临时文件。 allowDiskUse选项的 exception 是以下聚合操作;这些操作必须在内存限制限制内:
  • $graphLookup stage

  • $group阶段中使用的$addToSet累加器表达式(从版本 3.6.17 开始)

  • $group阶段中使用的$push累加器表达式(从版本 3.6.17 开始)

如果管道包含在aggregate()操作中观察到allowDiskUse: true的其他阶段,则allowDiskUse: true选项对这些其他阶段有效。

2d Geospatial queries cannot use the $or operator

See

$or2 d 索引内部

  • Geospatial Queries
    • 对于球形查询,请使用2dsphere索引结果。

对于球形查询使用2d索引可能会导致错误的结果,例如对于围绕极点的球形查询使用2d索引。

在版本 3.6 中进行了更改:写入次数从1,000增加到100,000。此限制也适用于旧版OP_INSERT消息。

mongo Shell 中的Bulk()操作以及驱动程序中的类似方法没有此限制。

Sessions

  • Sessions and $external Username Limit

    • 在版本 3.6.3 中更改:要与$external个身份验证用户(即 Kerberos,LDAP,x.509 用户)一起使用会话,用户名不能超过 10k 字节。
  • Session Idle Timeout

    • 在此阈值内未使用refreshSessions刷新且 30 分钟未进行任何读或写操作的会话被标记为已过期,并且可以随时由 MongoDB 服务器关闭。关闭会话会终止正在进行的所有操作,并打开与该会话关联的游标。这包括配置为noCursorTimeoutmaxTimeMS大于 30 分钟的游标。

考虑发布db.collection.find()的应用程序。服务器返回游标以及find()cursor.batchSize()定义的一批文档。每当应用程序从服务器请求新一批文档时,会话都会刷新。但是,如果应用程序花费超过 30 分钟的时间来处理当前批次的文档,则该会话将被标记为已过期并关闭。当应用程序请求下一批文档时,服务器将返回错误,因为在关闭会话时光标被杀死。

对于返回游标的操作,如果游标可能闲置了 30 分钟以上,请使用Session.startSession()在显式会话中发出操作,并使用refreshSessions命令定期刷新该会话。例如:

var session = db.getMongo().startSession()
var sessionId = session.getSessionId().id

var cursor = session.getDatabase("examples").getCollection("data").find().noCursorTimeout()
var refreshTimestamp = new Date() // take note of time at operation start

while (cursor.hasNext()) {

  // Check if more than 5 minutes have passed since the last refresh
  if ( (new Date()-refreshTimestamp)/1000 > 300 ) {
    print("refreshing session")
    db.adminCommand({"refreshSessions" : [sessionId]})
    refreshTimestamp = new Date()
  }

  // process cursor normally

}

在示例操作中,db.collection.find()方法与显式会话关联。游标使用noCursorTimeout()配置,以防止服务器在空闲时关闭游标。 while循环包括一个块,该块使用refreshSessions每 5 分钟刷新一次会话。由于会话将永远不会超过 30 分钟的空闲超时,因此游标可以无限期保持打开状态。

对于 MongoDB 驱动程序,请参考driver documentation以获取有关创建会话的说明和语法。

Shell

mongo shell 提示每行的限制为 4095 个代码点。如果您 Importing 的行中包含 4095 个以上的代码点,则 Shell 将截断它。