可重试写入功能允许驱动程序在出现网络错误或在副本集或分片集群中找不到运行状况良好的 主节点 (primary node in the replica set)时重试特定的写入操作。
兼容性
可重试写入需要:
- 部署拓扑结构
- 副本集或分片集群。在独立运行的实例上不受支持。
- 引擎加密
- 具有文档级锁定的存储引擎,例如WiredTiger或内存中。
- MongoDB 驱动程序
与MongoDB 3.6+ 兼容的驱动程序。
Java 3.6 +
Python 3.6+
C 1.9+
Go 1.8+
C# 2.5 +
节点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+ 和
featureCompatibilityVersion3.6+。请参阅setFeatureCompatibilityVersion。 - 写确认
- 使用 写关注
0的写入不可重试。
行为
可重试写入和多文档事务
事务提交和中止操作是可重试的。即使 retryWrites 为 false,驱动程序一旦出错也会重试这些操作。
ACID 事务内的写入不可单独重试,无论 retryWrites 的值如何。
有关事务的更多信息,请参阅事务。
启用可重试写入
- MongoDB 驱动程序
- 与 MongoDB 4.2及更高版本兼容的驱动程序默认启用可重试写入。 早期的驱动程序需要
retryWrites=true选项。 在使用与 MongoDB 4兼容的驱动程序的应用程序中,可以省略retryWrites=true选项。 2及更高版本。要禁用可重试写入功能,使用与 MongoDB 4.2 及更高版本兼容的驱动程序的应用程序必须在连接字符串中包含retryWrites=false。 mongoshmongosh默认默认可重试写入。要禁用,请使用--retryWrites=false:mongosh --retryWrites=false
可重试写入操作
如果MongoDB已确认写关注(write concern),则会重试这些操作:
注意
事务内部的写入不可单独重试。
方法 | 描述 |
|---|---|
插入 | |
单个文档更新 | |
单个文档删除 | |
| |
仅单文档写入操作的批量写入操作。可重试的批量操作可以包括指定写入操作的任意组合,但包括任何多文档写入操作,例如 | |
批量写入操作只包括单文档写入操作。可重试批量操作可以包括指定写入操作的任意组合,但不能包括任何多文档写入操作,例如为 |
持续性网络错误
MongoDB重试写入一次。这可以解决暂时性网络错误和副本集选举,但不能解决持续性网络错误。
故障转移周期
驱动程序等待 serverSelectionTimeoutMS 找到新的主节点 (primary node in the replica set),然后重试。如果故障转移的时间超过此超时时间,则可重试写入将失败。
警告
如果客户端无响应的时间超过 localLogicalSessionTimeoutMinutes,则写入可能会重试,并在客户端恢复时再次应用。
诊断
serverStatus 包括 transactions 部分中的可重试写入统计信息。
针对 local 数据库的可重试写入
官方驱动程序启用可重试写入。除非禁用可重试写入,否则写入 local 数据库 将失败。
要禁用,请在retryWrites=false 连接字符串 中设立 。
Error Handling
从 MongoDB 6.1 开始,如果可重试写入的第一次和第二次尝试都失败而没有执行单独的写入,则 MongoDB 将返回带有NoWritesPerformed 标签的错误。
NoWritesPerformed 标签区分 insertMany() 等批量操作的结果。在insertMany 操作中,可能会出现以下结果:
结果: | MongoDB 输出 |
|---|---|
未插入任何文档。 | 返回错误但不带 |
部分工作已完成。(至少插入一个文档,但不是全部。) | 返回错误但不带 |
所有文档均已插入。 | 成功返回。 |
应用程序可以使用 NoWritesPerformed 标签来明确确定没有插入任何文档。。此错误报告使应用程序可以在处理可重试写入时保持数据库的准确状态
在 MongoDB 的早期版本中,当第一次和第二次可重试写入操作失败时,将会返回错误。但是,指明未执行任何写入操作时没有区别。