真实CPU利用率需计算BUSY_TIME/(BUSY_TIME+IDLE_TIME)占比,而非看绝对值;IOWAIT_TIME飙升、LOAD持续超NUM_CPUS、PI/PO频繁交换等才是真实瓶颈信号。
awr 里 busy_time 和 idle_time 数值很大(比如几千万),不代表 cpu 忙——得算比例:busy_time / (busy_time + idle_time) 才是真实 cpu 利用率。一个 112 核的机器,busy_time=12933418、idle_time=269466546,实际利用率仅约 4.6%,远没到瓶颈。
容易踩的坑:
IOWAIT_TIME:它飙升(比如从几十跳到上万)说明 CPU 大量时间在等磁盘,此时即使 BUSY_TIME 不高,也是 I/O 卡住导致的“假性空闲”LOAD 值:如果 LOAD 持续 > NUM_CPUS(如 112),哪怕 CPU 利用率才 30%,也可能因运行队列过长引发响应延迟LOAD 和 IOWAIT_TIME 一起看,比单看 CPU% 更早暴露问题。例如 LOAD 从 4 升到 9,同时 IOWAIT_TIME 占 BUSY_TIME 比例超 5%,基本可断定是磁盘拖慢;若 LOAD 升高但 USER_TIME 占比很低(比如 1200 万 / 1293 万 ≈ 93%),说明负载集中在内核态或不可中断睡眠(D 状态),要翻 Top 5 Timed Events 查 db file sequential read 或 log file sync。
注意:LOAD 是三个值(1/5/15 分钟),如果 1 分钟值远高于 15 分钟,说明刚发生突发负载;反之则可能已持续过载。
这通常不是真没负载,而是 Oracle 解析 /proc/loadavg 失败。Linux 2.6+ 内核该文件用空格分隔(如 0.12 0.25 0.33 1/256 12345),但老版本 Oracle(如 10g R2、11.1.0.x)仍按制表符解析,导致截断失败填入 0。
实操建议:
cat /proc/loadavg 确认输出格式9789725)GV$OSSTAT 视图的 LOAD 字段(不是 LOAD_AVERAGE)AWR 默认每小时采样一次,会错过短时尖峰。比如某 SQL 每分钟跑一次、每次耗 CPU 5 秒,AWR 就可能只记到 5 秒,而实际每秒都在吃资源。
交叉验证方法:
mpstat -P ALL 1 5 抓 5 秒粒度的实时 CPU 分布adb -w 1 5(Solaris)或 pidstat -u 1 5(Linux)看 Oracle 进程瞬时占用V$SYSMETRIC:执行 SELECT value/100 FROM v$sysmetric WHERE metric_name = 'CPU Usage Per Sec',这个才是每秒 Oracle 实际占的 CPU 毫秒数真正难判断的,是那种 CPU 利用率不高但 LOAD 居高不下、且 IOWAIT_TIME 波动剧烈的情况——它往往指向底层存储响应不稳或驱动异常,AWR 看不出,得结合 iostat -x 1 和 dmesg 日志。