[SERVER-18128] Replica set secondary allows rs.initiate() while performing initial sync Created: 20/Apr/15  Updated: 20/Apr/15  Resolved: 20/Apr/15

Status: Closed
Project: Core Server
Component/s: Replication
Affects Version/s: 2.4.11, 2.6.8, 3.0.1
Fix Version/s: None

Type: Bug Priority: Major - P3
Reporter: Eric Sommer Assignee: Unassigned
Resolution: Done Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Attachments: Text File mongod.debug.log    
Issue Links:
Related
Operating System: ALL
Steps To Reproduce:

See above.

Participants:

 Description   

Scenario:

Create RS with two data nodes (A,B) and an arbiter.
Give A priority 2, B priority 1 -> A becomes primary
Kill A process -> B (with lower priority) becomes primary
Delete all data files from A
Connect to B and add data:

for (var i = 1; i <= 200000; i++) { db.testData.insert( { x : i } ) }
db.copyDatabase("test", "test1” )
db.copyDatabase("test", "test2” )
etc.

The idea is to make initial sync take some time.

Start A process as follows:

mongod --replSet replset --dbpath <path> --logpath <path>/mongod.log --port <port> --logappend --fork ; mongo --port <port> --eval "printjson(rs.initiate())"

This will start A, which will come up and start initial sync. rs.initiate() command will run while initial sync is taking place. Command should fail, but it will succeed.

mongod --replSet replset --dbpath /Users/ericsommer/data/301rs/replset/rs2/db --logpath /Users/ericsommer/data/301rs/replset/rs2/mongod.log --port 30001 --logappend --fork ; mongo --port 30001 --eval "printjson(rs.initiate())"
about to fork child process, waiting until server is ready for connections.
forked process: 7005
child process started successfully, parent exiting
MongoDB shell version: 3.0.1
connecting to: 127.0.0.1:30001/test
{
	"info2" : "no configuration explicitly specified -- making one",
	"me" : "Erics-MBP.home:30001",
	"ok" : 1
}

Command doesn’t succeed if:

  • mongod reaches secondary state before rs.initiate() is called
  • with default priorities

See attached log mongodb.debug.log from node A.

Customer found bug in 2.4.11. Tested with 3.0.1 and 2.6.8 – same behavior.



 Comments   
Comment by Eric Milkie [ 20/Apr/15 ]

There is no way to know, because at startup the node has no config, so whatever tells it the config first is what wins.
Conceivably, we could add some new command line parameters that would tell it to ignore initiate() commands, but this would reduce flexibility and add complication.
The problem you describe is fairly narrow in scope: it requires that the user run the rs.initiate() shell helper with no parameters, in a script, combined with the startup of the mongod binary. Since this is a fairly imperative thing to do (I can't think of a good use case for someone doing this, unless they really wanted to have one-node replica sets not suitable for production use), it is hard to "second-guess" such an action by putting in roadblocks.

Comment by Eric Sommer [ 20/Apr/15 ]

I was only differentiating between before and after it went into SECONDARY state. I was referring to before-SECONDARY as "during initial sync". But I see what you're saying. So this did occur during that period you describe "where the node has no configuration and will thus respond to initiate requests."

Does that mean there's no way to prevent a rs.initiate() during that period?

Comment by Eric Milkie [ 20/Apr/15 ]

Hi Eric,
I don't see in the attached log where the node ran initial sync as you claim. I should note that initial sync does not immediately occur after node startup; there is a period of time where the node has no configuration and will thus respond to initiate requests.

Generated at Thu Feb 08 03:46:39 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.