1. oracle DB Time
1.1. DB Time
DB Time : Amount of elapsed time (in microseconds) spent performing Database user-level calls. This does not include the elapsed time spent on instance background processes such as PMON.
DB TIME:所有前台用户级调用(foreground user-level calls)花费在database上执行的时间总和,包括CPU time、IO time、cpu on queue time和其他一系列非空闲等待时间,但不包括后台进程background processes执行时间。它是数据库负载的指示灯。
DB Time = DB CPU Time(前台session调用)+ DB Wait Time(用户会话的非空闲等待:Non-Idle Wait)+ Wait on CPU queue
DB CPU Time = active user session * Elapsed Time
当前服务器逻辑CPU的数量是4,而自然流逝的时间为60分钟,也就是说CPU总共可以提供的时间为 4 * 60.17 = 240.68 分钟
。而当前CPU花费了 24.67 分钟在处理Oralce非空闲等待和运算上,这样就可以计算出CPU花费在Oracle上的负载:24.67 / 240.68 = 10.25%。
数据库负载 = DB Time / (CPUs * Elapsed)
- AWR报告中查询DB Time的SQL语句
SELECT z.* FROM (SELECT a.instance_number, a.snap_id, c.begin_interval_time + 0 AS begin_time, c.end_interval_time + 0 AS end_time, ceil((CAST(c.end_interval_time AS DATE) - CAST(c.begin_interval_time AS DATE)) * 24 * 60) AS "Elapsed TIME", ROUND(a.VALUE - LAG(a.VALUE, 1, '0') OVER(ORDER BY a.instance_number, a.snap_id)) AS "DB TIME" FROM (SELECT x.snap_id, x.instance_number, x.stat_name, SUM(x.VALUE) / 1000000 / 60 AS VALUE FROM dba_hist_sys_time_model x WHERE x.dbid = (SELECT dbid FROM v$database) AND UPPER(x.stat_name) IN UPPER('DB TIME') GROUP BY x.instance_number, x.snap_id, x.stat_name) a, dba_hist_snapshot c WHERE a.snap_id = c.snap_id AND c.dbid = (SELECT dbid FROM v$database) AND c.instance_number = a.instance_number) z WHERE z.begin_time >= SYSDATE - 7 ORDER BY z.instance_number,z.begin_time DESC;
1.2. DB CPU
DB CPU : Amount of CPU time (in microseconds) spent on database user-level calls. This does not include the CPU time spent on instance background processes such as PMON.
DB CPU:所有前台用户级调用(foreground user-level calls)database时CPU服务时间总和,不包括实例后台进程 background processes执行时间。
需要注意的是AWR是一个数据合集。比如在1分钟之内,1个用户等待了30秒钟,那么10个用户等待事件就是300秒。CPU时间也是一样,在1分钟之内,1个CPU处理30秒钟,那么4个CPU就是120秒。这些时间都是以累积的方式记录在AWR当中的。
从网上看到一个很好的例子:
假设一家理发店统计 1 小时(60.17(mins))营业情况,店内一共有4个理发师(4个CPU),顾客在理发店的累计逗留时间就是 DB TIME:24.67 (mins)。如果拿顾客累计逗留时间除以营业时间,24.67 / 60.17 = 0.41, 也就是说,在这一小时营业时间内,店内平均有 0.41 个顾客。顾客的累计逗留时间(DB TIME)不是理发师(CPU)的累计工作时间,如果两个顾客都要烫发,正巧只有一个烫发机,则其中一个顾客需要等待(CPU队列时间),这段时间理发师没有干活。所以,DB CPU 是一定会小于 DB Time的(理发师剪头发的时间一定小于顾客在店内逗留的时间)。
2. Load Profile
首先 DB Times(s) per second,它是 DB Time 与 Elapsed的比率,这个结果是指在一个自然时间秒内 DB Time 所耗费的时间。
DB Time(Per Second)= DB Time/ Elapsed Time = 24.67 / 60.17 = 0.41
其次是 DB CPU(s) per second,它表示每秒钟使用的CPU内核的平均数量(通俗的理解:1钞钟内使用了多少CPU)。理想情况下,这个值应该小于大部分时间可用的CPU核心总数,以便DB能够良好地执行。
此处有4个逻辑CPU,理论上我们每秒可以使用4秒的CPU时间,这里实际使用了不到1秒的CPU时间。
DB CPU(Per Second)= DB CPU Time/Elapsed Time = 109.34 秒/ (60.17 分钟 * 60) = 0.03
DB CPU占DB Time的比例为:(0.03 / 0.41)* 100% = 7.3%
,即DB Time中,只有 7.3% 的时间为DB CPU Time,其余为非空闲等待时间。非空闲等待占用了大量的资源。虽然这一个小时内CPU利用率只有7.3%,整体看比较低,但是不意味着数据库的负载很低,有两种情况:
-
负荷可能集中在某个时间段,这就需要我们观察每个时间段的数据库负荷。
-
数据库的瓶颈可能不在CPU,而在磁盘或者网络:
- 数据库内存较少,大部分时间消耗在磁盘的读取上,这个可以从磁盘的响应速度判断。
- 网络带宽不足,数据库要发送大量数据到客户端,在这里形成了等待。
3. Operating System Statistics
Operating System Statistics 操作系统统计信息, TIME相关的指标单位均为百分之一秒(厘秒)。其中:
NUM_CPU_SOCKETS
:物理CPU的个数NUM_CPU_CORES
:CPU的核数NUM_CPUS
:逻辑CPU的个数IDLE_TIME
:CPU处于空闲状态的时间SYS_TIME
:CPU在内核中花费的时间USER_TIME
:CPU在执行用户程序时花费的时间BUSY_TIME
:Busy_Time=SYS_TIME+USER_TIME 消耗的CPU时间片AVG_BUSY_TIME
:AVG_BUSY_TIME= BUSY_TIME/NUM_CPUSOS_CPU_WAIT_TIME
:进程等OS调度的时间IOWAIT_TIME
:CPU等待IO所用的时间
查询CPU数量的SQL语句为:
/*
-- CPU data from dba_hist_osstat
*/
col c1 heading '#|CPUs' format 999
col c2 heading '#|CPU|Cores' format 999
col c3 heading '#|CPU|Sockets' format 999
SELECT
(SELECT max(value) FROM dba_hist_osstat
WHERE stat_name = 'NUM_CPUS') c1,
(SELECT max(value) FROM dba_hist_osstat
WHERE stat_name = 'NUM_CPU_CORES') c2,
(SELECT max(value) FROM dba_hist_osstat
WHERE stat_name = 'NUM_CPU_SOCKETS') c3
FROM dual;
另外有如下公式:
BUSY_TIME + IDLE_TIME = ELAPSED_TIME * CPU_COUNT
此处 121157 + 1301802 = 1422959
60.17 * 60 * 100 * 4 = 1444080
4. Host CPU 与 Instance CPU
4.1. Host CPU(主机CPU)
Load Average begin/end:代表每个CPU的大致运行队列大小。
%User:表示CPU一共花了多少比例的时间运行在用户态空间或者说是用户进程(running user space processes)。典型的用户态空间程序有:Shells、数据库、web服务器……
计算公式如下:
%User = USER_TIME / (BUSY_TIME + IDLE_TIME) * 100
此处 %User = 89138 / (121157 + 1301802) * 100 = 6.3%
%System:表示CPU花了多少比例的时间在内核空间运行。分配内存、IO操作、创建子进程……都是内核操作。这也表明,当IO操作频繁时,System参数会很高。
计算公式如下:
%System = SYS_TIME / (BUSY_TIME + IDLE_TIME) * 100
此处 %System = 31160 / (121157 + 1301802) * 100 = 2.2%
%Idle:表示CPU处于空闲状态时间比例。
计算公式如下:
%Idle = IDLE_TIME / (BUSY_TIME + IDLE_TIME) * 100
此处 %Idle = 1301802 / (121157 + 1301802) * 100 = 91.5%
%WIO表示CPU在等待io操作完成,这个可能是io过慢或者io操作过多导致。此处为4.9%,也就是说当前的系统IO存在瓶颈 。
计算公式如下:
%WIO = IOWAIT_TIME / (BUSY_TIME + IDLE_TIME) * 100
此处 %WIO = 70083 / (121157 + 1301802) * 100 = 4.9%
3.2. Instance CPU(实例CPU)
%Total CPU,是指该实例所使用的CPU占总CPU的比例(即% of total CPU for Instance)
计算公式如下:
%Total CPU = (DB CPU + backupground cpu time) / (OS Busy Time + OS IDLE TIME) -- 注意统一时间单位
此处 Total CPU = (109.34 + 21.78) * 100 / (121157 + 1301802) * 100 = 0.9%
%Busy CPU,是指该实例所使用的CPU占总的被使用CPU的比例 (即% of busy CPU for Instance),例如:共4个逻辑CPU,其中3个被完全使用,3个中的1个完全被该实例使用,则%Total CPU= ¼ = 25%,而%Busy CPU= 1/3= 33%
当CPU高时一般看%Busy CPU 可以确定CPU到底是否是本实例消耗的,还是主机上其他程序消耗的。
计算公式如下:
%Busy CPU=(DB CPU + backupground cpu time) / OS Busy Time =(Instance CPU %Total CPU)/ (1- Host CPU
%Idle) -- 注意统一时间单位
此处%Busy CPU = (109.34 + 21.78) * 100 / 121157 * 100 = 10.8%
同时%Busy CPU = 0.921 / (1 - 0.915) = 10.8
%DB time waiting for CPU (Resource Manager) 是指当使用了resource manager限制某个用户和会话使用CPU,而产生的等待。会产生resmgr:cpu quantum等待事件,如果产生该等待事件需要和RSRC_MGR的值结合起来判断。解决方法是需要修改资源限制的plan。
5. Time Model Statistics
在 AWR 报告中,Time Model Statistics 记录了数据库用户维度(User Calls)的总时间消耗分布。
这部分信息来自:SYS.DBA_HIST_SYS_TIME_MODEL ,是通过针对前后两个采样点的差值计算得来的。
计算的SQL如下:
SELECT a.instance_number,
a.snap_id,
a.stat_name,
ROUND((b.value - a.value) / 1000000, 2) AS "Time(s)"
FROM sys.dba_hist_sys_time_model a,
sys.dba_hist_sys_time_model b
WHERE a.snap_id = &start_snap_id
AND b.snap_id = &end_snap_id
AND a.stat_name = b.stat_name
AND ROUND((b.value - a.value)/1000000,2) > 0
ORDER BY 4 DESC;