Connecting to Mongo in Replica set mode - mongodb

I have a standalone Mongo instance running a replica set. I can't seem to connect and run any queries in the Mongo shell however. I get the following:
error: { "$err" : "not master and slaveOk=false", "code" : 13435 }
I set SlaveOk like so:
db.getMongo().setSlaveOk()
..but I still get an error:
error: {
"$err" : "not master or secondary; cannot currently read from this replSet member",
"code" : 13436
}
I can't seem to find a straight answer on Google: how do I connect to my replica set using the mongo shell?

I got the same problem and solved it using
rs.initiate()

If you are connecting to a node in a replica set that is not the master, you need to explicitly tell the client that it is ok that your are not connected to a master..
You can do this by calling
rs.slaveOk()
You can then perform your query.
Note that you will only be able to perform queries, not make changes to the repository, when connected to a slave node.

You are connected to a node that is neither in state secondary or primary. This node could be an arbiter or possibly a secondary in recovery mode. For example, if I had a replica set of 3 nodes, (where there is one primary, a secondary and an arbiter) I would get the same error if I had connected to the arbiter and issued a query even after I had set slaveOK true. The shell's command line prompt should indicate what state the node you are connected is in:
foo:ARBITER> db.test.find()
error: {
"$err" : "not master or secondary; cannot currently read from this replSet member",
"code" : 13436
}

have you tried: db.getMongo().setSlaveOk(true)

I also got the error. But when i tried connecting to the secondary node using the machine name instead of 'localhost' or 127.0.0.1 the error went away.

This error is only displayed when you are running an instance that's part of a replica set in standalone mode without completely removing it from the replica set.
e.g. You restart your instance on a different port but don't remove the --repSet option when starting it.
This starts it but neither as a primary nor as a secondary, hence the error
not master or secondary;
Depending on what you intended to do initially, either restart the instance on the correct port and with the correct --repSet option. This adds it to the replica set and gets rid of this error
If you intended to run the instance as standalone for some time (say to create an index), then start it on a different port WITHOUT the --repSet option

I got the same error while running aggregate() on staging server with two replica sets.I think you need to change the read preference to 'secondaryPreferred'.
Just put .read('secondaryPreferred') after the query function.

Related

What's the equivalent of `rs.slaveOk()` for config file in MongoDB?

I have set up my MongoDB on local machine with replicaSet, and I have this error:
An error occurred while loading navigation: 'not master and
slaveOk=false': It is recommended to change your read preference in
the connection dialog to Primary Preferred or Secondary Preferred or
provide a replica set name for a full topology connection.
If I don't exec this command on secondary servers,
rs.slaveOk()
After using the command, the problem is solved, but only temporarily. After restarting the servers, the above error pops up again, I again have to stop it using the command.
How can I somehow define the slaveOk in a config file, so that I don't have to allow slaveOk each time I start the server?
Your connection string should look something like this:
mongodb://mongodb0.example.com:27017,mongodb1.example.com:27017,mongodb2.example.com:27017/?replicaSet=myRepl
If you are connecting from shell
mongo "mongodb://mongodb0.example.com:27017,mongodb1.example.com:27017,mongodb2.example.com:27017/?replicaSet=myRepl"
OR
mongo --host myRepl/mongodb0.example.com.local:27017,mongodb1.example.com.local:27017,mongodb2.example.com.local:27017
Where myRepl is the replica set name, mongodbX.example.com.local:27017 are your nodes.

How to find the replica set name?

I have an M0 instance created at mongodb.com using all the defaults. I copied the URI connection string from the Atlas Connection dialog. It was recognized in mongoDB Compass and the connection details form was automatically filled out.
It worked fine for a few weeks and I could browse my documents. Then all of a sudden I am getting:
An error occurred while loading navigation: 'not master and slaveOk=false': It is recommended to change your read preference in the connection dialog to Primary Preferred or Secondary Preferred or provide a replica set name for a full topology connection.
I searched and most suggest to explicitly specify the Replica Set Name. The automatic settings have Read Preference set to Primary and the Replica Set Name is blank.
Why is this error occurring suddenly, and how do I find out the replica set name to use?
To find the replica set name:
Open the mongo shell and type the command:
rs.status()
this will give you a document with the replica set name (under the key set):
{
"set" : "Name of your replica set",
...
}
Actually you can easily type the following on the Mongo Shell
rs.status().set
This will return you the replica set name
Why is this error occurring suddenly
The error message is triggered because there was a Replica Set Election that changed the state of the instance that you're connecting from Primary to Secondary.
When connecting using MongoDB Compass, and no replica set name specified. The connection would be a direct connection to the instance, instead of a connection to the replica set (automatic topology discovery).
how do I find out the replica set name to use?
On MongoDB Atlas project page, select the Deployment link on the left hand side menu. Under Processes tab, with Topology view you should see the replica set name (this should be the default view presented when you click on Deployment).
Generally, the replica set name is the cluster name plus -shard-0. i.e. cluster name test, replica set name is test-shard-0.
In the mongo shell - I executed rs.status() and copied the set name.
In the Compass client, I selected the previously used / 'Recent' connection string from the left hand side and clicked the 'Fill in connection fields individually" link above the string box.
Clicked the 'More Options' tab and pasted the set name into 'the Replica set name' field (mine was previously empty)
This fixed it for me and was able to connect.
On connecting to primary mongod server locally you will notice that the prompt has the replica set name. Example:
ssh -i "keyfile.pem" MongoDPrimary:27017 (Connect to MongoD server)
mongo (Connect to MongoD database)
s0:PRIMARY> (Mongo Shell Prompt)
In the above prompt:
"s0" refers to the replica set name
"Primary" refers to the primary replica.
rs.status() although good requires you to authenticate against the DB which can

Can't create user

I was using MongoDB version 2.6.6 on Google Compute Engine and used the click to deploy method.
rs0:SECONDARY> db.createUser({user:"admin", pwd:"secret_password", roles:[{role:"root", db:"admin"}]})
2015-07-13T15:02:28.434+0000 Error: couldn't add user: not master at src/mongo/shell/db.js:1004
rs0:SECONDARY> use admin
switched to db admin
rs0:SECONDARY> db.createUser({user:"admin", pwd:"secret_password", roles:["root"]})
2015-07-13T15:13:28.591+0000 Error: couldn't add user: not master at src/mongo/shell/db.js:1004
I had a similar problem with mongo 3.2:
Error: couldn't add user: not master :
When trying to create a new user, with root role.
I was using only a local copy of mongo.
In my mongod.conf file I had the following uncommented:
replication:
replSetName: <node name>
Commenting that out and restarting fixed the problem. I guess mongo thought it was part of a replication set, and was confused as to who the Master was.
Edit:
I've also found that if you ARE trying to setup a replication set, and you get the above error, then run:
rs.initiate()
This will start a replication set, and set the current node as PRIMARY.
Exit, and then log back in and you should see:
PRIMARY>
Now create users as needed.
I ran into this error when scripting replica set creation.
The solution was to add a delay between rs.initiate() and db.createUser().
Replica set creation is seemingly done in background and it takes time for the primary node to actually become primary. In interactive use this doesn't cause a problem because there is a delay while typing the next command, but when scripting the interactions the delay may need to be forced.
MongoDB will be deployed in a cluster of Compute Engine instances (also known as a MongoDB replica set). Each instance will use a boot disk and separate disk for database files.
Primary and master nodes are the nodes that can accept writes. MongoDB’s replication is “single-master:” only one node can accept write operations at a time.
Secondary and slave nodes are read-only nodes that replicate from the primary.
Your error message looks like you are trying to add the user on the secondary. Try adding the user in the primary.
I ran into this issue when I thought I was running mongo 3.4 but it was mongo 3.6. Uninstalling 3.6 and installing 3.4 fixed my issue.

MongoDB how to become master

I am creating a MongoDB database through a linux terminal and I am trying to create a collection for the database.
But when I run the command: db.createCollection("mainCollection") I get the following error message: { "note" : "from execCommand", "ok" : 0, "errmsg" : "not master" }
I'm not exactly sure what this means. How can I make the database master?
Thanks
You have started the mongod with the --replSet option (or equivalent configuratin file option). That puts the mongod into a mode where it will not allow any writes until it receives a replica set configuration.
For an existing replica set this is accomplished by doing a rs.add("<host>:<port>") on the existing primary for the replica set.
Based on the conversation around this question I think you have a single MongoDB instance and do not plan to have a true multi-member replica set. If that is the case you have two options:
Stop trying to run a replica set
Stop the mongod.
Wipe the data directory for the mongod process.
Restart the mongod process without the --replSet option on the command line/config.
Initialize the mongod as a single node replica set.
Run rs.initiate() from the shell (no config is required). You will get disconnected but the shell will automatically reconnect and then you can create collections and do other writes.
Thats expected behaviour "Viratan" if you are querying on the replica set and the shell you are connected with is not the Primary.
You can do either of these two things.
Disconnect from the current shell and connect with the Primary. In mongo shell you would see it written "PRIMARY" or "SECONDARY".
In case you want the same member as the primary then you can increase the priority of that particular member and/or force the formar primary to stepDown. once the primary is step down, the election would occur and because the desired member has higher priority that would become primary.
you can follow the below link to change the priority of a member http://docs.mongodb.org/manual/tutorial/force-member-to-be-primary
Once you are connected with Primary in either ways, you can query the DB and do your stuff.
Happy Mongoing.. :-)
-$
you are trying to create a new collection on secondary.thats why it is giving as error please use primary to create new

MongoDB sharding: host does not belong to replica set

I am a Mongo newbie.
I am trying to sping up a MongoDB cluster with both sharding and replication. Cluster schema which I want to implement is: https://github.com/ansible/ansible-examples/raw/master/mongodb/images/site.png
I am using server IP as replication set name. I.e. I am building replication sets with commands below:
rs.initiate()
rs.add("10.148.28.51:27118")
rs.add("10.148.28.52:27118")
rs.add("10.148.28.53:27118")
Replication is being configured correctly so when I am executing rs.status() on PRIMARY host 10.148.28.51 I am getting "10.148.28.51" as repl.set name: https://gist.github.com/daniilyar/630bc6fe7723ed06f243
But when I am trying to add shards at mongos instance it gives me 2 opposite errors (depending on what addShard() syntax variation I use):
mongos> sh.addShard("10.148.28.51:27118")
{
"ok" : 0,
"errmsg" : "host is part of set 10.148.28.51, use replica set url format <setname>/<server1>,<server2>,...."
}
mongos> sh.addShard("10.148.28.51/10.148.28.51:27118")
{
"ok" : 0,
"errmsg" : "in seed list 10.148.28.51/10.148.28.51:27118, host 10.148.28.51:27118 does not belong to replica set 10.148.28.51"
}
How do I add shard if Mongo tells that "host X is in replica set Y" and that "host X does not belong to replica set Y" in the same time?
Any help would be greatly appreciated
From your description sounds like you need to tweak the way your are using the rs.add(..) command. You state you are using the IP address as the name of the replica set but this is not how rs.add(...) interprets the argument.
The argument you pass is the hostname (or IP) and port of the mongod instance you are looking to add to the replica set notthe replica set name. You set-up this configuration when connected via mongo to the primary. The replSet name is set when the primary is started:
mongod --replSet "rs1"
sets the as name of rs1.
I'd have a read over: http://docs.mongodb.org/manual/tutorial/convert-replica-set-to-replicated-shard-cluster/ as it covers pretty much what you appear to be trying to do.
I'd also consider what you are trying to achieve as it sounds (from your description) like you may end up with a single replicated shard (!!!) when you most probably are looking to create multiple shards each of which have their data replicated.
References:
rs.add command - http://docs.mongodb.org/manual/reference/method/rs.add/
rs.addShard command - http://docs.mongodb.org/manual/reference/method/sh.addShard/
Sharded Cluster -
http://docs.mongodb.org/manual/core/sharded-cluster-components/
Thank you for good explanation, now I understand. If you use in rs.add(IP:port), Mongo adds replica set member with name ip-X-Y-Z-R:. It seems to be Mongo's default behavior. So in my case solution was to use command:
sh.addShard("10.148.28.51/**ip-10-148-28-51**:27118")
instead of:
sh.addShard("10.148.28.51/**10.148.28.51**:27118")