Retryable Writes可重试写入
On this page本页内容
Retryable writes allow MongoDB drivers to automatically retry certain write operations a single time if they encounter network errors, or if they cannot find a healthy primary in the replica set or sharded cluster. 可重试写入允许MongoDB驱动程序在遇到网络错误时,或者在副本集或分片集群中找不到健康的primary时,自动重试某些写入操作。[1]
Prerequisites先决条件
Retryable writes have the following requirements:可重试写入具有以下要求:
Supported Deployment Topologies支持的部署拓扑Retryable writes require a replica set or sharded cluster, and do not support standalone instances.可重试写入需要副本集或分片集群,并且不支持独立实例。Supported Storage Engine支持的存储引擎Retryable writes require a storage engine supporting document-level locking, such as the WiredTiger or in-memory storage engines.可重试写入需要支持文档级锁定的存储引擎,如WiredTiger或内存中存储引擎。- 3.6+ MongoDB Drivers
-
Clients require MongoDB drivers updated for MongoDB 3.6 or greater:客户端需要为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 Version
The MongoDB version of every node in the cluster must be集群中每个节点的MongoDB版本必须为3.6
or greater, and thefeatureCompatibilityVersion
of each node in the cluster must be3.6
or greater.3.6
或更高版本,集群中每个结点的featureCompatibilityVersion
必须为3.6
及更高版本。See有关setFeatureCompatibilityVersion
for more information on thefeatureCompatibilityVersion
flag.featureCompatibilityVersion
标志的详细信息,请参阅setFeatureCompatibilityVersion
。Write Acknowledgment写书确认Write operations issued with a Write Concern of写入关注为0
are not retryable.0
时发出的写入操作是不可重试的。
Retryable Writes and Multi-Document Transactions可重试写入和多文档事务
New in version 4.0. 4.0版新增。
The transaction commit and abort operations are retryable write operations. 事务提交和中止操作是可重试的写入操作。If the commit operation or the abort operation encounters an error, MongoDB drivers retry the operation a single time regardless of whether 如果提交操作或中止操作遇到错误,MongoDB驱动程序将重试该操作一次,无论retryWrites
is set to false
.retryWrites
是否设置为false
。
The write operations inside the transaction are not individually retryable, regardless of value of 无论retryWrites
.retryWrites
的值如何,事务中的写入操作都不能单独重试。
For more information on transactions, see Transactions.有关事务的更多信息,请参阅事务。
Enabling Retryable Writes启用可重试写入
- MongoDB Drivers
Drivers compatible with MongoDB 4.2 and higher enable Retryable Writes by default.与MongoDB 4.2及更高版本兼容的驱动程序默认启用可重试写入。Earlier drivers require the早期的驱动程序需要retryWrites=true
option.retryWrites=true
选项。The在使用与MongoDB 4.2及更高版本兼容的驱动程序的应用程序中,可以省略retryWrites=true
option can be omitted in applications that use drivers compatible with MongoDB 4.2 and higher.retryWrites=true
选项。
To disable retryable writes, applications that use drivers compatible with MongoDB 4.2 and higher must include要禁用可重试写入,使用与MongoDB 4.2及更高版本兼容的驱动程序的应用程序必须在连接字符串中包含retryWrites=false
in the connection string.retryWrites=false
。mongosh
-
Retryable writes are enabled by default inmongosh
.mongosh
中默认启用可重试写入。To disable retryable writes, use the要禁用可重试写入,请使用--retryWrites=false
command line option:--retryWrites=false
命令行选项:mongosh --retryWrites=false
Retryable Write Operations可重试写入操作
The following write operations are retryable when issued with acknowledged write concern; e.g., Write Concern cannot be 当发出确认的写入问题时,以下写入操作是可重试的;例如,写入关注不能为{w: 0}
.{w: 0}
。
The write operations inside the transactions are not individually retryable.事务中的写入操作不能单独重试。
db.collection.insertOne() db.collection.insertMany() | |
db.collection.updateOne() db.collection.replaceOne() | |
db.collection.deleteOne() db.collection.remove() justOne is true justOne 为true | |
db.collection.findAndModify() db.collection.findOneAndDelete() db.collection.findOneAndReplace() db.collection.findOneAndUpdate() | findAndModify findAndModify operations are single document operations.findAndModify 操作都是单个文档操作。 |
db.collection.bulkWrite() | updateMany .updateMany 。 |
Bulk | update which specifies true for the multi option.multi 选项指定true 的update 。 |
Updates to Shard Key Values分片键值的更新
Starting in MongoDB 4.2, you can update a document's shard key value (unless the shard key field is the immutable 从MongoDB 4.2开始,您可以通过以可重试写入或在事务中发出单个文档_id
field) by issuing single-document update/findAndModify operations either as a retryable write or in a transaction. update
/findAndModify
操作来更新文档的分片键值(除非分片键字段是不可变的_id
字段)。For details, see Change a Document's Shard Key Value.有关详细信息,请参阅更改文档的分片键值。
[1] | (1, 2) upsert: true and multi: false ) that encounter a duplicate key exception. upsert: true 和multi: false 更新)。 |
Behavior行为
Persistent Network Errors持续的网络错误
MongoDB retryable writes make only one retry attempt. MongoDB可重试写入只进行一次重试尝试。This helps address transient network errors and replica set elections, but not persistent network errors.这有助于解决暂时的网络错误和副本集选举,但不会解决持久的网络错误。
Failover Period故障转移周期
If the driver cannot find a healthy primary in the destination replica set or sharded cluster shard, the drivers wait 如果驱动程序在目标副本集中或已分片的集群分片中找不到健康的primary,则驱动程序会等待serverSelectionTimeoutMS
milliseconds to determine the new primary before retrying. Retryable writes do not address instances where the failover period exceeds serverSelectionTimeoutMS
.serverSelectionTimeoutMS
毫秒来确定新的主服务器然后重试。可重试写入不会处理故障转移周期超过serverSelectionTimeoutMS
的实例。
If the client application becomes temporarily unresponsive for more than the 如果客户端应用程序在发出写入操作后暂时没有响应超过localLogicalSessionTimeoutMinutes
after issuing a write operation, there is a chance that when the client applications starts responding (without a restart), the write operation may be retried and applied again.localLogicalSessionTimeoutMinutes
,则当客户端应用程序开始响应(不重新启动)时,可能会重试并再次应用写入操作。
Duplicate Key Errors on UpsertUpsert上的重复键错误
MongoDB 4.2 will retry single-document upsert operations (i.e 只有在满足以下所有条件的情况下,MongoDB 4.2才会重试由于重复键错误而失败的单文档追加操作(即upsert : true
and multi : false
) that fail due to a duplicate key error only if the operation meets all of the following conditions:upsert : true
和multi : false
):
The target collection has a unique index that caused the duplicate key error.目标集合具有导致重复键错误的唯一索引。The update match condition is either:更新匹配条件为:A single equality predicate单个相等谓词{ "fieldA" : "valueA" }
,or
a logical AND of equality predicates相等谓词的逻辑AND{ "fieldA" : "valueA", "fieldB" : "valueB" }
The set of fields in the unique index key pattern matches the set of fields in the update query predicate.唯一索引键模式中的字段集与更新查询谓词中的字段集中匹配。The update operation does not modify any of the fields in the query predicate.更新操作不会修改查询谓词中的任何字段。
The following table contains examples of upsert operations that the server can or cannot retry on a duplicate key error:下表包含服务器可以或不能在出现重复键错误时重试的追加启动操作示例:
{ _id : 1 } |
db.collName.updateOne( | Yes |
{ fieldA : 1 }
|
db.collName.updateOne( | Yes |
{ |
db.collName.updateOne( | Yes |
{ fieldA : 1 }
|
db.collName.updateOne( | NofieldA is not an equality fieldA 上的查询谓词不是相等项 |
{ fieldA : 1 }
|
db.collName.updateOne( | No |
{ _id : 1 }
|
db.collName.updateOne( | NofieldA ) does not match the set of index key fields (_id ). fieldA )与索引键字段集(_id )不匹配。 |
{ fieldA : 1 }
|
db.collName.updateOne( | NofieldA , fieldC ) does not match the set of index key fields (fieldA ). fieldA ,fieldC )与索引键字段集(fieldA )不匹配。 |
Prior to MongoDB 4.2, MongoDB retryable writes did not support retrying upserts which failed due to duplicate key errors.在MongoDB 4.2之前,MongoDB可重试写入不支持重试由于重复键错误而失败的错误。
Diagnostics诊断
The serverStatus
command, and its mongosh
shell helper db.serverStatus()
includes statistics on retryable writes in the transactions
section.serverStatus
命令及其mongosh
shell助手db.serverStatus()
在transactions
部分中包含可重试写入的统计信息。
Retryable Writes Against local
Database针对local
数据库的可重试写入
local
DatabaseThe official MongoDB 4.2-series drivers enable retryable writes by default. MongoDB 4.2系列的官方驱动程序默认启用可重试写入。Applications which write to the 写入local
database will encounter write errors upon upgrading to 4.2-series drivers unless retryable writes are explicitly disabled.local
数据库的应用程序在升级到4.2系列驱动程序时将遇到写入错误,除非明确禁用了可重试写入。
To disable retryable writes, specify 要禁用可重试写入,请在MongoDB集群的连接字符串中指定retryWrites=false
in the connection string for the MongoDB cluster.retryWrites=false
。
Error Handling错误处理
Starting in MongoDB 6.1, if both the first and second attempt of a retryable write fail without a single write being performed, MongoDB returns an error with the 从MongoDB 6.1开始,如果可重试写入的第一次和第二次尝试都失败了,而没有执行一次写入,MongoDB将返回一个带有NoWritesPerformed
label.NoWritesPerformed
标签的错误。
The NoWritesPerformed
label differentiates the results of batch operations like insertMany()
. NoWritesPerformed
标签区分insertMany()
等批处理操作的结果。In an 在insertMany
operation, one of the following outcomes can occur:insertMany
操作中,可能会出现以下结果之一:
NoWritesPerformed label.NoWritesPerformed 标签的错误。 | |
NoWritesPerformed label.NoWritesPerformed 标签。 | |
Applications can use the 应用程序可以使用NoWritesPerformed
label to definitively determine that no documents were inserted. NoWritesPerformed
标签来确定是否未插入任何文档。This error reporting lets the application maintain an accurate state of the database when handling retryable writes.此错误报告使应用程序在处理可重试写入时能够保持数据库的准确状态。
In previous versions of MongoDB, an error is returned when both the first and second attempts of a retryable write fail. 在MongoDB的早期版本中,当可重试写入的第一次和第二次尝试都失败时,会返回一个错误。However, there is no distinction made to indicate that no writes were performed.但是,没有任何区别表明没有执行任何写入操作。