DBMS_REDEFINITION是唯一支持在线将非分区表转为分区表的方案,因其采用双表并行同步机制,在用户持续读写时完成数据迁移与原子切换,但需满足主键约束、列类型兼容、权限充足等硬性条件。
DBMS_REDEFINITION 不是物化视图本身,而是借用了物化视图的底层机制来实现在线重定义。它不依赖物化视图对象存在,也不受物化视图刷新、主表变更或 ON COMMIT 等限制影响。真正要解决“分区交换限制”,比如普通表无法直接 EXCHANGE PARTITION(因结构不匹配、约束缺失、段未预建等),就得绕开交换,用在线重定义把整张表替换成带分区的新结构——这是更可靠、更可控的路径。
为什么不能直接用 EXCHANGE PARTITION 替换非分区表
非分区表和分区表在数据字典层级结构不同,alter table ... exchange partition 要求两个段严格满足:列顺序/类型/长度一致、约束兼容、索引可继承、统计信息可迁移,且目标分区必须已存在并为空。普通表没有分区键定义、无 partition by 元数据,强行交换会报 ora-14097: column type or size mismatch in alter table exchange partition 或 ora-14098: index mismatch on exchange。
- 即使加了相同列、建了本地索引,只要原表没声明为分区表,就无法被识别为合法交换源
-
EXCHANGE是 DDL 级别操作,全程需要排他锁,无法做到“在线” - 无法处理含
LOB、XMLTYPE、虚拟列等复杂列类型的隐式不兼容
CAN_REDEF_TABLE 检查失败的常见原因
执行 DBMS_REDEFINITION.CAN_REDEF_TABLE 报错,不是流程卡住,而是提前暴露硬性约束。最常触发的几个点:
- 表没有主键,且没显式指定
CONS_USE_ROWID—— 必须有唯一锚点,否则无法保证行映射一致性 - 用户权限不足:
SELECT ANY TABLE、CREATE ANY TABLE、EXECUTE_CATALOG_ROLE缺一不可 - 表属于
SYS或SYSTEM用户 —— 这是 Oracle 硬编码禁止的,必须导出到普通用户下再操作 - 表空间剩余空间
注意:CAN_REDEF_TABLE 成功只代表“能启动”,不代表后续每一步都稳;它不校验中间表结构是否真能承载原表全部数据(比如 NOT NULL 列在中间表里被漏写)。
中间表(interim table)建表时的关键避坑点
中间表不是简单 CREATE TABLE AS SELECT 就完事。它是重定义流程里的“新骨架”,结构错误会导致 START_REDEF_TABLE 失败或 FINISH_REDEF_TABLE 后数据错乱。
- 分区键列必须与未来分区策略强相关,例如按日期分区,
par_date列不能为NULL,且类型建议用DATE(避免TO_DATE表达式导致分区裁剪失效) - 所有原表上的
NOT NULL约束必须在中间表中显式声明,但新增列严禁加NOT NULL(否则COPY_TABLE_DEPENDENTS会失败) - 索引、约束、触发器不要手动建——交由
COPY_TABLE_DEPENDENTS自动同步,否则可能漏掉隐藏依赖(如基于函数的索引) - 如果原表有
ENABLE ROW MOVEMENT,中间表也得加上,否则大字段更新时可能报ORA-14402
SYNC_INTERIM_TABLE 什么时候必须调用
当原表在 START_REDEF_TABLE 到 FINISH_REDEF_TABLE 之间持续有 DML(尤其是高并发 UPDATE/DELETE),就必须周期性执行 SYNC_INTERIM_TABLE,否则中间表会滞后,FINISH 阶段可能因版本冲突失败或丢失变更。
- 不是“可选优化”,而是“数据一致性刚需”——尤其对日均百万级更新的业务表
- 建议在业务低峰期首次同步后,每 5~15 分钟跑一次,具体间隔看 DML 频率;可用
DBA_TAB_MODIFICATIONS监控变更量 - 该过程会短暂持有
SRX(Share Row eXclusive)锁,不影响查询,但会阻塞其他重定义操作 - 别依赖“只 sync 一次”,
FINISH_REDEF_TABLE内部其实也会做最后一次强制 sync,但前提是前面没积压太多 delta
真正难的从来不是语法,而是判断哪一步该停、哪一步该压、哪一步必须人工介入校验——比如 COPY_TABLE_DEPENDENTS 返回警告说某个函数索引被跳过,就得立刻查文档确认是否影响业务逻辑,而不是默认忽略。











