DBMS_REDEFINITION在线重定义本质是Oracle内部基于物化视图机制实现的预建快照+增量同步,而非手动创建物化视图;它支持普通表转分区表,能完整迁移索引、约束、触发器等依赖对象,并通过FINISH_REDEF_TABLE原子切换保障一致性。
DBMS_REDEFINITION 的在线重定义本质就是靠物化视图机制实现的,但它**不是让你手动创建物化视图**,而是 Oracle 内部用类似物化视图 prebuilt 的方式维护中间表与原表的数据一致性。所以别去查 CREATE MATERIALIZED VIEW 语法——这条路走不通,也起不到“在线重定义”的作用。
为什么不能直接用物化视图替代在线重定义
物化视图本身不支持“把一张普通表原地变成分区表”,它只能做数据快照或查询重写。你想改表结构(比如加分区键、拆分物理存储),必须走 dbms_redefinition 流程。强行用物化视图+重命名的方式,会丢失索引、约束、触发器、权限等依赖对象,且无法保证主键/唯一性约束在切换瞬间的一致性。
CAN_REDEF_TABLE 检查失败的常见原因
执行 DBMS_REDEFINITION.CAN_REDEF_TABLE 报错,基本锁定以下几类问题:
- 源表没有主键,又没显式指定
CONS_USE_ROWID—— 默认按主键校验,没主键就直接失败 - 用户权限不足:缺
SELECT ANY TABLE、LOCK ANY TABLE、EXECUTE_CATALOG_ROLE - 目标表空间剩余空间不足 —— 要求至少能放下原表 + 中间表两份数据
- 表在
SYS或SYSTEM用户下 —— 这两个 schema 明确被禁止
如何避免 FINISH_REDEF_TABLE 阶段锁表太久
FINISH_REDEF_TABLE 最后一步会短暂加 DML 锁(非 DDL 锁),但时长取决于未同步的增量数据量。容易卡住是因为前面漏做了 SYNC_INTERIM_TABLE:
- 大表建议每 10–30 分钟主动调一次
SYNC_INTERIM_TABLE,尤其在业务低峰期批量跑 - 不要等所有业务写入停了再启动
FINISH_REDEF_TABLE,那样积压的变更日志可能要同步几分钟 - 如果原表有高频
UPDATE,注意SYNC_INTERIM_TABLE不保证语句级一致性,只保证事务级最终一致
中间表建错导致 START_REDEF_TABLE 失败的关键点
中间表(interim table)不是随便建个同名分区表就行,必须严格满足:
- 列名、数据类型、长度、精度、空值性(NULL/NOT NULL)必须和源表完全一致(新增列除外)
- 新增列不能带
NOT NULL约束 —— 否则START_REDEF_TABLE直接报 ORA-12082 - 分区字段必须是源表已有列,不能是表达式(如
TRUNC(dt));范围/列表/哈希分区都支持,但间隔分区(Interval)需 11gR2+ 且注意默认分区行为 - 建表语句里不能带
NOLOGGING—— 在线重定义全程强制 logging
COPY_TABLE_DEPENDENTS 报错,其实根源早在 START_REDEF_TABLE 前就埋下了:比如中间表少了个隐藏列、索引字段顺序不一致、甚至表空间配额没给够。这些细节不逐条对齐,光看错误码很难定位。


















