Como eu (com segurança) mato operações de execução longa no MongoDB?

11

Ocasionalmente, as operações ficam fora de controle no MongoDB e podem terminar em execução por centenas de segundos, afetando o desempenho até que sejam eliminadas ou concluídas.

Quando isso acontece, eu sei que tenho killOp()disponível, mas como eu mato apenas operações de longa duração direcionadas sem também matar (por exemplo) as operações de longa duração envolvidas na replicação (o que pode ser perigoso)?

Adam C
fonte

Respostas:

15

Isso pode ser um pouco complicado, mas o fato de o shell do MongoDB ser basicamente um interpretador Javascript nos oferece opções decentes em termos de filtragem. Aqui está a função que eu uso para fazer isso:

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

Isso mata apenas as consultas acima do maxSecsRunninglimite e não toca em nada em execução no localbanco de dados, que é onde estão as oplogvidas (e, portanto, é o banco de dados envolvido nas operações de replicação de longa execução. É relativamente fácil adicionar critérios à ifcondicional interna direcionar com mais precisão as operações conforme necessário, com base em necessidades específicas.

O código também está disponível como uma essência (onde eu lembrarei de atualizá-lo continuamente).

Adam C
fonte
Eu já vi vários scripts para este. No entanto, verificar se a operação está sendo executada no banco de dados local é uma boa melhoria.
João
sim - eu dei isso inúmeras vezes, e vi um post com um script muito perigoso para matar ops, então pensei que eu iria me dar um agradável e versão facilmente linkable
Adam C
3
Acredito que este seja um script perigoso pelo menos ao usar replicasets. A execução db.currentOp()em nosso banco de dados sharded retorna operações no espaço de nome "" (também conhecido como ns: "") que são executadas por muito tempo com uma descrição de "repl writer worker n" (onde n é um número inteiro). Eu sugeriria colocar os namespaces nos seus bancos de dados reais na lista de permissões com consultas que você pode querer matar. Algo como, em && (['users', 'analytics'].indexOf(op.ns) != -1)vez da !op.ns.startsWithcondição.
precisa saber é
Bom ponto, e é perfeitamente possível que o espaço para nome em branco ocorra com mais frequência em versões mais recentes - eu pretendia originalmente manter o script atualizado, mas agora deixei o MongoDB, portanto é improvável que eu tenha medo. Se você enviar seu código atualizado (com uma nota que ela se aplica a versões posteriores) aqui como uma resposta Eu ficaria feliz em votar lo :)
Adam C