MongoDB慢日志

Database Profile

Database Profiler收集有关正在运行的数据库命令,包括CRUD操作以及配置和管理命令。Profiler将收集的数据写入admin数据库下的system.profile的固定集合。Database Profiler默认情况是OFF的,可以在数据库或实例上启用Profiler

分析级别

level 描述
0 默认级别,profiler处于关闭状态并且没有任何数据
1 将超过slowms时间的操作记录在固定集合中
2 记录所有的操作数据

当前数据库设置分析级别并设置慢操作阈值(毫秒)

1
db.setProfilingLevel(1,{slowms:1000})

查看分析级别

1
2
> db.getProfilingStatus()
{ "was" : 0, "slowms" : 100, "sampleRate" : 1.0, "ok" : 1 }
  • was表示当前的分析级别
  • slowms表示慢操作阈值,以毫秒为单位
  • sampleRate表示分析的慢操作百分比

为整个实例启用分析需要在启动时指定下列参数,或者在参数文件中指定operationProfiling

1
mongod --profile 1 --slowms 15 --slowOpSampleRate 0.5

无法在Mongos实例上启用profiler,要在分片环境启用profiler,必须为群集中每个实例启用profiler。从MongoDB 4.0开始可以在Mongos设置slowms和slowOpSampleRate来配置诊断日志

分析慢查询日志

查询最近的十条日志

1
db.system.profile.find().limit(10).sort( { ts : -1 } ).pretty()

查询特定集合的操作

1
db.system.profile.find( { ns : 'mydb.test' } ).pretty()

查询command外的操作

1
db.system.profile.find( { op: { $ne : 'command' } } ).pretty()

查询特定时间范围内

1
2
3
4
5
6
db.system.profile.find({
  ts : {
    $gt: new ISODate("2012-12-09T03:00:00Z"),
    $lt: new ISODate("2012-12-09T03:40:00Z")
  }
},{user:0}).sort({millis:-1})

分析查询结果

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
{
"op" : "query",                     #操作类型,有insert、query、update、remove、getmore、command  
"ns" : "F10data3.f10_2_8_3_jgcc",
"query" : {                         #具体的查询语句,包括过滤条件,limit行数
    filter" : {
        "jzrq" : {
            "$gte" : ISODate("2017-03-31T16:00:00.000+0000"),
            "$lte" : ISODate("2017-06-30T15:59:59.000+0000")
        },
        "jglxfldm" : 10.0
    },
    "ntoreturn" : 200.0,    
    "sort" : {                      #如果有排序,则显示排序的字段
        "RsId" : 1.0
    }
},
"keysExamined" : 0.0,               #索引扫描数量 这里是全表扫描,没有用索引 所以是 0
"docsExamined" : 69608.0,           #浏览的文档数 这里是全表扫描 所以是整个collection中的全部文档数
"numYield" : 546.0,                 #该操作为了使其他操作完成而放弃的次数。通常来说,当他们需要访问
                                    还没有完全读入内存中的数据时,操作将放弃。这使得在MongoDB为了
                                    放弃操作进行数据读取的同时,还有数据在内存中的其他操作可以完成。
"locks" : {                         #锁信息,R:全局读锁;W:全局写锁;r:特定数据库的读锁;w:特定数据库的写锁
    "Global" : {
        "acquireCount" : {
            "r" : NumberLong(1094)  #该操作获取一个全局级锁花费的时间。
        }
    },
    "Database" : {
        "acquireCount" : {
            "r" : NumberLong(547)  
        }
    },
    "Collection" : {
        "acquireCount" : {
            "r" : NumberLong(547)
        }
    }
},
"nreturned" : 200.0,                #返回的文档数量
"responseLength" : 57695.0,         #返回字节长度,如果这个数字很大,考虑值返回所需字段
"millis" : 264.0,                   #消耗的时间(毫秒)
"planSummary" : "COLLSCAN, COLLSCAN", #执行概览 从这里看来 是全表扫描
"execStats" : {                       #详细的执行计划 这里先略过 后续可以用 explain来具体分析
},
"ts" : ISODate("2017-08-24T02:32:49.768+0000"),  #命令执行的时间
"client" : "10.3.131.96",                        #访问的ip或者主机
"allUsers" : [
],
"user" : ""
}

更改system.profile集合大小

由于system.profile集合是一个仅1M大小的固定集合,如果需要增加或减少该结合的大小,必须按照下列步骤操作

  1. 禁用分析
    1
    
    db.setProfilingLevel(0)
    
  2. 删除system.profile集合
    1
    
    db.system.profile.drop()
    
  3. 创建一个新的system.profile集合
    1
    
    db.createCollection("system.profile" , {capped : true , size : 4000000})
    
  4. 重新启用分析
    1
    
    db.setProfilingLevel(1)
    

如果修改的secondary节点的system.profile大小,需要将其以standalone模式启动再进行修改

更多参考内容请查看链接:Database Profiler

Licensed under CC BY-NC-SA 4.0
comments powered by Disqus