awr报告中db cpu总和高不等于负载均衡,需按实例计算db cpu/ cpu count比率(>0.8为真饱和),并结合gv$sql、gv$session、scan监听器负载字段及gc块收发比定位单节点cpu高根源。

AWR报告里看到DB CPU总和高,不等于节点负载均衡——真正的问题往往藏在实例级指标割裂、服务配置失配或客户端连接行为异常中。
看DB CPU占比前先算真实饱和度
直接比各节点DB CPU秒数会误导:节点1占70%可能只是因为它的cpu_count是节点2的两倍。必须交叉验证:
- 查每个节点CPU核数:
SELECT value FROM gv$parameter WHERE name = 'cpu_count' AND inst_id = 1 - 查某时段各节点DB CPU(秒):
SELECT inst_id, round(value/1000000, 2) cpu_sec FROM gv$sysmetric_history WHERE metric_name = 'DB CPU' AND begin_time > SYSDATE-1/24 - 算比率:
DB CPU (sec) / cpu_count> 0.8 才算真饱和;低于0.5却持续高等待,大概率是GC或锁阻塞导致CPU空转
确认是否真有SQL绑定到单节点
不能只信“SQL ordered by CPU Time”汇总页——它把所有实例执行堆在一起。关键动作是:
- 进AWR报告的
SQL Statistics → SQL ordered by Elapsed Time,点开每条SQL的Instance Detail链接,看executions和cpu_time在各节点分布 - 查
gv$sql确认分布:SELECT inst_id, executions, cpu_time/1000000 cpu_sec, buffer_gets FROM gv$sql WHERE sql_id = 'abc123xyz' ORDER BY inst_id - 检查
gv$session里service_name和inst_id是否强关联——某些应用用TNS alias硬编码了INSTANCE_NAME,绕过了服务层负载均衡
检查服务注册与SCAN监听器负载字段
哪怕客户端写了LOAD_BALANCE=on,如果服务没在多个实例上注册带负载数据,连接照样全打首节点:
- 运行
lsnrctl status LISTENER_SCAN1 | grep -A 10 "Service \"your_service_name\"",输出中必须出现load=42这类字段,否则PMON没上报或REMOTE_LISTENER指向错误 - 确认每个实例
REMOTE_LISTENER指向SCAN地址(如scan.example.com:1521),不是VIP或localhost - 改完
REMOTE_LISTENER后,立刻在每个实例执行ALTER SYSTEM REGISTER;否则可能延迟数分钟才更新负载信息
盯住GC黑洞节点的接收/服务比
单节点CPU高常是结果而非原因——它可能正被其他节点疯狂“拉块”,变成GC黑洞:
- 查实时GC分布:
SELECT inst_id, name, value FROM gv$sysstat WHERE name IN ('gc cr blocks received','gc cr blocks served') AND inst_id = 1 - 若某节点
gc cr blocks received远大于gc cr blocks served(比如3:1),说明它被动接收多、主动服务少,已是瓶颈节点 - 配合
iftop -P udp -f "host 169.254.x.x"观察私网流量:该节点接收速率是其他节点3倍以上即为异常,此时net.core.rmem_max过小(gc cr block lost
最容易被忽略的是:AWR快照间隔太长(比如1小时)会掩盖短时尖峰,而RAC中GC拥塞、CSSD心跳延迟、UDP重传飙升都是秒级事件;生产环境建议设为15–30分钟,并用ASH补采样验证。











