1

I have these 3 commands:

  mongo cdt_prod_playground --host "mngdb-cbt-stg-01:27058" -u cdtprodplayground -p "x" --eval "db.${file%.*}.remove({})"
  mongo cdt_prod_playground --host "mngdb-cbt-stg-02:27058" -u cdtprodplayground -p "x" --eval "db.${file%.*}.remove({})" 
  mongo cdt_prod_playground --host "mngdb-cbt-stg-03:27058" -u cdtprodplayground -p "x" --eval "db.${file%.*}.remove({})"

I want to run them and stop when the first one succeeds. One way to do that I guess would be to them into an array and break out of the loop when the commands succeeds, but how do I do that?

(The reason is I need to do this is because I don't know which host is the replica set PRIMARY, so I just have to test it brute force, because I don't have the authorization to run rs.status().)

3

Instead of trying a command on all replica set members to figure out which one is the current primary, you should use a replica set connection string with your mongo command line. You can optionally include username and password credentials in the connection string instead of using separate command line parameters.

Example using the MongoDB 3.6.3 shell:

mongo "mongodb://USERNAME:PASSWORD@mngdb-cbt-stg-01:27058,mngdb-cbt-stg-02:27058/DATABASE?replicaSet=cdt_prod_playground" --eval "db.${file%.*}.remove({})"

You don't have to list all members of your replica set in the connection string. I used two in my example above as that should ensure discovering the primary in a three member replica set (which needs 2/3 voting members available to maintain a primary). The driver/client will determine the current members as long as you include the replicaSet name in the connection string and at least one of the members in the connection string is healthy.

See Connection String URI Format for a reference of available options.

Also note that calling db.collection.remove({}) will delete individual documents while maintaining the index definitions. If you have a significant amount of collection data to remove, it would be faster to call db.colellection.drop() and recreate any required indexes.

The reason is I need to do this is because I don't know which host is the replica set PRIMARY, so I just have to test it brute force, because I don't have the authorization to run rs.status()

If you need to discover the current primary programatically, you can use the isMaster command. This command is used by MongoDB drivers and clients (like the mongo shell) as part of the initial connection negotiation. When connected to a replica set member, the isMaster output includes primary and other details for current replica set state.

As at MongoDB 3.6 the isMaster command does not require authentication, since it is used to provide information that drivers/clients need for server discovery and negotiating an authenticated connection.

2

IIUC, you could join the lines with || if mongo returns non-zero on error. As described in man bash:

An OR list has the form

           command1 || command2

   command2 is executed if and only if command1 returns a non-zero exit status.  The return status of AND and OR lists is the exit status of the last command executed in the list.

I don't have mongo here but I can post an example succeeds.sh:

#!/usr/bin/env sh
nonexistent-command || \
echo a || \
echo b || \
echo c    

Run:

$ ./succeeds.sh
./succedds.sh: line 3: nonexistent-command: command not found
a

As you can see the script stops at a because it's the first command that has succeeded.

1
hostlist=(mngdb-cbt-stg-01:27058 mngdb-cbt-stg-02:27058 mngdb-cbt-stg-03:27058)
hostnum=0
set -u
/bin/false; while [[ 0 -ne $? ]]; do 
  mongo cdt_prod_playground --host "${hostlist[$hostnum]}" -u cdtprodplayground -p "x" --eval "db.${file%.*}.remove({})"
  hostnum=$((hostnum+1))
done
  • IMHO hostnum is redundant in this case. I'd substitute that while part with for host in "${hostlist[@]}"; do command "$host" && break; done – nxnev Mar 23 '18 at 20:13
  • A cat with many skins. – DopeGhoti Mar 23 '18 at 20:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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