[CDRIVER-704] $readPreference sent to non-mongos Created: 14/Jun/15  Updated: 19/Oct/16  Resolved: 08/Sep/15

Status: Closed
Project: C Driver
Component/s: libmongoc
Affects Version/s: None
Fix Version/s: 1.2-rc0

Type: Bug Priority: Major - P3
Reporter: A. Jesse Jiryu Davis Assignee: A. Jesse Jiryu Davis
Resolution: Done Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Duplicate
is duplicated by CDRIVER-829 Queries with non-primary read prefere... Closed
Related
related to CDRIVER-240 Commands sent to mongos sometimes bre... Closed
related to PHPC-409 mongoc 1.2.0-rc0[-dev] changes Closed

 Description   

Revealed testing CDRIVER-679, the driver sends

{ $query: { ... }, $readPreference: { mode: "secondary", tags: [] } }

to a replica set secondary.

Uncomment the query pattern in _test_kill_cursors to reproduce.

To match Server Selection, the driver must send $readPreference only to mongos:

https://github.com/mongodb/specifications/blob/master/source/server-selection/server-selection.rst#passing-read-preference-to-mongos

Verify the rest of $readPreference and slaveOkay-bit handling, too.



 Comments   
Comment by Githook User [ 11/Jan/16 ]

Author:

{u'username': u'ajdavis', u'name': u'A. Jesse Jiryu Davis', u'email': u'jesse@mongodb.com'}

Message: CDRIVER-704 fix slaveOkay bit and $readPreference

The driver sends $readPreference to mongods and mongoses, but it should
only send it to mongoses. Furthermore, it should not send
$readPreference to a mongos if the preference is secondaryPreferred.
Finally, it should set the SlaveOkay wire-protocol bit when
communicating with a standalone or replica set secondary.
Branch: 1.3.0-dev
https://github.com/mongodb/mongo-c-driver/commit/abeca13630c52459717ab4cbfa181c7769c1aa80

Comment by Githook User [ 26/Oct/15 ]

Author:

{u'username': u'ajdavis', u'name': u'A. Jesse Jiryu Davis', u'email': u'jesse@mongodb.com'}

Message: CDRIVER-704 fix slaveOkay bit and $readPreference

The driver sends $readPreference to mongods and mongoses, but it should
only send it to mongoses. Furthermore, it should not send
$readPreference to a mongos if the preference is secondaryPreferred.
Finally, it should set the SlaveOkay wire-protocol bit when
communicating with a standalone or replica set secondary.
Branch: debian
https://github.com/mongodb/mongo-c-driver/commit/abeca13630c52459717ab4cbfa181c7769c1aa80

Comment by Githook User [ 05/Oct/15 ]

Author:

{u'username': u'jmikola', u'name': u'Jeremy Mikola', u'email': u'jmikola@gmail.com'}

Message: PHPC-409: $readPreference is no longer sent to non-mongos nodes

Fixed by CDRIVER-704
Branch: master
https://github.com/mongodb-labs/mongo-php-driver-prototype/commit/51a9ad7ef4b2a57489f5d9f9e26bbc3100835450

Comment by Githook User [ 08/Sep/15 ]

Author:

{u'username': u'ajdavis', u'name': u'A. Jesse Jiryu Davis', u'email': u'jesse@mongodb.com'}

Message: CDRIVER-704 fix slaveOkay bit and $readPreference

The driver sends $readPreference to mongods and mongoses, but it should
only send it to mongoses. Furthermore, it should not send
$readPreference to a mongos if the preference is secondaryPreferred.
Finally, it should set the SlaveOkay wire-protocol bit when
communicating with a standalone or replica set secondary.
Branch: 1.2.0-dev
https://github.com/mongodb/mongo-c-driver/commit/abeca13630c52459717ab4cbfa181c7769c1aa80

Comment by Hannes Magnusson [ 11/Aug/15 ]

It appears we are also sending $readPreference to a primary when a command is re-routed to a primary while readpreference would otherwise direct the command elsewhere:

{ ping: 1, $readPreference: { mode: "secondaryPreferred", tags: [] } }

Comment by A. Jesse Jiryu Davis [ 16/Jul/15 ]

It seems like the driver does not set SlaveOkay. These two wrongs make a right, when combined with a bizarre quirk in mongod. A secondary considers a query like this:

{$query: {...}, $readPreference: <anything>}

... to be the same as a query with the SlaveOkay bit set.

mongos has had special handling of $readPreference since version 2.2 (SERVER-4464). As a side effect of that implementation, a mongod 2.2 secondary considers any query of the above form to be the same as a query with SlaveOkay. This is completely independent of sharding.

It doesn't matter what the $readPreference contains:

rs-22:SECONDARY> db.test.findOne()
Error: { "$err" : "not master and slaveOk=false", "code" : 13435 }
rs-22:SECONDARY> db.test.findOne({$query: {}, $readPreference: {mode: 'primary'}})
{ "_id" : 1 }
rs-22:SECONDARY> db.test.findOne({$query: {}, $readPreference: "rabbit"})
{ "_id" : 1 }

Generated at Wed Feb 07 21:10:23 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.