1 分析器(Database Profiler) 概述
官网连接如下:
https://www.mongodb.com/docs/manual/tutorial/manage-the-database-profiler/
数据库分析器用于收集mongod实例执行的数据库命令的详细信息,这些信息包括CRUD操作以及配置和管理命令。 分析器将收集到的所有数据写入system.profile集合。 同oplog 一样,system.profile 集合也是一个固定大小的集合,主要用于支持高吞吐量的insert 和文档检索(capped collection)。
MongoDB 4.4 中 journal 和 oplog 日志 说明
https://www.cndba.cn/dave/article/107979
shard1:PRIMARY> db.system.profile.stats()
{
"ns" : "test.system.profile",
"size" : 1447,
"count" : 1,
"avgObjSize" : 1447,
"storageSize" : 20480,
"freeStorageSize" : 0,
"capped" : true,
"max" : -1,
"maxSize" : 1048576,
"sleepCount" : 0,
"sleepMS" : 0,
"wiredTiger" : {
"metadata" : {
"formatVersion" : 1
},
……
MongoDB 默认没有启用profiler。 可以对每个实例或者数据库来启用profiler。当然,启用profiler 数据库性能也会带来一定的影响,不过可以通过配置profiling level 来降低这个影响。
对于shard cluster 环境,不能直接对mongos 实例启动prifiling,必须对cluster中的每个mongod实例分别启动profiling。 从MongoDB 4.0 开始,可以对mongos 实例配置—slowms 和slowOpSampleRate 参数,以在diagnostic log中记录慢操作。
MongoDB profiler 有如下3个级别:
- 默认级别,不收集任何数据。
- 该级别会收集超过slowms 设置的长操作或者匹配的filter, 比如count、delete、find、insert、update等等。 这里要注意,如果设置了filter,那么只收集filter的数据,slowms和sampleRate 的参数设置对分析器无效。
- 该级别会收集所有操作的数据。
更多相关信息可以参考如下官网:
Database Profiler Output
https://www.mongodb.com/docs/manual/reference/database-profiler/db.currentOp()
https://www.mongodb.com/docs/manual/reference/method/db.currentOp/Profile Command
https://www.mongodb.com/docs/manual/reference/command/profile/
2 相关操作
2.1 启用和关闭分析器
将分析器的级别设置为大于0时,即启用分析器。 启用分析器之后,MongoDB 会自动创建system.profile 集合,用来存储分析器的数据。
shard1:SECONDARY> db.setProfilingLevel(2)
{
"was" : 0,
"slowms" : 100,
"sampleRate" : 1,
"ok" : 1,
……
查看分析器级别:
shard1:SECONDARY> db.getProfilingStatus()
{
"was" : 2,
"slowms" : 100,
"sampleRate" : 1,
……
关闭分析器:
shard1:SECONDARY> db.setProfilingLevel(0)
{
"was" : 2,
"slowms" : 100,
"sampleRate" : 1,
"ok" : 1,
……
2.2 配置分析器
2.2.1 配置 slowms
profiler 有2个相关参数,slowms 和sampleRate , 当通过profile 命令或者 db.setProfilingLevel() 方法来设置时,那么就是单个数据库级别的配置。 当通过配置文件来设置时,那么就是全局配置,对所有实例都生效。
设置慢操作的阈值:在刚才查询中我们可以看到,慢操作的阈值默认是100ms。 我们可以通过如下方法来修改慢操作的阈值。
- 通过profile命令或者 db.setProfilingLevel() 方法来设置。
- 在启动mongodb时指定—slowms 选项。
- 在配置文件中设置slowOpThresholdMs的值。
shard1:SECONDARY> db.setProfilingLevel(1, { slowms: 20 })
shard1:SECONDARY> db.getProfilingStatus()
{
"was" : 1,
"slowms" : 20,
"sampleRate" : 1,
……
2.2.2 配置sampleRate
在事务量很大的清下,记录所有的慢操作可能会占用更多的资源,对系统影响也会更大,因此可以设置sampleRate 参数,即只对所有慢操作按一定比率进行分析。 sampleRate 默认为1,对所有慢操作进行分析,该参数的设置区间是:0 到1,这里仅当profile 级别为1时才有效。
可以通过如下方法进行设置:
- 通过profile命令或者db.setProfilingLevel() 方法进行设置。
- 在启动实例时指定—slowOpSampleRate 参数。
- 在配置文件中指定slowOpSampleRate 参数。
以下命令设置profiler 级别为1,并且只对所有慢操作进行随机的42%的比例进行分析。
shard1:SECONDARY> db.setProfilingLevel(1, { sampleRate: 0.42 })
{
"was" : 1,
"slowms" : 20,
"sampleRate" : 1,
"ok" : 1,
……
shard1:SECONDARY> db.getProfilingStatus()
{
"was" : 1,
"slowms" : 20,
"sampleRate" : 0.42,
……
2.2.3 配置Filter
从MongoDB 4.4.2 开始,可以配置Filter 来控制profiled 的操作。
可以通过如下方法来配置Filter:
- 通过profile命令或者db.setProfilingLevel() 方法
- 在配置文件中设置filter。
对于mongod 实例,filter 会影响diagnostic log 和profiler(如果启用了)。
对于mongos 实例,filter 只影响diagnostic log,因为profiling 不支持mongos实例。
同时还需要注意的一点,就是在设置filter 之后,slowms和 sampleRate 选项将失效。
比如:
shard1:SECONDARY> db.setProfilingLevel( 2, { filter: { op: "query", millis: { $gt: 2000 } } } )
{
"was" : 1,
"slowms" : 20,
"sampleRate" : 0.42,
"note" : "When a filter expression is set, slowms and sampleRate are not used for profiling and slow-query log lines.",
"ok" : 1,
……
这里通过filter 仅记录超过2秒的的query 操作。
这里完整的filter 清单可以查看如下链接:
https://www.mongodb.com/docs/manual/reference/database-profiler/#std-label-profiler
2.3 查看分析器日志
分析器的日志保存在system.profile 的集合中。 可以查看该集群来看相关信息。
详细的分析可以参考官方手册:
Database Profiler Output
https://www.mongodb.com/docs/manual/reference/database-profiler/
这里看几个常规命令:
查看最近10条记录:
shard1:PRIMARY> db.system.profile.find().limit(10).sort( { ts : -1 } ).pretty()
查看command($cmd) 操作外的所有操作:
shard1:PRIMARY> db.system.profile.find( { op: { $ne : 'command' } } ).pretty()
查看特定集合的操作:
shard1:PRIMARY> db.system.profile.find( { ns : 'cndba.user' } ).pretty()
查看操作超过5ms的操作:
shard1:PRIMARY> db.system.profile.find( { millis : { $gt : 5 } } ).pretty()
查看特定时间范围的操作:
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 } )
查看最近的5条记录:
在mongosh 中,在启动profile的情况下,可以直接执行如下命令:
shard1:PRIMARY> show profile
来查看最近5条超过1 ms的操作。
3 分析器的开销(Profiler Overhead)
启用profiling会对数据库的性能有一定的影响,特别是在配置2级,并且阈值为1ms的情况下。 因为分析器使用system.profile 来存储日志,所以对磁盘空间也有一定的消耗。因此在生产环境启用profiling 之前需要考虑其对性能和安全性的影响。
3.1 system.profile 集合
system.profile 集合是固定大小集合(capped collection),默认大小为1M。
shard1:PRIMARY> show tables
system.profile
system.roles
system.users
system.version
shard1:PRIMARY> db.getCollection("system.profile").storageSize()
4096
shard1:PRIMARY>
该大小集合可以存储大约几千条profile documents。 因为是固定大小集合,所以当达到限制时,会覆盖最早的documents 数据。因此,如果需要更多的pfofling data,我们可以修改system.profile 集合的大小。
步骤如下:
- 禁用profiling。
- 删除system.profile 集合。
- 创建新的system.profile 集合。
- 启用profiling。
比如这里创建一个4000000 bytes (4 MB)的system.profile 集合:
shard1:PRIMARY> db.setProfilingLevel(0)
shard1:PRIMARY> db.system.profile.drop()
shard1:PRIMARY> db.createCollection( "system.profile", { capped: true, size:4000000 } )
shard1:PRIMARY> db.setProfilingLevel(1)
3.2 副本集环境secondary 维护
在副本集环境中,如果要修改secondary 节点的system.profile 集合,必须先停止secondary 节点,并以standalone 模式启动,在执行上述步骤,修改完成后,在以副本集模式启动。
关于模式副本节点维护,参考如下博客:
MongoDB 4.4 副本集 维护步骤 说明
https://www.cndba.cn/dave/article/107981
版权声明:本文为博主原创文章,未经博主允许不得转载。