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. 最佳实践

  1. 测试:演练
  2. CAN_REDEF_TABLE:先检查
  3. 中间同步:长时间
  4. 依赖对象:COPY_TABLE_DEPENDENTS
  5. 错误检查:num_errors
  6. 业务低峰:执行
  7. 监控:进度
  8. 备份:前备份
  9. 中止预案:ABORT
  10. 文档:流程

16. 参考资料

[1] Oracle Database Administrator’s Guide 19c, “Online Table Redefinition” https://docs.oracle.com/en/database/oracle/oracle-database/19/admin/