Retryable Writes

New in version 3.6.

Retryable writes allow MongoDB drivers to automatically retry certainwrite operations a single time if they encounter network errors, or ifthey cannot find a healthy primary in thereplica sets or sharded cluster. [1]

Prerequisites

Retryable writes have the following requirements:

  • Supported Deployment Topologies
  • Retryable writes require a replica setor sharded cluster, and do notsupport standalone instances.
  • Supported Storage Engine
  • Retryable writes require a storage engine supporting document-levellocking, such as the WiredTiger orin-memory storage engines.
  • 3.6+ MongoDB Drivers
  • Clients require MongoDB drivers updated for MongoDB 3.6 or greater:

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 Version
  • The MongoDB version of every node in the cluster must be 3.6 orgreater, and the featureCompatibilityVersion of each node in thecluster must be 3.6 or greater. SeesetFeatureCompatibilityVersion for more information onthe featureCompatibilityVersion flag.
  • Write Acknowledgment
  • Write operations issued with a Write Concern of 0are not retryable.

Retryable Writes and Multi-Document Transactions

New in version 4.0.

The transaction commit and abort operationsare retryable write operations. If the commit operation or the abortoperation encounters an error, MongoDB drivers retry the operation asingle time regardless of whether retryWrites is set tofalse.

The write operations inside the transaction are not individuallyretryable, regardless of value of retryWrites.

For more information on transactions, see Transactions.

Enabling Retryable Writes

  • MongoDB Drivers
  • The official MongoDB 3.6 and 4.0-compatible drivers required including theretryWrites=true option in the connectionstring to enable retryable writes for that connection.

The official MongoDB 4.2-compatible drivers enable Retryable Writes bydefault. Applications upgrading to the 4.2-compatible drivers that requireretryable writes may omit the retryWrites=trueoption. Applications upgrading to the 4.2-compatible drivers that requiredisabling retryable writes must includeretryWrites=false in the connection string.

  1. mongo --retryWrites

Retryable Write Operations

The following write operations are retryable when issued withacknowledged write concern; e.g., Write Concerncannot be {w: 0}.

Note

The write operations inside the transactions are not individually retryable.

MethodsDescriptions
db.collection.insertOne()db.collection.insert()db.collection.insertMany()Insert operations.
db.collection.updateOne()db.collection.replaceOne()db.collection.save()db.collection.update() where multi is falseSingle-document update operations. [1]
db.collection.deleteOne()db.collection.remove() where justOne is trueSingle document delete operations.
db.collection.findAndModify()db.collection.findOneAndDelete()db.collection.findOneAndReplace()db.collection.findOneAndUpdate()findAndModify operations. All findAndModify operationsare single document operations.
db.collection.bulkWrite() with the following writeoperations:- insertOne- updateOne- replaceOne- deleteOneBulk write operations that only consist of the single-documentwrite operations. A retryable bulk operation can include anycombination of the specified write operations but cannot includeany multi-document write operations, such as updateMany.
Bulk operations for:- Bulk.find.removeOne()- Bulk.find.replaceOne()- Bulk.find.replaceOne()Bulk write operations that only consist of the single-documentwrite operations. A retryable bulk operation can include anycombination of the specified write operations but cannot includeany multi-document write operations, such as update whichspecifies true for the multi option.
[1](1, 2)MongoDB 4.2 will retry certain single-document upserts(update with upsert: true and multi: false) that encounter aduplicate key exception. See Duplicate Key Errors on Upsert forconditions.Prior to MongoDB 4.2, MongoDB would not retry upsert operationsthat encountered a duplicate key error.

Behavior

Persistent Network Errors

MongoDB retryable writes make only one retry attempt. This helpsaddress transient network errors andreplica set elections, but not persistentnetwork errors.

Failover Period

If the driver cannot find a healthy primary in the destinationreplica set or sharded cluster shard, the drivers waitserverSelectionTimeoutMS milliseconds to determine the newprimary before retrying. Retryable writes do not address instances wherethe failover period exceeds serverSelectionTimeoutMS.

Warning

If the client application becomes temporarily unresponsive for morethan the localLogicalSessionTimeoutMinutes afterissuing a write operation, there is a chance that when the clientapplications starts responding (without a restart), the writeoperation may be retried and applied again.

Duplicate Key Errors on Upsert

MongoDB 4.2 will retry single-document upsert operations(i.e upsert : true and multi : false) thatfail due to a duplicate key error only if the operation meetsall of the following conditions:

  • The target collection has a unique index that caused the duplicate keyerror.

  • 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 setof fields in the update query predicate.

  • The update operation does not modify any of the fields in thequery predicate.

The following table contains examples of upsert operations thatthe server can or cannot retry on a duplicate key error:

Unique Index Key PatternUpdate OperationRetryable
  1. { _id : 1 }
  1. db.collName.updateOne( { _id : ObjectId("1aa1c1efb123f14aaa167aaa") }, { $set : { fieldA : 25 } }, { upsert : true })
Yes
  1. { fieldA : 1 }
  1. db.collName.updateOne( { fieldA : { $in : [ 25 ] } }, { $set : { fieldB : "someValue" } }, { upsert : true })
Yes
  1. { fieldA : 1, fieldB : 1}
  1. db.collName.updateOne( { fieldA : 25, fieldB : "someValue" }, { $set : { fieldC : false } }, { upsert : true })
Yes
  1. { fieldA : 1 }
  1. db.collName.updateOne( { fieldA : { $lte : 25 } }, { $set : { fieldC : true } }, { upsert : true })
NoThe query predicate on fieldA is not an equality
  1. { fieldA : 1 }
  1. db.collName.updateOne( { fieldA : { $in : [ 25 ] } }, { $set : { fieldA : 20 } }, { upsert : true })
NoThe update operation modifies fields specified in thequery predicate.
  1. { _id : 1 }
  1. db.collName.updateOne( { fieldA : { $in : [ 25 ] } }, { $set : { fieldA : 20 } }, { upsert : true })
NoThe set of query predicate fields (fieldA) does notmatch the set of index key fields (_id).
  1. { fieldA : 1 }
  1. db.collName.updateOne( { fieldA : 25, fieldC : true }, { $set : { fieldD : false } }, { upsert : true })
NoThe set of query predicate fields (fieldA, fieldC)does not match the set of index key fields (fieldA).

Prior to MongoDB 4.2, MongoDB retryable writes did not supportretrying upserts which failed due to duplicate key errors.

Diagnostics

New in version 3.6.3.

The serverStatus command, and its mongoshell helper db.serverStatus() includes statistics onretryable writes in the transactions section.

Retryable Writes Against local Database

The official MongoDB 4.2-series drivers enable retryable writes by default.Applications which write to the localdatabase will encounter write errors uponupgrading to 4.2-series drivers unless retryable writes are explicitlydisabled.

To disable retryable writes, specifyretryWrites=false in theconnection string for the MongoDB cluster.