24
了解 Oracle 在线重定义 Online Redefinition by Maclean.liu [email protected] www.oracledatabase12g.com

了解Oracle在线重定义online redefinition

Embed Size (px)

DESCRIPTION

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

Citation preview

Page 1: 了解Oracle在线重定义online redefinition

了解 Oracle在线重定义Online Redefinition

by [email protected]

www.oracledatabase12g.com

Page 2: 了解Oracle在线重定义online redefinition

About Me

l Email:[email protected]

l Blog:www.oracledatabase12g.com

l Oracle Certified Database Administrator Master 10g and 11g

l Over 6 years experience with Oracle DBA technology

l Over 7 years experience with Linux technology

l Member Independent Oracle Users Group

l Member All China Oracle Users Group

l Presents for advanced Oracle topics: RAC, DataGuard, Performance Tuning and Oracle Internal.

Page 3: 了解Oracle在线重定义online redefinition

How To Find Maclean Liu?

Page 4: 了解Oracle在线重定义online redefinition

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

在线重定义 Online Redefinition 特性在许多场景中都是十分有用的,例如:

• 修改表的 Storage 存储参数 • 在同一 Schema 下将表移动到不同的表空间 • 转换非分区表为分区表 • 添加或删除分区 • 重新创建表以减少碎片,降低高水位 • 将堆组织的表改变为索引组织表 • 添加或删除列

Page 5: 了解Oracle在线重定义online redefinition

使用 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):

Page 6: 了解Oracle在线重定义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_pk

CONSTANT 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 name PROCEDURE can_redef_table(uname IN VARCHAR2, tname IN VARCHAR2, options_flag IN PLS_INTEGER := 1, part_name IN VARCHAR2 := NULL);

Page 7: 了解Oracle在线重定义online redefinition

步骤 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)

Page 8: 了解Oracle在线重定义online redefinition

希望在此原表结构基础上加入默认为 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 参数可以用于指定在临时表初始化过程中数据行按照字段排序。

Page 9: 了解Oracle在线重定义online redefinition

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 redefined PROCEDURE 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,那么错误会在错误堆栈中显性输出。

Page 10: 了解Oracle在线重定义online redefinition

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 - don't 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 dependent objects for which errors were raised while attempting to create similar objects on the interim table

of the redefinition.)来判断在使用 COPY_TABLE_DEPENDENTS 存储过程克隆依赖对象过程中是否产生了错误。该视图记录了重定义过 程中在克隆依赖对象时产生的错误。 克隆对象可能因缺少系统资源或原表的一个逻辑结构变化而失败。

Page 11: 了解Oracle在线重定义online redefinition

在我们成功克隆这些依赖对象后,相关错误将会从该视图中被移除。 我们可以反复执行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 以后出现的,在早期版本中我们是要手动重命名依赖对象的。

Page 12: 了解Oracle在线重定义online redefinition

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 and

displays 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)会牵涉到重定义后的表上,且这些约束会被自动启用。

Page 13: 了解Oracle在线重定义online redefinition

若重定义以 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)

Page 14: 了解Oracle在线重定义online redefinition

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 方式重定义:

Page 15: 了解Oracle在线重定义online redefinition

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 - Production

SQL> select * from global_name;

GLOBAL_NAME--------------------------------------------------------------------------------www.oracledatabase12g.com & www.askmaclean.com

SQL> 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_MV

SQL> drop materialized view CAL_MONTH_SALES_MV;

Materialized view dropped.

SQL> drop materialized view FWEEK_PSCAT_SALES_MV;

Materialized view dropped.

SQL> begin

Page 16: 了解Oracle在线重定义online redefinition

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,...................................

Page 17: 了解Oracle在线重定义online redefinition

建表 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_ID TIME_ID,CHANNEL_ID CHANNEL_ID,PROMO_ID PROMO_ID,QUANTITY_SOLD QUANTITY_SOLD,AMOUNT_SOLD AMOUNT_SOLD', options_flag => DBMS_REDEFINITION.CONS_USE_ROWID);end;PL/SQL procedure successfully completed.

Elapsed: 00:00:04.23

SQL> select count(*) from int_sales;

COUNT(*)---------- 921539

Elapsed: 00:00:00.23

Page 18: 了解Oracle在线重定义online redefinition

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 4

Elapsed: 00:00:00.06

SQL> 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 bitmap

indexes, 这里可以通过 REGISTER_DEPENDENT_OBJECT 来注册 LOCAL bitmap indexes依

Page 19: 了解Oracle在线重定义online redefinition

赖对象,作为教学示例我们不这样做,而选择不克隆索引类型的依赖对象,指定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.03

5. 利用 sync_interim_table 过程同步临时表的数据减少 finish_redef_table 的耗时:

SQL> select count(*) from sales;

COUNT(*)---------- 923046

Elapsed: 00:00:00.01

SQL> select count(*) from int_sales;

COUNT(*)---------- 921539

Elapsed: 00:00:00.24

SQL> begin 2 dbms_redefinition.sync_redef_table(uname => 'SH', 3 orig_table => 'SALES', 4 int_table => 'INT_SALES'); 5 end; 6 /

Page 20: 了解Oracle在线重定义online redefinition

PL/SQL procedure successfully completed.

Elapsed: 00:00:00.87

SQL> select count(*) from int_sales;

COUNT(*)---------- 923135

6.执行 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(*)---------- 55515

Elapsed: 00:00:00.02

SQL> select distinct maclean from sales;

MACLEAN---------- 188

Elapsed: 00:00:00.32

Page 21: 了解Oracle在线重定义online redefinition

以上成功完成了对 SALES 表的 Online Redefinition,由非分区表在线重定义为分区表且增加了一个字段。

这里因为我们使用 rowid 方式,所以重定义完的表上会多出一个隐藏字段, 从 10.2 开始M_ROW$$的隐藏列会被命名为 SYS_%DATE%的形式,且默认即为 unused状态:

SQL> set linesize 90 pagesize 1400

SQL> 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 N COLUMN_ID--- ------------------------------ ----------- -------------- ---------- - ----------DEFAULT_LENGTH--------------DATA_DEFAULT--------------------------------------------------------------------------------NUM_DISTINCT LOW_VALUE------------ ----------------------------------------------------------------HIGH_VALUE DENSITY NUM_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 VIR SEGMENT_COLUMN_ID-------------------- --- --- ----------- ----------- - --- --- --- --- -----------------INTERNAL_COLUMN_ID HISTOGRAM------------------ ---------------QUALIFIED_COL_NAME------------------------------------------------------------------------------------------SH SALESSYS_C00009_11120703:40:57$VARCHAR2 255 Y

Page 22: 了解Oracle在线重定义online redefinition

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 1

SQL> alter table sales drop unused columns;

Table altered.

Elapsed: 00:00:13.36

SQL> select * from dba_unused_col_tabs ;

no rows selected

Page 23: 了解Oracle在线重定义online redefinition

若在完成重定义(执行 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);

Page 24: 了解Oracle在线重定义online redefinition

© 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