Как (безопасно) убить длительные операции в MongoDB?


11

Иногда операции выходят из-под контроля в MongoDB и могут заканчиваться выполнением в течение сотен секунд, и влияют на производительность, пока они не будут уничтожены или завершены.

Когда это происходит, я знаю, что у меня есть в killOp()наличии, но как убить только целевые длительные операции, не убивая (например) длительные операции, связанные с репликацией (что может быть опасно)?

Ответы:


15

Это может быть немного сложно, но тот факт, что оболочка MongoDB является в основном интерпретатором Javascript, дает нам достойные варианты с точки зрения фильтрации. Вот функция, которую я использую для достижения этой цели:

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

Это убьет только запросы, превышающие maxSecsRunningпороговое значение, и не коснется ничего, работающего с localбазой данных, которая находится там, где oplogживет (и, следовательно, является базой данных, которая участвует в длительных операциях репликации. Относительно легко добавить критерии к внутреннему ifусловному условию). более точно нацеливать операции по мере необходимости на основе конкретных потребностей.

Код также доступен в виде суть (где я буду помнить, чтобы обновить его на постоянной основе).


Я видел несколько сценариев для этого. Тем не менее, проверка того, выполняется ли операция с локальной базой данных, является хорошим улучшением.
Joao

да - я рассказывал об этом много раз и видел сообщение в блоге с очень опасным сценарием для убийства ops, так что подумал, что дам себе хорошую и легко связываемую версию
Адам С

3
Я считаю, что это опасный сценарий, по крайней мере, при использовании репликаций. Запуск db.currentOp()в нашей защищенной базе данных возвращает операции в «» пространстве имен (aka ns: »), которые очень долго выполняются с деск« repl writer worker n »(где n - целое число). Я хотел бы предложить занести в белый список пространства имен для ваших реальных баз данных с запросами, которые вы, возможно, захотите убить. Нечто подобное && (['users', 'analytics'].indexOf(op.ns) != -1)вместо !op.ns.startsWithсостояния.
runamok

Хорошая мысль, и вполне возможно, что пустое пространство имен чаще встречается в новых версиях - я изначально намеревался поддерживать скрипт в актуальном состоянии, но сейчас я оставил MongoDB, так что я вряд ли боюсь. Если вы отправите свой обновленный код (с пометкой, что он применим к более поздним версиям) здесь в качестве ответа, я с радостью проголосую за вас :)
Адам С
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.