Bagaimana cara saya (dengan aman) membunuh operasi yang berjalan lama di MongoDB?

11

Kadang-kadang operasi keluar dari kendali di MongoDB dan mungkin berakhir berjalan selama ratusan detik, dan berdampak pada kinerja sampai mereka terbunuh atau selesai.

Ketika itu terjadi, saya tahu saya telah killOp()tersedia untuk saya, tetapi bagaimana cara saya membunuh hanya operasi jangka panjang yang ditargetkan tanpa juga membunuh (misalnya) operasi jangka panjang yang terlibat dalam replikasi (yang bisa berbahaya)?

Adam C
sumber

Jawaban:

15

Ini mungkin sedikit rumit, tetapi fakta bahwa shell MongoDB pada dasarnya adalah penerjemah Javascript memberi kita opsi yang layak dalam hal penyaringan. Berikut adalah fungsi yang saya gunakan untuk mencapai ini:

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

Ini hanya akan membunuh permintaan di atas maxSecsRunningambang batas dan tidak akan menyentuh apa pun yang berjalan terhadap localbasis data, yang merupakan tempat oplogtinggalnya (dan karenanya merupakan basis data yang terlibat dalam operasi replikasi yang berjalan lama. Ini relatif mudah untuk menambahkan kriteria ke ifkondisi dalam untuk lebih tepatnya menargetkan operasi sesuai kebutuhan berdasarkan kebutuhan spesifik.

Kode ini juga tersedia sebagai intisari (di mana saya akan ingat untuk memperbaruinya secara berkelanjutan).

Adam C
sumber
Saya telah melihat beberapa skrip untuk yang satu ini. Namun demikian, untuk memeriksa apakah operasi berjalan terhadap database lokal merupakan perbaikan yang bagus.
joao
yeah - Saya telah memberikan ini berkali-kali, dan melihat posting blog dengan skrip yang sangat berbahaya untuk membunuh ops, jadi saya pikir saya akan memberikan versi yang bagus dan mudah ditautkan
Adam C
3
Saya percaya ini adalah skrip berbahaya setidaknya saat menggunakan replika. Berjalan db.currentOp()di basis data kami yang diembed, mengembalikan operasi di "" namespace (alias ns: "") yang berjalan sangat lama dengan desc "repl writer worker n" (di mana n adalah integer). Saya akan menyarankan daftar putih ruang nama ke database Anda yang sebenarnya dengan pertanyaan yang mungkin ingin Anda bunuh. Sesuatu seperti && (['users', 'analytics'].indexOf(op.ns) != -1)bukannya !op.ns.startsWithkondisinya.
runamok
Poin bagus, dan sangat mungkin bahwa ruang nama kosong lebih sering terjadi di versi yang lebih baru - Saya awalnya bermaksud menjaga agar skrip tetap mutakhir, tetapi sekarang saya telah meninggalkan MongoDB, jadi sepertinya saya tidak takut. Jika Anda mengirimkan kode Anda yang diperbarui (dengan catatan yang berlaku untuk versi yang lebih baru) di sini sebagai jawaban, saya akan dengan senang hati memilih Anda :)
Adam C