dbms_redefinition是oracle唯一支持业务不中断的普通表转分区表方案;12.2+的alter table modify partition by online仅适用于单列简单分区,复杂场景仍须在线重定义。

Oracle 普通表转分区表,DBMS_REDEFINITION 是唯一能在业务不中断前提下完成的方案;12.2+ 虽支持 ALTER TABLE ... MODIFY PARTITION BY ... ONLINE,但仅适用于简单分区场景(如单列 LIST / RANGE),复杂分区策略(多列、INTERVAL、子分区、历史数据跨年范围等)仍必须走在线重定义。
DBMS_REDEFINITION.CAN_REDEF_TABLE 检查失败的常见原因
执行 DBMS_REDEFINITION.CAN_REDEF_TABLE 报错是高频卡点,不是配置问题,而是硬性约束未满足:
-
ORA-12089:源表无主键 —— 必须先加主键(ALTER TABLE ... ADD PRIMARY KEY),不能依赖唯一索引替代 -
PLS-00201或ORA-00904:当前用户缺少EXECUTE权限 —— 需 DBA 执行GRANT EXECUTE ON SYS.DBMS_REDEFINITION TO <user></user> -
ORA-23539:表正被重定义中未清理 —— 立即执行DBMS_REDEFINITION.ABORT_REDEF_TABLE,否则后续所有操作都会阻塞 - 使用
CONS_USE_ROWID方式绕过主键要求?仅限测试环境;生产中会丢失外键/约束一致性,且COPY_TABLE_DEPENDENTS无法同步触发器和权限
中间表(interim table)建表的关键细节
中间表不是“结构一致就行”,它直接决定最终分区行为和性能边界:
- 分区键列类型、精度、时区属性必须与源表完全一致(例如源表
SFSJ DATE,中间表不能用TS TIMESTAMP) - 分区策略需覆盖全部历史数据 —— 若源表最早数据是
2010-03-15,第一个VALUES LESS THAN分区上限至少设为2011-01-01,否则START_REDEF_TABLE会因数据无法归入任何分区而报ORA-14019 - 显式指定
TABLESPACE,避免默认走SYSTEM或用户默认表空间导致空间不足 —— 在线重定义期间,原表 + 中间表 + 日志表三者共存,实际需 ≥ 2.5 倍原表空间 - 不要在中间表上提前建索引 ——
COPY_TABLE_DEPENDENTS会自动按最佳方式重建(如将全局索引转为 LOCAL),手动建反而可能冲突
SYNC_INTERIM_TABLE 不是“一次同步就完事”
大表重定义时,SYNC_INTERIM_TABLE 的作用常被误解为“增量同步收尾”。实际上它承担的是关键的数据一致性保障:
- 首次调用后,Oracle 开始捕获源表 DML 变更写入内部日志表;此时若不做二次同步,
FINISH_REDEF_TABLE会因日志积压超限失败 - 建议在业务低峰期执行第一次
SYNC_INTERIM_TABLE,再观察 10–15 分钟,确认日志表(sys.mlog$_<table_name></table_name>)无持续增长后,再执行第二次 —— 这能大幅缩短FINISH阶段的锁表时间(通常从分钟级压到秒级) - 若同步耗时过长,检查是否因源表存在大量未提交事务或长事务阻塞日志应用 ——
V$TRANSACTION和V$SESSION_LONGOPS是定位依据
真正容易被忽略的是依赖对象状态:重定义完成后,原表上的同义词、物化视图日志、审计策略不会自动迁移,必须人工校验并重新绑定;另外,FINISH_REDEF_TABLE 后原表名指向新分区表,但旧表段(含数据)仍物理存在,需 DBA 手动 DROP TABLE <interim_table_name> PURGE</interim_table_name> 释放空间 —— 这步漏掉,等于白做。











