mlog$_表不可随意删除,必须先通过dba_registered_snapshots和dba_mview_logs确认无活跃依赖;重建须用drop materialized view log on owner.table_name,禁用truncate/drop table;重建后须立即收集统计信息、重建snaptime$$/sequence$$索引,并确保with子句参数匹配原刷新逻辑。

确认MLOG$_表是否真能删,不能只看物化视图是否存在
物化视图被删了,不代表日志就能动——MLOG$_表可能还在被其他物化视图共享引用。硬删会导致后续刷新报ORA-12003或ORA-12083。必须交叉查两个系统视图:
– SELECT * FROM DBA_REGISTERED_SNAPSHOTS WHERE LOG_OWNER = 'SCHEMA_NAME' AND LOG_NAME = 'MLOG$_TABLE_NAME':返回空才说明没 MV 正在注册使用该日志
– SELECT LOG_TABLE, MASTER, ROWIDS, PRIMARY_KEY FROM DBA_MVIEW_LOGS WHERE LOG_TABLE = 'MLOG$_TABLE_NAME':确认该日志未被其他 MV 共享(注意多个 MV 可共用一个日志)
任一查询有结果,都代表还有活跃依赖,此时重建日志会失败或引发刷新异常。
重建前必须用DROP MATERIALIZED VIEW LOG,禁用TRUNCATE/DROP TABLE
TRUNCATE TABLE sys.mlog$_xxx看似快,但会残留段头元信息,后续插入可能触发ORA-00604;DROP TABLE sys.mlog$_xxx直接破坏数据字典,再建同名日志大概率报ORA-12083。正确做法是:
– 指定基表名,不是日志表名:DROP MATERIALIZED VIEW LOG ON owner.table_name
– 跨 schema 必须写全:DROP MATERIALIZED VIEW LOG ON scott.emp
– 执行前确保基表无长事务,否则操作会被阻塞(锁等待超时常见于高并发DML场景)
重建日志时WITH子句参数必须匹配原刷新逻辑
重建不是简单照搬旧语句。关键参数要对齐实际使用需求:
– 如果原物化视图走FAST刷新且依赖主键变更,必须含WITH PRIMARY KEY
– 如果涉及UPDATE/DELETE捕获旧值,INCLUDING NEW VALUES不可省略,否则增量失效
– 若物化视图SQL中引用了特定列(如用于JOIN或FILTER),这些列必须显式加入SEQUENCE(col1, col2)
– 多个物化视图共享日志时,所有MV定义中涉及的列都要覆盖到,否则某个MV刷新会静默退化为COMPLETE
示例:CREATE MATERIALIZED VIEW LOG ON scott.emp WITH PRIMARY KEY, SEQUENCE(empno, deptno, sal) INCLUDING NEW VALUES;
重建后三件事不做,等于白干
删完、重建完不补这三步,刷新照样慢、空间照样涨:
– 立即收集统计信息:DBMS_STATS.GATHER_TABLE_STATS('SCHEMA_NAME', 'MLOG$_TABLE_NAME'),否则优化器仍走全表扫描
– 重建关键索引:CREATE INDEX idx_mlog_snap_seq ON mlog$_xxx (snaptime$$, sequence$$),这是FAST刷新性能命脉
– 若空间未释放,mlog$_xxx不支持SHRINK SPACE,只能导出数据 → DROP MATERIALIZED VIEW LOG ON owner.table_name → 重建日志
最常被跳过的是索引重建和统计信息更新——日志行数少了,但没索引+过期统计,刷新时照样全表扫描+磁盘排序。











