10

Occasionally operations get out of control in MongoDB and might end up running for hundreds of seconds, and impact performance until they are killed or completed.

When that happens, I know I have killOp() available to me but how do I kill only targeted long running operations without also killing (for example) the long running operations involved in replication (which can be dangerous)?

14

This can be a little tricky, but the fact that the MongoDB shell is basically a Javascript interpreter gives us decent options in terms of filtering. Here is the function I use to accomplish this:

// kills long running ops in MongoDB (taking seconds as an arg to define "long")
// attempts to be a bit safer than killing all by excluding replication related operations
// and only targeting queries as opposed to commands etc.
killLongRunningOps = function(maxSecsRunning) {
    currOp = db.currentOp();
    for (oper in currOp.inprog) {
        op = currOp.inprog[oper-0];
        if (op.secs_running > maxSecsRunning && op.op == "query" && !op.ns.startsWith("local")) {
            print("Killing opId: " + op.opid
            + " running over for secs: "
            + op.secs_running);
            db.killOp(op.opid);
        }
    }
};

This will only kill queries above the maxSecsRunning threshold and will not touch anything running against the local database, which is where the oplog lives (and hence is the database that is involved in the long running replication ops. It is relatively easy to add criteria to the inner if conditional to more precisely target operations as needed based on specific needs.

The code is also available as a gist (where I will remember to update it on an ongoing basis).

  • I've seen several scripts for this one. Nevertheless, to check if the operation is running against the local database is a nice improvement. – joao Mar 3 '14 at 13:48
  • yeah - I have given this out numerous times, and saw a blog post with a very dangerous script for killing ops, so thought I would give myself a nice and easily linkable version – Adam C Mar 3 '14 at 15:44
  • 2
    I believe this is a dangerous script at least when using replicasets. Running db.currentOp() on our sharded database returns operations in the "" namespace (aka ns: "") that are very long running with a desc of "repl writer worker n" (where n is an integer). I would suggest whitelisting the namespaces to your actual databases with queries that you may want to kill. Something like && (['users', 'analytics'].indexOf(op.ns) != -1) instead of the !op.ns.startsWith condition. – runamok Aug 10 '15 at 17:26
  • Good point, and it's entirely possible that the blank namespace happens more frequently in newer versions - I originally intended to keep the script up to date, but I have now left MongoDB, so that is unlikely I am afraid. If you submit your updated code (with a note that it applies to later versions) here as an answer I will happily vote you up :) – Adam C Aug 10 '15 at 17:32

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.