Redefining Tables Online

 

在数据库系统中,偶尔需要修改表的物理或者逻辑结构,出于下面几个目的:

  1、提高查询或者DML的性能

  2、适应应用程序的改变

  3、管理存储

 online table redefinition 是Oracle 提供的一种在修改表结构时没有显著影响表可用性的一种机制。online table redefinition 比传统的表重新定义在可用性方面有了很大的提高。

当表是在线重定义时,在重定义的过程中可以同时查询和DML操作,表加独占模式的锁在一个很小的窗口,窗口大小依赖于表大小和重定义的复杂度,对用户来说是完全透明的。

表在线重定义需要的空间约等于表使用的空间,如果增加新列,需要更多的空间。

 

表在线重定义的方式:

1、 使用EM 的重组对象向导

2、 使用DBMS_REDEFINITION 包

 

Online Table Redefinition特点:

1、修改表或者聚簇的存储参数

2、将表或者聚簇移动到其他表空间

3、在表或聚簇中增加、修改、删除一列或多列

4、增加或者删除分区支持(仅非聚簇表)

5、改变分区结构

6、改变单个表分区的物理特性,包括在相同schema中移到不同的表空间

7、改变物化视图日志或者Oracle Streams Advanced Queueing 队列表的物理特性

8、添加支持并行查询

9、重建表或聚簇减少碎片

10、将常规表变更为索引组织表或者将索引组织表转换为常规表

11、将关系表转换为对象列的表或者反向操作

12、将对象表转换为关系表或者对象列的表,反之亦可

 

 

通过使用DBMS_REDEFINITION执行在线重定义

在线重定义表步骤如下:

1、选择重定义方法

     基于主键:选一个主键或者伪主键用来重定义。伪主键是唯一键,有 not null 约束。此方式,表重定义前后的版本需要有相同的主键列。推荐使用基于主键的方式(默认方式)

     基于rowid:如果没有可用的键值是使用此方法。重定义后,增加了一个隐藏列M_ROW$$ ,建议重定义完成后删除或者将该列设置为unused,若COMPATIBLE设置为10.2.0 或者更高,在重定义最后阶段自动设置为unused,也可使用ALTER TABLE ... DROP UNUSED COLUMNS将其删除。(对应索引组织表不能使用此方式)

 

2、调用CAN_REDEF_TABLE检验表是否可以在线重定义

3、创建一个空的临时表(和重定义的表在一个schema)并指定所有的物理和逻辑属性。如果删除了列,在临时表中不包含该列的定义信息,增加列,在临时表中增加列的定义信息,修改列时,在临时表中定义需要修改的参数。临时表不必创建索引、约束、授权、触发器,因为在第六步复制依赖对象时会定义。

4、(可选的)如果重定义的是大表并希望在下一步中提高性能可以并行执行,使用如下语句:

     alter session force parallel  dml parallel degree-of-parallelism;

       alter session force parallel  query paralleldegree-of parallelism;

 

5、调用START_REDEF_TABLE开始重定义,需提供如下信息:

   重定义的表的表名及schema名

   临时表名

   列映射

   重定义方法( DBMS_REDEFINITION.CONS_USE_PK、DBMS_REDEFINITION.CONS_USE_ROWID),若未指定,默认是CONS_USE_PK

      列排序(可选)

      若个重定义的表是一个仅一个分区的分区表,指定分区名

     注意:如果由于某种原因,START_REDEF_TABLE失败,需调用ABORT_REDEF_TABLE,不然后续尝试重定义表将会失败。

 

6、从定义表复制依赖对象(如:triggers, indexes, materialized view logs, grants, and constraints)和统计信息到临时表。

       自动创建依赖对象  :COPY_TABLE_DEPENDENTS过程在临时表上自动创建、注册依赖对象

      手动创建依赖对象

 

7、执行FINISH_REDEF_TABLE 完成表的重定义。在执行该过程中,原表加独占锁,锁时间依赖于表数据量。然而FINISH_REDEF_TABLE 需要等待所有挂起的DML提交后才完成重定义。

 

8、如果使用的是通过rowid重定义并且COMPATIBLE 设置是10.1.0或者更低,将隐藏列M_ROW$$ 删除或者设置为unused。

     ALTER TABLE table_name SET UNUNSED(M_ROW$$);

     如果COMPATIBLE设置为10.2.0或更高,当重定义完成后隐藏列自动设置为UNUSED,可以通过ALTER TABLE ... DROP UNUSED COLUMNS语句删除该列。

9、等待针对临时表的所有长时间允许的查询结束,删除临时表。

 

 

示例如下:

原表:

SQL> desc xezf.reo_online_test;
 Name        Null?    Type
 ----------------------------------------- -------- ----------------------------
 PROD_ID       NOT NULL NUMBER(6)
 PROD_NAME         VARCHAR2(200)
 CP_ID        NOT NULL NUMBER(3)
 PROD_SELLING_PRICE        NUMBER(6,2)
 PROD_STATUS       NOT NULL VARCHAR2(4)
 PROD_DESC         VARCHAR2(800)
 PROD_OID         VARCHAR2(40)
 PROD_ALERTCOUNT        NUMBER(4)
 PROD_PY         VARCHAR2(50)
 CPREPORT_FLAG         NUMBER(1)
 CHECKTIME_BUSY         NUMBER
 CHECKTIME_IDLE         NUMBER
 TIME_ALARM         DATE
 ADVANCE         NUMBER
 PROD_TYPE         NUMBER
 PAY_URL         VARCHAR2(100)
 BALANCE_PERIOD         NUMBER
 BUY_MODE         VARCHAR2(32)
 SDK_PRICE         NUMBER(6,2)
 CP_VISIBLE         NUMBER
 INTERRELATE_PROD_ID        NUMBER(6)
 INTERRELATE_FLAG        NUMBER

 

1、通过CAN_REDEF_TABLE检查表

 

SQL>  exec  DBMS_REDEFINITION.CAN_REDEF_TABLE('xezf','reo_online_test', DBMS_REDEFINITION.CONS_USE_PK);

            PL/SQL procedure successfully completed.

 

2、建立临时表,表结构如下:

SQL> desc  xezf.temp_online_test
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 PROD_ID                                   NOT NULL NUMBER(6)
 PROD_NAME                                          VARCHAR2(250)
 CP_ID                                     NOT NULL NUMBER(5)
 PROD_PY                                            VARCHAR2(50)
 DJ_TEST                                            NUMBER

 

3、调用START_REDEF_TABLE开始重定义

 

SQL>  exec  DBMS_REDEFINITION.START_REDEF_TABLE('xezf', 'reo_online_test','temp_online_test','PROD_ID PROD_ID,PROD_NAME   PROD_NAME,CP_ID      CP_ID,PROD_PY PROD_PY,12 dj_test',dbms_redefinition.cons_use_pk);

       PL/SQL procedure successfully completed.

 

4、从定义表复制依赖对象

SQL >   variable num_errors number;

SQL>  exec dbms_redefinition.COPY_TABLE_DEPENDENTS('xezf','reo_online_test','temp_ONLINE_TEST',dbms_redefinition.cons_orig_params ,true,true,true,true,num_errors);

 

5、执行FINISH_REDEF_TABLE 完成表的重定义

SQL> exec dbms_redefinition.FINISH_REDEF_TABLE('xezf','reo_online_test','temp_ONLINE_TEST');

       PL/SQL procedure successfully completed.

 

6、查看重定义完成的表

SQL> desc xezf.reo_online_test
 Name        Null?    Type
 ----------------------------------------- -------- ----------------------------
 PROD_ID       NOT NULL NUMBER(6)
 PROD_NAME         VARCHAR2(250)
 CP_ID        NOT NULL NUMBER(5)
 PROD_PY         VARCHAR2(50)
 DJ_TEST         NUMBER

 

7、删除临时表

 

DBMS_REDEFINITION涉及的过程后续介绍

 

 

 

 

 


 

 

你可能感兴趣的:(oracle)