data engineering

mongodb slow query check.(and kill slow query)

qkqhxla1 2018. 12. 6. 13:28

https://medium.com/@igorkhomenko/troubleshooting-mongodb-100-cpu-load-and-slow-queries-da622c6e1339


서버에서 갑자기 cpu가 100%까지 치솟았다. 몽고디비가 cpu가 높은 원인이었고, 여러 프로그램에서 몽고에 접근하고 있어서 도대체 어떤 프로그램에서 어떻게 접근하는 프로세스가 문제인지 확인할수가 없었다.


구글링에 검색해보니 위 명령어가 나왔다.


db.currentOp({"secs_running": {$gte: 3}}) 


치면 엄청나게 유용하다. 오래걸리는 쿼리가 접근하는 컬렉션과, 필터를 어떤식으로 걸었는지가 다 나온다. 


아래는 위 블로그 주인이 적은거 그대로 가져다 붙임.

db.currentOp({“secs_running”: {$gte: 3}})
{
"inprog" : [
{
    "desc" : "conn8003244",
    "threadId" : "0x5e7e56c0",
    "connectionId" : 8003244,
    "opid" : 891016392,
    "active" : true,
    "secs_running" : 3,
    "microsecs_running" : NumberLong(3575970),
    "op" : "query",
    "ns" : "quickblox_production.custom_data",
    "query" : {
        "$query" : {
            "start" : {
                "$lte" : ISODate("2017-11-15T13:57:55Z")
             },
            "application_id" : 53894,
            "class_name" : "Broadcast"
        },
        "$orderby" : {
            "start" : -1
        }
    },
"planSummary": ...,
    "client" : "10.0.0.87:46290",
    "numYields" : 5601,
    "locks" : ...,
    "waitingForLock" : false,
    "lockStats" : ...
}
]
}

I highlighted the most important keys to analize:

  • active: means the query is ‘in progress’ state
  • secs_running: query’s duration, in seconds
  • ns: a collection name against you perform the query.
  • query: the query body.

So now we know how to find slow queries that can lead to high CPU load.


mongodb kill slow query.

https://gist.github.com/kylemclaren/3c09a4dda5991cf0bf9c


에서 가져옴.


killLongRunningOps = function(maxSecsRunning) {
    currOp = db.currentOp();
    for (oper in currOp.inprog) {
        op = currOp.inprog[oper-0];
        if (op.secs_running > maxSecsRunning && op.op == "query") {
            print("Killing opId: " + op.opid
                    + " running for over secs: "
                    + op.secs_running
                    + ', collection name : ' + op.ns);
            //db.killOp(op.opid);
        }
    }
};
killLongRunningOps(3)

이처럼 검색하고 db.killOp의 주석을 풀어주면 kill.한다. 위 예제는 3초넘게 걸린 쿼리만 찾아서 출력하는 예제.