2

We have a single client that serially writes on two documents (with {w:1}). For example, the original documents may be:

{_id: "a", value: 0}, {_id: "b", value: 0}

and the client updates document "a" to {_id: "a", value: 1} and then, after the update completes, the client updates document "b" to {_id: "b", value: 1}.

A second client calls find({}) afterwards. The second client reads from a secondary, which may have not received all the changes. Obviously it can read the following states:

  • {_id:"a",value:0},{_id:"b",value:0}
  • {_id:"a",value:1},{_id:"b",value:0}
  • {_id:"a",value:1},{_id:"b",value:1}

which are "real" states on the primary (at some moment in the past).

Can the second client see a state like: {_id:"a",value:0},{_id:"b",value:1}? Notice that this state never existed on the primary.

P.S. The explanation here says:

Secondaries ... apply write operations in the order that they appear in the oplog.

Does that mean the secondaries change their documents at the same order they were updated on the primary?

P.S. does find cursors "freeze" the state of the documents that they are reading (i.e. ignore changes that were made after the cursor was created)? Could things be different if I used find(...).sort({_id:-1}) or if document "a"'s id was "c" (i.e. larger than "b")?

Thanks

Oren
  • 2,767
  • 3
  • 25
  • 37

2 Answers2

1

First question: yes, the operations on the secondary are performed in the same order as on the primary. All operations are recorded in the oplog. The oplog itself is not a journal of the queries performed (i.e. updateMany()) but what has to be done on the actual documents so it's operations become idempotent.

Regarding the cursor operation. It might happen that documents get moved or updated while iterating over the cursor. It may even happen, that the same document appears twice on the cursor if it's index or storage location changes during the update.

There is a special snapshot mode that provides some sort of isolation, but it has some limitations, i.e. it cannot be used with sharding

Gerald Mücke
  • 10,724
  • 2
  • 50
  • 67
0

if our documnet was updated by sequence on master

  1. change A
  2. change B
  3. change C

then secondaries will update document with the same sequence:

  1. change A

    documnet can be read without other changes applied

  2. change B

    documnet can be read without other changes applied

  3. change C

For locking see this as mongo can optimise operations sequence, which can allow reads even if document update is fired to proceed.

profesor79
  • 9,213
  • 3
  • 31
  • 52
  • What about the `find` operation? if `find` finds two documents "a" and "b" in that order, can it return document "a" before the changes and document "b" after the changes? – Oren May 30 '16 at 11:48
  • @Oren - that's all timing connected with `W:1`, so if `find` will fail in sequence before secondary will process `change B`, then `change A` is sent back to client. – profesor79 May 30 '16 at 11:55