Oracle 在线重定义(DBMS_REDEFINITION)
Oracle 在线重定义(DBMS_REDEFINITION)
适用版本:Oracle Database 9i / 10g / 11g / 12c / 19c / 23ai 文档版本:v1.0 / 2026-07
1. 概述
在线重定义 在业务运行时重组表[1]:
用途:
- 修改表结构
- 改变分区策略
- 重组数据
- 修改列类型
2. 流程
2.1 步骤
- 验证可重定义
- 创建中间表
- 启动重定义
- 同步数据
- 完成重定义
2.2 概念
- 原表:业务表
- 中间表:新结构表
- 物化视图:同步
3. 实战
3.1 验证
BEGIN
DBMS_REDEFINITION.CAN_REDEF_TABLE(
uname => 'SCOTT',
tname => 'EMPLOYEES',
options_flag => DBMS_REDEFINITION.CONS_USE_PK
-- CONS_USE_PK / CONS_USE_ROWID
);
END;
/
3.2 创建中间表
CREATE TABLE employees_new (
id NUMBER PRIMARY KEY,
name VARCHAR2(100),
salary NUMBER,
hire_date DATE
)
PARTITION BY RANGE (hire_date) (
PARTITION p2020 VALUES LESS THAN (TO_DATE('2021-01-01', 'YYYY-MM-DD')),
PARTITION p2021 VALUES LESS THAN (TO_DATE('2022-01-01', 'YYYY-MM-DD')),
PARTITION p_max VALUES LESS THAN (MAXVALUE)
);
3.3 启动重定义
BEGIN
DBMS_REDEFINITION.START_REDEF_TABLE(
uname => 'SCOTT',
orig_table => 'EMPLOYEES',
int_table => 'EMPLOYEES_NEW',
col_mapping => 'id id, name name, salary salary, hire_date hire_date',
options_flag => DBMS_REDEFINITION.CONS_USE_PK
);
END;
/
3.4 同步(可选)
BEGIN
DBMS_REDEFINITION.SYNC_INTERIM_TABLE(
uname => 'SCOTT',
orig_table => 'EMPLOYEES',
int_table => 'EMPLOYEES_NEW'
);
END;
/
3.5 添加依赖对象
-- 触发器、索引、约束、授权
-- 自动或手动
BEGIN
DBMS_REDEFINITION.COPY_TABLE_DEPENDENTS(
uname => 'SCOTT',
orig_table => 'EMPLOYEES',
int_table => 'EMPLOYEES_NEW',
copy_indexes => DBMS_REDEFINITION.CONS_ORIG_PARAMS,
copy_triggers => TRUE,
copy_constraints => TRUE,
copy_privileges => TRUE,
ignore_errors => FALSE
);
END;
/
3.6 完成
BEGIN
DBMS_REDEFINITION.FINISH_REDEF_TABLE(
uname => 'SCOTT',
orig_table => 'EMPLOYEES',
int_table => 'EMPLOYEES_NEW'
);
END;
/
3.7 清理
DROP TABLE employees_new;
4. 选项
4.1 CONS_USE_PK
- 基于主键
- 表必须有主键
4.2 CONS_USE_ROWID
- 基于 ROWID
- 无主键表
5. 重定义模式
5.1 完全
- 默认
- 全表同步
5.2 增量
BEGIN
DBMS_REDEFINITION.START_REDEF_TABLE(
...,
options_flag => DBMS_REDEFINITION.CONS_USE_PK + DBMS_REDEFINITION.CONS_MATERIALIZED
);
END;
/
6. 中断
6.1 中止
BEGIN
DBMS_REDEFINITION.ABORT_REDEF_TABLE(
uname => 'SCOTT',
orig_table => 'EMPLOYEES',
int_table => 'EMPLOYEES_NEW'
);
END;
/
6.2 清理
DROP TABLE employees_new;
DROP MATERIALIZED VIEW employees_new; -- 如有
7. 应用场景
7.1 增加分区
-- 单表变分区表
BEGIN
DBMS_REDEFINITION.START_REDEF_TABLE(...);
END;
/
7.2 修改列
-- 修改列类型
-- 中间表用新类型
7.3 表压缩
CREATE TABLE new_table ... COMPRESS FOR OLTP;
7.4 重组表
-- 降低高水位
-- 减少碎片
8. 监控
8.1 查看
SELECT * FROM dba_redefinition_tables;
8.2 进度
-- v$session_longops
SELECT
sid,
serial#,
opname,
sofar,
totalwork,
ROUND(sofar / totalwork * 100, 2) AS pct
FROM v$session_longops
WHERE opname LIKE '%REDEF%';
9. 限制
9.1 不支持
- IOT
- 含 LONG 列
- 含用户定义类型
- 物化视图容器表
- AQ 队列表
9.2 主键要求
- CONS_USE_PK 必须有主键
- 否则用 CONS_USE_ROWID
10. 性能优化
10.1 并行
ALTER SESSION ENABLE PARALLEL DML;
ALTER SESSION FORCE PARALLEL DML PARALLEL 8;
ALTER SESSION FORCE PARALLEL QUERY PARALLEL 8;
10.2 NOLOGGING
CREATE TABLE new_table NOLOGGING AS ...;
10.3 分批同步
-- 多次 SYNC
EXEC DBMS_REDEFINITION.SYNC_INTERIM_TABLE(...);
11. 常见坑与排错
11.1 ORA-12091: 物化视图存在
-- 删除依赖物化视图
DROP MATERIALIZED VIEW ...;
11.2 ORA-23539: 表正在重定义
-- 中止
EXEC DBMS_REDEFINITION.ABORT_REDEF_TABLE(...);
11.3 依赖对象错误
-- 1. ignore_errors => TRUE
-- 2. 检查 dba_redefinition_errors
SELECT * FROM dba_redefinition_errors;
12. 最佳实践
- 业务低峰:性能
- 并行:加速
- NOLOGGING:少 Redo
- 分批 SYNC:长操作
- 依赖对象复制:完整
- 监控进度:v$session_longops
- 测试验证:先测试
- 备份:失败回滚
- 检查错误:dba_redefinition_errors
- 完成后清理:中间表
13. 参考资料
[1] Oracle Database Administrator’s Guide 19c, “Online Redefinition” https://docs.oracle.com/en/database/oracle/oracle-database/19/admin/online-redefinition.html