• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
了解Oracle在线重定义online redefinition
 

了解Oracle在线重定义online redefinition

on

  • 1,889 views

Online ...

Online Redefinition在线重定义对象是Oracle中很酷的一种特性,它可以帮助我们在7*24在线的系统中从容地做出数据对象的在线定义修改,是Oracle数据库保证其高可用性的重要技术。

Statistics

Views

Total Views
1,889
Views on SlideShare
1,437
Embed Views
452

Actions

Likes
0
Downloads
43
Comments
0

8 Embeds 452

http://www.oracledatabase12g.com 219
http://www.askmaclean.com 198
http://feeds2.feedburner.com 14
http://translate.googleusercontent.com 10
http://www.zhuaxia.com 5
http://zhuaxia.com 3
http://webcache.googleusercontent.com 2
http://xianguo.com 1
More...

Accessibility

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    了解Oracle在线重定义online redefinition 了解Oracle在线重定义online redefinition Document Transcript

    • 了解 Oracle 在线重定义 Online Redefinition by Maclean.liu liu.maclean@gmail.com www.oracledatabase12g.com
    • About Mel Email:liu.maclean@gmail.coml Blog:www.oracledatabase12g.coml Oracle Certified Database Administrator Master 10gand 11gl Over 6 years experience with Oracle DBA technologyl Over 7 years experience with Linux technologyl Member Independent Oracle Users Groupl Member All China Oracle Users Groupl Presents for advanced Oracle topics: RAC,DataGuard, Performance Tuning and Oracle Internal.
    • How To Find Maclean Liu?
    • Online Redefinition 在线重定义对象是 Oracle 中很酷的一种特性,它可以帮助我们在 7*24 在线的系统中从容地做出数据对象的在线定义修改,是 Oracle 数据库保证其高可用性的重要技术。在线重定义 Online Redefinition 特性在许多场景中都是十分有用的,例如: • 修改表的 Storage 存储参数 • 在同一 Schema 下将表移动到不同的表空间 • 转换非分区表为分区表 • 添加或删除分区 • 重新创建表以减少碎片,降低高水位 • 将堆组织的表改变为索引组织表 • 添加或删除列
    • 使用 Online Redefinition 在线重定义需要用到 DBMS_REDEFINITION 程序包,EXECUTE_CATALOG_ROLE 角色默认被赋予该 PL/SQL Package 的执行权限。除了执行该程序包的权限外,用户还需要拥有以下权限: • CREATE ANY TABLE • ALTER ANY TABLE • DROP ANY TABLE • LOCK ANY TABLE • SELECT ANY TABLE若要执行 COPY_TABLE_DEPENDENTS 存储过程则还需要以下权限: • CREATE ANY TRIGGER • CREATE ANY INDEX在早期版本中在线重定义(Online Redefinition)对于某些具有特殊数据类型的表存在诸多限制,从 Oracle 10g 开始拥有以下数据类型的表也支持在线重定义(Online Redefinition)了: 1. 存在 LONG 类型 column 字段的表可以被在线重定义(redefined online);但是 LONG 类 型字段只能被转换为 character large object 即 CLOB 2. 存在 LONG RAW 类型 column 字段的表可以被在线重定义(redefined online);但是 LONG RAW 类型字段只能被转换为 binary large object 即 BLOB此外从 10g 开始支持对 replication table 的在线重定义: 1. 包含在 master-master replications 中的表 2. 在 n-way master 复制环境中没有 horizontal 或 vertical subsetting,或者允许 column transformations 的表我们可以通过以下步骤一步一步地完成对一张普通堆表的在线重定义(Online Redefinition):
    • 步骤 1:决定我们所要使用的重定义方式(redefinition method),存在 2 种方式: • 第一种是我们较为推荐的方式,采用 Primary Key 主键或者 pseudoprimary key 伪主键 实施重定义(从 Oracle 10g 开始支持 pseudoprimary key 伪主键)。 这里 pseudoprimary key 伪主键要求是唯一键且所有的成员列均是非空 NOT NULL。使用该种方式,重定 义前和重定义后版本的表均必须有相同的 Primary Key 主键或者 pseudoprimary key 伪 主键列。不管是从性能角度,还是从操作的复杂度考虑,常规场景中都推荐尽可能使 用此种方式 • 第二种方式是使用 rowid 进行 redefinition。首先索引组织表 index-organized table (IOT) 不支持使用 rowid 的重定义方式。此外,若使用该种 redefinition 方式,最终会有一个 隐藏的字段 M_ROW$$被加入到重定义后版 本的表上,Oracle 官方推荐在重定义完成 后将该 M_ROW$$字段 drop 掉或者标记为 unused。步骤 2:通过调用 DBMS_REDEFINITION.CAN_REDEF_TABLE 存储过程并以OPTIONS_FLAG(flag indicating user options to use)参数指定所要使用的重定义方式,来验证原表是否可以以这样的方式来在线重定义。若原表不符合指定重定义方式的要求,那么该过程会报出一个错误,说 明该表不能在线重定义的具体原因。若指定 OPTIONS_FLAG 为常数 DBMS_REDEFINITION.CONS_USE_PK(cons_use_pkCONSTANT PLS_INTEGER := 1;),意为使用 primary keys 或 pseudoprimary keys 的重定义方式。若指定 OPTIONS_FLAG 为常数DBMS_REDEFINITION.CONS_USE_ROWID(cons_use_rowid CONSTANT PLS_INTEGER :=2;),意为使用 rowid 的重定义方式。DBMS_REDEFINITION.CAN_REDEF_TABLE 过程的详细定义如下:-- NAME: can_redef_table - check if given table can be re-defined-- INPUTS: uname - table owner name-- tname - table name-- options_flag - flag indicating user options to use-- part_name - partition namePROCEDURE can_redef_table(uname IN VARCHAR2, tname IN VARCHAR2, options_flag IN PLS_INTEGER := 1, part_name IN VARCHAR2 := NULL);
    • 步骤 3:在原表的同一 Schema 下创建一张空的临时表(interim table), 该表具有所有我们想要的属性。若有 column 字段需要通过重定义 drop 掉,那么就在这张临时表的定义中去掉该column。同理若有 column 字段 需要通过重定义加入到表上,那么就在临时表上加入该column 的定义。理论上我们可以并行地实施表的在线重定义;若已经同时指定了原表和临时表的并发度,那么也请确保实施操作的本会话(session)已经启用了会话 级别的并行执行, 这样 Oracle 服务进程会在实施重定义的过程中尽可能地使用并行执行( parallel execution )。可以采用以下 ALTER SESSION 命令启用并行的 DML 和查询:alter session force parallel dml parallel 4;alter session force parallel query parallel 4;如原表的结构为 HR.JOBS:SQL> desc hr.jobs; Name Null? Type ----------------------------------------- -------- ---------------------------- JOB_ID NOT NULL VARCHAR2(10) JOB_TITLE NOT NULL VARCHAR2(35) MIN_SALARY NUMBER(8) MAX_SALARY NUMBER(8) EXEMPT_STATUS VARCHAR2(3)
    • 希望在此原表结构基础上加入默认为 188 的 Number 类型名为 Maclean 的字段 column,那么我们创建临时表如下:SQL> create table hr.jobs_hist_int 2 ( job_id varchar2(10) primary key, 3 job_title varchar2(35) NOT NULL, 4 min_salary number(8), 5 max_salary number(8), 6 exempt_status varchar2(3), 7 maclean number(8) default 188);Table created.步骤 4: 调用 DBMS_REDEFINITION.START_REDEF_TABLE 存储过程启动重定义进程,使用该过程需要指定以下的参数: 1. 将要重定义的表名 2. 临时表的名字(interim table name) 3. 字段的映射信息(column mapping) 4. 重定义使用的方式(primary key or rowid) 5. 此外还可以指定用以排序的字段若字段映射参数 column mapping 未指定,那么 Oracle 假设所有原表上的列(字段名不变)都被包含在中间表上了。 若指定了 column mapping 信息,那么只有那些在字段映射中明确指定的原表字段被考虑重定义。若没有指定使用何种重定义方式,那么 Oracle 默认会采用primary keys 或 pseudoprimary keys 的方式。从 10g 开始出现了 ORDERBY_COLS 参数可以用于指定在临时表初始化过程中数据行按照字段排序。
    • DBMS_REDEFINITION.START_REDEF_TABLE 过程的具体定义如下:-- NAME: start_redef_table - start the online re-organization-- INPUTS: uname - schema name-- orig_table - name of table to be re-organized-- int_table - name of interim table-- col_mapping - select list col mapping-- options_flag - flag indicating user options to use-- orderby_cols - comma separated list of order by columns-- followed by the optional ascending/descending-- keyword-- part_name - name of the partition to be redefinedPROCEDURE start_redef_table(uname IN VARCHAR2, orig_table IN VARCHAR2, int_table IN VARCHAR2, col_mapping IN VARCHAR2 := NULL, options_flag IN BINARY_INTEGER := 1, orderby_cols IN VARCHAR2 := NULL, part_name IN VARCHAR2 := NULL);步骤 5: 使用 10g 以后出现的 COPY_TABLE_DEPENDENTS 存储过程在临时表上自动创建如 constraints, triggers, indexes,privileges 类型的依赖对象(dependent object)。该COPY_TABLE_DEPENDENTS 过程同时也会注册这些依赖对象。使用 COPY_TABLE_DEPENDENTS 克隆依赖对象要比后面介绍REGISTER_DEPENDENT_OBJECTS 过程来得简单方便。该存储过程的 NUM_ERRORS(number of errors that occurred while cloning ddl)输出参数,显示了其运行过程中所产生的错误数量。若 IGNORE_ERRORS(TRUE implies continue after errors,FALSE otherwise)参数设置为 TRUE,那么该过程会忽略错误信息并不输出,继续其工作。若设置为 FALSE,那么错误会在错误堆栈中显性输出。
    • DBMS_REDEFINITION.COPY_TABLE_DEPENDENTS 过程的定义如下: -- NAME: copy_table_dependents -- -- INPUTS: uname - schema name -- orig_table - name of table to be re-organized -- int_table - name of interim table -- copy_indexes - integer value indicating whether to -- copy indexes -- 0 - dont copy -- 1 - copy using storage params/tablespace -- of original index -- copy_triggers - TRUE implies copy triggers, FALSE otherwise -- copy_constraints - TRUE implies copy constraints, FALSE -- otherwise -- copy_privileges - TRUE implies copy priviliges, FALSE -- otherwise -- ignore errors - TRUE implies continue after errors, FALSE -- otherwise -- num_errors - number of errors that occurred while -- cloning ddl -- copy_statistics - TURE implies copy table statistics, FALSE -- otherwise. -- If copy_indexes is 1, copy index -- related statistics, 0 otherwise. PROCEDURE copy_table_dependents(uname IN VARCHAR2, orig_table IN VARCHAR2, int_table IN VARCHAR2, copy_indexes IN PLS_INTEGER := 1, copy_triggers IN BOOLEAN := TRUE, copy_constraints IN BOOLEAN := TRUE, copy_privileges IN BOOLEAN := TRUE, ignore_errors IN BOOLEAN := FALSE, num_errors OUT PLS_INTEGER, copy_statistics IN BOOLEAN := FALSE);我们可以通过查询 10g 以后出现的 DBA_REDEFINITION_ERRORS 视图(DBA_REDEFINITION_ERRORS is an online redefinition view and displays the dependentobjects for which errors were raised while attempting to create similar objects on the interim tableof the redefinition.)来判断在使用 COPY_TABLE_DEPENDENTS 存储过程克隆依赖对象过程中是否产生了错误。该视图记录了重定义过 程中在克隆依赖对象时产生的错误。 克隆对象可能因缺少系统资源或原表的一个逻辑结构变化而失败。
    • 在我们成功克隆这些依赖对象后,相关错误将会从该视图中被移除。 我们可以反复执行COPY_TABLE_DEPENDENTS 或后面介绍的 REGISTER_DEPENDENT_OBJECTS 过程尝试重新克隆依赖对象。示例错误如下:SQL> select * from DBA_REDEFINITION_ERRORS;OBJECT_TYP OBJECT_OWNER OBJECT_NAME---------- ------------------------------ ------------------------------BASE_TABLE_OWNER BASE_TABLE_NAME------------------------------ ------------------------------DDL_TXT--------------------------------------------------------------------------------INDEX HR JOB_ID_PKHR JOBSCREATE UNIQUE INDEX "HR"."TMP$$_JOB_ID_PK0" ON "HR"."INT_JOBS_HIST" ("JOB_ID")步骤 6: 这不是必需的步骤。我们也可以使用 10g 以后出现的REGISTER_DEPENDENT_OBJECT 将正要重定义的表上 的依赖对象注册到临时表上对应的依赖对象。 换句话说 COPY_TABLE_DEPENDENTS 的功能,REGISTER_DEPENDENT_OBJECT 也是可以做到的,但是没有COPY_TABLE_DEPENDENTS 来得简单方便。若我们想在原表的基础上建立额外的依赖对象,那么也可以用该过程来手动建立。若之前的 COPY_TABLE_DEPENDENTS 运行失败了,那么也可以通过 REGISTER_DEPENDENT_OBJECT 来手工补救,注册那些没有克 隆成功的依赖对象。注意 REGISTER_DEPENDENT_OBJECT 过程也是 10g 以后出现的,在早期版本中我们是要手动重命名依赖对象的。
    • DBMS_REDEFINITION.REGISTER_DEPENDENT_OBJECT 的详细定义如下: -- NAME: register_dependent_object - register dependent object -- -- INPUTS: uname - schema name -- orig_table - name of table to be re-organized -- int_table - name of interim table -- dep_type - type of the dependent object -- dep_owner - name of the dependent object owner -- dep_orig_name- name of the dependent object defined on table -- being re-organized -- dep_int_name - name of the corressponding dependent object on -- the interim table PROCEDURE register_dependent_object(uname IN VARCHAR2, orig_table IN VARCHAR2, int_table IN VARCHAR2, dep_type IN PLS_INTEGER, dep_owner IN VARCHAR2, dep_orig_name IN VARCHAR2, dep_int_name IN VARCHAR2);与 REGISTER_DEPENDENT_OBJECT 相反, unregister_dependent_object 过程用以注销依赖对象(unregister dependent object)。通过查询 10g 以后出现的 DBA_REDEFINITION_OBJECTS(an online redefinition view anddisplays the objects involved in the current redefinitions.)可以确认是否所有需要的依赖的对象都已被注册。该视图记录显示地被 REGISTER_DEPENDENT_OBJECT 注 册的或隐式地被COPY_TABLE_DEPENDENTS 注册的依赖对象。注意该视图仅包含当前重定义的信息。步骤 7:执行 DBMS_REDEFINITION.FINISH_REDEF_TABLE 存储过程完成表的在线重定义。在此 procedure 运行过程中,原表会被以 Exclusive lock mode(TM lmode=6)排他模式锁住极为短暂的一段时间(秒级),具体这段时间的长短受到原表上数据量的影响。 同时在此过程中,会发生以下事件: • 原表被真正意义上重定义,拥有临时表的所有属性、索引、约束、授权和触发器。 • 已注册的依赖对象会被自动重命名 • 临时表上的参考约束(referential constraint)会牵涉到重定义后的表上,且这些约束会被 自动启用。
    • 若重定义以 rowid 方式完成,那么重定义后的表上会出现一个隐藏字段叫做 M_ROW$$,我们推荐将该隐藏字段设置为 unused:ALTER TABLE table_name SET UNUSED (M_ROW$$)DBMS_REDEFINITION.FINISH_REDEF_TABLE 过程的详细定义如下: -- NAME: finish_redef_table - complete the online re-organization -- INPUTS: uname - schema name -- orig_table - name of table to be re-organized -- int_table - name of interim table -- part_name - name of the partition being redefined PROCEDURE finish_redef_table(uname IN VARCHAR2, orig_table IN VARCHAR2, int_table IN VARCHAR2, part_name IN VARCHAR2 := NULL);以上我们了解了一个在线重定义的主要步骤,以及 10g 中引入的一些新的 procedure 和有用视图,接下来我们实际操作一个在线重定义示范:原表的定义和数据量如下:create table SH.SALES( PROD_ID NUMBER not null, CUST_ID NUMBER not null, TIME_ID DATE not null, CHANNEL_ID NUMBER not null, PROMO_ID NUMBER not null, QUANTITY_SOLD NUMBER(10,2) not null, AMOUNT_SOLD NUMBER(10,2) not null)alter table SH.SALES add constraint SALES_CHANNEL_FK foreign key (CHANNEL_ID) references SH.CHANNELS (CHANNEL_ID);alter table SH.SALES add constraint SALES_CUSTOMER_FK foreign key (CUST_ID)
    • references SH.CUSTOMERS (CUST_ID);alter table SH.SALES add constraint SALES_PRODUCT_FK foreign key (PROD_ID) references SH.PRODUCTS (PROD_ID);alter table SH.SALES add constraint SALES_PROMO_FK foreign key (PROMO_ID) references SH.PROMOTIONS (PROMO_ID);alter table SH.SALES add constraint SALES_TIME_FK foreign key (TIME_ID) references SH.TIMES (TIME_ID);-- Create/Recreate indexescreate bitmap index SH.SALES_CHANNEL_BIX on SH.SALES (CHANNEL_ID);create bitmap index SH.SALES_CUST_BIX on SH.SALES (CUST_ID);create bitmap index SH.SALES_PROD_BIX on SH.SALES (PROD_ID);create bitmap index SH.SALES_PROMO_BIX on SH.SALES (PROMO_ID);create bitmap index SH.SALES_TIME_BIX on SH.SALES (TIME_ID);SQL> select count(*) from sh.sales; COUNT(*)---------- 918843现在希望在原表的基础上增加默认为 188 的 number 类型 maclean 字段,且将该表转换为按照range (TIME_ID)范围分区的分区表。因为该表上有 7*24 的更新业务如下,所以只能使用在线重定义方式,且因为该表上没有Primary key,所以只能使用 rowid 的重定义方式:begin loop insert into sh.sales values (42, 938, to_date(1998-01-01, YYYY-MM-DD), 2, 999, 1, 800); insert into sh.sales values (42, 938, to_date(1998-01-01, YYYY-MM-DD), 2, 999, 1, 800); delete sh.sales where rownum = 1; commit; dbms_lock.sleep(0.5); end loop;end;1. 利用 can_redef_table 存储过程验证原表是否可以以 rowid 方式重定义:
    • SQL> select * from v$version;BANNER----------------------------------------------------------------Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - 64biPL/SQL Release 10.2.0.1.0 - ProductionCORE 10.2.0.1.0 ProductionTNS for Linux: Version 10.2.0.1.0 - ProductionNLSRTL Version 10.2.0.1.0 - ProductionSQL> select * from global_name;GLOBAL_NAME--------------------------------------------------------------------------------www.oracledatabase12g.com & www.askmaclean.comSQL> conn sh/shConnected.SQL> begin 2 dbms_redefinition.can_redef_table(uname => SH, 3 tname => SALES, 4 options_flag =>DBMS_REDEFINITION.CONS_USE_ROWID); 5 end; 6 /begin*ERROR at line 1:ORA-12091: cannot online redefine table "SH"."SALES" with materialized viewsORA-06512: at "SYS.DBMS_REDEFINITION", line 137ORA-06512: at "SYS.DBMS_REDEFINITION", line 1478ORA-06512: at line 2发现 SALES 表上有物化视图,这回导致 online redefine 无法进行,找出物化视图并 drop 掉,完成重定义后可以重建这些 materialized view:SQL> select mview_name from dba_mviews where owner = SH;MVIEW_NAME------------------------------FWEEK_PSCAT_SALES_MVCAL_MONTH_SALES_MVSQL> drop materialized view CAL_MONTH_SALES_MV;Materialized view dropped.SQL> drop materialized view FWEEK_PSCAT_SALES_MV;Materialized view dropped.SQL> begin
    • 2 dbms_redefinition.can_redef_table(uname => SH, 3 tname => SALES, 4 options_flag =>DBMS_REDEFINITION.CONS_USE_ROWID); 5 end; 6 /PL/SQL procedure successfully completed.再次验证成功。2. 创建空的临时表,在原表的基础上加入 MACLEAN 字段以及分区定义:create table SH.INT_SALES( PROD_ID NUMBER not null, CUST_ID NUMBER not null, TIME_ID DATE not null, CHANNEL_ID NUMBER not null, PROMO_ID NUMBER not null, QUANTITY_SOLD NUMBER(10,2) not null, AMOUNT_SOLD NUMBER(10,2) not null, MACLEAN NUMBER(10,2) default 188 not null)partition by range (TIME_ID)( partition SALES_1995 values less than (TO_DATE( 1996-01-01 00:00:00, SYYYY-MM-DD HH24:MI:SS, NLS_CALENDAR=GREGORIAN)) tablespace EXAMPLE pctfree 0 initrans 1 maxtrans 255, partition SALES_1996 values less than (TO_DATE( 1997-01-01 00:00:00, SYYYY-MM-DD HH24:MI:SS, NLS_CALENDAR=GREGORIAN)) tablespace EXAMPLE pctfree 0 initrans 1 maxtrans 255, partition SALES_H1_1997 values less than (TO_DATE( 1997-07-01 00:00:00,SYYYY-MM-DD HH24:MI:SS, NLS_CALENDAR=GREGORIAN)) tablespace EXAMPLE pctfree 0 initrans 1 maxtrans 255,...................................
    • 建表 DDL 过长,以上节选主要部分并在会话级别启用 FORCE PARALLEL:alter session force parallel dml parallel 4;alter session force parallel query parallel 4;3.调用 DBMS_REDEFINITION.START_REDEF_TABLE 存储过程启动重定义进程SQL> set timing on;begin DBMS_REDEFINITION.START_REDEF_TABLE(uname => SH, orig_table => SALES, int_table => INT_SALES, col_mapping => PROD_ID PROD_ID,CUST_ID CUST_ID,TIME_IDTIME_ID,CHANNEL_ID CHANNEL_ID,PROMO_ID PROMO_ID,QUANTITY_SOLDQUANTITY_SOLD,AMOUNT_SOLD AMOUNT_SOLD, options_flag => DBMS_REDEFINITION.CONS_USE_ROWID);end;PL/SQL procedure successfully completed.Elapsed: 00:00:04.23SQL> select count(*) from int_sales; COUNT(*)---------- 921539Elapsed: 00:00:00.23
    • 4. 调用 COPY_TABLE_DEPENDENTS 过程克隆依赖对象:SQL> DECLARE 2 num_errors PLS_INTEGER; 3 BEGIN 4 DBMS_REDEFINITION.COPY_TABLE_DEPENDENTS(uname => SH, 5 orig_table => SALES, 6 int_table => INT_SALES, 7 copy_indexes =>DBMS_REDEFINITION.cons_orig_params, 8 copy_triggers => TRUE, 9 copy_constraints => FALSE, 10 copy_privileges => TRUE, 11 ignore_errors => FALSE, 12 num_errors => num_errors, 13 copy_statistics => TRUE); 14 END; 15 /DECLARE*ERROR at line 1:ORA-25122: Only LOCAL bitmap indexes are permitted on partitioned tablesORA-06512: at "SYS.DBMS_REDEFINITION", line 1173ORA-06512: at "SYS.DBMS_REDEFINITION", line 1712ORA-06512: at line 4Elapsed: 00:00:00.06SQL> select * from DBA_REDEFINITION_ERRORS;OBJECT_TYP OBJECT_OWNER OBJECT_NAME---------- ------------------------------ ------------------------------BASE_TABLE_OWNER BASE_TABLE_NAME------------------------------ ------------------------------DDL_TXT--------------------------------------------------------------------------------INDEX SH SALES_CHANNEL_BIXSH SALESCREATE BITMAP INDEX "SH"."TMP$$_SALES_CHANNEL_BIX0" ON "SH"."INT_SALES" ("CHANNE因为原表上有 bitmap indexes,而目标的 partitioned tables(分区表)仅支持 LOCAL bitmapindexes, 这里可以通过 REGISTER_DEPENDENT_OBJECT 来注册 LOCAL bitmap indexes 依
    • 赖对象,作为教学示例我们不这样做,而选择不克隆索引类型的依赖对象,指定copy_indexes 参数为 0:SQL> DECLARE 2 num_errors PLS_INTEGER; 3 BEGIN 4 DBMS_REDEFINITION.COPY_TABLE_DEPENDENTS(uname => SH, 5 orig_table => SALES, 6 int_table => INT_SALES, 7 copy_indexes => 0, 8 copy_triggers => TRUE, 9 copy_constraints => FALSE, 10 copy_privileges => TRUE, 11 ignore_errors => FALSE, 12 num_errors => num_errors, 13 copy_statistics => TRUE); 14 END; 15 /PL/SQL procedure successfully completed.Elapsed: 00:00:03.035. 利用 sync_interim_table 过程同步临时表的数据减少 finish_redef_table 的耗时:SQL> select count(*) from sales; COUNT(*)---------- 923046Elapsed: 00:00:00.01SQL> select count(*) from int_sales; COUNT(*)---------- 921539Elapsed: 00:00:00.24SQL> begin 2 dbms_redefinition.sync_redef_table(uname => SH, 3 orig_table => SALES, 4 int_table => INT_SALES); 5 end; 6 /
    • PL/SQL procedure successfully completed.Elapsed: 00:00:00.87SQL> select count(*) from int_sales; COUNT(*)---------- 9231356.执行 finish_redef_table 过程完成重定义:begin dbms_redefinition.finish_redef_table(uname => SH, orig_table => SALES, int_table => INT_SALES);end;/SQL> desc sales; Name Null? Type ----------------------------------------- -------- ---------------------------- PROD_ID NOT NULL NUMBER CUST_ID NOT NULL NUMBER TIME_ID NOT NULL DATE CHANNEL_ID NOT NULL NUMBER PROMO_ID NOT NULL NUMBER QUANTITY_SOLD NOT NULL NUMBER(10,2) AMOUNT_SOLD NOT NULL NUMBER(10,2) MACLEAN NOT NULL NUMBER(10,2)SQL> select count(*) from sales partition (SALES_Q2_2000); COUNT(*)---------- 55515Elapsed: 00:00:00.02SQL> select distinct maclean from sales; MACLEAN---------- 188Elapsed: 00:00:00.32
    • 以上成功完成了对 SALES 表的 Online Redefinition,由非分区表在线重定义为分区表且增加了一个字段。这里因为我们使用 rowid 方式,所以重定义完的表上会多出一个隐藏字段, 从 10.2 开始M_ROW$$的隐藏列会被命名为 SYS_%DATE%的形式,且默认即为 unused 状态:SQL> set linesize 90 pagesize 1400SQL> select * 2 from dba_tab_cols 3 where owner = SH 4 and column_name like SYS% 5 and table_name=SALES;OWNER TABLE_NAME------------------------------ ------------------------------COLUMN_NAME------------------------------DATA_TYPE------------------------------------------------------------------------------------------DAT DATA_TYPE_OWNER DATA_LENGTH DATA_PRECISION DATA_SCALE NCOLUMN_ID--- ------------------------------ ----------- -------------- ---------- -----------DEFAULT_LENGTH--------------DATA_DEFAULT--------------------------------------------------------------------------------NUM_DISTINCT LOW_VALUE------------ ----------------------------------------------------------------HIGH_VALUE DENSITYNUM_NULLS---------------------------------------------------------------- --------------------NUM_BUCKETS LAST_ANAL SAMPLE_SIZE CHARACTER_SET_NAME----------- --------- ----------- --------------------------------------------CHAR_COL_DECL_LENGTH GLO USE AVG_COL_LEN CHAR_LENGTH C V80 DAT HID VIRSEGMENT_COLUMN_ID-------------------- --- --- ----------- ----------- - --- --- --- --------------------INTERNAL_COLUMN_ID HISTOGRAM------------------ ---------------QUALIFIED_COL_NAME------------------------------------------------------------------------------------------SH SALESSYS_C00009_11120703:40:57$VARCHAR2 255 Y
    • CHAR_CS 255 NO NO 255 B NO YES YES NO 9 9 NONESYS_C00009_11120703:40:57$==========================================================================================SQL> select * from dba_unused_col_tabs ;OWNER TABLE_NAME COUNT------------------------------ ------------------------------ ----------SH SALES 1SQL> alter table sales drop unused columns;Table altered.Elapsed: 00:00:13.36SQL> select * from dba_unused_col_tabs ;no rows selected
    • 若在完成重定义(执行 finish_redef_table)之前希望中断在线重定义表,则需要使用DBMS_REDEFINITION.ABORT_REDEF_TABLE 明确手动中断 abort,如:begin dbms_redefinition.abort_redef_table(uname => SH, orig_table => SALES, int_table => INT_SALES);end;/该 abort_redef_table 过程的详细定义如下: -- NAME: abort_redef_table - clean up after errors or abort the -- online re-organization -- INPUTS: uname - schema name -- orig_table - name of table to be re-organized -- int_table - name of interim table -- part_name - name of the partition being redefined PROCEDURE abort_redef_table(uname IN VARCHAR2, orig_table IN VARCHAR2, int_table IN VARCHAR2, part_name IN VARCHAR2 := NULL);
    • © 2011, www.oracledatabase12g.com. 版权所有.文章允许转载,但必须以链接方式注明源地址,否则追究法律责任.相关文章 | Related Posts: 1. How to check and disable Adaptive Cursor Sharing in 11g 2. How to Re-Organize a Table Online 3. 解决 ORA-14098 分区交换索引不匹配错误 4. Oracle SQL Developer 的一个 Bug 5. 滚动游标失效(Rolling Cursor Invalidations) 6. SCRIPT: VALIDATE.SQL to ANALYZE .. VALIDATE STRUCTURE objects in a Tablespace 7. SQL PLAN MANAGEMENT 8. How to find error message from OMS repository