move操作导致物化视图日志失效,因其重置rowid、清空dba_mview_logs中rowids字段并破坏数据字典一致性,使fast刷新失败;必须drop而非truncate或drop table日志表,并重建with rowid及索引等。

需要重建。MOVE操作(包括ALTER TABLE ... MOVE、MOVE PARTITION)会重置基表的物理结构,导致原有物化视图日志(MLOG$_xxx)与基表元数据脱节,后续FAST刷新必然失败。
为什么MOVE后日志失效?
物化视图日志依赖基表的ROWID稳定性及数据字典中的一致性快照。MOVE操作会:
- 生成全新段、重分配所有行的ROWID,而MLOG$_xxx中仍存旧ROWID指向已不存在的物理位置
- 清空基表的DBA_MVIEW_LOGS中ROWIDS字段值(查SELECT ROWIDS FROM DBA_MVIEW_LOGS WHERE MASTER = 'TABLE_NAME'会返回N)
- 导致DBMS_MVIEW.EXPLAIN_MVIEW报告FAST_REFRESHABLE = 'NO',错误码常为ORA-12054或ORA-12015
MOVE后不重建日志的典型错误现象
执行DBMS_MVIEW.REFRESH('mv_name', 'F')时:
- 刷新静默退化为COMPLETE,无报错但性能骤降
- 查询DBA_MVIEWS.STALENESS显示'UNUSABLE'而非'STALE'
- 日志表MLOG$_xxx中SNAPTIME$$持续不更新,SELECT COUNT(*) FROM MLOG$_xxx长期为0,即使基表有DML
- V$SESSION_WAIT中可见enq: TX - row lock contention或db file sequential read在日志表上长时间等待
重建日志的实操要点
必须用DROP MATERIALIZED VIEW LOG ON owner.table_name,不能TRUNCATE或DROP TABLE日志表:
- TRUNCATE TABLE MLOG$_xxx残留段头信息,后续插入触发ORA-00604
- DROP TABLE MLOG$_xxx破坏数据字典,再建同名日志大概率报ORA-12083
- 重建语句必须显式包含WITH ROWID(MOVE后ROWID已变,不可省略)
- 若原日志含SEQUENCE(col1, col2),重建时需保持列列表完全一致,否则共享该日志的其他物化视图刷新会失败
- 执行前确认基表无长事务:SELECT blocking_session, sql_id FROM v$session WHERE event = 'enq: TX - row lock contention'
重建后必须立即补的三件事
否则日志“存在但无效”:
- 收集统计信息:DBMS_STATS.GATHER_TABLE_STATS('SCHEMA_NAME', 'MLOG$_TABLE_NAME'),否则优化器对日志扫描走全表
- 重建snaptime$$和sequence$$索引:CREATE INDEX idx_mlog_snap_seq ON MLOG$_TABLE_NAME (snaptime$$, sequence$$)
- 验证是否被其他物化视图共享:SELECT * FROM DBA_REGISTERED_SNAPSHOTS WHERE LOG_OWNER = 'SCHEMA_NAME' AND LOG_NAME = 'MLOG$_TABLE_NAME',非空则需协调所有依赖方同步调整
MOVE是物理操作,日志不是元数据附属品——它和基表一样需要被当作独立对象重新对齐。漏掉任一环节,FAST刷新就只是个摆设。











