必须先确认快照覆盖异常时段,因os指标是分钟级聚合的快照数据,非实时;若cpu或内存突增发生在快照间隔中(如14:00–15:00),仅取整点快照会漏掉峰值,需查最近快照时间点并优先选用异常前后15分钟内的连续快照对,必要时手动补采。

看Operating System Statistics前先确认快照是否覆盖异常时段
AWR的OS指标只存在于快照中,不是实时数据。如果CPU或内存突增发生在两个快照之间(比如14:00–15:00),而你只取了14:00和15:00的snap_id,就可能漏掉峰值——FREE_MEMORY_BYTES在14:32跌了20GB,但在快照里只体现为平滑下降。
实操建议:
- 用
SELECT snap_id, begin_interval_time FROM dba_hist_snapshot WHERE begin_interval_time BETWEEN SYSDATE-1 AND SYSDATE ORDER BY snap_id查最近快照时间点,优先选异常发生前后15分钟内的连续快照对 - 若默认1小时间隔不够细,手动执行
EXEC DBMS_WORKLOAD_REPOSITORY.CREATE_SNAPSHOT()补采 - RAC环境必须用
@?/rdbms/admin/awrrpti.sql按实例生成报告,否则NUM_CPUS_ONLINE和LOAD会被平均失真
FREE_MEMORY_BYTES和INACTIVE_MEMORY_BYTES走势比绝对值重要
单看FREE_MEMORY_BYTES=12.4G毫无意义。真正危险的是它持续单向下跌,且INACTIVE_MEMORY_BYTES没同步上升——说明内存没被释放,而是被进程长期占用(比如未关闭的游标、泄漏的PGA)。
常见错误现象:
-
SWAP_FREE_BYTES剩68GB,但PI和PO每秒几百KB → 内存已不足,Swap正在高频换页 -
INACTIVE_MEMORY_BYTES从30G降到5G,FREE_MEMORY_BYTES却从15G升到18G → 可能是Oracle自动释放了SGA_TARGET,需查v$memory_target_advice - Linux上
/proc/meminfo里的Active(anon)比AWR的INACTIVE_MEMORY_BYTES更敏感,怀疑泄漏时必须两边比对
IOWAIT_TIME占比超5%或LOAD > NUM_CPUS时别只查磁盘
IOWAIT_TIME本身数值低不等于安全。如果它占BUSY_TIME比例超过5%,说明CPU大量时间在等IO——这时db file sequential read等待高,大概率是存储慢,而不是SQL问题。
但更隐蔽的情况是:LOAD从4升到9,而USER_TIME占比仅12%,SYS_TIME和IOWAIT_TIME飙升 → 瓶颈在内核态或驱动层,比如网卡中断风暴、文件系统锁争用。
实操建议:
- 对比
LOAD和NUM_CPUS:若LOAD > NUM_CPUS(如NUM_CPUS=112,LOAD=120),即使CPU利用率才30%,也说明运行队列已满 - 查
v$osstat里NUM_CPU_CORES和NUM_CPUS是否相等:不等说明开了超线程,某些SQL绑定核心后会导致调度不均 -
TCP_RECEIVE_SIZE_MAX和GLOBAL_RECEIVE_SIZE_MAX不匹配(如前者1MB,后者4MB)会引发RAC节点间网络延迟,表现为gc cr block lost增多
OS指标“全正常”时更要翻ASH验证瞬时毛刺
AWR的OS统计是分钟级聚合,会抹平秒级尖峰。曾遇到FREE_MEMORY_BYTES在快照里稳定在15G,但ASH显示每分钟有3个会话因ORA-04030(内存不足)被杀——根源是某PL/SQL过程每分钟分配2GB临时内存又不释放。
所以当OS指标看似健康但业务报慢时:
- 立刻查
SELECT sample_time, session_state, event FROM v$active_session_history WHERE sample_time > SYSDATE-1/24 AND event LIKE '%memory%' ORDER BY sample_time - 重点关注
session_state = 'ON CPU'但event为空的记录,这代表纯计算消耗,不是等待 - 结合
DBA_HIST_SQLSTAT查sql_id的pga_allocated峰值,比AWR报告里的平均值更有参考价值
OS负载异常最麻烦的地方不在数据难找,而在指标之间存在隐性耦合:比如SWAP_USED_BYTES上涨会拖慢log file parallel write,进而抬高log file sync,最后让DBA误判为归档日志写慢——实际得先停掉非Oracle进程,再调Oracle内存参数。











