Parfois, les opérations deviennent incontrôlables dans MongoDB et peuvent finir par s'exécuter pendant des centaines de secondes, et affecter les performances jusqu'à ce qu'elles soient tuées ou terminées.
Lorsque cela se produit, je sais que j'ai killOp()
à ma disposition, mais comment puis-je tuer uniquement les opérations de longue durée ciblées sans tuer également (par exemple) les opérations de longue durée impliquées dans la réplication ( qui peut être dangereux)?
Cela peut être un peu délicat, mais le fait que le shell MongoDB soit fondamentalement un interpréteur Javascript nous donne des options décentes en termes de filtrage. Voici la fonction que j'utilise pour y parvenir:
// 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);
}
}
};
Cela ne tuera que les requêtes au-dessus du seuil maxSecsRunning
et ne touchera rien qui s'exécute sur la base de données local
, où se trouve la oplog
(et donc la base de données impliquée dans les opérations de réplication à long terme. Il est relativement facile d'ajouter des critères au if
interne conditionnel pour cibler plus précisément les opérations selon les besoins en fonction des besoins spécifiques.
Le code est également disponible sous la forme a Gist (où je me souviendrai de le mettre à jour régulièrement).