主键列被删或修改后mlog$_表立刻失效,因日志元数据未同步更新,primary_key仍为'y'但实际不可用;须先验证主键状态与日志依赖,再drop并重建日志,且with子句须匹配当前主键或rowid机制。

主键列被删或修改后,MLOG$_表立刻失效
基表执行 ALTER TABLE ... DROP PRIMARY KEY 或 MODIFY 主键列类型(如 NUMBER(10) → NUMBER(12)),物化视图日志不会自动更新,DBA_MVIEW_LOGS.PRIMARY_KEY 仍为 'Y',但实际已不可用。后续 REFRESH FAST 会静默退化为 COMPLETE,甚至报 ORA-12054。
验证方式:查 SELECT CONSTRAINT_NAME, STATUS FROM DBA_CONSTRAINTS WHERE TABLE_NAME = 'YOUR_TABLE' AND CONSTRAINT_TYPE = 'P',必须有 ENABLED 的主键;再查 SELECT PRIMARY_KEY FROM DBA_MVIEW_LOGS WHERE MASTER = 'YOUR_TABLE',若返回 'Y' 但主键已不存在,说明日志元数据断裂。
- 不能只重建主键——必须先
DROP MATERIALIZED VIEW LOG ON owner.table_name - 重建日志时,
WITH PRIMARY KEY才有效;若主键已删,只能改用WITH ROWID(前提是基表非 IOT) - 如果原物化视图定义含
REFRESH FAST ON COMMIT,主键失效会导致提交直接报ORA-12008
分区键列参与主键时,物化视图日志必须显式包含该列
Oracle 要求:若主键含分区键列(如 (id, part_date),且 part_date 是分区键),该列必须出现在物化视图日志的 SEQUENCE() 列表中,否则 EXPLAIN_MVIEW 会标记 REFRESH_FROM_LOG_AFTER_INSERT 为 DISABLED,FAST 刷新不可用。
常见错误是建日志时只写 WITH PRIMARY KEY,没加 SEQUENCE(part_date),导致 SPLIT PARTITION 或 EXCHANGE PARTITION 后增量变更无法捕获。
- 正确写法:
CREATE MATERIALIZED VIEW LOG ON t WITH PRIMARY KEY, SEQUENCE(part_date) INCLUDING NEW VALUES - 若分区键列未在物化视图
SELECT中出现,FAST 能力也会被禁用,即使日志里有它 -
INCLUDING NEW VALUES必须显式声明,否则EXCHANGE后新分区数据不进日志
主键变更后,物化视图本身可能变 INVALID
主键被删或重命名,物化视图元数据中仍引用旧主键列名,下次访问(查询、刷新、COMPILE)时触发依赖解析失败,DBA_MVIEWS.STATUS 变为 'INVALID',此时 COMPILE 会报 ORA-04063,不是修复手段。
关键区别:STATUS = 'INVALID' 是编译态失败,STALENESS = 'UNUSABLE' 是刷新能力失效——二者常共存,但处理顺序不能错:先解决 INVALID,再处理 UNUSABLE。
- 先确认基表当前主键结构是否与物化视图定义兼容,不兼容就需
CREATE OR REPLACE MATERIALIZED VIEW - 若物化视图含聚合或
JOIN,主键变更后可能需重写逻辑,不能仅靠COMPILE -
DBA_MVIEWS.STALENESS_REASON字段常为空,真正线索在EXPLAIN_MVIEW输出的CAPABILITY_NAME和RELATED_TEXT
重建日志前必须确认无共享依赖
一个 MLOG$_xxx 表可能被多个物化视图共享。主键变更后若直接 DROP TABLE MLOG$_xxx 或 TRUNCATE,其他依赖该日志的物化视图刷新会报 ORA-12003 或 ORA-12083。
安全检查两步缺一不可:
-
SELECT * FROM DBA_REGISTERED_SNAPSHOTS WHERE LOG_OWNER = 'SCHEMA' 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 共享 - 跨 schema 操作必须写全限定名:
DROP MATERIALIZED VIEW LOG ON scott.emp,不能只写表名
最易忽略的是:基表有长事务未提交时,DROP MATERIALIZED VIEW LOG 会被阻塞,等待超时后看似成功实则未生效——需结合 V$SESSION_BLOCKERS 排查。











