mongodb, replicates and error: { "$err" : "not master and slaveOk=false", "code" : 13435 }
Asked Answered
C

9

203

I tried mongo replica sets for the first time.

I am using ubuntu on ec2 and I booted up three instances. I used the private IP address of each of the instances. I picked on as the primary and below is the code.

mongo --host Private IP Address
rs.initiate()
rs.add(“Private IP Address”)
rs.addArb(“Private IP Address”)

All at this point is fine. When I go to the http://ec2-xxx-xxx-xxx-xxx.compute-1.amazonaws.com:28017/_replSet site I see that I have a primary, seconday, and arbitor.

Ok, now for a test.

On the primary create a database in this is the code:

use tt
db.tt.save( { a : 123 } )

on the secondary, I then do this and get the below error:

db.tt.find()
error: { "$err" : "not master and slaveOk=false", "code" : 13435 }

I am very new to mongodb and replicates but I thought that if I do something in one, it goes to the other. So, if I add a record in one, what do I have to do to replicate across machines?

Candlewood answered 24/1, 2012 at 16:14 Comment(1)
figured out that I have to use rs.slaveOk(); That leaves me to another question. I have to do this do this for every query? What if I am on the master node?Candlewood
J
319

You have to set "secondary okay" mode to let the mongo shell know that you're allowing reads from a secondary. This is to protect you and your applications from performing eventually consistent reads by accident. You can do this in the shell with:

rs.secondaryOk()

After that you can query normally from secondaries.

A note about "eventual consistency": under normal circumstances, replica set secondaries have all the same data as primaries within a second or less. Under very high load, data that you've written to the primary may take a while to replicate to the secondaries. This is known as "replica lag", and reading from a lagging secondary is known as an "eventually consistent" read, because, while the newly written data will show up at some point (barring network failures, etc), it may not be immediately available.

Edit: You only need to set secondaryOk when querying from secondaries, and only once per session.

Jayejaylene answered 24/1, 2012 at 16:30 Comment(2)
Always check the manual before you go executing commands you don't understand on your DBs. There could be consequences to the command that the answer doesn't explain. Does this command change the way read ope rations are distributed for all connections to the replica set? Better find out. This command appears as far back as v2.2 docs.mongodb.com/v2.2/reference/method/rs.slaveOk You can (and should) always replace the "/manual/" portion of a docs.mongodb.com URL to your specific version to make sure you are getting relevant info.Ingraft
slaveOk() is deprecated and may be removed in the next major release. Please use secondaryOk() instead.Hehre
L
50

To avoid typing rs.slaveOk() every time, do this:

Create a file named replStart.js, containing one line: rs.slaveOk()

Then include --shell replStart.js when you launch the Mongo shell. Of course, if you're connecting locally to a single instance, this doesn't save any typing.

Lassitude answered 25/3, 2013 at 19:54 Comment(2)
A better way to save on typing would be to add rs.slaveOk() to your ~/.mongorc.js file, which will be automatically executed when starting the mongo shell.Raggedy
I find it useful to put the default configuration in ~/.mongorc.js and custom configurations in replStart.js or adminStart.js or whatever.Lassitude
B
43

in mongodb2.0

you should type

rs.slaveOk()

in secondary mongod node

Bamberger answered 29/2, 2012 at 8:50 Comment(0)
N
13

THIS IS JUST A NOTE FOR ANYONE DEALING WITH THIS PROBLEM USING THE RUBY DRIVER

I had this same problem when using the Ruby Gem.

To set slaveOk in Ruby, you just pass it as an argument when you create the client like this:

mongo_client = MongoClient.new("localhost", 27017, { slave_ok: true })

https://github.com/mongodb/mongo-ruby-driver/wiki/Tutorial#making-a-connection

mongo_client = MongoClient.new # (optional host/port args)

Notice that 'args' is the third optional argument.

Norma answered 28/5, 2014 at 21:4 Comment(0)
S
8

I got here searching for the same error, but from Node.js native driver. The answer for me was combination of answers by campeterson and Prabhat.

The issue is that readPreference setting defaults to primary, which then somehow leads to the confusing slaveOk error. My problem is that I just wan to read from my replica set from any node. I don't even connect to it as to replicaset. I just connect to any node to read from it.

Setting readPreference to primaryPreferred (or better to the ReadPreference.PRIMARY_PREFERRED constant) solved it for me. Just pass it as an option to MongoClient.connect() or to client.db() or to any find(), aggregate() or other function.

const { MongoClient, ReadPreference } = require('mongodb');
const client = await MongoClient.connect(MONGODB_CONNECTIONSTRING, { readPreference: ReadPreference.PRIMARY_PREFERRED });
Semester answered 25/5, 2020 at 8:9 Comment(0)
T
7

WARNING: slaveOk() is deprecated and may be removed in the next major release. Please use secondaryOk() (in the mongo shell) instead.

Trakas answered 17/10, 2020 at 15:35 Comment(0)
M
4

slaveOk does not work anymore. One needs to use readPreference https://docs.mongodb.com/v3.0/reference/read-preference/#primaryPreferred

e.g.

const client = new MongoClient(mongoURL + "?readPreference=primaryPreferred", { useUnifiedTopology: true, useNewUrlParser: true });
Mediocre answered 30/8, 2019 at 22:11 Comment(0)
A
2

I am just adding this answer for an awkward situation from DB provider.

what happened in our case is the primary and secondary db shifted reversely (primary to secondary and vice versa) and we are getting the same error.

so please check in the configuration settings for database status which may help you.

Artemas answered 23/11, 2016 at 10:38 Comment(0)
P
0

Adding readPreference as PRIMARY

const { MongoClient, ReadPreference } = require('mongodb');
const client = new MongoClient(url, { readPreference: ReadPreference.PRIMARY_PREFERRED});
client.connect();
Perspicacity answered 4/10, 2021 at 14:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.