¿Cómo mato (con seguridad) las operaciones de larga duración en MongoDB?

11

Ocasionalmente, las operaciones se descontrolan en MongoDB y pueden terminar ejecutándose durante cientos de segundos e impactar el rendimiento hasta que se eliminen o se completen.

Cuando eso suceda, sé que tengo killOp()a mi disposición, pero ¿cómo mato solo las operaciones de ejecución prolongada sin también matar (por ejemplo) las operaciones de ejecución prolongada involucradas en la replicación (que puede ser peligroso)?

Adam C
fuente

Respuestas:

15

Esto puede ser un poco complicado, pero el hecho de que el shell MongoDB sea básicamente un intérprete de Javascript nos da opciones decentes en términos de filtrado. Aquí está la función que uso para lograr esto:

// 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);
        }
    }
};

Esto solo eliminará las consultas por encima del maxSecsRunningumbral y no tocará nada que se ejecute contra la localbase de datos, que es donde oplogvive (y, por lo tanto, es la base de datos que participa en las operaciones de replicación de larga ejecución. Es relativamente fácil agregar criterios al ifcondicional interno para dirigir con mayor precisión las operaciones según sea necesario en función de necesidades específicas.

El código también está disponible como una esencia (donde recordaré actualizarlo de forma continua).

Adam C
fuente
He visto varios guiones para este. Sin embargo, verificar si la operación se ejecuta en la base de datos local es una buena mejora.
joao
sí, he dado esto en numerosas ocasiones y vi una publicación de blog con un guión muy peligroso para matar operaciones, así que pensé en darme una versión agradable y fácilmente enlazable
Adam C
3
Creo que este es un script peligroso al menos cuando se usan conjuntos de réplicas. La ejecución db.currentOp()en nuestra base de datos fragmentada devuelve operaciones en el "" espacio de nombres (también conocido como ns: "") que se ejecutan durante mucho tiempo con un desc de "repl writer worker n" (donde n es un número entero). Sugeriría incluir en la lista blanca los espacios de nombres a sus bases de datos reales con consultas que desee eliminar. Algo parecido en && (['users', 'analytics'].indexOf(op.ns) != -1)lugar de la !op.ns.startsWithcondición.
runamok
Buen punto, y es completamente posible que el espacio de nombres en blanco ocurra con mayor frecuencia en las versiones más nuevas: originalmente tenía la intención de mantener el script actualizado, pero ahora he dejado MongoDB, por lo que es poco probable que tenga miedo. Si envía su código actualizado (con una nota de que se aplica a versiones posteriores) aquí como respuesta, felizmente lo votaré :)
Adam C