必须交叉验证DBA_REGISTERED_SNAPSHOTS和DBA_MVIEW_LOGS两个视图确认无物化视图引用后,再用DBMS_MVIEW.PURGE_LOG安全清理,并立即收集统计信息、重建snaptime$$/sequence$$索引,否则刷新性能断崖下跌。

不能直接 TRUNCATE 或 DELETE sys.mlog$_xxx 表,否则刷新会中断、空间很快回涨、甚至触发 ORA-00604 或 ORA-12083。
怎么确认日志表是否真能清理?
必须交叉验证两个视图,缺一不可:
-
SELECT 1 FROM DBA_REGISTERED_SNAPSHOTS WHERE LOG_OWNER = 'SCHEMA' AND LOG_NAME = 'MLOG$_TABLE_NAME'—— 若无返回,说明没有物化视图正在注册使用该日志 -
SELECT LOG_TABLE, MASTER, ROWIDS FROM DBA_MVIEW_LOGS WHERE LOG_TABLE = 'MLOG$_TABLE_NAME'—— 确认该日志未被其他物化视图引用;多个 MV 可共享一个日志,得逐个核对LOG_TABLE和LOG_OWNER
只查 DBA_MVIEWS 是无效的,它不记录日志绑定关系。
用 DBMS_MVIEW.PURGE_LOG 安全清旧数据
这是唯一支持在线、分批、不锁表的官方方式,且会同步更新 snaptime$$ 标记,避免后续刷新继续写入已清理区间:
- 保留最近 7 天:
BEGIN DBMS_MVIEW.PURGE_LOG('MASTER_TABLE', 7); COMMIT; END; - 按年份清理(如清 2023 年前):需 PL/SQL 循环调用,每次传固定天数并
COMMIT,防止 UNDO 撑爆 - 严禁
DELETE FROM mlog$_xxx WHERE snaptime$$ —— 全表扫描 + 全表锁 + 长事务阻塞风险极高
清理后必须立刻补的三件事
否则刷新性能会断崖下跌,甚至变慢十倍:
- 立即收集统计信息:
DBMS_STATS.GATHER_TABLE_STATS('SCHEMA_NAME', 'MLOG$_TABLE_NAME'),否则优化器仍走全表扫描 - 检查并重建关键索引:
CREATE INDEX idx_mlog_snap_seq ON mlog$_xxx (snaptime$$, sequence$$)—— 这是 FAST 刷新定位增量记录的唯一高效路径 - 若空间仍未释放:
sys.mlog$_xxx不支持SHRINK SPACE,只能导出数据 →DROP MATERIALIZED VIEW LOG ON owner.table_name→ 重建日志
真正卡住人的,从来不是日志表有多大,而是清理后忘了建索引、没更新统计信息、也没确认 snaptime$$ 是否被所有活跃 MV 正确消费。











