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を殺すための非常に危険なスクリプトのブログ投稿を見たので、私は自分に素敵で簡単にリンクできるバージョンを与えようと思いました
Adam C

3
少なくともレプリカセットを使用する場合、これは危険なスクリプトだと思います。db.currentOp()シャードされたデータベースで実行すると、 ""ネームスペース(別名ns: "")で、 "repl writer worker n"(nは整数)のdescで非常に長時間実行される操作が返されます。強制終了したいクエリを使用して、実際のデータベースの名前空間をホワイトリストに登録することをお勧めします。状態の&& (['users', 'analytics'].indexOf(op.ns) != -1)代わりのようなもの!op.ns.startsWith
runamok

良い点、そして新しい名前空間では空白の名前空間がより頻繁に発生する可能性があります-私はもともとスクリプトを最新に保つことを意図していましたが、今はMongoDBを離れたので、恐らくそうではありません。更新されたコード(以降のバージョンに適用されることに注意してください)を回答としてここに送信すると、喜んで投票します:)
Adam C
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.