- ———————Response time = Service time + Wait time—
服务时间(Servicetime)就是进程“真正”在cpu上运行的时间,可以简单理解为AWR中的cpu time/db cpu,服务时间包括前台进程(Server process)和后台进程(Backgroud process)消耗的时间。等待时间就是等待某种资源的时间耗费,比如等待锁资源的耗费,可以简单对应为awr中的wait time, 等待时间包括很多类型,一般最常见的是IO等待和并发等待,比如进程等待从物理磁盘读取数据块到内存中的等待。
Awr中的db time可以简单对应为Responsetime;对于操作系统而言,一个进程要么在cpu中运行,要么处于等待队列中;注意这里的“等待”并不完全等同于os中的等待。
- —————————db time与cpu time——————————
DB time是整个数据库用户进程消耗的总时间,可用于衡量一个数据库整体负载,这有一些类似unix/linux系统中的平均负载(average load)指标。
我们来看一份awr:
Snap Id | Snap Time | Sessions | Cursors/Session |
---|---|---|---|
Begin Snap | 9820 | 13-2月 -12 08:00:17 | |
End Snap | 9821 | 13-2月 -12 09:00:13 | |
Elapsed | 59.93 (mins) | ||
DB Time | 437.53 (mins) |
我们可以看到这一个awr的间隔时间为60分钟,而db time达到了437分钟,比率大致为7.3,我们这一个系统为16 core cpu 的小型机,那么在60分钟可以提供的cpu time为16*60=960分钟的cpu time;如果我们的db time全部都由cpu time来构成(当然是不可能的,Oracle总会有一些等待),cpu的占用率为46%;cpu资源还是足够的;考虑到db time还包括一部分wait time,我们的cpu占用率会远远低于46%。
Db time主要用于对比同一系统的不同时段,或同一时段的不同系统来得到整体负载的初步映象,对比法是性能调整中,屡试不爽的重要法门!
Snap Id | Snap Time | Sessions | Cursors/Session |
---|---|---|---|
Begin Snap | 9820 | 14-2月 -12 08:00:17 | |
End Snap | 9821 | 14-2月 -12 09:00:13 | |
Elapsed | 59.93 (mins) | ||
DB Time | 1,139.42 (mins) |
接下来我们来讨论一下cputime,cpu time在awr中也表示为db cpu,同时cpu time也是一个空闲等待事件,但这三者没有太大区别,时间值也是相同的。cpu time是Oracle对操作系统而言真正意义上的cpu消耗。那如何计算一个Oracle实例对操作系统的时间占比呢?很简单,公式如下:这同样是一个16 core的系统,不同医院同一时段的系统,我们可以看到在会话数(sessions)与每个会话的平均cursor数量(Cursors/Session)都小于前一个系统的情况下(可以简单的理解为医院的规模和应用范围都小于前一个系统),db time大幅增加;总的db time达到了1139分钟,据此我们初步认为从整体来看第二个系统的性能是比较差的。
Cpu time/ (Elapsed time * CPU cores)
在AWR中的top 5 waits或Time ModelStatistics都可以找到 cpu time
- —————————Time ModelStatistics—————————
在awr中,Time ModelStatistics用于回答“到底前台进程消耗了多少时间?”,“语句解析消耗了多少时间?”等诸如此类的问题,我们来看一个例子:
Statistic Name | Time (s) | % of DB Time |
---|---|---|
connection management call elapsed time | 21,708.46 | 15.22 |
sql execute elapsed time | 21,596.44 | 15.14 |
parse time elapsed | 17,648.50 | 12.37 |
hard parse elapsed time | 9,081.89 | 6.37 |
hard parse (sharing criteria) elapsed time | 4,158.48 | 2.92 |
hard parse (bind mismatch) elapsed time | 3,189.62 | 2.24 |
PL/SQL execution elapsed time | 2,362.21 | 1.66 |
DB CPU | 2,311.28 | 1.62 |
PL/SQL compilation elapsed time | 145.25 | 0.1 |
failed parse elapsed time | 89.78 | 0.06 |
sequence load elapsed time | 69.16 | 0.05 |
repeated bind elapsed time | 0.21 | 0 |
DB time | 142,622.31 | |
background elapsed time | 4,871.65 | |
background cpu time |
我们看到,真于用于sql执行的时间(sql execute elapsed time)只占到了15.14%;这个比率是非常低的,作来一个相对正常的系统,这一比率不应低于90%甚至更高!我们看到用于连接管理(connection management call elapsed time)的时间为15%,用于sql解析(parse time elapsed)的时为12.37%,且其中硬解析sql(hard parse elapsed time)的时间为6.37%。从这几个方面来看,我们可以作一些合理的推测:
系统是否存在频繁连接和断开连接的情况?如果存在这种情况,是否是网络不稳定,或者监听程序存在问题造成了这个情况?还有就是中间件到数据库服务器的连接池是否出了问题?
Sql语句解析不合理;这是否因为共享池设置过小?应用程序是否未使用绑定变量?还是因为开启了SGA自动管理,带来了严重的内存颠簸现象?
可以看到,通过对时间模型的分析,可以帮助我们结合等待事件、latch信息等内容而对性能问题作出更为准确的判断。
Awr中也采集了部分操作系统的信息,特别是到了11g,更进一步的帮我们计算出了cpu占用率,非常方便;awr中的Operating System Statistics部分:
从图中,我们可以得到cpu数量、busy_time、idle_time、iowait_time、物理内存等信息,对于我们了解系统级的性能信息很有帮助。比如我可以透过如下公式来计算awr采集期间的平均cpu占用率:
BUSY_TIME/( BUSY_TIME+ IDLE_TIME) * 100%
具体到我们的例子,2,387,903/(2,387,903+3,389,758)*100%=41.33%。当然这里的cpu占用率,是从操作系统层面来看的,并不是Oracle实例的cpu占用情况,因为主机可以运行了其他Oracle实例、或者中间件之类的其他软件系统。同时,我们也可以通过IOWAIT_TIME来初步判断我们的系统是否存在io瓶颈。
- —————————多关注平均时间—————————
“平均”是一个很有意思的话题,大家对平均的最直观的感受就是统计局发布“XX地区平均收入已经突破XX元”,很多人都会发出“拖伟大祖国的后腿了!”这样的感叹。根据平均理论:即使我们的头被火烧,脚浸泡在冰水里,也不会感到难受!这种情况在AWR的分析中也是需要注意的。
Awr采集的是一段时间整体性能数据,可能平均数据看起来没有问题,但前端用户可能还是感觉慢,因为某些次数的长时间等待被其他较短时间的等待给“平均”掉了!这就需要我们区别不同的类型的问题,可能这些问题并不适合awr来诊断,而应该选用更合适的ash、sql trace等工具进行诊断。但这并说明“平均”的时间没有任何价值,只是需要具体问题具体分析。
我们这里谈一下等待事件的平均等待时间:
对于IO类型的等待事件来说,比如常见的db file sequential read平均等待时间一般不要超过10ms,这是根据当前硬盘的机械结构、转速等得出的一个经验值,因为单块10000转的普通磁盘,寻道时间在7-10ms左右。当然,如果考虑存储缓存、文件系统缓存、IO大小等情况,这个值一般在4-7ms之间;同时必须是IO系统在正常的iops(每秒的io次数,用于衡量存储并发吞量)下才有意义。如果超过经验值很多,就要分析具体的原因了,可能是存储的缓存功能没有启用、raid组中的磁盘损坏、不合理的raid级别等各种原因;当然也有可能是系统io负载过大,存储的负担较重,如果是这种情况就需要给合应用的io量(物理读与逻辑读),特别是sql的io情况来分析了。
我们再来看一个真实的案例:
我们看到整个系统的等待事件主要集中在IO上。db file sequential read的平均等待时间为66ms,而log filesync达到了惊人的493ms,也就是近0.5秒。log file sync一般由事务提交引起,也就是说一个事务光在提交上,就需要花费0.5s!请记住,这还是一个平均数,还有很多事务,是远远大于这个时间的!最终检查出来的原因是医院的存储使用了7200转的sata硬盘构建的RAID5,这样的配置对于ZLHIS这样的oltp系统来说,无疑就是灾难!
- —————————次数—————————
前面谈的都是“时间”,下面我们来谈一下次数,同时作为本文的结束。首先,一些latch相关的等待事件,与latch中的sleep的次数相一致!比如library cache lock/pin、latch:shared pool等。比如: