日期:2014-05-16  浏览次数:20587 次

怎么在线对表进行分区(How to perform online redefinition)!

怎么在线对表进行分区(How to perform online redefinition)!


   今天是2013-10-17,之前同事做过一个表的在线分区,当时情况是这样的,有一个大表,每个月多要删除一个月的数据,当delete的时候不但速度慢,而且会产生一个undo的bug,考虑到使用分区表来解决此问题,也就是按照每个月划分range 分区,删除上一个月的数据的时候直接truncate partition 。我们使用dbms_redefinition包来完成表的在线分区功能。
创建一个在线表:
1、选择重新定义的方法。
一种为by key,也就是一个primary key 和psseudo-primary key,sseudo-primary is not null constraints, For this method, the versions of the tables before and after redefinition should have the same primary key columns,如果不指定options_flag则表示 使用默认该方法。
第二种是by rowid,添加了一个M_ROW$$的隐藏列,10.2.0之后,完了之后自动设置该column为unused,并且可以使用alter table ....drop unused column 去删除它。
2、使用can_redef_table确认一下该表是否可以在线重定义,如果不行的话那么就会报错
3、创建一个过渡表(在同一个schema下)包含所需的物理结构和逻辑属性。不是必须要创建该表的索引啊、约束啊、触发器啊等等。因为在使用copy_table_dependents的时候会自动创建。
4、如果使用by rowid,那么需要启动表的movement,alter table 。。。。。enable row movement;
5、为了加快处理大表的速度,可以使用并行操作。alter session force parallel dml paralle number; alter session force parallel query parallel number;
6、开始重新定义进程start_redef_table,指定schema和表名,指定过渡表,指定重定义的方法(dbms_redefinition.cons_use_pk or dbms_redefinition.cons_use_rowid)。
note:
You can query the DBA_REDEFINITION_OBJECTS view to list the objects currently involved in online redefinition.

If START_REDEF_TABLE fails for any reason, you must call ABORT_REDEF_TABLE, otherwise subsequent attempts to redefine the table will fail.
7、复制dependent 对象(如索引、触发器、物理话视图日志、授权、约束)和统计信息从需要新定义的表到过渡表中。有两种办法、1中是首选的也就是自动。2中是需要手动操作
对于第一种,我们使用dbms_redefinition.copy_table_dependents过程来在内部表中自动创建依赖的对象。但这会使该过渡表的dependent的名字和original dependent objects的名字一样。
第二种,就是手动进行操作了。注意要在执行完操作后必须是使用register_dependent_object 过程来重新注册这些依赖的对象。
8、执行finish_table完成表的重定义操作。
9、如果使用by rowid那么要删除伪列。在10.2.0之前会产生M_row$$一个标示列,需要设置unused然后删除,在10.2.0之后该M_ROW$$会自动设置为unused,可以执行alter table drop unused columns;
10、等待一段时间,保证所有的查询都在临时表中,那么接着删除该过渡表,有可能出现ORA-08103的错误。(谨记)

目前我有张表为amy。共有100多万条数据。如下:
SQL> conn rhys/amy;
Connected.

SQL> select count(*) from amy;

  COUNT(*)
----------
   1032509

SQL>

SQL> desc amy;
 Name                          Null?    Type
 ----------------------------- -------- --------------------
 ID                                     NUMBER
 CREATE_DATE                            TIMESTAMP(6)

SQL>
查看该表 是否可以进行在线重定义。
SQL> execute dbms_redefinition.can_redef_table('RHYS','AMY',dbms_redefinition.cons_use_rowid);

PL/SQL procedure successfully completed.

SQL> alter table amy add constraint primary_key_id primary key (id);

Table altered.

SQL>

创建过渡表:
SQL> get bb.sql
  1  create table amy_temp(
  2  id number,
  3  create_date timestamp
  4  )
  5  partition by range(id)
  6  (
  7  partition part200000 values less than (200000),
  8  partition part500000 values less than (500000),
  9  partition part_other values less than (maxvalue)
 10* )
SQL> r
  1  create table amy_temp(
  2  id number,
  3  create_date timestamp
  4  )
  5  partition by range(id)
  6  (
  7  partition part200000 values less than (200000),
&nbs