[SERVER-46903] Ensure mongo shell respects readPreference for $out and $merge when 'Mongo.setReadPref' is called Created: 16/Mar/20  Updated: 29/Oct/23  Resolved: 11/May/20

Status: Closed
Project: Core Server
Component/s: Querying, Shell
Affects Version/s: None
Fix Version/s: 4.7.0

Type: Task Priority: Major - P3
Reporter: Mihai Andrei Assignee: Mihai Andrei
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Depends
Backwards Compatibility: Minor Change
Sprint: Query 2020-03-23, Query 2020-05-18
Participants:

 Description   

When Mongo.setReadPref('secondary') is called from the mongo shell when connected to a secondary, an aggregate with $out/$merge errors with 'NotMasterNoSlaveOk' and doesn't run. The only way to get this to work is to use the legacy 'Mongo.setSlaveOk(true)'.

Update Mongo.setReadPref() to respect the specified readPreference.



 Comments   
Comment by Githook User [ 11/May/20 ]

Author:

{'name': 'Mihai Andrei', 'email': 'mihai.andrei@10gen.com', 'username': 'mtandrei'}

Message: SERVER-46903 Ensure mongo shell respects readPreference for $out and $merge when 'Mongo.setReadPref' is called
Branch: master
https://github.com/mongodb/mongo/commit/7c9225a68a9e6d2d9f4507812fcbcf7924dce45d

Comment by David Storch [ 25/Mar/20 ]

The drivers team currently plans to update read preference behavior for $out, $merge, and mapReduce as part of their 4.6 compatible releases rather than their 4.4 compatible releases. They advise that we do the same for the shell. Therefore, I am returning this ticket to the backlog.

Note that in addition to the behavior described by mihai.andrei above for connections to individual nodes, the read preference is not respected for $out/$merge/mapReduce operations run against replica set node connections. Consider the following short repro script for this behavior:

let rst = new ReplSetTest({nodes: 2});
rst.startSet();
rst.initiate();
 
// Enable log level 1 on both primary and secondary.
rst.getPrimary().getDB("test").setLogLevel(1);
rst.getSecondary().getDB("test").setLogLevel(1);
 
assert.commandWorked(rst.getPrimary().getDB("test").source.insert({_id: 1}));
assert.commandWorked(rst.getPrimary().getDB("test").source.insert({_id: 2}));
 
let replSetConn = new Mongo(rst.getURL());
replSetConn.setReadPref("secondary");
const testDb = replSetConn.getDB("test");
 
// This operation gets targeted to the primary, despite the secondary read preference set on the connection.
assert.eq(0, testDb.source.aggregate([{$out: "target"}]).itcount());
 
// This operation gets sent to the secondary as expected.
assert.eq(2, testDb.source.aggregate([{$addFields: {newField: 1}}]).itcount());
 
rst.stopSet();

Examining the logs will show that the $addFields operation is sent to the replica set secondary node due to the "secondary" read preference. However, for the $out operation the read preference is ignored and the operation is send to the primary.

CC divjot.arora behackett

Comment by David Storch [ 19/Mar/20 ]

We should hold off on implementing these changes until the drivers team has a clearer plan.

Generated at Thu Feb 08 05:12:46 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.