Come posso uccidere (in modo sicuro) operazioni di lunga durata in MongoDB?


11

Occasionalmente le operazioni sfuggono al controllo in MongoDB e potrebbero finire in esecuzione per centinaia di secondi e influire sulle prestazioni fino a quando non vengono uccise o completate.

Quando ciò accade, so di avere a killOp()disposizione me, ma come posso uccidere solo operazioni di lunga durata mirate senza anche uccidere (ad esempio) le operazioni di lunga durata coinvolte nella replica (che può essere pericoloso)?

Risposte:


15

Questo può essere un po 'complicato, ma il fatto che la shell MongoDB sia fondamentalmente un interprete Javascript ci offre opzioni decenti in termini di filtro. Ecco la funzione che uso per realizzare questo:

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

Questo ucciderà solo le query al di sopra della maxSecsRunningsoglia e non toccherà nulla in esecuzione sul localdatabase, che è dove oplogvivono (e quindi è il database che è coinvolto nelle operazioni di replica a lungo termine. È relativamente facile aggiungere criteri al ifcondizionale interno indirizzare più precisamente le operazioni secondo necessità in base a esigenze specifiche.

Il codice è disponibile anche come sintesi (dove ricorderò di aggiornarlo su base continuativa).


Ho visto diversi script per questo. Tuttavia, verificare se l'operazione è in esecuzione sul database locale è un bel miglioramento.
Joao

sì - l'ho dato molte volte e ho visto un post sul blog con una sceneggiatura molto pericolosa per uccidere operazioni, quindi ho pensato di darmi una versione piacevole e facilmente collegabile
Adam C

3
Credo che questo sia uno script pericoloso almeno quando si usano replicaset. L'esecuzione db.currentOp()sul nostro database frammentato restituisce operazioni nello "" spazio dei nomi (alias ns: "") che sono molto lunghe con una descrizione di "sostituire il writer n" (dove n è un numero intero). Suggerirei di inserire nella whitelist gli spazi dei nomi nei database reali con query che potresti voler eliminare. Qualcosa di simile && (['users', 'analytics'].indexOf(op.ns) != -1)invece della !op.ns.startsWithcondizione.
Runamok,

Un buon punto, ed è del tutto possibile che lo spazio dei nomi vuoto si verifichi più frequentemente nelle versioni più recenti: inizialmente intendevo mantenere aggiornato lo script, ma ora ho lasciato MongoDB, quindi è improbabile che temo. Se invii il tuo codice aggiornato (con una nota che si applica alle versioni successive) qui come risposta, ti voterò felicemente :)
Adam C
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.