11

How to set rs.slaveOk() in secondary mongodb servers in replicaset via commandline?

I tried following methods :

${MONGO_HOME}/bin/mongo --port ${MONGO_PORT2} --host ${MONGO_SECONDARY2} --eval "printjson(rs.slaveOk())"

${MONGO_HOME}/bin/mongo --port ${MONGO_PORT2} --host ${MONGO_SECONDARY2} --eval "printjson(rs.slaveOk(true))"

${MONGO_HOME}/bin/mongo --port ${MONGO_PORT2} --host ${MONGO_SECONDARY2} --eval "printjson(db.getSiblingDB('admin').getMongo().setSlaveOk())"

the command executes with undefined in the output log. I am trying to set this via the shell in primary server.

NitheshKHP
  • 381
  • 1
  • 2
  • 13
  • rs.slaveOk() does not have a return type. What are you trying to achieve? – Martin Oct 27 '15 at 12:51
  • the return value part was misleading. when i try to execute the above mentioned command via a shell script, it doesn't work. – NitheshKHP Oct 28 '15 at 04:38
  • You keep saying things doesn't work, but provide no information on what you are trying to do and no error messages?! – Martin Oct 28 '15 at 08:28
  • I am trying to execute rs.slaveOk() in a secondary server via unix commandline. There are no errors, the code executes but the secondary server still can't accept reads. – NitheshKHP Oct 28 '15 at 09:32
  • setSlaveOk() does not change whether a replica will accepts reads. It enables a connection to be used for queries even if that connection is to a slave server, the setting has no effect on the server. – Martin Oct 28 '15 at 09:54
  • ok i get it now, i didn't read the docs correctly. Thanks for clarifying it. – NitheshKHP Oct 28 '15 at 10:18

3 Answers3

23

Create a file /etc/mongorc.js and add rs.slaveOk() there. The file is being evaluated on each shell startup.

For more information have a look here

From MongoDB version 4.4 onwards, you might get a warning displayed like:

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

So, please prefer using rs.secondaryOk()

swateek
  • 6,735
  • 8
  • 34
  • 48
goral
  • 1,275
  • 11
  • 17
6

Calling the below should work fine, there is no return type for the method so nothing will get printed back to the screen

${MONGO_HOME}/bin/mongo --port ${MONGO_PORT2} --host ${MONGO_SECONDARY2} --eval "rs.slaveOk()"

Running rs.slaveOk in the mongo.exe will also how how it is implemented as it is just a helper method:

> rs.slaveOk
function (value) { return db.getMongo().setSlaveOk(value); }
>

And also the setSlaveOk method:

> db.getMongo().setSlaveOk
function ( value ) {
     if( value == undefined ) value = true;
     this.slaveOk = value;
}

You could always try to query one of the collections on the secondary to make sure the node is queryable:

> db.test.findOne()
null 

Update - bit more clarity

Setting slaveOk() is only valid for that console session that it was executed in, so you would need to pass in a script or stay connected to the console with the --shell arguments for exmaple

C:\mongodb\bin>mongo.exe --port 27012 --eval "rs.slaveOk()" --shell
MongoDB shell version: 3.0.5
connecting to: 127.0.0.1:27012/test
type "help" for help
rs1:SECONDARY> db.test.find()
{ "_id" : ObjectId("5630fdf2af4abd9f8ae7f79c"), "test" : true }
rs1:SECONDARY>

If we don't pass in the rs.slaveOk() the we get the following response:

C:\mongodb\bin>mongo.exe --port 27012 --shell
MongoDB shell version: 3.0.5
connecting to: 127.0.0.1:27012/test
type "help" for help
rs1:SECONDARY> db.test.find()
Error: error: { "$err" : "not master and slaveOk=false", "code" : 13435 }
rs1:SECONDARY> exit
bye
Kevin Smith
  • 13,746
  • 4
  • 52
  • 77
1

JFYI : looks like rs.slaveOk() will be deprecated soon, instead MongoDB suggest to use rs.secondaryOk()

Following is the official warning you gonna see in MongoShell:

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

Cheers

Immu
  • 746
  • 5
  • 10