21

Read the docs a few times but still cannot understand the difference in the behavior of "majority" and "linearizable" read concerns:

"majority"
The query returns the instance’s most recent data acknowledged as having been written to a majority of members in the replica set.

"linearizable"
The query returns data that reflects all successful writes issued with a write concern of "majority" and acknowledged prior to the start of the read operation.

The docs also mention an option "writeConcernMajorityJournalDefault", it says that with that option set to false the data can be rolled back even when using "linearizable".

Could someone explain please, how both concerns work and how this option impacts them?

Community
  • 1
  • 1
Kit Isaev
  • 680
  • 8
  • 19
  • Good question. The difference between the _local_ and _majority_ read concerns is understandable, but the difference that _linearizable_ makes escapes me. I can't see anything in the docs which explains how, if you use a [majority readConcern](https://docs.mongodb.com/manual/reference/read-concern/), and have [writeConcernMajorityJournalDefault](https://docs.mongodb.com/manual/reference/replica-configuration/#rsconf.writeConcernMajorityJournalDefault), it is possible to ever read data which is at risk of being rolled back. – Vince Bowdren Apr 04 '17 at 15:04
  • I have flagged this for migration to [dba.stackexchange.com](https://dba.stackexchange.com) in the hope of finding the answer there. – Vince Bowdren Apr 04 '17 at 15:13

3 Answers3

32

"Linearizable" read concern was introduced in MongoDb 3.4 to solve a possible issue with "majority" Read concern.

Lets try to understand the problem with "majority" read concern to sense what "Linearizable" brings to us.

Suppose, we have a replicaset of 3 nodes, which looks something like this:

3 node replica set

Where, A is Primary, B is Secondary, C is Secondary

Lets also have two users Alice and Bob, which will be performing some operations on following document which resides in "users" collection.

{
 "_id": 100234,
 "name": "Katelyn"
}

At time instant T0:

following happens,

  1. Alice gets connected to A (primary) and issues following command.

db.users.find({"_id":100234}); --> with read concern 'majority'

Output:

{ "_id" : 100234, "name" : "Katelyn" }

  1. B and C realizes that A has stopped responding and starts election procedure.(May be due to network partitioning).

At time instant T1:

following happens,

  1. Due to the election process, B stands as a new primary.

However, till the time A is not communicated or A itself realizes that it needs to demote itself to a secondary it continues serving as a primary (this is generally for a very small period of time though).

enter image description here

At time instant T2:

  1. Bob gets connected to B (new primary) and issues following command.

db.users.update( {"_id":100234}, {$set: {name:"Sansa"} } ); --> with write concern 'majority'.

  1. Bob is acknowledged of write.

At time instant T3:

  1. Alice gets connected to A (old primary) and issues following command.

db.users.find({"_id":100234}); --> read concern 'majority'

Output:

{ "_id" : 100234, "name" : "Katelyn" }

Alice here gets the stale data even after issuing the majority read concern, i.e the write made by Bob is not visible to Alice. Thus, the property of "Linearizability" is compensated in this case.

Definition of Linearizability: writes should appear to be instantaneous. Imprecisely, once a write completes, all later reads (where “later” is defined by wall-clock start time) should return the value of that write or the value of a later write. Once a read returns a particular value, all later reads should return that value or the value of a later write.

Hence, comes the solution i.e "linearizable" read concern. With this property, mongod checks its primary and can see majority of nodes before issuing the results of read operation. However, there is a performance cost penality of using this Read Concern over "majority", thus this is not a replacement for "majority" read concern.


Regarding writeConcernMajorityJournalDefault property, it is merely a replica set configuration option. It accepts boolean value.

True means, MongoDB acknowledges the write operation after a majority of the voting members have written to the on-disk journal.

False means, MongoDB acknowledges the write operation after a majority of the voting members have applied the operation in memory.

The above property is applicable only when, write concern "majority" is used and journaling flag is not specified.

Sankalp Bhatt
  • 1,154
  • 13
  • 17
4

In my understanding, Read Concern majority in an node will immediately return the read query with the most recent majority committed (written to the majority of the nodes) data that is available in that node. On the other hand, Read Concern linearizable will wait till the completion concurrently executing writes to propagate to a majority of replica set members before returning results.

Both of them guaranty that the data read has been acknowledged by a majority of the replica set members, i.e. the documents read are durable and guaranteed not to roll back.

As Read Concern linearizable waits for the concurrently executing writes to be finished, it's performance is significantly slower than that of Read Concern majority.

Similarly, since Read Concern majority don't wait for the concurrently executing writes, it will return fast, but it may return stale data(still durable & w:majority acknowledged). See this example for details: https://docs.mongodb.com/manual/reference/read-concern-majority/#example

In that example between t3~t5 (after t3 and before t5) primary and secondaries will return different data with Read Concern majority.

afsungur
  • 3
  • 2
Mostafiz Rahman
  • 8,169
  • 7
  • 57
  • 74
1

The accepted answer is very detailed already, but for those who don't want to read long answers:

  1. Majority read concern only guarantees the read data is majority-committed and will not be rolled back. That means the read data may not be up to date.
  2. Majority read concern can go to either primary or secondary. (and the read result can differ depending where you read from)
  3. Linearizable read ensures what Majority read concern gives you,and it also ensures the read data is always up to date. That means the read has to be go to primary.
  4. To detect network partition, Linearizable has to always contact other nodes to make sure a majority are available, and throw an error if not. (If this check is not performed, the read data can't always be update to date).
suitianshi
  • 3,300
  • 1
  • 17
  • 34