在线重定义——分区表改造
在数据库管理过程中,随着数据量的不断增长,普通表的查询、维护成本不断上升。为了提升查询性能和管理效率,通常需要将大表进行分区处理。
本文介绍如何使用 Oracle 在线重定义(DBMS_REDEFINITION) 的方式对现有大表进行分区操作,以保障业务持续可用,整个过程中仅在最后切换阶段会短暂锁表,最大程度减少对业务的影响。具体步骤如下:
本操作环境:Oracle 11g
1. 创建临时表 CW_MZSFMX_INTERIM
create table CWSF3.CW_MZSFMX_INTERIM
(JLID NUMBER(10),BMID NUMBER(4),ZKID NUMBER(4),BRBH VARCHAR2(28),BRXM VARCHAR2(20),DWDM VARCHAR2(5),ZHID NUMBER(8),XMID NUMBER(8),FLM VARCHAR2(8),TJM VARCHAR2(4),MC VARCHAR2(100),KZJB VARCHAR2(1),YZLB VARCHAR2(2),DJ NUMBER(8,2),SL NUMBER(4),ZFJE NUMBER(9,2),JZJE NUMBER(9,2),JMJE NUMBER(9,2),ZLJE NUMBER(9,2),ZFBL NUMBER(3,2),YSID NUMBER(5),JYID NUMBER(10),SFYQ VARCHAR2(2),ZTBZ VARCHAR2(1) default '1',ZLHDID NUMBER(9) default 0,JMID NUMBER(8),SFLX VARCHAR2(1),SFRYID NUMBER(8),SFSJ DATE,SPBZ VARCHAR2(1) default '0',BZDM VARCHAR2(2),BAFLM VARCHAR2(3)
)
partition by range(SFSJ)
(partition CW_MZSFMX_p1 values less than (to_date('2011-01-01','yyyy-mm-dd')),partition CW_MZSFMX_p2 values less than (to_date('2012-01-01','yyyy-mm-dd')),partition CW_MZSFMX_p3 values less than (to_date('2013-01-01','yyyy-mm-dd')),-- 以下省略
);
2. 验证表是否可以在线重定义
【验证是否支持在线重定义,需要表有主键或伪主键】
exec dbms_redefinition.can_redef_table('CWSF3', 'CW_MZSFMX');
3. 启动重定义过程
【初始化中间表数据,后续源表新增数据不会自动同步】
exec dbms_redefinition.start_redef_table('CWSF3', 'CW_MZSFMX', 'CW_MZSFMX_INTERIM');
4. 复制依赖对象
【复制源表上的索引、触发器、授权、约束等到中间表】
DECLAREnum_errors PLS_INTEGER;
BEGINDBMS_REDEFINITION.COPY_TABLE_DEPENDENTS('CWSF3', 'CW_MZSFMX', 'CW_MZSFMX_INTERIM', num_errors => num_errors);
END;
/
5. 同步源表与中间表数据(可选)
【将启动重定义后源表变更的数据同步到中间表】
BEGINDBMS_REDEFINITION.SYNC_INTERIM_TABLE('CWSF3', 'CW_MZSFMX', 'CW_MZSFMX_INTERIM');
END;
/
6. 完成重定义切换
【将中间表切换为正式表,正式完成分区改造】
exec dbms_redefinition.finish_redef_table('CWSF3', 'CW_MZSFMX', 'CW_MZSFMX_INTERIM');
7. 后续处理
【修改约束为启用并校验】
select 'alter table cwsf3.'||table_name||' enable validate constraint '||constraint_name||';'
from dba_constraints
where table_name = 'CW_MZSFMX';
【查看临时表空间使用情况】
select TEMPORARY_TABLESPACE from dba_users where username = 'CWSF3';
select * from dba_temp_free_space;
【如需中断重定义,可执行终止操作】
exec dbms_redefinition.abort_redef_table('CWSF3', 'CW_MZSFMX', 'CW_MZSFMX_INTERIM');
【查看重定义相关对象与错误信息】
select * from dba_redefinition_objects;
select * from dba_redefinition_errors;
【完成后收集表统计信息】
exec DBMS_STATS.GATHER_TABLE_STATS(OWNNAME => 'CWSF3',TABNAME => 'CW_MZSFMX',ESTIMATE_PERCENT => 1,METHOD_OPT => 'for all columns size repeat',DEGREE => 8,GRANULARITY => 'ALL',CASCADE => TRUE
);
总结
通过以上步骤,可以在不停机的情况下完成大表的分区处理,充分利用了 Oracle 在线重定义技术,有效降低了分区改造对业务系统的影响。
需要注意的是,在执行过程中,务必做好以下几点准备工作:
评估表的数据量与表空间使用情况;
确保源表存在主键或可唯一标识记录的伪主键;
全程关注临时表空间和日志空间使用情况,避免空间不足导致的中断;
重定义完成后及时收集统计信息,确保后续查询性能正常。
如果在实际操作过程中遇到问题,可以通过查询 DBA_REDEFINITION_ERRORS 视图定位详细错误信息,及时调整方案。