11G online redefinition的几个常用实例

11G的online redefinition有了不少功能增强,相信大家都在其他地方早已经看到这些概念,于是不再废话,直接来看一下我们可能常常需要问到的几种实际例子。

1.Add column

11G的alter table add column操作已经有了不小改进,尤其是对add column with default value采用ecol$表存储default value从而避免了对整表的update操作,但也因此引入了不断对ecol$表的查询的overhead。于是,此时我们想到了online redefinition。

--建测试表的SQL(分别建立各种相关的object用来测试):

--按照官方文档,trigger是不会自动recompile的,其他一般在online redefinition之后都为valid的状态,省去了DBA的麻烦。

create table hao(object_id,object_name,status) tablespace test_assm
as select object_id,object_name,status from dba_objects;

alter table hao add constraint haopk primary key (object_id);

create public synonym synhao for hao;

create view viewhao as select * from hao;

create or replace trigger thao  before insert on hao for each row
declare
 v_d hao%rowtype;
begin
 select * into v_d from hao where rownum=1;
end;
/


--建立TMPHAO作为中间表,并且add new column

SQL> create table tmphao as select * from hao where 1=2;

Table created.

SQL> alter table tmphao add object_id2 number;

Table altered.

SQL> select object_name,object_type,status from user_objects;

OBJECT_NAM OBJECT_TYPE         STATUS
---------- ------------------- -------
HAO        TABLE               VALID
HAOPK      INDEX               VALID
THAO       TRIGGER             VALID
TMPHAO     TABLE               VALID
VIEWHAO    VIEW                VALID

SQL> BEGIN
  2  DBMS_REDEFINITION.CAN_REDEF_TABLE(UNAME=>'HAO',TNAME=>'HAO',OPTIONS_FLAG=>DBMS_REDEFINITION.CONS_USE_PK);
  3  END;
  4  /

PL/SQL procedure successfully completed.

--这里我设定新加的column的default value为0

SQL> BEGIN
  2  DBMS_REDEFINITION.START_REDEF_TABLE('HAO', 'HAO','TMPHAO',
  3  'object_id object_id,object_name object_name,status status,0 object_id2',dbms_redefinition.cons_use_pk);
  4  END;
  5  / 

PL/SQL procedure successfully completed.

--我们看到开始重定义时,为了保证在该表的并发dml操作,其实是通过建立MV log来保证的。

SQL> select table_name from user_tables;

TABLE_NAME
------------------------------
HAO
MLOG$_HAO
RUPD$_HAO
TMPHAO

SQL> insert into hao values(1986000,'1986','1');

1 row created.

SQL> commit;

Commit complete.

SQL> select DMLTYPE$$,OLD_NEW$$ from MLOG$_HAO;

D O
- -
I N


SQL> DECLARE
  2  num_errors PLS_INTEGER;
  3  BEGIN
  4  DBMS_REDEFINITION.COPY_TABLE_DEPENDENTS('HAO', 'HAO','TMPHAO',
  5  DBMS_REDEFINITION.CONS_ORIG_PARAMS, TRUE, TRUE, TRUE, TRUE, num_errors);
  6  END;
  7  /

PL/SQL procedure successfully completed.

SQL> select object_name, base_table_name, ddl_txt from
  2  DBA_REDEFINITION_ERRORS;

no rows selected

--而DBMS_REDEFINITION.SYNC_INTERIM_TABLE的作用有点像对MV的一次fast refresh,以减少finish online redefinition的lock时间。

SQL> BEGIN
  2  DBMS_REDEFINITION.SYNC_INTERIM_TABLE('HAO', 'HAO', 'TMPHAO');
  3  END;
  4  /  

PL/SQL procedure successfully completed.

SQL> select DMLTYPE$$,OLD_NEW$$ from MLOG$_HAO;

no rows selected

SQL> BEGIN
  2  DBMS_REDEFINITION.FINISH_REDEF_TABLE('HAO', 'HAO', 'TMPHAO');
  3  END;
  4  /  

PL/SQL procedure successfully completed.

SQL> select table_name from user_tables;

TABLE_NAME
------------------------------
HAO
TMPHAO

--这里我们看到view和trigger为INVALID,trigger可以理解,但view为什么呢?

--原来是因为view里有select *的字样,oracle自动转换为当时的具体字段,所以这点要注意。

--而trigger里也有select *,但是并没有转换为当时的具体字段。

SQL>  select object_name,object_type,status from user_objects;

OBJECT_NAME          OBJECT_TYPE         STATUS
-------------------- ------------------- -------
HAO                  TABLE               VALID
HAOPK                INDEX               VALID
THAO                 TRIGGER             INVALID
TMP$$_HAOPK0         INDEX               VALID
TMP$$_THAO0          TRIGGER             INVALID
TMPHAO               TABLE               VALID
VIEWHAO              VIEW                INVALID

SQL> select text from user_views;

TEXT
--------------------------------------------------------------------------------
select "OBJECT_ID","OBJECT_NAME","STATUS" from hao

SQL> select trigger_body from user_triggers where trigger_name='THAO';

TRIGGER_BODY
--------------------------------------------------------------------------------
declare
 v_d hao%rowtype;
begin
 select * into v_d from hao where rownum=1;
end;

--我们可以通过触发view和trigger一次,就可以让其自动recompile为VALID状态。

SQL> select * from VIEWHAO where rownum=1;

 OBJECT_ID OBJECT_NAME          STATUS
---------- -------------------- -------
       105 ACCESS$              VALID

SQL> insert into hao values(999999,'999999','9','0');

1 row created.

SQL> insert into tmphao values(999999,'999999','9');

1 row created.

SQL> select object_name,object_type,status from user_objects;

OBJECT_NAME          OBJECT_TYPE         STATUS
-------------------- ------------------- -------
HAO                  TABLE               VALID
HAOPK                INDEX               VALID
THAO                 TRIGGER             VALID
TMP$$_HAOPK0         INDEX               VALID
TMP$$_THAO0          TRIGGER             VALID
TMPHAO               TABLE               VALID
VIEWHAO              VIEW                VALID

--synonym也为INVALID状态,只需引用一次即可。

SQL> select OBJECT_NAME,OBJECT_TYPE,STATUS from dba_objects where OBJECT_NAME='SYNHAO';

OBJECT_NAME          OBJECT_TYPE         STATUS
-------------------- ------------------- -------
SYNHAO               SYNONYM             INVALID

SQL> show parameter compatible

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
compatible                           string      11.2.0.1
SQL> select * from SYNHAO where rownum=1;

 OBJECT_ID OBJECT_NAME          STATUS  OBJECT_ID2
---------- -------------------- ------- ----------
       105 ACCESS$              VALID            0

SQL> select OBJECT_NAME,OBJECT_TYPE,STATUS from dba_objects where OBJECT_NAME='SYNHAO';

OBJECT_NAME          OBJECT_TYPE         STATUS
-------------------- ------------------- -------
SYNHAO               SYNONYM             VALID

--除此之外,我在《在线重定义表导致constraint变成novalidate》里专门提到过这种情况:

SQL> l
  1  select CONSTRAINT_NAME,TABLE_NAME,STATUS,VALIDATED from user_constraints
  2* where CONSTRAINT_NAME='HAOPK'
SQL> /

CONSTRAINT_NAME                TABLE_NAME                     STATUS   VALIDATED
------------------------------ ------------------------------ -------- -------------
HAOPK                          HAO                            ENABLED  NOT VALIDATED


SQL> alter table hao enable validate primary key;

Table altered.

SQL> select CONSTRAINT_NAME,TABLE_NAME,STATUS,VALIDATED from user_constraints
  2  where CONSTRAINT_NAME='HAOPK'                                           
  3  ;

CONSTRAINT_NAME                TABLE_NAME                     STATUS   VALIDATED
------------------------------ ------------------------------ -------- -------------
HAOPK                          HAO                            ENABLED  VALIDATED

--如果我们在online redefinition过程中遇到任何Error,都可以立即终止:

BEGIN
DBMS_REDEFINITION.ABORT_REDEF_TABLE('HAO', 'HAO','TMPHAO');
END;
/

2.普通表转为partition table

--建立TMPHAO2为一个range partition table作为中间表

create table tmphao2
(OBJECT_ID NUMBER,
OBJECT_NAME VARCHAR2(128),
STATUS VARCHAR2(7),
OBJECT_ID2 NUMBER)
partition by range(OBJECT_ID)
(partition p1 values less than(10),
partition p2 values less than(20),
partition p3 values less than(maxvalue)
);
  

--同样的命令,只是记得查看所有invalid的objects。

SQL> BEGIN
  2  DBMS_REDEFINITION.CAN_REDEF_TABLE(UNAME=>'HAO',TNAME=>'HAO',OPTIONS_FLAG=>DBMS_REDEFINITION.CONS_USE_PK);
  3  END;
  4  /

PL/SQL procedure successfully completed.        


SQL> BEGIN
  2  DBMS_REDEFINITION.START_REDEF_TABLE('HAO', 'HAO','TMPHAO2',
  3  '*',dbms_redefinition.cons_use_pk);
  4  END;
  5  /         
 

SQL> DECLARE
  2  num_errors PLS_INTEGER;
  3  BEGIN
  4  DBMS_REDEFINITION.COPY_TABLE_DEPENDENTS('HAO', 'HAO','TMPHAO2',
  5  DBMS_REDEFINITION.CONS_ORIG_PARAMS, TRUE, TRUE, TRUE, TRUE, num_errors);
  6  END;        
  7  /        
        
PL/SQL procedure successfully completed.                                                                    
 
SQL> select object_name, base_table_name, ddl_txt from
  2  DBA_REDEFINITION_ERRORS;
        
no rows selected 
 
SQL> BEGIN
  2  DBMS_REDEFINITION.FINISH_REDEF_TABLE('HAO', 'HAO', 'TMPHAO2');
  3  END;
  4  /  

PL/SQL procedure successfully completed. 
 
SQL>  select PARTITION_NAME from user_tab_partitions where TABLE_NAME='HAO';

PARTITION_NAME
------------------------------
P1
P2
P3

3.更改被index的column name。

--这时我在前面的HAO的object_id2上建立index。

SQL> create index haoidx2 on HAO(object_id2) local;

Index created.

--在TMPHAO3中将object_id2改为object_id3

--如果直接DBMS_REDEFINITION.COPY_TABLE_DEPENDENTS,会报错说找不到object_id2这个column。

--所以需要我们手工register

create table tmphao3
(OBJECT_ID NUMBER,
OBJECT_NAME VARCHAR2(128),
STATUS VARCHAR2(7),
OBJECT_ID3 NUMBER)
partition by range(OBJECT_ID)
(partition p1 values less than(10),
partition p2 values less than(20),
partition p3 values less than(maxvalue)
); 

SQL> create index haoidx3 on tmphao3(object_id3) local;

Index created.

exec DBMS_REDEFINITION.CAN_REDEF_TABLE(UNAME=>'HAO',TNAME=>'HAO',OPTIONS_FLAG=>DBMS_REDEFINITION.CONS_USE_PK);
 
BEGIN
DBMS_REDEFINITION.START_REDEF_TABLE('HAO', 'HAO','TMPHAO3',
'OBJECT_ID OBJECT_ID,OBJECT_NAME OBJECT_NAME,STATUS STATUS,OBJECT_ID2 OBJECT_ID3',dbms_redefinition.cons_use_pk);
END;
/


BEGIN
DBMS_REDEFINITION.REGISTER_DEPENDENT_OBJECT(
uname => 'HAO',
orig_table => 'HAO',
int_table => 'TMPHAO3',
dep_type => DBMS_REDEFINITION.CONS_INDEX,
dep_owner => 'HAO',
dep_orig_name => 'HAOIDX2',
dep_int_name => 'HAOIDX3');
END;
/
 
DECLARE                                                                        
num_errors PLS_INTEGER;                                                      
BEGIN                                                                        
DBMS_REDEFINITION.COPY_TABLE_DEPENDENTS('HAO', 'HAO','TMPHAO3',              
DBMS_REDEFINITION.CONS_ORIG_PARAMS, TRUE, TRUE, TRUE, TRUE, num_errors);     
END;                                                                         
/
                                                                                                                                         
SQL>  select object_name, base_table_name, ddl_txt from      
  2   DBA_REDEFINITION_ERRORS;                               
                                                             
no rows selected   

exec DBMS_REDEFINITION.FINISH_REDEF_TABLE('HAO', 'HAO', 'TMPHAO3'); 

SQL> l                                                                        
  1* select INDEX_NAME,COLUMN_NAME from user_ind_columns where TABLE_NAME='HAO'
SQL> /                                                                        
                                                                              
INDEX_NAME                     COLUMN_NAM                                     
------------------------------ ----------                                     
HAOIDX2                        OBJECT_ID3                                     
HAOPK                          OBJECT_ID
                                      

4.更改表所在的tablespace

过程完全如前。只是中间表建立在所期望的tablespace上。

5.long转换为clob,long raw转换为blob

create table hao2 (id number primary key,name long);
insert into hao2 select object_id,'hao' from dba_objects;

create table tmp_hao2 (id number,name clob);

BEGIN
DBMS_REDEFINITION.START_REDEF_TABLE('HAO', 'HAO2','TMP_HAO2',
'id id,to_lob(name) name',dbms_redefinition.cons_use_pk);
END;
/

 
DECLARE                                                                        
num_errors PLS_INTEGER;                                                      
BEGIN                                                                        
DBMS_REDEFINITION.COPY_TABLE_DEPENDENTS('HAO', 'HAO2','TMP_HAO2',              
DBMS_REDEFINITION.CONS_ORIG_PARAMS, TRUE, TRUE, TRUE, TRUE, num_errors);     
END;                                                                         
/

SQL>  select object_name, base_table_name, ddl_txt from      
  2   DBA_REDEFINITION_ERRORS;                               
                                                             
no rows selected   

exec DBMS_REDEFINITION.FINISH_REDEF_TABLE('HAO', 'HAO2', 'TMP_HAO2'); 
                                                                  
SQL>  desc hao2                                                                
 Name                                      Null?    Type                       
 ----------------------------------------- -------- ----------------------------
 ID                                        NOT NULL NUMBER                     
 NAME                                               CLOB
           

 

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/15415488/viewspace-626671/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/15415488/viewspace-626671/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值