search by tags

for the user

adventures into the land of the command line

changing mongo replica set id while it's running

Say you see a message from one of the secondaries that looks like this:

"lastHeartbeatMessage" : "Our set name of bello_mongo does not match name hello_mongo reported by remote node",

Oh scheisse…

> use local
> db.system.replset.find()

{ "_id" : "bello_mongo", "version" : 1, "protocolVersion" : NumberLong(1), "members" : [ { "_id" : 0, "host" : "server0:27017", "arbiterOnly" : false, "buildIndexes" : true, "hidden" : false, "priority" : 1, "tags" : {  }, "slaveDelay" : NumberLong(0), "votes" : 1 }, { "_id" : 1, "host" : "server1:27017", "arbiterOnly" : false, "buildIndexes" : true, "hidden" : false, "priority" : 1, "tags" : {  }, "slaveDelay" : NumberLong(0), "votes" : 1 }, { "_id" : 2, "host" : "server2:27017", "arbiterOnly" : false, "buildIndexes" : true, "hidden" : false, "priority" : 1, "tags" : {  }, "slaveDelay" : NumberLong(0), "votes" : 1 } ], "settings" : { "chainingAllowed" : true, "heartbeatIntervalMillis" : 2000, "heartbeatTimeoutSecs" : 10, "electionTimeoutMillis" : 10000, "getLastErrorModes" : {  }, "getLastErrorDefaults" : { "w" : 1, "wtimeout" : 0 }, "replicaSetId" : ObjectId("572c7ec68d7eXXXXXXXXXX") } }

OR

> db.system.replset.update({}, { "_id" : "bello_mongo", "version" : 1, "protocolVersion" : NumberLong(1), "members" : [ { "_id" : 0, "host" : "server0:27017", "arbiterOnly" : false, "buildIndexes" : true, "hidden" : false, "priority" : 1, "tags" : {  }, "slaveDelay" : NumberLong(0), "votes" : 1 }, { "_id" : 1, "host" : "server1:27017", "arbiterOnly" : false, "buildIndexes" : true, "hidden" : false, "priority" : 1, "tags" : {  }, "slaveDelay" : NumberLong(0), "votes" : 1 }, { "_id" : 2, "host" : "server2:27017", "arbiterOnly" : false, "buildIndexes" : true, "hidden" : false, "priority" : 1, "tags" : {  }, "slaveDelay" : NumberLong(0), "votes" : 1 } ], "settings" : { "chainingAllowed" : true, "heartbeatIntervalMillis" : 2000, "heartbeatTimeoutSecs" : 10, "electionTimeoutMillis" : 10000, "getLastErrorModes" : {  }, "getLastErrorDefaults" : { "w" : 1, "wtimeout" : 0 }, "replicaSetId" : ObjectId("572c7ec68d7eXXXXXXXXXX") } })

OR:

> use local
> cfg = db.system.replset.findOne( { "_id": "bello_mongo" } )
> cfg._id = "hello_mongo"
> db.system.replset.update( { "_id": "bello_mongo" } , cfg )
> rs.reconfig(cfg)

The result of any of these will be:

WriteResult({
    "nMatched" : 0,
    "nUpserted" : 0,
    "nModified" : 0,
    "writeError" : {
        "code" : 16837,
        "errmsg" : "The _id field cannot be changed from {_id: \"bello_mongo\"} to {_id: \"hello_mongo\"}."
    }
})

Scheisse…

Then I came across this. The correct method is:

Stop all the servers.

If authentication is enabled, make sure it is disabled or changes to the local.system.replset collection may not be authorised.

Start up each server without the –replSet option, pointing at the correct data directory.

Update the local.system.replset doc on each server with the new replica set name. You have to change it on every server individually.

$ mongo
> use local
> var doc = db.system.replset.findOne()
> doc._id = 'hello_mongo'
> db.system.replset.save(doc)
> db.system.replset.remove({_id:'bello_mongo'})

Change the /etc/mongod.conf replSet option to the new name on all the servers and also don’t to put authentication back if you are using it.

Restart them all with the original options.