3

I have a simple replica set with 3 members

Ouput of rs.status()

{
    ...,
    "members" : [
        {
            "_id": 1,
            "name": "localhost:27021",
            "stateStr": "PRIMARY",
        },
        {
            "_id": 2,
            "name": "localhost:27022",
            "stateStr": "SECONDARY",
        },
        {
            "_id": 3,
            "name": "localhost:27023",
            "stateStr": "SECONDARY",
        }
    ]
}

I removed one member

rs.remove("localhost:27023")

Now rs.status()

{
    ...,
    "members" : [
        {
            "_id": 1,
            "name": "localhost:27021",
            "stateStr": "PRIMARY",
        },
        {
            "_id": 2,
            "name": "localhost:27022",
            "stateStr": "SECONDARY",
        },
    ]
}

Now I used a mongodb connection URL with removed instance. It connected to replica set members successfully!!

var url = 'mongodb://localhost:27023/myproject?replicaSet=rs0';
MongoClient.connect(url, function(err, db) {
  console.log("Connected correctly to server");
  db.close();
});

I could see the connection was established with replica set members(localhost:27022 and localhost:27023)

2019-04-17T18:59:04.727+0900 I NETWORK  [thread1] connection accepted from 127.0.0.1:53284 #6 (3 connections now open)
2019-04-17T18:59:04.727+0900 I NETWORK  [conn6] received client metadata from 127.0.0.1:53284 conn6: { driver: { name: "nodejs", version: "3.2.3" }, os: { type: "Linux", name: "linux", architecture: "x64", version: "4.15.0-47-generic" }, platform: "Node.js v10.15.0, LE, mongodb-core: 3.2.3" }
2019-04-17T18:59:04.736+0900 I -        [conn6] end connection 127.0.0.1:53284 (3 connections now open)
2019-04-17T18:59:35.334+0900 I ASIO     [NetworkInterfaceASIO-RS-0] Ending idle connection to host localhost:27021 because the pool meets constraints; 1 connections to that host remain open

Can someone explain this? Connecting to replica set members through a removed member. Could not find any explanation in any docs.

Sreeragh A R
  • 2,871
  • 3
  • 27
  • 54
  • rs.remove only updates replSetReconfig, it doesn't shut down mongod. – Alex Blex Apr 17 '19 at 15:04
  • @AlexBlex I actually wanted to know why the connection between replica set and removed member is maintained. – Sreeragh A R Apr 21 '19 at 09:01
  • 1
    The documention explictly requires you to shutdown the mongod instance before issuing `rs.remove()`: https://docs.mongodb.com/manual/tutorial/remove-replica-set-member/#remove-a-member-using-rs-remove. Maybe you failed to follow the first step which might have resulted in improper replicaset state. Try running re.reconfig() and reconnecting. – Nidhin David Apr 22 '19 at 08:24

1 Answers1

3

This is a driver behavior. By default, a client connects to a replica set will try to connect to the primary node. In this case, connecting to mongodb://localhost:27023/myproject?replicaSet=rs0 will first connect to localhost:27023 and checks if the connected node is master/primary, using command {isMaster: 1}. From the results, it detects localhost:27023 is not master/primary but it also has the other nodes info available. The next steps are to connect to other nodes until it finds the primary.

You should shut down localhost:27023 and it won't even connect.

simagix
  • 1,832
  • 1
  • 9
  • 11
  • "but it also has the other nodes info available" - Could you please explain this more? Why info is kept even after it is removed from replica set? Any link to official docs will also do. Thanks – Sreeragh A R Apr 29 '19 at 15:31
  • replica metadata is replicated to the node before it is removed from the replica set. You can use mongo shell to connect to `localhost:27023` w/o replicaSet=rs0, `mongodb://localhost:27023/myproject`, and issue command `rs.isMaster()`. The result will show `ismaster: false` but also has the other hosts info. The nodeJS driver source codes is https://github.com/mongodb/node-mongodb-native. – simagix Apr 29 '19 at 15:50