官方定义:
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意义并不大,我们后面来解释。
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 1 2529.48 49.4%
2017-12-25_15 1 1117.32 21.82%
2017-12-26_09 1 1102.96 21.54%
2017-12-28_09 1 1098.52 21.46%
2017-12-26_05 1 1049.19 20.49%
2017-12-22_13 1 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 1 632.37 49.4%
2017-12-25_15 1 279.33 21.82%
2017-12-26_09 1 275.74 21.54%
2017-12-28_09 1 274.63 21.46%
2017-12-26_05 1 262.30 20.49%
2017-12-22_13 1 251.72 19.67%
上面的sql当然还可以简写以减少计算压力。