在线重定义是通过物化视图进行更新,下面我们做一个实验来更了解在线重定义的原理:
SQL> alter table test add constraint PK_ID primary key (object_id);
表已更改。
SQL> create table test_partition
(
OWNER VARCHAR2(30),
OBJECT_NAME VARCHAR2(128),
SUBOBJECT_NAME VARCHAR2(30),
OBJECT_ID NUMBER,
DATA_OBJECT_ID NUMBER,
OBJECT_TYPE VARCHAR2(19),
CREATED DATE,
LAST_DDL_TIME DATE,
TIMESTAMP VARCHAR2(19),
STATUS VARCHAR2(7),
TEMPORARY VARCHAR2(1),
GENERATED VARCHAR2(1),
SECONDARY VARCHAR2(1)
)partition by list (object_type)
(
partition p1 values ('TABLE'),
partition p2 values ('TABLE PARTITION'),
partition p3 values ('INDEX'),
partition p4 values ('INDEX PARTITION'),
partition p5 values ('PROCEDURE'),
partition p6 values ('FUNCTION'),
partition other values (default)
);
表已创建。
SQL> alter table test_partition add constraint PK_PID primary key (object_id);
表已更改。
--如果表不满足重定义的条件,将会报错并给出原因。
--用DBMS_REDEFINITION.CONS_USE_PK代表用主键,是默认选项,也可以用rowid的方式,这里不讨论
SQL> EXEC DBMS_REDEFINITION.CAN_REDEF_TABLE(user, 'TEST', DBMS_REDEFINITION.CONS_USE_PK);
PL/SQL 过程已成功完成。
SQL> select owner,mview_name from user_mviews;
未选定行
SQL> select log_owner,master,log_table from user_mview_logs;
未选定行
--创建含on prebuilt table的物化视图和物化视图日志
--实现通过物化视图刷新当前表中数据进入中间表
SQL> EXEC DBMS_REDEFINITION.START_REDEF_TABLE(USER, 'TEST', 'TEST_PARTITION');
PL/SQL 过程已成功完成。
SQL> select owner,mview_name from user_mviews;
OWNER MVIEW_NAME
------------------------------ ------------------------------
TEST TEST_PARTITION
SQL> select log_owner,master,log_table from user_mview_logs;
LOG_OWNER MASTER LOG_TABLE
------------------------------ ------------------------------ ------------------------------
TEST TEST MLOG$_TEST
--实现物化视图刷新在执行同步时操作过程中变化数据。
SQL> EXEC dbms_redefinition.sync_interim_table(user, 'TEST','TEST_PARTITION') ;
PL/SQL 过程已成功完成。
--锁定原表,防止表上的DML,物化视图执行刷新,完成刷新后,将删除物化视图和对应的日志。
SQL> EXEC DBMS_REDEFINITION.FINISH_REDEF_TABLE(USER, 'TEST', 'TEST_PARTITION');
PL/SQL 过程已成功完成。
SQL> select owner,mview_name from user_mviews;
未选定行
SQL> select log_owner,master,log_table from user_mview_logs;
未选定行
SQL> select count(*) from test_partition;
COUNT(*)
----------
50504