一、说明
在线重定义具有以下功能:- 修改表的存储参数;
- 可以将表转移到其他表空间;
- 在表上增加、修改或删除一列或是多列;
- 增加并行查询选项;
- 增加分区支持;
- 修改分区结构;
- 重建表以减少碎片;
- 将堆表改为索引组织表或相反的操作;
二、方法
- 基于主键(默认方式)
- 基于ROWID。
三、注意
- 在线重定义的一些限制
- 要求原始表和中间表在同一个方案下;
- 要求有2倍甚至是多于2倍的表空间空间;
- 如果使用主键重定义的方式,原始表上要有主键;
- ROWID的方式不能用于索引组织表,而且重定义后会存在隐藏列M_ROW$$。
四、操作
- 确认表是否可以做在线重定义
EXEC DBMS_REDEFINITION.CAN_REDEF_TABLE('<user_name>', '<table_name>');
- 创建中间表(与原表结构相同)
- 开始在线重定义
注意,Oracle会在重定义过程中会新建两张表RUPD$_<table_name>和MLOG$_<table_name>,其实Oracle在线重定义是通过物化视图的LOG来实现的。做完这一步后,在中间表中也有了相同的数据
BEGIN DBMS_REDEFINITION.START_REDEF_TABLE('<user_name>', '<table_name>', '<table_tmp>'); END;
- 把原始表的权限、约束、索引、物化视图LOG在中间表上创建一份
set serveroutput on var v_err number exec DBMS_REDEFINITION.COPY_TABLE_DEPENDENTS('<user_name>', '<table_name>', '<table_tmp>', NUM_ERRORS => :v_err); print v_err
- 数据同步
插入一条记录到原始表中,中间表上是看不到的,这个操作会被记录在MLOG$_<table_name>中,需要我们主动同步到中间表中
虽然当做第六步的时候,Oracle会自动同步数据,不过这样会加长表不可用的时间,所以还是建议我们单独做
EXEC DBMS_REDEFINITION.SYNC_INTERIM_TABLE('<user_name>', '<table_name>', '<table_tmp>');
- 完成在线重定义
EXEC DBMS_REDEFINITION.FINISH_REDEF_TABLE('<user_name>', '<table_name>', '<table_tmp>');
- 校验
- 查看objects
校验时,会发现,RUPD$_<table_name>和MLOG$_<table_name>被自动删除
SELECT OBJECT_ID, OBJECT_NAME, OBJECT_TYPE, STATUS FROM USER_OBJECTS WHERE OBJECT_NAME LIKE '%<table_name>%';
- 查看表结构
SELECT TABLE_NAME, PARTITION_NAME FROM DBA_TAB_PARTITIONS WHERE TABLE_NAME = '<table_name>';
- 查看相关索引
SELECT TABLE_NAME, INDEX_NAME, STATUS FROM DBA_INDEXES WHERE TABLE_NAME = '<table_name>';
- 查看表中数据
SELECT * FROM <TABLE_NAME>;
- 查看objects