MongoDB Cursors – Tracing the Origin of noTimeout Cursors

cursorsdebuggingmongodb

I'm currently managing a Mongo DB instance that has several applications using it. It's been accumulating noTimeout cursors, and, while it's easy enough to cull them if they start getting overwhelming, it's a waste of memory and I'd like to track down the culprit process.

Is there some way to view the origin of noTimeout cursors? Any information, whether it's the original query, the collection it's on, or even the data that's left over, would be immensely useful.

According to these docs, it appears that the only information I can get on the cursors is in db.serverStatus().metrics.cursor and includes only counts of the cursors, not any data about the individual cursors.

Is there a way to get additional information?

My apologies if this isn't appropriate for DBA, it didn't seem like the right kind of question for SO and seemed too dev focused for ServerFault. Please let me know if this is an issue.

Best Answer

I ended up using this command:

mongo --quiet --eval "var c=new Mongo();var o=[];db.adminCommand('listDatabases').databases.forEach(function(d){o=o.concat(c.getDB(d.name).currentOp(true).inprog.filter(function(d){return d.op=='query';}).map(function(d){return d.query;}));});o" > cursor.json

The expanded form of the actual js in there is

var conn = new Mongo();
var cursorInfo = [];
db.adminCommand('listDatabases').databases.forEach(function(d) {
    var database = conn.getDB(d.name)
    cursorInfo = cursorInfo.concat(database.currentOp(true).inprog.filter(function(d) {
                return d.op == 'query';
            }).map(function(d) {
                return d.query;
            }));
});
cursorInfo

The command will get the information from db.currentOp(true).inprog about current querying cursors for every db and save it into the file cursor.json.