ASH不记录网络丢包,仅反映Oracle内核感知的等待结果;需将其作为“症状指示器”,结合ocssd.log心跳日志、ping延迟分布及ethtool网卡统计交叉验证丢包。

ASH 本身不记录网络丢包,查 gv$active_session_history 永远看不到 “TCP packet loss” 或 “retransmit” 这类事件——它只反映 Oracle 内核感知到的等待结果。真要定位节点间丢包,得把 ASH 当作“症状指示器”,再结合底层网络日志和系统指标交叉验证。
为什么 ASH 里找不到丢包,却还要先看它?
因为丢包会引发可观察的、带时间戳的等待毛刺,而 ASH 是唯一能秒级捕获这些毛刺的数据库视图。重点不是找“丢包”,而是找丢包引发的典型连锁反应:
-
gc buffer busy acquire在多个节点上同时激增,且time_waited分布出现大量 >5ms 的样本(正常应 - 同一时间段内,
gc cr block busy和gc current block 2-way等待事件在不同节点呈镜像式此消彼长 -
enq: TX - row lock contention出现跨实例阻塞链(blocking_instance != inst_id),但持锁会话本身 CPU 使用率极低、SQL 执行快,说明不是锁逻辑问题,而是 GC 块没及时送达
用 GV$ASH 快速筛出可疑时段和节点
别扫全表,也别依赖 AWR 报告里的笼统统计。直接跑这个查询,聚焦最近 3 分钟:
SELECT inst_id, event, COUNT(*) cnt,
ROUND(AVG(time_waited)/1000, 1) avg_ms,
ROUND(STDDEV(time_waited)/1000, 1) std_ms
FROM gv$active_session_history
WHERE sample_time > SYSDATE - 3/1440
AND event IN ('gc buffer busy acquire',
'gc cr block busy',
'gc current block 2-way',
'gc cr block busy')
GROUP BY inst_id, event
HAVING AVG(time_waited) > 5000 -- 平均等待超 5ms
ORDER BY avg_ms DESC;
如果某节点 gc buffer busy acquire 的 avg_ms 明显高于其他节点(比如 12.3 vs 其他节点平均 1.8),且 std_ms 很大(如 28.7),说明延迟抖动严重——这比稳定高延迟更指向丢包或乱序。
确认丢包后,下一步必须跳到操作系统层
ASH 只告诉你“可能丢了”,真要坐实,立刻切到节点操作系统:
- 查心跳日志:
/oracle/11.2.0/grid/log/,搜/cssd/ocssd.log CRS-1611(75% 心跳丢失)和CRS-1610(90% 丢失),多节点密集出现即铁证 - 用
ping -c 100 -i 0.1看延迟分布:>5ms 的包占比超过 5%,GC 等待必然上扬;若出现超时(timeout)行,基本可断定丢包 - 跑
ethtool -S eth2 | grep -E "(rx_discards|tx_aborted_errors|rx_errors)",只要非零,就是网卡、驱动或交换机层面的问题,和 Oracle 参数无关
最容易被忽略的是:gc buffer busy acquire 高并不等于存储慢,也不等于 SQL 写法差——在 RAC 里,它大概率是网络抖动的第一张多米诺骨牌。等你在 ASH 里看到它,网络问题通常已持续几十秒,必须立刻停止查 SQL 执行计划,转去翻 ocssd.log 和 ping 结果。











