1

I'm having some trouble to understand how replicaSet works using 2 nodes and a arbiter, using MongoDB 6 community in 3 servers with ubuntu 22.04.

My actual scenario is I have 2 servers in a replicaSet where first is primary (priority 1) and a secondary with priority 0.5 (I had set up like that, so I could always have primary as the main server). A third server do not store any data working as arbiter.

I tested turning off my primary, so my secondary was elected as primary with no problem. But if I try to write any data on it, he doesn't save until my primary comes back.

The idea is to have my secondary as a spare server in case my primary fails for any reason, so my apps could keep saving and reading.

I know I could use 3 nodes of server, so I would have 2 writable servers to vote, mas considering this database will have about 1TB of data, I can't have a third server saving the same amount o data for now.

I tried some commands about the write concern, but I had two different behaviours:

1 - Using this command, using mongodb Compass, seems to write new data, but it's not listed until the primary comes back:

db.adminCommand({ "setDefaultRWConcern": 1, "defaultWriteConcern": { "w": 1 } })

2 - Using mongodb Compass, show "Iinserting Document", but never finish, until primary comes back:

db.adminCommand({ "setDefaultRWConcern": 1, "defaultWriteConcern": { "w": "majority" } })

Update on how connected: Via an PHP application, using ssh with mongosh MongoDB Compass with connection string (with help from Wernfried): mongodb://rootuser:rootpasswd@primaryip:27017,secondaryip:27017/?replicaSet=myRepl&authSource=admin&readPreference=primaryPreferred

If I turn off my primary server, the secondary is elected as primary, but I cannot write until both nodes are online.

That's how my rs.conf() looks right now

{
   _id: 'rspd01',
   version: 13,
   term: 51,
   members: [
     {
        _id: 0,
        host: 'primaryIP:27017',
        arbiterOnly: false,
        buildIndexes: true,
        hidden: false,
        priority: 1,
        tags: {},
        secondaryDelaySecs: Long("0"),
        votes: 1
     },
     {
        _id: 1,
        host: 'secondaryIP:27017',
        arbiterOnly: false,
        buildIndexes: true,
        hidden: false,
        priority: 0.5,
        tags: {},
        secondaryDelaySecs: Long("0"),
        votes: 1
     },
     {
        _id: 2,
        host: 'arbiterIP:27017',
        arbiterOnly: true,
        buildIndexes: true,
        hidden: false,
        priority: 0,
        tags: {},
        secondaryDelaySecs: Long("0"),
        votes: 1
     }
   ],
   protocolVersion: Long("1"),
   writeConcernMajorityJournalDefault: true,
   settings: {
      chainingAllowed: true,
      heartbeatIntervalMillis: 2000,
      heartbeatTimeoutSecs: 10,
      electionTimeoutMillis: 10000,
      catchUpTimeoutMillis: -1,
      catchUpTakeoverDelayMillis: 30000,
      getLastErrorModes: {},
      getLastErrorDefaults: { w: 1, wtimeout: 0 },
      replicaSetId: ObjectId("64863fd09a9b54d4cd0da913")
   }
}

There's any command I can make to work with this structure?

Best regards.

7
  • How do you connect to the replica set? Try with option readPreference=primaryPreferred Jun 12, 2023 at 15:03
  • To insert I'm trying using mongodb Compass or via ssh using mongosh, after autenticate I try with db.dados.insertOne({"name": "test123"}) . Tried to change readPreference using db.getMongo().setReadPref("primary") but no result.
    – Rafael
    Jun 12, 2023 at 17:04
  • What is your connection string? I suggested primaryPreferred, not primary Jun 12, 2023 at 17:56
  • Sorry, I tried with setReadPref with primaryPreferred too, I usually just connect via ssh typing mongosh then use admin and db.auth("user", "password") in mongodb Compass I also tried using this connection string mongodb://rootuser:rootpasswd@secondaryip:27017/?authMechanism=DEFAULT&authSource=admin&readPreference=primaryPreferred
    – Rafael
    Jun 12, 2023 at 19:52
  • You should list all replica set members (because usually you don't know whether all servers are up and running) and you must connect to the replica set, i.e. mongodb://rootuser:rootpasswd@primaryip:27017,secondaryip:27017/?replicaSet=myRepl&authSource=admin&readPreference=primaryPreferred See Connection String URI Format Jun 12, 2023 at 20:26

1 Answer 1

1

Note, in MongoDB you have two different majorities.

  • One majority applies to elect a PRIMARY, in your case all three members are counted, i.e. if one member is not available then you still have the majority available.

  • The other majority applies to write data, in your case only the two data bearing notes are counted. If one of them goes down then the majority is not available anymore - despite the fact that you have an ARBITER.

So, for a 3-member PSA replica set, the only meaningful RW concern is

db.adminCommand({ setDefaultRWConcern: 1, defaultWriteConcern: { w: 1 } }) 

Typically you run this command only once when you setup your MongoDB.

Be aware, some commands (e.g. rename a collection) enforce write concern { w: "majority" }, you cannot change it. Thus, the majority must be available when you like to run such commands. Otherwise, you need to demote the member which is not available to a non-voting member, i.e. change replica settings to { votes: 0, priority: 0}.

5
  • Thanks for that explanation, but even using those adminCommands, still don't write, if I do a ` db.dados.insertOne({"name": "test 123"}) ` returns { acknowledged: true, insertedIds { 0: ObjectId("648866849ad548e0d9ee4db7") } but still not saving until primary is back. There is no way to make it the secondary accept writing when primary is not available? I updated my question with my rs.conf()
    – Rafael
    Jun 13, 2023 at 12:54
  • No, you can never write into a SECONDARY. The command is executed successfully, how do you check whether it has been written? What do you get from rs.status()? Jun 13, 2023 at 13:01
  • But when my secondary is elected primary it shouldn't be able to write? If I make a find({}) it shows nothing from insert, only after the previous primary is back. I updated my question with my rs.status()
    – Rafael
    Jun 13, 2023 at 13:12
  • After election you must reconnect. Usually this happens automatically, provided you used proper readPreference You added rs.conf() to your question, not rs.status() Jun 13, 2023 at 14:07
  • Sorry, I misunderstood the rs.conf(). I had reconfigured all replicaSet and now works with no problem. Thank you very much for all the information
    – Rafael
    Jun 13, 2023 at 15:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.