必须显式设置ATOMIC_REFRESH=>FALSE,否则默认事务级锁导致卡死;需验证FAST刷新能力、清理残留注册与日志,避免静默退化为更慢的COMPLETE刷新。

查清谁在锁物化视图或基表
物化视图刷新卡住,本质是它执行的 DML(比如 DELETE/INSERT)和业务写入发生了锁冲突。不能直接猜,得看 v$locked_object 和 v$session 的实时快照:
- 先确认锁对象:
SELECT object_name, locked_mode FROM v$locked_object lo, dba_objects ao WHERE lo.object_id = ao.object_id—— 重点盯基表名、MLOG$_*日志表、物化视图本身的名字 - 再找锁源头:
SELECT sid, serial#, sql_id, event, blocking_session FROM v$session WHERE sid IN (SELECT session_id FROM v$locked_object)—— 如果 blocking_session 非空,且对应会话的event是enq: TX - row lock contention或library cache lock,基本就是它 - 别急着 kill:如果锁定会话正在跑一个长事务(哪怕不碰 MV 相关表),它可能占着 undo 段或回滚段资源,导致刷新事务无法推进;优先中止该业务事务,比硬 kill 更稳妥
强制解除刷新事务锁(atomic_refresh=FALSE)
默认 DBMS_MVIEW.REFRESH 走 atomic_refresh => TRUE,整个刷新包在一个事务里,DELETE + INSERT 全程加锁、写 redo/undo。对大 MV,这极易撑爆 undo 表空间并死锁。生产环境必须显式关掉:
- 手动刷新时加参数:
DBMS_MVIEW.REFRESH('MV_NAME', atomic_refresh => FALSE) - 定时作业(
DBMS_SCHEDULER或DBMS_JOB)里调用的封装过程,必须把atomic_refresh => FALSE显式传进去,不能依赖默认值 - 副作用要接受:设为
FALSE后,刷新过程会先TRUNCATE再INSERT /*+ APPEND */,物化视图会短暂为空;应用层得能容忍这个窗口期,否则需配合双读逻辑
检查 FAST 刷新是否已退化,避免“假解锁”
atomic_refresh => FALSE 只对真正支持 FAST 刷新的物化视图有效。如果日志缺失、基表被 ALTER、或定义含聚合/分析函数,Oracle 会静默退化为 COMPLETE 刷新——你改了参数,但锁没少,反而更慢更重。
- 验证能力:
SELECT fast_refreshable FROM user_mviews WHERE mview_name = 'MV_NAME'—— 必须返回FAST,不能是DIRLOADDML或UNDEFINED - 查日志有效性:
SELECT can_use_log FROM user_mviews WHERE mview_name = 'MV_NAME'—— 返回NO就说明日志已失效,FAST 刷新实际不可用 - 若已退化,得先修复日志或重建 MV,否则改参数只是掩耳盗铃
清理残留注册与堆积日志(防锁复发)
长期未刷新的远程 MV、已删但未注销的本地 MV,会让 MLOG$_* 日志持续堆积,后续刷新时扫描大量无效记录,间接拉长持锁时间,甚至触发 ORA-12034。
- 找“挂尸”MV:
SELECT owner, name, mview_site, snapid FROM dba_registered_mviews WHERE name NOT IN (SELECT object_name FROM dba_objects WHERE object_type = 'MATERIALIZED VIEW') - 先注销:
DBMS_MVIEW.UNREGISTER_MVIEW('OWNER', 'MV_NAME', 'MVIEW_SITE')——MVIEW_SITE必须大小写、端口、域名完全一致,否则报ORA-12006 - 再 purge:
DBMS_MVIEW.PURGE_MVIEW_FROM_LOG('OWNER', 'MASTER_TABLE_NAME', SNAPID)——SNAPID必须来自上一步查出的值,不是随便填的数字 - purge 前务必加锁基表:
LOCK TABLE master_table IN EXCLUSIVE MODE,防止 DML 干扰内部时间戳判断
最常被忽略的是:锁解了,但日志没清,下一次刷新照样慢、照样卡。清理注册和 purge 日志不是可选项,而是让锁问题不再复发的必要闭环。


















