ITPub博客

首页 > Linux操作系统 > Linux操作系统 > 从一个小程序脚本看DB Time

从一个小程序脚本看DB Time

原创 Linux操作系统 作者:realkid4 时间:2013-11-17 11:51:45 0 删除 编辑
 

Oracle 10g开始,Oracle数据库开始进入性能度量收集、自诊断、智能调整阶段。应该说,就数据库本质特性而言,9i奠定了基础结构,之后一直到11gOracle的体系结构就没有发生本质性的变化。

各种Oracle10g新特性中,笔者认为比较吸引人的特性是ASMMAWR基础信息库。ASMMAutomatic Shared Memory Managment)让DBA从设置多大的内存池的纠结问题中解放出来。而AWR就是Statspack的“转正”版本,为调优人员发挥作用奠定基础。

AWRAutomatic Workload Repository)建立在Oracle内部的性能度量基础上。在Oracle运行过程中,我们可以通过很多视图来查看数据库的“real time”情况。例如v$session可以看到数据库会话情况,v$sqlv$sqlarea记录了当前shared pool中缓存SQL语句和执行计划情况,v$sysstat记录了系统启动至今的诸多等待事件信息。而AWR就是以特定的间隔频率(默认为一小时),将其记录保存为一系列的Snapshot,从而便于日后诊断的工具。

使用AWR最方便最快捷的方法就是使用Oracle提供的AWR报告生成接口,它是我们可以找到的性能分析、对比报告。应该看到,虽然AWR提供了数据库特定时间区间详细的数据情况,但是很多个性化的分析需求还是不能满足的。

应该看到,AWR本质上是建立在对性能数据的周期性收集上。对我们而言,AWR基础库是一个非常宝贵的信息资源,用好这个资源,可以帮助我们以更好的方式进行性能分析。一些自定义的工具,也是基于AWR库的基础信息。

但是,AWR报告的生成过程是通过调用数据库自身加密存储过程实现的。很多细节和数据选择规律,都是对我们封闭的。当我们进行数据选取时候,要注意指标的含义和度量,避免选择错误。

1DB Time

问题起源自笔者想进行的一个分析,希望将一周内每个小时(或者每几个)的DB Time抽取出来,形成一个关于DB Time变化趋势的图形,从而查看数据库应用负载变化趋势。

AWR报告分析中,DB Time是首先需要分析的指标。Elapse TimeDB Time也是AWR初学者需要看的第一个重要分析情况。

所谓Elapse Time,就表示生成AWR报告过程中,两个Snapshot镜像之间的时间差。这个值体现的是性能基准,就是告诉分析人员,选择分析的期间是多长时间。

DB Time的概念应该说是很多的。在AWR中的DB Time表示的前台服务进程调用消耗时间,也就是user-level调用。数据库的消耗包括两个层面,一个是前台应用消耗,就是我们连接的应用,比如应用程序访问的消耗。而后台消耗,就是后台进程background process的工作消耗。DB Time应该说是我们分析应用性能消耗的重要考量指标。

但是,单纯的看待DB Time是不行的。因为数据库并行的存在,多个user process是可以并行的。DB Time在计量所有Process度量的时候,是要和CPU的个数相匹配。比较常用的公式是DB TimeElapse Time * CPU_Count相对比。如果DB Time接近乘积值,就表示数据库应用负载(注意是应用负载)很高。反之,就表示数据库比较空闲。

2、第一版脚本

回到问题本身。直接使用AWR报告,肯定不能实现只分析DB Time的目的。所以一个思路是挖掘(mineAWR基础信息库,从里面抽取出来。

AWR库视图是有特征的,代表是以dba_hist_作为前缀。数据库实时的性能视图,在AWR库中的对应物基本是同名的。比如我们常用的v$sysstat,对应在AWR库里面就是dba_hist_sysstat

自定义AWR程序脚本,都需要围绕视图dba_hist_snapshot。这个视图记录了每次进行AWR Snapshot生成的信息。应该说,这个视图是AWR的核心。DB Time信息从哪里找呢?

首先想到的是v$sysstat视图,里面的stat_namekey-value方式记录了很多度量。其中有一个项目就是DB time

于是,第一版脚本生成了。

select snap_id, snap_time, value, v, (value-v) from(

select snap_id, snap_time, value , (lag(value) over (order by snap_id)) v from

(select sp.snap_id, to_char(begin_interval_time,'yyyy-mm-dd hh24:mi:ss') snap_time, value

from dba_hist_snapshot sp, dba_hist_sysstat sy

where sp.snap_id=sy.snap_id

  and sp.instance_number=sy.instance_number

  and sp.begin_interval_time>=to_timestamp('2013-11-09 00:00:00','YYYY-MM-DD hh24:mi:ss')

  and sp.begin_interval_time

  and sy.stat_name='DB time'

  --and mod(sp.snap_id,2)=0

order by sp.snap_id));

通过begin_interval_time来定位选取时间片段的范围,通过stat_name确定选取的度量名称。注意,度量中的value记录的是一个累计值,而非期间值。所以使用前后snapshot之间相减的方法进行求差。

整理结果片段如下:

SNAP_ID

SNAP_TIME

VALUE

V

(VALUE-V)/60/1000000

6967

2013/11/9 1:00

740280500

739899753

380747

6968

2013/11/9 2:00

740766773

740280500

486273

6969

2013/11/9 3:00

741324347

740766773

557574

6970

2013/11/9 4:00

741700063

741324347

375716

6971

2013/11/9 5:00

742080734

741700063

380671

似乎存在问题。笔者的系统是一个典型的OLAP系统,夜间从2-3点进行ETL动作。这个时间段的DB Time最多是可以理解。其他时候访问量很少,而且负载不会很高。

结果的时间片中,时间分布比较均匀。虽然在高负载时间段中有起伏,但是起伏幅度不够。

另一个层面,就是度量。根据官方资料介绍,DB Time对应的是microsecond,也就是百万分之一秒。无论如何高峰时间也不能对应上这个取值。

之后,笔者选取了一个小时的snapshot,生成AWR正式报告。看到提取的时间。

Snap Id

Snap Time

Sessions

Cursors/Session

Begin Snap:

7111

15-11-13 02:00:36

50

4.0

End Snap:

7112

15-11-13 03:00:40

60

3.4

Elapsed:

 

60.07 (mins)

 

 

DB Time:

 

17.03 (mins)

 

 

一小时内运行的DB time17分钟。而对应的snapshot信息很难对应到17分钟。

SNAP_ID

SNAP_TIME

VALUE

V

(VALUE-V)

7111

2013/11/15 1:00

797983510

7112

2013/11/15 2:00

798476477

797983510

492967

3、第二个脚本

问题可能出现的是两个方面,一个是笔者选取的视图位置有问题。另一个笔者对指标取值的分析解析错误。

后者可能性不大。虽然AWR解析资料库是在后台加密情况下完成,但是特殊的解析算法没有过多的意义。

视图位置问题,只有一种可能:就是AWR选择这个DB Time而非v$sysstat中的DB Time

在度量Oracle过程中,方法论也有很多流派过程。从最早的Hit Rate,到现在的Event Based,相同的数据库度量概念,曾经被赋予不同的度量含义。

Oracle曾经提出过一个system time model的概念,基于视图sys_time_model。笔者猜想是不是AWR选取的是这个模型里面取值呢?

SQL> desc dba_hist_sys_time_model

Name            Type         Nullable Default Comments

--------------- ------------ -------- ------- --------

SNAP_ID         NUMBER                                

DBID            NUMBER                                

INSTANCE_NUMBER NUMBER                                 

STAT_ID         NUMBER                                

STAT_NAME       VARCHAR2(64)                          

VALUE           NUMBER       Y                        

修改的第二个版本脚本。

select snap_id, snap_time, value, v, (value-v)/60/1000000 from(

select snap_id, snap_time, value , (lag(value) over (order by snap_id)) v from

(select sp.snap_id, to_char(begin_interval_time,'yyyy-mm-dd hh24:mi:ss') snap_time, value

from dba_hist_snapshot sp, dba_hist_sys_time_model sy

where sp.snap_id=sy.snap_id

  and sp.instance_number=sy.instance_number

  and sp.snap_id in (7111, 7112)

  and sy.stat_name='DB time' 

order by sp.snap_id));

结果:

SNAP_ID

SNAP_TIME

VALUE

V

(VALUE-V)/60/1000000

7111

2013/11/15 1:00

3.24849E+11

7112

2013/11/15 2:00

3.25871E+11

3.24849E+11

17.02656

出现期望的17.02分钟。对应的转换公式也是百万分之一秒转换。

4、结论

问题解决了。有几个方面需要额外说明:

首先,使用db_hist_sysstat不适应的情况,目前只发现在DB Time中存在。其他经常统计的指标,如redo sizehard parse (count)之类的,依然可以使用这个视图。

另外,db_hist_sysstat中的DB Time,笔者认为是一个累计时间,也就是前后台进程累积的度量情况。而非我们目前已经接受的前台应用时间。

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/17203031/viewspace-776773/,如需转载,请注明出处,否则将追究法律责任。

下一篇: PL/SQL与DDL语句
请登录后发表评论 登录
全部评论
求道~

注册时间:2010-11-30

  • 博文量
    545
  • 访问量
    7631172