oracle表转为分区表,在线转化为分区表

只能利用ORACLE 10g的一个新特性,DBMS_REDEFINITION包在线转换成分区表,然后将以前的分区直接truncate掉,这样以前几个小时才能完成的工作,1分钟内就可以搞定,具体操作过程如下。

Oracle10g之后的新特性:

DBMS_REDEFINITION包支持在线对表结构进行重定义,包括添加、删除列等操作,整个操作过程中只在数据同步时对原表临时进行加锁处理,基本上可以忽略对业务的影响,特别是对于银行、电信行业非RAC环境使用DBMS_REDEFINITION对表行DDL修改是一种非常不错的选择。

在这里我们只用DBMS_REDEFINITION对非区表完成分区转换,具体使用方法如下:

第一步:选择转换方法

有两种选择,一种是建立主键,我的生产环境没有主键,那么我们只能选择rowid这种方法

第二步:检查表是否可以重定义

begin

DBMS_REDEFINITION.CAN_REDEF_TABLE(uname=>'orabpel',

tname=>'AUDIT_TRAIL',

options_flag => dbms_redefinition.cons_use_rowid);

end;说明:如果此不可重定义,直接会报不能重定义的原因,如果可以重定义,提示PL/SQL执行完成,红色选项是可选项,默认是按主键方法进行转换,因我操作的环境没有主键,那么只能选择rowid这种方法

第三步:创建转换临时表

uid-17069315-id-4933658.html

说明:因10g不支持间隔分区,只能通过手工进行创建分区,图片只显示了部分内容,下面基本上一样,需要注意日期的写法,同时要注意分区只能将小的日期放在前面,大的放在后面,否则会报ORA-14037分区"AUDIT_TRAIL"分区界限过高!第四步:设置并行操作

alter session force parallel dml parallel 4;

alter session force parallel query parallel 4;因为我的表是90G,比较大,为加快处理速度设置并行执行,如果表比较小,这一步可以不要!

第五步:开始重定义表结构

BEGIN

DBMS_REDEFINITION.START_REDEF_TABLE(uname=> 'orabpel',

orig_table=> 'AUDIT_TRAIL',

int_table=> 'AUDIT_TRAIL_EMP',options_flag => dbms_redefinition.cons_use_rowid

);--红色部分容易忽略END;

注意:此过程比较消耗时间,会把中间表填满数据,所以此时要有足够的空间产生新中间表数据

第六步:同步临时表

BEGIN

DBMS_REDEFINITION.SYNC_INTERIM_TABLE(uname=> 'orabpel',

orig_table => 'AUDIT_TRAIL',

int_table=> 'AUDIT_TRAIL_EMP'

);

END;

--此过程比较快,只是同步从开始转换到现在产生的新数据

第七步:完成重定义

BEGIN

DBMS_REDEFINITION.FINISH_REDEF_TABLE(uname=> 'orabpel',

orig_table => 'AUDIT_TRAIL',

int_table=> 'AUDIT_TRAIL_EMP'

);

END;第八步:删除临时表

BEGIN

truncate table AUDIT_TRAIL_EMP;--大表不要忘记这步操作哦drop table AUDIT_TRAIL_EMP;--删除临时表的定义

END;

如果顺利的话到此就结束了,原表变成了分区表,在没有停业务的情况下完成了表的在线重定义,但是操作过程中往往没那么顺利,执行过程中报错怎么处理呢?

第九步:异常情况下终止操作

BEGIN

DBMS_REDEFINITION.ABORT_REDEF_TABLE(uname=> 'orabpel',

orig_table => 'AUDIT_TRAIL',

int_table=> 'AUDIT_TRAIL_EMP'

);

END;

在执行任何一步出错,都可以执行第九步终止转换操作!

第十步:检查验证有效性

做完以后一定要检查是否有失效对像

select * from dba_objects where status<>'VALID' and owner='orabpel';

发现有失效的包 ,处理方法

alter package orabpel.collxa compile;

处理完失效对像后查看最后一个分区的数据是否在增长,验证转换后分区是否可用

select count(*) from orabpel.audit_trail_1309;

发现数据并没有增长,肯定是那里出了问题,然后查看alert.log是否有报错

发现报错如下:

Some indexes or index [sub]partitions of table ORABPEL.AUDIT_TRAIL have been marked unusable

处理方法如下:

SELECT 'ALTER INDEX ' || INDEX_OWNER || '.' || INDEX_NAME ||

'REBUILD PARTITION ' || PARTITION_NAME || ' NOLOGGING online;'

FROM DBA_IND_PARTITIONS

WHERE INDEX_OWNER NOT IN ('SYS', 'SYSTEM', 'PUBLIC')

AND STATUS = 'UNUSABLE'

UNION ALL

SELECT 'alter index ' || OWNER || '.' || A.INDEX_NAME ||

' REBUILD online nologging;'

FROM DBA_INDEXES A

WHERE OWNER NOT IN ('SYS', 'SYSTEM', 'PUBLIC')

AND STATUS = 'UNUSABLE';

跟据执行结果执行,否则数据将不能正常写入,(切记!)

alter index ORABPEL.CS_PK1 REBUILD online nologging;

再次查询分区表数据是否正常写入

select count(*) from orabpel.audit_trail;

发现数据增长很快,至此操作验证成功!

总结:在线重定义并不能100%保证不影响业务,我在测试库上发现不影响业务,但是在正式库操作完以报最新分区表数据并没有增加,alert.log报上面的错误,处理完以后数据才正常写入,因此操作完以后一定要记得查看dba_objects去及时处理失效对像,同时查看alert.log是否有异常信息及时进行相应的处理,最后一定要验证最后一个分区表数据是否在增长,只能这样我们才能确认我们转换后的分区表是可用的!特别需要注意的是,如果你的库是10g的库,一定要及时增加分区,因为10g不支持间隔分区,需要人为手工的及时添加新的分区,如果在11g里面间隔分区可以做到自动添加新的分区,但是看表的DDL语句时发现并没有隔间分区的关键字,这就是为什么同样的语句在10g需要手工添加分区,而在11g却可以自动增加分区的原因。不知道为什么11g中间隔分区表DDL语句看不到间隔分区关键字,知道的朋友可以QQ交流一下!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值