DBMS_REDEFINITION 是 Oracle 12c+企业版在线将普通表转分区表的唯一可靠方式;ALTER TABLE MODIFY PARTITION BY 易失败,禁用。需确保主键无 DEFAULT 值、禁用 MV Log/审计等干扰项,中间表字段定义须完全一致、分区键不可加 NOT NULL、不手动建索引;START 后必须定期 SYNC 再 FINISH,COPY_TABLE_DEPENDENTS 需显式设置 COPY_INDEXES=>1 并手动补 MV Log。

DBMS_REDEFINITION 是 Oracle 12c 及以上企业版中唯一能真正在线完成普通表转分区表的可靠方式;ALTER TABLE MODIFY PARTITION BY 在多数生产场景下会静默失败或直接报错,别碰。
为什么 CAN_REDEF_TABLE 成功不代表真能重定义
执行 EXEC DBMS_REDEFINITION.CAN_REDEF_TABLE('SCHEMA', 'TABLE_NAME') 返回成功,只说明基础结构没硬性冲突。你还得手动确认:
- 表必须有主键(
ORDER_ID这类列 OK),且主键列定义里不能含DEFAULT SEQ.NEXTVAL或SYSTIMESTAMP—— 即使触发器逻辑正常,字段定义违规也会在START_REDEF_TABLE阶段崩 - 检查是否启用了物化视图日志、审计策略(
audit_policy)、DBMS_FLASHBACK_ARCHIVE或 REF 列 —— 这些会让COPY_TABLE_DEPENDENTS失败 - 临时中间表 + 原表数据 ≈ 2×原表大小;
TEMP表空间也要够(同步阶段大量排序用)
中间表建表时三个致命细节
中间表不是复制原 DDL 就完事。稍不注意,START_REDEF_TABLE 就抛 ORA-14197 或导致后续数据不一致:
- 字段定义必须完全一致:包括长度单位 ——
VARCHAR2(120)和VARCHAR2(120 CHAR)被 Oracle 视为不同类型 - 分区键列(如
ORDER_DATE)**不能加NOT NULL约束**,除非原表对应列也强制非空;否则START_REDEF_TABLE直接报错 - **不要自己建索引、约束、触发器** —— 全部交给
COPY_TABLE_DEPENDENTS同步;你手动建了,后续会冲突或丢失
START_REDEF_TABLE 后必须 SYNC_INTERIM_TABLE 才能 FINISH
很多人调完 START_REDEF_TABLE 就急着 FINISH_REDEF_TABLE,结果报 ORA-12008 或数据丢失。真实流程是:
-
START_REDEF_TABLE只启动初始快照复制,不保证实时一致性 - 业务持续写入期间,必须定期执行
SYNC_INTERIM_TABLE做增量同步(尤其大表建议每 15–30 分钟一次) - 最后一步
FINISH_REDEF_TABLE才会原子切换:锁表极短(毫秒级),把原表元数据指向新分区结构,并清理中间对象
漏掉 SYNC_INTERIM_TABLE,等于让中间表“停在半路”,FINISH 时会丢掉切换窗口内的所有变更。
COPY_TABLE_DEPENDENTS 的常见失败点
这个过程看似自动,但几个参数和状态极易踩坑:
-
COPY_INDEXES默认为 0(不复制),想保留索引必须显式传1;全局索引若没在COPY_TABLE_DEPENDENTS中列出,FINISH阶段会直接报ORA-14098 -
IGNORE_ERRORS => TRUE可绕过部分非关键错误(比如权限缺失),但不会跳过约束/索引定义冲突 - 如果原表有基于函数的索引或虚拟列上的索引,
COPY_TABLE_DEPENDENTS可能静默跳过 —— 必须事后手动验证索引状态(SELECT status FROM dba_indexes WHERE table_name = 'NEW_TABLE_NAME')
最常被忽略的是:COPY_TABLE_DEPENDENTS 不复制物化视图日志(MV Log),哪怕原表有。如果你依赖 MV Log 做 ETL,重定义后要手动重建。


















