Oracle 在线重定义实战详解
Oracle 在线重定义实战详解
适用版本:Oracle Database 10g / 11g / 12c / 19c / 23ai 文档版本:v1.0 / 2026-07
1. 概述
在线重定义允许在线修改表结构[1]:
详细见:Oracle 在线重定义详解。
2. 应用场景
2.1 表结构变更
- 修改列类型
- 添加/删除列
- 修改约束
- 重组表
2.2 存储变更
- 表空间迁移
- 分区改造
- 压缩
2.3 性能优化
- 重建
- 重组
- 消除碎片
3. 步骤
3.1 检查
EXEC DBMS_REDEFINITION.CAN_REDEF_TABLE(
uname => 'SCOTT',
tname => 'EMP',
options_flag => DBMS_REDEFINITION.CONS_USE_PK
);
3.2 创建临时表
CREATE TABLE scott.emp_new (
id NUMBER PRIMARY KEY,
name VARCHAR2(100),
salary NUMBER,
dept_id NUMBER
) TABLESPACE new_ts;
3.3 开始重定义
BEGIN
DBMS_REDEFINITION.START_REDEF_TABLE(
uname => 'SCOTT',
orig_table => 'EMP',
int_table => 'EMP_NEW',
col_mapping => 'id id, name name, salary salary, dept_id dept_id',
options_flag => DBMS_REDEFINITION.CONS_USE_PK
);
END;
/
3.4 同步依赖对象
DECLARE
v_num PLS_INTEGER;
BEGIN
DBMS_REDEFINITION.COPY_TABLE_DEPENDENTS(
uname => 'SCOTT',
orig_table => 'EMP',
int_table => 'EMP_NEW',
copy_indexes => DBMS_REDEFINITION.CONS_ORIG_PARAMS,
copy_triggers => TRUE,
copy_constraints => TRUE,
copy_privileges => TRUE,
num_errors => v_num
);
END;
/
3.5 同步数据
BEGIN
DBMS_REDEFINITION.SYNC_INTERIM_TABLE(
uname => 'SCOTT',
orig_table => 'EMP',
int_table => 'EMP_NEW'
);
END;
/
3.6 完成
BEGIN
DBMS_REDEFINITION.FINISH_REDEF_TABLE(
uname => 'SCOTT',
orig_table => 'EMP',
int_table => 'EMP_NEW'
);
END;
/
3.7 清理
DROP TABLE scott.emp_new PURGE;
4. 中间同步
4.1 长时间操作
-- 多次同步
EXEC DBMS_REDEFINITION.SYNC_INTERIM_TABLE('SCOTT', 'EMP', 'EMP_NEW');
4.2 作用
- 减少最后 FINISH 时间
- 增量同步
5. 分区改造
5.1 非分区 → 分区
-- 临时表分区
CREATE TABLE scott.emp_new (
id NUMBER,
name VARCHAR2(100),
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 p2022 VALUES LESS THAN (TO_DATE('2023-01-01', 'YYYY-MM-DD')),
PARTITION pmax VALUES LESS THAN (MAXVALUE)
);
-- 重定义
BEGIN
DBMS_REDEFINITION.START_REDEF_TABLE(...);
...
END;
/
6. 表空间迁移
6.1 临时表
CREATE TABLE scott.emp_new TABLESPACE new_ts AS
SELECT * FROM scott.emp WHERE 1=0;
6.2 重定义
BEGIN
DBMS_REDEFINITION.START_REDEF_TABLE(...);
...
END;
/
7. 压缩改造
7.1 临时表
CREATE TABLE scott.emp_new COMPRESS FOR OLTP AS
SELECT * FROM scott.emp WHERE 1=0;
7.2 重定义
BEGIN
DBMS_REDEFINITION.START_REDEF_TABLE(...);
...
END;
/
详细见:Oracle 表压缩技术详解。
8. 列变更
8.1 添加列
CREATE TABLE scott.emp_new AS
SELECT *, CAST(NULL AS VARCHAR2(100)) AS new_col
FROM scott.emp WHERE 1=0;
8.2 类型变更
CREATE TABLE scott.emp_new (
id NUMBER,
salary NUMBER(10, 2) -- 原为 NUMBER
);
8.3 列映射
BEGIN
DBMS_REDEFINITION.START_REDEF_TABLE(
...,
col_mapping => 'id id, salary TO_NUMBER(salary) salary'
);
END;
/
9. 监控
9.1 进度
SELECT * FROM v$session_longops
WHERE opname LIKE '%REDEFINITION%';
9.2 临时表
SELECT COUNT(*) FROM scott.emp_new;
10. 限制
10.1 不支持
- 嵌套表
- IOT 部分场景
- 物化视图日志
- LONG RAW
10.2 主键
- 表必须有主键
- 或 ROWID(CONS_USE_ROWID)
11. 中止
11.1 ABORT_REDEF_TABLE
BEGIN
DBMS_REDEFINITION.ABORT_REDEF_TABLE(
uname => 'SCOTT',
orig_table => 'EMP',
int_table => 'EMP_NEW'
);
END;
/
DROP TABLE scott.emp_new PURGE;
12. 应用场景
12.1 在线维护
- 业务不停
- 表结构变更
- 性能优化
12.2 分区改造
- 非分区 → 分区
- 分区策略变更
12.3 压缩
- 启用压缩
- 节省空间
12.4 表空间
- 迁移
- 整理
13. 性能
13.1 影响
- 源表可读写
- 物化视图日志
- 轻微开销
13.2 时间
- 数据量决定
- 增量同步
- 最后 FINISH 快
14. 常见坑与排错
14.1 ORA-12091
- 物化视图日志存在
- 删除
14.2 ORA-12088
- 不能重定义
- 检查依赖
14.3 依赖对象错误
-- 查看
SELECT object_name, object_type, status
FROM user_objects
WHERE object_name LIKE 'EMP_NEW%';
15. 最佳实践
- 测试:演练
- CAN_REDEF_TABLE:先检查
- 中间同步:长时间
- 依赖对象:COPY_TABLE_DEPENDENTS
- 错误检查:num_errors
- 业务低峰:执行
- 监控:进度
- 备份:前备份
- 中止预案:ABORT
- 文档:流程
16. 参考资料
[1] Oracle Database Administrator’s Guide 19c, “Online Table Redefinition” https://docs.oracle.com/en/database/oracle/oracle-database/19/admin/