数据库分析器:

         数据库分析器(Database Profiler)收集有关针对的mongod实例运行操作命令的详细信息。探查器的输出可帮助识别效率低下的查询和操作,这包括CRUD操作以及配置和管理命令。

        分析器(Profiler)将收集到的所有信息写入system.profile集合,Profile集合是个有固定大小的集合(默认1M),支持基于插入顺序的插入和检索文档的高吞吐量操作。Profile集合的工作方式类似于循环缓冲区:一旦集合填满了它所分配的空间,它就会重写集合中最旧的文档,从而为新文档腾出空间。

慢查询:

        我们将超过指定时间的查询称为“慢查询”。 在MongoDB中你可以设置一个查询时长的限额值来确定是否是慢查询,默认是100毫秒。通过这些慢查询你可以方便的监测这些查询是否使用了全集合扫描或者索引扫描。

       MongoDB的数据库分析器默认是关闭的。长时间开启会对数据库有性能方面的影响,所以最好是使用完性能分析后,将此功能关闭,以避免以数据库性能造成影响。

分析器开启:

语法:

db.setProfilingLevel(<level>, <options>)

参数:

参数 类型 描述
level
integer

配置分析器级别。提供以级别:

级别 描述
0 分析器已关闭,并且不收集任何数据。这是默认的分析器级别。
1 分析器收集的数据花费的时间超过的值slowms
2 分析器收集所有操作的数据。

 

options document or integer

可选的。接受整数或配置文档。如果将整数值作为options参数而不是配置文档作为参数传递,则该值将分配给slowms。提供以下选项:

slowms
默认值:100
类型:integer
 
慢操作的时间阈值,单位为毫秒。运行时间超过此阈值的操作被认为是慢查询。

logLevel设置为0,MongoDB以由slowOpSampleRate确定的速率将慢速操作记录到诊断日志中。

sampleRate
默认值:1.0
类型:double

慢查询分析的百分比率。 sampleRate接受0到1之间的值(包括0和1)。

sampleRate 值默认为1,表示都采集,0.35 表示采集35%的内容

filter
类型: object
过滤器表达式,控制哪些操作分析和记录。
New in version 4.4.2.

 

返回

该方法返回一个包含先前设置值的文档。

  • 单机版
  • 副本集成员
  • mongos实例
{ "was" : 0, "slowms" : 100, "sampleRate" : 1, "ok" : 1 }
{
   "was" : 0,
   "slowms" : 100,
   "sampleRate" : 1,
   "ok" : 1,
   "$clusterTime" : {
      "clusterTime" : Timestamp(1572991238, 1),
      "signature" : {
         "hash" : BinData(0,"hg6GnlrVhV9MAhwWdeHmHQ4T4qU="),
         "keyId" : NumberLong("6755945537557495811")
      }
   },
   "operationTime" : Timestamp(1572991238, 1)
}
{
   "was" : 0,
   "slowms" : 100,
   "sampleRate" : 1,
   "ok" : 1,
   "operationTime" : Timestamp(1572991499, 2),
   "$clusterTime" : {
      "clusterTime" : Timestamp(1572991499, 2),
      "signature" : {
         "hash" : BinData(0,"nhCquIxUw7thlrBudXe3PnsnvP0="),
         "keyId" : NumberLong("6755946491040235540")
      }
   }
}

说明:

  • was是上一个 level 设置。
  • slowms先前的 slowms 设置。
  • sampleRate先前的 sampleRate设置。
  • filter 是先前的 filter 设置. (New in MongoDB 4.4.2)
  • note 是解释 filter 行为的字符串。此字段仅在filter也出现时出现在输出中. (New in MongoDB 4.4.2)

 

要查看当前配置级别,请参阅db.getProfilingStatus()

使用示例:

#  为所有数据库开启慢查询记录
db.setProfilingLevel(2)
#  指定数据库,并指定阈值慢查询 ,超过20毫秒的查询被记录
use test
db.setProfilingLevel(1, { slowms: 20 })
#  随机采集慢查询的百分比值,sampleRate 值默认为1,表示都采集,0.42 表示采集42%的内容。
db.setProfilingLevel(1, { sampleRate: 0.42 }) 

#记录所有操作日志,过滤查询操作超过2秒的
db.setProfilingLevel( 2, { filter: { op: "query", millis: { $gt: 2000 } } } )

# 查询慢查询级别和其它信息
db.getProfilingStatus()
# 仅返回慢查询级别
db.getProfilingLevel()

 

分析日志查询:

# 查询最近的10个慢查询日志
db.system.profile.find().limit(10).sort( { ts : -1 } ).pretty()

# 查询除命令类型为 ‘command’ 的日志
db.system.profile.find( { op: { $ne : 'command' } } ).pretty()

# 查询数据库为 mydb 集合为 test 的 日志
db.system.profile.find( { ns : 'mydb.test' } ).pretty()

# 查询 低于 5毫秒的日志
db.system.profile.find( { millis : { $gt : 5 } } ).pretty()

# 查询时间从 2012-12-09 3点整到 2012-12-09 3点40分之间的日志
db.system.profile.find({
  ts : {
    $gt: new ISODate("2012-12-09T03:00:00Z"),
    $lt: new ISODate("2012-12-09T03:40:00Z")
  }
}).pretty()

# 下面的示例查看时间范围,将用户字段从输出中删除以使其更容易阅读,并根据每个操作运行的时间对结果进行排序
db.system.profile.find({
  ts : {
    $gt: new ISODate("2011-07-12T03:00:00Z"),
    $lt: new ISODate("2011-07-12T03:40:00Z")
  }
}, { user: 0 }).sort( { millis: -1 } )

system.profile集合字段解析:

{
   "op" : "query",   # 操作类型,值可为command、count、distinct、geoNear、getMore、group、insert、mapReduce、query、remove、update
   "ns" : "test.report", # 操作的数据库和集合
   "command" : {     # 命令
      "find" : "report",  # 操作的集合
      "filter" : { "a" : { "$lte" : 500 } }, # 查询条件
      "lsid" : {    
         "id" : UUID("5ccd5b81-b023-41f3-8959-bf99ed696ce9") #用户的会话id
      },
      "$db" : "test"  # 操作的数据库
   },
   "cursorid" : 33629063128,  # query和getmore 的游标id
   "keysExamined" : 101, # MongoDB为执行操作而扫描的索引键的数量
   "docsExamined" : 101, # MongoDB为了执行操作而扫描的集合中的文档数。
   "numYield" : 2, # 让步次数,操作时让其他的操作完成的次数。
   "nreturned" : 101, # 操作返回的文档数
   "queryHash" : "811451DD", # 查询的hash值
   "planCacheKey" : "759981BA", 
   "locks" : {  # 操作期间的锁和所的类型
      "Global" : {  #表示全局锁定
         "acquireCount" : { #锁定的次数
            "r" : NumberLong(3)  # 表示共享锁 
         }
      },
      "Database" : {   # 数据库锁
         "acquireCount" : { "r" : NumberLong(1) },
         "acquireWaitCount" : { "r" : NumberLong(1) },
         "timeAcquiringMicros" : { "r" : NumberLong(69130694) }
      },
      "Collection" : {  # 集合锁
         "acquireCount" : { "r" : NumberLong(1) }
      }
   },
   "storage" : { # 储存
      "data" : {
         "bytesRead" : NumberLong(14736), #操作 从磁盘放到缓存的数据的字节数
         "timeReadingMicros" : NumberLong(17) # 操作 花费在磁盘读取的时间,以微妙为单位
      }
   },
   "responseLength" : 1305014, # 操作返回结果的文档长度,单位为字节
   "protocol" : "op_msg", # 消息的协议
   "millis" : 69132, # 从 MongoDB 操作开始到结束耗费的时间
   "planSummary" : "IXSCAN { a: 1, _id: -1 }",  # 摘要
   "execStats" : {  # 操作执行过程中的详细信息
      "stage" : "FETCH", # 操作形式 ,COLLSCAN 用于集合扫描,IXSCAN 用于扫描索引键,FETCH 用于检索文档
      "nReturned" : 101, # 返回的文档数量
      "executionTimeMillisEstimate" : 0,
      "works" : 101,
      "advanced" : 101,
      "needTime" : 0,
      "needYield" : 0,
      "saveState" : 3,
      "restoreState" : 2,
      "isEOF" : 0,
      "invalidates" : 0,
      "docsExamined" : 101,
      "alreadyHasObj" : 0,
      "inputStage" : {
         ...
      }
   },
   "ts" : ISODate("2019-01-14T16:57:33.450Z"), #操作的时间戳
   "client" : "127.0.0.1",  # 客户端的ip
   "appName" : "MongoDB Shell", #客户端应用标识符
   "allUsers" : [
      {
         "user" : "someuser", # 用户
         "db" : "admin"  # 验证的数据库
      }
   ],
   "user" : "someuser@admin"  # 经过验证的用户
}

分析器关闭:

use test
db.setProfilingLevel(0)

 

改变分析器集合的大小:

db.setProfilingLevel(0)
db.system.profile.drop()
# 创建4M大小的集合
db.createCollection( "system.profile", { capped: true, size:4000000 } )
db.setProfilingLevel(1)

 

参考文献:

https://docs.mongodb.com/manual/tutorial/manage-the-database-profiler/

https://www.cnblogs.com/operationhome/p/10728654.html