最近公司叫我写一个程序已监控mongodb,防止有mongodb运行异常的情况发生了.而没人知道


在网上查了很久资料发现可以使用 db.currentOp()

下面..db.currentOp()的相关资料


  执行命令会返回一个inprog数组,数组中每个元素都是一个nested document,以其中一个为例,解释下具体意思:

{
         "opid" : 37432,//此操作的id
         "active" : false,//此操作是否处于活动状态
         "secs_running" : 0,//此操作运行了多少秒
         "op" : "query",//具体的操作行为,包括(insert/query/update/remove/getmore/command)
         "ns" : "category.categoryDocs",//此操作的命名空间,数据库名.集合名
        //具体的操作语句
         "query" : {
                 "cname" : "查询语句",
                 "sort" : 2
         },
         "client" : "*.*.*.*:21758",//连接的客户端信息
         "desc" : "conn724",//数据库连接描述
         "threadId" : "0x78156940",//线程id
         "connectionId" : 724,//数据库连接id
         "waitingForLock" : false,//是否在等待获取锁,
         "numYields" : 0,
         "lockStats" : {
                 "timeLockedMicros" : {//此操作获得以下锁后,把持的微秒时间
                            "R" : NumberLong(0),//整个mongodb服务实例的全局读锁
                            "W" : NumberLong(0),//整个mongodb服务实例的全局写锁
                             "r" : NumberLong(170),//整个数据库实例的读锁
                            "w" : NumberLong(0)//整个数据库实例的写锁
                 },
                 "timeAcquiringMicros" : {//此操作为了获得以下的锁,而耗费等待的微秒时间
                            "R" : NumberLong(),//整个mongodb服务实例的全局读锁
                            "W" : NumberLong(),//整个mongodb服务实例的全局写锁
                             "r" : NumberLong(5),//整个数据库实例的读锁
                            "w" : NumberLong(0),//整个数据库实例的写锁
                 }
         }
 }

 

    时间单位换算:

1秒=1000毫秒(ms) 1毫秒=1/1,000秒(s) 
          1秒=1,000,000 微秒(μs) 1微秒=1/1,000,000秒(s)

 

 

   其实,我们可以写脚本对inprog数组进行筛选来得到自己想要的数据,比如:

 

1:--获取已停止活动+操作为查询的数据

db.currentOp(true).inprog.forEach(
   function(opDoc){//opDoc其实是返回的每个op操作对象
     if(!opDoc.active && opDoc.op=='query')
        printjson(d)//打印信息
     }
 )

 

 2:--正在进行中+操作为查询的数据

db.currentOp(true).inprog.forEach(
   function(opDoc){//opDoc其实是返回的每个op操作对象
     if(opDoc.active && opDoc.op=='query')
        printjson(d)//打印信息
     }
 )

 

       通过以上监控如果发现某个操作比较慢,还可以对其进行kill,很简单,知道了具体的opid后,一句命令就可以搞定,so easy:

   db.killOp(opid) //kill当前的操作 opid为具体的操作id号,当然了,只能kill正在进行中的

 

在java中操作此命令...

1. //查询条件q可以把需要的过滤出来  
2. q = new BasicDBObject("$all", true);  
3. currentOp = db.getCollection("$cmd.sys.inprog").findOne(q);  
4.     System.out.println(currentOp.toString());