[SERVER-4193] Cursor closed if limit is 1 Created: 02/Nov/11  Updated: 01/Aug/19  Resolved: 30/Apr/12

Status: Closed
Project: Core Server
Component/s: Sharding
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Major - P3
Reporter: Alex Yakushev Assignee: Antoine Girbal
Resolution: Cannot Reproduce Votes: 6
Labels: cursor, query
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

any


Operating System: ALL
Participants:

 Description   

If limit is 1, and batchsize is 0, DBApiLayer.chooseBatchSize will return -1, and the cursor will be closed as a result.

in DBApiLayer.chooseBatchSize, I see
if (res == 1)

{ // optimization: use negative batchsize to close cursor res = -1; }

Code to replicate
I have 4 entries in the collection

DB m = Mongo.connect(new DBAddress("host", "dbname"));

DBCursor c1 = m.getCollection("mycoll").find();
int count1 = 0;
while (c1.hasNext())

{ c1.next(); count1++; }

System.out.println("Count 1 is: " + count1);

DBCursor c2 = m.getCollection("buttons").find().skip(2).limit(1);
int count2 = 0;
while (c2.hasNext())

{ c2.next(); count2++; }

System.out.println("Count 2 is: " + count2);

Output:
Count 1 is: 4
Count 2 is: 0



 Comments   
Comment by Antoine Girbal [ 30/Apr/12 ]

tried again, could not reproduce issue through Java driver with mongo 2.0.2.
Are you still seeing issue with more recent mongo?
In theory the java optimization is good to keep.

Comment by Spencer Brody (Inactive) [ 29/Nov/11 ]

I could not reproduce this in the shell or with pymongo, and given that changing an optimization in the java driver fixed the issue, I think this likely is an issue with the java driver, as was originally expected. Antoine, could you take another look and see if you can reproduce it on a sharded system?

Comment by Alex Yakushev [ 04/Nov/11 ]

Server version 1.8.4 has the same problem

Comment by Alex Yakushev [ 02/Nov/11 ]

Removing the optimization that I mentioned in the description from DBApiLayer.chooseBatchSize seems to fix the issue.

Comment by Alex Yakushev [ 02/Nov/11 ]

Server version is 1.8.3

Comment by Scott Hernandez (Inactive) [ 02/Nov/11 ]

What server version are you using? This probably has nothing to do with java.

Comment by Alex Yakushev [ 02/Nov/11 ]

Just discovered that the bug shows up only for sharded collections
Shell commands always work correctly.

> db.runCommand(

{enablesharding: "alex-test"}

)

{ "ok" : 1 }

> db.runCommand({shardcollection:"alex-test.buttons", key: {_id:1}})

{ "collectionsharded" : "alex-test.buttons", "ok" : 1 }

> use alex-test
switched to db alex-test
> db.buttons.find()

{ "_id" : ObjectId("4eb1025141dadce09bc24fb0"), "a" : 1 } { "_id" : ObjectId("4eb1025441dadce09bc24fb1"), "a" : 2 } { "_id" : ObjectId("4eb1025641dadce09bc24fb2"), "a" : 3 } { "_id" : ObjectId("4eb1025841dadce09bc24fb3"), "a" : 4 }

> db.buttons.find().skip(2).limit(1)

{ "_id" : ObjectId("4eb1025641dadce09bc24fb2"), "a" : 3 }

Output of my test java code: (using mongo-2.7.0-rc1.jar)
Count 1 is: 4
Count 2 is: 0

Running the same code on an unsharded collection:
> db.fingers.find()

{ "_id" : ObjectId("4eb103bb41dadce09bc24fb4"), "b" : 1 } { "_id" : ObjectId("4eb103bd41dadce09bc24fb5"), "b" : 2 } { "_id" : ObjectId("4eb103c041dadce09bc24fb6"), "b" : 3 } { "_id" : ObjectId("4eb103c341dadce09bc24fb7"), "b" : 4 }

> db.fingers.find().skip(2).limit(1)

{ "_id" : ObjectId("4eb103c041dadce09bc24fb6"), "b" : 3 }

Java output:
Count 1 is: 4
Count 2 is: 1

Comment by Antoine Girbal [ 02/Nov/11 ]

ok that's odd, it works fine for me using 2.7 beta driver
Collection:
Cursor id=0, ns=test.test, query={ }, numIterated=4, addr=localhost:27001
{ "_id" :

{ "$oid" : "4eb0d931276e8a923b13aceb"}

, "a" : 1.0}
{ "_id" :

{ "$oid" : "4eb0d932276e8a923b13acec"}

, "a" : 1.0}
{ "_id" :

{ "$oid" : "4eb0d932276e8a923b13aced"}

, "a" : 1.0}
{ "_id" :

{ "$oid" : "4eb0d933276e8a923b13acee"}

, "a" : 1.0}

If I query with your options:
Cursor id=0, ns=test.test, query={ }, numIterated=1, skip=2, limit=1, addr=localhost:27001
{ "_id" :

{ "$oid" : "4eb0d932276e8a923b13aced"}

, "a" : 1.0}

could you try with the driver from git HEAD?
could you display result of both db.buttons.find() and db.buttons.find().skip(2).limit(1) from shell?

Comment by Alex Yakushev [ 02/Nov/11 ]

I tried to change my silly db and collection names when I posted this example. Alas, now my secret is out, I was querying the "buttons" collection in both cases.

It works when skip =0. With skip >0, it returns an empty cursor.

Comment by Antoine Girbal [ 02/Nov/11 ]

I am not seeing this bug.
In your test, the 2nd find() queries a different collection, maybe there is nothing in it?
limit(1) is optimized to limit(-1) since a single doc always fits in a batch, and cursor should be closed.

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