- MongoDB CRUD Operations >
- MongoDB CRUD Concepts >
- Perform Quorum Reads on Replica Sets
Perform Quorum Reads on Replica Sets¶
New in version 3.2.
Overview¶
When reading from the primary of a replica set, it is possible to read
data that is stale or not durable, depending on the read concern used
[1]. With a read concern level of
"local", a client can read data before it is
durable; that is, before they have propagated to enough replica
set members to avoid a rollback. A read concern level of
"majority" guarantees durable reads but may return stale
data that has been overwritten by another write operation.
This tutorial outlines a procedure that uses
db.collection.findAndModify() to read data that is not stale
and cannot be rolled back. To do so, the procedure uses the
findAndModify() method with a write
concern to modify a dummy field in a document.
Specifically, the procedure requires that:
db.collection.findAndModify()use an exact match query, and a unique index must exist to satisfy the query.findAndModify()must actually modify a document; i.e. result in a change to the document.findAndModify()must use the write concern{ w: "majority" }.
Important
The “quorum read” procedure has a substantial cost over simply using
a read concern of "majority" because it incurs write
latency rather than read latency. This technique should only be used
if staleness is absolutely intolerable.
Prerequisites¶
This tutorial reads from a collection named products. Initialize
the collection using the following operation.
The documents in this collection contain a dummy field named
_dummy_field that will be incremented by the
db.collection.findAndModify() in the tutorial. If the field
does not exist, the db.collection.findAndModify() operation
will add the field to the document. The purpose of the field is to
ensure that the db.collection.findAndModify() results in a
modification to the document.
Procedure¶
Create a unique index.¶
Create a unique index on the fields that will be used to specify an
exact match in the db.collection.findAndModify() operation.
This tutorial will use an exact match on the sku field. As such,
create a unique index on the sku field.
Use findAndModify to read committed data.¶
Use the db.collection.findAndModify() method to make a
trivial update to the document you want to read and return the
modified document. A write concern of { w: "majority" } is required. To specify the document to read, you must
use an exact match query that is supported by a unique index.
The following findAndModify() operation
specifies an exact match on the uniquely indexed field sku and
increments the field named _dummy_field in the matching document.
While not necessary, the write concern for this command also includes
a wtimeout value of 5000 milliseconds to prevent the
operation from blocking forever if the write cannot propagate to a
majority of voting members.
Even in situations where two nodes in the replica set believe that
they are the primary, only one will be able to complete the write with
w: "majority". As such, the
findAndModify() method with
"majority" write concern will be successful only when
the client has connected to the true primary to perform the operation.
Since the quorum read procedure only increments a dummy field in the
document, you can safely repeat invocations of
findAndModify(), adjusting the
wtimeout as necessary.
| [1] | In some circumstances, two nodes in a replica set
may transiently believe that they are the primary, but at most, one
of them will be able to complete writes with { w:
"majority" } write concern. The node that can complete
{ w: "majority" } writes is the current
primary, and the other node is a former primary that has not yet
recognized its demotion, typically due to a network partition.
When this occurs, clients that connect to the former primary may
observe stale data despite having requested read preference
primary, and new writes to the former primary will
eventually roll back. |