不能直接用DBA_HIST_ACTIVE_SESS_HISTORY查昨晚备份卡顿,因其默认仅保留1小时采样且定时备份多发生在低峰期导致样本稀疏、阻塞链易断裂;应使用v$active_session_history(或RAC下gv$active_session_history)动态切片定位,并结合event与sql_id关联分析。

不能直接用 DBA_HIST_ACTIVE_SESS_HISTORY 查昨晚的备份卡顿——它默认只保留 1 小时采样,且定时备份(如 RMAN)引发的卡顿往往发生在低峰期,样本稀疏、阻塞链易断裂;必须用 v$active_session_history(或 RAC 下的 gv$active_session_history)在备份窗口内做动态时间切片,再结合 event 和 sql_id 关联定位。
为什么 DBA_HIST_ACTIVE_SESS_HISTORY 对不上昨晚的备份时间点
DBA_HIST_ACTIVE_SESS_HISTORY 是从内存视图 v$active_session_history 每 10 秒批量刷入的,保留策略通常为 1 小时。昨晚的定时备份若发生在凌晨 2:00–2:30,现在查历史表大概率已清空。即使没清空,备份期间的采样也可能因负载突增而被跳过,或因 blocking_session 字段在 19c 前版本不稳定,导致锁等待链断裂。
- 写死时间范围(如
SAMPLE_TIME BETWEEN TIMESTAMP '2026-09-27 02:00:00' AND TIMESTAMP '2026-09-27 02:30:00')基本无效:ASH 内存早没了,历史表没数据就是没数据 - 别指望靠 AWR 报告里的“ASH 数据链接”回溯:那是按快照聚合的摘要,丢失秒级精度,无法还原备份过程中某条 RMAN channel 的 I/O 等待尖刺
- 真正能查到的,只有备份当时还在内存里的那部分
v$active_session_history——但前提是你要在备份刚结束、还没被覆盖前立刻查
如果备份已结束,还能抢救吗?
能,但要换思路:不找“卡顿本身”,而是找“卡顿的痕迹”。RMAN 备份会触发大量 direct path read、db file sequential read 或 enq: TS - contention(临时表空间争用),这些事件会在 ASH 中留下密集采样特征,即使内存样本已被覆盖,也可通过关联对象和会话行为反推。
- 查
v$sql中近期执行过的 RMAN 相关 SQL:SELECT sql_id, sql_text FROM v$sql WHERE sql_text LIKE '%RMAN%',拿到sql_id后去查它的历史执行统计(elapsed_time/executions)是否在备份窗口异常放大 - 查备份时段的
gv$session_longops:SELECT * FROM gv$session_longops WHERE start_time > TRUNC(SYSDATE)-1 AND opname LIKE '%RMAN%' AND sofar != totalwork,确认是否有未完成的 longops 记录残留(说明当时确实在跑备份) - 查
gv$sysstat的增量变化:SELECT name, value FROM gv$sysstat WHERE name IN ('physical reads', 'physical writes', 'db block gets') AND value > (SELECT value FROM gv$sysstat@snapshot_before_backup)—— 需提前有备份前快照,否则只能靠 alert 日志里的时间戳比对
如何用 gv$active_session_history 定位备份中的真实卡点
RAC 环境下必须用 gv$active_session_history,否则只看到当前节点;关键不是看“谁在备份”,而是看“谁被备份拖慢了”。备份本身是后台任务,真正卡住的是前台业务会话。
- 限定时间窗口必须用动态表达式:
SAMPLE_TIME > SYSDATE - INTERVAL '5' MINUTE—— 不要用字符串时间,避免时区/格式误差 - 重点过滤三类 event:
direct path read(RMAN 通道读数据文件)、db file sequential read(控制文件/归档日志读)、enq: TS - contention(RMAN 使用临时表空间排序时争用) - 不要只盯
sql_id,同一sql_id可能对应多个sql_plan_hash_value;加current_obj#和program辅助判断,比如program = 'rman@host (TNS V1-V3)'就是 RMAN 进程 - 发现某业务 SQL 在备份窗口内连续多秒处于
session_state = 'WAITING'且event = 'direct path read',基本可断定它被 RMAN 的 I/O 带宽抢占了
备份卡顿的典型信号与误判点
很多 DBA 看到 direct path read 就以为是 RMAN 在读,其实 PL/SQL 批量插入、物化视图刷新、甚至大表 CREATE TABLE AS SELECT 也会触发。真要锁定是备份引起的,得交叉验证。
- 查
v$rman_status或v$rman_backup_job_details确认备份作业实际运行时间,和 ASH 时间戳对齐;注意字段start_time/end_time是 DATE 类型,别用 TO_CHAR 比较 -
event = 'enq: TX - row lock contention'在备份期间出现,大概率不是备份导致,而是业务事务恰好撞上备份引发的锁升级或 ITL 争用,别一锅端 - 如果
sql_id为空但program是rman,且event是control file sequential read,说明 RMAN 正在读控制文件头,属于正常开销,不算卡顿 - 最易忽略的一点:
gv$active_session_history里session_id和serial#对应的是会话,不是 RMAN channel 编号;一个 RMAN job 可能启多个 channel,每个 channel 占一个会话,需聚合统计











