环境:
select *from v$version;
BANNER
--------------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Prod
PL/SQL Release 10.2.0.1.0 - Production
CORE 10.2.0.1.0 Production
TNS for 32-bit Windows: Version 10.2.0.1.0 - Production
NLSRTL Version 10.2.0.1.0 - Production
依据:
《ORACLE 高可用环境》--陈吉平
实验:
1 create table
create table test(a int, b int);
declare
i int;
begin
for i in 1..100 loop
insert into test values(i, 100-i);
end loop;
commit;
end;
/
create table audit_test
(c int)
/
insert into audit_test(c)
values((select count(1) from test))
/
create or replace trigger tr_test
before insert or update or delete on test
for each row
declare
pragma autonomous_transaction;
begin
update audit_test set c=c+1;
commit;
end;
/
2 检查该表是否可以被重定义
EXEC dbms_redefinition.can_redef_table('THINKAW','TEST');
--注:执行权限的问题,或者在SYS下执行,如果用户有EXEC DBMS_REDEFINITION的权限。
--grant execute on dbms_redefinition to thinkaw;
alter table test add constraint pk_test primary key(a)
/
3 create middle table
create table mid_test
(a int, b int, c int)
partition by range(a)
(partition p10 values less than(50),
partition p20 values less than(100),
partition p30 values less than(150),
partition p40 values less than (200))
/
select object_name, object_type, status, object_id, data_object_id
from user_objects
/
3 执行在线重定义
exec dbms_redefinition.start_redef_table('THINKAW','TEST','MID_TEST','a a,b b,0 c');
--注:如果没有足够的权限,则可能会遇到如下的错误:
第 1 行出现错误:
ORA-01031: 权限不足
ORA-06512: 在 "SYS.DBMS_REDEFINITION", line 50
ORA-06512: 在 "SYS.DBMS_REDEFINITION", line 1343
ORA-06512: 在 line 1
grant create any table,
alter any table,
rop any table,
lock any table,
select any table
to thinkaw
/
re exec dbms_redefinition.start_redef_table('THINKAW','TEST','MID_TEST','a a,b b,0 c');
select count(1) from mid_test;
re select object_name, object_type, status, object_id, data_object_id
from user_objects
/
查询到多了如下两个表:
MLOG$_TEST TABLE VALID 9751 9751
RUPD$_TEST TABLE VALID 9752
--some select
select count(1) from test;
select count(1)from mlog$_test;
select count(1) from rupd$_test;
select count(1)from mid_test;
select count(1) from audit_test;
4 在middle table上Create Primary Key或者Not NULL的唯一Constraints
alter table mid_test add constraint mid_test_pk primary key(a);
create trigger
……
5 exec sync
exec dbms_redefinition.sync_interim_table('THINKAW','TEST','MID_TEST');
--作用:刷新自start redefinition到sync之间原表的变化到MIDDLE TABLE
6 SOME WORK
将原表的一些权限赋给中间表
7 执行重构完成的过程
exec dbms_redefinition.finish_redef_table('THINKAW','TEST','MID_TEST');
--注:在本步中执行的是sync到finish之间的原表变化更新到MIDDLE TABLE和两个表名互换的过程。
--这里的表名更换涉及到的数据字典比较多,包括触发器中的名称。
结论:
1 原理同MV,从start redefine开始建立MV;
疑问:
1 为何MIDDLE TABLE需要在Sync之前建立主键等约束,书上说是为了避免刷新或者切换造成的失败,这里不太理解,我自己理解为如果不建立约束,那么重定义完成之后就投入使用的表是有问题的(可能会导致破坏原表完整性的数据进入);