判断RAC节点负载是否均衡,应重点分析AWR中RAC Statistics部分的GC块收发统计(如gc cr blocks received/served),而非仅看CPU或会话数;接收远大于服务表明被动拉数据,服务远大于接收则为热点持有者;需结合gv$sysstat实时对比、等待事件(如gc buffer busy acquire)及跨节点通信延迟交叉验证。

怎么看 RAC 节点负载不均:别只看 CPU 和会话数
AWR 报告里“Instance Activity Stats”里的 CPU 使用率或当前会话数(logons current)不能直接判断 RAC 负载是否均衡。真正暴露不均的,是节点间协同开销的失衡——比如某节点收得多、发得少,或长期充当“中转站”,自己没干多少活却在疯狂收发 GC 块。
实操建议:
- 必须翻到 AWR 报告中的 RAC Statistics 部分(不是 Instance Activity Stats),这里才有 per-instance 的全局缓存统计
- 重点关注四列:
gc cr blocks received、gc current blocks received、gc cr blocks served、gc current blocks served - 接收多但服务少 → 该节点本地缓存/计算资源不足,被动拉数据;服务多但接收少 → 它是热点数据持有者,被其他节点频繁请求
- 单看总量没意义:4 节点的
gc cr blocks received若为 100k / 95k / 110k / 20k,第 4 节点就是异常点,标准差比平均值更有诊断价值
为什么 AWR 的 “Interconnect Traffic per Second” 不可信
这个表格给出的字节数是估算值,不能用来判断节点间流量是否偏斜。它基于默认块大小(8KB)× 块数推算,但真实 UDP 包含 IP/UDP/以太网头部,实际线缆字节数高 15%–20%,且混杂 CSSD 心跳、OCR 同步等非 GC 流量。
实操建议:
- 用
iftop -P udp -f "host 169.254.x.x and host 169.254.y.y"在每个节点上实时观察双向流量,盯发送/接收速率是否严重偏离均值(如某节点发送量是其他节点的 3 倍以上) - 查
gv$sysstat实时对比各节点 GC 流量分布:SELECT inst_id, name, value FROM gv$sysstat WHERE name IN ('gc cr blocks received','gc current blocks received','gc cr blocks served','gc current blocks served') - 务必带上
inst_id过滤,否则sum()会把所有节点数据合并,掩盖真实偏斜 - 理想情况下,各节点
received总和应 ≈served总和;若某节点received >> served,说明它正被“喂数据”,可能因 SQL 绑定不均或本地资源瓶颈
如何交叉验证 GC 流量异常是否真导致性能问题
GC 流量高 ≠ 性能差。关键要看等待事件是否同步恶化,以及延迟是否真实升高。比如 gc buffer busy acquire 占比仅 1.2%,但平均等待 18 ms 且只由 7 个活跃会话触发,就基本锁定 RAC 热点块争用;而 gc cr block lost 频发,则要查 TCP_RECEIVE_SIZE_MAX 是否与 GLOBAL_RECEIVE_SIZE_MAX(默认 4MB)不匹配。
实操建议:
- Top 5 Timed Foreground Events 中,若出现
gc current block busy或gc buffer busy acquire,立刻下钻DBA_HIST_ACTIVE_SESS_HISTORY,按inst_id和event过滤,确认是否集中在单一节点 - 查
gv$sysstat中gc receive time和global enqueue get time,这两个隐藏指标更能反映跨节点通信的真实延迟 - 对比
log file sync和log file parallel write的 Avg Wait (ms):前者远高于后者,说明问题不在存储,而在应用提交频率或 Data Guard SYNC 配置 -
enq: TX - row lock contention若 Wait Time 占 DB Time >1%,哪怕只排第 9,也得手动搜enq:并结合DBA_HIST_ACTIVE_SESS_HISTORY下钻阻塞链
容易被忽略的内存与缓存层误导点
节点内存使用率不均常被误读为“负载不均”,但 80% 以上是 SGA/PGA 分配偏差、OS 非 Oracle 进程或共享内存段残留所致。更危险的是:盲目调大 db_cache_size 可能制造新瓶颈——比如节点 1 SGA 暴涨挤压 shared_pool,引发大量硬解析和 ORA-4031,CPU 升高、GC 等待飙升。
实操建议:
- 查
gv$memory_dynamic_components确认 DEFAULT buffer cache 实际分配,对比各节点值是否偏离超 2 倍;若某节点明显偏高,先查是否启用了 AMM(memory_target),此时手动设db_cache_size会被忽略 - 跑
SELECT SUM(pga_used_mem)/1024/1024/1024 FROM gv$process算各节点 PGA 实际用量,注意是gv$process,不是v$process - 查 OS 层
ps aux --sort=-%mem | head -20,特别留意 Python/Java/备份脚本等常驻进程;再用ipcs -m检查 hugepage 段是否残留 - RAC 中
buffer cache hit ratio失效:一个节点显示 95%,但其中 40% 的“命中”是从其他节点拉 CR 块来的,不算真高效;更应关注physical reads direct占比——太高说明全表扫描绕缓存,调db_cache_size没用
真正卡住排查节奏的,往往不是指标看不懂,而是忘了 inst_id 这个前缀——漏掉它,所有 gv$ 视图都变成单实例视角,跨节点争用瞬间隐身。


















