4

I wish to run mongodump to secondary (not primary). So I need as output hostname and port of one secondary.

# ./mongo  -udbadm admin --port 27100 -p --quiet --eval "printjson(rs.status().members.map(function(m) { return {'name':m.name, 'stateStr':m.stateStr} }))"
Enter password: 
[
        {
                "name" : "example-1.domain:27200",
                "stateStr" : "SECONDARY"
        },
        {
                "name" : "example-2.domain:27200",
                "stateStr" : "PRIMARY"
        },
        {
                "name" : "example-3.domain:27200",
                "stateStr" : "SECONDARY"
        }
]

With shell script tools is no problem for me to extract one secondary with hostname and port. My question howto do this job the MongoDB way? What tools do you recommend me? I heard that jq is better for JSON data. But don't know howto extract only one secondary host.

3 Answers 3

5

It's worth noting that if you pass in a replicaset string into mongodump it defaults to reading from a secondary from the set (note: in 3.0.5+ this is not the case if you connect to a mongos in a sharded cluster). If your replica set name was repl1 it would be something like:

./mongodump --host repl1/example-1.domain:27200,example-2.domain:27200 

For reference, in the more recent versions (since the tools were re-written in Go), this is done by setting Monotonic mode when not connected to a mongos (source from 3.0.6 here).

To answer your specific question, a really simple way to parse rs.status() is with a filter, and it will fit on one line:

rs.status().members.filter(function(rsStatus) { return rsStatus.state === 2;})[0].name 

That will return the name field of the first (hence [0]) secondary (state === 2) found in the array of members returned by rs.status()

4
  • Except for the change of for 3.0.5, this behavior seems to be undocumented. Is this worth a ticket? Sep 8, 2015 at 21:23
  • It used to be documented I am pretty sure (though I can't dig it up now). Given some of the comments in the tickets, it seems it may not yet be final that secondary is the default, but it has been that way for some time. It is implied by the note about the behavior when connected to the mongos, but not explicitly stated, so probably worth a DOCS ticket
    – Adam C
    Sep 8, 2015 at 21:35
  • "If the string passed to --host is prefixed by the replica set name, mongodump reads from the primary" seems to have changed since then
    – caub
    Sep 10, 2018 at 19:23
  • The tools have been completely rewritten in Go since this, and there have been several major versions released, so I expect many things have changed
    – Adam C
    Sep 10, 2018 at 20:36
1

No need to use another tool, you could just:

./mongo  -udbadm admin --port 27100 -p --quiet --eval "rs.status().members.find((m) => m.stateStr === "SECONDARY").name"

to get:

example-1.domain:27200

Note that the find method will return the first element found.

0

Something like this will give you 1 secondary:

# ./mongo  -udbadm admin --port 27100 -p --quiet --eval "var i=0; rs.status().members.forEach( function(myDoc) { if (myDoc.stateStr=='SECONDARY' && i==0) { print(myDoc.name); i++;} })"

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.