其中EXEC DBMS_REDEFINITION.CAN_REDEF_TABLE('CSADMIN', 'XXOLD', DBMS_REDEFINITION.CONS_USE_PK);代表用主键,是默认选项
EXEC DBMS_REDEFINITION.CAN_REDEF_TABLE('CSADMIN', 'XXNEW', DBMS_REDEFINITION.CONS_USE_rowid);代表用rowid
用rowid的方式在转换之后会生成一个伪列,查询伪列名称
select * from user_tab_cols where table_name='OLD'
然后将伪列drop掉
alter table old set unused column "SYS_C00003_09111110:43:01$"
alter table old drop unused column
查询unused column 通过:select * from user_unused_col_tabs
在执行EXEC DBMS_REDEFINITION.START_REDEF_TABLE('CSADMIN', 'XXOLD','XXNEW',2);之后系统会将旧表的数据刷新到新表,同时生成一张名为
M$LOG_XXOLD的物化视图。此后,对新表的更新都会记录在这个视图里,在执行DBMS_REDEFINITION.sync_interim_table('CSADMIN','XXOLD','XXNEW');
或者EXEC DBMS_REDEFINITION.finish_redef_table('CSADMIN','XXOLD','XXNEW');后会自动将物化视图的记录更新到新表中。
sync_interim_table的目的是为了缩短finish时锁定表的时间。在执行finish之后,会自动删除这个物化视图。
如果中间过程出错要重新定义表的话,先执行 dbms_redefinition.abort_redef_table中断转换,然后要手工删除物化视图和新表再重新定义。
DROP MATERILIZED VIEW XXNEW;
DROP TABLE XXNEW;
DROP MATERILIZED VIEW LOG ON XXOLD;
交换后,旧表上的index和constraint也会交换到新表,同样新表上的定义也会交换给旧表。所以在finish前要先在新表上做相应的index和constraint,还有表的权限定义
以下是具体的测试。
**************************************************************************************
测试1:不管新表中的内容如何,在start之后都会被刷新成旧表的内容
SQL> select count(*) from old;
COUNT(*)
----------
4
SQL> select count(*) from new;
COUNT(*)
----------
4
SQL> insert into new values ('e',sysdate);
1 row inserted
SQL> commit;
Commit complete
SQL> exec dbms_redefinition.start_redef_table('csadmin','old','new',null,2);
PL/SQL procedure successfully completed
SQL> select count(*) from new;
COUNT(*)
----------
4
SQL> select count(*) from old;
COUNT(*)
----------
4
****************************************************************************************
测试2:在start之后,对新表的更新会记录在mlog$_old中,执行sync_interim_table时同步到new,同时清空
mlog$_old;在finish时也会同步一次,同时删除mlog$_old;
SQL> exec dbms_redefinition.start_redef_table('csadmin','old','new',null,2);
PL/SQL procedure successfully completed
SQL> select count(*) from new;
COUNT(*)
----------
4
SQL> select count(*) from old;
COUNT(*)
----------
4
SQL> insert into old values ('e',sysdate);
1 row inserted
SQL> commit;
Commit complete
SQL> select count(*) from mlog$_old;
COUNT(*)
----------
1
SQL> select count(*) from new;
COUNT(*)
----------
4
SQL> exec dbms_redefinition.sync_interim_table('csadmin','old','new');
PL/SQL procedure successfully completed
SQL> select count(*) from old;
COUNT(*)
----------
5
SQL> select count(*) from new;
COUNT(*)
----------
5
SQL> select count(*) from mlog$_old;
COUNT(*)
----------
0
SQL> insert into old values ('f',sysdate);
1 row inserted
SQL> commit;
Commit complete
SQL> select count(*) from old;
COUNT(*)
----------
6
SQL> select count(*) from new;
COUNT(*)
| 广告合作:400-664-0084 全国热线:400-664-0084 Copyright 2010 - 2017 www.my8848.com 珠峰网 粤ICP备15066211号 珠峰网 版权所有 All Rights Reserved
|