物化视图刷新不进v$sql_monitor,ash是唯一实时线索;因其本质为后台pl/sql调用链,触发的底层sql不被v$sql_monitor捕获,而ash每秒采样活跃会话,可精准定位刷新卡点、退化路径及资源瓶颈。

物化视图刷新不进V$SQL_MONITOR,ASH是唯一实时线索
物化视图刷新(DBMS_MVIEW.REFRESH)本质是后台 PL/SQL 调用链,触发的底层 SQL 不会出现在 V$SQL_MONITOR 中——哪怕执行超 5 秒、状态为 EXECUTING。此时 V$ACTIVE_SESSION_HISTORY(ASH)成为唯一能抓到“正在发生什么”的窗口,因为它每秒采样一次活跃会话,不管 SQL 是否被监控视图收录。
关键前提是:数据库参数 statistics_level 必须为 TYPICAL 或 ALL;BASIC 下 ASH 停止采样,整段刷新过程在历史里“消失”。
- 刷新期间查
V$ACTIVE_SESSION_HISTORY,过滤条件必须含program LIKE '%DBMS_MVIEW%'或plsql_entry_object_id IN (SELECT object_id FROM dba_objects WHERE object_name = 'DBMS_MVIEW') - 别只看
EVENT字段——很多刷新卡点表现为ON CPU,实际是 CPU 密集型排序或哈希连接,不是真在计算,而是 PGA 不足导致反复 spill 到磁盘 -
SAMPLE_TIME要用TO_TIMESTAMP精确对齐,避免因时区或格式误判时间范围
从ASH定位FAST刷新退化为COMPLETE的证据
当 V$ALL_SQL_PLAN_MONITOR 显示某步骤卡在 TABLE ACCESS BY INDEX ROWID 且 elapsed_time 持续上涨、output_rows 几乎不动时,ASH 可交叉验证是否已退化:若同一时间段内大量采样行显示 SQL_ID 对应的是全表扫描基表(如 SELECT * FROM sales WHERE ...),而非日志表(MLOG$_SALES)扫描,则说明 FAST 已失效,Oracle 正在走 COMPLETE 路径。
常见退化诱因在 ASH 中有迹可循:
- 出现大量
enq: TX - row lock contention:说明日志表缺失SEQUENCE()或主键字段,FAST 无法构造增量 delta,被迫回退 -
event = 'direct path read'频繁且wait_time高:COMPLETE 刷新读取基表时未走缓存,直接磁盘读,常因 buffer cache 不足或表太大 -
PLSQL_ENTRY_OBJECT_ID指向DBMS_SNAPSHOT而非DBMS_MVIEW:19c 内部仍沿用旧包名,但行为一致;重点看后续调用栈中是否有SNAP_FAST_REFRESH(FAST)或SNAP_COMPLETE_REFRESH(COMPLETE)
并行刷新卡住时,ASH比V$PX_SESSION更早暴露问题
启用并行刷新(parallelism => 4, atomic_refresh => FALSE)后,若性能未提升甚至更慢,V$PX_SESSION 可能显示 Q00x 进程都在运行,但 ASH 能揭示真实瓶颈:
- 多个采样行
SESSION_ID相同、SQL_ID不同,但都卡在enq: PS - contention:说明parallel_max_servers设置过小,进程排队等并行服务进程 - 部分 Q00x 进程
EVENT = 'db file sequential read',而其他进程ON CPU:表明 I/O 成为木桶短板,并行度再高也无意义 -
WAIT_CLASS = 'Concurrency'占比突增,且P1TEXT = 'name|mode'显示'library cache lock':说明atomic_refresh => TRUE未关,TRUNCATE 仍在抢锁,所谓“并行”只是多个进程一起等锁
注意:V$PX_SESSION 只反映“有没有并行进程”,ASH 才告诉你“它们到底在干什么”。
刷新慢但没明显等待?查ASH里的“伪空闲”现象
有时 ASH 显示大量采样行为 SESSION_STATE = 'ON CPU',EVENT 为空,TIME_WAITED = 0,看起来像“纯计算”,实则是内存压力信号:
- 结合
V$PGASTAT查total PGA allocated是否接近pga_aggregate_limit:若达 90%+,说明排序/哈希区频繁溢出,CPU 时间实际花在磁盘 I/O 上 - 看
SQL_OPCODE = 6(UPDATE)或2(INSERT)的采样占比:COMPLETE 刷新中大量 DML 会触发 undo 管理开销,ASH 不体现为等待事件,但会拖慢整体节奏 -
PLSQL_ENTRY_SUBPROGRAM_ID若指向REFRESH_MV的深层子程序(如REFRESH_SINGLE_MV),且持续时间长,说明单次刷新逻辑本身复杂,可能涉及多层嵌套 MV 依赖,需检查user_mview_analysis中capable_flag = 'N'的项
这类问题最难排查,因为没有传统“等待事件”报错,但 ASH 的采样密度和字段组合能拼出完整执行画像——漏掉任何一个字段,都可能把内存耗尽误判为 SQL 写法低效。











