May be I found a cursor bug in MongoDB.
I use the newest java-7-openjdk-amd64 on a Ubuntu 13.04 machine.
MongoDB has version 2.4.6
In addition I use spring-data-mongodb 1.3.1 with mongo-java-driver 2.10.1
My Query is { "EMPID" : { "$ne" : "" }}.
There are 1929 records in my Database.
The code that handles this query is
final MongoConverter converter = mongoTemplate.getConverter();
final DBCollection coll = mongoTemplate.getCollection(typeRepository.getCollectionName(type));
final DBCursor cursor = coll.find(parseQuery(handler.query()), prepareFields(handler.fields()));
try {
handler.start();
handler.setCount(cursor.count());
cursor.skip(handler.skip());
cursor.limit(handler.limit());
if (handler.sort() != null) {
cursor.sort(buildSort(handler.sort()));
}
int count = 0;
while (cursor.hasNext()) {
final DBObject obj = cursor.next();
if (!handler.handle(converter.read(GenericObject.class, obj))) {
log.info("stop further processing of generic objects cause handler returns false");
break;
}
count++;
log.debug("Wrote {} of {} records to handler.", count, cursor.count());
}
log.debug("Explain MongoDB query: {}", cursor.explain());
} catch (final MongoException e) {
throw new ServiceException(400, e.getMessage());
} finally {
cursor.close();
handler.stop();
}
When the bug occurs, the cursor has 11 Entries, but writes 25 to the handler.
2013-10-11 10:07:46,065 DEBUG d.p.f.s.mongodb.ObjectRepository - Wrote 25 of 11 records to handler.
2013-10-11 10:07:46,103 DEBUG d.p.f.s.mongodb.ObjectRepository - Explain MongoDB query: { "cursor" : "BtreeCursor EMPID_1 multi" , "isMultiKey" : false , "n" : 25 , "nscannedObjects" : 11 , "nscanned" : 12 , "nscannedObjectsAllPlans" : 49 , "nscannedAllPlans" : 51 , "scanAndOrder" : true , "indexOnly" : false , "nYields" : 0 , "nChunkSkips" : 0 , "millis" : 1 , "indexBounds" : { "EMPID" : [ [ { "$minElement" : 1} , ""] , [ "" , { "$maxElement" : 1}]]} , "allPlans" : [ { "cursor" : "BtreeCursor EMPID_1 multi" , "n" : 11 , "nscannedObjects" : 11 , "nscanned" : 12 , "indexBounds" : { "EMPID" : [ [ { "$minElement" : 1} , ""] , [ "" , { "$maxElement" : 1}]]}} , { "cursor" : "BtreeCursor EMPID_-1 multi" , "n" : 12 , "nscannedObjects" : 12 , "nscanned" : 13 , "indexBounds" : { "EMPID" : [ [ { "$maxElement" : 1} , ""] , [ "" , { "$minElement" : 1}]]}} , { "cursor" : "BtreeCursor EMPID_1_LASTNAME_1_FIRSTNAME_1_modified_1 multi" , "n" : 13 , "nscannedObjects" : 13 , "nscanned" : 13 , "indexBounds" : { "EMPID" : [ [ { "$minElement" : 1} , ""] , [ "" , { "$maxElement" : 1}]] , "LASTNAME" : [ [ { "$minElement" : 1} , { "$maxElement" : 1}]] , "FIRSTNAME" : [ [ { "$minElement" : 1} , { "$maxElement" : 1}]] , "modified" : [ [ { "$minElement" : 1} , { "$maxElement" : 1}]]}} , { "cursor" : "BasicCursor" , "n" : 13 , "nscannedObjects" : 13 , "nscanned" : 13 , "indexBounds" : { }}] , "oldPlan" : { "cursor" : "BtreeCursor EMPID_1 multi" , "indexBounds" : { "EMPID" : [ [ { "$minElement" : 1} , ""] , [ "" , { "$maxElement" : 1}]]}} , "server" : "vlmucext07:27017"}
2013-10-11 10:07:46,103 WARN d.p.feeder.web.ObjectController - Something goes really wrong: Count: 11, Entries: 25
Retry!
So the cursor delivers more entries, then itself counts...
It fills to the limit of 25 that we use for pagination.
My Workaround is, to check for this problem, and send the query a second time immediately.
Now the Last log is:
2013-10-11 10:07:46,538 DEBUG d.p.f.s.mongodb.ObjectRepository - Wrote 11 of 11 records to handler.
2013-10-11 10:07:46,577 DEBUG d.p.f.s.mongodb.ObjectRepository - Explain MongoDB query: { "cursor" : "BtreeCursor EMPID_1 multi" , "isMultiKey" : false , "n" : 25 , "nscannedObjects" : 11 , "nscanned" : 12 , "nscannedObjectsAllPlans" : 49 , "nscannedAllPlans" : 51 , "scanAndOrder" : true , "indexOnly" : false , "nYields" : 0 , "nChunkSkips" : 0 , "millis" : 1 , "indexBounds" : { "EMPID" : [ [ { "$minElement" : 1} , ""] , [ "" , { "$maxElement" : 1}]]} , "allPlans" : [ { "cursor" : "BtreeCursor EMPID_1 multi" , "n" : 11 , "nscannedObjects" : 11 , "nscanned" : 12 , "indexBounds" : { "EMPID" : [ [ { "$minElement" : 1} , ""] , [ "" , { "$maxElement" : 1}]]}} , { "cursor" : "BtreeCursor EMPID_-1 multi" , "n" : 12 , "nscannedObjects" : 12 , "nscanned" : 13 , "indexBounds" : { "EMPID" : [ [ { "$maxElement" : 1} , ""] , [ "" , { "$minElement" : 1}]]}} , { "cursor" : "BtreeCursor EMPID_1_LASTNAME_1_FIRSTNAME_1_modified_1 multi" , "n" : 13 , "nscannedObjects" : 13 , "nscanned" : 13 , "indexBounds" : { "EMPID" : [ [ { "$minElement" : 1} , ""] , [ "" , { "$maxElement" : 1}]] , "LASTNAME" : [ [ { "$minElement" : 1} , { "$maxElement" : 1}]] , "FIRSTNAME" : [ [ { "$minElement" : 1} , { "$maxElement" : 1}]] , "modified" : [ [ { "$minElement" : 1} , { "$maxElement" : 1}]]}} , { "cursor" : "BasicCursor" , "n" : 13 , "nscannedObjects" : 13 , "nscanned" : 13 , "indexBounds" : { }}] , "oldPlan" : { "cursor" : "BtreeCursor EMPID_1 multi" , "indexBounds" : { "EMPID" : [ [ { "$minElement" : 1} , ""] , [ "" , { "$maxElement" : 1}]]}} , "server" : "vlmucext07:27017"}
As far as I see, the explains are equal.
The Problem happens from time to time, but I can reproduce it after MongoDB restart and Jetty Restart.
Is there a bug or is it my fault?
Regards