ash是唯一能秒级捕捉物化视图刷新真实负载的手段,通过实时查询v$active_session_history可精准定位on cpu、log file sync或阻塞问题,并区分刷新自身慢还是拖慢基表dml。
物化视图刷新卡在 on cpu 或 log file sync 怎么定位
ash 是唯一能秒级捕捉刷新过程真实负载的手段——v$active_session_history 每秒采样一次活动会话,比 awr 快照(默认每小时)精细得多。别等刷新结束再查,得在它跑着的时候实时盯住。
执行刷新时,立刻查:
SELECT sample_time, session_state, event, sql_id, program, blocking_session
FROM v$active_session_history
WHERE sample_time >= SYSDATE - 1/1440 -- 过去1分钟
AND (program LIKE '%DBMS_MVIEW%' OR sql_id IN (
SELECT sql_id FROM v$sql WHERE sql_text LIKE '%MERGE%MV_%' OR sql_text LIKE '%INSERT%/*+ APPEND */%MLOG%'))
ORDER BY sample_time DESC;
- 如果大量行显示
SESSION_STATE = 'ON CPU'且SQL_ID对应物化视图基表或日志表扫描,说明是 CPU 密集型计算(如大范围日志扫描、HASH JOIN 膨胀),不是 I/O 或锁问题 - 若频繁出现
event = 'log file sync',说明刷新事务提交太频繁或 REDO 写入慢,要检查是否用了ATOMIC_REFRESH => FALSE导致拆成多个小事务 -
blocking_session非空,说明刷新被其他会话阻塞(比如基表正被大事务更新并持有 TX 锁)
为什么 DBA_HIST_ACTIVE_SESS_HISTORY 查不到刷新期间的 ASH 数据
不是数据丢了,是刷新时间太短或 ASH 缓冲区溢出。Oracle 默认只保留约 1 小时的内存 ASH 数据,而 DBA_HIST_ACTIVE_SESS_HISTORY 是从内存刷到磁盘的副本,每 10 秒一次,且受 _ash_size 参数和 SGA 分配限制。
确认当前 ASH 是否覆盖目标时段:
SELECT sample_time_oldest, sample_time_newest, used_buffer_size, total_buffer_size FROM v$ash_info;
-
sample_time_oldest比你刷新开始时间还晚 → 内存里根本没采到那段数据 -
used_buffer_size / total_buffer_size > 0.9→ 缓冲区满,旧样本被覆盖,需调大_ash_size(重启生效) - 刷新耗时 DBA_HIST_ACTIVE_SESS_HISTORY,必须用
V$ACTIVE_SESSION_HISTORY实时查
ASH 里看到大量 enq: TX - row lock contention 怎么关联到物化视图
这个等待事件本身不提“物化视图”,但它常出现在 FAST 刷新的 MERGE 或 DELETE 步骤中——因为物化视图刷新会按日志里的 seq$$ 顺序逐条处理变更,若基表同一行被并发 UPDATE 多次,日志里就会积压多条记录,刷新时按序重放就必然排队等 TX 锁。
抓关键线索:
SELECT sql_id, event, p1text, p1, p2text, p2, current_obj# FROM v$active_session_history WHERE event = 'enq: TX - row lock contention' AND sample_time >= SYSDATE - 1/288; -- 过去5分钟
-
p1 = 1415072406(即 'TX')且p2是事务槽号 → 关联v$transaction找出持锁会话 -
current_obj#对应基表 OBJECT_ID → 确认是不是你的源表(查dba_objects) - 结合
sql_id去v$sql查 SQL 文本,大概率含MERGE INTO MV_...或DELETE FROM MLOG$_...
如何区分是刷新本身慢,还是它拖慢了基表 DML
ON COMMIT 模式下,物化视图刷新和基表事务绑定,但 ASH 不会直接标记“这是刷新引起的”。得靠时间线交叉验证。
分两步查:
1. 在基表高并发期,查基表 DML 的 ASH 样本:
SELECT program, event, COUNT(*) c
FROM v$active_session_history
WHERE current_obj# = (SELECT object_id FROM dba_objects WHERE object_name = 'YOUR_BASE_TABLE')
AND sample_time BETWEEN TO_DATE('2026-06-15 10:00', 'yyyy-mm-dd hh24:mi')
AND TO_DATE('2026-06-15 10:05', 'yyyy-mm-dd hh24:mi')
GROUP BY program, event
ORDER BY c DESC;
2. 同一时段,查物化视图相关 SQL:
SELECT sql_id, COUNT(*) c FROM v$active_session_history WHERE sql_id IN ( SELECT sql_id FROM v$sql WHERE sql_text LIKE '%REFRESH%' OR sql_text LIKE '%MV_%' ) AND sample_time BETWEEN ... -- 同上时间段 GROUP BY sql_id ORDER BY c DESC;
- 如果基表 DML 的
event大量是enq: TX - row lock contention,且同期有物化视图刷新的sql_id高频出现 → 刷新正在争抢同一行锁 - 如果基表 DML 的
program是应用连接池(如jdbc thin client),但event却是DFS lock handle或latch: cache buffers chains→ 刷新引发的间接争用(如日志表索引块热块)
真正难缠的是隐性耦合:物化视图日志表 MLOG$_xxx 和基表在同一表空间,刷新 INSERT 日志时触发 IO 争用,让基表 DML 的 db file sequential read 延迟上升——这种得结合 V$SYSTEM_EVENT 和存储层监控交叉判断。











