Retryable Writes可重试的写

On this page本页内容

New in version 3.6.版本3.6中的新功能。

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 sets or sharded cluster. 可重试写入允许MongoDB驱动程序在遇到网络错误或在副本集分片集群中找不到正常的主服务器时,自动重试某些写入操作一次。[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 DriversMongoDB驱动程序

Clients require MongoDB drivers updated for MongoDB 3.6 or greater:客户端需要为MongoDB 3.6或更高版本更新MongoDB驱动程序:

Java 3.6+

Python 3.6+

C 1.9+

C# 2.5+

Node 3.0+

Ruby 2.5+

Perl 2.0+

PHPC 1.4+

Scala 2.2+

MongoDB VersionMongoDB版本
The MongoDB version of every node in the cluster must be 3.6 or greater, and the featureCompatibilityVersion of each node in the cluster must be 3.6 or greater. 群集中每个节点的MongoDB版本必须为3.6或更高版本,群集中每个节点的featureCompatibilityVersion必须为3.6或更高版本。See setFeatureCompatibilityVersion for more information on the featureCompatibilityVersion 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 retryWrites is set to false.如果提交操作或中止操作遇到错误,MongoDB驱动程序将重试该操作一次,无论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 DriversMongoDB驱动程序

The official MongoDB 3.6 and 4.0-compatible drivers required including the retryWrites=true option in the connection string to enable retryable writes for that connection.官方的MongoDB 3.6和4.0兼容驱动程序需要在连接字符串中包含retryWrites=true选项,才能为该连接启用可重试写入。

The official MongoDB 4.2-compatible drivers enable Retryable Writes by default. 官方的MongoDB 4.2兼容驱动程序默认情况下支持可重试写入Applications upgrading to the 4.2-compatible drivers that require retryable writes may omit the retryWrites=true option. 如果应用程序升级到4.2兼容的驱动程序时需要可重试写入,则可能会忽略retryWrites=true选项。Applications upgrading to the 4.2-compatible drivers that require disabling retryable writes must include retryWrites=false in the connection string.升级到4.2兼容驱动程序且需要禁用可重试写入的应用程序必须在连接字符串中包含retryWrites=false

mongo shell

To enable retryable writes in the mongo shell, use the --retryWrites command line option:要在mongo shell中启用可重试写入,请使用--retryWrites命令行选项:

mongo --retryWrites

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}

Note

The write operations inside the transactions are not individually retryable.事务中的写入操作不可单独重试。

Methods方法Descriptions描述
Insert operations.插入操作。
Single-document update operations. 单文档更新操作。[1]
db.collection.remove() where justOne is true其中justOnetrue
Single document delete operations.单文档删除操作。
findAndModify operations. 操作。All findAndModify operations are single document operations.所有findAndModify操作都是单文档操作。

db.collection.bulkWrite() with the following write operations:通过以下写入操作:

Bulk write operations that only consist of the single-document write operations. 只包含单个文档写入操作的批量写入操作。A retryable bulk operation can include any combination of the specified write operations but cannot include any multi-document write operations, such as updateMany.可重试批量操作可以包括指定写入操作的任何组合,但不能包括任何多文档写入操作,例如updateMany

Bulk operations for:操作用于:

Bulk write operations that only consist of the single-document write operations. 只包含单个文档写入操作的批量写入操作。A retryable bulk operation can include any combination of the specified write operations but cannot include any multi-document write operations, such as update which specifies true for the multi option.可重试的批量操作可以包括指定的写入操作的任何组合,但不能包括任何多文档写入操作,例如为multi选项指定trueupdate

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 _id field) by issuing single-document update/findAndModify operations either as a retryable write or in a transaction. 从MongoDB 4.2开始,您可以通过以可重试写入或在事务中发出单个文档更新/查找和修改操作来更新文档的分片键值(除非分片键字段是不可变的_id字段)。For details, see Change a Document’s Shard Key Value.有关详细信息,请参阅更改文档的分片键值

[1](1, 2)

MongoDB 4.2 will retry certain single-document upserts (update with upsert: true and multi: false) that encounter a duplicate key exception. MongoDB 4.2将重试遇到重复密钥异常的某些单文档upsert(upsert:truemulti:false更新)。See Duplicate Key Errors on Upsert for conditions.有关条件,请参阅Upsert上的复制键错误

Prior to MongoDB 4.2, MongoDB would not retry upsert operations that encountered a duplicate key error.在MongoDB 4.2之前,MongoDB不会重试遇到重复密钥错误的upsert操作。

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 serverSelectionTimeoutMS milliseconds to determine the new primary before retrying. 如果驱动程序在目标副本集中或分片群集分片中找不到正常的主服务器,则驱动程序将等待serverSelectionTimeoutMS毫秒以确定新的主服务器,然后重试。Retryable writes do not address instances where the failover period exceeds serverSelectionTimeoutMS.可重试写入不会处理故障切换周期超过serverSelectionTimeoutMS的实例。

Warning

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 upsert : true and multi : false) that fail due to a duplicate key error only if the operation meets all of the following conditions:MongoDB 4.2将重试由于重复密钥错误而失败的单文档upsert操作(即upsert:truemulti: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等式谓词的逻辑与逻辑关系

      { "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:下表包含服务器可以或不能重试重复密钥错误的upsert操作示例:

Unique Index Key Pattern唯一索引键模式Update Operation更新操作Retryable可重试
{ _id : 1 }
db.collName.updateOne(
  { _id : ObjectId("1aa1c1efb123f14aaa167aaa") },
  { $set : { fieldA : 25 } },
  { upsert : true }
)
Yes
{ fieldA : 1 }
db.collName.updateOne(
  { fieldA : { $in : [ 25 ] } },
  { $set : { fieldB : "someValue" } },
  { upsert : true }
)
Yes
{
  fieldA : 1,
  fieldB : 1
}
db.collName.updateOne(
  { fieldA : 25, fieldB : "someValue" },
  { $set : { fieldC : false } },
  { upsert : true }
)
Yes
{ fieldA : 1 }
db.collName.updateOne(
  { fieldA : { $lte : 25 } },
  { $set : { fieldC : true } },
  { upsert : true }
)

No

The query predicate on fieldA is not an equalityfieldA上的查询谓词不是一个等式

{ fieldA : 1 }
db.collName.updateOne(
  { fieldA : { $in : [ 25 ] } },
  { $set : { fieldA : 20 } },
  { upsert : true }
)

No

The update operation modifies fields specified in the query predicate.更新操作修改查询谓词中指定的字段。

{ _id : 1 }
db.collName.updateOne(
  { fieldA : { $in : [ 25 ] } },
  { $set : { fieldA : 20 } },
  { upsert : true }
)

No

The set of query predicate fields (fieldA) does not match the set of index key fields (_id).查询谓词字段集(fieldA)与索引键字段集(_id)不匹配。

{ fieldA : 1 }
db.collName.updateOne(
  { fieldA : 25, fieldC : true },
  { $set : { fieldD : false } },
  { upsert : true }
)

No

The set of query predicate fields (fieldA, fieldC) does not match the set of index key fields (fieldA).查询谓词字段集(fieldAfieldC)与索引键字段集(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诊断学

New in version 3.6.3.3.6.3版新增。

The serverStatus command, and its mongo shell helper db.serverStatus() includes statistics on retryable writes in the transactions section.serverStatus命令及其mongo shell助手dbserverStatus()transactions部分包含关于可重试写入的统计信息。

Retryable Writes Against local Database针对local数据库的可重试写入

The 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.在升级到4.2系列驱动程序时,写入local数据库的应用程序将遇到写入错误,除非明确禁用可重试写入。

To disable retryable writes, specify retryWrites=false in the connection string for the MongoDB cluster.要禁用可重试写入,请在MongoDB集群的连接字符串中指定retryWrites=false