[JAVA-1801] impossible to get profile status from Secondary Created: 06/May/15  Updated: 06/May/15  Resolved: 06/May/15

Status: Closed
Project: Java Driver
Component/s: Command Operations, Documentation
Affects Version/s: 3.0.0
Fix Version/s: None

Type: Bug Priority: Major - P3
Reporter: Kay Agahd Assignee: Ross Lawley
Resolution: Done Votes: 0
Labels: driver, java
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

Linux 64 Bit


Issue Links:
Related
related to JAVA-1802 Improve runCommand API documentation Closed

 Description   

I can't get the profile status of a Secondary (s132) because the driver is looping and eventually times out:

2015-05-05 17:59:55,829 [main] INFO  org.mongodb.driver.cluster - No server chosen by PrimaryServerSelector from cluster description ClusterDescription{type=REPLICA_SET, connectionMode=SINGLE, all=[ServerDescription{address=s132:27017, type=REPLICA_SET_SECONDARY, state=CONNECTED, ok=true, version=ServerVersion{versionList=[2, 6, 4]}, minWireVersion=0, maxWireVersion=2, maxDocumentSize=16777216, roundTripTimeNanos=8836176, setName='offerStoreDE3', hosts=[s132:27017, s124:27017], passives=[], arbiters=[], primary='s124:27017', tagSet=TagSet{[]}}]}. Waiting for 30000 ms before timing out
2015-05-05 17:59:56,315 [cluster-ClusterId{value='5548e8fbf03cf20477e864a9', description='null'}-s132:27017] DEBUG org.mongodb.driver.cluster - Checking status of s132:27017
2015-05-05 17:59:56,324 [cluster-ClusterId{value='5548e8fbf03cf20477e864a9', description='null'}-s132:27017] DEBUG org.mongodb.driver.cluster - Updating cluster description to  {type=REPLICA_SET, servers=[{address=s132:27017, type=REPLICA_SET_SECONDARY, roundTripTime=8,8 ms, state=CONNECTED}]
2015-05-05 17:59:56,824 [cluster-ClusterId{value='5548e8fbf03cf20477e864a9', description='null'}-s132:27017] DEBUG org.mongodb.driver.cluster - Checking status of s132:27017
2015-05-05 17:59:56,834 [cluster-ClusterId{value='5548e8fbf03cf20477e864a9', description='null'}-s132:27017] DEBUG org.mongodb.driver.cluster - Updating cluster description to  {type=REPLICA_SET, servers=[{address=s132:27017, type=REPLICA_SET_SECONDARY, roundTripTime=8,9 ms, state=CONNECTED}]
2015-05-05 17:59:57,333 [cluster-ClusterId{value='5548e8fbf03cf20477e864a9', description='null'}-s132:27017] DEBUG org.mongodb.driver.cluster - Checking status of s132:27017
2015-05-05 17:59:57,343 [cluster-ClusterId{value='5548e8fbf03cf20477e864a9', description='null'}-s132:27017] DEBUG org.mongodb.driver.cluster - Updating cluster description to  {type=REPLICA_SET, servers=[{address=s132:27017, type=REPLICA_SET_SECONDARY, roundTripTime=8,8 ms, state=CONNECTED}]
2015-05-05 17:59:57,842 [cluster-ClusterId{value='5548e8fbf03cf20477e864a9', description='null'}-s132:27017] DEBUG org.mongodb.driver.cluster - Checking status of s132:27017

However, checking the profile status of the Primary (s124) works fine.

My java code is like this:

MongoClientOptions options = MongoClientOptions.builder().
                    connectTimeout(2000).
                    socketTimeout(10000).
                    readPreference(ReadPreference.secondaryPreferred()).
                    build();
MongoCredential mc = MongoCredential.createCredential("user", "db", "XXXX".toCharArray());
MongoClient mongo = new MongoClient(new ServerAddress("s132:27017"), Lists.newArrayList(mc), options);
MongoDatabase myDB = mongo.getDatabase("myDB");
 
BsonDocument bd = BsonDocument.parse("{profile:1}");
Bson bson = (Bson)bd;
Document doc = monitor.myDB.runCommand(bson); //loops until timeout
Object obj = doc.get("slowms");

In the mongo shell I can do the same without problems:

offerStoreDE3:SECONDARY> db.runCommand({profile:1})
{ "was" : 0, "slowms" : 100, "ok" : 1 }

The status of the replSet is as follows:

offerStoreDE3:SECONDARY> rs.status()
{
    "set" : "offerStoreDE3",
    "date" : ISODate("2015-05-05T16:09:47Z"),
    "myState" : 2,
    "syncingTo" : "s124:27017",
    "members" : [
        {
            "_id" : 7,
            "name" : "s124:27017",
            "health" : 1,
            "state" : 1,
            "stateStr" : "PRIMARY",
            "uptime" : 1400,
            "optime" : Timestamp(1430740008, 1),
            "optimeDate" : ISODate("2015-05-04T11:46:48Z"),
            "lastHeartbeat" : ISODate("2015-05-05T16:09:45Z"),
            "lastHeartbeatRecv" : ISODate("2015-05-05T16:09:47Z"),
            "pingMs" : 0,
            "electionTime" : Timestamp(1430840794, 1),
            "electionDate" : ISODate("2015-05-05T15:46:34Z")
        },
        {
            "_id" : 8,
            "name" : "s132:27017",
            "health" : 1,
            "state" : 2,
            "stateStr" : "SECONDARY",
            "uptime" : 1740,
            "optime" : Timestamp(1430740008, 1),
            "optimeDate" : ISODate("2015-05-04T11:46:48Z"),
            "self" : true
        }
    ],
    "ok" : 1
}

See also http://stackoverflow.com/questions/30058223/how-to-get-profile-status-from-secondary-using-mongodb-java-driver-3-0-0



 Comments   
Comment by Kay Agahd [ 06/May/15 ]

Great, that makes it clear! It just needs to be added to the docs. Thanks!

Comment by Ross Lawley [ 06/May/15 ]

Excellent, you're correct it doesn't use the readPreference from the MongoClientOptions for runCommand.

Where the commands are run are based on if a read preference is supplied:

method read preference use case
runCommand(Bson command) primary run write commands.
eg. create index, create collection, drop collection etc..
runCommand(Bson command, ReadPreference readPreference) as supplied run read commands.
eg dbstats, profile, ismaster etc..

I hope that clarifies the situation, as this behaviour is the intended behaviour I'm marking this ticket as "works as designed". However, because the javadocs aren't clear I have added JAVA-1802 to ensure they are updated and the intended use cases are clarified.

Comment by Kay Agahd [ 06/May/15 ]

Thanks Ross, but ReadPreference.secondaryPreferred() is already passed by the MongoClientOptions. Is this ignored?
In any case, your suggestion works!

Comment by Ross Lawley [ 06/May/15 ]

Hi kay.agahd@idealo.de,

The runCommand(bson); will always direct the command to the primary node as it expects a write command.

For explicit read commands can must supply the read preference, for example:

Document doc = myDB.runCommand(bson, ReadPreference.secondaryPreferred());

Comment by Kay Agahd [ 06/May/15 ]

I made a typo. Instead of

Document doc = monitor.myDB.runCommand(bson); //loops until timeout

it should be

Document doc = myDB.runCommand(bson); //loops until timeout


The problem remains the same of course.

Generated at Thu Feb 08 08:55:31 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.