“文档” 菜单
文档首页
/
MongoDB Manual
/

MongoDB 限制和阈值

在此页面上

  • MongoDB Atlas 限制
  • BSON 文档
  • 命名限制
  • 命名警告
  • namespaces
  • 索引
  • 排序
  • 数据
  • 副本集
  • 分片集群
  • 操作
  • 会话

本文档收集了 MongoDB 系统的硬限制和软限制。除非另有说明,否则此页面上的限制适用于在以下所有环境中托管的部署:

  • MongoDB Atlas :用于在云中部署 MongoDB 的完全托管服务

  • MongoDB Enterprise:基于订阅、自我管理的 MongoDB 版本

  • MongoDB Community:源代码可用、免费使用且可自行管理的 MongoDB 版本

以下限制仅适用于 MongoDB Atlas 中托管的部署。如果其中任何限制对您的组织造成问题,请联系 Atlas 支持部门

组件
极限
多区域集群中的分片
12
单地区集群中的分片
50
多区域集群的跨地区网络权限
40。此外,任何项目中的集群跨越超过 40 多个区域,您无法在此项目中创建多区域集群。
每个副本集或分片的可选举节点
7
配置服务器集群层(最小值和最大值)
M30

MongoDB Atlas 根据集群级和,限制并发传入连接。MongoDB Atlas 连接限制按节点应用。对于分片集群,MongoDB Atlas 连接限制按 mongos 路由器应用。Mongo 路由器的数量等于所有分片中副本集节点的数量。

您的读取偏好还会影响 MongoDB Atlas 可以为给定查询分配的连接总数。

MongoDB Atlas 对指定集群层的连接限制如下:

注意

MongoDB Atlas 为每个集群保留少量连接,用于支持 Atlas 服务。

如果通过私有连接,连接到多云 MongoDB Atlas 部署,则只能访问您连接的相同云提供商中的节点。此云提供商可能在其地区中没有主节点。发生这种情况时,必须在连接字符串中指定从节点读取偏好模式才能访问该部署。

如果需要通过专用连接从当前提供商访问多云 MongoDB Atlas 部署的所有节点,则必须执行以下操作之一:

  • 在当前提供者中为每个其余提供者配置一个 VPN。

  • 为其余的每个提供商配置 MongoDB Atlas 的私有端点

虽然对单个 MongoDB Atlas 集群中的集合数量没有硬性限制,但如果集群为大量集合和索引提供服务,其性能可能会下降。集合越大,对性能的影响越大。

MongoDB Atlas 群集层建议的集合和索引的最大合并数量如下:

MongoDB Atlas 集群层
建议的最大值
M10
5,000 个集合和索引
M20 / M30
10,000 个集合和索引
M40/+
100,000 个集合和索引

MongoDB Atlas 部署具有以下组织和项目限制:

组件
极限
每个 MongoDB Atlas 项目的数据库用户数
100
每个 MongoDB Atlas 项目的 Atlas 用户数
500
每个 MongoDB Atlas 组织的 Atlas 用户数
500
每个 MongoDB Atlas 组织的 API 密钥数
500
每个 MongoDB Atlas 项目的访问列表条目数
200
每个 MongoDB Atlas 团队的用户数
250
每个 MongoDB Atlas 项目的团队数
100
每个 MongoDB Atlas 组织的团队数
250
每个 MongoDB Atlas 用户的团队数
100
每个 MongoDB Atlas 用户的组织数
250
每个 MongoDB Atlas 用户的关联组织数
50
每个 MongoDB Atlas 项目的集群数
25
每个 MongoDB Atlas 组织的项目数
250
每个 MongoDB Atlas 项目的自定义 MongoDB 角色
100
为每个数据库用户分配的角色数
100
每个 MongoDB Atlas 组织的小时计费
$ 50
每个 MongoDB Atlas 项目的联合数据库实例
25
每个 MongoDB Atlas 项目的网络对等连接总数
50。此外,MongoDB Atlas 根据 CIDR 块和为项目选择的地区,限制每个网络对等连接的节点数。
每个 MongoDB Atlas 项目的待处理网络对等连接
25
每个地区的 AWS PrivateLink 可寻址目标数
50
每个地区的 Azure PrivateLink 可寻址目标
150
每个 MongoDB Atlas 项目的唯一分片键数
40
每个 MongoDB Atlas 项目的 Atlas Data Lake 管道数
25
M0 每个 MongoDB Atlas 项目的集群数
1

MongoDB Atlas 会限制长度并为以下组件标签强制执行 ReGex 要求:

组件
字符限制
正则表达式模式
集群名称
64 [1]
^([a-zA-Z0-9]([a-zA-Z0-9-]){0,21}(?<!-)([\w]{0,42}))$ [2]
项目名称
64
^[\p{L}\p{N}\-_.(),:&@+']{1,64}$ [3]
组织名称
64
^[\p{L}\p{N}\-_.(),:&@+']{1,64}$ [3]
API 密钥说明
250
[1] 如果启用了仅对等互连模式,集群名称字符数限制为 23。
[2] MongoDB Atlas 使用集群名称的前 23 个字符。这些字符在该集群的项目内必须是唯一的。少于 23 个字符的集群名称不能以连字符 (-) 结尾。超过 23 个字符的集群名称不能将连字符作为第 23 个字符。
[3]( 1 , 2 ) 组织和项目名称可以包含任何 Unicode 字母或数字以及以下标点符号:-_.(),:&@+'

其他限制适用于 MongoDB Atlas 无服务器实例、免费集群和共享集群。要了解详情,请参阅以下资源:

MongoDB Atlas 不支持某些 MongoDB 命令。此外,某些命令仅在 MongoDB Atlas 免费集群中受支持。要了解详情,请参阅以下资源:

BSON 文档大小

BSON 文档的大小限制为 16 MB。

最大文档大小有助于确保单个文档不会使用过多的 RAM,或者传输过程中不会使用过多的带宽。MongoDB 会提供 GridFS API 来存储超过最大大小的文档。有关 GridFS 的详细信息,请参阅 mongofiles驱动程序文档。

BSON 文档的嵌套深度

MongoDB 支持 BSON 文档的嵌套级别不超过 100 个。每个对象或数组都会添加一个级别。

数据库名称中大小写的使用

请勿依靠大小写来区分数据库。例如,不能使用下面这两个名称相似的数据库:salesDataSalesData

在 MongoDB 中创建数据库后,在引用数据库时必须使用一致的大小写。举个例子,如果创建了salesData 数据库,引用时不要其他大小写,例如 salesdataSalesData

对 Windows 数据库名称的限制

对于在 Windows 上运行的 MongoDB 部署,数据库名称不得包含以下任意字符:

/\. "$*<>:|?

数据库名称还不能包含 null 字符。

UNIX 和 Linux 系统上数据库名称的限制

对于在 Unix 和 Linux 系统上运行的 MongoDB 部署,数据库名称不得包含以下任何字符:

/\. "$

数据库名称还不能包含 null 字符。

数据库名称长度

数据库名称不能为空且必须小于 64 字节。

对集合名称的限制

集合名称应以下划线或字母字符开头,并且不能

  • 包含 $

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

  • 包含 null 字符。

  • system. 前缀开头。(保留以供内部使用。)

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

命名空间长度:

未分片集合和视图的命名空间长度限制为 255 字节,分片集合的命名空间长度限制为 235 字节。对于集合或视图,命名空间包括数据库名称、点 (.) 分隔符和集合/视图名称(如 <database>.<collection>)。

字段名称限制
  • 字段名称不能包含 null 字符。

  • 服务器允许存储包含点 (.) 和美元符号 ($) 的字段名称。

  • MongodB 5.0 改进了对在字段名称中使用 ($) 和 (.) 的支持。有一些限制。请参阅字段名称注意事项,了解详情。

对 _id 的限制

字段名称 _id 保留用作主键;它的值在集合中必须是唯一的、不可变的,并且可以是除数组之外的任何类型。如果 _id 包含子字段,则子字段名称不能以 ($) 符号开头。

警告

请注意,本部分讨论的问题可能会导致数据丢失或损坏。

MongoDB 查询语言不支持具有重复字段名称的文档。虽然某些 BSON 构建器可能支持创建具有重复字段名称的 BSON 文档,但即使插入成功或看似成功,也不支持将这些文档插入 MongoDB。例如,通过 MongoDB 驱动程序插入具有重复字段名称的 BSON 文档可能会导致驱动程序在插入之前静默删除重复值,或者导致插入包含重复字段的无效文档。对任何此类文档的查询都会导致任意且不一致的结果。

从 MongoDB 5.0 开始,文档字段名称可以是美元 ($) 前缀,并且可以包含句点 (.)。但是,对于使用这些字符的字段名称,mongoimportmongoexport 在某些情况下可能无法按预期运行。

MongoDB 扩展 JSON v2 无法区分类型封装器和碰巧与类型封装器同名的字段。不要在相应的 BSON 表示可能包含美元 ($) 前缀键的上下文中使用扩展 JSON 格式。DBRef 机制是该一般规则的例外。

在字段名中使用带句号 (.) 的 mongoimportmongoexport 也有限制。由于 CSV 文件使用句点 (.) 表示数据层次结构,因此字段名称中的句点 (.) 会被误读为嵌套级别。

使用以美元符号 ($) 为前缀的字段名称或包含句点 (.) 的字段名称时,如果在 MongoDB 5.0 之前的服务器上将这些字段名称与未确认的写入(写关注 w=0)结合使用,则数据丢失的可能性很小。

运行insert更新findAndModify命令时,5.0 兼容的驱动程序取消了对使用字段名称以美元 ( $ ) 为前缀或包含句点 ( . ) 的文档的限制。在早期的驱动程序版本中,这些字段名称会产生客户端错误。

无论驱动程序连接到哪个服务器版本,这些限制均会被删除。如果 5.0 驱动程序将文档发送到较旧的服务器,则会拒绝该文档,而不会发送错误。

命名空间长度

未分片集合和视图的命名空间长度限制为 255 字节,分片集合的命名空间长度限制为 235 字节。对于集合或视图,命名空间包括数据库名称、点 (.) 分隔符和集合/视图名称(如 <database>.<collection>)。

提示

另请参阅:

每个集合的索引数量

单个集合最多可以有 64 个索引。

复合索引中索引字段的数量

复合索引中的字段不能超过 32 个。

查询无法同时使用文本索引和地理空间索引

不能将需要特殊文本索引$text 查询与需要其他类型特殊索引的查询运算符组合使用。例如,您不能将 $text 查询与 $near 操作符组合使用。

具有 2dsphere 索引的字段只能保存几何图形

具有 2dsphere 索引的字段必须以坐标对GeoJSON 数据的形式保存几何数据。如果您尝试在 2dsphere 索引字段中插入包含非几何数据的文档,或者在索引字段包含非几何数据的集合上构建 2dsphere 索引,则操作会失败。

2dsphere 索引键的有限数量

为了生成 2dsphere 索引键,mongodGeoJSON 形状映射到内部表示形式。生成的内部表示可能是很大的值数组。

mongod 为保存数组的字段生成索引键时,mongod 会为每个数组元素生成一个索引键。对于复合索引,mongod 会计算为每个字段生成的键集的笛卡尔积。如果两个集合都很大,那么计算笛卡尔积可能会导致操作超出内存限制。

indexMaxNumGeneratedKeysPerDocument 限制为单个文档生成的最大键数,防止出现内存不足错误。默认每个文档 100000 个索引键。可以提高限制,但如果某个操作需要的键数超过 indexMaxNumGeneratedKeysPerDocument 参数指定的键数,则操作就会失败。

WiredTiger 存储引擎从涵盖查询返回的 NaN 值始终为双精度类型

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

多键索引

键索引不能涵盖对数组字段的查询。

地理空间索引

地理空间索引不能覆盖查询。

索引构建中的内存使用情况

createIndexes 支持在集合上建立一个或多个索引。createIndexes 使用磁盘上的内存和临时文件的组合来完成索引构建。createIndexes 的默认内存使用限制为 200 MB,内存在使用单个 createIndexes 命令构建的所有索引之间共享。达到内存限制后,createIndexes 将使用 --dbpath 目录中名为 _tmp 的子目录中的临时磁盘文件来完成构建。

您可以通过设置 maxIndexBuildMemoryUsageMegabytes 服务器参数来覆盖内存限制。设置更高的内存限制可能会加快完成索引构建过程。但是,相对于系统上未使用的 RAM 而言,将此限制设置得太高可能会导致内存耗尽和服务器关闭。

索引构建可以通过用户命令(如创建索引)或管理过程(如初始同步)启动。 二者均受到maxIndexBuildMemoryUsageMegabytes设置的限制的约束。

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

提示

为了最大限度减少在副本集和带有副本集分片的分片集群上构建索引的影响,使用滚动索引构建过程,如副本集上构建滚动索引中所述。

排序规则和索引类型

以下索引只支持简单的二进制比较,不支持排序规则

提示

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

隐藏索引
排序键的最大数量

您最多可以对 32 个键进行排序。

固定大小集合的最大文档数

如果您使用 createmax 参数指定固定大小集合中的最大文档数,则该值必须小于 2 31 个文档。

如果在创建固定大小集合时未指定最大文档数,则对文档数没有限制。

副本集的节点数

副本集最多可以有 50 个节点。

副本集投票节点数

一个副本集最多可以有 7 个投票成员。对于成员总数超过 7 的副本集,请参阅无投票权的成员

自动创建的 oplog 的最大大小

如果您没有显式指定 oplog 大小(即使用 oplogSizeMB--oplogSize),MongoDB 将创建一个不大于 50 GB 的 oplog。[4]

[4] oplog 的大小可能会超过其配置的大小限制,从而避免删除 majority commit point

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

分片环境中的不可用操作

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

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

在 MongoDB 5.0 及更早版本中,您无法在 $lookup 阶段的 from 参数中指定分片集合

分片集群中涵盖的查询

mongos 上运行时,如果索引包含分片键,则索引只能覆盖分片集合的查询。

分片集合中的单份文档修改操作

要对指定 justOnemulti: false 选项的分片集合使用 update remove() 操作:

  • 如果您仅针对一个分片,则可以在查询规范中使用部分分片键,或者

  • 您可以在查询规范中提供分片键_id 字段。

分片集合中的唯一索引

MongoDB 不支持跨分片的唯一索引,除非唯一索引包含完整分片键作为索引的前缀。在这些情况下,MongoDB 将在整个键上强制执行唯一性,而不是单个字段。

提示

请参阅:

对任意字段的唯一约束,了解另一种方法。

每个迁移范围的最大文档数量

默认情况下,如果一个范围中的文档数大于配置的范围大小除以平均文档大小的结果的 2 倍,则 MongoDB 无法移动该范围。如果 MongoDB 可以移动数据段的子范围并将大小减小到小于该值,则负载均衡器可以迁移范围以实现该目的。db.collection.stats() 包括 avgObjSize 字段,它表示集合中的平均文档大小。

对于太大而无法迁移的数据段:

  • 负载均衡器设置 attemptToBalanceJumboChunks 允许负载均衡器迁移太大而无法移动的数据段,只要这些数据段未标记为 jumbo。有关详情,请参阅超出大小限制的负载均衡范围

    在发出 moveRangemoveChunk 命令时,可以指定 forceJumbo 选项以允许迁移太大而无法移动的范围。范围可能标记为巨大,也可能未标记为巨大。

分片键索引类型

分片键索引可为分片键的升序索引、以分片键开头并指定分片键升序的复合索引或是哈希索引

分片键索引不能为:

分片键选择

更改分片键的选项取决于您当前运行的 MongoDB 版本:

单调递增分片键可能会限制插入吞吐量

对于插入量较高的集群,具有单调递增和递减键的分片键可能会影响插入吞吐量。如果分片键是 _id 字段,请注意 _id 字段的默认值是 ObjectId,其值通常会递增。

当使用单调递增的分片键插入文档时,所有插入内容都属于单个分片上的同一个数据段。系统最终会划分接收所有写入操作的数据段范围并迁移其内容,从而更均匀地分布数据。然而,集群始终只将插入操作定向到单个分片,这会造成插入吞吐量瓶颈。

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

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

哈希分片键哈希索引存储具有升序值的键的哈希值。

排序操作

如果 MongoDB 无法使用一个或多个索引来获取排序顺序,则 MongoDB 必须对数据执行阻塞排序操作。阻塞是指要求 SORT 阶段在返回任何输出文档之前读取所有输入文档,从而阻止该特定查询的数据流。

如果 MongoDB 需要使用超过 100 MB 的系统内存进行阻塞排序操作,则 MongoDB 将返回错误,除非查询指定了 cursor.allowDiskUse()allowDiskUse() 允许 MongoDB 在处理阻塞排序操作时使用磁盘上的临时文件来存储超过 100 MB 系统内存限制的数据。

有关排序和索引使用的更多信息,请参阅排序和索引使用

聚合管道操作

从 MongoDB 6.0 开始,allowDiskUseByDefault 参数可控制需要 100 MB 以上内存容量来执行的管道阶段是否默认会将临时文件写入磁盘。

  • 如果将 allowDiskUseByDefault 设为 true,则默认情况下,需要 100 MB 以上内存容量的管道阶段会将临时文件写入磁盘。您可以使用 { allowDiskUse: false } 选项来为特定的 findaggregate 命令禁用将临时文件写入磁盘的功能。

  • 如果 allowDiskUseByDefault 设置为 false,则默认情况下,需要超过 100 MB 的内存才能执行的管道阶段会引发错误。您可以使用 { allowDiskUse: true } 选项来为特定 findaggregate 启用向磁盘写入临时文件的功能。

$search 聚合阶段不限于 100 MB 的 RAM,因为它在单独的进程中运行。

allowDiskUsetrue 时,可将临时文件写入磁盘的阶段示例如下:

注意

管道阶段对文档流进行操作,每个管道阶段接收文档,对其进行处理,然后输出结果文档。

某些阶段在处理完所有传入文档之前无法输出任何文档。这些管道阶段必须将其阶段输出保留在 RAM 中,直到处理完所有传入文档。因此,这些管道阶段所需的空间可能超过 100 MB 的限制。

如果某一 $sort 管道阶段的结果超过此限制,则可考虑添加一个 $limit 阶段

如果聚合阶段因为内存限制而写入临时文件,则分析器日志消息诊断日志消息包含一个 usedDisk 指示器。

聚合和读关注
2d 地理空间查询不能使用 $or 操作符

提示

地理空间查询

对于球面查询,请使用2dsphere索引结果。

使用2d索引进行球面查询可能会导致不正确的结果,例如使用2d索引进行环绕极点的球面查询。

地理空间坐标
  • 有效经度值介于 -180180 之间,两者均包括在内。

  • 有效纬度值介于 -9090 之间,两者均包括在内。

GeoJSON 多边形的面积

对于$geoIntersects$geoWithin ,如果指定面积大于单个半球的单环多边形,请包括the custom MongoDB coordinate reference system in the $geometry表达式;否则, $geoIntersects$geoWithin会查询互补几何图形。 对于面积大于半球的所有其他 GeoJSON 多边形, $geoIntersects$geoWithin会查询互补几何体。

多文档事务

对于多文档事务

  • 可以在事务中创建集合和索引。有关详细信息,请参阅在事务中创建集合和索引

  • 事务中使用的集合可以位于不同的数据库中。

    注意

    您无法在跨分片写事务中创建新集合。例如,如果您在一个分片中写入一个现有集合,并在另一个分片中隐式创建一个集合,MongoDB 将无法在同一事务中执行这两个操作。

  • 不能写入固定大小集合。

  • 固定大小集合读取时不能使用读关注 "snapshot"。(从 MongoDB 5.0 开始)

  • 不能在 configadminlocal 数据库中读取/写入集合。

  • 不能写入 system.* 集合。

  • 不能使用 explain 或类似命令返回受支持操作的查询计划。

  • 对于在 ACID 事务外部创建的游标,无法在 ACID 事务内部调用 getMore

  • 对于在事务中创建的游标,无法在事务外部调用 getMore

事务中不允许执行以下操作:

事务具有由 transactionLifetimeLimitSeconds 指定的生命周期限制。默认为 60 秒。

写入命令批处理限制大小

100,000 允许在单个批处理操作中进行写入(由针对服务器的单个请求所定义)。

在 3.6 版本进行了更改:限制从 1,000 提高到 100,000 次写入。此限制也应用于旧版 OP_INSERT 消息。

mongosh 中的 Bulk() 操作和驱动程序中的类似方法没有这个限制。

视图

视图定义 pipeline 不能包含 $out$merge 阶段。这一限制也适用于嵌入式管道,例如在 $lookup$facet 阶段中使用的管道。

视图有以下操作限制:

投影限制
$-前缀字段路径限制
find()findAndModify() 投影无法投影以 $ 开头的字段,但 DBRef 字段除外。例如,如下操作无效:
db.inventory.find( {}, { "$instock.warehouse": 0, "$item": 0, "detail.$price": 1 } )
$ 位置操作符放置限制
$ 投影操作符只能出现在字段路径的末尾,例如 "field.$""fieldA.fieldB.$"。例如,以下操作是无效的:
db.inventory.find( { }, { "instock.$.qty": 1 } )
要解决此问题,请删除字段路径中位于 $ 投影运算符之后的部分。
空字段名称投影限制
find()findAndModify() 投影不能包含空字段名称的投影。例如,以下操作无效:
db.inventory.find( { }, { "": 0 } )
在以前的版本中,MongoDB 会将空字段的包含/排除操作视为对不存在字段的投影。
路径冲突:嵌入式文档及其字段
不能投影包含任何嵌入式文档字段的嵌入文档。例如,假设 inventory 集合中有一些包含 size 字段的文档:
{ ..., size: { h: 10, w: 15.25, uom: "cm" }, ... }
以下操作会失败并显示 Path collision 错误,因为它会尝试同时投影 size 文档和 size.uom 字段:
db.inventory.find( {}, { size: 1, "size.uom": 1 } )
在以前的版本中,嵌入式文档与其字段之间的最后投影决定实际投影:
  • 如果嵌入式文档的投影位于其字段的所有投影之后,则 MongoDB 会投影该嵌入式文档。例如,投影文档 { "size.uom": 1, size: 1 } 生成与投影文档 { size: 1 } 相同的结果。

  • 如果嵌入式文档的投影位于其任何字段的投影之前,MongoDB 会投影指定的一个或多个字段。例如,投影文档 { "size.uom": 1, size: 1, "size.h": 1 } 生成与投影文档 { "size.uom": 1, "size.h": 1 } 相同的结果。

路径冲突:数组和嵌入式字段的 $slice
find()findAndModify() 投影不能同时包含数组的 $slice 和数组中嵌入的字段。例如,假设一个包含数组字段 instock 的集合 inventory
{ ..., instock: [ { warehouse: "A", qty: 35 }, { warehouse: "B", qty: 15 }, { warehouse: "C", qty: 35 } ], ... }
以下操作失败并显示 Path collision 错误:
db.inventory.find( {}, { "instock": { $slice: 1 }, "instock.warehouse": 0 } )
在以前的版本中,投影应用两个投影并返回instock数组中的第一个元素 ($slice: 1),但抑制投影元素中的warehouse字段。从 MongoDB 4.4 开始,要获得相同的结果,请使用具有两个独立 $project 阶段的 db.collection.aggregate() 方法。
$ 位置操作符和 $slice 限制
find()findAndModify() 投影不能将 $slice 投影表达式作为 $ 投影表达式的一部分。例如,以下操作无效:
db.inventory.find( { "instock.qty": { $gt: 25 } }, { "instock.$": { $slice: 1 } } )
在之前的版本中,MongoDB 返回instock数组中符合查询条件的第一个元素( instock.$);即位置投影"instock.$"优先,而$slice:1是无需操作。"instock.$": { $slice: 1 }不排除任何其他文档字段。
会话和 $external 用户名限制

要对 $external 身份验证用户(Kerberos、LDAP 或 x.509 用户)使用客户端会话和因果一致性保证,用户名不能大于 10k 字节。

会话空闲超时

连续 30 分钟未收到读取或写入操作在此阈值内未使用 refreshSessions 进行刷新的会话将被标记为已过期,并可由 MongoDB Server 随时将其关闭。关闭会话时会终止所有进行中的操作并打开与该会话关联的游标。这包括使用 noCursorTimeout() 配置的游标或 maxTimeMS() 超过 30 分钟的游标。

考虑一个发出 db.collection.find() 的应用程序。服务器返回一个游标以及一批由 find()cursor.batchSize() 定义的文档。每次应用程序从服务器请求一批新文档时,此会话均会刷新。但是,如果应用程序处理当前批次文档的时间超过 30 分钟,则会将此会话标记为已过期并关闭。当应用程序请求下一批文档时,服务器会返回错误,因为会话关闭时游标已终止。

对于返回游标的操作,如果游标的空闲时间可能超过 30 分钟,则使用 Mongo.startSession() 在显式会话中发出操作,并使用 refreshSessions 命令定期刷新会话。例如:

var session = db.getMongo().startSession()
var sessionId = session
sessionId // show the sessionId
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 驱动程序,请参阅驱动程序文档以获取创建会话的说明和语法。

← MongoDB 集群参数