Docs 菜单

Docs 主页开发应用程序MongoDB Manual

可重试写入 (Retryable Writes)

在此页面上

  • 先决条件
  • 可重试写入和多文档事务
  • 启用可重试写入
  • 可重试写入操作
  • 行为

可重试写入允许 MongoDB 驱动程序在遇到网络错误或者在 副本集分片集群 中找不到健康的 主 节点时自动重试某些写入操作。

可重试写入具有以下要求:

支持的部署拓扑结构
可重试写入需要副本集分片集群,并且支持独立实例
支持的存储引擎
可重试写入需要支持文档级锁定的存储引擎,例如 WiredTiger内存存储引擎。
3.6+ MongoDB 驱动程序

客户端需要针对 MongoDB 3.6 或更高版本更新 MongoDB 驱动程序:

Java 3.6 及更高版本

Python 3.6+

C 1.9+

Go 1.8+

C# 2.5+

Node 3.0+

Ruby 2.5+

Rust 2.1+

Swift 1.2+

Perl 2.0 及更高版本

PHPC 1.4+

Scala 2.2+

C++ 3.6.6+

MongoDB 版本
集群中每个节点的 MongoDB 版本必须为 3.6 或更高版本,并且集群中每个节点的 featureCompatibilityVersion 必须为 3.6 或更高版本。有关 featureCompatibilityVersion 标志的详细信息,请参阅 setFeatureCompatibilityVersion
写确认
写关注0 时发出的写入操作不可重试。

4.0 版本中的新功能

事务提交和中止操作是可重试的写入操作。如果提交操作或中止操作遇到错误,则不管 retryWrites 是否设置为 false,MongoDB 驱动程序都会重试该操作一次。

事务中的写入操作不可单独重试,无论 retryWrites 的值如何。

有关事务的更多信息,请参阅事务

MongoDB 驱动程序
与 MongoDB 4兼容的驱动程序。 2及更高版本默认启用可重试写入。早期的驱动程序需要retryWrites=true选项。在使用与 MongoDB 4兼容的驱动程序的应用程序中,可以省略retryWrites=true选项。 2及更高版本。

要禁用可重试写入功能,使用与 MongoDB 4.2 及更高版本兼容的驱动程序的应用程序必须在连接字符串中包含 retryWrites=false
mongosh

默认情况下,在mongosh中启用可重试写入。要禁用可重试写入,请使用--retryWrites=false命令行选项:

mongosh --retryWrites=false

当以确认写发出时,以下写入操作是可重试的;例如,写关注不能为 {w: 0}

注意

事务中的写入操作不可单独重试。

方法
描述
插入操作
单个文档更新操作
单个文档删除操作
findAndModify 操作。所有 findAndModify 操作都是单文档操作。

db.collection.bulkWrite() 与以下写入操作一起使用:

仅单文档写入操作的批量写入操作。可重试的批量操作可以包括指定写入操作的任意组合,但包括任何多文档写入操作,例如 updateMany
批量写入操作只包括单文档写入操作。可重试批量操作可以包括指定写入操作的任意组合,但不能包括任何多文档写入操作,例如为 multi 选项指定 trueupdate

MongoDB 可重试写入仅进行一次重试尝试。这有助于解决暂时性网络错误和副本集选举,但不能解决持续性网络错误。

如果驱动程序在目标副本集或分片集群分片中找不到正常的主节点,则驱动程序将等待 serverSelectionTimeoutMS 毫秒,以确定新的主节点,然后再重试。可重试写入不处理故障转移周期超过 serverSelectionTimeoutMS 的实例。

警告

如果客户端应用程序在发出写入操作后暂时无响应的时间超过 localLogicalSessionTimeoutMinutes,则当客户端应用程序开始响应(无需重启)时,可能会重试并再次应用写入操作。

serverStatus命令及其mongosh Shell 助手db.serverStatus()transactions部分中包含有关可重试写入的统计信息。

默认情况下,官方 MongoDB 4.2 系列驱动程序支持可重试写入。除非显式禁用可重试写入,否则,写入 local 数据库的应用程序将在升级到 4.2 系列驱动程序时遇到写入错误。

要禁用可重试写入,请在 MongoDB 集群连接字符串中指定 retryWrites=false

从 MongoDB 6.1 开始,如果可重试写入的第一次和第二次尝试都失败而没有执行单独的写入,则 MongoDB 将返回带有NoWritesPerformed 标签的错误。

NoWritesPerformed 标签区分 insertMany() 等批量操作的结果。在insertMany 操作中,可能会出现以下结果:

结果:
MongoDB 输出
未插入任何文档。
返回错误但不带 NoWritesPerformed 标签。
部分工作已完成。(至少插入一个文档,但不是全部。)
返回错误但不带 NoWritesPerformed 标签。
所有文档均已插入。
成功返回。

应用程序可以使用 NoWritesPerformed 标签来明确确定没有插入任何文档。。此错误报告使应用程序可以在处理可重试写入时保持数据库的准确状态

在 MongoDB 的早期版本中,当第一次和第二次可重试写入操作失败时,将会返回错误。但是,指明未执行任何写入操作时没有区别。

← 批量写入操作