当前位置: 首页 > 工具软件 > MinDB > 使用案例 >

浅析oracle dbtime

郭瀚海
2023-12-01

dbtime的定义

官方定义:

This statistics represents the total time spent in database calls and is an indicator of the total instance workload. It is calculated by aggregating the CPU and wait times of all sessions not waiting on idle wait events (non-idle user sessions).


dbtime是花费在数据库上的时间,是所有实例负载的度量。dbtime=DB CPU+non-idle user sessions。db time is the time spent in the database(源自tom),这句话就很容易理解,dbtime终归是花费在数据库上的时间。

当实例启动时,dbtime就开始积累。我比较喜欢把db time理解为数据库负载的度量,但是直接查询dbtime意义并不大,我们后面来解释。


相关视图

v$sys_time_model
select value from v$sys_time_model where stat_name='DB time'
v$sys_time_model中的value(DB time)是time spent in database的总值,这个值不断的在增大,是及时的,单位是ms。这个db time跟awr中显示的db time是有差别的。awr中的db time 是2个时刻db time的差值,用于度量某一时段database的负载程度。其实一般来说把db time理解成database负载程度的度量即可,实际v$sys_time_model中的value(DB time)还是多数用来计算差值的。

dba_hist_sys_time_model
awr报告中的dbtime是怎么计算来的呢?就是来自dba_hist_sys_time_model。dba_hist_视图其实就是v$_视图的历史记录,我们找到时间段,找到snap_id,就可以查找dbtime的差值,也就可以计算那个时间段数据库的负载情况了。

dba_hist_wr_control
快照生成和保存的时间,默认是1小时,在某些环境下(比如需要更细粒度的snap,方便分析数据库),snap_interval会设置的更小

select * from dba_hist_wr_control


DBID SNAP_INTERVAL RETENTION TOPNSQL

1169591385 +00000 00:15:00.0 +00007 00:00:00.0        100

快照15分钟生成一次,保留7天


dbms_workload_repository包可以更改快照的设定

dbtime的计算


 select to_char(end_interval_time,'yyyy-mm-dd_hh24') v_date,a.instance_number inst_id,round((b.value-a.value)/1000000/60,2) v_dbtime,
round((b.value-a.value)/1000000/60/(64*60/100),2)||'%' db_cpu_pct
from dba_hist_sys_time_model a,dba_hist_sys_time_model b ,dba_hist_snapshot c
where a.stat_name='DB time' and b.stat_name='DB time' 
      and a.dbid=b.dbid and a.dbid=(select dbid from v$database)
      and a.instance_number= b.instance_number and c.instance_number=b.instance_number
      and a.snap_id=c.snap_id
      and b.snap_id=c.snap_id+1 
      and C.END_INTERVAL_TIME>=sysdate-7
      and a.instance_number=&inst_id
      order by v_dbtime desc;  


这个脚本可以直接使用,只需要输入实例号,输出哪个快照负载最高。这个脚本也是前辈留下的,由于太懒并不想仔细研究。直接执行执行试试
V_DATE INST_ID V_DBTIME DB_CPU_PCT
2017-12-24_23 2529.48 49.4%
2017-12-25_15 1117.32 21.82%
2017-12-26_09 1102.96 21.54%
2017-12-28_09 1098.52 21.46%
2017-12-26_05 1049.19 20.49%

2017-12-22_13 1006.97 19.67%

看上去好像是没问题,cpu负载也出来了,但实际上是有问题的。

还是从sql分析

v_date列是snap的结束时间

inst_id列是实例编号

v_dbtime是awr上的dbtime,因为单位是ms,需要单位换算。b.value-a.value除以100000得到s,除以60得到min

db_cpu_pct是cpu负载,用dbtime除以cpu除以时间计算得出

那么问题在哪呢?问题就在这个时间换算上,不是说sql编写有问题,而是这个sql是针对60min的dbtime来计算,而不是15min。


v_dbtime为 

round(b.value-a.value)/1000000/60,2) 

其实应该是

round(b.value-a.value)/1000000/60/4,2) 


db_cpu_pct为

round((b.value-a.value)/1000000/60/(64*60/100),2)   --(64为lcpu数,可以从v$osstat中获取,但不一定有数据,视操作系统而定)

改写为

round((b.value-a.value)/1000000/60/4/(64*15/100),2)

简化一下

round((b.value-a.value)/1000000/64*100),2)

所以db_cpu_pct的值是正确的,v_dbtime是错误的。


如果db_cpu_pct不是很懂的话,可以这样理解,设pct(60)为60min的dbtime值,pct(15)为15min的dbtime值

pct(60)=round((b.value-a.value)/1000000/60/(64*60/100),2)

=(b.value-a.value)/1000000/60/(64*60/100)

=(b.value-a.value)/64/(3.6*10^8)


pct(15)=round((b.value-a.value)/1000000/60/4/(64*15/100),2)

=(b.value-a.value)/1000000/60/4/(64*15/100)

=(b.value-a.value)/64/(3.6*10^8)


snap的interval time为15min时的dbtime计算方法应该改写一下

select to_char(end_interval_time,'yyyy-mm-dd_hh24') v_date,a.instance_number inst_id,round((b.value-a.value)/1000000/60/4,2) v_dbtime,
round((b.value-a.value)/1000000/60/4/(64*15/100),2)||'%' db_cpu_pct
from dba_hist_sys_time_model a,dba_hist_sys_time_model b ,dba_hist_snapshot c
where a.stat_name='DB time' and b.stat_name='DB time' 
      and a.dbid=b.dbid and a.dbid=(select dbid from v$database)
      and a.instance_number= b.instance_number and c.instance_number=b.instance_number
      and a.snap_id=c.snap_id
      and b.snap_id=c.snap_id+1 
      and C.END_INTERVAL_TIME>=sysdate-7
      and a.instance_number=&inst_id
      order by v_dbtime desc;  

V_DATE INST_ID V_DBTIME DB_CPU_PCT
2017-12-24_23 632.37 49.4%
2017-12-25_15 279.33 21.82%
2017-12-26_09 275.74 21.54%
2017-12-28_09 274.63 21.46%
2017-12-26_05 262.30 20.49%

2017-12-22_13 251.72 19.67%


上面的sql当然还可以简写以减少计算压力。

当我们知道cpu_pct后就知道数据库那段时间负载较高,然后就可以通过ash和awr进行进一步的分析





 类似资料: