I want to create a MongoDB replica set, and according to the documentation I need to run sth like this in my first mongo instance in order to config the replica set and this works fine. However, I was wondering if there is a way to automate this process and don't ssh to the server and run this piece of code every time. I tried putting it in a config file but it didn't work
rs.initiate( {
_id : "rs0",
members: [
{ _id: 0, host: "mongodb0.example.net:27017" },
{ _id: 1, host: "mongodb1.example.net:27017" },
{ _id: 2, host: "mongodb2.example.net:27017" }
]
})
Are you talking about situation where you create replica set(s) with docker, terraform, ... kind of tools?
You can always include local init -script what have that rs.initiate(...) command.
Replica set needs ALWAYS initial initiate -command. Without it, it doesn't exist.
Although the question is a bit old, I think it is important to show a possible solution to future readers!
This repo https://github.com/deRemo/dockerized-mongodb presents a python script to automate the configuration of a replica set in a "dockerized" scenario. Have a look at configure_rs.py
Here I extrapolated the important bits:
#!/usr/bin/python3
import os,sys
if len(sys.argv) < 2:
print("USAGE: ./script ip1 ip2 ... (hostname are also valid, if recognised)")
exit()
print("Configuring replica set...")
members = []
for i in range(1, len(sys.argv)):
prio = 1 if i == 1 else 0 #prioritize first member for the primary election
members.append("{_id: "+str(i-1)+", host: \'"+str(sys.argv[i])+"\', priority: "+str(prio)+"}")
#stringify members and prepare rs config
members = ', '.join(d for d in members)
cfg = "{_id: 'rs0', members: ["+members+"]}"
os.system("./mongo --host "+sys.argv[1]+" --eval \"JSON.stringify(db.adminCommand({'replSetInitiate' : "+cfg+"}))\"")
The script takes as input the hostnames of the machines where your mongod instances are deployed (make sure that they are reachable over your network)
Related
I have created 3 Digitalocean droplet. By default, I choose Ubuntu 18.06 and MongoDB 4.
Here I have 3 droplets by default MongoDB config and all are up. I have access to "mongo" shell for all of them.
Now I want to run a replica-set setting by this code:
rs.initiate(
{_id : "rs0",
members: [
{ _id: 0, host: "20.30.40.50:27017" },
{ _id: 1, host: "20.30.40.51:27017" },
{ _id: 2, host: "20.30.40.52:27017" }
]
})
In this config, I just told MongoDB that rune the replica set and it retrieves me the error
no replies config has been received
I did not add any bindIp yet also when I added bindIp, I could not start MongoDB again. I put in mongo.conf like this:
bindIp: 127.0.0.1,20.30.40.51,20.30.40.52
Also, There is a private network between these 3 droplets by IP example: 10.10.1.1 Can I take advantage of this private IP to make it easier and safer?
I have configured a replica set for MongoDB manually.
Once I have launched the daemons on 3 nodes and after they are up and running, from the node which I have identified as "Primary" I run the following command:
mongo
This will drop me into the mongo shell
use admin
Create replica set config:
cfg = {
_id: 'csReplicaSet',
members: [
{ _id: 0, host: 'node1IpAddress:27017'},
{ _id: 1, host: 'node2IpAddress:27017'},
{ _id: 2, host: 'node3IpAddress:27017', arbiterOnly: true}
]
}
rs.initiate(cfg)
I want to know how can I do these steps in a JavaScript file that will be recognised by mongo. I want to automate these steps.
Passing your init script to the mongo shell
Programmatically, you're almost there. You could save your instructions to a JavaScript file and run this on the mongo command line. You should also capture & print the results of rs.initiate() in case there is an error:
eg. contents of initreplica.js:
var cfg = { _id: 'csReplicaSet',
members: [
{ _id: 0, host: 'node1IpAddress:27017'},
{ _id: 1, host: 'node2IpAddress:27017'},
{ _id: 2, host: 'node3IpAddress:27017', arbiterOnly: true}
]
};
var error = rs.initiate(cfg);
printjson(error);
Run this from the command line with:
mongo node1IpAddress:27017/admin initreplica.js
Note that this assumes your three mongod nodes have been started on the same IP addresses including --replSet csReplicaSet parameter. You also only need to do this init sequence once unless you are rebuilding the replica set from scratch (and there is no existing replica set config).
I would also recommend reading the section of the manual on Writing Scripts for the mongo shell. It includes some helpful hints such as how to open new connections to other MongoDB servers as well as the JavaScript equivalents of some shell helpers like use <db>.
Automating a production deployment
If you're looking for ways to automate building a production MongoDB cluster, you should look into recipes for configuration management tools like Chef or Puppet. There is also an Automation feature coming soon as part of MMS (MongoDB Management Service); the Automation feature is currently in beta testing.
I Just run it this way
mongo --port 27018 init_replica.set.js
and this is the script for init from the
config = { _id: "m101", members:[
{ _id : 0, host : "MYHOST:27017" ,priority : 0, slaveDelay : 5 },
{ _id : 1, host : "MYHOST:27018"},
{ _id : 2, host : "MYHOST:27019"} ]
};
rs.initiate(config);
rs.status();
Consider, I have 4 replicate sets and the config is as follows:
{
"_id": "rs_0",
"version": 5,
"members" : [
{"_id": 1, "host": "127.0.0.1:27001"},
{"_id": 2, "host": "127.0.0.1:27002"},
{"_id": 3, "host": "127.0.0.1:27003"},
{"_id": 4, "host": "127.0.0.1:27004"}
]
}
I am able to connect to all sets using
mongo --port <port>
There are documents for getting information on Convert a Standalone to a Replica Set, but can anyone tell me how to convert back to standalone from replica set?
Remove all secondary hosts from replica set (rs.remove('host:port')), restart the mongo deamon without replSet parameter (editing /etc/mongo.conf) and the secondary hosts starts in standalone mode again.
The Primary host is tricky one, because you can't remove it from the replica set with rs.remove.
Once you have only the primary node in the replica set, you should exit mongo shell and stop mongo. Then you edit the /etc/mongo.conf and remove the replSet parameter and start mongo again.
Once you start mongo you are already in standalone mode, but the mongo shell will prompt a message like:
2015-07-31T12:02:51.112+0100 [initandlisten] ** WARNING: mongod started without --replSet yet 1 documents are present in local.system.replset
to remove the warning you can do 2 procedures:
1) Droping the local db and restarting mongo:
use local
db.dropDatabase();
/etc/init.d/mongod restart
2)Or if you don't want to be so radical, you can do:
use local
db.system.replset.find()
and it will prompt a message like:
{ "_id" : "replicaSetName", "version" : 1, "members" : [ { "_id" : 0, "host" : "hostprimary:mongoport" } ] }
then you will erase it using:
db.system.replset.remove({ "_id" : "replicaSetName", "version" : 1, "members" : [ { "_id" : 0, "host" : "hostprimary:mongoport" } ] })
and it will probably prompt:
WriteResult({ "nRemoved" : 1 })
Now, you can restart the mongo and the warning should be gone, and you will have your mongo in standalone mode without warnings
Just remove a host from replica set (rs.remove('host:port')), relaunch it without replSet parameter and it's standalone again.
On an Ubuntu Machine
Stop your mongo server
open /etc/mongod.conf
Comment the replication and replSetName line
#replication:
#replSetName: rs0
Start your mongo server and go to mongo shell
drop local database
use local
db.dropDatabase()
Restart mongo
The MongoDB Documentation suggests the following to perform maintenance on a replica set member, which brings the the replica set member into standalone mode for further operations. With little modification it can be made standalone:
If node in concern is the only node in a shard, drain the chunks to other shards as per MongoDB documentation here, or else the sharded database will break, i.e.
Make sure balancer is enabled by connecting to mongos and run sh.startBalancer(timeout, interval)
For the shard in concern, go to admin database and db.adminCommand( { removeShard: "mongodb0" } )
Check draining status by repeating above removeShard command, wait for draining to complete
If node in concern is primary, do rs.stepDown(300)
Stop the node by running db.shutdownServer()
Change the yaml config by:
commenting out replication.replSetName (--replSetName in command line)
commenting out sharding.clusterRole for shard or config server (--shardsvc and --configsvr in command line)
commenting out net.port, then change it to a different port (--port in command line)
Start the mongod instance
If change is permanent, go to other mongod instance and run rs.remove("host:port")
After this, the node in concern should be up and running in standalone mode.
Follow below steps :
Go to mongo shell on Secondary servers
Stop the secondary servers by using below command :
use admin
db.shutdownServer()
Go to Linux shell- on secondary servers and type below command :
sudo service mongod stop
Starting the MongoDB replication -
Go to Linux shell - on secondary servers and type below command :
sudo service mongod start
Starting the MongoDB replication -
Go to primary and type below commands to start the replication :
a] rs.initiate()
b] rs.add("Secondar -1:port no")
c] rs.add("Secondary-2:port no")
d] rs.add({ "_id" : 3, "host" : "Hidden_member:port no", "priority" : 0,
"hidden" : true })
e] rs.status()
I have a mongo 2 node cluster running, with this replica set config.
config = {_id: "repl1", members:[
{_id: 0, host: 'localhost:15000'},
{_id: 1, host: '192.168.2.100:15000'}]
}
I have to move these both nodes on to new servers. I have copied everything from old to new servers, but I'm running into issues while reconfiguring the replica config due to ip change on the 2nd node.
I have tried this.
config = {_id: "repl1", members:[
{_id: 0, host: 'localhost:15000'},
{_id: 1, host: '192.168.2.200:15000'}]
}
rs.reconfig(config)
{
"startupStatus" : 1,
"errmsg" : "loading local.system.replset config (LOADINGCONFIG)",
"ok" : 0
}
It shows above message, but change is not happening.
I also tried changing replica set name but pointing to the same data dirs.
I am getting the following error:
rs.initiate()
{
"errmsg" : "local.oplog.rs is not empty on the initiating member. cannot initiate.",
"ok" : 0
}
What are the right steps to change the IP but keeping the data on the 2nd node, or do i need to recreate/resync the 2nd node?
Well , I had the same problem.
I had to delete all replication and oplog.
use local
db.dropDatabase()
restart your mongo with new set name
config = {_id: "repl1", members:[
{_id: 0, host: 'localhost:15000'},
{_id: 1, host: '192.168.2.100:15000'}]
}
rs.initiate(config)
I hope this works for you too
You can use force option when reconfiguring replica set:
rs.reconfig(config, {force: true})
Note that, as Adam already suggested in the comments, you should have at least 3 nodes: 2 full nodes and 1 arbiter (minimum supported configuration) or 3 full nodes (minimum recommended configuration) so that primary node can be elected.
I realise this is an old post, but I discovered I was getting this exact same error when trying to change the port used by secondaries in my replica set.
In my case, I needed to stop the secondary whose config I was changing, and bring it up on its new address and port BEFORE applying the changed config on the Primary.
This is in the mongo documentation, but the order in which I had to bring things up and down was something I'd mis-read on the first pass, so for clarity I've repeated that here:
Shut down the secondary member of the replica set you are moving.
Bring that secondary back up at its new address
Make the configuration change as detailed in the original post above
You can use rs.reconfig option. First retrieve the current configuration with rs.conf(). Modify the configuration document as needed, and then pass the modified document to rs.reconfig()
More info in docs.
Recently we made live the mongodb sharding concept and its working fine in production server. But we have configured the public IP address instead of internal IP. So we have to change the internal ip in mongodb db sharding.
Please clarify whether its possible or not. If possible means, please share your input.
public ip example:
conf = {_id : "data1",members : [{_id : 0, host : "10.17.18.01:10001", votes : 2},{_id : 1, host : "10.17.19.02:10002", votes : 1},{_id:2, host: "10.17.19.03:10003", votes : 3, arbiterOnly: true}]}
internal ip example
conf = {_id : "data1",members : [{_id : 0, host : "20.17.18.01:10001", votes : 2},{_id : 1, host : "20.17.19.02:10002", votes : 1},{_id:2, host: "20.17.19.03:10003", votes : 3, arbiterOnly: true}]}
whether it will work. Pls suggest.
Regards,
Kumaran
You said you're trying to update the IPs in the sharding system, but the config documents you provided as an example look like a replica set configuration. If it's actually your replica set configuration you want to update, you should just be able to remove the entry for the old IP address from the replica set configuration, then add the node back in with the new IP. See http://www.mongodb.org/display/DOCS/Replica+Set+Configuration and http://www.mongodb.org/display/DOCS/Reconfiguring+when+Members+are+Up for more details.
If it's actually the sharding configuration you want to update, it will be a bit more complicated.
Throwing in an answer, even though this is a dated question for anyone else who might view this.
I would recommend using host names / host entries on your servers to handle local and external ips. However, to update the hosts in your case, you would have to change the replica set config.
Log into the Primary in the replica set then do the following:
> cfg = rs.conf()
> cfg.members[0].host = "[new host1]:[port]"
> cfg.members[1].host = "[new host2]:[port]"
> cfg.members[2].host = "[new host3]:[port]"
cfg.members is obviously a zero-index array, you can reuse that for how every many replicas you have.
> rs.reconfig( cfg )
From there, you would want to re-add your shards with the newly specified hosts.
from inside mongos.
simply use the following command to update the IPs of the shard servers:
db.shards.update({_id: <<"shard name">>} , {$set: {"host" : "newIP:27018"}})
Example:
db.shards.update({_id: "shard000"} , {$set: {"host" : "172.31.1.1:27018"}})
172.31.1.1 is the private ip address of your shard server in the private network.
avoid using a dynamic ip address.
If you want to do any modification in the Shard configuration then you should
use config
db.shards.update( { _id : } , { $set : { ... } } )
Please make sure that you restart your config server and mongos after making this change.