通过 gv$active_session_history 可定位存储网络抖动:需在 rac 环境用 gv$(非 v$),限定 3 分钟内采样,筛选 session_state='waiting' 且 event 含 db file sequential/scattered read、log file sync 或 write complete waits,重点识别同一 sql_id+event 连续 ≥3 秒密集采样,并交叉验证 i/o 指标突变、重传率升高及同存储其他库共性现象。

查 gv$active_session_history 时必须过滤 ON CPU + db file scattered/sequential read
存储网络抖动导致的写入超时,通常不会直接表现为 SQL 执行慢,而是会触发大量 I/O 等待事件,且集中在特定时间窗口。ASH 中最相关的线索是 session_state = 'ON CPU' 少、event 高频出现 db file sequential read(单块读)或 db file scattered read(多块读),尤其是伴随 write complete waits 或 log file sync 延迟升高。
关键点:
- 必须用
gv$active_session_history(RAC 环境),否则可能漏掉 IO 延迟发生在 node2 但你在 node1 上查不到 - 时间窗口要窄:用
SAMPLE_TIME > SYSDATE - INTERVAL '3' MINUTE,避免被历史噪声淹没——网络抖动往往是秒级尖刺 - 别只看平均等待时间;重点找连续 3–5 秒内同一
sql_id+ 同一event的密集采样,例如:SELECT sql_id, event, COUNT(*) cnt, MIN(sample_time), MAX(sample_time) FROM gv$active_session_history WHERE session_state = 'WAITING' AND event IN ('db file sequential read', 'db file scattered read', 'log file sync', 'write complete waits') AND sample_time > SYSDATE - INTERVAL '3' MINUTE GROUP BY sql_id, event HAVING COUNT(*) >= 3 ORDER BY cnt DESC;
识别是否真由存储网络抖动引发,而非数据库自身问题
ASH 能告诉你“等了”,但不能直接说“是网络抖动”。需要交叉验证三类信号:
- 查
v$sysmetric中的DB Block Changes Per Sec和Physical Reads Per Sec是否同步骤降,而Wait Time Per Sec(尤其是User I/O类)陡升 → 指向底层 I/O 响应变慢 - 确认
event = 'enq: TX - row lock contention'是否极少出现 → 排除锁争用干扰;若大量出现,则优先查阻塞链,不是网络问题 - 对比同一时段其他业务库(同存储后端)是否也出现类似 ASH 模式 → 若共性发生,基本锁定存储网络层
- 检查
v$iostat_file中对应数据文件的AVG_READ_TIME和AVG_WRITE_TIME是否突增(>20ms 是危险信号)
结合 OceanBase 文档中网络抖动判断逻辑做反向印证
虽然你用的是 Oracle,但存储网络抖动的底层表现和诊断思路与 OceanBase 一致:丢包、重传、专线延迟波动。Oracle 本身不暴露 TCP 层指标,但你可以从主机侧补全这一环:
- 在数据库服务器上运行:
tsar --tcp -i 1 -d20260827(注意把日期换成当天),看retran是否持续 ≥ 0.05(即 5% 重传率)超过 10 秒 - 如果重传率异常,再查该服务器到存储节点(如 NFS server、ASM diskgroup target、Exadata cell)的
ping -c 100 -i 0.1 <storage_ip></storage_ip>,观察丢包率和 jitter - 特别注意:Oracle RAC 的 voting disk 或 OCR 所在磁盘路径若也走同一网络链路,
retran高时可能连带触发cssd误判节点死亡 —— 这会放大写入超时现象
写入超时后如何快速止损,而非等 ASH 报告
ASH 是诊断工具,不是应急开关。当确认是存储网络抖动引发写入超时,优先动作不是调优 SQL,而是隔离影响面:
- 暂停非核心批处理作业:查
v$session中program包含expdp、rman、或自定义 ETL 工具名的会话,用ALTER SYSTEM KILL SESSION '<sid>,<serial>' IMMEDIATE</serial></sid>快速释放 I/O 压力 - 临时降低 LGWR 写日志频率(仅限紧急):
ALTER SYSTEM SET "_log_io_size"=512 SCOPE=MEMORY(减小每次写入量,缓解抖动期间积压) - 如果是 Exadata Cloud@Customer 环境,立即验证 NFS 可达性:
showmount -e <nfs_server></nfs_server>+rpcinfo -p <nfs_server></nfs_server>,按文档重连共享辅助 NFS - 切勿在此时收集 AWR 报告或跑 SQL Tuning Advisor —— 它们本身会加重 I/O 和 CPU,恶化抖动反馈循环
真正难的不是发现抖动,而是区分「抖动已恢复但 Oracle 还在重试」和「抖动仍在持续」。后者在 ASH 里表现为相同 sql_id 在不同分钟段反复出现高 time_waited 样本;前者则样本突然归零,但 v$session_longops 里仍有未完成的 DBMS_STATS 或备份任务卡住。这时候得去查 GV$SESSION_WAIT_HISTORY 最近 10 条记录,看最后一次等待是否已退出。











