dbms_redefinition在线重定义表结构 可以在表分区的时候使用

dbms_redefinition在线重定义表结构

(2013-08-29 22:52:58)

转载▼

标签:

dbms_redefinition

非分区表转换成分区表

王显伟

在线重定义表结构

在线转换非分区表

分类: ORACLE新特性实践

刚接手一套系统应用数据库,因为项目建设期间种种原因,库是非归档模式也没有备份,更让我无语的是有个表增长的比较快,将近90G大小,每隔一段时间都要删除前三个月以前的数据,然后再用shrink收缩空间,因为是非分区表,shrink很是浪费时间,而且很多时间无法正常完成shrink操作,想将它改成分区表,同时业务部门又允许停数据库,只能利用ORACLE 10g的一个新特性,DBMS_REDEFINITION包在线转换成分区表,然后将以前的分区直接truncate掉,这样以前几个小时才能完成的工作,1分钟内就可以搞定,具体操作过程如下。

    操作环境说明:ORACLE 10G 10.2.0.4,HP-UNIX系统

    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这种方法

第三步:创建转换临时表


说明:因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交流一下!

时间: 2024-08-07 21:16:52

dbms_redefinition在线重定义表结构 可以在表分区的时候使用的相关文章

Oracle在线重定义(online redefinition)--将普通表改为分区表

使用Oracle的在线重定义技术,可以将Oracle的普通表改为分区表.操作如下: STEP1:测试表是否可以在线重定义,这里以unixdev数据库的LIJIAMAN.BSTEST为例 EXEC DBMS_REDEFINITION.CAN_REDEF_TABLE('LIJIAMAN','BSTEST', DBMS_REDEFINITION.CONS_USE_PK); 如果表上没有主键,则会报错:SQL> exec dbms_redefinition.start_redef_table('LIJI

使用ORACLE在线重定义将普通表改为分区表

1.首先建立测试表,并插入测试数据: create table myPartition(id number,code varchar2(5),identifier varchar2(20)); insert into myPartition values(1,'01','01-01-0001-000001'); insert into myPartition values(2,'02','02-01-0001-000001'); insert into myPartition values(3,

一个完整的以在线重定义方式普通表转分区表的方案

1. 转分区表原因 生产数据库,一张表,一亿多行数据,绝大部分查询按月为维度做时间范围查 询,未分区状态下,查询IO量大,计划以分区截剪的方式减少IO量,提升前前台查询性能 2. 实施目的 将未分区的oXX_XXt_owner.id_oXXXdx_mX表以(stat_XXcle)字段为分区键,以在定义的方式转换成按月分区表的时间范围分区表,利且在线重定义的特性,保留权限的不漏赋以及极少时间的影响生产. 3. 注意事项 (1)       数据库若是双节点,只需在其中一个节点的数据库上实施. (2

Oracle在线重定义DBMS_REDEFINITION 普通表—&gt;分区表

实验环境:RHEL 6.4 + Oracle 11.2.0.3实验:在线重定义 普通表 为 分区表,包括主键对应的索引都改造为分区索引. 1,构造普通表t_objects conn test1/test1; create table t_objects as select * from dba_objects; SQL> select count(1) from t_objects; COUNT(1) ---------- 468738 --t_objects建立主键和索引 alter tabl

ORACLE系统包DBMS_REDEFINITION实现表的在线重定义

ORACLE自带的DBMS_REDEFINITION包功能非常强大,可以用于降低高水位线,回收碎片空间,对表做在线重定义(添加或删除字段,改变字段类型,普通表重定义表为分区表,分区表重定义表为普通表等等) 另外,它有一个非常强大的功能,"在线"二字体现得淋漓尽致,但是也并不是完全的在线,因为在完成重定义前的最后一下,会持会表级排他锁,但这个锁定时间是可控的. 如果你也曾为delete无法降低高水位线而烦恼或者由于历史表太大导致维护困难,我相信这篇文章将对你有很大的感触,因此相信绝大朋友

Oracle已有数据表建立表分区—在线重定义

今天在做数据抽取的时候,发现有一张业务表数据量达到了5000W,所以就想将此表改为分区表.分区表的有点如下: 1.改善查询性能:对分区对象的查询可以仅搜索自己关心的分区,提高检索速度.2.增强可用性:如果表的某个分区出现故障,表在其他分区的数据仍然可用:3.维护方便:如果表的某个分区出现故障,需要修复数据,只修复该分区即可:4.均衡I/O:可以把不同的分区映射到磁盘以平衡I/O,改善整个系统性能. 第一步:首先对要在线重定义的表自行验证,看该表是否可以重定义,如果不可以则会提示错误信息 SQL>

oracle在线重定义表

在一个高可用系统中,如果需要改变一个表的定义是一件比较棘手的问题,尤其是对于7×24系统.Oracle提供的基本语法基本可以满足一般性修改,但是对于把普通堆表改为分区表,把索引组织表修改为堆表等操作就无法完成了.而且,对于被大量DML语句访问的表,幸运的是,Oracle从9i版本开始提供了在线重定义表功能,通过调用DBMS_REDEFINITION包,可以在修改表结构的同时允许DML操作. 在线重定义表具有以下功能:修改表的存储参数:可以将表转移到其他表空间:增加并行查询选项:增加或删除分区:重

如何对已经存在数据的表进行在线重定义方式实现分区

转一位大神的笔记. Oracle的普通表没有办法通过修改属性的方式直接转化为分区表,必须通过重建的方式进行转变,下面介绍三种效率比较高的方法,并说明它们各自的特点. 方法一:利用原表重建分区表. 步骤: SQL> CREATE TABLE T (ID NUMBER PRIMARY KEY, TIME DATE); 表已创建. SQL> INSERT INTO T SELECT ROWNUM, CREATED FROM DBA_OBJECTS; 已创建6264行. SQL> COMMIT;

oracle普通表转分区表(在线重定义方式)

1.1.TAB_TAOBAO_BILL 1.1.1检查下这张表是否可以在线重定义,无报错表示可以,报错会给出错误信息: exec dbms_redefinition.can_redef_table('ycheng', 'P_TAB_TAOBAO_BILL'); 1.1.2.expdp导出表进行备份(这里的DATA_PUMP_1目录是/data1/dpdump) expdp \'\/ as sysdba\' directory=DATA_PUMP_1 tables=TAB_TAOBAO_BILL